diff --git a/.changeset/afraid-fans-cross.md b/.changeset/afraid-fans-cross.md deleted file mode 100644 index 1901d8ce0f..0000000000 --- a/.changeset/afraid-fans-cross.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@backstage/create-app': patch -'@backstage/cli': patch ---- - -Add `config.d.ts` files to the list of included file in `tsconfig.json`. - -This allows ESLint to detect issues or deprecations in those files. diff --git a/.changeset/angry-hotels-warn.md b/.changeset/angry-hotels-warn.md deleted file mode 100644 index 07caaba574..0000000000 --- a/.changeset/angry-hotels-warn.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/backend-defaults': minor -'@backstage/backend-common': minor ---- - -**BREAKING**: You can no longer supply a `basePath` option to the host discovery implementation. In the new backend system, the ability to choose this path has been removed anyway at the plugin router level. diff --git a/.changeset/angry-mayflies-collect.md b/.changeset/angry-mayflies-collect.md new file mode 100644 index 0000000000..df49f98b33 --- /dev/null +++ b/.changeset/angry-mayflies-collect.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-components': patch +--- + +Correct size of FavoriteToggle and inherit non-starred color from parent diff --git a/.changeset/angry-windows-decide.md b/.changeset/angry-windows-decide.md new file mode 100644 index 0000000000..6a5c225e80 --- /dev/null +++ b/.changeset/angry-windows-decide.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +Fix extra divider displayed in owner list picker on list tasks page diff --git a/.changeset/big-rules-nail.md b/.changeset/big-rules-nail.md new file mode 100644 index 0000000000..959ce2a26e --- /dev/null +++ b/.changeset/big-rules-nail.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-search-backend-module-elasticsearch': patch +--- + +Align the configuration schema with the docs and actual behavior of the code diff --git a/.changeset/big-spies-stare.md b/.changeset/big-spies-stare.md deleted file mode 100644 index bab1643284..0000000000 --- a/.changeset/big-spies-stare.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-techdocs-backend': patch ---- - -Dedicated token for techdocs cache sync diff --git a/.changeset/blue-forks-cry.md b/.changeset/blue-forks-cry.md deleted file mode 100644 index 1bcc1d0b59..0000000000 --- a/.changeset/blue-forks-cry.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-auth-backend-module-aws-alb-provider': patch ---- - -Fix a bug where the signer was checked from the payload instead of the header diff --git a/.changeset/breezy-bulldogs-smell.md b/.changeset/breezy-bulldogs-smell.md new file mode 100644 index 0000000000..69825142cb --- /dev/null +++ b/.changeset/breezy-bulldogs-smell.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +Create a separate route for the Scaffolder template editor and add the ability to refresh the page without closing the directory. Also, when the directory is closed, the user will stay on the editor page and can load a template folder from there. diff --git a/.changeset/breezy-flowers-dance.md b/.changeset/breezy-flowers-dance.md deleted file mode 100644 index faa9fd0697..0000000000 --- a/.changeset/breezy-flowers-dance.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-app-api': patch ---- - -Deprecate the `featureDiscoveryServiceFactory` in favor of using `@backstage/backend-defaults#discoveryFeatureLoader` instead. diff --git a/.changeset/brown-actors-clap.md b/.changeset/brown-actors-clap.md deleted file mode 100644 index af25a6e87f..0000000000 --- a/.changeset/brown-actors-clap.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-plugin-api': minor ---- - -**BREAKING**: The deprecated identity and token manager services have been removed. This means that `coreServices.identity` and `coreServices.tokenManager` are gone, along with related types and utilities in other packages. diff --git a/.changeset/brown-boxes-arrive.md b/.changeset/brown-boxes-arrive.md deleted file mode 100644 index edefc0dcaf..0000000000 --- a/.changeset/brown-boxes-arrive.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/frontend-plugin-api': minor ---- - -**BREAKING**: Removed support for "v1" extensions. This means that it is no longer possible to declare inputs and outputs as objects when using `createExtension`. In addition, all extension creators except for `createComponentExtension` have been removed, use the equivalent blueprint instead. See the [1.30 migration documentation](https://backstage.io/docs/frontend-system/architecture/migrations/#130) for more information on this change. diff --git a/.changeset/brown-frogs-walk.md b/.changeset/brown-frogs-walk.md new file mode 100644 index 0000000000..6fae44be73 --- /dev/null +++ b/.changeset/brown-frogs-walk.md @@ -0,0 +1,17 @@ +--- +'@backstage/plugin-scaffolder-backend': patch +--- + +Add `fetch:template:file` scaffolder action to download a single file and template the contents. Example usage: + +```yaml +- id: fetch-file + name: Fetch File + action: fetch:template:file + input: + url: https://github.com/backstage/software-templates/blob/main/scaffolder-templates/create-react-app/skeleton/catalog-info.yaml + targetPath: './target/catalog-info.yaml' + values: + component_id: My Component + owner: Test +``` diff --git a/.changeset/brown-worms-sneeze.md b/.changeset/brown-worms-sneeze.md deleted file mode 100644 index 51359dd384..0000000000 --- a/.changeset/brown-worms-sneeze.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-techdocs-react': patch ---- - -Fixed issue in useShadowRootElements which could lead to unlimited render loops diff --git a/.changeset/calm-brooms-fail.md b/.changeset/calm-brooms-fail.md deleted file mode 100644 index a87b5ad38c..0000000000 --- a/.changeset/calm-brooms-fail.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -'@backstage/backend-dynamic-feature-service': patch ---- - -Deprecate the `dynamicPluginsServiceRef`, `dynamicPluginsServiceFactory` and `dynamicPluginsServiceFactoryWithOptions` in favor of using the `dynamicPluginsFeatureDiscoveryLoader` to discover dynamic features in a new backend system. - -See usage examples below: - -Example using the `dynamicPluginsFeatureDiscoveryLoader` loader in a backend instance: - -```ts -import { createBackend } from '@backstage/backend-defaults'; -import { dynamicPluginsFeatureDiscoveryLoader } from '@backstage/backend-dynamic-feature-service'; -//... - -const backend = createBackend(); -backend.add(dynamicPluginsFeatureDiscoveryLoader); -//... -backend.start(); -``` - -Passing options to the `dynamicPluginsFeatureDiscoveryLoader` loader in a backend instance: - -```ts -import { createBackend } from '@backstage/backend-defaults'; -import { dynamicPluginsFeatureDiscoveryLoader } from '@backstage/backend-dynamic-feature-service'; -import { myCustomModuleLoader } from './myCustomModuleLoader'; -//... - -const backend = createBackend(); -backend.add( - dynamicPluginsFeatureDiscoveryLoader({ - moduleLoader: myCustomModuleLoader, - }), -); -//... -backend.start(); -``` diff --git a/.changeset/calm-toes-melt.md b/.changeset/calm-toes-melt.md deleted file mode 100644 index b8a7b12c46..0000000000 --- a/.changeset/calm-toes-melt.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-app-api': patch ---- - -The `defaultConfigLoader` now also reads configuration from scripts tags with `type="backstage.io/config"`. The tag is expected to contain a JSON-serialized array of `AppConfig` objects. If any of these script tags are present, the injected runtime configuration in the static assets will no longer be used. diff --git a/.changeset/chair-fairs-drive.md b/.changeset/chair-fairs-drive.md new file mode 100644 index 0000000000..91c00c063a --- /dev/null +++ b/.changeset/chair-fairs-drive.md @@ -0,0 +1,9 @@ +--- +'@backstage/frontend-plugin-api': minor +--- + +Removed deprecated `namespace` option from `createExtension` and `createExtensionBlueprint`, including `.make` and `.makeWithOverides`, it's no longer necessary and will use the `pluginId` instead. + +Removed deprecated `createExtensionOverrides` this should be replaced with `createFrontendModule` instead. + +Removed deprecated `BackstagePlugin` type, use `FrontendPlugin` type instead from this same package. diff --git a/.changeset/chilled-cameras-change.md b/.changeset/chilled-cameras-change.md deleted file mode 100644 index 8491761594..0000000000 --- a/.changeset/chilled-cameras-change.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-gitlab': patch ---- - -Internal update to use the new cache manager diff --git a/.changeset/chilled-dolphins-join.md b/.changeset/chilled-dolphins-join.md new file mode 100644 index 0000000000..4c3f5a381b --- /dev/null +++ b/.changeset/chilled-dolphins-join.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog': minor +--- + +Updated default columns for location entities to remove description and tags from the catalog table view. diff --git a/.changeset/chilly-birds-shout.md b/.changeset/chilly-birds-shout.md deleted file mode 100644 index dfa99b6f5d..0000000000 --- a/.changeset/chilly-birds-shout.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/backend-common': minor ---- - -**BREAKING**: Simplifications and cleanup as part of the Backend System 1.0 work. - -- The deprecated `dropDatabase` function has now been removed, without replacement. diff --git a/.changeset/clever-paws-stare.md b/.changeset/clever-paws-stare.md new file mode 100644 index 0000000000..ad56a5306e --- /dev/null +++ b/.changeset/clever-paws-stare.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Added functionality to the prepack script that will append the default export type for entry points to the `exports` object before publishing. This is to help with identifying the declarative integration points for plugins without needing to fetch or run the plugins first. diff --git a/.changeset/cold-nails-rescue.md b/.changeset/cold-nails-rescue.md new file mode 100644 index 0000000000..b7667305ca --- /dev/null +++ b/.changeset/cold-nails-rescue.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': minor +--- + +**BREAKING**: The Jest configuration defined at `@backstage/cli/config/jest` no longer collects configuration defined in the `"jest"` field from all parent `package.json` files. Instead, it will only read and merge configuration from the `package.json` in the monorepo root if it exists, as well as the target package. In addition, configuration defined in the root `package.json` will now only be merged into each package configuration if it is a valid project-level configuration key. diff --git a/.changeset/cold-ways-protect.md b/.changeset/cold-ways-protect.md deleted file mode 100644 index 26b693fcc6..0000000000 --- a/.changeset/cold-ways-protect.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-dynamic-feature-service': patch ---- - -Relax type check for a plugin's default export to also accept a BackendFeature defined as a function instead of an object diff --git a/.changeset/cool-actors-sin.md b/.changeset/cool-actors-sin.md deleted file mode 100644 index 4d5b2589c5..0000000000 --- a/.changeset/cool-actors-sin.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-auth-backend-module-aws-alb-provider': patch ---- - -Throw correct error when email is missing from the claims diff --git a/.changeset/cool-melons-check.md b/.changeset/cool-melons-check.md deleted file mode 100644 index 462a023dca..0000000000 --- a/.changeset/cool-melons-check.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -'@backstage/frontend-test-utils': patch -'@backstage/frontend-app-api': patch -'@backstage/core-compat-api': patch -'@backstage/plugin-catalog-import': patch -'@backstage/plugin-catalog-graph': patch -'@backstage/plugin-catalog-react': patch -'@backstage/plugin-user-settings': patch -'@backstage/plugin-search-react': patch -'@backstage/plugin-kubernetes': patch -'@backstage/plugin-scaffolder': patch -'@backstage/plugin-api-docs': patch -'@backstage/plugin-devtools': patch -'@backstage/plugin-techdocs': patch -'@backstage/plugin-catalog': patch -'@backstage/plugin-search': patch -'@backstage/plugin-home': patch -'@backstage/plugin-org': patch ---- - -Updated exports to use the new type parameters for extensions and extension blueprints. diff --git a/.changeset/cool-poems-hammer.md b/.changeset/cool-poems-hammer.md deleted file mode 100644 index fd5897343e..0000000000 --- a/.changeset/cool-poems-hammer.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-search-react': patch ---- - -Slight type tweak to match newer React versions better diff --git a/.changeset/create-app-1727774359.md b/.changeset/create-app-1727774359.md new file mode 100644 index 0000000000..b50d431d4b --- /dev/null +++ b/.changeset/create-app-1727774359.md @@ -0,0 +1,5 @@ +--- +'@backstage/create-app': patch +--- + +Bumped create-app version. diff --git a/.changeset/cuddly-rocks-invent.md b/.changeset/cuddly-rocks-invent.md deleted file mode 100644 index c4ce8ebdb9..0000000000 --- a/.changeset/cuddly-rocks-invent.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-dynamic-feature-service': minor ---- - -**BREAKING**: `dynamicPluginsServiceFactory` is no longer callable as a function. If you need to provide options to make a custom factory, use `dynamicPluginsSchemasServiceFactoryWithOptions` instead. diff --git a/.changeset/curly-brooms-raise.md b/.changeset/curly-brooms-raise.md deleted file mode 100644 index 84c8892f7c..0000000000 --- a/.changeset/curly-brooms-raise.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-search-backend': patch ---- - -Deprecate create router as the legacy backend system will no longer be supported. diff --git a/.changeset/curly-foxes-brake.md b/.changeset/curly-foxes-brake.md new file mode 100644 index 0000000000..6946f30371 --- /dev/null +++ b/.changeset/curly-foxes-brake.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +Apply `defaultValue` props in `MultiEntityPicker` diff --git a/.changeset/cyan-cooks-sing.md b/.changeset/cyan-cooks-sing.md new file mode 100644 index 0000000000..70492d0165 --- /dev/null +++ b/.changeset/cyan-cooks-sing.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend-module-gerrit': patch +--- + +Fixed an issue preventing the provider's `schedule` config from being applied." diff --git a/.changeset/cyan-peaches-lay.md b/.changeset/cyan-peaches-lay.md new file mode 100644 index 0000000000..a2b393caf8 --- /dev/null +++ b/.changeset/cyan-peaches-lay.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +Create a separate route for the template form editor so we refresh it without being redirected to scaffolder edit page. diff --git a/.changeset/cyan-vans-study.md b/.changeset/cyan-vans-study.md new file mode 100644 index 0000000000..a69b95fd85 --- /dev/null +++ b/.changeset/cyan-vans-study.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend': patch +--- + +Include step name and step id to checkpoint key diff --git a/.changeset/dry-beers-shake.md b/.changeset/dry-beers-shake.md deleted file mode 100644 index 59ff5ead54..0000000000 --- a/.changeset/dry-beers-shake.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/frontend-defaults': minor ---- - -Initial release of this package, which provides a default app setup through the `createApp` function. This replaces the existing `createApp` method from `@backstage/frontend-app-api`. diff --git a/.changeset/dry-frogs-drum.md b/.changeset/dry-frogs-drum.md new file mode 100644 index 0000000000..c929732943 --- /dev/null +++ b/.changeset/dry-frogs-drum.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +Change task list created at column to show timestamp diff --git a/.changeset/dry-glasses-push.md b/.changeset/dry-glasses-push.md deleted file mode 100644 index 31a04db24a..0000000000 --- a/.changeset/dry-glasses-push.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-auth-node': patch ---- - -Extend the "unable to resolve user identity" message diff --git a/.changeset/dry-monkeys-mate.md b/.changeset/dry-monkeys-mate.md deleted file mode 100644 index 51883ddefa..0000000000 --- a/.changeset/dry-monkeys-mate.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-kubernetes-backend': patch ---- - -The `KubernetesBuilder` and its related types has been marked as deprecared. This backend should instead be initialized using the new backend system. diff --git a/.changeset/early-drinks-kneel.md b/.changeset/early-drinks-kneel.md new file mode 100644 index 0000000000..c744cd5d7c --- /dev/null +++ b/.changeset/early-drinks-kneel.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-scaffolder-backend': minor +'@backstage/plugin-scaffolder-node': minor +--- + +Added pagination support for listing of tasks and the ability to filter on several users and task statuses. diff --git a/.changeset/early-sloths-cross.md b/.changeset/early-sloths-cross.md new file mode 100644 index 0000000000..7f4a563918 --- /dev/null +++ b/.changeset/early-sloths-cross.md @@ -0,0 +1,49 @@ +--- +'@backstage/plugin-signals-react': patch +'@backstage/plugin-signals': patch +'@backstage/plugin-api-docs-module-protoc-gen-doc': patch +'@backstage/plugin-techdocs-module-addons-contrib': patch +'@backstage/plugin-catalog-unprocessed-entities': patch +'@backstage/plugin-scaffolder-node-test-utils': patch +'@backstage/plugin-techdocs-addons-test-utils': patch +'@backstage/frontend-plugin-api': patch +'@backstage/frontend-test-utils': patch +'@backstage/integration-react': patch +'@backstage/plugin-kubernetes-cluster': patch +'@backstage/frontend-app-api': patch +'@backstage/core-compat-api': patch +'@backstage/core-components': patch +'@backstage/core-plugin-api': patch +'@backstage/plugin-kubernetes-react': patch +'@backstage/plugin-permission-react': patch +'@backstage/plugin-scaffolder-react': patch +'@backstage/version-bridge': patch +'@backstage/plugin-app-visualizer': patch +'@backstage/plugin-catalog-import': patch +'@backstage/plugin-techdocs-react': patch +'@backstage/app-defaults': patch +'@backstage/core-app-api': patch +'@backstage/plugin-catalog-graph': patch +'@backstage/plugin-catalog-react': patch +'@backstage/plugin-config-schema': patch +'@backstage/plugin-notifications': patch +'@backstage/plugin-user-settings': patch +'@backstage/plugin-search-react': patch +'@backstage/test-utils': patch +'@backstage/dev-utils': patch +'@backstage/plugin-auth-react': patch +'@backstage/plugin-home-react': patch +'@backstage/plugin-kubernetes': patch +'@backstage/plugin-scaffolder': patch +'@backstage/plugin-org-react': patch +'@backstage/plugin-api-docs': patch +'@backstage/plugin-devtools': patch +'@backstage/plugin-techdocs': patch +'@backstage/plugin-catalog': patch +'@backstage/theme': patch +'@backstage/plugin-search': patch +'@backstage/plugin-home': patch +'@backstage/plugin-org': patch +--- + +Move `@types/react` to a peer dependency. diff --git a/.changeset/early-swans-grab.md b/.changeset/early-swans-grab.md deleted file mode 100644 index 4526067275..0000000000 --- a/.changeset/early-swans-grab.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-confluence-to-markdown': patch -'@backstage/plugin-scaffolder-backend-module-cookiecutter': patch -'@backstage/plugin-scaffolder-backend-module-gitlab': patch -'@backstage/plugin-scaffolder-backend-module-sentry': patch -'@backstage/plugin-scaffolder-backend-module-yeoman': patch -'@backstage/plugin-scaffolder-backend-module-rails': patch -'@backstage/plugin-user-settings-backend': patch -'@backstage/plugin-devtools-backend': patch ---- - -Update README installation instructions diff --git a/.changeset/eight-steaks-chew.md b/.changeset/eight-steaks-chew.md new file mode 100644 index 0000000000..4651d3fb8c --- /dev/null +++ b/.changeset/eight-steaks-chew.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-scaffolder-react': minor +'@backstage/plugin-scaffolder': minor +--- + +Added support for `FormFieldBlueprint` to create field extensions in the Scaffolder plugin diff --git a/.changeset/eighty-tables-hope.md b/.changeset/eighty-tables-hope.md deleted file mode 100644 index 203cc8bb65..0000000000 --- a/.changeset/eighty-tables-hope.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/frontend-test-utils': patch ---- - -Internal update to add support for passing an `ApiRegistry` when creating the node tree diff --git a/.changeset/eleven-pugs-hear.md b/.changeset/eleven-pugs-hear.md new file mode 100644 index 0000000000..5d65057e0b --- /dev/null +++ b/.changeset/eleven-pugs-hear.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-api-docs': patch +'@backstage/plugin-catalog': patch +--- + +Empty states updated with external link icon for learn more links diff --git a/.changeset/empty-coats-sparkle.md b/.changeset/empty-coats-sparkle.md deleted file mode 100644 index 7e3b791c6b..0000000000 --- a/.changeset/empty-coats-sparkle.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/frontend-test-utils': minor ---- - -Removed support for testing "v1" extensions, where outputs are defined as an object rather than an array. diff --git a/.changeset/fair-chairs-drive.md b/.changeset/fair-chairs-drive.md new file mode 100644 index 0000000000..fae2195821 --- /dev/null +++ b/.changeset/fair-chairs-drive.md @@ -0,0 +1,5 @@ +--- +'@backstage/frontend-app-api': minor +--- + +Removed deprecated `createApp` and `CreateAppFeatureLoader` from `@backstage/frontend-app-api`, use the same `createApp` and `CreateAppFeatureLoader` import from `@backstage/frontend-defaults` instead. diff --git a/.changeset/famous-badgers-drop.md b/.changeset/famous-badgers-drop.md deleted file mode 100644 index af519cf964..0000000000 --- a/.changeset/famous-badgers-drop.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-test-utils': patch ---- - -Added missing service mock for `mockServices.rootConfig.mock`, and fixed the definition of `mockServices.rootHttpRouter.factory` to not have a duplicate callback. diff --git a/.changeset/famous-bobcats-remain.md b/.changeset/famous-bobcats-remain.md new file mode 100644 index 0000000000..6943eb7e56 --- /dev/null +++ b/.changeset/famous-bobcats-remain.md @@ -0,0 +1,5 @@ +--- +'@backstage/eslint-plugin': patch +--- + +Internal refactor to deal with `estree` upgrade diff --git a/.changeset/fifty-trainers-watch.md b/.changeset/fifty-trainers-watch.md new file mode 100644 index 0000000000..5cef1ad2b2 --- /dev/null +++ b/.changeset/fifty-trainers-watch.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-techdocs': patch +--- + +Make `emptyState` input optional on `entity-content:techdocs` extension so that +the default empty state extension works correctly. diff --git a/.changeset/five-gorillas-pay.md b/.changeset/five-gorillas-pay.md new file mode 100644 index 0000000000..c5cd18a186 --- /dev/null +++ b/.changeset/five-gorillas-pay.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +Create a separate route for the custom fields explorer so we refresh it without being redirected to scaffolder edit page. diff --git a/.changeset/five-tigers-share.md b/.changeset/five-tigers-share.md deleted file mode 100644 index 507614c8b8..0000000000 --- a/.changeset/five-tigers-share.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': patch ---- - -Found the issue during testing the clean up of the workspace for the database implementation. diff --git a/.changeset/five-turkeys-taste.md b/.changeset/five-turkeys-taste.md new file mode 100644 index 0000000000..7f3361ebbf --- /dev/null +++ b/.changeset/five-turkeys-taste.md @@ -0,0 +1,5 @@ +--- +'@backstage/repo-tools': patch +--- + +Properly log instructions when APIs do not match diff --git a/.changeset/flat-eels-exist.md b/.changeset/flat-eels-exist.md new file mode 100644 index 0000000000..fb30b51e82 --- /dev/null +++ b/.changeset/flat-eels-exist.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Remove unknown dependency `diff` diff --git a/.changeset/flat-kangaroos-push.md b/.changeset/flat-kangaroos-push.md deleted file mode 100644 index b046beeeb1..0000000000 --- a/.changeset/flat-kangaroos-push.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -'@backstage/frontend-plugin-api': minor ---- - -**BREAKING**: Updated the type parameters for `ExtensionDefinition` and `ExtensionBlueprint` to only have a single object parameter. The base type parameter is exported as `ExtensionDefinitionParameters` and `ExtensionBlueprintParameters` respectively. This is shipped as an immediate breaking change as we expect usage of these types to be rare, and it does not affect the runtime behavior of the API. - -This is a breaking change as it changes the type parameters. Existing usage can generally be updated as follows: - -- `ExtensionDefinition` -> `ExtensionDefinition` -- `ExtensionDefinition` -> `ExtensionDefinition` -- `ExtensionDefinition` -> `ExtensionDefinition<{ config: TConfig }>` -- `ExtensionDefinition` -> `ExtensionDefinition<{ config: TConfig, configInput: TConfigInput }>` - -If you need to infer the parameter you can use `ExtensionDefinitionParameters`, for example: - -```ts -import { - ExtensionDefinition, - ExtensionDefinitionParameters, -} from '@backstage/frontend-plugin-api'; - -function myUtility( - ext: ExtensionDefinition, -): T['config'] { - // ... -} -``` - -The same patterns apply to `ExtensionBlueprint`. - -This change is made to improve the readability of API references and ability to evolve the type parameters in the future. diff --git a/.changeset/fluffy-pears-cry.md b/.changeset/fluffy-pears-cry.md new file mode 100644 index 0000000000..2da74eb857 --- /dev/null +++ b/.changeset/fluffy-pears-cry.md @@ -0,0 +1,6 @@ +--- +'@backstage/repo-tools': minor +--- + +Update @microsoft/api-extractor and use their api report resolution. +Change api report format from `api-report.md` to `report.api.md` diff --git a/.changeset/forty-toes-float.md b/.changeset/forty-toes-float.md deleted file mode 100644 index b6ca5139ea..0000000000 --- a/.changeset/forty-toes-float.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/frontend-test-utils': minor ---- - -**BREAKING**: The deprecated `.render()` method has been removed from the extension tester. diff --git a/.changeset/four-moons-watch.md b/.changeset/four-moons-watch.md new file mode 100644 index 0000000000..3d0b25c1d5 --- /dev/null +++ b/.changeset/four-moons-watch.md @@ -0,0 +1,5 @@ +--- +'@backstage/integration-react': patch +--- + +Revert of change #26430 diff --git a/.changeset/four-parents-buy.md b/.changeset/four-parents-buy.md deleted file mode 100644 index ac216c3c08..0000000000 --- a/.changeset/four-parents-buy.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/frontend-app-api': minor ---- - -**BREAKING**: The `createSpecializedApp` function now creates a bare-bones app without any of the default app structure or APIs. To re-introduce this functionality if you need to use `createSpecializedApp` you can install the `app` plugin from `@backstage/plugin-app`. - -In addition, the `createApp` and `CreateAppFeatureLoader` exports are now deprecated as they are being moved to `@backstage/frontend-defaults`, which should be used instead. diff --git a/.changeset/four-ties-raise.md b/.changeset/four-ties-raise.md deleted file mode 100644 index 163443afff..0000000000 --- a/.changeset/four-ties-raise.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-react': minor ---- - -Add `ui:backstage.review.name` option for custom item names on scaffolder review page, and also add support for rendering the `title` property instead of the key name. diff --git a/.changeset/fresh-apes-dress.md b/.changeset/fresh-apes-dress.md deleted file mode 100644 index 6e20e53bcd..0000000000 --- a/.changeset/fresh-apes-dress.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@backstage/frontend-plugin-api': patch -'@backstage/frontend-test-utils': patch -'@backstage/frontend-app-api': patch -'@backstage/plugin-app': minor ---- - -Introduce the `@backstage/plugin-app` package to hold all of the built-in extensions for easy consumption and overriding. diff --git a/.changeset/fresh-bears-prove.md b/.changeset/fresh-bears-prove.md deleted file mode 100644 index a4098a4b18..0000000000 --- a/.changeset/fresh-bears-prove.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/cli': patch -'@backstage/create-app': patch ---- - -Update templates to not refer to backend-common diff --git a/.changeset/fresh-pumas-clean.md b/.changeset/fresh-pumas-clean.md deleted file mode 100644 index 2140f62651..0000000000 --- a/.changeset/fresh-pumas-clean.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-app-backend': patch -'@backstage/plugin-app-node': patch ---- - -Fixing dependency metadata with the new `@backstage/plugin-app` package diff --git a/.changeset/friendly-cougars-return.md b/.changeset/friendly-cougars-return.md new file mode 100644 index 0000000000..8852177e0a --- /dev/null +++ b/.changeset/friendly-cougars-return.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Added support for a new experimental `EXPERIMENTAL_TRIM_NEXT_ENTRY` flag which removes any `./next` entry points present in packages when building and publishing. diff --git a/.changeset/friendly-days-march.md b/.changeset/friendly-days-march.md deleted file mode 100644 index a190c50a43..0000000000 --- a/.changeset/friendly-days-march.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/frontend-plugin-api': patch ---- - -Added `createFrontendModule` as a replacement for `createExtensionOverrides`, which is now deprecated. - -Deprecated the `BackstagePlugin` and `FrontendFeature` type in favor of `FrontendPlugin` and `FrontendFeature` from `@backstage/frontend-app-api` respectively. diff --git a/.changeset/friendly-months-march.md b/.changeset/friendly-months-march.md deleted file mode 100644 index 0bb9cd7cf0..0000000000 --- a/.changeset/friendly-months-march.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/frontend-app-api': patch -'@backstage/core-compat-api': patch ---- - -Added support for new `FrontendPlugin` and `FrontendModule` types. diff --git a/.changeset/funny-houses-rest.md b/.changeset/funny-houses-rest.md deleted file mode 100644 index 21efce8c19..0000000000 --- a/.changeset/funny-houses-rest.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-techdocs-backend': patch ---- - -The `createRouter` and its related types has been marked as deprecared. This backend should instead be initialized using the new backend system. diff --git a/.changeset/funny-rocks-train.md b/.changeset/funny-rocks-train.md new file mode 100644 index 0000000000..f5b2fbba63 --- /dev/null +++ b/.changeset/funny-rocks-train.md @@ -0,0 +1,6 @@ +--- +'@backstage/frontend-plugin-api': patch +'@backstage/frontend-test-utils': patch +--- + +Internal refactor of usage of opaque types. diff --git a/.changeset/fuzzy-elephants-tease.md b/.changeset/fuzzy-elephants-tease.md new file mode 100644 index 0000000000..014a1136fd --- /dev/null +++ b/.changeset/fuzzy-elephants-tease.md @@ -0,0 +1,5 @@ +--- +'@backstage/create-app': patch +--- + +Fixed lack of `.yarnrc.yml` in the template. diff --git a/.changeset/fuzzy-feet-exist.md b/.changeset/fuzzy-feet-exist.md deleted file mode 100644 index 35ef1e58fd..0000000000 --- a/.changeset/fuzzy-feet-exist.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -'@backstage/frontend-plugin-api': patch -'@backstage/plugin-app': patch ---- - -Deprecated the `namespace` option for `createExtensionBlueprint` and `createExtension`, these are no longer required and will default to the `pluginId` instead. - -You can migrate some of your extensions that use `createExtensionOverrides` to using `createFrontendModule` instead and providing a `pluginId` there. - -```ts -// Before -createExtensionOverrides({ - extensions: [ - createExtension({ - name: 'my-extension', - namespace: 'my-namespace', - kind: 'test', - ... - }) - ], -}); - -// After -createFrontendModule({ - pluginId: 'my-namespace', - extensions: [ - createExtension({ - name: 'my-extension', - kind: 'test', - ... - }) - ], -}); -``` diff --git a/.changeset/fuzzy-mails-walk.md b/.changeset/fuzzy-mails-walk.md deleted file mode 100644 index b46fbd59c4..0000000000 --- a/.changeset/fuzzy-mails-walk.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-plugin-api': patch ---- - -Deprecate the `featureDiscoveryServiceRef` in favor of using the new `discoveryFeatureLoader` instead. diff --git a/.changeset/fuzzy-spies-share.md b/.changeset/fuzzy-spies-share.md deleted file mode 100644 index 99108b81a0..0000000000 --- a/.changeset/fuzzy-spies-share.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-signals-backend': patch ---- - -The `createRouter` and its related types has been marked as deprecared. This backend should instead be initialized using the new backend system. diff --git a/.changeset/gentle-hats-act.md b/.changeset/gentle-hats-act.md deleted file mode 100644 index e78076c9c5..0000000000 --- a/.changeset/gentle-hats-act.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/frontend-defaults': patch ---- - -Added a new `CreateAppOptions` type for the `createApp` options. diff --git a/.changeset/giant-jars-mix.md b/.changeset/giant-jars-mix.md deleted file mode 100644 index 652e23a280..0000000000 --- a/.changeset/giant-jars-mix.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/create-app': patch -'@backstage/plugin-devtools': patch ---- - -Minor dockerfile syntax update diff --git a/.changeset/giant-kiwis-retire.md b/.changeset/giant-kiwis-retire.md new file mode 100644 index 0000000000..380e05042f --- /dev/null +++ b/.changeset/giant-kiwis-retire.md @@ -0,0 +1,5 @@ +--- +'@backstage/app-defaults': patch +--- + +Added `externalLink` to icon defaults diff --git a/.changeset/gold-pots-end.md b/.changeset/gold-pots-end.md new file mode 100644 index 0000000000..e7291fc3ad --- /dev/null +++ b/.changeset/gold-pots-end.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': minor +--- + +Improved the layout of the manage templates page (`/edit`) by adding icons and descriptions that better describe what each page is for. Updated the header menu to link back to the scaffolder create page. diff --git a/.changeset/gorgeous-scissors-wave.md b/.changeset/gorgeous-scissors-wave.md deleted file mode 100644 index 1db406b940..0000000000 --- a/.changeset/gorgeous-scissors-wave.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-app-api': patch ---- - -Updated the error message for missing service dependencies to include the plugin and module IDs. diff --git a/.changeset/great-zebras-hunt.md b/.changeset/great-zebras-hunt.md deleted file mode 100644 index 252f270092..0000000000 --- a/.changeset/great-zebras-hunt.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/cli': patch ---- - -The app build process now outputs an additional `index.html.tmpl` file. This is an non-templated version of the `index.html` file, which can be used to delay templating until runtime. - -The new `index.html.tmpl` file also sets a `backstage-public-path` meta tag to be templated at runtime. The meta tag is in turn picked up by the new `@backstage/cli/config/webpack-public-path.js` entry point script, which uses it to set the runtime public path of the Webpack bundle. diff --git a/.changeset/green-bottles-live.md b/.changeset/green-bottles-live.md new file mode 100644 index 0000000000..6bed257eee --- /dev/null +++ b/.changeset/green-bottles-live.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-scaffolder-react': patch +'@backstage/plugin-scaffolder': patch +--- + +Add support for pagination in scaffolder tasks list diff --git a/.changeset/green-worms-rescue.md b/.changeset/green-worms-rescue.md deleted file mode 100644 index 992012ad7d..0000000000 --- a/.changeset/green-worms-rescue.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Add `checks: 'read'` for default GitHub app permissions diff --git a/.changeset/happy-ligers-think.md b/.changeset/happy-ligers-think.md new file mode 100644 index 0000000000..69dd68ae6c --- /dev/null +++ b/.changeset/happy-ligers-think.md @@ -0,0 +1,5 @@ +--- +'@backstage/app-defaults': patch +--- + +Updated the `bitbucket-server-auth` default API to set its environment based on the `auth.environment` config option instead of being hardcoded to `development`. diff --git a/.changeset/healthy-moons-drum.md b/.changeset/healthy-moons-drum.md deleted file mode 100644 index 0f61d0b141..0000000000 --- a/.changeset/healthy-moons-drum.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -'@backstage/backend-plugin-api': minor ---- - -Removed the following deprecated exports - -- `BackendPluginConfig` use `CreateBackendPluginOptions` -- `BackendModuleConfig` use `CreateBackendModuleOptions` -- `ExtensionPointConfig` use `CreateExtensionPointOptions` diff --git a/.changeset/heavy-suits-judge.md b/.changeset/heavy-suits-judge.md deleted file mode 100644 index d5c00184c7..0000000000 --- a/.changeset/heavy-suits-judge.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-user-settings-backend': patch ---- - -In preparation to stop supporting to the legacy backend system, the `createRouter` function is now deprecated and we strongly recommend you [migrate](https://backstage.io/docs/backend-system/building-backends/migrating) your backend to the new system. diff --git a/.changeset/heavy-ties-tell.md b/.changeset/heavy-ties-tell.md new file mode 100644 index 0000000000..072b0c7860 --- /dev/null +++ b/.changeset/heavy-ties-tell.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-backend-module-microsoft-provider': patch +--- + +Add `skipUserProfile` config flag to Microsoft authenticator diff --git a/.changeset/hip-pandas-think.md b/.changeset/hip-pandas-think.md deleted file mode 100644 index a43349db63..0000000000 --- a/.changeset/hip-pandas-think.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-techdocs-node': patch ---- - -Fix typo and unify TechDocs casing in doc strings diff --git a/.changeset/honest-impalas-rescue.md b/.changeset/honest-impalas-rescue.md new file mode 100644 index 0000000000..bac076bba6 --- /dev/null +++ b/.changeset/honest-impalas-rescue.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-components': patch +--- + +Fixed a bug in the `SidebarSubmenu` core component that caused the nested menu to overlap with the sidebar when the user hovers over the pinned sidebar. diff --git a/.changeset/hungry-buckets-repair.md b/.changeset/hungry-buckets-repair.md new file mode 100644 index 0000000000..fde682d603 --- /dev/null +++ b/.changeset/hungry-buckets-repair.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +Change "Register Existing Component" CTA to outlined as it's not a primary action on the scaffolder pages diff --git a/.changeset/khaki-crews-rule.md b/.changeset/khaki-crews-rule.md deleted file mode 100644 index 4d8eb32083..0000000000 --- a/.changeset/khaki-crews-rule.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -'@backstage/plugin-app-backend': patch ---- - -**BREAKING**: The app backend now supports the new `index.html.tmpl` output from `@backstage/cli`. If available, the `index.html` will be templated at runtime with the current configuration of the app backend. - -This is marked as a breaking change because you must now supply the app build-time configuration to the backend. This change also affects the public path behavior, where it is no longer necessary to build the app with the correct public path upfront. You now only need to supply a correct `app.baseUrl` to the app backend plugin at runtime. - -An effect that this change has is that the `index.html` will now contain and present the frontend configuration in an easily readable way, which can aid in debugging. This data was always available in the frontend, but it was injected and hidden in the static bundle. - -This templating behavior is enabled by default, but it can be disabled by setting the `app.disableConfigInjection` configuration option to `true`. diff --git a/.changeset/kind-moose-learn.md b/.changeset/kind-moose-learn.md deleted file mode 100644 index 810064b1a1..0000000000 --- a/.changeset/kind-moose-learn.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-app-api': minor ---- - -**BREAKING**: The deprecated `identityServiceFactory` and `tokenManagerServiceFactory` have been removed. diff --git a/.changeset/kind-walls-speak.md b/.changeset/kind-walls-speak.md deleted file mode 100644 index 441e247dea..0000000000 --- a/.changeset/kind-walls-speak.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-defaults': minor ---- - -**BREAKING**: The backwards compatibility with plugins using legacy auth through the token manager service has been removed. This means that instead of falling back to using the old token manager, requests towards plugins that don't support the new auth system will simply fail. Please make sure that all plugins in your deployment are hosted within a backend instance from the new backend system. diff --git a/.changeset/large-hats-reply.md b/.changeset/large-hats-reply.md new file mode 100644 index 0000000000..02fe00d70c --- /dev/null +++ b/.changeset/large-hats-reply.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': minor +--- + +Text field content of the `EntityPicker` is now more readable as it uses entity title instead of entity reference. diff --git a/.changeset/large-plants-rhyme.md b/.changeset/large-plants-rhyme.md new file mode 100644 index 0000000000..3566826730 --- /dev/null +++ b/.changeset/large-plants-rhyme.md @@ -0,0 +1,30 @@ +--- +'@backstage/frontend-plugin-api': patch +--- + +It is now possible to override the blueprint parameters when overriding an extension created from a blueprint: + +```ts +const myExtension = MyBlueprint.make({ + params: { + myParam: 'myDefault', + }, +}); + +const myOverride = myExtension.override({ + params: { + myParam: 'myOverride', + }, +}); +const myFactoryOverride = myExtension.override({ + factory(origFactory) { + return origFactory({ + params: { + myParam: 'myOverride', + }, + }); + }, +}); +``` + +The provided parameters will be merged with the original parameters of the extension. diff --git a/.changeset/large-poets-check.md b/.changeset/large-poets-check.md deleted file mode 100644 index 393d26ac9b..0000000000 --- a/.changeset/large-poets-check.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-bitbucket-cloud': patch -'@backstage/plugin-search-backend-module-techdocs': patch -'@backstage/plugin-search-backend-module-catalog': patch -'@backstage/plugin-search-backend-module-explore': patch -'@backstage/plugin-permission-node': patch -'@backstage/plugin-signals-backend': patch -'@backstage/plugin-auth-backend': patch ---- - -Internal refactor to remove dependencies on the identity and token manager services, which have been removed. Public APIs no longer require the identity service or token manager to be provided. diff --git a/.changeset/light-rats-travel.md b/.changeset/light-rats-travel.md new file mode 100644 index 0000000000..de497567ef --- /dev/null +++ b/.changeset/light-rats-travel.md @@ -0,0 +1,54 @@ +--- +'@backstage/plugin-scaffolder-backend-module-confluence-to-markdown': patch +'@backstage/plugin-search-backend-module-stack-overflow-collator': patch +'@backstage/plugin-catalog-backend-module-incremental-ingestion': patch +'@backstage/plugin-scaffolder-backend-module-notifications': patch +'@backstage/plugin-catalog-backend-module-bitbucket-cloud': patch +'@backstage/plugin-scaffolder-backend-module-cookiecutter': patch +'@backstage/plugin-auth-backend-module-aws-alb-provider': patch +'@backstage/plugin-search-backend-module-elasticsearch': patch +'@backstage/plugin-auth-backend-module-guest-provider': patch +'@backstage/plugin-catalog-backend-module-unprocessed': patch +'@backstage/plugin-notifications-backend-module-email': patch +'@backstage/plugin-auth-backend-module-oidc-provider': patch +'@backstage/plugin-catalog-backend-module-gitlab-org': patch +'@backstage/backend-dynamic-feature-service': patch +'@backstage/plugin-scaffolder-backend-module-github': patch +'@backstage/plugin-scaffolder-backend-module-gitlab': patch +'@backstage/plugin-scaffolder-backend-module-yeoman': patch +'@backstage/plugin-scaffolder-backend-module-rails': patch +'@backstage/plugin-catalog-backend-module-openapi': patch +'@backstage/plugin-search-backend-module-techdocs': patch +'@backstage/plugin-catalog-backend-module-github': patch +'@backstage/plugin-events-backend-module-aws-sqs': patch +'@backstage/plugin-search-backend-module-catalog': patch +'@backstage/plugin-search-backend-module-explore': patch +'@backstage/plugin-scaffolder-node-test-utils': patch +'@backstage/plugin-search-backend-module-pg': patch +'@backstage/plugin-notifications-backend': patch +'@backstage/plugin-search-backend-node': patch +'@backstage/plugin-kubernetes-backend': patch +'@backstage/plugin-notifications-node': patch +'@backstage/plugin-permission-backend': patch +'@backstage/plugin-scaffolder-backend': patch +'@backstage/backend-defaults': patch +'@backstage/backend-app-api': patch +'@backstage/plugin-devtools-backend': patch +'@backstage/plugin-techdocs-backend': patch +'@backstage/plugin-catalog-backend': patch +'@backstage/plugin-kubernetes-node': patch +'@backstage/plugin-permission-node': patch +'@backstage/plugin-scaffolder-node': patch +'@backstage/plugin-signals-backend': patch +'@backstage/plugin-events-backend': patch +'@backstage/plugin-search-backend': patch +'@backstage/plugin-proxy-backend': patch +'@backstage/plugin-auth-backend': patch +'@backstage/plugin-signals-node': patch +'@backstage/plugin-app-backend': patch +'@backstage/plugin-events-node': patch +'@backstage/plugin-auth-node': patch +'@backstage/cli': patch +--- + +Remove references to in-repo backend-common diff --git a/.changeset/long-humans-hunt.md b/.changeset/long-humans-hunt.md new file mode 100644 index 0000000000..e27ebfbd3d --- /dev/null +++ b/.changeset/long-humans-hunt.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': minor +--- + +Added ability to create a new local scaffolder template to ease onboarding when creating new templates. diff --git a/.changeset/loud-brooms-pull.md b/.changeset/loud-brooms-pull.md deleted file mode 100644 index 8ed3e22c5b..0000000000 --- a/.changeset/loud-brooms-pull.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@backstage/catalog-client': patch -'@backstage/plugin-catalog-backend': patch ---- - -Moved `getEntities` ordering to utilize database instead of having it inside catalog client - -Please note that the latest version of `@backstage/catalog-client` will not order the entities in the same way as before. This is because the ordering is now done in the database query instead of in the client. If you rely on the ordering of the entities, you may need to update your backend plugin or code to handle this change. diff --git a/.changeset/loud-hotels-tan.md b/.changeset/loud-hotels-tan.md new file mode 100644 index 0000000000..34890dfe97 --- /dev/null +++ b/.changeset/loud-hotels-tan.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-react': minor +--- + +Added a new prop, `disableTooltip` to the `EntityRefLink` component diff --git a/.changeset/lucky-sheep-cover.md b/.changeset/lucky-sheep-cover.md deleted file mode 100644 index 9b9420a73a..0000000000 --- a/.changeset/lucky-sheep-cover.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-common': patch ---- - -The `legacyPlugin` and `makeLegacyPlugin` helpers now provide their own shim implementation of the identity and token manager services, as these services are being removed from the new backend system. diff --git a/.changeset/metal-garlics-fetch.md b/.changeset/metal-garlics-fetch.md deleted file mode 100644 index 076b5f34a5..0000000000 --- a/.changeset/metal-garlics-fetch.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/frontend-plugin-api': patch -'@backstage/frontend-app-api': patch ---- - -Moved several implementations of built-in APIs from being hardcoded in the app to instead be provided as API extensions. This moves all API-related inputs from the `app` extension to the respective API extensions. For example, extensions created with `ThemeBlueprint` are now attached to the `themes` input of `api:app-theme` rather than the `app` extension. diff --git a/.changeset/metal-rivers-grin.md b/.changeset/metal-rivers-grin.md deleted file mode 100644 index b70750c98d..0000000000 --- a/.changeset/metal-rivers-grin.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-test-utils': patch ---- - -There is a new `mockErrorHandler` utility to help in mocking the error middleware in tests. diff --git a/.changeset/mighty-cheetahs-call.md b/.changeset/mighty-cheetahs-call.md deleted file mode 100644 index f5d17d8b20..0000000000 --- a/.changeset/mighty-cheetahs-call.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-defaults': patch ---- - -Move down the discovery config to be in the root diff --git a/.changeset/mighty-days-kiss.md b/.changeset/mighty-days-kiss.md deleted file mode 100644 index f78e602e25..0000000000 --- a/.changeset/mighty-days-kiss.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/backend-defaults': patch -'@backstage/backend-app-api': patch ---- - -`auth.externalAccess` should be optional in the config schema diff --git a/.changeset/nasty-lamps-greet.md b/.changeset/nasty-lamps-greet.md new file mode 100644 index 0000000000..75d8086db7 --- /dev/null +++ b/.changeset/nasty-lamps-greet.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': minor +--- + +Added ability to link to a specific action on the actions page diff --git a/.changeset/nasty-tigers-knock.md b/.changeset/nasty-tigers-knock.md deleted file mode 100644 index c48d725779..0000000000 --- a/.changeset/nasty-tigers-knock.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -'@backstage/backend-common': patch -'@backstage/backend-dynamic-feature-service': patch -'@backstage/plugin-app-backend': patch -'@backstage/plugin-catalog-backend-module-aws': patch -'@backstage/plugin-catalog-backend-module-azure': patch -'@backstage/plugin-catalog-backend-module-bitbucket-cloud': patch -'@backstage/plugin-catalog-backend-module-bitbucket-server': patch -'@backstage/plugin-catalog-backend-module-gerrit': patch -'@backstage/plugin-catalog-backend-module-github': patch -'@backstage/plugin-catalog-backend-module-gitlab': patch -'@backstage/plugin-catalog-backend-module-incremental-ingestion': patch -'@backstage/plugin-catalog-backend-module-msgraph': patch -'@backstage/plugin-catalog-backend-module-puppetdb': patch -'@backstage/plugin-catalog-backend': patch -'@backstage/plugin-events-backend-module-aws-sqs': patch -'@backstage/plugin-events-backend-module-azure': patch -'@backstage/plugin-events-backend-module-bitbucket-cloud': patch -'@backstage/plugin-events-backend-module-gerrit': patch -'@backstage/plugin-events-backend-module-github': patch -'@backstage/plugin-events-backend-module-gitlab': patch -'@backstage/plugin-events-backend': patch -'@backstage/plugin-kubernetes-backend': patch -'@backstage/plugin-permission-backend': patch -'@backstage/plugin-proxy-backend': patch -'@backstage/plugin-scaffolder-backend': patch -'@backstage/plugin-search-backend-module-catalog': patch -'@backstage/plugin-search-backend-module-elasticsearch': patch -'@backstage/plugin-search-backend-module-explore': patch -'@backstage/plugin-search-backend-module-pg': patch -'@backstage/plugin-search-backend-module-techdocs': patch -'@backstage/plugin-search-backend': patch -'@backstage/plugin-techdocs-backend': patch -'@backstage/plugin-user-settings-backend': patch ---- - -Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. diff --git a/.changeset/new-poets-unite.md b/.changeset/new-poets-unite.md deleted file mode 100644 index 83172ffd66..0000000000 --- a/.changeset/new-poets-unite.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-kubernetes': patch ---- - -Make k8s entity content appear on components & resources only by default in new FE system diff --git a/.changeset/nice-badgers-travel.md b/.changeset/nice-badgers-travel.md new file mode 100644 index 0000000000..7ec79b56d8 --- /dev/null +++ b/.changeset/nice-badgers-travel.md @@ -0,0 +1,5 @@ +--- +'@backstage/repo-tools': minor +--- + +Adds a new command `backstage-repo-tools peer-deps` for validating your usage of peer dependencies in your plugins. It currently supports react related peer dependencies. It also has a `--fix` mode for quickly fixing any issues that it finds. diff --git a/.changeset/ninety-mayflies-raise.md b/.changeset/ninety-mayflies-raise.md deleted file mode 100644 index 62042c2615..0000000000 --- a/.changeset/ninety-mayflies-raise.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-search-backend-module-elasticsearch': patch -'@backstage/plugin-search-backend-module-pg': patch ---- - -Internal refactor to use `LoggerService` and `DatabaseService` instead of the legacy `Logger` and `PluginDatabaseManager` types. diff --git a/.changeset/odd-goats-kiss.md b/.changeset/odd-goats-kiss.md deleted file mode 100644 index 0f199c1a1e..0000000000 --- a/.changeset/odd-goats-kiss.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-components': patch ---- - -Added `titleComponent` prop to `SignInPage` component to allow further customization of the title using `ReactNode` diff --git a/.changeset/olive-phones-sniff.md b/.changeset/olive-phones-sniff.md deleted file mode 100644 index d70953435c..0000000000 --- a/.changeset/olive-phones-sniff.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-common': patch ---- - -Add `pg-format` as a dependency diff --git a/.changeset/plenty-dragons-know.md b/.changeset/plenty-dragons-know.md deleted file mode 100644 index 2aa8458011..0000000000 --- a/.changeset/plenty-dragons-know.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/frontend-defaults': patch ---- - -Added `createPublicSignInApp`, used to creating apps for the public entry point. diff --git a/.changeset/polite-days-flash.md b/.changeset/polite-days-flash.md new file mode 100644 index 0000000000..6a54d08c5a --- /dev/null +++ b/.changeset/polite-days-flash.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-compat-api': patch +--- + +Internal update to remove deprecated `BackstagePlugin` type and move to `FrontendPlugin` diff --git a/.changeset/poor-dodos-wait.md b/.changeset/poor-dodos-wait.md new file mode 100644 index 0000000000..f1d0b4e941 --- /dev/null +++ b/.changeset/poor-dodos-wait.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +Add translation to the editor toolbar component. diff --git a/.changeset/popular-cooks-camp.md b/.changeset/popular-cooks-camp.md deleted file mode 100644 index 4049825efd..0000000000 --- a/.changeset/popular-cooks-camp.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-test-utils': minor ---- - -**BREAKING**: Removed service mocks for the identity and token manager services, which have been removed from `@backstage/backend-plugin-api`. diff --git a/.changeset/pre.json b/.changeset/pre.json index 0266c977a1..1d47683d1b 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -2,309 +2,262 @@ "mode": "pre", "tag": "next", "initialVersions": { - "example-app": "0.2.100", - "@backstage/app-defaults": "1.5.10", - "example-app-next": "0.0.14", - "app-next-example-plugin": "0.0.14", - "example-backend": "0.0.29", - "@backstage/backend-app-api": "0.9.0", - "@backstage/backend-common": "0.24.0", - "@backstage/backend-defaults": "0.4.2", + "example-app": "0.2.101", + "@backstage/app-defaults": "1.5.11", + "example-app-next": "0.0.15", + "app-next-example-plugin": "0.0.15", + "example-backend": "0.0.30", + "@backstage/backend-app-api": "1.0.0", + "@backstage/backend-defaults": "0.5.0", "@backstage/backend-dev-utils": "0.1.5", - "@backstage/backend-dynamic-feature-service": "0.3.0", - "example-backend-legacy": "0.2.101", - "@backstage/backend-openapi-utils": "0.1.16", - "@backstage/backend-plugin-api": "0.8.0", - "@backstage/backend-test-utils": "0.5.0", - "@backstage/catalog-client": "1.6.6", - "@backstage/catalog-model": "1.6.0", - "@backstage/cli": "0.27.0", + "@backstage/backend-dynamic-feature-service": "0.4.0", + "example-backend-legacy": "0.2.102", + "@backstage/backend-openapi-utils": "0.1.18", + "@backstage/backend-plugin-api": "1.0.0", + "@backstage/backend-test-utils": "1.0.0", + "@backstage/catalog-client": "1.7.0", + "@backstage/catalog-model": "1.7.0", + "@backstage/cli": "0.27.1", "@backstage/cli-common": "0.1.14", - "@backstage/cli-node": "0.2.7", - "@backstage/codemods": "0.1.49", + "@backstage/cli-node": "0.2.8", + "@backstage/codemods": "0.1.50", "@backstage/config": "1.2.0", - "@backstage/config-loader": "1.9.0", - "@backstage/core-app-api": "1.14.2", - "@backstage/core-compat-api": "0.2.8", - "@backstage/core-components": "0.14.10", - "@backstage/core-plugin-api": "1.9.3", - "@backstage/create-app": "0.5.18", - "@backstage/dev-utils": "1.0.37", - "e2e-test": "0.2.19", + "@backstage/config-loader": "1.9.1", + "@backstage/core-app-api": "1.15.0", + "@backstage/core-compat-api": "0.3.0", + "@backstage/core-components": "0.15.0", + "@backstage/core-plugin-api": "1.9.4", + "@backstage/create-app": "0.5.19", + "@backstage/dev-utils": "1.1.0", + "e2e-test": "0.2.20", "@backstage/e2e-test-utils": "0.1.1", "@backstage/errors": "1.2.4", - "@backstage/eslint-plugin": "0.1.8", - "@backstage/frontend-app-api": "0.8.0", - "@backstage/frontend-plugin-api": "0.7.0", - "@backstage/frontend-test-utils": "0.1.12", - "@backstage/integration": "1.14.0", + "@backstage/eslint-plugin": "0.1.9", + "@backstage/frontend-app-api": "0.9.0", + "@backstage/frontend-defaults": "0.1.0", + "@internal/frontend": "0.0.1", + "@backstage/frontend-plugin-api": "0.8.0", + "@backstage/frontend-test-utils": "0.2.0", + "@backstage/integration": "1.15.0", "@backstage/integration-aws-node": "0.1.12", - "@backstage/integration-react": "1.1.30", + "@backstage/integration-react": "1.1.31", + "@internal/opaque": "0.0.1", "@backstage/release-manifests": "0.0.11", - "@backstage/repo-tools": "0.9.5", - "@techdocs/cli": "1.8.17", - "techdocs-cli-embedded-app": "0.2.99", - "@backstage/test-utils": "1.5.10", - "@backstage/theme": "0.5.6", + "@backstage/repo-tools": "0.9.7", + "@techdocs/cli": "1.8.19", + "techdocs-cli-embedded-app": "0.2.100", + "@backstage/test-utils": "1.6.0", + "@backstage/theme": "0.5.7", "@backstage/types": "1.1.1", - "@backstage/version-bridge": "1.0.8", - "yarn-plugin-backstage": "0.0.1", - "@backstage/plugin-api-docs": "0.11.8", + "@backstage/version-bridge": "1.0.9", + "yarn-plugin-backstage": "0.0.2", + "@backstage/plugin-api-docs": "0.11.9", "@backstage/plugin-api-docs-module-protoc-gen-doc": "0.1.7", - "@backstage/plugin-app-backend": "0.3.72", - "@backstage/plugin-app-node": "0.1.23", - "@backstage/plugin-app-visualizer": "0.1.9", - "@backstage/plugin-auth-backend": "0.22.10", - "@backstage/plugin-auth-backend-module-atlassian-provider": "0.2.4", - "@backstage/plugin-auth-backend-module-aws-alb-provider": "0.1.15", - "@backstage/plugin-auth-backend-module-azure-easyauth-provider": "0.1.6", - "@backstage/plugin-auth-backend-module-bitbucket-provider": "0.1.6", - "@backstage/plugin-auth-backend-module-cloudflare-access-provider": "0.2.0", - "@backstage/plugin-auth-backend-module-gcp-iap-provider": "0.2.18", - "@backstage/plugin-auth-backend-module-github-provider": "0.1.20", - "@backstage/plugin-auth-backend-module-gitlab-provider": "0.1.20", - "@backstage/plugin-auth-backend-module-google-provider": "0.1.20", - "@backstage/plugin-auth-backend-module-guest-provider": "0.1.9", - "@backstage/plugin-auth-backend-module-microsoft-provider": "0.1.18", - "@backstage/plugin-auth-backend-module-oauth2-provider": "0.2.4", - "@backstage/plugin-auth-backend-module-oauth2-proxy-provider": "0.1.16", - "@backstage/plugin-auth-backend-module-oidc-provider": "0.2.4", - "@backstage/plugin-auth-backend-module-okta-provider": "0.0.16", - "@backstage/plugin-auth-backend-module-onelogin-provider": "0.1.4", - "@backstage/plugin-auth-backend-module-pinniped-provider": "0.1.17", - "@backstage/plugin-auth-backend-module-vmware-cloud-provider": "0.2.4", - "@backstage/plugin-auth-node": "0.5.0", - "@backstage/plugin-auth-react": "0.1.5", - "@backstage/plugin-bitbucket-cloud-common": "0.2.22", - "@backstage/plugin-catalog": "1.22.0", - "@backstage/plugin-catalog-backend": "1.25.0", - "@backstage/plugin-catalog-backend-module-aws": "0.4.0", - "@backstage/plugin-catalog-backend-module-azure": "0.2.0", - "@backstage/plugin-catalog-backend-module-backstage-openapi": "0.3.0", - "@backstage/plugin-catalog-backend-module-bitbucket-cloud": "0.3.0", - "@backstage/plugin-catalog-backend-module-bitbucket-server": "0.2.0", - "@backstage/plugin-catalog-backend-module-gcp": "0.2.0", - "@backstage/plugin-catalog-backend-module-gerrit": "0.2.0", - "@backstage/plugin-catalog-backend-module-github": "0.7.0", - "@backstage/plugin-catalog-backend-module-github-org": "0.2.0", - "@backstage/plugin-catalog-backend-module-gitlab": "0.4.0", - "@backstage/plugin-catalog-backend-module-gitlab-org": "0.1.0", - "@backstage/plugin-catalog-backend-module-incremental-ingestion": "0.5.0", - "@backstage/plugin-catalog-backend-module-ldap": "0.8.0", - "@backstage/plugin-catalog-backend-module-logs": "0.0.2", - "@backstage/plugin-catalog-backend-module-msgraph": "0.6.0", - "@backstage/plugin-catalog-backend-module-openapi": "0.1.41", - "@backstage/plugin-catalog-backend-module-puppetdb": "0.2.0", - "@backstage/plugin-catalog-backend-module-scaffolder-entity-model": "0.1.21", - "@backstage/plugin-catalog-backend-module-unprocessed": "0.4.10", - "@backstage/plugin-catalog-common": "1.0.26", - "@backstage/plugin-catalog-graph": "0.4.8", - "@backstage/plugin-catalog-import": "0.12.2", - "@backstage/plugin-catalog-node": "1.12.5", - "@backstage/plugin-catalog-react": "1.12.3", - "@backstage/plugin-catalog-unprocessed-entities": "0.2.7", + "@backstage/plugin-app": "0.1.0", + "@backstage/plugin-app-backend": "0.3.74", + "@backstage/plugin-app-node": "0.1.25", + "@backstage/plugin-app-visualizer": "0.1.10", + "@backstage/plugin-auth-backend": "0.23.0", + "@backstage/plugin-auth-backend-module-atlassian-provider": "0.3.0", + "@backstage/plugin-auth-backend-module-auth0-provider": "0.1.0", + "@backstage/plugin-auth-backend-module-aws-alb-provider": "0.2.0", + "@backstage/plugin-auth-backend-module-azure-easyauth-provider": "0.2.0", + "@backstage/plugin-auth-backend-module-bitbucket-provider": "0.2.0", + "@backstage/plugin-auth-backend-module-bitbucket-server-provider": "0.1.0", + "@backstage/plugin-auth-backend-module-cloudflare-access-provider": "0.3.0", + "@backstage/plugin-auth-backend-module-gcp-iap-provider": "0.3.0", + "@backstage/plugin-auth-backend-module-github-provider": "0.2.0", + "@backstage/plugin-auth-backend-module-gitlab-provider": "0.2.0", + "@backstage/plugin-auth-backend-module-google-provider": "0.2.0", + "@backstage/plugin-auth-backend-module-guest-provider": "0.2.0", + "@backstage/plugin-auth-backend-module-microsoft-provider": "0.2.0", + "@backstage/plugin-auth-backend-module-oauth2-provider": "0.3.0", + "@backstage/plugin-auth-backend-module-oauth2-proxy-provider": "0.2.0", + "@backstage/plugin-auth-backend-module-oidc-provider": "0.3.0", + "@backstage/plugin-auth-backend-module-okta-provider": "0.1.0", + "@backstage/plugin-auth-backend-module-onelogin-provider": "0.2.0", + "@backstage/plugin-auth-backend-module-pinniped-provider": "0.2.0", + "@backstage/plugin-auth-backend-module-vmware-cloud-provider": "0.3.0", + "@backstage/plugin-auth-node": "0.5.2", + "@backstage/plugin-auth-react": "0.1.6", + "@backstage/plugin-bitbucket-cloud-common": "0.2.23", + "@backstage/plugin-catalog": "1.23.0", + "@backstage/plugin-catalog-backend": "1.26.0", + "@backstage/plugin-catalog-backend-module-aws": "0.4.2", + "@backstage/plugin-catalog-backend-module-azure": "0.2.2", + "@backstage/plugin-catalog-backend-module-backstage-openapi": "0.4.0", + "@backstage/plugin-catalog-backend-module-bitbucket-cloud": "0.3.2", + "@backstage/plugin-catalog-backend-module-bitbucket-server": "0.2.2", + "@backstage/plugin-catalog-backend-module-gcp": "0.3.0", + "@backstage/plugin-catalog-backend-module-gerrit": "0.2.2", + "@backstage/plugin-catalog-backend-module-github": "0.7.3", + "@backstage/plugin-catalog-backend-module-github-org": "0.3.0", + "@backstage/plugin-catalog-backend-module-gitlab": "0.4.2", + "@backstage/plugin-catalog-backend-module-gitlab-org": "0.2.0", + "@backstage/plugin-catalog-backend-module-incremental-ingestion": "0.5.3", + "@backstage/plugin-catalog-backend-module-ldap": "0.9.0", + "@backstage/plugin-catalog-backend-module-logs": "0.1.0", + "@backstage/plugin-catalog-backend-module-msgraph": "0.6.2", + "@backstage/plugin-catalog-backend-module-openapi": "0.2.0", + "@backstage/plugin-catalog-backend-module-puppetdb": "0.2.2", + "@backstage/plugin-catalog-backend-module-scaffolder-entity-model": "0.2.0", + "@backstage/plugin-catalog-backend-module-unprocessed": "0.5.0", + "@backstage/plugin-catalog-common": "1.1.0", + "@backstage/plugin-catalog-graph": "0.4.9", + "@backstage/plugin-catalog-import": "0.12.3", + "@backstage/plugin-catalog-node": "1.13.0", + "@backstage/plugin-catalog-react": "1.13.0", + "@backstage/plugin-catalog-unprocessed-entities": "0.2.8", "@backstage/plugin-catalog-unprocessed-entities-common": "0.0.4", - "@backstage/plugin-config-schema": "0.1.58", - "@backstage/plugin-devtools": "0.1.17", - "@backstage/plugin-devtools-backend": "0.3.9", + "@backstage/plugin-config-schema": "0.1.59", + "@backstage/plugin-devtools": "0.1.18", + "@backstage/plugin-devtools-backend": "0.4.0", "@backstage/plugin-devtools-common": "0.1.12", - "@backstage/plugin-events-backend": "0.3.10", - "@backstage/plugin-events-backend-module-aws-sqs": "0.4.0", - "@backstage/plugin-events-backend-module-azure": "0.2.9", - "@backstage/plugin-events-backend-module-bitbucket-cloud": "0.2.9", - "@backstage/plugin-events-backend-module-gerrit": "0.2.9", - "@backstage/plugin-events-backend-module-github": "0.2.9", - "@backstage/plugin-events-backend-module-gitlab": "0.2.9", - "@backstage/plugin-events-backend-test-utils": "0.1.33", - "@backstage/plugin-events-node": "0.3.9", - "@internal/plugin-todo-list": "1.0.30", - "@internal/plugin-todo-list-backend": "1.0.30", + "@backstage/plugin-events-backend": "0.3.12", + "@backstage/plugin-events-backend-module-aws-sqs": "0.4.2", + "@backstage/plugin-events-backend-module-azure": "0.2.11", + "@backstage/plugin-events-backend-module-bitbucket-cloud": "0.2.11", + "@backstage/plugin-events-backend-module-gerrit": "0.2.11", + "@backstage/plugin-events-backend-module-github": "0.2.11", + "@backstage/plugin-events-backend-module-gitlab": "0.2.11", + "@backstage/plugin-events-backend-test-utils": "0.1.35", + "@backstage/plugin-events-node": "0.4.0", + "@internal/plugin-todo-list": "1.0.31", + "@internal/plugin-todo-list-backend": "1.0.31", "@internal/plugin-todo-list-common": "1.0.21", - "@backstage/plugin-home": "0.7.9", - "@backstage/plugin-home-react": "0.1.16", - "@backstage/plugin-kubernetes": "0.11.13", - "@backstage/plugin-kubernetes-backend": "0.18.4", - "@backstage/plugin-kubernetes-cluster": "0.0.14", - "@backstage/plugin-kubernetes-common": "0.8.2", - "@backstage/plugin-kubernetes-node": "0.1.17", - "@backstage/plugin-kubernetes-react": "0.4.2", - "@backstage/plugin-notifications": "0.3.0", - "@backstage/plugin-notifications-backend": "0.3.4", - "@backstage/plugin-notifications-backend-module-email": "0.2.0", + "@backstage/plugin-home": "0.7.10", + "@backstage/plugin-home-react": "0.1.17", + "@backstage/plugin-kubernetes": "0.11.14", + "@backstage/plugin-kubernetes-backend": "0.18.6", + "@backstage/plugin-kubernetes-cluster": "0.0.15", + "@backstage/plugin-kubernetes-common": "0.8.3", + "@backstage/plugin-kubernetes-node": "0.1.19", + "@backstage/plugin-kubernetes-react": "0.4.3", + "@backstage/plugin-notifications": "0.3.1", + "@backstage/plugin-notifications-backend": "0.4.0", + "@backstage/plugin-notifications-backend-module-email": "0.3.0", "@backstage/plugin-notifications-common": "0.0.5", - "@backstage/plugin-notifications-node": "0.2.4", - "@backstage/plugin-org": "0.6.28", - "@backstage/plugin-org-react": "0.1.27", - "@backstage/plugin-permission-backend": "0.5.47", - "@backstage/plugin-permission-backend-module-allow-all-policy": "0.1.20", + "@backstage/plugin-notifications-node": "0.2.6", + "@backstage/plugin-org": "0.6.29", + "@backstage/plugin-org-react": "0.1.28", + "@backstage/plugin-permission-backend": "0.5.49", + "@backstage/plugin-permission-backend-module-allow-all-policy": "0.2.0", "@backstage/plugin-permission-common": "0.8.1", - "@backstage/plugin-permission-node": "0.8.1", - "@backstage/plugin-permission-react": "0.4.25", - "@backstage/plugin-proxy-backend": "0.5.4", - "@backstage/plugin-scaffolder": "1.24.0", - "@backstage/plugin-scaffolder-backend": "1.24.0", - "@backstage/plugin-scaffolder-backend-module-azure": "0.1.15", - "@backstage/plugin-scaffolder-backend-module-bitbucket": "0.2.13", - "@backstage/plugin-scaffolder-backend-module-bitbucket-cloud": "0.1.13", - "@backstage/plugin-scaffolder-backend-module-bitbucket-server": "0.1.13", - "@backstage/plugin-scaffolder-backend-module-confluence-to-markdown": "0.2.24", - "@backstage/plugin-scaffolder-backend-module-cookiecutter": "0.2.47", - "@backstage/plugin-scaffolder-backend-module-gcp": "0.1.1", - "@backstage/plugin-scaffolder-backend-module-gerrit": "0.1.15", - "@backstage/plugin-scaffolder-backend-module-gitea": "0.1.13", - "@backstage/plugin-scaffolder-backend-module-github": "0.4.1", - "@backstage/plugin-scaffolder-backend-module-gitlab": "0.4.5", - "@backstage/plugin-scaffolder-backend-module-notifications": "0.0.6", - "@backstage/plugin-scaffolder-backend-module-rails": "0.4.40", - "@backstage/plugin-scaffolder-backend-module-sentry": "0.1.31", - "@backstage/plugin-scaffolder-backend-module-yeoman": "0.3.7", - "@backstage/plugin-scaffolder-common": "1.5.5", - "@backstage/plugin-scaffolder-node": "0.4.9", - "@backstage/plugin-scaffolder-node-test-utils": "0.1.10", - "@backstage/plugin-scaffolder-react": "1.11.0", - "@backstage/plugin-search": "1.4.15", - "@backstage/plugin-search-backend": "1.5.15", - "@backstage/plugin-search-backend-module-catalog": "0.2.0", - "@backstage/plugin-search-backend-module-elasticsearch": "1.5.4", - "@backstage/plugin-search-backend-module-explore": "0.2.0", - "@backstage/plugin-search-backend-module-pg": "0.5.33", - "@backstage/plugin-search-backend-module-stack-overflow-collator": "0.2.0", - "@backstage/plugin-search-backend-module-techdocs": "0.2.0", - "@backstage/plugin-search-backend-node": "1.3.0", + "@backstage/plugin-permission-node": "0.8.3", + "@backstage/plugin-permission-react": "0.4.26", + "@backstage/plugin-proxy-backend": "0.5.6", + "@backstage/plugin-scaffolder": "1.25.0", + "@backstage/plugin-scaffolder-backend": "1.25.0", + "@backstage/plugin-scaffolder-backend-module-azure": "0.2.0", + "@backstage/plugin-scaffolder-backend-module-bitbucket": "0.3.0", + "@backstage/plugin-scaffolder-backend-module-bitbucket-cloud": "0.2.0", + "@backstage/plugin-scaffolder-backend-module-bitbucket-server": "0.2.0", + "@backstage/plugin-scaffolder-backend-module-confluence-to-markdown": "0.3.0", + "@backstage/plugin-scaffolder-backend-module-cookiecutter": "0.3.0", + "@backstage/plugin-scaffolder-backend-module-gcp": "0.2.0", + "@backstage/plugin-scaffolder-backend-module-gerrit": "0.2.0", + "@backstage/plugin-scaffolder-backend-module-gitea": "0.2.0", + "@backstage/plugin-scaffolder-backend-module-github": "0.5.0", + "@backstage/plugin-scaffolder-backend-module-gitlab": "0.5.0", + "@backstage/plugin-scaffolder-backend-module-notifications": "0.1.0", + "@backstage/plugin-scaffolder-backend-module-rails": "0.5.0", + "@backstage/plugin-scaffolder-backend-module-sentry": "0.2.0", + "@backstage/plugin-scaffolder-backend-module-yeoman": "0.4.0", + "@backstage/plugin-scaffolder-common": "1.5.6", + "@backstage/plugin-scaffolder-node": "0.4.11", + "@backstage/plugin-scaffolder-node-test-utils": "0.1.12", + "@backstage/plugin-scaffolder-react": "1.12.0", + "@backstage/plugin-search": "1.4.16", + "@backstage/plugin-search-backend": "1.5.17", + "@backstage/plugin-search-backend-module-catalog": "0.2.2", + "@backstage/plugin-search-backend-module-elasticsearch": "1.5.6", + "@backstage/plugin-search-backend-module-explore": "0.2.2", + "@backstage/plugin-search-backend-module-pg": "0.5.35", + "@backstage/plugin-search-backend-module-stack-overflow-collator": "0.3.0", + "@backstage/plugin-search-backend-module-techdocs": "0.2.2", + "@backstage/plugin-search-backend-node": "1.3.2", "@backstage/plugin-search-common": "1.2.14", - "@backstage/plugin-search-react": "1.7.14", - "@backstage/plugin-signals": "0.0.9", - "@backstage/plugin-signals-backend": "0.1.9", - "@backstage/plugin-signals-node": "0.1.9", - "@backstage/plugin-signals-react": "0.0.4", - "@backstage/plugin-techdocs": "1.10.8", - "@backstage/plugin-techdocs-addons-test-utils": "1.0.37", - "@backstage/plugin-techdocs-backend": "1.10.10", + "@backstage/plugin-search-react": "1.8.0", + "@backstage/plugin-signals": "0.0.10", + "@backstage/plugin-signals-backend": "0.2.0", + "@backstage/plugin-signals-node": "0.1.11", + "@backstage/plugin-signals-react": "0.0.5", + "@backstage/plugin-techdocs": "1.10.9", + "@backstage/plugin-techdocs-addons-test-utils": "1.0.38", + "@backstage/plugin-techdocs-backend": "1.10.13", "@backstage/plugin-techdocs-common": "0.1.0", - "@backstage/plugin-techdocs-module-addons-contrib": "1.1.13", - "@backstage/plugin-techdocs-node": "1.12.9", - "@backstage/plugin-techdocs-react": "1.2.7", - "@backstage/plugin-user-settings": "0.8.11", - "@backstage/plugin-user-settings-backend": "0.2.22", + "@backstage/plugin-techdocs-module-addons-contrib": "1.1.14", + "@backstage/plugin-techdocs-node": "1.12.11", + "@backstage/plugin-techdocs-react": "1.2.8", + "@backstage/plugin-user-settings": "0.8.12", + "@backstage/plugin-user-settings-backend": "0.2.24", "@backstage/plugin-user-settings-common": "0.0.1", - "@backstage/plugin-app": "0.0.0", - "@backstage/frontend-defaults": "0.0.0" + "@internal/scaffolder": "0.0.1" }, "changesets": [ - "afraid-fans-cross", - "angry-hotels-warn", - "big-spies-stare", - "blue-forks-cry", - "breezy-flowers-dance", - "brown-actors-clap", - "brown-boxes-arrive", - "brown-worms-sneeze", - "calm-brooms-fail", - "chilled-cameras-change", - "chilly-birds-shout", - "cold-ways-protect", - "cool-actors-sin", - "cool-melons-check", - "cool-poems-hammer", - "cuddly-rocks-invent", - "curly-brooms-raise", - "dry-beers-shake", - "dry-glasses-push", - "dry-monkeys-mate", - "eighty-tables-hope", - "empty-coats-sparkle", - "famous-badgers-drop", - "five-tigers-share", - "flat-kangaroos-push", - "forty-toes-float", - "four-parents-buy", - "four-ties-raise", - "fresh-apes-dress", - "fresh-bears-prove", - "fresh-pumas-clean", - "friendly-days-march", - "friendly-months-march", - "funny-houses-rest", - "fuzzy-feet-exist", - "fuzzy-mails-walk", - "fuzzy-spies-share", - "gentle-hats-act", - "giant-jars-mix", - "gorgeous-scissors-wave", - "green-worms-rescue", - "healthy-moons-drum", - "heavy-suits-judge", - "hip-pandas-think", - "kind-moose-learn", - "kind-walls-speak", - "large-poets-check", - "loud-brooms-pull", - "lucky-sheep-cover", - "metal-garlics-fetch", - "metal-rivers-grin", - "mighty-cheetahs-call", - "mighty-days-kiss", - "nasty-tigers-knock", - "new-poets-unite", - "ninety-mayflies-raise", - "odd-goats-kiss", - "olive-phones-sniff", - "plenty-dragons-know", - "popular-cooks-camp", - "purple-cows-sing", - "purple-glasses-tease", - "quick-suns-swim", - "quiet-spies-clean", - "rare-feet-melt", - "real-pants-rule", - "renovate-53b7d25", - "renovate-546c524", - "renovate-93d032c", - "renovate-b8911c2", - "rich-bees-tickle", - "rotten-crabs-hear", - "serious-cheetahs-help", - "serious-spies-knock", - "sharp-fans-tan", - "sharp-items-study", - "sharp-mayflies-beg", - "shiny-carpets-worried", - "shiny-carpets-worry", - "shiny-zoos-film", - "short-moles-brush", - "silent-eyes-lie", - "six-goats-sort", - "six-humans-guess", - "sixty-rabbits-cheat", - "slimy-chefs-think", - "smart-gifts-report", - "smart-owls-sell", - "spicy-poems-hammer", - "spicy-vans-eat", - "sweet-cows-clean", - "swift-fishes-rush", - "swift-garlics-mix", - "swift-radios-enjoy", - "swift-seahorses-share", - "tall-camels-march", - "tame-hornets-shake", - "tasty-pigs-vanish", - "thick-walls-share", - "tiny-icons-sit", - "tiny-waves-provide", - "tough-peaches-kneel", - "tricky-apricots-film", - "twenty-clouds-melt", - "twenty-queens-grow", - "unlucky-cycles-clean", - "violet-apricots-smoke", - "violet-jokes-tap", - "warm-boxes-grab-2", - "warm-boxes-grab", - "wild-buses-notice", - "wise-forks-play", - "wise-scissors-help", - "witty-years-cry", - "yellow-bees-hope" + "angry-mayflies-collect", + "angry-windows-decide", + "big-rules-nail", + "breezy-bulldogs-smell", + "brown-frogs-walk", + "chair-fairs-drive", + "chilled-dolphins-join", + "clever-paws-stare", + "cold-nails-rescue", + "create-app-1727774359", + "curly-foxes-brake", + "cyan-cooks-sing", + "cyan-peaches-lay", + "cyan-vans-study", + "dry-frogs-drum", + "early-drinks-kneel", + "early-sloths-cross", + "eight-steaks-chew", + "eleven-pugs-hear", + "fair-chairs-drive", + "famous-bobcats-remain", + "fifty-trainers-watch", + "five-gorillas-pay", + "five-turkeys-taste", + "flat-eels-exist", + "fluffy-pears-cry", + "four-moons-watch", + "friendly-cougars-return", + "funny-rocks-train", + "fuzzy-elephants-tease", + "giant-kiwis-retire", + "gold-pots-end", + "green-bottles-live", + "happy-ligers-think", + "honest-impalas-rescue", + "hungry-buckets-repair", + "large-hats-reply", + "large-plants-rhyme", + "light-rats-travel", + "long-humans-hunt", + "loud-hotels-tan", + "nasty-lamps-greet", + "nice-badgers-travel", + "polite-days-flash", + "pretty-plants-hammer", + "quiet-dingos-bathe", + "renovate-156753b", + "rich-deers-attend", + "rich-needles-collect", + "rude-apricots-eat", + "shy-olives-swim", + "slow-gorillas-thank", + "slow-trees-compare", + "sour-grapes-trade", + "sour-phones-fix", + "stale-roses-serve", + "strange-bees-attack", + "strong-monkeys-melt", + "sweet-chicken-smash", + "thirty-pets-fry", + "tiny-pugs-kick", + "tough-pillows-sip", + "two-plums-fail", + "weak-bottles-cross" ] } diff --git a/.changeset/pretty-buses-repair.md b/.changeset/pretty-buses-repair.md new file mode 100644 index 0000000000..e5575c36c1 --- /dev/null +++ b/.changeset/pretty-buses-repair.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +Standardize template editor pages desktop and mobile layouts. diff --git a/.changeset/pretty-plants-hammer.md b/.changeset/pretty-plants-hammer.md new file mode 100644 index 0000000000..c070f769c4 --- /dev/null +++ b/.changeset/pretty-plants-hammer.md @@ -0,0 +1,5 @@ +--- +'@backstage/integration-react': minor +--- + +Added new ScmAuth method `forBitbucketServer` that uses correct OAuth scopes by default. Also updated `forBitbucket` method to allow overriding the default OAuth scopes. diff --git a/.changeset/purple-cows-sing.md b/.changeset/purple-cows-sing.md deleted file mode 100644 index 3391ced648..0000000000 --- a/.changeset/purple-cows-sing.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-plugin-api': minor ---- - -Removed deprecated `ServiceFactoryOrFunction` type. diff --git a/.changeset/purple-glasses-tease.md b/.changeset/purple-glasses-tease.md deleted file mode 100644 index 5a107c1a2b..0000000000 --- a/.changeset/purple-glasses-tease.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -'@backstage/plugin-search-backend-module-techdocs': patch -'@backstage/plugin-search-backend-module-catalog': patch -'@backstage/plugin-search-backend-module-explore': patch ---- - -The following collator factories are deprecated, please [migrate](https://backstage.io/docs/backend-system/building-backends/migrating) to the new backend system and follow the instructions below to install collators via module: - -- `DefaultCatalogCollatorFactory`: https://github.com/backstage/backstage/blob/nbs10/search-deprecate-create-router/plugins/search-backend-module-catalog/README.md#installation; -- `ToolDocumentCollatorFactory`: https://github.com/backstage/backstage/blob/nbs10/search-deprecate-create-router/plugins/search-backend-module-explore/README.md#installation; -- `DefaultTechDocsCollatorFactory`: https://github.com/backstage/backstage/blob/nbs10/search-deprecate-create-router/plugins/search-backend-module-techdocs/README.md#installation. diff --git a/.changeset/quick-suns-swim.md b/.changeset/quick-suns-swim.md deleted file mode 100644 index 6113253e22..0000000000 --- a/.changeset/quick-suns-swim.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-defaults': patch ---- - -Accept `ConfigService` instead of `Config` in constructors/factories diff --git a/.changeset/quiet-dingos-bathe.md b/.changeset/quiet-dingos-bathe.md new file mode 100644 index 0000000000..b0e41de687 --- /dev/null +++ b/.changeset/quiet-dingos-bathe.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend': patch +--- + +Fixed a bug where the concurrency limiter for URL reading was not honored diff --git a/.changeset/quiet-spies-clean.md b/.changeset/quiet-spies-clean.md deleted file mode 100644 index ba277f4021..0000000000 --- a/.changeset/quiet-spies-clean.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-graph': patch ---- - -Fixed a bug in the `CatalogGraphPage` component where, after clicking on some nodes, clicking the back button would break the navigation. This issue caused the entire navigation to fail and behaved differently across various browsers. diff --git a/.changeset/rare-crabs-cheat.md b/.changeset/rare-crabs-cheat.md new file mode 100644 index 0000000000..6b4fd37ed7 --- /dev/null +++ b/.changeset/rare-crabs-cheat.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs': patch +--- + +Add support for mkdocs material palette conditional hashes. diff --git a/.changeset/rare-feet-melt.md b/.changeset/rare-feet-melt.md deleted file mode 100644 index b28b09a29d..0000000000 --- a/.changeset/rare-feet-melt.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-user-settings-backend': patch ---- - -Replaced usage of the deprecated identity service with the new HTTP auth service for the new backend system. diff --git a/.changeset/rare-rabbits-flow.md b/.changeset/rare-rabbits-flow.md new file mode 100644 index 0000000000..6b64957d59 --- /dev/null +++ b/.changeset/rare-rabbits-flow.md @@ -0,0 +1,29 @@ +--- +'@backstage/plugin-catalog-backend-module-bitbucket-cloud': minor +--- + +Fixes the event-based updates at `BitbucketCloudEntityProvider`. + +Previously, this entity provider had optional event support for legacy backends +that could be enabled by passing `catalogApi`, `events`, and `tokenManager`. + +For the new/current backend system, the `catalogModuleBitbucketCloudEntityProvider` +(`catalog.bitbucket-cloud-entity-provider`), event support was enabled by default. + +A recent change removed `tokenManager` as a dependency from the module as well as removed it as input. +While this didn't break the instantiation of the module, it broke the event-based updates, +and led to a runtime misbehavior, accompanied by an info log message. + +This change will replace the use of `tokenManager` with the use of `auth` (`AuthService`). + +Additionally, to simplify, it will make `catalogApi` and `events` required dependencies. +For the current backend system, this change is transparent and doesn't require any action. +For the legacy backend system, this change will require you to pass those dependencies +if you didn't do it already. + +BREAKING CHANGES: + +_(For legacy backend users only.)_ + +Previously optional `catalogApi`, and `events` are required now. +A new required dependency `auth` was added. diff --git a/.changeset/real-pants-rule.md b/.changeset/real-pants-rule.md deleted file mode 100644 index 8d6d3dc708..0000000000 --- a/.changeset/real-pants-rule.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/plugin-auth-backend-module-microsoft-provider': patch -'@backstage/plugin-auth-backend': patch -'@backstage/plugin-catalog-backend-module-msgraph': patch ---- - -Allow users without defined email to be ingested by the `msgraph` catalog plugin and add `userIdMatchingUserEntityAnnotation` sign-in resolver for the Microsoft auth provider to support sign-in for users without defined email. diff --git a/.changeset/red-squids-own.md b/.changeset/red-squids-own.md deleted file mode 100644 index 4f6a1635d6..0000000000 --- a/.changeset/red-squids-own.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -'@backstage/integration': minor ---- - -The Gerrit integration can now resolve Gitiles urls that point to the following -refs: - -- HEAD -- A SHA -- Tag -- Branch diff --git a/.changeset/renovate-156753b.md b/.changeset/renovate-156753b.md new file mode 100644 index 0000000000..0ef9afb0e2 --- /dev/null +++ b/.changeset/renovate-156753b.md @@ -0,0 +1,7 @@ +--- +'@backstage/plugin-kubernetes-cluster': patch +'@backstage/plugin-kubernetes-react': patch +'@backstage/plugin-kubernetes': patch +--- + +Updated dependency `@kubernetes-models/base` to `^5.0.0`. diff --git a/.changeset/renovate-53b7d25.md b/.changeset/renovate-53b7d25.md deleted file mode 100644 index 0c4f7255d3..0000000000 --- a/.changeset/renovate-53b7d25.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/cli': patch -'@backstage/plugin-scaffolder-backend': patch ---- - -Updated dependency `esbuild` to `^0.23.0`. diff --git a/.changeset/renovate-546c524.md b/.changeset/renovate-546c524.md deleted file mode 100644 index bbe6d8afc5..0000000000 --- a/.changeset/renovate-546c524.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/repo-tools': patch ---- - -Updated dependency `@useoptic/openapi-utilities` to `^0.55.0`. diff --git a/.changeset/renovate-93d032c.md b/.changeset/renovate-93d032c.md deleted file mode 100644 index b34e5a2e23..0000000000 --- a/.changeset/renovate-93d032c.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/codemods': patch ---- - -Updated dependency `jscodeshift` to `^0.16.0`. diff --git a/.changeset/renovate-b8911c2.md b/.changeset/renovate-b8911c2.md deleted file mode 100644 index 9f93a13254..0000000000 --- a/.changeset/renovate-b8911c2.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-react': patch ---- - -Updated dependency `use-immer` to `^0.10.0`. diff --git a/.changeset/rich-bees-tickle.md b/.changeset/rich-bees-tickle.md deleted file mode 100644 index a2af89c867..0000000000 --- a/.changeset/rich-bees-tickle.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-defaults': patch ---- - -Wrap scheduled tasks from the scheduler core service now in OpenTelemetry spans diff --git a/.changeset/rich-deers-attend.md b/.changeset/rich-deers-attend.md new file mode 100644 index 0000000000..1b26636009 --- /dev/null +++ b/.changeset/rich-deers-attend.md @@ -0,0 +1,7 @@ +--- +'@backstage/backend-app-api': patch +--- + +The backend will no longer exit immediately if any plugin or modules fails to initialize. Instead, the backend will wait for all plugins and modules to either start up successfully or throw, and then shut down the backend if there were any initialization errors. + +This fixes an issue where backend initialization errors in adjacent plugins during database schema migration could cause the database migrations to be stuck in a locked state. diff --git a/.changeset/rich-needles-collect.md b/.changeset/rich-needles-collect.md new file mode 100644 index 0000000000..dab36e9543 --- /dev/null +++ b/.changeset/rich-needles-collect.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-react': minor +--- + +Renamed Template Editor to Manage Templates. diff --git a/.changeset/rotten-crabs-hear.md b/.changeset/rotten-crabs-hear.md deleted file mode 100644 index 69148c59c1..0000000000 --- a/.changeset/rotten-crabs-hear.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-notifications-backend': patch ---- - -Validate notification link when new notification is created diff --git a/.changeset/rude-apricots-eat.md b/.changeset/rude-apricots-eat.md new file mode 100644 index 0000000000..198d6a0ec7 --- /dev/null +++ b/.changeset/rude-apricots-eat.md @@ -0,0 +1,6 @@ +--- +'@backstage/backend-defaults': patch +'@backstage/integration': patch +--- + +Updating error message for getProjectId when fetching Gitlab project from its url to be more accurate diff --git a/.changeset/serious-cheetahs-help.md b/.changeset/serious-cheetahs-help.md deleted file mode 100644 index 88bad696c5..0000000000 --- a/.changeset/serious-cheetahs-help.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/plugin-catalog-react': patch -'@backstage/plugin-search-react': patch -'@backstage/plugin-catalog': patch ---- - -The `/alpha` export no longer export extension creators for the new frontend system, existing usage should be switched to use the equivalent extension blueprint instead. For more information see the [new frontend system 1.30 migration documentation](https://backstage.io/docs/frontend-system/architecture/migrations#130). diff --git a/.changeset/serious-spies-knock.md b/.changeset/serious-spies-knock.md deleted file mode 100644 index 1484753019..0000000000 --- a/.changeset/serious-spies-knock.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-kubernetes-backend': patch ---- - -Skip start without proper config diff --git a/.changeset/sharp-fans-tan.md b/.changeset/sharp-fans-tan.md deleted file mode 100644 index add4a85758..0000000000 --- a/.changeset/sharp-fans-tan.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@backstage/plugin-scaffolder-react': patch ---- - -- Fix secret widget field not displaying as required. -- Fix secret widget not able to be required inside nested objects. -- Fix secret widget not able to be disabled. -- Support `minLength` and `maxLength` properties for secret widget. diff --git a/.changeset/sharp-items-study.md b/.changeset/sharp-items-study.md deleted file mode 100644 index 61e8af54b6..0000000000 --- a/.changeset/sharp-items-study.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -'@backstage/backend-defaults': patch ---- - -Exports the `discoveryFeatureLoader` as a replacement for the deprecated `featureDiscoveryService`. -The `discoveryFeatureLoader` is a new backend system [feature loader](https://backstage.io/docs/backend-system/architecture/feature-loaders/) that discovers backend features from the current `package.json` and its dependencies. -Here is an example using the `discoveryFeatureLoader` loader in a new backend instance: - -```ts -import { createBackend } from '@backstage/backend-defaults'; -import { discoveryFeatureLoader } from '@backstage/backend-defaults'; -//... - -const backend = createBackend(); -//... -backend.add(discoveryFeatureLoader); -//... -backend.start(); -``` diff --git a/.changeset/sharp-mayflies-beg.md b/.changeset/sharp-mayflies-beg.md deleted file mode 100644 index c78335c187..0000000000 --- a/.changeset/sharp-mayflies-beg.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/frontend-app-api': patch ---- - -Internal refactor following removal of v1 extension support. The app implementation itself still supports v1 extensions at runtime. diff --git a/.changeset/shiny-carpets-worried.md b/.changeset/shiny-carpets-worried.md deleted file mode 100644 index c0093b49aa..0000000000 --- a/.changeset/shiny-carpets-worried.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-compat-api': minor ---- - -**BREAKING**: The `namespace` parameter for API's is now defaulted to the `pluginId` which was discovered. This means that if you're overriding API's by using ID's directly, they might have changed to include the plugin ID too. diff --git a/.changeset/shiny-carpets-worry.md b/.changeset/shiny-carpets-worry.md deleted file mode 100644 index 53688df920..0000000000 --- a/.changeset/shiny-carpets-worry.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/frontend-plugin-api': patch -'@backstage/frontend-test-utils': patch -'@backstage/frontend-app-api': patch ---- - -Removing deprecated `namespace` parameter in favour of `pluginId` instead diff --git a/.changeset/shiny-zoos-film.md b/.changeset/shiny-zoos-film.md deleted file mode 100644 index f9fb8cdce5..0000000000 --- a/.changeset/shiny-zoos-film.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -'@backstage/plugin-signals': patch ---- - -Added a `SignalsDisplay` extension to allows the signals plugin to be installed in an app as follows: - -```tsx -export default app.createRoot( - <> - - - - - - {routes} - - , -); -``` - -With this in place you can remove the explicit installation via the `plugins` option for `createApp`. diff --git a/.changeset/short-moles-brush.md b/.changeset/short-moles-brush.md deleted file mode 100644 index 033805c2b5..0000000000 --- a/.changeset/short-moles-brush.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': minor ---- - -`createRouter` and its related types has been marked as deprecared. This backend should instead be initialized using the new backend system. diff --git a/.changeset/shy-olives-swim.md b/.changeset/shy-olives-swim.md new file mode 100644 index 0000000000..8a9a07fa81 --- /dev/null +++ b/.changeset/shy-olives-swim.md @@ -0,0 +1,11 @@ +--- +'@backstage/backend-dynamic-feature-service': patch +'@backstage/plugin-search-backend-module-techdocs': patch +'@backstage/plugin-search-backend-module-catalog': patch +'@backstage/plugin-search-backend-module-explore': patch +'@backstage/plugin-events-backend-module-github': patch +'@backstage/plugin-events-backend-module-gitlab': patch +'@backstage/plugin-events-node': patch +--- + +Updated backend installation instructions. diff --git a/.changeset/silent-eyes-lie.md b/.changeset/silent-eyes-lie.md deleted file mode 100644 index e9da3d2685..0000000000 --- a/.changeset/silent-eyes-lie.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/test-utils': minor ---- - -Added the icons option to the renderInTestApp function's TestAppOptions to be forwarded to the icons option of `createApp`. diff --git a/.changeset/silly-readers-build.md b/.changeset/silly-readers-build.md new file mode 100644 index 0000000000..4797c2b036 --- /dev/null +++ b/.changeset/silly-readers-build.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +Add an actions filter on the list actions page and drawer. diff --git a/.changeset/six-goats-sort.md b/.changeset/six-goats-sort.md deleted file mode 100644 index 5df8924066..0000000000 --- a/.changeset/six-goats-sort.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-gitlab': patch ---- - -Remove dependency on backend-common diff --git a/.changeset/six-humans-guess.md b/.changeset/six-humans-guess.md deleted file mode 100644 index 60845257c8..0000000000 --- a/.changeset/six-humans-guess.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-proxy-backend': patch ---- - -Deprecated `createRouter` and its router options in favour of the new backend system. diff --git a/.changeset/sixty-rabbits-cheat.md b/.changeset/sixty-rabbits-cheat.md deleted file mode 100644 index 0161e272ed..0000000000 --- a/.changeset/sixty-rabbits-cheat.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-search-react': minor ---- - -Make use of the `useApp` hook to retrieve the specified search icon in the SearchBar diff --git a/.changeset/slimy-chefs-think.md b/.changeset/slimy-chefs-think.md deleted file mode 100644 index 7fa546a399..0000000000 --- a/.changeset/slimy-chefs-think.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@backstage/plugin-notifications-backend-module-email': patch -'@backstage/plugin-catalog-backend-module-github': patch -'@backstage/plugin-notifications-backend': patch -'@backstage/plugin-techdocs-backend': patch ---- - -Refactor to use injected catalog client in the new backend system diff --git a/.changeset/slow-gorillas-thank.md b/.changeset/slow-gorillas-thank.md new file mode 100644 index 0000000000..2c52964a47 --- /dev/null +++ b/.changeset/slow-gorillas-thank.md @@ -0,0 +1,9 @@ +--- +'@backstage/plugin-events-backend': patch +--- + +The events backend now has its own built-in event bus for distributing events across multiple backend instances. It exposes a new HTTP API under `/bus/v1/` for publishing and reading events from the bus, as well as its own storage and notification mechanism for events. + +The backing event store for the bus only supports scaled deployment if PostgreSQL is used as the DBMS. If SQLite or MySQL is used, the event bus will fall back to an in-memory store that does not support multiple backend instances. + +The default `EventsService` implementation from `@backstage/plugin-events-node` has also been updated to use the new events bus. diff --git a/.changeset/slow-trees-compare.md b/.changeset/slow-trees-compare.md new file mode 100644 index 0000000000..18e1a82ff9 --- /dev/null +++ b/.changeset/slow-trees-compare.md @@ -0,0 +1,8 @@ +--- +'@backstage/plugin-scaffolder-backend': patch +'@backstage/plugin-scaffolder-react': patch +'@backstage/plugin-scaffolder-node': patch +'@backstage/plugin-scaffolder': patch +--- + +Make it possible to manually retry the scaffolder template from the step it failed diff --git a/.changeset/smart-gifts-report.md b/.changeset/smart-gifts-report.md deleted file mode 100644 index fa3c8d96e9..0000000000 --- a/.changeset/smart-gifts-report.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@backstage/plugin-catalog-unprocessed-entities': patch ---- - -Show additional info on DevTools unprocessed entities table - -- Location path (so that it's easier to search the failed entity from the YAML URL) -- Time info of last discovery and next refresh time so that users can be aware of it and can sort the errors based on the time. diff --git a/.changeset/smart-owls-sell.md b/.changeset/smart-owls-sell.md deleted file mode 100644 index 0a2b555a20..0000000000 --- a/.changeset/smart-owls-sell.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-defaults': patch ---- - -Properly indent the config schema diff --git a/.changeset/sour-grapes-trade.md b/.changeset/sour-grapes-trade.md new file mode 100644 index 0000000000..acbb6cdbe7 --- /dev/null +++ b/.changeset/sour-grapes-trade.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +The Jest configuration will now search for a `src/setupTests.*` file with any valid script extension, not only `.ts`. diff --git a/.changeset/sour-phones-fix.md b/.changeset/sour-phones-fix.md new file mode 100644 index 0000000000..d2519f2ef5 --- /dev/null +++ b/.changeset/sour-phones-fix.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend-module-gitlab': patch +--- + +Updated `gitlab:group:ensureExists` action to instead use oauth client. diff --git a/.changeset/spicy-poems-hammer.md b/.changeset/spicy-poems-hammer.md deleted file mode 100644 index 23e86e178e..0000000000 --- a/.changeset/spicy-poems-hammer.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-techdocs-node': patch ---- - -As the `@backstage/backend-common` package is deprecated, we have updated the `techdocs-node` package to stop depending on it. diff --git a/.changeset/spicy-vans-eat.md b/.changeset/spicy-vans-eat.md deleted file mode 100644 index 037a5f18e0..0000000000 --- a/.changeset/spicy-vans-eat.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-app-api': patch ---- - -Fix feature loaders in CJS double-default nested builds diff --git a/.changeset/stale-roses-serve.md b/.changeset/stale-roses-serve.md new file mode 100644 index 0000000000..29dee56e22 --- /dev/null +++ b/.changeset/stale-roses-serve.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-events-node': patch +--- + +The default implementation of the `EventsService` now uses the new event bus for distributing events across multiple backend instances if the events backend plugin is installed. diff --git a/.changeset/strange-bees-attack.md b/.changeset/strange-bees-attack.md new file mode 100644 index 0000000000..c4e95097f8 --- /dev/null +++ b/.changeset/strange-bees-attack.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-components': patch +--- + +`Link` component now accepts `externalLinkIcon` prop diff --git a/.changeset/strong-monkeys-melt.md b/.changeset/strong-monkeys-melt.md new file mode 100644 index 0000000000..ef33b0cddd --- /dev/null +++ b/.changeset/strong-monkeys-melt.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +The `LEGACY_BACKEND_START` flag is now deprecated. diff --git a/.changeset/sweet-chicken-smash.md b/.changeset/sweet-chicken-smash.md new file mode 100644 index 0000000000..9aa4c60803 --- /dev/null +++ b/.changeset/sweet-chicken-smash.md @@ -0,0 +1,14 @@ +--- +'@backstage/cli': minor +--- + +**BREAKING**: Removed the following deprecated commands: + +- `create`: Use `backstage-cli new` instead +- `create-plugin`: Use `backstage-cli new` instead +- `plugin:diff`: Use `backstage-cli fix` instead +- `test`: Use `backstage-cli repo test` or `backstage-cli package test` instead +- `versions:check`: Use `yarn dedupe` or `yarn-deduplicate` instead +- `clean`: Use `backstage-cli package clean` instead + +In addition, the experimental `install` and `onboard` commands have been removed since they have not received any updates since their introduction and we're expecting usage to be low. If you where relying on these commands, please let us know by opening an issue towards the main Backstage repository. diff --git a/.changeset/sweet-cows-clean.md b/.changeset/sweet-cows-clean.md deleted file mode 100644 index fa2004186e..0000000000 --- a/.changeset/sweet-cows-clean.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/frontend-test-utils': patch ---- - -Added the ability to provide additional `extensions` and `features` to `renderInTestApp` diff --git a/.changeset/swift-fishes-rush.md b/.changeset/swift-fishes-rush.md deleted file mode 100644 index ccfa3a0e40..0000000000 --- a/.changeset/swift-fishes-rush.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Fixed an issue where published frontend packages would end up with an invalid import structure if a single module imported both `.css` and `.svg` files. diff --git a/.changeset/swift-garlics-mix.md b/.changeset/swift-garlics-mix.md deleted file mode 100644 index fc0993be3f..0000000000 --- a/.changeset/swift-garlics-mix.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -'@backstage/backend-app-api': minor -'@backstage/backend-common': minor -'@backstage/backend-defaults': minor -'@backstage/backend-plugin-api': minor -'@backstage/backend-test-utils': minor -'@backstage/plugin-auth-backend-module-atlassian-provider': minor -'@backstage/plugin-auth-backend-module-aws-alb-provider': minor -'@backstage/plugin-auth-backend-module-azure-easyauth-provider': minor -'@backstage/plugin-auth-backend-module-bitbucket-provider': minor -'@backstage/plugin-auth-backend-module-cloudflare-access-provider': minor -'@backstage/plugin-auth-backend-module-gcp-iap-provider': minor -'@backstage/plugin-auth-backend-module-github-provider': minor -'@backstage/plugin-auth-backend-module-gitlab-provider': minor -'@backstage/plugin-auth-backend-module-google-provider': minor -'@backstage/plugin-auth-backend-module-guest-provider': minor -'@backstage/plugin-auth-backend-module-microsoft-provider': minor -'@backstage/plugin-auth-backend-module-oauth2-provider': minor -'@backstage/plugin-auth-backend-module-oauth2-proxy-provider': minor -'@backstage/plugin-auth-backend-module-oidc-provider': minor -'@backstage/plugin-auth-backend-module-okta-provider': minor -'@backstage/plugin-auth-backend-module-onelogin-provider': minor -'@backstage/plugin-auth-backend-module-pinniped-provider': minor -'@backstage/plugin-auth-backend-module-vmware-cloud-provider': minor -'@backstage/plugin-auth-backend': minor -'@backstage/plugin-catalog-backend-module-backstage-openapi': minor -'@backstage/plugin-catalog-backend-module-gcp': minor -'@backstage/plugin-catalog-backend-module-github-org': minor -'@backstage/plugin-catalog-backend-module-gitlab-org': minor -'@backstage/plugin-catalog-backend-module-ldap': minor -'@backstage/plugin-catalog-backend-module-logs': minor -'@backstage/plugin-catalog-backend-module-openapi': minor -'@backstage/plugin-catalog-backend-module-scaffolder-entity-model': minor -'@backstage/plugin-catalog-backend-module-unprocessed': minor -'@backstage/plugin-devtools-backend': minor -'@backstage/plugin-events-node': minor -'@backstage/plugin-notifications-backend-module-email': minor -'@backstage/plugin-notifications-backend': minor -'@backstage/plugin-permission-backend-module-allow-all-policy': minor -'@backstage/plugin-scaffolder-backend-module-azure': minor -'@backstage/plugin-scaffolder-backend-module-bitbucket-cloud': minor -'@backstage/plugin-scaffolder-backend-module-bitbucket-server': minor -'@backstage/plugin-scaffolder-backend-module-bitbucket': minor -'@backstage/plugin-scaffolder-backend-module-confluence-to-markdown': minor -'@backstage/plugin-scaffolder-backend-module-cookiecutter': minor -'@backstage/plugin-scaffolder-backend-module-gcp': minor -'@backstage/plugin-scaffolder-backend-module-gerrit': minor -'@backstage/plugin-scaffolder-backend-module-gitea': minor -'@backstage/plugin-scaffolder-backend-module-github': minor -'@backstage/plugin-scaffolder-backend-module-gitlab': minor -'@backstage/plugin-scaffolder-backend-module-notifications': minor -'@backstage/plugin-scaffolder-backend-module-rails': minor -'@backstage/plugin-scaffolder-backend-module-sentry': minor -'@backstage/plugin-scaffolder-backend-module-yeoman': minor -'@backstage/plugin-search-backend-module-stack-overflow-collator': minor -'@backstage/plugin-signals-backend': minor ---- - -**BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. - -This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. - -As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. diff --git a/.changeset/swift-radios-enjoy.md b/.changeset/swift-radios-enjoy.md deleted file mode 100644 index 495117e3c6..0000000000 --- a/.changeset/swift-radios-enjoy.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-common': patch ---- - -Internal refactor to re-declare the token manager service which was removed from `@backstage/backend-plugin-api`, but is still supported in this package for backwards compatibility. diff --git a/.changeset/swift-seahorses-share.md b/.changeset/swift-seahorses-share.md deleted file mode 100644 index deaf2ab042..0000000000 --- a/.changeset/swift-seahorses-share.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-incremental-ingestion': patch ---- - -Updated the README to include documentation for the new backend support diff --git a/.changeset/tall-camels-march.md b/.changeset/tall-camels-march.md deleted file mode 100644 index 892a8f19af..0000000000 --- a/.changeset/tall-camels-march.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-signals': patch ---- - -Put a name on the `SignalsDisplay` component extension diff --git a/.changeset/tame-hornets-shake.md b/.changeset/tame-hornets-shake.md deleted file mode 100644 index bf96193b55..0000000000 --- a/.changeset/tame-hornets-shake.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-react': patch ---- - -Fix an issue where keys with duplicate final key parts are not all displayed in the `ReviewState`. Change the way the keys are formatted to include the full schema path, separated by `>`. diff --git a/.changeset/tasty-pigs-vanish.md b/.changeset/tasty-pigs-vanish.md deleted file mode 100644 index 73556c70d5..0000000000 --- a/.changeset/tasty-pigs-vanish.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog': patch ---- - -Entity presentation api now only fetches fields that are required to display entity title diff --git a/.changeset/thick-walls-share.md b/.changeset/thick-walls-share.md deleted file mode 100644 index 798b1561b4..0000000000 --- a/.changeset/thick-walls-share.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-gerrit': patch ---- - -Added test cases for publish:gerrit action examples diff --git a/.changeset/thirty-pets-fry.md b/.changeset/thirty-pets-fry.md new file mode 100644 index 0000000000..2a588bb161 --- /dev/null +++ b/.changeset/thirty-pets-fry.md @@ -0,0 +1,8 @@ +--- +'@backstage/frontend-plugin-api': minor +'@backstage/core-plugin-api': minor +--- + +**BREAKING PRODUCERS**: The `IconComponent` no longer accepts `fontSize="default"`. This has effectively been removed from Material-UI since its last two major versions, and has not worked properly for them in a long time. + +This change should not have an effect on neither users of MUI4 nor MUI5/6, since the updated interface should still let you send the respective `SvgIcon` types into interfaces where relevant (e.g. as app icons). diff --git a/.changeset/tiny-icons-sit.md b/.changeset/tiny-icons-sit.md deleted file mode 100644 index 7dc35a46fd..0000000000 --- a/.changeset/tiny-icons-sit.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-react': patch ---- - -Small internal fix to better work with recent `lodash` versions diff --git a/.changeset/tiny-pugs-kick.md b/.changeset/tiny-pugs-kick.md new file mode 100644 index 0000000000..2d6f83b325 --- /dev/null +++ b/.changeset/tiny-pugs-kick.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +Update the Scaffolder template editor to quickly access installed custom fields and actions when editing a template. diff --git a/.changeset/tiny-waves-provide.md b/.changeset/tiny-waves-provide.md deleted file mode 100644 index aabafcfd6b..0000000000 --- a/.changeset/tiny-waves-provide.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/backend-plugin-api': patch -'@backstage/backend-defaults': patch -'@backstage/backend-common': patch ---- - -Allow the cache service to accept the human duration format for TTL diff --git a/.changeset/tough-fireants-itch.md b/.changeset/tough-fireants-itch.md new file mode 100644 index 0000000000..3567ac82d0 --- /dev/null +++ b/.changeset/tough-fireants-itch.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-techdocs-backend': patch +'@backstage/plugin-techdocs-node': patch +--- + +Allow to pass StorageOptions to GCS Publisher diff --git a/.changeset/tough-peaches-kneel.md b/.changeset/tough-peaches-kneel.md deleted file mode 100644 index 7674da8879..0000000000 --- a/.changeset/tough-peaches-kneel.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend': patch ---- - -Fixed an issue with the by-query call, where ordering by a field that does not exist on all entities led to not all results being returned diff --git a/.changeset/tough-pillows-sip.md b/.changeset/tough-pillows-sip.md new file mode 100644 index 0000000000..aea3e2d5a0 --- /dev/null +++ b/.changeset/tough-pillows-sip.md @@ -0,0 +1,5 @@ +--- +'@backstage/integration': patch +--- + +Updated functions parseHarnessUrl, getHarnessLatestCommitUrl, getHarnessFileContentsUrl and getHarnessArchiveUrl to fix parsing of urls diff --git a/.changeset/tricky-apricots-film.md b/.changeset/tricky-apricots-film.md deleted file mode 100644 index 7b1c28fdb9..0000000000 --- a/.changeset/tricky-apricots-film.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-signals-react': patch ---- - -Fix for `useSignal` returning the inverse value for `isSignalsAvailable`. diff --git a/.changeset/twenty-clouds-melt.md b/.changeset/twenty-clouds-melt.md deleted file mode 100644 index dee2b0f8ef..0000000000 --- a/.changeset/twenty-clouds-melt.md +++ /dev/null @@ -1,64 +0,0 @@ ---- -'@backstage/backend-defaults': minor ---- - -**BREAKING**: The default backend instance no longer provides implementations for the identity and token manager services, which have been removed from `@backstage/backend-plugin-api`. - -If you rely on plugins that still require these services, you can add them to your own backend by re-creating the service reference and factory. - -The following can be used to implement the identity service: - -```ts -import { - coreServices, - createServiceFactory, - createServiceRef, -} from '@backstage/backend-plugin-api'; -import { - DefaultIdentityClient, - IdentityApi, -} from '@backstage/plugin-auth-node'; - -backend.add( - createServiceFactory({ - service: createServiceRef({ id: 'core.identity' }), - deps: { - discovery: coreServices.discovery, - }, - async factory({ discovery }) { - return DefaultIdentityClient.create({ discovery }); - }, - }), -); -``` - -The following can be used to implement the token manager service: - -```ts -import { ServerTokenManager, TokenManager } from '@backstage/backend-common'; -import { createBackend } from '@backstage/backend-defaults'; -import { - coreServices, - createServiceFactory, - createServiceRef, -} from '@backstage/backend-plugin-api'; - -backend.add( - createServiceFactory({ - service: createServiceRef({ id: 'core.tokenManager' }), - deps: { - config: coreServices.rootConfig, - logger: coreServices.rootLogger, - }, - createRootContext({ config, logger }) { - return ServerTokenManager.fromConfig(config, { - logger, - allowDisabledTokenManager: true, - }); - }, - async factory(_deps, tokenManager) { - return tokenManager; - }, - }), -); -``` diff --git a/.changeset/twenty-jobs-repeat.md b/.changeset/twenty-jobs-repeat.md deleted file mode 100644 index 1ea98319d7..0000000000 --- a/.changeset/twenty-jobs-repeat.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-techdocs': patch ---- - -Enhanced the table hover effect with a lighter color and updated the border radius to align with Backstage's theme styling diff --git a/.changeset/twenty-queens-grow.md b/.changeset/twenty-queens-grow.md deleted file mode 100644 index 1236488dbe..0000000000 --- a/.changeset/twenty-queens-grow.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder': minor ---- - -Added EntityOwnerPicker component to the TemplateListPage to allow filtering on owner diff --git a/.changeset/two-plums-fail.md b/.changeset/two-plums-fail.md new file mode 100644 index 0000000000..9d976ab4b5 --- /dev/null +++ b/.changeset/two-plums-fail.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend-module-bitbucket-server': patch +--- + +Use protocol from Bitbucket Server apiBaseUrl config parameter instead of hard-coded https diff --git a/.changeset/unlucky-cycles-clean.md b/.changeset/unlucky-cycles-clean.md deleted file mode 100644 index 5b582dec59..0000000000 --- a/.changeset/unlucky-cycles-clean.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-react': patch ---- - -Scaffolder review page shows static amount of asterisks for secret fields. diff --git a/.changeset/violet-apricots-smoke.md b/.changeset/violet-apricots-smoke.md deleted file mode 100644 index 80caf466eb..0000000000 --- a/.changeset/violet-apricots-smoke.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/create-app': patch ---- - -Remove references to the `@backstage/backend-tasks` in versions of the `create-app` package, as it has been deprecated. diff --git a/.changeset/violet-jokes-tap.md b/.changeset/violet-jokes-tap.md deleted file mode 100644 index 5b79ced6cd..0000000000 --- a/.changeset/violet-jokes-tap.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -'@backstage/frontend-plugin-api': patch -'@backstage/frontend-app-api': patch ---- - -Added support for defining `replaces` in `createExtensionInput` which will allow extensions to redirect missing `attachTo` points to an input of the created extension. - -```ts -export const AppThemeApi = ApiBlueprint.makeWithOverrides({ - name: 'app-theme', - inputs: { - themes: createExtensionInput([ThemeBlueprint.dataRefs.theme], { - // attachTo: { id: 'app', input: 'themes'} will be redirected to this input instead - replaces: [{ id: 'app', input: 'themes' }], - }), - }, - factory: () { - ... - } -}); -``` diff --git a/.changeset/warm-boxes-grab-2.md b/.changeset/warm-boxes-grab-2.md deleted file mode 100644 index f1928c8be7..0000000000 --- a/.changeset/warm-boxes-grab-2.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/frontend-plugin-api': patch ---- - -A new `apis` parameter has been added to `factory` for extensions. This is a way to access utility APIs without being coupled to the React context. diff --git a/.changeset/warm-boxes-grab.md b/.changeset/warm-boxes-grab.md deleted file mode 100644 index e10dbe086c..0000000000 --- a/.changeset/warm-boxes-grab.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/frontend-app-api': patch ---- - -Added the `root` extension the replace the `app` extension as the root of the app. diff --git a/.changeset/weak-bottles-cross.md b/.changeset/weak-bottles-cross.md new file mode 100644 index 0000000000..c12d32d7db --- /dev/null +++ b/.changeset/weak-bottles-cross.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend': patch +--- + +Fix a bug where etags were expiring too soon in the URL reader diff --git a/.changeset/wild-buses-notice.md b/.changeset/wild-buses-notice.md deleted file mode 100644 index 3620786aa8..0000000000 --- a/.changeset/wild-buses-notice.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-defaults': patch ---- - -Added the option to skip database migrations by setting `skipMigrations: true` in config. This can be done globally in the database config or by plugin id. diff --git a/.changeset/wise-forks-play.md b/.changeset/wise-forks-play.md deleted file mode 100644 index 1c8be76d19..0000000000 --- a/.changeset/wise-forks-play.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -'@backstage/backend-defaults': minor ---- - -**BREAKING**: Simplifications and cleanup as part of the Backend System 1.0 work. - -For the `/database` subpath exports: - -- The deprecated `dropDatabase` function has now been removed, without replacement. -- The deprecated `LegacyRootDatabaseService` type has now been removed. -- The return type from `DatabaseManager.forPlugin` is now directly a `DatabaseService`, as arguably expected. -- `DatabaseManager.forPlugin` now requires the `deps` argument, with the logger and lifecycle services. - -For the `/cache` subpath exports: - -- The `PluginCacheManager` type has been removed. You can still import it from `@backstage/backend-common`, but it's deprecated there, and you should move off of that package by migrating fully to the new backend system. -- Accordingly, `CacheManager.forPlugin` immediately returns a `CacheService` instead of a `PluginCacheManager`. The outcome of this is that you no longer need to make the extra `.getClient()` call. The old `CacheManager` with the old behavior still exists on `@backstage/backend-common`, but the above recommendations apply. diff --git a/.changeset/wise-scissors-help.md b/.changeset/wise-scissors-help.md deleted file mode 100644 index c8fd2d4c44..0000000000 --- a/.changeset/wise-scissors-help.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@backstage/backend-defaults': patch -'@backstage/backend-app-api': patch -'@backstage/backend-common': patch -'@backstage/backend-plugin-api': patch ---- - -Updates to the config schema to match reality diff --git a/.changeset/witty-years-cry.md b/.changeset/witty-years-cry.md deleted file mode 100644 index 48c566730b..0000000000 --- a/.changeset/witty-years-cry.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-permission-backend': patch ---- - -Deprecated `createRouter` and its router options in favour of the new backend system. diff --git a/.changeset/yellow-bees-hope.md b/.changeset/yellow-bees-hope.md deleted file mode 100644 index 1ea8690c20..0000000000 --- a/.changeset/yellow-bees-hope.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/frontend-app-api': minor ---- - -Removed deprecated `icons` property passing to `createApp` and `createSpecializedApp`. Use `IconBundleBlueprint.make` to create extensions instead and include them in the app. diff --git a/.eslintrc.js b/.eslintrc.js index 01cad187be..eb2a07b3b0 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -263,4 +263,7 @@ module.exports = { }, }, ], + settings: { + 'testing-library/custom-queries': 'off', + }, }; diff --git a/.github/vale/config/vocabularies/Backstage/accept.txt b/.github/vale/config/vocabularies/Backstage/accept.txt index 320bb2e0ce..2cbcc484f7 100644 --- a/.github/vale/config/vocabularies/Backstage/accept.txt +++ b/.github/vale/config/vocabularies/Backstage/accept.txt @@ -39,6 +39,8 @@ Brex broadcasted bugfixes builtins +bundler +bundlers callout CDNs Chai @@ -112,6 +114,7 @@ DOMPurify don'ts dynatrace Dynatrace +dyno ecco elasticsearch Entra @@ -163,6 +166,7 @@ Heroku hoc horizontalpodautoscalers Hostname +hotspot hotspots howto http @@ -199,6 +203,7 @@ Knex knip Koyeb KPIs +kroki Kuang kubectl kubernetes @@ -279,6 +284,8 @@ OpenSearch OpenShift openssl orgs +Overridable +overridable padding paddings pagerduty @@ -452,6 +459,7 @@ unmount unregister unregistering unregistration +unstarred untracked upsert upstreams diff --git a/.github/workflows/api-breaking-changes-comment.yml b/.github/workflows/api-breaking-changes-comment.yml index abb98c03e1..e28f147706 100644 --- a/.github/workflows/api-breaking-changes-comment.yml +++ b/.github/workflows/api-breaking-changes-comment.yml @@ -22,7 +22,7 @@ jobs: action: ${{ steps.event.outputs.ACTION }} steps: - name: Harden Runner - uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: disable-sudo: true egress-policy: block diff --git a/.github/workflows/api-breaking-changes.yml b/.github/workflows/api-breaking-changes.yml index 12d33b450e..3e27955f8a 100644 --- a/.github/workflows/api-breaking-changes.yml +++ b/.github/workflows/api-breaking-changes.yml @@ -14,7 +14,7 @@ jobs: if: ${{ github.event_name != 'pull_request' || github.event.action != 'closed' }} steps: - name: Harden Runner - uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: egress-policy: audit @@ -27,13 +27,13 @@ jobs: run: git fetch --depth 1 origin ${{ github.base_ref }} - name: setup-node - uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 + uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 with: node-version: 18.x registry-url: https://registry.npmjs.org/ - name: yarn install - uses: backstage/actions/yarn-install@3c138326f7fcbf253b88170c1f29bae8e975d47c # v0.6.14 + uses: backstage/actions/yarn-install@25145dd4117d50e1da9330e9ed2893bc6b75373e # v0.6.15 with: cache-prefix: linux-v18 diff --git a/.github/workflows/automate_area-labels.yml b/.github/workflows/automate_area-labels.yml index fcff8bc11a..89e1adc3c3 100644 --- a/.github/workflows/automate_area-labels.yml +++ b/.github/workflows/automate_area-labels.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: egress-policy: audit diff --git a/.github/workflows/automate_changeset_feedback.yml b/.github/workflows/automate_changeset_feedback.yml index 1d8e29fab0..1f07a848fb 100644 --- a/.github/workflows/automate_changeset_feedback.yml +++ b/.github/workflows/automate_changeset_feedback.yml @@ -23,7 +23,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: egress-policy: audit @@ -34,7 +34,7 @@ jobs: ref: 'refs/pull/${{ github.event.pull_request.number }}/merge' - name: fetch base run: git fetch --depth 1 origin ${{ github.base_ref }} - - uses: backstage/actions/changeset-feedback@3c138326f7fcbf253b88170c1f29bae8e975d47c # v0.6.14 + - uses: backstage/actions/changeset-feedback@25145dd4117d50e1da9330e9ed2893bc6b75373e # v0.6.15 name: Generate feedback with: diff-ref: 'origin/master' diff --git a/.github/workflows/automate_merge_message.yml b/.github/workflows/automate_merge_message.yml index 2bc7940971..4ab75b816f 100644 --- a/.github/workflows/automate_merge_message.yml +++ b/.github/workflows/automate_merge_message.yml @@ -24,7 +24,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: egress-policy: audit diff --git a/.github/workflows/automate_stale.yml b/.github/workflows/automate_stale.yml index 1ffeac1cc0..b7adc5235a 100644 --- a/.github/workflows/automate_stale.yml +++ b/.github/workflows/automate_stale.yml @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: egress-policy: audit diff --git a/.github/workflows/ci-noop.yml b/.github/workflows/ci-noop.yml index 9b54e6fe6f..321e4b57e7 100644 --- a/.github/workflows/ci-noop.yml +++ b/.github/workflows/ci-noop.yml @@ -40,7 +40,7 @@ jobs: name: Test ${{ matrix.node-version }} steps: - name: Harden Runner - uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: egress-policy: audit diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5cbe2e15a3..886abafcd7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,20 +28,20 @@ jobs: name: Install ${{ matrix.node-version }} steps: - name: Harden Runner - uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: egress-policy: audit - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: use node.js ${{ matrix.node-version }} - uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 + uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 with: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@3c138326f7fcbf253b88170c1f29bae8e975d47c # v0.6.14 + uses: backstage/actions/yarn-install@25145dd4117d50e1da9330e9ed2893bc6b75373e # v0.6.15 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} @@ -64,20 +64,20 @@ jobs: name: Verify ${{ matrix.node-version }} steps: - name: Harden Runner - uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: egress-policy: audit - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: use node.js ${{ matrix.node-version }} - uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 + uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 with: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@3c138326f7fcbf253b88170c1f29bae8e975d47c # v0.6.14 + uses: backstage/actions/yarn-install@25145dd4117d50e1da9330e9ed2893bc6b75373e # v0.6.15 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} @@ -90,6 +90,9 @@ jobs: - name: verify local dependency ranges run: node scripts/verify-local-dependencies.js + - name: verify peer dependency ranges + run: yarn lint:peer-deps + - name: check for missing repo fixes run: yarn fix --check @@ -216,13 +219,13 @@ jobs: run: git fetch origin ${{ github.event.pull_request.base.ref }} - name: use node.js ${{ matrix.node-version }} - uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 + uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 with: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@3c138326f7fcbf253b88170c1f29bae8e975d47c # v0.6.14 + uses: backstage/actions/yarn-install@25145dd4117d50e1da9330e9ed2893bc6b75373e # v0.6.15 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} diff --git a/.github/workflows/cron.yml b/.github/workflows/cron.yml index 2ac5434f72..48ac1db289 100644 --- a/.github/workflows/cron.yml +++ b/.github/workflows/cron.yml @@ -10,11 +10,11 @@ jobs: timeout-minutes: 10 steps: - name: Harden Runner - uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: egress-policy: audit - - uses: backstage/actions/cron@3c138326f7fcbf253b88170c1f29bae8e975d47c # v0.6.14 + - uses: backstage/actions/cron@25145dd4117d50e1da9330e9ed2893bc6b75373e # v0.6.15 with: app-id: ${{ secrets.BACKSTAGE_GOALIE_APPLICATION_ID }} private-key: ${{ secrets.BACKSTAGE_GOALIE_PRIVATE_KEY }} diff --git a/.github/workflows/deploy_docker-image.yml b/.github/workflows/deploy_docker-image.yml index 86db3795bc..a45c9c35bd 100644 --- a/.github/workflows/deploy_docker-image.yml +++ b/.github/workflows/deploy_docker-image.yml @@ -20,7 +20,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: egress-policy: audit @@ -31,13 +31,13 @@ jobs: ref: ${{ github.event.client_payload.version && env.RELEASE_VERSION || github.ref }} - name: use node.js ${{ matrix.node-version }} - uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 + uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 with: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@3c138326f7fcbf253b88170c1f29bae8e975d47c # v0.6.14 + uses: backstage/actions/yarn-install@25145dd4117d50e1da9330e9ed2893bc6b75373e # v0.6.15 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} @@ -45,6 +45,7 @@ jobs: run: npx @backstage/create-app env: BACKSTAGE_APP_NAME: example-app + YARN_ENABLE_IMMUTABLE_INSTALLS: false - name: yarn build run: yarn build:backend @@ -61,7 +62,7 @@ jobs: uses: docker/setup-buildx-action@988b5a0280414f521da01fcc63a27aeeb4b104db # v3.6.1 - name: Build and push - uses: docker/build-push-action@ca052bb54ab0790a636c9b5f226502c73d547a25 # v5.4.0 + uses: docker/build-push-action@5cd11c3a4ced054e52742c5fd54dca954e0edd85 # v6.7.0 with: context: './example-app' file: ./example-app/packages/backend/Dockerfile diff --git a/.github/workflows/deploy_microsite.yml b/.github/workflows/deploy_microsite.yml index 8f3820ae62..9ae266280f 100644 --- a/.github/workflows/deploy_microsite.yml +++ b/.github/workflows/deploy_microsite.yml @@ -23,7 +23,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: egress-policy: audit @@ -59,13 +59,13 @@ jobs: ref: refs/tags/${{ steps.find-release.outputs.result }} - name: use node.js 18.x - uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 + uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 with: node-version: 18.x registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@3c138326f7fcbf253b88170c1f29bae8e975d47c # v0.6.14 + uses: backstage/actions/yarn-install@25145dd4117d50e1da9330e9ed2893bc6b75373e # v0.6.15 with: cache-prefix: ${{ runner.os }}-v18.x @@ -91,7 +91,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: egress-policy: audit @@ -99,13 +99,13 @@ jobs: uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: use node.js 18.x - uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 + uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 with: node-version: 18.x registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@3c138326f7fcbf253b88170c1f29bae8e975d47c # v0.6.14 + uses: backstage/actions/yarn-install@25145dd4117d50e1da9330e9ed2893bc6b75373e # v0.6.15 with: cache-prefix: ${{ runner.os }}-v18.x @@ -158,12 +158,12 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: egress-policy: audit - name: use node.js 18.x - uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 + uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 with: node-version: 18.x registry-url: https://registry.npmjs.org/ # Needed for auth @@ -184,6 +184,11 @@ jobs: name: stable-reference path: docs/reference + - name: grab lastest releases docs + run: | + git fetch origin master --depth 1 + git checkout FETCH_HEAD -- docs/releases + - name: generate stable docs run: yarn docusaurus docs:version stable working-directory: microsite @@ -220,7 +225,7 @@ jobs: run: ls microsite/build && ls microsite/build/storybook - name: Deploy both microsite and storybook to gh-pages - uses: JamesIves/github-pages-deploy-action@94f3c658273cf92fb48ef99e5fbc02bd2dc642b2 # v4.6.3 + uses: JamesIves/github-pages-deploy-action@920cbb300dcd3f0568dbc42700c61e2fd9e6139c # v4.6.4 with: branch: gh-pages folder: microsite/build diff --git a/.github/workflows/deploy_packages.yml b/.github/workflows/deploy_packages.yml index f86c1db4fa..92210e90be 100644 --- a/.github/workflows/deploy_packages.yml +++ b/.github/workflows/deploy_packages.yml @@ -71,12 +71,12 @@ jobs: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: use node.js ${{ matrix.node-version }} - uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 + uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 with: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@3c138326f7fcbf253b88170c1f29bae8e975d47c # v0.6.14 + uses: backstage/actions/yarn-install@25145dd4117d50e1da9330e9ed2893bc6b75373e # v0.6.15 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} @@ -144,7 +144,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: egress-policy: audit diff --git a/.github/workflows/issue.yaml b/.github/workflows/issue.yaml index c8793d3ab0..2cd355b75e 100644 --- a/.github/workflows/issue.yaml +++ b/.github/workflows/issue.yaml @@ -16,7 +16,7 @@ jobs: if: github.repository == 'backstage/backstage' steps: - name: Harden Runner - uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: egress-policy: audit diff --git a/.github/workflows/pr-review-comment-trigger.yaml b/.github/workflows/pr-review-comment-trigger.yaml index 27a5a78052..7e3faaebc5 100644 --- a/.github/workflows/pr-review-comment-trigger.yaml +++ b/.github/workflows/pr-review-comment-trigger.yaml @@ -20,7 +20,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: egress-policy: audit @@ -30,7 +30,7 @@ jobs: run: | mkdir -p ./pr echo $PR_NUMBER > ./pr/pr_number - - uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6 + - uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 with: name: pr_number-${{ github.event.pull_request.number }} path: pr/ diff --git a/.github/workflows/pr-review-comment.yaml b/.github/workflows/pr-review-comment.yaml index 6133fdef8a..517a978a83 100644 --- a/.github/workflows/pr-review-comment.yaml +++ b/.github/workflows/pr-review-comment.yaml @@ -17,7 +17,7 @@ jobs: steps: # Inspired by https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#using-data-from-the-triggering-workflow - name: Harden Runner - uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: egress-policy: audit @@ -40,7 +40,7 @@ jobs: const prNumber = artifact.name.slice('pr_number-'.length) core.setOutput('pr-number', prNumber); - - uses: backstage/actions/re-review@3c138326f7fcbf253b88170c1f29bae8e975d47c # v0.6.14 + - uses: backstage/actions/re-review@25145dd4117d50e1da9330e9ed2893bc6b75373e # v0.6.15 with: app-id: ${{ secrets.BACKSTAGE_GOALIE_APPLICATION_ID }} private-key: ${{ secrets.BACKSTAGE_GOALIE_PRIVATE_KEY }} diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 510d5242f4..7639ac14db 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -18,12 +18,12 @@ jobs: if: github.repository == 'backstage/backstage' && ( github.event.pull_request || github.event.issue.pull_request ) steps: - name: Harden Runner - uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: egress-policy: audit - name: PR sync - uses: backstage/actions/pr-sync@3c138326f7fcbf253b88170c1f29bae8e975d47c # v0.6.14 + uses: backstage/actions/pr-sync@25145dd4117d50e1da9330e9ed2893bc6b75373e # v0.6.15 with: github-token: ${{ secrets.GH_SERVICE_ACCOUNT_TOKEN }} app-id: ${{ secrets.BACKSTAGE_GOALIE_APPLICATION_ID }} diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 0d22deeca1..53489d8c0e 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -29,7 +29,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: egress-policy: audit @@ -58,7 +58,7 @@ jobs: # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: 'Upload artifact' - uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6 + uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 with: name: SARIF file path: results.sarif @@ -67,6 +67,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: 'Upload to code-scanning' - uses: github/codeql-action/upload-sarif@2c779ab0d087cd7fe7b826087247c2c81f27bfa6 # v3.26.5 + uses: github/codeql-action/upload-sarif@8214744c546c1e5c8f03dde8fab3a7353211988d # v3.26.7 with: sarif_file: results.sarif diff --git a/.github/workflows/sync_code-formatting.yml b/.github/workflows/sync_code-formatting.yml index 859f077095..f59eb048e0 100644 --- a/.github/workflows/sync_code-formatting.yml +++ b/.github/workflows/sync_code-formatting.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: egress-policy: audit @@ -20,12 +20,12 @@ jobs: fetch-depth: 0 - name: use node.js ${{ matrix.node-version }} - uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 + uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 with: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@3c138326f7fcbf253b88170c1f29bae8e975d47c # v0.6.14 + uses: backstage/actions/yarn-install@25145dd4117d50e1da9330e9ed2893bc6b75373e # v0.6.15 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} diff --git a/.github/workflows/sync_dependabot-changesets.yml b/.github/workflows/sync_dependabot-changesets.yml index 357b7f5cd9..adf39be8df 100644 --- a/.github/workflows/sync_dependabot-changesets.yml +++ b/.github/workflows/sync_dependabot-changesets.yml @@ -11,7 +11,7 @@ jobs: if: github.actor == 'dependabot[bot]' && github.repository == 'backstage/backstage' steps: - name: Harden Runner - uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: egress-policy: audit diff --git a/.github/workflows/sync_release-manifest.yml b/.github/workflows/sync_release-manifest.yml index 898aaa74c7..87a8837c48 100644 --- a/.github/workflows/sync_release-manifest.yml +++ b/.github/workflows/sync_release-manifest.yml @@ -8,7 +8,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: egress-policy: audit @@ -19,13 +19,13 @@ jobs: ref: v${{ github.event.client_payload.version }} - name: use node.js 18.x - uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 + uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 with: node-version: 18.x registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@3c138326f7fcbf253b88170c1f29bae8e975d47c # v0.6.14 + uses: backstage/actions/yarn-install@25145dd4117d50e1da9330e9ed2893bc6b75373e # v0.6.15 with: cache-prefix: ${{ runner.os }}-v18.x diff --git a/.github/workflows/sync_renovate-changesets.yml b/.github/workflows/sync_renovate-changesets.yml index 19072a443b..200bc6eaaa 100644 --- a/.github/workflows/sync_renovate-changesets.yml +++ b/.github/workflows/sync_renovate-changesets.yml @@ -11,7 +11,7 @@ jobs: if: github.actor == 'renovate[bot]' && github.repository == 'backstage/backstage' steps: - name: Harden Runner - uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: egress-policy: audit diff --git a/.github/workflows/sync_snyk-github-issues.yml b/.github/workflows/sync_snyk-github-issues.yml index 0369f89648..9c709508b3 100644 --- a/.github/workflows/sync_snyk-github-issues.yml +++ b/.github/workflows/sync_snyk-github-issues.yml @@ -12,24 +12,24 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: egress-policy: audit - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: use node.js 18.x - uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 + uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 with: node-version: 18.x registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@3c138326f7fcbf253b88170c1f29bae8e975d47c # v0.6.14 + uses: backstage/actions/yarn-install@25145dd4117d50e1da9330e9ed2893bc6b75373e # v0.6.15 with: cache-prefix: ${{ runner.os }}-v18.x - name: Create Snyk report - uses: snyk/actions/node@9213221444c2dc9e8b2502c1e857c26d851e84a7 # master + uses: snyk/actions/node@cdb760004ba9ea4d525f2e043745dfe85bb9077e # master continue-on-error: true # Snyk CLI exits with error when vulnerabilities are found with: args: > diff --git a/.github/workflows/sync_snyk-monitor.yml b/.github/workflows/sync_snyk-monitor.yml index 99fb8e16bd..1b48930410 100644 --- a/.github/workflows/sync_snyk-monitor.yml +++ b/.github/workflows/sync_snyk-monitor.yml @@ -25,13 +25,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: egress-policy: audit - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: Monitor and Synchronize Snyk Policies - uses: snyk/actions/node@9213221444c2dc9e8b2502c1e857c26d851e84a7 # master + uses: snyk/actions/node@cdb760004ba9ea4d525f2e043745dfe85bb9077e # master with: command: monitor args: > @@ -46,7 +46,7 @@ jobs: # Above we run the `monitor` command, this runs the `test` command which is # the one that generates the SARIF report that we can upload to GitHub. - name: Create Snyk report - uses: snyk/actions/node@9213221444c2dc9e8b2502c1e857c26d851e84a7 # master + uses: snyk/actions/node@cdb760004ba9ea4d525f2e043745dfe85bb9077e # master continue-on-error: true # To make sure that SARIF upload gets called with: args: > @@ -58,6 +58,6 @@ jobs: SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} NODE_OPTIONS: --max-old-space-size=7168 - name: Upload Snyk report - uses: github/codeql-action/upload-sarif@2c779ab0d087cd7fe7b826087247c2c81f27bfa6 # v3.26.5 + uses: github/codeql-action/upload-sarif@8214744c546c1e5c8f03dde8fab3a7353211988d # v3.26.7 with: sarif_file: snyk.sarif diff --git a/.github/workflows/sync_version-packages.yml b/.github/workflows/sync_version-packages.yml index 3a29ba3c79..aac606ae90 100644 --- a/.github/workflows/sync_version-packages.yml +++ b/.github/workflows/sync_version-packages.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: egress-policy: audit diff --git a/.github/workflows/verify_accessibility-noop.yml b/.github/workflows/verify_accessibility-noop.yml index 8d8cb30789..37ce3513e9 100644 --- a/.github/workflows/verify_accessibility-noop.yml +++ b/.github/workflows/verify_accessibility-noop.yml @@ -26,7 +26,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: egress-policy: audit diff --git a/.github/workflows/verify_accessibility.yml b/.github/workflows/verify_accessibility.yml index fd86075ea0..cfeb8ba51f 100644 --- a/.github/workflows/verify_accessibility.yml +++ b/.github/workflows/verify_accessibility.yml @@ -20,17 +20,17 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: egress-policy: audit - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: Use Node.js 18.x - uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 + uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 with: node-version: 18.x - name: yarn install - uses: backstage/actions/yarn-install@3c138326f7fcbf253b88170c1f29bae8e975d47c # v0.6.14 + uses: backstage/actions/yarn-install@25145dd4117d50e1da9330e9ed2893bc6b75373e # v0.6.15 with: cache-prefix: ${{ runner.os }}-v18.x - name: run Lighthouse CI diff --git a/.github/workflows/verify_codeql.yml b/.github/workflows/verify_codeql.yml index ea31ea6431..63ba85906e 100644 --- a/.github/workflows/verify_codeql.yml +++ b/.github/workflows/verify_codeql.yml @@ -42,7 +42,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: egress-policy: audit @@ -55,7 +55,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@2c779ab0d087cd7fe7b826087247c2c81f27bfa6 # v3.26.5 + uses: github/codeql-action/init@8214744c546c1e5c8f03dde8fab3a7353211988d # v3.26.7 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -66,7 +66,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@2c779ab0d087cd7fe7b826087247c2c81f27bfa6 # v3.26.5 + uses: github/codeql-action/autobuild@8214744c546c1e5c8f03dde8fab3a7353211988d # v3.26.7 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -80,4 +80,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@2c779ab0d087cd7fe7b826087247c2c81f27bfa6 # v3.26.5 + uses: github/codeql-action/analyze@8214744c546c1e5c8f03dde8fab3a7353211988d # v3.26.7 diff --git a/.github/workflows/verify_docs-quality.yml b/.github/workflows/verify_docs-quality.yml index 8e1a91d850..8e2ae20596 100644 --- a/.github/workflows/verify_docs-quality.yml +++ b/.github/workflows/verify_docs-quality.yml @@ -12,7 +12,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: egress-policy: audit diff --git a/.github/workflows/verify_e2e-kubernetes-noop.yml b/.github/workflows/verify_e2e-kubernetes-noop.yml deleted file mode 100644 index 544c4e6186..0000000000 --- a/.github/workflows/verify_e2e-kubernetes-noop.yml +++ /dev/null @@ -1,30 +0,0 @@ -# NO-OP placeholder that always passes for other paths -# This is here so that we're able to set the status check as required - -name: E2E Kubernetes Void -on: - pull_request: - paths-ignore: - - 'yarn.lock' - - '.github/workflows/verify_e2e-kubernetes.yml' - - 'packages/backend-common/src/**' - -permissions: - contents: read - -jobs: - verify: - runs-on: ubuntu-latest - - strategy: - matrix: - node-version: [18.x, 20.x] - - name: Kubernetes ${{ matrix.node-version }} - steps: - - name: Harden Runner - uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 - with: - egress-policy: audit - - - run: echo NOOP diff --git a/.github/workflows/verify_e2e-kubernetes.yml b/.github/workflows/verify_e2e-kubernetes.yml deleted file mode 100644 index 18eee7e3f2..0000000000 --- a/.github/workflows/verify_e2e-kubernetes.yml +++ /dev/null @@ -1,47 +0,0 @@ -name: E2E Kubernetes -on: - # NOTE: If you change these you must update verify_kubernetes-noop.yml as well - pull_request: - paths: - - 'yarn.lock' - - '.github/workflows/verify_e2e-kubernetes.yml' - - 'packages/backend-common/src/**' - -jobs: - verify: - runs-on: ubuntu-latest - - strategy: - matrix: - node-version: [18.x, 20.x] - - env: - CI: true - KUBERNETES_TESTS: true - - name: Kubernetes ${{ matrix.node-version }} - steps: - - name: Harden Runner - uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 - with: - egress-policy: audit - - - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - - - name: use node.js ${{ matrix.node-version }} - uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 - with: - node-version: ${{ matrix.node-version }} - registry-url: https://registry.npmjs.org/ # Needed for auth - - - name: yarn install - uses: backstage/actions/yarn-install@3c138326f7fcbf253b88170c1f29bae8e975d47c # v0.6.14 - with: - cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} - - - name: bootstrap kind - uses: helm/kind-action@0025e74a8c7512023d06dc019c617aa3cf561fde # v1.10.0 - - - name: kubernetes test - working-directory: packages/backend-common - run: yarn test:kubernetes diff --git a/.github/workflows/verify_e2e-linux-noop.yml b/.github/workflows/verify_e2e-linux-noop.yml index 024f288255..f4f24f14f5 100644 --- a/.github/workflows/verify_e2e-linux-noop.yml +++ b/.github/workflows/verify_e2e-linux-noop.yml @@ -29,7 +29,7 @@ jobs: name: E2E Linux ${{ matrix.node-version }} steps: - name: Harden Runner - uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: egress-policy: audit diff --git a/.github/workflows/verify_e2e-linux.yml b/.github/workflows/verify_e2e-linux.yml index 1c1ed7a3eb..69a92abb9a 100644 --- a/.github/workflows/verify_e2e-linux.yml +++ b/.github/workflows/verify_e2e-linux.yml @@ -41,7 +41,7 @@ jobs: name: E2E Linux ${{ matrix.node-version }} steps: - name: Harden Runner - uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: egress-policy: audit @@ -53,12 +53,12 @@ jobs: git config --global user.name 'GitHub e2e user' - name: use node.js ${{ matrix.node-version }} - uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 + uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 with: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@3c138326f7fcbf253b88170c1f29bae8e975d47c # v0.6.14 + uses: backstage/actions/yarn-install@25145dd4117d50e1da9330e9ed2893bc6b75373e # v0.6.15 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} diff --git a/.github/workflows/verify_e2e-techdocs.yml b/.github/workflows/verify_e2e-techdocs.yml index e2788e2d47..15bb9b3479 100644 --- a/.github/workflows/verify_e2e-techdocs.yml +++ b/.github/workflows/verify_e2e-techdocs.yml @@ -30,7 +30,7 @@ jobs: name: Techdocs steps: - name: Harden Runner - uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: egress-policy: audit diff --git a/.github/workflows/verify_e2e-windows-noop.yml b/.github/workflows/verify_e2e-windows-noop.yml index 5244a78919..b3998522c9 100644 --- a/.github/workflows/verify_e2e-windows-noop.yml +++ b/.github/workflows/verify_e2e-windows-noop.yml @@ -25,7 +25,7 @@ jobs: name: E2E Windows ${{ matrix.node-version }} steps: - name: Harden Runner - uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: egress-policy: audit diff --git a/.github/workflows/verify_e2e-windows.yml b/.github/workflows/verify_e2e-windows.yml index 8663e420eb..911698867c 100644 --- a/.github/workflows/verify_e2e-windows.yml +++ b/.github/workflows/verify_e2e-windows.yml @@ -31,7 +31,7 @@ jobs: name: E2E Windows ${{ matrix.node-version }} steps: - name: Harden Runner - uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: egress-policy: audit @@ -50,7 +50,7 @@ jobs: git config --global user.name 'GitHub e2e user' - name: use node.js ${{ matrix.node-version }} - uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 + uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 with: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth @@ -78,7 +78,7 @@ jobs: uses: browser-actions/setup-chrome@803ef6dfb4fdf22089c9563225d95e4a515820a0 # latest - name: yarn install - uses: backstage/actions/yarn-install@3c138326f7fcbf253b88170c1f29bae8e975d47c # v0.6.14 + uses: backstage/actions/yarn-install@25145dd4117d50e1da9330e9ed2893bc6b75373e # v0.6.15 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} diff --git a/.github/workflows/verify_fossa.yml b/.github/workflows/verify_fossa.yml index 3a5899d3cf..8b3bfc9b13 100644 --- a/.github/workflows/verify_fossa.yml +++ b/.github/workflows/verify_fossa.yml @@ -14,7 +14,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: egress-policy: audit diff --git a/.github/workflows/verify_microsite-noop.yml b/.github/workflows/verify_microsite-noop.yml index daec683da6..f4c5ea4104 100644 --- a/.github/workflows/verify_microsite-noop.yml +++ b/.github/workflows/verify_microsite-noop.yml @@ -21,7 +21,7 @@ jobs: name: Microsite steps: - name: Harden Runner - uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: egress-policy: audit diff --git a/.github/workflows/verify_microsite.yml b/.github/workflows/verify_microsite.yml index a290b221b2..5527953767 100644 --- a/.github/workflows/verify_microsite.yml +++ b/.github/workflows/verify_microsite.yml @@ -24,14 +24,14 @@ jobs: name: Microsite steps: - name: Harden Runner - uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: egress-policy: audit - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: use node.js 18.x - uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 + uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 with: node-version: 18.x - uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5 diff --git a/.github/workflows/verify_microsite_accessibility-noop.yml b/.github/workflows/verify_microsite_accessibility-noop.yml index a3e8e7fdec..49721e7f51 100644 --- a/.github/workflows/verify_microsite_accessibility-noop.yml +++ b/.github/workflows/verify_microsite_accessibility-noop.yml @@ -24,7 +24,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: egress-policy: audit diff --git a/.github/workflows/verify_microsite_accessibility.yml b/.github/workflows/verify_microsite_accessibility.yml index b2c98c1e58..350c46309e 100644 --- a/.github/workflows/verify_microsite_accessibility.yml +++ b/.github/workflows/verify_microsite_accessibility.yml @@ -15,14 +15,14 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: egress-policy: audit - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: Use Node.js 18.x - uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 + uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 with: node-version: 18.x diff --git a/.github/workflows/verify_storybook-noop.yml b/.github/workflows/verify_storybook-noop.yml index 1f9ded9587..115c79c9c3 100644 --- a/.github/workflows/verify_storybook-noop.yml +++ b/.github/workflows/verify_storybook-noop.yml @@ -28,7 +28,7 @@ jobs: name: Storybook steps: - name: Harden Runner - uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: egress-policy: audit diff --git a/.github/workflows/verify_storybook.yml b/.github/workflows/verify_storybook.yml index 9bea2f3dc9..458ef69690 100644 --- a/.github/workflows/verify_storybook.yml +++ b/.github/workflows/verify_storybook.yml @@ -28,7 +28,7 @@ jobs: name: Storybook steps: - name: Harden Runner - uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: egress-policy: audit @@ -37,12 +37,12 @@ jobs: fetch-depth: 0 # Required to retrieve git history - name: use node.js ${{ matrix.node-version }} - uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 + uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 with: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@3c138326f7fcbf253b88170c1f29bae8e975d47c # v0.6.14 + uses: backstage/actions/yarn-install@25145dd4117d50e1da9330e9ed2893bc6b75373e # v0.6.15 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} - name: storybook yarn install @@ -51,7 +51,7 @@ jobs: - run: yarn build-storybook - - uses: chromaui/action@b984808b772126a9f44b2b7737b131b68a2ede32 # v11 + - uses: chromaui/action@f4e60a7072abcac4203f4ca50613f28e199a52ba # v11 with: token: ${{ secrets.GITHUB_TOKEN }} # projectToken intentionally shared to allow collaborators to run Chromatic on forks diff --git a/.github/workflows/verify_windows.yml b/.github/workflows/verify_windows.yml index feb209dc2b..9846ff28d2 100644 --- a/.github/workflows/verify_windows.yml +++ b/.github/workflows/verify_windows.yml @@ -29,14 +29,14 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: egress-policy: audit - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: use node.js ${{ matrix.node-version }} - uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 + uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 with: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth diff --git a/.prettierignore b/.prettierignore index 3a16bd1388..c7a16065e5 100644 --- a/.prettierignore +++ b/.prettierignore @@ -4,8 +4,13 @@ microsite coverage *.hbs templates +# old reports api-report.md api-report-*.md +# new reports +report.api.md +report-*.api.md + knip-report.md cli-report.md plugins/scaffolder-backend/sample-templates diff --git a/ADOPTERS.md b/ADOPTERS.md index 76114b6965..3f9005ecb9 100644 --- a/ADOPTERS.md +++ b/ADOPTERS.md @@ -274,3 +274,4 @@ _You can do this by using the [Adopter form](https://info.backstage.spotify.com/ | [DPG Media](https://www.dpgmediagroup.com) | [@benjidotsh](https://github.com/benjidotsh), [@lvstb](https://github.com/lvstb), [@ssliman](https://github.com/ssliman), [@edewel-beep](https://github.com/edewel-beep) | Access to infrastructure, documentation and internal tooling | | [Baloise](https://www.baloise.ch) | [@dweber019](https://github.com/dweber019), [@mikevader](https://github.com/mikevader) | We are using Backstage as internal developer protal for use cases like software catalog, documentation, infrastructure. | | [Cigna](https://www.cigna.com/) / [Evernorth](https://www.evernorth.com/) | [@raphtalia](https://github.com/raphtalia), [Devon Paluso](mailto:Devon.Paluso@evernorth.com), [Bryan Rego](mailto:Bryan.Rego@evernorth.com), [Ian Skillings](mailto:Ian.Skillings@evernorth.com) | Internal developer portal providing TechDocs, software templates, centralized secret management, with information consolidation from ServiceNow, Okta, GitHub, GitLab, and WebEx. | +| [Infobip](https://www.infobip.com/) | [Antonio Ereiz](https://github.com/SonilPro) | Visual representation of all our entities registered within an existing internal catalog, along with a UI for editing their manifests. It serves as the go-to place for new internal tools that require a user interface and provides standardization of new components using Software Templates. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f10116844b..c1a0283f09 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,7 +2,7 @@ Our vision for Backstage is for it to become the trusted standard toolbox (read: UX layer) for the open source infrastructure landscape. Think of it like Kubernetes for developer experience. We realize this is an ambitious goal. We can’t do it alone. -Therefore we want to create a strong community of contributors -- all working together to create the kind of delightful experience that our developers deserve. +Therefore, we want to create a strong community of contributors -- all working together to create the kind of delightful experience that our developers deserve. Contributions are welcome, and they are greatly appreciated! Every little bit helps, and credit will always be given. ❤️ @@ -41,7 +41,7 @@ We encourage you to catch any accessibility issues already in the development ph ## Get Started! -So...feel ready to jump in? Let's do this. 👏🏻💯 +So... feel ready to jump in? Let's do this. 👏🏻💯 ### Cloning the Repository @@ -103,7 +103,7 @@ If you want to get a better understanding of the layout of the repo now that you ## Coding Guidelines -All code is formatted with `prettier` using the configuration in the repo. If possible we recommend configuring your editor to format automatically, but you can also use the `yarn prettier --write ` command to format files. +All code is formatted with `prettier` using the configuration in the repo. If possible, we recommend configuring your editor to format automatically, but you can also use the `yarn prettier --write ` command to format files. A consistent coding style is included via [EditorConfig](https://editorconfig.org/) with the file [`.editorconfig`](.editorconfig) at the root of the repo. Depending on your editor of choice, it will either support it out of the box or you can [download a plugin](https://editorconfig.org/#download) for the config to be applied. @@ -184,7 +184,7 @@ Changesets **are** needed for new packages, as that is what triggers the package ### Writing changesets -Changesets are an important part of the development process. They are used to generate Changelog entries for all changes to the project. Ultimately they are read by the end users to learn about important changes and fixes to the project. Some of these fixes might require manual intervention from users so it's important to write changesets that users understand and can take action on. +Changesets are an important part of the development process. They are used to generate Changelog entries for all changes to the project. Ultimately, they are read by the end users to learn about important changes and fixes to the project. Some of these fixes might require manual intervention from users so it's important to write changesets that users understand and can take action on. Here are some important do's and don'ts when writing changesets: @@ -274,7 +274,7 @@ These changes are **required** to `packages/backend/src/plugins/catalog.ts` As with other CNCF projects, Backstage has adopted a [Developers Certificate of Origin (DCO)](https://developercertificate.org/). A DCO is a lightweight way for a developer to certify that they wrote or otherwise have the right to submit code or documentation to a project. -To certify the code you submit to the repository you'll need to add a `Signed-off-by` line to your commits. +To certify the code you submit to the repository, you'll need to add a `Signed-off-by` line to your commits. `$ git commit -s -m 'Awesome commit message'` @@ -330,9 +330,9 @@ There are two ways you can do this: 1. You can run `yarn build:api-reports` from the root of the project and it will go through all of the existing API Reports and update them or create new ones as needed. This may take a while but is generally the best method if you are new to this. 2. You can run `yarn build:api-reports plugins/` from the root and it will update the existing API Report or create a new one. -> Note: the above commands assume you've run `yarn install` before hand or recently +> Note: the above commands assume you've run `yarn install` beforehand or recently. -Each plugin/package has its own API Report which means you might see more then one file updated or created depending on your changes. These changes will then need to be committed as well. +Each plugin/package has its own API Report which means you might see more than one file updated or created depending on your changes. These changes will then need to be committed as well. ## Submitting a Pull Request @@ -374,7 +374,7 @@ Once you've submitted a Pull Request (PR) the various bots will come out and do - checking for commits for their DCO (Developer Certificate of Origin) - kick of the various CI builds -Once these have been completed it's just a matter of being patient as the reviewers have time they will begin to review your PR. When the review begins there may be a few layers to this but the general rule is that you need approval from one of the core maintainers and one from the specific area impacted by your PR. You may also have someone from the community review your changes, this can really help speed things up as they may catch some early items making the review for the maintainers simpler. Once you have the two (2) approvals it's ready to be merged, this task is also done by the maintainers. +Once these steps are completed, it's just a matter of being patient. As the reviewers have time, they will begin reviewing your PR. When the review process begins, there may be a few layers to this, but the general rule is that you need approval from one of the core maintainers and one from the specific area impacted by your PR. You may also have someone from the community review your changes. This can really help speed things up as they may catch some early items making the review for the maintainers simpler. Once you have the two (2) approvals, it's ready to be merged, a task that is also performed by the maintainers. ### Review Tips diff --git a/README.md b/README.md index 4cba1082b0..64a7b34b64 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,10 @@ To engage with our community, you can use the following resources: - [Backstage Community Sessions](https://github.com/backstage/community) - Join monthly meetups and explore Backstage community - Give us a star ⭐️ - If you are using Backstage or think it is an interesting project, we would love a star ❤️ +## Governance + +See the [GOVERNANCE.md](https://github.com/backstage/community/blob/main/GOVERNANCE.md) document in the [backstage/community](https://github.com/backstage/community) repository. + ## License Copyright 2020-2024 © The Backstage Authors. All rights reserved. The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation, please see our Trademark Usage page: https://www.linuxfoundation.org/trademark-usage diff --git a/REVIEWING.md b/REVIEWING.md index c443c15d77..66af880f43 100644 --- a/REVIEWING.md +++ b/REVIEWING.md @@ -68,7 +68,7 @@ In general our changeset feedback bot will take care of informing whether a chan Changes that do NOT need a new changeset: -- Changes to any test, storybook, or other local development files, for example, `MyComponent.test.tsx`, `MyComponent.stories.tsx`, `**mocks**/MyMock.ts`, `.eslintrc.js`, `setupTests.ts`, or `api-report.md`. Explained differently, it is only files that affect the published package that need changesets, such as source files and additional resources like `package.json`, `README.md`, `config.d.ts`, etc. +- Changes to any test, storybook, or other local development files, for example, `MyComponent.test.tsx`, `MyComponent.stories.tsx`, `**mocks**/MyMock.ts`, `.eslintrc.js`, `setupTests.ts`, or `report.api.md`. Explained differently, it is only files that affect the published package that need changesets, such as source files and additional resources like `package.json`, `README.md`, `config.d.ts`, etc. - When tweaking a change that has not yet been released, you can rely on and potentially modify the existing changeset instead. - Changes that do not belong to a published packages, either because it's not a package at all, such as `docs/`, or because the package is private, such as `packages/app`. - Changes that do not end up having an effect on the published package, such as whitespace fixes or code formatting changes. Although it's also fine to have a short changeset for these kind of changes too. @@ -168,7 +168,7 @@ In this section we will be talking about changed "types", but by that we mean an #### API Reports -We generate API Reports using the [API Extractor](https://api-extractor.com/) tool. These reports are generated for most packages in the Backstage repository, and are stored in the `api-report.md` file of each package. For CLI package we use custom tooling, and instead store the result in `cli-report.md`. Whenever the public API of a package changes, the API Report needs to be updated to reflect the new state of the API. Our CI checks will fail if the API reports are not up to date in a pull request. +We generate API Reports using the [API Extractor](https://api-extractor.com/) tool. These reports are generated for most packages in the Backstage repository, and are stored in the `report.api.md` file of each package. For CLI package we use custom tooling, and instead store the result in `cli-report.md`. Whenever the public API of a package changes, the API Report needs to be updated to reflect the new state of the API. Our CI checks will fail if the API reports are not up to date in a pull request. Each API report contains a list of all the exported types of each package. As long as the API report does not have any warnings it will contain the full publicly facing API of the package, meaning you do not need to consider any other changes to the package from the point of view of TypeScript API stability. diff --git a/beps/0001-notifications-system/README.md b/beps/0001-notifications-system/README.md index 541e75e555..91c1a81fe1 100644 --- a/beps/0001-notifications-system/README.md +++ b/beps/0001-notifications-system/README.md @@ -74,7 +74,7 @@ The `signal` plugin provides the following: ### Signals Plugin -In the backend the signal plugin implements a general purpose message bus for sending signals from backend plugins to connected users. It relies on the `EventBroker` from the [events plugin](https://github.com/backstage/backstage/blob/master/plugins/events-backend/README.md) for the actual message passing in the backend. In order to support scaled deployments, each signal backend instance has a separate subscription to the event broker so that each instance receives all events. It is then up to each backend instance to filter out events that are not relevant to it. For this reason, signals should be kept lightweight and not contain unnecessary data. +In the backend the signal plugin implements a general purpose message bus for sending signals from backend plugins to connected users. It relies on the `EventsService` from the [events plugin](https://github.com/backstage/backstage/blob/master/plugins/events-node/README.md) for the actual message passing in the backend. In order to support scaled deployments, each signal backend instance has a separate subscription to the events service so that each instance receives all events. It is then up to each backend instance to filter out events that are not relevant to it. For this reason, signals should be kept lightweight and not contain unnecessary data. In the frontend the signal plugin has a persistent connection to the signal backend. This is initially implemented as a WebSocket connection, but could in the future also receive fallback mechanisms such as Server Sent Events or long polling. It is important that this connection is authenticated as we will be routing signals to specific users. The exact implementation of the authentication is not part of this proposal, but it should use whatever the outcome of the discussion in issue [#19581](https://github.com/backstage/backstage/issues/19581) is. @@ -427,22 +427,22 @@ The notification and signal plugins are released as two new plugins in the Backs For the notification plugin to reach a stable release we much reach the following: -- A stable notifications payload format. -- A stable notifications recipient filter format. -- The event broker must have at least one implementation that supports scaled deployments. +- [ ] A stable notifications payload format. +- [ ] A stable notifications recipient filter format. +- [x] The events service must have at least one implementation that supports scaled deployments. Done in #24916. For the signal plugin to reach a stable release we much reach the following: -- A stable signal recipient filter format. -- A stable signal channel API in the frontend. +- [ ] A stable signal recipient filter format. +- [ ] A stable signal channel API in the frontend. If any changes are required to the frontend framework to facilitate the implementation of notifications or signals, these will be released as experimental alpha features. They will stay in alpha until they are deemed stable enough, which must happen before a stable release of the notifications system. ## Dependencies -Since the signal plugin relies on the event broker for communication, it is a dependency for the notifications system as a whole. The event broker does not currently implement any transport for scaled deployments, which is a requirement for scaled deployments of the notification system. +~Since the signal plugin relies on the events service for communication, it is a dependency for the notifications system as a whole. The events service does not currently implement any transport for scaled deployments, which is a requirement for scaled deployments of the notification system. -Alternatively the notifications can work without the signals, but in this case the notifications are updated only during page refresh. +Alternatively the notifications can work without the signals, but in this case the notifications are updated only during page refresh.~ ## Alternatives diff --git a/beps/0001-notifications-system/notifications-architecture.drawio.svg b/beps/0001-notifications-system/notifications-architecture.drawio.svg index 9f8194b499..9c6bb00119 100644 --- a/beps/0001-notifications-system/notifications-architecture.drawio.svg +++ b/beps/0001-notifications-system/notifications-architecture.drawio.svg @@ -1,4 +1,4 @@ - + @@ -133,13 +133,13 @@
- Event Broker + EventsService
- Event Broker + EventsService diff --git a/beps/0002-dynamic-frontend-plugins/README.md b/beps/0002-dynamic-frontend-plugins/README.md index db223c959d..1007732eec 100644 --- a/beps/0002-dynamic-frontend-plugins/README.md +++ b/beps/0002-dynamic-frontend-plugins/README.md @@ -595,7 +595,7 @@ Singleton "might have to" list: > NOTE: Can leverage [Generate module sharing map](#generate-module-sharing-map). -Component libraries are usually large (thousands of svg icons in @mui/icons) and it is inefficient to share them as a whole. **Tree shaking is disabled for shared modules**. That means sharing large packages in multiple versions will result in a bloated JS in browsers. +Component libraries are usually large (thousands of SVG icons in `@mui/icons`) and it is inefficient to share them as a whole. **Tree shaking is disabled for shared modules**. That means sharing large packages in multiple versions will result in a bloated JS in browsers. Sharing components like these can be done on module level. Instead of sharing the entire package, share its individual components: @@ -625,7 +625,7 @@ There is also a conflict with the chunk splitting currently used in the Backstag #### Webpack chunk optimization -Custom webpack chunk splitting configuration can be problematic, especially when modifying runtime and vendor chunks. Module federation creates its own chunks. Shared modules that are not set up to be eagerly loaded (using the `eager` configuration) **cannot be included inside the entry script**. With a custom chunk splitting setup, they can potentially be forced into the entry script, causing runtime errors. On the other hand, some critical runtime code that has to be in the entry script, cna be forced out of it. This is particularly problematic for the "shell" application. +Custom webpack chunk splitting configuration can be problematic, especially when modifying runtime and vendor chunks. Module federation creates its own chunks. Shared modules that are not set up to be eagerly loaded (using the `eager` configuration) **cannot be included inside the entry script**. With a custom chunk splitting setup, they can potentially be forced into the entry script, causing runtime errors. On the other hand, some critical runtime code that has to be in the entry script, can be forced out of it. This is particularly problematic for the "shell" application. Chunk optimization should be disabled for the initial implementation. diff --git a/docs/accessibility/index.md b/docs/accessibility/index.md index da10d60dd2..021c8309be 100644 --- a/docs/accessibility/index.md +++ b/docs/accessibility/index.md @@ -52,7 +52,7 @@ Running this command will use the [Lighthouse config](https://github.com/backsta ::: -### Use Lighthouse Github Action on your own repo +### Use Lighthouse GitHub Action on your own repo If your Backstage plugin lives outside of the [Backstage main repository](https://github.com/backstage/backstage/), and you use GitHub Actions for continuous integration, we encourage you to add and modify the [Accessibility GitHub workflow](https://github.com/backstage/backstage/blob/master/.github/workflows/verify_accessibility.yml) to your needs. diff --git a/docs/api/deprecations.md b/docs/api/deprecations.md index 664d7c327d..a9127426f0 100644 --- a/docs/api/deprecations.md +++ b/docs/api/deprecations.md @@ -26,7 +26,7 @@ opens up for other type of themes, and removes the hardcoded usage of To migrate an existing theme, remove the `theme` property and move it over to a new `Provider` component, using `ThemeProvider` from Material UI to provide the new -theme, along with ``. For example a theme that currently looks like +theme, along with ``. For example, a theme that currently looks like this: ```tsx @@ -84,8 +84,8 @@ migrate to your own custom API. First, you'll need to define a new Utility API reference. If you're only using the API for sign-in, you can put the definition in `packages/app/src/apis.ts`. However, if you need to access your auth API inside plugins you you'll need to -export it from a common package. If you don't already have one we recommended -creating `@internal/apis` and from there export the API reference. +export it from a common package. If you don't already have one, we recommend +creating `@internal/apis` and from there exporting the API reference. ```ts // `ProfileInfoApi & BackstageIdentityApi & SessionApi` are required for sign-in @@ -101,7 +101,7 @@ export const acmeAuthApiRef: ApiRef< }); ``` -Next you'll want to wire up the API inside `packages/app/src/apis.ts`, which +Next, you'll want to wire up the API inside `packages/app/src/apis.ts`, which varies depending on which API you're replacing. If you for example are replacing the `oauth2ApiRef`, the factory might look like this: diff --git a/docs/api/utility-apis.md b/docs/api/utility-apis.md index 5df8fc334a..06183f1fc0 100644 --- a/docs/api/utility-apis.md +++ b/docs/api/utility-apis.md @@ -166,10 +166,10 @@ the final say in what APIs will be loaded at runtime? The app may override the factories for any of the core or plugin APIs, with the exception of the config, app theme, and identity APIs. These are static APIs that are tied into the [`createApp`](../reference/app-defaults.createapp.md) implementation and -therefore not possible to override. +therefore, not possible to override. Overriding APIs is useful for apps that want to switch out behavior to tailor it -to their environment. In some cases plugins, may also export multiple +to their environment. In some cases, plugins may also export multiple implementations of the same API, where they each have their own different requirements, for example, backend storage and the surrounding environment. diff --git a/docs/architecture-decisions/index.md b/docs/architecture-decisions/index.md index 615d737fe1..3432264453 100644 --- a/docs/architecture-decisions/index.md +++ b/docs/architecture-decisions/index.md @@ -27,7 +27,7 @@ Records should be stored under the `architecture-decisions` directory. - Address and integrate feedback from the community - Eventually, assign a number - Add the path of the ADR to the microsite sidebar in - [`sidebars.json`](https://github.com/backstage/backstage/blob/master/microsite/sidebars.json) + [`sidebars.js`](https://github.com/backstage/backstage/blob/master/microsite/sidebars.js) - Add the path of the ADR to the [`mkdocs.yml`](https://github.com/backstage/backstage/blob/master/mkdocs.yml) - Merge the pull request diff --git a/docs/auth/add-auth-provider.md b/docs/auth/add-auth-provider.md index 8ea8a4ffc0..51424f1c10 100644 --- a/docs/auth/add-auth-provider.md +++ b/docs/auth/add-auth-provider.md @@ -244,7 +244,7 @@ export const providerAuthenticator = createOAuthAuthenticator({ Here are some examples of authenticators that are already implemented in the codebase: - [Google](https://github.com/backstage/backstage/blob/master/plugins/auth-backend-module-google-provider/src/authenticator.ts) -- [Github](https://github.com/backstage/backstage/blob/master/plugins/auth-backend-module-github-provider/src/authenticator.ts) +- [GitHub](https://github.com/backstage/backstage/blob/master/plugins/auth-backend-module-github-provider/src/authenticator.ts) - [Okta](https://github.com/backstage/backstage/blob/master/plugins/auth-backend-module-okta-provider/src/authenticator.ts) ### Creating proxy auth based provider diff --git a/docs/auth/auth0/provider--old.md b/docs/auth/auth0/provider--old.md new file mode 100644 index 0000000000..a089236aca --- /dev/null +++ b/docs/auth/auth0/provider--old.md @@ -0,0 +1,75 @@ +--- +id: provider--old +title: Auth0 Authentication Provider +sidebar_label: Auth0 +description: Adding Auth0 as an authentication provider in Backstage +--- + +:::info +This documentation is written for the old backend which has been replaced by +[the new backend system](../../backend-system/index.md), being the default since +Backstage [version 1.24](../../releases/v1.24.0.md). If have migrated to the new +backend system, you may want to read [its own article](./provider.md) +instead. Otherwise, [consider migrating](../../backend-system/building-backends/08-migrating.md)! +::: + +The Backstage `core-plugin-api` package comes with an Auth0 authentication +provider that can authenticate users using OAuth. + +## Create an Auth0 Application + +1. Log in to the [Auth0 dashboard](https://manage.auth0.com/dashboard/) +2. Navigate to **Applications** +3. Create an Application + - Name: Backstage (or your custom app name) + - Application type: Single Page Web Application +4. Click on the Settings tab +5. Add under `Application URIs` > `Allowed Callback URLs`: + `http://localhost:7007/api/auth/auth0/handler/frame` +6. Click `Save Changes` + +## Configuration + +The provider configuration can then be added to your `app-config.yaml` under the +root `auth` configuration: + +```yaml +auth: + environment: development + providers: + auth0: + development: + clientId: ${AUTH_AUTH0_CLIENT_ID} + clientSecret: ${AUTH_AUTH0_CLIENT_SECRET} + domain: ${AUTH_AUTH0_DOMAIN_ID} + audience: ${AUTH_AUTH0_AUDIENCE} + connection: ${AUTH_AUTH0_CONNECTION} + connectionScope: ${AUTH_AUTH0_CONNECTION_SCOPE} + session: + secret: ${AUTH_SESSION_SECRET} +``` + +The Auth0 provider is a structure with these configuration keys: + +- `clientId`: The Application client ID, found on the Auth0 Application page +- `clientSecret`: The Application client secret, found on the Auth0 Application + page +- `domain`: The Application domain, found on the Auth0 Application page + +It additionally relies on the following configuration to function: + +- `session.secret`: The session secret is a key used for signing and/or encrypting cookies set by the application to maintain session state. In this case, 'your session secret' should be replaced with a long, complex, and unique string that only your application knows. + +Auth0 requires a session, so you need to give the session a secret key. + +## Optional Configuration + +- `audience`: The intended recipients of the token +- `connection`: Social identity provider name. To check the available social connections, please visit [Auth0 Social Connections](https://marketplace.auth0.com/features/social-connections). +- `connectionScope`: Additional scopes in the interactive token request. It should always be used in combination with the `connection` parameter + +## Adding the provider to the Backstage frontend + +To add the provider to the frontend, add the `auth0AuthApi` reference and +`SignInPage` component as shown in +[Adding the provider to the sign-in page](../index.md#sign-in-configuration). diff --git a/docs/auth/auth0/provider.md b/docs/auth/auth0/provider.md index ae44114906..bc2a02fe1f 100644 --- a/docs/auth/auth0/provider.md +++ b/docs/auth/auth0/provider.md @@ -5,6 +5,13 @@ sidebar_label: Auth0 description: Adding Auth0 as an authentication provider in Backstage --- +:::info +This documentation is written for [the new backend system](../../backend-system/index.md) which is the default since Backstage +[version 1.24](../../releases/v1.24.0.md). If you are still on the old backend +system, you may want to read [its own article](./provider--old.md) +instead, and [consider migrating](../../backend-system/building-backends/08-migrating.md)! +::: + The Backstage `core-plugin-api` package comes with an Auth0 authentication provider that can authenticate users using OAuth. @@ -54,12 +61,46 @@ It additionally relies on the following configuration to function: Auth0 requires a session, so you need to give the session a secret key. -## Optional Configuration +### Optional - `audience`: The intended recipients of the token - `connection`: Social identity provider name. To check the available social connections, please visit [Auth0 Social Connections](https://marketplace.auth0.com/features/social-connections). - `connectionScope`: Additional scopes in the interactive token request. It should always be used in combination with the `connection` parameter +### Resolvers + +This provider includes several resolvers out of the box that you can use: + +- `emailMatchingUserEntityProfileEmail`: Matches the email address from the auth provider with the User entity that has a matching `spec.profile.email`. If no match is found it will throw a `NotFoundError`. +- `emailLocalPartMatchingUserEntityName`: Matches the [local part](https://en.wikipedia.org/wiki/Email_address#Local-part) of the email address from the auth provider with the User entity that has a matching `name`. If no match is found it will throw a `NotFoundError`. + +:::note Note + +The resolvers will be tried in order, but will only be skipped if they throw a `NotFoundError`. + +::: + +If these resolvers do not fit your needs you can build a custom resolver, this is covered in the [Building Custom Resolvers](../identity-resolver.md#building-custom-resolvers) section of the Sign-in Identities and Resolvers documentation. + +## Backend Installation + +To add the provider to the backend we will first need to install the package by running this command: + +```bash title="from your Backstage root directory" +yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-auth0-provider +``` + +Then we will need to add this line: + +```ts title="packages/backend/src/index.ts" +import { createBackend } from '@backstage/backend-defaults'; +//... +backend.add(import('@backstage/plugin-auth-backend')); +// highlight-add-next-line +backend.add(import('@backstage/plugin-auth-backend-module-auth0-provider')); +//... +``` + ## Adding the provider to the Backstage frontend To add the provider to the frontend, add the `auth0AuthApi` reference and diff --git a/docs/auth/bitbucketServer/provider--old.md b/docs/auth/bitbucketServer/provider--old.md new file mode 100644 index 0000000000..fdd8fa35be --- /dev/null +++ b/docs/auth/bitbucketServer/provider--old.md @@ -0,0 +1,60 @@ +--- +id: provider--od +title: Bitbucket Server Authentication Provider +sidebar_label: Bitbucket Server +description: Adding Bitbucket Server OAuth as an authentication provider in Backstage +--- + +:::info +This documentation is written for the old backend which has been replaced by +[the new backend system](../../backend-system/index.md), being the default since +Backstage [version 1.24](../../releases/v1.24.0.md). If have migrated to the new +backend system, you may want to read [its own article](./provider.md) +instead. Otherwise, [consider migrating](../../backend-system/building-backends/08-migrating.md)! +::: + +The Backstage `core-plugin-api` package comes with a Bitbucket Server authentication provider that can authenticate +users using Bitbucket Server. This does **NOT** work with Bitbucket Cloud. + +## Create an Application Link in Bitbucket Server + +To add Bitbucket Server authentication, you must create an incoming application link. Follow the steps described in +the [Bitbucket Server documentation](https://confluence.atlassian.com/bitbucketserver/configure-an-incoming-link-1108483657.html) +to create one. + +## Configuration + +The provider configuration can then be added to your `app-config.yaml` under the root `auth` configuration: + +```yaml +auth: + environment: development + providers: + bitbucketServer: + development: + host: bitbucket.org + clientId: ${AUTH_BITBUCKET_SERVER_CLIENT_ID} + clientSecret: ${AUTH_BITBUCKET_SERVER_CLIENT_SECRET} +``` + +The Bitbucket Server provider is a structure with two configuration keys: + +- `clientId`: The client ID that was generated by Bitbucket, e.g. `b0f868455c15dcdff5c5fb5d173ae684`. +- `clientSecret`: The client secret tied to the generated client ID. + +## Adding the provider to the Backstage frontend + +To add the provider to the frontend, add the `bitbucketServerAuthApi` reference and `SignInPage` component as shown +in [Adding the provider to the sign-in page](../index.md#sign-in-configuration). + +## Using Bitbucket Server for sign-in + +In order to use the Bitbucket Server provider for sign-in, you must configure it with a `signIn.resolver`. See +the [Sign-In Resolver documentation](../identity-resolver.md) for more details on how this is done. Note that for the +Bitbucket Server provider, you'll want to use `bitbucketServer` as the provider ID, +and `providers.bitbucketServer.create` for the provider factory. + +The `@backstage/plugin-auth-backend` plugin also comes with a built-in resolver that can be used if desired. +The `emailMatchingUserEntityProfileEmail` identifies users by matching their Bitbucket Server email address to the email +address of `User` entities in the catalog. Note that you must populate your catalog with matching entities or users will +not be able to sign in with this resolver. diff --git a/docs/auth/bitbucketServer/provider.md b/docs/auth/bitbucketServer/provider.md index 82aebc20b2..c41457d09c 100644 --- a/docs/auth/bitbucketServer/provider.md +++ b/docs/auth/bitbucketServer/provider.md @@ -5,6 +5,13 @@ sidebar_label: Bitbucket Server description: Adding Bitbucket Server OAuth as an authentication provider in Backstage --- +:::info +This documentation is written for [the new backend system](../../backend-system/index.md) which is the default since Backstage +[version 1.24](../../releases/v1.24.0.md). If you are still on the old backend +system, you may want to read [its own article](./provider--old.md) +instead, and [consider migrating](../../backend-system/building-backends/08-migrating.md)! +::: + The Backstage `core-plugin-api` package comes with a Bitbucket Server authentication provider that can authenticate users using Bitbucket Server. This does **NOT** work with Bitbucket Cloud. @@ -24,7 +31,7 @@ auth: providers: bitbucketServer: development: - host: bitbucket.org + host: bitbucket.example.org clientId: ${AUTH_BITBUCKET_SERVER_CLIENT_ID} clientSecret: ${AUTH_BITBUCKET_SERVER_CLIENT_SECRET} ``` @@ -34,19 +41,50 @@ The Bitbucket Server provider is a structure with two configuration keys: - `clientId`: The client ID that was generated by Bitbucket, e.g. `b0f868455c15dcdff5c5fb5d173ae684`. - `clientSecret`: The client secret tied to the generated client ID. -## Adding the provider to the Backstage frontend +### Resolvers -To add the provider to the frontend, add the `bitbucketServerAuthApi` reference and `SignInPage` component as shown -in [Adding the provider to the sign-in page](../index.md#sign-in-configuration). +This provider includes several resolvers out of the box that you can use: -## Using Bitbucket Server for sign-in +- `emailMatchingUserEntityProfileEmail`: Matches the email address from the auth provider with the User entity that has a matching `spec.profile.email`. If no match is found it will throw a `NotFoundError`. +- `emailLocalPartMatchingUserEntityName`: Matches the [local part](https://en.wikipedia.org/wiki/Email_address#Local-part) of the email address from the auth provider with the User entity that has a matching `name`. If no match is found it will throw a `NotFoundError`. -In order to use the Bitbucket Server provider for sign-in, you must configure it with a `signIn.resolver`. See -the [Sign-In Resolver documentation](../identity-resolver.md) for more details on how this is done. Note that for the -Bitbucket Server provider, you'll want to use `bitbucketServer` as the provider ID, -and `providers.bitbucketServer.create` for the provider factory. +:::note Note -The `@backstage/plugin-auth-backend` plugin also comes with a built-in resolver that can be used if desired. -The `emailMatchingUserEntityProfileEmail` identifies users by matching their Bitbucket Server email address to the email -address of `User` entities in the catalog. Note that you must populate your catalog with matching entities or users will -not be able to sign in with this resolver. +The resolvers will be tried in order, but will only be skipped if they throw a `NotFoundError`. + +::: + +If these resolvers do not fit your needs you can build a custom resolver, this is covered in the [Building Custom Resolvers](../identity-resolver.md#building-custom-resolvers) section of the Sign-in Identities and Resolvers documentation. + +## Backend Installation + +To add the provider to the backend we will first need to install the package by running this command: + +```bash title="from your Backstage root directory" +yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-bitbucket-server-provider +``` + +Then we will need to add this line: + +```ts title="packages/backend/src/index.ts" +//... +backend.add(import('@backstage/plugin-auth-backend')); +// highlight-add-start +backend.add( + import('@backstage/plugin-auth-backend-module-bitbucket-server-provider'), +); +// highlight-add-end +//... +``` + +## Frontend Configuration + +### Sign-in + +To add the provider to the frontend, add the `bitbucketServerAuthApiRef` reference and +`SignInPage` component as shown in +[Adding the provider to the sign-in page](../index.md#sign-in-configuration). + +### ScmAuth + +For backstage to be able to use the oauth token of the logged in user to access the Bitbucket Server API, you need to add it to list of ScmAuth providers as shown in [Custom ScmAuthApi Implementation](../index.md#custom-scmauthapi-implementation) using the `ScmAuth.forBitbucketServer` method. diff --git a/docs/auth/gitlab/provider.md b/docs/auth/gitlab/provider.md index 73546411bf..4f5339f5b9 100644 --- a/docs/auth/gitlab/provider.md +++ b/docs/auth/gitlab/provider.md @@ -19,6 +19,7 @@ should point to your Backstage backend auth handler. 1. Set this to `http://localhost:7007/api/auth/gitlab/handler/frame` for local development. 2. Set this to `http://{APP_FQDN}:{APP_BACKEND_PORT}/api/auth/gitlab/handler/frame` for non-local deployments. 3. Select the following scopes from the list: + - [x] `api` Grants full read-write access to the api. This is only required if users need to be able to create merge requests with their own permissions. - [x] `read_user` Grants read-only access to the authenticated user's profile through the /user API endpoint, which includes username, public email, and full name. Also grants access to read-only API endpoints under /users. - [x] `read_repository` Grants read-only access to repositories on private projects using Git-over-HTTP (not using the API). - [x] `write_repository` Grants read-write access to repositories on private projects using Git-over-HTTP (not using the API). diff --git a/docs/auth/identity-resolver.md b/docs/auth/identity-resolver.md index dbebf3056c..d6b377d990 100644 --- a/docs/auth/identity-resolver.md +++ b/docs/auth/identity-resolver.md @@ -142,8 +142,28 @@ backend.add(import('@backstage/plugin-auth-backend-module-github-provider')); When you want to supply a custom sign-in resolver, as a general pattern you remove that last import and instead construct your own provider using the -facilities from the same package. You can leave the config unchanged from -before. +facilities from the same package. + +Make sure that your `auth` config in your `app-config.yaml` does not contain +any `resolvers` field - otherwise, they take priority. + +```yaml title="in e.g. app-config.yaml" +auth: + environment: development + providers: + github: + development: + clientId: ${AUTH_GITHUB_CLIENT_ID} + clientSecret: ${AUTH_GITHUB_CLIENT_SECRET} + enterpriseInstanceUrl: ${AUTH_GITHUB_ENTERPRISE_INSTANCE_URL} +/* highlight-remove-start */ + signIn: + resolvers: + - resolver: usernameMatchingUserEntityName + - resolver: emailMatchingUserEntityProfileEmail + - resolver: emailLocalPartMatchingUserEntityName +/* highlight-remove-end */ +``` ```ts title="in packages/backend/src/index.ts" /* highlight-add-start */ diff --git a/docs/auth/index.md b/docs/auth/index.md index de579d039a..2384943c52 100644 --- a/docs/auth/index.md +++ b/docs/auth/index.md @@ -36,8 +36,7 @@ Backstage comes with many common authentication providers in the core library: - [OneLogin](onelogin/provider.md) - [VMware Cloud](vmware-cloud/provider.md) -These built-in providers handle the authentication flow for a particular service -including required scopes, callbacks, etc. These providers are each added to a +These built-in providers handle the authentication flow for a particular service, including required scopes, callbacks, etc. These providers are each added to a Backstage app in a similar way. ## Configuring Authentication Providers @@ -58,7 +57,7 @@ auth: See the documentation for a particular provider to see what configuration is needed. -The `providers` key may have several authentication providers, if multiple +The `providers` key may have several authentication providers if multiple authentication methods are supported. Each provider may also have configuration for different authentication environments (development, production, etc). This allows a single auth backend to serve multiple environments, such as running a @@ -68,15 +67,14 @@ the local `auth.environment` setting will be selected. ## Sign-In Configuration Using an authentication provider for sign-in is something you need to configure -both in the frontend app, as well as the `auth` backend plugin. For information +both in the frontend app as well as the `auth` backend plugin. For information on how to configure the backend app, see [Sign-in Identities and Resolvers](./identity-resolver.md). The rest of this section will focus on how to configure sign-in for the frontend app. Sign-in is configured by providing a custom `SignInPage` app component. It will be rendered before any other routes in the app and is responsible for providing the identity of the current user. The `SignInPage` can render any number of pages and -components, or just blank space with logic running in the background. In the end -however it must provide a valid Backstage user identity through the `onSignInSuccess` +components, or just blank space with logic running in the background. In the end, however, it must provide a valid Backstage user identity through the `onSignInSuccess` callback prop, at which point the rest of the app is rendered. If you want to, you can use the `SignInPage` component that is provided by `@backstage/core-components`, @@ -149,7 +147,7 @@ const app = createApp({ ### Conditionally Render Sign In Provider -In the above example you have both Guest and GitHub sign-in options, this is helpful for non-production but in Production you will most likely not want to offer Guest access. You can easily use information from your config to help conditionally render the provider: +In the above example, you have both Guest and GitHub sign-in options; this is helpful for non-production, but in Production you will most likely not want to offer Guest access. You can easily use information from your config to help conditionally render the provider: ```tsx title="packages/app/src/App.tsx" import { @@ -207,7 +205,7 @@ and [OAuth2 Proxy](./oauth2-proxy/provider.md). When using a proxy provider, you'll end up wanting to use a different sign-in page, as there is no need for further user interaction once you've signed in towards the proxy. -All the sign-in page needs to do is to call the `/refresh` endpoint of the auth providers +All the sign-in page needs to do is call the `/refresh` endpoint of the auth providers to get the existing session, which is exactly what the `ProxiedSignInPage` does. The only thing you need to do to configure the `ProxiedSignInPage` is to pass the ID of the provider like this: @@ -250,7 +248,7 @@ Headers can also be returned in an async manner: A downside of this method is that it can be cumbersome to set up for local development. As a workaround for this, it's possible to dynamically select the sign-in page based on -what environment the app is running in, and then use a different sign-in method for local +what environment the app is running in and then use a different sign-in method for local development, if one is needed at all. Depending on the exact setup, one might choose to select the sign-in method based on the `process.env.NODE_ENV` environment variable, by checking the `hostname` of the current location, or by accessing the configuration API @@ -286,7 +284,7 @@ sign-in resolvers so that they resolve to the same identity regardless of the me ## Scaffolder Configuration (Software Templates) -If you want to use the authentication capabilities of the [Repository Picker](../features/software-templates/writing-templates.md#the-repository-picker) inside your software templates you will need to configure the [`ScmAuthApi`](https://backstage.io/docs/reference/integration-react.scmauthapi) alongside your authentication provider. It is an API used to authenticate towards different SCM systems in a generic way, based on what resource is being accessed. +If you want to use the authentication capabilities of the [Repository Picker](../features/software-templates/writing-templates.md#the-repository-picker) inside your software templates, you will need to configure the [`ScmAuthApi`](https://backstage.io/docs/reference/integration-react.scmauthapi) alongside your authentication provider. It is an API used to authenticate towards different SCM systems in a generic way, based on what resource is being accessed. To set it up, you'll need to add an API factory entry to `packages/app/src/apis.ts`. The example below sets up the `ScmAuthApi` for an already configured GitLab authentication provider: @@ -305,7 +303,7 @@ In case you are using a custom authentication providers, you might need to add a ## For Plugin Developers The Backstage frontend core APIs provide a set of Utility APIs for plugin developers -to use, both to access the user identity, as well as third party resources. +to use, both to access the user identity as well as third-party resources. ### Identity for Plugin Developers @@ -323,21 +321,21 @@ to interact directly with the `IdentityApi`. ### Accessing Third Party Resources -A common pattern for talking to third party services in Backstage is +A common pattern for talking to third-party services in Backstage is user-to-server requests, where short-lived OAuth Access Tokens are requested by plugins to authenticate calls to external services. These calls can be made either directly to the services or through a backend plugin or service. -By relying on user-to-server calls we keep the coupling between the frontend and -backend low, and provide a much lower barrier for plugins to make use of third -party services. This is in comparison to for example a session-based system, +By relying on user-to-server calls, we keep the coupling between the frontend and +backend low and provide a much lower barrier for plugins to make use of third +party services. This is in comparison to, for example, a session-based system where access tokens are stored server-side. Such a solution would require a much deeper coupling between the auth backend plugin, its session storage, and other backend plugins or separate services. A goal of Backstage is to make it as easy as possible to create new plugins, and an auth solution based on user-to-server OAuth helps in that regard. -The method with which frontend plugins request access to third party services is +The method with which frontend plugins request access to third-party services is through [Utility APIs](../api/utility-apis.md) for each service provider. These are all suffixed with `*AuthApiRef`, for example `githubAuthApiRef`. For a full list of providers, see the diff --git a/docs/auth/microsoft/provider.md b/docs/auth/microsoft/provider.md index 60104b99b7..f20e17ea6c 100644 --- a/docs/auth/microsoft/provider.md +++ b/docs/auth/microsoft/provider.md @@ -73,6 +73,7 @@ auth: - resolver: emailMatchingUserEntityProfileEmail - resolver: emailLocalPartMatchingUserEntityName - resolver: emailMatchingUserEntityAnnotation + - resolver: userIdMatchingUserEntityAnnotation ``` The Microsoft provider is a structure with three mandatory configuration keys: @@ -85,6 +86,7 @@ The Microsoft provider is a structure with three mandatory configuration keys: 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, to be requested in addition to the required ones. +- `skipUserProfile` (optional): If true, skips loading the user profile even if the `User.Read` scope is present. This is a performance optimization during login and can be used with resolvers that only needs the email address in `spec.profile.email` obtained when the `email` OAuth2 scope is present. ### Resolvers @@ -93,6 +95,7 @@ This provider includes several resolvers out of the box that you can use: - `emailMatchingUserEntityProfileEmail`: Matches the email address from the auth provider with the User entity that has a matching `spec.profile.email`. If no match is found it will throw a `NotFoundError`. - `emailLocalPartMatchingUserEntityName`: Matches the [local part](https://en.wikipedia.org/wiki/Email_address#Local-part) of the email address from the auth provider with the User entity that has a matching `name`. If no match is found it will throw a `NotFoundError`. - `emailMatchingUserEntityAnnotation`: Matches the email address from the auth provider with the User entity where the value of the `microsoft.com/email` annotation matches. If no match is found it will throw a `NotFoundError`. +- `userIdMatchingUserEntityAnnotation`: Matches the user profile ID from the auth provider with the User entity where the value of the `graph.microsoft.com/user-id` annotation matches. This resolver is recommended to resolve users without an email in their profile. If no match is found it will throw a `NotFoundError`. :::note Note diff --git a/docs/auth/oauth2-proxy/provider.md b/docs/auth/oauth2-proxy/provider.md index 0901685b2f..84e2b307e6 100644 --- a/docs/auth/oauth2-proxy/provider.md +++ b/docs/auth/oauth2-proxy/provider.md @@ -13,6 +13,12 @@ a cluster. In general the `oauth2-proxy` supports all OpenID Connect providers, for more details check this [list of supported providers](https://oauth2-proxy.github.io/oauth2-proxy/docs/configuration/oauth_provider). +:::note Note + +OAuth2 Proxy does not provide a way to authenticate requests, you must instead ensure that your Backstage instance is only accessible through the OAuth2 Proxy. If you need more strict validation, consider using a different provider. + +::: + ## Configuration The provider configuration can be added to your `app-config.yaml` under the root diff --git a/docs/auth/oidc--old.md b/docs/auth/oidc--old.md new file mode 100644 index 0000000000..904e48c9a3 --- /dev/null +++ b/docs/auth/oidc--old.md @@ -0,0 +1,289 @@ +--- +id: oidc--old +title: OIDC provider from scratch +description: This section shows how to use an OIDC provider from scratch, same steps apply for custom providers. +--- + +:::info +This documentation is written for the old backend which has been replaced by +[the new backend system](../backend-system/index.md), being the default since +Backstage [version 1.24](../releases/v1.24.0.md). If have migrated to the new +backend system, you may want to read [its own article](./oidc.md) +instead. Otherwise, [consider migrating](../backend-system/building-backends/08-migrating.md)! +::: + +This section shows how to use an OIDC provider from scratch, same steps apply for custom +providers. Please note these steps are for using a provider, not how to implement one, +and Backstage recommends creating custom providers specific to the IDP, so we'll use a +`azureOIDC` provider throughout this example, feel free to change any of those refs +to your provider name. + +## Summary + +To add providers not enabled by default like OIDC, we need to follow some steps, we +assume you already have a sign in page to which we'll add the provider so users can +sign in through the provider. In simple steps here's how you enable the provider: + +- Create an API reference to identify the provider. +- Create the API factory that will handle the authentication. +- Add or reuse an auth provider so you can authenticate. +- Add or reuse a resolver to handle the result from the authentication. +- Configure the provider to access your 3rd party auth solution. +- Add the provider to sign in page so users can login with it. + +We'll explain each step more in detail next. + +### The API reference + +An API reference exist for the sake of **Dependency Injection**, check [Utility APIs][4] +for extended explanation. + +In this OIDC example, we'll create the API reference directly in the +`packages/app/src/apis.ts` file, it is not a requirement to put the reference in this +file. Any location will do as long as it's available to be imported to where the API +factory is, as well as easily accessible to the rest of the application so any package +and plugin can inject the API instance when necessary. + +An example of such would be when you use an auth provider from a library installed with +NPM, or any other library repository, you would import the API ref from the library. + +```ts +export const azureOIDCAuthApiRef: ApiRef< + OpenIdConnectApi & ProfileInfoApi & BackstageIdentityApi & SessionApi +> = createApiRef({ + id: 'auth.my-custom-provider', +}); +``` + +Please note a few things, the ID can be anything you want as long as it doesn't conflict +with other refs, backstage recommends to use a custom name that references your custom +provider, for example we are using OIDC protocol with Azure, so we could use something +like `auth.azure.oidc` as well. + +Also we're exporting this reference, as well as the `typings`, we need to +be able to import this reference anywhere in the app, and the `typings` will tell typescript +what instance we're getting from DI when injecting the API. In this case we are defining +an API for authentication, so we tell TS that this instance complies with 4 API +interfaces: + +- The OICD API that will handle authentication. +- Profile API for requesting user profile info from the auth provider in question. +- Backstage identity API to handle and associate the user profile with backstage identity. +- Session API, to handle the session the user will have while logged in. + +### The API Factory + +A factory is a function that can take some parameters or dependencies and return an +instance of something, in our case it will be a function that requests some backstage +APIs and use them to create an instance of an OIDC API provider. + +Please note that this function only runs (creates the instance) when somewhere else in +the app you request the DI to give you an instance of the OIDC provider using the API ref +defined above, and the DI will only run this function the first time, from then on any +other DI injection will just receive the same instance created the first time, basically +the instance is cached by the DI library, a singleton. + +Let's add our OIDC API factory to the APIs array in the `packages/app/src/apis.ts` file: + +```ts title="packages/app/src/apis.ts" +/* highlight-add-next-line */ +import { OAuth2 } from '@backstage/core-app-api'; + +export const apis: AnyApiFactory[] = [ + /* highlight-add-start */ + createApiFactory({ + api: azureOIDCAuthApiRef, + deps: { + discoveryApi: discoveryApiRef, + oauthRequestApi: oauthRequestApiRef, + configApi: configApiRef, + }, + factory: ({ discoveryApi, oauthRequestApi, configApi }) => + OAuth2.create({ + configApi, + discoveryApi, + oauthRequestApi, + provider: { + id: 'my-auth-provider', + title: 'My custom auth provider', + icon: () => null, + }, + environment: configApi.getOptionalString('auth.environment'), + defaultScopes: ['openid', 'profile', 'email'], + popupOptions: { + // optional, used to customize login in popup size + size: { + fullscreen: true, + }, + /** + * or specify popup width and height + * size: { + width: 1000, + height: 1000, + } + */ + }, + }), + }), + /* highlight-add-end */ + // .. +]; +``` + +Please note we're importing the `OAuth2` class from `@backstage/core-app-api` effectively +delegating the authentication to it. Also we're using the `my-auth-provider` ID to tell +`OAuth2` to use the auth provider we'll define in the next section, and added the default +scopes to request ID, profile, email and user read permissions. + +## The Auth Provider + +The Auth Provider is responsible for authenticating with the 3rd party service, and give +us back the credentials, here's where you pick which protocol to use, be it Auth0, OAuth2, +OIDC, SAML or any other that your 3rd party IDP provider supports. + +For this example we'll use OIDC, we pass a factory to the `providerFactories` object with +the ID you picked to represent the Auth provider, this ID has to match with the provider's +`id` inside the API factory, the yaml config provider key under `auth.providers`, and the +callback URI provider segment (you'll have to configure your IDP to handle the callback +URI properly). + +```ts +export default async function createPlugin( + env: PluginEnvironment, +): Promise { + return await createRouter({ + logger: env.logger, + config: env.config, + database: env.database, + discovery: env.discovery, + tokenManager: env.tokenManager, + providerFactories: { + ...defaultAuthProviderFactories, + /* highlight-add-next-line */ + 'my-auth-provider': providers.oidc.create({}), + }, + // .. +}) +``` + +### The Resolver + +Resolvers exist to map user identity from the 3rd party (in this case an azure IDP +provider) to the backstage user identity, for a detailed explanation check the +[Identity Resolver][1] page, it explains how to write a custom resolver as well as +linking the built in resolvers of backstage. + +The default OIDC provider does not support SignIn, we need to add such support by +adding a resolver for a SignIn request. + +The OIDC provider doesn't provide any build-in resolvers, so we'll need to define our own: + +```ts +import { + DEFAULT_NAMESPACE, + /* highlight-add-next-line */ + stringifyEntityRef, +} from '@backstage/catalog-model'; + +export default async function createPlugin( + env: PluginEnvironment, +): Promise { + return await createRouter({ + logger: env.logger, + config: env.config, + database: env.database, + discovery: env.discovery, + tokenManager: env.tokenManager, + providerFactories: { + ...defaultAuthProviderFactories, + 'my-auth-provider': providers.oidc.create({ + /* highlight-add-start */ + signIn: { + resolver(info, ctx) { + const userRef = stringifyEntityRef({ + kind: 'User', + name: info.result.userinfo.sub, + namespace: DEFAULT_NAMESPACE, + }); + return ctx.issueToken({ + claims: { + sub: userRef, // The user's own identity + ent: [userRef], // A list of identities that the user claims ownership through + }, + }); + }, + }, + /* highlight-add-end */ + }), + }, + // .. + }) +``` + +### The configuration + +Since we are using our custom OIDC Auth Provider, we need to add a configuration based +on the provider used, in this case based on OIDC protocol (remember the 3rd party has to +support the protocol). + +In this example we'll configure OIDC with `my-auth-provider`, to do so we need to +[Create app registration][2] in the Azure console, the only difference is that the +`http://localhost:7007/api/auth/microsoft/handler/frame` URL needs to change to +`http://localhost:7007/api/auth/my-auth-provider/handler/frame`. + +Then we need to configure the env variables for the provider, based on the provider's code +in `plugins/auth-backend/src/providers/oidc/provider.ts` we need the following variables +in the `app-config.yaml`: + +```yaml title="app-config.yaml" +auth: + environment: development + ### Providing an auth.session.secret will enable session support in the auth-backend + session: + secret: ${SESSION_SECRET} + providers: + my-auth-provider: + development: + metadataUrl: https://example.com/.well-known/openid-configuration + clientId: ${AUTH_MY_CLIENT_ID} + clientSecret: ${AUTH_MY_CLIENT_SECRET} +``` + +Anything enclosed in `${}` can be replaced directly in the yaml, or provided as +environment variables, the way you obtain all these except `scope` and `prompt` is to +check the App Registration you created: + +- `clientId`: Grab from the Overview page. +- `clientSecret`: Can only be seen when creating the secret, if you lose it you'll need a + new secret. +- `metadataUrl`: In Overview > Endpoints tab, grab OpenID Connect metadata document URL. +- `authorizationUrl` and `tokenUrl`: Open the `metadataUrl` in a browser, that json will + hold these 2 urls somewhere in there. +- `tokenEndpointAuthMethod`: Don't define it, use the default unless you know what it does. +- `tokenSignedResponseAlg`: Don't define it, use the default unless you know what it does. +- `scope`: Only used if we didn't specify `defaultScopes` in the provider's factory, + basically the same thing. +- `prompt`: Recommended to use `auto` so the browser will request login to the IDP if the + user has no active session. + +Note that for the time being, any change in this yaml file requires a restart of the app, +also you need to have the `session.secret` part to use OIDC (some other providers might +need this as well) to support user sessions. + +### The Sign In provider + +The last step is to add the provider to the `SignInPage` so users can sign in with your +new provider, please follow the [Sign In Configuration][3] docs, here's where you import +and use the API reference we defined earlier. + +## Note + +These steps apply to most if not all the providers, including custom providers, the main +difference between different providers will be the contents of the API factory, the code +in the Auth Provider Factory, the resolver, and the different variables each provider +needs in the YAML config or env variables. + +[1]: https://backstage.io/docs/auth/identity-resolver +[2]: https://backstage.io/docs/auth/microsoft/provider#create-an-app-registration-on-azure +[3]: https://backstage.io/docs/auth/#sign-in-configuration +[4]: https://backstage.io/docs/api/utility-apis diff --git a/docs/auth/oidc.md b/docs/auth/oidc.md index 98d0e63255..4040a272b4 100644 --- a/docs/auth/oidc.md +++ b/docs/auth/oidc.md @@ -4,6 +4,13 @@ title: OIDC provider from scratch description: This section shows how to use an OIDC provider from scratch, same steps apply for custom providers. --- +:::info +This documentation is written for [the new backend system](../backend-system/index.md) which is the default since Backstage +[version 1.24](../releases/v1.24.0.md). If you are still on the old backend +system, you may want to read [its own article](./oidc--old.md) +instead, and [consider migrating](../backend-system/building-backends/08-migrating.md)! +::: + This section shows how to use an OIDC provider from scratch, same steps apply for custom providers. Please note these steps are for using a provider, not how to implement one, and Backstage recommends creating custom providers specific to the IDP, so we'll use a @@ -13,7 +20,7 @@ to your provider name. ## Summary To add providers not enabled by default like OIDC, we need to follow some steps, we -assume you already have a sign in page to which we'll add the provider so users can +assume you already have a sign-in page to which we'll add the provider so users can sign in through the provider. In simple steps here's how you enable the provider: - Create an API reference to identify the provider. @@ -133,85 +140,86 @@ The Auth Provider is responsible for authenticating with the 3rd party service, us back the credentials, here's where you pick which protocol to use, be it Auth0, OAuth2, OIDC, SAML or any other that your 3rd party IDP provider supports. -For this example we'll use OIDC, we pass a factory to the `providerFactories` object with -the ID you picked to represent the Auth provider, this ID has to match with the provider's -`id` inside the API factory, the yaml config provider key under `auth.providers`, and the -callback URI provider segment (you'll have to configure your IDP to handle the callback -URI properly). - -```ts -export default async function createPlugin( - env: PluginEnvironment, -): Promise { - return await createRouter({ - logger: env.logger, - config: env.config, - database: env.database, - discovery: env.discovery, - tokenManager: env.tokenManager, - providerFactories: { - ...defaultAuthProviderFactories, - /* highlight-add-next-line */ - 'my-auth-provider': providers.oidc.create({}), - }, - // .. -}) -``` - ### The Resolver Resolvers exist to map user identity from the 3rd party (in this case an azure IDP -provider) to the backstage user identity, for a detailed explanation check the -[Identity Resolver][1] page, it explains how to write a custom resolver as well as -linking the built in resolvers of backstage. +provider) to the backstage user identity. -The default OIDC provider does not support SignIn, we need to add such support by -adding a resolver for a SignIn request. +The default OIDC provider has built-in resolvers, here is how you configure them: -The OIDC provider doesn't provide any build-in resolvers, so we'll need to define our own: - -```ts -import { - DEFAULT_NAMESPACE, - /* highlight-add-next-line */ - stringifyEntityRef, -} from '@backstage/catalog-model'; - -export default async function createPlugin( - env: PluginEnvironment, -): Promise { - return await createRouter({ - logger: env.logger, - config: env.config, - database: env.database, - discovery: env.discovery, - tokenManager: env.tokenManager, - providerFactories: { - ...defaultAuthProviderFactories, - 'my-auth-provider': providers.oidc.create({ - /* highlight-add-start */ - signIn: { - resolver(info, ctx) { - const userRef = stringifyEntityRef({ - kind: 'User', - name: info.result.userinfo.sub, - namespace: DEFAULT_NAMESPACE, - }); - return ctx.issueToken({ - claims: { - sub: userRef, // The user's own identity - ent: [userRef], // A list of identities that the user claims ownership through - }, - }); - }, - }, - /* highlight-add-end */ - }), - }, - // .. - }) +```yaml title="app-config.yaml" +auth: + environment: development + providers: + oidc: + development: + # ... + signIn: + resolvers: + # typically you would pick one of these + - resolver: emailLocalPartMatchingUserEntityName + - resolver: emailMatchingUserEntityProfileEmail ``` +But you can also write a custom resolver as well, see an example below: + +```ts title="in packages/backend/src/index.ts" +/* highlight-add-start */ +import { createBackendModule } from '@backstage/backend-plugin-api'; +import { + authProvidersExtensionPoint, + createOAuthProviderFactory, +} from '@backstage/plugin-auth-node'; +import { oidcAuthenticator } from '@backstage/plugin-auth-backend-module-oidc-provider'; + +const myAuthProviderModule = createBackendModule({ + // This ID must be exactly "auth" because that's the plugin it targets + pluginId: 'auth', + // This ID must be unique, but can be anything + moduleId: 'my-auth-provider', + register(reg) { + reg.registerInit({ + deps: { providers: authProvidersExtensionPoint }, + async init({ providers }) { + providers.registerProvider({ + // This ID must match the actual provider config, e.g. addressing + // auth.providers.azure means that this must be "azure". + providerId: 'my-auth-provider', + // Use createProxyAuthProviderFactory instead if it's one of the proxy + // based providers rather than an OAuth based one + factory: createOAuthProviderFactory({ + // For more info about authenticators please see https://backstage.io/docs/auth/add-auth-provider/#adding-an-oauth-based-provider + authenticator: oidcAuthenticator, + async signInResolver(info, ctx) { + const userRef = stringifyEntityRef({ + kind: 'User', + name: info.result.userinfo.sub, + namespace: DEFAULT_NAMESPACE, + }); + return ctx.issueToken({ + claims: { + sub: userRef, // The user's own identity + ent: [userRef], // A list of identities that the user claims ownership through + }, + }); + }, + }), + }); + }, + }); + }, +}); +/* highlight-add-end */ +//... +backend.add(import('@backstage/plugin-auth-backend')); +/* highlight-add-next-line */ +backend.add(myAuthProviderModule); +//... +``` + +For a more a detailed explanation about resolvers check the +[Identity Resolver][1] page. + ### The configuration Since we are using our custom OIDC Auth Provider, we need to add a configuration based diff --git a/docs/backend-system/architecture/02-backends.md b/docs/backend-system/architecture/02-backends.md index 3386cff3f7..4afdeea560 100644 --- a/docs/backend-system/architecture/02-backends.md +++ b/docs/backend-system/architecture/02-backends.md @@ -24,7 +24,7 @@ const backend = createBackend(); backend.add(import('@backstage/plugin-catalog-backend/alpha')); // Features can also be installed using an explicit reference -backend.add(scaffolderPlugin()); +backend.add(scaffolderPlugin); // Start up the backend backend.start(); diff --git a/docs/backend-system/architecture/03-services.md b/docs/backend-system/architecture/03-services.md index 57f6b20b73..ad437e471e 100644 --- a/docs/backend-system/architecture/03-services.md +++ b/docs/backend-system/architecture/03-services.md @@ -197,7 +197,7 @@ When declaring a service factory you may also want to make the export the buildi ```ts export class DefaultFooService { static create(options: { transform: (foo: string) => string }) { - return new DefaultFooService(options.transform ?? (foo) => foo); + return new DefaultFooService(options.transform ?? ((foo) => foo); } private constructor(private readonly transform: (foo: string) => string) {} diff --git a/docs/backend-system/architecture/04-plugins.md b/docs/backend-system/architecture/04-plugins.md index 5aef71e24f..f2a6b856b9 100644 --- a/docs/backend-system/architecture/04-plugins.md +++ b/docs/backend-system/architecture/04-plugins.md @@ -41,7 +41,7 @@ The `createBackendPlugin` return value is exported as `examplePlugin`, which is ```ts import { examplePlugin } from 'backstage-plugin-example-backend'; -backend.add(examplePlugin()); +backend.add(examplePlugin); ``` By convention every plugin package should export its plugin instance as the default export from the package: diff --git a/docs/backend-system/building-backends/08-migrating.md b/docs/backend-system/building-backends/08-migrating.md index 67104c7ba9..188cd4f26f 100644 --- a/docs/backend-system/building-backends/08-migrating.md +++ b/docs/backend-system/building-backends/08-migrating.md @@ -431,7 +431,7 @@ catalog: /* highlight-add-end */ ``` -#### Github +#### GitHub For `GithubDiscoveryProcessor`, `GithubMultiOrgReaderProcessor` and `GithubOrgReaderProcessor`, first migrate to the equivalent Entity Provider. @@ -445,7 +445,7 @@ backend.add(import('@backstage/plugin-catalog-backend-module-github/alpha')); ``` If you were providing a `schedule` in code, this now needs to be set via configuration. -All other Github configuration in `app-config.yaml` remains the same. +All other GitHub configuration in `app-config.yaml` remains the same. ```yaml title="app-config.yaml" catalog: @@ -675,7 +675,7 @@ backend.add( import('@backstage/plugin-catalog-backend-module-scaffolder-entity-model'), ); /* highlight-add-next-line */ -backend.add(catalogModuleCustomExtensions()); +backend.add(catalogModuleCustomExtensions); ``` This also requires that you have a dependency on the corresponding node package, @@ -762,9 +762,9 @@ const otherPluginModuleCustomExtensions = createBackendModule({ const backend = createBackend(); backend.add(import('@backstage/plugin-events-backend/alpha')); /* highlight-add-next-line */ -backend.add(eventsModuleCustomExtensions()); +backend.add(eventsModuleCustomExtensions); /* highlight-add-next-line */ -backend.add(otherPluginModuleCustomExtensions()); +backend.add(otherPluginModuleCustomExtensions); ``` Here we've placed the module directly in the backend index file just to get @@ -841,7 +841,7 @@ const scaffolderModuleCustomExtensions = createBackendModule({ const backend = createBackend(); backend.add(import('@backstage/plugin-scaffolder-backend/alpha')); /* highlight-add-next-line */ -backend.add(scaffolderModuleCustomExtensions()); +backend.add(scaffolderModuleCustomExtensions); ``` This also requires that you have a dependency on the corresponding node package, diff --git a/docs/backend-system/core-services/auth.md b/docs/backend-system/core-services/auth.md index f1243f11fe..8a3a63805d 100644 --- a/docs/backend-system/core-services/auth.md +++ b/docs/backend-system/core-services/auth.md @@ -73,7 +73,8 @@ router.get('/makes-calls', async (req, res) => { onBehalfOf: await httpAuth.credentials(req), targetPluginId: 'catalog', }); - // make a call using the token +}); +// make a call using the token ``` This ensures that the original caller and their associated permissions are @@ -106,7 +107,7 @@ objects. For example checking what type of principal (caller type - e.g. user or service) they represent. For example: ```ts -if (auth.isPrincipal(credentials, 'user)) { +if (auth.isPrincipal(credentials, 'user')) { // In here, the TypeScript type of the credentials object has been properly // narrowed to `BackstageCredentials` so you can // access its specific properties such as `credentials.principal.userEntityRef`. diff --git a/docs/backend-system/core-services/http-auth.md b/docs/backend-system/core-services/http-auth.md index 05a26fc075..13938c921d 100644 --- a/docs/backend-system/core-services/http-auth.md +++ b/docs/backend-system/core-services/http-auth.md @@ -47,6 +47,7 @@ can do so like this: router.get('/some-request', async (req, res) => { const credentials = await httpAuth.credentials(req, { allow: ['user'] }); // Do something with the credentials here +}); ``` The second argument is optional, but in this example we specified that we only diff --git a/docs/backend-system/core-services/user-info.md b/docs/backend-system/core-services/user-info.md index e9d17f1dd7..73f461d1ec 100644 --- a/docs/backend-system/core-services/user-info.md +++ b/docs/backend-system/core-services/user-info.md @@ -47,6 +47,7 @@ additional information about that principal. router.get('/some-request', async (req, res) => { const credentials = await httpAuth.credentials(req, { allow: ['user'] }); const info = await userInfo.getUserInfo(credentials); +}); ``` The `userInfo` service only deals with credentials that contain user principals, @@ -61,6 +62,8 @@ router.get('/some-request', async (req, res) => { if (auth.isPrincipal(credentials, 'user')) { const info = await userInfo.getUserInfo(credentials); // ... + } +}); ``` The user info contains data that was extracted during sign-in for the given diff --git a/docs/contribute/project-structure.md b/docs/contribute/project-structure.md index f06fba0523..32a692e700 100644 --- a/docs/contribute/project-structure.md +++ b/docs/contribute/project-structure.md @@ -39,7 +39,7 @@ the code. - [`docs/`](https://github.com/backstage/backstage/tree/master/docs) - This is where we keep all of our documentation Markdown files. These end up on https://backstage.io/docs. Just keep in mind that changes to the - [`sidebars.json`](https://github.com/backstage/backstage/blob/master/microsite/sidebars.json) + [`sidebars.js`](https://github.com/backstage/backstage/blob/master/microsite/sidebars.js) file may be needed as sections are added/removed. - [`.editorconfig`](https://github.com/backstage/backstage/tree/master/.editorconfig) - diff --git a/docs/deployment/docker.md b/docs/deployment/docker.md index 7b71c2eb61..1017684595 100644 --- a/docs/deployment/docker.md +++ b/docs/deployment/docker.md @@ -40,49 +40,58 @@ package with `yarn build:backend`. In a CI workflow it might look something like this, from the root: ```bash -yarn install --frozen-lockfile +yarn install --immutable # tsc outputs type definitions to dist-types/ in the repo root, which are then consumed by the build yarn tsc # Build the backend, which bundles it all up into the packages/backend/dist folder. # The configuration files here should match the one you use inside the Dockerfile below. -yarn build:backend --config ../../app-config.yaml +yarn build:backend --config ../../app-config.yaml --config ../../app-config.production.yaml ``` Once the host build is complete, we are ready to build our image. The following `Dockerfile` is included when creating a new app with `@backstage/create-app`: ```dockerfile -FROM node:18-bookworm-slim +FROM node:20-bookworm-slim + +# Set Python interpreter for `node-gyp` to use +ENV PYTHON=/usr/bin/python3 # Install isolate-vm dependencies, these are needed by the @backstage/plugin-scaffolder-backend. RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ --mount=type=cache,target=/var/lib/apt,sharing=locked \ apt-get update && \ apt-get install -y --no-install-recommends python3 g++ build-essential && \ - yarn config set python /usr/bin/python3 + rm -rf /var/lib/apt/lists/* # Install sqlite3 dependencies. You can skip this if you don't use sqlite3 in the image, # in which case you should also move better-sqlite3 to "devDependencies" in package.json. RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ --mount=type=cache,target=/var/lib/apt,sharing=locked \ apt-get update && \ - apt-get install -y --no-install-recommends libsqlite3-dev + apt-get install -y --no-install-recommends libsqlite3-dev && \ + rm -rf /var/lib/apt/lists/* # From here on we use the least-privileged `node` user to run the backend. USER node # This should create the app dir as `node`. -# If it is instead created as `root` then the `tar` command below will -# fail: `can't create directory 'packages/': Permission denied`. -# If this occurs, then ensure BuildKit is enabled (`DOCKER_BUILDKIT=1`) -# so the app dir is correctly created as `node`. +# If it is instead created as `root` then the `tar` command below will fail: `can't create directory 'packages/': Permission denied`. +# If this occurs, then ensure BuildKit is enabled (`DOCKER_BUILDKIT=1`) so the app dir is correctly created as `node`. WORKDIR /app +# Copy files needed by Yarn +COPY --chown=node:node .yarn ./.yarn +COPY --chown=node:node .yarnrc.yml ./ + # This switches many Node.js dependencies to production mode. ENV NODE_ENV=production +# This disables node snapshot for Node 20 to work with the Scaffolder +ENV NODE_OPTIONS "--no-node-snapshot" + # Copy repo skeleton first, to avoid unnecessary docker cache invalidation. # The skeleton contains the package.json of each package in the monorepo, # and along with yarn.lock and the root package.json, that's enough to run yarn install. @@ -90,7 +99,7 @@ COPY --chown=node:node yarn.lock package.json packages/backend/dist/skeleton.tar RUN tar xzf skeleton.tar.gz && rm skeleton.tar.gz RUN --mount=type=cache,target=/home/node/.cache/yarn,sharing=locked,uid=1000,gid=1000 \ - yarn install --frozen-lockfile --production --network-timeout 300000 + yarn workspaces focus --all --production && rm -rf "$(yarn cache clean)" # This will include the examples, if you don't need these simply remove this line COPY --chown=node:node examples ./examples @@ -169,10 +178,12 @@ the repo root: ```dockerfile # Stage 1 - Create yarn install skeleton layer -FROM node:18-bookworm-slim AS packages +FROM node:20-bookworm-slim AS packages WORKDIR /app COPY package.json yarn.lock ./ +COPY .yarn ./.yarn +COPY .yarnrc.yml ./ COPY packages packages @@ -182,57 +193,65 @@ COPY plugins plugins RUN find packages \! -name "package.json" -mindepth 2 -maxdepth 2 -exec rm -rf {} \+ # Stage 2 - Install dependencies and build packages -FROM node:18-bookworm-slim AS build +FROM node:20-bookworm-slim AS build + +# Set Python interpreter for `node-gyp` to use +ENV PYTHON=/usr/bin/python3 # Install isolate-vm dependencies, these are needed by the @backstage/plugin-scaffolder-backend. RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ --mount=type=cache,target=/var/lib/apt,sharing=locked \ apt-get update && \ apt-get install -y --no-install-recommends python3 g++ build-essential && \ - yarn config set python /usr/bin/python3 + rm -rf /var/lib/apt/lists/* # Install sqlite3 dependencies. You can skip this if you don't use sqlite3 in the image, # in which case you should also move better-sqlite3 to "devDependencies" in package.json. RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ --mount=type=cache,target=/var/lib/apt,sharing=locked \ apt-get update && \ - apt-get install -y --no-install-recommends libsqlite3-dev + apt-get install -y --no-install-recommends libsqlite3-dev && \ + rm -rf /var/lib/apt/lists/* USER node WORKDIR /app COPY --from=packages --chown=node:node /app . +COPY --from=packages --chown=node:node /app/.yarn ./.yarn +COPY --from=packages --chown=node:node /app/.yarnrc.yml ./ RUN --mount=type=cache,target=/home/node/.cache/yarn,sharing=locked,uid=1000,gid=1000 \ - yarn install --frozen-lockfile --network-timeout 600000 + yarn install --immutable COPY --chown=node:node . . RUN yarn tsc RUN yarn --cwd packages/backend build -# If you have not yet migrated to package roles, use the following command instead: -# RUN yarn --cwd packages/backend backstage-cli backend:bundle --build-dependencies RUN mkdir packages/backend/dist/skeleton packages/backend/dist/bundle \ && tar xzf packages/backend/dist/skeleton.tar.gz -C packages/backend/dist/skeleton \ && tar xzf packages/backend/dist/bundle.tar.gz -C packages/backend/dist/bundle # Stage 3 - Build the actual backend image and install production dependencies -FROM node:18-bookworm-slim +FROM node:20-bookworm-slim + +# Set Python interpreter for `node-gyp` to use +ENV PYTHON=/usr/bin/python3 # Install isolate-vm dependencies, these are needed by the @backstage/plugin-scaffolder-backend. RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ --mount=type=cache,target=/var/lib/apt,sharing=locked \ apt-get update && \ apt-get install -y --no-install-recommends python3 g++ build-essential && \ - yarn config set python /usr/bin/python3 + rm -rf /var/lib/apt/lists/* # Install sqlite3 dependencies. You can skip this if you don't use sqlite3 in the image, # in which case you should also move better-sqlite3 to "devDependencies" in package.json. RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ --mount=type=cache,target=/var/lib/apt,sharing=locked \ apt-get update && \ - apt-get install -y --no-install-recommends libsqlite3-dev + apt-get install -y --no-install-recommends libsqlite3-dev && \ + rm -rf /var/lib/apt/lists/* # From here on we use the least-privileged `node` user to run the backend. USER node @@ -245,13 +264,15 @@ USER node WORKDIR /app # Copy the install dependencies from the build stage and context +COPY --from=build --chown=node:node /app/.yarn ./.yarn +COPY --from=build --chown=node:node /app/.yarnrc.yml ./ COPY --from=build --chown=node:node /app/yarn.lock /app/package.json /app/packages/backend/dist/skeleton/ ./ # Note: The skeleton bundle only includes package.json files -- if your app has # plugins that define a `bin` export, the bin files need to be copied as well to # be linked in node_modules/.bin during yarn install. RUN --mount=type=cache,target=/home/node/.cache/yarn,sharing=locked,uid=1000,gid=1000 \ - yarn install --frozen-lockfile --production --network-timeout 600000 + yarn workspaces focus --all --production && rm -rf "$(yarn cache clean)" # Copy the built packages from the build stage COPY --from=build --chown=node:node /app/packages/backend/dist/bundle/ ./ @@ -265,6 +286,9 @@ COPY --chown=node:node examples ./examples # This switches many Node.js dependencies to production mode. ENV NODE_ENV=production +# This disables node snapshot for Node 20 to work with the Scaffolder +ENV NODE_OPTIONS "--no-node-snapshot" + CMD ["node", "packages/backend", "--config", "app-config.yaml", "--config", "app-config.production.yaml"] ``` diff --git a/docs/deployment/flightcontrol.md b/docs/deployment/flightcontrol.md index 14e0b308a6..df0c9284fb 100644 --- a/docs/deployment/flightcontrol.md +++ b/docs/deployment/flightcontrol.md @@ -7,7 +7,7 @@ description: Deploying Backstage to AWS Fargate via Flightcontrol This guide explains how to deploy Backstage to [Flightcontrol](https://www.flightcontrol.dev?ref=backstage), a platform that fully automates deployments to Amazon Web Services (AWS). Flightcontrol supports git-driven and image registry deployments. -Before you begin, make sure you have a [Flightcontrol account](https://app.flightcontrol.dev/signup?ref=backstage) and a [Github account](https://github.com/login) to follow this guide. +Before you begin, make sure you have a [Flightcontrol account](https://app.flightcontrol.dev/signup?ref=backstage) and a [GitHub account](https://github.com/login) to follow this guide. # Creating a Dockerfile and .dockerignore @@ -28,7 +28,7 @@ The following two code snippets demonstrate this method. The first block of code # yarn build:backend # # Once the commands have been run, you can build the image using `yarn build-image` -FROM node:18-bookworm-slim as build +FROM node:20-bookworm-slim as build USER node WORKDIR /app @@ -43,7 +43,7 @@ RUN yarn tsc # The configuration files here should match the one you use inside the Dockerfile below. RUN yarn build:backend --config ../../app-config.yaml -FROM node:18-bookworm-slim +FROM node:20-bookworm-slim # Install isolate-vm dependencies, these are needed by the @backstage/plugin-scaffolder-backend. RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ diff --git a/docs/deployment/heroku.md b/docs/deployment/heroku.md index 51d0b4b439..8961848894 100644 --- a/docs/deployment/heroku.md +++ b/docs/deployment/heroku.md @@ -126,7 +126,7 @@ heroku stack:set container -a Locally run the [host build commands](https://backstage.io/docs/deployment/docker/#host-build), they must be run whenever you are going to publish a new image: ```shell -yarn install --frozen-lockfile +yarn install --immutable yarn tsc yarn build:backend --config ../../app-config.yaml --config ../../app-config.production.yaml ``` diff --git a/docs/features/kubernetes/installation.md b/docs/features/kubernetes/installation.md index 279c9cbf3f..bd6a15a542 100644 --- a/docs/features/kubernetes/installation.md +++ b/docs/features/kubernetes/installation.md @@ -96,6 +96,7 @@ async function main() { // ... /* highlight-add-next-line */ apiRouter.use('/kubernetes', await kubernetes(kubernetesEnv)); +} ``` That's it! The Kubernetes frontend and backend have now been added to your diff --git a/docs/features/search/how-to-guides.md b/docs/features/search/how-to-guides.md index 2c51e6ded5..9a4ce9e834 100644 --- a/docs/features/search/how-to-guides.md +++ b/docs/features/search/how-to-guides.md @@ -170,11 +170,14 @@ const highlightOverride = { ## How to render search results using extensions -Extensions for search results let you customize components used to render search result items, It is possible to provide your own search result item extensions or use the ones provided by plugin packages: +Extensions for search results let you customize components used to render search result items, It is possible to provide your own search result item extensions or use the ones provided by plugin packages. ### 1. Providing an extension in your plugin package -Using the example below, you can provide an extension to be used as a default result item: +> Note: You must use the `plugin.provide()` function to make a search item renderer available. Unlike rendering a list in a standard MUI Table or similar, you cannot simply provide +> a rendering function to the `` component. + +Using the example below, you can provide an extension to be used as a search result item: ```tsx title="plugins/your-plugin/src/plugin.ts" import { createPlugin } from '@backstage/core-plugin-api'; @@ -224,7 +227,7 @@ export const YourSearchResultListItemExtension = plugin.provide( ); ``` -Remember to export your new extension: +Remember to export your new extension via your plugin's `index.ts` so that it is available from within your app: ```tsx title="plugins/your-plugin/src/index.ts" export { YourSearchResultListItem } from './plugin.ts'; @@ -232,9 +235,12 @@ export { YourSearchResultListItem } from './plugin.ts'; For more details, see the [createSearchResultListItemExtension](https://backstage.io/docs/reference/plugin-search-react.createsearchresultlistitemextension) API reference. -### 2. Using an extension in your Backstage app +### 2. Custom search result extension in the SearchPage -Now that you know how a search result item is provided, let's finally see how they can be used, for example, to compose a page in your application: +Once you have exposed your item renderer via the `plugin.provide()` function, you can now override the default search item renderers and tell the `` component +which renderers to use. Note that the order of the renderers matters! The first one that matches via its predicate function will be used. + +Here is an example of customizing your `SearchPage`: ```tsx title="packages/app/src/components/searchPage.tsx" import React from 'react'; @@ -286,9 +292,38 @@ const SearchPage = () => ( export const searchPage = ; ``` -> **Important**: A default result item extension should be placed as the last child, so it can be used only when no other extensions match the result being rendered. If a non-default extension is specified, the `DefaultResultListItem` component will be used. +> **Important**: A default result item extension (one that does not have a predicate) should be placed as the last child, so it can be used only when no other extensions match the result being rendered. +> If a non-default extension is specified, the `DefaultResultListItem` component will be used. -As another example, here's a search modal that renders results with extensions: +### 2. Custom search result extension in the SidebarSearchModal + +You may be using the SidebarSearchModal component. In this case, you can customize the search items in this component as follows: + +```tsx title="packages/app/src/components/Root/Root.tsx" +import { SidebarSearchModal } from '@backstage/plugin-search'; +... +export const Root = ({ children }: PropsWithChildren<{}>) => { + const styles = useStyles(); + + return + + ... + } />, + /* Provide an existing search item renderer */ + } /> + ]} /> + ... + + {children} + ; +}; +``` + +### 3. Custom search result extension in a custom SearchModal + +Assuming you have completely customized your SearchModal, here's an example that renders results with extensions: ```tsx title="packages/app/src/components/searchModal.tsx" import React from 'react'; diff --git a/docs/features/software-catalog/configuration.md b/docs/features/software-catalog/configuration.md index 67382aa6ce..dff09a9397 100644 --- a/docs/features/software-catalog/configuration.md +++ b/docs/features/software-catalog/configuration.md @@ -31,7 +31,7 @@ catalog (`UrlReaderProcessor`), so no processor configuration is needed. This processor _does however_ need an [integration](../../integrations/index.md) to understand how to retrieve a given URL. For the example above, you would need to configure the [GitHub integration](../../integrations/github/locations.md) to -read files from github.com. +read files from [github.com](https://github.com/). The locations added through static configuration cannot be removed through the catalog locations API. To remove these locations, you must remove them from the diff --git a/docs/features/software-catalog/descriptor-format.md b/docs/features/software-catalog/descriptor-format.md index 57c2283586..17bdac56e9 100644 --- a/docs/features/software-catalog/descriptor-format.md +++ b/docs/features/software-catalog/descriptor-format.md @@ -527,6 +527,8 @@ spec: system: artist-engagement-portal dependsOn: - resource:default/artists-db + dependencyOf: + - component:default/artist-web-lookup providesApis: - artist-api ``` @@ -636,6 +638,17 @@ field is optional. | [`Component`](#kind-component) | Same as this entity, typically `default` | [`dependsOn`, and reverse `dependencyOf`](well-known-relations.md#dependson-and-dependencyof) | | [`Resource`](#kind-resource) | Same as this entity, typically `default` | [`dependsOn`, and reverse `dependencyOf`](well-known-relations.md#dependson-and-dependencyof) | +### `spec.dependencyOf` [optional] + +An array of [entity references](references.md#string-references) to the +components and resources that the component is a dependency of, e.g. `artist-web-lookup`. +This field is optional. + +| [`kind`](#apiversion-and-kind-required) | Default [`namespace`](#namespace-optional) | Generated [relation](well-known-relations.md) type | +| --------------------------------------- | ------------------------------------------ | --------------------------------------------------------------------------------------------- | +| [`Component`](#kind-component) | Same as this entity, typically `default` | [`dependencyOf`, and reverse `dependsOn`](well-known-relations.md#dependson-and-dependencyof) | +| [`Resource`](#kind-resource) | Same as this entity, typically `default` | [`dependencyOf`, and reverse `dependsOn`](well-known-relations.md#dependson-and-dependencyof) | + ## Kind: Template The following describes the following entity kind: diff --git a/docs/features/software-catalog/external-integrations.md b/docs/features/software-catalog/external-integrations.md index 4d5b283c4e..ff6853e1e7 100644 --- a/docs/features/software-catalog/external-integrations.md +++ b/docs/features/software-catalog/external-integrations.md @@ -77,28 +77,30 @@ yarn new --select backend-module --option id=catalog The class will have this basic structure: -```ts -import { UrlReader } from '@backstage/backend-common'; +```ts title="plugins/catalog-backend-module-frobs/src/FrobsProvider.ts" import { Entity } from '@backstage/catalog-model'; import { EntityProvider, EntityProviderConnection, } from '@backstage/plugin-catalog-node'; -import { SchedulerServiceTaskRunner } from '@backstage/backend-plugin-api'; +import { + SchedulerServiceTaskRunner, + UrlReaderService, +} from '@backstage/backend-plugin-api'; /** * Provides entities from fictional frobs service. */ export class FrobsProvider implements EntityProvider { private readonly env: string; - private readonly reader: UrlReader; + private readonly reader: UrlReaderService; private connection?: EntityProviderConnection; private taskRunner: SchedulerServiceTaskRunner; /** [1] */ constructor( env: string, - reader: UrlReader, + reader: UrlReaderService, taskRunner: SchedulerServiceTaskRunner, ) { this.env = env; @@ -114,7 +116,7 @@ export class FrobsProvider implements EntityProvider { /** [3] */ async connect(connection: EntityProviderConnection): Promise { this.connection = connection; - this.taskRunner.run({ + await this.taskRunner.run({ id: this.getProviderName(), fn: async () => { await this.run(); @@ -131,7 +133,7 @@ export class FrobsProvider implements EntityProvider { const response = await this.reader.readUrl( `https://frobs-${this.env}.example.com/data`, ); - const data = JSON.parse(await response.buffer()).toString(); + const data = JSON.parse((await response.buffer()).toString()); /** [5] */ const entities: Entity[] = frobsToEntities(data); @@ -200,7 +202,7 @@ bucket is accessible. There are two different types of mutation. The first is `'full'`, which means to figuratively throw away the contents of -the bucket and replacing it with all of the new contents specified. Under the +the bucket and replacing it with all the new contents specified. Under the hood, this is actually implemented through a highly efficient delta mechanism for performance reasons, since it is common that the difference from one run to the other is actually very small. This strategy is convenient for providers that @@ -436,66 +438,66 @@ We create a basic entity provider as shown above. In the example below we might import { ANNOTATION_LOCATION, ANNOTATION_ORIGIN_LOCATION, -} from '@backstage/catalog-model' +} from '@backstage/catalog-model'; import { EntityProvider, EntityProviderConnection, -} from '@backstage/plugin-catalog-backend' -import { WebClient } from '@slack/web-api' -import {kebabCase} from 'lodash' +} from '@backstage/plugin-catalog-backend'; +import { WebClient } from '@slack/web-api'; +import { kebabCase } from 'lodash'; interface Staff { - displayName: string - slackUserId: string - jobTitle: string - photoUrl: string - address: string - email:string + displayName: string; + slackUserId: string; + jobTitle: string; + photoUrl: string; + address: string; + email: string; } export class UserEntityProvider implements EntityProvider { - private readonly getStaffUrl: string - protected readonly slackTeam: string - protected readonly slackToken: string - protected connection?: EntityProviderConnection + private readonly getStaffUrl: string; + protected readonly slackTeam: string; + protected readonly slackToken: string; + protected connection?: EntityProviderConnection; static fromConfig(config: Config, options: { logger: Logger }) { - const getStaffUrl = config.getString('staff.url') - const slackToken = config.getString('slack.token') - const slackTeam = config.getString('slack.team') + const getStaffUrl = config.getString('staff.url'); + const slackToken = config.getString('slack.token'); + const slackTeam = config.getString('slack.team'); return new UserEntityProvider({ ...options, getStaffUrl, slackToken, slackTeam, - }) + }); } private constructor(options: { - getStaffUrl: string - slackToken: string - slackTeam: string + getStaffUrl: string; + slackToken: string; + slackTeam: string; }) { - this.getStaffUrl = options.getStaffUrl - this.slackToken = options.slackToken - this.slackTeam = options.slackTeam + this.getStaffUrl = options.getStaffUrl; + this.slackToken = options.slackToken; + this.slackTeam = options.slackTeam; } - async getAllStaff(): Promise{ - await return axios.get(this.getStaffUrl) + async getAllStaff(): Promise { + return await axios.get(this.getStaffUrl); } public async connect(connection: EntityProviderConnection): Promise { - this.connection = connection + this.connection = connection; } async run(): Promise { if (!this.connection) { - throw new Error('User Connection Not initialized') + throw new Error('User Connection Not initialized'); } - const userResources: UserEntity[] = [] - const staff = await this.getAllStaff() + const userResources: UserEntity[] = []; + const staff = await this.getAllStaff(); for (const user of staff) { // we can add any links here in this case it would be adding a slack link to the users so you can directly slack them. @@ -508,7 +510,7 @@ export class UserEntityProvider implements EntityProvider { icon: 'message', }, ] - : undefined + : undefined; const userEntity: UserEntity = { kind: 'User', apiVersion: 'backstage.io/v1alpha1', @@ -531,20 +533,20 @@ export class UserEntityProvider implements EntityProvider { }, memberOf: [], }, - } + }; - userResources.push(userEntity) + userResources.push(userEntity); } await this.connection.applyMutation({ type: 'full', - entities: userResources.map((entity) => ({ + entities: userResources.map(entity => ({ entity, locationKey: 'hr-user-https://www.hrurl.com/', })), - }) + }); + } } - ``` ## Custom Processors @@ -595,7 +597,7 @@ startup. They are at the heart of all catalog logic, and have the ability to read the contents of locations, modify in-flight entities that were read out of a location, perform validation, and more. The catalog comes with a set of builtin processors, that have the ability to read from a list of well known -location types, to perform the basic processing needs, etc, but more can be +location types, to perform the basic processing needs, etc., but more can be added by the organization that adopts Backstage. We will now show the process of creating a new processor and location type, @@ -654,18 +656,18 @@ yarn new --select backend-module --option id=catalog The class will have this basic structure: ```ts -import { UrlReader } from '@backstage/backend-common'; import { processingResult, CatalogProcessor, CatalogProcessorEmit, } from '@backstage/plugin-catalog-node'; +import { UrlReaderService } from '@backstage/backend-plugin-api'; import { LocationSpec } from '@backstage/plugin-catalog-common'; // A processor that reads from the fictional System-X export class SystemXReaderProcessor implements CatalogProcessor { - constructor(private readonly reader: UrlReader) {} + constructor(private readonly reader: UrlReaderService) {} getProcessorName(): string { return 'SystemXReaderProcessor'; @@ -784,8 +786,8 @@ locations in GitHub. This example aims to demonstrate how to add the same behavior for `system-x` that we implemented earlier. ```ts -import { UrlReader } from '@backstage/backend-common'; import { Entity } from '@backstage/catalog-model'; +import { UrlReaderService } from '@backstage/backend-plugin-api'; import { processingResult, CatalogProcessor, @@ -808,7 +810,7 @@ type CacheItem = { }; export class SystemXReaderProcessor implements CatalogProcessor { - constructor(private readonly reader: UrlReader) {} + constructor(private readonly reader: UrlReaderService) {} getProcessorName() { // The processor name must be unique. @@ -851,7 +853,7 @@ export class SystemXReaderProcessor implements CatalogProcessor { } // For this example the JSON payload is a single entity. - const entity: Entity = JSON.parse(response.buffer.toString()); + const entity: Entity = JSON.parse((await response.buffer()).toString()); emit(processingResult.entity(location, entity)); // Update the cache with the new ETag and entity used for the next run. @@ -922,13 +924,13 @@ const makeEntityFromCustomFormatJson = ( [ANNOTATION_LOCATION]: `${location.type}:${location.target}`, [ANNOTATION_ORIGIN_LOCATION]: `${location.type}:${location.target}`, }, - } + }, spec: { type: component.type, owner: component.author, - lifecycle: 'experimental' - } - } + lifecycle: 'experimental', + }, + }; }; export const customEntityDataParser: CatalogProcessorParser = async function* ({ @@ -960,9 +962,8 @@ export const customEntityDataParser: CatalogProcessorParser = async function* ({ // Is this a catalog-info.yaml file? if (json.apiVersion) { yield processingResult.entity(location, json as Entity); - - // let's treat this like it's our custom format instead. } else { + // let's treat this like it's our custom format instead. yield processingResult.entity( location, makeEntityFromCustomFormatJson(json, location), @@ -978,7 +979,7 @@ export const customEntityDataParser: CatalogProcessorParser = async function* ({ } } } -} +}; ``` This is a lot of code right now, as this is a pretty niche use-case, so we don't currently provide many helpers for you to be able to provide custom implementations easier or to compose together different parsers. @@ -1085,7 +1086,7 @@ interface Service { } ``` -These are the only 3 methods that you need to implement. `getProviderName()` is pretty self explanatory and it's identical to the `getProviderName()` method on a regular Entity Provider. +These are the only 3 methods that you need to implement. `getProviderName()` is pretty self-explanatory and it's identical to the `getProviderName()` method on a regular Entity Provider. ```ts import { IncrementalEntityProvider } from '@backstage/plugin-catalog-backend-module-incremental-ingestion'; @@ -1178,7 +1179,7 @@ export class MyIncrementalEntityProvider async next( context: Context, - cursor?: Cursor = { page: 1 }, + cursor: Cursor = { page: 1 }, ): Promise> { const { apiClient } = context; diff --git a/docs/features/software-catalog/faq.md b/docs/features/software-catalog/faq.md new file mode 100644 index 0000000000..d44414c1a7 --- /dev/null +++ b/docs/features/software-catalog/faq.md @@ -0,0 +1,26 @@ +--- +id: faq +title: Catalog FAQ +sidebar_label: FAQ +description: This page answers frequently asked questions about the catalog +--- + +This page answers frequently asked questions about the catalog. + +## Is it all that important to have users and groups in the catalog at all? + +Yes. One of the most important concepts in the catalog is that it exposes your org structure and ownership properly, allowing your users to effectively understand and communicate around your systems. Having catalog entries for users and groups enables end users to navigate around Backstage and click on those owners and being presented with rich information pages around them, instead of getting 404 Not Found pages. + +## Can I create users in the catalog on-demand as they sign in? + +When standing up a new Backstage instance, adopters are faced with the realization that the catalog tends to have interactions with sign-in. Therefore the question often comes up, whether it's doable to have users pop up in the catalog on-demand only as they sign in. + +This should really be avoided. Our general guidance is to set up a proper integration upfront with your authority for organizational data ([LDAP](../../integrations/ldap/org.md), [Azure](../../integrations/azure/org.md), bespoke HR systems, etc) and batch ingest _all_ users and groups from there into the catalog, whether they sign in or not. This tends to give the superior experience for users, with the smallest amount possible of complexity and frustration. + +To give some background, [signing in](../../auth/index.md) technically only requires the `auth` backend which supports the flows that establish who the current user is. At the end of that process, a so called [sign-in resolver](../../auth/identity-resolver.md) is tasked with translating the third party established identity (for example the attributes returned for your AD entry) into a Backstage identity. This important step is made much simpler if the catalog is populated with users and groups from that same third party, because identities line up trivially and you can use the out-of-the-box provided sign-in resolvers for it. As a side note, you can also write your own resolver that does not interact with the catalog at all if you so desire, but let's assume that you do not chose this advanced option. + +Doing on-demand user creation _is_ technically possible by writing custom [entity providers](./external-integrations.md). But it comes with significant problems both for technical and end user quality of life reasons. + +On the technical side, this is unwanted complexity. You need to implement and maintain a custom provider, instead of what usually amounts to a very easily set-up batch ingestion schedule with providers that come out of the box. Also even if you do this, the catalog is an eventually consistent engine. The user that the provider feeds into the system is not guaranteed to appear immediately. Your experience will likely be only partially functional at bootstrapping time which may have unwanted side effects. + +On the user experience side, a Backstage experience without complete organizational data is a serious hindrance to getting the full power out of the tool. Your users won't be able to click on owners and seeing who they are and what teams they belong to. They won't be able to find out what the communications paths are when they need to reach you or your managers when something goes wrong or they have a feature request. They can't get an overview of what teams own and how they relate to each other. It will be a much more barren experience. Organizational data is highly valuable to have centrally available, complete and correct. diff --git a/docs/features/software-templates/builtin-actions.md b/docs/features/software-templates/builtin-actions.md index 301fb4c457..5bfc038c1d 100644 --- a/docs/features/software-templates/builtin-actions.md +++ b/docs/features/software-templates/builtin-actions.md @@ -45,13 +45,8 @@ backend.add( // scaffolder plugin backend.add(import('@backstage/plugin-scaffolder-backend/alpha')); -{ - /* highlight-add-start */ -} +/* highlight-add-next-line */ backend.add(import('@backstage/plugin-scaffolder-backend-module-github')); -{ - /* highlight-add-end */ -} backend.start(); ``` @@ -87,16 +82,16 @@ allow most templates built for `fetch:cookiecutter` to work without any changes. ```yaml title="template.yaml" steps: - id: fetch-base - name: Fetch Base - # highlight-remove-next-line - action: fetch:cookiecutter - # highlight-add-next-line - action: fetch:template - input: - url: ./skeleton - # highlight-add-next-line - cookiecutterCompat: true - values: + name: Fetch Base + # highlight-remove-next-line + action: fetch:cookiecutter + # highlight-add-next-line + action: fetch:template + input: + url: ./skeleton + # highlight-add-next-line + cookiecutterCompat: true + values: ``` ### Manual migration diff --git a/docs/features/software-templates/dry-run-testing.md b/docs/features/software-templates/dry-run-testing.md index dfabad265e..15c2684808 100644 --- a/docs/features/software-templates/dry-run-testing.md +++ b/docs/features/software-templates/dry-run-testing.md @@ -4,7 +4,7 @@ title: Dry Run Testing description: How to enable and implement dry run testing in actions --- -Scaffolder templates can be tested using the dry run feature of scaffolder actions. This allows you to simulate the effects of running a scaffolder action without making any actual changes to your environment, for example creating a webhook in Github. Once dry run is enabled in the scaffolder action, you can add handling to actions you use in your scaffolder templates to define how an action should operate in a dry run scenario. +Scaffolder templates can be tested using the dry run feature of scaffolder actions. This allows you to simulate the effects of running a scaffolder action without making any actual changes to your environment, for example creating a webhook in GitHub. Once dry run is enabled in the scaffolder action, you can add handling to actions you use in your scaffolder templates to define how an action should operate in a dry run scenario. ## Enabling dry run testing diff --git a/docs/features/software-templates/index.md b/docs/features/software-templates/index.md index d4fa6ac971..077090743f 100644 --- a/docs/features/software-templates/index.md +++ b/docs/features/software-templates/index.md @@ -91,19 +91,29 @@ There could be situations where you would like to disable the ![Disable Button](../../assets/software-templates/disable-register-existing-component-button.png) -To do so, you will un-register / remove the `catalogImportPlugin.routes.importPage` -from `backstage/packages/app/src/App.tsx`: +To do so, you need to explicitly disable the default route binding from the `scaffolderPlugin.registerComponent` to the Catalog Import page. + +This can be done in `backstage/packages/app/src/App.tsx`: ```diff const app = createApp({ apis, bindRoutes({ bind }) { -- bind(scaffolderPlugin.externalRoutes, { + bind(scaffolderPlugin.externalRoutes, { ++ registerComponent: false, - registerComponent: catalogImportPlugin.routes.importPage, -- }); - bind(orgPlugin.externalRoutes, { - catalogIndex: catalogPlugin.routes.catalogIndex, + viewTechDoc: techdocsPlugin.routes.docRoot, }); +}) +``` + +OR in `app-config.yaml`: + +```yaml +app: + routes: + bindings: + scaffolder.registerComponent: false ``` After the change, you should no longer see the button. diff --git a/docs/features/software-templates/migrating-to-rjsf-v5.md b/docs/features/software-templates/migrating-to-rjsf-v5.md index 856841bdd4..8357d7567b 100644 --- a/docs/features/software-templates/migrating-to-rjsf-v5.md +++ b/docs/features/software-templates/migrating-to-rjsf-v5.md @@ -44,7 +44,7 @@ It's possible that if you have a hard dependency on any of the `@rjsf/*` librari /* highlight-remove-next-line */ import { FieldValidation } from '@rjsf/core'; /* highlight-add-next-line */ -import { FieldValidation } from '@rjsf/utils; +import { FieldValidation } from '@rjsf/utils'; ``` ## Escape hatch diff --git a/docs/features/software-templates/writing-custom-actions.md b/docs/features/software-templates/writing-custom-actions.md index 98457d2e8d..e5a82c09a9 100644 --- a/docs/features/software-templates/writing-custom-actions.md +++ b/docs/features/software-templates/writing-custom-actions.md @@ -43,6 +43,7 @@ After running the command, the CLI will create a new directory with your new sca Let's create a simple action that adds a new file and some contents that are passed as `input` to the function. Within the generated directory, locate the file at `src/actions/example/example.ts`. Feel free to rename this file along with its generated unit test. We will replace the existing placeholder code with our custom action code as follows: ```ts title="With Zod" +import { resolveSafeChildPath } from '@backstage/backend-plugin-api'; import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; import fs from 'fs-extra'; import { z } from 'zod'; @@ -62,7 +63,7 @@ export const createNewFileAction = () => { async handler(ctx) { await fs.outputFile( - `${ctx.workspacePath}/${ctx.input.filename}`, + resolveSafeChildPath(ctx.workspacePath, ctx.input.filename), ctx.input.contents, ); }, @@ -90,6 +91,7 @@ The `createTemplateAction` takes an object which specifies the following: You can also choose to define your custom action using JSON schema instead of `zod`: ```ts title="With JSON Schema" +import { resolveSafeChildPath } from '@backstage/backend-plugin-api'; import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; import { writeFile } from 'fs'; @@ -118,7 +120,7 @@ export const createNewFileAction = () => { async handler(ctx) { const { signal } = ctx; await writeFile( - `${ctx.workspacePath}/${ctx.input.filename}`, + resolveSafeChildPath(ctx.workspacePath, ctx.input.filename), ctx.input.contents, { signal }, _ => {}, diff --git a/docs/features/software-templates/writing-templates.md b/docs/features/software-templates/writing-templates.md index 13dbe6da4b..71ca0c56ae 100644 --- a/docs/features/software-templates/writing-templates.md +++ b/docs/features/software-templates/writing-templates.md @@ -891,7 +891,7 @@ const scaffolderModuleCustomFilters = createBackendModule({ const backend = createBackend(); backend.add(import('@backstage/plugin-scaffolder-backend/alpha')); /* highlight-add-next-line */ -backend.add(scaffolderModuleCustomFilters()); +backend.add(scaffolderModuleCustomFilters); ``` If you still use the legacy backend system, then you will use the `createRouter()` function of the `Scaffolder plugin` @@ -947,3 +947,19 @@ Have in mind that changes in this form will not be saved on the template and is ### Custom Field Explorer The custom filed explorer allows you to select any custom field loaded on the backstage instance and test different values and configurations. + +## Presentation + +You can configure the text of the "Back", "Review", and "Create" buttons using the `spec.presentation` field of your Software Template. You might want have a Template that doesn't "Create" something but rather "Updates" it. This feature will allow you to change it as needed. Here's an example of how to use this: + +```yaml +--- +spec: + owner: scaffolder/maintainers + type: website + presentation: + buttonLabels: + backButtonText: 'Return' + createButtonText: 'Update' + reviewButtonText: 'Verify' +``` diff --git a/docs/features/techdocs/extensions.md b/docs/features/techdocs/extensions.md new file mode 100644 index 0000000000..6c69d076a4 --- /dev/null +++ b/docs/features/techdocs/extensions.md @@ -0,0 +1,62 @@ +--- +id: extensions +title: Using TechDocs Extensions +sidebar_label: Using TechDocs Extensions +description: How to use the built-in TechDocs extension points +--- + +# TechDocs Backend Extensions + +The TechDocs backend plugin provides the following extension points: + +- `techdocsPreparerExtensionPoint` + - Register a custom docs [PreparerBase extension](https://backstage.io/docs/reference/plugin-techdocs-node.preparerbase/) + - Ideal for when you want a custom type of docs created for a specific entity type +- `techdocsBuildsExtensionPoint` + - Allows overriding the build phase Winston log transport (by default does not log to console) + - Allows overriding the [DocsBuildStrategy](https://backstage.io/docs/reference/plugin-techdocs-node.docsbuildstrategy/) +- `techdocsPublisherExtensionPoint` + - Register a custom docs publisher +- `techdocsGeneratorExtensionPoint` + - Register a custom [TechdocsGenerator](https://backstage.io/docs/reference/plugin-techdocs-node.techdocsgenerator/) + +Extension points are exported from `@backstage/plugin-techdocs-backend`. + +## Examples + +### Log TechDocs Build phase details to console + +By default, the TechDocs build phase logs to the UI, but does not log to the console. However, the +`techdocsBuildsExtensionPoint` can be used to setup a custom Winston transport for TechDocs build logs. + +Here is an example of logging to console: + +```typescript jsx title="packages/backend/src/extensions/techDocsExtension.ts" +import { techdocsBuildsExtensionPoint } from '@backstage/plugin-techdocs-backend'; +import { createBackendModule } from '@backstage/backend-plugin-api'; +import { transports } from 'winston'; + +export const techDocsExtension = createBackendModule({ + pluginId: 'techdocs', + moduleId: 'techdocs-build-log-transport-extension', + register(env) { + env.registerInit({ + deps: { + build: techdocsBuildsExtensionPoint, + }, + async init({ build }) { + // You can obviously use any custom transport here... + build.setBuildLogTransport(new transports.Console()); + }, + }); + }, +}); +``` + +And then of course register this extension with the backend: + +```typescript jsx title="packages/backend/src/index.ts" +import {techDocsExtension} from "./extensions/techDocsExtension"; +... +backend.add(techDocsExtension); +``` diff --git a/docs/features/techdocs/how-to-guides.md b/docs/features/techdocs/how-to-guides.md index e47af8d1d7..7712d675f5 100644 --- a/docs/features/techdocs/how-to-guides.md +++ b/docs/features/techdocs/how-to-guides.md @@ -800,7 +800,7 @@ const techdocsCustomBuildStrategy = createBackendModule({ /* highlight-add-start */ backend.add(import('@backstage/plugin-techdocs-backend/alpha')); -backend.add(techdocsCustomBuildStrategy()); +backend.add(techdocsCustomBuildStrategy); /* highlight-add-end */ backend.start(); @@ -874,3 +874,23 @@ metadata: TechDocs supports using the [mkdocs-redirects](https://github.com/mkdocs/mkdocs-redirects/tree/master) plugin to create a redirect map for any TechDocs site. This allows broken links from renamed or moved pages in your site to be redirected to their specified replacement. TechDocs will notify the user that the page they are trying to access is no longer maintained. Then, they will be redirected. External site redirects are not supported. If an external redirect is provided, the user will instead be redirected to the index page of the documentation site. + +## Create download links for static assets + +You may want to make files available for download by your users such as PDF +documents, images, or code templates. Download links for files included in your +docs directory can be made by adding `{: download }` after a markdown link. + +``` +[Link text](https://example.com/foo.jpg){: download } +``` + +The user's browser will download the file as `download.jpg` when the link is +clicked. + +Specify a file name to control the name the file will be given when it is +downloaded: + +``` +[Link text](https://example.com/foo.jpg){: download="foo.jpg" } +``` diff --git a/docs/features/techdocs/using-cloud-storage.md b/docs/features/techdocs/using-cloud-storage.md index 6ba826ea62..bdafb3532c 100644 --- a/docs/features/techdocs/using-cloud-storage.md +++ b/docs/features/techdocs/using-cloud-storage.md @@ -120,6 +120,36 @@ techdocs: Your Backstage app is now ready to use Google Cloud Storage for TechDocs, to store and read the static generated documentation files. +### Extending default Storage configuration + +If you need a non-standard configuration of Google Cloud Storage client, +`TechdocsPublisherExtensionPoint` is something you should look at. +You can register custom `StorageOptions` that will be used to configure the client. To do so, you +need to register publisher settings inside your module init, like in the following example: + +```typescript +export const gcsPublisherCustomizer = createBackendModule({ + pluginId: 'techdocs', + moduleId: 'gcs-publisher-customizer', + register(reg) { + reg.registerInit({ + deps: { + techdocsExtensionPoint: techdocsPublisherExtensionPoint, + }, + async init({ techdocsExtensionPoint }) { + const customOptions: StorageOptions = { + userAgent: 'my-custom-user-agent', + }; + techdocsExtensionPoint.registerPublisherSettings( + 'googleGcs', + customOptions, + ); + }, + }); + }, +}); +``` + ## Configuring AWS S3 Bucket with TechDocs **1. Set `techdocs.publisher.type` config in your `app-config.yaml`** diff --git a/docs/frontend-system/architecture/00-index.md b/docs/frontend-system/architecture/00-index.md index 8585eb76fc..20a12ba1e8 100644 --- a/docs/frontend-system/architecture/00-index.md +++ b/docs/frontend-system/architecture/00-index.md @@ -18,7 +18,7 @@ Regardless of whether you are setting up your own backstage instance, developing plugins, or extending plugins with new features, it is important to understand these concepts. -The diagram below provides an overview of the different building blocks, and the other blocks that each of them interact with. +The diagram below provides an overview of the different building blocks and the other blocks that each of them interacts with. ![frontend system building blocks diagram](../../assets/frontend-system/architecture-building-blocks.drawio.svg) @@ -28,11 +28,11 @@ This is the app instance itself that you create and use as the root of your Back ### Extensions -Extensions are the building blocks that build out both the visual and non-visual structure of the application. There are both built-in extensions provided by the app itself, as well as extensions provided by plugins. Each extension is attached to a parent with which it shares data, and can have any number of children of its own. It is up to the app to wire together all extensions into a single tree known as the app extension tree. It is from this structure that the entire app can then be instantiated and rendered. +Extensions are the building blocks that build out both the visual and non-visual structure of the application. There are both built-in extensions provided by the app itself as well as extensions provided by plugins. Each extension is attached to a parent with which it shares data and can have any number of children of its own. It is up to the app to wire together all extensions into a single tree known as the app extension tree. It is from this structure that the entire app can then be instantiated and rendered. ### Plugins -Plugins provide the actual features inside an app. The size of a plugin can range from a tiny component to an entire new system in which other plugins can be composed and integrated. Plugins can be completely standalone, or build on top of each other to extend existing plugins and augment their features. Plugins can communicate with each other by composing their extensions, or by sharing Utility APIs and routes. +Plugins provide the actual features inside an app. The size of a plugin can range from a tiny component to an entire new system in which other plugins can be composed and integrated. Plugins can be completely standalone or built on top of each other to extend existing plugins and augment their features. Plugins can communicate with each other by composing their extensions or by sharing Utility APIs and routes. ### Extension Overrides @@ -40,11 +40,11 @@ In addition to the built-in extensions and extensions provided by plugins, it is ### Utility APIs -Utility APIs provide functionality that makes it easier to build plugins, make it possible for plugins to share functionality with other plugins, as well as serve as a customization point for integrators to change the behavior of the app. Each Utility API is defined by a TypeScript interface as well as a reference used to access the implementations. The implementations of Utility APIs are defined by extensions that are provided and can be overridden the same as any other extension. +Utility APIs provide functionality that makes it easier to build plugins, make it possible for plugins to share functionality with other plugins, as well as serve as a customization point for integrators to change the behaviour of the app. Each Utility API is defined by a TypeScript interface as well as a reference used to access the implementations. The implementations of Utility APIs are defined by extensions that are provided and can be overridden the same as any other extension. ### Routes -The Backstage routing system adds a layer of indirection that makes it possible for plugins to route to each other's extensions without explicit knowledge of what URL paths the extension are rendered at or if they even exist at all. It makes it possible for plugins to share routes with each other and dynamically generate concrete links at runtime. It is the responsibility of the app to resolve these links to actual URLs, but it is also possible for integrators to define their own route bindings that decide how the links should be resolved. The routing system also lets plugins define internal routes, aiding in the linking to different content in the same plugin. +The Backstage routing system adds a layer of indirection that makes it possible for plugins to route to each other's extensions without explicit knowledge of what URL paths the extensions are rendered at or if they even exist at all. It makes it possible for plugins to share routes with each other and dynamically generate concrete links at runtime. It is the responsibility of the app to resolve these links to actual URLs, but it is also possible for integrators to define their own route bindings that decide how the links should be resolved. The routing system also lets plugins define internal routes, aiding in the linking to different content in the same plugin. ## Package structure diff --git a/docs/frontend-system/architecture/25-extension-overrides.md b/docs/frontend-system/architecture/25-extension-overrides.md index 785843f6e0..faaf446f41 100644 --- a/docs/frontend-system/architecture/25-extension-overrides.md +++ b/docs/frontend-system/architecture/25-extension-overrides.md @@ -79,6 +79,48 @@ const myOverrideExtension = myExtension.override({ Note the `yield*` expression, which forwards all values from the provided iterable to the generator, in this case the original factory output. +## Overriding blueprint parameters + +If you are overriding an extension that was originally created from an [extension blueprint](./23-extension-blueprints.md), you are able to override the parameters that were originally provided for the blueprint. This can be done directly as an option to `.override`, or when calling the original factory in the override factory. The provided parameter overrides will be merged with the existing parameters that where provided when creating the extension from the blueprint. + +For example, consider the following extension created from the `PageBlueprint`: + +```tsx +const exampleExtension = PageBlueprint.make({ + params: { + loader: () => + import('./components/ExamplePage').then(m => ), + defaultPath: '/example', + }, +}); +``` + +You can immediately override parameters through the `params` option: + +```tsx +const overrideExtension = exampleExtension.override({ + params: { + loader: () => + import('./components/OverridePage').then(m => ), + }, +}); +``` + +It is also possible to pass parameter overrides when calling the original factory in the override factory: + +```tsx +const overrideExtension = exampleExtension.override({ + factory(originalFactory) { + return originalFactory({ + params: { + loader: () => + import('./components/OverridePage').then(m => ), + }, + }); + }, +}); +``` + ## Overriding declared outputs When overriding an extension you can provide a new output declaration. This **replaces** any existing output declaration, which means that if you want to forward any of the original output you will need to declare it again. The following example shows how to override an extension and replace the output declaration: @@ -263,23 +305,19 @@ const overrideExtension = exampleExtension.override({ To install extension overrides in a Backstage app you should use `plugin.withOverrides` whenever you are overriding or adding extensions for a plugin. See the section on [overriding a plugin](./15-plugins.md#overriding-a-plugin) for more information. -There is also a `createExtensionOverrides` function that can be used to install a collection of standalone extensions in an app. This method will be replaced with a different mechanism in the future, but for now remains the only way to override the built-in extensions in the app or to package extensions for a plugin package separate from the plugin itself. - Note that while using either of these options you don't necessarily need to use the extension `.override(...)` method to create the overrides. You can also create new extensions with `createExtension` or a blueprint that are either completely net-new extensions, or override an existing extension by using the same `kind`, `namespace` and `name` to produce the same extension ID. -### Creating a standalone extension bundle +### Creating a frontend module -The following example shows how to create a standalone extension bundle that overrides the search page from the search plugin: +The following example shows how to create a frontend module that overrides the search page from the search plugin: ```tsx import { createPageExtension, - createExtensionOverrides, + createFrontendModule, } from '@backstage/frontend-plugin-api'; const customSearchPage = PageBlueprint.make({ - // Since this is a standalone extension we need to provide the namespace to match the search plugin - namespace: 'search', params: { defaultPath: '/search', loader: () => @@ -287,7 +325,8 @@ const customSearchPage = PageBlueprint.make({ }, }); -export default createExtensionOverrides({ +export default createFrontendModule({ + pluginId: 'search', extensions: [customSearchPage], }); ``` @@ -296,12 +335,14 @@ Assuming the above code resides in the `@internal/search-page` package, you can ```tsx title="packages/app/src/App.tsx" import { createApp } from '@backstage/frontend-defaults'; -import searchPageOverride from '@internal/search-page'; +import searchPageModule from '@internal/search-page'; const app = createApp({ // highlight-next-line - features: [searchPageOverride], + features: [searchPageModule], }); export default app.createRoot(); ``` + +You must define a `pluginId` when creating a frontend module, and the plugin must also be installed for the module to be loaded. diff --git a/docs/frontend-system/architecture/36-routes.md b/docs/frontend-system/architecture/36-routes.md index 2a9b372b1c..8ed3024edd 100644 --- a/docs/frontend-system/architecture/36-routes.md +++ b/docs/frontend-system/architecture/36-routes.md @@ -251,6 +251,8 @@ app: # point to the Catalog details page when the Scaffolder component details ref is used # highlight-next-line scaffolder.componentDetails: catalog.details + # explicitly disable the default route binding from the scaffolder to the catalog import page + scaffolder.registerComponent: false ``` 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: @@ -268,6 +270,7 @@ const app = createApp({ }); bind(scaffolder.externalRoutes, { componentDetails: catalog.routes.details, + registerComponent: false, }); }, // highlight-end diff --git a/docs/frontend-system/architecture/60-migrations.md b/docs/frontend-system/architecture/60-migrations.md index a1ab0197f7..9e84899dc2 100644 --- a/docs/frontend-system/architecture/60-migrations.md +++ b/docs/frontend-system/architecture/60-migrations.md @@ -14,6 +14,94 @@ This section provides migration guides for different versions of the frontend sy This guide is intended for app and plugin authors who have already migrated their code to the new frontend system, and are looking to keep it up to date with the latest changes. These guides do not cover trivial migrations that can be explained in a deprecation message, such as a renamed export. +## 1.31 + +### `namespace` parameter should be removed + +The `namespace` parameter to all `createExtension`, `createExtensionBlueprint` or any `.make()` or `.makeWithOverrides()` method can be removed. This will now default to the `id` of the `plugin` which should already be the case. + +### `createExtensionOverrides` -> `createFrontendModule` + +Extensions will need to be wrapped in a module in order to be installed in the frontend. This means that the `createExtensionOverrides` function should be replaced with `createFrontendModule`, and the `pluginId` parameter should be set with the target `pluginId` that you're overriding. + +For example: + +```tsx +import { + createPageExtension, + createExtensionOverrides, +} from '@backstage/frontend-plugin-api'; + +const customSearchPage = PageBlueprint.make({ + namespace: 'search', + params: { + defaultPath: '/search', + loader: () => + import('./CustomSearchPage').then(m => ), + }, +}); + +export default createExtensionOverrides({ + extensions: [customSearchPage], +}); +``` + +Should now look like this: + +```tsx +import { + createPageExtension, + createFrontendModule, +} from '@backstage/frontend-plugin-api'; + +const customSearchPage = PageBlueprint.make({ + params: { + defaultPath: '/search', + loader: () => + import('./CustomSearchPage').then(m => ), + }, +}); + +export default createFrontendModule({ + pluginId: 'search', + extensions: [customSearchPage], +}); +``` + +### Moved `createApp` + +The `createApp` function has been moved to the new `@backstage/frontend-defaults` package. The old export from `@backstage/frontend-app-api` is now deprecated and should be replaced with the new one. + +### Removed support for "v1" extensions + +Extensions created with `@backstage/frontend-plugin-api` from before the 1.30 release are no longer supported by `createApp`. To be able to use extensions in a new app, they need to be created with `@backstage/frontend-plugin-api` version 0.7.0 or later. + +### New type parameters for `ExtensionDefinition` and `ExtensionBlueprint` + +The type parameters of `ExtensionDefinition` and `ExtensionBlueprint` have been updated to use a single type parameter with an object, in order to make them easier to read and evolve. + +Existing usage can generally be updated as follows: + +`ExtensionDefinition` -> `ExtensionDefinition` +`ExtensionDefinition` -> `ExtensionDefinition` +`ExtensionDefinition` -> `ExtensionDefinition<{ config: TConfig }>` +`ExtensionDefinition` -> `ExtensionDefinition<{ config: TConfig, configInput: TConfigInput }>` + +If you need to infer the parameter you can use `ExtensionDefinitionParameters` and `ExtensionBlueprintParameters`, for example: + +```tsx +import { + ExtensionDefinition, + ExtensionDefinitionParameters, +} from '@backstage/frontend-plugin-api'; + +function myUtility( + ext: ExtensionDefinition, +): T['config'] { + // ... +} +``` + ## 1.30 ### Reworked extension inputs and outputs diff --git a/docs/frontend-system/building-apps/08-migrating.md b/docs/frontend-system/building-apps/08-migrating.md index 96e7dd2bd5..6efd0c7841 100644 --- a/docs/frontend-system/building-apps/08-migrating.md +++ b/docs/frontend-system/building-apps/08-migrating.md @@ -95,7 +95,7 @@ At this point the contents of your app should be past the initial migration stag ## Migrating `createApp` Options -Many of the `createApp` options have been migrated to use extensions instead. Each will have their own [extension blueprint](../architecture/23-extension-blueprints.md) that you use to create a custom extension. To add these standalone extensions to the app they need to be passed to `createExtensionOverrides`, which bundles them into a _feature_ that you can install in the app. See the [standalone extensions](../architecture/25-extension-overrides.md#creating-a-standalone-extension-bundle) section for more information. +Many of the `createApp` options have been migrated to use extensions instead. Each will have their own [extension blueprint](../architecture/23-extension-blueprints.md) that you use to create a custom extension. To add these standalone extensions to the app they need to be passed to `createFrontendModule`, which bundles them into a _feature_ that you can install in the app. See the [frontend module](../architecture/25-extension-overrides.md#creating-a-frontend-module) section for more information. For example, assuming you have a `lightTheme` extension that you want to add to your app, you can use the following: @@ -103,7 +103,8 @@ For example, assuming you have a `lightTheme` extension that you want to add to const app = createApp({ features: [ // highlight-add-start - createExtensionOverrides({ + createFrontendModule({ + pluginId: 'app', extensions: [lightTheme], }), // highlight-add-end @@ -287,6 +288,7 @@ const app = createApp({ ), }, ], +}); ``` Can be converted to the following extension: @@ -342,7 +344,8 @@ const exampleIconBundle = IconBundleBlueprint.make({ const app = createApp({ features: [ - createExtensionOverrides({ + createFrontendModule({ + pluginId: 'app', extensions: [exampleIconBundle], }), ], @@ -567,7 +570,8 @@ Here is an example converting the `CustomAppBarrier` into extension: createApp({ // ... features: [ - createExtensionOverrides({ + createFrontendModule({ + pluginId: 'app', extensions: [ AppRootWrapperBlueprint.make({ name: 'custom-app-barrier', diff --git a/docs/frontend-system/building-plugins/03-common-extension-blueprints.md b/docs/frontend-system/building-plugins/03-common-extension-blueprints.md index 5193fd85b1..d08de7012d 100644 --- a/docs/frontend-system/building-plugins/03-common-extension-blueprints.md +++ b/docs/frontend-system/building-plugins/03-common-extension-blueprints.md @@ -50,14 +50,14 @@ Translation extension provide custom translation messages for the app. They can These are the [extension blueprints](../architecture/23-extension-blueprints.md) provided by the Backstage core feature plugins. -### EntityCard - [Reference](https://github.com/backstage/backstage/blob/master/plugins/catalog-react/api-report-alpha.md) +### EntityCard - [Reference](https://github.com/backstage/backstage/blob/master/plugins/catalog-react/report-alpha.api.md) Creates entity cards to be displayed on the entity pages of the catalog plugin. Exported as `EntityCardBlueprint`. -### EntityContent - [Reference](https://github.com/backstage/backstage/blob/master/plugins/catalog-react/api-report-alpha.md) +### EntityContent - [Reference](https://github.com/backstage/backstage/blob/master/plugins/catalog-react/report-alpha.api.md) Creates entity content to be displayed on the entity pages of the catalog plugin. Exported as `EntityContentBlueprint`. -### SearchResultListItem - [Reference](https://github.com/backstage/backstage/blob/master/plugins/search-react/api-report-alpha.md) +### SearchResultListItem - [Reference](https://github.com/backstage/backstage/blob/master/plugins/search-react/report-alpha.api.md) Creates search result list items for different types of search results, to be displayed in search result lists. Exported as `SearchResultListItemBlueprint`. diff --git a/docs/frontend-system/utility-apis/04-configuring.md b/docs/frontend-system/utility-apis/04-configuring.md index e403104506..4847fc6eaf 100644 --- a/docs/frontend-system/utility-apis/04-configuring.md +++ b/docs/frontend-system/utility-apis/04-configuring.md @@ -41,13 +41,14 @@ Like with other extension types, you replace Utility APIs with your own custom i ```tsx title="in your app" /* highlight-add-start */ -import { createExtensionOverrides } from '@backstage/frontend-plugin-api'; +import { createFrontendModule } from '@backstage/frontend-plugin-api'; class CustomWorkImpl implements WorkApi { /* ... */ } -const myOverrides = createExtensionOverrides({ +const workModule = createFrontendModule({ + pluginId: 'work', extensions: [ ApiBlueprint.make({ params: { @@ -66,7 +67,7 @@ export default createApp({ features: [ // ... other features /* highlight-add-next-line */ - myOverrides, + workModule, ], }); ``` diff --git a/docs/getting-started/app-custom-theme.md b/docs/getting-started/app-custom-theme.md index 4c013440da..1bff5b1eb0 100644 --- a/docs/getting-started/app-custom-theme.md +++ b/docs/getting-started/app-custom-theme.md @@ -48,6 +48,8 @@ import { createApp } from '@backstage/app-defaults'; import { ThemeProvider } from '@material-ui/core/styles'; import CssBaseline from '@material-ui/core/CssBaseline'; import LightIcon from '@material-ui/icons/WbSunny'; +import { UnifiedThemeProvider} from '@backstage/theme'; +import { myTheme } from './themes/myTheme'; const app = createApp({ apis: ..., diff --git a/docs/getting-started/config/authentication.md b/docs/getting-started/config/authentication.md index 5d0262c682..2442d2b767 100644 --- a/docs/getting-started/config/authentication.md +++ b/docs/getting-started/config/authentication.md @@ -8,7 +8,7 @@ Audience: Admins or Developers ## Summary -We'll be walking you through how to setup authentication for your Backstage app using Github. After finishing this guide, you'll have both working authentication and users in your Backstage app to match to the users logging in! +We'll be walking you through how to setup authentication for your Backstage app using GitHub. After finishing this guide, you'll have both working authentication and users in your Backstage app to match to the users logging in! There are multiple authentication providers available for you to use with Backstage, feel free to follow [their instructions for adding authentication](../../auth/index.md). diff --git a/docs/getting-started/index.md b/docs/getting-started/index.md index 8bb30d1db8..0d5529f611 100644 --- a/docs/getting-started/index.md +++ b/docs/getting-started/index.md @@ -23,11 +23,11 @@ If you are planning to contribute a new feature or bug fix to the Backstage proj This guide assumes a basic understanding of working on a Linux based operating system and have some experience with the terminal, specifically, these commands: `npm`, `yarn`. -- Access to a Unix-based operating system, such as Linux, MacOS or +- Access to a Unix-based operating system, such as Linux, macOS or [Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/) - A GNU-like build environment available at the command line. For example, on Debian/Ubuntu you will want to have the `make` and `build-essential` packages installed. - On MacOS, you will want to have run `xcode-select --install` to get the XCode command line build tooling in place. + On macOS, you will want to have run `xcode-select --install` to get the XCode command line build tooling in place. - An account with elevated rights to install the dependencies - `curl` or `wget` installed - Node.js [Active LTS Release](https://nodejs.org/en/about/previous-releases) installed using one of these @@ -111,7 +111,7 @@ If this fails on the `yarn install` step, it's likely that you will need to inst ## 2. Run the Backstage app -You Backstage app is fully installed and ready to be run! Now that the installation is complete, you can go to the application directory and start the app using the `yarn dev` command. The `yarn dev` command will run both the frontend and backend as separate processes (named `[0]` and `[1]`) in the same window. +Your Backstage app is fully installed and ready to be run! Now that the installation is complete, you can go to the application directory and start the app using the `yarn dev` command. The `yarn dev` command will run both the frontend and backend as separate processes (named `[0]` and `[1]`) in the same window. ```bash cd my-backstage-app # your app name diff --git a/docs/getting-started/logging-in.md b/docs/getting-started/logging-in.md index 7d6fb5d55b..16596865a2 100644 --- a/docs/getting-started/logging-in.md +++ b/docs/getting-started/logging-in.md @@ -12,7 +12,7 @@ This guide will provide a quick tutorial on how to log in to your Backstage inst ## Prerequisites -You should have already [have a standalone app](./index.md) and completed the Github OAuth app setup defined in [the authentication tutorial](./config/authentication.md). +You should have already [have a standalone app](./index.md) and completed the GitHub OAuth app setup defined in [the authentication tutorial](./config/authentication.md). ## 1. Login to Backstage @@ -22,13 +22,13 @@ If you're not already logged in, you should see a login screen like this, ![Screenshot of the login screen](../assets/getting-started/login-screen.png) -To login, you should choose the "Github" provider and click the "Sign in" button. This will redirect you to a Github OAuth page. Verify that the scopes mentioned on that page match the setup you did in [the authentication tutorial](./config/authentication.md). Once you click "Confirm", you will be brought back to the Backstage interface and signed in! +To login, you should choose the "GitHub" provider and click the "Sign in" button. This will redirect you to a GitHub OAuth page. Verify that the scopes mentioned on that page match the setup you did in [the authentication tutorial](./config/authentication.md). Once you click "Confirm", you will be brought back to the Backstage interface and signed in! If you are already logged in, you will be automatically brought to your Backstage instance. ## 2. Verify that you're logged in -Once you've logged in, find the "Settings" item in the navigation bar to the left. Click it and you will see your profile. If you see your profile picture and name from Github here, congratulations! You've successfully set up a Github authentication integration. +Once you've logged in, find the "Settings" item in the navigation bar to the left. Click it and you will see your profile. If you see your profile picture and name from GitHub here, congratulations! You've successfully set up a GitHub authentication integration. diff --git a/docs/integrations/bitbucketCloud/discovery.md b/docs/integrations/bitbucketCloud/discovery.md index 6ba9c0aa1f..102feb46d7 100644 --- a/docs/integrations/bitbucketCloud/discovery.md +++ b/docs/integrations/bitbucketCloud/discovery.md @@ -51,33 +51,6 @@ Further documentation: ### Installation with Legacy Backend System -#### Installation without Events Support - -And then add the entity provider to your catalog builder: - -```ts title="packages/backend/src/plugins/catalog.ts" -/* highlight-add-next-line */ -import { BitbucketCloudEntityProvider } from '@backstage/plugin-catalog-backend-module-bitbucket-cloud'; - -export default async function createPlugin( - env: PluginEnvironment, -): Promise { - const builder = await CatalogBuilder.create(env); - /* highlight-add-start */ - builder.addEntityProvider( - BitbucketCloudEntityProvider.fromConfig(env.config, { - logger: env.logger, - scheduler: env.scheduler, - }), - ); - /* highlight-add-end */ - - // .. -} -``` - -#### Installation with Events Support - Please follow the installation instructions at - @@ -104,19 +77,17 @@ export default async function createPlugin( env: PluginEnvironment, ): Promise { const builder = await CatalogBuilder.create(env); - builder.addProcessor(new ScaffolderEntitiesProcessor()); /* highlight-add-start */ const bitbucketCloudProvider = BitbucketCloudEntityProvider.fromConfig( env.config, { + auth: env.auth, catalogApi: new CatalogClient({ discoveryApi: env.discovery }), events: env.events, logger: env.logger, scheduler: env.scheduler, - tokenManager: env.tokenManager, }, ); - env.eventBroker.subscribe(bitbucketCloudProvider); builder.addEntityProvider(bitbucketCloudProvider); /* highlight-add-end */ const { processingEngine, router } = await builder.build(); diff --git a/docs/integrations/github/org.md b/docs/integrations/github/org.md index 61e42567a9..22b55fee98 100644 --- a/docs/integrations/github/org.md +++ b/docs/integrations/github/org.md @@ -169,7 +169,7 @@ const backend = createBackend(); backend.add(import('@backstage/plugin-catalog-backend/alpha')); -backend.add(githubOrgModule()); +backend.add(githubOrgModule); backend.start(); ``` diff --git a/docs/integrations/gitlab/discovery.md b/docs/integrations/gitlab/discovery.md index 79bd37061a..10746aff88 100644 --- a/docs/integrations/gitlab/discovery.md +++ b/docs/integrations/gitlab/discovery.md @@ -34,9 +34,9 @@ Then add the following to your backend initialization: // optional if you want to use AWS SQS instead of HTTP endpoints to receive external events // backend.add(import('@backstage/plugin-events-backend-module-aws-sqs/alpha')); // optional - event router for gitlab. See.: https://github.com/backstage/backstage/blob/master/plugins/events-backend-module-gitlab/README.md -// backend.add(eventsModuleGitlabEventRouter()); +// backend.add(eventsModuleGitlabEventRouter); // optional - token validator for the gitlab topic -// backend.add(eventsModuleGitlabWebhook()); +// backend.add(eventsModuleGitlabWebhook); backend.add(import('@backstage/plugin-catalog-backend-module-gitlab/alpha')); ``` diff --git a/docs/integrations/gitlab/org.md b/docs/integrations/gitlab/org.md index 24b64d1116..c13db4401b 100644 --- a/docs/integrations/gitlab/org.md +++ b/docs/integrations/gitlab/org.md @@ -39,9 +39,9 @@ Then add the following to your backend initialization: // optional if you want to use AWS SQS instead of HTTP endpoints to receive external events // backend.add(import('@backstage/plugin-events-backend-module-aws-sqs/alpha')); // optional - event router for gitlab. See.: https://github.com/backstage/backstage/blob/master/plugins/events-backend-module-gitlab/README.md -// backend.add(eventsModuleGitlabEventRouter()); +// backend.add(eventsModuleGitlabEventRouter); // optional - token validator for the gitlab topic -// backend.add(eventsModuleGitlabWebhook()); +// backend.add(eventsModuleGitlabWebhook); backend.add(import('@backstage/plugin-catalog-backend-module-gitlab-org')); ``` @@ -171,7 +171,10 @@ catalog: host: gitlab.com orgEnabled: true group: org/teams # Required for gitlab.com when `orgEnabled: true`. Optional for self managed. Must not end with slash. Accepts only groups under the provided path (which will be stripped) - allowInherited: true # Allow groups to be ingested even if there are no direct members. + relations: # Optional + - INHERITED # Optional. Members of any ancestor groups will also be considered members of the current group. + - DESCENDANTS # Optional. Members of any descendant groups will also be considered members of the current group. + - SHARED_FROM_GROUPS # Optional. Members of any invited groups will also be considered members of the current group. groupPattern: '[\s\S]*' # Optional. Filters found groups based on provided pattern. Defaults to `[\s\S]*`, which means to not filter anything schedule: # Same options as in SchedulerServiceTaskScheduleDefinition. Optional for the Legacy Backend System. # supports cron, ISO duration, "human duration" as used in code @@ -193,6 +196,32 @@ entities will only be ingested for the configured group, or its descendant group but not any ancestor groups higher than the configured group path. Only groups which contain members will be ingested. +### Subgroup Membership + +GitLab groups and subgroups provide a hierarchical structure for organizing projects and users. Membership in a parent group extends automatically to its subgroups, ensuring consistent permissions at all levels. Additionally, membership can be managed using invited groups, where one group can be added to another. For Backstage users integrating with GitLab, understanding this [inheritance model](https://docs.gitlab.co.jp/ee/user/group/subgroups/#subgroup-membership) and the concept of invited groups is crucial for accurately mapping and managing group and user entities. + +The `GitLabOrgDiscoveryEntityProvider` mirrors GitLab's membership behavior as follows: + +- By default, every direct member of a GitLab group is also a member of the corresponding group in Backstage. +- To include members of subgroups as members of the parent group, configure the `relations` array with the `DESCENDANTS` option. +- To include members of parent groups as members of their subgroups, configure the `relations` array with the `INHERITED` option. This also has the effect that subgroups with no direct members will not be skipped in the group ingestion process and will be added as a group entity in Backstage; +- To include members of invited groups as members of the inviting group, configure the `relations` array with the `SHARED_FROM_GROUPS` option. + +The previous `allowInherited` will be deprecated in future versions. Use the `relations` array with the `INHERITED` option instead. + +```yaml +catalog: + providers: + gitlab: + development: + relations: + - INHERITED + - DESCENDANTS + - SHARED_FROM_GROUPS +``` + +Refer to the [GitLab Group Member Relation](https://docs.gitlab.com/ee/api/graphql/reference/#groupmemberrelation) documentation for more information. + ### Users For self hosted, all `User` entities are ingested from the entire instance by default. @@ -202,6 +231,8 @@ of the top-level group for the configured group path will be ingested. In both cases (SaaS & self hosted), you can limit the ingested users to users directly assigned to the group defined in your `app-config.yaml` by setting the configuration key `restrictUsersToGroup: true`. This is especially useful when you have a large user base that you don't want to import by default. +On SaaS, you can choose to include users to be ingested that do not have a paid seat. This can be useful when using a free version of Gitlab, or when you use Guest Users on Gitlab Ultimate. Unfortunately, this will also lead to some technical users that might be imported into your user base. While project & group access tokens are filtered, service accounts will remain. [Learn more about Billable Users](https://docs.gitlab.com/ee/subscriptions/self_managed/index.html#billable-users). + ```yaml catalog: providers: @@ -210,7 +241,8 @@ catalog: host: gitlab.com ## Could also be self hosted. orgEnabled: true group: org/teams # Required for gitlab.com when `orgEnabled: true`. Optional for self managed. Must not end with slash. Accepts only groups under the provided path (which will be stripped) - restrictUsersToGroup: true # Backstage will ingest only users directly assigned to org/teams. + restrictUsersToGroup: true # Optional: Backstage will ingest only users directly assigned to org/teams. + includeUsersWithoutSeat: false # Optional: Set to true to include users without paid seat, only applicable for SaaS ``` ### Limiting `User` and `Group` entity ingestion in the provider diff --git a/docs/notifications/index.md b/docs/notifications/index.md index 86a67ce211..ddbb156dac 100644 --- a/docs/notifications/index.md +++ b/docs/notifications/index.md @@ -33,7 +33,7 @@ Example of use-cases: ## Installation in Older Environments -Newer versions of instances created by the create-app have both the notifications and signals plugins included by default, this section can be skipped right to the Configuration. +Newer versions of instances created by the create-app have both the notifications and signals plugins included by default; this section can be skipped right to the Configuration. Following installation instructions are valid for enabling the plugins in older environments. @@ -136,15 +136,15 @@ If the signals plugin is properly configured, it will be automatically discovere The Notifications backend plugin provides an API to create notifications, list notifications per logged-in user, and search based on parameters. -The plugin uses a relational [database](https://backstage.io/docs/getting-started/config/database) for persistence, no specifics are introduced in this context. +The plugin uses a relational [database](https://backstage.io/docs/getting-started/config/database) for persistence; no specifics are introduced in this context. No additional configuration in the app-config is needed, except for optional additional modules for `processors`. ### Notifications Frontend -The recipients of notifications have to be entities in the catalog, e.g. of the User or Group kind. +The recipients of notifications have to be entities in the catalog, e.g., of the User or Group kind. -Otherwise no specific configuration is needed for the front-end notifications plugin. +Otherwise, no specific configuration is needed for the front-end notifications plugin. All parametrization is done through component properties, such as the `NotificationsSidebarItem`, which can be used as an active left-side menu item in the front-end. @@ -196,7 +196,7 @@ notificationService.send({ }); ``` -Refer the [API documentation](https://github.com/backstage/backstage/blob/master/plugins/notifications-node/api-report.md) for further details. +Refer the [API documentation](https://github.com/backstage/backstage/blob/master/plugins/notifications-node/report.api.md) for further details. ### Signals diff --git a/docs/openapi/definitions/auth.yaml b/docs/openapi/definitions/auth.yaml index 1ed649da9c..07b18866c6 100644 --- a/docs/openapi/definitions/auth.yaml +++ b/docs/openapi/definitions/auth.yaml @@ -9,7 +9,7 @@ info: The purpose of the Auth APIs in Backstage are to identify the user, and to provide a way for plugins to request access to 3rd party services on behalf of that user. - The API is supplied with a list of providers - such as `Google` or `Github` - and will add the endpoints + The API is supplied with a list of providers - such as `Google` or `GitHub` - and will add the endpoints described below to each of those providers. Read more about [User Authentication and Authorization in Backstage](https://github.com/backstage/backstage/blob/master/docs/auth/overview.md). diff --git a/docs/overview/threat-model.md b/docs/overview/threat-model.md index 74c055a86c..2b78d022f9 100644 --- a/docs/overview/threat-model.md +++ b/docs/overview/threat-model.md @@ -41,13 +41,13 @@ The built-in protection against unauthorized access does not by default include ## Common Backend Configuration -There are many common facilities that are configured centrally and available to all Backstage backend plugins. For example there is a `DatabaseManager` that provides access to a SQL database, `SchedulerService` for scheduling long-running tasks, `Logger` as a general logging facility, and `UrlReader` for reading content from external sources. These are all configured either directly in code, or within the `backend` block of the static configuration. The appropriate care needs to be taken to ensure that any secrets remain confidential and no malicious configuration is injected. +There are many common facilities that are configured centrally and available to all Backstage backend plugins. For example there is a `DatabaseService` that provides access to a SQL database, `SchedulerService` for scheduling long-running tasks, `LoggerService` as a general logging facility, and `UrlReaderService` for reading content from external sources. These are all configured either directly in code, or within the `backend` block of the static configuration. The appropriate care needs to be taken to ensure that any secrets remain confidential and no malicious configuration is injected. In a typical Backstage setup, there is no boundary between plugins that run on the same host. Likewise, there is no boundary between plugins that share the same database access. Any plugin that is running on a host that has access to the logical database of any other plugin should be considered to have full access to that other plugin. For example, even if you deploy the `auth` and `catalog` plugins on separate hosts with separate configuration and credentials, the `catalog` plugin is still considered to have full access to the `auth` plugin as long as the `catalog` plugin has access to the `auth` plugin's logical database. The only way to create a boundary between the two plugins is to deploy them in such a way that they do not have access to each others’ database. This applies to the database facility as well as any other shared resources, such as the cache. -The `UrlReader` facility is of particular interest for a secure Backstage configuration. In particular the `backend.reading.allow` configuration lists the hosts that you trust the backend to be able to read content from on behalf of users. It is extremely important that this list does not, for example, allow access to instance metadata endpoints of cloud providers, or other endpoints that your Backstage instance may have access to which contain sensitive information. In general it is recommended to keep the list minimal and only allow reading from required endpoints. The same concerns apply to custom implementations of the `UrlReader` interface, if you need to implement these through code. +The `UrlReaderService` facility is of particular interest for a secure Backstage configuration. In particular the `backend.reading.allow` configuration lists the hosts that you trust the backend to be able to read content from on behalf of users. It is extremely important that this list does not, for example, allow access to instance metadata endpoints of cloud providers, or other endpoints that your Backstage instance may have access to which contain sensitive information. In general it is recommended to keep the list minimal and only allow reading from required endpoints. The same concerns apply to custom implementations of the `UrlReader` interface, if you need to implement these through code. -Note that the `UrlReader` system operates with a service context and is not integrated with the Backstage permission system or other external access control mechanisms. This means users of your Backstage instance may be able to read external content which that individual should not have access to. For example, the `$text` placeholder in a `catalog-info.yaml` can be used to read contents from a source such as a GitHub repository that the user does not have direct access too. If this is a concern it is recommended to either disable or replace the resolvers in the catalog placeholder processor and similar features in any other plugin. +Note that the `UrlReaderService` system operates with a service context and is not integrated with the Backstage permission system or other external access control mechanisms. This means users of your Backstage instance may be able to read external content which that individual should not have access to. For example, the `$text` placeholder in a `catalog-info.yaml` can be used to read contents from a source such as a GitHub repository that the user does not have direct access too. If this is a concern it is recommended to either disable or replace the resolvers in the catalog placeholder processor and similar features in any other plugin. ## Authentication @@ -79,7 +79,7 @@ By default all internal users are allowed to create and delete entities. If this By default, Scaffolding jobs execute directly on the host machine, including any actions defined in the template. Because the Scaffolder templates are considered a more sensitive area it is recommended to control access to create and update templates to trusted parties. Template execution is intended to be secure regardless of input, but we still recommend this additional layer of protection. The string templating is executed in a [node VM sandbox](https://github.com/laverdet/isolated-vm) to mitigate the possibility of remote code execution attacks. -The Scaffolder often has elevated permissions to for example create repositories in a Github organization. The operator should therefore be cautious of Scaffolder Templates that for example delete or update existing resources as the user input is typically user defined and can therefore delete or modify resources maliciously or by mistake. +The Scaffolder often has elevated permissions to for example create repositories in a GitHub organization. The operator should therefore be cautious of Scaffolder Templates that for example delete or update existing resources as the user input is typically user defined and can therefore delete or modify resources maliciously or by mistake. One strategy that allows you to reduce the access that the Scaffolder service has is to rely on user credentials when executing actions. For example, a GitHub App integration could be configured with read-only permissions, with a separate user OAuth token used to create repositories. This requires that your users have access to create repositories in the first place. diff --git a/docs/permissions/getting-started.md b/docs/permissions/getting-started.md index d2c487e6ea..118282bbd4 100644 --- a/docs/permissions/getting-started.md +++ b/docs/permissions/getting-started.md @@ -87,7 +87,7 @@ To help validate the permission framework is setup we'll create a Test Permissio // permission plugin backend.add(import('@backstage/plugin-permission-backend/alpha')); /* highlight-add-next-line */ - backend.add(import('./extensions/permissionPolicyExtension')); + backend.add(import('./extensions/permissionsPolicyExtension')); ``` You now have a Test Permission Policy in place, this will help us test that the permission framework is working in the next section. diff --git a/docs/plugins/integrating-plugin-into-software-catalog.md b/docs/plugins/integrating-plugin-into-software-catalog.md index 1ec3df69cf..d47be7f4c0 100644 --- a/docs/plugins/integrating-plugin-into-software-catalog.md +++ b/docs/plugins/integrating-plugin-into-software-catalog.md @@ -54,7 +54,7 @@ To begin, you will need to import your plugin in the entities page. Located at your backstage app. ```tsx -import { MyPluginEntityContent } from '@backstage/plugin-my-plugin; +import { MyPluginEntityContent } from '@backstage/plugin-my-plugin'; ``` To add your component to the Entity view, you will need to modify the diff --git a/docs/plugins/new-backend-system.md b/docs/plugins/new-backend-system.md index e8a2ca1b19..12525b9f95 100644 --- a/docs/plugins/new-backend-system.md +++ b/docs/plugins/new-backend-system.md @@ -101,7 +101,7 @@ export const examplePlugin = createBackendPlugin({ The plugin can then be installed in the backend using the returned plugin factory function: ```ts -backend.add(examplePlugin()); +backend.add(examplePlugin); ``` If we wanted our plugin to accept options as well, we'd accept the options as the second parameter of the register method: @@ -266,7 +266,7 @@ class GoogleCloudLogger implements LoggerService { const backend = createBackend(); // supplies additional or replacement services to the backend -backend.add(GoogleCloudLogger.factory()); +backend.add(GoogleCloudLogger.factory); ``` ## Testing diff --git a/docs/publishing.md b/docs/publishing.md index 50d78ebf09..740292949f 100644 --- a/docs/publishing.md +++ b/docs/publishing.md @@ -51,7 +51,7 @@ Additional steps for the main line release - Mention any security fixes - Create Release Notes PR - Add the release note file as [`/docs/releases/vx.y.0.md`](./releases) - - Add an entry to [`/microsite/sidebar.json`](https://github.com/backstage/backstage/blob/master/microsite/sidebars.json) for the release note + - Add an entry to [`/microsite/sidebar.js`](https://github.com/backstage/backstage/blob/master/microsite/sidebars.js) for the release note - Update the navigation bar item in [`/microsite/docusaurus.config.ts`](https://github.com/backstage/backstage/blob/master/microsite/docusaurus.config.ts) to point to the new release note - Finally copy the content, without the metadata header, into the description of the [`Version Packages` Pull Request](https://github.com/backstage/backstage/pulls?q=is%3Aopen+is%3Apr+in%3Atitle+%22Version+Packages) diff --git a/docs/releases/v1.31.0-changelog.md b/docs/releases/v1.31.0-changelog.md new file mode 100644 index 0000000000..9f0868c042 --- /dev/null +++ b/docs/releases/v1.31.0-changelog.md @@ -0,0 +1,3633 @@ +# Release v1.31.0 + +Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.31.0](https://backstage.github.io/upgrade-helper/?to=1.31.0) + +## @backstage/backend-app-api@1.0.0 + +### Major Changes + +- ec1b4be: Release 1.0 of the new backend system! :tada: + + The backend system is finally getting promoted to 1.0.0. This means that the API is now stable and breaking changes should not occur until version 2.0.0, see our [package versioning policy](https://backstage.io/docs/overview/versioning-policy/#package-versioning-policy) for more information what this means. + + This release also marks the end of the old backend system based on `createRouter` exports. Going forward backend plugins packages will start to deprecate and later this year remove exports supporting the old backend system. If you would like to help out with this transition, see or consult the [migration guide](https://backstage.io/docs/backend-system/building-plugins-and-modules/migrating/#remove-support-for-the-old-backend-system). + +### Minor Changes + +- 19ff127: **BREAKING**: The deprecated `identityServiceFactory` and `tokenManagerServiceFactory` have been removed. +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- cd38da8: Deprecate the `featureDiscoveryServiceFactory` in favor of using `@backstage/backend-defaults#discoveryFeatureLoader` instead. +- 8ccf784: All created backend instances now share a the same `process` exit listeners, and on exit the process will wait for all backend instances to shut down before exiting. This fixes the `EventEmitter` leak warnings in tests. +- 6ed9264: chore(deps): bump `path-to-regexp` from 6.2.2 to 8.0.0 +- c246372: Updated the error message for missing service dependencies to include the plugin and module IDs. +- 7f779c7: `auth.externalAccess` should be optional in the config schema +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- 51a69b5: Fix feature loaders in CJS double-default nested builds +- 0b2a402: Updates to the config schema to match reality +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/plugin-permission-node@0.8.3 + - @backstage/config-loader@1.9.1 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/backend-plugin-api@1.0.0 + +### Major Changes + +- ec1b4be: Release 1.0 of the new backend system! :tada: + + The backend system is finally getting promoted to 1.0.0. This means that the API is now stable and breaking changes should not occur until version 2.0.0, see our [package versioning policy](https://backstage.io/docs/overview/versioning-policy/#package-versioning-policy) for more information what this means. + + This release also marks the end of the old backend system based on `createRouter` exports. Going forward backend plugins packages will start to deprecate and later this year remove exports supporting the old backend system. If you would like to help out with this transition, see or consult the [migration guide](https://backstage.io/docs/backend-system/building-plugins-and-modules/migrating/#remove-support-for-the-old-backend-system). + +### Minor Changes + +- 19ff127: **BREAKING**: The deprecated identity and token manager services have been removed. This means that `coreServices.identity` and `coreServices.tokenManager` are gone, along with related types and utilities in other packages. + +- f687050: Removed the following deprecated exports + + - `BackendPluginConfig` use `CreateBackendPluginOptions` + - `BackendModuleConfig` use `CreateBackendModuleOptions` + - `ExtensionPointConfig` use `CreateExtensionPointOptions` + +- 4d82481: Removed deprecated `ServiceFactoryOrFunction` type. + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- cd38da8: Deprecate the `featureDiscoveryServiceRef` in favor of using the new `discoveryFeatureLoader` instead. +- 8052b9b: Add a `toJSON` on refs so that they can appear in expectations in jest tests +- 66dbf0a: Allow the cache service to accept the human duration format for TTL +- 0b2a402: Updates to the config schema to match reality +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/backend-test-utils@1.0.0 + +### Major Changes + +- ec1b4be: Release 1.0 of the new backend system! :tada: + + The backend system is finally getting promoted to 1.0.0. This means that the API is now stable and breaking changes should not occur until version 2.0.0, see our [package versioning policy](https://backstage.io/docs/overview/versioning-policy/#package-versioning-policy) for more information what this means. + + This release also marks the end of the old backend system based on `createRouter` exports. Going forward backend plugins packages will start to deprecate and later this year remove exports supporting the old backend system. If you would like to help out with this transition, see or consult the [migration guide](https://backstage.io/docs/backend-system/building-plugins-and-modules/migrating/#remove-support-for-the-old-backend-system). + +### Minor Changes + +- 19ff127: **BREAKING**: Removed service mocks for the identity and token manager services, which have been removed from `@backstage/backend-plugin-api`. +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- 710f621: Added missing service mock for `mockServices.rootConfig.mock`, and fixed the definition of `mockServices.rootHttpRouter.factory` to not have a duplicate callback. +- f421d2a: Make MySQL pool settings a bit more lax +- 0363bf1: There is a new `mockErrorHandler` utility to help in mocking the error middleware in tests. +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-defaults@0.5.0 + - @backstage/backend-app-api@1.0.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/plugin-events-node@0.4.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/backend-common@0.25.0 + +### Minor Changes + +- a4bac3c: **BREAKING**: You can no longer supply a `basePath` option to the host discovery implementation. In the new backend system, the ability to choose this path has been removed anyway at the plugin router level. + +- 988c145: **BREAKING**: Simplifications and cleanup as part of the Backend System 1.0 work. + + - The deprecated `dropDatabase` function has now been removed, without replacement. + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- 6ed9264: chore(deps): bump `path-to-regexp` from 6.2.2 to 8.0.0 +- 8ba77ed: The `legacyPlugin` and `makeLegacyPlugin` helpers now provide their own shim implementation of the identity and token manager services, as these services are being removed from the new backend system. +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- 2e9ec14: Add `pg-format` as a dependency +- 82539fe: Updated dependency `archiver` to `^7.0.0`. +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- 3606843: Internal fixes to match `testcontainers` update +- 19ff127: Internal refactor to re-declare the token manager service which was removed from `@backstage/backend-plugin-api`, but is still supported in this package for backwards compatibility. +- 66dbf0a: Allow the cache service to accept the human duration format for TTL +- 0b2a402: Updates to the config schema to match reality +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/integration@1.15.0 + - @backstage/config-loader@1.9.1 + - @backstage/backend-dev-utils@0.1.5 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + +## @backstage/backend-defaults@0.5.0 + +### Minor Changes + +- a4bac3c: **BREAKING**: You can no longer supply a `basePath` option to the host discovery implementation. In the new backend system, the ability to choose this path has been removed anyway at the plugin router level. + +- 359fcd7: **BREAKING**: The backwards compatibility with plugins using legacy auth through the token manager service has been removed. This means that instead of falling back to using the old token manager, requests towards plugins that don't support the new auth system will simply fail. Please make sure that all plugins in your deployment are hosted within a backend instance from the new backend system. + +- baeef13: **BREAKING** Removed `createLifecycleMiddleware` and `LifecycleMiddlewareOptions` to clean up API surface. These exports have no external usage and do not provide value in its current form. If you were using these exports, please reach out to the maintainers to discuss your use case. + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +- 19ff127: **BREAKING**: The default backend instance no longer provides implementations for the identity and token manager services, which have been removed from `@backstage/backend-plugin-api`. + + If you rely on plugins that still require these services, you can add them to your own backend by re-creating the service reference and factory. + + The following can be used to implement the identity service: + + ```ts + import { + coreServices, + createServiceFactory, + createServiceRef, + } from '@backstage/backend-plugin-api'; + import { + DefaultIdentityClient, + IdentityApi, + } from '@backstage/plugin-auth-node'; + + backend.add( + createServiceFactory({ + service: createServiceRef({ id: 'core.identity' }), + deps: { + discovery: coreServices.discovery, + }, + async factory({ discovery }) { + return DefaultIdentityClient.create({ discovery }); + }, + }), + ); + ``` + + The following can be used to implement the token manager service: + + ```ts + import { ServerTokenManager, TokenManager } from '@backstage/backend-common'; + import { createBackend } from '@backstage/backend-defaults'; + import { + coreServices, + createServiceFactory, + createServiceRef, + } from '@backstage/backend-plugin-api'; + + backend.add( + createServiceFactory({ + service: createServiceRef({ id: 'core.tokenManager' }), + deps: { + config: coreServices.rootConfig, + logger: coreServices.rootLogger, + }, + createRootContext({ config, logger }) { + return ServerTokenManager.fromConfig(config, { + logger, + allowDisabledTokenManager: true, + }); + }, + async factory(_deps, tokenManager) { + return tokenManager; + }, + }), + ); + ``` + +- 055b75b: **BREAKING**: Simplifications and cleanup as part of the Backend System 1.0 work. + + For the `/database` subpath exports: + + - The deprecated `dropDatabase` function has now been removed, without replacement. + - The deprecated `LegacyRootDatabaseService` type has now been removed. + - The return type from `DatabaseManager.forPlugin` is now directly a `DatabaseService`, as arguably expected. + - `DatabaseManager.forPlugin` now requires the `deps` argument, with the logger and lifecycle services. + + For the `/cache` subpath exports: + + - The `PluginCacheManager` type has been removed. You can still import it from `@backstage/backend-common`, but it's deprecated there, and you should move off of that package by migrating fully to the new backend system. + - Accordingly, `CacheManager.forPlugin` immediately returns a `CacheService` instead of a `PluginCacheManager`. The outcome of this is that you no longer need to make the extra `.getClient()` call. The old `CacheManager` with the old behavior still exists on `@backstage/backend-common`, but the above recommendations apply. + +### Patch Changes + +- 213664e: Fixed an issue where the `useRedisSets` configuration for the cache service would have no effect. + +- 6ed9264: chore(deps): bump `path-to-regexp` from 6.2.2 to 8.0.0 + +- 622360e: Move down the discovery config to be in the root + +- 7f779c7: `auth.externalAccess` should be optional in the config schema + +- fe6fd8c: Accept `ConfigService` instead of `Config` in constructors/factories + +- 82539fe: Updated dependency `archiver` to `^7.0.0`. + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. + +- 5705424: Wrap scheduled tasks from the scheduler core service now in OpenTelemetry spans + +- 7a72ec8: Exports the `discoveryFeatureLoader` as a replacement for the deprecated `featureDiscoveryService`. + The `discoveryFeatureLoader` is a new backend system [feature loader](https://backstage.io/docs/backend-system/architecture/feature-loaders/) that discovers backend features from the current `package.json` and its dependencies. + Here is an example using the `discoveryFeatureLoader` loader in a new backend instance: + + ```ts + import { createBackend } from '@backstage/backend-defaults'; + import { discoveryFeatureLoader } from '@backstage/backend-defaults'; + //... + + const backend = createBackend(); + //... + backend.add(discoveryFeatureLoader); + //... + backend.start(); + ``` + +- b2a329d: Properly indent the config schema + +- 66dbf0a: Allow the cache service to accept the human duration format for TTL + +- 5a8fcb4: Added the option to skip database migrations by setting `skipMigrations: true` in config. This can be done globally in the database config or by plugin id. + +- 0b2a402: Updates to the config schema to match reality + +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-app-api@1.0.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/cli-node@0.2.8 + - @backstage/plugin-permission-node@0.8.3 + - @backstage/integration@1.15.0 + - @backstage/config-loader@1.9.1 + - @backstage/plugin-events-node@0.4.0 + - @backstage/backend-dev-utils@0.1.5 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + +## @backstage/backend-dynamic-feature-service@0.4.0 + +### Minor Changes + +- 9080f57: **BREAKING**: `dynamicPluginsServiceFactory` is no longer callable as a function. If you need to provide options to make a custom factory, use `dynamicPluginsSchemasServiceFactoryWithOptions` instead. + +### Patch Changes + +- cd38da8: Deprecate the `dynamicPluginsServiceRef`, `dynamicPluginsServiceFactory` and `dynamicPluginsServiceFactoryWithOptions` in favor of using the `dynamicPluginsFeatureDiscoveryLoader` to discover dynamic features in a new backend system. + + See usage examples below: + + Example using the `dynamicPluginsFeatureDiscoveryLoader` loader in a backend instance: + + ```ts + import { createBackend } from '@backstage/backend-defaults'; + import { dynamicPluginsFeatureDiscoveryLoader } from '@backstage/backend-dynamic-feature-service'; + //... + + const backend = createBackend(); + backend.add(dynamicPluginsFeatureDiscoveryLoader); + //... + backend.start(); + ``` + + Passing options to the `dynamicPluginsFeatureDiscoveryLoader` loader in a backend instance: + + ```ts + import { createBackend } from '@backstage/backend-defaults'; + import { dynamicPluginsFeatureDiscoveryLoader } from '@backstage/backend-dynamic-feature-service'; + import { myCustomModuleLoader } from './myCustomModuleLoader'; + //... + + const backend = createBackend(); + backend.add( + dynamicPluginsFeatureDiscoveryLoader({ + moduleLoader: myCustomModuleLoader, + }), + ); + //... + backend.start(); + ``` + +- e27f889: Relax type check for a plugin's default export to also accept a BackendFeature defined as a function instead of an object + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. + +- Updated dependencies + - @backstage/backend-defaults@0.5.0 + - @backstage/backend-common@0.25.0 + - @backstage/backend-app-api@1.0.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/plugin-catalog-backend@1.26.0 + - @backstage/plugin-app-node@0.1.25 + - @backstage/cli-node@0.2.8 + - @backstage/plugin-permission-node@0.8.3 + - @backstage/plugin-events-backend@0.3.12 + - @backstage/config-loader@1.9.1 + - @backstage/plugin-events-node@0.4.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-scaffolder-node@0.4.11 + - @backstage/plugin-search-backend-node@1.3.2 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/catalog-client@1.7.0 + +### Minor Changes + +- 78475c3: Allow offset mode paging in entity list provider +- 29e57c7: Add catalog service mocks under the `/testUtils` subpath export. + +### Patch Changes + +- 1882cfe: Moved `getEntities` ordering to utilize database instead of having it inside catalog client + + Please note that the latest version of `@backstage/catalog-client` will not order the entities in the same way as before. This is because the ordering is now done in the database query instead of in the client. If you rely on the ordering of the entities, you may need to update your backend plugin or code to handle this change. + +- Updated dependencies + - @backstage/catalog-model@1.7.0 + - @backstage/errors@1.2.4 + +## @backstage/catalog-model@1.7.0 + +### Minor Changes + +- 74acf06: Add `dependencyOf` prop to catalog model for Component kind to enable building relationship graphs with both directions using `dependsOn` and `dependencyOf`. + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/core-app-api@1.15.0 + +### Minor Changes + +- ddbeace: Added the ability to explicitly disable routes through the `bindRoutes` option by passing `false` as the route target. This also fixes a bug where route bindings in config were incorrectly prioritized above the ones in code in certain situations. + +### Patch Changes + +- ea69e46: The `defaultConfigLoader` now also reads configuration from scripts tags with `type="backstage.io/config"`. The tag is expected to contain a JSON-serialized array of `AppConfig` objects. If any of these script tags are present, the injected runtime configuration in the static assets will no longer be used. +- b537bd7: Allow custom star icons to be provided via the `star` and `unstarred` icon overrides. See how to override existing icons in the [Backstage documentation](https://backstage.io/docs/getting-started/app-custom-theme/#custom-icons). +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.9.4 + - @backstage/version-bridge@1.0.9 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## @backstage/core-compat-api@0.3.0 + +### Minor Changes + +- 6db849e: **BREAKING**: The `namespace` parameter for API's is now defaulted to the `pluginId` which was discovered. This means that if you're overriding API's by using ID's directly, they might have changed to include the plugin ID too. + +### Patch Changes + +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. +- c816e2d: Added support for new `FrontendPlugin` and `FrontendModule` types. +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/version-bridge@1.0.9 + +## @backstage/core-components@0.15.0 + +### Minor Changes + +- 9adc552: Added missing items to `overridableComponents` + + **BREAKING** Overridable component name for styling `OAuthRequestDialog` changed to `BackstageOAuthRequestDialog`. Overridable component name `BackstageMissingAnnotationEmptyState` that was previously deprecated has been removed. + +### Patch Changes + +- c891b69: Add `FavoriteToggle` in `core-components` to standardise favorite marking +- 0944334: Removed default title set to Unknown page on `ContentHeaderTitle` component to support usage of component without title prop. +- f325258: Use getOptionalString for optional app.support.items\[].links\[].title +- af4c146: Support menu items should not be buttons in favour of links +- 107a147: Fixed `Table` width being overridden by custom `style` prop. +- b537bd7: Allow custom star icons to be provided via the `star` and `unstarred` icon overrides. See how to override existing icons in the [Backstage documentation](https://backstage.io/docs/getting-started/app-custom-theme/#custom-icons). +- 06b8206: Added `titleComponent` prop to `SignInPage` component to allow further customization of the title using `ReactNode` +- dbbd93e: Internal update to match recent React types +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.9.4 + - @backstage/theme@0.5.7 + - @backstage/version-bridge@1.0.9 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/dev-utils@1.1.0 + +### Minor Changes + +- 10b1452: Allow using translations in `createDevApp` + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/plugin-catalog-react@1.13.0 + - @backstage/core-app-api@1.15.0 + - @backstage/integration-react@1.1.31 + - @backstage/catalog-model@1.7.0 + - @backstage/app-defaults@1.5.11 + - @backstage/core-plugin-api@1.9.4 + - @backstage/theme@0.5.7 + +## @backstage/frontend-app-api@0.9.0 + +### Minor Changes + +- 7c80650: **BREAKING**: The `createSpecializedApp` function now creates a bare-bones app without any of the default app structure or APIs. To re-introduce this functionality if you need to use `createSpecializedApp` you can install the `app` plugin from `@backstage/plugin-app`. + + In addition, the `createApp` and `CreateAppFeatureLoader` exports are now deprecated as they are being moved to `@backstage/frontend-defaults`, which should be used instead. + +- 62cce6c: Removed deprecated `icons` property passing to `createApp` and `createSpecializedApp`. Use `IconBundleBlueprint.make` to create extensions instead and include them in the app. + +### Patch Changes + +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. + +- 2bb9517: Introduce the `@backstage/plugin-app` package to hold all of the built-in extensions for easy consumption and overriding. + +- c816e2d: Added support for new `FrontendPlugin` and `FrontendModule` types. + +- f3a2b91: Moved several implementations of built-in APIs from being hardcoded in the app to instead be provided as API extensions. This moves all API-related inputs from the `app` extension to the respective API extensions. For example, extensions created with `ThemeBlueprint` are now attached to the `themes` input of `api:app-theme` rather than the `app` extension. + +- 0c70949: Reverse the order of API factory initialization in order to make sure that overrides from modules take priority + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. + +- 5446061: Internal refactor following removal of v1 extension support. The app implementation itself still supports v1 extensions at runtime. + +- 948d431: Removing deprecated `namespace` parameter in favour of `pluginId` instead + +- ddbeace: Added the ability to explicitly disable routes through the `bindRoutes` option by passing `false` as the route target. This also fixes a bug where route bindings in config were incorrectly prioritized above the ones in code in certain situations. + +- 98850de: Added support for defining `replaces` in `createExtensionInput` which will allow extensions to redirect missing `attachTo` points to an input of the created extension. + + ```ts + export const AppThemeApi = ApiBlueprint.makeWithOverrides({ + name: 'app-theme', + inputs: { + themes: createExtensionInput([ThemeBlueprint.dataRefs.theme], { + // attachTo: { id: 'app', input: 'themes'} will be redirected to this input instead + replaces: [{ id: 'app', input: 'themes' }], + }), + }, + factory: () { + ... + } + }); + ``` + +- 4a66456: Added the `root` extension the replace the `app` extension as the root of the app. + +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0 + - @backstage/core-app-api@1.15.0 + - @backstage/frontend-defaults@0.1.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/version-bridge@1.0.9 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/frontend-defaults@0.1.0 + +### Minor Changes + +- 7c80650: Initial release of this package, which provides a default app setup through the `createApp` function. This replaces the existing `createApp` method from `@backstage/frontend-app-api`. + +### Patch Changes + +- 7d19cd5: Added a new `CreateAppOptions` type for the `createApp` options. +- 7d19cd5: Added `createPublicSignInApp`, used to creating apps for the public entry point. +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0 + - @backstage/frontend-app-api@0.9.0 + - @backstage/plugin-app@0.1.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/frontend-plugin-api@0.8.0 + +### Minor Changes + +- 5446061: **BREAKING**: Removed support for "v1" extensions. This means that it is no longer possible to declare inputs and outputs as objects when using `createExtension`. In addition, all extension creators except for `createComponentExtension` have been removed, use the equivalent blueprint instead. See the [1.30 migration documentation](https://backstage.io/docs/frontend-system/architecture/migrations/#130) for more information on this change. +- fec8b57: **BREAKING**: Updated the type parameters for `ExtensionDefinition` and `ExtensionBlueprint` to only have a single object parameter. The base type parameter is exported as `ExtensionDefinitionParameters` and `ExtensionBlueprintParameters` respectively. This is shipped as an immediate breaking change as we expect usage of these types to be rare, and it does not affect the runtime behavior of the API. + + This is a breaking change as it changes the type parameters. Existing usage can generally be updated as follows: + + - `ExtensionDefinition` -> `ExtensionDefinition` + - `ExtensionDefinition` -> `ExtensionDefinition` + - `ExtensionDefinition` -> `ExtensionDefinition<{ config: TConfig }>` + - `ExtensionDefinition` -> `ExtensionDefinition<{ config: TConfig, configInput: TConfigInput }>` + + If you need to infer the parameter you can use `ExtensionDefinitionParameters`, for example: + + ```ts + import { + ExtensionDefinition, + ExtensionDefinitionParameters, + } from '@backstage/frontend-plugin-api'; + + function myUtility( + ext: ExtensionDefinition, + ): T['config'] { + // ... + } + ``` + + The same patterns apply to `ExtensionBlueprint`. + + This change is made to improve the readability of API references and ability to evolve the type parameters in the future. + +### Patch Changes + +- 2bb9517: Introduce the `@backstage/plugin-app` package to hold all of the built-in extensions for easy consumption and overriding. + +- c816e2d: Added `createFrontendModule` as a replacement for `createExtensionOverrides`, which is now deprecated. + + Deprecated the `BackstagePlugin` and `FrontendFeature` type in favor of `FrontendPlugin` and `FrontendFeature` from `@backstage/frontend-app-api` respectively. + +- 52f9c5a: Deprecated the `namespace` option for `createExtensionBlueprint` and `createExtension`, these are no longer required and will default to the `pluginId` instead. + + You can migrate some of your extensions that use `createExtensionOverrides` to using `createFrontendModule` instead and providing a `pluginId` there. + + ```ts + // Before + createExtensionOverrides({ + extensions: [ + createExtension({ + name: 'my-extension', + namespace: 'my-namespace', + kind: 'test', + ... + }) + ], + }); + + // After + createFrontendModule({ + pluginId: 'my-namespace', + extensions: [ + createExtension({ + name: 'my-extension', + kind: 'test', + ... + }) + ], + }); + ``` + +- f3a2b91: Moved several implementations of built-in APIs from being hardcoded in the app to instead be provided as API extensions. This moves all API-related inputs from the `app` extension to the respective API extensions. For example, extensions created with `ThemeBlueprint` are now attached to the `themes` input of `api:app-theme` rather than the `app` extension. + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. + +- 948d431: Removing deprecated `namespace` parameter in favour of `pluginId` instead + +- 043d7cd: Internal refactor + +- 220f4f7: Remove unnecessary config object on IconBundleBlueprint + +- 2a61422: The `factory` option is no longer required when overriding an extension. + +- 98850de: Added support for defining `replaces` in `createExtensionInput` which will allow extensions to redirect missing `attachTo` points to an input of the created extension. + + ```ts + export const AppThemeApi = ApiBlueprint.makeWithOverrides({ + name: 'app-theme', + inputs: { + themes: createExtensionInput([ThemeBlueprint.dataRefs.theme], { + // attachTo: { id: 'app', input: 'themes'} will be redirected to this input instead + replaces: [{ id: 'app', input: 'themes' }], + }), + }, + factory: () { + ... + } + }); + ``` + +- 4a66456: A new `apis` parameter has been added to `factory` for extensions. This is a way to access utility APIs without being coupled to the React context. + +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/version-bridge@1.0.9 + - @backstage/types@1.1.1 + +## @backstage/frontend-test-utils@0.2.0 + +### Minor Changes + +- 5446061: Removed support for testing "v1" extensions, where outputs are defined as an object rather than an array. +- e6e488c: **BREAKING**: The deprecated `.render()` method has been removed from the extension tester. + +### Patch Changes + +- 2a61422: The extension tester will no longer unconditionally enable any additional extensions that have been added. +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. +- 4a66456: Internal update to add support for passing an `ApiRegistry` when creating the node tree +- 2bb9517: Introduce the `@backstage/plugin-app` package to hold all of the built-in extensions for easy consumption and overriding. +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- 948d431: Removing deprecated `namespace` parameter in favour of `pluginId` instead +- 043d7cd: Internal refactor +- f6d1874: Added the ability to provide additional `extensions` and `features` to `renderInTestApp` +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0 + - @backstage/frontend-app-api@0.9.0 + - @backstage/plugin-app@0.1.0 + - @backstage/test-utils@1.6.0 + - @backstage/version-bridge@1.0.9 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## @backstage/integration@1.15.0 + +### Minor Changes + +- 1573014: The Gerrit integration can now resolve Gitiles urls that point to the following + refs: + + - HEAD + - A SHA + - Tag + - Branch + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/test-utils@1.6.0 + +### Minor Changes + +- d47be30: Added the icons option to the renderInTestApp function's TestAppOptions to be forwarded to the icons option of `createApp`. + +### Patch Changes + +- b537bd7: Allow custom star icons to be provided via the `star` and `unstarred` icon overrides. See how to override existing icons in the [Backstage documentation](https://backstage.io/docs/getting-started/app-custom-theme/#custom-icons). +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-app-api@1.15.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/theme@0.5.7 + - @backstage/plugin-permission-react@0.4.26 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-app@0.1.0 + +### Minor Changes + +- 2bb9517: Introduce the `@backstage/plugin-app` package to hold all of the built-in extensions for easy consumption and overriding. + +### Patch Changes + +- 52f9c5a: Deprecated the `namespace` option for `createExtensionBlueprint` and `createExtension`, these are no longer required and will default to the `pluginId` instead. + + You can migrate some of your extensions that use `createExtensionOverrides` to using `createFrontendModule` instead and providing a `pluginId` there. + + ```ts + // Before + createExtensionOverrides({ + extensions: [ + createExtension({ + name: 'my-extension', + namespace: 'my-namespace', + kind: 'test', + ... + }) + ], + }); + + // After + createFrontendModule({ + pluginId: 'my-namespace', + extensions: [ + createExtension({ + name: 'my-extension', + kind: 'test', + ... + }) + ], + }); + ``` + +- 57bf6ae: Fix issue with `AlertDisplay` and other components defined with `AppRootElementBlueprint` not being rendered when at the `SignInWrapper` + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. + +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/frontend-plugin-api@0.8.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/theme@0.5.7 + - @backstage/plugin-permission-react@0.4.26 + +## @backstage/plugin-auth-backend@0.23.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- 527d973: Migrated the `Bitbucket Server` auth provider to be implemented using the new `@backstage/plugin-auth-backend-module-bitbucket-server-provider` module. +- d908d8c: Migrated the `Auth0` auth provider to be implemented using the new `@backstage/plugin-auth-backend-module-auth0-provider` module. +- 19ff127: Internal refactor to remove dependencies on the identity and token manager services, which have been removed. Public APIs no longer require the identity service or token manager to be provided. +- 3c2d690: Allow users without defined email to be ingested by the `msgraph` catalog plugin and add `userIdMatchingUserEntityAnnotation` sign-in resolver for the Microsoft auth provider to support sign-in for users without defined email. +- 92118cd: Updated dependency `@node-saml/passport-saml` to `^5.0.0`. +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/plugin-auth-backend-module-aws-alb-provider@0.2.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/catalog-model@1.7.0 + - @backstage/catalog-client@1.7.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/plugin-auth-backend-module-auth0-provider@0.1.0 + - @backstage/plugin-auth-backend-module-microsoft-provider@0.2.0 + - @backstage/plugin-auth-backend-module-atlassian-provider@0.3.0 + - @backstage/plugin-auth-backend-module-bitbucket-provider@0.2.0 + - @backstage/plugin-auth-backend-module-github-provider@0.2.0 + - @backstage/plugin-auth-backend-module-gitlab-provider@0.2.0 + - @backstage/plugin-auth-backend-module-google-provider@0.2.0 + - @backstage/plugin-auth-backend-module-oauth2-provider@0.3.0 + - @backstage/plugin-auth-backend-module-oidc-provider@0.3.0 + - @backstage/plugin-auth-backend-module-okta-provider@0.1.0 + - @backstage/plugin-auth-backend-module-onelogin-provider@0.2.0 + - @backstage/plugin-auth-backend-module-bitbucket-server-provider@0.1.0 + - @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.2.0 + - @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.3.0 + - @backstage/plugin-auth-backend-module-gcp-iap-provider@0.3.0 + - @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.2.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-auth-backend-module-atlassian-provider@0.3.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + +## @backstage/plugin-auth-backend-module-auth0-provider@0.1.0 + +### Minor Changes + +- d908d8c: New module for `@backstage/plugin-auth-backend` that adds a Auth0 auth provider. + +### Patch Changes + +- 0a3a13e: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + +## @backstage/plugin-auth-backend-module-aws-alb-provider@0.2.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- ecbc47e: Fix a bug where the signer was checked from the payload instead of the header +- 8d1fb8d: Throw correct error when email is missing from the claims +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/plugin-auth-backend@0.23.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.2.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/catalog-model@1.7.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-bitbucket-provider@0.2.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + +## @backstage/plugin-auth-backend-module-bitbucket-server-provider@0.1.0 + +### Minor Changes + +- 527d973: New module for `@backstage/plugin-auth-backend` that adds a `Bitbucket Server` auth provider. + +### Patch Changes + +- 0a3a13e: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + +## @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.3.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-gcp-iap-provider@0.3.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-auth-backend-module-github-provider@0.2.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + +## @backstage/plugin-auth-backend-module-gitlab-provider@0.2.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + +## @backstage/plugin-auth-backend-module-google-provider@0.2.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + +## @backstage/plugin-auth-backend-module-guest-provider@0.2.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- 339c67d: This provider will now reject authentication attempts rather than halt backend startup when `dangerouslyAllowOutsideDevelopment` is not set in production. +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/catalog-model@1.7.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-microsoft-provider@0.2.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- 3c2d690: Allow users without defined email to be ingested by the `msgraph` catalog plugin and add `userIdMatchingUserEntityAnnotation` sign-in resolver for the Microsoft auth provider to support sign-in for users without defined email. +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + +## @backstage/plugin-auth-backend-module-oauth2-provider@0.3.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + +## @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.2.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-oidc-provider@0.3.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/plugin-auth-backend@0.23.0 + +## @backstage/plugin-auth-backend-module-okta-provider@0.1.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + +## @backstage/plugin-auth-backend-module-onelogin-provider@0.2.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + +## @backstage/plugin-auth-backend-module-pinniped-provider@0.2.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/config@1.2.0 + +## @backstage/plugin-auth-backend-module-vmware-cloud-provider@0.3.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/catalog-model@1.7.0 + +## @backstage/plugin-catalog@1.23.0 + +### Minor Changes + +- 78475c3: Allow offset mode paging in entity list provider + +### Patch Changes + +- c891b69: Add `FavoriteToggle` in `core-components` to standardise favorite marking +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- 5446061: The `/alpha` export no longer export extension creators for the new frontend system, existing usage should be switched to use the equivalent extension blueprint instead. For more information see the [new frontend system 1.30 migration documentation](https://backstage.io/docs/frontend-system/architecture/migrations#130). +- 0ff53c8: Enable loading state for paginated catalog tables by passing `isLoading` prop +- 180a45f: Entity presentation api now only fetches fields that are required to display entity title +- a159180: Added missing items to `overridableComponents` +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/plugin-catalog-react@1.13.0 + - @backstage/frontend-plugin-api@0.8.0 + - @backstage/core-compat-api@0.3.0 + - @backstage/plugin-search-react@1.8.0 + - @backstage/integration-react@1.1.31 + - @backstage/catalog-model@1.7.0 + - @backstage/catalog-client@1.7.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/plugin-permission-react@0.4.26 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.6 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-catalog-backend@1.26.0 + +### Minor Changes + +- 74acf06: Add `dependencyOf` prop to catalog model for Component kind to enable building relationship graphs with both directions using `dependsOn` and `dependencyOf`. +- 78475c3: Allow offset mode paging in entity list provider +- bd35cdb: The `analyze-location` endpoint is now protected by the `catalog.location.analyze` permission. + The `validate-entity` endpoint is now protected by the `catalog.entity.validate` permission. + +### Patch Changes + +- 1882cfe: Moved `getEntities` ordering to utilize database instead of having it inside catalog client + + Please note that the latest version of `@backstage/catalog-client` will not order the entities in the same way as before. This is because the ordering is now done in the database query instead of in the client. If you rely on the ordering of the entities, you may need to update your backend plugin or code to handle this change. + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. + +- 53cce86: Fixed an issue with the by-query call, where ordering by a field that does not exist on all entities led to not all results being returned + +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/catalog-client@1.7.0 + - @backstage/plugin-search-backend-module-catalog@0.2.2 + - @backstage/plugin-permission-node@0.8.3 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/integration@1.15.0 + - @backstage/backend-openapi-utils@0.1.18 + - @backstage/plugin-events-node@0.4.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-catalog-backend-module-backstage-openapi@0.4.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/backend-openapi-utils@0.1.18 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-catalog-backend-module-gcp@0.3.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/config@1.2.0 + - @backstage/plugin-kubernetes-common@0.8.3 + +## @backstage/plugin-catalog-backend-module-github-org@0.3.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/plugin-catalog-backend-module-github@0.7.3 + - @backstage/plugin-events-node@0.4.0 + - @backstage/config@1.2.0 + +## @backstage/plugin-catalog-backend-module-gitlab-org@0.2.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-catalog-backend-module-gitlab@0.4.2 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/plugin-events-node@0.4.0 + +## @backstage/plugin-catalog-backend-module-ldap@0.9.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- b50e4a8: Add support for optional configuration of `dnAttributeName` and `uuidAttributeName` in LDAP vendor +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-backend-module-logs@0.1.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-catalog-backend@1.26.0 + - @backstage/plugin-events-node@0.4.0 + +## @backstage/plugin-catalog-backend-module-openapi@0.2.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-catalog-backend@1.26.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/integration@1.15.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/plugin-scaffolder-common@1.5.6 + +## @backstage/plugin-catalog-backend-module-unprocessed@0.5.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-unprocessed-entities-common@0.0.4 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-catalog-common@1.1.0 + +### Minor Changes + +- bd35cdb: The `analyze-location` endpoint is now protected by the `catalog.location.analyze` permission. + The `validate-entity` endpoint is now protected by the `catalog.entity.validate` permission. + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-catalog-node@1.13.0 + +### Minor Changes + +- bd35cdb: The `analyze-location` endpoint is now protected by the `catalog.location.analyze` permission. + The `validate-entity` endpoint is now protected by the `catalog.entity.validate` permission. +- 29e57c7: Add catalog service mocks under the `/testUtils` subpath export. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/catalog-client@1.7.0 + - @backstage/plugin-permission-node@0.8.3 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-catalog-react@1.13.0 + +### Minor Changes + +- 78475c3: Allow offset mode paging in entity list provider + +### Patch Changes + +- c891b69: Add `FavoriteToggle` in `core-components` to standardise favorite marking +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. +- b537bd7: Allow custom star icons to be provided via the `star` and `unstarred` icon overrides. See how to override existing icons in the [Backstage documentation](https://backstage.io/docs/getting-started/app-custom-theme/#custom-icons). +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- 5446061: The `/alpha` export no longer export extension creators for the new frontend system, existing usage should be switched to use the equivalent extension blueprint instead. For more information see the [new frontend system 1.30 migration documentation](https://backstage.io/docs/frontend-system/architecture/migrations#130). +- a159180: Added missing items to `overridableComponents` +- ae9b6cb: Small internal fix to better work with recent `lodash` versions +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/frontend-plugin-api@0.8.0 + - @backstage/core-compat-api@0.3.0 + - @backstage/integration-react@1.1.31 + - @backstage/catalog-model@1.7.0 + - @backstage/catalog-client@1.7.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/version-bridge@1.0.9 + - @backstage/plugin-permission-react@0.4.26 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-devtools-backend@0.4.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- 5d1670f: Update README installation instructions +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-permission-node@0.8.3 + - @backstage/config-loader@1.9.1 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-devtools-common@0.1.12 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-events-node@0.4.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + +## @backstage/plugin-notifications-backend@0.4.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- 1c6f142: Internal refactor to avoid use of insecure coding patterns. +- 4a53dd0: Implement icon in backend and show icon in table if available. +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- f195972: Validate notification link when new notification is created +- 5edd344: Refactor to use injected catalog client in the new backend system +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/plugin-signals-node@0.1.11 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/catalog-model@1.7.0 + - @backstage/catalog-client@1.7.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/plugin-events-node@0.4.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.6 + +## @backstage/plugin-notifications-backend-module-email@0.3.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- 5edd344: Refactor to use injected catalog client in the new backend system +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/catalog-client@1.7.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.6 + +## @backstage/plugin-permission-backend-module-allow-all-policy@0.2.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/plugin-permission-node@0.8.3 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-scaffolder@1.25.0 + +### Minor Changes + +- 860ad3a: Expose styles for TemplateEditor, TemplateFormPreviewer and CustomFieldExplorer +- 4baad34: Added support for `omitExtraData` and `liveOmit` for rjsf in the scaffolder +- 5143616: Added EntityOwnerPicker component to the TemplateListPage to allow filtering on owner + +### Patch Changes + +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. + +- b0a5c9f: The `ui:options` for `OwnedEntityPicker` field are now passed to `EntityPicker`. This allows you to use any `ui:options` which `EntityPicker` accepts in the `OwnedEntityPicker` field including `allowArbitraryValues` and `defaultNamespace`. + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. + +- 0a50d44: Updated dependency `@rjsf/utils` to `5.21.1`. + Updated dependency `@rjsf/core` to `5.21.1`. + Updated dependency `@rjsf/material-ui` to `5.21.1`. + Updated dependency `@rjsf/validator-ajv8` to `5.21.1`. + +- fa9d8da: Updated dependency `@rjsf/utils` to `5.20.1`. + Updated dependency `@rjsf/core` to `5.20.1`. + Updated dependency `@rjsf/material-ui` to `5.20.1`. + Updated dependency `@rjsf/validator-ajv8` to `5.20.1`. + +- 0944334: Removed duplicated titles on Scaffolder `TemplateListPage` component + +- 7976081: Added support for all request parameters in the Github create/update environment API in the Github environment create scaffolder action. + + Disable MultiEntityPicker when `maxItems` limit is reached defined in `JSONSchema` + +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/plugin-catalog-react@1.13.0 + - @backstage/frontend-plugin-api@0.8.0 + - @backstage/core-compat-api@0.3.0 + - @backstage/integration-react@1.1.31 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-scaffolder-react@1.12.0 + - @backstage/catalog-client@1.7.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/integration@1.15.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/plugin-permission-react@0.4.26 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.6 + +## @backstage/plugin-scaffolder-backend@1.25.0 + +### Minor Changes + +- df9ae9e: Added scaffolder action publish:bitbucketCloud:pull-request +- 62898bd: `createRouter` and its related types has been marked as deprecared. This backend should instead be initialized using the new backend system. + +### Patch Changes + +- f0c6b25: Allow listing file contents with `debug:log` scaffolder action + +- c160951: Found the issue during testing the clean up of the workspace for the database implementation. + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. + +- f865103: Updated dependency `esbuild` to `^0.23.0`. + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. + +- 7976081: Added support for all request parameters in the Github create/update environment API in the Github environment create scaffolder action. + + Disable MultiEntityPicker when `maxItems` limit is reached defined in `JSONSchema` + +- Updated dependencies + - @backstage/backend-defaults@0.5.0 + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.5.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.0 + - @backstage/catalog-client@1.7.0 + - @backstage/plugin-permission-node@0.8.3 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/plugin-scaffolder-backend-module-github@0.5.0 + - @backstage/integration@1.15.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.0 + - @backstage/plugin-scaffolder-backend-module-azure@0.2.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.0 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.2.0 + - @backstage/plugin-scaffolder-backend-module-gitea@0.2.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-bitbucket-cloud-common@0.2.23 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-scaffolder-common@1.5.6 + - @backstage/plugin-scaffolder-node@0.4.11 + +## @backstage/plugin-scaffolder-backend-module-azure@0.2.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- 59d8da4: Publish Azure action now uses basic authentication to authenticate to Git when Azure integration is configured to use App Registration/Service Account or Managed Identity. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/integration@1.15.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.11 + +## @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.0 + - @backstage/integration@1.15.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.11 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- df9ae9e: Added scaffolder action publish:bitbucketCloud:pull-request +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/integration@1.15.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-bitbucket-cloud-common@0.2.23 + - @backstage/plugin-scaffolder-node@0.4.11 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/integration@1.15.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.11 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.3.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- 5d1670f: Update README installation instructions +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/integration@1.15.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.11 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.3.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- 5d1670f: Update README installation instructions +- Updated dependencies + - @backstage/backend-defaults@0.5.0 + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/integration@1.15.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.11 + +## @backstage/plugin-scaffolder-backend-module-gcp@0.2.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/integration@1.15.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.11 + +## @backstage/plugin-scaffolder-backend-module-gerrit@0.2.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- 9e5923d: Added test cases for publish:gerrit action examples +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/integration@1.15.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.11 + +## @backstage/plugin-scaffolder-backend-module-gitea@0.2.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/integration@1.15.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.11 + +## @backstage/plugin-scaffolder-backend-module-github@0.5.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- 22a19e6: Added the ability for the actions `publish:github` and `github:repo:create` to take inputs for 'custom properties' for organization repositories. + +- 162cdf4: Update dependency @octokit/webhooks to 10.9.2 due to SNYK-JS-OCTOKITWEBHOOKS-6129527 + +- 7976081: Added support for all request parameters in the Github create/update environment API in the Github environment create scaffolder action. + + Disable MultiEntityPicker when `maxItems` limit is reached defined in `JSONSchema` + +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/catalog-client@1.7.0 + - @backstage/integration@1.15.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.11 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.5.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- 5d1670f: Update README installation instructions +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/integration@1.15.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.11 + +## @backstage/plugin-scaffolder-backend-module-notifications@0.1.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.6 + - @backstage/plugin-scaffolder-node@0.4.11 + +## @backstage/plugin-scaffolder-backend-module-rails@0.5.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- 5d1670f: Update README installation instructions +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/integration@1.15.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.11 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.2.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- 5d1670f: Update README installation instructions +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.11 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.4.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- 5d1670f: Update README installation instructions +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.11 + - @backstage/plugin-scaffolder-node-test-utils@0.1.12 + +## @backstage/plugin-scaffolder-react@1.12.0 + +### Minor Changes + +- 4512f71: Add `ui:backstage.review.name` option for custom item names on scaffolder review page, and also add support for rendering the `title` property instead of the key name. +- 4baad34: Added support for `omitExtraData` and `liveOmit` for rjsf in the scaffolder + +### Patch Changes + +- 1f3c5aa: Fix scaffolder review step issue where schema options are not handled for fields on multi-step templates. +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- 0a50d44: Updated dependency `@rjsf/utils` to `5.21.1`. + Updated dependency `@rjsf/core` to `5.21.1`. + Updated dependency `@rjsf/material-ui` to `5.21.1`. + Updated dependency `@rjsf/validator-ajv8` to `5.21.1`. +- fa9d8da: Updated dependency `@rjsf/utils` to `5.20.1`. + Updated dependency `@rjsf/core` to `5.20.1`. + Updated dependency `@rjsf/material-ui` to `5.20.1`. + Updated dependency `@rjsf/validator-ajv8` to `5.20.1`. +- c2cbe1e: Updated dependency `use-immer` to `^0.10.0`. +- b0f0118: Remove unnecessary singleton wrapping of `scaffolderApiRef`. +- 3ebb64f: - Fix secret widget field not displaying as required. + - Fix secret widget not able to be required inside nested objects. + - Fix secret widget not able to be disabled. + - Support `minLength` and `maxLength` properties for secret widget. +- 8dd6ef6: Fix an issue where keys with duplicate final key parts are not all displayed in the `ReviewState`. Change the way the keys are formatted to include the full schema path, separated by `>`. +- 9a0672a: Scaffolder review page shows static amount of asterisks for secret fields. +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/plugin-catalog-react@1.13.0 + - @backstage/catalog-model@1.7.0 + - @backstage/catalog-client@1.7.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/theme@0.5.7 + - @backstage/version-bridge@1.0.9 + - @backstage/plugin-permission-react@0.4.26 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.6 + +## @backstage/plugin-search-backend-module-stack-overflow-collator@0.3.0 + +### Minor Changes + +- 479808f: Always set default request parameters for requests to stackoverflow while allow to overwrite them. Remove site parameter as causing the request to fail. +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/config@1.2.0 + - @backstage/plugin-search-backend-node@1.3.2 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-react@1.8.0 + +### Minor Changes + +- 9d66d8c: Make use of the `useApp` hook to retrieve the specified search icon in the SearchBar + +### Patch Changes + +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. +- f26ff99: Slight type tweak to match newer React versions better +- dbbd93e: Internal update to match recent React types +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- 5446061: The `/alpha` export no longer export extension creators for the new frontend system, existing usage should be switched to use the equivalent extension blueprint instead. For more information see the [new frontend system 1.30 migration documentation](https://backstage.io/docs/frontend-system/architecture/migrations#130). +- a159180: Added missing items to `overridableComponents` +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/frontend-plugin-api@0.8.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/theme@0.5.7 + - @backstage/version-bridge@1.0.9 + - @backstage/types@1.1.1 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-signals-backend@0.2.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- a0f1f0d: Bump the `ws` library +- 3ec5ccb: The `createRouter` and its related types has been marked as deprecared. This backend should instead be initialized using the new backend system. +- 19ff127: Internal refactor to remove dependencies on the identity and token manager services, which have been removed. Public APIs no longer require the identity service or token manager to be provided. +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/plugin-signals-node@0.1.11 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/plugin-events-node@0.4.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## @backstage/app-defaults@1.5.11 + +### Patch Changes + +- b537bd7: Allow custom star icons to be provided via the `star` and `unstarred` icon overrides. See how to override existing icons in the [Backstage documentation](https://backstage.io/docs/getting-started/app-custom-theme/#custom-icons). +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/core-app-api@1.15.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/theme@0.5.7 + - @backstage/plugin-permission-react@0.4.26 + +## @backstage/backend-openapi-utils@0.1.18 + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/errors@1.2.4 + +## @backstage/cli@0.27.1 + +### Patch Changes + +- d2d2313: Add `config.d.ts` files to the list of included file in `tsconfig.json`. + + This allows ESLint to detect issues or deprecations in those files. + +- 16ffdd6: Remove direct `vite` dependency + +- 8069f4a: Update Scaffolder module template to add itself to the backend + +- 97422b0: Update templates to not refer to backend-common + +- 0e1a817: The app build process now outputs an additional `index.html.tmpl` file. This is an non-templated version of the `index.html` file, which can be used to delay templating until runtime. + + The new `index.html.tmpl` file also sets a `backstage-public-path` meta tag to be templated at runtime. The meta tag is in turn picked up by the new `@backstage/cli/config/webpack-public-path.js` entry point script, which uses it to set the runtime public path of the Webpack bundle. + +- 1b5c264: Add `checks: 'read'` for default GitHub app permissions + +- b4685e7: Added `watchOptions` to frontend webpack config for compatibility with Yarn PnP + +- d29fc1b: Updated dependency `@module-federation/enhanced` to `^0.6.0`. + +- f865103: Updated dependency `esbuild` to `^0.23.0`. + +- ab7713a: Updated dependency `eslint-plugin-jest` to `^28.0.0`. + +- c78ff91: Updated dependency `@rollup/plugin-commonjs` to `^26.0.0`. + +- 4ebf36f: Upgrade to `vite@v5` + +- 2d3caaf: The build commands now support the new `backstage.inline` flag in `package.json`, which causes the contents of private packages to be inlined into the consuming package, rather than be treated as an external dependency. + +- 569c3f0: Fixed an issue where published frontend packages would end up with an invalid import structure if a single module imported both `.css` and `.svg` files. + +- 3d88455: Add support for `backstage:^` version ranges to versions:bump when using the experimental yarn plugin + +- d10f6b6: Allow overriding minify flag with build repo command + +- Updated dependencies + - @backstage/catalog-model@1.7.0 + - @backstage/cli-node@0.2.8 + - @backstage/integration@1.15.0 + - @backstage/config-loader@1.9.1 + - @backstage/eslint-plugin@0.1.9 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/release-manifests@0.0.11 + - @backstage/types@1.1.1 + +## @backstage/cli-node@0.2.8 + +### Patch Changes + +- 0c70f43: Add definition for the new `backstage.inline` field in `package.json`. +- Updated dependencies + - @backstage/cli-common@0.1.14 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/codemods@0.1.50 + +### Patch Changes + +- 0894166: Updated dependency `jscodeshift` to `^0.16.0`. +- Updated dependencies + - @backstage/cli-common@0.1.14 + +## @backstage/config-loader@1.9.1 + +### Patch Changes + +- ef3c507: Updated dependency `typescript-json-schema` to `^0.65.0`. +- Updated dependencies + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/core-plugin-api@1.9.4 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/version-bridge@1.0.9 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/create-app@0.5.19 + +### Patch Changes + +- d2d2313: Add `config.d.ts` files to the list of included file in `tsconfig.json`. + + This allows ESLint to detect issues or deprecations in those files. + +- 4975e63: Yarn 4 is now the default for `create-app`. Also updated `yarn dev` script to use `yarn workspaces foreach` and removed unused Lerna and Concurrently dependencies. + +- 4735881: Bumped create-app version. + +- 97422b0: Update templates to not refer to backend-common + +- 019d9ad: Minor dockerfile syntax update + +- e03acd8: Updated Dockerfile base image to `node:20-bookworm-slim` from `node:18-bookworm-slim` + +- bf370c2: Remove references to the `@backstage/backend-tasks` in versions of the `create-app` package, as it has been deprecated. + +- Updated dependencies + - @backstage/cli-common@0.1.14 + +## @backstage/eslint-plugin@0.1.9 + +### Patch Changes + +- 08895e3: Added support for linting dependencies on workspace packages with the `backstage.inline` flag. + +## @backstage/integration-react@1.1.31 + +### Patch Changes + +- 8a9d797: Remove unnecessary broad permissions from Gitlab `SCMAuth` + + Newer versions of Gitlab (after 2019) do not require the broad api permissions to write to repos. + +- Updated dependencies + - @backstage/integration@1.15.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/config@1.2.0 + +## @backstage/repo-tools@0.9.7 + +### Patch Changes + +- 5c4aa2f: Updated dependency `@useoptic/openapi-utilities` to `^0.55.0`. +- 1a8837e: Avoid generating API reports for packages with `backstage.inline` set. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/cli-node@0.2.8 + - @backstage/config-loader@1.9.1 + - @backstage/cli-common@0.1.14 + - @backstage/errors@1.2.4 + +## @techdocs/cli@1.8.19 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.0 + - @backstage/plugin-techdocs-node@1.12.11 + - @backstage/catalog-model@1.7.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + +## @backstage/theme@0.5.7 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. + +## @backstage/version-bridge@1.0.9 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. + +## @backstage/plugin-api-docs@0.11.9 + +### Patch Changes + +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- 8a474f2: Updating docs to use `createFrontendModule` instead +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/plugin-catalog-react@1.13.0 + - @backstage/plugin-catalog@1.23.0 + - @backstage/frontend-plugin-api@0.8.0 + - @backstage/core-compat-api@0.3.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/plugin-permission-react@0.4.26 + +## @backstage/plugin-app-backend@0.3.74 + +### Patch Changes + +- 72a8c7b: Return HTTP status 400 rather than 500 when receiving an unknown POST request. + +- d3f79d1: Fixing dependency metadata with the new `@backstage/plugin-app` package + +- 590fb2d: **BREAKING**: The app backend now supports the new `index.html.tmpl` output from `@backstage/cli`. If available, the `index.html` will be templated at runtime with the current configuration of the app backend. + + This is marked as a breaking change because you must now supply the app build-time configuration to the backend. This change also affects the public path behavior, where it is no longer necessary to build the app with the correct public path upfront. You now only need to supply a correct `app.baseUrl` to the app backend plugin at runtime. + + An effect that this change has is that the `index.html` will now contain and present the frontend configuration in an easily readable way, which can aid in debugging. This data was always available in the frontend, but it was injected and hidden in the static bundle. + + This templating behavior is enabled by default, but it can be disabled by setting the `app.disableConfigInjection` configuration option to `true`. + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. + +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/plugin-app-node@0.1.25 + - @backstage/config-loader@1.9.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-app-node@0.1.25 + +### Patch Changes + +- d3f79d1: Fixing dependency metadata with the new `@backstage/plugin-app` package +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/config-loader@1.9.1 + +## @backstage/plugin-app-visualizer@0.1.10 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/frontend-plugin-api@0.8.0 + - @backstage/core-plugin-api@1.9.4 + +## @backstage/plugin-auth-node@0.5.2 + +### Patch Changes + +- c46eb0f: Extend the "unable to resolve user identity" message +- d908d8c: Accepts an optional options object in the `PassportOAuthAuthenticatorHelper.authenticate` method. +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- 6f409b7: The `emailMatchingUserEntityProfileEmail` sign-in resolver will now also try matching emails with plus addressing removed. +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/catalog-client@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-auth-react@0.1.6 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/errors@1.2.4 + +## @backstage/plugin-bitbucket-cloud-common@0.2.23 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.15.0 + +## @backstage/plugin-catalog-backend-module-aws@0.4.2 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-defaults@0.5.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/integration@1.15.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-kubernetes-common@0.8.3 + +## @backstage/plugin-catalog-backend-module-azure@0.2.2 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/integration@1.15.0 + - @backstage/config@1.2.0 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.3.2 + +### Patch Changes + +- 19ff127: Internal refactor to remove dependencies on the identity and token manager services, which have been removed. Public APIs no longer require the identity service or token manager to be provided. +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/catalog-client@1.7.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/integration@1.15.0 + - @backstage/plugin-events-node@0.4.0 + - @backstage/config@1.2.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.23 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.2.2 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/integration@1.15.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-catalog-backend-module-gerrit@0.2.2 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/integration@1.15.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-catalog-backend-module-github@0.7.3 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- 5edd344: Refactor to use injected catalog client in the new backend system +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-catalog-backend@1.26.0 + - @backstage/catalog-client@1.7.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/integration@1.15.0 + - @backstage/plugin-events-node@0.4.0 + - @backstage/config@1.2.0 + +## @backstage/plugin-catalog-backend-module-gitlab@0.4.2 + +### Patch Changes + +- 53b24d9: Internal update to use the new cache manager + +- 0476be3: Add the `relations` array to allow Backstage to mirror GitLab's membership behavior, including descendant, inherited, and shared-from-group memberships. + + The previous `allowInherited` config option will be deprecated in future versions. Use the `relations` array with the `INHERITED` option instead. + + ```yaml + catalog: + providers: + gitlab: + development: + relations: + - INHERITED + ``` + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. + +- b446954: Remove dependency on backend-common + +- 06cc084: Added a `includeUsersWithoutSeat` config option that allow import of users without a paid seat, e.g. for Gitlab Free on SaaS. Defaults to false + +- Updated dependencies + - @backstage/backend-defaults@0.5.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/integration@1.15.0 + - @backstage/plugin-events-node@0.4.0 + - @backstage/config@1.2.0 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.5.3 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- 4b28e39: Updated the README to include documentation for the new backend support +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-catalog-backend@1.26.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/plugin-events-node@0.4.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-catalog-backend-module-msgraph@0.6.2 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- 3c2d690: Allow users without defined email to be ingested by the `msgraph` catalog plugin and add `userIdMatchingUserEntityAnnotation` sign-in resolver for the Microsoft auth provider to support sign-in for users without defined email. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/config@1.2.0 + +## @backstage/plugin-catalog-backend-module-puppetdb@0.2.2 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-graph@0.4.9 + +### Patch Changes + +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. +- da91078: Fixed a bug in the `CatalogGraphPage` component where, after clicking on some nodes, clicking the back button would break the navigation. This issue caused the entire navigation to fail and behaved differently across various browsers. +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- 8a474f2: Updating docs to use `createFrontendModule` instead +- a159180: Added missing items to `overridableComponents` +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/plugin-catalog-react@1.13.0 + - @backstage/frontend-plugin-api@0.8.0 + - @backstage/core-compat-api@0.3.0 + - @backstage/catalog-model@1.7.0 + - @backstage/catalog-client@1.7.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-import@0.12.3 + +### Patch Changes + +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. +- f3c90da: Support button title should be contained in a single menu item +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/plugin-catalog-react@1.13.0 + - @backstage/frontend-plugin-api@0.8.0 + - @backstage/core-compat-api@0.3.0 + - @backstage/integration-react@1.1.31 + - @backstage/catalog-model@1.7.0 + - @backstage/catalog-client@1.7.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/integration@1.15.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-catalog-unprocessed-entities@0.2.8 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. + +- 4f08c85: Show additional info on DevTools unprocessed entities table + + - Location path (so that it's easier to search the failed entity from the YAML URL) + - Time info of last discovery and next refresh time so that users can be aware of it and can sort the errors based on the time. + +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/catalog-model@1.7.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/errors@1.2.4 + +## @backstage/plugin-config-schema@0.1.59 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-devtools@0.1.18 + +### Patch Changes + +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. +- 019d9ad: Minor dockerfile syntax update +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/frontend-plugin-api@0.8.0 + - @backstage/core-compat-api@0.3.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/plugin-permission-react@0.4.26 + - @backstage/errors@1.2.4 + - @backstage/plugin-devtools-common@0.1.12 + +## @backstage/plugin-events-backend@0.3.12 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-events-node@0.4.0 + - @backstage/config@1.2.0 + +## @backstage/plugin-events-backend-module-aws-sqs@0.4.2 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-events-node@0.4.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-events-backend-module-azure@0.2.11 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-events-node@0.4.0 + +## @backstage/plugin-events-backend-module-bitbucket-cloud@0.2.11 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-events-node@0.4.0 + +## @backstage/plugin-events-backend-module-gerrit@0.2.11 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-events-node@0.4.0 + +## @backstage/plugin-events-backend-module-github@0.2.11 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-events-node@0.4.0 + - @backstage/config@1.2.0 + +## @backstage/plugin-events-backend-module-gitlab@0.2.11 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-events-node@0.4.0 + - @backstage/config@1.2.0 + +## @backstage/plugin-events-backend-test-utils@0.1.35 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.0 + +## @backstage/plugin-home@0.7.10 + +### Patch Changes + +- c891b69: Add `FavoriteToggle` in `core-components` to standardise favorite marking +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- 0a50d44: Updated dependency `@rjsf/utils` to `5.21.1`. + Updated dependency `@rjsf/core` to `5.21.1`. + Updated dependency `@rjsf/material-ui` to `5.21.1`. + Updated dependency `@rjsf/validator-ajv8` to `5.21.1`. +- fa9d8da: Updated dependency `@rjsf/utils` to `5.20.1`. + Updated dependency `@rjsf/core` to `5.20.1`. + Updated dependency `@rjsf/material-ui` to `5.20.1`. + Updated dependency `@rjsf/validator-ajv8` to `5.20.1`. +- a159180: Added missing items to `overridableComponents` +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/plugin-catalog-react@1.13.0 + - @backstage/frontend-plugin-api@0.8.0 + - @backstage/core-app-api@1.15.0 + - @backstage/core-compat-api@0.3.0 + - @backstage/catalog-model@1.7.0 + - @backstage/catalog-client@1.7.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/theme@0.5.7 + - @backstage/plugin-home-react@0.1.17 + - @backstage/config@1.2.0 + +## @backstage/plugin-home-react@0.1.17 + +### Patch Changes + +- 0a50d44: Updated dependency `@rjsf/utils` to `5.21.1`. + Updated dependency `@rjsf/core` to `5.21.1`. + Updated dependency `@rjsf/material-ui` to `5.21.1`. + Updated dependency `@rjsf/validator-ajv8` to `5.21.1`. +- fa9d8da: Updated dependency `@rjsf/utils` to `5.20.1`. + Updated dependency `@rjsf/core` to `5.20.1`. + Updated dependency `@rjsf/material-ui` to `5.20.1`. + Updated dependency `@rjsf/validator-ajv8` to `5.20.1`. +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/core-plugin-api@1.9.4 + +## @backstage/plugin-kubernetes@0.11.14 + +### Patch Changes + +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. +- bfc0f42: Make k8s entity content appear on components & resources only by default in new FE system +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/plugin-catalog-react@1.13.0 + - @backstage/frontend-plugin-api@0.8.0 + - @backstage/core-compat-api@0.3.0 + - @backstage/catalog-model@1.7.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/plugin-kubernetes-react@0.4.3 + - @backstage/plugin-kubernetes-common@0.8.3 + +## @backstage/plugin-kubernetes-backend@0.18.6 + +### Patch Changes + +- a0f1f0d: Bump the `ws` library +- f55f8bf: The `KubernetesBuilder` and its related types has been marked as deprecared. This backend should instead be initialized using the new backend system. +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- ca96b66: Skip start without proper config +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/catalog-model@1.7.0 + - @backstage/catalog-client@1.7.0 + - @backstage/plugin-permission-node@0.8.3 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/plugin-kubernetes-node@0.1.19 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.8.3 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-kubernetes-cluster@0.0.15 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/plugin-catalog-react@1.13.0 + - @backstage/catalog-model@1.7.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/plugin-kubernetes-react@0.4.3 + - @backstage/plugin-kubernetes-common@0.8.3 + +## @backstage/plugin-kubernetes-common@0.8.3 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.0 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-kubernetes-node@0.1.19 + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.8.3 + +## @backstage/plugin-kubernetes-react@0.4.3 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/catalog-model@1.7.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.8.3 + +## @backstage/plugin-notifications@0.3.1 + +### Patch Changes + +- 653f60b: Severity filter label newly contains "Min severity" to better describe range instead of exact value. +- 4a53dd0: Implement icon in backend and show icon in table if available. +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/theme@0.5.7 + - @backstage/plugin-signals-react@0.0.5 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.5 + +## @backstage/plugin-notifications-node@0.2.6 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/plugin-signals-node@0.1.11 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/catalog-client@1.7.0 + - @backstage/plugin-notifications-common@0.0.5 + +## @backstage/plugin-org@0.6.29 + +### Patch Changes + +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- 8a474f2: Updating docs to use `createFrontendModule` instead +- a159180: Added missing items to `overridableComponents` +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/plugin-catalog-react@1.13.0 + - @backstage/frontend-plugin-api@0.8.0 + - @backstage/core-compat-api@0.3.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/core-plugin-api@1.9.4 + +## @backstage/plugin-org-react@0.1.28 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/plugin-catalog-react@1.13.0 + - @backstage/catalog-model@1.7.0 + - @backstage/catalog-client@1.7.0 + - @backstage/core-plugin-api@1.9.4 + +## @backstage/plugin-permission-backend@0.5.49 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- fcb9356: Deprecated `createRouter` and its router options in favour of the new backend system. +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/plugin-permission-node@0.8.3 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-permission-node@0.8.3 + +### Patch Changes + +- 19ff127: Internal refactor to remove dependencies on the identity and token manager services, which have been removed. Public APIs no longer require the identity service or token manager to be provided. +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-permission-react@0.4.26 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.9.4 + - @backstage/config@1.2.0 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-proxy-backend@0.5.6 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- d298e6e: Deprecated `createRouter` and its router options in favour of the new backend system. +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-common@1.5.6 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.0 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-scaffolder-node@0.4.11 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/integration@1.15.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.6 + +## @backstage/plugin-scaffolder-node-test-utils@0.1.12 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-test-utils@1.0.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.11 + +## @backstage/plugin-search@1.4.16 + +### Patch Changes + +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. +- eca03bd: Added ability to customize the search items within the SidebarSearchModal +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/plugin-catalog-react@1.13.0 + - @backstage/frontend-plugin-api@0.8.0 + - @backstage/core-compat-api@0.3.0 + - @backstage/plugin-search-react@1.8.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/version-bridge@1.0.9 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-backend@1.5.17 + +### Patch Changes + +- 5726390: Deprecate create router as the legacy backend system will no longer be supported. +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-defaults@0.5.0 + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-permission-node@0.8.3 + - @backstage/backend-openapi-utils@0.1.18 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-backend-node@1.3.2 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-backend-module-catalog@0.2.2 + +### Patch Changes + +- 19ff127: Internal refactor to remove dependencies on the identity and token manager services, which have been removed. Public APIs no longer require the identity service or token manager to be provided. + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. + +- 5726390: The following collator factories are deprecated, please [migrate](https://backstage.io/docs/backend-system/building-backends/migrating) to the new backend system and follow the instructions below to install collators via module: + + - `DefaultCatalogCollatorFactory`: ; + - `ToolDocumentCollatorFactory`: ; + - `DefaultTechDocsCollatorFactory`: . + +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/catalog-client@1.7.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-backend-node@1.3.2 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-backend-module-elasticsearch@1.5.6 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- 5726390: Internal refactor to use `LoggerService` and `DatabaseService` instead of the legacy `Logger` and `PluginDatabaseManager` types. +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-backend-node@1.3.2 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-backend-module-explore@0.2.2 + +### Patch Changes + +- 19ff127: Internal refactor to remove dependencies on the identity and token manager services, which have been removed. Public APIs no longer require the identity service or token manager to be provided. + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. + +- 5726390: The following collator factories are deprecated, please [migrate](https://backstage.io/docs/backend-system/building-backends/migrating) to the new backend system and follow the instructions below to install collators via module: + + - `DefaultCatalogCollatorFactory`: ; + - `ToolDocumentCollatorFactory`: ; + - `DefaultTechDocsCollatorFactory`: . + +- 276f433: Updated dependency `@backstage-community/plugin-explore-common` to `^0.0.5`. + +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/config@1.2.0 + - @backstage/plugin-search-backend-node@1.3.2 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-backend-module-pg@0.5.35 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- 5726390: Internal refactor to use `LoggerService` and `DatabaseService` instead of the legacy `Logger` and `PluginDatabaseManager` types. +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/config@1.2.0 + - @backstage/plugin-search-backend-node@1.3.2 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-backend-module-techdocs@0.2.2 + +### Patch Changes + +- 19ff127: Internal refactor to remove dependencies on the identity and token manager services, which have been removed. Public APIs no longer require the identity service or token manager to be provided. + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. + +- 5726390: The following collator factories are deprecated, please [migrate](https://backstage.io/docs/backend-system/building-backends/migrating) to the new backend system and follow the instructions below to install collators via module: + + - `DefaultCatalogCollatorFactory`: ; + - `ToolDocumentCollatorFactory`: ; + - `DefaultTechDocsCollatorFactory`: . + +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/plugin-techdocs-node@1.12.11 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/catalog-client@1.7.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/config@1.2.0 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-backend-node@1.3.2 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-backend-node@1.3.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-signals@0.0.10 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. + +- 5add8e1: Added a `SignalsDisplay` extension to allows the signals plugin to be installed in an app as follows: + + ```tsx + export default app.createRoot( + <> + + + + + + {routes} + + , + ); + ``` + + With this in place you can remove the explicit installation via the `plugins` option for `createApp`. + +- 3e9b1a4: Put a name on the `SignalsDisplay` component extension + +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/theme@0.5.7 + - @backstage/plugin-signals-react@0.0.5 + - @backstage/types@1.1.1 + +## @backstage/plugin-signals-node@0.1.11 + +### Patch Changes + +- a0f1f0d: Bump the `ws` library +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/plugin-events-node@0.4.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-signals-react@0.0.5 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- 0389801: Fix for `useSignal` returning the inverse value for `isSignalsAvailable`. +- Updated dependencies + - @backstage/core-plugin-api@1.9.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-techdocs@1.10.9 + +### Patch Changes + +- c891b69: Add `FavoriteToggle` in `core-components` to standardise favorite marking + +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. + +- fe94ad8: Fixes left navigation positioning when using mkdocs blog plugin + +- b0206dc: Added support for setting page status with 'new' and 'deprecated' values, allowing visual indication of page status in TechDocs. To use include the following at the top of your markdown file: + + ```markdown + --- + status: new + --- + ``` + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. + +- c7cb4c0: Add `empty-state:techdocs/entity-content` extension to allow overriding the empty state for the entity page techdocs tab. + +- 97db53e: Enhanced the table hover effect with a lighter color and updated the border radius to align with Backstage's theme styling + +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/plugin-catalog-react@1.13.0 + - @backstage/frontend-plugin-api@0.8.0 + - @backstage/plugin-techdocs-react@1.2.8 + - @backstage/core-compat-api@0.3.0 + - @backstage/plugin-search-react@1.8.0 + - @backstage/integration-react@1.1.31 + - @backstage/catalog-model@1.7.0 + - @backstage/integration@1.15.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/theme@0.5.7 + - @backstage/plugin-auth-react@0.1.6 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-techdocs-common@0.1.0 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.38 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.13.0 + - @backstage/plugin-techdocs@1.10.9 + - @backstage/plugin-catalog@1.23.0 + - @backstage/plugin-techdocs-react@1.2.8 + - @backstage/core-app-api@1.15.0 + - @backstage/plugin-search-react@1.8.0 + - @backstage/integration-react@1.1.31 + - @backstage/test-utils@1.6.0 + - @backstage/core-plugin-api@1.9.4 + +## @backstage/plugin-techdocs-backend@1.10.13 + +### Patch Changes + +- 086c32d: Dedicated token for techdocs cache sync +- 5b679ac: The `createRouter` and its related types has been marked as deprecared. This backend should instead be initialized using the new backend system. +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- 5edd344: Refactor to use injected catalog client in the new backend system +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/plugin-techdocs-node@1.12.11 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/catalog-client@1.7.0 + - @backstage/plugin-search-backend-module-techdocs@0.2.2 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/integration@1.15.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-techdocs-common@0.1.0 + +## @backstage/plugin-techdocs-module-addons-contrib@1.1.14 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/plugin-techdocs-react@1.2.8 + - @backstage/integration-react@1.1.31 + - @backstage/integration@1.15.0 + - @backstage/core-plugin-api@1.9.4 + +## @backstage/plugin-techdocs-node@1.12.11 + +### Patch Changes + +- f715f5c: Move `TechdocsContainerRunner` from `publish` to `generate`. +- 4417dd4: Fix typo and unify TechDocs casing in doc strings +- 57da51f: Add support for mapping custom tags in the techdocs yaml parser that validates the mkdocs.yaml file +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- 3606843: Internal fixes to match `testcontainers` update +- 33ebb28: As the `@backstage/backend-common` package is deprecated, we have updated the `techdocs-node` package to stop depending on it. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/integration@1.15.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-techdocs-common@0.1.0 + +## @backstage/plugin-techdocs-react@1.2.8 + +### Patch Changes + +- 5ee3d27: Fixed issue in useShadowRootElements which could lead to unlimited render loops +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/catalog-model@1.7.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/version-bridge@1.0.9 + - @backstage/config@1.2.0 + +## @backstage/plugin-user-settings@0.8.12 + +### Patch Changes + +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- da86ac2: Update README to clarify location of additional tabs example +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/plugin-catalog-react@1.13.0 + - @backstage/frontend-plugin-api@0.8.0 + - @backstage/core-app-api@1.15.0 + - @backstage/core-compat-api@0.3.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/theme@0.5.7 + - @backstage/plugin-signals-react@0.0.5 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-user-settings-common@0.0.1 + +## @backstage/plugin-user-settings-backend@0.2.24 + +### Patch Changes + +- 5d1670f: Update README installation instructions +- 164ce3e: In preparation to stop supporting to the legacy backend system, the `createRouter` function is now deprecated and we strongly recommend you [migrate](https://backstage.io/docs/backend-system/building-backends/migrating) your backend to the new system. +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- 1b98099: Replaced usage of the deprecated identity service with the new HTTP auth service for the new backend system. +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-defaults@0.5.0 + - @backstage/plugin-signals-node@0.1.11 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-user-settings-common@0.0.1 + +## example-app@0.2.101 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/plugin-catalog-react@1.13.0 + - @backstage/plugin-techdocs@1.10.9 + - @backstage/plugin-catalog@1.23.0 + - @backstage/plugin-home@0.7.10 + - @backstage/cli@0.27.1 + - @backstage/plugin-techdocs-react@1.2.8 + - @backstage/core-app-api@1.15.0 + - @backstage/frontend-app-api@0.9.0 + - @backstage/plugin-catalog-import@0.12.3 + - @backstage/plugin-catalog-graph@0.4.9 + - @backstage/plugin-user-settings@0.8.12 + - @backstage/plugin-search-react@1.8.0 + - @backstage/plugin-kubernetes@0.11.14 + - @backstage/plugin-scaffolder@1.25.0 + - @backstage/plugin-api-docs@0.11.9 + - @backstage/plugin-devtools@0.1.18 + - @backstage/plugin-search@1.4.16 + - @backstage/plugin-org@0.6.29 + - @backstage/integration-react@1.1.31 + - @backstage/plugin-notifications@0.3.1 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-scaffolder-react@1.12.0 + - @backstage/app-defaults@1.5.11 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/theme@0.5.7 + - @backstage/plugin-auth-react@0.1.6 + - @backstage/plugin-catalog-unprocessed-entities@0.2.8 + - @backstage/plugin-kubernetes-cluster@0.0.15 + - @backstage/plugin-permission-react@0.4.26 + - @backstage/plugin-signals@0.0.10 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.14 + - @backstage/config@1.2.0 + - @backstage/plugin-search-common@1.2.14 + +## example-app-next@0.0.15 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/plugin-catalog-react@1.13.0 + - @backstage/plugin-techdocs@1.10.9 + - @backstage/plugin-catalog@1.23.0 + - @backstage/plugin-home@0.7.10 + - @backstage/cli@0.27.1 + - @backstage/frontend-plugin-api@0.8.0 + - @backstage/plugin-techdocs-react@1.2.8 + - @backstage/core-app-api@1.15.0 + - @backstage/frontend-app-api@0.9.0 + - @backstage/core-compat-api@0.3.0 + - @backstage/plugin-catalog-import@0.12.3 + - @backstage/plugin-catalog-graph@0.4.9 + - @backstage/plugin-user-settings@0.8.12 + - @backstage/plugin-search-react@1.8.0 + - @backstage/plugin-kubernetes@0.11.14 + - @backstage/plugin-scaffolder@1.25.0 + - @backstage/plugin-api-docs@0.11.9 + - @backstage/plugin-search@1.4.16 + - @backstage/plugin-org@0.6.29 + - @backstage/integration-react@1.1.31 + - @backstage/frontend-defaults@0.1.0 + - @backstage/plugin-notifications@0.3.1 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-scaffolder-react@1.12.0 + - @backstage/plugin-app@0.1.0 + - @backstage/app-defaults@1.5.11 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/theme@0.5.7 + - @backstage/plugin-auth-react@0.1.6 + - @backstage/plugin-catalog-unprocessed-entities@0.2.8 + - @backstage/plugin-kubernetes-cluster@0.0.15 + - @backstage/plugin-permission-react@0.4.26 + - @backstage/plugin-signals@0.0.10 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.14 + - @backstage/plugin-app-visualizer@0.1.10 + - @backstage/config@1.2.0 + - @backstage/plugin-search-common@1.2.14 + +## app-next-example-plugin@0.0.15 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/frontend-plugin-api@0.8.0 + +## example-backend@0.0.30 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.0 + - @backstage/plugin-kubernetes-backend@0.18.6 + - @backstage/plugin-signals-backend@0.2.0 + - @backstage/plugin-techdocs-backend@1.10.13 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-search-backend@1.5.17 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/plugin-devtools-backend@0.4.0 + - @backstage/plugin-app-backend@0.3.74 + - @backstage/plugin-notifications-backend@0.4.0 + - @backstage/plugin-scaffolder-backend@1.25.0 + - @backstage/plugin-auth-backend@0.23.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-catalog-backend@1.26.0 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.0 + - @backstage/plugin-search-backend-module-techdocs@0.2.2 + - @backstage/plugin-search-backend-module-catalog@0.2.2 + - @backstage/plugin-search-backend-module-explore@0.2.2 + - @backstage/plugin-permission-node@0.8.3 + - @backstage/plugin-permission-backend@0.5.49 + - @backstage/plugin-proxy-backend@0.5.6 + - @backstage/plugin-scaffolder-backend-module-github@0.5.0 + - @backstage/plugin-auth-backend-module-github-provider@0.2.0 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.4.0 + - @backstage/plugin-catalog-backend-module-openapi@0.2.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.5.0 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.0 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-backend-node@1.3.2 + +## example-backend-legacy@0.2.102 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.0 + - @backstage/backend-common@0.25.0 + - @backstage/plugin-kubernetes-backend@0.18.6 + - @backstage/plugin-signals-backend@0.2.0 + - @backstage/plugin-signals-node@0.1.11 + - @backstage/plugin-techdocs-backend@1.10.13 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-search-backend@1.5.17 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.3.0 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.5.0 + - @backstage/plugin-scaffolder-backend-module-rails@0.5.0 + - @backstage/plugin-devtools-backend@0.4.0 + - @backstage/plugin-app-backend@0.3.74 + - @backstage/plugin-scaffolder-backend@1.25.0 + - @backstage/plugin-auth-backend@0.23.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-catalog-backend@1.26.0 + - @backstage/catalog-client@1.7.0 + - @backstage/plugin-search-backend-module-techdocs@0.2.2 + - @backstage/plugin-search-backend-module-catalog@0.2.2 + - @backstage/plugin-search-backend-module-explore@0.2.2 + - @backstage/plugin-permission-node@0.8.3 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/plugin-events-backend@0.3.12 + - @backstage/plugin-permission-backend@0.5.49 + - @backstage/plugin-proxy-backend@0.5.6 + - @backstage/plugin-search-backend-module-elasticsearch@1.5.6 + - @backstage/plugin-search-backend-module-pg@0.5.35 + - @backstage/integration@1.15.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.5.0 + - @backstage/plugin-events-node@0.4.0 + - @backstage/config@1.2.0 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-backend-node@1.3.2 + +## e2e-test@0.2.20 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.5.19 + - @backstage/cli-common@0.1.14 + - @backstage/errors@1.2.4 + +## @internal/frontend@0.0.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0 + - @backstage/version-bridge@1.0.9 + - @backstage/types@1.1.1 + +## techdocs-cli-embedded-app@0.2.100 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/plugin-techdocs@1.10.9 + - @backstage/plugin-catalog@1.23.0 + - @backstage/cli@0.27.1 + - @backstage/plugin-techdocs-react@1.2.8 + - @backstage/core-app-api@1.15.0 + - @backstage/integration-react@1.1.31 + - @backstage/catalog-model@1.7.0 + - @backstage/app-defaults@1.5.11 + - @backstage/test-utils@1.6.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/theme@0.5.7 + - @backstage/config@1.2.0 + +## yarn-plugin-backstage@0.0.2 + +### Patch Changes + +- bd32d5a: Add additional check before packing workspace to verify that all backstage:^ versions have been removed. +- Updated dependencies + - @backstage/cli-common@0.1.14 + - @backstage/release-manifests@0.0.11 + +## @internal/plugin-todo-list@1.0.31 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/core-plugin-api@1.9.4 + +## @internal/plugin-todo-list-backend@1.0.31 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/errors@1.2.4 diff --git a/docs/releases/v1.31.0-next.2-changelog.md b/docs/releases/v1.31.0-next.2-changelog.md new file mode 100644 index 0000000000..1547a48332 --- /dev/null +++ b/docs/releases/v1.31.0-next.2-changelog.md @@ -0,0 +1,2415 @@ +# Release v1.31.0-next.2 + +Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.31.0-next.2](https://backstage.github.io/upgrade-helper/?to=1.31.0-next.2) + +## @backstage/backend-app-api@1.0.0-next.2 + +### Major Changes + +- ec1b4be: Release 1.0 of the new backend system! :tada: + + The backend system is finally getting promoted to 1.0.0. This means that the API is now stable and breaking changes should not occur until version 2.0.0, see our [package versioning policy](https://backstage.io/docs/overview/versioning-policy/#package-versioning-policy) for more information what this means. + + This release also marks the end of the old backend system based on `createRouter` exports. Going forward backend plugins packages will start to deprecate and later this year remove exports supporting the old backend system. If you would like to help out with this transition, see or consult the [migration guide](https://backstage.io/docs/backend-system/building-plugins-and-modules/migrating/#remove-support-for-the-old-backend-system). + +### Patch Changes + +- 6ed9264: chore(deps): bump `path-to-regexp` from 6.2.2 to 8.0.0 +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/config-loader@1.9.1-next.0 + - @backstage/plugin-permission-node@0.8.3-next.2 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/backend-plugin-api@1.0.0-next.2 + +### Major Changes + +- ec1b4be: Release 1.0 of the new backend system! :tada: + + The backend system is finally getting promoted to 1.0.0. This means that the API is now stable and breaking changes should not occur until version 2.0.0, see our [package versioning policy](https://backstage.io/docs/overview/versioning-policy/#package-versioning-policy) for more information what this means. + + This release also marks the end of the old backend system based on `createRouter` exports. Going forward backend plugins packages will start to deprecate and later this year remove exports supporting the old backend system. If you would like to help out with this transition, see or consult the [migration guide](https://backstage.io/docs/backend-system/building-plugins-and-modules/migrating/#remove-support-for-the-old-backend-system). + +### Patch Changes + +- 8052b9b: Add a `toJSON` on refs so that they can appear in expectations in jest tests +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/backend-test-utils@1.0.0-next.2 + +### Major Changes + +- ec1b4be: Release 1.0 of the new backend system! :tada: + + The backend system is finally getting promoted to 1.0.0. This means that the API is now stable and breaking changes should not occur until version 2.0.0, see our [package versioning policy](https://backstage.io/docs/overview/versioning-policy/#package-versioning-policy) for more information what this means. + + This release also marks the end of the old backend system based on `createRouter` exports. Going forward backend plugins packages will start to deprecate and later this year remove exports supporting the old backend system. If you would like to help out with this transition, see or consult the [migration guide](https://backstage.io/docs/backend-system/building-plugins-and-modules/migrating/#remove-support-for-the-old-backend-system). + +### Patch Changes + +- f421d2a: Make MySQL pool settings a bit more lax +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-app-api@1.0.0-next.2 + - @backstage/backend-defaults@0.5.0-next.2 + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.4.0-next.2 + +## @backstage/backend-defaults@0.5.0-next.2 + +### Minor Changes + +- baeef13: **BREAKING** Removed `createLifecycleMiddleware` and `LifecycleMiddlewareOptions` to clean up API surface. These exports have no external usage and do not provide value in its current form. If you were using these exports, please reach out to the maintainers to discuss your use case. + +### Patch Changes + +- 6ed9264: chore(deps): bump `path-to-regexp` from 6.2.2 to 8.0.0 +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-app-api@1.0.0-next.2 + - @backstage/backend-common@0.25.0-next.2 + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/cli-node@0.2.8-next.0 + - @backstage/integration@1.15.0-next.0 + - @backstage/config-loader@1.9.1-next.0 + - @backstage/plugin-permission-node@0.8.3-next.2 + - @backstage/backend-dev-utils@0.1.5 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.4.0-next.2 + +## @backstage/catalog-client@1.7.0-next.1 + +### Minor Changes + +- 78475c3: Allow offset mode paging in entity list provider + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.6.0 + - @backstage/errors@1.2.4 + +## @backstage/dev-utils@1.1.0-next.2 + +### Minor Changes + +- 10b1452: Allow using translations in `createDevApp` + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/plugin-catalog-react@1.13.0-next.2 + - @backstage/core-app-api@1.14.3-next.0 + - @backstage/integration-react@1.1.31-next.0 + - @backstage/app-defaults@1.5.11-next.1 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/theme@0.5.7-next.0 + - @backstage/catalog-model@1.6.0 + +## @backstage/integration@1.15.0-next.0 + +### Minor Changes + +- 1573014: The Gerrit integration can now resolve Gitiles urls that point to the following + refs: + + - HEAD + - A SHA + - Tag + - Branch + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-auth0-provider@0.1.0-next.0 + +### Minor Changes + +- d908d8c: New module for `@backstage/plugin-auth-backend` that adds a Auth0 auth provider. + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + +## @backstage/plugin-auth-backend-module-bitbucket-server-provider@0.1.0-next.0 + +### Minor Changes + +- 527d973: New module for `@backstage/plugin-auth-backend` that adds a `Bitbucket Server` auth provider. + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + +## @backstage/plugin-catalog@1.23.0-next.2 + +### Minor Changes + +- 78475c3: Allow offset mode paging in entity list provider + +### Patch Changes + +- c891b69: Add `FavoriteToggle` in `core-components` to standardise favorite marking +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/plugin-catalog-react@1.13.0-next.2 + - @backstage/integration-react@1.1.31-next.0 + - @backstage/catalog-client@1.7.0-next.1 + - @backstage/plugin-search-react@1.8.0-next.2 + - @backstage/core-compat-api@0.3.0-next.2 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/frontend-plugin-api@0.8.0-next.2 + - @backstage/plugin-permission-react@0.4.26-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-scaffolder-common@1.5.5 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-catalog-backend@1.26.0-next.2 + +### Minor Changes + +- 78475c3: Allow offset mode paging in entity list provider + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-client@1.7.0-next.1 + - @backstage/integration@1.15.0-next.0 + - @backstage/backend-openapi-utils@0.1.18-next.2 + - @backstage/plugin-permission-node@0.8.3-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.2 + - @backstage/plugin-events-node@0.4.0-next.2 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-backend-module-catalog@0.2.2-next.2 + +## @backstage/plugin-catalog-react@1.13.0-next.2 + +### Minor Changes + +- 78475c3: Allow offset mode paging in entity list provider + +### Patch Changes + +- c891b69: Add `FavoriteToggle` in `core-components` to standardise favorite marking +- b537bd7: Allow custom star icons to be provided via the `star` and `unstarred` icon overrides. See how to override existing icons in the [Backstage documentation](https://backstage.io/docs/getting-started/app-custom-theme/#custom-icons). +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/integration-react@1.1.31-next.0 + - @backstage/catalog-client@1.7.0-next.1 + - @backstage/core-compat-api@0.3.0-next.2 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/frontend-plugin-api@0.8.0-next.2 + - @backstage/version-bridge@1.0.9-next.0 + - @backstage/plugin-permission-react@0.4.26-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-scaffolder@1.25.0-next.2 + +### Minor Changes + +- 860ad3a: Expose styles for TemplateEditor, TemplateFormPreviewer and CustomFieldExplorer +- 4baad34: Added support for `omitExtraData` and `liveOmit` for rjsf in the scaffolder + +### Patch Changes + +- b0a5c9f: The `ui:options` for `OwnedEntityPicker` field are now passed to `EntityPicker`. This allows you to use any `ui:options` which `EntityPicker` accepts in the `OwnedEntityPicker` field including `allowArbitraryValues` and `defaultNamespace`. +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- fa9d8da: Updated dependency `@rjsf/utils` to `5.20.1`. + Updated dependency `@rjsf/core` to `5.20.1`. + Updated dependency `@rjsf/material-ui` to `5.20.1`. + Updated dependency `@rjsf/validator-ajv8` to `5.20.1`. +- 0944334: Removed duplicated titles on Scaffolder `TemplateListPage` component +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/plugin-catalog-react@1.13.0-next.2 + - @backstage/integration-react@1.1.31-next.0 + - @backstage/plugin-scaffolder-react@1.12.0-next.2 + - @backstage/catalog-client@1.7.0-next.1 + - @backstage/integration@1.15.0-next.0 + - @backstage/core-compat-api@0.3.0-next.2 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/frontend-plugin-api@0.8.0-next.2 + - @backstage/plugin-permission-react@0.4.26-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-scaffolder-common@1.5.5 + +## @backstage/plugin-scaffolder-backend@1.25.0-next.2 + +### Minor Changes + +- df9ae9e: Added scaffolder action publish:bitbucketCloud:pull-request + +### Patch Changes + +- f0c6b25: Allow listing file contents with `debug:log` scaffolder action +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-defaults@0.5.0-next.2 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.5.0-next.2 + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-client@1.7.0-next.1 + - @backstage/plugin-scaffolder-backend-module-github@0.5.0-next.2 + - @backstage/integration@1.15.0-next.0 + - @backstage/plugin-permission-node@0.8.3-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-bitbucket-cloud-common@0.2.23-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.0-next.2 + - @backstage/plugin-catalog-node@1.12.7-next.2 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-scaffolder-backend-module-azure@0.2.0-next.2 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.0-next.2 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.0-next.2 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.2.0-next.2 + - @backstage/plugin-scaffolder-backend-module-gitea@0.2.0-next.2 + - @backstage/plugin-scaffolder-common@1.5.5 + - @backstage/plugin-scaffolder-node@0.4.11-next.2 + +## @backstage/plugin-scaffolder-react@1.12.0-next.2 + +### Minor Changes + +- 4baad34: Added support for `omitExtraData` and `liveOmit` for rjsf in the scaffolder + +### Patch Changes + +- 1f3c5aa: Fix scaffolder review step issue where schema options are not handled for fields on multi-step templates. +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- fa9d8da: Updated dependency `@rjsf/utils` to `5.20.1`. + Updated dependency `@rjsf/core` to `5.20.1`. + Updated dependency `@rjsf/material-ui` to `5.20.1`. + Updated dependency `@rjsf/validator-ajv8` to `5.20.1`. +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/plugin-catalog-react@1.13.0-next.2 + - @backstage/catalog-client@1.7.0-next.1 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/theme@0.5.7-next.0 + - @backstage/version-bridge@1.0.9-next.0 + - @backstage/plugin-permission-react@0.4.26-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.5 + +## @backstage/app-defaults@1.5.11-next.1 + +### Patch Changes + +- b537bd7: Allow custom star icons to be provided via the `star` and `unstarred` icon overrides. See how to override existing icons in the [Backstage documentation](https://backstage.io/docs/getting-started/app-custom-theme/#custom-icons). +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/core-app-api@1.14.3-next.0 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/theme@0.5.7-next.0 + - @backstage/plugin-permission-react@0.4.26-next.0 + +## @backstage/backend-common@0.25.0-next.2 + +### Patch Changes + +- 6ed9264: chore(deps): bump `path-to-regexp` from 6.2.2 to 8.0.0 +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- 3606843: Internal fixes to match `testcontainers` update +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/integration@1.15.0-next.0 + - @backstage/config-loader@1.9.1-next.0 + - @backstage/backend-dev-utils@0.1.5 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + +## @backstage/backend-dynamic-feature-service@0.4.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-app-api@1.0.0-next.2 + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-defaults@0.5.0-next.2 + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/cli-node@0.2.8-next.0 + - @backstage/plugin-catalog-backend@1.26.0-next.2 + - @backstage/config-loader@1.9.1-next.0 + - @backstage/plugin-events-backend@0.3.12-next.2 + - @backstage/plugin-permission-node@0.8.3-next.2 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-app-node@0.1.25-next.2 + - @backstage/plugin-events-node@0.4.0-next.2 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-scaffolder-node@0.4.11-next.2 + - @backstage/plugin-search-backend-node@1.3.2-next.2 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/backend-openapi-utils@0.1.18-next.2 + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/errors@1.2.4 + +## @backstage/cli@0.27.1-next.2 + +### Patch Changes + +- 16ffdd6: Remove direct `vite` dependency + +- 8069f4a: Update Scaffolder module template to add itself to the backend + +- 0e1a817: The app build process now outputs an additional `index.html.tmpl` file. This is an non-templated version of the `index.html` file, which can be used to delay templating until runtime. + + The new `index.html.tmpl` file also sets a `backstage-public-path` meta tag to be templated at runtime. The meta tag is in turn picked up by the new `@backstage/cli/config/webpack-public-path.js` entry point script, which uses it to set the runtime public path of the Webpack bundle. + +- d29fc1b: Updated dependency `@module-federation/enhanced` to `^0.6.0`. + +- 4ebf36f: Upgrade to `vite@v5` + +- 2d3caaf: The build commands now support the new `backstage.inline` flag in `package.json`, which causes the contents of private packages to be inlined into the consuming package, rather than be treated as an external dependency. + +- 3d88455: Add support for `backstage:^` version ranges to versions:bump when using the experimental yarn plugin + +- Updated dependencies + - @backstage/cli-node@0.2.8-next.0 + - @backstage/integration@1.15.0-next.0 + - @backstage/config-loader@1.9.1-next.0 + - @backstage/eslint-plugin@0.1.9-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/release-manifests@0.0.11 + - @backstage/types@1.1.1 + +## @backstage/cli-node@0.2.8-next.0 + +### Patch Changes + +- 0c70f43: Add definition for the new `backstage.inline` field in `package.json`. +- Updated dependencies + - @backstage/cli-common@0.1.14 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/config-loader@1.9.1-next.0 + +### Patch Changes + +- ef3c507: Updated dependency `typescript-json-schema` to `^0.65.0`. +- Updated dependencies + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/core-app-api@1.14.3-next.0 + +### Patch Changes + +- ea69e46: The `defaultConfigLoader` now also reads configuration from scripts tags with `type="backstage.io/config"`. The tag is expected to contain a JSON-serialized array of `AppConfig` objects. If any of these script tags are present, the injected runtime configuration in the static assets will no longer be used. +- b537bd7: Allow custom star icons to be provided via the `star` and `unstarred` icon overrides. See how to override existing icons in the [Backstage documentation](https://backstage.io/docs/getting-started/app-custom-theme/#custom-icons). +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/version-bridge@1.0.9-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## @backstage/core-compat-api@0.3.0-next.2 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/frontend-plugin-api@0.8.0-next.2 + - @backstage/version-bridge@1.0.9-next.0 + +## @backstage/core-components@0.14.11-next.1 + +### Patch Changes + +- c891b69: Add `FavoriteToggle` in `core-components` to standardise favorite marking +- 0944334: Removed default title set to Unknown page on `ContentHeaderTitle` component to support usage of component without title prop. +- f325258: Use getOptionalString for optional app.support.items\[].links\[].title +- af4c146: Support menu items should not be buttons in favour of links +- b537bd7: Allow custom star icons to be provided via the `star` and `unstarred` icon overrides. See how to override existing icons in the [Backstage documentation](https://backstage.io/docs/getting-started/app-custom-theme/#custom-icons). +- dbbd93e: Internal update to match recent React types +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/theme@0.5.7-next.0 + - @backstage/version-bridge@1.0.9-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/core-plugin-api@1.9.4-next.0 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/version-bridge@1.0.9-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/create-app@0.5.19-next.2 + +### Patch Changes + +- Bumped create-app version. +- Updated dependencies + - @backstage/cli-common@0.1.14 + +## @backstage/eslint-plugin@0.1.9-next.0 + +### Patch Changes + +- 08895e3: Added support for linting dependencies on workspace packages with the `backstage.inline` flag. + +## @backstage/frontend-app-api@0.9.0-next.2 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-app-api@1.14.3-next.0 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/frontend-defaults@0.1.0-next.1 + - @backstage/frontend-plugin-api@0.8.0-next.2 + - @backstage/version-bridge@1.0.9-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/frontend-defaults@0.1.0-next.1 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/plugin-app@0.1.0-next.2 + - @backstage/frontend-app-api@0.9.0-next.2 + - @backstage/frontend-plugin-api@0.8.0-next.2 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/frontend-plugin-api@0.8.0-next.2 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- 043d7cd: Internal refactor +- 2a61422: The `factory` option is no longer required when overriding an extension. +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/version-bridge@1.0.9-next.0 + - @backstage/types@1.1.1 + +## @backstage/frontend-test-utils@0.2.0-next.2 + +### Patch Changes + +- 2a61422: The extension tester will no longer unconditionally enable any additional extensions that have been added. +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- 043d7cd: Internal refactor +- Updated dependencies + - @backstage/test-utils@1.6.0-next.1 + - @backstage/plugin-app@0.1.0-next.2 + - @backstage/frontend-app-api@0.9.0-next.2 + - @backstage/frontend-plugin-api@0.8.0-next.2 + - @backstage/version-bridge@1.0.9-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## @backstage/integration-react@1.1.31-next.0 + +### Patch Changes + +- 8a9d797: Remove unnecessary broad permissions from Gitlab `SCMAuth` + + Newer versions of Gitlab (after 2019) do not require the broad api permissions to write to repos. + +- Updated dependencies + - @backstage/integration@1.15.0-next.0 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/config@1.2.0 + +## @backstage/repo-tools@0.9.7-next.2 + +### Patch Changes + +- 1a8837e: Avoid generating API reports for packages with `backstage.inline` set. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/cli-node@0.2.8-next.0 + - @backstage/config-loader@1.9.1-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/cli-common@0.1.14 + - @backstage/errors@1.2.4 + +## @techdocs/cli@1.8.19-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.0-next.2 + - @backstage/plugin-techdocs-node@1.12.11-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + +## @backstage/test-utils@1.6.0-next.1 + +### Patch Changes + +- b537bd7: Allow custom star icons to be provided via the `star` and `unstarred` icon overrides. See how to override existing icons in the [Backstage documentation](https://backstage.io/docs/getting-started/app-custom-theme/#custom-icons). +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-app-api@1.14.3-next.0 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/theme@0.5.7-next.0 + - @backstage/plugin-permission-react@0.4.26-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/theme@0.5.7-next.0 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. + +## @backstage/version-bridge@1.0.9-next.0 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. + +## @backstage/plugin-api-docs@0.11.9-next.2 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- 8a474f2: Updating docs to use `createFrontendModule` instead +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/plugin-catalog-react@1.13.0-next.2 + - @backstage/plugin-catalog@1.23.0-next.2 + - @backstage/core-compat-api@0.3.0-next.2 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/frontend-plugin-api@0.8.0-next.2 + - @backstage/plugin-permission-react@0.4.26-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/plugin-catalog-common@1.0.26 + +## @backstage/plugin-app@0.1.0-next.2 + +### Patch Changes + +- 57bf6ae: Fix issue with `AlertDisplay` and other components defined with `AppRootElementBlueprint` not being rendered when at the `SignInWrapper` +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/frontend-plugin-api@0.8.0-next.2 + - @backstage/theme@0.5.7-next.0 + - @backstage/plugin-permission-react@0.4.26-next.0 + +## @backstage/plugin-app-backend@0.3.74-next.2 + +### Patch Changes + +- 590fb2d: **BREAKING**: The app backend now supports the new `index.html.tmpl` output from `@backstage/cli`. If available, the `index.html` will be templated at runtime with the current configuration of the app backend. + + This is marked as a breaking change because you must now supply the app build-time configuration to the backend. This change also affects the public path behavior, where it is no longer necessary to build the app with the correct public path upfront. You now only need to supply a correct `app.baseUrl` to the app backend plugin at runtime. + + An effect that this change has is that the `index.html` will now contain and present the frontend configuration in an easily readable way, which can aid in debugging. This data was always available in the frontend, but it was injected and hidden in the static bundle. + + This templating behavior is enabled by default, but it can be disabled by setting the `app.disableConfigInjection` configuration option to `true`. + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/config-loader@1.9.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-app-node@0.1.25-next.2 + +## @backstage/plugin-app-node@0.1.25-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/config-loader@1.9.1-next.0 + +## @backstage/plugin-app-visualizer@0.1.10-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/frontend-plugin-api@0.8.0-next.2 + +## @backstage/plugin-auth-backend@0.23.0-next.2 + +### Patch Changes + +- 527d973: Migrated the `Bitbucket Server` auth provider to be implemented using the new `@backstage/plugin-auth-backend-module-bitbucket-server-provider` module. +- d908d8c: Migrated the `Auth0` auth provider to be implemented using the new `@backstage/plugin-auth-backend-module-auth0-provider` module. +- 92118cd: Updated dependency `@node-saml/passport-saml` to `^5.0.0`. +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-client@1.7.0-next.1 + - @backstage/plugin-auth-backend-module-auth0-provider@0.1.0-next.0 + - @backstage/plugin-auth-backend-module-atlassian-provider@0.3.0-next.2 + - @backstage/plugin-auth-backend-module-bitbucket-provider@0.2.0-next.2 + - @backstage/plugin-auth-backend-module-github-provider@0.2.0-next.2 + - @backstage/plugin-auth-backend-module-gitlab-provider@0.2.0-next.2 + - @backstage/plugin-auth-backend-module-google-provider@0.2.0-next.2 + - @backstage/plugin-auth-backend-module-microsoft-provider@0.2.0-next.2 + - @backstage/plugin-auth-backend-module-oauth2-provider@0.3.0-next.2 + - @backstage/plugin-auth-backend-module-oidc-provider@0.3.0-next.2 + - @backstage/plugin-auth-backend-module-okta-provider@0.1.0-next.2 + - @backstage/plugin-auth-backend-module-onelogin-provider@0.2.0-next.2 + - @backstage/plugin-auth-backend-module-bitbucket-server-provider@0.1.0-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-backend-module-aws-alb-provider@0.2.0-next.2 + - @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.2.0-next.2 + - @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.3.0-next.2 + - @backstage/plugin-auth-backend-module-gcp-iap-provider@0.3.0-next.2 + - @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.2.0-next.2 + - @backstage/plugin-catalog-node@1.12.7-next.2 + +## @backstage/plugin-auth-backend-module-atlassian-provider@0.3.0-next.2 + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + +## @backstage/plugin-auth-backend-module-aws-alb-provider@0.2.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/plugin-auth-backend@0.23.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.2.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-bitbucket-provider@0.2.0-next.2 + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + +## @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.3.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-gcp-iap-provider@0.3.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-auth-backend-module-github-provider@0.2.0-next.2 + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + +## @backstage/plugin-auth-backend-module-gitlab-provider@0.2.0-next.2 + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + +## @backstage/plugin-auth-backend-module-google-provider@0.2.0-next.2 + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + +## @backstage/plugin-auth-backend-module-guest-provider@0.2.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-microsoft-provider@0.2.0-next.2 + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + +## @backstage/plugin-auth-backend-module-oauth2-provider@0.3.0-next.2 + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + +## @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.2.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-oidc-provider@0.3.0-next.2 + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/plugin-auth-backend@0.23.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + +## @backstage/plugin-auth-backend-module-okta-provider@0.1.0-next.2 + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + +## @backstage/plugin-auth-backend-module-onelogin-provider@0.2.0-next.2 + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + +## @backstage/plugin-auth-backend-module-pinniped-provider@0.2.0-next.2 + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/config@1.2.0 + +## @backstage/plugin-auth-backend-module-vmware-cloud-provider@0.3.0-next.2 + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-model@1.6.0 + +## @backstage/plugin-auth-node@0.5.2-next.2 + +### Patch Changes + +- d908d8c: Accepts an optional options object in the `PassportOAuthAuthenticatorHelper.authenticate` method. +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-client@1.7.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-auth-react@0.1.6-next.1 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-bitbucket-cloud-common@0.2.23-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.15.0-next.0 + +## @backstage/plugin-catalog-backend-module-aws@0.4.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/integration@1.15.0-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.2 + - @backstage/plugin-kubernetes-common@0.8.2 + +## @backstage/plugin-catalog-backend-module-azure@0.2.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/integration@1.15.0-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.2 + +## @backstage/plugin-catalog-backend-module-backstage-openapi@0.4.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/backend-openapi-utils@0.1.18-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.12.7-next.2 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.3.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-client@1.7.0-next.1 + - @backstage/integration@1.15.0-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.23-next.0 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.2 + - @backstage/plugin-events-node@0.4.0-next.2 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.2.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/integration@1.15.0-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.12.7-next.2 + +## @backstage/plugin-catalog-backend-module-gcp@0.3.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-node@1.12.7-next.2 + - @backstage/plugin-kubernetes-common@0.8.2 + +## @backstage/plugin-catalog-backend-module-gerrit@0.2.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/integration@1.15.0-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.12.7-next.2 + +## @backstage/plugin-catalog-backend-module-github@0.7.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-client@1.7.0-next.1 + - @backstage/plugin-catalog-backend@1.26.0-next.2 + - @backstage/integration@1.15.0-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.2 + - @backstage/plugin-events-node@0.4.0-next.2 + +## @backstage/plugin-catalog-backend-module-github-org@0.3.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-backend-module-github@0.7.3-next.2 + - @backstage/plugin-catalog-node@1.12.7-next.2 + - @backstage/plugin-events-node@0.4.0-next.2 + +## @backstage/plugin-catalog-backend-module-gitlab@0.4.2-next.2 + +### Patch Changes + +- 0476be3: Add the `relations` array to allow Backstage to mirror GitLab's membership behavior, including descendant, inherited, and shared-from-group memberships. + + The previous `allowInherited` config option will be deprecated in future versions. Use the `relations` array with the `INHERITED` option instead. + + ```yaml + catalog: + providers: + gitlab: + development: + relations: + - INHERITED + ``` + +- Updated dependencies + - @backstage/backend-defaults@0.5.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/integration@1.15.0-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.2 + - @backstage/plugin-events-node@0.4.0-next.2 + +## @backstage/plugin-catalog-backend-module-gitlab-org@0.2.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/plugin-catalog-backend-module-gitlab@0.4.2-next.2 + - @backstage/plugin-catalog-node@1.12.7-next.2 + - @backstage/plugin-events-node@0.4.0-next.2 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.5.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/plugin-catalog-backend@1.26.0-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.12.7-next.2 + - @backstage/plugin-events-node@0.4.0-next.2 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-catalog-backend-module-ldap@0.9.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.2 + +## @backstage/plugin-catalog-backend-module-logs@0.1.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/plugin-catalog-backend@1.26.0-next.2 + - @backstage/plugin-events-node@0.4.0-next.2 + +## @backstage/plugin-catalog-backend-module-msgraph@0.6.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.2 + +## @backstage/plugin-catalog-backend-module-openapi@0.2.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/plugin-catalog-backend@1.26.0-next.2 + - @backstage/integration@1.15.0-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.2 + +## @backstage/plugin-catalog-backend-module-puppetdb@0.2.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.12.7-next.2 + +## @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.2 + - @backstage/plugin-scaffolder-common@1.5.5 + +## @backstage/plugin-catalog-backend-module-unprocessed@0.5.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.12.7-next.2 + - @backstage/plugin-catalog-unprocessed-entities-common@0.0.4 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-catalog-graph@0.4.9-next.2 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- 8a474f2: Updating docs to use `createFrontendModule` instead +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/plugin-catalog-react@1.13.0-next.2 + - @backstage/catalog-client@1.7.0-next.1 + - @backstage/core-compat-api@0.3.0-next.2 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/frontend-plugin-api@0.8.0-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-import@0.12.3-next.2 + +### Patch Changes + +- f3c90da: Support button title should be contained in a single menu item +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/plugin-catalog-react@1.13.0-next.2 + - @backstage/integration-react@1.1.31-next.0 + - @backstage/catalog-client@1.7.0-next.1 + - @backstage/integration@1.15.0-next.0 + - @backstage/core-compat-api@0.3.0-next.2 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/frontend-plugin-api@0.8.0-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.0.26 + +## @backstage/plugin-catalog-node@1.12.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-client@1.7.0-next.1 + - @backstage/plugin-permission-node@0.8.3-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-catalog-unprocessed-entities@0.2.8-next.1 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-config-schema@0.1.59-next.1 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-devtools@0.1.18-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/core-compat-api@0.3.0-next.2 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/frontend-plugin-api@0.8.0-next.2 + - @backstage/plugin-permission-react@0.4.26-next.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-devtools-common@0.1.12 + +## @backstage/plugin-devtools-backend@0.4.0-next.2 + +### Patch Changes + +- 5d1670f: Update README installation instructions +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/config-loader@1.9.1-next.0 + - @backstage/plugin-permission-node@0.8.3-next.2 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-devtools-common@0.1.12 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-events-backend@0.3.12-next.2 + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/config@1.2.0 + - @backstage/plugin-events-node@0.4.0-next.2 + +## @backstage/plugin-events-backend-module-aws-sqs@0.4.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.4.0-next.2 + +## @backstage/plugin-events-backend-module-azure@0.2.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/plugin-events-node@0.4.0-next.2 + +## @backstage/plugin-events-backend-module-bitbucket-cloud@0.2.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/plugin-events-node@0.4.0-next.2 + +## @backstage/plugin-events-backend-module-gerrit@0.2.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/plugin-events-node@0.4.0-next.2 + +## @backstage/plugin-events-backend-module-github@0.2.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/config@1.2.0 + - @backstage/plugin-events-node@0.4.0-next.2 + +## @backstage/plugin-events-backend-module-gitlab@0.2.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/config@1.2.0 + - @backstage/plugin-events-node@0.4.0-next.2 + +## @backstage/plugin-events-backend-test-utils@0.1.35-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.0-next.2 + +## @backstage/plugin-events-node@0.4.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + +## @backstage/plugin-home@0.7.10-next.2 + +### Patch Changes + +- c891b69: Add `FavoriteToggle` in `core-components` to standardise favorite marking +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- fa9d8da: Updated dependency `@rjsf/utils` to `5.20.1`. + Updated dependency `@rjsf/core` to `5.20.1`. + Updated dependency `@rjsf/material-ui` to `5.20.1`. + Updated dependency `@rjsf/validator-ajv8` to `5.20.1`. +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/plugin-catalog-react@1.13.0-next.2 + - @backstage/core-app-api@1.14.3-next.0 + - @backstage/catalog-client@1.7.0-next.1 + - @backstage/core-compat-api@0.3.0-next.2 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/frontend-plugin-api@0.8.0-next.2 + - @backstage/theme@0.5.7-next.0 + - @backstage/plugin-home-react@0.1.17-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + +## @backstage/plugin-home-react@0.1.17-next.1 + +### Patch Changes + +- fa9d8da: Updated dependency `@rjsf/utils` to `5.20.1`. + Updated dependency `@rjsf/core` to `5.20.1`. + Updated dependency `@rjsf/material-ui` to `5.20.1`. + Updated dependency `@rjsf/validator-ajv8` to `5.20.1`. +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/core-plugin-api@1.9.4-next.0 + +## @backstage/plugin-kubernetes@0.11.14-next.2 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/plugin-catalog-react@1.13.0-next.2 + - @backstage/core-compat-api@0.3.0-next.2 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/frontend-plugin-api@0.8.0-next.2 + - @backstage/plugin-kubernetes-react@0.4.3-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/plugin-kubernetes-common@0.8.2 + +## @backstage/plugin-kubernetes-backend@0.18.6-next.2 + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-client@1.7.0-next.1 + - @backstage/plugin-kubernetes-node@0.1.19-next.2 + - @backstage/plugin-permission-node@0.8.3-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.12.7-next.2 + - @backstage/plugin-kubernetes-common@0.8.2 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-kubernetes-cluster@0.0.15-next.2 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/plugin-catalog-react@1.13.0-next.2 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/plugin-kubernetes-react@0.4.3-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/plugin-kubernetes-common@0.8.2 + +## @backstage/plugin-kubernetes-node@0.1.19-next.2 + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.8.2 + +## @backstage/plugin-kubernetes-react@0.4.3-next.1 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.8.2 + +## @backstage/plugin-notifications@0.3.1-next.2 + +### Patch Changes + +- 653f60b: Severity filter label newly contains "Min severity" to better describe range instead of exact value. +- 4a53dd0: Implement icon in backend and show icon in table if available. +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/theme@0.5.7-next.0 + - @backstage/plugin-signals-react@0.0.5-next.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.5 + +## @backstage/plugin-notifications-backend@0.4.0-next.2 + +### Patch Changes + +- 4a53dd0: Implement icon in backend and show icon in table if available. +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-client@1.7.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.12.7-next.2 + - @backstage/plugin-events-node@0.4.0-next.2 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.6-next.2 + - @backstage/plugin-signals-node@0.1.11-next.2 + +## @backstage/plugin-notifications-backend-module-email@0.3.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-client@1.7.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.12.7-next.2 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.6-next.2 + +## @backstage/plugin-notifications-node@0.2.6-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-client@1.7.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-signals-node@0.1.11-next.2 + +## @backstage/plugin-org@0.6.29-next.2 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- 8a474f2: Updating docs to use `createFrontendModule` instead +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/plugin-catalog-react@1.13.0-next.2 + - @backstage/core-compat-api@0.3.0-next.2 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/frontend-plugin-api@0.8.0-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/plugin-catalog-common@1.0.26 + +## @backstage/plugin-org-react@0.1.28-next.2 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/plugin-catalog-react@1.13.0-next.2 + - @backstage/catalog-client@1.7.0-next.1 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/catalog-model@1.6.0 + +## @backstage/plugin-permission-backend@0.5.49-next.2 + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/plugin-permission-node@0.8.3-next.2 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-permission-backend-module-allow-all-policy@0.2.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/plugin-permission-node@0.8.3-next.2 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-permission-node@0.8.3-next.2 + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-permission-react@0.4.26-next.0 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-proxy-backend@0.5.6-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-backend-module-azure@0.2.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/integration@1.15.0-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.11-next.2 + +## @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/integration@1.15.0-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.0-next.2 + - @backstage/plugin-scaffolder-node@0.4.11-next.2 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.0-next.2 + +### Patch Changes + +- df9ae9e: Added scaffolder action publish:bitbucketCloud:pull-request +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/integration@1.15.0-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-bitbucket-cloud-common@0.2.23-next.0 + - @backstage/plugin-scaffolder-node@0.4.11-next.2 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/integration@1.15.0-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.11-next.2 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.3.0-next.2 + +### Patch Changes + +- 5d1670f: Update README installation instructions +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/integration@1.15.0-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.11-next.2 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.3.0-next.2 + +### Patch Changes + +- 5d1670f: Update README installation instructions +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-defaults@0.5.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/integration@1.15.0-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.11-next.2 + +## @backstage/plugin-scaffolder-backend-module-gcp@0.2.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/integration@1.15.0-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.11-next.2 + +## @backstage/plugin-scaffolder-backend-module-gerrit@0.2.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/integration@1.15.0-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.11-next.2 + +## @backstage/plugin-scaffolder-backend-module-gitea@0.2.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/integration@1.15.0-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.11-next.2 + +## @backstage/plugin-scaffolder-backend-module-github@0.5.0-next.2 + +### Patch Changes + +- 22a19e6: Added the ability for the actions `publish:github` and `github:repo:create` to take inputs for 'custom properties' for organization repositories. +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/integration@1.15.0-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.11-next.2 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.5.0-next.2 + +### Patch Changes + +- 5d1670f: Update README installation instructions +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/integration@1.15.0-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.11-next.2 + +## @backstage/plugin-scaffolder-backend-module-notifications@0.1.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.6-next.2 + - @backstage/plugin-scaffolder-node@0.4.11-next.2 + +## @backstage/plugin-scaffolder-backend-module-rails@0.5.0-next.2 + +### Patch Changes + +- 5d1670f: Update README installation instructions +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/integration@1.15.0-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.11-next.2 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.2.0-next.2 + +### Patch Changes + +- 5d1670f: Update README installation instructions +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.11-next.2 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.4.0-next.2 + +### Patch Changes + +- 5d1670f: Update README installation instructions +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.11-next.2 + - @backstage/plugin-scaffolder-node-test-utils@0.1.12-next.2 + +## @backstage/plugin-scaffolder-node@0.4.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/integration@1.15.0-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.5 + +## @backstage/plugin-scaffolder-node-test-utils@0.1.12-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-test-utils@1.0.0-next.2 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.11-next.2 + +## @backstage/plugin-search@1.4.16-next.2 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/plugin-catalog-react@1.13.0-next.2 + - @backstage/plugin-search-react@1.8.0-next.2 + - @backstage/core-compat-api@0.3.0-next.2 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/frontend-plugin-api@0.8.0-next.2 + - @backstage/version-bridge@1.0.9-next.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-backend@1.5.17-next.2 + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-defaults@0.5.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/backend-openapi-utils@0.1.18-next.2 + - @backstage/plugin-permission-node@0.8.3-next.2 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-backend-node@1.3.2-next.2 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-backend-module-catalog@0.2.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-client@1.7.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.2 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-backend-node@1.3.2-next.2 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-backend-module-elasticsearch@1.5.6-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-backend-node@1.3.2-next.2 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-backend-module-explore@0.2.2-next.2 + +### Patch Changes + +- 276f433: Updated dependency `@backstage-community/plugin-explore-common` to `^0.0.5`. +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/config@1.2.0 + - @backstage/plugin-search-backend-node@1.3.2-next.2 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-backend-module-pg@0.5.35-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/config@1.2.0 + - @backstage/plugin-search-backend-node@1.3.2-next.2 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-backend-module-stack-overflow-collator@0.3.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/config@1.2.0 + - @backstage/plugin-search-backend-node@1.3.2-next.2 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-backend-module-techdocs@0.2.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-client@1.7.0-next.1 + - @backstage/plugin-techdocs-node@1.12.11-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.2 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-backend-node@1.3.2-next.2 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-backend-node@1.3.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-react@1.8.0-next.2 + +### Patch Changes + +- dbbd93e: Internal update to match recent React types +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/frontend-plugin-api@0.8.0-next.2 + - @backstage/theme@0.5.7-next.0 + - @backstage/version-bridge@1.0.9-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-signals@0.0.10-next.2 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/theme@0.5.7-next.0 + - @backstage/plugin-signals-react@0.0.5-next.1 + - @backstage/types@1.1.1 + +## @backstage/plugin-signals-backend@0.2.0-next.2 + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.4.0-next.2 + - @backstage/plugin-signals-node@0.1.11-next.2 + +## @backstage/plugin-signals-node@0.1.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.4.0-next.2 + +## @backstage/plugin-signals-react@0.0.5-next.1 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-techdocs@1.10.9-next.2 + +### Patch Changes + +- c891b69: Add `FavoriteToggle` in `core-components` to standardise favorite marking +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- 97db53e: Enhanced the table hover effect with a lighter color and updated the border radius to align with Backstage's theme styling +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/plugin-catalog-react@1.13.0-next.2 + - @backstage/integration-react@1.1.31-next.0 + - @backstage/plugin-search-react@1.8.0-next.2 + - @backstage/integration@1.15.0-next.0 + - @backstage/core-compat-api@0.3.0-next.2 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/frontend-plugin-api@0.8.0-next.2 + - @backstage/theme@0.5.7-next.0 + - @backstage/plugin-auth-react@0.1.6-next.1 + - @backstage/plugin-techdocs-react@1.2.8-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-techdocs-common@0.1.0 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.38-next.2 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.13.0-next.2 + - @backstage/plugin-techdocs@1.10.9-next.2 + - @backstage/plugin-catalog@1.23.0-next.2 + - @backstage/core-app-api@1.14.3-next.0 + - @backstage/integration-react@1.1.31-next.0 + - @backstage/test-utils@1.6.0-next.1 + - @backstage/plugin-search-react@1.8.0-next.2 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/plugin-techdocs-react@1.2.8-next.2 + +## @backstage/plugin-techdocs-backend@1.10.13-next.2 + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-client@1.7.0-next.1 + - @backstage/plugin-techdocs-node@1.12.11-next.2 + - @backstage/integration@1.15.0-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.2 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-backend-module-techdocs@0.2.2-next.2 + - @backstage/plugin-techdocs-common@0.1.0 + +## @backstage/plugin-techdocs-module-addons-contrib@1.1.14-next.2 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/integration-react@1.1.31-next.0 + - @backstage/integration@1.15.0-next.0 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/plugin-techdocs-react@1.2.8-next.2 + +## @backstage/plugin-techdocs-node@1.12.11-next.2 + +### Patch Changes + +- 57da51f: Add support for mapping custom tags in the techdocs yaml parser that validates the mkdocs.yaml file +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- 3606843: Internal fixes to match `testcontainers` update +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/integration@1.15.0-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-techdocs-common@0.1.0 + +## @backstage/plugin-techdocs-react@1.2.8-next.2 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/version-bridge@1.0.9-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + +## @backstage/plugin-user-settings@0.8.12-next.2 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- da86ac2: Update README to clarify location of additional tabs example +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/plugin-catalog-react@1.13.0-next.2 + - @backstage/core-app-api@1.14.3-next.0 + - @backstage/core-compat-api@0.3.0-next.2 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/frontend-plugin-api@0.8.0-next.2 + - @backstage/theme@0.5.7-next.0 + - @backstage/plugin-signals-react@0.0.5-next.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-user-settings-common@0.0.1 + +## @backstage/plugin-user-settings-backend@0.2.24-next.2 + +### Patch Changes + +- 5d1670f: Update README installation instructions +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-defaults@0.5.0-next.2 + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-node@0.1.11-next.2 + - @backstage/plugin-user-settings-common@0.0.1 + +## example-app@0.2.101-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/plugin-catalog-react@1.13.0-next.2 + - @backstage/plugin-techdocs@1.10.9-next.2 + - @backstage/plugin-catalog@1.23.0-next.2 + - @backstage/plugin-home@0.7.10-next.2 + - @backstage/cli@0.27.1-next.2 + - @backstage/core-app-api@1.14.3-next.0 + - @backstage/integration-react@1.1.31-next.0 + - @backstage/plugin-scaffolder@1.25.0-next.2 + - @backstage/plugin-notifications@0.3.1-next.2 + - @backstage/plugin-scaffolder-react@1.12.0-next.2 + - @backstage/app-defaults@1.5.11-next.1 + - @backstage/plugin-catalog-import@0.12.3-next.2 + - @backstage/plugin-search-react@1.8.0-next.2 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/frontend-app-api@0.9.0-next.2 + - @backstage/theme@0.5.7-next.0 + - @backstage/plugin-api-docs@0.11.9-next.2 + - @backstage/plugin-auth-react@0.1.6-next.1 + - @backstage/plugin-catalog-graph@0.4.9-next.2 + - @backstage/plugin-catalog-unprocessed-entities@0.2.8-next.1 + - @backstage/plugin-kubernetes-cluster@0.0.15-next.2 + - @backstage/plugin-kubernetes@0.11.14-next.2 + - @backstage/plugin-org@0.6.29-next.2 + - @backstage/plugin-permission-react@0.4.26-next.0 + - @backstage/plugin-search@1.4.16-next.2 + - @backstage/plugin-signals@0.0.10-next.2 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.14-next.2 + - @backstage/plugin-techdocs-react@1.2.8-next.2 + - @backstage/plugin-user-settings@0.8.12-next.2 + - @backstage/plugin-devtools@0.1.18-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-search-common@1.2.14 + +## example-app-next@0.0.15-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/plugin-catalog-react@1.13.0-next.2 + - @backstage/plugin-techdocs@1.10.9-next.2 + - @backstage/plugin-catalog@1.23.0-next.2 + - @backstage/plugin-home@0.7.10-next.2 + - @backstage/cli@0.27.1-next.2 + - @backstage/core-app-api@1.14.3-next.0 + - @backstage/integration-react@1.1.31-next.0 + - @backstage/plugin-scaffolder@1.25.0-next.2 + - @backstage/plugin-notifications@0.3.1-next.2 + - @backstage/plugin-scaffolder-react@1.12.0-next.2 + - @backstage/app-defaults@1.5.11-next.1 + - @backstage/plugin-catalog-import@0.12.3-next.2 + - @backstage/plugin-app@0.1.0-next.2 + - @backstage/plugin-search-react@1.8.0-next.2 + - @backstage/core-compat-api@0.3.0-next.2 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/frontend-app-api@0.9.0-next.2 + - @backstage/frontend-defaults@0.1.0-next.1 + - @backstage/frontend-plugin-api@0.8.0-next.2 + - @backstage/theme@0.5.7-next.0 + - @backstage/plugin-api-docs@0.11.9-next.2 + - @backstage/plugin-auth-react@0.1.6-next.1 + - @backstage/plugin-catalog-graph@0.4.9-next.2 + - @backstage/plugin-catalog-unprocessed-entities@0.2.8-next.1 + - @backstage/plugin-kubernetes-cluster@0.0.15-next.2 + - @backstage/plugin-kubernetes@0.11.14-next.2 + - @backstage/plugin-org@0.6.29-next.2 + - @backstage/plugin-permission-react@0.4.26-next.0 + - @backstage/plugin-search@1.4.16-next.2 + - @backstage/plugin-signals@0.0.10-next.2 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.14-next.2 + - @backstage/plugin-techdocs-react@1.2.8-next.2 + - @backstage/plugin-user-settings@0.8.12-next.2 + - @backstage/plugin-app-visualizer@0.1.10-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-search-common@1.2.14 + +## app-next-example-plugin@0.0.15-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/frontend-plugin-api@0.8.0-next.2 + +## example-backend@0.0.30-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.0-next.2 + - @backstage/plugin-devtools-backend@0.4.0-next.2 + - @backstage/plugin-scaffolder-backend@1.25.0-next.2 + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/plugin-auth-backend@0.23.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/plugin-catalog-backend@1.26.0-next.2 + - @backstage/plugin-app-backend@0.3.74-next.2 + - @backstage/plugin-notifications-backend@0.4.0-next.2 + - @backstage/plugin-scaffolder-backend-module-github@0.5.0-next.2 + - @backstage/plugin-auth-backend-module-github-provider@0.2.0-next.2 + - @backstage/plugin-kubernetes-backend@0.18.6-next.2 + - @backstage/plugin-permission-backend@0.5.49-next.2 + - @backstage/plugin-permission-node@0.8.3-next.2 + - @backstage/plugin-search-backend@1.5.17-next.2 + - @backstage/plugin-signals-backend@0.2.0-next.2 + - @backstage/plugin-techdocs-backend@1.10.13-next.2 + - @backstage/plugin-search-backend-module-explore@0.2.2-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.0-next.2 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.4.0-next.2 + - @backstage/plugin-catalog-backend-module-openapi@0.2.0-next.2 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.0-next.2 + - @backstage/plugin-catalog-backend-module-unprocessed@0.5.0-next.2 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.0-next.2 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-proxy-backend@0.5.6-next.2 + - @backstage/plugin-search-backend-module-catalog@0.2.2-next.2 + - @backstage/plugin-search-backend-module-techdocs@0.2.2-next.2 + - @backstage/plugin-search-backend-node@1.3.2-next.2 + +## example-backend-legacy@0.2.102-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-defaults@0.5.0-next.2 + - @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.3.0-next.2 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.5.0-next.2 + - @backstage/plugin-scaffolder-backend-module-rails@0.5.0-next.2 + - @backstage/plugin-devtools-backend@0.4.0-next.2 + - @backstage/plugin-scaffolder-backend@1.25.0-next.2 + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/plugin-auth-backend@0.23.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-client@1.7.0-next.1 + - @backstage/plugin-catalog-backend@1.26.0-next.2 + - @backstage/plugin-app-backend@0.3.74-next.2 + - @backstage/integration@1.15.0-next.0 + - @backstage/plugin-events-backend@0.3.12-next.2 + - @backstage/plugin-kubernetes-backend@0.18.6-next.2 + - @backstage/plugin-permission-backend@0.5.49-next.2 + - @backstage/plugin-permission-node@0.8.3-next.2 + - @backstage/plugin-search-backend@1.5.17-next.2 + - @backstage/plugin-signals-backend@0.2.0-next.2 + - @backstage/plugin-techdocs-backend@1.10.13-next.2 + - @backstage/plugin-search-backend-module-explore@0.2.2-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.0-next.2 + - @backstage/plugin-catalog-backend-module-unprocessed@0.5.0-next.2 + - @backstage/plugin-catalog-node@1.12.7-next.2 + - @backstage/plugin-events-node@0.4.0-next.2 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-proxy-backend@0.5.6-next.2 + - @backstage/plugin-search-backend-module-catalog@0.2.2-next.2 + - @backstage/plugin-search-backend-module-elasticsearch@1.5.6-next.2 + - @backstage/plugin-search-backend-module-pg@0.5.35-next.2 + - @backstage/plugin-search-backend-module-techdocs@0.2.2-next.2 + - @backstage/plugin-search-backend-node@1.3.2-next.2 + - @backstage/plugin-signals-node@0.1.11-next.2 + +## e2e-test@0.2.20-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.5.19-next.2 + - @backstage/cli-common@0.1.14 + - @backstage/errors@1.2.4 + +## @internal/frontend@0.0.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0-next.2 + - @backstage/version-bridge@1.0.9-next.0 + - @backstage/types@1.1.1 + +## techdocs-cli-embedded-app@0.2.100-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/plugin-techdocs@1.10.9-next.2 + - @backstage/plugin-catalog@1.23.0-next.2 + - @backstage/cli@0.27.1-next.2 + - @backstage/core-app-api@1.14.3-next.0 + - @backstage/integration-react@1.1.31-next.0 + - @backstage/app-defaults@1.5.11-next.1 + - @backstage/test-utils@1.6.0-next.1 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/theme@0.5.7-next.0 + - @backstage/plugin-techdocs-react@1.2.8-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + +## @internal/plugin-todo-list@1.0.31-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/core-plugin-api@1.9.4-next.0 + +## @internal/plugin-todo-list-backend@1.0.31-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/errors@1.2.4 diff --git a/docs/releases/v1.31.0.md b/docs/releases/v1.31.0.md new file mode 100644 index 0000000000..37b11c2b56 --- /dev/null +++ b/docs/releases/v1.31.0.md @@ -0,0 +1,144 @@ +--- +id: v1.31.0 +title: v1.31.0 +description: Backstage Release v1.31.0 +--- + +These are the release notes for the v1.31.0 release of [Backstage](https://backstage.io/). + +A huge thanks to the whole team of maintainers and contributors as well as the amazing Backstage Community for the hard work in getting this release developed and done. + +## Highlights + +### Backend System 1.0 🎉 + +The time has come for releasing [the new Backend System](https://backstage.io/docs/backend-system/) as stable version 1.0! This means that the API is now stable and breaking changes should not occur until version 2.0, see our [package versioning policy](https://backstage.io/docs/overview/versioning-policy/#package-versioning-policy) for more information about this. + +There is documentation in place both for [migrating backends](https://backstage.io/docs/backend-system/building-backends/migrating) and [migrating plugins](https://backstage.io/docs/backend-system/building-plugins-and-modules/migrating), and we encourage you to start doing so as soon as possible. Going forward, we will increasingly refer to this as "The backend system", and the previous one as "The old backend system". The main Backstage and [community-plugins](https://github.com/backstage/community-plugins) repositories have already been more or less fully migrated over. + +The backend system brings a host of improvements to the way that backends and their features are constructed. Instead of the old convention-based structure that could lead to migration pains, features now fit together with dependency injection like a jigsaw puzzle while leveraging powerful core services and extending each other dynamically with additional behaviors. And this is just scratching the surface of it - do check out [the docs](https://backstage.io/docs/backend-system/)! + +We are very excited about this important milestone after a long period of development and refinement together with our passionate community, and hope that you will find it as refreshing and simple yet powerful as it was envisioned to be. This also lays the foundation for us being able to continue iterating at a high pace without incurring undue end user breakages during upgrades. + +Keep the feedback coming! Either on the [Community Discord](https://discord.gg/backstage-687207715902193673), or [through issues](https://github.com/backstage/backstage/issues/new/choose) on GitHub. Also if you’re looking for a way to help, please take a look at these [backstage](https://github.com/backstage/backstage/issues/26353) and [community plugins](https://github.com/backstage/community-plugins/issues/1176) issues about deprecating old-backend capabilities of already migrated plugins. + +#### Technical details + +At a technical level, the following packages are now on major version 1, and their major version 0 will stop receiving feature updates: + +- `@backstage/backend-app-api` +- `@backstage/backend-plugin-api` +- `@backstage/backend-test-utils` + +The following packages are deprecated and frozen (have stopped receiving updates). Please use the above three packages and `@backstage/backend-defaults` to replace them. You may still use the compatibility adapters in `@backstage/backend-common` short term while performing a gradual migration. + +- `@backstage/backend-common` +- `@backstage/backend-tasks` + +The following core services have been entirely removed. Please migrate to the [new auth system](https://backstage.io/docs/tutorials/auth-service-migration/). + +- `coreServices.identity` +- `coreServices.tokenManager` + +The backwards compatibility with plugins using legacy auth through the token manager service has also been removed. This means that instead of falling back to using the old token manager, requests towards plugins that don't support the new auth system will simply fail. Please make sure that all plugins in your deployment are hosted within a backend instance from the new backend system; a mixture of new and old will lead to auth problems. + +For a lot more detail about what changed and what migration steps might be needed, check the release notes for versions [1.27](https://backstage.io/docs/next/releases/v1.27.0#backend-system-deprecations), [1.28](https://backstage.io/docs/next/releases/v1.28.0#new-backend-system-api-movement-towards-10-release), [1.29](https://backstage.io/docs/next/releases/v1.29.0#breaking-backend-system-deprecations-and-removals) and [1.30](https://backstage.io/docs/releases/v1.30.0#breaking-backend-system-deprecations-and-removals). + +### New Frontend System Updates + +Some new things have landed in this version for the continued work on the New Frontend System. We’ve introduced the `@backstage/plugin-app` package, which is now responsible for housing the built in extensions and providing an entry point to override them using `appPlugin.override()`. + +There’s a new round of deprecations as we move forward with the New Frontend System. Namespace is no longer required to be provided to all extensions, or Blueprints and their respective `.make` or `.makeWithOverrides` methods. This will now default to the ID of the plugin that they are installed alongside. + +We’ve deprecated `createExtensionOverrides` and introduced a new `createFrontendModule` method which replaces it and takes a required `pluginId` for which to associate the extensions that you’re providing to override or compliment the corresponding plugin. + +We’ve also deprecated the `createApp` import from `@backstage/frontend-app-api` and you should now use the same import from `@backstage/frontend-defaults` instead which aligns nicely to the New Backend System patterns. + +There’s more information on the above deprecations and migrations in the [1.31 migration docs](https://backstage.io/docs/frontend-system/architecture/migrations#131) + +We’ve removed V1 extension support, so all extensions should now be defined with the array form of outputs, instead of the previously deprecated object form. + +All previous extension creators that have the Blueprint equivalent have also been removed as they were previously deprecated. Instead of `createExtension` you should migrate to using `Blueprint.make` instead. + +Also the deprecated `.render` method has been removed from `createExtensionTester`, you should be able to use `renderInTestApp` directly with the `tester.reactElement()` instead. + +There’s also [migration docs](https://backstage.io/docs/frontend-system/architecture/migrations#130) for the above removals from the last deprecation ICYMI! + +### Yarn v4 by Default + +When creating a new Backstage repository with `@backstage/create-app`, it will now be powered by Yarn version 4. There have been several improvements in later versions of Yarn, so this should improve the experience when getting started. + +If you are still on version 1 in your pre-existing repository, there’s [a guide](https://backstage.io/docs/tutorials/yarn-migration/) for getting onto newer releases. At this point we recommend moving ahead with moving off of version 1 of Yarn. + +Contributed by [@awanlin](https://github.com/awanlin) in [#26610](https://github.com/backstage/backstage/pull/26610) + +### App Runtime Templating + +The `@backstage/plugin-app-backend` now supports injection of all parts of the frontend configuration at runtime, including the public path and configuration values that are templated into `index.html`. + +The build process for frontend apps in the `@backstage/cli` now outputs an additional `index.html.tmpl` file. If this file is present in the build, the `app` backend will use this file to template a new `index.html` using the configuration that’s present in the `app` backend. This change also switches the full frontend configuration to be injected directly into the `index.html` file inside a `script` tag, rather than deep in the static resources. + +### Guest auth no longer halting production startup + +The `@backstage/plugin-auth-backend-module-guest-provider` module will no longer cause the backend to fail to start up in production, it now instead refuses authentication attempts. The halting of the startup could lead to knock-on effects such as migration tables staying locked. + +### New Catalog Permissions + +The `analyze-location` endpoint of the catalog is now protected by the `catalog.location.analyze` permission, and the `validate-entity` endpoint is now protected by the `catalog.entity.validate` permission. If you have enabled the [permissions system](https://backstage.io/docs/permissions/overview), you may want to adjust your policy accordingly. + +Contributed by [@04kash](https://github.com/04kash) in [#25924](https://github.com/backstage/backstage/pull/25924) + +### GitLab Provider + +The GitLab org entity provider now has a new `relations` configuration option that controls how GitLab memberships are modeled in Backstage. As part of this change the existing `allowInherited` option has been deprecated as it can now be expressed as `relations: [INHERITED]`. + +Contributed by [@elaine-mattos](https://github.com/elaine-mattos) in [#25363](https://github.com/backstage/backstage/pull/25363) + +### Star Icon Overrides + +Allow custom star icons to be provided via the star and unstarred icon overrides. See how to override existing icons in the [Backstage documentation](https://backstage.io/docs/getting-started/app-custom-theme/#custom-icons). + +### Migrated Auth Providers + +The last two backend auth providers - Auth0 and BitBucket Server - were migrated to new backend modules, closing the big community effort in getting the [auth providers migration](https://github.com/backstage/backstage/issues/19476) done. + +Thanks again to everyone who helped out, it is greatly appreciated! + +### Catalog Client Performance Improvements + +A hotspot was found in the code, where calls to the catalog backend to fetch entities performed work on the client side that were better done on the server side. After this update, you may see significant reduction in CPU usage on callers that fetch large amounts of data from the catalog. + +Contributed by [@drodil](https://github.com/drodil) in [#26240](https://github.com/backstage/backstage/pull/26240) + +### New Catalog Service Mocks + +When testing features that interact with the catalog, it’s common to want to inject a mocked or faked catalog client. To make life simpler, we’ve added a `catalogServiceMock` to `@backstage/plugin-catalog-node/testUtils`. Just like many of the `mockServices` from the test backend utilities, it lets you create partial mocks to make assertions on, as well as entire fake catalogs pre-populated with a static set of entities. Check it out! + +### Scaffolder Fixes + +Added support for `liveOmit` and `omitExtraData` options to the form which will allow for trimming superfluous data from the resulting data collected from the user. We will be testing this one for this release and promote this as the default if all goes to plan for the next mainline release. Thanks [@jboeijenga](https://github.com/jboeijenga)! + +[@stepghenglass](https://github.com/stephenglass) has been on a roll, and contributed a bunch of fixes for the Scaffolder and the `SecretField`. It now supports being `disabled`, `required` and `maxLength` and `minLength` being set from the schema. They’ve also contributed some fixes for the `ReviewState` component, to correctly parse the `ui:backstage` options for nested fields in the parameters schema. Thanks to [@richcooper95](https://github.com/richcooper95) for some other improvements to that component too and making it look much better when you have nested properties in the summary 💅. + +## Security Fixes + +- Fix in the Catalog backend where a vulnerability could be exploited to disrupt the backend instance availability. +- A fix for a vulnerability in the TechDocs backend that could allow unauthorized access to TechDocs content when hosting the content externally. +- A fix for a vulnerability in the TechDocs backend that could allow authenticated users to bypass script injection protections. + +## Upgrade path + +We recommend that you keep your Backstage project up to date with this latest release. For more guidance on how to upgrade, check out the documentation for [keeping Backstage updated](https://backstage.io/docs/getting-started/keeping-backstage-updated). + +## Links and References + +Below you can find a list of links and references to help you learn about and start using this new release. + +- [Backstage official website](https://backstage.io/), [documentation](https://backstage.io/docs/), and [getting started guide](https://backstage.io/docs/getting-started/) +- [GitHub repository](https://github.com/backstage/backstage) +- Backstage's [versioning and support policy](https://backstage.io/docs/overview/versioning-policy) +- [Community Discord](https://discord.gg/backstage-687207715902193673) for discussions and support +- [Changelog](https://github.com/backstage/backstage/tree/master/docs/releases/v1.31.0-changelog.md) +- Backstage [Demos](https://backstage.io/demos), [Blog](https://backstage.io/blog), [Roadmap](https://backstage.io/docs/overview/roadmap) and [Plugins](https://backstage.io/plugins) + +Sign up for our [newsletter](https://info.backstage.spotify.com/newsletter_subscribe) if you want to be informed about what is happening in the world of Backstage. diff --git a/docs/releases/v1.32.0-next.0-changelog.md b/docs/releases/v1.32.0-next.0-changelog.md new file mode 100644 index 0000000000..8168a5659a --- /dev/null +++ b/docs/releases/v1.32.0-next.0-changelog.md @@ -0,0 +1,2238 @@ +# Release v1.32.0-next.0 + +Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.32.0-next.0](https://backstage.github.io/upgrade-helper/?to=1.32.0-next.0) + +## @backstage/cli@0.28.0-next.0 + +### Minor Changes + +- 6129076: **BREAKING**: Removed the following deprecated commands: + + - `create`: Use `backstage-cli new` instead + - `create-plugin`: Use `backstage-cli new` instead + - `plugin:diff`: Use `backstage-cli fix` instead + - `test`: Use `backstage-cli repo test` or `backstage-cli package test` instead + - `versions:check`: Use `yarn dedupe` or `yarn-deduplicate` instead + - `clean`: Use `backstage-cli package clean` instead + + In addition, the experimental `install` and `onboard` commands have been removed since they have not received any updates since their introduction and we're expecting usage to be low. If you where relying on these commands, please let us know by opening an issue towards the main Backstage repository. + +### Patch Changes + +- 520a383: Added functionality to the prepack script that will append the default export type for entry points to the `exports` object before publishing. This is to help with identifying the declarative integration points for plugins without needing to fetch or run the plugins first. +- 094eaa3: Remove references to in-repo backend-common +- 79ba5a8: The `LEGACY_BACKEND_START` flag is now deprecated. +- Updated dependencies + - @backstage/catalog-model@1.7.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.8 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/eslint-plugin@0.1.9 + - @backstage/integration@1.15.0 + - @backstage/release-manifests@0.0.11 + - @backstage/types@1.1.1 + +## @backstage/core-plugin-api@1.10.0-next.0 + +### Minor Changes + +- bfd4bec: **BREAKING PRODUCERS**: The `IconComponent` no longer accepts `fontSize="default"`. This has effectively been removed from Material-UI since its last two major versions, and has not worked properly for them in a long time. + + This change should not have an effect on neither users of MUI4 nor MUI5/6, since the updated interface should still let you send the respective `SvgIcon` types into interfaces where relevant (e.g. as app icons). + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.9 + +## @backstage/frontend-app-api@0.10.0-next.0 + +### Minor Changes + +- 4a5ba19: Removed deprecated `createApp` and `CreateAppFeatureLoader` from `@backstage/frontend-app-api`, use the same `createApp` and `CreateAppFeatureLoader` import from `@backstage/frontend-defaults` instead. + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/frontend-defaults@0.1.1-next.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.15.1-next.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.9 + +## @backstage/frontend-plugin-api@0.9.0-next.0 + +### Minor Changes + +- 4a5ba19: Removed deprecated `namespace` option from `createExtension` and `createExtensionBlueprint`, including `.make` and `.makeWithOverides`, it's no longer necessary and will use the `pluginId` instead. + + Removed deprecated `createExtensionOverrides` this should be replaced with `createFrontendModule` instead. + + Removed deprecated `BackstagePlugin` type, use `FrontendPlugin` type instead from this same package. + +- bfd4bec: **BREAKING PRODUCERS**: The `IconComponent` no longer accepts `fontSize="default"`. This has effectively been removed from Material-UI since its last two major versions, and has not worked properly for them in a long time. + + This change should not have an effect on neither users of MUI4 nor MUI5/6, since the updated interface should still let you send the respective `SvgIcon` types into interfaces where relevant (e.g. as app icons). + +### Patch Changes + +- 873e424: Internal refactor of usage of opaque types. + +- 323aae8: It is now possible to override the blueprint parameters when overriding an extension created from a blueprint: + + ```ts + const myExtension = MyBlueprint.make({ + params: { + myParam: 'myDefault', + }, + }); + + const myOverride = myExtension.override({ + params: { + myParam: 'myOverride', + }, + }); + const myFactoryOverride = myExtension.override({ + factory(origFactory) { + return origFactory({ + params: { + myParam: 'myOverride', + }, + }); + }, + }); + ``` + + The provided parameters will be merged with the original parameters of the extension. + +- Updated dependencies + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.9 + +## @backstage/repo-tools@0.10.0-next.0 + +### Minor Changes + +- 30c2be9: Update @microsoft/api-extractor and use their api report resolution. + Change api report format from `api-report.md` to `report.api.md` + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.8 + - @backstage/config-loader@1.9.1 + - @backstage/errors@1.2.4 + +## @backstage/plugin-catalog@1.24.0-next.0 + +### Minor Changes + +- 71f9f0c: Updated default columns for location entities to remove description and tags from the catalog table view. + +### Patch Changes + +- 46b5a20: Empty states updated with external link icon for learn more links +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/core-compat-api@0.3.1-next.0 + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/plugin-catalog-react@1.13.1-next.0 + - @backstage/plugin-search-react@1.8.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.32-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-permission-react@0.4.27-next.0 + - @backstage/plugin-scaffolder-common@1.5.6 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-scaffolder@1.26.0-next.0 + +### Minor Changes + +- bf6eaf3: Added support for `FormFieldBlueprint` to create field extensions in the Scaffolder plugin +- cc3f80c: Added ability to create a new local scaffolder template to ease onboarding when creating new templates. +- 5492eb6: Added ability to link to a specific action on the actions page + +### Patch Changes + +- b2b2aa8: Fix extra divider displayed in owner list picker on list tasks page +- 7f1f483: Create a separate route for the Scaffolder template editor and add the ability to refresh the page without closing the directory. Also, when the directory is closed, the user will stay on the editor page and can load a template folder from there. +- 7a3d622: Create a separate route for the template form editor so we refresh it without being redirected to scaffolder edit page. +- 4698646: Change task list created at column to show timestamp +- 4130291: Create a separate route for the custom fields explorer so we refresh it without being redirected to scaffolder edit page. +- 11e0752: Make it possible to manually retry the scaffolder template from the step it failed +- 09fcd95: Update the Scaffolder template editor to quickly access installed custom fields and actions when editing a template. +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/plugin-scaffolder-react@1.13.0-next.0 + - @backstage/core-compat-api@0.3.1-next.0 + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/plugin-catalog-react@1.13.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.15.0 + - @backstage/integration-react@1.1.32-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-permission-react@0.4.27-next.0 + - @backstage/plugin-scaffolder-common@1.5.6 + +## @backstage/plugin-scaffolder-backend@1.26.0-next.0 + +### Minor Changes + +- 3ec4e6d: Added pagination support for listing of tasks and the ability to filter on several users and task statuses. + +### Patch Changes + +- 734c2d4: Add `fetch:template:file` scaffolder action to download a single file and template the contents. Example usage: + + ```yaml + - id: fetch-file + name: Fetch File + action: fetch:template:file + input: + url: https://github.com/backstage/software-templates/blob/main/scaffolder-templates/create-react-app/skeleton/catalog-info.yaml + targetPath: './target/catalog-info.yaml' + values: + component_id: My Component + owner: Test + ``` + +- 094eaa3: Remove references to in-repo backend-common + +- 11e0752: Make it possible to manually retry the scaffolder template from the step it failed + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.5.0-next.0 + - @backstage/plugin-scaffolder-backend-module-github@0.5.1-next.0 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.5.1-next.0 + - @backstage/backend-defaults@0.5.1-next.0 + - @backstage/plugin-permission-node@0.8.4-next.0 + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.15.0 + - @backstage/types@1.1.1 + - @backstage/plugin-bitbucket-cloud-common@0.2.23 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.1-next.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-scaffolder-backend-module-azure@0.2.1-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.1-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.1-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.1-next.0 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.2.1-next.0 + - @backstage/plugin-scaffolder-backend-module-gitea@0.2.1-next.0 + - @backstage/plugin-scaffolder-common@1.5.6 + +## @backstage/plugin-scaffolder-node@0.5.0-next.0 + +### Minor Changes + +- 3ec4e6d: Added pagination support for listing of tasks and the ability to filter on several users and task statuses. + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- 11e0752: Make it possible to manually retry the scaffolder template from the step it failed +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.15.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.6 + +## @backstage/plugin-scaffolder-react@1.13.0-next.0 + +### Minor Changes + +- bf6eaf3: Added support for `FormFieldBlueprint` to create field extensions in the Scaffolder plugin + +### Patch Changes + +- 11e0752: Make it possible to manually retry the scaffolder template from the step it failed +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/plugin-catalog-react@1.13.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/theme@0.5.7 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.9 + - @backstage/plugin-permission-react@0.4.27-next.0 + - @backstage/plugin-scaffolder-common@1.5.6 + +## @backstage/app-defaults@1.5.12-next.0 + +### Patch Changes + +- 46b5a20: Added `externalLink` to icon defaults +- 8c40e55: Updated the `bitbucket-server-auth` default API to set its environment based on the `auth.environment` config option instead of being hardcoded to `development`. +- Updated dependencies + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/core-app-api@1.15.1-next.0 + - @backstage/theme@0.5.7 + - @backstage/plugin-permission-react@0.4.27-next.0 + +## @backstage/backend-app-api@1.0.1-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common + +- 04af116: The backend will no longer exit immediately if any plugin or modules fails to initialize. Instead, the backend will wait for all plugins and modules to either start up successfully or throw, and then shut down the backend if there were any initialization errors. + + This fixes an issue where backend initialization errors in adjacent plugins during database schema migration could cause the database migrations to be stuck in a locked state. + +- Updated dependencies + - @backstage/plugin-permission-node@0.8.4-next.0 + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/backend-defaults@0.5.1-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/backend-app-api@1.0.1-next.0 + - @backstage/plugin-permission-node@0.8.4-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-dev-utils@0.1.5 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.8 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/integration@1.15.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + +## @backstage/backend-dynamic-feature-service@0.4.1-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- 2f88f88: Updated backend installation instructions. +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.5.0-next.0 + - @backstage/plugin-search-backend-node@1.3.3-next.0 + - @backstage/backend-defaults@0.5.1-next.0 + - @backstage/backend-app-api@1.0.1-next.0 + - @backstage/plugin-catalog-backend@1.26.1-next.0 + - @backstage/plugin-permission-node@0.8.4-next.0 + - @backstage/plugin-events-backend@0.3.13-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.8 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-app-node@0.1.26-next.0 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/backend-openapi-utils@0.1.19-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/errors@1.2.4 + +## @backstage/backend-plugin-api@1.0.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/backend-test-utils@1.0.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.1-next.0 + - @backstage/backend-app-api@1.0.1-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/core-app-api@1.15.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.9 + +## @backstage/core-compat-api@0.3.1-next.0 + +### Patch Changes + +- 4a5ba19: Internal update to remove deprecated `BackstagePlugin` type and move to `FrontendPlugin` +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/version-bridge@1.0.9 + +## @backstage/core-components@0.15.1-next.0 + +### Patch Changes + +- 46b5a20: `Link` component now accepts `externalLinkIcon` prop +- Updated dependencies + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.7 + - @backstage/version-bridge@1.0.9 + +## @backstage/create-app@0.5.21-next.0 + +### Patch Changes + +- a7674d6: Fixed lack of `.yarnrc.yml` in the template. +- Updated dependencies + - @backstage/cli-common@0.1.14 + +## @backstage/dev-utils@1.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/app-defaults@1.5.12-next.0 + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/plugin-catalog-react@1.13.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/core-app-api@1.15.1-next.0 + - @backstage/integration-react@1.1.32-next.0 + - @backstage/theme@0.5.7 + +## @backstage/frontend-defaults@0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/frontend-app-api@0.10.0-next.0 + - @backstage/plugin-app@0.1.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/frontend-test-utils@0.2.1-next.0 + +### Patch Changes + +- 873e424: Internal refactor of usage of opaque types. +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/frontend-app-api@0.10.0-next.0 + - @backstage/plugin-app@0.1.1-next.0 + - @backstage/config@1.2.0 + - @backstage/test-utils@1.6.1-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.9 + +## @backstage/integration-react@1.1.32-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.15.0 + +## @techdocs/cli@1.8.20-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/plugin-techdocs-node@1.12.12-next.0 + +## @backstage/test-utils@1.6.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.15.1-next.0 + - @backstage/theme@0.5.7 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-permission-react@0.4.27-next.0 + +## @backstage/plugin-api-docs@0.11.10-next.0 + +### Patch Changes + +- 46b5a20: Empty states updated with external link icon for learn more links +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/plugin-catalog@1.24.0-next.0 + - @backstage/core-compat-api@0.3.1-next.0 + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/plugin-catalog-react@1.13.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-permission-react@0.4.27-next.0 + +## @backstage/plugin-app@0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/theme@0.5.7 + - @backstage/plugin-permission-react@0.4.27-next.0 + +## @backstage/plugin-app-backend@0.3.75-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-app-node@0.1.26-next.0 + +## @backstage/plugin-app-node@0.1.26-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config-loader@1.9.1 + +## @backstage/plugin-app-visualizer@0.1.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + +## @backstage/plugin-auth-backend@0.23.1-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-auth-backend-module-aws-alb-provider@0.2.1-next.0 + - @backstage/plugin-auth-backend-module-oidc-provider@0.3.1-next.0 + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-backend-module-atlassian-provider@0.3.1-next.0 + - @backstage/plugin-auth-backend-module-auth0-provider@0.1.1-next.0 + - @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.2.1-next.0 + - @backstage/plugin-auth-backend-module-bitbucket-provider@0.2.1-next.0 + - @backstage/plugin-auth-backend-module-bitbucket-server-provider@0.1.1-next.0 + - @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.3.1-next.0 + - @backstage/plugin-auth-backend-module-gcp-iap-provider@0.3.1-next.0 + - @backstage/plugin-auth-backend-module-github-provider@0.2.1-next.0 + - @backstage/plugin-auth-backend-module-gitlab-provider@0.2.1-next.0 + - @backstage/plugin-auth-backend-module-google-provider@0.2.1-next.0 + - @backstage/plugin-auth-backend-module-microsoft-provider@0.2.1-next.0 + - @backstage/plugin-auth-backend-module-oauth2-provider@0.3.1-next.0 + - @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.2.1-next.0 + - @backstage/plugin-auth-backend-module-okta-provider@0.1.1-next.0 + - @backstage/plugin-auth-backend-module-onelogin-provider@0.2.1-next.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + +## @backstage/plugin-auth-backend-module-atlassian-provider@0.3.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + +## @backstage/plugin-auth-backend-module-auth0-provider@0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + +## @backstage/plugin-auth-backend-module-aws-alb-provider@0.2.1-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-auth-backend@0.23.1-next.0 + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-bitbucket-provider@0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + +## @backstage/plugin-auth-backend-module-bitbucket-server-provider@0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + +## @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.3.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-gcp-iap-provider@0.3.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-auth-backend-module-github-provider@0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + +## @backstage/plugin-auth-backend-module-gitlab-provider@0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + +## @backstage/plugin-auth-backend-module-google-provider@0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + +## @backstage/plugin-auth-backend-module-guest-provider@0.2.1-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-microsoft-provider@0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + +## @backstage/plugin-auth-backend-module-oauth2-provider@0.3.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + +## @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-oidc-provider@0.3.1-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-auth-backend@0.23.1-next.0 + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + +## @backstage/plugin-auth-backend-module-okta-provider@0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + +## @backstage/plugin-auth-backend-module-onelogin-provider@0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + +## @backstage/plugin-auth-backend-module-pinniped-provider@0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + +## @backstage/plugin-auth-backend-module-vmware-cloud-provider@0.3.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + +## @backstage/plugin-auth-node@0.5.3-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-auth-react@0.1.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-catalog-backend@1.26.1-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-search-backend-module-catalog@0.2.3-next.0 + - @backstage/plugin-permission-node@0.8.4-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/backend-openapi-utils@0.1.19-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.15.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-catalog-backend-module-aws@0.4.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.15.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-kubernetes-common@0.8.3 + +## @backstage/plugin-catalog-backend-module-azure@0.2.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.15.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + +## @backstage/plugin-catalog-backend-module-backstage-openapi@0.4.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-openapi-utils@0.1.19-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.13.1-next.0 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.3.3-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.15.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.23 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.2.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.15.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + +## @backstage/plugin-catalog-backend-module-gcp@0.3.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-kubernetes-common@0.8.3 + +## @backstage/plugin-catalog-backend-module-gerrit@0.2.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.15.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + +## @backstage/plugin-catalog-backend-module-github@0.7.4-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-catalog-backend@1.26.1-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.15.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + +## @backstage/plugin-catalog-backend-module-github-org@0.3.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend-module-github@0.7.4-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + +## @backstage/plugin-catalog-backend-module-gitlab@0.4.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.1-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.15.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + +## @backstage/plugin-catalog-backend-module-gitlab-org@0.2.1-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/plugin-catalog-backend-module-gitlab@0.4.3-next.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.5.4-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-catalog-backend@1.26.1-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-catalog-backend-module-ldap@0.9.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + +## @backstage/plugin-catalog-backend-module-logs@0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.26.1-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + +## @backstage/plugin-catalog-backend-module-msgraph@0.6.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + +## @backstage/plugin-catalog-backend-module-openapi@0.2.1-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-catalog-backend@1.26.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.15.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + +## @backstage/plugin-catalog-backend-module-puppetdb@0.2.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.13.1-next.0 + +## @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-scaffolder-common@1.5.6 + +## @backstage/plugin-catalog-backend-module-unprocessed@0.5.1-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-catalog-unprocessed-entities-common@0.0.4 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-catalog-graph@0.4.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/core-compat-api@0.3.1-next.0 + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/plugin-catalog-react@1.13.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-import@0.12.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/core-compat-api@0.3.1-next.0 + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/plugin-catalog-react@1.13.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.15.0 + - @backstage/integration-react@1.1.32-next.0 + - @backstage/plugin-catalog-common@1.1.0 + +## @backstage/plugin-catalog-node@1.13.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-node@0.8.4-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-catalog-react@1.13.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/core-compat-api@0.3.1-next.0 + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.32-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.9 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-permission-react@0.4.27-next.0 + +## @backstage/plugin-catalog-unprocessed-entities@0.2.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-config-schema@0.1.60-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-devtools@0.1.19-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/core-compat-api@0.3.1-next.0 + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-devtools-common@0.1.12 + - @backstage/plugin-permission-react@0.4.27-next.0 + +## @backstage/plugin-devtools-backend@0.4.1-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-permission-node@0.8.4-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-devtools-common@0.1.12 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-events-backend@0.3.13-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common + +- 5c728ee: The events backend now has its own built-in event bus for distributing events across multiple backend instances. It exposes a new HTTP API under `/bus/v1/` for publishing and reading events from the bus, as well as its own storage and notification mechanism for events. + + The backing event store for the bus only supports scaled deployment if PostgreSQL is used as the DBMS. If SQLite or MySQL is used, the event bus will fall back to an in-memory store that does not support multiple backend instances. + + The default `EventsService` implementation from `@backstage/plugin-events-node` has also been updated to use the new events bus. + +- Updated dependencies + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/backend-openapi-utils@0.1.19-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-events-backend-module-aws-sqs@0.4.3-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-events-backend-module-azure@0.2.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + +## @backstage/plugin-events-backend-module-bitbucket-cloud@0.2.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + +## @backstage/plugin-events-backend-module-gerrit@0.2.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + +## @backstage/plugin-events-backend-module-github@0.2.12-next.0 + +### Patch Changes + +- 2f88f88: Updated backend installation instructions. +- Updated dependencies + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + +## @backstage/plugin-events-backend-module-gitlab@0.2.12-next.0 + +### Patch Changes + +- 2f88f88: Updated backend installation instructions. +- Updated dependencies + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + +## @backstage/plugin-events-backend-test-utils@0.1.36-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.1-next.0 + +## @backstage/plugin-events-node@0.4.1-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- 2f88f88: Updated backend installation instructions. +- a90ce4a: The default implementation of the `EventsService` now uses the new event bus for distributing events across multiple backend instances if the events backend plugin is installed. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-home@0.7.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/core-compat-api@0.3.1-next.0 + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/plugin-catalog-react@1.13.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.15.1-next.0 + - @backstage/theme@0.5.7 + - @backstage/plugin-home-react@0.1.18-next.0 + +## @backstage/plugin-home-react@0.1.18-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + +## @backstage/plugin-kubernetes@0.11.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/core-compat-api@0.3.1-next.0 + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/plugin-catalog-react@1.13.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-kubernetes-common@0.8.3 + - @backstage/plugin-kubernetes-react@0.4.4-next.0 + +## @backstage/plugin-kubernetes-backend@0.18.7-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-kubernetes-node@0.1.20-next.0 + - @backstage/plugin-permission-node@0.8.4-next.0 + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-kubernetes-common@0.8.3 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-kubernetes-cluster@0.0.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/plugin-catalog-react@1.13.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-kubernetes-common@0.8.3 + - @backstage/plugin-kubernetes-react@0.4.4-next.0 + +## @backstage/plugin-kubernetes-node@0.1.20-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.8.3 + +## @backstage/plugin-kubernetes-react@0.4.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.8.3 + +## @backstage/plugin-notifications@0.3.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.7 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-signals-react@0.0.6-next.0 + +## @backstage/plugin-notifications-backend@0.4.1-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-notifications-node@0.2.7-next.0 + - @backstage/plugin-signals-node@0.1.12-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-notifications-common@0.0.5 + +## @backstage/plugin-notifications-backend-module-email@0.3.1-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-notifications-node@0.2.7-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-notifications-common@0.0.5 + +## @backstage/plugin-notifications-node@0.2.7-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-signals-node@0.1.12-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-notifications-common@0.0.5 + +## @backstage/plugin-org@0.6.30-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/core-compat-api@0.3.1-next.0 + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/plugin-catalog-react@1.13.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-catalog-common@1.1.0 + +## @backstage/plugin-org-react@0.1.29-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/plugin-catalog-react@1.13.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + +## @backstage/plugin-permission-backend@0.5.50-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-permission-node@0.8.4-next.0 + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-permission-backend-module-allow-all-policy@0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-node@0.8.4-next.0 + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-permission-node@0.8.4-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-permission-react@0.4.27-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-proxy-backend@0.5.7-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-backend-module-azure@0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.5.0-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.15.0 + +## @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.5.0-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.15.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.1-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.1-next.0 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.5.0-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.15.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.23 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.5.0-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.15.0 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.3.1-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.5.0-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.15.0 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.3.1-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.5.0-next.0 + - @backstage/backend-defaults@0.5.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.15.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-backend-module-gcp@0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.5.0-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.15.0 + +## @backstage/plugin-scaffolder-backend-module-gerrit@0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.5.0-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.15.0 + +## @backstage/plugin-scaffolder-backend-module-gitea@0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.5.0-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.15.0 + +## @backstage/plugin-scaffolder-backend-module-github@0.5.1-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.5.0-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.15.0 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.5.1-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- f2f68cf: Updated `gitlab:group:ensureExists` action to instead use oauth client. +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.5.0-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.15.0 + +## @backstage/plugin-scaffolder-backend-module-notifications@0.1.1-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.5.0-next.0 + - @backstage/plugin-notifications-node@0.2.7-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/plugin-notifications-common@0.0.5 + +## @backstage/plugin-scaffolder-backend-module-rails@0.5.1-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.5.0-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.15.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.5.0-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.4.1-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.5.0-next.0 + - @backstage/plugin-scaffolder-node-test-utils@0.1.13-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-node-test-utils@0.1.13-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.5.0-next.0 + - @backstage/backend-test-utils@1.0.1-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-search@1.4.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/core-compat-api@0.3.1-next.0 + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/plugin-catalog-react@1.13.1-next.0 + - @backstage/plugin-search-react@1.8.1-next.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.9 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-backend@1.5.18-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-search-backend-node@1.3.3-next.0 + - @backstage/backend-defaults@0.5.1-next.0 + - @backstage/plugin-permission-node@0.8.4-next.0 + - @backstage/backend-openapi-utils@0.1.19-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-backend-module-catalog@0.2.3-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- 2f88f88: Updated backend installation instructions. +- Updated dependencies + - @backstage/plugin-search-backend-node@1.3.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-backend-module-elasticsearch@1.5.7-next.0 + +### Patch Changes + +- d78b07c: Align the configuration schema with the docs and actual behavior of the code +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-search-backend-node@1.3.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-backend-module-explore@0.2.3-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- 2f88f88: Updated backend installation instructions. +- Updated dependencies + - @backstage/plugin-search-backend-node@1.3.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-backend-module-pg@0.5.36-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-search-backend-node@1.3.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-backend-module-stack-overflow-collator@0.3.1-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-search-backend-node@1.3.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-backend-module-techdocs@0.2.3-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- 2f88f88: Updated backend installation instructions. +- Updated dependencies + - @backstage/plugin-search-backend-node@1.3.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-techdocs-node@1.12.12-next.0 + +## @backstage/plugin-search-backend-node@1.3.3-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/backend-defaults@0.5.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-react@1.8.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/theme@0.5.7 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.9 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-signals@0.0.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/theme@0.5.7 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.6-next.0 + +## @backstage/plugin-signals-backend@0.2.1-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-signals-node@0.1.12-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-signals-node@0.1.12-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-signals-react@0.0.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-techdocs@1.10.10-next.0 + +### Patch Changes + +- a77cb40: Make `emptyState` input optional on `entity-content:techdocs` extension so that + the default empty state extension works correctly. +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/core-compat-api@0.3.1-next.0 + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/plugin-catalog-react@1.13.1-next.0 + - @backstage/plugin-search-react@1.8.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.15.0 + - @backstage/integration-react@1.1.32-next.0 + - @backstage/theme@0.5.7 + - @backstage/plugin-auth-react@0.1.7-next.0 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-techdocs-react@1.2.9-next.0 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.39-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.24.0-next.0 + - @backstage/plugin-techdocs@1.10.10-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/plugin-catalog-react@1.13.1-next.0 + - @backstage/plugin-search-react@1.8.1-next.0 + - @backstage/core-app-api@1.15.1-next.0 + - @backstage/integration-react@1.1.32-next.0 + - @backstage/test-utils@1.6.1-next.0 + - @backstage/plugin-techdocs-react@1.2.9-next.0 + +## @backstage/plugin-techdocs-backend@1.10.14-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-search-backend-module-techdocs@0.2.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.15.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-techdocs-node@1.12.12-next.0 + +## @backstage/plugin-techdocs-module-addons-contrib@1.1.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/integration@1.15.0 + - @backstage/integration-react@1.1.32-next.0 + - @backstage/plugin-techdocs-react@1.2.9-next.0 + +## @backstage/plugin-techdocs-node@1.12.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.15.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-techdocs-common@0.1.0 + +## @backstage/plugin-techdocs-react@1.2.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/version-bridge@1.0.9 + +## @backstage/plugin-user-settings@0.8.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/core-compat-api@0.3.1-next.0 + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/plugin-catalog-react@1.13.1-next.0 + - @backstage/core-app-api@1.15.1-next.0 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.7 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.6-next.0 + - @backstage/plugin-user-settings-common@0.0.1 + +## @backstage/plugin-user-settings-backend@0.2.25-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.1-next.0 + - @backstage/plugin-signals-node@0.1.12-next.0 + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-user-settings-common@0.0.1 + +## example-app@0.2.102-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder@1.26.0-next.0 + - @backstage/plugin-catalog@1.24.0-next.0 + - @backstage/cli@0.28.0-next.0 + - @backstage/plugin-scaffolder-react@1.13.0-next.0 + - @backstage/plugin-api-docs@0.11.10-next.0 + - @backstage/frontend-app-api@0.10.0-next.0 + - @backstage/plugin-techdocs@1.10.10-next.0 + - @backstage/app-defaults@1.5.12-next.0 + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/plugin-catalog-graph@0.4.10-next.0 + - @backstage/plugin-catalog-import@0.12.4-next.0 + - @backstage/plugin-catalog-react@1.13.1-next.0 + - @backstage/plugin-devtools@0.1.19-next.0 + - @backstage/plugin-home@0.7.11-next.0 + - @backstage/plugin-kubernetes@0.11.15-next.0 + - @backstage/plugin-org@0.6.30-next.0 + - @backstage/plugin-search@1.4.17-next.0 + - @backstage/plugin-search-react@1.8.1-next.0 + - @backstage/plugin-user-settings@0.8.13-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.15.1-next.0 + - @backstage/integration-react@1.1.32-next.0 + - @backstage/theme@0.5.7 + - @backstage/plugin-auth-react@0.1.7-next.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.9-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.16-next.0 + - @backstage/plugin-notifications@0.3.2-next.0 + - @backstage/plugin-permission-react@0.4.27-next.0 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-signals@0.0.11-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.15-next.0 + - @backstage/plugin-techdocs-react@1.2.9-next.0 + +## example-app-next@0.0.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder@1.26.0-next.0 + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/plugin-catalog@1.24.0-next.0 + - @backstage/cli@0.28.0-next.0 + - @backstage/plugin-scaffolder-react@1.13.0-next.0 + - @backstage/plugin-api-docs@0.11.10-next.0 + - @backstage/frontend-app-api@0.10.0-next.0 + - @backstage/plugin-techdocs@1.10.10-next.0 + - @backstage/app-defaults@1.5.12-next.0 + - @backstage/core-compat-api@0.3.1-next.0 + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/frontend-defaults@0.1.1-next.0 + - @backstage/plugin-app@0.1.1-next.0 + - @backstage/plugin-app-visualizer@0.1.11-next.0 + - @backstage/plugin-catalog-graph@0.4.10-next.0 + - @backstage/plugin-catalog-import@0.12.4-next.0 + - @backstage/plugin-catalog-react@1.13.1-next.0 + - @backstage/plugin-home@0.7.11-next.0 + - @backstage/plugin-kubernetes@0.11.15-next.0 + - @backstage/plugin-org@0.6.30-next.0 + - @backstage/plugin-search@1.4.17-next.0 + - @backstage/plugin-search-react@1.8.1-next.0 + - @backstage/plugin-user-settings@0.8.13-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.15.1-next.0 + - @backstage/integration-react@1.1.32-next.0 + - @backstage/theme@0.5.7 + - @backstage/plugin-auth-react@0.1.7-next.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.9-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.16-next.0 + - @backstage/plugin-notifications@0.3.2-next.0 + - @backstage/plugin-permission-react@0.4.27-next.0 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-signals@0.0.11-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.15-next.0 + - @backstage/plugin-techdocs-react@1.2.9-next.0 + +## app-next-example-plugin@0.0.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/core-components@0.15.1-next.0 + +## example-backend@0.0.31-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.26.0-next.0 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.1-next.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.5.1-next.0 + - @backstage/plugin-scaffolder-backend-module-github@0.5.1-next.0 + - @backstage/plugin-catalog-backend-module-openapi@0.2.1-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.2.3-next.0 + - @backstage/plugin-search-backend-module-catalog@0.2.3-next.0 + - @backstage/plugin-search-backend-module-explore@0.2.3-next.0 + - @backstage/plugin-notifications-backend@0.4.1-next.0 + - @backstage/plugin-search-backend-node@1.3.3-next.0 + - @backstage/plugin-kubernetes-backend@0.18.7-next.0 + - @backstage/plugin-permission-backend@0.5.50-next.0 + - @backstage/backend-defaults@0.5.1-next.0 + - @backstage/plugin-devtools-backend@0.4.1-next.0 + - @backstage/plugin-techdocs-backend@1.10.14-next.0 + - @backstage/plugin-catalog-backend@1.26.1-next.0 + - @backstage/plugin-permission-node@0.8.4-next.0 + - @backstage/plugin-signals-backend@0.2.1-next.0 + - @backstage/plugin-events-backend@0.3.13-next.0 + - @backstage/plugin-search-backend@1.5.18-next.0 + - @backstage/plugin-proxy-backend@0.5.7-next.0 + - @backstage/plugin-auth-backend@0.23.1-next.0 + - @backstage/plugin-app-backend@0.3.75-next.0 + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-auth-backend-module-github-provider@0.2.1-next.0 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.4.1-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.1-next.0 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.1-next.0 + - @backstage/plugin-permission-common@0.8.1 + +## example-backend-legacy@0.2.103-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-module-elasticsearch@1.5.7-next.0 + - @backstage/plugin-scaffolder-backend@1.26.0-next.0 + - @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.3.1-next.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.5.1-next.0 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.5.1-next.0 + - @backstage/plugin-scaffolder-backend-module-rails@0.5.1-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.2.3-next.0 + - @backstage/plugin-search-backend-module-catalog@0.2.3-next.0 + - @backstage/plugin-search-backend-module-explore@0.2.3-next.0 + - @backstage/plugin-search-backend-module-pg@0.5.36-next.0 + - @backstage/plugin-search-backend-node@1.3.3-next.0 + - @backstage/plugin-kubernetes-backend@0.18.7-next.0 + - @backstage/plugin-permission-backend@0.5.50-next.0 + - @backstage/backend-defaults@0.5.1-next.0 + - @backstage/plugin-devtools-backend@0.4.1-next.0 + - @backstage/plugin-techdocs-backend@1.10.14-next.0 + - @backstage/plugin-catalog-backend@1.26.1-next.0 + - @backstage/plugin-permission-node@0.8.4-next.0 + - @backstage/plugin-signals-backend@0.2.1-next.0 + - @backstage/plugin-events-backend@0.3.13-next.0 + - @backstage/plugin-search-backend@1.5.18-next.0 + - @backstage/plugin-proxy-backend@0.5.7-next.0 + - @backstage/plugin-auth-backend@0.23.1-next.0 + - @backstage/plugin-signals-node@0.1.12-next.0 + - @backstage/plugin-app-backend@0.3.75-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.15.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.1-next.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-permission-common@0.8.1 + +## e2e-test@0.2.21-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.5.21-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/errors@1.2.4 + +## @internal/frontend@0.0.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.9 + +## @internal/scaffolder@0.0.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-react@1.13.0-next.0 + +## techdocs-cli-embedded-app@0.2.101-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.24.0-next.0 + - @backstage/cli@0.28.0-next.0 + - @backstage/plugin-techdocs@1.10.10-next.0 + - @backstage/app-defaults@1.5.12-next.0 + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.15.1-next.0 + - @backstage/integration-react@1.1.32-next.0 + - @backstage/test-utils@1.6.1-next.0 + - @backstage/theme@0.5.7 + - @backstage/plugin-techdocs-react@1.2.9-next.0 + +## @internal/plugin-todo-list@1.0.32-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + +## @internal/plugin-todo-list-backend@1.0.32-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/errors@1.2.4 diff --git a/docs/releases/v1.32.0-next.1-changelog.md b/docs/releases/v1.32.0-next.1-changelog.md new file mode 100644 index 0000000000..d62c0e753f --- /dev/null +++ b/docs/releases/v1.32.0-next.1-changelog.md @@ -0,0 +1,1556 @@ +# Release v1.32.0-next.1 + +Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.32.0-next.1](https://backstage.github.io/upgrade-helper/?to=1.32.0-next.1) + +## @backstage/cli@0.28.0-next.1 + +### Minor Changes + +- 55b8b84: **BREAKING**: The Jest configuration defined at `@backstage/cli/config/jest` no longer collects configuration defined in the `"jest"` field from all parent `package.json` files. Instead, it will only read and merge configuration from the `package.json` in the monorepo root if it exists, as well as the target package. In addition, configuration defined in the root `package.json` will now only be merged into each package configuration if it is a valid project-level configuration key. + +### Patch Changes + +- 03810d2: Remove unknown dependency `diff` +- cebee4f: Added support for a new experimental `EXPERIMENTAL_TRIM_NEXT_ENTRY` flag which removes any `./next` entry points present in packages when building and publishing. +- 55b8b84: The Jest configuration will now search for a `src/setupTests.*` file with any valid script extension, not only `.ts`. +- Updated dependencies + - @backstage/eslint-plugin@0.1.10-next.0 + - @backstage/integration@1.15.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.8 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/release-manifests@0.0.11 + - @backstage/types@1.1.1 + +## @backstage/integration-react@1.2.0-next.1 + +### Minor Changes + +- a11495a: Added new ScmAuth method `forBitbucketServer` that uses correct OAuth scopes by default. Also updated `forBitbucket` method to allow overriding the default OAuth scopes. + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- 3dbac17: Revert of change #26430 +- Updated dependencies + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/integration@1.15.1-next.0 + - @backstage/config@1.2.0 + +## @backstage/repo-tools@0.10.0-next.1 + +### Minor Changes + +- 8eb3033: Adds a new command `backstage-repo-tools peer-deps` for validating your usage of peer dependencies in your plugins. It currently supports react related peer dependencies. It also has a `--fix` mode for quickly fixing any issues that it finds. + +### Patch Changes + +- 1f6706f: Properly log instructions when APIs do not match +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.8 + - @backstage/config-loader@1.9.1 + - @backstage/errors@1.2.4 + +## @backstage/plugin-catalog-react@1.14.0-next.1 + +### Minor Changes + +- 6812980: Added a new prop, `disableTooltip` to the `EntityRefLink` component + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/frontend-plugin-api@0.9.0-next.1 + - @backstage/integration-react@1.2.0-next.1 + - @backstage/core-compat-api@0.3.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/plugin-permission-react@0.4.27-next.1 + - @backstage/version-bridge@1.0.10-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-scaffolder@1.26.0-next.1 + +### Minor Changes + +- c433ae9: Improved the layout of the manage templates page (`/edit`) by adding icons and descriptions that better describe what each page is for. Updated the header menu to link back to the scaffolder create page. +- 7bfaf23: Text field content of the `EntityPicker` is now more readable as it uses entity title instead of entity reference. + +### Patch Changes + +- f6c15d8: Apply `defaultValue` props in `MultiEntityPicker` +- e969dc7: Move `@types/react` to a peer dependency. +- 785d68f: Add support for pagination in scaffolder tasks list +- 94a7bcd: Change "Register Existing Component" CTA to outlined as it's not a primary action on the scaffolder pages +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/frontend-plugin-api@0.9.0-next.1 + - @backstage/integration-react@1.2.0-next.1 + - @backstage/core-compat-api@0.3.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/plugin-permission-react@0.4.27-next.1 + - @backstage/plugin-scaffolder-react@1.13.0-next.1 + - @backstage/plugin-catalog-react@1.14.0-next.1 + - @backstage/integration@1.15.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-scaffolder-common@1.5.6 + +## @backstage/plugin-scaffolder-react@1.13.0-next.1 + +### Minor Changes + +- d851b5b: Renamed Template Editor to Manage Templates. + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- 785d68f: Add support for pagination in scaffolder tasks list +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/frontend-plugin-api@0.9.0-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/plugin-permission-react@0.4.27-next.1 + - @backstage/version-bridge@1.0.10-next.0 + - @backstage/plugin-catalog-react@1.14.0-next.1 + - @backstage/theme@0.5.8-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.6 + +## @backstage/app-defaults@1.5.12-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/plugin-permission-react@0.4.27-next.1 + - @backstage/core-app-api@1.15.1-next.1 + - @backstage/theme@0.5.8-next.0 + +## @backstage/backend-defaults@0.5.1-next.1 + +### Patch Changes + +- 920004b: Updating error message for getProjectId when fetching Gitlab project from its url to be more accurate +- Updated dependencies + - @backstage/integration@1.15.1-next.0 + - @backstage/backend-app-api@1.0.1-next.0 + - @backstage/backend-dev-utils@0.1.5 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.8 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/plugin-permission-node@0.8.4-next.0 + +## @backstage/backend-dynamic-feature-service@0.4.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.26.2-next.1 + - @backstage/backend-defaults@0.5.1-next.1 + - @backstage/backend-app-api@1.0.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.8 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-app-node@0.1.26-next.0 + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/plugin-events-backend@0.3.13-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-permission-node@0.8.4-next.0 + - @backstage/plugin-scaffolder-node@0.5.0-next.1 + - @backstage/plugin-search-backend-node@1.3.3-next.1 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/backend-test-utils@1.0.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.1-next.1 + - @backstage/backend-app-api@1.0.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + +## @backstage/core-app-api@1.15.1-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/version-bridge@1.0.10-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## @backstage/core-compat-api@0.3.1-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/version-bridge@1.0.10-next.0 + +## @backstage/core-components@0.15.1-next.1 + +### Patch Changes + +- 3f76d0e: Correct size of FavoriteToggle and inherit non-starred color from parent +- e969dc7: Move `@types/react` to a peer dependency. +- 83e2887: Fixed a bug in the `SidebarSubmenu` core component that caused the nested menu to overlap with the sidebar when the user hovers over the pinned sidebar. +- Updated dependencies + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/version-bridge@1.0.10-next.0 + - @backstage/theme@0.5.8-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/core-plugin-api@1.10.0-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/version-bridge@1.0.10-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/create-app@0.5.21-next.1 + +### Patch Changes + +- Bumped create-app version. +- Updated dependencies + - @backstage/cli-common@0.1.14 + +## @backstage/dev-utils@1.1.2-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/integration-react@1.2.0-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/app-defaults@1.5.12-next.1 + - @backstage/core-app-api@1.15.1-next.1 + - @backstage/plugin-catalog-react@1.14.0-next.1 + - @backstage/theme@0.5.8-next.0 + - @backstage/catalog-model@1.7.0 + +## @backstage/eslint-plugin@0.1.10-next.0 + +### Patch Changes + +- 63963f6: Internal refactor to deal with `estree` upgrade + +## @backstage/frontend-app-api@0.10.0-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/version-bridge@1.0.10-next.0 + - @backstage/core-app-api@1.15.1-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/frontend-defaults@0.1.1-next.1 + - @backstage/types@1.1.1 + +## @backstage/frontend-defaults@0.1.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.1 + - @backstage/frontend-app-api@0.10.0-next.1 + - @backstage/plugin-app@0.1.1-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/frontend-plugin-api@0.9.0-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/version-bridge@1.0.10-next.0 + - @backstage/types@1.1.1 + +## @backstage/frontend-test-utils@0.2.1-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.1 + - @backstage/frontend-app-api@0.10.0-next.1 + - @backstage/version-bridge@1.0.10-next.0 + - @backstage/test-utils@1.6.1-next.1 + - @backstage/plugin-app@0.1.1-next.1 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## @backstage/integration@1.15.1-next.0 + +### Patch Changes + +- 920004b: Updating error message for getProjectId when fetching Gitlab project from its url to be more accurate +- 090e49a: Updated functions parseHarnessUrl, getHarnessLatestCommitUrl, getHarnessFileContentsUrl and getHarnessArchiveUrl to fix parsing of urls +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @techdocs/cli@1.8.20-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.1-next.1 + - @backstage/catalog-model@1.7.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/plugin-techdocs-node@1.12.12-next.1 + +## @backstage/test-utils@1.6.1-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/plugin-permission-react@0.4.27-next.1 + - @backstage/core-app-api@1.15.1-next.1 + - @backstage/theme@0.5.8-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/theme@0.5.8-next.0 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. + +## @backstage/version-bridge@1.0.10-next.0 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. + +## @backstage/plugin-api-docs@0.11.11-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/frontend-plugin-api@0.9.0-next.1 + - @backstage/core-compat-api@0.3.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/plugin-permission-react@0.4.27-next.1 + - @backstage/plugin-catalog-react@1.14.0-next.1 + - @backstage/plugin-catalog@1.24.0-next.1 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-catalog-common@1.1.0 + +## @backstage/plugin-api-docs-module-protoc-gen-doc@0.1.8-next.0 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. + +## @backstage/plugin-app@0.1.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/frontend-plugin-api@0.9.0-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/plugin-permission-react@0.4.27-next.1 + - @backstage/theme@0.5.8-next.0 + +## @backstage/plugin-app-visualizer@0.1.11-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/frontend-plugin-api@0.9.0-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + +## @backstage/plugin-auth-react@0.1.7-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/errors@1.2.4 + +## @backstage/plugin-bitbucket-cloud-common@0.2.24-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.15.1-next.0 + +## @backstage/plugin-catalog@1.24.0-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/frontend-plugin-api@0.9.0-next.1 + - @backstage/integration-react@1.2.0-next.1 + - @backstage/core-compat-api@0.3.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/plugin-permission-react@0.4.27-next.1 + - @backstage/plugin-catalog-react@1.14.0-next.1 + - @backstage/plugin-search-react@1.8.1-next.1 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-scaffolder-common@1.5.6 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-catalog-backend@1.26.2-next.1 + +### Patch Changes + +- 62747f8: Fixed a bug where the concurrency limiter for URL reading was not honored +- 8206f49: Fix a bug where etags were expiring too soon in the URL reader +- Updated dependencies + - @backstage/integration@1.15.1-next.0 + - @backstage/backend-openapi-utils@0.1.19-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-permission-node@0.8.4-next.0 + - @backstage/plugin-search-backend-module-catalog@0.2.3-next.1 + +## @backstage/plugin-catalog-backend-module-aws@0.4.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.1-next.1 + - @backstage/integration@1.15.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-kubernetes-common@0.8.3 + +## @backstage/plugin-catalog-backend-module-azure@0.2.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.15.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.3.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.15.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.24-next.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.2.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.15.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.13.1-next.0 + +## @backstage/plugin-catalog-backend-module-gerrit@0.2.3-next.1 + +### Patch Changes + +- 5b6edf1: Fixed an issue preventing the provider's `schedule` config from being applied." +- Updated dependencies + - @backstage/integration@1.15.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.13.1-next.0 + +## @backstage/plugin-catalog-backend-module-github@0.7.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.26.2-next.1 + - @backstage/integration@1.15.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + +## @backstage/plugin-catalog-backend-module-github-org@0.3.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-backend-module-github@0.7.5-next.1 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + +## @backstage/plugin-catalog-backend-module-gitlab@0.4.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.1-next.1 + - @backstage/integration@1.15.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + +## @backstage/plugin-catalog-backend-module-gitlab-org@0.2.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/plugin-catalog-backend-module-gitlab@0.4.3-next.1 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.5.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.26.2-next.1 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-catalog-backend-module-logs@0.1.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.26.2-next.1 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + +## @backstage/plugin-catalog-backend-module-openapi@0.2.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.26.2-next.1 + - @backstage/integration@1.15.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + +## @backstage/plugin-catalog-graph@0.4.11-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/frontend-plugin-api@0.9.0-next.1 + - @backstage/core-compat-api@0.3.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/plugin-catalog-react@1.14.0-next.1 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-import@0.12.5-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/frontend-plugin-api@0.9.0-next.1 + - @backstage/integration-react@1.2.0-next.1 + - @backstage/core-compat-api@0.3.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/plugin-catalog-react@1.14.0-next.1 + - @backstage/integration@1.15.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.1.0 + +## @backstage/plugin-catalog-unprocessed-entities@0.2.9-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/catalog-model@1.7.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-config-schema@0.1.60-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-devtools@0.1.19-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/frontend-plugin-api@0.9.0-next.1 + - @backstage/core-compat-api@0.3.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/plugin-permission-react@0.4.27-next.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-devtools-common@0.1.12 + +## @backstage/plugin-home@0.7.12-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/frontend-plugin-api@0.9.0-next.1 + - @backstage/core-compat-api@0.3.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/core-app-api@1.15.1-next.1 + - @backstage/plugin-catalog-react@1.14.0-next.1 + - @backstage/plugin-home-react@0.1.18-next.1 + - @backstage/theme@0.5.8-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + +## @backstage/plugin-home-react@0.1.18-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + +## @backstage/plugin-kubernetes@0.11.16-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- 605e0bb: Updated dependency `@kubernetes-models/base` to `^5.0.0`. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/frontend-plugin-api@0.9.0-next.1 + - @backstage/core-compat-api@0.3.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/plugin-kubernetes-react@0.4.4-next.1 + - @backstage/plugin-catalog-react@1.14.0-next.1 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-kubernetes-common@0.8.3 + +## @backstage/plugin-kubernetes-cluster@0.0.17-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- 605e0bb: Updated dependency `@kubernetes-models/base` to `^5.0.0`. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/plugin-kubernetes-react@0.4.4-next.1 + - @backstage/plugin-catalog-react@1.14.0-next.1 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-kubernetes-common@0.8.3 + +## @backstage/plugin-kubernetes-react@0.4.4-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- 605e0bb: Updated dependency `@kubernetes-models/base` to `^5.0.0`. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/catalog-model@1.7.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.8.3 + +## @backstage/plugin-notifications@0.3.2-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/plugin-signals-react@0.0.6-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/theme@0.5.8-next.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.5 + +## @backstage/plugin-org@0.6.31-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/frontend-plugin-api@0.9.0-next.1 + - @backstage/core-compat-api@0.3.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/plugin-catalog-react@1.14.0-next.1 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-catalog-common@1.1.0 + +## @backstage/plugin-org-react@0.1.30-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/plugin-catalog-react@1.14.0-next.1 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + +## @backstage/plugin-permission-react@0.4.27-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-scaffolder-backend@1.26.0-next.1 + +### Patch Changes + +- 2f90932: Include step name and step id to checkpoint key +- Updated dependencies + - @backstage/backend-defaults@0.5.1-next.1 + - @backstage/integration@1.15.1-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.1-next.1 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.24-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.1-next.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-permission-node@0.8.4-next.0 + - @backstage/plugin-scaffolder-backend-module-azure@0.2.1-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.1-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.1-next.1 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.2.1-next.1 + - @backstage/plugin-scaffolder-backend-module-gitea@0.2.1-next.1 + - @backstage/plugin-scaffolder-backend-module-github@0.5.1-next.1 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.5.1-next.1 + - @backstage/plugin-scaffolder-common@1.5.6 + - @backstage/plugin-scaffolder-node@0.5.0-next.1 + +## @backstage/plugin-scaffolder-backend-module-azure@0.2.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.15.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.5.0-next.1 + +## @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.15.1-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.1-next.1 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.1-next.1 + - @backstage/plugin-scaffolder-node@0.5.0-next.1 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.15.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-bitbucket-cloud-common@0.2.24-next.0 + - @backstage/plugin-scaffolder-node@0.5.0-next.1 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.1-next.1 + +### Patch Changes + +- 66a6b45: Use protocol from Bitbucket Server apiBaseUrl config parameter instead of hard-coded https +- Updated dependencies + - @backstage/integration@1.15.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.5.0-next.1 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.3.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.15.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.5.0-next.1 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.3.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.1-next.1 + - @backstage/integration@1.15.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.5.0-next.1 + +## @backstage/plugin-scaffolder-backend-module-gcp@0.2.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.15.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.5.0-next.1 + +## @backstage/plugin-scaffolder-backend-module-gerrit@0.2.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.15.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.5.0-next.1 + +## @backstage/plugin-scaffolder-backend-module-gitea@0.2.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.15.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.5.0-next.1 + +## @backstage/plugin-scaffolder-backend-module-github@0.5.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.15.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.5.0-next.1 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.5.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.15.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.5.0-next.1 + +## @backstage/plugin-scaffolder-backend-module-notifications@0.1.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.7-next.0 + - @backstage/plugin-scaffolder-node@0.5.0-next.1 + +## @backstage/plugin-scaffolder-backend-module-rails@0.5.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.15.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.5.0-next.1 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.2.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.5.0-next.1 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.4.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node-test-utils@0.1.13-next.1 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.5.0-next.1 + +## @backstage/plugin-scaffolder-node@0.5.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.15.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.6 + +## @backstage/plugin-scaffolder-node-test-utils@0.1.13-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/backend-test-utils@1.0.1-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.5.0-next.1 + +## @backstage/plugin-search@1.4.18-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/frontend-plugin-api@0.9.0-next.1 + - @backstage/core-compat-api@0.3.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/version-bridge@1.0.10-next.0 + - @backstage/plugin-catalog-react@1.14.0-next.1 + - @backstage/plugin-search-react@1.8.1-next.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-backend@1.5.18-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.1-next.1 + - @backstage/backend-openapi-utils@0.1.19-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-permission-node@0.8.4-next.0 + - @backstage/plugin-search-backend-node@1.3.3-next.1 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-backend-module-catalog@0.2.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-backend-node@1.3.3-next.1 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-backend-module-elasticsearch@1.5.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-backend-node@1.3.3-next.1 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-backend-module-explore@0.2.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-search-backend-node@1.3.3-next.1 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-backend-module-pg@0.5.36-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-search-backend-node@1.3.3-next.1 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-backend-module-stack-overflow-collator@0.3.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-search-backend-node@1.3.3-next.1 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-backend-module-techdocs@0.2.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-backend-node@1.3.3-next.1 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-techdocs-node@1.12.12-next.1 + +## @backstage/plugin-search-backend-node@1.3.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.1-next.1 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-react@1.8.1-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/frontend-plugin-api@0.9.0-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/version-bridge@1.0.10-next.0 + - @backstage/theme@0.5.8-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-signals@0.0.11-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/plugin-signals-react@0.0.6-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/theme@0.5.8-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-signals-react@0.0.6-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/types@1.1.1 + +## @backstage/plugin-techdocs@1.10.11-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/frontend-plugin-api@0.9.0-next.1 + - @backstage/integration-react@1.2.0-next.1 + - @backstage/core-compat-api@0.3.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/plugin-techdocs-react@1.2.9-next.1 + - @backstage/plugin-catalog-react@1.14.0-next.1 + - @backstage/plugin-search-react@1.8.1-next.1 + - @backstage/plugin-auth-react@0.1.7-next.1 + - @backstage/theme@0.5.8-next.0 + - @backstage/integration@1.15.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-techdocs-common@0.1.0 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.40-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/integration-react@1.2.0-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/plugin-techdocs-react@1.2.9-next.1 + - @backstage/core-app-api@1.15.1-next.1 + - @backstage/plugin-catalog-react@1.14.0-next.1 + - @backstage/plugin-search-react@1.8.1-next.1 + - @backstage/test-utils@1.6.1-next.1 + - @backstage/plugin-techdocs@1.10.11-next.1 + - @backstage/plugin-catalog@1.24.0-next.1 + +## @backstage/plugin-techdocs-backend@1.10.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.15.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-backend-module-techdocs@0.2.3-next.1 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-techdocs-node@1.12.12-next.1 + +## @backstage/plugin-techdocs-module-addons-contrib@1.1.16-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/integration-react@1.2.0-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/plugin-techdocs-react@1.2.9-next.1 + - @backstage/integration@1.15.1-next.0 + +## @backstage/plugin-techdocs-node@1.12.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.15.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-techdocs-common@0.1.0 + +## @backstage/plugin-techdocs-react@1.2.9-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/version-bridge@1.0.10-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + +## @backstage/plugin-user-settings@0.8.14-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/plugin-signals-react@0.0.6-next.1 + - @backstage/frontend-plugin-api@0.9.0-next.1 + - @backstage/core-compat-api@0.3.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/core-app-api@1.15.1-next.1 + - @backstage/plugin-catalog-react@1.14.0-next.1 + - @backstage/theme@0.5.8-next.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-user-settings-common@0.0.1 + +## @backstage/plugin-user-settings-backend@0.2.25-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.1-next.1 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/plugin-signals-node@0.1.12-next.0 + - @backstage/plugin-user-settings-common@0.0.1 + +## example-app@0.2.102-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/cli@0.28.0-next.1 + - @backstage/plugin-scaffolder@1.26.0-next.1 + - @backstage/plugin-signals@0.0.11-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.16-next.1 + - @backstage/plugin-catalog-unprocessed-entities@0.2.9-next.1 + - @backstage/integration-react@1.2.0-next.1 + - @backstage/plugin-kubernetes-cluster@0.0.17-next.1 + - @backstage/frontend-app-api@0.10.0-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/plugin-permission-react@0.4.27-next.1 + - @backstage/plugin-scaffolder-react@1.13.0-next.1 + - @backstage/plugin-catalog-import@0.12.5-next.1 + - @backstage/plugin-techdocs-react@1.2.9-next.1 + - @backstage/app-defaults@1.5.12-next.1 + - @backstage/core-app-api@1.15.1-next.1 + - @backstage/plugin-catalog-graph@0.4.11-next.1 + - @backstage/plugin-catalog-react@1.14.0-next.1 + - @backstage/plugin-notifications@0.3.2-next.1 + - @backstage/plugin-user-settings@0.8.14-next.1 + - @backstage/plugin-search-react@1.8.1-next.1 + - @backstage/plugin-auth-react@0.1.7-next.1 + - @backstage/plugin-kubernetes@0.11.16-next.1 + - @backstage/plugin-api-docs@0.11.11-next.1 + - @backstage/plugin-devtools@0.1.19-next.1 + - @backstage/plugin-techdocs@1.10.11-next.1 + - @backstage/plugin-catalog@1.24.0-next.1 + - @backstage/theme@0.5.8-next.0 + - @backstage/plugin-search@1.4.18-next.1 + - @backstage/plugin-home@0.7.12-next.1 + - @backstage/plugin-org@0.6.31-next.1 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-search-common@1.2.14 + +## example-app-next@0.0.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/cli@0.28.0-next.1 + - @backstage/plugin-scaffolder@1.26.0-next.1 + - @backstage/plugin-signals@0.0.11-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.16-next.1 + - @backstage/plugin-catalog-unprocessed-entities@0.2.9-next.1 + - @backstage/frontend-plugin-api@0.9.0-next.1 + - @backstage/integration-react@1.2.0-next.1 + - @backstage/plugin-kubernetes-cluster@0.0.17-next.1 + - @backstage/frontend-app-api@0.10.0-next.1 + - @backstage/core-compat-api@0.3.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/plugin-permission-react@0.4.27-next.1 + - @backstage/plugin-scaffolder-react@1.13.0-next.1 + - @backstage/plugin-app-visualizer@0.1.11-next.1 + - @backstage/plugin-catalog-import@0.12.5-next.1 + - @backstage/plugin-techdocs-react@1.2.9-next.1 + - @backstage/app-defaults@1.5.12-next.1 + - @backstage/core-app-api@1.15.1-next.1 + - @backstage/plugin-catalog-graph@0.4.11-next.1 + - @backstage/plugin-catalog-react@1.14.0-next.1 + - @backstage/plugin-notifications@0.3.2-next.1 + - @backstage/plugin-user-settings@0.8.14-next.1 + - @backstage/plugin-search-react@1.8.1-next.1 + - @backstage/plugin-auth-react@0.1.7-next.1 + - @backstage/plugin-kubernetes@0.11.16-next.1 + - @backstage/plugin-api-docs@0.11.11-next.1 + - @backstage/plugin-techdocs@1.10.11-next.1 + - @backstage/plugin-catalog@1.24.0-next.1 + - @backstage/theme@0.5.8-next.0 + - @backstage/plugin-search@1.4.18-next.1 + - @backstage/plugin-home@0.7.12-next.1 + - @backstage/plugin-org@0.6.31-next.1 + - @backstage/plugin-app@0.1.1-next.1 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/frontend-defaults@0.1.1-next.1 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-search-common@1.2.14 + +## app-next-example-plugin@0.0.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/frontend-plugin-api@0.9.0-next.1 + +## example-backend@0.0.31-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.26.0-next.1 + - @backstage/plugin-catalog-backend@1.26.2-next.1 + - @backstage/backend-defaults@0.5.1-next.1 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-app-backend@0.3.75-next.0 + - @backstage/plugin-auth-backend@0.23.1-next.0 + - @backstage/plugin-auth-backend-module-github-provider@0.2.1-next.0 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.1-next.0 + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.4.1-next.0 + - @backstage/plugin-catalog-backend-module-openapi@0.2.2-next.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.1-next.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.5.1-next.0 + - @backstage/plugin-devtools-backend@0.4.1-next.0 + - @backstage/plugin-events-backend@0.3.13-next.0 + - @backstage/plugin-kubernetes-backend@0.18.7-next.0 + - @backstage/plugin-notifications-backend@0.4.1-next.0 + - @backstage/plugin-permission-backend@0.5.50-next.0 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.1-next.0 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-permission-node@0.8.4-next.0 + - @backstage/plugin-proxy-backend@0.5.7-next.0 + - @backstage/plugin-scaffolder-backend-module-github@0.5.1-next.1 + - @backstage/plugin-search-backend@1.5.18-next.1 + - @backstage/plugin-search-backend-module-catalog@0.2.3-next.1 + - @backstage/plugin-search-backend-module-explore@0.2.3-next.1 + - @backstage/plugin-search-backend-module-techdocs@0.2.3-next.1 + - @backstage/plugin-search-backend-node@1.3.3-next.1 + - @backstage/plugin-signals-backend@0.2.1-next.0 + - @backstage/plugin-techdocs-backend@1.10.14-next.1 + +## example-backend-legacy@0.2.103-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.26.0-next.1 + - @backstage/plugin-catalog-backend@1.26.2-next.1 + - @backstage/backend-defaults@0.5.1-next.1 + - @backstage/integration@1.15.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/plugin-app-backend@0.3.75-next.0 + - @backstage/plugin-auth-backend@0.23.1-next.0 + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.1-next.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.5.1-next.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-devtools-backend@0.4.1-next.0 + - @backstage/plugin-events-backend@0.3.13-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/plugin-kubernetes-backend@0.18.7-next.0 + - @backstage/plugin-permission-backend@0.5.50-next.0 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-permission-node@0.8.4-next.0 + - @backstage/plugin-proxy-backend@0.5.7-next.0 + - @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.3.1-next.1 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.5.1-next.1 + - @backstage/plugin-scaffolder-backend-module-rails@0.5.1-next.1 + - @backstage/plugin-search-backend@1.5.18-next.1 + - @backstage/plugin-search-backend-module-catalog@0.2.3-next.1 + - @backstage/plugin-search-backend-module-elasticsearch@1.5.7-next.1 + - @backstage/plugin-search-backend-module-explore@0.2.3-next.1 + - @backstage/plugin-search-backend-module-pg@0.5.36-next.1 + - @backstage/plugin-search-backend-module-techdocs@0.2.3-next.1 + - @backstage/plugin-search-backend-node@1.3.3-next.1 + - @backstage/plugin-signals-backend@0.2.1-next.0 + - @backstage/plugin-signals-node@0.1.12-next.0 + - @backstage/plugin-techdocs-backend@1.10.14-next.1 + +## e2e-test@0.2.21-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.5.21-next.1 + - @backstage/cli-common@0.1.14 + - @backstage/errors@1.2.4 + +## @internal/frontend@0.0.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.1 + - @backstage/version-bridge@1.0.10-next.0 + - @backstage/types@1.1.1 + +## @internal/scaffolder@0.0.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-react@1.13.0-next.1 + +## techdocs-cli-embedded-app@0.2.101-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/cli@0.28.0-next.1 + - @backstage/integration-react@1.2.0-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/plugin-techdocs-react@1.2.9-next.1 + - @backstage/app-defaults@1.5.12-next.1 + - @backstage/core-app-api@1.15.1-next.1 + - @backstage/test-utils@1.6.1-next.1 + - @backstage/plugin-techdocs@1.10.11-next.1 + - @backstage/plugin-catalog@1.24.0-next.1 + - @backstage/theme@0.5.8-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + +## @internal/plugin-todo-list@1.0.32-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 diff --git a/docs/tooling/cli/02-build-system.md b/docs/tooling/cli/02-build-system.md index 1bcf7ad30c..ab7dc07802 100644 --- a/docs/tooling/cli/02-build-system.md +++ b/docs/tooling/cli/02-build-system.md @@ -420,7 +420,7 @@ The following is an example of a `Dockerfile` that can be used to package the output of building a package with role `'backend'` into an image: ```Dockerfile -FROM node:18-bookworm-slim +FROM node:20-bookworm-slim WORKDIR /app COPY yarn.lock package.json packages/backend/dist/skeleton.tar.gz ./ diff --git a/docs/tooling/package-metadata.md b/docs/tooling/package-metadata.md index 63ce6d1085..ad9d5ec5a0 100644 --- a/docs/tooling/package-metadata.md +++ b/docs/tooling/package-metadata.md @@ -156,6 +156,26 @@ This field indicates that a package has been renamed and moved to a new location } ``` +### `backstage.inline` + +If set to `true` this field indicates that monorepo package is private and should be inlined into dependent packages rather than being treated as a dependency. This effectively means that all imported code from the inlined package will be copied into the consuming package, once for each package. + +This flag affects various parts of the Backstage tooling, for example the way the Backstage CLI builds work, the way that `@backstage/eslint-plugin` lints dependencies on the package, and how it's treated by `@backstage/repo-tools`. + +The `backstage.inline` field is primarily intended to aid in the implementation of the Backstage core framework in the main Backstage repository, but it can be used in other projects as well. + +Setting this flag also requires the top-level `private` field to be set as well, since inline packages should not be published. + +```js title="Example usage of the backstage.moved field" +{ + "name": "@internal/utils", + "backstage": { + "inline": true + } + ... +} +``` + ## Metadata for Published Packages When publishing a package with the help of the Backstage CLI, there are a number of metadata checks that are performed to ensure that the package is correctly set up for the Backstage ecosystem. These checks are performed by the `backstage-cli package prepack` command, which is used to prepare a package for publishing. These checks can all also be verified separately using the `backstage-cli repo fix --publish` command, and in many cases the required metadata can be generated automatically. It is therefore important to make running the `fix` command part of your workflow in any project that is publishing Backstage packages. diff --git a/docs/tutorials/yarn-migration.md b/docs/tutorials/yarn-migration.md index 5c87125277..fc525ed23b 100644 --- a/docs/tutorials/yarn-migration.md +++ b/docs/tutorials/yarn-migration.md @@ -1,12 +1,10 @@ --- id: yarn-migration -title: Migration to Yarn 3 -description: Guide for how to migrate a Backstage project to use Yarn 3 +title: Migration to Yarn 4 +description: Guide for how to migrate a Backstage project to use Yarn 4 --- -While Backstage projects created with `@backstage/create-app` use [Yarn 1](https://classic.yarnpkg.com/) by default, it -is possible to switch them to instead use [Yarn 3](https://yarnpkg.com/). Tools like `yarn backstage-cli versions:bump` will -still work, as they recognize both lockfile formats. +Backstage projects created with `@backstage/create-app` now use [Yarn 4](https://yarnpkg.com/), you may have a previous version of Backstage that is still using [Yarn 1](https://classic.yarnpkg.com/) that you'll want to migrate, this tutorial will help you with this task. ## Migration @@ -19,7 +17,7 @@ First off, be sure to have the updated ignore entries in your app. These are inc Add the following to `.gitignore`: ```gitignore -# Yarn 3 files +# Yarn files .pnp.* .yarn/* !.yarn/patches @@ -38,12 +36,18 @@ And this to `.dockerignore`: ### Installation -Let's move on to the actual installation. We'd recommend making separate Git commits of most of these steps, in case you need to go back and debug anything. To install Yarn 3, run the following command in the project root: +Let's move on to the actual installation. We'd recommend making separate Git commits of most of these steps, in case you need to go back and debug anything. To install Yarn 4, run the following command in the project root: ```bash -yarn set version 3.x +yarn set version 4.x ``` +:::note + +If the above command doesn't work then you may need to run `yarn set version latest` but use this with caution as it may take you to a version beyond Yarn 4 + +::: + We'll need the Yarn workspace tools plugin later on, so let's install that too: ```bash @@ -56,23 +60,23 @@ In case you had a `.yarnrc` you can delete it now, but be sure to migrate over a ### Migrate Usage -At this point you'll be all set up with Yarn 3! What remains is to migrate any usage of Yarn according to their [migration guide](https://yarnpkg.com/getting-started/migration). For example, any `yarn install --frozen-lockfile` commands should be replaced with `yarn install --immutable`. +At this point you'll be all set up with Yarn 4! What remains is to migrate any usage of Yarn according to their [migration guide](https://yarnpkg.com/getting-started/migration). For example, any `yarn install --frozen-lockfile` commands should be replaced with `yarn install --immutable`. -You'll also need to update any `Dockerfile`s to add instructions to copy in your Yarn 3 installation into the image: +You'll also need to update any `Dockerfile`s to add instructions to copy in your Yarn 4 installation into the image: ```Dockerfile COPY .yarn ./.yarn COPY .yarnrc.yml ./ ``` -In a multi-stage `Dockerfile`, each stage that runs a `yarn` command will also need the Yarn 3 installation. For example, in the final stage you may need to add the following: +In a multi-stage `Dockerfile`, each stage that runs a `yarn` command will also need the Yarn 4 installation. For example, in the final stage you may need to add the following: ```Dockerfile COPY --from=build --chown=node:node /app/.yarn ./.yarn COPY --from=build --chown=node:node /app/.yarnrc.yml ./ ``` -The `--production` flag to `yarn install` has been removed in Yarn 3, instead you need to use `yarn workspaces focus --all --production` to avoid installing development dependencies in your production deployment. A tradeoff of this is that `yarn workspaces focus` does not support the `--immutable` flag. +The `--production` flag to `yarn install` has been removed in Yarn 4, instead you need to use `yarn workspaces focus --all --production` to avoid installing development dependencies in your production deployment. A tradeoff of this is that `yarn workspaces focus` does not support the `--immutable` flag. ```Dockerfile RUN yarn workspaces focus --all --production && rm -rf "$(yarn cache clean)" @@ -81,8 +85,6 @@ RUN yarn workspaces focus --all --production && rm -rf "$(yarn cache clean)" Additionally, `yarn config` has been reworked from being able to store any arbitrary key-value pairs to only supporting a handful of predefined pairs. Previously, we would set our preferred `python3` interpreter to work around [any issues related to node-gyp](https://github.com/backstage/backstage/issues/11583) so we need to provide an appropriate substitute. ```Dockerfile -FROM node:16-bullseye-slim - # highlight-add-start # Set Python interpreter for `node-gyp` to use ENV PYTHON=/usr/bin/python3 diff --git a/microsite/README.md b/microsite/README.md index 5bd20254b6..62a28fb6a3 100644 --- a/microsite/README.md +++ b/microsite/README.md @@ -61,7 +61,7 @@ my-docusaurus/ css/ img/ package.json - sidebars.json + sidebars.js siteConfig.js ``` @@ -116,19 +116,20 @@ For more information about blog posts, click [here](https://docusaurus.io/docs/e My new content here.. ``` -2. Refer to that doc's ID in an existing sidebar in `website/sidebars.json`: +2. Refer to that doc's ID in an existing sidebar in `website/sidebars.js`: - ```javascript + ```js // Add newly-created-doc to the Getting Started category of docs - { - "docs": { - "Getting Started": [ - "quick-start", - "newly-created-doc" // new doc here - ], - ... - }, - ... + module.exports = { + ... + docs: { + "Getting Started": [ + "quick-start", + "newly-created-doc" // new doc here + ], + ... + }, + ... } ``` diff --git a/microsite/blog/2024-09-24-dynatrace-adopter-spotlight.mdx b/microsite/blog/2024-09-24-dynatrace-adopter-spotlight.mdx new file mode 100644 index 0000000000..7e029e0aab --- /dev/null +++ b/microsite/blog/2024-09-24-dynatrace-adopter-spotlight.mdx @@ -0,0 +1,95 @@ +--- +title: 'Adopter Spotlight: Level-up developer experience with observability and security in context' +author: Johannes Bräuer, Dynatrace +authorURL: https://github.com/johannes-b +authorImageURL: https://avatars.githubusercontent.com/u/729071?v=4 +--- + +**TL;DR** +To enhance the developer experience, Dynatrace adopted Backstage as its central developer portal and enhances Backstage entities with real-time data. This decision, along with the symbiosis between the Dynatrace platform and Backstage, has unlocked two significant opportunities. + +- First, centralizing all development-related artifacts and democratizing ownership have reduced onboarding time for our teams. +- Second, we enhanced the developer experience by integrating observability and security data into Backstage, offering seamless entry points to Dynatrace for in-depth analysis. + +![Dynatrace adopting Backstage](assets/2024-09-24/com0027.Dynatrace.Adopter.png) + +{/* truncate */} + +## Why and how Dynatrace rolled out Backstage + +A few years ago, Dynatrace developers worked with large monolithic repositories to develop functionality for our platform’s agent and server sides. The server component was particularly large, consisting of 260 Gradle projects in a single repository. This setup centralized development processes for the developers, making it easier for them to push the code while versioning, delivery, and hotfixes were handled automatically. However, maintaining the speed and manageability of these processes required a lot of effort. + +Dynatrace decided to move towards the current Dynatrace platform model as the next evolutionary step of our product. This decision led to an architectural change of splitting the monolithic repository into multiple projects. The platform is designed to enable the development of apps on top of platform capabilities to unlock faster innovations and decouple them from the release cycles of other components. Based on this decision, it became apparent that the number of platform components and individual apps would increase significantly, eliminating the option of a single repository to unify all processes. Besides, the risk of increasing cognitive load in software development was high due to development being spread across multiple touchpoints, a challenge discussed in research for years ([Sweller, 1988](), [Robert, 2008](https://dl.acm.org/doi/10.5555/1388398)). Consequently, the need to standardize project creation became crucial to ensure corporate governance and compliance even before the first commit was pushed. + + + +Therefore, the Dynatrace Platform Engineering team initiated a project to standardize and simplify the process for starting service or application development. This effort was initially named “project initializer” and launched around the same time Backstage joined the CNCF. Although the platform engineering team saw initial success with the project initializer, we quickly realized that there was a greater demand for centralizing development activities and providing appropriate guidelines. For example, we noted that the complexity of integrating new code had shifted from the build phase to the deployment phase, transferring relatively complex integration tasks from continuous integration to continuous deployment. Overall, the main requirements and focal points were: + +- **Ownership**: Who is responsible for which service or app? Who owns infrastructure resources? +- **Documentation**: Where is the documentation of a service or app? +- **CI/CD view**: How does the build pipeline in GitHub/Jenkins progress, and what about the ArgoCD deployment? +- **Dependency management**: Do we know which APIs are used? +- **Observability and security**: Where is a service deployed, and is it healthy and secure? + +For more details on Dynatrace's adoption of Backstage, please watch the recording, [How We Made Backstage Improve Developer Efficiency of 1000+ Engineers](https://www.youtube.com/watch?v=0or5K_3HieA), BackstageCon, November 6, 2023 in Chicago. Illinois. + +## Quick wins with ownership democratization and self-service templates + +The discussion on whether to make, buy, or adopt led us to heavily favor Backstage as the chosen solution for our internal developer platform (IDP). We have successfully integrated Backstage within Dynatrace, marking our early wins. This was accomplished by linking it to our internal team management solution. Feeding this data into Backstage resolved the previously lacking transparency concerning the responsibilities and ownership of services and infrastructure. Furthermore, we have contextualized Stack Overflow and CI/CD solutions with entities monitored by Backstage to fulfill developers' requests for a unified view. + +Next to establishing a solid software catalog view, providing self-service templates for project and infrastructure creation—initially a focus of the original developer experience—has also been incorporated into Backstage. This enhancement allows the use of a comprehensive set of templates for bootstrapping platform services or applications across different tool stacks. Ultimately, developers can effortlessly use a template to create a ready-to-use repository with observability and security pre-configured. + +## Static model enrichment with real-time observability and security + +After addressing ownership, documentation, and a centralized CI/CD view, our developers highlighted the necessity of accessing real-time data about their services and applications within the Backstage service catalog. This need arose from the understanding that integrating a code change can be optimally evaluated on a deployed version of their service alongside related components. Specifically, the developers were interested in seeing at a high level: + +- Where specific versions of services are deployed, +- How their services perform in the hardening phase and production environments, +- Which inbound and outbound dependencies their service has, +- Whether any problems, security vulnerabilities, or SLO breaches are related to their service, and +- Which recent error logs have been collected. + +The open source community already developed a Backstage plugin capable of fetching Dynatrace problems and synthetics into Backstage. However, we chose to develop a new plugin that works with the new Dynatrace platform API. Additionally, it was necessary to support Kubernetes use cases by default to offer, for example, deployment overviews out-of-the-box. Based on the feedback from developers, we identified four essential requirements. + +### Coverage of the software development lifecycle + +Observing the software development lifecycle necessitates consolidating all development and delivery phases. In Dynatrace, monitoring the development stage is distinct from rolling out new versions to the hardening and production stages. Nonetheless, developers desire an end-to-end view from development to production. To support this, the plugin allows connections to multiple Dynatrace environments to retrieve data for the various rollout phases. + +### Kubernetes observability + +When using the Backstage Kubernetes plugin, an annotation is required to surface your Kubernetes components as part of an entity (for more information, please refer to [Backstage documentation](https://backstage.io/docs/features/kubernetes/configuration/#surfacing-your-kubernetes-components-as-part-of-an-entity)). The Dynatrace plugin utilizes this convention to automatically populate monitoring data from Kubernetes deployments into the deployment overview in Backstage. Therefore, additional configuration is unnecessary to enrich Backstage entities with real-time observability data from Kubernetes, as shown below. Additionally, deep links open Dynatrace analysis views for more contextual details. + +![Kubernetes deployment overview](assets/2024-09-24/backstage_dynatrace_plugin_K8s.png) + +### Reliability and security in context + +While Kubernetes observability was requested to be provided out of the box, we quickly realized that developers prefer to define the insights they want to see by themselves. To remain flexible and to reduce the customization effort required from the platform engineering teams, the plugin allows for the definition of custom queries within the `config.yaml` file. The Backstage `config.yaml` file requires special attention since platform teams use this file to standardize entity specifications, while developers use it to customize their Backstage views. After releasing this new functionality, we observed developers moving in two distinct directions: + +- Querying quality gate validation results of a new version they’re developing + +![Release validation overview](assets/2024-09-24/backstage_srg_validations.png) + +- Fetching runtime security vulnerability information across different stages + +![Security vulnerabilities in context](assets/2024-09-24/backstage_catalog_security_vulnerabilites.png) + +### Error logs at hand + +Developers love logs. Direct access to logs, especially error logs, was a crucial requirement for the plugin. Our developers want to see the current number of error logs accompanied by a direct link to the raw log line, which provides significant value in problem triaging and fixing. With the plugin, we offer a high-level overview of log statistics, with the rich analysis capabilities of Dynatrace available at a single click. + +## Conclusion + +To enhance the developer experience, Dynatrace adopted Backstage as its central developer portal and enhances Backstage entities with real-time data. This decision, along with the symbiosis between the Dynatrace platform and Backstage, has unlocked two significant opportunities. + +First, centralizing all development-related artifacts and democratizing ownership have reduced onboarding time for our teams. Although it might seem that onboarding time is only relevant for new developers, it is also important when developers move to a different team, pick up a service or application they haven’t worked on for a while, or replace their laptops. Moreover, a low onboarding time is crucial when quickly kicking off work on a new service or solution app. This became a necessity with the new Dynatrace platform. + +Second, we enhanced the developer experience by integrating observability and security data into Backstage, offering seamless entry points to Dynatrace for in-depth analysis. This improvement was crucial as we noted a shift in integration tasks from build to development time, necessitating insights into a later phase of the software lifecycle for our developers. In essence, end-to-end validation of code changes could no longer be accomplished with build pipelines—either in Jenkins or GitHub—but required deployment in production-like environments that facilitate real-world interaction with other components. Consequently, real-time observability data from these environments must be relayed to the developer. + +## What`s next? + +Backstage is a crucial element for Dynatrace's developer experience, providing out-of-the-box core functionality for every developer and supporting extensibility where needed. Our Backstage extension is maintained as an open-source project and is available for every Backstage user. Don't hesitate to utilize it or to contribute: https://github.com/Dynatrace/backstage-plugin + +If you have a great Backstage story to tell, please share your experience with us to the variety of use case areas. diff --git a/microsite/blog/assets/2024-09-24/backstage_catalog_security_vulnerabilites.png b/microsite/blog/assets/2024-09-24/backstage_catalog_security_vulnerabilites.png new file mode 100644 index 0000000000..19d74cf472 Binary files /dev/null and b/microsite/blog/assets/2024-09-24/backstage_catalog_security_vulnerabilites.png differ diff --git a/microsite/blog/assets/2024-09-24/backstage_dynatrace_plugin_K8s.png b/microsite/blog/assets/2024-09-24/backstage_dynatrace_plugin_K8s.png new file mode 100644 index 0000000000..11681e064e Binary files /dev/null and b/microsite/blog/assets/2024-09-24/backstage_dynatrace_plugin_K8s.png differ diff --git a/microsite/blog/assets/2024-09-24/backstage_srg_validations.png b/microsite/blog/assets/2024-09-24/backstage_srg_validations.png new file mode 100644 index 0000000000..49d2371092 Binary files /dev/null and b/microsite/blog/assets/2024-09-24/backstage_srg_validations.png differ diff --git a/microsite/blog/assets/2024-09-24/com0027.Dynatrace.Adopter.png b/microsite/blog/assets/2024-09-24/com0027.Dynatrace.Adopter.png new file mode 100644 index 0000000000..b5a3c4c720 Binary files /dev/null and b/microsite/blog/assets/2024-09-24/com0027.Dynatrace.Adopter.png differ diff --git a/microsite/data/plugins/github-copilot.yaml b/microsite/data/plugins/github-copilot.yaml new file mode 100644 index 0000000000..5228d66ec5 --- /dev/null +++ b/microsite/data/plugins/github-copilot.yaml @@ -0,0 +1,10 @@ +--- +title: GitHub Copilot Adoption Metrics +author: ESW +authorUrl: https://esw.com +category: Reporting +description: Github Copilot plugin integrates with the Copilot API to provide metrics on Copilot adoption within your organization. +documentation: https://github.com/backstage/community-plugins/tree/main/workspaces/copilot/plugins/copilot +iconUrl: https://platformnewsletter.blob.core.windows.net/$web/copilot.png +npmPackageName: '@backstage-community/plugin-copilot' +addedDate: '2024-10-21' diff --git a/microsite/data/plugins/github-workflows.yaml b/microsite/data/plugins/github-workflows.yaml index 743e7a5b1b..f80e6f3f29 100644 --- a/microsite/data/plugins/github-workflows.yaml +++ b/microsite/data/plugins/github-workflows.yaml @@ -4,7 +4,7 @@ author: VeeCode Platform authorUrl: https://platform.vee.codes/ category: CI/CD description: The Github Workflows plugin provides an alternative for manually triggering GitHub workflows from within your Backstage component. -documentation: https://platform.vee.codes/plugin/Github%20workflows/ +documentation: https://platform.vee.codes/plugin/github-workflows/ iconUrl: https://veecode-platform.github.io/support/imgs/logo_2.svg npmPackageName: '@veecode-platform/backstage-plugin-github-workflows' tags: diff --git a/microsite/data/plugins/gitlab-pipelines.yaml b/microsite/data/plugins/gitlab-pipelines.yaml index d40419e464..4b77d67e07 100644 --- a/microsite/data/plugins/gitlab-pipelines.yaml +++ b/microsite/data/plugins/gitlab-pipelines.yaml @@ -4,7 +4,7 @@ author: VeeCode Platform authorUrl: https://platform.vee.codes category: CI/CD description: The Gitlab pipelines plugin integrates GitlabCi with its backstage component in a simple way. -documentation: https://platform.vee.codes/plugin/Gitlab%20Pipelines/ +documentation: https://platform.vee.codes/plugin/gitlab-pipelines/ iconUrl: https://veecode-platform.github.io/support/imgs/logo_1.svg npmPackageName: '@veecode-platform/backstage-plugin-gitlab-pipelines' tags: diff --git a/microsite/data/plugins/harness-ccm.yaml b/microsite/data/plugins/harness-ccm.yaml new file mode 100644 index 0000000000..e696fdca4b --- /dev/null +++ b/microsite/data/plugins/harness-ccm.yaml @@ -0,0 +1,11 @@ +title: Harness Cloud Cost Management +author: harness.io +authorUrl: https://github.com/harness/backstage-plugins +category: FinOps +description: This plugin helps you to manage and optimize cloud costs using Harness Cloud Cost Management module directly inside Backstage. +documentation: https://github.com/harness/backstage-plugins/tree/main/plugins/harness-ccm +iconUrl: https://static.harness.io/ng-static/images/favicon.png +npmPackageName: '@harnessio/backstage-plugin-harness-ccm' +tags: + - finops +addedDate: '2024-09-27' diff --git a/microsite/data/plugins/kong-service-manager.yaml b/microsite/data/plugins/kong-service-manager.yaml index 78ff37e36e..2b5f444479 100644 --- a/microsite/data/plugins/kong-service-manager.yaml +++ b/microsite/data/plugins/kong-service-manager.yaml @@ -4,7 +4,7 @@ author: VeeCode Platform authorUrl: https://platform.vee.codes/ category: api-manager description: The Kong Service Manager plugin provides information about the kong service, a list of the routes it has and also offers the possibility of manipulating plugins without leaving the backstage. -documentation: https://platform.vee.codes/plugin/Kong%20Service%20Manager/ +documentation: https://platform.vee.codes/plugin/kong-service-manager/ iconUrl: https://veecode-platform.github.io/support/imgs/logo_3.svg npmPackageName: '@veecode-platform/plugin-kong-service-manager' tags: diff --git a/microsite/data/plugins/kubernetes-gpt-analyzer.yaml b/microsite/data/plugins/kubernetes-gpt-analyzer.yaml index 78bd0fe4c4..e5de961869 100644 --- a/microsite/data/plugins/kubernetes-gpt-analyzer.yaml +++ b/microsite/data/plugins/kubernetes-gpt-analyzer.yaml @@ -4,7 +4,7 @@ author: VeeCode Platform authorUrl: https://platform.vee.codes/ category: Monitoring description: The Kubernetes GPT Analyzer plug-in uses artificial intelligence with the help of k8s-operator to analyze and optimize your Kubernetes entities, improving the management and performance of your cluster. It makes it easier to detect anomalies and suggest best practices. -documentation: https://platform.vee.codes/plugin/Kubernetes%20GPT%20Analyzer/ +documentation: https://platform.vee.codes/plugin/kubernetes-gpt-analyzer/ iconUrl: https://veecode-platform.github.io/support/imgs/logo_4.svg npmPackageName: '@veecode-platform/backstage-plugin-kubernetes-gpt-analyzer' tags: diff --git a/microsite/data/plugins/scaffolder-backend-module-webex.yaml b/microsite/data/plugins/scaffolder-backend-module-webex.yaml new file mode 100644 index 0000000000..f2113b2a8d --- /dev/null +++ b/microsite/data/plugins/scaffolder-backend-module-webex.yaml @@ -0,0 +1,11 @@ +--- +title: Cisco Webex Scaffolder Actions +author: Robert Lindley +authorUrl: https://github.com/Coderrob +category: Scaffolder +description: >- + A Backstage.io plugin that enables sending Webex messages via + Incoming Webhooks within scaffolder templates. +documentation: https://github.com/Coderrob/backstage-plugin-scaffolder-backend-module-webex +npmPackageName: '@coderrob/backstage-plugin-scaffolder-backend-module-webex' +addedDate: '2024-09-04' diff --git a/microsite/docusaurus.config.ts b/microsite/docusaurus.config.ts index 96edb57dea..af96ef4c42 100644 --- a/microsite/docusaurus.config.ts +++ b/microsite/docusaurus.config.ts @@ -22,6 +22,7 @@ import { themes } from 'prism-react-renderer'; import type * as Preset from '@docusaurus/preset-classic'; import { Config } from '@docusaurus/types'; import RedirectPlugin from '@docusaurus/plugin-client-redirects'; +import { releases } from './releases'; const backstageTheme = themes.vsDark; backstageTheme.plain.backgroundColor = '#232323'; @@ -85,7 +86,7 @@ const config: Config = { docs: { editUrl: 'https://github.com/backstage/backstage/edit/master/docs/', path: '../docs', - sidebarPath: 'sidebars.json', + sidebarPath: 'sidebars.js', ...(useVersionedDocs ? { includeCurrentVersion: true, @@ -295,7 +296,7 @@ const config: Config = { position: 'left', }, { - to: 'docs/releases/v1.30.0', + to: `docs/releases/${releases[0]}`, label: 'Releases', position: 'left', }, diff --git a/microsite/lighthouserc.js b/microsite/lighthouserc.js index f0024ee0b3..c75138d4c3 100644 --- a/microsite/lighthouserc.js +++ b/microsite/lighthouserc.js @@ -14,7 +14,7 @@ * limitations under the License. */ -var sidebars = require('./sidebars.json'); +const sidebars = require('./sidebars'); module.exports = { ci: { diff --git a/microsite/releases.js b/microsite/releases.js new file mode 100644 index 0000000000..4136b0edad --- /dev/null +++ b/microsite/releases.js @@ -0,0 +1,21 @@ +const fs = require('fs'); +const path = require('path'); + +const docsDir = path.resolve(__dirname, '../docs'); + +exports.releases = fs + .readdirSync(path.resolve(docsDir, 'releases')) + .filter(doc => doc.match(/^v\d+\.\d+\.\d+\.md$/)) + .map(doc => doc.replace(/\.md$/, '')) + .sort((a, b) => { + // Semver sort + const aVal = a + .slice(1) + .split('.') + .reduce((acc, val) => acc * 1000 + parseInt(val), 0); + const bVal = b + .slice(1) + .split('.') + .reduce((acc, val) => acc * 1000 + parseInt(val), 0); + return bVal - aVal; + }); diff --git a/microsite/sidebars.js b/microsite/sidebars.js new file mode 100644 index 0000000000..871cec0a0f --- /dev/null +++ b/microsite/sidebars.js @@ -0,0 +1,532 @@ +const { releases } = require('./releases'); + +module.exports = { + docs: { + Overview: [ + 'overview/what-is-backstage', + 'overview/architecture-overview', + 'overview/roadmap', + 'overview/vision', + 'overview/background', + 'overview/adopting', + 'overview/versioning-policy', + 'overview/threat-model', + 'overview/support', + 'overview/logos', + ], + 'Getting Started': [ + 'getting-started/index', + { + type: 'category', + label: 'Configuring Backstage', + items: [ + 'getting-started/config/database', + 'getting-started/config/authentication', + 'getting-started/configure-app-with-plugins', + 'getting-started/app-custom-theme', + 'getting-started/homepage', + ], + }, + { + type: 'category', + label: 'Using Backstage', + items: [ + 'getting-started/logging-in', + 'getting-started/register-a-component', + 'getting-started/create-a-component', + ], + }, + 'getting-started/keeping-backstage-updated', + 'getting-started/concepts', + ], + 'Core Features': [ + { + type: 'category', + label: 'Software Catalog', + items: [ + 'features/software-catalog/software-catalog-overview', + 'features/software-catalog/life-of-an-entity', + 'features/software-catalog/configuration', + 'features/software-catalog/system-model', + 'features/software-catalog/descriptor-format', + 'features/software-catalog/references', + 'features/software-catalog/well-known-annotations', + 'features/software-catalog/well-known-relations', + 'features/software-catalog/well-known-statuses', + 'features/software-catalog/extending-the-model', + 'features/software-catalog/external-integrations', + 'features/software-catalog/catalog-customization', + 'features/software-catalog/software-catalog-api', + 'features/software-catalog/creating-the-catalog-graph', + 'features/software-catalog/faq', + ], + }, + { + type: 'category', + label: 'Kubernetes', + items: [ + 'features/kubernetes/overview', + 'features/kubernetes/installation', + 'features/kubernetes/configuration', + 'features/kubernetes/authentication', + 'features/kubernetes/authentication-strategies', + 'features/kubernetes/troubleshooting', + 'features/kubernetes/proxy', + ], + }, + { + type: 'category', + label: 'Software Templates', + items: [ + 'features/software-templates/software-templates-index', + 'features/software-templates/configuration', + 'features/software-templates/adding-templates', + 'features/software-templates/writing-templates', + 'features/software-templates/input-examples', + 'features/software-templates/builtin-actions', + 'features/software-templates/writing-custom-actions', + 'features/software-templates/writing-tests-for-actions', + 'features/software-templates/writing-custom-field-extensions', + 'features/software-templates/writing-custom-step-layouts', + 'features/software-templates/authorizing-scaffolder-template-details', + 'features/software-templates/migrating-to-rjsf-v5', + 'features/software-templates/migrating-from-v1beta2-to-v1beta3', + 'features/software-templates/dry-run-testing', + ], + }, + { + type: 'category', + label: 'Backstage Search', + items: [ + 'features/search/search-overview', + 'features/search/getting-started', + 'features/search/concepts', + 'features/search/architecture', + 'features/search/search-engines', + 'features/search/collators', + 'features/search/how-to-guides', + ], + }, + { + type: 'category', + label: 'TechDocs', + items: [ + 'features/techdocs/techdocs-overview', + 'features/techdocs/getting-started', + 'features/techdocs/concepts', + 'features/techdocs/addons', + 'features/techdocs/architecture', + 'features/techdocs/extensions', + 'features/techdocs/creating-and-publishing', + 'features/techdocs/configuration', + 'features/techdocs/using-cloud-storage', + 'features/techdocs/configuring-ci-cd', + 'features/techdocs/cli', + 'features/techdocs/how-to-guides', + 'features/techdocs/troubleshooting', + 'features/techdocs/faqs', + ], + }, + ], + Integrations: [ + 'integrations/index', + { + type: 'category', + label: 'AWS S3', + items: [ + 'integrations/aws-s3/locations', + 'integrations/aws-s3/discovery', + ], + }, + { + type: 'category', + label: 'Azure', + items: [ + 'integrations/azure/locations', + 'integrations/azure/discovery', + 'integrations/azure/org', + ], + }, + { + type: 'category', + label: 'Bitbucket Cloud', + items: [ + 'integrations/bitbucketCloud/locations', + 'integrations/bitbucketCloud/discovery', + ], + }, + { + type: 'category', + label: 'Bitbucket Server', + items: [ + 'integrations/bitbucketServer/locations', + 'integrations/bitbucketServer/discovery', + ], + }, + { + type: 'category', + label: 'Datadog', + items: ['integrations/datadog-rum/installation'], + }, + { + type: 'category', + label: 'Gerrit', + items: [ + 'integrations/gerrit/locations', + 'integrations/gerrit/discovery', + ], + }, + { + type: 'category', + label: 'GitHub', + items: [ + 'integrations/github/locations', + 'integrations/github/discovery', + 'integrations/github/org', + 'integrations/github/github-apps', + ], + }, + { + type: 'category', + label: 'GitLab', + items: [ + 'integrations/gitlab/locations', + 'integrations/gitlab/discovery', + 'integrations/gitlab/org', + ], + }, + { + type: 'category', + label: 'Gitea', + items: ['integrations/gitea/locations'], + }, + { + type: 'category', + label: 'Harness', + items: ['integrations/harness/locations'], + }, + { + type: 'category', + label: 'Google GCS', + items: ['integrations/google-cloud-storage/locations'], + }, + { + type: 'category', + label: 'LDAP', + items: ['integrations/ldap/org'], + }, + ], + Plugins: [ + 'plugins/index', + 'plugins/existing-plugins', + 'plugins/create-a-plugin', + 'plugins/plugin-development', + 'plugins/structure-of-a-plugin', + 'plugins/integrating-plugin-into-software-catalog', + 'plugins/integrating-search-into-plugins', + 'plugins/composability', + 'plugins/internationalization', + 'plugins/analytics', + 'plugins/feature-flags', + { + type: 'category', + label: 'OpenAPI', + items: [ + 'openapi/01-getting-started', + 'openapi/generate-client', + 'openapi/test-case-validation', + ], + }, + { + type: 'category', + label: 'Backends and APIs', + items: [ + 'plugins/proxying', + 'plugins/backend-plugin', + 'plugins/call-existing-api', + ], + }, + { + type: 'category', + label: 'Testing', + items: ['plugins/testing'], + }, + { + type: 'category', + label: 'Publishing', + items: [ + 'plugins/publish-private', + 'plugins/add-to-directory', + 'plugins/observability', + ], + }, + ], + Configuration: [ + 'conf/index', + 'conf/reading', + 'conf/writing', + 'conf/defining', + ], + Notifications: ['notifications/index'], + 'Auth and identity': [ + 'auth/index', + { + type: 'category', + label: 'Included providers', + items: [ + 'auth/auth0/provider', + 'auth/atlassian/provider', + 'auth/aws-alb/provider', + 'auth/microsoft/provider', + 'auth/microsoft/easy-auth', + 'auth/bitbucket/provider', + 'auth/bitbucketServer/provider', + 'auth/cloudflare/provider', + 'auth/github/provider', + 'auth/gitlab/provider', + 'auth/google/provider', + 'auth/google/gcp-iap-auth', + 'auth/guest/provider', + 'auth/okta/provider', + 'auth/oauth2-proxy/provider', + 'auth/onelogin/provider', + 'auth/vmware-cloud/provider', + ], + }, + 'auth/identity-resolver', + 'auth/oauth', + 'auth/oidc', + 'auth/add-auth-provider', + 'auth/service-to-service-auth', + 'auth/autologout', + 'auth/troubleshooting', + ], + Permissions: [ + 'permissions/overview', + 'permissions/concepts', + 'permissions/getting-started', + 'permissions/writing-a-policy', + 'permissions/frontend-integration', + 'permissions/custom-rules', + { + type: 'category', + label: 'Tutorial: using Permissions in your plugin', + items: [ + 'permissions/plugin-authors/01-setup', + 'permissions/plugin-authors/02-adding-a-basic-permission-check', + 'permissions/plugin-authors/03-adding-a-resource-permission-check', + 'permissions/plugin-authors/04-authorizing-access-to-paginated-data', + 'permissions/plugin-authors/05-frontend-authorization', + ], + }, + ], + Tooling: [ + { + type: 'category', + label: 'Backstage CLI', + items: [ + 'tooling/cli/overview', + 'tooling/cli/build-system', + 'tooling/cli/commands', + ], + }, + { + type: 'category', + label: 'Local Development', + items: [ + 'tooling/local-dev/linking-local-packages', + 'tooling/local-dev/debugging', + 'tooling/local-dev/profiling', + ], + }, + 'tooling/package-metadata', + ], + Deployment: [ + 'deployment/index', + 'deployment/scaling', + 'deployment/docker', + 'deployment/k8s', + 'deployment/heroku', + 'deployment/koyeb', + 'deployment/flightcontrol', + { + type: 'category', + label: 'Using Backstage Deploy (alpha)', + items: ['deployment/backstage-deploy/aws-lightsail'], + }, + ], + 'New Backend System': [ + 'backend-system/index', + { + type: 'category', + label: 'Architecture', + items: [ + 'backend-system/architecture/index', + 'backend-system/architecture/services', + 'backend-system/architecture/plugins', + 'backend-system/architecture/extension-points', + 'backend-system/architecture/modules', + 'backend-system/architecture/feature-loaders', + 'backend-system/architecture/naming-patterns', + ], + }, + { + type: 'category', + label: 'Building Backends', + items: [ + 'backend-system/building-backends/index', + 'backend-system/building-backends/migrating', + ], + }, + { + type: 'category', + label: 'Building Plugins & Modules', + items: [ + 'backend-system/building-plugins-and-modules/index', + 'backend-system/building-plugins-and-modules/testing', + 'backend-system/building-plugins-and-modules/migrating', + ], + }, + { + type: 'category', + label: 'Core Services', + items: [ + 'backend-system/core-services/index', + 'backend-system/core-services/auth', + 'backend-system/core-services/cache', + 'backend-system/core-services/database', + 'backend-system/core-services/discovery', + 'backend-system/core-services/http-auth', + 'backend-system/core-services/http-router', + 'backend-system/core-services/identity', + 'backend-system/core-services/lifecycle', + 'backend-system/core-services/logger', + 'backend-system/core-services/permissions', + 'backend-system/core-services/plugin-metadata', + 'backend-system/core-services/root-config', + 'backend-system/core-services/root-health', + 'backend-system/core-services/root-http-router', + 'backend-system/core-services/root-lifecycle', + 'backend-system/core-services/root-logger', + 'backend-system/core-services/scheduler', + 'backend-system/core-services/token-manager', + 'backend-system/core-services/url-reader', + 'backend-system/core-services/user-info', + ], + }, + ], + 'New Frontend System': [ + 'frontend-system/index', + { + type: 'category', + label: 'Architecture', + items: [ + 'frontend-system/architecture/index', + 'frontend-system/architecture/app', + 'frontend-system/architecture/plugins', + 'frontend-system/architecture/extensions', + 'frontend-system/architecture/extension-blueprints', + 'frontend-system/architecture/extension-overrides', + 'frontend-system/architecture/references', + 'frontend-system/architecture/utility-apis', + 'frontend-system/architecture/routes', + 'frontend-system/architecture/naming-patterns', + 'frontend-system/architecture/migrations', + ], + }, + { + type: 'category', + label: 'Building Plugins', + items: [ + 'frontend-system/building-plugins/index', + 'frontend-system/building-plugins/testing', + 'frontend-system/building-plugins/common-extension-blueprints', + 'frontend-system/building-plugins/built-in-data-refs', + 'frontend-system/building-plugins/migrating', + ], + }, + { + type: 'category', + label: 'Building Apps', + items: [ + 'frontend-system/building-apps/index', + 'frontend-system/building-apps/configuring-extensions', + 'frontend-system/building-apps/built-in-extensions', + 'frontend-system/building-apps/plugin-conversion', + 'frontend-system/building-apps/migrating', + ], + }, + { + type: 'category', + label: 'Utility APIs', + items: [ + 'frontend-system/utility-apis/index', + 'frontend-system/utility-apis/creating', + 'frontend-system/utility-apis/consuming', + 'frontend-system/utility-apis/configuring', + ], + }, + ], + 'Designing for Backstage': [ + 'dls/design', + 'dls/component-design-guidelines', + 'dls/contributing-to-storybook', + 'dls/figma', + ], + 'API Reference': [ + { + type: 'category', + label: 'Guides', + items: ['api/utility-apis'], + }, + { + type: 'category', + label: 'API Reference', + items: ['reference/index'], + }, + 'api/deprecations', + ], + Tutorials: [ + 'tutorials/quickstart-app-plugin', + 'tutorials/react-router-stable-migration', + 'tutorials/react18-migration', + 'tutorials/package-role-migration', + 'tutorials/migrating-away-from-core', + 'tutorials/configuring-plugin-databases', + 'tutorials/switching-sqlite-postgres', + 'tutorials/using-backstage-proxy-within-plugin', + 'tutorials/yarn-migration', + 'tutorials/migrate-to-mui5', + 'tutorials/auth-service-migration', + 'tutorials/enable-public-entry', + 'tutorials/setup-opentelemetry', + ], + 'Architecture Decision Records (ADRs)': [ + 'architecture-decisions/adrs-overview', + 'architecture-decisions/adrs-adr001', + 'architecture-decisions/adrs-adr002', + 'architecture-decisions/adrs-adr003', + 'architecture-decisions/adrs-adr004', + 'architecture-decisions/adrs-adr005', + 'architecture-decisions/adrs-adr006', + 'architecture-decisions/adrs-adr007', + 'architecture-decisions/adrs-adr008', + 'architecture-decisions/adrs-adr009', + 'architecture-decisions/adrs-adr010', + 'architecture-decisions/adrs-adr011', + 'architecture-decisions/adrs-adr012', + 'architecture-decisions/adrs-adr013', + ], + FAQ: ['faq/index', 'faq/product', 'faq/technical'], + Accessibility: ['accessibility/index'], + Contribute: [ + 'contribute/index', + 'contribute/getting-involved', + 'contribute/project-structure', + ], + References: ['references/glossary'], + }, + releases: { + 'Release Notes': releases.map(release => `releases/${release}`), + }, +}; diff --git a/microsite/sidebars.json b/microsite/sidebars.json deleted file mode 100644 index d134486024..0000000000 --- a/microsite/sidebars.json +++ /dev/null @@ -1,560 +0,0 @@ -{ - "docs": { - "Overview": [ - "overview/what-is-backstage", - "overview/architecture-overview", - "overview/roadmap", - "overview/vision", - "overview/background", - "overview/adopting", - "overview/versioning-policy", - "overview/threat-model", - "overview/support", - "overview/logos" - ], - "Getting Started": [ - "getting-started/index", - { - "type": "category", - "label": "Configuring Backstage", - "items": [ - "getting-started/config/database", - "getting-started/config/authentication", - "getting-started/configure-app-with-plugins", - "getting-started/app-custom-theme", - "getting-started/homepage" - ] - }, - { - "type": "category", - "label": "Using Backstage", - "items": [ - "getting-started/logging-in", - "getting-started/register-a-component", - "getting-started/create-a-component" - ] - }, - "getting-started/keeping-backstage-updated", - "getting-started/concepts" - ], - "Core Features": [ - { - "type": "category", - "label": "Software Catalog", - "items": [ - "features/software-catalog/software-catalog-overview", - "features/software-catalog/life-of-an-entity", - "features/software-catalog/configuration", - "features/software-catalog/system-model", - "features/software-catalog/descriptor-format", - "features/software-catalog/references", - "features/software-catalog/well-known-annotations", - "features/software-catalog/well-known-relations", - "features/software-catalog/well-known-statuses", - "features/software-catalog/extending-the-model", - "features/software-catalog/external-integrations", - "features/software-catalog/catalog-customization", - "features/software-catalog/software-catalog-api", - "features/software-catalog/creating-the-catalog-graph" - ] - }, - { - "type": "category", - "label": "Kubernetes", - "items": [ - "features/kubernetes/overview", - "features/kubernetes/installation", - "features/kubernetes/configuration", - "features/kubernetes/authentication", - "features/kubernetes/authentication-strategies", - "features/kubernetes/troubleshooting", - "features/kubernetes/proxy" - ] - }, - { - "type": "category", - "label": "Software Templates", - "items": [ - "features/software-templates/software-templates-index", - "features/software-templates/configuration", - "features/software-templates/adding-templates", - "features/software-templates/writing-templates", - "features/software-templates/input-examples", - "features/software-templates/builtin-actions", - "features/software-templates/writing-custom-actions", - "features/software-templates/writing-tests-for-actions", - "features/software-templates/writing-custom-field-extensions", - "features/software-templates/writing-custom-step-layouts", - "features/software-templates/authorizing-scaffolder-template-details", - "features/software-templates/migrating-to-rjsf-v5", - "features/software-templates/migrating-from-v1beta2-to-v1beta3", - "features/software-templates/dry-run-testing" - ] - }, - { - "type": "category", - "label": "Backstage Search", - "items": [ - "features/search/search-overview", - "features/search/getting-started", - "features/search/concepts", - "features/search/architecture", - "features/search/search-engines", - "features/search/collators", - "features/search/how-to-guides" - ] - }, - { - "type": "category", - "label": "TechDocs", - "items": [ - "features/techdocs/techdocs-overview", - "features/techdocs/getting-started", - "features/techdocs/concepts", - "features/techdocs/addons", - "features/techdocs/architecture", - "features/techdocs/creating-and-publishing", - "features/techdocs/configuration", - "features/techdocs/using-cloud-storage", - "features/techdocs/configuring-ci-cd", - "features/techdocs/cli", - "features/techdocs/how-to-guides", - "features/techdocs/troubleshooting", - "features/techdocs/faqs" - ] - } - ], - "Integrations": [ - "integrations/index", - { - "type": "category", - "label": "AWS S3", - "items": [ - "integrations/aws-s3/locations", - "integrations/aws-s3/discovery" - ] - }, - { - "type": "category", - "label": "Azure", - "items": [ - "integrations/azure/locations", - "integrations/azure/discovery", - "integrations/azure/org" - ] - }, - { - "type": "category", - "label": "Bitbucket Cloud", - "items": [ - "integrations/bitbucketCloud/locations", - "integrations/bitbucketCloud/discovery" - ] - }, - { - "type": "category", - "label": "Bitbucket Server", - "items": [ - "integrations/bitbucketServer/locations", - "integrations/bitbucketServer/discovery" - ] - }, - { - "type": "category", - "label": "Datadog", - "items": ["integrations/datadog-rum/installation"] - }, - { - "type": "category", - "label": "Gerrit", - "items": [ - "integrations/gerrit/locations", - "integrations/gerrit/discovery" - ] - }, - { - "type": "category", - "label": "GitHub", - "items": [ - "integrations/github/locations", - "integrations/github/discovery", - "integrations/github/org", - "integrations/github/github-apps" - ] - }, - { - "type": "category", - "label": "GitLab", - "items": [ - "integrations/gitlab/locations", - "integrations/gitlab/discovery", - "integrations/gitlab/org" - ] - }, - { - "type": "category", - "label": "Gitea", - "items": ["integrations/gitea/locations"] - }, - { - "type": "category", - "label": "Harness", - "items": ["integrations/harness/locations"] - }, - { - "type": "category", - "label": "Google GCS", - "items": ["integrations/google-cloud-storage/locations"] - }, - { - "type": "category", - "label": "LDAP", - "items": ["integrations/ldap/org"] - } - ], - "Plugins": [ - "plugins/index", - "plugins/existing-plugins", - "plugins/create-a-plugin", - "plugins/plugin-development", - "plugins/structure-of-a-plugin", - "plugins/integrating-plugin-into-software-catalog", - "plugins/integrating-search-into-plugins", - "plugins/composability", - "plugins/internationalization", - "plugins/analytics", - "plugins/feature-flags", - { - "type": "category", - "label": "OpenAPI", - "items": [ - "openapi/01-getting-started", - "openapi/generate-client", - "openapi/test-case-validation" - ] - }, - { - "type": "category", - "label": "Backends and APIs", - "items": [ - "plugins/proxying", - "plugins/backend-plugin", - "plugins/call-existing-api" - ] - }, - { - "type": "category", - "label": "Testing", - "items": ["plugins/testing"] - }, - { - "type": "category", - "label": "Publishing", - "items": [ - "plugins/publish-private", - "plugins/add-to-directory", - "plugins/observability" - ] - } - ], - "Configuration": [ - "conf/index", - "conf/reading", - "conf/writing", - "conf/defining" - ], - "Notifications": ["notifications/index"], - "Auth and identity": [ - "auth/index", - { - "type": "category", - "label": "Included providers", - "items": [ - "auth/auth0/provider", - "auth/atlassian/provider", - "auth/aws-alb/provider", - "auth/microsoft/provider", - "auth/microsoft/easy-auth", - "auth/bitbucket/provider", - "auth/bitbucketServer/provider", - "auth/cloudflare/provider", - "auth/github/provider", - "auth/gitlab/provider", - "auth/google/provider", - "auth/google/gcp-iap-auth", - "auth/guest/provider", - "auth/okta/provider", - "auth/oauth2-proxy/provider", - "auth/onelogin/provider", - "auth/vmware-cloud/provider" - ] - }, - "auth/identity-resolver", - "auth/oauth", - "auth/oidc", - "auth/add-auth-provider", - "auth/service-to-service-auth", - "auth/autologout", - "auth/troubleshooting" - ], - "Permissions": [ - "permissions/overview", - "permissions/concepts", - "permissions/getting-started", - "permissions/writing-a-policy", - "permissions/frontend-integration", - "permissions/custom-rules", - { - "type": "category", - "label": "Tutorial: using Permissions in your plugin", - "items": [ - "permissions/plugin-authors/01-setup", - "permissions/plugin-authors/02-adding-a-basic-permission-check", - "permissions/plugin-authors/03-adding-a-resource-permission-check", - "permissions/plugin-authors/04-authorizing-access-to-paginated-data", - "permissions/plugin-authors/05-frontend-authorization" - ] - } - ], - "Tooling": [ - { - "type": "category", - "label": "Backstage CLI", - "items": [ - "tooling/cli/overview", - "tooling/cli/build-system", - "tooling/cli/commands" - ] - }, - { - "type": "category", - "label": "Local Development", - "items": [ - "tooling/local-dev/linking-local-packages", - "tooling/local-dev/debugging", - "tooling/local-dev/profiling" - ] - }, - "tooling/package-metadata" - ], - "Deployment": [ - "deployment/index", - "deployment/scaling", - "deployment/docker", - "deployment/k8s", - "deployment/heroku", - "deployment/koyeb", - "deployment/flightcontrol", - { - "type": "category", - "label": "Using Backstage Deploy (alpha)", - "items": ["deployment/backstage-deploy/aws-lightsail"] - } - ], - "New Backend System": [ - "backend-system/index", - { - "type": "category", - "label": "Architecture", - "items": [ - "backend-system/architecture/index", - "backend-system/architecture/services", - "backend-system/architecture/plugins", - "backend-system/architecture/extension-points", - "backend-system/architecture/modules", - "backend-system/architecture/feature-loaders", - "backend-system/architecture/naming-patterns" - ] - }, - { - "type": "category", - "label": "Building Backends", - "items": [ - "backend-system/building-backends/index", - "backend-system/building-backends/migrating" - ] - }, - { - "type": "category", - "label": "Building Plugins & Modules", - "items": [ - "backend-system/building-plugins-and-modules/index", - "backend-system/building-plugins-and-modules/testing", - "backend-system/building-plugins-and-modules/migrating" - ] - }, - { - "type": "category", - "label": "Core Services", - "items": [ - "backend-system/core-services/index", - "backend-system/core-services/auth", - "backend-system/core-services/cache", - "backend-system/core-services/database", - "backend-system/core-services/discovery", - "backend-system/core-services/http-auth", - "backend-system/core-services/http-router", - "backend-system/core-services/identity", - "backend-system/core-services/lifecycle", - "backend-system/core-services/logger", - "backend-system/core-services/permissions", - "backend-system/core-services/plugin-metadata", - "backend-system/core-services/root-config", - "backend-system/core-services/root-health", - "backend-system/core-services/root-http-router", - "backend-system/core-services/root-lifecycle", - "backend-system/core-services/root-logger", - "backend-system/core-services/scheduler", - "backend-system/core-services/token-manager", - "backend-system/core-services/url-reader", - "backend-system/core-services/user-info" - ] - } - ], - "New Frontend System": [ - "frontend-system/index", - { - "type": "category", - "label": "Architecture", - "items": [ - "frontend-system/architecture/index", - "frontend-system/architecture/app", - "frontend-system/architecture/plugins", - "frontend-system/architecture/extensions", - "frontend-system/architecture/extension-blueprints", - "frontend-system/architecture/extension-overrides", - "frontend-system/architecture/references", - "frontend-system/architecture/utility-apis", - "frontend-system/architecture/routes", - "frontend-system/architecture/naming-patterns", - "frontend-system/architecture/migrations" - ] - }, - { - "type": "category", - "label": "Building Plugins", - "items": [ - "frontend-system/building-plugins/index", - "frontend-system/building-plugins/testing", - "frontend-system/building-plugins/common-extension-blueprints", - "frontend-system/building-plugins/built-in-data-refs", - "frontend-system/building-plugins/migrating" - ] - }, - { - "type": "category", - "label": "Building Apps", - "items": [ - "frontend-system/building-apps/index", - "frontend-system/building-apps/configuring-extensions", - "frontend-system/building-apps/built-in-extensions", - "frontend-system/building-apps/plugin-conversion", - "frontend-system/building-apps/migrating" - ] - }, - { - "type": "category", - "label": "Utility APIs", - "items": [ - "frontend-system/utility-apis/index", - "frontend-system/utility-apis/creating", - "frontend-system/utility-apis/consuming", - "frontend-system/utility-apis/configuring" - ] - } - ], - "Designing for Backstage": [ - "dls/design", - "dls/component-design-guidelines", - "dls/contributing-to-storybook", - "dls/figma" - ], - "API Reference": [ - { - "type": "category", - "label": "Guides", - "items": ["api/utility-apis"] - }, - { - "type": "category", - "label": "API Reference", - "items": ["reference/index"] - }, - "api/deprecations" - ], - "Tutorials": [ - "tutorials/quickstart-app-plugin", - "tutorials/react-router-stable-migration", - "tutorials/react18-migration", - "tutorials/package-role-migration", - "tutorials/migrating-away-from-core", - "tutorials/configuring-plugin-databases", - "tutorials/switching-sqlite-postgres", - "tutorials/using-backstage-proxy-within-plugin", - "tutorials/yarn-migration", - "tutorials/migrate-to-mui5", - "tutorials/auth-service-migration", - "tutorials/enable-public-entry", - "tutorials/setup-opentelemetry" - ], - "Architecture Decision Records (ADRs)": [ - "architecture-decisions/adrs-overview", - "architecture-decisions/adrs-adr001", - "architecture-decisions/adrs-adr002", - "architecture-decisions/adrs-adr003", - "architecture-decisions/adrs-adr004", - "architecture-decisions/adrs-adr005", - "architecture-decisions/adrs-adr006", - "architecture-decisions/adrs-adr007", - "architecture-decisions/adrs-adr008", - "architecture-decisions/adrs-adr009", - "architecture-decisions/adrs-adr010", - "architecture-decisions/adrs-adr011", - "architecture-decisions/adrs-adr012", - "architecture-decisions/adrs-adr013" - ], - "FAQ": ["faq/index", "faq/product", "faq/technical"], - "Accessibility": ["accessibility/index"], - "Contribute": [ - "contribute/index", - "contribute/getting-involved", - "contribute/project-structure" - ], - "References": ["references/glossary"] - }, - "releases": { - "Release Notes": [ - "releases/v1.30.0", - "releases/v1.29.0", - "releases/v1.28.0", - "releases/v1.27.0", - "releases/v1.26.0", - "releases/v1.25.0", - "releases/v1.24.0", - "releases/v1.23.0", - "releases/v1.22.0", - "releases/v1.21.0", - "releases/v1.20.0", - "releases/v1.19.0", - "releases/v1.18.0", - "releases/v1.17.0", - "releases/v1.16.0", - "releases/v1.15.0", - "releases/v1.14.0", - "releases/v1.13.0", - "releases/v1.12.0", - "releases/v1.11.0", - "releases/v1.10.0", - "releases/v1.9.0", - "releases/v1.8.0", - "releases/v1.7.0", - "releases/v1.6.0", - "releases/v1.5.0", - "releases/v1.4.0", - "releases/v1.3.0", - "releases/v1.2.0", - "releases/v1.1.0", - "releases/v1.0.0" - ] - } -} diff --git a/microsite/tsconfig.json b/microsite/tsconfig.json index 71bc403643..9a5106747e 100644 --- a/microsite/tsconfig.json +++ b/microsite/tsconfig.json @@ -2,6 +2,7 @@ "extends": "@docusaurus/tsconfig", "compilerOptions": { "baseUrl": ".", + "allowJs": true, "types": [ "node", "@docusaurus/module-type-aliases", diff --git a/microsite/yarn.lock b/microsite/yarn.lock index d8f8ccc44f..13c7575934 100644 --- a/microsite/yarn.lock +++ b/microsite/yarn.lock @@ -2715,92 +2715,92 @@ __metadata: languageName: node linkType: hard -"@swc/core-darwin-arm64@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-darwin-arm64@npm:1.5.29" +"@swc/core-darwin-arm64@npm:1.7.26": + version: 1.7.26 + resolution: "@swc/core-darwin-arm64@npm:1.7.26" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@swc/core-darwin-x64@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-darwin-x64@npm:1.5.29" +"@swc/core-darwin-x64@npm:1.7.26": + version: 1.7.26 + resolution: "@swc/core-darwin-x64@npm:1.7.26" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@swc/core-linux-arm-gnueabihf@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-linux-arm-gnueabihf@npm:1.5.29" +"@swc/core-linux-arm-gnueabihf@npm:1.7.26": + version: 1.7.26 + resolution: "@swc/core-linux-arm-gnueabihf@npm:1.7.26" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@swc/core-linux-arm64-gnu@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-linux-arm64-gnu@npm:1.5.29" +"@swc/core-linux-arm64-gnu@npm:1.7.26": + version: 1.7.26 + resolution: "@swc/core-linux-arm64-gnu@npm:1.7.26" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-arm64-musl@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-linux-arm64-musl@npm:1.5.29" +"@swc/core-linux-arm64-musl@npm:1.7.26": + version: 1.7.26 + resolution: "@swc/core-linux-arm64-musl@npm:1.7.26" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@swc/core-linux-x64-gnu@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-linux-x64-gnu@npm:1.5.29" +"@swc/core-linux-x64-gnu@npm:1.7.26": + version: 1.7.26 + resolution: "@swc/core-linux-x64-gnu@npm:1.7.26" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-x64-musl@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-linux-x64-musl@npm:1.5.29" +"@swc/core-linux-x64-musl@npm:1.7.26": + version: 1.7.26 + resolution: "@swc/core-linux-x64-musl@npm:1.7.26" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@swc/core-win32-arm64-msvc@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-win32-arm64-msvc@npm:1.5.29" +"@swc/core-win32-arm64-msvc@npm:1.7.26": + version: 1.7.26 + resolution: "@swc/core-win32-arm64-msvc@npm:1.7.26" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@swc/core-win32-ia32-msvc@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-win32-ia32-msvc@npm:1.5.29" +"@swc/core-win32-ia32-msvc@npm:1.7.26": + version: 1.7.26 + resolution: "@swc/core-win32-ia32-msvc@npm:1.7.26" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@swc/core-win32-x64-msvc@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-win32-x64-msvc@npm:1.5.29" +"@swc/core-win32-x64-msvc@npm:1.7.26": + version: 1.7.26 + resolution: "@swc/core-win32-x64-msvc@npm:1.7.26" conditions: os=win32 & cpu=x64 languageName: node linkType: hard "@swc/core@npm:^1.3.46": - version: 1.5.29 - resolution: "@swc/core@npm:1.5.29" + version: 1.7.26 + resolution: "@swc/core@npm:1.7.26" dependencies: - "@swc/core-darwin-arm64": 1.5.29 - "@swc/core-darwin-x64": 1.5.29 - "@swc/core-linux-arm-gnueabihf": 1.5.29 - "@swc/core-linux-arm64-gnu": 1.5.29 - "@swc/core-linux-arm64-musl": 1.5.29 - "@swc/core-linux-x64-gnu": 1.5.29 - "@swc/core-linux-x64-musl": 1.5.29 - "@swc/core-win32-arm64-msvc": 1.5.29 - "@swc/core-win32-ia32-msvc": 1.5.29 - "@swc/core-win32-x64-msvc": 1.5.29 + "@swc/core-darwin-arm64": 1.7.26 + "@swc/core-darwin-x64": 1.7.26 + "@swc/core-linux-arm-gnueabihf": 1.7.26 + "@swc/core-linux-arm64-gnu": 1.7.26 + "@swc/core-linux-arm64-musl": 1.7.26 + "@swc/core-linux-x64-gnu": 1.7.26 + "@swc/core-linux-x64-musl": 1.7.26 + "@swc/core-win32-arm64-msvc": 1.7.26 + "@swc/core-win32-ia32-msvc": 1.7.26 + "@swc/core-win32-x64-msvc": 1.7.26 "@swc/counter": ^0.1.3 - "@swc/types": ^0.1.8 + "@swc/types": ^0.1.12 peerDependencies: "@swc/helpers": "*" dependenciesMeta: @@ -2827,7 +2827,7 @@ __metadata: peerDependenciesMeta: "@swc/helpers": optional: true - checksum: 19e3f8525ce4f4d9f6f3f62825b1f13e1e76146390930b6d5e663c0bb2c5e95ef3bf30268110d1444ea92b99dd95bfe5a3c6e2a3c0dd79291505dc7da1ed3dab + checksum: 8249f2af001f2b5b312ccace4e3a8575bf286bb0f67f029eb58ef8b144f73e37f766800859161ef87c0993e586055238c000ab17dddf9d3760edcfa63ffd22e6 languageName: node linkType: hard @@ -2838,12 +2838,12 @@ __metadata: languageName: node linkType: hard -"@swc/types@npm:^0.1.8": - version: 0.1.8 - resolution: "@swc/types@npm:0.1.8" +"@swc/types@npm:^0.1.12": + version: 0.1.12 + resolution: "@swc/types@npm:0.1.12" dependencies: "@swc/counter": ^0.1.3 - checksum: e564d0e37b0e28546973c6d50c7a179395912a97168d695cfe9cf1051199c8b828680cdafcb8d43948f76d3703873bafb88dfb5bc2dfe0596b4ad18fcaf90c80 + checksum: cf7f89e46f859864075d7965582baea9c5f98830f45b1046251568c9bdf1ca484b1bf37f6d3c32b7c82ecf8cd5df89d22f05268c391819c44e49911bb1a8e71a languageName: node linkType: hard @@ -3949,9 +3949,9 @@ __metadata: languageName: node linkType: hard -"body-parser@npm:1.20.2": - version: 1.20.2 - resolution: "body-parser@npm:1.20.2" +"body-parser@npm:1.20.3": + version: 1.20.3 + resolution: "body-parser@npm:1.20.3" dependencies: bytes: 3.1.2 content-type: ~1.0.5 @@ -3961,11 +3961,11 @@ __metadata: http-errors: 2.0.0 iconv-lite: 0.4.24 on-finished: 2.4.1 - qs: 6.11.0 + qs: 6.13.0 raw-body: 2.5.2 type-is: ~1.6.18 unpipe: 1.0.0 - checksum: 14d37ec638ab5c93f6099ecaed7f28f890d222c650c69306872e00b9efa081ff6c596cd9afb9930656aae4d6c4e1c17537bea12bb73c87a217cb3cfea8896737 + checksum: 1a35c59a6be8d852b00946330141c4f142c6af0f970faa87f10ad74f1ee7118078056706a05ae3093c54dabca9cd3770fa62a170a85801da1a4324f04381167d languageName: node linkType: hard @@ -4131,13 +4131,16 @@ __metadata: languageName: node linkType: hard -"call-bind@npm:^1.0.0, call-bind@npm:^1.0.2": - version: 1.0.2 - resolution: "call-bind@npm:1.0.2" +"call-bind@npm:^1.0.2, call-bind@npm:^1.0.7": + version: 1.0.7 + resolution: "call-bind@npm:1.0.7" dependencies: - function-bind: ^1.1.1 - get-intrinsic: ^1.0.2 - checksum: f8e31de9d19988a4b80f3e704788c4a2d6b6f3d17cfec4f57dc29ced450c53a49270dc66bf0fbd693329ee948dd33e6c90a329519aef17474a4d961e8d6426b0 + es-define-property: ^1.0.0 + es-errors: ^1.3.0 + function-bind: ^1.1.2 + get-intrinsic: ^1.2.4 + set-function-length: ^1.2.1 + checksum: 295c0c62b90dd6522e6db3b0ab1ce26bdf9e7404215bda13cfee25b626b5ff1a7761324d58d38b1ef1607fc65aca2d06e44d2e18d0dfc6c14b465b00d8660029 languageName: node linkType: hard @@ -4290,7 +4293,7 @@ __metadata: languageName: node linkType: hard -"chokidar@npm:>=3.0.0 <4.0.0, chokidar@npm:^3.4.2, chokidar@npm:^3.5.3": +"chokidar@npm:^3.4.2, chokidar@npm:^3.5.3": version: 3.5.3 resolution: "chokidar@npm:3.5.3" dependencies: @@ -4309,6 +4312,15 @@ __metadata: languageName: node linkType: hard +"chokidar@npm:^4.0.0": + version: 4.0.0 + resolution: "chokidar@npm:4.0.0" + dependencies: + readdirp: ^4.0.1 + checksum: f528f5cf22135fcdbe2ee44a89de3ebff4f94db7e101c55e5d92169bd4b52ce5b97d3ee0b74fe4fb57a065d2f2efce82f8bc687751e56b0a1870e9fe201b1c99 + languageName: node + linkType: hard + "chownr@npm:^2.0.0": version: 2.0.0 resolution: "chownr@npm:2.0.0" @@ -5005,6 +5017,17 @@ __metadata: languageName: node linkType: hard +"define-data-property@npm:^1.1.4": + version: 1.1.4 + resolution: "define-data-property@npm:1.1.4" + dependencies: + es-define-property: ^1.0.0 + es-errors: ^1.3.0 + gopd: ^1.0.1 + checksum: 8068ee6cab694d409ac25936eb861eea704b7763f7f342adbdfe337fc27c78d7ae0eff2364b2917b58c508d723c7a074326d068eef2e45c4edcd85cf94d0313b + languageName: node + linkType: hard + "define-lazy-prop@npm:^2.0.0": version: 2.0.0 resolution: "define-lazy-prop@npm:2.0.0" @@ -5328,6 +5351,13 @@ __metadata: languageName: node linkType: hard +"encodeurl@npm:~2.0.0": + version: 2.0.0 + resolution: "encodeurl@npm:2.0.0" + checksum: abf5cd51b78082cf8af7be6785813c33b6df2068ce5191a40ca8b1afe6a86f9230af9a9ce694a5ce4665955e5c1120871826df9c128a642e09c58d592e2807fe + languageName: node + linkType: hard + "encoding@npm:^0.1.13": version: 0.1.13 resolution: "encoding@npm:0.1.13" @@ -5384,6 +5414,22 @@ __metadata: languageName: node linkType: hard +"es-define-property@npm:^1.0.0": + version: 1.0.0 + resolution: "es-define-property@npm:1.0.0" + dependencies: + get-intrinsic: ^1.2.4 + checksum: f66ece0a887b6dca71848fa71f70461357c0e4e7249696f81bad0a1f347eed7b31262af4a29f5d726dc026426f085483b6b90301855e647aa8e21936f07293c6 + languageName: node + linkType: hard + +"es-errors@npm:^1.3.0": + version: 1.3.0 + resolution: "es-errors@npm:1.3.0" + checksum: ec1414527a0ccacd7f15f4a3bc66e215f04f595ba23ca75cdae0927af099b5ec865f9f4d33e9d7e86f512f252876ac77d4281a7871531a50678132429b1271b5 + languageName: node + linkType: hard + "es-module-lexer@npm:^1.2.1": version: 1.2.1 resolution: "es-module-lexer@npm:1.2.1" @@ -5607,41 +5653,41 @@ __metadata: linkType: hard "express@npm:^4.17.3": - version: 4.19.2 - resolution: "express@npm:4.19.2" + version: 4.21.0 + resolution: "express@npm:4.21.0" dependencies: accepts: ~1.3.8 array-flatten: 1.1.1 - body-parser: 1.20.2 + body-parser: 1.20.3 content-disposition: 0.5.4 content-type: ~1.0.4 cookie: 0.6.0 cookie-signature: 1.0.6 debug: 2.6.9 depd: 2.0.0 - encodeurl: ~1.0.2 + encodeurl: ~2.0.0 escape-html: ~1.0.3 etag: ~1.8.1 - finalhandler: 1.2.0 + finalhandler: 1.3.1 fresh: 0.5.2 http-errors: 2.0.0 - merge-descriptors: 1.0.1 + merge-descriptors: 1.0.3 methods: ~1.1.2 on-finished: 2.4.1 parseurl: ~1.3.3 - path-to-regexp: 0.1.7 + path-to-regexp: 0.1.10 proxy-addr: ~2.0.7 - qs: 6.11.0 + qs: 6.13.0 range-parser: ~1.2.1 safe-buffer: 5.2.1 - send: 0.18.0 - serve-static: 1.15.0 + send: 0.19.0 + serve-static: 1.16.2 setprototypeof: 1.2.0 statuses: 2.0.1 type-is: ~1.6.18 utils-merge: 1.0.1 vary: ~1.1.2 - checksum: 212dbd6c2c222a96a61bc927639c95970a53b06257080bb9e2838adb3bffdb966856551fdad1ab5dd654a217c35db94f987d0aa88d48fb04d306340f5f34dca5 + checksum: 1c5212993f665809c249bf00ab550b989d1365a5b9171cdfaa26d93ee2ef10cd8add520861ec8d5da74b3194d8374e1d9d53e85ef69b89fd9c4196b87045a5d4 languageName: node linkType: hard @@ -5768,18 +5814,18 @@ __metadata: languageName: node linkType: hard -"finalhandler@npm:1.2.0": - version: 1.2.0 - resolution: "finalhandler@npm:1.2.0" +"finalhandler@npm:1.3.1": + version: 1.3.1 + resolution: "finalhandler@npm:1.3.1" dependencies: debug: 2.6.9 - encodeurl: ~1.0.2 + encodeurl: ~2.0.0 escape-html: ~1.0.3 on-finished: 2.4.1 parseurl: ~1.3.3 statuses: 2.0.1 unpipe: ~1.0.0 - checksum: 92effbfd32e22a7dff2994acedbd9bcc3aa646a3e919ea6a53238090e87097f8ef07cced90aa2cc421abdf993aefbdd5b00104d55c7c5479a8d00ed105b45716 + checksum: a8c58cd97c9cd47679a870f6833a7b417043f5a288cd6af6d0f49b476c874a506100303a128b6d3b654c3d74fa4ff2ffed68a48a27e8630cda5c918f2977dcf4 languageName: node linkType: hard @@ -5963,10 +6009,10 @@ __metadata: languageName: node linkType: hard -"function-bind@npm:^1.1.1": - version: 1.1.1 - resolution: "function-bind@npm:1.1.1" - checksum: b32fbaebb3f8ec4969f033073b43f5c8befbb58f1a79e12f1d7490358150359ebd92f49e72ff0144f65f2c48ea2a605bff2d07965f548f6474fd8efd95bf361a +"function-bind@npm:^1.1.1, function-bind@npm:^1.1.2": + version: 1.1.2 + resolution: "function-bind@npm:1.1.2" + checksum: 2b0ff4ce708d99715ad14a6d1f894e2a83242e4a52ccfcefaee5e40050562e5f6dafc1adbb4ce2d4ab47279a45dc736ab91ea5042d843c3c092820dfe032efb1 languageName: node linkType: hard @@ -5993,14 +6039,16 @@ __metadata: languageName: node linkType: hard -"get-intrinsic@npm:^1.0.2, get-intrinsic@npm:^1.1.1": - version: 1.1.3 - resolution: "get-intrinsic@npm:1.1.3" +"get-intrinsic@npm:^1.1.3, get-intrinsic@npm:^1.2.4": + version: 1.2.4 + resolution: "get-intrinsic@npm:1.2.4" dependencies: - function-bind: ^1.1.1 - has: ^1.0.3 + es-errors: ^1.3.0 + function-bind: ^1.1.2 + has-proto: ^1.0.1 has-symbols: ^1.0.3 - checksum: 152d79e87251d536cf880ba75cfc3d6c6c50e12b3a64e1ea960e73a3752b47c69f46034456eae1b0894359ce3bc64c55c186f2811f8a788b75b638b06fab228a + hasown: ^2.0.0 + checksum: 414e3cdf2c203d1b9d7d33111df746a4512a1aa622770b361dadddf8ed0b5aeb26c560f49ca077e24bfafb0acb55ca908d1f709216ccba33ffc548ec8a79a951 languageName: node linkType: hard @@ -6140,6 +6188,15 @@ __metadata: languageName: node linkType: hard +"gopd@npm:^1.0.1": + version: 1.0.1 + resolution: "gopd@npm:1.0.1" + dependencies: + get-intrinsic: ^1.1.3 + checksum: a5ccfb8806e0917a94e0b3de2af2ea4979c1da920bc381667c260e00e7cafdbe844e2cb9c5bcfef4e5412e8bf73bab837285bc35c7ba73aaaf0134d4583393a6 + languageName: node + linkType: hard + "got@npm:^12.1.0": version: 12.6.0 resolution: "got@npm:12.6.0" @@ -6208,12 +6265,19 @@ __metadata: languageName: node linkType: hard -"has-property-descriptors@npm:^1.0.0": - version: 1.0.0 - resolution: "has-property-descriptors@npm:1.0.0" +"has-property-descriptors@npm:^1.0.0, has-property-descriptors@npm:^1.0.2": + version: 1.0.2 + resolution: "has-property-descriptors@npm:1.0.2" dependencies: - get-intrinsic: ^1.1.1 - checksum: a6d3f0a266d0294d972e354782e872e2fe1b6495b321e6ef678c9b7a06a40408a6891817350c62e752adced73a94ac903c54734fee05bf65b1905ee1368194bb + es-define-property: ^1.0.0 + checksum: fcbb246ea2838058be39887935231c6d5788babed499d0e9d0cc5737494c48aba4fe17ba1449e0d0fbbb1e36175442faa37f9c427ae357d6ccb1d895fbcd3de3 + languageName: node + linkType: hard + +"has-proto@npm:^1.0.1": + version: 1.0.3 + resolution: "has-proto@npm:1.0.3" + checksum: fe7c3d50b33f50f3933a04413ed1f69441d21d2d2944f81036276d30635cad9279f6b43bc8f32036c31ebdfcf6e731150f46c1907ad90c669ffe9b066c3ba5c4 languageName: node linkType: hard @@ -6247,6 +6311,15 @@ __metadata: languageName: node linkType: hard +"hasown@npm:^2.0.0": + version: 2.0.2 + resolution: "hasown@npm:2.0.2" + dependencies: + function-bind: ^1.1.2 + checksum: e8516f776a15149ca6c6ed2ae3110c417a00b62260e222590e54aa367cbcd6ed99122020b37b7fbdf05748df57b265e70095d7bf35a47660587619b15ffb93db + languageName: node + linkType: hard + "hast-util-from-parse5@npm:^8.0.0": version: 8.0.1 resolution: "hast-util-from-parse5@npm:8.0.1" @@ -7843,10 +7916,10 @@ __metadata: languageName: node linkType: hard -"merge-descriptors@npm:1.0.1": - version: 1.0.1 - resolution: "merge-descriptors@npm:1.0.1" - checksum: 5abc259d2ae25bb06d19ce2b94a21632583c74e2a9109ee1ba7fd147aa7362b380d971e0251069f8b3eb7d48c21ac839e21fa177b335e82c76ec172e30c31a26 +"merge-descriptors@npm:1.0.3": + version: 1.0.3 + resolution: "merge-descriptors@npm:1.0.3" + checksum: 52117adbe0313d5defa771c9993fe081e2d2df9b840597e966aadafde04ae8d0e3da46bac7ca4efc37d4d2b839436582659cd49c6a43eacb3fe3050896a105d1 languageName: node linkType: hard @@ -8765,10 +8838,10 @@ __metadata: languageName: node linkType: hard -"object-inspect@npm:^1.9.0": - version: 1.12.2 - resolution: "object-inspect@npm:1.12.2" - checksum: a534fc1b8534284ed71f25ce3a496013b7ea030f3d1b77118f6b7b1713829262be9e6243acbcb3ef8c626e2b64186112cb7f6db74e37b2789b9c789ca23048b2 +"object-inspect@npm:^1.13.1": + version: 1.13.2 + resolution: "object-inspect@npm:1.13.2" + checksum: 9f850b3c045db60e0e97746e809ee4090d6ce62195af17dd1e9438ac761394a7d8ec4f7906559aea5424eaf61e35d3e53feded2ccd5f62fcc7d9670d3c8eb353 languageName: node linkType: hard @@ -9090,10 +9163,10 @@ __metadata: languageName: node linkType: hard -"path-to-regexp@npm:0.1.7": - version: 0.1.7 - resolution: "path-to-regexp@npm:0.1.7" - checksum: 69a14ea24db543e8b0f4353305c5eac6907917031340e5a8b37df688e52accd09e3cebfe1660b70d76b6bd89152f52183f28c74813dbf454ba1a01c82a38abce +"path-to-regexp@npm:0.1.10": + version: 0.1.10 + resolution: "path-to-regexp@npm:0.1.10" + checksum: ab7a3b7a0b914476d44030340b0a65d69851af2a0f33427df1476100ccb87d409c39e2182837a96b98fb38c4ef2ba6b87bdad62bb70a2c153876b8061760583c languageName: node linkType: hard @@ -9634,14 +9707,14 @@ __metadata: linkType: hard "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" + version: 2.4.0 + resolution: "prism-react-renderer@npm:2.4.0" dependencies: "@types/prismjs": ^1.26.0 clsx: ^2.0.0 peerDependencies: react: ">=16.0.0" - checksum: b12a7d502c1e764d94f7d3c84aee9cd6fccc676bb7e21dee94d37eb2e7e62e097a343999e1979887cb83a57cbdea48d2046aa74d07bce05caa25f4c296df30b6 + checksum: d15d944a8cbf05f7b04deecd2cf4ffb08229a6027918641b6f046cd8ab24b65ca4ebe4ac8e95a53a7d7cefb1bba8df3ce394fe4f1d75418e34fa92553dc63ef7 languageName: node linkType: hard @@ -9744,12 +9817,12 @@ __metadata: languageName: node linkType: hard -"qs@npm:6.11.0": - version: 6.11.0 - resolution: "qs@npm:6.11.0" +"qs@npm:6.13.0": + version: 6.13.0 + resolution: "qs@npm:6.13.0" dependencies: - side-channel: ^1.0.4 - checksum: 6e1f29dd5385f7488ec74ac7b6c92f4d09a90408882d0c208414a34dd33badc1a621019d4c799a3df15ab9b1d0292f97c1dd71dc7c045e69f81a8064e5af7297 + side-channel: ^1.0.6 + checksum: e9404dc0fc2849245107108ce9ec2766cde3be1b271de0bf1021d049dc5b98d1a2901e67b431ac5509f865420a7ed80b7acb3980099fe1c118a1c5d2e1432ad8 languageName: node linkType: hard @@ -10021,6 +10094,13 @@ __metadata: languageName: node linkType: hard +"readdirp@npm:^4.0.1": + version: 4.0.1 + resolution: "readdirp@npm:4.0.1" + checksum: b39747defe52922c2478874ffbb1fd0bececa7b3170466a5bc770795dd5296a309598990cbd809732079b2363e989d0008b8e91cfbac7b726f68c1947db2d31c + languageName: node + linkType: hard + "readdirp@npm:~3.6.0": version: 3.6.0 resolution: "readdirp@npm:3.6.0" @@ -10444,15 +10524,15 @@ __metadata: linkType: hard "sass@npm:^1.57.1": - version: 1.77.8 - resolution: "sass@npm:1.77.8" + version: 1.79.1 + resolution: "sass@npm:1.79.1" dependencies: - chokidar: ">=3.0.0 <4.0.0" + chokidar: ^4.0.0 immutable: ^4.0.0 source-map-js: ">=0.6.2 <2.0.0" bin: sass: sass.js - checksum: 6b5dce17faa1bd1e349b4825bf7f76559a32f3f95d789cd2847623c88ee9635e1485d3458532a05fa5b9134cfbce79a4bad3f13dc63c2433632347674db0abae + checksum: df014f287055c750349b7461ed8477662c7f9c8999cc1b10eb9096ccd4a67f850511e8828ba8780515513741a932d01b1948bd33d40cdac1403a13b6718fa14c languageName: node linkType: hard @@ -10561,9 +10641,9 @@ __metadata: languageName: node linkType: hard -"send@npm:0.18.0": - version: 0.18.0 - resolution: "send@npm:0.18.0" +"send@npm:0.19.0": + version: 0.19.0 + resolution: "send@npm:0.19.0" dependencies: debug: 2.6.9 depd: 2.0.0 @@ -10578,7 +10658,7 @@ __metadata: on-finished: 2.4.1 range-parser: ~1.2.1 statuses: 2.0.1 - checksum: 74fc07ebb58566b87b078ec63e5a3e41ecd987e4272ba67b7467e86c6ad51bc6b0b0154133b6d8b08a2ddda360464f71382f7ef864700f34844a76c8027817a8 + checksum: 5ae11bd900c1c2575525e2aa622e856804e2f96a09281ec1e39610d089f53aa69e13fd8db84b52f001d0318cf4bb0b3b904ad532fc4c0014eb90d32db0cff55f languageName: node linkType: hard @@ -10622,15 +10702,15 @@ __metadata: languageName: node linkType: hard -"serve-static@npm:1.15.0": - version: 1.15.0 - resolution: "serve-static@npm:1.15.0" +"serve-static@npm:1.16.2": + version: 1.16.2 + resolution: "serve-static@npm:1.16.2" dependencies: - encodeurl: ~1.0.2 + encodeurl: ~2.0.0 escape-html: ~1.0.3 parseurl: ~1.3.3 - send: 0.18.0 - checksum: af57fc13be40d90a12562e98c0b7855cf6e8bd4c107fe9a45c212bf023058d54a1871b1c89511c3958f70626fff47faeb795f5d83f8cf88514dbaeb2b724464d + send: 0.19.0 + checksum: dffc52feb4cc5c68e66d0c7f3c1824d4e989f71050aefc9bd5f822a42c54c9b814f595fc5f2b717f4c7cc05396145f3e90422af31186a93f76cf15f707019759 languageName: node linkType: hard @@ -10641,6 +10721,20 @@ __metadata: languageName: node linkType: hard +"set-function-length@npm:^1.2.1": + version: 1.2.2 + resolution: "set-function-length@npm:1.2.2" + dependencies: + define-data-property: ^1.1.4 + es-errors: ^1.3.0 + function-bind: ^1.1.2 + get-intrinsic: ^1.2.4 + gopd: ^1.0.1 + has-property-descriptors: ^1.0.2 + checksum: a8248bdacdf84cb0fab4637774d9fb3c7a8e6089866d04c817583ff48e14149c87044ce683d7f50759a8c50fb87c7a7e173535b06169c87ef76f5fb276dfff72 + languageName: node + linkType: hard + "setprototypeof@npm:1.1.0": version: 1.1.0 resolution: "setprototypeof@npm:1.1.0" @@ -10707,14 +10801,15 @@ __metadata: languageName: node linkType: hard -"side-channel@npm:^1.0.4": - version: 1.0.4 - resolution: "side-channel@npm:1.0.4" +"side-channel@npm:^1.0.6": + version: 1.0.6 + resolution: "side-channel@npm:1.0.6" dependencies: - call-bind: ^1.0.0 - get-intrinsic: ^1.0.2 - object-inspect: ^1.9.0 - checksum: 351e41b947079c10bd0858364f32bb3a7379514c399edb64ab3dce683933483fc63fb5e4efe0a15a2e8a7e3c436b6a91736ddb8d8c6591b0460a24bb4a1ee245 + call-bind: ^1.0.7 + es-errors: ^1.3.0 + get-intrinsic: ^1.2.4 + object-inspect: ^1.13.1 + checksum: bfc1afc1827d712271453e91b7cd3878ac0efd767495fd4e594c4c2afaa7963b7b510e249572bfd54b0527e66e4a12b61b80c061389e129755f34c493aad9b97 languageName: node linkType: hard diff --git a/mkdocs.yml b/mkdocs.yml index 4d4d039756..aa545111d4 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -6,7 +6,7 @@ edit_uri: edit/master/docs plugins: - techdocs-core -# For sidebar navigation on https://backstage.io/, see `microsite/sidebars.json` +# For sidebar navigation on https://backstage.io/, see `microsite/sidebars.js` nav: - Overview: - What is Backstage?: 'overview/what-is-backstage.md' @@ -48,6 +48,7 @@ nav: - External integrations: 'features/software-catalog/external-integrations.md' - Catalog Customization: 'features/software-catalog/catalog-customization.md' - API: 'features/software-catalog/api.md' + - FAQ: 'features/software-catalog/faq.md' - Kubernetes: - Overview: 'features/kubernetes/index.md' - Installation: 'features/kubernetes/installation.md' @@ -84,6 +85,7 @@ nav: - Configuring CI/CD to generate and publish TechDocs sites: 'features/techdocs/configuring-ci-cd.md' - CLI: 'features/techdocs/cli.md' - HOW TO guides: 'features/techdocs/how-to-guides.md' + - Extensions: 'features/techdocs/extensions.md' - Troubleshooting: 'features/techdocs/troubleshooting.md' - FAQ: 'features/techdocs/FAQ.md' - Integrations: diff --git a/package.json b/package.json index 4028f7bacd..425b1c1a38 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "root", - "version": "1.31.0-next.1", + "version": "1.32.0-next.1", "private": true, "repository": { "type": "git", @@ -17,7 +17,7 @@ "build:all": "backstage-cli repo build --all", "build:api-docs": "LANG=en_EN yarn build:api-reports --docs --exclude 'plugins/@(adr|adr-backend|adr-common|airbrake|airbrake-backend|allure|analytics-module-ga|analytics-module-ga4|analytics-module-newrelic-browser|apache-airflow|api-docs|api-docs-module-protoc-gen-doc|apollo-explorer|app-visualizer|azure-devops|azure-devops-backend|azure-devops-common|azure-sites|azure-sites-backend|azure-sites-common|badges|badges-backend|bazaar|bazaar-backend|bitbucket-cloud-common|bitrise|catalog-graph|catalog-graphql|catalog-import|catalog-unprocessed-entities|cicd-statistics|cicd-statistics-module-gitlab|circleci|cloudbuild|code-climate|code-coverage|code-coverage-backend|codescene|config-schema|cost-insights|cost-insights-common|dynatrace|entity-feedback|entity-feedback-backend|entity-feedback-common|entity-validation|example-todo-list|example-todo-list-backend|example-todo-list-common|firehydrant|fossa|gcalendar|gcp-projects|git-release-manager|github-actions|github-deployments|github-issues|github-pull-requests-board|gitops-profiles|gocd|graphiql|graphql-backend|graphql-voyager|ilert|jenkins|jenkins-backend|jenkins-common|kafka|kafka-backend|lighthouse|lighthouse-backend|lighthouse-common|linguist|linguist-backend|linguist-common|microsoft-calendar|newrelic|newrelic-dashboard|nomad|nomad-backend|octopus-deploy|opencost|pagerduty|periskop|periskop-backend|playlist|playlist-backend|playlist-common|proxy-backend|puppetdb|rollbar|rollbar-backend|sentry|shortcuts|splunk-on-call|stack-overflow|stack-overflow-backend|stackstorm|tech-radar|tech-radar-2|todo|todo-backend|xcmetrics)'", "build:api-reports": "yarn build:api-reports:only --tsc", - "build:api-reports:only": "NODE_OPTIONS=--max-old-space-size=8192 backstage-repo-tools api-reports --allow-warnings 'packages/backend-app-api,packages/backend-common,packages/core-components,plugins/+(catalog|catalog-import|git-release-manager|jenkins|kubernetes)' -o ae-wrong-input-file-type --validate-release-tags", + "build:api-reports:only": "NODE_OPTIONS=--max-old-space-size=8192 backstage-repo-tools api-reports --allow-warnings 'packages/backend-app-api,packages/core-components,plugins/+(catalog|catalog-import|git-release-manager|jenkins|kubernetes)' -o ae-wrong-input-file-type --validate-release-tags", "build:backend": "yarn workspace example-backend build", "build:knip-reports": "backstage-repo-tools knip-reports", "build:plugins-report": "node ./scripts/build-plugins-report", @@ -31,6 +31,7 @@ "lint": "backstage-cli repo lint --since origin/master", "lint:all": "backstage-cli repo lint", "lint:docs": "node ./scripts/check-docs-quality", + "lint:peer-deps": "backstage-repo-tools peer-deps", "lint:type-deps": "backstage-repo-tools type-deps", "new": "backstage-cli new --scope backstage --baseVersion 0.0.0 --no-private", "prepare": "husky", @@ -116,7 +117,7 @@ "cross-env": "^7.0.0", "e2e-test": "workspace:*", "eslint": "^8.6.0", - "eslint-plugin-notice": "^0.9.10", + "eslint-plugin-notice": "^1.0.0", "eslint-plugin-react": "^7.28.0", "eslint-plugin-testing-library": "^6.0.0", "fs-extra": "^11.2.0", diff --git a/packages/app-defaults/CHANGELOG.md b/packages/app-defaults/CHANGELOG.md index 449f249236..281ac7d936 100644 --- a/packages/app-defaults/CHANGELOG.md +++ b/packages/app-defaults/CHANGELOG.md @@ -1,5 +1,56 @@ # @backstage/app-defaults +## 1.5.12-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/plugin-permission-react@0.4.27-next.1 + - @backstage/core-app-api@1.15.1-next.1 + - @backstage/theme@0.5.8-next.0 + +## 1.5.12-next.0 + +### Patch Changes + +- 46b5a20: Added `externalLink` to icon defaults +- 8c40e55: Updated the `bitbucket-server-auth` default API to set its environment based on the `auth.environment` config option instead of being hardcoded to `development`. +- Updated dependencies + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/core-app-api@1.15.1-next.0 + - @backstage/theme@0.5.7 + - @backstage/plugin-permission-react@0.4.27-next.0 + +## 1.5.11 + +### Patch Changes + +- b537bd7: Allow custom star icons to be provided via the `star` and `unstarred` icon overrides. See how to override existing icons in the [Backstage documentation](https://backstage.io/docs/getting-started/app-custom-theme/#custom-icons). +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/core-app-api@1.15.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/theme@0.5.7 + - @backstage/plugin-permission-react@0.4.26 + +## 1.5.11-next.1 + +### Patch Changes + +- b537bd7: Allow custom star icons to be provided via the `star` and `unstarred` icon overrides. See how to override existing icons in the [Backstage documentation](https://backstage.io/docs/getting-started/app-custom-theme/#custom-icons). +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/core-app-api@1.14.3-next.0 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/theme@0.5.7-next.0 + - @backstage/plugin-permission-react@0.4.26-next.0 + ## 1.5.11-next.0 ### Patch Changes diff --git a/packages/app-defaults/package.json b/packages/app-defaults/package.json index 0e0cb11cbe..6dfe1aaa49 100644 --- a/packages/app-defaults/package.json +++ b/packages/app-defaults/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/app-defaults", - "version": "1.5.11-next.0", + "version": "1.5.12-next.1", "description": "Provides the default wiring of a Backstage App", "backstage": { "role": "web-library" @@ -48,12 +48,21 @@ "@backstage/cli": "workspace:^", "@backstage/test-utils": "workspace:^", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^15.0.0", - "@types/react": "^16.13.1 || ^17.0.0" + "@testing-library/react": "^16.0.0", + "@types/react": "^18.0.0", + "react": "^18.0.2", + "react-dom": "^18.0.2", + "react-router-dom": "^6.3.0" }, "peerDependencies": { + "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } } diff --git a/packages/app-defaults/api-report.md b/packages/app-defaults/report.api.md similarity index 100% rename from packages/app-defaults/api-report.md rename to packages/app-defaults/report.api.md diff --git a/packages/app-defaults/src/defaults/apis.ts b/packages/app-defaults/src/defaults/apis.ts index 4e9e1a492c..7fdbb78293 100644 --- a/packages/app-defaults/src/defaults/apis.ts +++ b/packages/app-defaults/src/defaults/apis.ts @@ -243,6 +243,7 @@ export const apis = [ discoveryApi, oauthRequestApi, defaultScopes: ['REPO_READ'], + environment: configApi.getOptionalString('auth.environment'), }), }), createApiFactory({ diff --git a/packages/app-defaults/src/defaults/icons.tsx b/packages/app-defaults/src/defaults/icons.tsx index 1ed5bf03c6..e0b93517e7 100644 --- a/packages/app-defaults/src/defaults/icons.tsx +++ b/packages/app-defaults/src/defaults/icons.tsx @@ -36,6 +36,9 @@ import MuiPersonIcon from '@material-ui/icons/Person'; import MuiWarningIcon from '@material-ui/icons/Warning'; import MuiStorageIcon from '@material-ui/icons/Storage'; import MuiFeaturedPlayListIcon from '@material-ui/icons/FeaturedPlayList'; +import Star from '@material-ui/icons/Star'; +import StarBorder from '@material-ui/icons/StarBorder'; +import OpenInNew from '@material-ui/icons/OpenInNew'; export const icons = { brokenImage: MuiBrokenImageIcon as IconComponent, @@ -62,4 +65,7 @@ export const icons = { 'kind:template': MuiFeaturedPlayListIcon as IconComponent, user: MuiPersonIcon as IconComponent, warning: MuiWarningIcon as IconComponent, + star: Star as IconComponent, + unstarred: StarBorder as IconComponent, + externalLink: OpenInNew as IconComponent, }; diff --git a/packages/app-next-example-plugin/CHANGELOG.md b/packages/app-next-example-plugin/CHANGELOG.md index 68879cd7aa..c86731a467 100644 --- a/packages/app-next-example-plugin/CHANGELOG.md +++ b/packages/app-next-example-plugin/CHANGELOG.md @@ -1,5 +1,37 @@ # app-next-example-plugin +## 0.0.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/frontend-plugin-api@0.9.0-next.1 + +## 0.0.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/core-components@0.15.1-next.0 + +## 0.0.15 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/frontend-plugin-api@0.8.0 + +## 0.0.15-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/frontend-plugin-api@0.8.0-next.2 + ## 0.0.15-next.1 ### Patch Changes diff --git a/packages/app-next-example-plugin/package.json b/packages/app-next-example-plugin/package.json index 89e2d353f6..721779d1b5 100644 --- a/packages/app-next-example-plugin/package.json +++ b/packages/app-next-example-plugin/package.json @@ -1,6 +1,6 @@ { "name": "app-next-example-plugin", - "version": "0.0.15-next.1", + "version": "0.0.16-next.1", "description": "Backstage internal example plugin", "backstage": { "role": "frontend-plugin", @@ -47,12 +47,22 @@ }, "devDependencies": { "@backstage/cli": "workspace:^", + "@types/react": "^18.0.0", "cross-fetch": "^4.0.0", - "msw": "^1.0.0" + "msw": "^1.0.0", + "react": "^18.0.2", + "react-dom": "^18.0.2", + "react-router-dom": "^6.3.0" }, "peerDependencies": { + "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } } diff --git a/packages/app-next-example-plugin/api-report.md b/packages/app-next-example-plugin/report.api.md similarity index 78% rename from packages/app-next-example-plugin/api-report.md rename to packages/app-next-example-plugin/report.api.md index 06d325b844..3094fee56e 100644 --- a/packages/app-next-example-plugin/api-report.md +++ b/packages/app-next-example-plugin/report.api.md @@ -17,7 +17,6 @@ const examplePlugin: FrontendPlugin< { 'page:example': ExtensionDefinition<{ kind: 'page'; - namespace: undefined; name: undefined; config: { path: string | undefined; @@ -40,6 +39,11 @@ const examplePlugin: FrontendPlugin< } >; inputs: {}; + params: { + defaultPath: string; + loader: () => Promise; + routeRef?: RouteRef | undefined; + }; }>; } >; @@ -48,5 +52,10 @@ export default examplePlugin; // @public (undocumented) export const ExampleSidebarItem: () => React_2.JSX.Element; +// Warnings were encountered during analysis: +// +// src/ExampleSidebarItem.d.ts:3:22 - (ae-undocumented) Missing documentation for "ExampleSidebarItem". +// src/plugin.d.ts:22:22 - (ae-undocumented) Missing documentation for "examplePlugin". + // (No @packageDocumentation comment for this package) ``` diff --git a/packages/app-next/CHANGELOG.md b/packages/app-next/CHANGELOG.md index 8ddcaad4b3..a4d5c97a8e 100644 --- a/packages/app-next/CHANGELOG.md +++ b/packages/app-next/CHANGELOG.md @@ -1,5 +1,185 @@ # example-app-next +## 0.0.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/cli@0.28.0-next.1 + - @backstage/plugin-scaffolder@1.26.0-next.1 + - @backstage/plugin-signals@0.0.11-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.16-next.1 + - @backstage/plugin-catalog-unprocessed-entities@0.2.9-next.1 + - @backstage/frontend-plugin-api@0.9.0-next.1 + - @backstage/integration-react@1.2.0-next.1 + - @backstage/plugin-kubernetes-cluster@0.0.17-next.1 + - @backstage/frontend-app-api@0.10.0-next.1 + - @backstage/core-compat-api@0.3.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/plugin-permission-react@0.4.27-next.1 + - @backstage/plugin-scaffolder-react@1.13.0-next.1 + - @backstage/plugin-app-visualizer@0.1.11-next.1 + - @backstage/plugin-catalog-import@0.12.5-next.1 + - @backstage/plugin-techdocs-react@1.2.9-next.1 + - @backstage/app-defaults@1.5.12-next.1 + - @backstage/core-app-api@1.15.1-next.1 + - @backstage/plugin-catalog-graph@0.4.11-next.1 + - @backstage/plugin-catalog-react@1.14.0-next.1 + - @backstage/plugin-notifications@0.3.2-next.1 + - @backstage/plugin-user-settings@0.8.14-next.1 + - @backstage/plugin-search-react@1.8.1-next.1 + - @backstage/plugin-auth-react@0.1.7-next.1 + - @backstage/plugin-kubernetes@0.11.16-next.1 + - @backstage/plugin-api-docs@0.11.11-next.1 + - @backstage/plugin-techdocs@1.10.11-next.1 + - @backstage/plugin-catalog@1.24.0-next.1 + - @backstage/theme@0.5.8-next.0 + - @backstage/plugin-search@1.4.18-next.1 + - @backstage/plugin-home@0.7.12-next.1 + - @backstage/plugin-org@0.6.31-next.1 + - @backstage/plugin-app@0.1.1-next.1 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/frontend-defaults@0.1.1-next.1 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-search-common@1.2.14 + +## 0.0.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder@1.26.0-next.0 + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/plugin-catalog@1.24.0-next.0 + - @backstage/cli@0.28.0-next.0 + - @backstage/plugin-scaffolder-react@1.13.0-next.0 + - @backstage/plugin-api-docs@0.11.10-next.0 + - @backstage/frontend-app-api@0.10.0-next.0 + - @backstage/plugin-techdocs@1.10.10-next.0 + - @backstage/app-defaults@1.5.12-next.0 + - @backstage/core-compat-api@0.3.1-next.0 + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/frontend-defaults@0.1.1-next.0 + - @backstage/plugin-app@0.1.1-next.0 + - @backstage/plugin-app-visualizer@0.1.11-next.0 + - @backstage/plugin-catalog-graph@0.4.10-next.0 + - @backstage/plugin-catalog-import@0.12.4-next.0 + - @backstage/plugin-catalog-react@1.13.1-next.0 + - @backstage/plugin-home@0.7.11-next.0 + - @backstage/plugin-kubernetes@0.11.15-next.0 + - @backstage/plugin-org@0.6.30-next.0 + - @backstage/plugin-search@1.4.17-next.0 + - @backstage/plugin-search-react@1.8.1-next.0 + - @backstage/plugin-user-settings@0.8.13-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.15.1-next.0 + - @backstage/integration-react@1.1.32-next.0 + - @backstage/theme@0.5.7 + - @backstage/plugin-auth-react@0.1.7-next.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.9-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.16-next.0 + - @backstage/plugin-notifications@0.3.2-next.0 + - @backstage/plugin-permission-react@0.4.27-next.0 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-signals@0.0.11-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.15-next.0 + - @backstage/plugin-techdocs-react@1.2.9-next.0 + +## 0.0.15 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/plugin-catalog-react@1.13.0 + - @backstage/plugin-techdocs@1.10.9 + - @backstage/plugin-catalog@1.23.0 + - @backstage/plugin-home@0.7.10 + - @backstage/cli@0.27.1 + - @backstage/frontend-plugin-api@0.8.0 + - @backstage/plugin-techdocs-react@1.2.8 + - @backstage/core-app-api@1.15.0 + - @backstage/frontend-app-api@0.9.0 + - @backstage/core-compat-api@0.3.0 + - @backstage/plugin-catalog-import@0.12.3 + - @backstage/plugin-catalog-graph@0.4.9 + - @backstage/plugin-user-settings@0.8.12 + - @backstage/plugin-search-react@1.8.0 + - @backstage/plugin-kubernetes@0.11.14 + - @backstage/plugin-scaffolder@1.25.0 + - @backstage/plugin-api-docs@0.11.9 + - @backstage/plugin-search@1.4.16 + - @backstage/plugin-org@0.6.29 + - @backstage/integration-react@1.1.31 + - @backstage/frontend-defaults@0.1.0 + - @backstage/plugin-notifications@0.3.1 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-scaffolder-react@1.12.0 + - @backstage/plugin-app@0.1.0 + - @backstage/app-defaults@1.5.11 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/theme@0.5.7 + - @backstage/plugin-auth-react@0.1.6 + - @backstage/plugin-catalog-unprocessed-entities@0.2.8 + - @backstage/plugin-kubernetes-cluster@0.0.15 + - @backstage/plugin-permission-react@0.4.26 + - @backstage/plugin-signals@0.0.10 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.14 + - @backstage/plugin-app-visualizer@0.1.10 + - @backstage/config@1.2.0 + - @backstage/plugin-search-common@1.2.14 + +## 0.0.15-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/plugin-catalog-react@1.13.0-next.2 + - @backstage/plugin-techdocs@1.10.9-next.2 + - @backstage/plugin-catalog@1.23.0-next.2 + - @backstage/plugin-home@0.7.10-next.2 + - @backstage/cli@0.27.1-next.2 + - @backstage/core-app-api@1.14.3-next.0 + - @backstage/integration-react@1.1.31-next.0 + - @backstage/plugin-scaffolder@1.25.0-next.2 + - @backstage/plugin-notifications@0.3.1-next.2 + - @backstage/plugin-scaffolder-react@1.12.0-next.2 + - @backstage/app-defaults@1.5.11-next.1 + - @backstage/plugin-catalog-import@0.12.3-next.2 + - @backstage/plugin-app@0.1.0-next.2 + - @backstage/plugin-search-react@1.8.0-next.2 + - @backstage/core-compat-api@0.3.0-next.2 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/frontend-app-api@0.9.0-next.2 + - @backstage/frontend-defaults@0.1.0-next.1 + - @backstage/frontend-plugin-api@0.8.0-next.2 + - @backstage/theme@0.5.7-next.0 + - @backstage/plugin-api-docs@0.11.9-next.2 + - @backstage/plugin-auth-react@0.1.6-next.1 + - @backstage/plugin-catalog-graph@0.4.9-next.2 + - @backstage/plugin-catalog-unprocessed-entities@0.2.8-next.1 + - @backstage/plugin-kubernetes-cluster@0.0.15-next.2 + - @backstage/plugin-kubernetes@0.11.14-next.2 + - @backstage/plugin-org@0.6.29-next.2 + - @backstage/plugin-permission-react@0.4.26-next.0 + - @backstage/plugin-search@1.4.16-next.2 + - @backstage/plugin-signals@0.0.10-next.2 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.14-next.2 + - @backstage/plugin-techdocs-react@1.2.8-next.2 + - @backstage/plugin-user-settings@0.8.12-next.2 + - @backstage/plugin-app-visualizer@0.1.10-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-search-common@1.2.14 + ## 0.0.15-next.1 ### Patch Changes diff --git a/packages/app-next/package.json b/packages/app-next/package.json index 397be2197a..bff21c3b89 100644 --- a/packages/app-next/package.json +++ b/packages/app-next/package.json @@ -1,16 +1,38 @@ { "name": "example-app-next", - "version": "0.0.15-next.1", + "version": "0.0.16-next.1", + "backstage": { + "role": "frontend" + }, "private": true, "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "packages/app-next" }, - "backstage": { - "role": "frontend" + "license": "Apache-2.0", + "files": [ + "dist" + ], + "scripts": { + "build": "backstage-cli package build", + "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", + "start": "backstage-cli package start --config ../../app-config.yaml --config app-config.yaml", + "test": "backstage-cli package test" + }, + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] }, - "bundled": true, "dependencies": { "@backstage/app-defaults": "workspace:^", "@backstage/catalog-model": "workspace:^", @@ -55,23 +77,19 @@ "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.61", "@octokit/rest": "^19.0.3", - "@vitejs/plugin-react": "^4.0.4", "history": "^5.0.0", "react": "^18.0.2", "react-dom": "^18.0.2", "react-router": "^6.3.0", "react-router-dom": "^6.3.0", "react-use": "^17.2.4", - "vite": "^4.4.9", - "vite-plugin-html": "^3.2.0", - "vite-plugin-node-polyfills": "^0.22.0", "zen-observable": "^0.10.0" }, "devDependencies": { "@backstage/test-utils": "workspace:^", "@testing-library/dom": "^10.0.0", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^15.0.0", + "@testing-library/react": "^16.0.0", "@testing-library/user-event": "^14.0.0", "@types/jquery": "^3.3.34", "@types/react": "*", @@ -79,27 +97,5 @@ "@types/zen-observable": "^0.8.0", "cross-env": "^7.0.0" }, - "scripts": { - "start": "backstage-cli package start --config ../../app-config.yaml --config app-config.yaml", - "build": "backstage-cli package build", - "clean": "backstage-cli package clean", - "test": "backstage-cli package test", - "lint": "backstage-cli package lint" - }, - "browserslist": { - "production": [ - ">0.2%", - "not dead", - "not op_mini all" - ], - "development": [ - "last 1 chrome version", - "last 1 firefox version", - "last 1 safari version" - ] - }, - "files": [ - "dist" - ], - "license": "Apache-2.0" + "bundled": true } diff --git a/packages/app-next/src/App.tsx b/packages/app-next/src/App.tsx index 0d686cd5a5..79adc13daf 100644 --- a/packages/app-next/src/App.tsx +++ b/packages/app-next/src/App.tsx @@ -15,7 +15,7 @@ */ import React from 'react'; -import { createApp } from '@backstage/frontend-app-api'; +import { createApp } from '@backstage/frontend-defaults'; import { pagesPlugin } from './examples/pagesPlugin'; import notFoundErrorPage from './examples/notFoundErrorPageExtension'; import userSettingsPlugin from '@backstage/plugin-user-settings/alpha'; @@ -82,6 +82,11 @@ TODO: /* app.tsx */ +/** + * TechDocs does support the new frontend system so this conversion is not + * strictly necessary, but it's left here to provide a demo of the utilities for + * converting legacy plugins. + */ const convertedTechdocsPlugin = convertLegacyPlugin(techdocsPlugin, { extensions: [ // TODO: We likely also need a way to convert an entire tree similar to collectLegacyRoutes diff --git a/packages/app/CHANGELOG.md b/packages/app/CHANGELOG.md index 4cfd9ca1a8..f72e393af7 100644 --- a/packages/app/CHANGELOG.md +++ b/packages/app/CHANGELOG.md @@ -1,5 +1,169 @@ # example-app +## 0.2.102-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/cli@0.28.0-next.1 + - @backstage/plugin-scaffolder@1.26.0-next.1 + - @backstage/plugin-signals@0.0.11-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.16-next.1 + - @backstage/plugin-catalog-unprocessed-entities@0.2.9-next.1 + - @backstage/integration-react@1.2.0-next.1 + - @backstage/plugin-kubernetes-cluster@0.0.17-next.1 + - @backstage/frontend-app-api@0.10.0-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/plugin-permission-react@0.4.27-next.1 + - @backstage/plugin-scaffolder-react@1.13.0-next.1 + - @backstage/plugin-catalog-import@0.12.5-next.1 + - @backstage/plugin-techdocs-react@1.2.9-next.1 + - @backstage/app-defaults@1.5.12-next.1 + - @backstage/core-app-api@1.15.1-next.1 + - @backstage/plugin-catalog-graph@0.4.11-next.1 + - @backstage/plugin-catalog-react@1.14.0-next.1 + - @backstage/plugin-notifications@0.3.2-next.1 + - @backstage/plugin-user-settings@0.8.14-next.1 + - @backstage/plugin-search-react@1.8.1-next.1 + - @backstage/plugin-auth-react@0.1.7-next.1 + - @backstage/plugin-kubernetes@0.11.16-next.1 + - @backstage/plugin-api-docs@0.11.11-next.1 + - @backstage/plugin-devtools@0.1.19-next.1 + - @backstage/plugin-techdocs@1.10.11-next.1 + - @backstage/plugin-catalog@1.24.0-next.1 + - @backstage/theme@0.5.8-next.0 + - @backstage/plugin-search@1.4.18-next.1 + - @backstage/plugin-home@0.7.12-next.1 + - @backstage/plugin-org@0.6.31-next.1 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-search-common@1.2.14 + +## 0.2.102-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder@1.26.0-next.0 + - @backstage/plugin-catalog@1.24.0-next.0 + - @backstage/cli@0.28.0-next.0 + - @backstage/plugin-scaffolder-react@1.13.0-next.0 + - @backstage/plugin-api-docs@0.11.10-next.0 + - @backstage/frontend-app-api@0.10.0-next.0 + - @backstage/plugin-techdocs@1.10.10-next.0 + - @backstage/app-defaults@1.5.12-next.0 + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/plugin-catalog-graph@0.4.10-next.0 + - @backstage/plugin-catalog-import@0.12.4-next.0 + - @backstage/plugin-catalog-react@1.13.1-next.0 + - @backstage/plugin-devtools@0.1.19-next.0 + - @backstage/plugin-home@0.7.11-next.0 + - @backstage/plugin-kubernetes@0.11.15-next.0 + - @backstage/plugin-org@0.6.30-next.0 + - @backstage/plugin-search@1.4.17-next.0 + - @backstage/plugin-search-react@1.8.1-next.0 + - @backstage/plugin-user-settings@0.8.13-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.15.1-next.0 + - @backstage/integration-react@1.1.32-next.0 + - @backstage/theme@0.5.7 + - @backstage/plugin-auth-react@0.1.7-next.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.9-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.16-next.0 + - @backstage/plugin-notifications@0.3.2-next.0 + - @backstage/plugin-permission-react@0.4.27-next.0 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-signals@0.0.11-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.15-next.0 + - @backstage/plugin-techdocs-react@1.2.9-next.0 + +## 0.2.101 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/plugin-catalog-react@1.13.0 + - @backstage/plugin-techdocs@1.10.9 + - @backstage/plugin-catalog@1.23.0 + - @backstage/plugin-home@0.7.10 + - @backstage/cli@0.27.1 + - @backstage/plugin-techdocs-react@1.2.8 + - @backstage/core-app-api@1.15.0 + - @backstage/frontend-app-api@0.9.0 + - @backstage/plugin-catalog-import@0.12.3 + - @backstage/plugin-catalog-graph@0.4.9 + - @backstage/plugin-user-settings@0.8.12 + - @backstage/plugin-search-react@1.8.0 + - @backstage/plugin-kubernetes@0.11.14 + - @backstage/plugin-scaffolder@1.25.0 + - @backstage/plugin-api-docs@0.11.9 + - @backstage/plugin-devtools@0.1.18 + - @backstage/plugin-search@1.4.16 + - @backstage/plugin-org@0.6.29 + - @backstage/integration-react@1.1.31 + - @backstage/plugin-notifications@0.3.1 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-scaffolder-react@1.12.0 + - @backstage/app-defaults@1.5.11 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/theme@0.5.7 + - @backstage/plugin-auth-react@0.1.6 + - @backstage/plugin-catalog-unprocessed-entities@0.2.8 + - @backstage/plugin-kubernetes-cluster@0.0.15 + - @backstage/plugin-permission-react@0.4.26 + - @backstage/plugin-signals@0.0.10 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.14 + - @backstage/config@1.2.0 + - @backstage/plugin-search-common@1.2.14 + +## 0.2.101-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/plugin-catalog-react@1.13.0-next.2 + - @backstage/plugin-techdocs@1.10.9-next.2 + - @backstage/plugin-catalog@1.23.0-next.2 + - @backstage/plugin-home@0.7.10-next.2 + - @backstage/cli@0.27.1-next.2 + - @backstage/core-app-api@1.14.3-next.0 + - @backstage/integration-react@1.1.31-next.0 + - @backstage/plugin-scaffolder@1.25.0-next.2 + - @backstage/plugin-notifications@0.3.1-next.2 + - @backstage/plugin-scaffolder-react@1.12.0-next.2 + - @backstage/app-defaults@1.5.11-next.1 + - @backstage/plugin-catalog-import@0.12.3-next.2 + - @backstage/plugin-search-react@1.8.0-next.2 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/frontend-app-api@0.9.0-next.2 + - @backstage/theme@0.5.7-next.0 + - @backstage/plugin-api-docs@0.11.9-next.2 + - @backstage/plugin-auth-react@0.1.6-next.1 + - @backstage/plugin-catalog-graph@0.4.9-next.2 + - @backstage/plugin-catalog-unprocessed-entities@0.2.8-next.1 + - @backstage/plugin-kubernetes-cluster@0.0.15-next.2 + - @backstage/plugin-kubernetes@0.11.14-next.2 + - @backstage/plugin-org@0.6.29-next.2 + - @backstage/plugin-permission-react@0.4.26-next.0 + - @backstage/plugin-search@1.4.16-next.2 + - @backstage/plugin-signals@0.0.10-next.2 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.14-next.2 + - @backstage/plugin-techdocs-react@1.2.8-next.2 + - @backstage/plugin-user-settings@0.8.12-next.2 + - @backstage/plugin-devtools@0.1.18-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-search-common@1.2.14 + ## 0.2.101-next.1 ### Patch Changes diff --git a/packages/app/package.json b/packages/app/package.json index 9d9431b6c1..e6eb6b9f20 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,6 +1,6 @@ { "name": "example-app", - "version": "0.2.101-next.1", + "version": "0.2.102-next.1", "backstage": { "role": "frontend" }, @@ -74,15 +74,15 @@ "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.61", "@octokit/rest": "^19.0.3", - "@vitejs/plugin-react": "^4.0.4", + "@vitejs/plugin-react": "^4.3.1", "history": "^5.0.0", "react": "^18.0.2", "react-dom": "^18.0.2", "react-router": "^6.3.0", "react-router-dom": "^6.3.0", "react-use": "^17.2.4", - "vite": "^4.4.9", - "vite-plugin-html": "^3.2.0", + "vite": "^5.0.0", + "vite-plugin-html": "^3.2.2", "vite-plugin-node-polyfills": "^0.22.0", "zen-observable": "^0.10.0" }, @@ -91,7 +91,7 @@ "@playwright/test": "^1.32.3", "@testing-library/dom": "^10.0.0", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^15.0.0", + "@testing-library/react": "^16.0.0", "@testing-library/user-event": "^14.0.0", "@types/jquery": "^3.3.34", "@types/react": "*", diff --git a/packages/app/src/App.tsx b/packages/app/src/App.tsx index ba556e8616..2b0bb00929 100644 --- a/packages/app/src/App.tsx +++ b/packages/app/src/App.tsx @@ -117,7 +117,10 @@ const routes = ( }> {homePage} - } /> + } + /> } diff --git a/packages/backend-app-api/CHANGELOG.md b/packages/backend-app-api/CHANGELOG.md index 9605e30ba3..20926596c5 100644 --- a/packages/backend-app-api/CHANGELOG.md +++ b/packages/backend-app-api/CHANGELOG.md @@ -1,5 +1,89 @@ # @backstage/backend-app-api +## 1.0.1-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- 04af116: The backend will no longer exit immediately if any plugin or modules fails to initialize. Instead, the backend will wait for all plugins and modules to either start up successfully or throw, and then shut down the backend if there were any initialization errors. + + This fixes an issue where backend initialization errors in adjacent plugins during database schema migration could cause the database migrations to be stuck in a locked state. + +- Updated dependencies + - @backstage/plugin-permission-node@0.8.4-next.0 + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## 1.0.0 + +### Major Changes + +- ec1b4be: Release 1.0 of the new backend system! :tada: + + The backend system is finally getting promoted to 1.0.0. This means that the API is now stable and breaking changes should not occur until version 2.0.0, see our [package versioning policy](https://backstage.io/docs/overview/versioning-policy/#package-versioning-policy) for more information what this means. + + This release also marks the end of the old backend system based on `createRouter` exports. Going forward backend plugins packages will start to deprecate and later this year remove exports supporting the old backend system. If you would like to help out with this transition, see https://github.com/backstage/backstage/issues/26353 or consult the [migration guide](https://backstage.io/docs/backend-system/building-plugins-and-modules/migrating/#remove-support-for-the-old-backend-system). + +### Minor Changes + +- 19ff127: **BREAKING**: The deprecated `identityServiceFactory` and `tokenManagerServiceFactory` have been removed. +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- cd38da8: Deprecate the `featureDiscoveryServiceFactory` in favor of using `@backstage/backend-defaults#discoveryFeatureLoader` instead. +- 8ccf784: All created backend instances now share a the same `process` exit listeners, and on exit the process will wait for all backend instances to shut down before exiting. This fixes the `EventEmitter` leak warnings in tests. +- 6ed9264: chore(deps): bump `path-to-regexp` from 6.2.2 to 8.0.0 +- c246372: Updated the error message for missing service dependencies to include the plugin and module IDs. +- 7f779c7: `auth.externalAccess` should be optional in the config schema +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- 51a69b5: Fix feature loaders in CJS double-default nested builds +- 0b2a402: Updates to the config schema to match reality +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/plugin-permission-node@0.8.3 + - @backstage/config-loader@1.9.1 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## 1.0.0-next.2 + +### Major Changes + +- ec1b4be: Release 1.0 of the new backend system! :tada: + + The backend system is finally getting promoted to 1.0.0. This means that the API is now stable and breaking changes should not occur until version 2.0.0, see our [package versioning policy](https://backstage.io/docs/overview/versioning-policy/#package-versioning-policy) for more information what this means. + + This release also marks the end of the old backend system based on `createRouter` exports. Going forward backend plugins packages will start to deprecate and later this year remove exports supporting the old backend system. If you would like to help out with this transition, see https://github.com/backstage/backstage/issues/26353 or consult the [migration guide](https://backstage.io/docs/backend-system/building-plugins-and-modules/migrating/#remove-support-for-the-old-backend-system). + +### Patch Changes + +- 6ed9264: chore(deps): bump `path-to-regexp` from 6.2.2 to 8.0.0 +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/config-loader@1.9.1-next.0 + - @backstage/plugin-permission-node@0.8.3-next.2 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.10.0-next.1 ### Patch Changes diff --git a/packages/backend-app-api/package.json b/packages/backend-app-api/package.json index 6582a60515..018eea139f 100644 --- a/packages/backend-app-api/package.json +++ b/packages/backend-app-api/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-app-api", - "version": "0.10.0-next.1", + "version": "1.0.1-next.0", "description": "Core API used by Backstage backend apps", "backstage": { "role": "node-library" @@ -50,7 +50,7 @@ "test": "backstage-cli package test" }, "dependencies": { - "@backstage/backend-common": "workspace:^", + "@backstage/backend-common": "^0.25.0", "@backstage/backend-plugin-api": "workspace:^", "@backstage/cli-common": "workspace:^", "@backstage/config": "workspace:^", @@ -76,7 +76,7 @@ "morgan": "^1.10.0", "node-fetch": "^2.7.0", "node-forge": "^1.3.1", - "path-to-regexp": "^6.2.1", + "path-to-regexp": "^8.0.0", "selfsigned": "^2.0.0", "stoppable": "^1.1.0", "triple-beam": "^1.4.1", @@ -96,7 +96,7 @@ "@types/stoppable": "^1.1.0", "http-errors": "^2.0.0", "msw": "^1.0.0", - "supertest": "^6.1.3" + "supertest": "^7.0.0" }, "configSchema": "config.d.ts" } diff --git a/packages/backend-app-api/api-report-alpha.md b/packages/backend-app-api/report-alpha.api.md similarity index 73% rename from packages/backend-app-api/api-report-alpha.md rename to packages/backend-app-api/report-alpha.api.md index 163cc325a1..e3f11bb800 100644 --- a/packages/backend-app-api/api-report-alpha.md +++ b/packages/backend-app-api/report-alpha.api.md @@ -13,5 +13,9 @@ export const featureDiscoveryServiceFactory: ServiceFactory< 'singleton' >; +// Warnings were encountered during analysis: +// +// src/alpha/featureDiscoveryServiceFactory.d.ts:5:22 - (ae-undocumented) Missing documentation for "featureDiscoveryServiceFactory". + // (No @packageDocumentation comment for this package) ``` diff --git a/packages/backend-app-api/api-report.md b/packages/backend-app-api/report.api.md similarity index 53% rename from packages/backend-app-api/api-report.md rename to packages/backend-app-api/report.api.md index 88fa34e6e4..ec32ec9b67 100644 --- a/packages/backend-app-api/api-report.md +++ b/packages/backend-app-api/report.api.md @@ -32,4 +32,14 @@ export interface CreateSpecializedBackendOptions { // (undocumented) defaultServiceFactories: ServiceFactory[]; } + +// Warnings were encountered during analysis: +// +// src/wiring/createSpecializedBackend.d.ts:5:1 - (ae-undocumented) Missing documentation for "createSpecializedBackend". +// src/wiring/types.d.ts:5:1 - (ae-undocumented) Missing documentation for "Backend". +// src/wiring/types.d.ts:6:5 - (ae-undocumented) Missing documentation for "add". +// src/wiring/types.d.ts:9:5 - (ae-undocumented) Missing documentation for "start". +// src/wiring/types.d.ts:10:5 - (ae-undocumented) Missing documentation for "stop". +// src/wiring/types.d.ts:15:1 - (ae-undocumented) Missing documentation for "CreateSpecializedBackendOptions". +// src/wiring/types.d.ts:16:5 - (ae-undocumented) Missing documentation for "defaultServiceFactories". ``` diff --git a/packages/backend-app-api/src/wiring/BackendInitializer.test.ts b/packages/backend-app-api/src/wiring/BackendInitializer.test.ts index b524301f21..8e92fc7120 100644 --- a/packages/backend-app-api/src/wiring/BackendInitializer.test.ts +++ b/packages/backend-app-api/src/wiring/BackendInitializer.test.ts @@ -418,6 +418,49 @@ describe('BackendInitializer', () => { ); }); + it('should forward errors when multiple plugins fail to start', async () => { + const init = new BackendInitializer([]); + init.add( + createBackendPlugin({ + pluginId: 'test-1', + register(reg) { + reg.registerInit({ + deps: {}, + async init() { + throw new Error('NOPE A'); + }, + }); + }, + }), + ); + init.add( + createBackendPlugin({ + pluginId: 'test-2', + register(reg) { + reg.registerInit({ + deps: {}, + async init() { + throw new Error('NOPE B'); + }, + }); + }, + }), + ); + const result = init.start(); + + await expect(result).rejects.toThrow('Backend startup failed'); + await expect(result).rejects.toMatchObject({ + errors: [ + expect.objectContaining({ + message: "Plugin 'test-1' startup failed; caused by Error: NOPE A", + }), + expect.objectContaining({ + message: "Plugin 'test-2' startup failed; caused by Error: NOPE B", + }), + ], + }); + }); + it('should forward errors when modules fail to start', async () => { const init = new BackendInitializer([]); init.add(testPlugin); diff --git a/packages/backend-app-api/src/wiring/BackendInitializer.ts b/packages/backend-app-api/src/wiring/BackendInitializer.ts index 7e29276a77..86771fbb74 100644 --- a/packages/backend-app-api/src/wiring/BackendInitializer.ts +++ b/packages/backend-app-api/src/wiring/BackendInitializer.ts @@ -49,8 +49,56 @@ export interface BackendRegisterInit { }; } +/** + * A registry of backend instances, used to manage process shutdown hooks across all instances. + */ +const instanceRegistry = new (class InstanceRegistry { + #registered = false; + #instances = new Set(); + + register(instance: BackendInitializer) { + if (!this.#registered) { + this.#registered = true; + + process.addListener('SIGTERM', this.#exitHandler); + process.addListener('SIGINT', this.#exitHandler); + process.addListener('beforeExit', this.#exitHandler); + } + + this.#instances.add(instance); + } + + unregister(instance: BackendInitializer) { + this.#instances.delete(instance); + } + + #exitHandler = async () => { + try { + const results = await Promise.allSettled( + Array.from(this.#instances).map(b => b.stop()), + ); + const errors = results.flatMap(r => + r.status === 'rejected' ? [r.reason] : [], + ); + + if (errors.length > 0) { + for (const error of errors) { + console.error(error); + } + process.exit(1); + } else { + process.exit(0); + } + } catch (error) { + console.error(error); + process.exit(1); + } + }; +})(); + export class BackendInitializer { #startPromise?: Promise; + #stopPromise?: Promise; #registrations = new Array(); #extensionPoints = new Map(); #serviceRegistry: ServiceRegistry; @@ -129,24 +177,11 @@ export class BackendInitializer { if (this.#startPromise) { throw new Error('Backend has already started'); } + if (this.#stopPromise) { + throw new Error('Backend has already stopped'); + } - const exitHandler = async () => { - process.removeListener('SIGTERM', exitHandler); - process.removeListener('SIGINT', exitHandler); - process.removeListener('beforeExit', exitHandler); - - try { - await this.stop(); - process.exit(0); - } catch (error) { - console.error(error); - process.exit(1); - } - }; - - process.addListener('SIGTERM', exitHandler); - process.addListener('SIGINT', exitHandler); - process.addListener('beforeExit', exitHandler); + instanceRegistry.register(this); this.#startPromise = this.#doStart(); await this.#startPromise; @@ -240,76 +275,91 @@ export class BackendInitializer { ); // All plugins are initialized in parallel - await Promise.all( + const results = await Promise.allSettled( allPluginIds.map(async pluginId => { - // Initialize all eager services - await this.#serviceRegistry.initializeEagerServicesWithScope( - 'plugin', - pluginId, - ); - - // Modules are initialized before plugins, so that they can provide extension to the plugin - const modules = moduleInits.get(pluginId); - if (modules) { - const tree = DependencyGraph.fromIterable( - Array.from(modules).map(([moduleId, moduleInit]) => ({ - value: { moduleId, moduleInit }, - // Relationships are reversed at this point since we're only interested in the extension points. - // If a modules provides extension point A we want it to be initialized AFTER all modules - // that depend on extension point A, so that they can provide their extensions. - consumes: Array.from(moduleInit.provides).map(p => p.id), - provides: Array.from(moduleInit.consumes).map(c => c.id), - })), - ); - const circular = tree.detectCircularDependency(); - if (circular) { - throw new ConflictError( - `Circular dependency detected for modules of plugin '${pluginId}', ${circular - .map(({ moduleId }) => `'${moduleId}'`) - .join(' -> ')}`, - ); - } - await tree.parallelTopologicalTraversal( - async ({ moduleId, moduleInit }) => { - const moduleDeps = await this.#getInitDeps( - moduleInit.init.deps, - pluginId, - moduleId, - ); - await moduleInit.init.func(moduleDeps).catch(error => { - throw new ForwardedError( - `Module '${moduleId}' for plugin '${pluginId}' startup failed`, - error, - ); - }); - }, - ); - } - - // Once all modules have been initialized, we can initialize the plugin itself - const pluginInit = pluginInits.get(pluginId); - // We allow modules to be installed without the accompanying plugin, so the plugin may not exist - if (pluginInit) { - const pluginDeps = await this.#getInitDeps( - pluginInit.init.deps, + try { + // Initialize all eager services + await this.#serviceRegistry.initializeEagerServicesWithScope( + 'plugin', pluginId, ); - await pluginInit.init.func(pluginDeps).catch(error => { - throw new ForwardedError( - `Plugin '${pluginId}' startup failed`, - error, + + // Modules are initialized before plugins, so that they can provide extension to the plugin + const modules = moduleInits.get(pluginId); + if (modules) { + const tree = DependencyGraph.fromIterable( + Array.from(modules).map(([moduleId, moduleInit]) => ({ + value: { moduleId, moduleInit }, + // Relationships are reversed at this point since we're only interested in the extension points. + // If a modules provides extension point A we want it to be initialized AFTER all modules + // that depend on extension point A, so that they can provide their extensions. + consumes: Array.from(moduleInit.provides).map(p => p.id), + provides: Array.from(moduleInit.consumes).map(c => c.id), + })), ); - }); + const circular = tree.detectCircularDependency(); + if (circular) { + throw new ConflictError( + `Circular dependency detected for modules of plugin '${pluginId}', ${circular + .map(({ moduleId }) => `'${moduleId}'`) + .join(' -> ')}`, + ); + } + await tree.parallelTopologicalTraversal( + async ({ moduleId, moduleInit }) => { + const moduleDeps = await this.#getInitDeps( + moduleInit.init.deps, + pluginId, + moduleId, + ); + await moduleInit.init.func(moduleDeps).catch(error => { + throw new ForwardedError( + `Module '${moduleId}' for plugin '${pluginId}' startup failed`, + error, + ); + }); + }, + ); + } + + // Once all modules have been initialized, we can initialize the plugin itself + const pluginInit = pluginInits.get(pluginId); + // We allow modules to be installed without the accompanying plugin, so the plugin may not exist + if (pluginInit) { + const pluginDeps = await this.#getInitDeps( + pluginInit.init.deps, + pluginId, + ); + await pluginInit.init.func(pluginDeps).catch(error => { + throw new ForwardedError( + `Plugin '${pluginId}' startup failed`, + error, + ); + }); + } + + initLogger.onPluginStarted(pluginId); + + // Once the plugin and all modules have been initialized, we can signal that the plugin has stared up successfully + const lifecycleService = await this.#getPluginLifecycleImpl(pluginId); + await lifecycleService.startup(); + } catch (error) { + initLogger.onPluginFailed(pluginId); + throw error; } - - initLogger.onPluginStarted(pluginId); - - // Once the plugin and all modules have been initialized, we can signal that the plugin has stared up successfully - const lifecycleService = await this.#getPluginLifecycleImpl(pluginId); - await lifecycleService.startup(); }), ); + const initErrors = results.flatMap(r => + r.status === 'rejected' ? [r.reason] : [], + ); + if (initErrors.length === 1) { + throw initErrors[0]; + } else if (initErrors.length > 1) { + // TODO(Rugvip): Seems like there aren't proper types for AggregateError yet + throw new (AggregateError as any)(initErrors, 'Backend startup failed'); + } + // Once all plugins and modules have been initialized, we can signal that the backend has started up successfully const lifecycleService = await this.#getRootLifecycleImpl(); await lifecycleService.startup(); @@ -336,7 +386,17 @@ export class BackendInitializer { } } + // It's fine to call .stop() multiple times, which for example can happen with manual stop + process exit async stop(): Promise { + instanceRegistry.unregister(this); + + if (!this.#stopPromise) { + this.#stopPromise = this.#doStop(); + } + await this.#stopPromise; + } + + async #doStop(): Promise { if (!this.#startPromise) { return; } diff --git a/packages/backend-app-api/src/wiring/createInitializationLogger.ts b/packages/backend-app-api/src/wiring/createInitializationLogger.ts index 566b5507ec..de323f914b 100644 --- a/packages/backend-app-api/src/wiring/createInitializationLogger.ts +++ b/packages/backend-app-api/src/wiring/createInitializationLogger.ts @@ -27,6 +27,7 @@ export function createInitializationLogger( rootLogger?: RootLoggerService, ): { onPluginStarted(pluginId: string): void; + onPluginFailed(pluginId: string): void; onAllStarted(): void; } { const logger = rootLogger?.child({ type: 'initialization' }); @@ -67,6 +68,16 @@ export function createInitializationLogger( starting.delete(pluginId); started.add(pluginId); }, + onPluginFailed(pluginId: string) { + starting.delete(pluginId); + const status = + starting.size > 0 + ? `, waiting for ${starting.size} other plugins to finish before shutting down the process` + : ''; + logger?.error( + `Plugin '${pluginId}' thew an error during startup${status}`, + ); + }, onAllStarted() { logger?.info(`Plugin initialization complete${getInitStatus()}`); diff --git a/packages/backend-common/CHANGELOG.md b/packages/backend-common/CHANGELOG.md deleted file mode 100644 index 2a488efd04..0000000000 --- a/packages/backend-common/CHANGELOG.md +++ /dev/null @@ -1,3836 +0,0 @@ -# @backstage/backend-common - -## 0.25.0-next.1 - -### Minor Changes - -- a4bac3c: **BREAKING**: You can no longer supply a `basePath` option to the host discovery implementation. In the new backend system, the ability to choose this path has been removed anyway at the plugin router level. -- 988c145: **BREAKING**: Simplifications and cleanup as part of the Backend System 1.0 work. - - - The deprecated `dropDatabase` function has now been removed, without replacement. - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-auth-node@0.5.2-next.1 - - @backstage/backend-dev-utils@0.1.5 - - @backstage/backend-plugin-api@0.9.0-next.1 - - @backstage/cli-common@0.1.14 - - @backstage/config@1.2.0 - - @backstage/config-loader@1.9.0 - - @backstage/errors@1.2.4 - - @backstage/integration@1.14.0 - - @backstage/integration-aws-node@0.1.12 - - @backstage/types@1.1.1 - -## 0.25.0-next.0 - -### Minor Changes - -- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. - - This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. - - As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. - -### Patch Changes - -- 8ba77ed: The `legacyPlugin` and `makeLegacyPlugin` helpers now provide their own shim implementation of the identity and token manager services, as these services are being removed from the new backend system. -- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. -- 2e9ec14: Add `pg-format` as a dependency -- 19ff127: Internal refactor to re-declare the token manager service which was removed from `@backstage/backend-plugin-api`, but is still supported in this package for backwards compatibility. -- 66dbf0a: Allow the cache service to accept the human duration format for TTL -- 0b2a402: Updates to the config schema to match reality -- Updated dependencies - - @backstage/backend-plugin-api@0.9.0-next.0 - - @backstage/plugin-auth-node@0.5.2-next.0 - - @backstage/backend-dev-utils@0.1.5 - - @backstage/cli-common@0.1.14 - - @backstage/config@1.2.0 - - @backstage/config-loader@1.9.0 - - @backstage/errors@1.2.4 - - @backstage/integration@1.14.0 - - @backstage/integration-aws-node@0.1.12 - - @backstage/types@1.1.1 - -## 0.24.0 - -### Minor Changes - -- 389f5a4: **BREAKING**: Removed the following `Url Reader` deprecated exports: - - - UrlReader: Use `UrlReaderService` from `@backstage/backend-plugin-api` instead; - - AzureUrlReader: Import from `@backstage/backend-defaults/urlReader` instead; - - BitbucketUrlReader: Import from `@backstage/backend-defaults/urlReader` instead; - - BitbucketCloudUrlReader: Import from `@backstage/backend-defaults/urlReader` instead; - - BitbucketServerUrlReader: Import from `@backstage/backend-defaults/urlReader` instead; - - GithubUrlReader: Import from `@backstage/backend-defaults/urlReader` instead; - - GitlabUrlReader: Import from `@backstage/backend-defaults/urlReader` instead; - - GerritUrlReader: Import from `@backstage/backend-defaults/urlReader` instead; - - GiteaUrlReader: Import from `@backstage/backend-defaults/urlReader` instead; - - HarnessUrlReader: Import from `@backstage/backend-defaults/urlReader` instead; - - AwsS3UrlReader: Import from `@backstage/backend-defaults/urlReader` instead; - - FetchUrlReader: Import from `@backstage/backend-defaults/urlReader` instead; - - UrlReaders: Import from `@backstage/backend-defaults/urlReader` instead; - - UrlReadersOptions: Import from `@backstage/backend-defaults/urlReader` instead; - - UrlReaderPredicateTuple: Import from `@backstage/backend-defaults/urlReader` instead; - - FromReadableArrayOptions: Import from `@backstage/backend-defaults/urlReader` instead; - - ReaderFactory: Import from `@backstage/backend-defaults/urlReader` instead; - - ReadUrlOptions:Use `UrlReaderServiceReadUrlOptions` from `@backstage/backend-plugin-api` instead; - - ReadUrlResponse: Use `UrlReaderServiceReadUrlResponse` from `@backstage/backend-plugin-api` instead; - - ReadUrlResponseFactory: Import from `@backstage/backend-defaults/urlReader` instead; - - ReadUrlResponseFactoryFromStreamOptions: Import from `@backstage/backend-defaults/urlReader` instead; - - ReadTreeOptions: Use `UrlReaderServiceReadTreeOptions` from `@backstage/backend-plugin-api` instead; - - ReadTreeResponse: Use `UrlReaderServiceReadTreeResponse` from `@backstage/backend-plugin-api` instead; - - ReadTreeResponseFile: Use `UrlReaderServiceReadTreeResponseFile` from `@backstage/backend-plugin-api` instead; - - ReadTreeResponseDirOptions: Use `UrlReaderServiceReadTreeResponseDirOptions` from `@backstage/backend-plugin-api` instead; - - ReadTreeResponseFactory: Import from `@backstage/backend-defaults/urlReader` instead; - - ReadTreeResponseFactoryOptions: Import from `@backstage/backend-defaults/urlReader` instead; - - SearchOptions: Use `UrlReaderServiceSearchOptions` from `@backstage/backend-plugin-api` instead; - - SearchResponse: Use `UrlReaderServiceSearchResponse` from `@backstage/backend-plugin-api` instead; - - SearchResponseFile: Use `UrlReaderServiceSearchResponseFile` from `@backstage/backend-plugin-api` instead. - -### Patch Changes - -- ba8571e: Setup user agent header for AWS sdk clients, this enables users to better track API calls made from Backstage to AWS APIs through things like CloudTrail. -- 93095ee: Make sure node-fetch is version 2.7.0 or greater -- 6795e33: This package is marked as `deprecated` and will be removed in a near future, please follow the deprecated instructions for the exports you still use. -- 7e13b7a: The remaining exports in the package have now been deprecated: - - - `cacheToPluginCacheManager` - - `createLegacyAuthAdapters` - - `LegacyCreateRouter` - - `legacyPlugin` - - `loggerToWinstonLogger` - - `makeLegacyPlugin` - - Users of these export should fully [migrate to the new backend system](https://backstage.io/docs/backend-system/building-backends/migrating). - -- ddde5fe: Internal type refactor. -- b63d378: export `createConfigSecretEnumerator` from `@backstage/backend-common` instead of `@backstage/backend-app-api`. -- Updated dependencies - - @backstage/backend-plugin-api@0.8.0 - - @backstage/config-loader@1.9.0 - - @backstage/plugin-auth-node@0.5.0 - - @backstage/backend-dev-utils@0.1.5 - - @backstage/integration@1.14.0 - - @backstage/cli-common@0.1.14 - - @backstage/config@1.2.0 - - @backstage/errors@1.2.4 - - @backstage/integration-aws-node@0.1.12 - - @backstage/types@1.1.1 - -## 0.23.4-next.3 - -### Patch Changes - -- ddde5fe: Internal type refactor. -- Updated dependencies - - @backstage/backend-plugin-api@0.8.0-next.3 - - @backstage/backend-dev-utils@0.1.4 - - @backstage/cli-common@0.1.14 - - @backstage/config@1.2.0 - - @backstage/config-loader@1.9.0-next.2 - - @backstage/errors@1.2.4 - - @backstage/integration@1.14.0-next.0 - - @backstage/integration-aws-node@0.1.12 - - @backstage/types@1.1.1 - - @backstage/plugin-auth-node@0.5.0-next.3 - -## 0.23.4-next.2 - -### Patch Changes - -- 93095ee: Make sure node-fetch is version 2.7.0 or greater -- Updated dependencies - - @backstage/backend-plugin-api@0.8.0-next.2 - - @backstage/config-loader@1.9.0-next.2 - - @backstage/plugin-auth-node@0.5.0-next.2 - - @backstage/integration@1.14.0-next.0 - - @backstage/integration-aws-node@0.1.12 - - @backstage/backend-dev-utils@0.1.4 - - @backstage/cli-common@0.1.14 - - @backstage/config@1.2.0 - - @backstage/errors@1.2.4 - - @backstage/types@1.1.1 - -## 0.23.4-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/config-loader@1.9.0-next.1 - - @backstage/backend-plugin-api@0.7.1-next.1 - - @backstage/integration@1.14.0-next.0 - - @backstage/integration-aws-node@0.1.12 - - @backstage/backend-dev-utils@0.1.4 - - @backstage/cli-common@0.1.14 - - @backstage/config@1.2.0 - - @backstage/errors@1.2.4 - - @backstage/types@1.1.1 - - @backstage/plugin-auth-node@0.4.18-next.1 - -## 0.23.4-next.0 - -### Patch Changes - -- ba8571e: Setup user agent header for AWS sdk clients, this enables users to better track API calls made from Backstage to AWS APIs through things like CloudTrail. -- 7e13b7a: The remaining exports in the package have now been deprecated: - - - `cacheToPluginCacheManager` - - `createLegacyAuthAdapters` - - `LegacyCreateRouter` - - `legacyPlugin` - - `loggerToWinstonLogger` - - `makeLegacyPlugin` - - Users of these export should fully [migrate to the new backend system](https://backstage.io/docs/backend-system/building-backends/migrating). - -- Updated dependencies - - @backstage/integration@1.14.0-next.0 - - @backstage/config-loader@1.8.2-next.0 - - @backstage/backend-dev-utils@0.1.4 - - @backstage/backend-plugin-api@0.7.1-next.0 - - @backstage/cli-common@0.1.14 - - @backstage/config@1.2.0 - - @backstage/errors@1.2.4 - - @backstage/integration-aws-node@0.1.12 - - @backstage/types@1.1.1 - - @backstage/plugin-auth-node@0.4.18-next.0 - -## 0.23.3 - -### Patch Changes - -- 8c09c97: Deprecate legacy status check factory, handler and types. -- d228862: Update default backend plugin created by the cli to use non-deprecated error handling middleware -- c964a3d: Add dependencies that are needed by cross-imports from backend-defaults -- b60db08: Fixing exporting of classes properly from new packages -- b9ed1bb: bumped better-sqlite3 from ^9.0.0 to ^11.0.0 -- Updated dependencies - - @backstage/backend-plugin-api@0.7.0 - - @backstage/integration@1.13.0 - - @backstage/plugin-auth-node@0.4.17 - - @backstage/config-loader@1.8.1 - - @backstage/backend-dev-utils@0.1.4 - - @backstage/cli-common@0.1.14 - - @backstage/config@1.2.0 - - @backstage/errors@1.2.4 - - @backstage/integration-aws-node@0.1.12 - - @backstage/types@1.1.1 - -## 0.23.3-next.1 - -### Patch Changes - -- b9ed1bb: bumped better-sqlite3 from ^9.0.0 to ^11.0.0 -- Updated dependencies - - @backstage/backend-dev-utils@0.1.4 - - @backstage/backend-plugin-api@0.6.22-next.1 - - @backstage/cli-common@0.1.14 - - @backstage/config@1.2.0 - - @backstage/config-loader@1.8.1 - - @backstage/errors@1.2.4 - - @backstage/integration@1.13.0-next.0 - - @backstage/integration-aws-node@0.1.12 - - @backstage/types@1.1.1 - - @backstage/plugin-auth-node@0.4.17-next.1 - -## 0.23.2-next.0 - -### Patch Changes - -- 8c09c97: Deprecate legacy status check factory, handler and types. -- d228862: Update default backend plugin created by the cli to use non-deprecated error handling middleware -- c964a3d: Add dependencies that are needed by cross-imports from backend-defaults -- b60db08: Fixing exporting of classes properly from new packages -- Updated dependencies - - @backstage/backend-plugin-api@0.6.21-next.0 - - @backstage/integration@1.13.0-next.0 - - @backstage/plugin-auth-node@0.4.16-next.0 - - @backstage/backend-dev-utils@0.1.4 - - @backstage/cli-common@0.1.14 - - @backstage/config@1.2.0 - - @backstage/config-loader@1.8.1 - - @backstage/errors@1.2.4 - - @backstage/integration-aws-node@0.1.12 - - @backstage/types@1.1.1 - -## 0.23.0 - -### Minor Changes - -- 395b973: Implemented `readTree` for Harness provider to support TechDocs functionality -- 02103be: Deprecated and moved over core services to `@backstage/backend-defaults` - -### Patch Changes - -- 9539a0b: Import utility functions from `backend-defaults` instead of `backend-app-api` -- b2c4607: Removed accents on deprecation note -- c6c0919: Updated configuration schema to include the `useRedisSets` cache config option. -- ed3074e: The `database` types, helpers and implementations were moved to the package `@backstage/backend-defaults` and deprecated from the package `@backstage/backend-commons`. -- 9cca724: The `TokenManager` has been deprecated in preparation for the [stable release of the New Backend System](https://github.com/backstage/backstage/issues/24493). Please [migrate](https://backstage.io/docs/tutorials/auth-service-migration) to the new `coreServices.auth`, `coreServices.httpAuth`, and `coreServices.userInfo` services as needed instead. -- 1779188: In preparation to the new backend system stable release, the `isDatabaseConflictError` helper have been moved to the `@backstage/backend-plugin-api` package and deprecated from `@backstage/backend-common`. -- 78a0b08: Internal refactor to handle `BackendFeature` contract change. -- e171620: Move `cache` implementation and types to the `@backstage/backend-defaults` package. -- 1a6f38a: `ContainerRunner`, `DockerContainerRunner` and `KubernetesContainerRunner` are now deprecated -- 8869b8e: We are deprecating the legacy `createServiceBuilder` factory, so if you are still using it, please checkout the migration guide and [migrate](https://backstage.io/docs/backend-system/building-plugins-and-modules/migrating) your plugin to use the new backend system. -- 0634fdc: Deprecated `dropDatabase` -- b2ee7f3: Moved over all URL reader functionality from `@backstage/backend-common` to `@backstage/backend-defaults/urlReader`. Please update your imports. -- d94a477: Removed the circular dependency on `@backstage/backend-app-api` -- 3bd04bb: We are deprecating the legacy router handlers and contexts in preparation for the new backend system stable release. -- 23ee9ab: Fix AWS CodeCommit integration by allowing to change the host -- e9a03c9: Finalizes the deprecation of legacy backend utilities. Deprecated utilities include the `ServiceBuilder` type, `notFoundHandler` and `redactWintonLogLine` functions. -- 6a576dc: Deprecate legacy service logger helpers and stop using `getVoidLogger` in tests. -- 032a7a6: Deprecate the legacy error and request logging handler types, respectively: `ErrorHandlerOptions` and `RequestLoggingHandlerFactory`. -- Updated dependencies - - @backstage/backend-plugin-api@0.6.19 - - @backstage/plugin-auth-node@0.4.14 - - @backstage/integration@1.12.0 - - @backstage/cli-common@0.1.14 - - @backstage/config-loader@1.8.1 - - @backstage/backend-dev-utils@0.1.4 - - @backstage/config@1.2.0 - - @backstage/errors@1.2.4 - - @backstage/integration-aws-node@0.1.12 - - @backstage/types@1.1.1 - -## 0.23.0-next.3 - -### Patch Changes - -- b2ee7f3: Moved over all URL reader functionality from `@backstage/backend-common` to `@backstage/backend-defaults/urlReader`. Please update your imports. -- 23ee9ab: Fix AWS CodeCommit integration by allowing to change the host -- Updated dependencies - - @backstage/backend-plugin-api@0.6.19-next.3 - - @backstage/plugin-auth-node@0.4.14-next.3 - - @backstage/integration@1.12.0-next.1 - - @backstage/cli-common@0.1.14-next.0 - - @backstage/backend-app-api@0.7.6-next.3 - - @backstage/config-loader@1.8.1-next.0 - - @backstage/backend-dev-utils@0.1.4 - - @backstage/config@1.2.0 - - @backstage/errors@1.2.4 - - @backstage/integration-aws-node@0.1.12 - - @backstage/types@1.1.1 - -## 0.23.0-next.2 - -### Minor Changes - -- 395b973: Implemented `readTree` for Harness provider to support TechDocs functionality - -### Patch Changes - -- 0634fdc: Deprecated `dropDatabase` -- Updated dependencies - - @backstage/backend-plugin-api@0.6.19-next.2 - - @backstage/integration@1.12.0-next.0 - - @backstage/backend-app-api@0.7.6-next.2 - - @backstage/plugin-auth-node@0.4.14-next.2 - - @backstage/config-loader@1.8.0 - - @backstage/backend-dev-utils@0.1.4 - - @backstage/cli-common@0.1.13 - - @backstage/config@1.2.0 - - @backstage/errors@1.2.4 - - @backstage/integration-aws-node@0.1.12 - - @backstage/types@1.1.1 - -## 0.23.0-next.1 - -### Minor Changes - -- 02103be: Deprecated and moved over core services to `@backstage/backend-defaults` - -### Patch Changes - -- Updated dependencies - - @backstage/backend-app-api@0.7.6-next.1 - - @backstage/backend-plugin-api@0.6.19-next.1 - - @backstage/config-loader@1.8.0 - - @backstage/plugin-auth-node@0.4.14-next.1 - -## 0.22.1-next.0 - -### Patch Changes - -- c6c0919: Updated configuration schema to include the `useRedisSets` cache config option. -- 1779188: In preparation to the new backend system stable release, the `isDatabaseConflictError` helper have been moved to the `@backstage/backend-plugin-api` package and deprecated from `@backstage/backend-common`. -- 8869b8e: We are deprecating the legacy `createServiceBuilder` factory, so if you are still using it, please checkout the migration guide and [migrate](https://backstage.io/docs/backend-system/building-plugins-and-modules/migrating) your plugin to use the new backend system. -- 3bd04bb: We are deprecating the legacy router handlers and contexts in preparation for the new backend system stable release. -- 6a576dc: Deprecate legacy service logger helpers and stop using `getVoidLogger` in tests. -- Updated dependencies - - @backstage/backend-app-api@0.7.6-next.0 - - @backstage/backend-plugin-api@0.6.19-next.0 - - @backstage/plugin-auth-node@0.4.14-next.0 - - @backstage/config-loader@1.8.0 - - @backstage/backend-dev-utils@0.1.4 - - @backstage/cli-common@0.1.13 - - @backstage/config@1.2.0 - - @backstage/errors@1.2.4 - - @backstage/integration@1.11.0 - - @backstage/integration-aws-node@0.1.12 - - @backstage/types@1.1.1 - -## 0.22.0 - -### Minor Changes - -- ed83f85: Internal refactor of the database code. - - **BREAKING**: The helper functions `createDatabaseClient` and `ensureDatabaseExists` have been removed from the public interface, since they have no usage within the repository and never were suitable for calling from the outside. Please consider using `coreServices.database` or `DatabaseManager` directly wherever possible instead. - -### Patch Changes - -- 2cc750d: Added `HarnessURLReader` with `readUrl` support. -- 57f692e: Preparing for a stable new backend system release, we are deprecating utilities in the `backend-common` that are not used by the core framework, such as the isomorphic `Git` class. As we will no longer support the isomorphic `Git` utility in the framework packages, we recommend plugins that start maintaining their own implementation of this class. -- 0ec0796: Plugins created through the `legacyPlugin` helper are now able to authenticate requests from plugins that are fully implemented using the new backend system. This fixes the `Key for the ES256 algorithm must be one of type KeyObject or CryptoKey. Received an instance of Uint8Array` error. -- d229dc4: Move path utilities from `backend-common` to the `backend-plugin-api` package. -- ccc8851: Added config prop `ensureSchemaExists` to support postgres instances where user can create schemas but not databases. -- f66bbb4: Only create a single actual connection to memcache/redis, even in cases where many `CacheService` instances are made -- ba0b8b4: Added option to `ServerTokenManager.fromConfig` that allows it to be instantiated in production without any configured keys. -- Updated dependencies - - @backstage/backend-app-api@0.7.3 - - @backstage/backend-plugin-api@0.6.18 - - @backstage/plugin-auth-node@0.4.13 - - @backstage/integration@1.11.0 - -## 0.22.0-next.2 - -### Patch Changes - -- 2cc750d: Added `HarnessURLReader` with `readUrl` support. -- ccc8851: Added config prop `ensureSchemaExists` to support postgres instances where user can create schemas but not databases. -- Updated dependencies - - @backstage/integration@1.11.0-next.0 - -## 0.22.0-next.1 - -### Minor Changes - -- ed83f85: Internal refactor of the database code. - - **BREAKING**: The helper functions `createDatabaseClient` and `ensureDatabaseExists` have been removed from the public interface, since they have no usage within the repository and never were suitable for calling from the outside. Please consider using `coreServices.database` or `DatabaseManager` directly wherever possible instead. - -### Patch Changes - -- Updated dependencies - - @backstage/backend-app-api@0.7.2-next.1 - - @backstage/plugin-auth-node@0.4.13-next.1 - - @backstage/config-loader@1.8.0 - - @backstage/backend-plugin-api@0.6.18-next.1 - -## 0.21.8-next.0 - -### Patch Changes - -- ba0b8b4: Added option to `ServerTokenManager.fromConfig` that allows it to be instantiated in production without any configured keys. -- Updated dependencies - - @backstage/backend-app-api@0.7.1-next.0 - - @backstage/plugin-auth-node@0.4.13-next.0 - - @backstage/backend-plugin-api@0.6.18-next.0 - - @backstage/backend-dev-utils@0.1.4 - - @backstage/cli-common@0.1.13 - - @backstage/config@1.2.0 - - @backstage/config-loader@1.8.0 - - @backstage/errors@1.2.4 - - @backstage/integration@1.10.0 - - @backstage/integration-aws-node@0.1.12 - - @backstage/types@1.1.1 - -## 0.21.7 - -### Patch Changes - -- 007e7ea: Added placeholder for `listPublicServiceKeys()` in the `AuthService` returned by `createLegacyAuthAdapters`. -- 00fca28: Ensure that `ServerTokenManager` also reads the new `backend.auth.externalAccess` settings -- 25ea3d2: Minor internal restructuring -- e31bacc: Added `pullOptions` to `DockerContainerRunner#runContainer` method to pass down options when pulling an image. -- 7b11422: Add AWS CodeCommit URL Reader/Integration -- 75a53b8: KubernetesContainerRunner.runContainer no longer closes the `logStream` it receives as input. -- Updated dependencies - - @backstage/config-loader@1.8.0 - - @backstage/backend-app-api@0.7.0 - - @backstage/backend-plugin-api@0.6.17 - - @backstage/plugin-auth-node@0.4.12 - - @backstage/integration@1.10.0 - - @backstage/integration-aws-node@0.1.12 - - @backstage/backend-dev-utils@0.1.4 - - @backstage/cli-common@0.1.13 - - @backstage/config@1.2.0 - - @backstage/errors@1.2.4 - - @backstage/types@1.1.1 - -## 0.21.7-next.1 - -### Patch Changes - -- 007e7ea: Added placeholder for `listPublicServiceKeys()` in the `AuthService` returned by `createLegacyAuthAdapters`. -- 75a53b8: KubernetesContainerRunner.runContainer no longer closes the `logStream` it receives as input. -- Updated dependencies - - @backstage/backend-app-api@0.7.0-next.1 - - @backstage/backend-plugin-api@0.6.17-next.1 - - @backstage/plugin-auth-node@0.4.12-next.1 - - @backstage/backend-dev-utils@0.1.4 - - @backstage/cli-common@0.1.13 - - @backstage/config@1.2.0 - - @backstage/config-loader@1.8.0-next.0 - - @backstage/errors@1.2.4 - - @backstage/integration@1.10.0-next.0 - - @backstage/integration-aws-node@0.1.12 - - @backstage/types@1.1.1 - -## 0.21.7-next.0 - -### Patch Changes - -- 7b11422: Add AWS CodeCommit URL Reader/Integration -- Updated dependencies - - @backstage/backend-app-api@0.6.3-next.0 - - @backstage/integration@1.10.0-next.0 - - @backstage/config-loader@1.8.0-next.0 - - @backstage/backend-dev-utils@0.1.4 - - @backstage/backend-plugin-api@0.6.17-next.0 - - @backstage/cli-common@0.1.13 - - @backstage/config@1.2.0 - - @backstage/errors@1.2.4 - - @backstage/integration-aws-node@0.1.12 - - @backstage/types@1.1.1 - - @backstage/plugin-auth-node@0.4.12-next.0 - -## 0.21.6 - -### Patch Changes - -- 81a995f: Updated dependency `aws-sdk-client-mock` to `^4.0.0`. -- Updated dependencies - - @backstage/backend-app-api@0.6.2 - - @backstage/plugin-auth-node@0.4.11 - - @backstage/integration-aws-node@0.1.12 - - @backstage/backend-plugin-api@0.6.16 - - @backstage/backend-dev-utils@0.1.4 - - @backstage/cli-common@0.1.13 - - @backstage/config@1.2.0 - - @backstage/config-loader@1.7.0 - - @backstage/errors@1.2.4 - - @backstage/integration@1.9.1 - - @backstage/types@1.1.1 - -## 0.21.5 - -### Patch Changes - -- 81a995f: Updated dependency `aws-sdk-client-mock` to `^4.0.0`. -- Updated dependencies - - @backstage/backend-app-api@0.6.1 - - @backstage/integration-aws-node@0.1.11 - - @backstage/plugin-auth-node@0.4.10 - - @backstage/backend-dev-utils@0.1.4 - - @backstage/backend-plugin-api@0.6.15 - - @backstage/cli-common@0.1.13 - - @backstage/config@1.2.0 - - @backstage/config-loader@1.7.0 - - @backstage/errors@1.2.4 - - @backstage/integration@1.9.1 - - @backstage/types@1.1.1 - -## 0.21.4 - -### Patch Changes - -- 7422430: Resolve the `basePath` before constructing the target path -- 999224f: Bump dependency `minimatch` to v9 -- e0b997c: Fix issue where `resolveSafeChildPath` path would incorrectly resolve when operating on a symlink -- 9802004: Added the `UserInfoApi` as both an optional input and as an output for `createLegacyAuthAdapters` -- 2af5354: Bump dependency `jose` to v5 -- ff40ada: Updated dependency `mysql2` to `^3.0.0`. -- 0fb419b: Updated dependency `uuid` to `^9.0.0`. - Updated dependency `@types/uuid` to `^9.0.0`. -- 568881f: Updated dependency `yauzl` to `^3.0.0`. -- 4a3d434: Added a `createLegacyAuthAdapters` function that can be used as a compatibility adapter for backend plugins who want to start using the new [`auth`](https://backstage.io/docs/backend-system/core-services/auth/) and [`httpAuth`](https://backstage.io/docs/backend-system/core-services/http-auth) services that were created as part of [BEP-0003](https://github.com/backstage/backstage/tree/master/beps/0003-auth-architecture-evolution). - - See the [Auth Service Migration tutorial](https://backstage.io/docs/tutorials/auth-service-migration) for more information on the usage of this adapter. - -- Updated dependencies - - @backstage/integration@1.9.1 - - @backstage/plugin-auth-node@0.4.9 - - @backstage/config@1.2.0 - - @backstage/errors@1.2.4 - - @backstage/backend-plugin-api@0.6.14 - - @backstage/backend-app-api@0.6.0 - - @backstage/config-loader@1.7.0 - - @backstage/backend-dev-utils@0.1.4 - - @backstage/cli-common@0.1.13 - - @backstage/integration-aws-node@0.1.10 - - @backstage/types@1.1.1 - -## 0.21.4-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/integration@1.9.1-next.2 - - @backstage/backend-app-api@0.6.0-next.2 - - @backstage/plugin-auth-node@0.4.9-next.2 - - @backstage/backend-dev-utils@0.1.4 - - @backstage/backend-plugin-api@0.6.14-next.2 - - @backstage/cli-common@0.1.13 - - @backstage/config@1.2.0-next.1 - - @backstage/config-loader@1.7.0-next.1 - - @backstage/errors@1.2.4-next.0 - - @backstage/integration-aws-node@0.1.10-next.1 - - @backstage/types@1.1.1 - -## 0.21.4-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.2.0-next.1 - - @backstage/config-loader@1.7.0-next.1 - - @backstage/backend-app-api@0.6.0-next.1 - - @backstage/backend-plugin-api@0.6.14-next.1 - - @backstage/integration@1.9.1-next.1 - - @backstage/integration-aws-node@0.1.10-next.1 - - @backstage/plugin-auth-node@0.4.9-next.1 - - @backstage/backend-dev-utils@0.1.4 - - @backstage/cli-common@0.1.13 - - @backstage/errors@1.2.4-next.0 - - @backstage/types@1.1.1 - -## 0.21.3-next.0 - -### Patch Changes - -- 7422430: Resolve the `basePath` before constructing the target path -- 999224f: Bump dependency `minimatch` to v9 -- e0b997c: Fix issue where `resolveSafeChildPath` path would incorrectly resolve when operating on a symlink -- 9802004: Added the `UserInfoApi` as both an optional input and as an output for `createLegacyAuthAdapters` -- 2af5354: Bump dependency `jose` to v5 -- ff40ada: Updated dependency `mysql2` to `^3.0.0`. -- 0fb419b: Updated dependency `uuid` to `^9.0.0`. - Updated dependency `@types/uuid` to `^9.0.0`. -- 568881f: Updated dependency `yauzl` to `^3.0.0`. -- 4a3d434: Added a `createLegacyAuthAdapters` function that can be used as a compatibility adapter for backend plugins who want to start using the new [`auth`](https://backstage.io/docs/backend-system/core-services/auth/) and [`httpAuth`](https://backstage.io/docs/backend-system/core-services/http-auth) services that were created as part of [BEP-0003](https://github.com/backstage/backstage/tree/master/beps/0003-auth-architecture-evolution). - - See the [Auth Service Migration tutorial](https://backstage.io/docs/tutorials/auth-service-migration) for more information on the usage of this adapter. - -- Updated dependencies - - @backstage/plugin-auth-node@0.4.8-next.0 - - @backstage/errors@1.2.4-next.0 - - @backstage/backend-plugin-api@0.6.13-next.0 - - @backstage/backend-app-api@0.6.0-next.0 - - @backstage/config-loader@1.6.3-next.0 - - @backstage/config@1.1.2-next.0 - - @backstage/integration@1.9.1-next.0 - - @backstage/integration-aws-node@0.1.10-next.0 - - @backstage/backend-dev-utils@0.1.4 - - @backstage/cli-common@0.1.13 - - @backstage/types@1.1.1 - -## 0.21.0 - -### Minor Changes - -- bbe374e: **BREAKING**: `A gitilesBaseUrl` must be provided for the Gerrit integration to work. - You can disable this check by setting `DISABLE_GERRIT_GITILES_REQUIREMENT=1` but - this will be removed in a future release. If you are not able to use the Gitiles - Gerrit plugin, please open an issue towards `https://github.com/backstage/backstage` -- e85aa98: drop databases after unit tests if the database instance is not running in docker - -### Patch Changes - -- 6707216: Added a new `LegacyRootDatabaseService` interface that can be used to avoid direct dependencies on the `DatabaseManager`. -- 842171a: Fix a bug with S3 Fetch that caused all objects to be flattened within a single folder on the local file system. -- 3489d05: `FetchUrlReader#readUrl()` now supports passing an optional `token` to authenticate requests. -- 9aac2b0: Use `--cwd` as the first `yarn` argument -- ece5a8f: Add a User-Agent header for calls towards Google Cloud Storage. -- 1f020fe: Support `token` in `readTree`, `readUrl` and `search` -- 6bb6f3e: Updated dependency `fs-extra` to `^11.2.0`. - Updated dependency `@types/fs-extra` to `^11.0.0`. -- d2e3ab9: Updated dependency `dockerode` to `^4.0.0`. -- 1cae748: Updated dependency `git-url-parse` to `^14.0.0`. -- e27b7f3: Fix rate limit detection by looking for HTTP status code 429 and updating the header `x-ratelimit-remaining` to look for in case of a 403 code is returned -- 7fb7a79: Add a config declaration for `workingDirectory` -- Updated dependencies - - @backstage/backend-app-api@0.5.11 - - @backstage/backend-plugin-api@0.6.10 - - @backstage/backend-dev-utils@0.1.4 - - @backstage/integration-aws-node@0.1.9 - - @backstage/integration@1.9.0 - - @backstage/config-loader@1.6.2 - - @backstage/cli-common@0.1.13 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - -## 0.21.0-next.3 - -### Minor Changes - -- bbe374e: **BREAKING**: `A gitilesBaseUrl` must be provided for the Gerrit integration to work. - You can disable this check by setting `DISABLE_GERRIT_GITILES_REQUIREMENT=1` but - this will be removed in a future release. If you are not able to use the Gitiles - Gerrit plugin, please open an issue towards `https://github.com/backstage/backstage` - -### Patch Changes - -- 6707216: Added a new `LegacyRootDatabaseService` interface that can be used to avoid direct dependencies on the `DatabaseManager`. -- 842171a: Fix a bug with S3 Fetch that caused all objects to be flattened within a single folder on the local file system. -- ece5a8f: Add a User-Agent header for calls towards Google Cloud Storage. -- 1cae748: Updated dependency `git-url-parse` to `^14.0.0`. -- Updated dependencies - - @backstage/integration-aws-node@0.1.9-next.0 - - @backstage/integration@1.9.0-next.1 - - @backstage/backend-app-api@0.5.11-next.3 - - @backstage/config-loader@1.6.2-next.0 - - @backstage/backend-dev-utils@0.1.4-next.0 - - @backstage/backend-plugin-api@0.6.10-next.3 - - @backstage/cli-common@0.1.13 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - -## 0.21.0-next.2 - -### Patch Changes - -- 3489d05: `FetchUrlReader#readUrl()` now supports passing an optional `token` to authenticate requests. -- 9aac2b0: Use `--cwd` as the first `yarn` argument -- 7fb7a79: Add a config declaration for `workingDirectory` -- Updated dependencies - - @backstage/backend-plugin-api@0.6.10-next.2 - - @backstage/backend-dev-utils@0.1.4-next.0 - - @backstage/backend-app-api@0.5.11-next.2 - - @backstage/config@1.1.1 - - @backstage/integration-aws-node@0.1.8 - - @backstage/cli-common@0.1.13 - - @backstage/config-loader@1.6.1 - - @backstage/errors@1.2.3 - - @backstage/integration@1.9.0-next.0 - - @backstage/types@1.1.1 - -## 0.21.0-next.1 - -### Patch Changes - -- 1f020fe: Support `token` in `readTree`, `readUrl` and `search` -- e27b7f3: Fix rate limit detection by looking for HTTP status code 429 and updating the header `x-ratelimit-remaining` to look for in case of a 403 code is returned -- Updated dependencies - - @backstage/backend-plugin-api@0.6.10-next.1 - - @backstage/integration@1.9.0-next.0 - - @backstage/backend-app-api@0.5.11-next.1 - - @backstage/backend-dev-utils@0.1.3 - - @backstage/cli-common@0.1.13 - - @backstage/config@1.1.1 - - @backstage/config-loader@1.6.1 - - @backstage/errors@1.2.3 - - @backstage/integration-aws-node@0.1.8 - - @backstage/types@1.1.1 - -## 0.21.0-next.0 - -### Minor Changes - -- e85aa98: drop databases after unit tests if the database instance is not running in docker - -### Patch Changes - -- Updated dependencies - - @backstage/backend-app-api@0.5.11-next.0 - - @backstage/config-loader@1.6.1 - - @backstage/backend-dev-utils@0.1.3 - - @backstage/backend-plugin-api@0.6.10-next.0 - - @backstage/cli-common@0.1.13 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/integration@1.8.0 - - @backstage/integration-aws-node@0.1.8 - - @backstage/types@1.1.1 - -## 0.20.1 - -### Patch Changes - -- 3b24eae: Adding support for removing file from git index -- 454d17c: Do not call fetch directly but rather use `fetchResponse` facility -- b6b15b2: Use sha256 instead of md5 for hash key calculation in caches - - This can have a side effect of invalidating caches (when cache key was >250 characters) - This improves compliance with FIPS nodejs - -- Updated dependencies - - @backstage/config-loader@1.6.1 - - @backstage/backend-plugin-api@0.6.9 - - @backstage/backend-dev-utils@0.1.3 - - @backstage/backend-app-api@0.5.10 - - @backstage/cli-common@0.1.13 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/integration@1.8.0 - - @backstage/integration-aws-node@0.1.8 - - @backstage/types@1.1.1 - -## 0.20.1-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-plugin-api@0.6.9-next.2 - - @backstage/backend-dev-utils@0.1.3-next.0 - - @backstage/backend-app-api@0.5.10-next.2 - - @backstage/config-loader@1.6.1-next.0 - -## 0.20.1-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/config-loader@1.6.1-next.0 - - @backstage/backend-app-api@0.5.10-next.1 - - @backstage/integration@1.8.0 - - @backstage/integration-aws-node@0.1.8 - - @backstage/config@1.1.1 - - @backstage/backend-dev-utils@0.1.2 - - @backstage/backend-plugin-api@0.6.9-next.1 - - @backstage/cli-common@0.1.13 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - -## 0.20.1-next.0 - -### Patch Changes - -- b6b15b2: Use sha256 instead of md5 for hash key calculation in caches - - This can have a side effect of invalidating caches (when cache key was >250 characters) - This improves compliance with FIPS nodejs - -- Updated dependencies - - @backstage/backend-app-api@0.5.10-next.0 - - @backstage/backend-dev-utils@0.1.2 - - @backstage/backend-plugin-api@0.6.9-next.0 - - @backstage/cli-common@0.1.13 - - @backstage/config@1.1.1 - - @backstage/config-loader@1.6.0 - - @backstage/errors@1.2.3 - - @backstage/integration@1.8.0 - - @backstage/integration-aws-node@0.1.8 - - @backstage/types@1.1.1 - -## 0.20.0 - -### Minor Changes - -- 870db76: Implemented `readTree` for Gitea provider to support TechDocs functionality - -### Patch Changes - -- 7f04128: Allow a default cache TTL to be set through the app config -- 1ad8906: Use `Readable.from` to fix some of the stream issues -- d86a007: Fixed the AwsS3UrlReader host regex and host to allow the S3 reading for CN AWS domain -- bc67498: Updated dependency `archiver` to `^6.0.0`. - Updated dependency `@types/archiver` to `^6.0.0`. -- 706fc3a: Updated dependency `@kubernetes/client-node` to `0.20.0`. -- 2666675: Updated dependency `@google-cloud/storage` to `^7.0.0`. -- d15d483: Add command `--runAsDefaultUser` for `@techdocs/cli generate` to bypass running the docker builds as host user for macOS and Linux. -- d1e00aa: Expose an `onAuth` handler for `git` actions to provide custom credentials -- Updated dependencies - - @backstage/config-loader@1.6.0 - - @backstage/backend-app-api@0.5.9 - - @backstage/integration@1.8.0 - - @backstage/backend-dev-utils@0.1.2 - - @backstage/backend-plugin-api@0.6.8 - - @backstage/cli-common@0.1.13 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/integration-aws-node@0.1.8 - - @backstage/types@1.1.1 - -## 0.20.0-next.3 - -### Patch Changes - -- d86a007: Fixed the AwsS3UrlReader host regex and host to allow the S3 reading for CN AWS domain -- Updated dependencies - - @backstage/backend-app-api@0.5.9-next.3 - - @backstage/backend-dev-utils@0.1.2 - - @backstage/backend-plugin-api@0.6.8-next.3 - - @backstage/cli-common@0.1.13 - - @backstage/config@1.1.1 - - @backstage/config-loader@1.6.0-next.0 - - @backstage/errors@1.2.3 - - @backstage/integration@1.8.0-next.1 - - @backstage/integration-aws-node@0.1.8 - - @backstage/types@1.1.1 - -## 0.20.0-next.2 - -### Patch Changes - -- bc67498: Updated dependency `archiver` to `^6.0.0`. - Updated dependency `@types/archiver` to `^6.0.0`. -- Updated dependencies - - @backstage/config-loader@1.6.0-next.0 - - @backstage/backend-app-api@0.5.9-next.2 - - @backstage/backend-dev-utils@0.1.2 - - @backstage/backend-plugin-api@0.6.8-next.2 - - @backstage/cli-common@0.1.13 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/integration@1.8.0-next.1 - - @backstage/integration-aws-node@0.1.8 - - @backstage/types@1.1.1 - -## 0.20.0-next.1 - -### Patch Changes - -- 2666675457: Updated dependency `@google-cloud/storage` to `^7.0.0`. -- Updated dependencies - - @backstage/backend-app-api@0.5.9-next.1 - - @backstage/integration@1.8.0-next.1 - - @backstage/backend-dev-utils@0.1.2 - - @backstage/backend-plugin-api@0.6.8-next.1 - - @backstage/cli-common@0.1.13 - - @backstage/config@1.1.1 - - @backstage/config-loader@1.5.3 - - @backstage/errors@1.2.3 - - @backstage/integration-aws-node@0.1.8 - - @backstage/types@1.1.1 - -## 0.20.0-next.0 - -### Minor Changes - -- 870db76a45: Implemented `readTree` for Gitea provider to support TechDocs functionality - -### Patch Changes - -- 7f04128bbc: Allow a default cache TTL to be set through the app config -- 1ad8906a9e: Use `Readable.from` to fix some of the stream issues -- 706fc3a7e1: Updated dependency `@kubernetes/client-node` to `0.20.0`. -- d15d483a49: Add command `--runAsDefaultUser` for `@techdocs/cli generate` to bypass running the docker builds as host user for macOS and Linux. -- d1e00aa17a: Expose an `onAuth` handler for `git` actions to provide custom credentials -- Updated dependencies - - @backstage/integration@1.8.0-next.0 - - @backstage/backend-app-api@0.5.9-next.0 - - @backstage/backend-plugin-api@0.6.8-next.0 - - @backstage/backend-dev-utils@0.1.2 - - @backstage/cli-common@0.1.13 - - @backstage/config@1.1.1 - - @backstage/config-loader@1.5.3 - - @backstage/errors@1.2.3 - - @backstage/integration-aws-node@0.1.8 - - @backstage/types@1.1.1 - -## 0.19.9 - -### Patch Changes - -- aa13482090: Limit the database creation concurrency to one, defensively -- 013611b42e: `knex` has been bumped to major version 3 and `better-sqlite3` to major version 9, which deprecate node 16 support. -- 3d043526f4: Updated dependency `aws-sdk-client-mock` to `^3.0.0`. -- Updated dependencies - - @backstage/config-loader@1.5.3 - - @backstage/integration@1.7.2 - - @backstage/backend-plugin-api@0.6.7 - - @backstage/integration-aws-node@0.1.8 - - @backstage/backend-app-api@0.5.8 - - @backstage/backend-dev-utils@0.1.2 - - @backstage/cli-common@0.1.13 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - -## 0.19.9-next.2 - -### Patch Changes - -- [#20570](https://github.com/backstage/backstage/pull/20570) [`013611b42e`](https://github.com/backstage/backstage/commit/013611b42ed457fefa9bb85fddf416cf5e0c1f76) Thanks [@freben](https://github.com/freben)! - `knex` has been bumped to major version 3 and `better-sqlite3` to major version 9, which deprecate node 16 support. - -- Updated dependencies - - @backstage/backend-plugin-api@0.6.7-next.2 - - @backstage/backend-app-api@0.5.8-next.2 - - @backstage/config-loader@1.5.3-next.0 - -## 0.19.9-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/integration@1.7.2-next.0 - - @backstage/backend-app-api@0.5.8-next.1 - - @backstage/config-loader@1.5.3-next.0 - - @backstage/backend-dev-utils@0.1.2 - - @backstage/backend-plugin-api@0.6.7-next.1 - - @backstage/cli-common@0.1.13 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/integration-aws-node@0.1.7 - - @backstage/types@1.1.1 - -## 0.19.9-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/config-loader@1.5.2-next.0 - - @backstage/backend-app-api@0.5.8-next.0 - - @backstage/integration@1.7.1 - - @backstage/integration-aws-node@0.1.7 - - @backstage/backend-dev-utils@0.1.2 - - @backstage/backend-plugin-api@0.6.7-next.0 - - @backstage/cli-common@0.1.13 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - -## 0.19.8 - -### Patch Changes - -- 74491c9602: The `HostDiscovery` export has been deprecated, import it from `@backstage/backend-app-api` instead. -- b95d66d4ea: Properly close write stream when writing temporary archive for processing zip-based `.readTree()` responses. -- b94f32271e: Added the ability to fetch git tags through the `Git` class. This is useful for scaffolder actions that want to take action based on tag versions in a cloned repository -- 0b55f773a7: Removed some unused dependencies -- 4c39e38f1e: Added `/testUtils` entry point, with a utility for mocking resolve package paths as returned by `resolvePackagePath`. -- 9101c0d1b6: Updated dependency `@kubernetes/client-node` to `0.19.0`. -- a250ad775f: Removed `mock-fs` dev dependency. -- 2a40cd46a8: Adds the optional flag for useRedisSets for the Redis cache to the config. -- 1c3d6fa2b2: The `useHotCleanup` and `useHotMemoize` helpers are now deprecated, since hot module reloads for backend are being phased out. -- Updated dependencies - - @backstage/integration@1.7.1 - - @backstage/backend-dev-utils@0.1.2 - - @backstage/config-loader@1.5.1 - - @backstage/errors@1.2.3 - - @backstage/cli-common@0.1.13 - - @backstage/backend-app-api@0.5.6 - - @backstage/backend-plugin-api@0.6.6 - - @backstage/config@1.1.1 - - @backstage/integration-aws-node@0.1.7 - - @backstage/types@1.1.1 - -## 0.19.8-next.2 - -### Patch Changes - -- 74491c9602: The `HostDiscovery` export has been deprecated, import it from `@backstage/backend-app-api` instead. -- b95d66d4ea: Properly close write stream when writing temporary archive for processing zip-based `.readTree()` responses. -- 0b55f773a7: Removed some unused dependencies -- 4c39e38f1e: Added `/testUtils` entry point, with a utility for mocking resolve package paths as returned by `resolvePackagePath`. -- a250ad775f: Removed `mock-fs` dev dependency. -- Updated dependencies - - @backstage/config-loader@1.5.1-next.1 - - @backstage/integration@1.7.1-next.1 - - @backstage/errors@1.2.3-next.0 - - @backstage/backend-app-api@0.5.6-next.2 - - @backstage/backend-dev-utils@0.1.2-next.0 - - @backstage/backend-plugin-api@0.6.6-next.2 - - @backstage/cli-common@0.1.13-next.0 - - @backstage/config@1.1.1-next.0 - - @backstage/integration-aws-node@0.1.7-next.0 - - @backstage/types@1.1.1 - -## 0.19.7-next.1 - -### Patch Changes - -- b94f32271e: Added the ability to fetch git tags through the `Git` class. This is useful for scaffolder actions that want to take action based on tag versions in a cloned repository -- Updated dependencies - - @backstage/backend-dev-utils@0.1.2-next.0 - - @backstage/backend-app-api@0.5.5-next.1 - - @backstage/backend-plugin-api@0.6.5-next.1 - - @backstage/config@1.1.0 - - @backstage/integration-aws-node@0.1.6 - - @backstage/cli-common@0.1.13-next.0 - - @backstage/config-loader@1.5.1-next.0 - - @backstage/errors@1.2.2 - - @backstage/integration@1.7.1-next.0 - - @backstage/types@1.1.1 - -## 0.19.7-next.0 - -### Patch Changes - -- 1c3d6fa2b2: The `useHotCleanup` and `useHotMemoize` helpers are now deprecated, since hot module reloads for backend are being phased out. -- Updated dependencies - - @backstage/integration@1.7.1-next.0 - - @backstage/config-loader@1.5.1-next.0 - - @backstage/cli-common@0.1.13-next.0 - - @backstage/config@1.1.0 - - @backstage/integration-aws-node@0.1.6 - - @backstage/backend-app-api@0.5.5-next.0 - - @backstage/backend-dev-utils@0.1.1 - - @backstage/backend-plugin-api@0.6.5-next.0 - - @backstage/errors@1.2.2 - - @backstage/types@1.1.1 - -## 0.19.5 - -### Patch Changes - -- 6847cd6225d6: Avoid starting database keepalive loop in tests. -- fd3fdd0e3338: The root logger is now initialized lazily, fixing a circular dependency issue with `@backstage/backend-app-api` that would result in `Cannot read properties of undefined (reading 'redacter')`. -- 5f1a92b9f19f: Use `DefaultAzureDevOpsCredentialsProvider` to retrieve credentials for Azure DevOps. -- 19a140418cc8: Added retries for initial database creation, as well as set minimum connection pool size for the database creation client to 0 and lowered the connection acquisition timeout. -- 05508a9757d2: Minor internal refactor -- cfc3ca6ce060: Changes needed to support MySQL -- Updated dependencies - - @backstage/backend-app-api@0.5.3 - - @backstage/config@1.1.0 - - @backstage/errors@1.2.2 - - @backstage/integration@1.7.0 - - @backstage/types@1.1.1 - - @backstage/backend-plugin-api@0.6.3 - - @backstage/config-loader@1.5.0 - - @backstage/backend-dev-utils@0.1.1 - - @backstage/cli-common@0.1.12 - - @backstage/integration-aws-node@0.1.6 - -## 0.19.5-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-app-api@0.5.3-next.3 - - @backstage/config@1.1.0-next.2 - - @backstage/errors@1.2.2-next.0 - - @backstage/integration@1.7.0-next.3 - - @backstage/types@1.1.1-next.0 - - @backstage/backend-plugin-api@0.6.3-next.3 - - @backstage/backend-dev-utils@0.1.1 - - @backstage/cli-common@0.1.12 - - @backstage/config-loader@1.5.0-next.3 - - @backstage/integration-aws-node@0.1.6-next.2 - -## 0.19.5-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-app-api@0.5.3-next.2 - - @backstage/config-loader@1.5.0-next.2 - - @backstage/config@1.1.0-next.1 - - @backstage/integration@1.7.0-next.2 - - @backstage/integration-aws-node@0.1.6-next.1 - - @backstage/backend-plugin-api@0.6.3-next.2 - - @backstage/backend-dev-utils@0.1.1 - - @backstage/cli-common@0.1.12 - - @backstage/errors@1.2.1 - - @backstage/types@1.1.0 - -## 0.19.5-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.1.0-next.0 - - @backstage/integration@1.7.0-next.1 - - @backstage/backend-app-api@0.5.3-next.1 - - @backstage/backend-plugin-api@0.6.3-next.1 - - @backstage/config-loader@1.5.0-next.1 - - @backstage/integration-aws-node@0.1.6-next.0 - - @backstage/backend-dev-utils@0.1.1 - - @backstage/cli-common@0.1.12 - - @backstage/errors@1.2.1 - - @backstage/types@1.1.0 - -## 0.19.4-next.0 - -### Patch Changes - -- 5f1a92b9f19f: Use `DefaultAzureDevOpsCredentialsProvider` to retrieve credentials for Azure DevOps. -- cfc3ca6ce060: Changes needed to support MySQL -- Updated dependencies - - @backstage/integration@1.7.0-next.0 - - @backstage/config-loader@1.5.0-next.0 - - @backstage/backend-app-api@0.5.2-next.0 - - @backstage/backend-dev-utils@0.1.1 - - @backstage/backend-plugin-api@0.6.2-next.0 - - @backstage/cli-common@0.1.12 - - @backstage/config@1.0.8 - - @backstage/errors@1.2.1 - - @backstage/integration-aws-node@0.1.5 - - @backstage/types@1.1.0 - -## 0.19.2 - -### Patch Changes - -- 629cbd194a87: Use `coreServices.rootConfig` instead of `coreService.config` -- 443afcf7f567: To improve performance, `GerritUrlReader.readTree()` now uses Gitiles to fetch an archive instead of cloning the repository. - If `gitilesBaseUrl` is not configured, `readTree` still uses Git to clone the repository. - - Added `stripFirstDirectory` option to `ReadTreeResponseFactory.fromTarArchive()`, allowing to disable stripping first directory - for `tar` archives. - -- 4b82382ed8c2: Fixed invalid configuration schema. The configuration schema may be more strict as a result. -- Updated dependencies - - @backstage/backend-app-api@0.5.0 - - @backstage/config-loader@1.4.0 - - @backstage/backend-plugin-api@0.6.0 - - @backstage/integration@1.6.0 - - @backstage/integration-aws-node@0.1.5 - - @backstage/backend-dev-utils@0.1.1 - - @backstage/cli-common@0.1.12 - - @backstage/config@1.0.8 - - @backstage/errors@1.2.1 - - @backstage/types@1.1.0 - -## 0.19.2-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-app-api@0.5.0-next.2 - - @backstage/backend-plugin-api@0.6.0-next.2 - - @backstage/config-loader@1.4.0-next.1 - -## 0.19.2-next.1 - -### Patch Changes - -- 629cbd194a87: Use `coreServices.rootConfig` instead of `coreService.config` -- 4b82382ed8c2: Fixed invalid configuration schema. The configuration schema may be more strict as a result. -- Updated dependencies - - @backstage/config-loader@1.4.0-next.1 - - @backstage/backend-app-api@0.5.0-next.1 - - @backstage/backend-plugin-api@0.6.0-next.1 - - @backstage/integration@1.5.1 - - @backstage/integration-aws-node@0.1.5 - - @backstage/backend-dev-utils@0.1.1 - - @backstage/cli-common@0.1.12 - - @backstage/config@1.0.8 - - @backstage/errors@1.2.1 - - @backstage/types@1.1.0 - -## 0.19.2-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/config-loader@1.4.0-next.0 - - @backstage/backend-app-api@0.4.6-next.0 - - @backstage/backend-dev-utils@0.1.1 - - @backstage/backend-plugin-api@0.5.5-next.0 - - @backstage/cli-common@0.1.12 - - @backstage/config@1.0.8 - - @backstage/errors@1.2.1 - - @backstage/integration@1.5.1 - - @backstage/integration-aws-node@0.1.5 - - @backstage/types@1.1.0 - -## 0.19.1 - -### Patch Changes - -- 787ddcc5ef99: use `Readable.from` to explicitly convert the `buffer` from `node-fetch` to a `Readable` stream -- Updated dependencies - - @backstage/errors@1.2.1 - - @backstage/backend-app-api@0.4.5 - - @backstage/backend-dev-utils@0.1.1 - - @backstage/backend-plugin-api@0.5.4 - - @backstage/cli-common@0.1.12 - - @backstage/config@1.0.8 - - @backstage/config-loader@1.3.2 - - @backstage/integration@1.5.1 - - @backstage/integration-aws-node@0.1.5 - - @backstage/types@1.1.0 - -## 0.19.1-next.0 - -### Patch Changes - -- 787ddcc5ef99: use `Readable.from` to explicitly convert the `buffer` from `node-fetch` to a `Readable` stream -- Updated dependencies - - @backstage/errors@1.2.1-next.0 - - @backstage/backend-app-api@0.4.5-next.0 - - @backstage/backend-dev-utils@0.1.1 - - @backstage/backend-plugin-api@0.5.4-next.0 - - @backstage/cli-common@0.1.12 - - @backstage/config@1.0.8 - - @backstage/config-loader@1.3.2-next.0 - - @backstage/integration@1.5.1-next.0 - - @backstage/integration-aws-node@0.1.5-next.0 - - @backstage/types@1.1.0 - -## 0.19.0 - -### Minor Changes - -- c7f848bcea3c: Support authentication with a service principal or managed identity for Azure DevOps - - Azure DevOps recently released support, in public preview, for authenticating with a service principal or managed identity instead of a personal access token (PAT): https://devblogs.microsoft.com/devops/introducing-service-principal-and-managed-identity-support-on-azure-devops/. With this change the Azure integration now supports service principals and managed identities for Azure AD backed Azure DevOps organizations. Service principal and managed identity authentication is not supported on Azure DevOps Server (on-premises) organizations. - -### Patch Changes - -- 4ef91ab46732: Updated the backend database connection configuration schema to set the password visibility to secret -- 52d599817680: Changed the default backend CacheClient to an in-memory cache when not explicitly configured. - - Explicit configuration of an **in-memory cache** can be removed from `app-config.yaml`, as this is now the default: - - ```diff - backend: - - cache: - - store: memory - ``` - -- 5f2c38c70f5b: Fix SNYK-JS-FASTXMLPARSER-5668858 (`fast-xml-parser`) by upgrading aws-sdk to at least the current latest version. -- eeb3f801fddf: `HostDiscovery` now strips trailing slashes in the `backend.baseUrl` config. -- 9f47a743632c: Fixed typo in HostDiscovery's JSDoc -- 810c6de51604: Remove unused dev dependency `aws-sdk-mock`. -- Updated dependencies - - @backstage/types@1.1.0 - - @backstage/integration-aws-node@0.1.4 - - @backstage/config-loader@1.3.1 - - @backstage/integration@1.5.0 - - @backstage/errors@1.2.0 - - @backstage/backend-app-api@0.4.4 - - @backstage/backend-plugin-api@0.5.3 - - @backstage/backend-dev-utils@0.1.1 - - @backstage/cli-common@0.1.12 - - @backstage/config@1.0.8 - -## 0.19.0-next.2 - -### Patch Changes - -- 5f2c38c70f5b: Fix SNYK-JS-FASTXMLPARSER-5668858 (`fast-xml-parser`) by upgrading aws-sdk to at least the current latest version. -- Updated dependencies - - @backstage/integration-aws-node@0.1.4-next.1 - - @backstage/backend-app-api@0.4.4-next.2 - - @backstage/backend-dev-utils@0.1.1 - - @backstage/backend-plugin-api@0.5.3-next.2 - - @backstage/cli-common@0.1.12 - - @backstage/config@1.0.7 - - @backstage/config-loader@1.3.1-next.1 - - @backstage/errors@1.2.0-next.0 - - @backstage/integration@1.5.0-next.0 - - @backstage/types@1.0.2 - -## 0.19.0-next.1 - -### Minor Changes - -- c7f848bcea3c: Support authentication with a service principal or managed identity for Azure DevOps - - Azure DevOps recently released support, in public preview, for authenticating with a service principal or managed identity instead of a personal access token (PAT): https://devblogs.microsoft.com/devops/introducing-service-principal-and-managed-identity-support-on-azure-devops/. With this change the Azure integration now supports service principals and managed identities for Azure AD backed Azure DevOps organizations. Service principal and managed identity authentication is not supported on Azure DevOps Server (on-premises) organizations. - -### Patch Changes - -- 4ef91ab46732: Updated the backend database connection configuration schema to set the password visibility to secret -- 9f47a743632c: Fixed typo in HostDiscovery's JSDoc -- Updated dependencies - - @backstage/integration@1.5.0-next.0 - - @backstage/errors@1.2.0-next.0 - - @backstage/backend-app-api@0.4.4-next.1 - - @backstage/backend-plugin-api@0.5.3-next.1 - - @backstage/config-loader@1.3.1-next.1 - - @backstage/integration-aws-node@0.1.4-next.0 - - @backstage/backend-dev-utils@0.1.1 - - @backstage/cli-common@0.1.12 - - @backstage/config@1.0.7 - - @backstage/types@1.0.2 - -## 0.18.6-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/config-loader@1.3.1-next.0 - - @backstage/backend-app-api@0.4.4-next.0 - - @backstage/integration@1.4.5 - - @backstage/integration-aws-node@0.1.3 - - @backstage/config@1.0.7 - - @backstage/backend-dev-utils@0.1.1 - - @backstage/backend-plugin-api@0.5.3-next.0 - - @backstage/cli-common@0.1.12 - - @backstage/errors@1.1.5 - - @backstage/types@1.0.2 - -## 0.18.5 - -### Patch Changes - -- 0297f7a54af: Remove the direct dependency on deprecated "request" library -- 284db225083: Updated the `DatabaseManager` to include the plugin id in the Postgres application name of the database connections created for each plugin. -- 3659c71c5d9: Standardize `@aws-sdk` v3 versions -- 42d817e76ab: Added `HostDiscovery` to supersede deprecated `SingleHostDiscovery` (deprecated due to name) -- Updated dependencies - - @backstage/config-loader@1.3.0 - - @backstage/integration@1.4.5 - - @backstage/integration-aws-node@0.1.3 - - @backstage/backend-app-api@0.4.3 - - @backstage/backend-dev-utils@0.1.1 - - @backstage/backend-plugin-api@0.5.2 - - @backstage/cli-common@0.1.12 - - @backstage/config@1.0.7 - - @backstage/errors@1.1.5 - - @backstage/types@1.0.2 - -## 0.18.5-next.1 - -### Patch Changes - -- 0297f7a54af: Remove the direct dependency on deprecated "request" library -- Updated dependencies - - @backstage/backend-app-api@0.4.3-next.1 - - @backstage/backend-plugin-api@0.5.2-next.1 - - @backstage/config-loader@1.3.0-next.0 - - @backstage/config@1.0.7 - - @backstage/integration-aws-node@0.1.2 - -## 0.18.5-next.0 - -### Patch Changes - -- 284db225083: Updated the `DatabaseManager` to include the plugin id in the Postgres application name of the database connections created for each plugin. -- 42d817e76ab: Added `HostDiscovery` to supersede deprecated `SingleHostDiscovery` (deprecated due to name) -- Updated dependencies - - @backstage/integration@1.4.5-next.0 - - @backstage/backend-app-api@0.4.3-next.0 - - @backstage/config-loader@1.3.0-next.0 - - @backstage/integration-aws-node@0.1.2 - - @backstage/backend-plugin-api@0.5.2-next.0 - - @backstage/backend-dev-utils@0.1.1 - - @backstage/cli-common@0.1.12 - - @backstage/config@1.0.7 - - @backstage/errors@1.1.5 - - @backstage/types@1.0.2 - -## 0.18.4 - -### Patch Changes - -- a1002df2dc2: Support commit hashes at `GithubUrlReader.readTree/search` additionally to branch names. - - Additionally, this will reduce the number of API calls from 2 to 1 for retrieving the "repo details" - for all cases besides when the default branch has to be resolved and used - (e.g., repo URL without any branch or commit hash). - -- 5c7ce585824: Allow an additionalConfig to be provided to loadBackendConfig that fetches config values during runtime. -- 2b15cb4aa0a: The dependency isomorphic-git is now on version 1.23.0 -- 34167270b31: Renamed the `loadBackendConfig` option `additionalConfig` to `additionalConfigs` as an array, and ensured that they get passed on properly. - - This is technically breaking, but the [original addition](https://github.com/backstage/backstage/pull/16643) hasn't been released in mainline yet so we are taking this step now as a `patch` change. - -- 420164593cf: Improve GitlabUrlReader to only load requested sub-path -- Updated dependencies - - @backstage/config-loader@1.2.0 - - @backstage/backend-app-api@0.4.2 - - @backstage/integration@1.4.4 - - @backstage/backend-dev-utils@0.1.1 - - @backstage/backend-plugin-api@0.5.1 - - @backstage/cli-common@0.1.12 - - @backstage/config@1.0.7 - - @backstage/errors@1.1.5 - - @backstage/integration-aws-node@0.1.2 - - @backstage/types@1.0.2 - -## 0.18.4-next.2 - -### Patch Changes - -- 5c7ce585824: Allow an additionalConfig to be provided to loadBackendConfig that fetches config values during runtime. -- Updated dependencies - - @backstage/backend-app-api@0.4.2-next.2 - - @backstage/backend-dev-utils@0.1.1 - - @backstage/backend-plugin-api@0.5.1-next.2 - - @backstage/cli-common@0.1.12 - - @backstage/config@1.0.7 - - @backstage/config-loader@1.1.9 - - @backstage/errors@1.1.5 - - @backstage/integration@1.4.4-next.0 - - @backstage/integration-aws-node@0.1.2 - - @backstage/types@1.0.2 - -## 0.18.4-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/integration@1.4.4-next.0 - - @backstage/backend-app-api@0.4.2-next.1 - - @backstage/backend-dev-utils@0.1.1 - - @backstage/backend-plugin-api@0.5.1-next.1 - - @backstage/cli-common@0.1.12 - - @backstage/config@1.0.7 - - @backstage/config-loader@1.1.9 - - @backstage/errors@1.1.5 - - @backstage/integration-aws-node@0.1.2 - - @backstage/types@1.0.2 - -## 0.18.4-next.0 - -### Patch Changes - -- 420164593cf: Improve GitlabUrlReader to only load requested sub-path -- Updated dependencies - - @backstage/backend-app-api@0.4.2-next.0 - - @backstage/config@1.0.7 - - @backstage/integration@1.4.3 - - @backstage/integration-aws-node@0.1.2 - - @backstage/backend-dev-utils@0.1.1 - - @backstage/backend-plugin-api@0.5.1-next.0 - - @backstage/cli-common@0.1.12 - - @backstage/config-loader@1.1.9 - - @backstage/errors@1.1.5 - - @backstage/types@1.0.2 - -## 0.18.3 - -### Patch Changes - -- f75097868a7: Adds config option `backend.database.role` to set ownership for newly created schemas and tables in Postgres - - The example config below connects to the database as user `v-backstage-123` but sets the ownership of - the create schemas and tables to `backstage` - - ```yaml - backend: - database: - client: pg - pluginDivisionMode: schema - role: backstage - connection: - user: v-backstage-123 - ... - ``` - -- 928a12a9b3e: Internal refactor of `/alpha` exports. -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- 87f0bbec175: AwsS3UrlReader upgraded to use aws-sdk v3 -- c1ee073a82b: Added `lastModifiedAt` field on `UrlReaderService` responses and a `lastModifiedAfter` option to `UrlReaderService.readUrl`. -- 482dae5de1c: Updated link to docs. -- Updated dependencies - - @backstage/errors@1.1.5 - - @backstage/backend-plugin-api@0.5.0 - - @backstage/backend-app-api@0.4.1 - - @backstage/config-loader@1.1.9 - - @backstage/integration@1.4.3 - - @backstage/backend-dev-utils@0.1.1 - - @backstage/cli-common@0.1.12 - - @backstage/config@1.0.7 - - @backstage/integration-aws-node@0.1.2 - - @backstage/types@1.0.2 - -## 0.18.3-next.2 - -### Patch Changes - -- f75097868a7: Adds config option `backend.database.role` to set ownership for newly created schemas and tables in Postgres - - The example config below connects to the database as user `v-backstage-123` but sets the ownership of - the create schemas and tables to `backstage` - - ```yaml - backend: - database: - client: pg - pluginDivisionMode: schema - role: backstage - connection: - user: v-backstage-123 - ... - ``` - -- 87f0bbec175: AwsS3UrlReader upgraded to use aws-sdk v3 -- Updated dependencies - - @backstage/backend-app-api@0.4.1-next.2 - - @backstage/backend-plugin-api@0.4.1-next.2 - - @backstage/config@1.0.7-next.0 - - @backstage/integration@1.4.3-next.0 - - @backstage/integration-aws-node@0.1.2-next.0 - -## 0.18.3-next.1 - -### Patch Changes - -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- 482dae5de1c: Updated link to docs. -- Updated dependencies - - @backstage/errors@1.1.5-next.0 - - @backstage/config-loader@1.1.9-next.0 - - @backstage/integration@1.4.3-next.0 - - @backstage/backend-plugin-api@0.4.1-next.1 - - @backstage/backend-dev-utils@0.1.1-next.0 - - @backstage/backend-app-api@0.4.1-next.1 - - @backstage/cli-common@0.1.12-next.0 - - @backstage/config@1.0.7-next.0 - - @backstage/types@1.0.2 - -## 0.18.3-next.0 - -### Patch Changes - -- 928a12a9b3: Internal refactor of `/alpha` exports. -- Updated dependencies - - @backstage/backend-plugin-api@0.4.1-next.0 - - @backstage/backend-app-api@0.4.1-next.0 - - @backstage/backend-dev-utils@0.1.0 - - @backstage/cli-common@0.1.11 - - @backstage/config@1.0.6 - - @backstage/config-loader@1.1.8 - - @backstage/errors@1.1.4 - - @backstage/integration@1.4.2 - - @backstage/types@1.0.2 - -## 0.18.2 - -### Patch Changes - -- 5febb216fe: **BREAKING**: The `CacheClient` interface must now also implement the `withOptions` method. The `.get()` method has also received a type parameter that helps ensure that `undefined` in the event of a cache miss is handled. - - Added a `cacheToPluginCacheManager` helper that converts a `CacheService` into a legacy `PluginCacheManager` instance. - -- 5febb216fe: Updated to match the new `CacheService` interface. -- e716946103: Updated usage of the lifecycle service. -- d31d8e00b3: Updated to work with the new `type: 'pem'` with `createHttpServer` from `@backstage/backend-app-api` -- 0ff03319be: Updated usage of `createBackendPlugin`. -- f60cca9da1: The `DatabaseManager.forPlugin` method now accepts additional service dependencies. There is no need to update existing code to pass these dependencies. -- 628e2bd89a: Updated dependency `@kubernetes/client-node` to `0.18.1`. -- Updated dependencies - - @backstage/backend-app-api@0.4.0 - - @backstage/backend-plugin-api@0.4.0 - - @backstage/backend-dev-utils@0.1.0 - - @backstage/cli-common@0.1.11 - - @backstage/config@1.0.6 - - @backstage/config-loader@1.1.8 - - @backstage/errors@1.1.4 - - @backstage/integration@1.4.2 - - @backstage/types@1.0.2 - -## 0.18.2-next.2 - -### Patch Changes - -- e716946103: Updated usage of the lifecycle service. -- d31d8e00b3: Updated to work with the new `type: 'pem'` with `createHttpServer` from `@backstage/backend-app-api` -- 0ff03319be: Updated usage of `createBackendPlugin`. -- f60cca9da1: The `DatabaseManager.forPlugin` method now accepts additional service dependencies. There is no need to update existing code to pass these dependencies. -- Updated dependencies - - @backstage/backend-app-api@0.4.0-next.2 - - @backstage/backend-plugin-api@0.4.0-next.2 - - @backstage/backend-dev-utils@0.1.0-next.0 - - @backstage/cli-common@0.1.11 - - @backstage/config@1.0.6 - - @backstage/config-loader@1.1.8 - - @backstage/errors@1.1.4 - - @backstage/integration@1.4.2 - - @backstage/types@1.0.2 - -## 0.18.2-next.1 - -### Patch Changes - -- 628e2bd89a: Updated dependency `@kubernetes/client-node` to `0.18.1`. -- Updated dependencies - - @backstage/backend-plugin-api@0.3.2-next.1 - - @backstage/backend-app-api@0.3.2-next.1 - - @backstage/cli-common@0.1.11 - - @backstage/config@1.0.6 - - @backstage/config-loader@1.1.8 - - @backstage/errors@1.1.4 - - @backstage/integration@1.4.2 - - @backstage/types@1.0.2 - -## 0.18.2-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-app-api@0.3.2-next.0 - - @backstage/backend-plugin-api@0.3.2-next.0 - -## 0.18.0 - -### Minor Changes - -- 5e2cebe9a3: **BREAKING**: Removed deprecated `read` method from the `UrlReader` interface. All implementations should use the `readUrl` method instead. - - Migrated `UrlReader` and related types to `backend/backend-plugin-api`, types remain re-exported from `backend-common` for now. - -### Patch Changes - -- 0e63aab311: Internal refactor of the logger and configuration loading implementations. -- 31e2309c8c: Added `legacyPlugin` and the lower level `makeLegacyPlugin` wrappers that convert legacy plugins to the new backend system. This will be used to ease the future migration to the new backend system, but we discourage use of it for now. -- 8e06f3cf00: Added `loggerToWinstonLogger`, which was moved from `@backstage/backend-plugin-api`. -- 2b1554cebf: Replaced dependencies on the `Logger` type from `winston` with `LoggerService` from `@backstage/backend-plugin-api`. This is not a breaking change as the `LoggerService` is a subset of the `Logger` interface. -- 5437fe488f: Migrated types related to `TokenManagerService`, `CacheService` and `DatabaseService` into backend-plugin-api. -- 6f02d23b01: Moved `PluginEndpointDiscovery` type from backend-common to backend-plugin-api. -- d592ec4f51: Updated the logger created by `createRootLogger` to make it possible to override the default `service` log label. -- b99c030f1b: Refactor to rely on `@backstage/backend-app-api` for the implementation of `createServiceBuilder`. -- f23eef3aa2: Updated dependency `better-sqlite3` to `^8.0.0`. -- Updated dependencies - - @backstage/backend-plugin-api@0.3.0 - - @backstage/backend-app-api@0.3.0 - - @backstage/config@1.0.6 - - @backstage/cli-common@0.1.11 - - @backstage/config-loader@1.1.8 - - @backstage/errors@1.1.4 - - @backstage/integration@1.4.2 - - @backstage/types@1.0.2 - -## 0.18.0-next.1 - -### Patch Changes - -- 8e06f3cf00: Added `loggerToWinstonLogger`, which was moved from `@backstage/backend-plugin-api`. -- 2b1554cebf: Replaced dependencies on the `Logger` type from `winston` with `LoggerService` from `@backstage/backend-plugin-api`. This is not a breaking change as the `LoggerService` is a subset of the `Logger` interface. -- 5437fe488f: Migrated types related to `TokenManagerService`, `CacheService` and `DatabaseService` into backend-plugin-api. -- d592ec4f51: Updated the logger created by `createRootLogger` to make it possible to override the default `service` log label. -- b99c030f1b: Refactor to rely on `@backstage/backend-app-api` for the implementation of `createServiceBuilder`. -- f23eef3aa2: Updated dependency `better-sqlite3` to `^8.0.0`. -- Updated dependencies - - @backstage/backend-app-api@0.3.0-next.1 - - @backstage/backend-plugin-api@0.3.0-next.1 - - @backstage/cli-common@0.1.11 - - @backstage/config@1.0.6-next.0 - - @backstage/config-loader@1.1.8-next.0 - - @backstage/errors@1.1.4 - - @backstage/integration@1.4.2-next.0 - - @backstage/types@1.0.2 - -## 0.18.0-next.0 - -### Minor Changes - -- 5e2cebe9a3: **BREAKING**: Removed deprecated `read` method from the `UrlReader` interface. All implementations should use the `readUrl` method instead. - - Migrated `UrlReader` and related types to `backend/backend-plugin-api`, types remain re-exported from `backend-common` for now. - -### Patch Changes - -- 6f02d23b01: Moved `PluginEndpointDiscovery` type from backend-common to backend-plugin-api. -- Updated dependencies - - @backstage/backend-plugin-api@0.2.1-next.0 - - @backstage/config@1.0.6-next.0 - - @backstage/cli-common@0.1.11 - - @backstage/config-loader@1.1.8-next.0 - - @backstage/errors@1.1.4 - - @backstage/integration@1.4.2-next.0 - - @backstage/types@1.0.2 - -## 0.17.0 - -### Minor Changes - -- de8a975911: Changed to use native `AbortController` and `AbortSignal` from Node.js, instead - of the one from `node-abort-controller`. This is possible now that the minimum - supported Node.js version of the project is 16. - - Note that their interfaces are very slightly different, but typically not in a - way that matters to consumers. If you see any typescript errors as a direct - result from this, they are compatible with each other in the ways that we - interact with them, and should be possible to type-cast across without ill - effects. - -### Patch Changes - -- d3fea4ae0a: Internal fixes to avoid implicit usage of globals -- 98776e638a: Fixed GitlabUrlReader to include api tokens in API calls -- 1f2b2de3fe: exported KubernetesContainerRunner, KubernetesContainerRunnerOptions, KubernetesContainerRunnerMountBase -- 840f2113c6: Fix `GitlabUrlReader.readTree` bug when there were no matching commits -- 20a5161f04: Adds MySQL support for the catalog-backend -- 3280711113: Updated dependency `msw` to `^0.49.0`. -- 9ce7866ecd: Updated dependency `@kubernetes/client-node` to `0.18.0`. -- 3c1302c07d: Updated dependency `@types/http-errors` to `^2.0.0`. -- 6b82598bd8: Added the ability to understand Job Artifact URLs to the GitLab integration -- dfc8edf9c5: Internal refactor to avoid usage of deprecated symbols. -- 8015ff1258: Tweaked wording to use inclusive terminology -- 8646067e07: Fixed `SingleHostDiscovery` so that it properly handles single-string `backend.listen` configurations such as `:80`. -- Updated dependencies - - @backstage/errors@1.1.4 - - @backstage/config-loader@1.1.7 - - @backstage/integration@1.4.1 - - @backstage/types@1.0.2 - - @backstage/cli-common@0.1.11 - - @backstage/config@1.0.5 - -## 0.17.0-next.3 - -### Patch Changes - -- 840f2113c6: Fix `GitlabUrlReader.readTree` bug when there were no matching commits -- Updated dependencies - - @backstage/cli-common@0.1.11-next.0 - - @backstage/config@1.0.5-next.1 - - @backstage/config-loader@1.1.7-next.2 - - @backstage/errors@1.1.4-next.1 - - @backstage/integration@1.4.1-next.1 - - @backstage/types@1.0.2-next.1 - -## 0.17.0-next.2 - -### Patch Changes - -- 98776e638a: Fixed GitlabUrlReader to include api tokens in API calls -- 20a5161f04: Adds MySQL support for the catalog-backend -- 3c1302c07d: Updated dependency `@types/http-errors` to `^2.0.0`. -- 8015ff1258: Tweaked wording to use inclusive terminology -- Updated dependencies - - @backstage/cli-common@0.1.11-next.0 - - @backstage/config@1.0.5-next.1 - - @backstage/config-loader@1.1.7-next.2 - - @backstage/errors@1.1.4-next.1 - - @backstage/integration@1.4.1-next.1 - - @backstage/types@1.0.2-next.1 - -## 0.17.0-next.1 - -### Minor Changes - -- de8a975911: Changed to use native `AbortController` and `AbortSignal` from Node.js, instead - of the one from `node-abort-controller`. This is possible now that the minimum - supported Node.js version of the project is 16. - - Note that their interfaces are very slightly different, but typically not in a - way that matters to consumers. If you see any typescript errors as a direct - result from this, they are compatible with each other in the ways that we - interact with them, and should be possible to type-cast across without ill - effects. - -### Patch Changes - -- d3fea4ae0a: Internal fixes to avoid implicit usage of globals -- 1f2b2de3fe: exported KubernetesContainerRunner, KubernetesContainerRunnerOptions, KubernetesContainerRunnerMountBase -- 6b82598bd8: Added the ability to understand Job Artifact URLs to the GitLab integration -- 8646067e07: Fixed `SingleHostDiscovery` so that it properly handles single-string `backend.listen` configurations such as `:80`. -- Updated dependencies - - @backstage/types@1.0.2-next.1 - - @backstage/config-loader@1.1.7-next.1 - - @backstage/config@1.0.5-next.1 - - @backstage/integration@1.4.1-next.1 - - @backstage/cli-common@0.1.10 - - @backstage/errors@1.1.4-next.1 - -## 0.16.1-next.0 - -### Patch Changes - -- 3280711113: Updated dependency `msw` to `^0.49.0`. -- dfc8edf9c5: Internal refactor to avoid usage of deprecated symbols. -- Updated dependencies - - @backstage/config-loader@1.1.7-next.0 - - @backstage/integration@1.4.1-next.0 - - @backstage/types@1.0.2-next.0 - - @backstage/cli-common@0.1.10 - - @backstage/config@1.0.5-next.0 - - @backstage/errors@1.1.4-next.0 - -## 0.16.0 - -### Minor Changes - -- a7607b5413: **BREAKING CHANGE**: The `UrlReader` interface has been updated to require that `readUrl` is implemented. `readUrl` has previously been optional to implement but a warning has been logged when calling its predecessor `read`. - The `read` method is now deprecated and will be removed in a future release. - -### Patch Changes - -- 88f99b8b13: Bumped `tar` dependency to `^6.1.12` in order to ensure Node.js v18 compatibility. -- 55227712dd: Generated development HTTPS backend certificate is now checked for expiration date instead of file age. -- d05e1841ce: This patch adds GiteaURLReader to the available classes. It currently only reads single files via gitea's public repos api -- e6ced2446a: Change to using `@keyv/memcache` now that `keyv-memcache` is deprecated -- 210a3b5668: Small update to fix compatibility with newer versions of the `keyv` library -- cfb30b700c: Pin `@kubernetes/client-node` version to `0.17.0`. -- c1784a4980: Replaces in-code uses of `GitHub` with `Github` and deprecates old versions. -- Updated dependencies - - @backstage/integration@1.4.0 - - @backstage/types@1.0.1 - - @backstage/cli-common@0.1.10 - - @backstage/config@1.0.4 - - @backstage/config-loader@1.1.6 - - @backstage/errors@1.1.3 - -## 0.16.0-next.1 - -### Patch Changes - -- 88f99b8b13: Bumped `tar` dependency to `^6.1.12` in order to ensure Node.js v18 compatibility. -- cfb30b700c: Pin `@kubernetes/client-node` version to `0.17.0`. -- Updated dependencies - - @backstage/cli-common@0.1.10 - - @backstage/config@1.0.4-next.0 - - @backstage/config-loader@1.1.6-next.0 - - @backstage/errors@1.1.3-next.0 - - @backstage/integration@1.4.0-next.0 - - @backstage/types@1.0.1-next.0 - -## 0.16.0-next.0 - -### Minor Changes - -- a7607b5413: **BREAKING CHANGE**: The `UrlReader` interface has been updated to require that `readUrl` is implemented. `readUrl` has previously been optional to implement but a warning has been logged when calling its predecessor `read`. - The `read` method is now deprecated and will be removed in a future release. - -### Patch Changes - -- 55227712dd: Generated development HTTPS backend certificate is now checked for expiration date instead of file age. -- d05e1841ce: This patch adds GiteaURLReader to the available classes. It currently only reads single files via gitea's public repos api -- 210a3b5668: Small update to fix compatibility with newer versions of the `keyv` library -- c1784a4980: Replaces in-code uses of `GitHub` with `Github` and deprecates old versions. -- Updated dependencies - - @backstage/integration@1.4.0-next.0 - - @backstage/types@1.0.1-next.0 - - @backstage/cli-common@0.1.10 - - @backstage/config@1.0.4-next.0 - - @backstage/config-loader@1.1.6-next.0 - - @backstage/errors@1.1.3-next.0 - -## 0.15.2 - -### Patch Changes - -- e8d7976413: Added back support for when no branch is provided for the Bitbucket Server `UrlReader` -- c44cf412de: Fix BitBucket server integration -- c31f7cdfbc: Fixed an issue where `getClient()` for a `pluginId` would return different clients and not share them -- 2d3a5f09ab: Use `response.json` rather than `response.send` where appropriate, as outlined in `SECURITY.md` -- Updated dependencies - - @backstage/cli-common@0.1.10 - - @backstage/config@1.0.3 - - @backstage/config-loader@1.1.5 - - @backstage/errors@1.1.2 - - @backstage/integration@1.3.2 - - @backstage/types@1.0.0 - -## 0.15.2-next.2 - -### Patch Changes - -- c44cf412de: Fix BitBucket server integration -- 2d3a5f09ab: Use `response.json` rather than `response.send` where appropriate, as outlined in `SECURITY.md` -- Updated dependencies - - @backstage/cli-common@0.1.10 - - @backstage/config@1.0.3-next.2 - - @backstage/config-loader@1.1.5-next.2 - - @backstage/errors@1.1.2-next.2 - - @backstage/integration@1.3.2-next.2 - - @backstage/types@1.0.0 - -## 0.15.2-next.1 - -### Patch Changes - -- c31f7cdfbc: Fixed an issue where `getClient()` for a `pluginId` would return different clients and not share them -- Updated dependencies - - @backstage/cli-common@0.1.10 - - @backstage/config@1.0.3-next.1 - - @backstage/config-loader@1.1.5-next.1 - - @backstage/errors@1.1.2-next.1 - - @backstage/integration@1.3.2-next.1 - - @backstage/types@1.0.0 - -## 0.15.2-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/cli-common@0.1.10 - - @backstage/config@1.0.3-next.0 - - @backstage/config-loader@1.1.5-next.0 - - @backstage/errors@1.1.2-next.0 - - @backstage/integration@1.3.2-next.0 - - @backstage/types@1.0.0 - -## 0.15.1 - -### Patch Changes - -- 399286d7dd: Workaround support for `swc` instead of `sucrase` -- eadf56bbbf: Bump `git-url-parse` version to `^13.0.0` -- c3c90280be: Added a keep-alive refresh loop to the `DatabaseManager`, keeping the connection - pool up. -- c3c90280be: The options part of `DatabaseManager.fromConfig` now accepts an optional logger - field. -- 3d4f5daadf: Remove use of deprecated trimLeft/trimRight -- bf3cc134eb: Implemented KubernetesContainerRunner: a ContainerRunner implementation that leverages Jobs on a kubernetes cluster - - ```ts - const kubeConfig = new KubeConfig(); - kubeConfig.loadFromDefault(); - - const options: KubernetesContainerRunnerOptions = { - kubeConfig, - // namespace where Jobs will be created - namespace: 'default', - // Jobs name will be prefixed with this name - name: 'my-runner', - // An existing Kubernetes volume that will be used - // as base for mounts - mountBase: { - volumeName: 'workdir', - // Every mount must start with the base path - // see example below - basePath: '/workdir', - }, - // Define a Pod template for the Jobs. It has to include - // a volume definition named as the mountBase volumeName - podTemplate: { - spec: { - containers: [], - volumes: [ - { - name: 'workdir', - persistentVolumeClaim: { - claimName: 'workdir-claim', - }, - }, - ], - }, - }, - }; - const containerRunner = new KubernetesContainerRunner(options); - - const runOptions: RunContainerOptions = { - imageName: 'golang:1.17', - args: ['echo', 'hello world'], - mountDirs: { - '/workdir/app': '/app', - }, - }; - containerRunner.runContainer(runOptions); - ``` - -- e3b1993788: Added port ranges in allowed hosts: - - ```yaml - reading: - allow: - - host: *.examples.org:900-1000 - ``` - -- 2f52e74b49: Got rid of usages of the uppercase String type -- 60b85d8ade: Updated dependency `helmet` to `^6.0.0`. - - Please note that these policies are no longer applied by default: - - helmet.contentSecurityPolicy no longer sets block-all-mixed-content directive by default - helmet.expectCt is no longer set by default. It can, however, be explicitly enabled. It will be removed in Helmet 7. - -- 667d917488: Updated dependency `msw` to `^0.47.0`. -- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. -- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. -- 709f468330: The `branch` command has been added to the `isomorphic-git` wrapper. -- 0c780278e0: Fix for entries being skipped or incomplete when reading large zip archives. -- 96689fbdcb: Workaround for a rare race condition in tests. -- Updated dependencies - - @backstage/integration@1.3.1 - - @backstage/config-loader@1.1.4 - - @backstage/cli-common@0.1.10 - - @backstage/config@1.0.2 - - @backstage/errors@1.1.1 - -## 0.15.1-next.3 - -### Patch Changes - -- 96689fbdcb: Workaround for a rare race condition in tests. -- Updated dependencies - - @backstage/config-loader@1.1.4-next.2 - - @backstage/cli-common@0.1.10-next.0 - - @backstage/config@1.0.2-next.0 - - @backstage/errors@1.1.1-next.0 - - @backstage/integration@1.3.1-next.2 - -## 0.15.1-next.2 - -### Patch Changes - -- eadf56bbbf: Bump `git-url-parse` version to `^13.0.0` -- 3d4f5daadf: Remove use of deprecated trimLeft/trimRight -- bf3cc134eb: Implemented KubernetesContainerRunner: a ContainerRunner implementation that leverages Jobs on a kubernetes cluster - - ```ts - const kubeConfig = new KubeConfig(); - kubeConfig.loadFromDefault(); - - const options: KubernetesContainerRunnerOptions = { - kubeConfig, - // namespace where Jobs will be created - namespace: 'default', - // Jobs name will be prefixed with this name - name: 'my-runner', - // An existing Kubernetes volume that will be used - // as base for mounts - mountBase: { - volumeName: 'workdir', - // Every mount must start with the base path - // see example below - basePath: '/workdir', - }, - // Define a Pod template for the Jobs. It has to include - // a volume definition named as the mountBase volumeName - podTemplate: { - spec: { - containers: [], - volumes: [ - { - name: 'workdir', - persistentVolumeClaim: { - claimName: 'workdir-claim', - }, - }, - ], - }, - }, - }; - const containerRunner = new KubernetesContainerRunner(options); - - const runOptions: RunContainerOptions = { - imageName: 'golang:1.17', - args: ['echo', 'hello world'], - mountDirs: { - '/workdir/app': '/app', - }, - }; - containerRunner.runContainer(runOptions); - ``` - -- e3b1993788: Added port ranges in allowed hosts: - - ```yaml - reading: - allow: - - host: *.examples.org:900-1000 - ``` - -- 2f52e74b49: Got rid of usages of the uppercase String type -- 667d917488: Updated dependency `msw` to `^0.47.0`. -- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. -- Updated dependencies - - @backstage/integration@1.3.1-next.1 - - @backstage/config-loader@1.1.4-next.1 - -## 0.15.1-next.1 - -### Patch Changes - -- c3c90280be: Added a keep-alive refresh loop to the `DatabaseManager`, keeping the connection - pool up. -- c3c90280be: The options part of `DatabaseManager.fromConfig` now accepts an optional logger - field. -- 60b85d8ade: Updated dependency `helmet` to `^6.0.0`. - - Please note that these policies are no longer applied by default: - - helmet.contentSecurityPolicy no longer sets block-all-mixed-content directive by default - helmet.expectCt is no longer set by default. It can, however, be explicitly enabled. It will be removed in Helmet 7. - -## 0.15.1-next.0 - -### Patch Changes - -- 399286d7dd: Workaround support for `swc` instead of `sucrase` -- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. -- Updated dependencies - - @backstage/config-loader@1.1.4-next.0 - - @backstage/integration@1.3.1-next.0 - -## 0.15.0 - -### Minor Changes - -- 12e9b54f0e: Added back support for when no branch is provided to the `UrlReader` for Bitbucket Server -- 30012e7d8c: - Added `force` and `remoteRef` option to `push` method in `git` actions - - Added `addRemote` and `deleteRemote` methods to `git` actions - -### Patch Changes - -- fc8a5f797b: Improve `scm/git` wrapper around `isomorphic-git` library : - - - Add `checkout` function, - - Add optional `remoteRef` parameter in the `push` function. - -- 5e4dc173f7: Added a second validation to the `dir()` method of ZIP archive responses returned from `readTree()` that ensures that extracted files do not fall outside the target directory. -- 1732a18a7a: Exported `redactLogLine` function to be able to use it in custom loggers and renamed it to `redactWinstonLogLine`. -- 3b7930b3e5: Add support for Bearer Authorization header / token-based auth at Git commands. -- cfa078e255: The `ZipArchiveResponse` now correctly handles corrupt ZIP archives. - - Before this change, certain corrupt ZIP archives either cause the inflater to throw (as expected), or will hang the parser indefinitely. - - By switching out the `zip` parsing library, we now write to a temporary directory, and load from disk which should ensure that the parsing of the `.zip` files are done correctly because `streaming` of `zip` paths is technically impossible without being able to parse the headers at the end of the file. - -- 770d3f92c4: The config prop `ensureExists` now applies to schema creation when `pluginDivisionMode` is set to `schema`. This means schemas will no longer accidentally be automatically created when `ensureExists` is set to `false`. -- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. -- Updated dependencies - - @backstage/integration@1.3.0 - -## 0.15.0-next.2 - -### Patch Changes - -- 5e4dc173f7: Added a second validation to the `dir()` method of ZIP archive responses returned from `readTree()` that ensures that extracted files do not fall outside the target directory. - -## 0.15.0-next.1 - -### Patch Changes - -- 1732a18a7a: Exported `redactLogLine` function to be able to use it in custom loggers and renamed it to `redactWinstonLogLine`. -- Updated dependencies - - @backstage/integration@1.3.0-next.1 - -## 0.15.0-next.0 - -### Minor Changes - -- 12e9b54f0e: Added back support for when no branch is provided to the `UrlReader` for Bitbucket Server -- 30012e7d8c: - Added `force` and `remoteRef` option to `push` method in `git` actions - - Added `addRemote` and `deleteRemote` methods to `git` actions - -### Patch Changes - -- fc8a5f797b: Improve `scm/git` wrapper around `isomorphic-git` library : - - - Add `checkout` function, - - Add optional `remoteRef` parameter in the `push` function. - -- 3b7930b3e5: Add support for Bearer Authorization header / token-based auth at Git commands. -- cfa078e255: The `ZipArchiveResponse` now correctly handles corrupt ZIP archives. - - Before this change, certain corrupt ZIP archives either cause the inflater to throw (as expected), or will hang the parser indefinitely. - - By switching out the `zip` parsing library, we now write to a temporary directory, and load from disk which should ensure that the parsing of the `.zip` files are done correctly because `streaming` of `zip` paths is technically impossible without being able to parse the headers at the end of the file. - -- 770d3f92c4: The config prop `ensureExists` now applies to schema creation when `pluginDivisionMode` is set to `schema`. This means schemas will no longer accidentally be automatically created when `ensureExists` is set to `false`. -- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. -- Updated dependencies - - @backstage/integration@1.3.0-next.0 - -## 0.14.1 - -### Patch Changes - -- b1edb5cfd9: Fix parsing of S3 URLs for the default region. -- c3cfc83af2: Updated JSDoc to be MDX compatible. -- e57180e45e: Added some more information to the error messages for `isomorphic-git` errors -- 1f75dfac29: Fix edge case bug when gitlab relativePath is repeated in the target URL. -- 90c87f28e8: Moving from Bitbucket Server endpoint from https://docs.atlassian.com/bitbucket-server/rest/7.9.0/bitbucket-rest.html#idp222 to https://docs.atlassian.com/bitbucket-server/rest/7.9.0/bitbucket-rest.html#idp224, to have the last commit in function of different branch, and not only the list of default branch -- 9de15a41d7: Upgrade @octokit/rest to 19.0.3 -- 0fc57887e8: Improve plural handling in logging output for secrets -- a70869e775: Updated dependency `msw` to `^0.43.0`. -- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. -- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. -- 679b32172e: Updated dependency `knex` to `^2.0.0`. -- e2d7b76f43: Upgrade git-url-parse to 12.0.0. - - Motivation for upgrade is transitively upgrading parse-url which is vulnerable - to several CVEs detected by Snyk. - - - SNYK-JS-PARSEURL-2935944 - - SNYK-JS-PARSEURL-2935947 - - SNYK-JS-PARSEURL-2936249 - -- 954a94f52f: Support self-hosted gitlab installations with relative URL. -- Updated dependencies - - @backstage/config-loader@1.1.3 - - @backstage/integration@1.2.2 - - @backstage/errors@1.1.0 - -## 0.14.1-next.3 - -### Patch Changes - -- 90c87f28e8: Moving from Bitbucket Server endpoint from https://docs.atlassian.com/bitbucket-server/rest/7.9.0/bitbucket-rest.html#idp222 to https://docs.atlassian.com/bitbucket-server/rest/7.9.0/bitbucket-rest.html#idp224, to have the last commit in function of different branch, and not only the list of default branch -- a70869e775: Updated dependency `msw` to `^0.43.0`. -- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. -- Updated dependencies - - @backstage/config-loader@1.1.3-next.1 - - @backstage/integration@1.2.2-next.3 - -## 0.14.1-next.2 - -### Patch Changes - -- 679b32172e: Updated dependency `knex` to `^2.0.0`. -- e2d7b76f43: Upgrade git-url-parse to 12.0.0. - - Motivation for upgrade is transitively upgrading parse-url which is vulnerable - to several CVEs detected by Snyk. - - - SNYK-JS-PARSEURL-2935944 - - SNYK-JS-PARSEURL-2935947 - - SNYK-JS-PARSEURL-2936249 - -- Updated dependencies - - @backstage/integration@1.2.2-next.2 - -## 0.14.1-next.1 - -### Patch Changes - -- 0fc57887e8: Improve plural handling in logging output for secrets -- Updated dependencies - - @backstage/errors@1.1.0-next.0 - - @backstage/integration@1.2.2-next.1 - - @backstage/config-loader@1.1.3-next.0 - -## 0.14.1-next.0 - -### Patch Changes - -- b1edb5cfd9: Fix parsing of S3 URLs for the default region. -- c3cfc83af2: Updated JSDoc to be MDX compatible. -- Updated dependencies - - @backstage/integration@1.2.2-next.0 - -## 0.14.0 - -### Minor Changes - -- 55647ec7df: **BREAKING**: Server-to-server tokens that are authenticated by the `ServerTokenManager` now must have an `exp` claim that has not expired. Tokens where the `exp` claim is in the past or missing are considered invalid and will throw an error. This is a followup to the deprecation from the `1.2` release of Backstage where perpetual tokens were deprecated. Be sure to update any usage of the `getToken()` method to have it be called every time a token is needed. Do not store tokens for later use. - -### Patch Changes - -- f72a6b8c62: Applied the `luxon` dependency fix from the `0.13.4` patch release. -- 5b22a8c97f: Applied the AWS S3 reading patch from the `0.13.5` patch release. -- f5283a42e2: Updated dependency `@google-cloud/storage` to `^6.0.0`. -- 8f7b1835df: Updated dependency `msw` to `^0.41.0`. -- Updated dependencies - - @backstage/integration@1.2.1 - - @backstage/config-loader@1.1.2 - -## 0.14.0-next.2 - -### Minor Changes - -- 55647ec7df: **BREAKING**: Server-to-server tokens that are authenticated by the `ServerTokenManager` now must have an `exp` claim that has not expired. Tokens where the `exp` claim is in the past or missing are considered invalid and will throw an error. This is a followup to the deprecation from the `1.2` release of Backstage where perpetual tokens were deprecated. Be sure to update any usage of the `getToken()` method to have it be called every time a token is needed. Do not store tokens for later use. - -### Patch Changes - -- Updated dependencies - - @backstage/integration@1.2.1-next.2 - -## 0.13.6-next.1 - -### Patch Changes - -- 8f7b1835df: Updated dependency `msw` to `^0.41.0`. -- Updated dependencies - - @backstage/config-loader@1.1.2-next.0 - - @backstage/integration@1.2.1-next.1 - -## 0.13.6-next.0 - -### Patch Changes - -- f72a6b8c62: Applied the `luxon` dependency fix from the `0.13.4` patch release. -- 5b22a8c97f: Applied the AWS S3 reading patch from the `0.13.5` patch release. -- Updated dependencies - - @backstage/integration@1.2.1-next.0 - -## 0.13.5 - -### Patch Changes - -- 667d2ed6f8: Fix a bug in the URL Reading towards AWS S3 where it would hang indefinitely. - -## 0.13.4 - -### Patch Changes - -- 739be2b079: Fixed potential crash by bumping the `luxon` dependency to `^2.3.1`. - -## 0.13.3 - -### Patch Changes - -- e0a6360b80: Added a `stream()` method to complement the `buffer()` method on `ReadUrlResponse`. A `ReadUrlResponseFactory` utility class is now also available, providing a simple, consistent way to provide a valid `ReadUrlResponse`. - - This method, though optional for now, will be required on the responses of `UrlReader.readUrl()` implementations in a future release. - -- 4b811aafce: Implemented the `UrlReader.search()` method for Google Cloud Storage. Due to limitations in the underlying storage API, only prefix-based searches are supported right now (for example, `https://storage.cloud.google.com/your-bucket/some-path/*`). -- 6673babab9: Gerrit integration: Added optional `cloneUrl` string to config. -- 75bf9e1da9: Split BitbucketUrlReader into BitbucketCloudUrlReader and BitbucketServerUrlReader. Backwards compatible. -- 28b0e4ddef: Update types to match the new version of `@keyv/redis` -- 5fcbd86960: **DEPRECATION**: Server-to-server authentication tokens issued from a - `TokenManager` (specifically, `ServerTokenManager`) now has an expiry time set, - for one hour in the future from when issued. This improves security. The ability - to pass in and validate tokens that either have a missing `exp` claim, or an - `exp` claim that expired in the past, is now deprecated. Trying to do so will - lead to logged warnings, and in a future release will instead lead to errors. - - It was always the case that users of this interface were expected to call its - `getToken()` method for every outgoing call and never hold on to any given token - for reuse. But this now has become even more important advice to heed, and you - should verify that you do not hold on to and reuse tokens such as these in your - own code. - -- cfc0f19699: Updated dependency `fs-extra` to `10.1.0`. -- 9ec4e0613e: Update to `jose` 4.6.0 -- Updated dependencies - - @backstage/integration@1.2.0 - - @backstage/cli-common@0.1.9 - - @backstage/config@1.0.1 - - @backstage/config-loader@1.1.1 - -## 0.13.3-next.2 - -### Patch Changes - -- e0a6360b80: Added a `stream()` method to complement the `buffer()` method on `ReadUrlResponse`. A `ReadUrlResponseFactory` utility class is now also available, providing a simple, consistent way to provide a valid `ReadUrlResponse`. - - This method, though optional for now, will be required on the responses of `UrlReader.readUrl()` implementations in a future release. - -- 4b811aafce: Implemented the `UrlReader.search()` method for Google Cloud Storage. Due to limitations in the underlying storage API, only prefix-based searches are supported right now (for example, `https://storage.cloud.google.com/your-bucket/some-path/*`). -- Updated dependencies - - @backstage/cli-common@0.1.9-next.0 - - @backstage/config@1.0.1-next.0 - - @backstage/config-loader@1.1.1-next.1 - - @backstage/integration@1.2.0-next.1 - -## 0.13.3-next.1 - -### Patch Changes - -- 28b0e4ddef: Update types to match the new version of `@keyv/redis` - -## 0.13.3-next.0 - -### Patch Changes - -- 6673babab9: Gerrit integration: Added optional `cloneUrl` string to config. -- 75bf9e1da9: Split BitbucketUrlReader into BitbucketCloudUrlReader and BitbucketServerUrlReader. Backwards compatible. -- cfc0f19699: Updated dependency `fs-extra` to `10.1.0`. -- 9ec4e0613e: Update to `jose` 4.6.0 -- Updated dependencies - - @backstage/integration@1.2.0-next.0 - - @backstage/config-loader@1.1.1-next.0 - -## 0.13.2 - -### Patch Changes - -- 19f6c6c32a: The backend will no longer fail to start up when configured secrets do not match the configuration schema. -- b7436743cb: Added the GerritUrlReader that implements "readUrl". -- 3ef123bbf0: Support external ID when assuming roles in S3 integration - - In order to assume a role created by a 3rd party as external - ID is needed. This change adds an optional field to the s3 - integration configuration and consumes that in the AwsS3UrlReader. - -- bae9359032: The logger returned from `getVoidLogger` is now uses a silenced console transport instead. -- 3ff0e79654: Tweaked the `UrlReader` multiplexer so that it uses the more helpful `NotAllowedError` messaging for all methods. -- 12608f8ba8: Add `@types/webpack-env` to dependencies. -- f9f512559b: Updated the visibility of database connection fields in config to be secret -- Updated dependencies - - @backstage/integration@1.1.0 - - @backstage/config-loader@1.1.0 - -## 0.13.2-next.2 - -### Patch Changes - -- 19f6c6c32a: The backend will no longer fail to start up when configured secrets do not match the configuration schema. -- Updated dependencies - - @backstage/config-loader@1.1.0-next.1 - - @backstage/integration@1.1.0-next.2 - -## 0.13.2-next.1 - -### Patch Changes - -- b7436743cb: Added the GerritUrlReader that implements "readUrl". -- bae9359032: The logger returned from `getVoidLogger` is now uses a silenced console transport instead. -- Updated dependencies - - @backstage/integration@1.1.0-next.1 - -## 0.13.2-next.0 - -### Patch Changes - -- 3ef123bbf0: Support external ID when assuming roles in S3 integration - - In order to assume a role created by a 3rd party as external - ID is needed. This change adds an optional field to the s3 - integration configuration and consumes that in the AwsS3UrlReader. - -- f9f512559b: Updated the visibility of database connection fields in config to be secret -- Updated dependencies - - @backstage/config-loader@1.0.1-next.0 - - @backstage/integration@1.0.1-next.0 - -## 0.13.1 - -### Patch Changes - -- efc73db10c: Use `better-sqlite3` instead of `@vscode/sqlite3` -- f24ef7864e: Minor typo fixes -- b66f70180f: Fix handling of bucket names with dots, in `AwsS3UrlReader` -- Updated dependencies - - @backstage/config-loader@1.0.0 - - @backstage/integration@1.0.0 - - @backstage/config@1.0.0 - - @backstage/errors@1.0.0 - - @backstage/types@1.0.0 - -## 0.13.0 - -### Minor Changes - -- ae9d6fb3df: **BREAKING**: - - - Removed the (since way back) deprecated `createDatabase` export, please use `createDatabaseClient` instead. - - Removed the (since way back) deprecated `SingleConnectionDatabaseManager` export, please use `DatabaseManager` instead. - -### Patch Changes - -- ab7cd7d70e: Do some groundwork for supporting the `better-sqlite3` driver, to maybe eventually replace `@vscode/sqlite3` (#9912) -- e0a69ba49f: build(deps): bump `fs-extra` from 9.1.0 to 10.0.1 -- aefca2a7e9: add support for ETag at `BitbucketUrlReader.readUrl` -- 3c2bc73901: Use `setupRequestMockHandlers` from `@backstage/backend-test-utils` -- b1aacbf96a: Applied the fix for the `/alpha` entry point resolution that was part of the `v0.70.1` release of Backstage. -- Updated dependencies - - @backstage/config-loader@0.9.7 - -## 0.13.0-next.0 - -### Minor Changes - -- ae9d6fb3df: **BREAKING**: - - - Removed the (since way back) deprecated `createDatabase` export, please use `createDatabaseClient` instead. - - Removed the (since way back) deprecated `SingleConnectionDatabaseManager` export, please use `DatabaseManager` instead. - -### Patch Changes - -- ab7cd7d70e: Do some groundwork for supporting the `better-sqlite3` driver, to maybe eventually replace `@vscode/sqlite3` (#9912) -- e0a69ba49f: build(deps): bump `fs-extra` from 9.1.0 to 10.0.1 -- aefca2a7e9: add support for ETag at `BitbucketUrlReader.readUrl` -- 3c2bc73901: Use `setupRequestMockHandlers` from `@backstage/backend-test-utils` -- b1aacbf96a: Applied the fix for the `/alpha` entry point resolution that was part of the `v0.70.1` release of Backstage. -- Updated dependencies - - @backstage/config-loader@0.9.7-next.0 - -## 0.12.1 - -### Patch Changes - -- Fixed runtime resolution of the `/alpha` entry point. - -## 0.12.0 - -### Minor Changes - -- 9a0510144f: **BREAKING**: The connection string for `redis` cache store now requires a protocol prefix. - - ```diff - backend: - cache: - store: redis - - connection: user:pass@cache.example.com:6379 - + connection: redis://user:pass@cache.example.com:6379 - ``` - -### Patch Changes - -- 0df6077ab5: DockerContainerRunner.runContainer now automatically removes the container when its execution terminates -- 34af86517c: ensure `apiBaseUrl` being set for Bitbucket integrations, replace hardcoded defaults -- b838717e92: Export FetchUrlReader to facilitate more flexible configuration of the backend. -- Updated dependencies - - @backstage/integration@0.8.0 - -## 0.11.0 - -### Minor Changes - -- 7d12e4cf32: feat(backend-common): add Redis backed cache store - -### Patch Changes - -- b2f8bb99d3: Make backend.auth.keys optional in config schema. Previously backend.auth was optional but keys was not, which meant that if another plugin introduced additional properties under backend.auth, it would implicitly make backend.auth.keys mandatory. -- d64b8d3678: chore(deps): bump `minimatch` from 3.0.4 to 5.0.0 -- Updated dependencies - - @backstage/config-loader@0.9.6 - - @backstage/integration@0.7.5 - -## 0.10.9 - -### Patch Changes - -- Fix for the previous release with missing type declarations. -- Updated dependencies - - @backstage/cli-common@0.1.8 - - @backstage/config@0.1.15 - - @backstage/config-loader@0.9.5 - - @backstage/errors@0.2.2 - - @backstage/integration@0.7.4 - - @backstage/types@0.1.3 - -## 0.10.8 - -### Patch Changes - -- 1ed305728b: Bump `node-fetch` to version 2.6.7 and `cross-fetch` to version 3.1.5 -- c77c5c7eb6: Added `backstage.role` to `package.json` -- 0107c9aa08: chore(deps): bump `helmet` from 4.4.1 to 5.0.2 -- b590e9b58d: Updated `isDatabaseConflictError` to handle modern sqlite conflict errors -- Updated dependencies - - @backstage/config-loader@0.9.4 - - @backstage/errors@0.2.1 - - @backstage/integration@0.7.3 - - @backstage/cli-common@0.1.7 - - @backstage/config@0.1.14 - - @backstage/types@0.1.2 - -## 0.10.7 - -### Patch Changes - -- 2441d1cf59: chore(deps): bump `knex` from 0.95.6 to 1.0.2 - - This also replaces `sqlite3` with `@vscode/sqlite3` 5.0.7 - -- 599f3dfa83: chore(deps-dev): bump `@types/concat-stream` from 1.6.1 to 2.0.0 -- c3868458d8: Removed unnecessary `get-port` dependency -- 04398e946e: Bump `selfsigned` to 2.0.0 - -## 0.10.7-next.0 - -### Patch Changes - -- 2441d1cf59: chore(deps): bump `knex` from 0.95.6 to 1.0.2 - - This also replaces `sqlite3` with `@vscode/sqlite3` 5.0.7 - -- 599f3dfa83: chore(deps-dev): bump `@types/concat-stream` from 1.6.1 to 2.0.0 -- c3868458d8: Removed unnecessary `get-port` dependency - -## 0.10.6 - -### Patch Changes - -- 50d039577a: Added a `Context` type for the backend, that can propagate an abort signal, a - deadline, and contextual values through the call stack. The main entrypoint is - the `Contexts` utility class that provides a root context creator and commonly - used decorators. - - These are marked as `@alpha` for now, and are therefore only accessible via - `@backstage/backend-common/alpha`. - -## 0.10.6-next.0 - -### Patch Changes - -- 50d039577a: Added a `Context` type for the backend, that can propagate an abort signal, a - deadline, and contextual values through the call stack. The main entrypoint is - the `Contexts` utility class that provides a root context creator and commonly - used decorators. - - These are marked as `@alpha` for now, and are therefore only accessible via - `@backstage/backend-common/alpha`. - -## 0.10.5 - -### Patch Changes - -- de9d7eba63: Fixed configuration schema incorrectly declaring `backend.listen.address` to exist, rather than `backend.listen.host`, which is the correct key. - -## 0.10.4 - -### Patch Changes - -- f685e1398f: Loading of app configurations now reference the `@deprecated` construct from - JSDoc to determine if a property in-use has been deprecated. Users are notified - of deprecated keys in the format: - - ```txt - The configuration key 'catalog.processors.githubOrg' of app-config.yaml is deprecated and may be removed soon. Configure a GitHub integration instead. - ``` - - When the `withDeprecatedKeys` option is set to `true` in the `process` method - of `loadConfigSchema`, the user will be notified that deprecated keys have been - identified in their app configuration. - - The `backend-common` and `plugin-app-backend` packages have been updated to set - `withDeprecatedKeys` to true so that users are notified of deprecated settings - by default. - -- Updated dependencies - - @backstage/integration@0.7.2 - - @backstage/config@0.1.13 - - @backstage/config-loader@0.9.3 - -## 0.10.4-next.0 - -### Patch Changes - -- f685e1398f: Loading of app configurations now reference the `@deprecated` construct from - JSDoc to determine if a property in-use has been deprecated. Users are notified - of deprecated keys in the format: - - ```txt - The configuration key 'catalog.processors.githubOrg' of app-config.yaml is deprecated and may be removed soon. Configure a GitHub integration instead. - ``` - - When the `withDeprecatedKeys` option is set to `true` in the `process` method - of `loadConfigSchema`, the user will be notified that deprecated keys have been - identified in their app configuration. - - The `backend-common` and `plugin-app-backend` packages have been updated to set - `withDeprecatedKeys` to true so that users are notified of deprecated settings - by default. - -- Updated dependencies - - @backstage/config@0.1.13-next.0 - - @backstage/config-loader@0.9.3-next.0 - - @backstage/integration@0.7.2-next.0 - -## 0.10.3 - -### Patch Changes - -- 5b406daabe: build(deps-dev): bump `http-errors` from 1.8.0 to 2.0.0 -- 5333451def: Cleaned up API exports -- db5310e25e: bump `logform` to use fixed version of `color` dependency -- 7946418729: Switched to using `@manypkg/get-packages` to list monorepo packages, which provides better support for different kind of monorepo setups. -- 3b4d8caff6: The GithubUrlReader is switched to use the DefaultGithubCredentialsProvider -- f77bd5c8ff: Clean up API reports -- Updated dependencies - - @backstage/config@0.1.12 - - @backstage/integration@0.7.1 - - @backstage/errors@0.2.0 - - @backstage/config-loader@0.9.2 - -## 0.10.2 - -### Patch Changes - -- 21ae56168e: Updated the Git class with the following: - - - Added `depth` and `noCheckout` options to Git clone, using these you can create a bare clone that includes just the git history - - New `log` function which you can use to view the commit history of a git repo - -- eacc582473: Reverted the default CSP configuration to include `'unsafe-eval'` again, which was mistakenly removed in the previous version. - -## 0.10.1 - -### Patch Changes - -- 94cdf5d1bd: In-memory cache clients instantiated from the same cache manager now share the same memory space. -- 916b2f1f3e: Use the default CSP policy provided by `helmet` directly rather than a copy. -- 7d4b4e937c: Uptake changes to the GitHub Credentials Provider interface. -- 995e4c7d9d: Added support for non-"amazonaws.com" hosts (for example when testing with LocalStack) in AwsS3UrlReader. -- Updated dependencies - - @backstage/integration@0.7.0 - - @backstage/config-loader@0.9.1 - -## 0.10.0 - -### Minor Changes - -- 2f8a9b665f: Auto-generate secrets for backend-to-backend auth in local development environments. - - When NODE_ENV is 'development', the ServerTokenManager will now generate a secret for backend-to-backend auth to make it simpler to work locally on Backstage instances that use backend-to-backend auth. For production deployments, a secret must still be manually configured as described in [the backend-to-backend auth tutorial](https://backstage.io/docs/tutorials/backend-to-backend-auth). - - After the change, the static `fromConfig` method on the `ServerTokenManager` requires a logger. - - ```diff - - const tokenManager = ServerTokenManager.fromConfig(config); - + const tokenManager = ServerTokenManager.fromConfig(config, { logger: root }); - ``` - -### Patch Changes - -- 776180b740: Fixed bug in backend-common to allow passing of remote option in order to enable passing remote url in --config option. The remote option should be passed along with reloadIntervalSeconds from packages/backend/src/index.ts (Updated the file as well) - - These changes are needed in `packages/backend/src/index.ts` if remote URLs are desired to be passed in --config option and read and watch remote files for config. - - ```diff - @@ -86,7 +86,11 @@ async function main() { - const config = await loadBackendConfig({ - argv: process.argv, - logger, - + remote: { - + reloadIntervalSeconds: 60 * 10 // Check remote config changes every 10 minutes. Change to your desired interval in seconds - + } - }); - + - const createEnv = makeCreateEnv(config); - - const healthcheckEnv = useHotMemoize(module, () => createEnv('healthcheck')); - ``` - -- 2462b9e275: Ensure temporary directories are cleaned up if an error is thrown in the `filter` callback of the `UrlReader.readTree` options. -- 2f6d8ec3b6: Updated the `ReadTreeResponse` documentation to clarify that the caller of `dir()` is responsible for removing the directory after use. -- Updated dependencies - - @backstage/config-loader@0.9.0 - -## 0.9.14 - -### Patch Changes - -- fe24bc9a32: Each plugin now saves to a separate sqlite database file when `connection.filename` is provided in the sqlite config. - Any existing sqlite database files will be ignored. - -## 0.9.13 - -### Patch Changes - -- dcd1a0c3f4: Minor improvement to the API reports, by not unpacking arguments directly -- 5a008576c4: Add possibility to use custom error handler -- 98a9c35f0c: Add options argument to support additional database migrations configuration -- 6298de32dd: Add knexConfig config section - -## 0.9.12 - -### Patch Changes - -- 905dd952ac: Create a `TokenManager` interface and `ServerTokenManager` implementation to generate and validate server tokens for authenticated backend-to-backend API requests. -- 6b500622d5: Move to using node-fetch internally instead of cross-fetch -- 54989b671d: Fixed a potential crash in the log redaction code -- Updated dependencies - - @backstage/integration@0.6.10 - - @backstage/config-loader@0.8.1 - -## 0.9.11 - -### Patch Changes - -- bab752e2b3: Change default port of backend from 7000 to 7007. - - This is due to the AirPlay Receiver process occupying port 7000 and preventing local Backstage instances on MacOS to start. - - You can change the port back to 7000 or any other value by providing an `app-config.yaml` with the following values: - - ``` - backend: - listen: 0.0.0.0:7123 - baseUrl: http://localhost:7123 - ``` - - More information can be found here: https://backstage.io/docs/conf/writing - -- Updated dependencies - - @backstage/errors@0.1.5 - -## 0.9.10 - -### Patch Changes - -- d7c1e0e34a: Added the `isDatabaseConflictError` function. -- e21e3c6102: Bumping minimum requirements for `dockerode` and `testcontainers` -- 1e99c73c75: Update internal usage of `configLoader.loadConfig` that now returns an object instead of an array of configs. -- 1daada3a06: Paths can be specified in backend.reading.allow to further restrict allowed targets -- 7ad9a07b27: Adding config prop `pluginDivisionMode` to allow plugins using the `pg` client to create their own management schemas in the db. This allows `pg` client plugins to work in separate schemas in the same db. -- 01f74aa878: Add `AbortSignal` support to `UrlReader` -- a8732a1200: Make sure that server builder `start()` propagates errors (such as failing to bind to the required port) properly and doesn't resolve the promise prematurely. - - After this change, the backend logger will be able to actually capture the error as it happens: - - ``` - 2021-11-11T10:54:21.334Z backstage info Initializing http server - 2021-11-11T10:54:21.335Z backstage error listen EADDRINUSE: address already in use :::7000 code=EADDRINUSE errno=-48 syscall=listen address=:: port=7000 - ``` - -- 26b5da1c1a: Do not redact empty or one-character strings. These imply that it's just a test or local dev, and unnecessarily ruin the log output. -- Updated dependencies - - @backstage/config-loader@0.8.0 - - @backstage/cli-common@0.1.6 - -## 0.9.9 - -### Patch Changes - -- 8c4cad0bf2: AWSS3UrlReader now throws a `NotModifiedError` (exported from @backstage/backend-common) when s3 returns a 304 response. -- 0611f3b3e2: Reading app config from a remote server -- Updated dependencies - - @backstage/config-loader@0.7.2 - -## 0.9.8 - -### Patch Changes - -- 96cfa561eb: Adjusted some API exports -- 10615525f3: Switch to use the json and observable types from `@backstage/types` -- 1be8d2abdb: Any set configurations which have been tagged with a visibility 'secret', are now redacted from log lines. -- Updated dependencies - - @backstage/config@0.1.11 - - @backstage/cli-common@0.1.5 - - @backstage/errors@0.1.4 - - @backstage/integration@0.6.9 - - @backstage/config-loader@0.7.1 - -## 0.9.7 - -### Patch Changes - -- be59619212: Add "rate limit exceeded" to error from GithubUrlReader if that is the cause of a read failure -- 36e67d2f24: Internal updates to apply more strict checks to throw errors. -- Updated dependencies - - @backstage/config-loader@0.7.0 - - @backstage/errors@0.1.3 - -## 0.9.6 - -### Patch Changes - -- 8f969d5a56: Correct error message typo -- a31afc5b62: Replace slash stripping regexp with trimEnd to remove CodeQL warning -- d7055285de: Add glob patterns support to config CORS options. It's possible to send patterns like: - - ```yaml - backend: - cors: - origin: - - https://*.my-domain.com - - http://localhost:700[0-9] - - https://sub-domain-+([0-9]).my-domain.com - ``` - -- Updated dependencies - - @backstage/config-loader@0.6.10 - - @backstage/integration@0.6.7 - - @backstage/cli-common@0.1.4 - -## 0.9.5 - -### Patch Changes - -- 8bb3c0a578: The `subscribe` method on the `Config` returned by `loadBackendConfig` is now forwarded through `getConfig` and `getOptionalConfig`. -- 0c8a59e293: Fix an issue where filtering in search doesn't work correctly for Bitbucket. -- Updated dependencies - - @backstage/integration@0.6.6 - - @backstage/config-loader@0.6.9 - -## 0.9.4 - -### Patch Changes - -- febddedcb2: Bump `lodash` to remediate `SNYK-JS-LODASH-590103` security vulnerability -- Updated dependencies - - @backstage/integration@0.6.5 - - @backstage/config@0.1.10 - -## 0.9.3 - -### Patch Changes - -- fab79adde1: Add AWS S3 Discovery Processor. Add readTree() to AwsS3UrlReader. Add ReadableArrayResponse type that implements ReadTreeResponse to use in AwsS3UrlReader's readTree() -- f7ad3a8925: Fix Azure `readTree` and `search` handling to properly support paths. -- 96fef17a18: Upgrade git-parse-url to v11.6.0 -- Updated dependencies - - @backstage/integration@0.6.4 - -## 0.9.2 - -### Patch Changes - -- 9e5ed27ec: Properly export all used types. -- Updated dependencies - - @backstage/cli-common@0.1.3 - - @backstage/config-loader@0.6.8 - - @backstage/errors@0.1.2 - - @backstage/config@0.1.9 - -## 0.9.1 - -### Patch Changes - -- 714a2a918: Export type that are needed to implement a new `UrlReader` -- Updated dependencies - - @backstage/integration@0.6.3 - -## 0.9.0 - -### Minor Changes - -- a365f1faf: The `ZipArchiveResponse` class now accepts an optional `stripFirstDirectory` parameter. Note that its default value is `false`, which leads to a breaking change in behaviour to previous versions of the class. If you use this class explicitly and want to retain the old behaviour, add a `true` parameter value to its constructor. - -### Patch Changes - -- Updated dependencies - - @backstage/integration@0.6.2 - - @backstage/config@0.1.8 - -## 0.8.10 - -### Patch Changes - -- 8543d9890: Add an optional `info` parameter to the `readTree` filter option with a `size` property. -- 4d909268c: Read responses in `UrlReader#read()` as array buffer instead of as text to allow reading non-text locations such as images. -- 9b4604b38: Add support for watching configuration by implementing the `subscribe` method in the configuration returned by `loadBackendConfig`. -- b8cb12009: Add AWS S3 URL Reader -- Updated dependencies - - @backstage/config@0.1.7 - - @backstage/config-loader@0.6.7 - - @backstage/integration@0.6.1 - -## 0.8.9 - -### Patch Changes - -- f7ce7c565: Use a more informative error message when URL reading isn't allowed due to no reader matching the target URL. -- ce1958021: Pass on credentials to the integrations package, so that it can properly pick the API route when using GitHub apps based auth -- Updated dependencies - - @backstage/integration@0.6.0 - -## 0.8.8 - -### Patch Changes - -- 6aa7c3db7: bump node-tar version to the latest -- Updated dependencies - - @backstage/config@0.1.6 - - @backstage/integration@0.5.9 - - @backstage/config-loader@0.6.6 - -## 0.8.7 - -### Patch Changes - -- f25357273: Implement the etag functionality in the `readUrl` method of `FetchUrlReader`. -- bdd6ab5f1: It's possible to customize the request logging handler when building the service. For example in your `backend` - - ``` - const service = createServiceBuilder(module) - .loadConfig(config) - .setRequestLoggingHandler((logger?: Logger): RequestHandler => { - const actualLogger = (logger || getRootLogger()).child({ - type: 'incomingRequest', - }); - return expressWinston.logger({ ... - ``` - -## 0.8.6 - -### Patch Changes - -- 5f6f2fd96: Support a `ensureExists` config option to skip ensuring a configured database exists. This allows deployment scenarios where - limited permissions are given for provisioned databases without privileges to create new databases. If set to `false`, the - database connection will not be validated prior to use which means the backend will not attempt to create the database if it - doesn't exist. You can configure this in your app-config.yaml: - - ```yaml - backend: - database: - ensureExists: false - ``` - - This defaults to `true` if unspecified. You can also configure this per plugin connection and will override the base option. - -- ad93bb035: Document the default behavior of `statusCheck` option in `createStatusCheckRouter`. -- ae84b20cf: Revert the upgrade to `fs-extra@10.0.0` as that seemed to have broken all installs inexplicably. -- Updated dependencies - - @backstage/config-loader@0.6.5 - -## 0.8.5 - -### Patch Changes - -- 09d3eb684: Added a `readUrl` method to the `UrlReader` interface that allows for complex response objects and is intended to replace the `read` method. This new method is currently optional to implement which allows for a soft migration to `readUrl` instead of `read` in the future. - - The main use case for `readUrl` returning an object instead of solely a read buffer is to allow for additional metadata such as ETag, which is a requirement for more efficient catalog processing. - - The `GithubUrlReader` and `GitlabUrlReader` readers fully implement `readUrl`. The other existing readers implement the new method but do not propagate or return ETags. - - While the `readUrl` method is not yet required, it will be in the future, and we already log deprecation warnings when custom `UrlReader` implementations that do not implement `readUrl` are used. We therefore recommend that any existing custom implementations are migrated to implement `readUrl`. - - The old `read` and the new `readUrl` methods can easily be implemented using one another, but we recommend moving the chunk of the implementation to the new `readUrl` method as `read` is being removed, for example this: - - ```ts - class CustomUrlReader implements UrlReader { - read(url: string): Promise { - const res = await fetch(url); - - if (!res.ok) { - // error handling ... - } - - return Buffer.from(await res.text()); - } - } - ``` - - Can be migrated to something like this: - - ```ts - class CustomUrlReader implements UrlReader { - read(url: string): Promise { - const res = await this.readUrl(url); - return res.buffer(); - } - - async readUrl( - url: string, - _options?: ReadUrlOptions, - ): Promise { - const res = await fetch(url); - - if (!res.ok) { - // error handling ... - } - - const buffer = Buffer.from(await res.text()); - return { buffer: async () => buffer }; - } - } - ``` - - While there is no usage of the ETag capability yet in the main Backstage packages, you can already add it to your custom implementations. To do so, refer to the documentation of the `readUrl` method and surrounding types, and the existing implementation in `packages/backend-common/src/reading/GithubUrlReader.ts`. - -- 6841e0113: fix minor version of git-url-parse as 11.5.x introduced a bug for Bitbucket Server -- c2db794f5: add defaultBranch property for publish GitHub action -- Updated dependencies - - @backstage/integration@0.5.8 - -## 0.8.4 - -### Patch Changes - -- 88d742eb8: Download archives as compressed tar files for GitLab to fix the `readTree` bug in TODO Plugin. -- ab5cc376f: Add new `isChildPath` and `resolveSafeChildPath` exports -- Updated dependencies - - @backstage/cli-common@0.1.2 - - @backstage/integration@0.5.7 - -## 0.8.3 - -### Patch Changes - -- e5cdf0560: Provide a more clear error message when database connection fails. -- 772dbdb51: Deprecates `SingleConnectionDatabaseManager` and provides an API compatible database - connection manager, `DatabaseManager`, which allows developers to configure database - connections on a per plugin basis. - - The `backend.database` config path allows you to set `prefix` to use an - alternate prefix for automatically generated database names, the default is - `backstage_plugin_`. Use `backend.database.plugin.` to set plugin - specific database connection configuration, e.g. - - ```yaml - backend: - database: - client: 'pg', - prefix: 'custom_prefix_' - connection: - host: 'localhost' - user: 'foo' - password: 'bar' - plugin: - catalog: - connection: - database: 'database_name_overriden' - scaffolder: - client: 'sqlite3' - connection: ':memory:' - ``` - - Migrate existing backstage installations by swapping out the database manager in the - `packages/backend/src/index.ts` file as shown below: - - ```diff - import { - - SingleConnectionDatabaseManager, - + DatabaseManager, - } from '@backstage/backend-common'; - - // ... - - function makeCreateEnv(config: Config) { - // ... - - const databaseManager = SingleConnectionDatabaseManager.fromConfig(config); - + const databaseManager = DatabaseManager.fromConfig(config); - // ... - } - ``` - -- Updated dependencies - - @backstage/config-loader@0.6.4 - -## 0.8.2 - -### Patch Changes - -- 92963779b: Omits the `upgrade-insecure-requests` Content-Security-Policy directive by default, to prevent automatic HTTPS request upgrading for HTTP-deployed Backstage sites. - - If you previously disabled this using `false` in your `app-config.yaml`, this line is no longer necessary: - - ```diff - backend: - csp: - - upgrade-insecure-requests: false - ``` - - To keep the existing behavior of `upgrade-insecure-requests` Content-Security-Policy being _enabled_, add the key with an empty array as the value in your `app-config.yaml`: - - ```diff - backend: - + csp: - + upgrade-insecure-requests: [] - ``` - - Read more on [upgrade-insecure-requests here](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/upgrade-insecure-requests). - -- eda9dbd5f: Download archives as compressed tar files for Bitbucket to keep executable permissions. -- Updated dependencies [eda9dbd5f] - - @backstage/integration@0.5.6 - -## 0.8.1 - -### Patch Changes - -- c7dad9218: All cache-related connection errors are now handled and logged by the cache manager. App Integrators may provide an optional error handler when instantiating the cache manager if custom error handling is needed. - - ```typescript - // Providing an error handler - const cacheManager = CacheManager.fromConfig(config, { - onError: e => { - if (isSomehowUnrecoverable(e)) { - gracefullyShutThingsDown(); - process.exit(1); - } - }, - }); - ``` - -- 65e6c4541: Remove circular dependencies -- 5001de908: Change GitlabUrlReader to SHA timestamp compare using only commits that modify given file path, if file path given -- Updated dependencies [65e6c4541] -- Updated dependencies [290405276] - - @backstage/integration@0.5.3 - - @backstage/config-loader@0.6.2 - -## 0.8.0 - -### Minor Changes - -- 22fd8ce2a: Introducing: a standard API for App Integrators to configure cache stores and Plugin Developers to interact with them. - - Two cache stores are currently supported. - - - `memory`, which is a very simple in-memory key/value store, intended for local development. - - `memcache`, which can be used to connect to a memcache host. - - Configuring and working with cache stores is very similar to the process for database connections. - - ```yaml - backend: - cache: - store: memcache - connection: user:pass@cache.example.com:11211 - ``` - - ```typescript - import { CacheManager } from '@backstage/backend-common'; - - // Instantiating a cache client for a plugin. - const cacheManager = CacheManager.fromConfig(config); - const somePluginCache = cacheManager.forPlugin('somePlugin'); - const cacheClient = somePluginCache.getClient(); - - // Using the cache client: - const cachedValue = await cacheClient.get('someKey'); - if (cachedValue) { - return cachedValue; - } else { - const someValue = await someExpensiveProcess(); - await cacheClient.set('someKey', someValue); - } - await cacheClient.delete('someKey'); - ``` - - Cache clients deal with TTLs in milliseconds. A TTL can be provided as a defaultTtl when getting a client, or may be passed when setting specific objects. If no TTL is provided, data will be persisted indefinitely. - - ```typescript - // Getting a client with a default TTL - const cacheClient = somePluginCache.getClient({ - defaultTtl: 3600000, - }); - - // Setting a TTL on a per-object basis. - cacheClient.set('someKey', data, { ttl: 3600000 }); - ``` - - Configuring a cache store is optional. Even when no cache store is configured, the cache manager will dutifully pass plugins a manager that resolves a cache client that does not actually write or read any data. - -### Patch Changes - -- f9fb4a205: Prep work for mysql support in backend-common - -## 0.7.0 - -### Minor Changes - -- e0bfd3d44: Refactor the `runDockerContainer(…)` function to an interface-based api. - This gives the option to replace the docker runtime in the future. - - Packages and plugins that previously used the `dockerode` as argument should be migrated to use the new `ContainerRunner` interface instead. - - ```diff - import { - - runDockerContainer, - + ContainerRunner, - PluginEndpointDiscovery, - } from '@backstage/backend-common'; - - import Docker from 'dockerode'; - - type RouterOptions = { - // ... - - dockerClient: Docker, - + containerRunner: ContainerRunner; - }; - - export async function createRouter({ - // ... - - dockerClient, - + containerRunner, - }: RouterOptions): Promise { - // ... - - + await containerRunner.runContainer({ - - await runDockerContainer({ - image: 'docker', - // ... - - dockerClient, - }); - - // ... - } - ``` - - To keep the `dockerode` based runtime, use the `DockerContainerRunner` implementation: - - ```diff - + import { - + ContainerRunner, - + DockerContainerRunner - + } from '@backstage/backend-common'; - - import { runDockerContainer } from '@backstage/backend-common'; - - + const containerRunner: ContainerRunner = new DockerContainerRunner({dockerClient}); - + await containerRunner.runContainer({ - - await runDockerContainer({ - image: 'docker', - // ... - - dockerClient, - }); - ``` - -### Patch Changes - -- 38ca05168: The default `@octokit/rest` dependency was bumped to `"^18.5.3"`. -- Updated dependencies [38ca05168] -- Updated dependencies [d8b81fd28] - - @backstage/integration@0.5.2 - - @backstage/config-loader@0.6.1 - - @backstage/config@0.1.5 - -## 0.6.3 - -### Patch Changes - -- d367f63b5: remove use of deprecated type HelmetOptions -- b42531cfe: Support configuration of file storage for SQLite databases. Every plugin has its - own database file at the specified path. - -## 0.6.2 - -### Patch Changes - -- b779b5fee: Add UrlReader for Google Cloud Storage -- Updated dependencies [82c66b8cd] - - @backstage/config-loader@0.6.0 - -## 0.6.1 - -### Patch Changes - -- 37e3a69f5: Export `ReadTreeResponseFile` and `SearchResponseFile`. - -## 0.6.0 - -### Minor Changes - -- 8686eb38c: Encode thrown errors in the backend as a JSON payload. This is technically a breaking change, since the response format even of errors are part of the contract. If you relied on the response being text, you will now have some extra JSON "noise" in it. It should still be readable by end users though. - - Before: - - ``` - NotFoundError: No entity named 'tara.macgovern2' found, with kind 'user' in namespace 'default' - at eval (webpack-internal:///../../plugins/catalog-backend/src/service/router.ts:117:17) - ``` - - After: - - ```json - { - "error": { - "name": "NotFoundError", - "message": "No entity named 'tara.macgovern2' found, with kind 'user' in namespace 'default'", - "stack": "NotFoundError: No entity named 'tara.macgovern2' found, with kind 'user' in namespace 'default'\n at eval (webpack-internal:///../../plugins/catalog-backend/src/service/router.ts:117:17)" - }, - "request": { - "method": "GET", - "url": "/entities/by-name/user/default/tara.macgovern2" - }, - "response": { - "statusCode": 404 - } - } - ``` - -- 8686eb38c: Removed the custom error types (e.g. `NotFoundError`). Those are now instead in the new `@backstage/errors` package. This is a breaking change, and you will have to update your imports if you were using these types. - - ```diff - -import { NotFoundError } from '@backstage/backend-common'; - +import { NotFoundError } from '@backstage/errors'; - ``` - -### Patch Changes - -- Updated dependencies [0434853a5] - - @backstage/config@0.1.4 - -## 0.5.6 - -### Patch Changes - -- d7245b733: Add a utility function runDockerContainer used to run a docker container (currently used by Scaffolder and TechDocs for their 'generate' processes) -- 761698831: Bump to the latest version of the Knex library. - - You will most likely want to bump your own `packages/backend/package.json` as well: - - ```diff - - "knex": "^0.21.18", - + "knex": "^0.95.1", - ``` - - Note that the recent versions of the Knex library have some changes that may affect your internal plugins' database migration files. Importantly, they now support `ALTER TABLE` on SQLite, and no longer accidentally remove indices when making some modifications. It now also exports the `Knex` typescript type as a named export. - - ```ts - import { Knex } from 'knex'; - ``` - -- Updated dependencies [277644e09] -- Updated dependencies [52f613030] -- Updated dependencies [905cbfc96] -- Updated dependencies [d4e77ec5f] - - @backstage/integration@0.5.1 - -## 0.5.5 - -### Patch Changes - -- 497859088: Add optional `logClientErrors` to errorHandler to log 4XX errors -- 8adb48df4: Change debug log format to print as color grey - -## 0.5.4 - -### Patch Changes - -- 16fb1d03a: pass registered logger to requestLoggingHandler -- 491f3a0ec: Implement `UrlReader.search` for the other providers (Azure, Bitbucket, GitLab) as well. - - The `UrlReader` subclasses now are implemented in terms of the respective `Integration` class. - -- 434b4e81a: Support globs in `FileReaderProcessor`. -- fb28da212: Switched to using `'x-access-token'` for authenticating Git over HTTPS towards GitHub. -- Updated dependencies [491f3a0ec] - - @backstage/integration@0.5.0 - -## 0.5.3 - -### Patch Changes - -- ffffea8e6: Minor updates to reflect the changes in `@backstage/integration` that made the fields `apiBaseUrl` and `apiUrl` mandatory. -- 82b2c11b6: Set explicit content-type in error handler responses. -- 965e200c6: Slight refactoring in support of a future search implementation in `UrlReader`. Mostly moving code around. -- 5a5163519: Implement `UrlReader.search` which implements glob matching. -- Updated dependencies [ffffea8e6] - - @backstage/integration@0.4.0 - -## 0.5.2 - -### Patch Changes - -- 2430ee7c2: Updated the `rootLogger` in `@backstage/backend-common` to support custom logging options. This is useful when you want to make some changes without re-implementing the entire logger and calling `setRootLogger` or `logger.configure`. For example you can add additional `defaultMeta` tags to each log entry. The following changes are included: - - - Added `createRootLogger` which accepts winston `LoggerOptions`. These options allow overriding the default keys. - - Example Usage: - - ```ts - // Create the logger - const logger = createRootLogger({ - defaultMeta: { appName: 'backstage', appEnv: 'prod' }, - }); - - // Add a custom logger transport - logger.add(new MyCustomTransport()); - - const config = await loadBackendConfig({ - argv: process.argv, - logger: getRootLogger(), // already set to new logger instance - }); - ``` - -- Updated dependencies [c4abcdb60] -- Updated dependencies [062df71db] -- Updated dependencies [064c513e1] -- Updated dependencies [e9aab60c7] -- Updated dependencies [3149bfe63] -- Updated dependencies [2e62aea6f] - - @backstage/integration@0.3.2 - - @backstage/config-loader@0.5.1 - -## 0.5.1 - -### Patch Changes - -- 26a3a6cf0: Honor the branch ref in the url when cloning. - - This fixes a bug in the scaffolder prepare stage where a non-default branch - was specified in the scaffolder URL but the default branch was cloned. - For example, even though the `other` branch is specified in this example, the - `master` branch was actually cloned: - - ```yaml - catalog: - locations: - - type: url - target: https://github.com/backstage/backstage/blob/other/plugins/scaffolder-backend/sample-templates/docs-template/template.yaml - ``` - - This also fixes a 404 in the prepare stage for GitLab URLs. - -- 664dd08c9: URL Reader's readTree: Fix bug with github.com URLs. -- 9dd057662: Upgrade [git-url-parse](https://www.npmjs.com/package/git-url-parse) to [v11.4.4](https://github.com/IonicaBizau/git-url-parse/pull/125) which fixes parsing an Azure DevOps branch ref. -- Updated dependencies [6800da78d] -- Updated dependencies [9dd057662] -- Updated dependencies [ef7957be4] -- Updated dependencies [ef7957be4] -- Updated dependencies [ef7957be4] - - @backstage/integration@0.3.1 - - @backstage/config-loader@0.5.0 - -## 0.5.0 - -### Minor Changes - -- 5345a1f98: Remove fallback option from `UrlReaders.create` and `UrlReaders.default`, as well as the default fallback reader. - - To be able to read data from endpoints outside of the configured integrations, you now need to explicitly allow it by - adding an entry in the `backend.reading.allow` list. For example: - - ```yml - backend: - baseUrl: ... - reading: - allow: - - host: example.com - - host: '*.examples.org' - ``` - - Apart from adding the above configuration, most projects should not need to take any action to migrate existing code. If you do happen to have your own fallback reader configured, this needs to be replaced with a reader factory that selects a specific set of URLs to work with. If you where wrapping the existing fallback reader, the new one that handles the allow list is created using `FetchUrlReader.factory`. - -- 09a370426: Remove support for HTTPS certificate generation parameters. Use `backend.https = true` instead. - -### Patch Changes - -- 0b135e7e0: Add support for GitHub Apps authentication for backend plugins. - - `GithubCredentialsProvider` requests and caches GitHub credentials based on a repository or organization url. - - The `GithubCredentialsProvider` class should be considered stateful since tokens will be cached internally. - Consecutive calls to get credentials will return the same token, tokens older than 50 minutes will be considered expired and reissued. - `GithubCredentialsProvider` will default to the configured access token if no GitHub Apps are configured. - - More information on how to create and configure a GitHub App to use with backstage can be found in the documentation. - - Usage: - - ```javascript - const credentialsProvider = new GithubCredentialsProvider(config); - const { token, headers } = await credentialsProvider.getCredentials({ - url: 'https://github.com/', - }); - ``` - - Updates `GithubUrlReader` to use the `GithubCredentialsProvider`. - -- 294a70cab: 1. URL Reader's `readTree` method now returns an `etag` in the response along with the blob. The etag is an identifier of the blob and will only change if the blob is modified on the target. Usually it is set to the latest commit SHA on the target. - - `readTree` also takes an optional `etag` in its options and throws a `NotModifiedError` if the etag matches with the etag of the resource. - - So, the `etag` can be used in building a cache when working with URL Reader. - - An example - - - ```ts - const response = await reader.readTree( - 'https://github.com/backstage/backstage', - ); - - const etag = response.etag; - - // Will throw a new NotModifiedError (exported from @backstage/backstage-common) - await reader.readTree('https://github.com/backstage/backstage', { - etag, - }); - ``` - - 2. URL Reader's readTree method can now detect the default branch. So, `url:https://github.com/org/repo/tree/master` can be replaced with `url:https://github.com/org/repo` in places like `backstage.io/techdocs-ref`. - -- 0ea032763: URL Reader: Use API response headers for archive filename in readTree. Fixes bug for users with hosted Bitbucket. -- Updated dependencies [0b135e7e0] -- Updated dependencies [fa8ba330a] -- Updated dependencies [ed6baab66] - - @backstage/integration@0.3.0 - -## 0.4.3 - -### Patch Changes - -- Updated dependencies [466354aaa] - - @backstage/integration@0.2.0 - -## 0.4.2 - -### Patch Changes - -- 5ecd50f8a: Fix HTTPS certificate generation and add new config switch, enabling it simply by setting `backend.https = true`. Also introduces caching of generated certificates in order to avoid having to add a browser override every time the backend is restarted. -- 00042e73c: Moving the Git actions to isomorphic-git instead of the node binding version of nodegit -- 0829ff126: Tweaked development log formatter to include extra fields at the end of each log line -- 036a84373: Provide support for on-prem azure devops -- Updated dependencies [ad5c56fd9] -- Updated dependencies [036a84373] - - @backstage/config-loader@0.4.1 - - @backstage/integration@0.1.5 - -## 0.4.1 - -### Patch Changes - -- 1d1c2860f: Implement readTree on BitBucketUrlReader and getBitbucketDownloadUrl -- 4eafdec4a: Introduce readTree method for GitLab URL Reader -- Updated dependencies [1d1c2860f] -- Updated dependencies [4eafdec4a] -- Updated dependencies [178e09323] - - @backstage/integration@0.1.4 - -## 0.4.0 - -### Minor Changes - -- 12bbd748c: Removes the Prometheus integration from `backend-common`. - - Rational behind this change is to keep the metrics integration of Backstage - generic. Instead of directly relying on Prometheus, Backstage will expose - metrics in a generic way. Integrators can then export the metrics in their - desired format. For example using Prometheus. - - To keep the existing behavior, you need to integrate Prometheus in your - backend: - - First, add a dependency on `express-prom-bundle` and `prom-client` to your backend. - - ```diff - // packages/backend/package.json - "dependencies": { - + "express-prom-bundle": "^6.1.0", - + "prom-client": "^12.0.0", - ``` - - Then, add a handler for metrics and a simple instrumentation for the endpoints. - - ```typescript - // packages/backend/src/metrics.ts - import { useHotCleanup } from '@backstage/backend-common'; - import { RequestHandler } from 'express'; - import promBundle from 'express-prom-bundle'; - import prom from 'prom-client'; - import * as url from 'url'; - - const rootRegEx = new RegExp('^/([^/]*)/.*'); - const apiRegEx = new RegExp('^/api/([^/]*)/.*'); - - export function normalizePath(req: any): string { - const path = url.parse(req.originalUrl || req.url).pathname || '/'; - - // Capture /api/ and the plugin name - if (apiRegEx.test(path)) { - return path.replace(apiRegEx, '/api/$1'); - } - - // Only the first path segment at root level - return path.replace(rootRegEx, '/$1'); - } - - /** - * Adds a /metrics endpoint, register default runtime metrics and instrument the router. - */ - export function metricsHandler(): RequestHandler { - // We can only initialize the metrics once and have to clean them up between hot reloads - useHotCleanup(module, () => prom.register.clear()); - - return promBundle({ - includeMethod: true, - includePath: true, - // Using includePath alone is problematic, as it will include path labels with high - // cardinality (e.g. path params). Instead we would have to template them. However, this - // is difficult, as every backend plugin might use different routes. Instead we only take - // the first directory of the path, to have at least an idea how each plugin performs: - normalizePath, - promClient: { collectDefaultMetrics: {} }, - }); - } - ``` - - Last, extend your router configuration with the `metricsHandler`: - - ```diff - +import { metricsHandler } from './metrics'; - - ... - - const service = createServiceBuilder(module) - .loadConfig(config) - .addRouter('', await healthcheck(healthcheckEnv)) - + .addRouter('', metricsHandler()) - .addRouter('/api', apiRouter); - ``` - - Your Prometheus metrics will be available at the `/metrics` endpoint. - -### Patch Changes - -- 38e24db00: Move the core url and auth logic to integration for the four major providers -- Updated dependencies [38e24db00] -- Updated dependencies [b8ecf6f48] -- Updated dependencies [e3bd9fc2f] -- Updated dependencies [e3bd9fc2f] - - @backstage/integration@0.1.3 - - @backstage/config@0.1.2 - -## 0.3.3 - -### Patch Changes - -- 612368274: Allow the `backend.listen.port` config to be both a number or a string. -- Updated dependencies [4e7091759] -- Updated dependencies [b4488ddb0] - - @backstage/config-loader@0.4.0 - -## 0.3.2 - -### Patch Changes - -- 3aa7efb3f: Added support for passing false as a CSP field value, to drop it from the defaults in the backend -- b3d4e4e57: Move the frontend visibility declarations of integrations config from @backstage/backend-common to @backstage/integration -- Updated dependencies [b3d4e4e57] - - @backstage/integration@0.1.2 - -## 0.3.1 - -### Patch Changes - -- bff3305aa: Added readTree support to AzureUrlReader -- b47dce06f: Make integration host and url configurations visible in the frontend - -## 0.3.0 - -### Minor Changes - -- 1722cb53c: Added support for loading and validating configuration schemas, as well as declaring config visibility through schemas. - - The new `loadConfigSchema` function exported by `@backstage/config-loader` allows for the collection and merging of configuration schemas from all nearby dependencies of the project. - - A configuration schema is declared using the `https://backstage.io/schema/config-v1` JSON Schema meta schema, which is based on draft07. The only difference to the draft07 schema is the custom `visibility` keyword, which is used to indicate whether the given config value should be visible in the frontend or not. The possible values are `frontend`, `backend`, and `secret`, where `backend` is the default. A visibility of `secret` has the same scope at runtime, but it will be treated with more care in certain contexts, and defining both `frontend` and `secret` for the same value in two different schemas will result in an error during schema merging. - - Packages that wish to contribute configuration schema should declare it in a root `"configSchema"` field in `package.json`. The field can either contain an inlined JSON schema, or a relative path to a schema file. Schema files can be in either `.json` or `.d.ts` format. - - TypeScript configuration schema files should export a single `Config` type, for example: - - ```ts - export interface Config { - app: { - /** - * Frontend root URL - * @visibility frontend - */ - baseUrl: string; - }; - } - ``` - -- 8e2effb53: Refactored UrlReader.readTree to be required and accept (url, options) - -### Patch Changes - -- 1722cb53c: Added configuration schema -- 7b37e6834: Added the integration package -- Updated dependencies [1722cb53c] -- Updated dependencies [7b37e6834] - - @backstage/config-loader@0.3.0 - - @backstage/integration@0.1.1 - - @backstage/test-utils@0.1.3 - -## 0.2.1 - -### Patch Changes - -- 33b7300eb: Capture plugin name under the /api/ prefix for http metrics - -## 0.2.0 - -### Minor Changes - -- 5249594c5: Add service discovery interface and implement for single host deployments - - Fixes #1847, #2596 - - Went with an interface similar to the frontend DiscoveryApi, since it's dead simple but still provides a lot of flexibility in the implementation. - - Also ended up with two different methods, one for internal endpoint discovery and one for external. The two use-cases are explained a bit more in the docs, but basically it's service-to-service vs callback URLs. - - This did get me thinking about uniqueness and that we're heading towards a global namespace for backend plugin IDs. That's probably fine, but if we're happy with that we should leverage it a bit more to simplify the backend setup. For example we'd have each plugin provide its own ID and not manually mount on paths in the backend. - - Draft until we're happy with the implementation, then I can add more docs and changelog entry. Also didn't go on a thorough hunt for places where discovery can be used, but I don't think there are many since it's been pretty awkward to do service-to-service communication. - -- 56e4eb589: Make CSP configurable to fix app-backend served app not being able to fetch - - See discussion [here on discord](https://discordapp.com/channels/687207715902193673/687235481154617364/758721460163575850) - -- e37c0a005: Use localhost to fall back to IPv4 if IPv6 isn't available -- f00ca3cb8: Auto-create plugin databases - - Relates to #1598. - - This creates databases for plugins before handing off control to plugins. - - The list of plugins currently need to be hard-coded depending on the installed plugins. A later PR will properly refactor the code to provide a factory pattern where plugins specify what they need, and Knex instances will be provided based on the input. - -- 6579769df: Add the ability to import components from Bitbucket Server to the service catalog -- 8c2b76e45: **BREAKING CHANGE** - - The existing loading of additional config files like `app-config.development.yaml` using APP_ENV or NODE_ENV has been removed. - Instead, the CLI and backend process now accept one or more `--config` flags to load config files. - - Without passing any flags, `app-config.yaml` and, if it exists, `app-config.local.yaml` will be loaded. - If passing any `--config ` flags, only those files will be loaded, **NOT** the default `app-config.yaml` one. - - The old behaviour of for example `APP_ENV=development` can be replicated using the following flags: - - ```bash - --config ../../app-config.yaml --config ../../app-config.development.yaml - ``` - -- 8afce088a: Use APP_ENV before NODE_ENV for determining what config to load -- 7bbeb049f: Change loadBackendConfig to return the config directly - -### Patch Changes - -- 440a17b39: Added new UrlReader interface for reading opaque data from URLs with different providers. - - This new URL reading system is intended as a replacement for the various integrations towards - external systems in the catalog, scaffolder, and techdocs. It is configured via a new top-level - config section called 'integrations'. - - Along with the UrlReader interface is a new UrlReaders class, which exposes static factory - methods for instantiating readers that can read from many different integrations simultaneously. - -- Updated dependencies [8c2b76e45] -- Updated dependencies [ce5512bc0] - - @backstage/config-loader@0.2.0 - - @backstage/test-utils@0.1.2 diff --git a/packages/backend-common/README.md b/packages/backend-common/README.md deleted file mode 100644 index e9f2f43e83..0000000000 --- a/packages/backend-common/README.md +++ /dev/null @@ -1,42 +0,0 @@ -# @backstage/backend-common - -> [!CAUTION] -> This package is deprecated and will be removed in a near future, so please follow the deprecated instructions for the exports you still use. - -Common functionality library for Backstage backends, implementing logging, -error handling and similar. - -## Usage - -Add the library to your backend package: - -```bash -# From your Backstage root directory -yarn --cwd packages/backend add @backstage/backend-common -``` - -then make use of the handlers and logger as necessary: - -```typescript -import { - errorHandler, - getRootLogger, - notFoundHandler, - requestLoggingHandler, -} from '@backstage/backend-common'; - -const app = express(); -app.use(requestLoggingHandler()); -app.use('/home', myHomeRouter); -app.use(notFoundHandler()); -app.use(errorHandler()); - -app.listen(PORT, () => { - getRootLogger().info(`Listening on port ${PORT}`); -}); -``` - -## Documentation - -- [Backstage Readme](https://github.com/backstage/backstage/blob/master/README.md) -- [Backstage Documentation](https://backstage.io/docs) diff --git a/packages/backend-common/api-report-alpha.md b/packages/backend-common/api-report-alpha.md deleted file mode 100644 index 046e8264fb..0000000000 --- a/packages/backend-common/api-report-alpha.md +++ /dev/null @@ -1,32 +0,0 @@ -## API Report File for "@backstage/backend-common" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -import { Duration } from 'luxon'; - -// @alpha @deprecated -export interface Context { - readonly abortSignal: AbortSignal; - readonly deadline: Date | undefined; - value(key: string): T | undefined; -} - -// @alpha @deprecated -export class Contexts { - static root(): Context; - static withAbort( - parentCtx: Context, - source: AbortController | AbortSignal, - ): Context; - static withTimeoutDuration(parentCtx: Context, timeout: Duration): Context; - static withTimeoutMillis(parentCtx: Context, timeout: number): Context; - static withValue( - parentCtx: Context, - key: string, - value: unknown | ((previous: unknown | undefined) => unknown), - ): Context; -} - -// (No @packageDocumentation comment for this package) -``` diff --git a/packages/backend-common/api-report-testUtils.md b/packages/backend-common/api-report-testUtils.md deleted file mode 100644 index d53748234e..0000000000 --- a/packages/backend-common/api-report-testUtils.md +++ /dev/null @@ -1,21 +0,0 @@ -## API Report File for "@backstage/backend-common" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -import { overridePackagePathResolution as overridePackagePathResolution_2 } from '@backstage/backend-plugin-api/testUtils'; -import { OverridePackagePathResolutionOptions as OverridePackagePathResolutionOptions_2 } from '@backstage/backend-plugin-api/testUtils'; -import { PackagePathResolutionOverride as PackagePathResolutionOverride_2 } from '@backstage/backend-plugin-api/testUtils'; - -// @public @deprecated (undocumented) -export const overridePackagePathResolution: typeof overridePackagePathResolution_2; - -// @public @deprecated (undocumented) -export type OverridePackagePathResolutionOptions = - OverridePackagePathResolutionOptions_2; - -// @public @deprecated (undocumented) -export type PackagePathResolutionOverride = PackagePathResolutionOverride_2; - -// (No @packageDocumentation comment for this package) -``` diff --git a/packages/backend-common/api-report.md b/packages/backend-common/api-report.md deleted file mode 100644 index 1a67d4877f..0000000000 --- a/packages/backend-common/api-report.md +++ /dev/null @@ -1,561 +0,0 @@ -## API Report File for "@backstage/backend-common" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -/// -/// - -import { AppConfig } from '@backstage/config'; -import { AuthCallback } from 'isomorphic-git'; -import { AuthService } from '@backstage/backend-plugin-api'; -import { BackendFeature } from '@backstage/backend-plugin-api'; -import { CacheService } from '@backstage/backend-plugin-api'; -import { CacheServiceOptions } from '@backstage/backend-plugin-api'; -import { CacheServiceSetOptions } from '@backstage/backend-plugin-api'; -import { Config } from '@backstage/config'; -import { ConfigSchema } from '@backstage/config-loader'; -import cors from 'cors'; -import { DatabaseService } from '@backstage/backend-plugin-api'; -import { DiscoveryService } from '@backstage/backend-plugin-api'; -import Docker from 'dockerode'; -import { ErrorRequestHandler } from 'express'; -import express from 'express'; -import { HttpAuthService } from '@backstage/backend-plugin-api'; -import { isChildPath as isChildPath_2 } from '@backstage/backend-plugin-api'; -import { isDatabaseConflictError as isDatabaseConflictError_2 } from '@backstage/backend-plugin-api'; -import { KubeConfig } from '@kubernetes/client-node'; -import { LifecycleService } from '@backstage/backend-plugin-api'; -import { LoadConfigOptionsRemote } from '@backstage/config-loader'; -import { Logger } from 'winston'; -import { LoggerService } from '@backstage/backend-plugin-api'; -import { MergeResult } from 'isomorphic-git'; -import { PermissionsService } from '@backstage/backend-plugin-api'; -import { PluginMetadataService } from '@backstage/backend-plugin-api'; -import { PushResult } from 'isomorphic-git'; -import { ReadCommitResult } from 'isomorphic-git'; -import { Request as Request_2 } from 'express'; -import { RequestHandler } from 'express'; -import { resolvePackagePath as resolvePackagePath_2 } from '@backstage/backend-plugin-api'; -import { resolveSafeChildPath as resolveSafeChildPath_2 } from '@backstage/backend-plugin-api'; -import { RootConfigService } from '@backstage/backend-plugin-api'; -import { Router } from 'express'; -import { SchedulerService } from '@backstage/backend-plugin-api'; -import { Server } from 'http'; -import { ServiceRef } from '@backstage/backend-plugin-api'; -import { TransportStreamOptions } from 'winston-transport'; -import { UrlReaderService } from '@backstage/backend-plugin-api'; -import { UserInfoService } from '@backstage/backend-plugin-api'; -import { V1PodTemplateSpec } from '@kubernetes/client-node'; -import * as winston from 'winston'; -import { Writable } from 'stream'; - -// @public @deprecated -export type AuthCallbackOptions = { - onAuth: AuthCallback; - logger?: LoggerService; -}; - -// @public @deprecated (undocumented) -export type CacheClient = CacheService; - -// @public @deprecated (undocumented) -export type CacheClientOptions = CacheServiceOptions; - -// @public @deprecated (undocumented) -export type CacheClientSetOptions = CacheServiceSetOptions; - -// @public @deprecated (undocumented) -export class CacheManager { - // (undocumented) - forPlugin(pluginId: string): PluginCacheManager; - static fromConfig( - config: RootConfigService, - options?: CacheManagerOptions, - ): CacheManager; -} - -// Warning: (ae-forgotten-export) The symbol "CacheManagerOptions_2" needs to be exported by the entry point index.d.ts -// -// @public @deprecated (undocumented) -export type CacheManagerOptions = CacheManagerOptions_2; - -// @public @deprecated -export function cacheToPluginCacheManager(cache: CacheService): { - getClient(options?: CacheServiceOptions): CacheService; -}; - -// @public @deprecated -export const coloredFormat: winston.Logform.Format; - -// @public @deprecated -export interface ContainerRunner { - runContainer(opts: RunContainerOptions): Promise; -} - -// Warning: (ae-forgotten-export) The symbol "createConfigSecretEnumerator_2" needs to be exported by the entry point index.d.ts -// -// @public @deprecated (undocumented) -export const createConfigSecretEnumerator: typeof createConfigSecretEnumerator_2; - -// @public @deprecated -export function createLegacyAuthAdapters< - TOptions extends { - auth?: AuthService; - httpAuth?: HttpAuthService; - userInfo?: UserInfoService; - identity?: LegacyIdentityService; - tokenManager?: TokenManager; - discovery: PluginEndpointDiscovery; - }, - TAdapters = (TOptions extends { - auth?: AuthService; - } - ? { - auth: AuthService; - } - : {}) & - (TOptions extends { - httpAuth?: HttpAuthService; - } - ? { - httpAuth: HttpAuthService; - } - : {}) & - (TOptions extends { - userInfo?: UserInfoService; - } - ? { - userInfo: UserInfoService; - } - : {}), ->(options: TOptions): TAdapters; - -// @public @deprecated -export function createRootLogger( - options?: winston.LoggerOptions, - env?: NodeJS.ProcessEnv, -): winston.Logger; - -// @public @deprecated -export function createServiceBuilder(_module: NodeModule): ServiceBuilder; - -// @public @deprecated -export function createStatusCheckRouter(options: { - logger: LoggerService; - path?: string; - statusCheck?: StatusCheck; -}): Promise; - -// @public @deprecated (undocumented) -export class DatabaseManager implements LegacyRootDatabaseService { - // (undocumented) - forPlugin( - pluginId: string, - deps?: - | { - lifecycle: LifecycleService; - pluginMetadata: PluginMetadataService; - } - | undefined, - ): PluginDatabaseManager; - // (undocumented) - static fromConfig( - config: Config, - options?: { - migrations?: DatabaseService['migrations']; - logger?: LoggerService; - }, - ): DatabaseManager; -} - -// Warning: (ae-forgotten-export) The symbol "DatabaseManagerOptions_2" needs to be exported by the entry point index.d.ts -// -// @public @deprecated (undocumented) -export type DatabaseManagerOptions = DatabaseManagerOptions_2; - -// @public @deprecated -export class DockerContainerRunner implements ContainerRunner { - constructor(options: { dockerClient: Docker }); - // (undocumented) - runContainer(options: RunContainerOptions): Promise; -} - -// @public @deprecated -export function errorHandler( - options?: ErrorHandlerOptions, -): ErrorRequestHandler; - -// @public @deprecated -export type ErrorHandlerOptions = { - showStackTraces?: boolean; - logger?: LoggerService; - logClientErrors?: boolean; -}; - -// @public @deprecated -export function getRootLogger(): winston.Logger; - -// @public @deprecated -export function getVoidLogger(): winston.Logger; - -// @public @deprecated -export class Git { - // (undocumented) - add(options: { dir: string; filepath: string }): Promise; - // (undocumented) - addRemote(options: { - dir: string; - remote: string; - url: string; - force?: boolean; - }): Promise; - // (undocumented) - branch(options: { dir: string; ref: string }): Promise; - // (undocumented) - checkout(options: { dir: string; ref: string }): Promise; - clone(options: { - url: string; - dir: string; - ref?: string; - depth?: number; - noCheckout?: boolean; - }): Promise; - // (undocumented) - commit(options: { - dir: string; - message: string; - author: { - name: string; - email: string; - }; - committer: { - name: string; - email: string; - }; - }): Promise; - currentBranch(options: { - dir: string; - fullName?: boolean; - }): Promise; - // (undocumented) - deleteRemote(options: { dir: string; remote: string }): Promise; - fetch(options: { - dir: string; - remote?: string; - tags?: boolean; - }): Promise; - // (undocumented) - static fromAuth: (options: StaticAuthOptions | AuthCallbackOptions) => Git; - // (undocumented) - init(options: { dir: string; defaultBranch?: string }): Promise; - log(options: { dir: string; ref?: string }): Promise; - merge(options: { - dir: string; - theirs: string; - ours?: string; - author: { - name: string; - email: string; - }; - committer: { - name: string; - email: string; - }; - }): Promise; - // (undocumented) - push(options: { - dir: string; - remote: string; - remoteRef?: string; - force?: boolean; - }): Promise; - readCommit(options: { dir: string; sha: string }): Promise; - remove(options: { dir: string; filepath: string }): Promise; - resolveRef(options: { dir: string; ref: string }): Promise; -} - -// @public @deprecated -class HostDiscovery implements DiscoveryService { - static fromConfig(config: Config): HostDiscovery; - // (undocumented) - getBaseUrl(pluginId: string): Promise; - // (undocumented) - getExternalBaseUrl(pluginId: string): Promise; -} -export { HostDiscovery }; -export { HostDiscovery as SingleHostDiscovery }; - -// @public @deprecated (undocumented) -export const isChildPath: typeof isChildPath_2; - -// @public @deprecated (undocumented) -export const isDatabaseConflictError: typeof isDatabaseConflictError_2; - -// @public @deprecated -export class KubernetesContainerRunner implements ContainerRunner { - constructor(options: KubernetesContainerRunnerOptions); - // (undocumented) - runContainer(options: RunContainerOptions): Promise; -} - -// @public @deprecated -export type KubernetesContainerRunnerMountBase = { - volumeName: string; - basePath: string; -}; - -// @public @deprecated -export type KubernetesContainerRunnerOptions = { - kubeConfig: KubeConfig; - name: string; - namespace?: string; - mountBase?: KubernetesContainerRunnerMountBase; - podTemplate?: V1PodTemplateSpec; - timeoutMs?: number; -}; - -// @public @deprecated (undocumented) -export type LegacyCreateRouter = (deps: TEnv) => Promise; - -// @public @deprecated -export interface LegacyIdentityService { - // (undocumented) - getIdentity(options: { request: Request_2 }): Promise< - | { - expiresInSeconds?: number; - token: string; - identity: { - type: 'user'; - userEntityRef: string; - ownershipEntityRefs: string[]; - }; - } - | undefined - >; -} - -// @public @deprecated -export const legacyPlugin: ( - name: string, - createRouterImport: Promise<{ - default: LegacyCreateRouter< - TransformedEnv< - { - cache: CacheService; - config: RootConfigService; - database: DatabaseService; - discovery: DiscoveryService; - logger: LoggerService; - permissions: PermissionsService; - scheduler: SchedulerService; - reader: UrlReaderService; - }, - { - logger: (log: LoggerService) => Logger; - cache: (cache: CacheService) => { - getClient(options?: CacheServiceOptions | undefined): CacheService; - }; - } - > & { - tokenManager: TokenManager; - identity: LegacyIdentityService; - } - >; - }>, -) => BackendFeature; - -// @public @deprecated (undocumented) -export type LegacyRootDatabaseService = { - forPlugin(pluginId: string): DatabaseService; -}; - -// @public @deprecated -export function loadBackendConfig(options: { - logger: LoggerService; - remote?: LoadConfigOptionsRemote; - additionalConfigs?: AppConfig[]; - argv: string[]; - watch?: boolean; -}): Promise; - -// @public @deprecated (undocumented) -export function loggerToWinstonLogger( - logger: LoggerService, - opts?: TransportStreamOptions, -): Logger; - -// @public @deprecated -export function makeLegacyPlugin< - TEnv extends Record, - TEnvTransforms extends { - [key in keyof TEnv]?: (dep: TEnv[key]) => unknown; - }, ->( - envMapping: { - [key in keyof TEnv]: ServiceRef; - }, - envTransforms: TEnvTransforms, -): ( - name: string, - createRouterImport: Promise<{ - default: LegacyCreateRouter< - TransformedEnv & { - tokenManager: TokenManager; - identity: LegacyIdentityService; - } - >; - }>, -) => BackendFeature; - -// @public @deprecated -export function notFoundHandler(): RequestHandler; - -// @public @deprecated (undocumented) -export type PluginCacheManager = { - getClient(options?: CacheServiceOptions): CacheService; -}; - -// @public @deprecated (undocumented) -export type PluginDatabaseManager = DatabaseService; - -// @public @deprecated (undocumented) -export type PluginEndpointDiscovery = DiscoveryService; - -// @public @deprecated -export interface PullOptions { - // (undocumented) - [key: string]: unknown; - // (undocumented) - authconfig?: { - username?: string; - password?: string; - auth?: string; - email?: string; - serveraddress?: string; - [key: string]: unknown; - }; -} - -// @public @deprecated -export function redactWinstonLogLine( - info: winston.Logform.TransformableInfo, -): winston.Logform.TransformableInfo; - -// @public @deprecated -export function requestLoggingHandler(logger?: LoggerService): RequestHandler; - -// @public @deprecated -export type RequestLoggingHandlerFactory = ( - logger?: LoggerService, -) => RequestHandler; - -// @public @deprecated (undocumented) -export const resolvePackagePath: typeof resolvePackagePath_2; - -// @public @deprecated (undocumented) -export const resolveSafeChildPath: typeof resolveSafeChildPath_2; - -// @public @deprecated -export type RunContainerOptions = { - imageName: string; - command?: string | string[]; - args: string[]; - logStream?: Writable; - mountDirs?: Record; - workingDir?: string; - envVars?: Record; - pullImage?: boolean; - defaultUser?: boolean; - pullOptions?: PullOptions; -}; - -// @public @deprecated -export class ServerTokenManager implements TokenManager { - // (undocumented) - authenticate(token: string): Promise; - // (undocumented) - static fromConfig( - config: Config, - options: ServerTokenManagerOptions, - ): TokenManager; - // (undocumented) - getToken(): Promise<{ - token: string; - }>; - static noop(): TokenManager; -} - -// @public @deprecated -export interface ServerTokenManagerOptions { - allowDisabledTokenManager?: boolean; - logger: LoggerService; -} - -// @public @deprecated -export type ServiceBuilder = { - loadConfig(config: Config): ServiceBuilder; - setPort(port: number): ServiceBuilder; - setHost(host: string): ServiceBuilder; - setLogger(logger: LoggerService): ServiceBuilder; - enableCors(options: cors.CorsOptions): ServiceBuilder; - setHttpsSettings(settings: { - certificate: - | { - key: string; - cert: string; - } - | { - hostname: string; - }; - }): ServiceBuilder; - addRouter(root: string, router: Router | RequestHandler): ServiceBuilder; - setRequestLoggingHandler( - requestLoggingHandler: RequestLoggingHandlerFactory, - ): ServiceBuilder; - setErrorHandler(errorHandler: ErrorRequestHandler): ServiceBuilder; - disableDefaultErrorHandler(): ServiceBuilder; - start(): Promise; -}; - -// @public @deprecated -export function setRootLogger(newLogger: winston.Logger): void; - -// @public @deprecated -export type StaticAuthOptions = { - username?: string; - password?: string; - token?: string; - logger?: LoggerService; -}; - -// @public @deprecated -export type StatusCheck = () => Promise; - -// @public @deprecated -export function statusCheckHandler( - options?: StatusCheckHandlerOptions, -): Promise; - -// @public @deprecated -export interface StatusCheckHandlerOptions { - statusCheck?: StatusCheck; -} - -// @public @deprecated (undocumented) -export interface TokenManager { - authenticate(token: string): Promise; - getToken(): Promise<{ - token: string; - }>; -} - -// @public @deprecated -export function useHotCleanup( - _module: NodeModule, - cancelEffect: () => void, -): void; - -// @public @deprecated -export function useHotMemoize(_module: NodeModule, valueFactory: () => T): T; -``` diff --git a/packages/backend-common/catalog-info.yaml b/packages/backend-common/catalog-info.yaml deleted file mode 100644 index ff38a4df75..0000000000 --- a/packages/backend-common/catalog-info.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: backstage-backend-common - title: '@backstage/backend-common' - description: Common functionality library for Backstage backends -spec: - lifecycle: experimental - type: backstage-node-library - owner: maintainers diff --git a/packages/backend-common/config.d.ts b/packages/backend-common/config.d.ts deleted file mode 100644 index 6146adfe83..0000000000 --- a/packages/backend-common/config.d.ts +++ /dev/null @@ -1,265 +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 { HumanDuration } from '@backstage/types'; - -export interface Config { - app: { - baseUrl: string; // defined in core, but repeated here without doc - }; - - backend: { - /** Backend configuration for when request authentication is enabled */ - auth?: { - /** Keys shared by all backends for signing and validating backend tokens. */ - keys?: { - /** - * Secret for generating tokens. Should be a base64 string, recommended - * length is 24 bytes. - * - * @visibility secret - */ - secret: string; - }[]; - }; - - baseUrl: string; // defined in core, but repeated here without doc - - /** Address that the backend should listen to. */ - listen: - | string - | { - /** Address of the interface that the backend should bind to. */ - host?: string; - /** Port that the backend should listen to. */ - port?: string | number; - }; - - /** - * HTTPS configuration for the backend. If omitted the backend will serve HTTP. - * - * Setting this to `true` will cause self-signed certificates to be generated, which - * can be useful for local development or other non-production scenarios. - */ - https?: - | true - | { - /** Certificate configuration */ - certificate?: { - /** PEM encoded certificate. Use $file to load in a file */ - cert: string; - /** - * PEM encoded certificate key. Use $file to load in a file. - * @visibility secret - */ - key: string; - }; - }; - - /** - * An absolute path to a directory that can be used as a working dir, for - * example as scratch space for large operations. - * - * @remarks - * - * Note that this must be an absolute path. - * - * If not set, the operating system's designated temporary directory is - * commonly used, but that is implementation defined per plugin. - * - * Plugins are encouraged to heed this config setting if present, to allow - * deployment in severely locked-down or limited environments. - */ - workingDirectory?: string; - - /** Database connection configuration, select base database type using the `client` field */ - database: { - /** Default database client to use */ - client: 'better-sqlite3' | 'sqlite3' | 'pg'; - /** - * Base database connection string, or object with individual connection properties - * @visibility secret - */ - connection: - | string - | { - /** - * Password that belongs to the client User - * @visibility secret - */ - password?: string; - /** - * Other connection settings - */ - [key: string]: unknown; - }; - /** Database name prefix override */ - prefix?: string; - /** - * Whether to ensure the given database exists by creating it if it does not. - * Defaults to true if unspecified. - */ - ensureExists?: boolean; - /** - * Whether to ensure the given database schema exists by creating it if it does not. - * Defaults to false if unspecified. - * - * NOTE: Currently only supported by the `pg` client when pluginDivisionMode: schema - */ - ensureSchemaExists?: boolean; - /** - * How plugins databases are managed/divided in the provided database instance. - * - * `database` -> Plugins are each given their own database to manage their schemas/tables. - * - * `schema` -> Plugins will be given their own schema (in the specified/default database) - * to manage their tables. - * - * NOTE: Currently only supported by the `pg` client. - * - * @default database - */ - pluginDivisionMode?: 'database' | 'schema'; - /** Configures the ownership of newly created schemas in pg databases. */ - role?: string; - /** - * Arbitrary config object to pass to knex when initializing - * (https://knexjs.org/#Installation-client). Most notable is the debug - * and asyncStackTraces booleans - */ - knexConfig?: object; - /** Plugin specific database configuration and client override */ - plugin?: { - [pluginId: string]: { - /** Database client override */ - client?: 'better-sqlite3' | 'sqlite3' | 'pg'; - /** - * Database connection string or Knex object override - * @visibility secret - */ - connection?: string | object; - /** - * Whether to ensure the given database exists by creating it if it does not. - * Defaults to base config if unspecified. - */ - ensureExists?: boolean; - /** - * Whether to ensure the given database schema exists by creating it if it does not. - * Defaults to false if unspecified. - * - * NOTE: Currently only supported by the `pg` client when pluginDivisionMode: schema - */ - ensureSchemaExists?: boolean; - /** - * Arbitrary config object to pass to knex when initializing - * (https://knexjs.org/#Installation-client). Most notable is the - * debug and asyncStackTraces booleans. - * - * This is merged recursively into the base knexConfig - */ - knexConfig?: object; - /** Configures the ownership of newly created schemas in pg databases. */ - role?: string; - }; - }; - }; - - /** Cache connection configuration, select cache type using the `store` field */ - cache?: - | { - store: 'memory'; - /** An optional default TTL (in milliseconds). */ - defaultTtl?: number | HumanDuration; - } - | { - store: 'redis'; - /** - * A redis connection string in the form `redis://user:pass@host:port`. - * @visibility secret - */ - connection: string; - /** An optional default TTL (in milliseconds). */ - defaultTtl?: number | HumanDuration; - /** - * Whether or not [useRedisSets](https://github.com/jaredwray/keyv/tree/main/packages/redis#useredissets) should be configured to this redis cache. - * Defaults to true if unspecified. - */ - useRedisSets?: boolean; - } - | { - store: 'memcache'; - /** - * A memcache connection string in the form `user:pass@host:port`. - * @visibility secret - */ - connection: string; - /** An optional default TTL (in milliseconds). */ - defaultTtl?: number | HumanDuration; - }; - - /** - * Properties returned upon CORS requests to the backend, including the app-backend. - */ - cors?: { - origin?: string | string[]; - methods?: string | string[]; - allowedHeaders?: string | string[]; - exposedHeaders?: string | string[]; - credentials?: boolean; - maxAge?: number; - preflightContinue?: boolean; - optionsSuccessStatus?: number; - }; - - /** - * Content Security Policy options. - * - * The keys are the plain policy ID, e.g. "upgrade-insecure-requests". The - * values are on the format that the helmet library expects them, as an - * array of strings. There is also the special value false, which means to - * remove the default value that Backstage puts in place for that policy. - */ - csp?: { [policyId: string]: string[] | false }; - - /** - * Configuration related to URL reading, used for example for reading catalog info - * files, scaffolder templates, and techdocs content. - */ - reading?: { - /** - * A list of targets to allow outgoing requests to. Users will be able to make - * requests on behalf of the backend to the targets that are allowed by this list. - */ - allow?: Array<{ - /** - * A host to allow outgoing requests to, being either a full host or - * a subdomain wildcard pattern with a leading `*`. For example `example.com` - * and `*.example.com` are valid values, `prod.*.example.com` is not. - * The host may also contain a port, for example `example.com:8080`. - */ - host: string; - - /** - * An optional list of paths. In case they are present only targets matching - * any of them will are allowed. You can use trailing slashes to make sure only - * subdirectories are allowed, for example `/mydir/` will allow targets with - * paths like `/mydir/a` but will block paths like `/mydir2`. - */ - paths?: string[]; - }>; - }; - }; -} diff --git a/packages/backend-common/knip-report.md b/packages/backend-common/knip-report.md deleted file mode 100644 index ae0fd612a9..0000000000 --- a/packages/backend-common/knip-report.md +++ /dev/null @@ -1,24 +0,0 @@ -# Knip report - -## Unused dependencies (3) - -| Name | Location | Severity | -| :-------------------- | :----------- | :------- | -| @manypkg/get-packages | package.json | error | -| @types/webpack-env | package.json | error | -| mysql2 | package.json | error | - -## Unused devDependencies (3) - -| Name | Location | Severity | -| :----------------- | :----------- | :------- | -| @types/webpack-env | package.json | error | -| better-sqlite3 | package.json | error | -| mysql2 | package.json | error | - -## Referenced optional peerDependencies (1) - -| Name | Location | Severity | -| :------------------- | :----------- | :------- | -| pg-connection-string | package.json | error | - diff --git a/packages/backend-common/package.json b/packages/backend-common/package.json deleted file mode 100644 index 1e052c8eba..0000000000 --- a/packages/backend-common/package.json +++ /dev/null @@ -1,156 +0,0 @@ -{ - "name": "@backstage/backend-common", - "version": "0.25.0-next.1", - "description": "Common functionality library for Backstage backends", - "backstage": { - "role": "node-library" - }, - "publishConfig": { - "access": "public" - }, - "keywords": [ - "backstage" - ], - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "packages/backend-common" - }, - "license": "Apache-2.0", - "exports": { - ".": "./src/index.ts", - "./alpha": "./src/alpha.ts", - "./testUtils": "./src/testUtils.ts", - "./package.json": "./package.json" - }, - "main": "src/index.ts", - "types": "src/index.ts", - "typesVersions": { - "*": { - "alpha": [ - "src/alpha.ts" - ], - "testUtils": [ - "src/testUtils.ts" - ], - "package.json": [ - "package.json" - ] - } - }, - "files": [ - "dist", - "config.d.ts" - ], - "scripts": { - "build": "backstage-cli package build", - "clean": "backstage-cli package clean", - "lint": "backstage-cli package lint", - "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack", - "start": "backstage-cli package start", - "test": "backstage-cli package test", - "test:kubernetes": "backstage-cli package test -t KubernetesContainerRunner --no-watch" - }, - "dependencies": { - "@aws-sdk/abort-controller": "^3.347.0", - "@aws-sdk/client-codecommit": "^3.350.0", - "@aws-sdk/client-s3": "^3.350.0", - "@aws-sdk/credential-providers": "^3.350.0", - "@aws-sdk/types": "^3.347.0", - "@backstage/backend-dev-utils": "workspace:^", - "@backstage/backend-plugin-api": "workspace:^", - "@backstage/cli-common": "workspace:^", - "@backstage/config": "workspace:^", - "@backstage/config-loader": "workspace:^", - "@backstage/errors": "workspace:^", - "@backstage/integration": "workspace:^", - "@backstage/integration-aws-node": "workspace:^", - "@backstage/plugin-auth-node": "workspace:^", - "@backstage/types": "workspace:^", - "@google-cloud/storage": "^7.0.0", - "@keyv/memcache": "^1.3.5", - "@keyv/redis": "^2.5.3", - "@kubernetes/client-node": "0.20.0", - "@manypkg/get-packages": "^1.1.3", - "@octokit/rest": "^19.0.3", - "@types/cors": "^2.8.6", - "@types/dockerode": "^3.3.0", - "@types/express": "^4.17.6", - "@types/luxon": "^3.0.0", - "@types/webpack-env": "^1.15.2", - "archiver": "^6.0.0", - "base64-stream": "^1.0.0", - "compression": "^1.7.4", - "concat-stream": "^2.0.0", - "cors": "^2.8.5", - "dockerode": "^4.0.0", - "express": "^4.17.1", - "express-promise-router": "^4.1.0", - "fs-extra": "^11.2.0", - "git-url-parse": "^14.0.0", - "helmet": "^6.0.0", - "isomorphic-git": "^1.23.0", - "jose": "^5.0.0", - "keyv": "^4.5.2", - "knex": "^3.0.0", - "lodash": "^4.17.21", - "logform": "^2.3.2", - "luxon": "^3.0.0", - "minimatch": "^9.0.0", - "minimist": "^1.2.5", - "morgan": "^1.10.0", - "mysql2": "^3.0.0", - "node-fetch": "^2.7.0", - "node-forge": "^1.3.1", - "p-limit": "^3.1.0", - "path-to-regexp": "^6.2.1", - "pg": "^8.11.3", - "pg-format": "^1.0.4", - "raw-body": "^2.4.1", - "selfsigned": "^2.0.0", - "stoppable": "^1.1.0", - "tar": "^6.1.12", - "triple-beam": "^1.4.1", - "uuid": "^9.0.0", - "winston": "^3.2.1", - "winston-transport": "^4.5.0", - "yauzl": "^3.0.0", - "yn": "^4.0.0" - }, - "devDependencies": { - "@aws-sdk/util-stream-node": "^3.350.0", - "@backstage/backend-test-utils": "workspace:^", - "@backstage/cli": "workspace:^", - "@types/archiver": "^6.0.0", - "@types/base64-stream": "^1.0.2", - "@types/compression": "^1.7.0", - "@types/concat-stream": "^2.0.0", - "@types/fs-extra": "^11.0.0", - "@types/http-errors": "^2.0.0", - "@types/morgan": "^1.9.0", - "@types/node-forge": "^1.3.0", - "@types/pg": "^8.6.6", - "@types/stoppable": "^1.1.0", - "@types/supertest": "^2.0.8", - "@types/tar": "^6.1.1", - "@types/webpack-env": "^1.15.2", - "@types/yauzl": "^2.10.0", - "aws-sdk-client-mock": "^4.0.0", - "better-sqlite3": "^11.0.0", - "http-errors": "^2.0.0", - "msw": "^1.0.0", - "mysql2": "^3.0.0", - "supertest": "^6.1.3" - }, - "peerDependencies": { - "pg-connection-string": "^2.3.0" - }, - "peerDependenciesMeta": { - "pg-connection-string": { - "optional": true - } - }, - "configSchema": "config.d.ts" -} diff --git a/packages/backend-common/src/compat/auth/createLegacyAuthAdapters.test.ts b/packages/backend-common/src/compat/auth/createLegacyAuthAdapters.test.ts deleted file mode 100644 index 49494761bf..0000000000 --- a/packages/backend-common/src/compat/auth/createLegacyAuthAdapters.test.ts +++ /dev/null @@ -1,145 +0,0 @@ -/* - * 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 { createLegacyAuthAdapters } from './createLegacyAuthAdapters'; -import { Request } from 'express'; -import { TokenManager } from '../../deprecated'; - -const mockTokenManager: TokenManager = { - async getToken(): Promise<{ token: string }> { - return { token: 'mock-token' }; - }, - async authenticate(token: string): Promise { - if (token !== 'mock-token') { - throw new Error('Invalid token'); - } - }, -}; - -describe('createLegacyAuthAdapters', () => { - it('should pass through auth if only auth is provided', () => { - const auth = {}; - const ret = createLegacyAuthAdapters({ - auth: auth as any, - tokenManager: mockTokenManager, - discovery: {} as any, - }); - - expect(ret.auth).toBe(auth); - }); - - it('should pass through httpAuth if only httpAuth is provided', () => { - const httpAuth = {}; - const ret = createLegacyAuthAdapters({ - httpAuth: httpAuth as any, - tokenManager: mockTokenManager, - discovery: {} as any, - }); - - expect(ret.httpAuth).toBe(httpAuth); - }); - - it('should pass through both auth and httpAuth if both are provided', () => { - const auth = {}; - const httpAuth = {}; - const ret = createLegacyAuthAdapters({ - auth: auth as any, - httpAuth: httpAuth as any, - tokenManager: mockTokenManager, - discovery: {} as any, - }); - - expect(ret.auth).toBe(auth); - expect(ret.httpAuth).toBe(httpAuth); - }); - - it('should pass through userInfo if it is provided', () => { - const auth = {}; - const userInfo = {}; - const ret = createLegacyAuthAdapters({ - auth: auth as any, - userInfo: userInfo as any, - tokenManager: mockTokenManager, - discovery: {} as any, - }); - - expect(ret.auth).toBe(auth); - expect(ret.userInfo).toBe(userInfo); - }); - - it('should adapt all services if none are provided', () => { - const ret = createLegacyAuthAdapters({ - auth: undefined, - httpAuth: undefined, - tokenManager: mockTokenManager, - discovery: {} as any, - }); - - expect(ret).toEqual({ - auth: expect.any(Object), - httpAuth: expect.any(Object), - userInfo: expect.any(Object), - }); - }); - - it('should forward tokens if no token manager is provided', async () => { - const { auth, httpAuth } = createLegacyAuthAdapters({ - auth: undefined, - httpAuth: undefined, - discovery: {} as any, - }); - - const credentials = await httpAuth.credentials({ - headers: { - authorization: 'Bearer my-token', - }, - } as Request); - - await expect( - auth.getPluginRequestToken({ - onBehalfOf: credentials, - targetPluginId: 'test', - }), - ).resolves.toEqual({ token: 'my-token' }); - }); - - it('should issue a new token if a token manager is provided', async () => { - const { auth, httpAuth } = createLegacyAuthAdapters({ - auth: undefined, - httpAuth: undefined, - tokenManager: { - ...mockTokenManager, - async getToken() { - return { token: 'new-token' }; - }, - }, - discovery: {} as any, - }); - - const credentials = await httpAuth.credentials({ - headers: { - authorization: 'Bearer mock-token', - }, - } as Request); - - await expect( - auth.getPluginRequestToken({ - onBehalfOf: credentials, - targetPluginId: 'test', - }), - ).resolves.toEqual({ token: 'new-token' }); - }); -}); diff --git a/packages/backend-common/src/compat/auth/createLegacyAuthAdapters.ts b/packages/backend-common/src/compat/auth/createLegacyAuthAdapters.ts deleted file mode 100644 index fc02d936d1..0000000000 --- a/packages/backend-common/src/compat/auth/createLegacyAuthAdapters.ts +++ /dev/null @@ -1,356 +0,0 @@ -/* - * 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 { - AuthService, - BackstageCredentials, - BackstageNonePrincipal, - BackstagePrincipalTypes, - BackstageServicePrincipal, - BackstageUserInfo, - BackstageUserPrincipal, - HttpAuthService, - UserInfoService, -} from '@backstage/backend-plugin-api'; -import { AuthenticationError, NotAllowedError } from '@backstage/errors'; -import type { Request, Response } from 'express'; -// eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { - createCredentialsWithServicePrincipal, - createCredentialsWithUserPrincipal, - createCredentialsWithNonePrincipal, - toInternalBackstageCredentials, -} from '../../../../backend-defaults/src/entrypoints/auth/helpers'; -// TODO is this circular thingy a problem? Test in e2e -import { - type IdentityApiGetIdentityRequest, - DefaultIdentityClient, -} from '@backstage/plugin-auth-node'; -import { decodeJwt } from 'jose'; -import { TokenManager, PluginEndpointDiscovery } from '../../deprecated'; -import { JsonObject } from '@backstage/types'; -import { LegacyIdentityService } from '../legacy'; - -class AuthCompat implements AuthService { - constructor( - private readonly identity: LegacyIdentityService, - private readonly tokenManager?: TokenManager, - ) {} - - isPrincipal( - credentials: BackstageCredentials, - type: TType, - ): credentials is BackstageCredentials { - const principal = credentials.principal as - | BackstageUserPrincipal - | BackstageServicePrincipal; - - if (principal.type !== type) { - return false; - } - - return true; - } - - async getNoneCredentials(): Promise< - BackstageCredentials - > { - return createCredentialsWithNonePrincipal(); - } - - async getOwnServiceCredentials(): Promise< - BackstageCredentials - > { - return createCredentialsWithServicePrincipal('external:backstage-plugin'); - } - - async authenticate(token: string): Promise { - // Defensively check whether it seems token-like first, just to support - // custom TokenManager implementations that don't emit JWTs specifically. - const payload = - token.split('.').length === 3 ? decodeJwt(token) : undefined; - - if (payload?.aud === 'backstage') { - // User Backstage token - const identity = await this.identity.getIdentity({ - request: { - headers: { authorization: `Bearer ${token}` }, - }, - } as IdentityApiGetIdentityRequest); - - if (!identity) { - throw new AuthenticationError('Invalid user token'); - } - - return createCredentialsWithUserPrincipal( - identity.identity.userEntityRef, - token, - this.#getJwtExpiration(token), - ); - } - - await this.tokenManager?.authenticate(token); - - return createCredentialsWithServicePrincipal( - 'external:backstage-plugin', - token, - ); - } - - async getPluginRequestToken(options: { - onBehalfOf: BackstageCredentials; - targetPluginId: string; - }): Promise<{ token: string }> { - const internalForward = toInternalBackstageCredentials(options.onBehalfOf); - const { type } = internalForward.principal; - - switch (type) { - // TODO: Check whether the principal is ourselves - case 'service': { - if (this.tokenManager) { - return this.tokenManager.getToken(); - } - return { token: internalForward.token ?? '' }; - } - case 'user': - if (!internalForward.token) { - throw new Error('User credentials is unexpectedly missing token'); - } - return { token: internalForward.token }; - // NOTE: this is not the behavior of this service in the new backend system, it only applies - // here since we'll need to accept and forward requests without authentication. - case 'none': - return { token: '' }; - default: - throw new AuthenticationError( - `Refused to issue service token for credential type '${type}'`, - ); - } - } - - async getLimitedUserToken( - credentials: BackstageCredentials, - ): Promise<{ token: string; expiresAt: Date }> { - const internalCredentials = toInternalBackstageCredentials(credentials); - - const { token } = internalCredentials; - - if (!token) { - throw new AuthenticationError( - 'User credentials is unexpectedly missing token', - ); - } - - return { token, expiresAt: this.#getJwtExpiration(token) }; - } - - #getJwtExpiration(token: string) { - const { exp } = decodeJwt(token); - if (!exp) { - throw new AuthenticationError('User token is missing expiration'); - } - return new Date(exp * 1000); - } - - listPublicServiceKeys(): Promise<{ keys: JsonObject[] }> { - throw new Error('Not implemented'); - } -} - -function getTokenFromRequest(req: Request) { - // TODO: support multiple auth headers (iterate rawHeaders) - const authHeader = req.headers.authorization; - if (typeof authHeader === 'string') { - const matches = authHeader.match(/^Bearer[ ]+(\S+)$/i); - const token = matches?.[1]; - if (token) { - return token; - } - } - - return undefined; -} - -const credentialsSymbol = Symbol('backstage-credentials'); - -type RequestWithCredentials = Request & { - [credentialsSymbol]?: Promise; -}; - -class HttpAuthCompat implements HttpAuthService { - #auth: AuthService; - - constructor(auth: AuthService) { - this.#auth = auth; - } - - async #extractCredentialsFromRequest(req: Request) { - const token = getTokenFromRequest(req); - if (!token) { - return this.#auth.getNoneCredentials(); - } - - return this.#auth.authenticate(token); - } - - async #getCredentials(req: RequestWithCredentials) { - return (req[credentialsSymbol] ??= - this.#extractCredentialsFromRequest(req)); - } - - async credentials( - req: Request, - options?: { - allow?: Array; - allowLimitedAccess?: boolean; - }, - ): Promise> { - const credentials = await this.#getCredentials(req); - - const allowed = options?.allow; - if (!allowed) { - return credentials as any; - } - - if (this.#auth.isPrincipal(credentials, 'none')) { - if (allowed.includes('none' as TAllowed)) { - return credentials as any; - } - - throw new AuthenticationError('Missing credentials'); - } else if (this.#auth.isPrincipal(credentials, 'user')) { - if (allowed.includes('user' as TAllowed)) { - return credentials as any; - } - - throw new NotAllowedError( - `This endpoint does not allow 'user' credentials`, - ); - } else if (this.#auth.isPrincipal(credentials, 'service')) { - if (allowed.includes('service' as TAllowed)) { - return credentials as any; - } - - throw new NotAllowedError( - `This endpoint does not allow 'service' credentials`, - ); - } - - throw new NotAllowedError( - 'Unknown principal type, this should never happen', - ); - } - - async issueUserCookie(_res: Response): Promise<{ expiresAt: Date }> { - return { expiresAt: new Date(Date.now() + 3600_000) }; - } -} - -export class UserInfoCompat implements UserInfoService { - async getUserInfo( - credentials: BackstageCredentials, - ): Promise { - const internalCredentials = toInternalBackstageCredentials(credentials); - if (internalCredentials.principal.type !== 'user') { - throw new Error('Only user credentials are supported'); - } - if (!internalCredentials.token) { - throw new Error('User credentials is unexpectedly missing token'); - } - const { sub: userEntityRef, ent: ownershipEntityRefs = [] } = decodeJwt( - internalCredentials.token, - ); - - if (typeof userEntityRef !== 'string') { - throw new Error('User entity ref must be a string'); - } - if ( - !Array.isArray(ownershipEntityRefs) || - ownershipEntityRefs.some(ref => typeof ref !== 'string') - ) { - throw new Error('Ownership entity refs must be an array of strings'); - } - - return { userEntityRef, ownershipEntityRefs }; - } -} - -/** - * An adapter that ensures presence of the auth and/or httpAuth services. - * @public - * @deprecated Migrate to use the new backend system and auth services instead. - */ -export function createLegacyAuthAdapters< - TOptions extends { - auth?: AuthService; - httpAuth?: HttpAuthService; - userInfo?: UserInfoService; - identity?: LegacyIdentityService; - tokenManager?: TokenManager; - discovery: PluginEndpointDiscovery; - }, - TAdapters = (TOptions extends { auth?: AuthService } - ? { auth: AuthService } - : {}) & - (TOptions extends { httpAuth?: HttpAuthService } - ? { httpAuth: HttpAuthService } - : {}) & - (TOptions extends { userInfo?: UserInfoService } - ? { userInfo: UserInfoService } - : {}), ->(options: TOptions): TAdapters { - const { - auth, - httpAuth, - userInfo = new UserInfoCompat(), - discovery, - } = options; - - if (auth && httpAuth) { - return { - auth, - httpAuth, - userInfo, - } as TAdapters; - } - - if (auth) { - return { - auth, - userInfo, - } as TAdapters; - } - - if (httpAuth) { - return { - httpAuth, - userInfo, - } as TAdapters; - } - - const identity = - options.identity ?? DefaultIdentityClient.create({ discovery }); - - const authImpl = new AuthCompat(identity, options.tokenManager); - - const httpAuthImpl = new HttpAuthCompat(authImpl); - - return { - auth: authImpl, - httpAuth: httpAuthImpl, - userInfo, - } as TAdapters; -} diff --git a/packages/backend-common/src/compat/cache/cacheToPluginCacheManager.ts b/packages/backend-common/src/compat/cache/cacheToPluginCacheManager.ts deleted file mode 100644 index 2ae55b016f..0000000000 --- a/packages/backend-common/src/compat/cache/cacheToPluginCacheManager.ts +++ /dev/null @@ -1,35 +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 { - CacheService, - CacheServiceOptions, -} from '@backstage/backend-plugin-api'; - -/** - * Compatibility wrapper for going from a new-backend cache service to the - * old-backend plugin cache manager. - * - * @public - * @deprecated Migrate to use the new CacheService instead. - */ -export function cacheToPluginCacheManager(cache: CacheService): { - getClient(options?: CacheServiceOptions): CacheService; -} { - return { - getClient: (opts: CacheServiceOptions) => cache.withOptions(opts), - }; -} diff --git a/packages/backend-common/src/compat/cache/index.ts b/packages/backend-common/src/compat/cache/index.ts deleted file mode 100644 index bdd857037b..0000000000 --- a/packages/backend-common/src/compat/cache/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 { cacheToPluginCacheManager } from './cacheToPluginCacheManager'; diff --git a/packages/backend-common/src/compat/legacy/legacy.test.ts b/packages/backend-common/src/compat/legacy/legacy.test.ts deleted file mode 100644 index b7a5ff1a78..0000000000 --- a/packages/backend-common/src/compat/legacy/legacy.test.ts +++ /dev/null @@ -1,170 +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 { - coreServices, - createBackendPlugin, -} from '@backstage/backend-plugin-api'; -import { - mockCredentials, - mockServices, - startTestBackend, -} from '@backstage/backend-test-utils'; -import { EventEmitter } from 'events'; -import { Router } from 'express'; -import request from 'supertest'; -import { createLegacyAuthAdapters } from '..'; -import { legacyPlugin } from './legacy'; -// eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { authServiceFactory } from '../../../../backend-defaults/src/entrypoints/auth'; - -describe('legacyPlugin', () => { - it('can auth across the new and old systems', async () => { - const emitter = new EventEmitter(); - - const done = new Promise(resolve => { - emitter.once('done', () => { - emitter.once('done', resolve); - }); - }); - - await startTestBackend({ - features: [ - authServiceFactory, - mockServices.rootConfig.factory({ - data: { - backend: { - auth: { - keys: [ - { - secret: 'test', - }, - ], - }, - }, - }, - }), - createBackendPlugin({ - pluginId: 'new', - register(reg) { - reg.registerInit({ - deps: { - auth: coreServices.auth, - discovery: coreServices.discovery, - }, - async init({ auth }) { - emitter.once('legacy-token', async otherToken => { - const credentials = await auth.authenticate(otherToken); - expect(credentials.principal).toEqual({ - type: 'service', - subject: 'external:backstage-plugin', - }); - emitter.emit('done'); - }); - - const { token } = await auth.getPluginRequestToken({ - onBehalfOf: await auth.getOwnServiceCredentials(), - targetPluginId: 'old', - }); - emitter.emit('new-token', token); - }, - }); - }, - }), - legacyPlugin( - 'old', - Promise.resolve({ - async default({ tokenManager, identity, discovery }) { - const { auth } = createLegacyAuthAdapters({ - tokenManager, - identity, - discovery, - auth: undefined as any as typeof coreServices.auth.T, - httpAuth: undefined as any as typeof coreServices.httpAuth.T, - }); - - emitter.once('new-token', async otherToken => { - const credentials = await auth.authenticate(otherToken); - expect(credentials.principal).toEqual({ - type: 'service', - subject: 'external:backstage-plugin', - }); - emitter.emit('done'); - }); - - const { token } = await tokenManager.getToken(); - emitter.emit('legacy-token', token); - - return Router(); - }, - }), - ), - ], - }); - - await done; - }); - - it('can auth users with the identity service shim', async () => { - const backend = await startTestBackend({ - features: [ - mockServices.rootConfig.factory({ - data: { - backend: { - auth: { - keys: [ - { - secret: 'test', - }, - ], - }, - }, - }, - }), - legacyPlugin( - 'test', - Promise.resolve({ - async default({ identity }) { - const router = Router(); - - router.get('/', async (req, res) => { - const user = await identity.getIdentity({ request: req }); - res.json(user); - }); - - return router; - }, - }), - ), - ], - }); - - const res = await request(backend.server) - .get('/api/test') - .set('authorization', mockCredentials.user.header()); - - const mockUserRef = mockCredentials.user().principal.userEntityRef; - expect(res.status).toBe(200); - expect(res.body).toEqual({ - token: mockCredentials.user.token(), - identity: { - type: 'user', - userEntityRef: mockUserRef, - ownershipEntityRefs: [mockUserRef], - }, - }); - }); -}); diff --git a/packages/backend-common/src/compat/legacy/legacy.ts b/packages/backend-common/src/compat/legacy/legacy.ts deleted file mode 100644 index bf051f3040..0000000000 --- a/packages/backend-common/src/compat/legacy/legacy.ts +++ /dev/null @@ -1,254 +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 { - AuthService, - coreServices, - createBackendPlugin, - LoggerService, - RootConfigService, - ServiceRef, - UserInfoService, -} from '@backstage/backend-plugin-api'; -import { RequestHandler } from 'express'; -import { cacheToPluginCacheManager } from '../cache'; -import { loggerToWinstonLogger } from '../logging'; -import { ServerTokenManager, TokenManager } from '../../deprecated'; -import { Request } from 'express'; - -/** - * @public - * @deprecated Fully use the new backend system instead. - */ -export type LegacyCreateRouter = (deps: TEnv) => Promise; - -/** @ignore */ -type TransformedEnv< - TEnv extends Record, - TEnvTransforms extends { [key in keyof TEnv]?: (dep: TEnv[key]) => unknown }, -> = { - [key in keyof TEnv]: TEnvTransforms[key] extends (dep: TEnv[key]) => infer R - ? R - : TEnv[key]; -}; - -// Since the plugin will be using the new system our callers will expect us to support the -// new plugin tokens, which we'll also be signaling by supporting the JWKS endpoint through -// the http router. -// This makes sure that we accept the new plugin tokens as valid tokens, but otherwise fall -// back to the legacy token manager. -function createTokenManagerShim( - auth: AuthService, - config: RootConfigService, - logger: LoggerService, -): TokenManager { - const tokenManager = ServerTokenManager.fromConfig(config, { logger }); - return { - async getToken() { - return tokenManager.getToken(); - }, - async authenticate(token) { - if (token) { - // Unless it's a valid service token, we'll let the token manager do - // validation. We'll throw if we for example receive an invalid user - // token here, but that's what the token manager does too. - const credentials = await auth.authenticate(token); - if (auth.isPrincipal(credentials, 'service')) { - return; - } - } - await tokenManager.authenticate(token); - }, - }; -} - -/** - * Originally IdentityApi from `@backstage/plugin-auth-node`, re-declared here for backwards compatibility - * @public - * @deprecated Only relevant for legacy plugins, which are deprecated. - */ -export interface LegacyIdentityService { - getIdentity(options: { request: Request }): Promise< - | { - expiresInSeconds?: number; - - token: string; - identity: { - type: 'user'; - userEntityRef: string; - ownershipEntityRefs: string[]; - }; - } - | undefined - >; -} - -// This doesn't use DefaultIdentityClient because we will be removing it and break support for ownershipEntityRefs -function createIdentityServiceShim( - auth: AuthService, - userInfo: UserInfoService, -): LegacyIdentityService { - return { - async getIdentity(options) { - const authHeader = options.request.headers.authorization; - if (typeof authHeader !== 'string') { - return undefined; - } - - const token = authHeader.match(/^Bearer[ ]+(\S+)$/i)?.[1]; - if (!token) { - return undefined; - } - - const credentials = await auth.authenticate(token); - if (!auth.isPrincipal(credentials, 'user')) { - return undefined; - } - - const info = await userInfo.getUserInfo(credentials); - - return { - token, - identity: { - type: 'user', - userEntityRef: info.userEntityRef, - ownershipEntityRefs: info.ownershipEntityRefs, - }, - }; - }, - }; -} - -/** - * Creates a new custom plugin compatibility wrapper. - * - * @public - * @deprecated Fully use the new backend system instead. - * @remarks - * - * Usually you can use {@link legacyPlugin} directly instead, but you might - * need to use this if you have customized the plugin environment in your backend. - */ -export function makeLegacyPlugin< - TEnv extends Record, - TEnvTransforms extends { [key in keyof TEnv]?: (dep: TEnv[key]) => unknown }, ->( - envMapping: { [key in keyof TEnv]: ServiceRef }, - envTransforms: TEnvTransforms, -) { - return ( - name: string, - createRouterImport: Promise<{ - default: LegacyCreateRouter< - TransformedEnv & { - tokenManager: TokenManager; - identity: LegacyIdentityService; - } - >; - }>, - ) => { - return createBackendPlugin({ - pluginId: name, - register(env) { - env.registerInit({ - deps: { - ...envMapping, - $$router: coreServices.httpRouter, - $$auth: coreServices.auth, - $$userInfo: coreServices.userInfo, - $$config: coreServices.rootConfig, - $$logger: coreServices.logger, - }, - async init({ - $$auth, - $$config, - $$logger, - $$router, - $$userInfo, - ...envDeps - }) { - const { default: createRouter } = await createRouterImport; - const pluginEnv = Object.fromEntries( - Object.entries(envDeps).map(([key, dep]) => { - const transform = envTransforms[key]; - if (transform) { - return [key, transform(dep)]; - } - return [key, dep]; - }), - ); - - const auth = $$auth as typeof coreServices.auth.T; - const config = $$config as typeof coreServices.rootConfig.T; - const logger = $$logger as typeof coreServices.logger.T; - const router = $$router as typeof coreServices.httpRouter.T; - const userInfo = $$userInfo as typeof coreServices.userInfo.T; - - // Token manager and identity services are no longer supported in the new backend system, so we provide shims for them. - pluginEnv.tokenManager = createTokenManagerShim( - auth, - config, - logger, - ); - pluginEnv.identity = createIdentityServiceShim(auth, userInfo); - - const pluginRouter = await createRouter( - pluginEnv as TransformedEnv & { - tokenManager: TokenManager; - identity: LegacyIdentityService; - }, - ); - router.use(pluginRouter); - }, - }); - }, - }); - }; -} - -/** - * Helper function to create a plugin from a legacy createRouter function and - * register it with the http router based on the plugin id. - * - * @public - * @deprecated Fully use the new backend system instead. - * @remarks - * - * This is intended to be used by plugin authors to ease the transition to the - * new backend system. - * - * @example - * - *```ts - *backend.add(legacyPlugin('kafka', import('./plugins/kafka'))); - *``` - */ -export const legacyPlugin = makeLegacyPlugin( - { - cache: coreServices.cache, - config: coreServices.rootConfig, - database: coreServices.database, - discovery: coreServices.discovery, - logger: coreServices.logger, - permissions: coreServices.permissions, - scheduler: coreServices.scheduler, - reader: coreServices.urlReader, - }, - { - logger: log => loggerToWinstonLogger(log), - cache: cache => cacheToPluginCacheManager(cache), - }, -); diff --git a/packages/backend-common/src/compat/logging/loggerToWinstonLogger.ts b/packages/backend-common/src/compat/logging/loggerToWinstonLogger.ts deleted file mode 100644 index 83871f48e3..0000000000 --- a/packages/backend-common/src/compat/logging/loggerToWinstonLogger.ts +++ /dev/null @@ -1,67 +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 { LoggerService } from '@backstage/backend-plugin-api'; -import { JsonObject } from '@backstage/types'; -import { Logger as WinstonLogger, createLogger } from 'winston'; -import Transport, { TransportStreamOptions } from 'winston-transport'; - -class BackstageLoggerTransport extends Transport { - constructor( - private readonly backstageLogger: LoggerService, - opts?: TransportStreamOptions, - ) { - super(opts); - } - - log(info: unknown, callback: VoidFunction) { - if (typeof info !== 'object' || info === null) { - callback(); - return; - } - const { level, message, ...meta } = info as JsonObject; - switch (level) { - case 'error': - this.backstageLogger.error(String(message), meta); - break; - case 'warn': - this.backstageLogger.warn(String(message), meta); - break; - case 'info': - this.backstageLogger.info(String(message), meta); - break; - case 'debug': - this.backstageLogger.debug(String(message), meta); - break; - default: - this.backstageLogger.info(String(message), meta); - } - callback(); - } -} - -/** - * @public - * @deprecated Migrate to use the new LoggerService instead. - */ -export function loggerToWinstonLogger( - logger: LoggerService, - opts?: TransportStreamOptions, -): WinstonLogger { - return createLogger({ - transports: [new BackstageLoggerTransport(logger, opts)], - }); -} diff --git a/packages/backend-common/src/deprecated/config/ObservableConfigProxy.test.ts b/packages/backend-common/src/deprecated/config/ObservableConfigProxy.test.ts deleted file mode 100644 index 876f5ac7d3..0000000000 --- a/packages/backend-common/src/deprecated/config/ObservableConfigProxy.test.ts +++ /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 { ConfigReader } from '@backstage/config'; -import { ObservableConfigProxy } from './ObservableConfigProxy'; - -describe('ObservableConfigProxy', () => { - it('should notify subscribers', () => { - const config = new ObservableConfigProxy(); - - const fn = jest.fn(); - const sub = config.subscribe(fn); - expect(config.getOptionalNumber('x')).toBe(undefined); - - config.setConfig(new ConfigReader({})); - expect(fn).toHaveBeenCalledTimes(1); - expect(config.getOptionalNumber('x')).toBe(undefined); - - config.setConfig(new ConfigReader({ x: 1 })); - expect(fn).toHaveBeenCalledTimes(2); - expect(config.getOptionalNumber('x')).toBe(1); - - config.setConfig(new ConfigReader({ x: 3 })); - expect(fn).toHaveBeenCalledTimes(3); - sub.unsubscribe(); - expect(config.getOptionalNumber('x')).toBe(3); - - config.setConfig(new ConfigReader({ x: 5 })); - expect(fn).toHaveBeenCalledTimes(3); - expect(config.getOptionalNumber('x')).toBe(5); - }); - - it('should forward subscriptions', () => { - const config1 = new ObservableConfigProxy(); - - const fn1 = jest.fn(); - const fn2 = jest.fn(); - const fn3 = jest.fn(); - const config2 = config1.getConfig('a'); - const config3 = config2.getConfig('b'); - const sub1 = config1.subscribe(fn1); - const sub2 = config2.subscribe!(fn2); - const sub3 = config3.subscribe!(fn3); - expect(config1.getOptionalNumber('x')).toBe(undefined); - expect(config2.getOptionalNumber('x')).toBe(undefined); - expect(config3.getOptionalNumber('x')).toBe(undefined); - - config1.setConfig(new ConfigReader({})); - expect(fn1).toHaveBeenCalledTimes(1); - expect(fn2).toHaveBeenCalledTimes(1); - expect(fn3).toHaveBeenCalledTimes(1); - expect(config1.getOptionalNumber('x')).toBe(undefined); - expect(config2.getOptionalNumber('x')).toBe(undefined); - expect(config3.getOptionalNumber('x')).toBe(undefined); - - config1.setConfig(new ConfigReader({ x: 1, a: { x: 2, b: { x: 3 } } })); - expect(fn1).toHaveBeenCalledTimes(2); - expect(fn2).toHaveBeenCalledTimes(2); - expect(fn3).toHaveBeenCalledTimes(2); - expect(config1.getNumber('x')).toBe(1); - expect(config2.getNumber('x')).toBe(2); - expect(config3.getNumber('x')).toBe(3); - - sub1.unsubscribe(); - sub2.unsubscribe(); - sub3.unsubscribe(); - - config1.setConfig(new ConfigReader({ x: 4, a: { x: 5, b: { x: 6 } } })); - expect(fn1).toHaveBeenCalledTimes(2); - expect(fn2).toHaveBeenCalledTimes(2); - expect(fn3).toHaveBeenCalledTimes(2); - expect(config1.getNumber('x')).toBe(4); - expect(config2.getNumber('x')).toBe(5); - expect(config3.getNumber('x')).toBe(6); - - config1.setConfig(new ConfigReader({})); - expect(() => config1.getNumber('x')).toThrow( - "Missing required config value at 'x'", - ); - expect(() => config2.getNumber('x')).toThrow( - "Missing required config value at 'a'", - ); - expect(() => config3.getNumber('x')).toThrow( - "Missing required config value at 'a'", - ); - - config1.setConfig( - new ConfigReader({ x: 's', a: { x: 's', b: { x: 's' } } }), - ); - expect(() => config1.getNumber('x')).toThrow( - "Unable to convert config value for key 'x' in 'mock-config' to a number", - ); - expect(() => config2.getNumber('x')).toThrow( - "Unable to convert config value for key 'a.x' in 'mock-config' to a number", - ); - expect(() => config3.getNumber('x')).toThrow( - "Unable to convert config value for key 'a.b.x' in 'mock-config' to a number", - ); - }); - - it('should make sub configs available as expected', () => { - const config = new ObservableConfigProxy(); - - config.setConfig(new ConfigReader({ a: { x: 1 } })); - - expect(config.getConfig('a')).toBeDefined(); - expect(config.getConfig('a').getNumber('x')).toBe(1); - expect(config.getConfig('a').getOptionalNumber('x')).toBe(1); - expect(config.getOptionalConfig('a')?.getNumber('x')).toBe(1); - expect(config.getOptionalConfig('a')?.getOptionalNumber('x')).toBe(1); - expect(config.getOptionalConfig('b')).toBeUndefined(); - expect(() => config.getConfig('b')).toBeDefined(); - expect(() => config.getConfig('b').get()).toThrow(); - }); -}); diff --git a/packages/backend-common/src/deprecated/config/ObservableConfigProxy.ts b/packages/backend-common/src/deprecated/config/ObservableConfigProxy.ts deleted file mode 100644 index 8c8d3b553f..0000000000 --- a/packages/backend-common/src/deprecated/config/ObservableConfigProxy.ts +++ /dev/null @@ -1,128 +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 { Config, ConfigReader } from '@backstage/config'; -import { JsonValue } from '@backstage/types'; - -export class ObservableConfigProxy implements Config { - private config: Config = new ConfigReader({}); - - private readonly subscribers: (() => void)[] = []; - - constructor( - private readonly parent?: ObservableConfigProxy, - private parentKey?: string, - ) { - if (parent && !parentKey) { - throw new Error('parentKey is required if parent is set'); - } - } - - setConfig(config: Config) { - if (this.parent) { - throw new Error('immutable'); - } - this.config = config; - for (const subscriber of this.subscribers) { - try { - subscriber(); - } catch (error) { - console.error(`Config subscriber threw error, ${error}`); - } - } - } - - subscribe(onChange: () => void): { unsubscribe: () => void } { - if (this.parent) { - return this.parent.subscribe(onChange); - } - - this.subscribers.push(onChange); - return { - unsubscribe: () => { - const index = this.subscribers.indexOf(onChange); - if (index >= 0) { - this.subscribers.splice(index, 1); - } - }, - }; - } - - private select(required: true): Config; - private select(required: false): Config | undefined; - private select(required: boolean): Config | undefined { - if (this.parent && this.parentKey) { - if (required) { - return this.parent.select(true).getConfig(this.parentKey); - } - return this.parent.select(false)?.getOptionalConfig(this.parentKey); - } - - return this.config; - } - - has(key: string): boolean { - return this.select(false)?.has(key) ?? false; - } - keys(): string[] { - return this.select(false)?.keys() ?? []; - } - get(key?: string): T { - return this.select(true).get(key); - } - getOptional(key?: string): T | undefined { - return this.select(false)?.getOptional(key); - } - getConfig(key: string): Config { - return new ObservableConfigProxy(this, key); - } - getOptionalConfig(key: string): Config | undefined { - if (this.select(false)?.has(key)) { - return new ObservableConfigProxy(this, key); - } - return undefined; - } - getConfigArray(key: string): Config[] { - return this.select(true).getConfigArray(key); - } - getOptionalConfigArray(key: string): Config[] | undefined { - return this.select(false)?.getOptionalConfigArray(key); - } - getNumber(key: string): number { - return this.select(true).getNumber(key); - } - getOptionalNumber(key: string): number | undefined { - return this.select(false)?.getOptionalNumber(key); - } - getBoolean(key: string): boolean { - return this.select(true).getBoolean(key); - } - getOptionalBoolean(key: string): boolean | undefined { - return this.select(false)?.getOptionalBoolean(key); - } - getString(key: string): string { - return this.select(true).getString(key); - } - getOptionalString(key: string): string | undefined { - return this.select(false)?.getOptionalString(key); - } - getStringArray(key: string): string[] { - return this.select(true).getStringArray(key); - } - getOptionalStringArray(key: string): string[] | undefined { - return this.select(false)?.getOptionalStringArray(key); - } -} diff --git a/packages/backend-common/src/deprecated/config/config.test.ts b/packages/backend-common/src/deprecated/config/config.test.ts deleted file mode 100644 index 865b1b4d60..0000000000 --- a/packages/backend-common/src/deprecated/config/config.test.ts +++ /dev/null @@ -1,74 +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 { loadConfigSchema } from '@backstage/config-loader'; -import { mockServices } from '@backstage/backend-test-utils'; -import { createConfigSecretEnumerator } from './config'; - -describe('createConfigSecretEnumerator', () => { - it('should enumerate secrets', async () => { - const logger = mockServices.logger.mock(); - - const enumerate = await createConfigSecretEnumerator({ - logger, - }); - const secrets = enumerate( - mockServices.rootConfig({ - data: { - backend: { auth: { keys: [{ secret: 'my-secret-password' }] } }, - }, - }), - ); - expect(Array.from(secrets)).toEqual(['my-secret-password']); - }, 20_000); // Bit higher timeout since we're loading all config schemas in the repo - - it('should enumerate secrets with explicit schema', async () => { - const logger = mockServices.logger.mock(); - - const enumerate = await createConfigSecretEnumerator({ - logger, - schema: await loadConfigSchema({ - serialized: { - schemas: [ - { - value: { - type: 'object', - properties: { - secret: { - visibility: 'secret', - type: 'string', - }, - }, - }, - path: '/mock', - }, - ], - backstageConfigSchemaVersion: 1, - }, - }), - }); - - const secrets = enumerate( - mockServices.rootConfig({ - data: { - secret: 'my-secret', - other: 'not-secret', - }, - }), - ); - expect(Array.from(secrets)).toEqual(['my-secret']); - }); -}); diff --git a/packages/backend-common/src/deprecated/config/config.ts b/packages/backend-common/src/deprecated/config/config.ts deleted file mode 100644 index d50476a9f2..0000000000 --- a/packages/backend-common/src/deprecated/config/config.ts +++ /dev/null @@ -1,133 +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 { LoggerService } from '@backstage/backend-plugin-api'; -import { AppConfig, Config } from '@backstage/config'; -import { setRootLoggerRedactionList } from '../logging/createRootLogger'; -// eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { createConfigSecretEnumerator as _createConfigSecretEnumerator } from '../../../../backend-defaults/src/entrypoints/rootConfig/createConfigSecretEnumerator'; - -import { resolve as resolvePath } from 'path'; -import parseArgs from 'minimist'; -import { findPaths } from '@backstage/cli-common'; -import { - loadConfig, - ConfigTarget, - LoadConfigOptionsRemote, -} from '@backstage/config-loader'; -import { ConfigReader } from '@backstage/config'; -import { ObservableConfigProxy } from './ObservableConfigProxy'; -import { isValidUrl } from './urls'; - -/** - * @public - * @deprecated Please migrate to the new backend system and use `coreServices.rootConfig` instead, or the {@link @backstage/config-loader#ConfigSources} facilities if required. - */ -export const createConfigSecretEnumerator = _createConfigSecretEnumerator; - -/** - * Load configuration for a Backend. - * - * This function should only be called once, during the initialization of the backend. - * - * @public - * @deprecated Please migrate to the new backend system and use `coreServices.rootConfig` instead, or the {@link @backstage/config-loader#ConfigSources} facilities if required. - */ -export async function loadBackendConfig(options: { - logger: LoggerService; - // process.argv or any other overrides - remote?: LoadConfigOptionsRemote; - additionalConfigs?: AppConfig[]; - argv: string[]; - watch?: boolean; -}): Promise { - const secretEnumerator = await createConfigSecretEnumerator({ - logger: options.logger, - }); - const { config } = await newLoadBackendConfig(options); - - setRootLoggerRedactionList(secretEnumerator(config)); - config.subscribe?.(() => - setRootLoggerRedactionList(secretEnumerator(config)), - ); - - return config; -} - -async function newLoadBackendConfig(options: { - remote?: LoadConfigOptionsRemote; - argv: string[]; - additionalConfigs?: AppConfig[]; - watch?: boolean; -}): Promise<{ config: Config }> { - const args = parseArgs(options.argv); - - const configTargets: ConfigTarget[] = [args.config ?? []] - .flat() - .map(arg => (isValidUrl(arg) ? { url: arg } : { path: resolvePath(arg) })); - - /* eslint-disable-next-line no-restricted-syntax */ - const paths = findPaths(__dirname); - - let currentCancelFunc: (() => void) | undefined = undefined; - - const config = new ObservableConfigProxy(); - const { appConfigs } = await loadConfig({ - configRoot: paths.targetRoot, - configTargets: configTargets, - remote: options.remote, - watch: - options.watch ?? true - ? { - onChange(newConfigs) { - console.info( - `Reloaded config from ${newConfigs - .map(c => c.context) - .join(', ')}`, - ); - const configsToMerge = [...newConfigs]; - if (options.additionalConfigs) { - configsToMerge.push(...options.additionalConfigs); - } - config.setConfig(ConfigReader.fromConfigs(configsToMerge)); - }, - stopSignal: new Promise(resolve => { - if (currentCancelFunc) { - currentCancelFunc(); - } - currentCancelFunc = resolve; - - // TODO(Rugvip): We keep this here for now to avoid breaking the old system - // since this is re-used in backend-common - if (module.hot) { - module.hot.addDisposeHandler(resolve); - } - }), - } - : undefined, - }); - console.info( - `Loaded config from ${appConfigs.map(c => c.context).join(', ')}`, - ); - - const finalAppConfigs = [...appConfigs]; - if (options.additionalConfigs) { - finalAppConfigs.push(...options.additionalConfigs); - } - config.setConfig(ConfigReader.fromConfigs(finalAppConfigs)); - - return { config }; -} diff --git a/packages/backend-common/src/deprecated/config/urls.test.ts b/packages/backend-common/src/deprecated/config/urls.test.ts deleted file mode 100644 index c2a67fb849..0000000000 --- a/packages/backend-common/src/deprecated/config/urls.test.ts +++ /dev/null @@ -1,34 +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 { isValidUrl } from './urls'; - -describe('isValidUrl', () => { - it('should return true for url', () => { - const validUrl = isValidUrl('http://some.valid.url'); - expect(validUrl).toBe(true); - }); - - it('should return false for absolute path', () => { - const validUrl = isValidUrl('/some/absolute/path'); - expect(validUrl).toBe(false); - }); - - it('should return false for relative path', () => { - const validUrl = isValidUrl('../some/relative/path'); - expect(validUrl).toBe(false); - }); -}); diff --git a/packages/backend-common/src/deprecated/config/urls.ts b/packages/backend-common/src/deprecated/config/urls.ts deleted file mode 100644 index 848cea25d9..0000000000 --- a/packages/backend-common/src/deprecated/config/urls.ts +++ /dev/null @@ -1,25 +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 function isValidUrl(url: string): boolean { - try { - // eslint-disable-next-line no-new - new URL(url); - return true; - } catch { - return false; - } -} diff --git a/packages/backend-common/src/deprecated/context/AbortContext.test.ts b/packages/backend-common/src/deprecated/context/AbortContext.test.ts deleted file mode 100644 index a6c522ffcf..0000000000 --- a/packages/backend-common/src/deprecated/context/AbortContext.test.ts +++ /dev/null @@ -1,344 +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 { AbortContext } from './AbortContext'; -import { RootContext } from './RootContext'; - -describe('AbortContext', () => { - afterEach(() => { - jest.useRealTimers(); - }); - - describe('forTimeoutMillis', () => { - it('can abort on a timeout', async () => { - jest.useFakeTimers(); - const timeout = 200; - const deadline = Date.now() + timeout; - - const root = new RootContext(); - - const child = AbortContext.forTimeoutMillis(root, timeout); - const childListener = jest.fn(); - child.abortSignal.addEventListener('abort', childListener); - - expect(child.abortSignal.aborted).toBe(false); - expect(Math.abs(+child.deadline! - deadline)).toBeLessThan(50); - expect(childListener).toHaveBeenCalledTimes(0); - - jest.advanceTimersByTime(timeout + 1); - - expect(child.abortSignal.aborted).toBe(true); - expect(childListener).toHaveBeenCalledTimes(1); - }); - - it('results in minimum deadline when parent triggers sooner', async () => { - jest.useFakeTimers(); - const parentTimeout = 200; - const childTimeout = 300; - const parentDeadline = Date.now() + parentTimeout; - const childDeadline = parentDeadline; // clamped - - const root = new RootContext(); - - const parent = AbortContext.forTimeoutMillis(root, parentTimeout); - const parentListener = jest.fn(); - parent.abortSignal.addEventListener('abort', parentListener); - - const child = AbortContext.forTimeoutMillis(parent, childTimeout); - const childListener = jest.fn(); - child.abortSignal.addEventListener('abort', childListener); - - expect(parent.abortSignal.aborted).toBe(false); - expect(child.abortSignal.aborted).toBe(false); - expect(Math.abs(+parent.deadline! - parentDeadline)).toBeLessThan(50); - expect(Math.abs(+child.deadline! - childDeadline)).toBeLessThan(50); - expect(parentListener).toHaveBeenCalledTimes(0); - expect(childListener).toHaveBeenCalledTimes(0); - - jest.advanceTimersByTime(parentTimeout + 1); - - expect(parent.abortSignal.aborted).toBe(true); - expect(child.abortSignal.aborted).toBe(true); - expect(parentListener).toHaveBeenCalledTimes(1); - expect(childListener).toHaveBeenCalledTimes(1); - }); - - it('results in minimum deadline when child triggers sooner', async () => { - jest.useFakeTimers(); - const parentTimeout = 300; - const childTimeout = 200; - const parentDeadline = Date.now() + parentTimeout; - const childDeadline = Date.now() + childTimeout; - - const root = new RootContext(); - - const parent = AbortContext.forTimeoutMillis(root, parentTimeout); - const parentListener = jest.fn(); - parent.abortSignal.addEventListener('abort', parentListener); - - const child = AbortContext.forTimeoutMillis(parent, childTimeout); - const childListener = jest.fn(); - child.abortSignal.addEventListener('abort', childListener); - - expect(parent.abortSignal.aborted).toBe(false); - expect(child.abortSignal.aborted).toBe(false); - expect(Math.abs(+parent.deadline! - parentDeadline)).toBeLessThan(50); - expect(Math.abs(+child.deadline! - childDeadline)).toBeLessThan(50); - expect(parentListener).toHaveBeenCalledTimes(0); - expect(childListener).toHaveBeenCalledTimes(0); - - jest.advanceTimersByTime(childTimeout + 1); - - expect(parent.abortSignal.aborted).toBe(false); - expect(child.abortSignal.aborted).toBe(true); - expect(parentListener).toHaveBeenCalledTimes(0); - expect(childListener).toHaveBeenCalledTimes(1); - - jest.advanceTimersByTime(parentTimeout - childTimeout + 1); - - expect(parent.abortSignal.aborted).toBe(true); - expect(child.abortSignal.aborted).toBe(true); - expect(parentListener).toHaveBeenCalledTimes(1); - expect(childListener).toHaveBeenCalledTimes(1); - }); - - it('child carries over parent signal state if parent was already aborted and had no deadline', async () => { - jest.useFakeTimers(); - const childTimeout = 200; - const childDeadline = Date.now() + childTimeout; - - const root = new RootContext(); - - const parentController = new AbortController(); - const parent = AbortContext.forSignal(root, parentController.signal); - - parentController.abort(); - - const child = AbortContext.forTimeoutMillis(parent, childTimeout); - const childListener = jest.fn(); - child.abortSignal.addEventListener('abort', childListener); - - expect(child.abortSignal.aborted).toBe(true); - expect(childListener).toHaveBeenCalledTimes(0); - expect(Math.abs(+child.deadline! - childDeadline)).toBeLessThan(50); - - jest.advanceTimersByTime(childTimeout + 1); - - expect(child.abortSignal.aborted).toBe(true); - expect(childListener).toHaveBeenCalledTimes(0); // still - }); - - it('child carries over parent signal state if parent was already aborted and had a deadline', async () => { - jest.useFakeTimers(); - const first = new RootContext(); - - const secondController = new AbortController(); - const second = AbortContext.forSignal(first, secondController.signal); - secondController.abort(); - - const third = AbortContext.forTimeoutMillis(second, 200); - const fourth = AbortContext.forTimeoutMillis(third, 300); - - expect(third.abortSignal.aborted).toBe(true); - expect(fourth.abortSignal.aborted).toBe(true); - expect(Math.abs(+fourth.deadline! - Date.now() - 200)).toBeLessThan(50); - }); - }); - - describe('forController', () => { - it('signals child when parent is aborted', () => { - const root = new RootContext(); - - const parentController = new AbortController(); - const parent = AbortContext.forController(root, parentController); - const parentListener = jest.fn(); - parent.abortSignal.addEventListener('abort', parentListener); - - const childController = new AbortController(); - const child = AbortContext.forController(parent, childController); - const childListener = jest.fn(); - child.abortSignal.addEventListener('abort', childListener); - - expect(parent.abortSignal.aborted).toBe(false); - expect(child.abortSignal.aborted).toBe(false); - expect(parentListener).toHaveBeenCalledTimes(0); - expect(childListener).toHaveBeenCalledTimes(0); - - parentController.abort(); - - expect(parent.abortSignal.aborted).toBe(true); - expect(child.abortSignal.aborted).toBe(true); - expect(parentListener).toHaveBeenCalledTimes(1); - expect(childListener).toHaveBeenCalledTimes(1); - }); - - it('does not signal parent when child is aborted', async () => { - const root = new RootContext(); - - const parentController = new AbortController(); - const parent = AbortContext.forController(root, parentController); - const parentListener = jest.fn(); - parent.abortSignal.addEventListener('abort', parentListener); - - const childController = new AbortController(); - const child = AbortContext.forController(parent, childController); - const childListener = jest.fn(); - child.abortSignal.addEventListener('abort', childListener); - - expect(parent.abortSignal.aborted).toBe(false); - expect(child.abortSignal.aborted).toBe(false); - expect(parentListener).toHaveBeenCalledTimes(0); - expect(childListener).toHaveBeenCalledTimes(0); - - childController.abort(); - - expect(parent.abortSignal.aborted).toBe(false); - expect(child.abortSignal.aborted).toBe(true); - expect(parentListener).toHaveBeenCalledTimes(0); - expect(childListener).toHaveBeenCalledTimes(1); - }); - - it('child carries over parent signal state if parent was already aborted', async () => { - const root = new RootContext(); - - const parentController = new AbortController(); - const parent = AbortContext.forController(root, parentController); - - parentController.abort(); - - const childController = new AbortController(); - const child = AbortContext.forController(parent, childController); - const childListener = jest.fn(); - child.abortSignal.addEventListener('abort', childListener); - - expect(parent.abortSignal.aborted).toBe(true); - expect(child.abortSignal.aborted).toBe(true); - expect(childListener).toHaveBeenCalledTimes(0); - - childController.abort(); - - expect(parent.abortSignal.aborted).toBe(true); - expect(child.abortSignal.aborted).toBe(true); - expect(childListener).toHaveBeenCalledTimes(0); - }); - - it('child carries over given signal state if it was already aborted', async () => { - const root = new RootContext(); - - const childController = new AbortController(); - childController.abort(); - - const child = AbortContext.forController(root, childController); - const childListener = jest.fn(); - child.abortSignal.addEventListener('abort', childListener); - - expect(child.abortSignal.aborted).toBe(true); - expect(childListener).toHaveBeenCalledTimes(0); - }); - }); - - describe('forSignal', () => { - it('signals child when parent is aborted', async () => { - const root = new RootContext(); - - const parentController = new AbortController(); - const parent = AbortContext.forSignal(root, parentController.signal); - const parentListener = jest.fn(); - parent.abortSignal.addEventListener('abort', parentListener); - - const childController = new AbortController(); - const child = AbortContext.forSignal(parent, childController.signal); - const childListener = jest.fn(); - child.abortSignal.addEventListener('abort', childListener); - - expect(parent.abortSignal.aborted).toBe(false); - expect(child.abortSignal.aborted).toBe(false); - expect(parentListener).toHaveBeenCalledTimes(0); - expect(childListener).toHaveBeenCalledTimes(0); - - parentController.abort(); - - expect(parent.abortSignal.aborted).toBe(true); - expect(child.abortSignal.aborted).toBe(true); - expect(parentListener).toHaveBeenCalledTimes(1); - expect(childListener).toHaveBeenCalledTimes(1); - }); - - it('does not signal parent when child is aborted', async () => { - const root = new RootContext(); - - const parentController = new AbortController(); - const parent = AbortContext.forSignal(root, parentController.signal); - const parentListener = jest.fn(); - parent.abortSignal.addEventListener('abort', parentListener); - - const childController = new AbortController(); - const child = AbortContext.forSignal(parent, childController.signal); - const childListener = jest.fn(); - child.abortSignal.addEventListener('abort', childListener); - - expect(parent.abortSignal.aborted).toBe(false); - expect(child.abortSignal.aborted).toBe(false); - expect(parentListener).toHaveBeenCalledTimes(0); - expect(childListener).toHaveBeenCalledTimes(0); - - childController.abort(); - - expect(parent.abortSignal.aborted).toBe(false); - expect(child.abortSignal.aborted).toBe(true); - expect(parentListener).toHaveBeenCalledTimes(0); - expect(childListener).toHaveBeenCalledTimes(1); - }); - - it('child carries over parent signal state if parent was already aborted', async () => { - const root = new RootContext(); - - const parentController = new AbortController(); - const parent = AbortContext.forSignal(root, parentController.signal); - - parentController.abort(); - - const childController = new AbortController(); - const child = AbortContext.forSignal(parent, childController.signal); - const childListener = jest.fn(); - child.abortSignal.addEventListener('abort', childListener); - - expect(parent.abortSignal.aborted).toBe(true); - expect(child.abortSignal.aborted).toBe(true); - expect(childListener).toHaveBeenCalledTimes(0); - - childController.abort(); - - expect(parent.abortSignal.aborted).toBe(true); - expect(child.abortSignal.aborted).toBe(true); - expect(childListener).toHaveBeenCalledTimes(0); - }); - - it('child carries over given signal state if it was already aborted', async () => { - const root = new RootContext(); - - const childController = new AbortController(); - childController.abort(); - - const child = AbortContext.forSignal(root, childController.signal); - const childListener = jest.fn(); - child.abortSignal.addEventListener('abort', childListener); - - expect(child.abortSignal.aborted).toBe(true); - expect(childListener).toHaveBeenCalledTimes(0); - }); - }); -}); diff --git a/packages/backend-common/src/deprecated/context/AbortContext.ts b/packages/backend-common/src/deprecated/context/AbortContext.ts deleted file mode 100644 index 92735fbcc6..0000000000 --- a/packages/backend-common/src/deprecated/context/AbortContext.ts +++ /dev/null @@ -1,132 +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 { Context } from './types'; - -/** - * A context that implements various abort related functionality. - */ -export class AbortContext implements Context { - /** - * Abort either when the parent aborts, or after the given timeout has - * expired. - * - * @param ctx - The parent context - * @param timeout - A timeout value, in milliseconds - * @returns A new context - */ - static forTimeoutMillis(ctx: Context, timeout: number): Context { - const desiredDeadline = new Date(Date.now() + timeout); - const actualDeadline = - ctx.deadline && ctx.deadline < desiredDeadline - ? ctx.deadline - : desiredDeadline; - - if (ctx.abortSignal.aborted) { - if (ctx.deadline && desiredDeadline === actualDeadline) { - return ctx; - } - return new AbortContext(ctx, ctx.abortSignal, actualDeadline); - } - - const controller = new AbortController(); - const timeoutHandle = setTimeout(abort, timeout); - ctx.abortSignal.addEventListener('abort', abort); - - function abort() { - ctx.abortSignal.removeEventListener('abort', abort); - clearTimeout(timeoutHandle!); - controller.abort(); - } - - return new AbortContext(ctx, controller.signal, actualDeadline); - } - - /** - * Abort either when the parent aborts, or when the given controller is - * triggered. - * - * @remarks - * - * If you have access to the controller, this function is more efficient than - * {@link AbortContext#forSignal}. - * - * @param ctx - The parent context - * @param controller - An abort controller - * @returns A new context - */ - static forController(ctx: Context, controller: AbortController): Context { - // Already aborted context / signal are fine to reuse as-is - if (ctx.abortSignal.aborted) { - return ctx; - } else if (controller.signal.aborted) { - return new AbortContext(ctx, controller.signal, ctx.deadline); - } - - function abort() { - ctx.abortSignal.removeEventListener('abort', abort); - controller.abort(); - } - - ctx.abortSignal.addEventListener('abort', abort); - - return new AbortContext(ctx, controller.signal, ctx.deadline); - } - - /** - * Abort either when the parent aborts, or when the given signal is triggered. - * - * @remarks - * - * If you have access to the controller and not just the signal, - * {@link AbortContext#forController} is slightly more efficient to use. - * - * @param ctx - The parent context - * @param signal - An abort signal - * @returns A new context - */ - static forSignal(ctx: Context, signal: AbortSignal): Context { - // Already aborted context / signal are fine to reuse as-is - if (ctx.abortSignal.aborted) { - return ctx; - } else if (signal.aborted) { - return new AbortContext(ctx, signal, ctx.deadline); - } - - const controller = new AbortController(); - - function abort() { - ctx.abortSignal.removeEventListener('abort', abort); - signal.removeEventListener('abort', abort); - controller.abort(); - } - - ctx.abortSignal.addEventListener('abort', abort); - signal.addEventListener('abort', abort); - - return new AbortContext(ctx, controller.signal, ctx.deadline); - } - - private constructor( - private readonly parent: Context, - readonly abortSignal: AbortSignal, - readonly deadline: Date | undefined, - ) {} - - value(key: string): T | undefined { - return this.parent.value(key); - } -} diff --git a/packages/backend-common/src/deprecated/context/Contexts.test.ts b/packages/backend-common/src/deprecated/context/Contexts.test.ts deleted file mode 100644 index c895b3bb49..0000000000 --- a/packages/backend-common/src/deprecated/context/Contexts.test.ts +++ /dev/null @@ -1,89 +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 { Duration } from 'luxon'; -import { Contexts } from './Contexts'; - -describe('Contexts', () => { - afterEach(() => { - jest.useRealTimers(); - }); - - describe('root', () => { - it('can create a root', () => { - const ctx = Contexts.root(); - expect(ctx.abortSignal).toBeDefined(); - expect(ctx.deadline).toBeUndefined(); - }); - }); - - describe('setAbort', () => { - it('works for controllers', () => { - const controller = new AbortController(); - const parent = Contexts.root(); - const child = Contexts.withAbort(parent, controller); - expect(child.abortSignal.aborted).toBe(false); - controller.abort(); - expect(child.abortSignal.aborted).toBe(true); - }); - - it('works for signals', () => { - const controller = new AbortController(); - const parent = Contexts.root(); - const child = Contexts.withAbort(parent, controller.signal); - expect(child.abortSignal.aborted).toBe(false); - controller.abort(); - expect(child.abortSignal.aborted).toBe(true); - }); - }); - - describe('setTimeoutDuration', () => { - it('works', () => { - jest.useFakeTimers(); - const parent = Contexts.root(); - const child = Contexts.withTimeoutDuration( - parent, - Duration.fromMillis(200), - ); - expect(child.abortSignal.aborted).toBe(false); - jest.advanceTimersByTime(100); - expect(child.abortSignal.aborted).toBe(false); - jest.advanceTimersByTime(101); - expect(child.abortSignal.aborted).toBe(true); - }); - }); - - describe('setTimeoutMillis', () => { - it('works', () => { - jest.useFakeTimers(); - const parent = Contexts.root(); - const child = Contexts.withTimeoutMillis(parent, 200); - expect(child.abortSignal.aborted).toBe(false); - jest.advanceTimersByTime(100); - expect(child.abortSignal.aborted).toBe(false); - jest.advanceTimersByTime(101); - expect(child.abortSignal.aborted).toBe(true); - }); - }); - - describe('setValue', () => { - it('works', () => { - const parent = Contexts.root(); - const child = Contexts.withValue(parent, 'k', 'v'); - expect(child.value('k')).toBe('v'); - }); - }); -}); diff --git a/packages/backend-common/src/deprecated/context/Contexts.ts b/packages/backend-common/src/deprecated/context/Contexts.ts deleted file mode 100644 index 026e3ce4e0..0000000000 --- a/packages/backend-common/src/deprecated/context/Contexts.ts +++ /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 { Duration } from 'luxon'; -import { AbortContext } from './AbortContext'; -import { RootContext } from './RootContext'; -import { Context } from './types'; -import { ValueContext } from './ValueContext'; - -/** - * Common context decorators. - * - * @alpha - * @deprecated This class is not used in the new Backend system, so it is going to be removed in a near future. - */ -export class Contexts { - /** - * Creates a root context. - * - * @remarks - * - * This should normally only be called near the root of an application. The - * created context is meant to be passed down into deeper levels, which may or - * may not make derived contexts out of it. - */ - static root(): Context { - return new RootContext(); - } - - /** - * Creates a derived context, which signals to abort operations either when - * any parent context signals, or when the given source is aborted. - * - * @remarks - * - * If the parent context was already aborted, then it is returned as-is. - * - * If the given source was already aborted, then a new already-aborted context - * is returned. - * - * @param parentCtx - A parent context that shall be used as a base - * @param source - An abort controller or signal that you intend to perhaps - * trigger at some later point in time. - * @returns A new {@link Context} - */ - static withAbort( - parentCtx: Context, - source: AbortController | AbortSignal, - ): Context { - return 'aborted' in source - ? AbortContext.forSignal(parentCtx, source) - : AbortContext.forController(parentCtx, source); - } - - /** - * Creates a derived context, which signals to abort operations either when - * any parent context signals, or when the given amount of time has passed. - * This may affect the deadline. - * - * @param parentCtx - A parent context that shall be used as a base - * @param timeout - The duration of time, after which the derived context will - * signal to abort. - * @returns A new {@link Context} - */ - static withTimeoutDuration(parentCtx: Context, timeout: Duration): Context { - return AbortContext.forTimeoutMillis(parentCtx, timeout.as('milliseconds')); - } - - /** - * Creates a derived context, which signals to abort operations either when - * any parent context signals, or when the given amount of time has passed. - * This may affect the deadline. - * - * @param parentCtx - A parent context that shall be used as a base - * @param timeout - The number of milliseconds, after which the derived - * context will signal to abort. - * @returns A new {@link Context} - */ - static withTimeoutMillis(parentCtx: Context, timeout: number): Context { - return AbortContext.forTimeoutMillis(parentCtx, timeout); - } - - /** - * Creates a derived context, which has a specific key-value pair set as well - * as all key-value pairs that were set in the original context. - * - * @param parentCtx - A parent context that shall be used as a base - * @param key - The key of the value to set - * @param value - The value, or a function that accepts the previous value (or - * undefined if not set yet) and computes the new value - * @returns A new {@link Context} - */ - static withValue( - parentCtx: Context, - key: string, - value: unknown | ((previous: unknown | undefined) => unknown), - ): Context { - const v = typeof value === 'function' ? value(parentCtx.value(key)) : value; - return ValueContext.forConstantValue(parentCtx, key, v); - } -} diff --git a/packages/backend-common/src/deprecated/context/RootContext.test.ts b/packages/backend-common/src/deprecated/context/RootContext.test.ts deleted file mode 100644 index 395786e3dc..0000000000 --- a/packages/backend-common/src/deprecated/context/RootContext.test.ts +++ /dev/null @@ -1,27 +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 { RootContext } from './RootContext'; - -describe('RootContext', () => { - it('returns empty values', async () => { - const ctx = new RootContext(); - expect(ctx.abortSignal).toBeDefined(); - expect(ctx.abortSignal.aborted).toBe(false); - expect(ctx.deadline).toBeUndefined(); - expect(ctx.value('a')).toBeUndefined(); - }); -}); diff --git a/packages/backend-common/src/deprecated/context/RootContext.ts b/packages/backend-common/src/deprecated/context/RootContext.ts deleted file mode 100644 index fd3690a945..0000000000 --- a/packages/backend-common/src/deprecated/context/RootContext.ts +++ /dev/null @@ -1,50 +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 { Context } from './types'; - -/** - * Since the root context can never abort, and since nobody is ever meant to - * dispatch events through it, we can use a static fake instance for efficiency. - * - * The reason that this was initially made for the root context is that due to - * the way that we always chain contexts off of it, sometimes a huge number of - * listeners want to add themselves to something that effectively never can be - * aborted in the first place. This triggered warnings that the max listeners - * limit was exceeded. - */ -class FakeAbortSignal implements AbortSignal { - readonly aborted = false; - readonly reason = undefined; - onabort() {} - throwIfAborted() {} - addEventListener() {} - removeEventListener() {} - dispatchEvent() { - return true; - } -} - -/** - * An empty root context. - */ -export class RootContext implements Context { - readonly abortSignal = new FakeAbortSignal(); - readonly deadline = undefined; - value(_key: string): T | undefined { - return undefined; - } -} diff --git a/packages/backend-common/src/deprecated/context/ValueContext.test.ts b/packages/backend-common/src/deprecated/context/ValueContext.test.ts deleted file mode 100644 index 6a216d4548..0000000000 --- a/packages/backend-common/src/deprecated/context/ValueContext.test.ts +++ /dev/null @@ -1,44 +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 { RootContext } from './RootContext'; -import { ValueContext } from './ValueContext'; - -describe('ValueContext', () => { - it('returns its own values, or delegates to the parent', async () => { - const root = new RootContext(); - const a = ValueContext.forConstantValue(root, 'a', 1); - const b = ValueContext.forConstantValue(a, 'x', 2); - const c = ValueContext.forConstantValue(b, 'a', 3); - const d = ValueContext.forConstantValue(c, 'b', 4); - - expect(a.value('a')).toBe(1); - expect(a.value('b')).toBeUndefined(); - expect(a.value('x')).toBeUndefined(); - - expect(b.value('a')).toBe(1); - expect(b.value('b')).toBeUndefined(); - expect(b.value('x')).toBe(2); - - expect(c.value('a')).toBe(3); - expect(c.value('b')).toBeUndefined(); - expect(c.value('x')).toBe(2); - - expect(d.value('a')).toBe(3); - expect(d.value('b')).toBe(4); - expect(d.value('x')).toBe(2); - }); -}); diff --git a/packages/backend-common/src/deprecated/context/ValueContext.ts b/packages/backend-common/src/deprecated/context/ValueContext.ts deleted file mode 100644 index c8e4426d05..0000000000 --- a/packages/backend-common/src/deprecated/context/ValueContext.ts +++ /dev/null @@ -1,45 +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 { Context } from './types'; - -/** - * A context that just holds a single value, and delegates the rest to its - * parent. - */ -export class ValueContext implements Context { - static forConstantValue(ctx: Context, key: string, value: unknown): Context { - return new ValueContext(ctx, key, value); - } - - constructor( - private readonly _parent: Context, - private readonly _key: string, - private readonly _value: unknown, - ) {} - - get abortSignal(): AbortSignal { - return this._parent.abortSignal; - } - - get deadline(): Date | undefined { - return this._parent.deadline; - } - - value(key: string): T | undefined { - return key === this._key ? (this._value as T) : this._parent.value(key); - } -} diff --git a/packages/backend-common/src/deprecated/context/index.ts b/packages/backend-common/src/deprecated/context/index.ts deleted file mode 100644 index 37a6e29c8c..0000000000 --- a/packages/backend-common/src/deprecated/context/index.ts +++ /dev/null @@ -1,18 +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 { Contexts } from './Contexts'; -export type { Context } from './types'; diff --git a/packages/backend-common/src/deprecated/context/types.ts b/packages/backend-common/src/deprecated/context/types.ts deleted file mode 100644 index d980f54e43..0000000000 --- a/packages/backend-common/src/deprecated/context/types.ts +++ /dev/null @@ -1,44 +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. - */ - -/** - * A context that is meant to be passed as a ctx variable down the call chain, - * to pass along scoped information and abort signals. - * - * @alpha - * @deprecated This type is not used in the new Backend system, so it is going to be removed in a near future. - */ -export interface Context { - /** - * Returns an abort signal that triggers when the current context or any of - * its parents signal for it. - */ - readonly abortSignal: AbortSignal; - - /** - * The point in time when the current context shall time out and abort, if - * applicable. - */ - readonly deadline: Date | undefined; - - /** - * Attempts to get a stored value by key from the context. - * - * @param key - The key of the value to get - * @returns The associated value, or undefined if not set - */ - value(key: string): T | undefined; -} diff --git a/packages/backend-common/src/deprecated/hot.ts b/packages/backend-common/src/deprecated/hot.ts deleted file mode 100644 index 94ebf52307..0000000000 --- a/packages/backend-common/src/deprecated/hot.ts +++ /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. - */ - -// Find all active hot module APIs of all ancestors of a module, including the module itself -function findAllAncestors(_module: NodeModule): NodeModule[] { - const ancestors = new Array(); - const parentIds = new Set(); - - function add(id: string | number, m: NodeModule) { - if (parentIds.has(id)) { - return; - } - parentIds.add(id); - ancestors.push(m); - - for (const parentId of (m as any).parents) { - const parent = require.cache[parentId]; - if (parent) { - add(parentId, parent); - } - } - } - - add(_module.id, _module); - - return ancestors; -} - -/** - * useHotCleanup allows cleanup of ongoing effects when a module is - * hot-reloaded during development. The cleanup function will be called - * whenever the module itself or any of its parent modules is hot-reloaded. - * - * Useful for cleaning intervals, timers, requests etc - * - * @public - * @deprecated Hot module reloading is no longer supported for backends. - * @example - * ```ts - * const intervalId = setInterval(doStuff, 1000); - * useHotCleanup(module, () => clearInterval(intervalId)); - * ``` - * @param _module - Reference to the current module where you invoke the fn - * @param cancelEffect - Fn that cleans up the ongoing effects - */ -export function useHotCleanup(_module: NodeModule, cancelEffect: () => void) { - if (_module.hot) { - const ancestors = findAllAncestors(_module); - let cancelled = false; - - const handler = () => { - if (!cancelled) { - cancelled = true; - cancelEffect(); - } - }; - - for (const m of ancestors) { - m.hot?.addDisposeHandler(handler); - } - } -} - -const CURRENT_HOT_MEMOIZE_INDEX_KEY = 'backstage.io/hmr-memoize-key'; - -/** - * Memoizes a generated value across hot-module reloads. This is useful for - * stateful parts of the backend, e.g. to retain a database. - * - * @public - * @deprecated Hot module reloading is no longer supported for backends. - * @example - * ```ts - * const db = useHotMemoize(module, () => createDB(dbParams)); - * ``` - * - * **NOTE:** Do not use inside conditionals or loops, - * same rules as for hooks apply (https://reactjs.org/docs/hooks-rules.html) - * - * @param _module - Reference to the current module where you invoke the fn - * @param valueFactory - Fn that returns the value you want to memoize - */ -export function useHotMemoize( - _module: NodeModule, - valueFactory: () => T, -): T { - if (!_module.hot) { - return valueFactory(); - } - - // When starting blank, reset the counter - if (!_module.hot.data?.[CURRENT_HOT_MEMOIZE_INDEX_KEY]) { - for (const ancestor of findAllAncestors(_module)) { - ancestor.hot?.addDisposeHandler(data => { - data[CURRENT_HOT_MEMOIZE_INDEX_KEY] = 1; - }); - } - - _module.hot.data = { - ..._module.hot.data, - [CURRENT_HOT_MEMOIZE_INDEX_KEY]: 1, - }; - } - - // Store data per module, based on the order of the code invocation - const index = _module.hot.data[CURRENT_HOT_MEMOIZE_INDEX_KEY]++; - const value = _module.hot.data[index] ?? valueFactory(); - - // Always add a handler that, upon a HMR event, reinstates the value. - _module.hot.addDisposeHandler(data => { - data[index] = value; - }); - - return value; -} diff --git a/packages/backend-common/src/deprecated/index.ts b/packages/backend-common/src/deprecated/index.ts deleted file mode 100644 index f769d4db09..0000000000 --- a/packages/backend-common/src/deprecated/index.ts +++ /dev/null @@ -1,282 +0,0 @@ -/* - * 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 { Config } from '@backstage/config'; - -// eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { HostDiscovery as _HostDiscovery } from '../../../backend-defaults/src/entrypoints/discovery/HostDiscovery'; - -// eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { CacheManager as _CacheManager } from '../../../backend-defaults/src/entrypoints/cache/CacheManager'; - -// eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { type CacheManagerOptions as _CacheManagerOptions } from '../../../backend-defaults/src/entrypoints/cache/types'; - -// eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { - DatabaseManager as _DatabaseManager, - type DatabaseManagerOptions as _DatabaseManagerOptions, -} from '../../../backend-defaults/src/entrypoints/database/DatabaseManager'; - -import { - DiscoveryService, - CacheService, - CacheServiceOptions, - CacheServiceSetOptions, - DatabaseService as _PluginDatabaseManager, - isDatabaseConflictError as _isDatabaseConflictError, - resolvePackagePath as _resolvePackagePath, - resolveSafeChildPath as _resolveSafeChildPath, - isChildPath as _isChildPath, - LifecycleService, - PluginMetadataService, - DatabaseService, - LoggerService, - RootConfigService, -} from '@backstage/backend-plugin-api'; - -export * from './hot'; -export * from './config'; -export * from './scm'; -export * from './tokens'; -export * from './logging'; -export * from './service'; -export * from './middleware'; -export * from './util'; - -/** - * @public - * @deprecated Use `DiscoveryService` from `@backstage/backend-plugin-api` instead - */ -export type PluginEndpointDiscovery = DiscoveryService; - -/** - * HostDiscovery is a basic PluginEndpointDiscovery implementation - * that can handle plugins that are hosted in a single or multiple deployments. - * - * The deployment may be scaled horizontally, as long as the external URL - * is the same for all instances. However, internal URLs will always be - * resolved to the same host, so there won't be any balancing of internal traffic. - * - * @public - * @deprecated Please import from `@backstage/backend-defaults/discovery` instead. - */ -export class HostDiscovery implements DiscoveryService { - /** - * Creates a new HostDiscovery discovery instance by reading - * from the `backend` config section, specifically the `.baseUrl` for - * discovering the external URL, and the `.listen` and `.https` config - * for the internal one. - * - * Can be overridden in config by providing a target and corresponding plugins in `discovery.endpoints`. - * eg. - * ```yaml - * discovery: - * endpoints: - * - target: https://internal.example.com/internal-catalog - * plugins: [catalog] - * - target: https://internal.example.com/secure/api/{{pluginId}} - * plugins: [auth, permission] - * - target: - * internal: https://internal.example.com/search - * external: https://example.com/search - * plugins: [search] - * ``` - * - * The fixed base path is `/api`, meaning the default full internal - * path for the `catalog` plugin will be `http://localhost:7007/api/catalog`. - */ - static fromConfig(config: Config) { - return new HostDiscovery(_HostDiscovery.fromConfig(config)); - } - - private constructor(private readonly impl: _HostDiscovery) {} - - async getBaseUrl(pluginId: string): Promise { - return this.impl.getBaseUrl(pluginId); - } - - async getExternalBaseUrl(pluginId: string): Promise { - return this.impl.getExternalBaseUrl(pluginId); - } -} - -/** - * SingleHostDiscovery is a basic PluginEndpointDiscovery implementation - * that assumes that all plugins are hosted in a single deployment. - * - * The deployment may be scaled horizontally, as long as the external URL - * is the same for all instances. However, internal URLs will always be - * resolved to the same host, so there won't be any balancing of internal traffic. - * - * @public - * @deprecated Use `HostDiscovery` from `@backstage/backend-defaults/discovery` instead - */ -export { HostDiscovery as SingleHostDiscovery }; - -/** - * @public - * @deprecated Use `CacheManager` from the `@backstage/backend-defaults` package instead - */ -export class CacheManager { - /** - * Creates a new {@link CacheManager} instance by reading from the `backend` - * config section, specifically the `.cache` key. - * - * @param config - The loaded application configuration. - */ - static fromConfig( - config: RootConfigService, - options: CacheManagerOptions = {}, - ): CacheManager { - return new CacheManager(_CacheManager.fromConfig(config, options)); - } - - private constructor(private readonly _impl: _CacheManager) {} - - forPlugin(pluginId: string): PluginCacheManager { - return { - getClient: options => { - const result = this._impl.forPlugin(pluginId); - return options ? result.withOptions(options) : result; - }, - }; - } -} - -/** - * @public - * @deprecated Use `CacheManagerOptions` from the `@backstage/backend-defaults` package instead - */ -export type CacheManagerOptions = _CacheManagerOptions; - -/** - * @public - * @deprecated Use `PluginCacheManager` from the `@backstage/backend-defaults` package instead - */ -export type PluginCacheManager = { - getClient(options?: CacheServiceOptions): CacheService; -}; - -/** - * @public - * @deprecated Use `CacheService` from the `@backstage/backend-plugin-api` package instead - */ -export type CacheClient = CacheService; - -/** - * @public - * @deprecated Use `CacheServiceSetOptions` from the `@backstage/backend-plugin-api` package instead - */ -export type CacheClientSetOptions = CacheServiceSetOptions; - -/** - * @public - * @deprecated Use `CacheServiceOptions` from the `@backstage/backend-plugin-api` package instead - */ -export type CacheClientOptions = CacheServiceOptions; - -/** - * @public - * @deprecated Use `DatabaseManager` from the `@backstage/backend-defaults` package instead - */ -export class DatabaseManager implements LegacyRootDatabaseService { - private constructor( - private readonly _databaseManager: _DatabaseManager, - private readonly logger?: LoggerService, - ) {} - - static fromConfig( - config: Config, - options?: { - migrations?: DatabaseService['migrations']; - logger?: LoggerService; - }, - ): DatabaseManager { - const _databaseManager = _DatabaseManager.fromConfig(config, options); - return new DatabaseManager(_databaseManager, options?.logger); - } - - forPlugin( - pluginId: string, - deps?: - | { lifecycle: LifecycleService; pluginMetadata: PluginMetadataService } - | undefined, - ): PluginDatabaseManager { - const logger: LoggerService = this.logger ?? { - debug() {}, - info() {}, - warn() {}, - error() {}, - child() { - return this; - }, - }; - const lifecycle: LifecycleService = deps?.lifecycle ?? { - addShutdownHook() {}, - addStartupHook() {}, - }; - return this._databaseManager.forPlugin(pluginId, { logger, lifecycle }); - } -} - -/** - * @public - * @deprecated Use `DatabaseManagerOptions` from the `@backstage/backend-defaults` package instead - */ -export type DatabaseManagerOptions = _DatabaseManagerOptions; - -/** - * @public - * @deprecated Use `DatabaseService` from the `@backstage/backend-plugin-api` package instead - */ -export type PluginDatabaseManager = _PluginDatabaseManager; - -/** - * @public - * @deprecated Use `DatabaseManager` from `@backstage/backend-defaults/database` instead, or migrate to the new backend system and use `coreServices.database` - */ -export type LegacyRootDatabaseService = { - forPlugin(pluginId: string): DatabaseService; -}; - -/** - * @public - * @deprecated This function is deprecated and will be removed in a future release, see https://github.com/backstage/backstage/issues/24493. - * Please use the `isDatabaseConflictError` function from the `@backstage/backend-plugin-api` package instead. - */ -export const isDatabaseConflictError = _isDatabaseConflictError; - -/** - * @public - * @deprecated This function is deprecated and will be removed in a future release, see https://github.com/backstage/backstage/issues/24493. - * Please use the `resolvePackagePath` function from the `@backstage/backend-plugin-api` package instead. - */ -export const resolvePackagePath = _resolvePackagePath; - -/** - * @public - * @deprecated This function is deprecated and will be removed in a future release, see https://github.com/backstage/backstage/issues/24493. - * Please use the `resolveSafeChildPath` function from the `@backstage/backend-plugin-api` package instead. - */ -export const resolveSafeChildPath = _resolveSafeChildPath; - -/** - * @public - * @deprecated This function is deprecated and will be removed in a future release, see https://github.com/backstage/backstage/issues/24493. - * Please use the `isChildPath` function from the `@backstage/cli-common` package instead. - */ -export const isChildPath = _isChildPath; diff --git a/packages/backend-common/src/deprecated/logging/createRootLogger.ts b/packages/backend-common/src/deprecated/logging/createRootLogger.ts deleted file mode 100644 index 04b3799381..0000000000 --- a/packages/backend-common/src/deprecated/logging/createRootLogger.ts +++ /dev/null @@ -1,137 +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. - */ - -// eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { WinstonLogger } from '../../../../backend-defaults/src/entrypoints/rootLogger/WinstonLogger'; -import { merge } from 'lodash'; -import * as winston from 'winston'; -import { format, LoggerOptions } from 'winston'; -import { TransformableInfo } from 'logform'; -import { setRootLogger } from './globalLoggers'; - -const getRedacter = (() => { - let redacter: ReturnType | undefined = - undefined; - return () => { - if (!redacter) { - redacter = WinstonLogger.redacter(); - } - return redacter; - }; -})(); - -export const setRootLoggerRedactionList = ( - redactions: Iterable, -): void => { - getRedacter().add(redactions); -}; - -/** - * A winston formatting function that finds occurrences of filteredKeys - * and replaces them with the corresponding identifier. - * - * @public - * @deprecated This utility is being deprecated along with the {@link https://github.com/backstage/backstage/issues/24493 |legacy backend system}. - * Migrate your {@link https://backstage.io/docs/backend-system/building-backends/migrating | backend} and {@link https://backstage.io/docs/backend-system/building-plugins-and-modules/migrating | plugin} to the new system and use the {@link https://github.com/backstage/backstage/pull/24730 | RedactionsService} for customization instead. - */ -export function redactWinstonLogLine( - info: winston.Logform.TransformableInfo, -): winston.Logform.TransformableInfo { - return getRedacter().format.transform( - info, - ) as winston.Logform.TransformableInfo; -} - -const colorizer = format.colorize(); - -// NOTE: This is a copy of the WinstonLogger.colorFormat to avoid a circular dependency -/** - * Creates a pretty printed winston log formatter. - * - * @public - * @deprecated As we are going to deprecate the legacy backend, this formatter utility will be removed in the future. - * If you need to format logs in the new system, please use the `WinstonLogger.colorFormat()` from `@backstage/backend-app-api` instead. - */ -export const coloredFormat = format.combine( - format.timestamp(), - format.colorize({ - colors: { - timestamp: 'dim', - prefix: 'blue', - field: 'cyan', - debug: 'grey', - }, - }), - format.printf((info: TransformableInfo) => { - const { timestamp, level, message, plugin, service, ...fields } = info; - const prefix = plugin || service; - const timestampColor = colorizer.colorize('timestamp', timestamp); - const prefixColor = colorizer.colorize('prefix', prefix); - - const extraFields = Object.entries(fields) - .map( - ([key, value]) => `${colorizer.colorize('field', `${key}`)}=${value}`, - ) - .join(' '); - - return `${timestampColor} ${prefixColor} ${level} ${message} ${extraFields}`; - }), -); - -/** - * Creates a default "root" logger. This also calls {@link setRootLogger} under - * the hood. - * - * @remarks - * - * This is the logger instance that will be the foundation for all other logger - * instances passed to plugins etc, in a given backend. - * - * @public - * @deprecated As we are going to deprecate the legacy backend, this function will be removed in the future. - * If you need to create the root logger in the new system, please check out this documentation: - * https://backstage.io/docs/backend-system/core-services/logger - */ -export function createRootLogger( - options: winston.LoggerOptions = {}, - env = process.env, -): winston.Logger { - const logger = winston - .createLogger( - merge( - { - level: env.LOG_LEVEL || 'info', - format: winston.format.combine( - getRedacter().format, - env.NODE_ENV === 'production' - ? winston.format.json() - : WinstonLogger.colorFormat(), - ), - transports: [ - new winston.transports.Console({ - silent: env.JEST_WORKER_ID !== undefined && !env.LOG_LEVEL, - }), - ], - }, - options, - ), - ) - .child({ service: 'backstage' }); - - setRootLogger(logger); - - return logger; -} diff --git a/packages/backend-common/src/deprecated/logging/globalLoggers.ts b/packages/backend-common/src/deprecated/logging/globalLoggers.ts deleted file mode 100644 index cbd5279d29..0000000000 --- a/packages/backend-common/src/deprecated/logging/globalLoggers.ts +++ /dev/null @@ -1,69 +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 * as winston from 'winston'; -import { createRootLogger } from './createRootLogger'; - -/** - * A logger that just throws away all messages. - * - * @public - * @deprecated As we are going to deprecate the legacy backend, this function will be removed in the future. - * If you need to mock the root logger in the new system, please use `mockServices.logger.mock()` from `@backstage/test-utils` instead. - */ -export function getVoidLogger(): winston.Logger { - return winston.createLogger({ - transports: [new winston.transports.Console({ silent: true })], - }); -} - -let rootLogger: winston.Logger; - -/** - * Gets the current root logger. - * - * @public - * @deprecated As we are going to deprecate the legacy backend, this function will be removed in the future. - * If you need to get the root logger in the new system, please check out this documentation: - * https://backstage.io/docs/backend-system/core-services/logger - */ -export function getRootLogger(): winston.Logger { - if (!rootLogger) { - rootLogger = createRootLogger(); - } - return rootLogger; -} - -/** - * Sets a completely custom default "root" logger. - * - * @remarks - * - * This is the logger instance that will be the foundation for all other logger - * instances passed to plugins etc, in a given backend. - * - * Only use this if you absolutely need to make a completely custom logger. - * Normally if you want to make light adaptations to the default logger - * behavior, you would instead call {@link createRootLogger}. - * - * @public - * @deprecated As we are going to deprecate the legacy backend, this function will be removed in the future. - * If you need to set the root logger in the new system, please check out this documentation: - * https://backstage.io/docs/backend-system/core-services/logger - */ -export function setRootLogger(newLogger: winston.Logger) { - rootLogger = newLogger; -} diff --git a/packages/backend-common/src/deprecated/logging/index.ts b/packages/backend-common/src/deprecated/logging/index.ts deleted file mode 100644 index b223f5c946..0000000000 --- a/packages/backend-common/src/deprecated/logging/index.ts +++ /dev/null @@ -1,22 +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 { getRootLogger, getVoidLogger, setRootLogger } from './globalLoggers'; -export { - createRootLogger, - redactWinstonLogLine, - coloredFormat, -} from './createRootLogger'; diff --git a/packages/backend-common/src/deprecated/middleware/errorHandler.test.ts b/packages/backend-common/src/deprecated/middleware/errorHandler.test.ts deleted file mode 100644 index 2544a0a863..0000000000 --- a/packages/backend-common/src/deprecated/middleware/errorHandler.test.ts +++ /dev/null @@ -1,252 +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 express from 'express'; -import { STATUS_CODES } from 'http'; -import createError from 'http-errors'; -import request from 'supertest'; -import { - AuthenticationError, - ConflictError, - InputError, - NotAllowedError, - NotFoundError, - NotModifiedError, - ResponseError, -} from '@backstage/errors'; -import { errorHandler } from './errorHandler'; - -describe('errorHandler', () => { - it('gives default code and message', async () => { - const app = express(); - app.use('/breaks', () => { - throw new Error('some message'); - }); - app.use(errorHandler()); - - const response = await request(app).get('/breaks'); - - expect(response.status).toBe(500); - expect(response.body).toEqual({ - error: expect.objectContaining({ - name: 'Error', - message: 'some message', - }), - request: { method: 'GET', url: '/breaks' }, - response: { statusCode: 500 }, - }); - }); - - it('does not try to send the response again if its already been sent', async () => { - const app = express(); - const mockSend = jest.fn(); - - app.use('/works_with_async_fail', (_, res) => { - res.status(200).send('hello'); - - // mutate the response object to test the middleware. - // it's hard to catch errors inside middleware from the outside. - res.send = mockSend; - throw new Error('some message'); - }); - - app.use(errorHandler()); - const response = await request(app).get('/works_with_async_fail'); - - expect(response.status).toBe(200); - expect(response.text).toBe('hello'); - - expect(mockSend).not.toHaveBeenCalled(); - }); - - it('takes code from http-errors library errors', async () => { - const app = express(); - app.use('/breaks', () => { - throw createError(432, 'Some Message'); - }); - app.use(errorHandler()); - - const response = await request(app).get('/breaks'); - - expect(response.status).toBe(432); - expect(response.body).toEqual({ - error: { - expose: true, - name: 'BadRequestError', - message: 'Some Message', - status: 432, - statusCode: 432, - }, - request: { - method: 'GET', - url: '/breaks', - }, - response: { statusCode: 432 }, - }); - }); - - it('handles well-known error classes', async () => { - const app = express(); - app.use('/NotModifiedError', () => { - throw new NotModifiedError(); - }); - app.use('/InputError', () => { - throw new InputError(); - }); - app.use('/AuthenticationError', () => { - throw new AuthenticationError(); - }); - app.use('/NotAllowedError', () => { - throw new NotAllowedError(); - }); - app.use('/NotFoundError', () => { - throw new NotFoundError(); - }); - app.use('/ConflictError', () => { - throw new ConflictError(); - }); - app.use('/ResponseErrorBackstagePlugin', async (_req, _res, next) => { - const mockedResponse = { - status: jest.fn(() => mockedResponse), - json: jest.fn(() => mockedResponse), - } as unknown as jest.Mocked; - - // serialize AuthenticationError in mockedResponse - errorHandler()( - new AuthenticationError('an error'), - { method: 'GET', url: '' } as express.Request, - mockedResponse, - jest.fn(), - ); - - const status = mockedResponse.status.mock.calls[0][0]; - next( - await ResponseError.fromResponse({ - headers: new Headers({ - 'content-type': 'application/json', - }), - ok: false, - redirected: false, - status, - statusText: STATUS_CODES[status]!, - type: 'default', - url: '', - text: async () => - JSON.stringify(mockedResponse.json.mock.calls[0][0]), - }), - ); - }); - app.use('/ResponseError', async (_req, _res, next) => { - next( - await ResponseError.fromResponse({ - headers: new Headers({ - 'content-type': 'application/json', - }), - ok: false, - redirected: false, - status: 403, - statusText: STATUS_CODES[403]!, - type: 'default', - url: '', - text: async () => JSON.stringify({}), - }), - ); - }); - app.use(errorHandler()); - - const r = request(app); - expect((await r.get('/NotModifiedError')).status).toBe(304); - expect((await r.get('/InputError')).status).toBe(400); - expect((await r.get('/InputError')).body.error.name).toBe('InputError'); - expect((await r.get('/AuthenticationError')).status).toBe(401); - expect((await r.get('/AuthenticationError')).body.error.name).toBe( - 'AuthenticationError', - ); - expect((await r.get('/NotAllowedError')).status).toBe(403); - expect((await r.get('/NotAllowedError')).body.error.name).toBe( - 'NotAllowedError', - ); - expect((await r.get('/NotFoundError')).status).toBe(404); - expect((await r.get('/NotFoundError')).body.error.name).toBe( - 'NotFoundError', - ); - expect((await r.get('/ConflictError')).status).toBe(409); - expect((await r.get('/ConflictError')).body.error.name).toBe( - 'ConflictError', - ); - expect((await r.get('/ResponseErrorBackstagePlugin')).status).toBe(401); - expect((await r.get('/ResponseErrorBackstagePlugin')).body.error.name).toBe( - 'ResponseError', - ); - expect((await r.get('/ResponseError')).status).toBe(403); - expect((await r.get('/ResponseError')).body.error.name).toBe( - 'ResponseError', - ); - }); - - it('logs all 500 errors', async () => { - const app = express(); - - const mockLogger = { child: jest.fn(), error: jest.fn() }; - mockLogger.child.mockImplementation(() => mockLogger as any); - - const thrownError = new Error('some error'); - - app.use('/breaks', () => { - throw thrownError; - }); - app.use(errorHandler({ logger: mockLogger as any })); - - await request(app).get('/breaks'); - - expect(mockLogger.error).toHaveBeenCalledWith( - 'Request failed with status 500', - thrownError, - ); - }); - - it('does not log 400 errors', async () => { - const app = express(); - - const mockLogger = { child: jest.fn(), error: jest.fn() }; - mockLogger.child.mockImplementation(() => mockLogger as any); - - app.use('/NotFound', () => { - throw new NotFoundError(); - }); - app.use(errorHandler({ logger: mockLogger as any })); - - await request(app).get('/NotFound'); - - expect(mockLogger.error).not.toHaveBeenCalled(); - }); - - it('log 400 errors when logClientErrors is true', async () => { - const app = express(); - - const mockLogger = { child: jest.fn(), error: jest.fn() }; - mockLogger.child.mockImplementation(() => mockLogger as any); - - app.use('/NotFound', () => { - throw new NotFoundError(); - }); - app.use(errorHandler({ logger: mockLogger as any, logClientErrors: true })); - - await request(app).get('/NotFound'); - - expect(mockLogger.error).toHaveBeenCalled(); - }); -}); diff --git a/packages/backend-common/src/deprecated/middleware/errorHandler.ts b/packages/backend-common/src/deprecated/middleware/errorHandler.ts deleted file mode 100644 index b4f07b9320..0000000000 --- a/packages/backend-common/src/deprecated/middleware/errorHandler.ts +++ /dev/null @@ -1,78 +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 { ErrorRequestHandler } from 'express'; -import { LoggerService } from '@backstage/backend-plugin-api'; -import { ConfigReader } from '@backstage/config'; -// eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { MiddlewareFactory } from '../../../../backend-defaults/src/entrypoints/rootHttpRouter/http/MiddlewareFactory'; -import { getRootLogger } from '../logging'; - -/** - * Options passed to the {@link errorHandler} middleware. - * - * @public - * @deprecated This type is being deprecated along with the {@link @backstage/backend-common#errorHandler} function. - */ -export type ErrorHandlerOptions = { - /** - * Whether error response bodies should show error stack traces or not. - * - * If not specified, by default shows stack traces only in development mode. - */ - showStackTraces?: boolean; - - /** - * Logger instance to log errors. - * - * If not specified, the root logger will be used. - */ - logger?: LoggerService; - - /** - * Whether any 4xx errors should be logged or not. - * - * If not specified, default to only logging 5xx errors. - */ - logClientErrors?: boolean; -}; - -/** - * Express middleware to handle errors during request processing. - * - * This is commonly the very last middleware in the chain. - * - * Its primary purpose is not to do translation of business logic exceptions, - * but rather to be a global catch-all for uncaught "fatal" errors that are - * expected to result in a 500 error. However, it also does handle some common - * error types (such as http-error exceptions) and returns the enclosed status - * code accordingly. - * - * @public - * @returns An Express error request handler - * @deprecated Use {@link @backstage/backend-defaults/rootHttpRouter#MiddlewareFactory.create.error} instead - */ -export function errorHandler( - options: ErrorHandlerOptions = {}, -): ErrorRequestHandler { - return MiddlewareFactory.create({ - config: new ConfigReader({}), - logger: options.logger ?? getRootLogger(), - }).error({ - logAllErrors: options.logClientErrors, - showStackTraces: options.showStackTraces, - }); -} diff --git a/packages/backend-common/src/deprecated/middleware/index.ts b/packages/backend-common/src/deprecated/middleware/index.ts deleted file mode 100644 index f4f4fcde0b..0000000000 --- a/packages/backend-common/src/deprecated/middleware/index.ts +++ /dev/null @@ -1,20 +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 * from './errorHandler'; -export * from './notFoundHandler'; -export * from './requestLoggingHandler'; -export * from './statusCheckHandler'; diff --git a/packages/backend-common/src/deprecated/middleware/notFoundHandler.test.ts b/packages/backend-common/src/deprecated/middleware/notFoundHandler.test.ts deleted file mode 100644 index b49e275a69..0000000000 --- a/packages/backend-common/src/deprecated/middleware/notFoundHandler.test.ts +++ /dev/null @@ -1,33 +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 express from 'express'; -import request from 'supertest'; -import { notFoundHandler } from './notFoundHandler'; - -describe('notFoundHandler', () => { - it('handles only missing routes', async () => { - const app = express(); - app.use('/exists', (_, res) => res.status(200).end()); - app.use(notFoundHandler()); - - const existsResponse = await request(app).get('/exists'); - const doesNotExistResponse = await request(app).get('/doesNotExist'); - - expect(existsResponse.status).toBe(200); - expect(doesNotExistResponse.status).toBe(404); - }); -}); diff --git a/packages/backend-common/src/deprecated/middleware/notFoundHandler.ts b/packages/backend-common/src/deprecated/middleware/notFoundHandler.ts deleted file mode 100644 index bb9504a9ec..0000000000 --- a/packages/backend-common/src/deprecated/middleware/notFoundHandler.ts +++ /dev/null @@ -1,38 +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. - */ - -// eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { MiddlewareFactory } from '../../../../backend-defaults/src/entrypoints/rootHttpRouter/http/MiddlewareFactory'; -import { ConfigReader } from '@backstage/config'; -import { RequestHandler } from 'express'; -import { getRootLogger } from '../logging'; - -/** - * Express middleware to handle requests for missing routes. - * - * Should be used as the very last handler in the chain, as it unconditionally - * returns a 404 status. - * - * @public - * @returns An Express request handler - * @deprecated Use {@link @backstage/backend-app-api#MiddlewareFactory.create.notFound} instead - */ -export function notFoundHandler(): RequestHandler { - return MiddlewareFactory.create({ - config: new ConfigReader({}), - logger: getRootLogger(), - }).notFound(); -} diff --git a/packages/backend-common/src/deprecated/middleware/requestLoggingHandler.test.ts b/packages/backend-common/src/deprecated/middleware/requestLoggingHandler.test.ts deleted file mode 100644 index ed24f2050b..0000000000 --- a/packages/backend-common/src/deprecated/middleware/requestLoggingHandler.test.ts +++ /dev/null @@ -1,46 +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 express from 'express'; -import request from 'supertest'; -import * as winston from 'winston'; -import { requestLoggingHandler } from './requestLoggingHandler'; - -describe('requestLoggingHandler', () => { - it('emits logs for each request', async () => { - const logger = winston.createLogger(); - jest.spyOn(logger, 'info').mockReturnValue(logger); - - const app = express(); - app.use(requestLoggingHandler(logger)); - app.use('/exists1', (_, res) => res.status(200).end()); - app.use('/exists2', (_, res) => res.status(201).end()); - - const r = request(app); - await r.get('/exists1'); - await r.get('/exists2'); - - expect(logger.info).toHaveBeenCalledTimes(2); - expect(logger.info).toHaveBeenNthCalledWith( - 1, - expect.stringContaining('200'), - ); - expect(logger.info).toHaveBeenNthCalledWith( - 2, - expect.stringContaining('201'), - ); - }); -}); diff --git a/packages/backend-common/src/deprecated/middleware/requestLoggingHandler.ts b/packages/backend-common/src/deprecated/middleware/requestLoggingHandler.ts deleted file mode 100644 index f30f2de659..0000000000 --- a/packages/backend-common/src/deprecated/middleware/requestLoggingHandler.ts +++ /dev/null @@ -1,37 +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. - */ - -// eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { MiddlewareFactory } from '../../../../backend-defaults/src/entrypoints/rootHttpRouter/http/MiddlewareFactory'; -import { RequestHandler } from 'express'; -import { ConfigReader } from '@backstage/config'; -import { LoggerService } from '@backstage/backend-plugin-api'; -import { getRootLogger } from '../logging'; - -/** - * Logs incoming requests. - * - * @public - * @param logger - An optional logger to use. If not specified, the root logger will be used. - * @returns An Express request handler - * @deprecated Use {@link @backstage/backend-app-api#MiddlewareFactory.create.logging} instead - */ -export function requestLoggingHandler(logger?: LoggerService): RequestHandler { - return MiddlewareFactory.create({ - config: new ConfigReader({}), - logger: logger ?? getRootLogger(), - }).logging(); -} diff --git a/packages/backend-common/src/deprecated/middleware/statusCheckHandler.test.ts b/packages/backend-common/src/deprecated/middleware/statusCheckHandler.test.ts deleted file mode 100644 index 7393276045..0000000000 --- a/packages/backend-common/src/deprecated/middleware/statusCheckHandler.test.ts +++ /dev/null @@ -1,55 +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 express from 'express'; -import request from 'supertest'; -import { statusCheckHandler } from './statusCheckHandler'; - -describe('statusCheckHandler', () => { - it('gives status 200 when using default', async () => { - const app = express(); - app.use('/healthcheck', await statusCheckHandler()); - - const response = await request(app).get('/healthcheck'); - - expect(response.status).toBe(200); - expect(response.text).toBe(JSON.stringify({ status: 'ok' })); - }); - - it('gives status 200 when status function returns true', async () => { - const app = express(); - const status = { foo: 'bar' }; - const statusCheck = () => Promise.resolve(status); - app.use('/healthcheck', await statusCheckHandler({ statusCheck })); - - const response = await request(app).get('/healthcheck'); - - expect(response.status).toBe(200); - expect(response.text).toBe(JSON.stringify(status)); - }); - - it('gives status 500 when status check throws an error', async () => { - const app = express(); - const statusCheck = () => { - throw Error('error!'); - }; - app.use('/healthcheck', await statusCheckHandler({ statusCheck })); - - const response = await request(app).get('/healthcheck'); - - expect(response.status).toBe(500); - }); -}); diff --git a/packages/backend-common/src/deprecated/middleware/statusCheckHandler.ts b/packages/backend-common/src/deprecated/middleware/statusCheckHandler.ts deleted file mode 100644 index ebaf84c1b9..0000000000 --- a/packages/backend-common/src/deprecated/middleware/statusCheckHandler.ts +++ /dev/null @@ -1,66 +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 { NextFunction, Request, Response, RequestHandler } from 'express'; - -/** - * A custom status checking function, passed to {@link statusCheckHandler} and - * {@link createStatusCheckRouter}. - * - * @public - * @deprecated Migrate to the {@link https://backstage.io/docs/backend-system/ | new backend system} and use the {@link https://backstage.io/docs/backend-system/core-services/root-health | Root Health Service} instead. - */ -export type StatusCheck = () => Promise; - -/** - * Options passed to {@link statusCheckHandler}. - * - * @public - * @deprecated Migrate to the {@link https://backstage.io/docs/backend-system/ | new backend system} and use the {@link https://backstage.io/docs/backend-system/core-services/root-health | Root Health Service} instead. - */ -export interface StatusCheckHandlerOptions { - /** - * Optional status function which returns a message. - */ - statusCheck?: StatusCheck; -} - -/** - * Express middleware for status checks. - * - * This is commonly used to implement healthcheck and readiness routes. - * - * @public - * @param options - An optional configuration object. - * @returns An Express error request handler - * @deprecated Migrate to the {@link https://backstage.io/docs/backend-system/ | new backend system} and use the {@link https://backstage.io/docs/backend-system/core-services/root-health | Root Health Service} instead. - */ -export async function statusCheckHandler( - options: StatusCheckHandlerOptions = {}, -): Promise { - const statusCheck: StatusCheck = options.statusCheck - ? options.statusCheck - : () => Promise.resolve({ status: 'ok' }); - - return async (_request: Request, response: Response, next: NextFunction) => { - try { - const status = await statusCheck(); - response.status(200).json(status); - } catch (err) { - next(err); - } - }; -} diff --git a/packages/backend-common/src/deprecated/scm/git.test.ts b/packages/backend-common/src/deprecated/scm/git.test.ts deleted file mode 100644 index 1c07dfb917..0000000000 --- a/packages/backend-common/src/deprecated/scm/git.test.ts +++ /dev/null @@ -1,606 +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. - */ -jest.mock('isomorphic-git'); -jest.mock('isomorphic-git/http/node'); -jest.mock('fs-extra'); - -import * as isomorphic from 'isomorphic-git'; -import { Git } from './git'; -import http from 'isomorphic-git/http/node'; -import fs from 'fs-extra'; - -describe('Git', () => { - beforeEach(() => { - jest.resetAllMocks(); - }); - - describe('add', () => { - it('should call isomorphic-git add with the correct arguments', async () => { - const git = Git.fromAuth({}); - const dir = 'mockdirectory'; - const filepath = 'mockfile/path'; - - await git.add({ dir, filepath }); - - expect(isomorphic.add).toHaveBeenCalledWith({ - fs, - dir, - filepath, - }); - }); - }); - - describe('addRemote', () => { - it('should call isomorphic-git with the correct arguments', async () => { - const git = Git.fromAuth({}); - const dir = 'mockdirectory'; - const remote = 'origin'; - const url = 'git@github.com/something/sads'; - const force = true; - - await git.addRemote({ dir, remote, url, force }); - - expect(isomorphic.addRemote).toHaveBeenCalledWith({ - fs, - dir, - remote, - url, - force, - }); - }); - }); - - describe('remove', () => { - it('should call isomorphic-git remove with the correct arguments', async () => { - const git = Git.fromAuth({}); - const dir = 'mockdirectory'; - const filepath = 'mockfile/path'; - - await git.remove({ dir, filepath }); - - expect(isomorphic.remove).toHaveBeenCalledWith({ - fs, - dir, - filepath, - }); - }); - }); - - describe('deleteRemote', () => { - it('should call isomorphic-git with the correct arguments', async () => { - const git = Git.fromAuth({}); - const dir = 'mockdirectory'; - const remote = 'origin'; - - await git.deleteRemote({ dir, remote }); - - expect(isomorphic.deleteRemote).toHaveBeenCalledWith({ - fs, - dir, - remote, - }); - }); - }); - - describe('checkout', () => { - it('should call isomorphic-git with the correct arguments', async () => { - const git = Git.fromAuth({}); - const dir = 'mockdirectory'; - const ref = 'master'; - - await git.checkout({ dir, ref }); - - expect(isomorphic.checkout).toHaveBeenCalledWith({ - fs, - dir, - ref, - }); - }); - }); - - describe('branch', () => { - it('should call isomorphic-git with the correct arguments', async () => { - const git = Git.fromAuth({}); - const dir = 'mockdirectory'; - const ref = 'master'; - - await git.branch({ dir, ref }); - - expect(isomorphic.branch).toHaveBeenCalledWith({ - fs, - dir, - ref, - }); - }); - }); - - describe('commit', () => { - it('should call isomorphic-git with the correct arguments', async () => { - const git = Git.fromAuth({}); - const dir = 'mockdirectory'; - const message = 'Inital Commit'; - const author = { - name: 'author', - email: 'test@backstage.io', - }; - const committer = { - name: 'comitter', - email: 'test@backstage.io', - }; - - await git.commit({ dir, message, author, committer }); - - expect(isomorphic.commit).toHaveBeenCalledWith({ - fs, - dir, - message, - author, - committer, - }); - }); - }); - - describe('clone', () => { - it('should call isomorphic-git with the correct arguments', async () => { - const url = 'http://github.com/some/repo'; - const dir = '/some/mock/dir'; - const auth = { - username: 'blob', - password: 'hunter2', - }; - const git = Git.fromAuth(auth); - - await git.clone({ url, dir }); - - expect(isomorphic.clone).toHaveBeenCalledWith({ - fs, - http, - url, - dir, - singleBranch: true, - depth: 1, - onProgress: expect.any(Function), - headers: { - 'user-agent': 'git/@isomorphic-git', - }, - onAuth: expect.any(Function), - }); - }); - - it('should call isomorphic-git with the correct arguments (Bearer)', async () => { - const url = 'http://github.com/some/repo'; - const dir = '/some/mock/dir'; - const auth = { - token: 'test', - }; - const git = Git.fromAuth(auth); - - await git.clone({ url, dir }); - - expect(isomorphic.clone).toHaveBeenCalledWith({ - fs, - http, - url, - dir, - singleBranch: true, - depth: 1, - onProgress: expect.any(Function), - headers: { - Authorization: 'Bearer test', - 'user-agent': 'git/@isomorphic-git', - }, - onAuth: expect.any(Function), - }); - }); - - it('should pass a function that returns the authorization as the onAuth handler when username and password are specified', async () => { - const url = 'http://github.com/some/repo'; - const dir = '/some/mock/dir'; - const auth = { - username: 'blob', - password: 'hunter2', - }; - const git = Git.fromAuth(auth); - - await git.clone({ url, dir }); - - const { onAuth } = ( - isomorphic.clone as unknown as jest.Mock<(typeof isomorphic)['clone']> - ).mock.calls[0][0]!; - - expect(onAuth()).toEqual(auth); - }); - - it('should pass the provided callback as the onAuth handler when on auth is specified', async () => { - const url = 'http://github.com/some/repo'; - const dir = '/some/mock/dir'; - const auth = { - username: 'from', - password: 'callback', - }; - - const git = Git.fromAuth({ onAuth: () => auth }); - - await git.clone({ url, dir }); - - const { onAuth } = ( - isomorphic.clone as unknown as jest.Mock<(typeof isomorphic)['clone']> - ).mock.calls[0][0]!; - - expect(onAuth()).toEqual(auth); - }); - - it('should propagate the data from the error handler', async () => { - const url = 'http://github.com/some/repo'; - const dir = '/some/mock/dir'; - const auth = { - username: 'blob', - password: 'hunter2', - }; - const git = Git.fromAuth(auth); - - (isomorphic.clone as jest.Mock).mockImplementation(() => { - const error: Error & { data?: unknown } = new Error('mock error'); - error.data = { some: 'more information here' }; - - throw error; - }); - - await expect(git.clone({ url, dir })).rejects.toThrow( - 'more information here', - ); - }); - }); - - describe('currentBranch', () => { - it('should call isomorphic-git with the correct arguments', async () => { - const dir = '/some/mock/dir'; - const fullName = true; - const git = Git.fromAuth({}); - - await git.currentBranch({ dir, fullName }); - - expect(isomorphic.currentBranch).toHaveBeenCalledWith({ - fs, - dir, - fullname: true, - }); - - await git.currentBranch({ dir }); - - expect(isomorphic.currentBranch).toHaveBeenCalledWith({ - fs, - dir, - fullname: false, - }); - }); - }); - - describe('fetch', () => { - it('should call isomorphic-git with the correct arguments', async () => { - const remote = 'http://github.com/some/repo'; - const dir = '/some/mock/dir'; - const auth = { - username: 'blob', - password: 'hunter2', - }; - const git = Git.fromAuth(auth); - - await git.fetch({ remote, dir, tags: true }); - - expect(isomorphic.fetch).toHaveBeenCalledWith({ - fs, - http, - remote, - dir, - tags: true, - onProgress: expect.any(Function), - headers: { - 'user-agent': 'git/@isomorphic-git', - }, - onAuth: expect.any(Function), - }); - }); - - it('should call isomorphic-git with the correct arguments (Bearer)', async () => { - const remote = 'http://github.com/some/repo'; - const dir = '/some/mock/dir'; - const auth = { - token: 'test', - }; - const git = Git.fromAuth(auth); - - await git.fetch({ remote, dir }); - - expect(isomorphic.fetch).toHaveBeenCalledWith({ - fs, - http, - remote, - dir, - tags: false, - onProgress: expect.any(Function), - headers: { - Authorization: 'Bearer test', - 'user-agent': 'git/@isomorphic-git', - }, - onAuth: expect.any(Function), - }); - }); - - it('should pass a function that returns the authorization as the onAuth handler', async () => { - const remote = 'http://github.com/some/repo'; - const dir = '/some/mock/dir'; - const auth = { - username: 'blob', - password: 'hunter2', - }; - const git = Git.fromAuth(auth); - - await git.fetch({ remote, dir }); - - const { onAuth } = ( - isomorphic.fetch as unknown as jest.Mock<(typeof isomorphic)['fetch']> - ).mock.calls[0][0]!; - - expect(onAuth()).toEqual(auth); - }); - - it('should propagate the data from the error handler', async () => { - const remote = 'http://github.com/some/repo'; - const dir = '/some/mock/dir'; - const auth = { - username: 'blob', - password: 'hunter2', - }; - const git = Git.fromAuth(auth); - - (isomorphic.fetch as jest.Mock).mockImplementation(() => { - const error: Error & { data?: unknown } = new Error('mock error'); - error.data = { some: 'more information here' }; - - throw error; - }); - - await expect(git.fetch({ remote, dir })).rejects.toThrow( - 'more information here', - ); - }); - }); - - describe('init', () => { - it('should call isomorphic-git with the correct arguments', async () => { - const dir = '/some/mock/dir'; - const defaultBranch = 'master'; - - const git = Git.fromAuth({}); - - await git.init({ dir, defaultBranch }); - - expect(isomorphic.init).toHaveBeenCalledWith({ - fs, - dir, - defaultBranch, - }); - }); - }); - - describe('merge', () => { - it('should call isomorphic-git with the correct arguments', async () => { - const dir = '/some/mock/dir'; - const author = { - name: 'author', - email: 'test@backstage.io', - }; - const committer = { - name: 'comitter', - email: 'test@backstage.io', - }; - const theirs = 'master'; - const ours = 'production'; - - const git = Git.fromAuth({}); - - await git.merge({ dir, theirs, ours, author, committer }); - - expect(isomorphic.merge).toHaveBeenCalledWith({ - fs, - dir, - ours, - theirs, - author, - committer, - }); - }); - }); - - describe('push', () => { - it('should call isomorphic-git with the correct arguments', async () => { - const remote = 'origin'; - const dir = '/some/mock/dir'; - const auth = { - username: 'blob', - password: 'hunter2', - }; - const git = Git.fromAuth(auth); - const remoteRef = 'master'; - const force = true; - - await git.push({ dir, remote, remoteRef, force }); - - expect(isomorphic.push).toHaveBeenCalledWith({ - fs, - http, - remote, - dir, - remoteRef, - force, - onProgress: expect.any(Function), - headers: { - 'user-agent': 'git/@isomorphic-git', - }, - onAuth: expect.any(Function), - }); - }); - - it('should call isomorphic-git with the correct arguments (Bearer)', async () => { - const remote = 'origin'; - const dir = '/some/mock/dir'; - const auth = { - token: 'test', - }; - const git = Git.fromAuth(auth); - const remoteRef = 'master'; - const force = true; - - await git.push({ dir, remote, remoteRef, force }); - - expect(isomorphic.push).toHaveBeenCalledWith({ - fs, - http, - remote, - dir, - remoteRef, - force, - onProgress: expect.any(Function), - headers: { - Authorization: 'Bearer test', - 'user-agent': 'git/@isomorphic-git', - }, - onAuth: expect.any(Function), - }); - }); - - it('should call isomorphic-git with remoteRef parameter', async () => { - const remote = 'origin'; - const remoteRef = 'refs/for/master'; - const dir = '/some/mock/dir'; - const auth = { - username: 'blob', - password: 'hunter2', - }; - const git = Git.fromAuth(auth); - - await git.push({ dir, remote, remoteRef }); - - expect(isomorphic.push).toHaveBeenCalledWith({ - fs, - http, - remote, - remoteRef, - dir, - onProgress: expect.any(Function), - headers: { - 'user-agent': 'git/@isomorphic-git', - }, - onAuth: expect.any(Function), - }); - }); - - it('should pass a function that returns the authorization as the onAuth handler', async () => { - const remote = 'origin'; - const dir = '/some/mock/dir'; - const auth = { - username: 'blob', - password: 'hunter2', - }; - const git = Git.fromAuth(auth); - const remoteRef = 'master'; - const force = true; - - await git.push({ remote, dir, remoteRef, force }); - - const { onAuth } = ( - isomorphic.push as unknown as jest.Mock<(typeof isomorphic)['push']> - ).mock.calls[0][0]!; - - expect(onAuth()).toEqual(auth); - }); - - it('should propagate the data from the error handler', async () => { - const remote = 'origin'; - const dir = '/some/mock/dir'; - const auth = { - username: 'blob', - password: 'hunter2', - }; - const git = Git.fromAuth(auth); - const remoteRef = 'master'; - const force = true; - - (isomorphic.push as jest.Mock).mockImplementation(() => { - const error: Error & { data?: unknown } = new Error('mock error'); - error.data = { some: 'more information here' }; - - throw error; - }); - - await expect(git.push({ remote, dir, remoteRef, force })).rejects.toThrow( - 'more information here', - ); - }); - }); - - describe('readCommit', () => { - it('should call isomorphic-git with the correct arguments', async () => { - const dir = '/some/mock/dir'; - const sha = 'as43bd7'; - - const git = Git.fromAuth({}); - - await git.readCommit({ dir, sha }); - - expect(isomorphic.readCommit).toHaveBeenCalledWith({ - fs, - dir, - oid: sha, - }); - }); - }); - - describe('resolveRef', () => { - it('should call isomorphic-git with the correct arguments', async () => { - const dir = '/some/mock/dir'; - const ref = 'as43bd7'; - - const git = Git.fromAuth({}); - - await git.resolveRef({ dir, ref }); - - expect(isomorphic.resolveRef).toHaveBeenCalledWith({ - fs, - dir, - ref, - }); - }); - }); - - describe('log', () => { - it('should call isomorphic-git with the correct arguments', async () => { - const dir = '/some/mock/dir'; - const ref = 'as43bd7'; - - const git = Git.fromAuth({}); - - await git.log({ dir, ref }); - - expect(isomorphic.log).toHaveBeenCalledWith({ - fs, - dir, - ref, - }); - }); - }); -}); diff --git a/packages/backend-common/src/deprecated/scm/git.ts b/packages/backend-common/src/deprecated/scm/git.ts deleted file mode 100644 index 1a182e6f4d..0000000000 --- a/packages/backend-common/src/deprecated/scm/git.ts +++ /dev/null @@ -1,357 +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 git, { - ProgressCallback, - MergeResult, - ReadCommitResult, - AuthCallback, -} from 'isomorphic-git'; -import http from 'isomorphic-git/http/node'; -import fs from 'fs-extra'; -import { LoggerService } from '@backstage/backend-plugin-api'; - -function isAuthCallbackOptions( - options: StaticAuthOptions | AuthCallbackOptions, -): options is AuthCallbackOptions { - return 'onAuth' in options; -} - -/** - * Configure static credential for authentication - * @public - * @deprecated This type is deprecated and will be removed in a future release, see https://github.com/backstage/backstage/issues/24493. - */ -export type StaticAuthOptions = { - username?: string; - password?: string; - token?: string; - logger?: LoggerService; -}; - -/** - * Configure an authentication callback that can provide credentials on demand - * @public - * @deprecated This type is deprecated and will be removed in a future release, see https://github.com/backstage/backstage/issues/24493. - */ -export type AuthCallbackOptions = { - onAuth: AuthCallback; - logger?: LoggerService; -}; - -/* -provider username password -Azure 'notempty' token -Bitbucket Cloud 'x-token-auth' token -Bitbucket Server username password or token -GitHub 'x-access-token' token -GitLab 'oauth2' token - -From : https://isomorphic-git.org/docs/en/onAuth with fix for GitHub - -Or token provided as `token` for Bearer auth header -instead of Basic Auth (e.g., Bitbucket Server). -*/ - -/** - * A convenience wrapper around the `isomorphic-git` library. - * @public - * @deprecated This class is deprecated and will be removed in a future release, see https://github.com/backstage/backstage/issues/24493. - */ - -export class Git { - private readonly headers: { - [x: string]: string; - }; - - private constructor( - private readonly config: { - onAuth: AuthCallback; - token?: string; - logger?: LoggerService; - }, - ) { - this.onAuth = config.onAuth; - - this.headers = { - 'user-agent': 'git/@isomorphic-git', - ...(config.token ? { Authorization: `Bearer ${config.token}` } : {}), - }; - } - - async add(options: { dir: string; filepath: string }): Promise { - const { dir, filepath } = options; - this.config.logger?.info(`Adding file {dir=${dir},filepath=${filepath}}`); - - return git.add({ fs, dir, filepath }); - } - - async addRemote(options: { - dir: string; - remote: string; - url: string; - force?: boolean; - }): Promise { - const { dir, url, remote, force } = options; - this.config.logger?.info( - `Creating new remote {dir=${dir},remote=${remote},url=${url}}`, - ); - return git.addRemote({ fs, dir, remote, url, force }); - } - - async deleteRemote(options: { dir: string; remote: string }): Promise { - const { dir, remote } = options; - this.config.logger?.info(`Deleting remote {dir=${dir},remote=${remote}}`); - return git.deleteRemote({ fs, dir, remote }); - } - - async checkout(options: { dir: string; ref: string }): Promise { - const { dir, ref } = options; - this.config.logger?.info(`Checking out branch {dir=${dir},ref=${ref}}`); - - return git.checkout({ fs, dir, ref }); - } - - async branch(options: { dir: string; ref: string }): Promise { - const { dir, ref } = options; - this.config.logger?.info(`Creating branch {dir=${dir},ref=${ref}`); - - return git.branch({ fs, dir, ref }); - } - - async commit(options: { - dir: string; - message: string; - author: { name: string; email: string }; - committer: { name: string; email: string }; - }): Promise { - const { dir, message, author, committer } = options; - this.config.logger?.info( - `Committing file to repo {dir=${dir},message=${message}}`, - ); - return git.commit({ fs, dir, message, author, committer }); - } - - /** https://isomorphic-git.org/docs/en/clone */ - async clone(options: { - url: string; - dir: string; - ref?: string; - depth?: number; - noCheckout?: boolean; - }): Promise { - const { url, dir, ref, depth, noCheckout } = options; - this.config.logger?.info(`Cloning repo {dir=${dir},url=${url}}`); - - try { - return await git.clone({ - fs, - http, - url, - dir, - ref, - singleBranch: true, - depth: depth ?? 1, - noCheckout, - onProgress: this.onProgressHandler(), - headers: this.headers, - onAuth: this.onAuth, - }); - } catch (ex) { - this.config.logger?.error(`Failed to clone repo {dir=${dir},url=${url}}`); - if (ex.data) { - throw new Error(`${ex.message} {data=${JSON.stringify(ex.data)}}`); - } - throw ex; - } - } - - /** https://isomorphic-git.org/docs/en/currentBranch */ - async currentBranch(options: { - dir: string; - fullName?: boolean; - }): Promise { - const { dir, fullName = false } = options; - return git.currentBranch({ fs, dir, fullname: fullName }) as Promise< - string | undefined - >; - } - - /** https://isomorphic-git.org/docs/en/fetch */ - async fetch(options: { - dir: string; - remote?: string; - tags?: boolean; - }): Promise { - const { dir, remote = 'origin', tags = false } = options; - this.config.logger?.info( - `Fetching remote=${remote} for repository {dir=${dir}}`, - ); - - try { - await git.fetch({ - fs, - http, - dir, - remote, - tags, - onProgress: this.onProgressHandler(), - headers: this.headers, - onAuth: this.onAuth, - }); - } catch (ex) { - this.config.logger?.error( - `Failed to fetch repo {dir=${dir},remote=${remote}}`, - ); - if (ex.data) { - throw new Error(`${ex.message} {data=${JSON.stringify(ex.data)}}`); - } - throw ex; - } - } - - async init(options: { dir: string; defaultBranch?: string }): Promise { - const { dir, defaultBranch = 'master' } = options; - this.config.logger?.info(`Init git repository {dir=${dir}}`); - - return git.init({ - fs, - dir, - defaultBranch, - }); - } - - /** https://isomorphic-git.org/docs/en/merge */ - async merge(options: { - dir: string; - theirs: string; - ours?: string; - author: { name: string; email: string }; - committer: { name: string; email: string }; - }): Promise { - const { dir, theirs, ours, author, committer } = options; - this.config.logger?.info( - `Merging branch '${theirs}' into '${ours}' for repository {dir=${dir}}`, - ); - - // If ours is undefined, current branch is used. - return git.merge({ - fs, - dir, - ours, - theirs, - author, - committer, - }); - } - - async push(options: { - dir: string; - remote: string; - remoteRef?: string; - force?: boolean; - }) { - const { dir, remote, remoteRef, force } = options; - this.config.logger?.info( - `Pushing directory to remote {dir=${dir},remote=${remote}}`, - ); - try { - return await git.push({ - fs, - dir, - http, - onProgress: this.onProgressHandler(), - remoteRef, - force, - headers: this.headers, - remote, - onAuth: this.onAuth, - }); - } catch (ex) { - this.config.logger?.error( - `Failed to push to repo {dir=${dir}, remote=${remote}}`, - ); - if (ex.data) { - throw new Error(`${ex.message} {data=${JSON.stringify(ex.data)}}`); - } - throw ex; - } - } - - /** https://isomorphic-git.org/docs/en/readCommit */ - async readCommit(options: { - dir: string; - sha: string; - }): Promise { - const { dir, sha } = options; - return git.readCommit({ fs, dir, oid: sha }); - } - - /** https://isomorphic-git.org/docs/en/remove */ - async remove(options: { dir: string; filepath: string }): Promise { - const { dir, filepath } = options; - this.config.logger?.info( - `Removing file from git index {dir=${dir},filepath=${filepath}}`, - ); - return git.remove({ fs, dir, filepath }); - } - - /** https://isomorphic-git.org/docs/en/resolveRef */ - async resolveRef(options: { dir: string; ref: string }): Promise { - const { dir, ref } = options; - return git.resolveRef({ fs, dir, ref }); - } - - /** https://isomorphic-git.org/docs/en/log */ - async log(options: { - dir: string; - ref?: string; - }): Promise { - const { dir, ref } = options; - return git.log({ - fs, - dir, - ref: ref ?? 'HEAD', - }); - } - - private onAuth: AuthCallback; - - private onProgressHandler = (): ProgressCallback => { - let currentPhase = ''; - - return event => { - if (currentPhase !== event.phase) { - currentPhase = event.phase; - this.config.logger?.info(event.phase); - } - const total = event.total - ? `${Math.round((event.loaded / event.total) * 100)}%` - : event.loaded; - this.config.logger?.debug(`status={${event.phase},total={${total}}}`); - }; - }; - - static fromAuth = (options: StaticAuthOptions | AuthCallbackOptions) => { - if (isAuthCallbackOptions(options)) { - const { onAuth, logger } = options; - return new Git({ onAuth, logger }); - } - - const { username, password, token, logger } = options; - return new Git({ onAuth: () => ({ username, password }), token, logger }); - }; -} diff --git a/packages/backend-common/src/deprecated/scm/index.ts b/packages/backend-common/src/deprecated/scm/index.ts deleted file mode 100644 index f9c59e99eb..0000000000 --- a/packages/backend-common/src/deprecated/scm/index.ts +++ /dev/null @@ -1,18 +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 { Git } from './git'; -export type { StaticAuthOptions, AuthCallbackOptions } from './git'; diff --git a/packages/backend-common/src/deprecated/service/createServiceBuilder.ts b/packages/backend-common/src/deprecated/service/createServiceBuilder.ts deleted file mode 100644 index e731056f72..0000000000 --- a/packages/backend-common/src/deprecated/service/createServiceBuilder.ts +++ /dev/null @@ -1,27 +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 { ServiceBuilderImpl } from './lib/ServiceBuilderImpl'; -import { ServiceBuilder } from './types'; - -/** - * Creates a new service builder. - * @public - * @deprecated We are going to deprecated this old way of creating services in a near future, if you are using this service helper, please checkout the {@link https://backstage.io/docs/backend-system/building-backends/migrating | backend} and {@link https://backstage.io/docs/backend-system/building-plugins-and-modules/migrating | plugin} migration guides. - */ -export function createServiceBuilder(_module: NodeModule): ServiceBuilder { - return new ServiceBuilderImpl(_module); -} diff --git a/packages/backend-common/src/deprecated/service/createStatusCheckRouter.test.ts b/packages/backend-common/src/deprecated/service/createStatusCheckRouter.test.ts deleted file mode 100644 index 604a1eb12f..0000000000 --- a/packages/backend-common/src/deprecated/service/createStatusCheckRouter.test.ts +++ /dev/null @@ -1,56 +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 express from 'express'; -import * as winston from 'winston'; -import request from 'supertest'; -import { createStatusCheckRouter } from './createStatusCheckRouter'; - -describe('createStatusCheckRouter', () => { - const logger = winston.createLogger(); - - it('gives status 200 when using default path', async () => { - const app = express(); - app.use('', await createStatusCheckRouter({ logger })); - - const response = await request(app).get('/healthcheck'); - - expect(response.status).toBe(200); - expect(response.text).toBe(JSON.stringify({ status: 'ok' })); - }); - - it('gives status 200 when using custom path', async () => { - const app = express(); - app.use('', await createStatusCheckRouter({ logger, path: '/ready' })); - - const response = await request(app).get('/ready'); - - expect(response.status).toBe(200); - expect(response.text).toBe(JSON.stringify({ status: 'ok' })); - }); - - it('gives status 500 when status check throws an error', async () => { - const app = express(); - const statusCheck = () => { - throw Error('error!'); - }; - app.use('', await createStatusCheckRouter({ logger, statusCheck })); - - const response = await request(app).get('/healthcheck'); - - expect(response.status).toBe(500); - }); -}); diff --git a/packages/backend-common/src/deprecated/service/createStatusCheckRouter.ts b/packages/backend-common/src/deprecated/service/createStatusCheckRouter.ts deleted file mode 100644 index fdece10ec5..0000000000 --- a/packages/backend-common/src/deprecated/service/createStatusCheckRouter.ts +++ /dev/null @@ -1,57 +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 { LoggerService } from '@backstage/backend-plugin-api'; -import Router from 'express-promise-router'; -import express from 'express'; -import { errorHandler, statusCheckHandler, StatusCheck } from '..'; - -/** - * Creates a default status checking router, that you can add to your express - * app. - * - * @remarks - * - * This adds a `/healthcheck` route (or any other path, if given as an - * argument), which your infra can call to see if the service is ready to serve - * requests. - * - * @public - * @deprecated Migrate to the {@link https://backstage.io/docs/backend-system/ | new backend system} and use the {@link https://backstage.io/docs/backend-system/core-services/root-health | Root Health Service} instead. - */ -export async function createStatusCheckRouter(options: { - logger: LoggerService; - /** - * The path (including a leading slash) that the health check should be - * mounted on. - * - * @defaultValue '/healthcheck' - */ - path?: string; - /** - * If not implemented, the default express middleware always returns 200. - * Override this to implement your own logic for a health check. - */ - statusCheck?: StatusCheck; -}): Promise { - const router = Router(); - const { path = '/healthcheck', statusCheck } = options; - - router.use(path, await statusCheckHandler({ statusCheck })); - router.use(errorHandler()); - - return router; -} diff --git a/packages/backend-common/src/deprecated/service/index.ts b/packages/backend-common/src/deprecated/service/index.ts deleted file mode 100644 index d01f25fad3..0000000000 --- a/packages/backend-common/src/deprecated/service/index.ts +++ /dev/null @@ -1,19 +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 { createServiceBuilder } from './createServiceBuilder'; -export { createStatusCheckRouter } from './createStatusCheckRouter'; -export type { ServiceBuilder, RequestLoggingHandlerFactory } from './types'; diff --git a/packages/backend-common/src/deprecated/service/lib/ServiceBuilderImpl.test.ts b/packages/backend-common/src/deprecated/service/lib/ServiceBuilderImpl.test.ts deleted file mode 100644 index 6229cbb683..0000000000 --- a/packages/backend-common/src/deprecated/service/lib/ServiceBuilderImpl.test.ts +++ /dev/null @@ -1,60 +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 { NextFunction, Request, Response } from 'express'; -import { applyCspDirectives, ServiceBuilderImpl } from './ServiceBuilderImpl'; - -describe('ServiceBuilderImpl', () => { - describe('applyCspDirectives', () => { - it('copies actual values', () => { - const result = applyCspDirectives({ key: ['value'] }); - expect(result).toEqual( - expect.objectContaining({ - 'default-src': ["'self'"], - key: ['value'], - }), - ); - }); - - it('removes false value keys', () => { - const result = applyCspDirectives({ 'upgrade-insecure-requests': false }); - expect(result!['upgrade-insecure-requests']).toBeUndefined(); - }); - }); - - describe('setCustomErrorHandler', () => { - it('check if custom error handler is undefined', () => { - const serviceBuilder = new ServiceBuilderImpl(module); - const serviceBuilderProto = Object.getPrototypeOf(serviceBuilder); - expect(serviceBuilderProto.errorHandler).toBeUndefined(); - }); - - it('adds custom error handler', () => { - const serviceBuilder = new ServiceBuilderImpl(module); - const serviceBuilderProto = Object.getPrototypeOf(serviceBuilder); - const customErrorHandler = ( - error: Error, - _req: Request, - _res: Response, - next: NextFunction, - ) => { - next(error); - }; - serviceBuilderProto.setErrorHandler(customErrorHandler); - expect(serviceBuilderProto.errorHandler).toEqual(customErrorHandler); - }); - }); -}); diff --git a/packages/backend-common/src/deprecated/service/lib/ServiceBuilderImpl.ts b/packages/backend-common/src/deprecated/service/lib/ServiceBuilderImpl.ts deleted file mode 100644 index b338eb20b1..0000000000 --- a/packages/backend-common/src/deprecated/service/lib/ServiceBuilderImpl.ts +++ /dev/null @@ -1,215 +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 { Config } from '@backstage/config'; -import compression from 'compression'; -import cors from 'cors'; -import express, { Router, ErrorRequestHandler } from 'express'; -import helmet, { HelmetOptions } from 'helmet'; -import { ContentSecurityPolicyOptions } from 'helmet/dist/types/middlewares/content-security-policy'; -import * as http from 'http'; -import { LoggerService } from '@backstage/backend-plugin-api'; -import { useHotCleanup } from '../../hot'; -import { getRootLogger } from '../../logging'; -import { - errorHandler as defaultErrorHandler, - notFoundHandler, - requestLoggingHandler as defaultRequestLoggingHandler, -} from '../../middleware'; -import { RequestLoggingHandlerFactory, ServiceBuilder } from '../types'; -// eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { - readCorsOptions, - readHelmetOptions, - readHttpServerOptions, - HttpServerOptions, - createHttpServer, -} from '../../../../../backend-defaults/src/entrypoints/rootHttpRouter/http'; - -export type CspOptions = Record; - -export class ServiceBuilderImpl implements ServiceBuilder { - private logger: LoggerService | undefined; - private serverOptions: HttpServerOptions; - private helmetOptions: HelmetOptions; - private corsOptions: cors.CorsOptions; - private routers: [string, Router][]; - private requestLoggingHandler: RequestLoggingHandlerFactory | undefined; - private errorHandler: ErrorRequestHandler | undefined; - private useDefaultErrorHandler: boolean; - // Reference to the module where builder is created - needed for hot module - // reloading - private module: NodeModule; - - constructor(moduleRef: NodeModule) { - this.routers = []; - this.module = moduleRef; - this.useDefaultErrorHandler = true; - - this.serverOptions = readHttpServerOptions(); - this.corsOptions = readCorsOptions(); - this.helmetOptions = readHelmetOptions(); - } - - loadConfig(config: Config): ServiceBuilder { - const backendConfig = config.getOptionalConfig('backend'); - - this.serverOptions = readHttpServerOptions(backendConfig); - this.corsOptions = readCorsOptions(backendConfig); - this.helmetOptions = readHelmetOptions(backendConfig); - - return this; - } - - setPort(port: number): ServiceBuilder { - this.serverOptions.listen.port = port; - return this; - } - - setHost(host: string): ServiceBuilder { - this.serverOptions.listen.host = host; - return this; - } - - setLogger(logger: LoggerService): ServiceBuilder { - this.logger = logger; - return this; - } - - setHttpsSettings(settings: { - certificate: { key: string; cert: string } | { hostname: string }; - }): ServiceBuilder { - if ('hostname' in settings.certificate) { - this.serverOptions.https = { - certificate: { - ...settings.certificate, - type: 'generated', - }, - }; - } else { - this.serverOptions.https = { - certificate: { - ...settings.certificate, - type: 'pem', - }, - }; - } - return this; - } - - enableCors(options: cors.CorsOptions): ServiceBuilder { - this.corsOptions = options; - return this; - } - - setCsp(options: CspOptions): ServiceBuilder { - const csp = this.helmetOptions.contentSecurityPolicy; - this.helmetOptions.contentSecurityPolicy = { - ...(typeof csp === 'object' ? csp : {}), - directives: applyCspDirectives(options), - }; - return this; - } - - addRouter(root: string, router: Router): ServiceBuilder { - this.routers.push([root, router]); - return this; - } - - setRequestLoggingHandler( - requestLoggingHandler: RequestLoggingHandlerFactory, - ) { - this.requestLoggingHandler = requestLoggingHandler; - return this; - } - - setErrorHandler(errorHandler: ErrorRequestHandler) { - this.errorHandler = errorHandler; - return this; - } - - disableDefaultErrorHandler() { - this.useDefaultErrorHandler = false; - return this; - } - - async start(): Promise { - const app = express(); - const logger = this.logger ?? getRootLogger(); - - app.use(helmet(this.helmetOptions)); - app.use(cors(this.corsOptions)); - app.use(compression()); - app.use( - (this.requestLoggingHandler ?? defaultRequestLoggingHandler)(logger), - ); - for (const [root, route] of this.routers) { - app.use(root, route); - } - app.use(notFoundHandler()); - - if (this.errorHandler) { - app.use(this.errorHandler); - } - - if (this.useDefaultErrorHandler) { - app.use(defaultErrorHandler()); - } - - const server = await createHttpServer(app, this.serverOptions, { logger }); - - useHotCleanup(this.module, () => - server.stop().catch(error => { - console.error(error); - }), - ); - - await server.start(); - - return server; - } -} - -// TODO(Rugvip): This is a duplicate of the same logic over in backend-app-api. -// It's needed as we don't want to export this helper from there, but need -// It to implement the setCsp method here. -export function applyCspDirectives( - directives: Record | undefined, -): ContentSecurityPolicyOptions['directives'] { - const result: ContentSecurityPolicyOptions['directives'] = - helmet.contentSecurityPolicy.getDefaultDirectives(); - - // TODO(Rugvip): We currently use non-precompiled AJV for validation in the frontend, which uses eval. - // It should be replaced by any other solution that doesn't require unsafe-eval. - result['script-src'] = ["'self'", "'unsafe-eval'"]; - - // TODO(Rugvip): This is removed so that we maintained backwards compatibility - // when bumping to helmet v5, we could remove this as well as - // skip setting `useDefaults: false` in the future. - delete result['form-action']; - - if (directives) { - for (const [key, value] of Object.entries(directives)) { - if (value === false) { - delete result[key]; - } else { - result[key] = value; - } - } - } - - return result; -} diff --git a/packages/backend-common/src/deprecated/service/types.ts b/packages/backend-common/src/deprecated/service/types.ts deleted file mode 100644 index ace0712d2f..0000000000 --- a/packages/backend-common/src/deprecated/service/types.ts +++ /dev/null @@ -1,135 +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 { Config } from '@backstage/config'; -import cors from 'cors'; -import { Router, RequestHandler, ErrorRequestHandler } from 'express'; -import { Server } from 'http'; -import { LoggerService } from '@backstage/backend-plugin-api'; - -/** - * A helper for building backend service instances. - * - * @public - * @deprecated This type is being deprecated along with the {@link @backstage/backend-common#createServiceBuilder} function. - */ -export type ServiceBuilder = { - /** - * Sets the service parameters based on configuration. - * - * @param config - The configuration to read - */ - loadConfig(config: Config): ServiceBuilder; - - /** - * Sets the port to listen on. - * - * If no port is specified, the service will first look for an environment - * variable named PORT and use that if present, otherwise it picks a default - * port (7007). - * - * @param port - The port to listen on - */ - setPort(port: number): ServiceBuilder; - - /** - * Sets the host to listen on. - * - * '' is express default, which listens to all interfaces. - * - * @param host - The host to listen on - */ - setHost(host: string): ServiceBuilder; - - /** - * Sets the logger to use for service-specific logging. - * - * If no logger is given, the default root logger is used. - * - * @param logger - A winston logger - */ - setLogger(logger: LoggerService): ServiceBuilder; - - /** - * Enables CORS handling using the given settings. - * - * If this method is not called, the resulting service will not have any - * built in CORS handling. - * - * @param options - Standard CORS options - */ - enableCors(options: cors.CorsOptions): ServiceBuilder; - - /** - * Configure self-signed certificate generation options. - * - * If this method is not called, the resulting service will use sensible defaults - * - * @param options - Standard certificate options - */ - setHttpsSettings(settings: { - certificate: { key: string; cert: string } | { hostname: string }; - }): ServiceBuilder; - - /** - * Adds a router (similar to the express .use call) to the service. - * - * @param root - The root URL to bind to (e.g. "/api/function1") - * @param router - An express router - */ - addRouter(root: string, router: Router | RequestHandler): ServiceBuilder; - - /** - * Set the request logging handler - * - * If no handler is given the default one is used - * - * @param requestLoggingHandler - a factory function that given a logger returns an handler - */ - setRequestLoggingHandler( - requestLoggingHandler: RequestLoggingHandlerFactory, - ): ServiceBuilder; - - /** - * Sets an additional errorHandler to run before the defaultErrorHandler. - * - * For execution of only the custom error handler make sure to also invoke disableDefaultErrorHandler() - * otherwise the defaultErrorHandler is executed at the end of the error middleware chain. - * - * @param errorHandler - an error handler - */ - setErrorHandler(errorHandler: ErrorRequestHandler): ServiceBuilder; - - /** - * Disables the default error handler - */ - disableDefaultErrorHandler(): ServiceBuilder; - - /** - * Starts the server using the given settings. - */ - start(): Promise; -}; - -/** - * A factory for request loggers. - * - * @public - * @deprecated This type is being deprecated along with the {@link @backstage/backend-common#createServiceBuilder} function. - */ -export type RequestLoggingHandlerFactory = ( - logger?: LoggerService, -) => RequestHandler; diff --git a/packages/backend-common/src/deprecated/tokens/ServerTokenManager.test.ts b/packages/backend-common/src/deprecated/tokens/ServerTokenManager.test.ts deleted file mode 100644 index 2f99164ec1..0000000000 --- a/packages/backend-common/src/deprecated/tokens/ServerTokenManager.test.ts +++ /dev/null @@ -1,392 +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 { ConfigReader } from '@backstage/config'; -import * as jose from 'jose'; -import { ServerTokenManager } from './ServerTokenManager'; -import { TokenManager } from './types'; -import { DateTime } from 'luxon'; -import { mockServices } from '@backstage/backend-test-utils'; - -const emptyConfig = new ConfigReader({}); -const configWithSecret = new ConfigReader({ - backend: { auth: { keys: [{ secret: 'a-secret-key' }] } }, -}); -const env = process.env; -const logger = mockServices.logger.mock(); - -describe('ServerTokenManager', () => { - beforeEach(() => { - process.env = { ...env }; - }); - - afterEach(() => { - process.env = env; - jest.useRealTimers(); - }); - - describe('getToken', () => { - it('should return a token', async () => { - const tokenManager = ServerTokenManager.fromConfig(configWithSecret, { - logger, - }); - expect((await tokenManager.getToken()).token).toBeDefined(); - }); - - it('should return a token string if using a noop TokenManager', async () => { - const tokenManager = ServerTokenManager.noop(); - expect((await tokenManager.getToken()).token).toBeDefined(); - }); - }); - - describe('authenticate', () => { - it('should not throw if token is valid', async () => { - const tokenManager = ServerTokenManager.fromConfig(configWithSecret, { - logger, - }); - const { token } = await tokenManager.getToken(); - await expect(tokenManager.authenticate(token)).resolves.not.toThrow(); - }); - - it('should throw if token is invalid', async () => { - const tokenManager = ServerTokenManager.fromConfig(configWithSecret, { - logger, - }); - await expect(tokenManager.authenticate('random-string')).rejects.toThrow( - /invalid server token/i, - ); - }); - - it('should validate server tokens created by a different instance using the same secret', async () => { - const tokenManager1 = ServerTokenManager.fromConfig(configWithSecret, { - logger, - }); - const tokenManager2 = ServerTokenManager.fromConfig(configWithSecret, { - logger, - }); - - const { token } = await tokenManager1.getToken(); - - await expect(tokenManager2.authenticate(token)).resolves.not.toThrow(); - }); - - it('should validate server tokens created using any of the secrets', async () => { - const tokenManager1 = ServerTokenManager.fromConfig( - new ConfigReader({ - backend: { auth: { keys: [{ secret: 'a1b2c3' }] } }, - }), - { logger }, - ); - const tokenManager2 = ServerTokenManager.fromConfig( - new ConfigReader({ - backend: { auth: { keys: [{ secret: 'd4e5f6' }] } }, - }), - { logger }, - ); - const tokenManager3 = ServerTokenManager.fromConfig( - new ConfigReader({ - backend: { - auth: { keys: [{ secret: 'a1b2c3' }, { secret: 'd4e5f6' }] }, - }, - }), - { logger }, - ); - - const { token: token1 } = await tokenManager1.getToken(); - await expect(tokenManager3.authenticate(token1)).resolves.not.toThrow(); - - const { token: token2 } = await tokenManager2.getToken(); - await expect(tokenManager3.authenticate(token2)).resolves.not.toThrow(); - }); - - it('should throw for server tokens created using a different secret', async () => { - const tokenManager1 = ServerTokenManager.fromConfig( - new ConfigReader({ - backend: { auth: { keys: [{ secret: 'a1b2c3' }] } }, - }), - { logger }, - ); - const tokenManager2 = ServerTokenManager.fromConfig( - new ConfigReader({ - backend: { auth: { keys: [{ secret: 'd4e5f6' }] } }, - }), - { logger }, - ); - - const { token } = await tokenManager1.getToken(); - - await expect(tokenManager2.authenticate(token)).rejects.toThrow( - /invalid server token/i, - ); - }); - - it('should throw for server tokens created using a noop TokenManager', async () => { - const noopTokenManager = ServerTokenManager.noop(); - const tokenManager = ServerTokenManager.fromConfig( - new ConfigReader({ - backend: { auth: { keys: [{ secret: 'a1b2c3' }] } }, - }), - { logger }, - ); - - const { token } = await noopTokenManager.getToken(); - - await expect(tokenManager.authenticate(token)).rejects.toThrow( - /invalid server token/i, - ); - }); - - it('should throw for server tokens created by a different generated secret', async () => { - (process.env as any).NODE_ENV = 'development'; - const tokenManager1 = ServerTokenManager.fromConfig( - new ConfigReader({ - backend: { auth: { keys: [{ secret: 'a1b2c3' }] } }, - }), - { logger }, - ); - const tokenManager2 = ServerTokenManager.fromConfig(emptyConfig, { - logger, - }); - - const { token } = await tokenManager2.getToken(); - - await expect(tokenManager1.authenticate(token)).rejects.toThrow( - /invalid server token/i, - ); - }); - - it('should throw for expired tokens, and re-issue new ones', async () => { - jest.useFakeTimers(); - - const tokenManager = ServerTokenManager.fromConfig(configWithSecret, { - logger, - }); - - const { token: token1 } = await tokenManager.getToken(); - await expect(tokenManager.authenticate(token1)).resolves.not.toThrow(); - - // Right before the reissue timeout, it still returns the same token - jest.advanceTimersByTime(9 * 60 * 1000); - const { token: token1Again } = await tokenManager.getToken(); - expect(token1).toEqual(token1Again); - await expect(tokenManager.authenticate(token1)).resolves.not.toThrow(); - - // Right after the reissue timeout, the old ones are still valid but returning a new token - jest.advanceTimersByTime(2 * 60 * 1000); - const { token: token2 } = await tokenManager.getToken(); - expect(token1).not.toEqual(token2); - await expect(tokenManager.authenticate(token1)).resolves.not.toThrow(); - await expect(tokenManager.authenticate(token2)).resolves.not.toThrow(); - - // After expiry of the first one, it gets warnings but the newest one is still valid - jest.advanceTimersByTime(52 * 60 * 1000); - await expect(tokenManager.authenticate(token1)).rejects.toThrow( - 'Invalid server token; caused by JWTExpired: "exp" claim timestamp check failed', - ); - await expect(tokenManager.authenticate(token2)).resolves.not.toThrow(); - }); - - it('should work with a manually crafted JWT', async () => { - const secret = 'a1b2c3'; - const token = await new jose.SignJWT({}) - .setProtectedHeader({ alg: 'HS256' }) - .setSubject('backstage-server') - .setExpirationTime(Date.now() + 1000 * 60 * 60) - .sign(jose.base64url.decode(secret)); - - const tokenManager = ServerTokenManager.fromConfig( - new ConfigReader({ - backend: { auth: { keys: [{ secret }] } }, - }), - { logger }, - ); - await expect(tokenManager.authenticate(token)).resolves.toBeUndefined(); - }); - - it('should reject tokens without exp claim', async () => { - const secret = 'a1b2c3'; - const token = await new jose.SignJWT({}) - .setProtectedHeader({ alg: 'HS256' }) - .setSubject('backstage-server') - .sign(jose.base64url.decode(secret)); - - const tokenManager = ServerTokenManager.fromConfig( - new ConfigReader({ - backend: { auth: { keys: [{ secret }] } }, - }), - { logger }, - ); - await expect(tokenManager.authenticate(token)).rejects.toThrow( - 'Invalid server token; caused by AuthenticationError: Server-to-server token had no exp claim', - ); - }); - - it('loads both old and new config', async () => { - const oldSecret = jose.base64url.encode('old'); - const newSecret = jose.base64url.encode('new'); - - const tokenManager = ServerTokenManager.fromConfig( - new ConfigReader({ - backend: { - auth: { - keys: [{ secret: oldSecret }], - externalAccess: [ - { type: 'legacy', options: { secret: newSecret } }, - ], - }, - }, - }), - { logger }, - ); - - const oldToken = await new jose.SignJWT({}) - .setProtectedHeader({ alg: 'HS256' }) - .setSubject('backstage-server') - .setExpirationTime(DateTime.now().plus({ minutes: 1 }).toUnixInteger()) - .sign(jose.base64url.decode(oldSecret)); - const newToken = await new jose.SignJWT({}) - .setProtectedHeader({ alg: 'HS256' }) - .setSubject('backstage-server') - .setExpirationTime(DateTime.now().plus({ minutes: 1 }).toUnixInteger()) - .sign(jose.base64url.decode(newSecret)); - - await expect(tokenManager.authenticate(oldToken)).resolves.not.toThrow(); - await expect(tokenManager.authenticate(newToken)).resolves.not.toThrow(); - }); - }); - - describe('fromConfig', () => { - describe('NODE_ENV === production', () => { - it('should throw if backend auth configuration is missing', () => { - expect(() => - ServerTokenManager.fromConfig(emptyConfig, { logger }), - ).toThrow(); - }); - - it('should throw if no keys are included in the configuration', () => { - expect(() => - ServerTokenManager.fromConfig( - new ConfigReader({ - backend: { auth: { keys: [] } }, - }), - { logger }, - ), - ).toThrow(); - }); - - it('should throw if any key is missing a secret property', () => { - expect(() => - ServerTokenManager.fromConfig( - new ConfigReader({ - backend: { - auth: { - keys: [{ secret: '123' }, {}, { secret: '789' }], - }, - }, - }), - { logger }, - ), - ).toThrow(); - }); - - it('should throw errors when disabled', async () => { - const manager = ServerTokenManager.fromConfig(new ConfigReader({}), { - logger, - allowDisabledTokenManager: true, - }); - - await expect(manager.getToken()).rejects.toThrow( - 'Unable to generate legacy token', - ); - await expect(manager.authenticate('nah')).rejects.toThrow( - 'Unable to authenticate legacy token', - ); - }); - }); - - describe('NODE_ENV === development', () => { - const generateSecretSpy = jest.spyOn(jose, 'generateSecret'); - - beforeEach(() => { - (process.env as any).NODE_ENV = 'development'; - }); - - afterEach(() => { - jest.clearAllMocks(); - }); - - it('should generate a key if no config is provided', async () => { - const tokenManager = ServerTokenManager.fromConfig(emptyConfig, { - logger, - }); - const token = await tokenManager.getToken(); - expect(token).toBeDefined(); - expect(generateSecretSpy).toHaveBeenCalledWith('HS256'); - }); - - it('should generate a key if no keys are provided in the configuration', async () => { - const tokenManager = ServerTokenManager.fromConfig( - new ConfigReader({ - backend: { auth: { keys: [] } }, - }), - { logger }, - ); - const token = await tokenManager.getToken(); - expect(token).toBeDefined(); - expect(generateSecretSpy).toHaveBeenCalledWith('HS256'); - }); - - it('should use provided secrets if config is provided', () => { - ServerTokenManager.fromConfig(configWithSecret, { logger }); - expect(generateSecretSpy).not.toHaveBeenCalled(); - }); - }); - }); - - describe('noop', () => { - let noopTokenManager: TokenManager; - - beforeEach(() => { - noopTokenManager = ServerTokenManager.noop(); - }); - - it('should accept tokens it generates', async () => { - const { token } = await noopTokenManager.getToken(); - - await expect(noopTokenManager.authenticate(token)).resolves.not.toThrow(); - }); - - it('should accept tokens generated by other noop token managers', async () => { - const noopTokenManager2 = ServerTokenManager.noop(); - await expect( - noopTokenManager.authenticate( - ( - await noopTokenManager2.getToken() - ).token, - ), - ).resolves.not.toThrow(); - }); - - it('should accept signed tokens', async () => { - const tokenManager = ServerTokenManager.fromConfig(configWithSecret, { - logger, - }); - await expect( - noopTokenManager.authenticate((await tokenManager.getToken()).token), - ).resolves.not.toThrow(); - }); - }); -}); diff --git a/packages/backend-common/src/deprecated/tokens/ServerTokenManager.ts b/packages/backend-common/src/deprecated/tokens/ServerTokenManager.ts deleted file mode 100644 index a9dee0f67a..0000000000 --- a/packages/backend-common/src/deprecated/tokens/ServerTokenManager.ts +++ /dev/null @@ -1,249 +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 { Config } from '@backstage/config'; -import { AuthenticationError } from '@backstage/errors'; -import { base64url, exportJWK, generateSecret, jwtVerify, SignJWT } from 'jose'; -import { DateTime, Duration } from 'luxon'; -import { LoggerService } from '@backstage/backend-plugin-api'; -import { TokenManager } from './types'; - -const TOKEN_ALG = 'HS256'; -const TOKEN_SUB = 'backstage-server'; -const TOKEN_EXPIRY_AFTER = Duration.fromObject({ hours: 1 }); -const TOKEN_REISSUE_AFTER = Duration.fromObject({ minutes: 10 }); - -/** - * A token manager that issues static fake tokens and never fails - * authentication. This can be useful for testing. - */ -class NoopTokenManager implements TokenManager { - public readonly isInsecureServerTokenManager: boolean = true; - - async getToken() { - return { token: '' }; - } - - async authenticate() {} -} - -/** - * A token manager that throws an error when trying to generate or authenticate tokens. - */ -class DisabledTokenManager implements TokenManager { - async getToken(): Promise<{ token: string }> { - throw new Error( - "Unable to generate legacy token, no legacy keys are configured in 'backend.auth.keys' or 'backend.auth.externalAccess'", - ); - } - - async authenticate() { - throw new AuthenticationError( - "Unable to authenticate legacy token, no legacy keys are configured in 'backend.auth.keys' or 'backend.auth.externalAccess'", - ); - } -} - -/** - * Options for {@link ServerTokenManager}. - * - * @public - * @deprecated Please {@link https://backstage.io/docs/tutorials/auth-service-migration | migrate} to the new `coreServices.auth`, `coreServices.httpAuth`, and `coreServices.userInfo` services as needed instead. - */ -export interface ServerTokenManagerOptions { - /** - * The logger to use. - */ - logger: LoggerService; - - /** - * Whether to disable the token manager if no keys are configured. - */ - allowDisabledTokenManager?: boolean; -} - -/** - * Creates and validates tokens for use during service-to-service - * authentication. - * - * @public - * @deprecated Please {@link https://backstage.io/docs/tutorials/auth-service-migration | migrate} to the new `coreServices.auth`, `coreServices.httpAuth`, and `coreServices.userInfo` services as needed instead. - */ -export class ServerTokenManager implements TokenManager { - private readonly options: ServerTokenManagerOptions; - private readonly verificationKeys: Uint8Array[]; - private signingKey: Uint8Array; - private privateKeyPromise: Promise | undefined; - private currentTokenPromise: Promise<{ token: string }> | undefined; - - /** - * Creates a token manager that issues static fake tokens and never fails - * authentication. This can be useful for testing. - */ - static noop(): TokenManager { - return new NoopTokenManager(); - } - - static fromConfig( - config: Config, - options: ServerTokenManagerOptions, - ): TokenManager { - const oldSecrets = config - .getOptionalConfigArray('backend.auth.keys') - ?.map(c => c.getString('secret')); - const newSecrets = config - .getOptionalConfigArray('backend.auth.externalAccess') - ?.filter(c => c.getString('type') === 'legacy') - .map(c => c.getString('options.secret')); - const secrets = [...(oldSecrets ?? []), ...(newSecrets ?? [])]; - - if (secrets.length) { - return new ServerTokenManager(secrets, options); - } - - // When using the new backend system with new auth services we instead rely - // on the new plugin auth and external access configurations. If no legacy - // keys are configured we disable the token manager completely, rather than - // requiring users to configure legacy keys. - if (options.allowDisabledTokenManager) { - return new DisabledTokenManager(); - } - - if (process.env.NODE_ENV !== 'development') { - throw new Error( - 'You must configure at least one key in backend.auth.keys for production.', - ); - } - - // For development, if a secret has not been configured, we auto generate a secret instead of throwing. - options.logger.warn( - 'Generated a secret for service-to-service authentication: DEVELOPMENT USE ONLY.', - ); - return new ServerTokenManager([], options); - } - - private constructor(secrets: string[], options: ServerTokenManagerOptions) { - if (!secrets.length && process.env.NODE_ENV !== 'development') { - throw new Error( - 'No secrets provided when constructing ServerTokenManager', - ); - } - this.options = options; - this.verificationKeys = secrets.map(s => base64url.decode(s)); - this.signingKey = this.verificationKeys[0]; - } - - // Called when no keys have been generated yet in the dev environment - private async generateKeys(): Promise { - if (process.env.NODE_ENV !== 'development') { - throw new Error( - 'Key generation is not supported outside of the dev environment', - ); - } - - if (this.privateKeyPromise) { - return this.privateKeyPromise; - } - - const promise = (async () => { - const secret = await generateSecret(TOKEN_ALG); - const jwk = await exportJWK(secret); - this.verificationKeys.push(base64url.decode(jwk.k ?? '')); - this.signingKey = this.verificationKeys[0]; - return; - })(); - - try { - this.privateKeyPromise = promise; - await promise; - } catch (error) { - // If we fail to generate a new key, we need to clear the state so that - // the next caller will try to generate another key. - this.options.logger.error(`Failed to generate new key, ${error}`); - delete this.privateKeyPromise; - } - - return promise; - } - - async getToken(): Promise<{ token: string }> { - if (!this.verificationKeys.length) { - await this.generateKeys(); - } - - if (this.currentTokenPromise) { - return this.currentTokenPromise; - } - - const result = Promise.resolve().then(async () => { - const jwt = await new SignJWT({}) - .setProtectedHeader({ alg: TOKEN_ALG }) - .setSubject(TOKEN_SUB) - .setExpirationTime( - DateTime.now().plus(TOKEN_EXPIRY_AFTER).toUnixInteger(), - ) - .sign(this.signingKey); - return { token: jwt }; - }); - - this.currentTokenPromise = result; - - result - .then(() => { - setTimeout(() => { - this.currentTokenPromise = undefined; - }, TOKEN_REISSUE_AFTER.toMillis()); - }) - .catch(() => { - this.currentTokenPromise = undefined; - }); - - return result; - } - - async authenticate(token: string): Promise { - let verifyError = undefined; - - for (const key of this.verificationKeys) { - try { - const { - protectedHeader: { alg }, - payload: { sub, exp }, - } = await jwtVerify(token, key); - - if (alg !== TOKEN_ALG) { - throw new AuthenticationError(`Illegal alg "${alg}"`); - } - - if (sub !== TOKEN_SUB) { - throw new AuthenticationError(`Illegal sub "${sub}"`); - } - - if (typeof exp !== 'number') { - throw new AuthenticationError( - 'Server-to-server token had no exp claim', - ); - } - return; - } catch (e) { - // Catch the verify exception and continue - verifyError = e; - } - } - - throw new AuthenticationError('Invalid server token', verifyError); - } -} diff --git a/packages/backend-common/src/deprecated/tokens/index.ts b/packages/backend-common/src/deprecated/tokens/index.ts deleted file mode 100644 index fe1b56df80..0000000000 --- a/packages/backend-common/src/deprecated/tokens/index.ts +++ /dev/null @@ -1,19 +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 { ServerTokenManager } from './ServerTokenManager'; -export type { ServerTokenManagerOptions } from './ServerTokenManager'; -export type { TokenManager } from './types'; diff --git a/packages/backend-common/src/deprecated/tokens/types.ts b/packages/backend-common/src/deprecated/tokens/types.ts deleted file mode 100644 index 41a2000868..0000000000 --- a/packages/backend-common/src/deprecated/tokens/types.ts +++ /dev/null @@ -1,38 +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. - */ - -/** - * @public - * @deprecated Please {@link https://backstage.io/docs/tutorials/auth-service-migration | migrate} to the new `coreServices.auth`, `coreServices.httpAuth`, and `coreServices.userInfo` services as needed instead. - */ -export interface TokenManager { - /** - * Fetches a valid token. - * - * @remarks - * - * Tokens are valid for roughly one hour; the actual deadline is set in the - * payload `exp` claim. Never hold on to tokens for reuse; always ask for a - * new one for each outgoing request. This ensures that you always get a - * valid, fresh one. - */ - getToken(): Promise<{ token: string }>; - - /** - * Validates a given token. - */ - authenticate(token: string): Promise; -} diff --git a/packages/backend-common/src/deprecated/util/ContainerRunner.ts b/packages/backend-common/src/deprecated/util/ContainerRunner.ts deleted file mode 100644 index 92081cea16..0000000000 --- a/packages/backend-common/src/deprecated/util/ContainerRunner.ts +++ /dev/null @@ -1,69 +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 { Writable } from 'stream'; - -/** - * Allows defining access credentials for a registry - * Follows dockerode auth configuration: - * {@link https://github.com/apocas/dockerode?tab=readme-ov-file#pull-from-private-repos} - * - * @public - * @deprecated This interface is deprecated and will be removed in a future release. - */ -export interface PullOptions { - authconfig?: { - username?: string; - password?: string; - auth?: string; - email?: string; - serveraddress?: string; - [key: string]: unknown; - }; - [key: string]: unknown; -} - -/** - * Options passed to the {@link ContainerRunner.runContainer} method. - * - * @public - * @deprecated This type is deprecated and will be removed in a future release. - */ -export type RunContainerOptions = { - imageName: string; - command?: string | string[]; - args: string[]; - logStream?: Writable; - mountDirs?: Record; - workingDir?: string; - envVars?: Record; - pullImage?: boolean; - defaultUser?: boolean; - pullOptions?: PullOptions; -}; - -/** - * Handles the running of containers, on behalf of others. - * - * @public - * @deprecated This interface is deprecated and will be removed in a future release. - */ -export interface ContainerRunner { - /** - * Runs a container image to completion. - */ - runContainer(opts: RunContainerOptions): Promise; -} diff --git a/packages/backend-common/src/deprecated/util/DockerContainerRunner.test.ts b/packages/backend-common/src/deprecated/util/DockerContainerRunner.test.ts deleted file mode 100644 index f5d0e18480..0000000000 --- a/packages/backend-common/src/deprecated/util/DockerContainerRunner.test.ts +++ /dev/null @@ -1,238 +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 fs from 'fs-extra'; -import Docker from 'dockerode'; -import Stream, { PassThrough } from 'stream'; -import { ContainerRunner } from './ContainerRunner'; -import { DockerContainerRunner, UserOptions } from './DockerContainerRunner'; -import { createMockDirectory } from '@backstage/backend-test-utils'; - -const mockDocker = new Docker() as jest.Mocked; - -describe('DockerContainerRunner', () => { - let containerTaskApi: ContainerRunner; - - const inputDir = createMockDirectory(); - const outputDir = createMockDirectory(); - - beforeEach(() => { - inputDir.clear(); - outputDir.clear(); - - jest.spyOn(mockDocker, 'pull').mockImplementation((async ( - _image: string, - _something: any, - handler: (err: Error | undefined, stream: PassThrough) => void, - ) => { - const mockStream = new PassThrough(); - handler(undefined, mockStream); - mockStream.end(); - }) as any); - - jest - .spyOn(mockDocker, 'run') - .mockResolvedValue([{ Error: null, StatusCode: 0 }]); - - jest - .spyOn(mockDocker, 'ping') - .mockResolvedValue(Buffer.from('OK', 'utf-8')); - - containerTaskApi = new DockerContainerRunner({ dockerClient: mockDocker }); - }); - - afterEach(() => { - jest.clearAllMocks(); - }); - - const imageName = 'dockerOrg/image'; - const args = ['bash', '-c', 'echo test']; - const mountDirs = { - [inputDir.path]: '/input', - [outputDir.path]: '/output', - }; - const workingDir = inputDir.path; - const envVars = { HOME: '/tmp', LOG_LEVEL: 'debug' }; - const envVarsArray = ['HOME=/tmp', 'LOG_LEVEL=debug']; - - it('should pull the docker container', async () => { - await containerTaskApi.runContainer({ - imageName, - args, - }); - - expect(mockDocker.pull).toHaveBeenCalledWith( - imageName, - {}, - expect.any(Function), - ); - - expect(mockDocker.run).toHaveBeenCalled(); - }); - - it('should pull the docker container with authentication', async () => { - await containerTaskApi.runContainer({ - imageName, - args, - pullOptions: { - authconfig: { - auth: 'aaaaaaaaa', - }, - }, - }); - - expect(mockDocker.pull).toHaveBeenCalledWith( - imageName, - { - authconfig: { - auth: 'aaaaaaaaa', - }, - }, - expect.any(Function), - ); - - expect(mockDocker.run).toHaveBeenCalled(); - }); - - it('should not pull the docker container when pullImage is false', async () => { - await containerTaskApi.runContainer({ - imageName, - args, - pullImage: false, - }); - - expect(mockDocker.pull).not.toHaveBeenCalled(); - expect(mockDocker.run).toHaveBeenCalled(); - }); - - it('should call the dockerClient run command with the correct arguments passed through', async () => { - await containerTaskApi.runContainer({ - imageName, - args, - mountDirs, - envVars, - workingDir, - }); - - expect(mockDocker.run).toHaveBeenCalledWith( - imageName, - args, - expect.any(Stream), - expect.objectContaining({ - Env: envVarsArray, - WorkingDir: workingDir, - HostConfig: { - AutoRemove: true, - Binds: expect.arrayContaining([ - `${await fs.realpath(inputDir.path)}:/input`, - `${await fs.realpath(outputDir.path)}:/output`, - ]), - }, - Volumes: { - '/input': {}, - '/output': {}, - }, - }), - ); - }); - - it('should ping docker to test availability', async () => { - await containerTaskApi.runContainer({ - imageName, - args, - }); - - expect(mockDocker.ping).toHaveBeenCalled(); - }); - - it('should pass through the user and group id from the host machine and set the home dir', async () => { - await containerTaskApi.runContainer({ - imageName, - args, - }); - - const userOptions: UserOptions = {}; - if (process.getuid && process.getgid) { - userOptions.User = `${process.getuid()}:${process.getgid()}`; - } - - expect(mockDocker.run).toHaveBeenCalledWith( - imageName, - args, - expect.any(Stream), - expect.objectContaining({ - ...userOptions, - }), - ); - }); - - it('throws a correct error if the command fails in docker', async () => { - mockDocker.run.mockResolvedValueOnce([ - { - Error: new Error('Something went wrong with docker'), - StatusCode: 0, - }, - ]); - - await expect( - containerTaskApi.runContainer({ - imageName, - args, - }), - ).rejects.toThrow(/Something went wrong with docker/); - }); - - describe('where docker is unavailable', () => { - const dockerError = 'a docker error'; - - beforeEach(() => { - jest.spyOn(mockDocker, 'ping').mockImplementationOnce(() => { - throw new Error(dockerError); - }); - }); - - it('should throw with a descriptive error message including the docker error message', async () => { - await expect( - containerTaskApi.runContainer({ - imageName, - args, - }), - ).rejects.toThrow(new RegExp(`.+: ${dockerError}`)); - }); - }); - - it('should pass through the log stream to the docker client', async () => { - const logStream = new PassThrough(); - await containerTaskApi.runContainer({ - imageName, - args, - logStream, - }); - - expect(mockDocker.run).toHaveBeenCalledWith( - imageName, - args, - logStream, - expect.objectContaining({ - HostConfig: { - AutoRemove: true, - Binds: [], - }, - Volumes: {}, - }), - ); - }); -}); diff --git a/packages/backend-common/src/deprecated/util/DockerContainerRunner.ts b/packages/backend-common/src/deprecated/util/DockerContainerRunner.ts deleted file mode 100644 index ea576e4a3a..0000000000 --- a/packages/backend-common/src/deprecated/util/DockerContainerRunner.ts +++ /dev/null @@ -1,132 +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 Docker from 'dockerode'; -import fs from 'fs-extra'; -import { ForwardedError } from '@backstage/errors'; -import { PassThrough } from 'stream'; -import { ContainerRunner, RunContainerOptions } from './ContainerRunner'; - -export type UserOptions = { - User?: string; -}; - -/** - * A {@link ContainerRunner} for Docker containers. - * - * @public - * @deprecated This class is deprecated and will be removed in a future release. - */ -export class DockerContainerRunner implements ContainerRunner { - private readonly dockerClient: Docker; - - constructor(options: { dockerClient: Docker }) { - this.dockerClient = options.dockerClient; - } - - async runContainer(options: RunContainerOptions) { - const { - imageName, - command, - args, - logStream = new PassThrough(), - mountDirs = {}, - workingDir, - envVars = {}, - pullImage = true, - defaultUser = false, - pullOptions = {}, - } = options; - - // Show a better error message when Docker is unavailable. - try { - await this.dockerClient.ping(); - } catch (e) { - throw new ForwardedError( - 'This operation requires Docker. Docker does not appear to be available. Docker.ping() failed with', - e, - ); - } - - if (pullImage) { - await new Promise((resolve, reject) => { - this.dockerClient.pull(imageName, pullOptions, (err, stream) => { - if (err) return reject(err); - stream.pipe(logStream, { end: false }); - stream.on('end', () => resolve()); - stream.on('error', (error: Error) => reject(error)); - return undefined; - }); - }); - } - - const userOptions: UserOptions = {}; - if (!defaultUser && process.getuid && process.getgid) { - // Files that are created inside the Docker container will be owned by - // root on the host system on non Mac systems, because of reasons. Mainly the fact that - // volume sharing is done using NFS on Mac and actual mounts in Linux world. - // So we set the user in the container as the same user and group id as the host. - // On Windows we don't have process.getuid nor process.getgid - userOptions.User = `${process.getuid()}:${process.getgid()}`; - } - - // Initialize volumes to mount based on mountDirs map - const Volumes: { [T: string]: object } = {}; - for (const containerDir of Object.values(mountDirs)) { - Volumes[containerDir] = {}; - } - - // Create bind volumes - const Binds: string[] = []; - for (const [hostDir, containerDir] of Object.entries(mountDirs)) { - // Need to use realpath here as Docker mounting does not like - // symlinks for binding volumes - const realHostDir = await fs.realpath(hostDir); - Binds.push(`${realHostDir}:${containerDir}`); - } - - // Create docker environment variables array - const Env = []; - for (const [key, value] of Object.entries(envVars)) { - Env.push(`${key}=${value}`); - } - - const [{ Error: error, StatusCode: statusCode }] = - await this.dockerClient.run(imageName, args, logStream, { - Volumes, - HostConfig: { - AutoRemove: true, - Binds, - }, - ...(workingDir ? { WorkingDir: workingDir } : {}), - Entrypoint: command, - Env, - ...userOptions, - } as Docker.ContainerCreateOptions); - - if (error) { - throw new Error( - `Docker failed to run with the following error message: ${error}`, - ); - } - - if (statusCode !== 0) { - throw new Error( - `Docker container returned a non-zero exit code (${statusCode})`, - ); - } - } -} diff --git a/packages/backend-common/src/deprecated/util/KubernetesContainerRunner.test.ts b/packages/backend-common/src/deprecated/util/KubernetesContainerRunner.test.ts deleted file mode 100644 index 706b78c4ae..0000000000 --- a/packages/backend-common/src/deprecated/util/KubernetesContainerRunner.test.ts +++ /dev/null @@ -1,310 +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 { - CoreV1Api, - KubeConfig, - RbacAuthorizationV1Api, -} from '@kubernetes/client-node'; -import { - KubernetesContainerRunner, - KubernetesContainerRunnerOptions, -} from './KubernetesContainerRunner'; -import { RunContainerOptions } from './ContainerRunner'; -import { PassThrough } from 'stream'; - -// This ensures E2E tests that require a Kubernetes cluster are only run -// where KUBERNETES_TESTS environment variable is true -const describeIfKubernetes = Boolean(process.env.KUBERNETES_TESTS) - ? describe - : describe.skip; - -jest.setTimeout(10 * 1000); - -describeIfKubernetes('KubernetesContainerRunner', () => { - const kubeConfig = new KubeConfig(); - kubeConfig.loadFromDefault(); - const name = 'kube-runner'; - - it('should throw error when no namespace is configured', () => { - const testConfig = new KubeConfig(); - testConfig.loadFromDefault(); - testConfig.addContext({ - name: 'test', - cluster: kubeConfig.getCurrentCluster()!.name, - user: kubeConfig.getCurrentUser()!.name, - }); - testConfig.setCurrentContext('test'); - const test = () => - new KubernetesContainerRunner({ - kubeConfig: testConfig, - name, - }); - expect(test).toThrow( - /Cannot read current namespace from Kubernetes cluster/, - ); - }); - - it('should throw error when mountBase is provided and podTemplate is invalid', () => { - const error = /A Pod template containing the volume .+ is required/; - const options: KubernetesContainerRunnerOptions = { - kubeConfig, - name, - namespace: 'default', - mountBase: { - basePath: '/workdir', - volumeName: 'workdir', - }, - }; - const test = () => { - return new KubernetesContainerRunner(options); - }; - expect(test).toThrow(error); - options.podTemplate = {}; - expect(test).toThrow(error); - options.podTemplate.spec = { containers: [] }; - expect(test).toThrow(error); - options.podTemplate.spec.volumes = []; - expect(test).toThrow(error); - }); - - it('should not run the container when the mounts are not subdirectories of the basePath', async () => { - const options: KubernetesContainerRunnerOptions = { - kubeConfig, - name, - namespace: 'default', - mountBase: { - basePath: '/workdir', - volumeName: 'workdir', - }, - podTemplate: { - spec: { - containers: [], - volumes: [ - { - name: 'workdir', - }, - ], - }, - }, - }; - const containerRunner = new KubernetesContainerRunner(options); - const logStream = new PassThrough(); - const runOptions: RunContainerOptions = { - imageName: 'golang:1.17', - args: ['echo', 'hello world'], - logStream, - mountDirs: { - '/notWorkdir/app': '/app', - }, - }; - await expect(containerRunner.runContainer(runOptions)).rejects.toThrow( - `Mounted '/notWorkdir/app' dir should be subdirectories of '${ - options!.mountBase!.basePath - }'`, - ); - }); - - it('should succeed when the container command returns a 0 exit code', async () => { - const options: KubernetesContainerRunnerOptions = { - kubeConfig, - name, - namespace: 'default', - }; - const containerRunner = new KubernetesContainerRunner(options); - const logStream = new PassThrough(); - const chunks: any[] = []; - logStream.on('data', chunk => chunks.push(Buffer.from(chunk))); - const runOptions: RunContainerOptions = { - imageName: 'alpine', - args: ['echo', 'hello world'], - logStream, - }; - await containerRunner.runContainer(runOptions); - const result = Buffer.concat(chunks).toString('utf8'); - expect(result).toBe('hello world\n'); - }); - - it('should fail when container run time exceeds the timeout', async () => { - const options: KubernetesContainerRunnerOptions = { - kubeConfig, - name, - namespace: 'default', - timeoutMs: 5000, - }; - const containerRunner = new KubernetesContainerRunner(options); - const runOptions: RunContainerOptions = { - imageName: 'alpine', - args: ['sleep', '10'], - }; - await expect(containerRunner.runContainer(runOptions)).rejects.toThrow( - `Failed to complete in ${options.timeoutMs} ms`, - ); - }); - - it('should fail when container command returns a non 0 exit code', async () => { - const options: KubernetesContainerRunnerOptions = { - kubeConfig, - name, - namespace: 'default', - }; - const containerRunner = new KubernetesContainerRunner(options); - const runOptions: RunContainerOptions = { - imageName: 'alpine', - args: ['fake'], - }; - await expect(containerRunner.runContainer(runOptions)).rejects.toThrow( - `Container execution failed`, - ); - }); - - it('should fail when job creation fails', async () => { - const options: KubernetesContainerRunnerOptions = { - kubeConfig, - name, - namespace: 'fake', - }; - const containerRunner = new KubernetesContainerRunner(options); - const runOptions: RunContainerOptions = { - imageName: 'golang:1.17', - args: ['echo', 'hello world'], - }; - await expect(containerRunner.runContainer(runOptions)).rejects.toThrow( - 'Kubernetes Job creation failed with the following error message: namespaces "fake" not found', - ); - }); - - it('should not close the original log stream', async () => { - const options: KubernetesContainerRunnerOptions = { - kubeConfig, - name, - namespace: 'default', - }; - const containerRunner = new KubernetesContainerRunner(options); - const logStream = new PassThrough(); - const runOptions: RunContainerOptions = { - imageName: 'alpine', - args: ['echo', 'hello world'], - logStream, - }; - - await containerRunner.runContainer(runOptions); - - expect(logStream.writableEnded).toBe(false); - expect(logStream.destroyed).toBe(false); - }); - - describe('with namespace test', () => { - let api: CoreV1Api; - let authApi: RbacAuthorizationV1Api; - - beforeAll(async () => { - api = kubeConfig.makeApiClient(CoreV1Api); - authApi = kubeConfig.makeApiClient(RbacAuthorizationV1Api); - await api.createNamespace({ - metadata: { - name: 'test', - }, - }); - }); - afterAll(async () => { - await api.deleteNamespace('test'); - }); - - it('should fail when watch fails', async () => { - const testConfig = await givenAServiceAccountThatCannotWatchPods( - api, - authApi, - kubeConfig, - ); - const options: KubernetesContainerRunnerOptions = { - kubeConfig: testConfig, - name, - namespace: 'test', - }; - const containerRunner = new KubernetesContainerRunner(options); - const runOptions: RunContainerOptions = { - imageName: 'golang:1.17', - args: ['echo', 'hello world'], - }; - await expect(containerRunner.runContainer(runOptions)).rejects.toThrow( - 'Kubernetes watch request failed with the following error message: Error: Forbidden', - ); - }); - }); -}); - -async function givenAServiceAccountThatCannotWatchPods( - api: CoreV1Api, - authApi: RbacAuthorizationV1Api, - kubeConfig: KubeConfig, -) { - await Promise.all([ - api.createNamespacedServiceAccount('test', { - metadata: { - name: 'test', - }, - }), - authApi.createNamespacedRole('test', { - metadata: { - name: 'test', - }, - rules: [ - { - apiGroups: ['batch'], - verbs: ['create'], - resources: ['jobs'], - }, - ], - }), - authApi.createNamespacedRoleBinding('test', { - metadata: { - name: 'test', - }, - subjects: [ - { - kind: 'ServiceAccount', - name: 'test', - }, - ], - roleRef: { - apiGroup: 'rbac.authorization.k8s.io', - kind: 'Role', - name: 'test', - }, - }), - ]); - const token = ( - await api.createNamespacedServiceAccountToken('test', 'test', { - spec: { - audiences: [], - }, - }) - ).body.status?.token; - const testConfig = new KubeConfig(); - testConfig.loadFromDefault(); - testConfig.addUser({ - name: 'test', - token, - }); - testConfig.addContext({ - name: 'test', - cluster: kubeConfig.getCurrentCluster()!.name, - user: 'test', - }); - testConfig.setCurrentContext('test'); - return testConfig; -} diff --git a/packages/backend-common/src/deprecated/util/KubernetesContainerRunner.ts b/packages/backend-common/src/deprecated/util/KubernetesContainerRunner.ts deleted file mode 100644 index 0402f70079..0000000000 --- a/packages/backend-common/src/deprecated/util/KubernetesContainerRunner.ts +++ /dev/null @@ -1,386 +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 { PassThrough, Writable } from 'stream'; -import { ContainerRunner, RunContainerOptions } from './ContainerRunner'; -import { - KubeConfig, - BatchV1Api, - V1Job, - V1EnvVar, - Log, - HttpError, - V1Status, - V1VolumeMount, - V1PodTemplateSpec, - V1Pod, - Watch, -} from '@kubernetes/client-node'; -import { v4 as uuid } from 'uuid'; - -/** - * An existing Kubernetes volume that will be used as base for mounts. - * - * Every mount must start with the 'basePath'. - * - * @public - * @deprecated This type is deprecated and will be removed in a future release. - */ -export type KubernetesContainerRunnerMountBase = { - volumeName: string; - basePath: string; -}; - -/** - * Options to create a {@link KubernetesContainerRunner} - * - * Kubernetes Jobs will be created on the provided 'namespace' - * and their names will be prefixed with the provided 'name'. - * - * 'podTemplate' defines a Pod template for the Jobs. It has to include - * a volume definition named as the {@link KubernetesContainerRunnerMountBase} 'volumeName'. - * - * @public - * @deprecated This type is deprecated and will be removed in a future release. - */ -export type KubernetesContainerRunnerOptions = { - kubeConfig: KubeConfig; - name: string; - namespace?: string; - mountBase?: KubernetesContainerRunnerMountBase; - podTemplate?: V1PodTemplateSpec; - timeoutMs?: number; -}; - -/** - * A {@link ContainerRunner} for Kubernetes. - * - * Runs containers leveraging Jobs on a Kubernetes cluster - * - * @public - * @deprecated This class is deprecated and will be removed in a future release. - */ -export class KubernetesContainerRunner implements ContainerRunner { - private readonly kubeConfig: KubeConfig; - private readonly batchV1Api: BatchV1Api; - private readonly log: Log; - private readonly name: string; - private readonly namespace: string; - private readonly mountBase?: KubernetesContainerRunnerMountBase; - private readonly podTemplate?: V1PodTemplateSpec; - private readonly timeoutMs: number; - private readonly containerName = 'executor'; - - private getNamespace(kubeConfig: KubeConfig, namespace?: string): string { - let _namespace = namespace; - if (!_namespace) { - _namespace = kubeConfig.getContextObject( - kubeConfig.currentContext, - )?.namespace; - } - if (!_namespace) { - throw new Error('Cannot read current namespace from Kubernetes cluster'); - } - return _namespace; - } - - private validateMountBase( - mountBase: KubernetesContainerRunnerMountBase, - podTemplate?: V1PodTemplateSpec, - ): KubernetesContainerRunnerMountBase { - if ( - !podTemplate?.spec?.volumes?.filter(v => v.name === mountBase.volumeName) - .length - ) { - throw new Error( - `A Pod template containing the volume ${mountBase.volumeName} is required`, - ); - } - if (!mountBase.basePath.endsWith('/')) { - mountBase.basePath += '/'; - } - return mountBase; - } - - constructor(options: KubernetesContainerRunnerOptions) { - const { kubeConfig, name, namespace, mountBase, podTemplate, timeoutMs } = - options; - this.kubeConfig = kubeConfig; - this.batchV1Api = kubeConfig.makeApiClient(BatchV1Api); - this.log = new Log(kubeConfig); - this.name = name; - this.namespace = this.getNamespace(kubeConfig, namespace); - if (mountBase) { - this.mountBase = this.validateMountBase(mountBase, podTemplate); - } - this.podTemplate = podTemplate; - this.timeoutMs = timeoutMs || 120 * 1000; - } - - async runContainer(options: RunContainerOptions) { - const { - imageName, - command, - args, - logStream, - mountDirs = {}, - workingDir, - envVars = {}, - } = options; - - const containerLogStream = new PassThrough(); - if (logStream) { - containerLogStream.pipe(logStream, { end: false }); - } - - const commandArr = typeof command === 'string' ? [command] : command; - - const volumeMounts: V1VolumeMount[] = []; - for (const [hostDir, containerDir] of Object.entries(mountDirs)) { - if (!this.mountBase) { - throw new Error( - 'A volumeName and a basePath must be configured to bind mount directories', - ); - } - if (!hostDir.startsWith(this.mountBase.basePath)) { - throw new Error( - `Mounted '${hostDir}' dir should be subdirectories of '${this.mountBase.basePath}'`, - ); - } - volumeMounts.push({ - name: this.mountBase.volumeName, - mountPath: containerDir, - subPath: hostDir.slice(this.mountBase.basePath.length), - }); - } - - const env = []; - for (const [key, value] of Object.entries(envVars)) { - env.push({ - name: key, - value: value, - } as V1EnvVar); - } - - const taskId = uuid(); - - // TODO find a way to merge recursively - const mergedPodTemplate: V1PodTemplateSpec = { - metadata: { - ...{ - labels: { - task: taskId, - }, - }, - ...this.podTemplate?.metadata, - }, - spec: { - ...{ - containers: [ - { - name: this.containerName, - image: imageName, - command: commandArr, - args: args, - env: env, - workingDir: workingDir, - volumeMounts: volumeMounts, - }, - ], - restartPolicy: 'Never', - }, - ...this.podTemplate?.spec, - }, - }; - - const jobSpec: V1Job = { - metadata: { - generateName: `${this.name}-`, - }, - spec: { - backoffLimit: 0, - ttlSecondsAfterFinished: 60, - template: mergedPodTemplate, - }, - }; - - await this.runJob(jobSpec, taskId, containerLogStream); - } - - private handleError(err: any, errorCallback: (reason: any) => void) { - if (err.code !== 'ECONNRESET' && err.message !== 'aborted') { - errorCallback( - handleKubernetesError( - 'Kubernetes watch request failed with the following error message:', - err, - ), - ); - } - } - - private watchPod( - taskId: string, - callback: (pod: V1Pod) => void, - errorCallback: (reason: any) => void, - ): Promise<{ abort: () => void }> { - const watch = new Watch(this.kubeConfig); - const labelSelector = `task=${taskId}`; - return watch.watch( - `/api/v1/namespaces/${this.namespace}/pods`, - { - labelSelector, - }, - (_, pod) => { - callback(pod); - }, - err => { - if (err) { - this.handleError(err, errorCallback); - } - }, - ); - } - - private tailLogs( - taskId: string, - logStream: Writable, - ): { promise: Promise; close: () => Promise } { - let log: Promise<{ abort: () => void }>; - let req: Promise<{ abort: () => void }>; - const watchPromise = new Promise((_, reject) => { - req = this.watchPod( - taskId, - pod => { - if ( - log === undefined && - (pod.status?.phase === 'Running' || - pod.status?.phase === 'Succeeded' || - pod.status?.phase === 'Failed') - ) { - log = this.log.log( - this.namespace, - pod.metadata?.name!, - this.containerName, - logStream, - { follow: true }, - ); - } - }, - reject, - ); - }); - const logPromise = new Promise((resolve, _) => { - if (!logStream.writableFinished) { - logStream.on('finish', () => { - resolve(); - }); - } else { - resolve(); - } - }); - const close = async () => { - if (req) { - (await req).abort(); - } - if (log) { - (await log).abort(); - } - }; - return { promise: Promise.race([watchPromise, logPromise]), close }; - } - - private waitPod(taskId: string): { - promise: Promise; - close: () => Promise; - } { - let req: Promise<{ abort: () => void }>; - const promise = new Promise(async (resolve, reject) => { - req = this.watchPod( - taskId, - pod => { - if (pod.status?.phase === 'Succeeded') { - resolve(); - } - if (pod.status?.phase === 'Failed') { - reject(new Error('Container execution failed')); - } - }, - reject, - ); - }); - const close = async () => { - if (req) { - (await req).abort(); - } - }; - return { promise, close }; - } - - private async createJob(jobSpec: V1Job): Promise { - return this.batchV1Api - .createNamespacedJob(this.namespace, jobSpec) - .catch(err => { - throw handleKubernetesError( - 'Kubernetes Job creation failed with the following error message:', - err, - ); - }); - } - - private async runJob( - jobSpec: V1Job, - taskId: string, - logStream: Writable, - ): Promise { - let timeout: NodeJS.Timeout; - const timeoutPromise = new Promise((_, reject) => { - timeout = setTimeout( - reject, - this.timeoutMs, - new Error(`Failed to complete in ${this.timeoutMs} ms`), - ); - }); - - const { promise: waitPromise, close: waitClose } = this.waitPod(taskId); - const { promise: tailPromise, close: tailClose } = this.tailLogs( - taskId, - logStream, - ); - - const taskPromise = Promise.all([ - waitPromise, - tailPromise, - this.createJob(jobSpec), - ]).finally(() => { - clearTimeout(timeout); - }); - - return Promise.race([timeoutPromise, taskPromise]) - .finally(() => { - return waitClose(); - }) - .finally(() => { - return tailClose(); - }); - } -} - -function handleKubernetesError(message: string, err: Error): Error { - if (err instanceof HttpError) { - return new Error(`${message} ${(err.body as V1Status).message}`); - } - return new Error(`${message} ${err}`); -} diff --git a/packages/backend-common/src/deprecated/util/index.ts b/packages/backend-common/src/deprecated/util/index.ts deleted file mode 100644 index 39bade08be..0000000000 --- a/packages/backend-common/src/deprecated/util/index.ts +++ /dev/null @@ -1,27 +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 type { - ContainerRunner, - RunContainerOptions, - PullOptions, -} from './ContainerRunner'; -export { DockerContainerRunner } from './DockerContainerRunner'; -export type { - KubernetesContainerRunnerOptions, - KubernetesContainerRunnerMountBase, -} from './KubernetesContainerRunner'; -export { KubernetesContainerRunner } from './KubernetesContainerRunner'; diff --git a/packages/backend-common/src/index.ts b/packages/backend-common/src/index.ts deleted file mode 100644 index e08bef3048..0000000000 --- a/packages/backend-common/src/index.ts +++ /dev/null @@ -1,27 +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. - */ - -/** - * Common functionality library for Backstage backends - * - * @remarks - * This package is deprecated and will be removed in a near future, so please follow the deprecated instructions for the exports you still use. - * - * @packageDocumentation - */ - -export * from './deprecated'; -export * from './compat'; diff --git a/packages/backend-common/src/testUtils.ts b/packages/backend-common/src/testUtils.ts deleted file mode 100644 index 397d97f20e..0000000000 --- a/packages/backend-common/src/testUtils.ts +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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 { - overridePackagePathResolution as _overridePackagePathResolution, - OverridePackagePathResolutionOptions as _OverridePackagePathResolutionOptions, - PackagePathResolutionOverride as _PackagePathResolutionOverride, -} from '@backstage/backend-plugin-api/testUtils'; - -/** - * @public - * @deprecated This function is deprecated and will be removed in future release, see https://github.com/backstage/backstage/issues/24493. - * Please use the `overridePackagePathResolution` function from the `@backstage/backend-plugin-api/testUtils` package instead. - */ -export const overridePackagePathResolution = _overridePackagePathResolution; - -/** - * @public - * @deprecated This type is deprecated and will be removed in a future release, see https://github.com/backstage/backstage/issues/24493. - * Please use the `OverridePackagePathResolutionOptions` type from the `@backstage/backend-plugin-api/testUtils` package instead. - */ -export type OverridePackagePathResolutionOptions = - _OverridePackagePathResolutionOptions; - -/** - * @public - * @deprecated This type is deprecated and will be removed in a future release, see https://github.com/backstage/backstage/issues/24493. - * Please use the `PackagePathResolutionOverride` type from the `@backstage/backend-plugin-api/testUtils` package instead. - */ -export type PackagePathResolutionOverride = _PackagePathResolutionOverride; diff --git a/packages/backend-defaults/CHANGELOG.md b/packages/backend-defaults/CHANGELOG.md index d9fa0e99f6..05cc779bbf 100644 --- a/packages/backend-defaults/CHANGELOG.md +++ b/packages/backend-defaults/CHANGELOG.md @@ -1,5 +1,209 @@ # @backstage/backend-defaults +## 0.5.1-next.1 + +### Patch Changes + +- 920004b: Updating error message for getProjectId when fetching Gitlab project from its url to be more accurate +- Updated dependencies + - @backstage/integration@1.15.1-next.0 + - @backstage/backend-app-api@1.0.1-next.0 + - @backstage/backend-dev-utils@0.1.5 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.8 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/plugin-permission-node@0.8.4-next.0 + +## 0.5.1-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/backend-app-api@1.0.1-next.0 + - @backstage/plugin-permission-node@0.8.4-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-dev-utils@0.1.5 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.8 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/integration@1.15.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + +## 0.5.0 + +### Minor Changes + +- a4bac3c: **BREAKING**: You can no longer supply a `basePath` option to the host discovery implementation. In the new backend system, the ability to choose this path has been removed anyway at the plugin router level. +- 359fcd7: **BREAKING**: The backwards compatibility with plugins using legacy auth through the token manager service has been removed. This means that instead of falling back to using the old token manager, requests towards plugins that don't support the new auth system will simply fail. Please make sure that all plugins in your deployment are hosted within a backend instance from the new backend system. +- baeef13: **BREAKING** Removed `createLifecycleMiddleware` and `LifecycleMiddlewareOptions` to clean up API surface. These exports have no external usage and do not provide value in its current form. If you were using these exports, please reach out to the maintainers to discuss your use case. +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +- 19ff127: **BREAKING**: The default backend instance no longer provides implementations for the identity and token manager services, which have been removed from `@backstage/backend-plugin-api`. + + If you rely on plugins that still require these services, you can add them to your own backend by re-creating the service reference and factory. + + The following can be used to implement the identity service: + + ```ts + import { + coreServices, + createServiceFactory, + createServiceRef, + } from '@backstage/backend-plugin-api'; + import { + DefaultIdentityClient, + IdentityApi, + } from '@backstage/plugin-auth-node'; + + backend.add( + createServiceFactory({ + service: createServiceRef({ id: 'core.identity' }), + deps: { + discovery: coreServices.discovery, + }, + async factory({ discovery }) { + return DefaultIdentityClient.create({ discovery }); + }, + }), + ); + ``` + + The following can be used to implement the token manager service: + + ```ts + import { ServerTokenManager, TokenManager } from '@backstage/backend-common'; + import { createBackend } from '@backstage/backend-defaults'; + import { + coreServices, + createServiceFactory, + createServiceRef, + } from '@backstage/backend-plugin-api'; + + backend.add( + createServiceFactory({ + service: createServiceRef({ id: 'core.tokenManager' }), + deps: { + config: coreServices.rootConfig, + logger: coreServices.rootLogger, + }, + createRootContext({ config, logger }) { + return ServerTokenManager.fromConfig(config, { + logger, + allowDisabledTokenManager: true, + }); + }, + async factory(_deps, tokenManager) { + return tokenManager; + }, + }), + ); + ``` + +- 055b75b: **BREAKING**: Simplifications and cleanup as part of the Backend System 1.0 work. + + For the `/database` subpath exports: + + - The deprecated `dropDatabase` function has now been removed, without replacement. + - The deprecated `LegacyRootDatabaseService` type has now been removed. + - The return type from `DatabaseManager.forPlugin` is now directly a `DatabaseService`, as arguably expected. + - `DatabaseManager.forPlugin` now requires the `deps` argument, with the logger and lifecycle services. + + For the `/cache` subpath exports: + + - The `PluginCacheManager` type has been removed. You can still import it from `@backstage/backend-common`, but it's deprecated there, and you should move off of that package by migrating fully to the new backend system. + - Accordingly, `CacheManager.forPlugin` immediately returns a `CacheService` instead of a `PluginCacheManager`. The outcome of this is that you no longer need to make the extra `.getClient()` call. The old `CacheManager` with the old behavior still exists on `@backstage/backend-common`, but the above recommendations apply. + +### Patch Changes + +- 213664e: Fixed an issue where the `useRedisSets` configuration for the cache service would have no effect. +- 6ed9264: chore(deps): bump `path-to-regexp` from 6.2.2 to 8.0.0 +- 622360e: Move down the discovery config to be in the root +- 7f779c7: `auth.externalAccess` should be optional in the config schema +- fe6fd8c: Accept `ConfigService` instead of `Config` in constructors/factories +- 82539fe: Updated dependency `archiver` to `^7.0.0`. +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- 5705424: Wrap scheduled tasks from the scheduler core service now in OpenTelemetry spans +- 7a72ec8: Exports the `discoveryFeatureLoader` as a replacement for the deprecated `featureDiscoveryService`. + The `discoveryFeatureLoader` is a new backend system [feature loader](https://backstage.io/docs/backend-system/architecture/feature-loaders/) that discovers backend features from the current `package.json` and its dependencies. + Here is an example using the `discoveryFeatureLoader` loader in a new backend instance: + + ```ts + import { createBackend } from '@backstage/backend-defaults'; + import { discoveryFeatureLoader } from '@backstage/backend-defaults'; + //... + + const backend = createBackend(); + //... + backend.add(discoveryFeatureLoader); + //... + backend.start(); + ``` + +- b2a329d: Properly indent the config schema +- 66dbf0a: Allow the cache service to accept the human duration format for TTL +- 5a8fcb4: Added the option to skip database migrations by setting `skipMigrations: true` in config. This can be done globally in the database config or by plugin id. +- 0b2a402: Updates to the config schema to match reality +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-app-api@1.0.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/cli-node@0.2.8 + - @backstage/plugin-permission-node@0.8.3 + - @backstage/integration@1.15.0 + - @backstage/config-loader@1.9.1 + - @backstage/plugin-events-node@0.4.0 + - @backstage/backend-dev-utils@0.1.5 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + +## 0.5.0-next.2 + +### Minor Changes + +- baeef13: **BREAKING** Removed `createLifecycleMiddleware` and `LifecycleMiddlewareOptions` to clean up API surface. These exports have no external usage and do not provide value in its current form. If you were using these exports, please reach out to the maintainers to discuss your use case. + +### Patch Changes + +- 6ed9264: chore(deps): bump `path-to-regexp` from 6.2.2 to 8.0.0 +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-app-api@1.0.0-next.2 + - @backstage/backend-common@0.25.0-next.2 + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/cli-node@0.2.8-next.0 + - @backstage/integration@1.15.0-next.0 + - @backstage/config-loader@1.9.1-next.0 + - @backstage/plugin-permission-node@0.8.3-next.2 + - @backstage/backend-dev-utils@0.1.5 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.4.0-next.2 + ## 0.5.0-next.1 ### Minor Changes diff --git a/packages/backend-defaults/package.json b/packages/backend-defaults/package.json index 2f157580bb..b3375de9a5 100644 --- a/packages/backend-defaults/package.json +++ b/packages/backend-defaults/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-defaults", - "version": "0.5.0-next.1", + "version": "0.5.1-next.1", "description": "Backend defaults used by Backstage backend apps", "backstage": { "role": "node-library" @@ -120,7 +120,7 @@ "@aws-sdk/credential-providers": "^3.350.0", "@aws-sdk/types": "^3.347.0", "@backstage/backend-app-api": "workspace:^", - "@backstage/backend-common": "workspace:^", + "@backstage/backend-common": "^0.25.0", "@backstage/backend-dev-utils": "workspace:^", "@backstage/backend-plugin-api": "workspace:^", "@backstage/cli-common": "workspace:^", @@ -142,7 +142,7 @@ "@opentelemetry/api": "^1.3.0", "@types/cors": "^2.8.6", "@types/express": "^4.17.6", - "archiver": "^6.0.0", + "archiver": "^7.0.0", "base64-stream": "^1.0.0", "better-sqlite3": "^11.0.0", "compression": "^1.7.4", @@ -169,7 +169,7 @@ "node-fetch": "^2.7.0", "node-forge": "^1.3.1", "p-limit": "^3.1.0", - "path-to-regexp": "^6.2.1", + "path-to-regexp": "^8.0.0", "pg": "^8.11.3", "pg-connection-string": "^2.3.0", "pg-format": "^1.0.4", @@ -190,15 +190,19 @@ "@backstage/backend-plugin-api": "workspace:^", "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", + "@types/archiver": "^6.0.0", + "@types/base64-stream": "^1.0.2", + "@types/concat-stream": "^2.0.0", "@types/http-errors": "^2.0.0", "@types/morgan": "^1.9.0", "@types/node-forge": "^1.3.0", "@types/pg-format": "^1.0.5", "@types/stoppable": "^1.1.0", + "@types/yauzl": "^2.10.0", "aws-sdk-client-mock": "^4.0.0", "http-errors": "^2.0.0", "msw": "^1.0.0", - "supertest": "^6.1.3", + "supertest": "^7.0.0", "wait-for-expect": "^3.0.2" }, "configSchema": "config.d.ts" diff --git a/packages/backend-defaults/api-report-auth.md b/packages/backend-defaults/report-auth.api.md similarity index 100% rename from packages/backend-defaults/api-report-auth.md rename to packages/backend-defaults/report-auth.api.md diff --git a/packages/backend-defaults/api-report-cache.md b/packages/backend-defaults/report-cache.api.md similarity index 100% rename from packages/backend-defaults/api-report-cache.md rename to packages/backend-defaults/report-cache.api.md diff --git a/packages/backend-defaults/api-report-database.md b/packages/backend-defaults/report-database.api.md similarity index 100% rename from packages/backend-defaults/api-report-database.md rename to packages/backend-defaults/report-database.api.md diff --git a/packages/backend-defaults/api-report-discovery.md b/packages/backend-defaults/report-discovery.api.md similarity index 74% rename from packages/backend-defaults/api-report-discovery.md rename to packages/backend-defaults/report-discovery.api.md index d168d33a71..e39d281b4e 100644 --- a/packages/backend-defaults/api-report-discovery.md +++ b/packages/backend-defaults/report-discovery.api.md @@ -23,5 +23,10 @@ export class HostDiscovery implements DiscoveryService { getExternalBaseUrl(pluginId: string): Promise; } +// Warnings were encountered during analysis: +// +// src/entrypoints/discovery/HostDiscovery.d.ts:44:5 - (ae-undocumented) Missing documentation for "getBaseUrl". +// src/entrypoints/discovery/HostDiscovery.d.ts:45:5 - (ae-undocumented) Missing documentation for "getExternalBaseUrl". + // (No @packageDocumentation comment for this package) ``` diff --git a/packages/backend-defaults/api-report-httpAuth.md b/packages/backend-defaults/report-httpAuth.api.md similarity index 100% rename from packages/backend-defaults/api-report-httpAuth.md rename to packages/backend-defaults/report-httpAuth.api.md diff --git a/packages/backend-defaults/api-report-httpRouter.md b/packages/backend-defaults/report-httpRouter.api.md similarity index 52% rename from packages/backend-defaults/api-report-httpRouter.md rename to packages/backend-defaults/report-httpRouter.api.md index dc612377ae..97805bc926 100644 --- a/packages/backend-defaults/api-report-httpRouter.md +++ b/packages/backend-defaults/report-httpRouter.api.md @@ -4,16 +4,8 @@ ```ts import { HttpRouterService } from '@backstage/backend-plugin-api'; -import { HumanDuration } from '@backstage/types'; -import { LifecycleService } from '@backstage/backend-plugin-api'; -import { RequestHandler } from 'express'; import { ServiceFactory } from '@backstage/backend-plugin-api'; -// @public -export function createLifecycleMiddleware( - options: LifecycleMiddlewareOptions, -): RequestHandler; - // @public export const httpRouterServiceFactory: ServiceFactory< HttpRouterService, @@ -21,12 +13,5 @@ export const httpRouterServiceFactory: ServiceFactory< 'singleton' >; -// @public -export interface LifecycleMiddlewareOptions { - // (undocumented) - lifecycle: LifecycleService; - startupRequestPauseTimeout?: HumanDuration; -} - // (No @packageDocumentation comment for this package) ``` diff --git a/packages/backend-defaults/api-report-lifecycle.md b/packages/backend-defaults/report-lifecycle.api.md similarity index 100% rename from packages/backend-defaults/api-report-lifecycle.md rename to packages/backend-defaults/report-lifecycle.api.md diff --git a/packages/backend-defaults/api-report-logger.md b/packages/backend-defaults/report-logger.api.md similarity index 100% rename from packages/backend-defaults/api-report-logger.md rename to packages/backend-defaults/report-logger.api.md diff --git a/packages/backend-defaults/api-report-permissions.md b/packages/backend-defaults/report-permissions.api.md similarity index 100% rename from packages/backend-defaults/api-report-permissions.md rename to packages/backend-defaults/report-permissions.api.md diff --git a/packages/backend-defaults/api-report-rootConfig.md b/packages/backend-defaults/report-rootConfig.api.md similarity index 72% rename from packages/backend-defaults/api-report-rootConfig.md rename to packages/backend-defaults/report-rootConfig.api.md index 2935ad1128..6c65d00a3b 100644 --- a/packages/backend-defaults/api-report-rootConfig.md +++ b/packages/backend-defaults/report-rootConfig.api.md @@ -31,5 +31,11 @@ export const rootConfigServiceFactory: (( ) => ServiceFactory) & ServiceFactory; +// Warnings were encountered during analysis: +// +// src/entrypoints/rootConfig/createConfigSecretEnumerator.d.ts:5:1 - (ae-undocumented) Missing documentation for "createConfigSecretEnumerator". +// src/entrypoints/rootConfig/rootConfigServiceFactory.d.ts:20:5 - (ae-undocumented) Missing documentation for "watch". +// src/entrypoints/rootConfig/rootConfigServiceFactory.d.ts:26:22 - (ae-undocumented) Missing documentation for "rootConfigServiceFactory". + // (No @packageDocumentation comment for this package) ``` diff --git a/packages/backend-defaults/api-report-rootHealth.md b/packages/backend-defaults/report-rootHealth.api.md similarity index 71% rename from packages/backend-defaults/api-report-rootHealth.md rename to packages/backend-defaults/report-rootHealth.api.md index b26de7cfda..fa09590c26 100644 --- a/packages/backend-defaults/api-report-rootHealth.md +++ b/packages/backend-defaults/report-rootHealth.api.md @@ -13,5 +13,9 @@ export const rootHealthServiceFactory: ServiceFactory< 'singleton' >; +// Warnings were encountered during analysis: +// +// src/entrypoints/rootHealth/rootHealthServiceFactory.d.ts:5:22 - (ae-undocumented) Missing documentation for "rootHealthServiceFactory". + // (No @packageDocumentation comment for this package) ``` diff --git a/packages/backend-defaults/api-report-rootHttpRouter.md b/packages/backend-defaults/report-rootHttpRouter.api.md similarity index 61% rename from packages/backend-defaults/api-report-rootHttpRouter.md rename to packages/backend-defaults/report-rootHttpRouter.api.md index 3686f25a12..9a435f5c27 100644 --- a/packages/backend-defaults/api-report-rootHttpRouter.md +++ b/packages/backend-defaults/report-rootHttpRouter.api.md @@ -154,5 +154,28 @@ export const rootHttpRouterServiceFactory: (( ) => ServiceFactory) & ServiceFactory; +// Warnings were encountered during analysis: +// +// src/entrypoints/rootHttpRouter/DefaultRootHttpRouter.d.ts:23:5 - (ae-undocumented) Missing documentation for "create". +// src/entrypoints/rootHttpRouter/DefaultRootHttpRouter.d.ts:25:5 - (ae-undocumented) Missing documentation for "use". +// src/entrypoints/rootHttpRouter/DefaultRootHttpRouter.d.ts:26:5 - (ae-undocumented) Missing documentation for "handler". +// src/entrypoints/rootHttpRouter/createHealthRouter.d.ts:6:1 - (ae-undocumented) Missing documentation for "createHealthRouter". +// src/entrypoints/rootHttpRouter/http/MiddlewareFactory.d.ts:9:5 - (ae-undocumented) Missing documentation for "config". +// src/entrypoints/rootHttpRouter/http/MiddlewareFactory.d.ts:10:5 - (ae-undocumented) Missing documentation for "logger". +// src/entrypoints/rootHttpRouter/http/types.d.ts:9:5 - (ae-undocumented) Missing documentation for "start". +// src/entrypoints/rootHttpRouter/http/types.d.ts:10:5 - (ae-undocumented) Missing documentation for "stop". +// src/entrypoints/rootHttpRouter/http/types.d.ts:11:5 - (ae-undocumented) Missing documentation for "port". +// src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.d.ts:9:1 - (ae-undocumented) Missing documentation for "RootHttpRouterConfigureContext". +// src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.d.ts:10:5 - (ae-undocumented) Missing documentation for "app". +// src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.d.ts:11:5 - (ae-undocumented) Missing documentation for "server". +// src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.d.ts:12:5 - (ae-undocumented) Missing documentation for "middleware". +// src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.d.ts:13:5 - (ae-undocumented) Missing documentation for "routes". +// src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.d.ts:14:5 - (ae-undocumented) Missing documentation for "config". +// src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.d.ts:15:5 - (ae-undocumented) Missing documentation for "logger". +// src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.d.ts:16:5 - (ae-undocumented) Missing documentation for "lifecycle". +// src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.d.ts:17:5 - (ae-undocumented) Missing documentation for "healthRouter". +// src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.d.ts:18:5 - (ae-undocumented) Missing documentation for "applyDefaults". +// src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.d.ts:38:22 - (ae-undocumented) Missing documentation for "rootHttpRouterServiceFactory". + // (No @packageDocumentation comment for this package) ``` diff --git a/packages/backend-defaults/api-report-rootLifecycle.md b/packages/backend-defaults/report-rootLifecycle.api.md similarity index 100% rename from packages/backend-defaults/api-report-rootLifecycle.md rename to packages/backend-defaults/report-rootLifecycle.api.md diff --git a/packages/backend-defaults/api-report-rootLogger.md b/packages/backend-defaults/report-rootLogger.api.md similarity index 55% rename from packages/backend-defaults/api-report-rootLogger.md rename to packages/backend-defaults/report-rootLogger.api.md index b353039c03..59b6242095 100644 --- a/packages/backend-defaults/api-report-rootLogger.md +++ b/packages/backend-defaults/report-rootLogger.api.md @@ -51,5 +51,19 @@ export interface WinstonLoggerOptions { transports?: transport[]; } +// Warnings were encountered during analysis: +// +// src/entrypoints/rootLogger/WinstonLogger.d.ts:8:1 - (ae-undocumented) Missing documentation for "WinstonLoggerOptions". +// src/entrypoints/rootLogger/WinstonLogger.d.ts:9:5 - (ae-undocumented) Missing documentation for "meta". +// src/entrypoints/rootLogger/WinstonLogger.d.ts:10:5 - (ae-undocumented) Missing documentation for "level". +// src/entrypoints/rootLogger/WinstonLogger.d.ts:11:5 - (ae-undocumented) Missing documentation for "format". +// src/entrypoints/rootLogger/WinstonLogger.d.ts:12:5 - (ae-undocumented) Missing documentation for "transports". +// src/entrypoints/rootLogger/WinstonLogger.d.ts:37:5 - (ae-undocumented) Missing documentation for "error". +// src/entrypoints/rootLogger/WinstonLogger.d.ts:38:5 - (ae-undocumented) Missing documentation for "warn". +// src/entrypoints/rootLogger/WinstonLogger.d.ts:39:5 - (ae-undocumented) Missing documentation for "info". +// src/entrypoints/rootLogger/WinstonLogger.d.ts:40:5 - (ae-undocumented) Missing documentation for "debug". +// src/entrypoints/rootLogger/WinstonLogger.d.ts:41:5 - (ae-undocumented) Missing documentation for "child". +// src/entrypoints/rootLogger/WinstonLogger.d.ts:42:5 - (ae-undocumented) Missing documentation for "addRedactions". + // (No @packageDocumentation comment for this package) ``` diff --git a/packages/backend-defaults/api-report-scheduler.md b/packages/backend-defaults/report-scheduler.api.md similarity index 81% rename from packages/backend-defaults/api-report-scheduler.md rename to packages/backend-defaults/report-scheduler.api.md index 10c0c0a943..351873ad31 100644 --- a/packages/backend-defaults/api-report-scheduler.md +++ b/packages/backend-defaults/report-scheduler.api.md @@ -24,5 +24,9 @@ export const schedulerServiceFactory: ServiceFactory< 'singleton' >; +// Warnings were encountered during analysis: +// +// src/entrypoints/scheduler/lib/DefaultSchedulerService.d.ts:8:5 - (ae-undocumented) Missing documentation for "create". + // (No @packageDocumentation comment for this package) ``` diff --git a/packages/backend-defaults/api-report-urlReader.md b/packages/backend-defaults/report-urlReader.api.md similarity index 59% rename from packages/backend-defaults/api-report-urlReader.md rename to packages/backend-defaults/report-urlReader.api.md index f8b8db2954..77f0d5ccbd 100644 --- a/packages/backend-defaults/api-report-urlReader.md +++ b/packages/backend-defaults/report-urlReader.api.md @@ -447,5 +447,78 @@ export type UrlReadersOptions = { factories?: ReaderFactory[]; }; +// Warnings were encountered during analysis: +// +// src/entrypoints/urlReader/lib/AwsS3UrlReader.d.ts:28:5 - (ae-undocumented) Missing documentation for "factory". +// src/entrypoints/urlReader/lib/AwsS3UrlReader.d.ts:40:5 - (ae-undocumented) Missing documentation for "read". +// src/entrypoints/urlReader/lib/AwsS3UrlReader.d.ts:41:5 - (ae-undocumented) Missing documentation for "readUrl". +// src/entrypoints/urlReader/lib/AwsS3UrlReader.d.ts:42:5 - (ae-undocumented) Missing documentation for "readTree". +// src/entrypoints/urlReader/lib/AwsS3UrlReader.d.ts:43:5 - (ae-undocumented) Missing documentation for "search". +// src/entrypoints/urlReader/lib/AwsS3UrlReader.d.ts:44:5 - (ae-undocumented) Missing documentation for "toString". +// src/entrypoints/urlReader/lib/AzureUrlReader.d.ts:14:5 - (ae-undocumented) Missing documentation for "factory". +// src/entrypoints/urlReader/lib/AzureUrlReader.d.ts:19:5 - (ae-undocumented) Missing documentation for "read". +// src/entrypoints/urlReader/lib/AzureUrlReader.d.ts:20:5 - (ae-undocumented) Missing documentation for "readUrl". +// src/entrypoints/urlReader/lib/AzureUrlReader.d.ts:21:5 - (ae-undocumented) Missing documentation for "readTree". +// src/entrypoints/urlReader/lib/AzureUrlReader.d.ts:22:5 - (ae-undocumented) Missing documentation for "search". +// src/entrypoints/urlReader/lib/AzureUrlReader.d.ts:23:5 - (ae-undocumented) Missing documentation for "toString". +// src/entrypoints/urlReader/lib/BitbucketCloudUrlReader.d.ts:14:5 - (ae-undocumented) Missing documentation for "factory". +// src/entrypoints/urlReader/lib/BitbucketCloudUrlReader.d.ts:18:5 - (ae-undocumented) Missing documentation for "read". +// src/entrypoints/urlReader/lib/BitbucketCloudUrlReader.d.ts:19:5 - (ae-undocumented) Missing documentation for "readUrl". +// src/entrypoints/urlReader/lib/BitbucketCloudUrlReader.d.ts:20:5 - (ae-undocumented) Missing documentation for "readTree". +// src/entrypoints/urlReader/lib/BitbucketCloudUrlReader.d.ts:21:5 - (ae-undocumented) Missing documentation for "search". +// src/entrypoints/urlReader/lib/BitbucketCloudUrlReader.d.ts:22:5 - (ae-undocumented) Missing documentation for "toString". +// src/entrypoints/urlReader/lib/BitbucketServerUrlReader.d.ts:14:5 - (ae-undocumented) Missing documentation for "factory". +// src/entrypoints/urlReader/lib/BitbucketServerUrlReader.d.ts:18:5 - (ae-undocumented) Missing documentation for "read". +// src/entrypoints/urlReader/lib/BitbucketServerUrlReader.d.ts:19:5 - (ae-undocumented) Missing documentation for "readUrl". +// src/entrypoints/urlReader/lib/BitbucketServerUrlReader.d.ts:20:5 - (ae-undocumented) Missing documentation for "readTree". +// src/entrypoints/urlReader/lib/BitbucketServerUrlReader.d.ts:21:5 - (ae-undocumented) Missing documentation for "search". +// src/entrypoints/urlReader/lib/BitbucketServerUrlReader.d.ts:22:5 - (ae-undocumented) Missing documentation for "toString". +// src/entrypoints/urlReader/lib/BitbucketUrlReader.d.ts:17:5 - (ae-undocumented) Missing documentation for "factory". +// src/entrypoints/urlReader/lib/BitbucketUrlReader.d.ts:21:5 - (ae-undocumented) Missing documentation for "read". +// src/entrypoints/urlReader/lib/BitbucketUrlReader.d.ts:22:5 - (ae-undocumented) Missing documentation for "readUrl". +// src/entrypoints/urlReader/lib/BitbucketUrlReader.d.ts:23:5 - (ae-undocumented) Missing documentation for "readTree". +// src/entrypoints/urlReader/lib/BitbucketUrlReader.d.ts:24:5 - (ae-undocumented) Missing documentation for "search". +// src/entrypoints/urlReader/lib/BitbucketUrlReader.d.ts:25:5 - (ae-undocumented) Missing documentation for "toString". +// src/entrypoints/urlReader/lib/FetchUrlReader.d.ts:24:5 - (ae-undocumented) Missing documentation for "read". +// src/entrypoints/urlReader/lib/FetchUrlReader.d.ts:25:5 - (ae-undocumented) Missing documentation for "readUrl". +// src/entrypoints/urlReader/lib/FetchUrlReader.d.ts:26:5 - (ae-undocumented) Missing documentation for "readTree". +// src/entrypoints/urlReader/lib/FetchUrlReader.d.ts:27:5 - (ae-undocumented) Missing documentation for "search". +// src/entrypoints/urlReader/lib/FetchUrlReader.d.ts:28:5 - (ae-undocumented) Missing documentation for "toString". +// src/entrypoints/urlReader/lib/GerritUrlReader.d.ts:29:5 - (ae-undocumented) Missing documentation for "factory". +// src/entrypoints/urlReader/lib/GerritUrlReader.d.ts:33:5 - (ae-undocumented) Missing documentation for "read". +// src/entrypoints/urlReader/lib/GerritUrlReader.d.ts:34:5 - (ae-undocumented) Missing documentation for "readUrl". +// src/entrypoints/urlReader/lib/GerritUrlReader.d.ts:35:5 - (ae-undocumented) Missing documentation for "readTree". +// src/entrypoints/urlReader/lib/GerritUrlReader.d.ts:36:5 - (ae-undocumented) Missing documentation for "search". +// src/entrypoints/urlReader/lib/GerritUrlReader.d.ts:37:5 - (ae-undocumented) Missing documentation for "toString". +// src/entrypoints/urlReader/lib/GiteaUrlReader.d.ts:14:5 - (ae-undocumented) Missing documentation for "factory". +// src/entrypoints/urlReader/lib/GiteaUrlReader.d.ts:18:5 - (ae-undocumented) Missing documentation for "read". +// src/entrypoints/urlReader/lib/GiteaUrlReader.d.ts:19:5 - (ae-undocumented) Missing documentation for "readUrl". +// src/entrypoints/urlReader/lib/GiteaUrlReader.d.ts:20:5 - (ae-undocumented) Missing documentation for "readTree". +// src/entrypoints/urlReader/lib/GiteaUrlReader.d.ts:21:5 - (ae-undocumented) Missing documentation for "search". +// src/entrypoints/urlReader/lib/GiteaUrlReader.d.ts:22:5 - (ae-undocumented) Missing documentation for "toString". +// src/entrypoints/urlReader/lib/GithubUrlReader.d.ts:20:5 - (ae-undocumented) Missing documentation for "factory". +// src/entrypoints/urlReader/lib/GithubUrlReader.d.ts:25:5 - (ae-undocumented) Missing documentation for "read". +// src/entrypoints/urlReader/lib/GithubUrlReader.d.ts:27:5 - (ae-undocumented) Missing documentation for "readUrl". +// src/entrypoints/urlReader/lib/GithubUrlReader.d.ts:28:5 - (ae-undocumented) Missing documentation for "readTree". +// src/entrypoints/urlReader/lib/GithubUrlReader.d.ts:29:5 - (ae-undocumented) Missing documentation for "search". +// src/entrypoints/urlReader/lib/GithubUrlReader.d.ts:30:5 - (ae-undocumented) Missing documentation for "toString". +// src/entrypoints/urlReader/lib/GitlabUrlReader.d.ts:14:5 - (ae-undocumented) Missing documentation for "factory". +// src/entrypoints/urlReader/lib/GitlabUrlReader.d.ts:18:5 - (ae-undocumented) Missing documentation for "read". +// src/entrypoints/urlReader/lib/GitlabUrlReader.d.ts:19:5 - (ae-undocumented) Missing documentation for "readUrl". +// src/entrypoints/urlReader/lib/GitlabUrlReader.d.ts:20:5 - (ae-undocumented) Missing documentation for "readTree". +// src/entrypoints/urlReader/lib/GitlabUrlReader.d.ts:21:5 - (ae-undocumented) Missing documentation for "search". +// src/entrypoints/urlReader/lib/GitlabUrlReader.d.ts:31:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen +// src/entrypoints/urlReader/lib/GitlabUrlReader.d.ts:32:8 - (tsdoc-undefined-tag) The TSDoc tag "@private" is not defined in this configuration +// src/entrypoints/urlReader/lib/GitlabUrlReader.d.ts:35:5 - (ae-undocumented) Missing documentation for "toString". +// src/entrypoints/urlReader/lib/HarnessUrlReader.d.ts:15:5 - (ae-undocumented) Missing documentation for "factory". +// src/entrypoints/urlReader/lib/HarnessUrlReader.d.ts:19:5 - (ae-undocumented) Missing documentation for "read". +// src/entrypoints/urlReader/lib/HarnessUrlReader.d.ts:20:5 - (ae-undocumented) Missing documentation for "readUrl". +// src/entrypoints/urlReader/lib/HarnessUrlReader.d.ts:21:5 - (ae-undocumented) Missing documentation for "readTree". +// src/entrypoints/urlReader/lib/HarnessUrlReader.d.ts:22:5 - (ae-undocumented) Missing documentation for "search". +// src/entrypoints/urlReader/lib/HarnessUrlReader.d.ts:23:5 - (ae-undocumented) Missing documentation for "toString". +// src/entrypoints/urlReader/lib/types.d.ts:74:5 - (ae-undocumented) Missing documentation for "fromTarArchive". +// src/entrypoints/urlReader/lib/types.d.ts:81:5 - (ae-undocumented) Missing documentation for "fromZipArchive". +// src/entrypoints/urlReader/lib/types.d.ts:82:5 - (ae-undocumented) Missing documentation for "fromReadableArray". + // (No @packageDocumentation comment for this package) ``` diff --git a/packages/backend-defaults/api-report-userInfo.md b/packages/backend-defaults/report-userInfo.api.md similarity index 100% rename from packages/backend-defaults/api-report-userInfo.md rename to packages/backend-defaults/report-userInfo.api.md diff --git a/packages/backend-defaults/api-report.md b/packages/backend-defaults/report.api.md similarity index 74% rename from packages/backend-defaults/api-report.md rename to packages/backend-defaults/report.api.md index def38beda7..9878336d27 100644 --- a/packages/backend-defaults/api-report.md +++ b/packages/backend-defaults/report.api.md @@ -11,4 +11,8 @@ export function createBackend(): Backend; // @public export const discoveryFeatureLoader: BackendFeature; + +// Warnings were encountered during analysis: +// +// src/CreateBackend.d.ts:6:1 - (ae-undocumented) Missing documentation for "createBackend". ``` diff --git a/packages/backend-defaults/src/entrypoints/cache/CacheManager.ts b/packages/backend-defaults/src/entrypoints/cache/CacheManager.ts index 41fe595123..a54959f155 100644 --- a/packages/backend-defaults/src/entrypoints/cache/CacheManager.ts +++ b/packages/backend-defaults/src/entrypoints/cache/CacheManager.ts @@ -147,7 +147,9 @@ export class CacheManager { let store: typeof KeyvRedis | undefined; return (pluginId, defaultTtl) => { if (!store) { - store = new KeyvRedis(this.connection); + store = new KeyvRedis(this.connection, { + useRedisSets: this.useRedisSets, + }); // Always provide an error handler to avoid stopping the process store.on('error', (err: Error) => { this.logger?.error('Failed to create redis cache client', err); diff --git a/packages/backend-defaults/src/entrypoints/httpRouter/createCredentialsBarrier.ts b/packages/backend-defaults/src/entrypoints/httpRouter/createCredentialsBarrier.ts index a69fa5a804..dd6c95ca82 100644 --- a/packages/backend-defaults/src/entrypoints/httpRouter/createCredentialsBarrier.ts +++ b/packages/backend-defaults/src/entrypoints/httpRouter/createCredentialsBarrier.ts @@ -27,7 +27,7 @@ export function createPathPolicyPredicate(policyPath: string) { return () => true; } - const pathRegex = pathToRegexp(policyPath, undefined, { + const { regexp: pathRegex } = pathToRegexp(policyPath, { end: false, }); diff --git a/packages/backend-defaults/src/entrypoints/httpRouter/createLifecycleMiddleware.ts b/packages/backend-defaults/src/entrypoints/httpRouter/createLifecycleMiddleware.ts index 3f8ee3ea69..18ff2f0840 100644 --- a/packages/backend-defaults/src/entrypoints/httpRouter/createLifecycleMiddleware.ts +++ b/packages/backend-defaults/src/entrypoints/httpRouter/createLifecycleMiddleware.ts @@ -23,7 +23,7 @@ export const DEFAULT_TIMEOUT = { seconds: 5 }; /** * Options for {@link createLifecycleMiddleware}. - * @public + * @internal */ export interface LifecycleMiddlewareOptions { lifecycle: LifecycleService; @@ -47,7 +47,7 @@ export interface LifecycleMiddlewareOptions { * If the service is shutting down, all requests will be rejected with a * {@link @backstage/errors#ServiceUnavailableError}. * - * @public + * @internal */ export function createLifecycleMiddleware( options: LifecycleMiddlewareOptions, diff --git a/packages/backend-defaults/src/entrypoints/httpRouter/index.ts b/packages/backend-defaults/src/entrypoints/httpRouter/index.ts index bc12480ae8..15bced5ef3 100644 --- a/packages/backend-defaults/src/entrypoints/httpRouter/index.ts +++ b/packages/backend-defaults/src/entrypoints/httpRouter/index.ts @@ -15,5 +15,3 @@ */ export { httpRouterServiceFactory } from './httpRouterServiceFactory'; -export { createLifecycleMiddleware } from './createLifecycleMiddleware'; -export type { LifecycleMiddlewareOptions } from './createLifecycleMiddleware'; diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader.test.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader.test.ts index dd6a0970d2..d0607767c2 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader.test.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader.test.ts @@ -697,7 +697,9 @@ describe('GitlabUrlReader', () => { (gitlabProcessor as any).getGitlabFetchUrl( 'https://gitlab.com/some/random/endpoint', ), - ).rejects.toThrow('Please provide full path to yaml file from GitLab'); + ).rejects.toThrow( + 'Failed converting /some/random/endpoint to a project id. Url path must include /blob/.', + ); }); }); diff --git a/packages/backend-dev-utils/api-report.md b/packages/backend-dev-utils/report.api.md similarity index 100% rename from packages/backend-dev-utils/api-report.md rename to packages/backend-dev-utils/report.api.md diff --git a/packages/backend-dynamic-feature-service/CHANGELOG.md b/packages/backend-dynamic-feature-service/CHANGELOG.md index e76ed0b504..ee2124a976 100644 --- a/packages/backend-dynamic-feature-service/CHANGELOG.md +++ b/packages/backend-dynamic-feature-service/CHANGELOG.md @@ -1,5 +1,150 @@ # @backstage/backend-dynamic-feature-service +## 0.4.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.26.2-next.1 + - @backstage/backend-defaults@0.5.1-next.1 + - @backstage/backend-app-api@1.0.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.8 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-app-node@0.1.26-next.0 + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/plugin-events-backend@0.3.13-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-permission-node@0.8.4-next.0 + - @backstage/plugin-scaffolder-node@0.5.0-next.1 + - @backstage/plugin-search-backend-node@1.3.3-next.1 + - @backstage/plugin-search-common@1.2.14 + +## 0.4.1-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- 2f88f88: Updated backend installation instructions. +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.5.0-next.0 + - @backstage/plugin-search-backend-node@1.3.3-next.0 + - @backstage/backend-defaults@0.5.1-next.0 + - @backstage/backend-app-api@1.0.1-next.0 + - @backstage/plugin-catalog-backend@1.26.1-next.0 + - @backstage/plugin-permission-node@0.8.4-next.0 + - @backstage/plugin-events-backend@0.3.13-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.8 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-app-node@0.1.26-next.0 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-common@1.2.14 + +## 0.4.0 + +### Minor Changes + +- 9080f57: **BREAKING**: `dynamicPluginsServiceFactory` is no longer callable as a function. If you need to provide options to make a custom factory, use `dynamicPluginsSchemasServiceFactoryWithOptions` instead. + +### Patch Changes + +- cd38da8: Deprecate the `dynamicPluginsServiceRef`, `dynamicPluginsServiceFactory` and `dynamicPluginsServiceFactoryWithOptions` in favor of using the `dynamicPluginsFeatureDiscoveryLoader` to discover dynamic features in a new backend system. + + See usage examples below: + + Example using the `dynamicPluginsFeatureDiscoveryLoader` loader in a backend instance: + + ```ts + import { createBackend } from '@backstage/backend-defaults'; + import { dynamicPluginsFeatureDiscoveryLoader } from '@backstage/backend-dynamic-feature-service'; + //... + + const backend = createBackend(); + backend.add(dynamicPluginsFeatureDiscoveryLoader); + //... + backend.start(); + ``` + + Passing options to the `dynamicPluginsFeatureDiscoveryLoader` loader in a backend instance: + + ```ts + import { createBackend } from '@backstage/backend-defaults'; + import { dynamicPluginsFeatureDiscoveryLoader } from '@backstage/backend-dynamic-feature-service'; + import { myCustomModuleLoader } from './myCustomModuleLoader'; + //... + + const backend = createBackend(); + backend.add( + dynamicPluginsFeatureDiscoveryLoader({ + moduleLoader: myCustomModuleLoader, + }), + ); + //... + backend.start(); + ``` + +- e27f889: Relax type check for a plugin's default export to also accept a BackendFeature defined as a function instead of an object +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-defaults@0.5.0 + - @backstage/backend-common@0.25.0 + - @backstage/backend-app-api@1.0.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/plugin-catalog-backend@1.26.0 + - @backstage/plugin-app-node@0.1.25 + - @backstage/cli-node@0.2.8 + - @backstage/plugin-permission-node@0.8.3 + - @backstage/plugin-events-backend@0.3.12 + - @backstage/config-loader@1.9.1 + - @backstage/plugin-events-node@0.4.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-scaffolder-node@0.4.11 + - @backstage/plugin-search-backend-node@1.3.2 + - @backstage/plugin-search-common@1.2.14 + +## 0.4.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-app-api@1.0.0-next.2 + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-defaults@0.5.0-next.2 + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/cli-node@0.2.8-next.0 + - @backstage/plugin-catalog-backend@1.26.0-next.2 + - @backstage/config-loader@1.9.1-next.0 + - @backstage/plugin-events-backend@0.3.12-next.2 + - @backstage/plugin-permission-node@0.8.3-next.2 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-app-node@0.1.25-next.2 + - @backstage/plugin-events-node@0.4.0-next.2 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-scaffolder-node@0.4.11-next.2 + - @backstage/plugin-search-backend-node@1.3.2-next.2 + - @backstage/plugin-search-common@1.2.14 + ## 0.4.0-next.1 ### Patch Changes diff --git a/packages/backend-dynamic-feature-service/README.md b/packages/backend-dynamic-feature-service/README.md index a2f29b3d8f..33033cf884 100644 --- a/packages/backend-dynamic-feature-service/README.md +++ b/packages/backend-dynamic-feature-service/README.md @@ -15,8 +15,8 @@ In the `backend` application, it can be enabled by adding the `backend-dynamic-f ```ts const backend = createBackend(); + -+ backend.add(dynamicPluginsFeatureDiscoveryServiceFactory()) // overridden version of the FeatureDiscoveryService which provides features loaded by dynamic plugins -+ backend.add(dynamicPluginsServiceFactory()) ++ backend.add(dynamicPluginsFeatureDiscoveryServiceFactory) // overridden version of the FeatureDiscoveryService which provides features loaded by dynamic plugins ++ backend.add(dynamicPluginsServiceFactory) + ``` diff --git a/packages/backend-dynamic-feature-service/package.json b/packages/backend-dynamic-feature-service/package.json index 451a373650..b1f6cf79e7 100644 --- a/packages/backend-dynamic-feature-service/package.json +++ b/packages/backend-dynamic-feature-service/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-dynamic-feature-service", - "version": "0.4.0-next.1", + "version": "0.4.2-next.1", "description": "Backstage dynamic feature service", "backstage": { "role": "node-library" @@ -46,7 +46,7 @@ }, "dependencies": { "@backstage/backend-app-api": "workspace:^", - "@backstage/backend-common": "workspace:^", + "@backstage/backend-common": "^0.25.0", "@backstage/backend-defaults": "workspace:^", "@backstage/backend-plugin-api": "workspace:^", "@backstage/cli-common": "workspace:^", diff --git a/packages/backend-dynamic-feature-service/api-report.md b/packages/backend-dynamic-feature-service/report.api.md similarity index 56% rename from packages/backend-dynamic-feature-service/api-report.md rename to packages/backend-dynamic-feature-service/report.api.md index f6972da50b..9170fedf43 100644 --- a/packages/backend-dynamic-feature-service/api-report.md +++ b/packages/backend-dynamic-feature-service/report.api.md @@ -276,5 +276,71 @@ export interface ScannedPluginPackage { manifest: ScannedPluginManifest; } +// Warnings were encountered during analysis: +// +// src/loader/types.d.ts:4:1 - (ae-undocumented) Missing documentation for "ModuleLoader". +// src/loader/types.d.ts:5:5 - (ae-undocumented) Missing documentation for "bootstrap". +// src/loader/types.d.ts:6:5 - (ae-undocumented) Missing documentation for "load". +// src/manager/plugin-manager.d.ts:10:1 - (ae-undocumented) Missing documentation for "DynamicPluginManagerOptions". +// src/manager/plugin-manager.d.ts:11:5 - (ae-undocumented) Missing documentation for "config". +// src/manager/plugin-manager.d.ts:12:5 - (ae-undocumented) Missing documentation for "logger". +// src/manager/plugin-manager.d.ts:13:5 - (ae-undocumented) Missing documentation for "preferAlpha". +// src/manager/plugin-manager.d.ts:14:5 - (ae-undocumented) Missing documentation for "moduleLoader". +// src/manager/plugin-manager.d.ts:19:1 - (ae-undocumented) Missing documentation for "DynamicPluginManager". +// src/manager/plugin-manager.d.ts:23:5 - (ae-undocumented) Missing documentation for "create". +// src/manager/plugin-manager.d.ts:27:5 - (ae-undocumented) Missing documentation for "availablePackages". +// src/manager/plugin-manager.d.ts:28:5 - (ae-undocumented) Missing documentation for "addBackendPlugin". +// src/manager/plugin-manager.d.ts:31:5 - (ae-undocumented) Missing documentation for "backendPlugins". +// src/manager/plugin-manager.d.ts:32:5 - (ae-undocumented) Missing documentation for "frontendPlugins". +// src/manager/plugin-manager.d.ts:33:5 - (ae-undocumented) Missing documentation for "plugins". +// src/manager/plugin-manager.d.ts:39:22 - (ae-undocumented) Missing documentation for "dynamicPluginsServiceRef". +// src/manager/plugin-manager.d.ts:43:1 - (ae-undocumented) Missing documentation for "DynamicPluginsFactoryOptions". +// src/manager/plugin-manager.d.ts:44:5 - (ae-undocumented) Missing documentation for "moduleLoader". +// src/manager/plugin-manager.d.ts:50:22 - (ae-undocumented) Missing documentation for "dynamicPluginsServiceFactoryWithOptions". +// src/manager/plugin-manager.d.ts:55:22 - (ae-undocumented) Missing documentation for "dynamicPluginsServiceFactory". +// src/manager/plugin-manager.d.ts:60:22 - (ae-undocumented) Missing documentation for "dynamicPluginsFeatureDiscoveryServiceFactory". +// src/manager/types.d.ts:27:1 - (ae-undocumented) Missing documentation for "LegacyPluginEnvironment". +// src/manager/types.d.ts:45:1 - (ae-undocumented) Missing documentation for "DynamicPluginProvider". +// src/manager/types.d.ts:46:5 - (ae-undocumented) Missing documentation for "plugins". +// src/manager/types.d.ts:51:1 - (ae-undocumented) Missing documentation for "BackendPluginProvider". +// src/manager/types.d.ts:52:5 - (ae-undocumented) Missing documentation for "backendPlugins". +// src/manager/types.d.ts:57:1 - (ae-undocumented) Missing documentation for "FrontendPluginProvider". +// src/manager/types.d.ts:58:5 - (ae-undocumented) Missing documentation for "frontendPlugins". +// src/manager/types.d.ts:63:1 - (ae-undocumented) Missing documentation for "BaseDynamicPlugin". +// src/manager/types.d.ts:64:5 - (ae-undocumented) Missing documentation for "name". +// src/manager/types.d.ts:65:5 - (ae-undocumented) Missing documentation for "version". +// src/manager/types.d.ts:66:5 - (ae-undocumented) Missing documentation for "role". +// src/manager/types.d.ts:67:5 - (ae-undocumented) Missing documentation for "platform". +// src/manager/types.d.ts:72:1 - (ae-undocumented) Missing documentation for "DynamicPlugin". +// src/manager/types.d.ts:76:1 - (ae-undocumented) Missing documentation for "FrontendDynamicPlugin". +// src/manager/types.d.ts:77:5 - (ae-undocumented) Missing documentation for "platform". +// src/manager/types.d.ts:82:1 - (ae-undocumented) Missing documentation for "BackendDynamicPlugin". +// src/manager/types.d.ts:83:5 - (ae-undocumented) Missing documentation for "platform". +// src/manager/types.d.ts:84:5 - (ae-undocumented) Missing documentation for "installer". +// src/manager/types.d.ts:89:1 - (ae-undocumented) Missing documentation for "BackendDynamicPluginInstaller". +// src/manager/types.d.ts:93:1 - (ae-undocumented) Missing documentation for "NewBackendPluginInstaller". +// src/manager/types.d.ts:94:5 - (ae-undocumented) Missing documentation for "kind". +// src/manager/types.d.ts:95:5 - (ae-undocumented) Missing documentation for "install". +// src/manager/types.d.ts:108:1 - (ae-undocumented) Missing documentation for "LegacyBackendPluginInstaller". +// src/manager/types.d.ts:109:5 - (ae-undocumented) Missing documentation for "kind". +// src/manager/types.d.ts:110:5 - (ae-undocumented) Missing documentation for "router". +// src/manager/types.d.ts:114:5 - (ae-undocumented) Missing documentation for "catalog". +// src/manager/types.d.ts:115:5 - (ae-undocumented) Missing documentation for "scaffolder". +// src/manager/types.d.ts:116:5 - (ae-undocumented) Missing documentation for "search". +// src/manager/types.d.ts:117:5 - (ae-undocumented) Missing documentation for "events". +// src/manager/types.d.ts:118:5 - (ae-undocumented) Missing documentation for "permissions". +// src/manager/types.d.ts:125:1 - (ae-undocumented) Missing documentation for "isBackendDynamicPluginInstaller". +// src/scanner/types.d.ts:5:1 - (ae-undocumented) Missing documentation for "ScannedPluginPackage". +// src/scanner/types.d.ts:6:5 - (ae-undocumented) Missing documentation for "location". +// src/scanner/types.d.ts:7:5 - (ae-undocumented) Missing documentation for "manifest". +// src/scanner/types.d.ts:12:1 - (ae-undocumented) Missing documentation for "ScannedPluginManifest". +// src/schemas/appBackendModule.d.ts:2:22 - (ae-undocumented) Missing documentation for "dynamicPluginsFrontendSchemas". +// src/schemas/rootLoggerServiceFactory.d.ts:2:22 - (ae-undocumented) Missing documentation for "dynamicPluginsRootLoggerServiceFactory". +// src/schemas/schemas.d.ts:7:1 - (ae-undocumented) Missing documentation for "DynamicPluginsSchemasService". +// src/schemas/schemas.d.ts:8:5 - (ae-undocumented) Missing documentation for "addDynamicPluginsSchemas". +// src/schemas/schemas.d.ts:21:1 - (ae-undocumented) Missing documentation for "DynamicPluginsSchemasOptions". +// src/schemas/schemas.d.ts:36:22 - (ae-undocumented) Missing documentation for "dynamicPluginsSchemasServiceFactoryWithOptions". +// src/schemas/schemas.d.ts:40:22 - (ae-undocumented) Missing documentation for "dynamicPluginsSchemasServiceFactory". + // (No @packageDocumentation comment for this package) ``` diff --git a/packages/backend-legacy/CHANGELOG.md b/packages/backend-legacy/CHANGELOG.md index 6a3068a37b..b12f216273 100644 --- a/packages/backend-legacy/CHANGELOG.md +++ b/packages/backend-legacy/CHANGELOG.md @@ -1,5 +1,171 @@ # example-backend-legacy +## 0.2.103-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.26.0-next.1 + - @backstage/plugin-catalog-backend@1.26.2-next.1 + - @backstage/backend-defaults@0.5.1-next.1 + - @backstage/integration@1.15.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/plugin-app-backend@0.3.75-next.0 + - @backstage/plugin-auth-backend@0.23.1-next.0 + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.1-next.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.5.1-next.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-devtools-backend@0.4.1-next.0 + - @backstage/plugin-events-backend@0.3.13-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/plugin-kubernetes-backend@0.18.7-next.0 + - @backstage/plugin-permission-backend@0.5.50-next.0 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-permission-node@0.8.4-next.0 + - @backstage/plugin-proxy-backend@0.5.7-next.0 + - @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.3.1-next.1 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.5.1-next.1 + - @backstage/plugin-scaffolder-backend-module-rails@0.5.1-next.1 + - @backstage/plugin-search-backend@1.5.18-next.1 + - @backstage/plugin-search-backend-module-catalog@0.2.3-next.1 + - @backstage/plugin-search-backend-module-elasticsearch@1.5.7-next.1 + - @backstage/plugin-search-backend-module-explore@0.2.3-next.1 + - @backstage/plugin-search-backend-module-pg@0.5.36-next.1 + - @backstage/plugin-search-backend-module-techdocs@0.2.3-next.1 + - @backstage/plugin-search-backend-node@1.3.3-next.1 + - @backstage/plugin-signals-backend@0.2.1-next.0 + - @backstage/plugin-signals-node@0.1.12-next.0 + - @backstage/plugin-techdocs-backend@1.10.14-next.1 + +## 0.2.103-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-module-elasticsearch@1.5.7-next.0 + - @backstage/plugin-scaffolder-backend@1.26.0-next.0 + - @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.3.1-next.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.5.1-next.0 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.5.1-next.0 + - @backstage/plugin-scaffolder-backend-module-rails@0.5.1-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.2.3-next.0 + - @backstage/plugin-search-backend-module-catalog@0.2.3-next.0 + - @backstage/plugin-search-backend-module-explore@0.2.3-next.0 + - @backstage/plugin-search-backend-module-pg@0.5.36-next.0 + - @backstage/plugin-search-backend-node@1.3.3-next.0 + - @backstage/plugin-kubernetes-backend@0.18.7-next.0 + - @backstage/plugin-permission-backend@0.5.50-next.0 + - @backstage/backend-defaults@0.5.1-next.0 + - @backstage/plugin-devtools-backend@0.4.1-next.0 + - @backstage/plugin-techdocs-backend@1.10.14-next.0 + - @backstage/plugin-catalog-backend@1.26.1-next.0 + - @backstage/plugin-permission-node@0.8.4-next.0 + - @backstage/plugin-signals-backend@0.2.1-next.0 + - @backstage/plugin-events-backend@0.3.13-next.0 + - @backstage/plugin-search-backend@1.5.18-next.0 + - @backstage/plugin-proxy-backend@0.5.7-next.0 + - @backstage/plugin-auth-backend@0.23.1-next.0 + - @backstage/plugin-signals-node@0.1.12-next.0 + - @backstage/plugin-app-backend@0.3.75-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.15.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.1-next.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-permission-common@0.8.1 + +## 0.2.102 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.0 + - @backstage/backend-common@0.25.0 + - @backstage/plugin-kubernetes-backend@0.18.6 + - @backstage/plugin-signals-backend@0.2.0 + - @backstage/plugin-signals-node@0.1.11 + - @backstage/plugin-techdocs-backend@1.10.13 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-search-backend@1.5.17 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.3.0 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.5.0 + - @backstage/plugin-scaffolder-backend-module-rails@0.5.0 + - @backstage/plugin-devtools-backend@0.4.0 + - @backstage/plugin-app-backend@0.3.74 + - @backstage/plugin-scaffolder-backend@1.25.0 + - @backstage/plugin-auth-backend@0.23.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-catalog-backend@1.26.0 + - @backstage/catalog-client@1.7.0 + - @backstage/plugin-search-backend-module-techdocs@0.2.2 + - @backstage/plugin-search-backend-module-catalog@0.2.2 + - @backstage/plugin-search-backend-module-explore@0.2.2 + - @backstage/plugin-permission-node@0.8.3 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/plugin-events-backend@0.3.12 + - @backstage/plugin-permission-backend@0.5.49 + - @backstage/plugin-proxy-backend@0.5.6 + - @backstage/plugin-search-backend-module-elasticsearch@1.5.6 + - @backstage/plugin-search-backend-module-pg@0.5.35 + - @backstage/integration@1.15.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.5.0 + - @backstage/plugin-events-node@0.4.0 + - @backstage/config@1.2.0 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-backend-node@1.3.2 + +## 0.2.102-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-defaults@0.5.0-next.2 + - @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.3.0-next.2 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.5.0-next.2 + - @backstage/plugin-scaffolder-backend-module-rails@0.5.0-next.2 + - @backstage/plugin-devtools-backend@0.4.0-next.2 + - @backstage/plugin-scaffolder-backend@1.25.0-next.2 + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/plugin-auth-backend@0.23.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-client@1.7.0-next.1 + - @backstage/plugin-catalog-backend@1.26.0-next.2 + - @backstage/plugin-app-backend@0.3.74-next.2 + - @backstage/integration@1.15.0-next.0 + - @backstage/plugin-events-backend@0.3.12-next.2 + - @backstage/plugin-kubernetes-backend@0.18.6-next.2 + - @backstage/plugin-permission-backend@0.5.49-next.2 + - @backstage/plugin-permission-node@0.8.3-next.2 + - @backstage/plugin-search-backend@1.5.17-next.2 + - @backstage/plugin-signals-backend@0.2.0-next.2 + - @backstage/plugin-techdocs-backend@1.10.13-next.2 + - @backstage/plugin-search-backend-module-explore@0.2.2-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.0-next.2 + - @backstage/plugin-catalog-backend-module-unprocessed@0.5.0-next.2 + - @backstage/plugin-catalog-node@1.12.7-next.2 + - @backstage/plugin-events-node@0.4.0-next.2 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-proxy-backend@0.5.6-next.2 + - @backstage/plugin-search-backend-module-catalog@0.2.2-next.2 + - @backstage/plugin-search-backend-module-elasticsearch@1.5.6-next.2 + - @backstage/plugin-search-backend-module-pg@0.5.35-next.2 + - @backstage/plugin-search-backend-module-techdocs@0.2.2-next.2 + - @backstage/plugin-search-backend-node@1.3.2-next.2 + - @backstage/plugin-signals-node@0.1.11-next.2 + ## 0.2.102-next.1 ### Patch Changes diff --git a/packages/backend-legacy/package.json b/packages/backend-legacy/package.json index 65e5a46f28..d7d4a68b4a 100644 --- a/packages/backend-legacy/package.json +++ b/packages/backend-legacy/package.json @@ -1,6 +1,6 @@ { "name": "example-backend-legacy", - "version": "0.2.102-next.1", + "version": "0.2.103-next.1", "backstage": { "role": "backend" }, @@ -28,7 +28,7 @@ "test": "backstage-cli package test" }, "dependencies": { - "@backstage/backend-common": "workspace:^", + "@backstage/backend-common": "^0.25.0", "@backstage/backend-defaults": "workspace:^", "@backstage/backend-plugin-api": "workspace:^", "@backstage/catalog-client": "workspace:^", diff --git a/packages/backend-openapi-utils/CHANGELOG.md b/packages/backend-openapi-utils/CHANGELOG.md index 3d62a9d121..9bb33dd55d 100644 --- a/packages/backend-openapi-utils/CHANGELOG.md +++ b/packages/backend-openapi-utils/CHANGELOG.md @@ -1,5 +1,31 @@ # @backstage/backend-openapi-utils +## 0.1.19-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/errors@1.2.4 + +## 0.1.18 + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/errors@1.2.4 + +## 0.1.18-next.2 + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/errors@1.2.4 + ## 0.1.18-next.1 ### Patch Changes diff --git a/packages/backend-openapi-utils/package.json b/packages/backend-openapi-utils/package.json index 37ae412be6..8f6fd1b6eb 100644 --- a/packages/backend-openapi-utils/package.json +++ b/packages/backend-openapi-utils/package.json @@ -1,10 +1,10 @@ { "name": "@backstage/backend-openapi-utils", + "version": "0.1.19-next.0", "description": "OpenAPI typescript support.", - "version": "0.1.18-next.1", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "node-library" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", @@ -17,25 +17,21 @@ "url": "https://github.com/backstage/backstage", "directory": "packages/backend-openapi-utils" }, - "backstage": { - "role": "node-library" - }, - "scripts": { - "start": "backstage-cli package start", - "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", - "clean": "backstage-cli package clean", - "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" - }, - "devDependencies": { - "@backstage/cli": "workspace:^", - "supertest": "^6.1.3" - }, + "license": "Apache-2.0", + "main": "src/index.ts", + "types": "src/index.ts", "files": [ "dist" ], + "scripts": { + "build": "backstage-cli package build", + "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" + }, "dependencies": { "@backstage/backend-plugin-api": "workspace:^", "@backstage/errors": "workspace:^", @@ -48,5 +44,9 @@ "lodash": "^4.17.21", "openapi-merge": "^1.3.2", "openapi3-ts": "^3.1.2" + }, + "devDependencies": { + "@backstage/cli": "workspace:^", + "supertest": "^7.0.0" } } diff --git a/packages/backend-openapi-utils/api-report.md b/packages/backend-openapi-utils/report.api.md similarity index 72% rename from packages/backend-openapi-utils/api-report.md rename to packages/backend-openapi-utils/report.api.md index 8e702b8c23..a0495f39b5 100644 --- a/packages/backend-openapi-utils/api-report.md +++ b/packages/backend-openapi-utils/report.api.md @@ -717,4 +717,84 @@ type ValueOf = T[keyof T]; // @public export const wrapInOpenApiTestServer: (app: Express_2) => Server | Express_2; + +// Warnings were encountered during analysis: +// +// src/router.d.ts:8:5 - (ae-undocumented) Missing documentation for "get". +// src/router.d.ts:9:5 - (ae-undocumented) Missing documentation for "post". +// src/router.d.ts:10:5 - (ae-undocumented) Missing documentation for "all". +// src/router.d.ts:11:5 - (ae-undocumented) Missing documentation for "put". +// src/router.d.ts:12:5 - (ae-undocumented) Missing documentation for "delete". +// src/router.d.ts:13:5 - (ae-undocumented) Missing documentation for "patch". +// src/router.d.ts:14:5 - (ae-undocumented) Missing documentation for "options". +// src/router.d.ts:15:5 - (ae-undocumented) Missing documentation for "head". +// src/types/common.d.ts:14:1 - (ae-undocumented) Missing documentation for "PathDoc". +// src/types/common.d.ts:60:1 - (ae-undocumented) Missing documentation for "DocPathTemplate". +// src/types/common.d.ts:64:1 - (ae-undocumented) Missing documentation for "DocPathMethod". +// src/types/common.d.ts:68:1 - (ae-undocumented) Missing documentation for "DocPathTemplateMethod". +// src/types/common.d.ts:72:1 - (ae-undocumented) Missing documentation for "MethodAwareDocPath". +// src/types/common.d.ts:78:1 - (ae-undocumented) Missing documentation for "DocOperation". +// src/types/common.d.ts:82:1 - (ae-undocumented) Missing documentation for "ComponentTypes". +// src/types/common.d.ts:86:1 - (ae-undocumented) Missing documentation for "ComponentRef". +// src/types/common.d.ts:92:1 - (ae-undocumented) Missing documentation for "SchemaRef". +// src/types/common.d.ts:100:1 - (ae-undocumented) Missing documentation for "ObjectWithContentSchema". +// src/types/common.d.ts:114:1 - (ae-undocumented) Missing documentation for "LastOf". +// src/types/common.d.ts:118:1 - (ae-undocumented) Missing documentation for "Push". +// src/types/common.d.ts:122:1 - (ae-undocumented) Missing documentation for "TuplifyUnion". +// src/types/common.d.ts:126:1 - (ae-undocumented) Missing documentation for "ConvertAll". +// src/types/common.d.ts:134:1 - (ae-undocumented) Missing documentation for "UnknownIfNever". +// src/types/common.d.ts:138:1 - (ae-undocumented) Missing documentation for "ToTypeSafe". +// src/types/common.d.ts:142:1 - (ae-undocumented) Missing documentation for "DiscriminateUnion". +// src/types/common.d.ts:146:1 - (ae-undocumented) Missing documentation for "MapDiscriminatedUnion". +// src/types/common.d.ts:152:1 - (ae-undocumented) Missing documentation for "PickOptionalKeys". +// src/types/common.d.ts:160:1 - (ae-undocumented) Missing documentation for "PickRequiredKeys". +// src/types/common.d.ts:168:1 - (ae-undocumented) Missing documentation for "OptionalMap". +// src/types/common.d.ts:176:1 - (ae-undocumented) Missing documentation for "RequiredMap". +// src/types/common.d.ts:184:1 - (ae-undocumented) Missing documentation for "FullMap". +// src/types/common.d.ts:190:1 - (ae-undocumented) Missing documentation for "Filter". +// src/types/express.d.ts:21:5 - (ae-undocumented) Missing documentation for "__call". +// src/types/express.d.ts:22:5 - (ae-undocumented) Missing documentation for "__call". +// src/types/immutable.d.ts:18:1 - (ae-undocumented) Missing documentation for "ImmutableObject". +// src/types/immutable.d.ts:24:1 - (ae-undocumented) Missing documentation for "ImmutableReferenceObject". +// src/types/immutable.d.ts:28:1 - (ae-undocumented) Missing documentation for "ImmutableOpenAPIObject". +// src/types/immutable.d.ts:32:1 - (ae-undocumented) Missing documentation for "ImmutableContentObject". +// src/types/immutable.d.ts:36:1 - (ae-undocumented) Missing documentation for "ImmutableRequestBodyObject". +// src/types/immutable.d.ts:40:1 - (ae-undocumented) Missing documentation for "ImmutableResponseObject". +// src/types/immutable.d.ts:44:1 - (ae-undocumented) Missing documentation for "ImmutableParameterObject". +// src/types/immutable.d.ts:48:1 - (ae-undocumented) Missing documentation for "HeaderObject". +// src/types/immutable.d.ts:49:5 - (ae-undocumented) Missing documentation for "in". +// src/types/immutable.d.ts:50:5 - (ae-undocumented) Missing documentation for "style". +// src/types/immutable.d.ts:55:1 - (ae-undocumented) Missing documentation for "ImmutableHeaderObject". +// src/types/immutable.d.ts:59:1 - (ae-undocumented) Missing documentation for "CookieObject". +// src/types/immutable.d.ts:60:5 - (ae-undocumented) Missing documentation for "in". +// src/types/immutable.d.ts:61:5 - (ae-undocumented) Missing documentation for "style". +// src/types/immutable.d.ts:66:1 - (ae-undocumented) Missing documentation for "ImmutableCookieObject". +// src/types/immutable.d.ts:70:1 - (ae-undocumented) Missing documentation for "QueryObject". +// src/types/immutable.d.ts:71:5 - (ae-undocumented) Missing documentation for "in". +// src/types/immutable.d.ts:72:5 - (ae-undocumented) Missing documentation for "style". +// src/types/immutable.d.ts:77:1 - (ae-undocumented) Missing documentation for "ImmutableQueryObject". +// src/types/immutable.d.ts:81:1 - (ae-undocumented) Missing documentation for "PathObject". +// src/types/immutable.d.ts:82:5 - (ae-undocumented) Missing documentation for "in". +// src/types/immutable.d.ts:83:5 - (ae-undocumented) Missing documentation for "style". +// src/types/immutable.d.ts:88:1 - (ae-undocumented) Missing documentation for "ImmutablePathObject". +// src/types/immutable.d.ts:92:1 - (ae-undocumented) Missing documentation for "ImmutableSchemaObject". +// src/types/params.d.ts:7:1 - (ae-undocumented) Missing documentation for "DocParameter". +// src/types/params.d.ts:16:1 - (ae-undocumented) Missing documentation for "DocParameters". +// src/types/params.d.ts:22:1 - (ae-undocumented) Missing documentation for "ParameterSchema". +// src/types/params.d.ts:26:1 - (ae-undocumented) Missing documentation for "MapToSchema". +// src/types/params.d.ts:32:1 - (ae-undocumented) Missing documentation for "ParametersSchema". +// src/types/params.d.ts:36:1 - (ae-undocumented) Missing documentation for "HeaderSchema". +// src/types/params.d.ts:40:1 - (ae-undocumented) Missing documentation for "CookieSchema". +// src/types/params.d.ts:44:1 - (ae-undocumented) Missing documentation for "PathSchema". +// src/types/params.d.ts:48:1 - (ae-undocumented) Missing documentation for "QuerySchema". +// src/types/requests.d.ts:9:1 - (ae-undocumented) Missing documentation for "RequestBody". +// src/types/requests.d.ts:13:1 - (ae-undocumented) Missing documentation for "RequestBodySchema". +// src/types/responses.d.ts:9:1 - (ae-undocumented) Missing documentation for "Response". +// src/types/responses.d.ts:13:1 - (ae-undocumented) Missing documentation for "ResponseSchemas". +// src/utility.d.ts:5:1 - (ae-undocumented) Missing documentation for "Response". +// src/utility.d.ts:9:1 - (ae-undocumented) Missing documentation for "Request". +// src/utility.d.ts:13:1 - (ae-undocumented) Missing documentation for "HeaderParameters". +// src/utility.d.ts:17:1 - (ae-undocumented) Missing documentation for "CookieParameters". +// src/utility.d.ts:21:1 - (ae-undocumented) Missing documentation for "PathParameters". +// src/utility.d.ts:25:1 - (ae-undocumented) Missing documentation for "QueryParameters". ``` diff --git a/packages/backend-plugin-api/CHANGELOG.md b/packages/backend-plugin-api/CHANGELOG.md index 5fdf43aaa6..252d59ea1c 100644 --- a/packages/backend-plugin-api/CHANGELOG.md +++ b/packages/backend-plugin-api/CHANGELOG.md @@ -1,5 +1,78 @@ # @backstage/backend-plugin-api +## 1.0.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.8.1 + +## 1.0.0 + +### Major Changes + +- ec1b4be: Release 1.0 of the new backend system! :tada: + + The backend system is finally getting promoted to 1.0.0. This means that the API is now stable and breaking changes should not occur until version 2.0.0, see our [package versioning policy](https://backstage.io/docs/overview/versioning-policy/#package-versioning-policy) for more information what this means. + + This release also marks the end of the old backend system based on `createRouter` exports. Going forward backend plugins packages will start to deprecate and later this year remove exports supporting the old backend system. If you would like to help out with this transition, see https://github.com/backstage/backstage/issues/26353 or consult the [migration guide](https://backstage.io/docs/backend-system/building-plugins-and-modules/migrating/#remove-support-for-the-old-backend-system). + +### Minor Changes + +- 19ff127: **BREAKING**: The deprecated identity and token manager services have been removed. This means that `coreServices.identity` and `coreServices.tokenManager` are gone, along with related types and utilities in other packages. +- f687050: Removed the following deprecated exports + + - `BackendPluginConfig` use `CreateBackendPluginOptions` + - `BackendModuleConfig` use `CreateBackendModuleOptions` + - `ExtensionPointConfig` use `CreateExtensionPointOptions` + +- 4d82481: Removed deprecated `ServiceFactoryOrFunction` type. +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- cd38da8: Deprecate the `featureDiscoveryServiceRef` in favor of using the new `discoveryFeatureLoader` instead. +- 8052b9b: Add a `toJSON` on refs so that they can appear in expectations in jest tests +- 66dbf0a: Allow the cache service to accept the human duration format for TTL +- 0b2a402: Updates to the config schema to match reality +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.8.1 + +## 1.0.0-next.2 + +### Major Changes + +- ec1b4be: Release 1.0 of the new backend system! :tada: + + The backend system is finally getting promoted to 1.0.0. This means that the API is now stable and breaking changes should not occur until version 2.0.0, see our [package versioning policy](https://backstage.io/docs/overview/versioning-policy/#package-versioning-policy) for more information what this means. + + This release also marks the end of the old backend system based on `createRouter` exports. Going forward backend plugins packages will start to deprecate and later this year remove exports supporting the old backend system. If you would like to help out with this transition, see https://github.com/backstage/backstage/issues/26353 or consult the [migration guide](https://backstage.io/docs/backend-system/building-plugins-and-modules/migrating/#remove-support-for-the-old-backend-system). + +### Patch Changes + +- 8052b9b: Add a `toJSON` on refs so that they can appear in expectations in jest tests +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.8.1 + ## 0.9.0-next.1 ### Patch Changes diff --git a/packages/backend-plugin-api/package.json b/packages/backend-plugin-api/package.json index 322c936b39..cc3f4d09c7 100644 --- a/packages/backend-plugin-api/package.json +++ b/packages/backend-plugin-api/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-plugin-api", - "version": "0.9.0-next.1", + "version": "1.0.1-next.0", "description": "Core API used by Backstage backend plugins", "backstage": { "role": "node-library" diff --git a/packages/backend-plugin-api/api-report-alpha.md b/packages/backend-plugin-api/report-alpha.api.md similarity index 73% rename from packages/backend-plugin-api/api-report-alpha.md rename to packages/backend-plugin-api/report-alpha.api.md index dea357502e..29c74e7ade 100644 --- a/packages/backend-plugin-api/api-report-alpha.md +++ b/packages/backend-plugin-api/report-alpha.api.md @@ -21,5 +21,10 @@ export const featureDiscoveryServiceRef: ServiceRef< 'singleton' >; +// Warnings were encountered during analysis: +// +// src/alpha.d.ts:3:1 - (ae-undocumented) Missing documentation for "FeatureDiscoveryService". +// src/alpha.d.ts:4:5 - (ae-undocumented) Missing documentation for "getBackendFeatures". + // (No @packageDocumentation comment for this package) ``` diff --git a/packages/backend-plugin-api/api-report-testUtils.md b/packages/backend-plugin-api/report-testUtils.api.md similarity index 70% rename from packages/backend-plugin-api/api-report-testUtils.md rename to packages/backend-plugin-api/report-testUtils.api.md index 8c9bba8398..8f2f871e90 100644 --- a/packages/backend-plugin-api/api-report-testUtils.md +++ b/packages/backend-plugin-api/report-testUtils.api.md @@ -22,5 +22,10 @@ export interface PackagePathResolutionOverride { restore(): void; } +// Warnings were encountered during analysis: +// +// src/testUtils.d.ts:2:1 - (ae-undocumented) Missing documentation for "PackagePathResolutionOverride". +// src/testUtils.d.ts:7:1 - (ae-undocumented) Missing documentation for "OverridePackagePathResolutionOptions". + // (No @packageDocumentation comment for this package) ``` diff --git a/packages/backend-plugin-api/api-report.md b/packages/backend-plugin-api/report.api.md similarity index 81% rename from packages/backend-plugin-api/api-report.md rename to packages/backend-plugin-api/report.api.md index 89dfe40dd9..e03179e851 100644 --- a/packages/backend-plugin-api/api-report.md +++ b/packages/backend-plugin-api/report.api.md @@ -735,4 +735,48 @@ export type UrlReaderServiceSearchResponseFile = { export interface UserInfoService { getUserInfo(credentials: BackstageCredentials): Promise; } + +// Warnings were encountered during analysis: +// +// src/services/definitions/HttpRouterService.d.ts:8:5 - (ae-undocumented) Missing documentation for "path". +// src/services/definitions/HttpRouterService.d.ts:9:5 - (ae-undocumented) Missing documentation for "allow". +// src/services/definitions/LifecycleService.d.ts:5:1 - (ae-undocumented) Missing documentation for "LifecycleServiceStartupHook". +// src/services/definitions/LifecycleService.d.ts:9:1 - (ae-undocumented) Missing documentation for "LifecycleServiceStartupOptions". +// src/services/definitions/LifecycleService.d.ts:18:1 - (ae-undocumented) Missing documentation for "LifecycleServiceShutdownHook". +// src/services/definitions/LifecycleService.d.ts:22:1 - (ae-undocumented) Missing documentation for "LifecycleServiceShutdownOptions". +// src/services/definitions/LoggerService.d.ts:10:5 - (ae-undocumented) Missing documentation for "error". +// src/services/definitions/LoggerService.d.ts:11:5 - (ae-undocumented) Missing documentation for "warn". +// src/services/definitions/LoggerService.d.ts:12:5 - (ae-undocumented) Missing documentation for "info". +// src/services/definitions/LoggerService.d.ts:13:5 - (ae-undocumented) Missing documentation for "debug". +// src/services/definitions/LoggerService.d.ts:14:5 - (ae-undocumented) Missing documentation for "child". +// src/services/definitions/PermissionsService.d.ts:9:5 - (ae-undocumented) Missing documentation for "credentials". +// src/services/definitions/RootHealthService.d.ts:5:1 - (ae-undocumented) Missing documentation for "RootHealthService". +// src/services/definitions/UserInfoService.d.ts:9:5 - (ae-undocumented) Missing documentation for "userEntityRef". +// src/services/definitions/UserInfoService.d.ts:10:5 - (ae-undocumented) Missing documentation for "ownershipEntityRefs". +// src/services/system/types.d.ts:35:1 - (ae-undocumented) Missing documentation for "ServiceFactory". +// src/services/system/types.d.ts:36:5 - (ae-undocumented) Missing documentation for "service". +// src/services/system/types.d.ts:39:1 - (ae-undocumented) Missing documentation for "ServiceRefOptions". +// src/services/system/types.d.ts:40:5 - (ae-undocumented) Missing documentation for "id". +// src/services/system/types.d.ts:41:5 - (ae-undocumented) Missing documentation for "scope". +// src/services/system/types.d.ts:42:5 - (ae-undocumented) Missing documentation for "multiton". +// src/services/system/types.d.ts:43:5 - (ae-undocumented) Missing documentation for "defaultFactory". +// src/services/system/types.d.ts:76:1 - (ae-undocumented) Missing documentation for "RootServiceFactoryOptions". +// src/services/system/types.d.ts:90:5 - (ae-undocumented) Missing documentation for "service". +// src/services/system/types.d.ts:91:5 - (ae-undocumented) Missing documentation for "deps". +// src/services/system/types.d.ts:92:5 - (ae-undocumented) Missing documentation for "factory". +// src/services/system/types.d.ts:95:1 - (ae-undocumented) Missing documentation for "PluginServiceFactoryOptions". +// src/services/system/types.d.ts:109:5 - (ae-undocumented) Missing documentation for "service". +// src/services/system/types.d.ts:110:5 - (ae-undocumented) Missing documentation for "deps". +// src/services/system/types.d.ts:111:5 - (ae-undocumented) Missing documentation for "createRootContext". +// src/services/system/types.d.ts:112:5 - (ae-undocumented) Missing documentation for "factory". +// src/types.d.ts:2:1 - (ae-undocumented) Missing documentation for "BackendFeature". +// src/types.d.ts:3:5 - (ae-undocumented) Missing documentation for "$$type". +// src/wiring/createBackendFeatureLoader.d.ts:10:5 - (ae-undocumented) Missing documentation for "deps". +// src/wiring/createBackendFeatureLoader.d.ts:13:5 - (ae-undocumented) Missing documentation for "loader". +// src/wiring/createBackendModule.d.ts:21:5 - (ae-undocumented) Missing documentation for "register". +// src/wiring/createBackendPlugin.d.ts:17:5 - (ae-undocumented) Missing documentation for "register". +// src/wiring/types.d.ts:30:5 - (ae-undocumented) Missing documentation for "registerExtensionPoint". +// src/wiring/types.d.ts:31:5 - (ae-undocumented) Missing documentation for "registerInit". +// src/wiring/types.d.ts:44:5 - (ae-undocumented) Missing documentation for "registerExtensionPoint". +// src/wiring/types.d.ts:45:5 - (ae-undocumented) Missing documentation for "registerInit". ``` diff --git a/packages/backend-plugin-api/src/services/system/types.ts b/packages/backend-plugin-api/src/services/system/types.ts index a14e388bd0..7e4b78b5a1 100644 --- a/packages/backend-plugin-api/src/services/system/types.ts +++ b/packages/backend-plugin-api/src/services/system/types.ts @@ -17,7 +17,9 @@ import { BackendFeature } from '../../types'; /** - * TODO + * A reference to a backend service. You can use these references to mark + * dependencies on services and having their implementations injected + * automatically. * * @public */ @@ -39,6 +41,11 @@ export type ServiceRef< */ scope: TScope; + /** + * Marks whether the service is a multiton or not. Multiton services the + * opposite of singletons - they can be provided many times, and when depended + * on, you receive an array of all provided instances. + */ multiton?: TInstances extends 'multiton' ? true : false; /** @@ -142,6 +149,15 @@ export function createServiceRef< toString() { return `serviceRef{${options.id}}`; }, + toJSON() { + // This avoids accidental calls to T happening e.g. in tests + return { + $$type: '@backstage/ServiceRef', + id, + scope, + multiton, + }; + }, $$type: '@backstage/ServiceRef', __defaultFactory: defaultFactory, } as ServiceRef & { diff --git a/packages/backend-test-utils/CHANGELOG.md b/packages/backend-test-utils/CHANGELOG.md index 28ee376101..75a57ff4dd 100644 --- a/packages/backend-test-utils/CHANGELOG.md +++ b/packages/backend-test-utils/CHANGELOG.md @@ -1,5 +1,92 @@ # @backstage/backend-test-utils +## 1.0.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.1-next.1 + - @backstage/backend-app-api@1.0.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + +## 1.0.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.1-next.0 + - @backstage/backend-app-api@1.0.1-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## 1.0.0 + +### Major Changes + +- ec1b4be: Release 1.0 of the new backend system! :tada: + + The backend system is finally getting promoted to 1.0.0. This means that the API is now stable and breaking changes should not occur until version 2.0.0, see our [package versioning policy](https://backstage.io/docs/overview/versioning-policy/#package-versioning-policy) for more information what this means. + + This release also marks the end of the old backend system based on `createRouter` exports. Going forward backend plugins packages will start to deprecate and later this year remove exports supporting the old backend system. If you would like to help out with this transition, see https://github.com/backstage/backstage/issues/26353 or consult the [migration guide](https://backstage.io/docs/backend-system/building-plugins-and-modules/migrating/#remove-support-for-the-old-backend-system). + +### Minor Changes + +- 19ff127: **BREAKING**: Removed service mocks for the identity and token manager services, which have been removed from `@backstage/backend-plugin-api`. +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- 710f621: Added missing service mock for `mockServices.rootConfig.mock`, and fixed the definition of `mockServices.rootHttpRouter.factory` to not have a duplicate callback. +- f421d2a: Make MySQL pool settings a bit more lax +- 0363bf1: There is a new `mockErrorHandler` utility to help in mocking the error middleware in tests. +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-defaults@0.5.0 + - @backstage/backend-app-api@1.0.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/plugin-events-node@0.4.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## 1.0.0-next.2 + +### Major Changes + +- ec1b4be: Release 1.0 of the new backend system! :tada: + + The backend system is finally getting promoted to 1.0.0. This means that the API is now stable and breaking changes should not occur until version 2.0.0, see our [package versioning policy](https://backstage.io/docs/overview/versioning-policy/#package-versioning-policy) for more information what this means. + + This release also marks the end of the old backend system based on `createRouter` exports. Going forward backend plugins packages will start to deprecate and later this year remove exports supporting the old backend system. If you would like to help out with this transition, see https://github.com/backstage/backstage/issues/26353 or consult the [migration guide](https://backstage.io/docs/backend-system/building-plugins-and-modules/migrating/#remove-support-for-the-old-backend-system). + +### Patch Changes + +- f421d2a: Make MySQL pool settings a bit more lax +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-app-api@1.0.0-next.2 + - @backstage/backend-defaults@0.5.0-next.2 + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.4.0-next.2 + ## 0.6.0-next.1 ### Patch Changes diff --git a/packages/backend-test-utils/package.json b/packages/backend-test-utils/package.json index a84aca9b52..427eb7c7a2 100644 --- a/packages/backend-test-utils/package.json +++ b/packages/backend-test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-test-utils", - "version": "0.6.0-next.1", + "version": "1.0.1-next.1", "description": "Test helpers library for Backstage backends", "backstage": { "role": "node-library" @@ -77,7 +77,7 @@ "devDependencies": { "@backstage/cli": "workspace:^", "@types/supertest": "^2.0.8", - "supertest": "^6.1.3" + "supertest": "^7.0.0" }, "peerDependencies": { "@types/jest": "*" diff --git a/packages/backend-test-utils/api-report.md b/packages/backend-test-utils/report.api.md similarity index 65% rename from packages/backend-test-utils/api-report.md rename to packages/backend-test-utils/report.api.md index 2bea998596..1235cd7cb3 100644 --- a/packages/backend-test-utils/api-report.md +++ b/packages/backend-test-utils/report.api.md @@ -474,4 +474,85 @@ export class TestDatabases { // (undocumented) supports(id: TestDatabaseId): boolean; } + +// Warnings were encountered during analysis: +// +// src/cache/TestCaches.d.ts:27:5 - (ae-undocumented) Missing documentation for "setDefaults". +// src/cache/TestCaches.d.ts:31:5 - (ae-undocumented) Missing documentation for "supports". +// src/cache/TestCaches.d.ts:32:5 - (ae-undocumented) Missing documentation for "eachSupportedId". +// src/database/TestDatabases.d.ts:29:5 - (ae-undocumented) Missing documentation for "setDefaults". +// src/database/TestDatabases.d.ts:33:5 - (ae-undocumented) Missing documentation for "supports". +// src/database/TestDatabases.d.ts:34:5 - (ae-undocumented) Missing documentation for "eachSupportedId". +// src/next/services/mockCredentials.d.ts:17:1 - (ae-undocumented) Missing documentation for "mockCredentials". +// src/next/services/mockCredentials.d.ts:58:9 - (ae-undocumented) Missing documentation for "invalidToken". +// src/next/services/mockCredentials.d.ts:59:9 - (ae-undocumented) Missing documentation for "invalidHeader". +// src/next/services/mockCredentials.d.ts:84:9 - (ae-undocumented) Missing documentation for "invalidToken". +// src/next/services/mockCredentials.d.ts:85:9 - (ae-undocumented) Missing documentation for "invalidCookie". +// src/next/services/mockCredentials.d.ts:116:9 - (ae-undocumented) Missing documentation for "invalidToken". +// src/next/services/mockCredentials.d.ts:117:9 - (ae-undocumented) Missing documentation for "invalidHeader". +// src/next/services/mockServices.d.ts:5:1 - (ae-undocumented) Missing documentation for "ServiceMock". +// src/next/services/mockServices.d.ts:13:1 - (ae-undocumented) Missing documentation for "mockServices". +// src/next/services/mockServices.d.ts:14:5 - (ae-undocumented) Missing documentation for "rootConfig". +// src/next/services/mockServices.d.ts:15:5 - (ae-undocumented) Missing documentation for "rootConfig". +// src/next/services/mockServices.d.ts:16:9 - (ae-undocumented) Missing documentation for "Options". +// src/next/services/mockServices.d.ts:19:15 - (ae-undocumented) Missing documentation for "factory". +// src/next/services/mockServices.d.ts:20:15 - (ae-undocumented) Missing documentation for "mock". +// src/next/services/mockServices.d.ts:22:5 - (ae-undocumented) Missing documentation for "rootLogger". +// src/next/services/mockServices.d.ts:23:5 - (ae-undocumented) Missing documentation for "rootLogger". +// src/next/services/mockServices.d.ts:24:9 - (ae-undocumented) Missing documentation for "Options". +// src/next/services/mockServices.d.ts:27:15 - (ae-undocumented) Missing documentation for "factory". +// src/next/services/mockServices.d.ts:28:15 - (ae-undocumented) Missing documentation for "mock". +// src/next/services/mockServices.d.ts:30:5 - (ae-undocumented) Missing documentation for "auth". +// src/next/services/mockServices.d.ts:34:5 - (ae-undocumented) Missing documentation for "auth". +// src/next/services/mockServices.d.ts:35:15 - (ae-undocumented) Missing documentation for "factory". +// src/next/services/mockServices.d.ts:36:15 - (ae-undocumented) Missing documentation for "mock". +// src/next/services/mockServices.d.ts:38:5 - (ae-undocumented) Missing documentation for "discovery". +// src/next/services/mockServices.d.ts:39:5 - (ae-undocumented) Missing documentation for "discovery". +// src/next/services/mockServices.d.ts:40:15 - (ae-undocumented) Missing documentation for "factory". +// src/next/services/mockServices.d.ts:41:15 - (ae-undocumented) Missing documentation for "mock". +// src/next/services/mockServices.d.ts:61:5 - (ae-undocumented) Missing documentation for "httpAuth". +// src/next/services/mockServices.d.ts:72:15 - (ae-undocumented) Missing documentation for "mock". +// src/next/services/mockServices.d.ts:82:5 - (ae-undocumented) Missing documentation for "userInfo". +// src/next/services/mockServices.d.ts:90:15 - (ae-undocumented) Missing documentation for "mock". +// src/next/services/mockServices.d.ts:92:5 - (ae-undocumented) Missing documentation for "cache". +// src/next/services/mockServices.d.ts:93:15 - (ae-undocumented) Missing documentation for "factory". +// src/next/services/mockServices.d.ts:94:15 - (ae-undocumented) Missing documentation for "mock". +// src/next/services/mockServices.d.ts:96:5 - (ae-undocumented) Missing documentation for "database". +// src/next/services/mockServices.d.ts:97:15 - (ae-undocumented) Missing documentation for "factory". +// src/next/services/mockServices.d.ts:98:15 - (ae-undocumented) Missing documentation for "mock". +// src/next/services/mockServices.d.ts:100:5 - (ae-undocumented) Missing documentation for "rootHealth". +// src/next/services/mockServices.d.ts:101:15 - (ae-undocumented) Missing documentation for "factory". +// src/next/services/mockServices.d.ts:102:15 - (ae-undocumented) Missing documentation for "mock". +// src/next/services/mockServices.d.ts:104:5 - (ae-undocumented) Missing documentation for "httpRouter". +// src/next/services/mockServices.d.ts:105:15 - (ae-undocumented) Missing documentation for "factory". +// src/next/services/mockServices.d.ts:106:15 - (ae-undocumented) Missing documentation for "mock". +// src/next/services/mockServices.d.ts:108:5 - (ae-undocumented) Missing documentation for "rootHttpRouter". +// src/next/services/mockServices.d.ts:109:15 - (ae-undocumented) Missing documentation for "factory". +// src/next/services/mockServices.d.ts:110:15 - (ae-undocumented) Missing documentation for "mock". +// src/next/services/mockServices.d.ts:112:5 - (ae-undocumented) Missing documentation for "lifecycle". +// src/next/services/mockServices.d.ts:113:15 - (ae-undocumented) Missing documentation for "factory". +// src/next/services/mockServices.d.ts:114:15 - (ae-undocumented) Missing documentation for "mock". +// src/next/services/mockServices.d.ts:116:5 - (ae-undocumented) Missing documentation for "logger". +// src/next/services/mockServices.d.ts:117:15 - (ae-undocumented) Missing documentation for "factory". +// src/next/services/mockServices.d.ts:118:15 - (ae-undocumented) Missing documentation for "mock". +// src/next/services/mockServices.d.ts:120:5 - (ae-undocumented) Missing documentation for "permissions". +// src/next/services/mockServices.d.ts:121:15 - (ae-undocumented) Missing documentation for "factory". +// src/next/services/mockServices.d.ts:122:15 - (ae-undocumented) Missing documentation for "mock". +// src/next/services/mockServices.d.ts:124:5 - (ae-undocumented) Missing documentation for "rootLifecycle". +// src/next/services/mockServices.d.ts:125:15 - (ae-undocumented) Missing documentation for "factory". +// src/next/services/mockServices.d.ts:126:15 - (ae-undocumented) Missing documentation for "mock". +// src/next/services/mockServices.d.ts:128:5 - (ae-undocumented) Missing documentation for "scheduler". +// src/next/services/mockServices.d.ts:129:15 - (ae-undocumented) Missing documentation for "factory". +// src/next/services/mockServices.d.ts:130:15 - (ae-undocumented) Missing documentation for "mock". +// src/next/services/mockServices.d.ts:132:5 - (ae-undocumented) Missing documentation for "urlReader". +// src/next/services/mockServices.d.ts:133:15 - (ae-undocumented) Missing documentation for "factory". +// src/next/services/mockServices.d.ts:134:15 - (ae-undocumented) Missing documentation for "mock". +// src/next/services/mockServices.d.ts:136:5 - (ae-undocumented) Missing documentation for "events". +// src/next/services/mockServices.d.ts:137:15 - (ae-undocumented) Missing documentation for "factory". +// src/next/services/mockServices.d.ts:138:15 - (ae-undocumented) Missing documentation for "mock". +// src/next/wiring/TestBackend.d.ts:5:1 - (ae-undocumented) Missing documentation for "TestBackendOptions". +// src/next/wiring/TestBackend.d.ts:6:5 - (ae-undocumented) Missing documentation for "extensionPoints". +// src/next/wiring/TestBackend.d.ts:14:5 - (ae-undocumented) Missing documentation for "features". +// src/next/wiring/TestBackend.d.ts:19:1 - (ae-undocumented) Missing documentation for "TestBackend". +// src/next/wiring/TestBackend.d.ts:30:1 - (ae-undocumented) Missing documentation for "startTestBackend". ``` diff --git a/packages/backend-test-utils/src/database/mysql.ts b/packages/backend-test-utils/src/database/mysql.ts index ab130dc5c8..b27edb7f9d 100644 --- a/packages/backend-test-utils/src/database/mysql.ts +++ b/packages/backend-test-utils/src/database/mysql.ts @@ -235,7 +235,11 @@ export class MysqlEngine implements Engine { client: this.#properties.driver, connection, pool: { - acquireTimeoutMillis: 10000, + min: 0, + max: 1, + acquireTimeoutMillis: 20_000, + createTimeoutMillis: 20_000, + createRetryIntervalMillis: 1_000, }, }); } diff --git a/packages/backend/CHANGELOG.md b/packages/backend/CHANGELOG.md index e5555f42a0..3badfd2a9a 100644 --- a/packages/backend/CHANGELOG.md +++ b/packages/backend/CHANGELOG.md @@ -1,5 +1,151 @@ # example-backend +## 0.0.31-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.26.0-next.1 + - @backstage/plugin-catalog-backend@1.26.2-next.1 + - @backstage/backend-defaults@0.5.1-next.1 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-app-backend@0.3.75-next.0 + - @backstage/plugin-auth-backend@0.23.1-next.0 + - @backstage/plugin-auth-backend-module-github-provider@0.2.1-next.0 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.1-next.0 + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.4.1-next.0 + - @backstage/plugin-catalog-backend-module-openapi@0.2.2-next.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.1-next.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.5.1-next.0 + - @backstage/plugin-devtools-backend@0.4.1-next.0 + - @backstage/plugin-events-backend@0.3.13-next.0 + - @backstage/plugin-kubernetes-backend@0.18.7-next.0 + - @backstage/plugin-notifications-backend@0.4.1-next.0 + - @backstage/plugin-permission-backend@0.5.50-next.0 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.1-next.0 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-permission-node@0.8.4-next.0 + - @backstage/plugin-proxy-backend@0.5.7-next.0 + - @backstage/plugin-scaffolder-backend-module-github@0.5.1-next.1 + - @backstage/plugin-search-backend@1.5.18-next.1 + - @backstage/plugin-search-backend-module-catalog@0.2.3-next.1 + - @backstage/plugin-search-backend-module-explore@0.2.3-next.1 + - @backstage/plugin-search-backend-module-techdocs@0.2.3-next.1 + - @backstage/plugin-search-backend-node@1.3.3-next.1 + - @backstage/plugin-signals-backend@0.2.1-next.0 + - @backstage/plugin-techdocs-backend@1.10.14-next.1 + +## 0.0.31-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.26.0-next.0 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.1-next.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.5.1-next.0 + - @backstage/plugin-scaffolder-backend-module-github@0.5.1-next.0 + - @backstage/plugin-catalog-backend-module-openapi@0.2.1-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.2.3-next.0 + - @backstage/plugin-search-backend-module-catalog@0.2.3-next.0 + - @backstage/plugin-search-backend-module-explore@0.2.3-next.0 + - @backstage/plugin-notifications-backend@0.4.1-next.0 + - @backstage/plugin-search-backend-node@1.3.3-next.0 + - @backstage/plugin-kubernetes-backend@0.18.7-next.0 + - @backstage/plugin-permission-backend@0.5.50-next.0 + - @backstage/backend-defaults@0.5.1-next.0 + - @backstage/plugin-devtools-backend@0.4.1-next.0 + - @backstage/plugin-techdocs-backend@1.10.14-next.0 + - @backstage/plugin-catalog-backend@1.26.1-next.0 + - @backstage/plugin-permission-node@0.8.4-next.0 + - @backstage/plugin-signals-backend@0.2.1-next.0 + - @backstage/plugin-events-backend@0.3.13-next.0 + - @backstage/plugin-search-backend@1.5.18-next.0 + - @backstage/plugin-proxy-backend@0.5.7-next.0 + - @backstage/plugin-auth-backend@0.23.1-next.0 + - @backstage/plugin-app-backend@0.3.75-next.0 + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-auth-backend-module-github-provider@0.2.1-next.0 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.4.1-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.1-next.0 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.1-next.0 + - @backstage/plugin-permission-common@0.8.1 + +## 0.0.30 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.0 + - @backstage/plugin-kubernetes-backend@0.18.6 + - @backstage/plugin-signals-backend@0.2.0 + - @backstage/plugin-techdocs-backend@1.10.13 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-search-backend@1.5.17 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/plugin-devtools-backend@0.4.0 + - @backstage/plugin-app-backend@0.3.74 + - @backstage/plugin-notifications-backend@0.4.0 + - @backstage/plugin-scaffolder-backend@1.25.0 + - @backstage/plugin-auth-backend@0.23.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-catalog-backend@1.26.0 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.0 + - @backstage/plugin-search-backend-module-techdocs@0.2.2 + - @backstage/plugin-search-backend-module-catalog@0.2.2 + - @backstage/plugin-search-backend-module-explore@0.2.2 + - @backstage/plugin-permission-node@0.8.3 + - @backstage/plugin-permission-backend@0.5.49 + - @backstage/plugin-proxy-backend@0.5.6 + - @backstage/plugin-scaffolder-backend-module-github@0.5.0 + - @backstage/plugin-auth-backend-module-github-provider@0.2.0 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.4.0 + - @backstage/plugin-catalog-backend-module-openapi@0.2.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.5.0 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.0 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-backend-node@1.3.2 + +## 0.0.30-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.0-next.2 + - @backstage/plugin-devtools-backend@0.4.0-next.2 + - @backstage/plugin-scaffolder-backend@1.25.0-next.2 + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/plugin-auth-backend@0.23.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/plugin-catalog-backend@1.26.0-next.2 + - @backstage/plugin-app-backend@0.3.74-next.2 + - @backstage/plugin-notifications-backend@0.4.0-next.2 + - @backstage/plugin-scaffolder-backend-module-github@0.5.0-next.2 + - @backstage/plugin-auth-backend-module-github-provider@0.2.0-next.2 + - @backstage/plugin-kubernetes-backend@0.18.6-next.2 + - @backstage/plugin-permission-backend@0.5.49-next.2 + - @backstage/plugin-permission-node@0.8.3-next.2 + - @backstage/plugin-search-backend@1.5.17-next.2 + - @backstage/plugin-signals-backend@0.2.0-next.2 + - @backstage/plugin-techdocs-backend@1.10.13-next.2 + - @backstage/plugin-search-backend-module-explore@0.2.2-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.0-next.2 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.4.0-next.2 + - @backstage/plugin-catalog-backend-module-openapi@0.2.0-next.2 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.0-next.2 + - @backstage/plugin-catalog-backend-module-unprocessed@0.5.0-next.2 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.0-next.2 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-proxy-backend@0.5.6-next.2 + - @backstage/plugin-search-backend-module-catalog@0.2.2-next.2 + - @backstage/plugin-search-backend-module-techdocs@0.2.2-next.2 + - @backstage/plugin-search-backend-node@1.3.2-next.2 + ## 0.0.30-next.1 ### Patch Changes diff --git a/packages/backend/Dockerfile b/packages/backend/Dockerfile index b64a26afad..e07c266057 100644 --- a/packages/backend/Dockerfile +++ b/packages/backend/Dockerfile @@ -9,7 +9,7 @@ # # Once the commands have been run, you can build the image using `yarn build-image` -FROM node:18-bookworm-slim +FROM node:20-bookworm-slim # Install sqlite3 dependencies. You can skip this if you don't use sqlite3 in the image, # in which case you should also move better-sqlite3 to "devDependencies" in package.json. diff --git a/packages/backend/package.json b/packages/backend/package.json index 7f81417b31..e6f158c0d3 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -1,30 +1,33 @@ { "name": "example-backend", - "version": "0.0.30-next.1", - "main": "dist/index.cjs.js", - "types": "src/index.ts", - "license": "Apache-2.0", - "private": true, + "version": "0.0.31-next.1", "backstage": { "role": "backend" }, + "private": true, + "keywords": [ + "backstage" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "packages/backend" }, - "keywords": [ - "backstage" + "license": "Apache-2.0", + "main": "dist/index.cjs.js", + "types": "src/index.ts", + "files": [ + "dist" ], "scripts": { "build": "backstage-cli package build", + "build-image": "docker build ../.. -f Dockerfile --tag example-backend", "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", "start": "backstage-cli package start --require ./src/instrumentation.js", - "test": "backstage-cli package test", - "build-image": "docker build ../.. -f Dockerfile --tag example-backend", - "start:prometheus": "docker run --mount type=bind,source=./prometheus.yml,destination=/etc/prometheus/prometheus.yml --publish published=9090,target=9090,protocol=tcp prom/prometheus" + "start:prometheus": "docker run --mount type=bind,source=./prometheus.yml,destination=/etc/prometheus/prometheus.yml --publish published=9090,target=9090,protocol=tcp prom/prometheus", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-defaults": "workspace:^", @@ -41,6 +44,7 @@ "@backstage/plugin-catalog-backend-module-scaffolder-entity-model": "workspace:^", "@backstage/plugin-catalog-backend-module-unprocessed": "workspace:^", "@backstage/plugin-devtools-backend": "workspace:^", + "@backstage/plugin-events-backend": "workspace:^", "@backstage/plugin-kubernetes-backend": "workspace:^", "@backstage/plugin-notifications-backend": "workspace:^", "@backstage/plugin-permission-backend": "workspace:^", @@ -57,15 +61,12 @@ "@backstage/plugin-search-backend-node": "workspace:^", "@backstage/plugin-signals-backend": "workspace:^", "@backstage/plugin-techdocs-backend": "workspace:^", - "@opentelemetry/auto-instrumentations-node": "^0.49.0", + "@opentelemetry/auto-instrumentations-node": "^0.50.0", "@opentelemetry/exporter-prometheus": "^0.53.0", "@opentelemetry/sdk-node": "^0.53.0", "example-app": "link:../app" }, "devDependencies": { "@backstage/cli": "workspace:^" - }, - "files": [ - "dist" - ] + } } diff --git a/packages/backend/src/index.ts b/packages/backend/src/index.ts index 952f3315c4..3e8c2910b1 100644 --- a/packages/backend/src/index.ts +++ b/packages/backend/src/index.ts @@ -39,6 +39,7 @@ backend.add( import('@backstage/plugin-catalog-backend-module-scaffolder-entity-model'), ); backend.add(import('@backstage/plugin-catalog-backend/alpha')); +backend.add(import('@backstage/plugin-events-backend/alpha')); backend.add(import('@backstage/plugin-devtools-backend')); backend.add(import('@backstage/plugin-kubernetes-backend/alpha')); backend.add( diff --git a/packages/catalog-client/CHANGELOG.md b/packages/catalog-client/CHANGELOG.md index cf175a3d23..7ccd4ebced 100644 --- a/packages/catalog-client/CHANGELOG.md +++ b/packages/catalog-client/CHANGELOG.md @@ -1,5 +1,34 @@ # @backstage/catalog-client +## 1.7.0 + +### Minor Changes + +- 78475c3: Allow offset mode paging in entity list provider +- 29e57c7: Add catalog service mocks under the `/testUtils` subpath export. + +### Patch Changes + +- 1882cfe: Moved `getEntities` ordering to utilize database instead of having it inside catalog client + + Please note that the latest version of `@backstage/catalog-client` will not order the entities in the same way as before. This is because the ordering is now done in the database query instead of in the client. If you rely on the ordering of the entities, you may need to update your backend plugin or code to handle this change. + +- Updated dependencies + - @backstage/catalog-model@1.7.0 + - @backstage/errors@1.2.4 + +## 1.7.0-next.1 + +### Minor Changes + +- 78475c3: Allow offset mode paging in entity list provider + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.6.0 + - @backstage/errors@1.2.4 + ## 1.6.7-next.0 ### Patch Changes diff --git a/packages/catalog-client/package.json b/packages/catalog-client/package.json index b0568e0b0d..2bf8d5cd88 100644 --- a/packages/catalog-client/package.json +++ b/packages/catalog-client/package.json @@ -1,15 +1,12 @@ { "name": "@backstage/catalog-client", - "version": "1.6.7-next.0", + "version": "1.7.0", "description": "An isomorphic client for the catalog backend", "backstage": { "role": "common-library" }, "publishConfig": { - "access": "public", - "main": "dist/index.cjs.js", - "module": "dist/index.esm.js", - "types": "dist/index.d.ts" + "access": "public" }, "keywords": [ "backstage" @@ -22,8 +19,23 @@ }, "license": "Apache-2.0", "sideEffects": false, + "exports": { + ".": "./src/index.ts", + "./testUtils": "./src/testUtils.ts", + "./package.json": "./package.json" + }, "main": "src/index.ts", "types": "src/index.ts", + "typesVersions": { + "*": { + "testUtils": [ + "src/testUtils.ts" + ], + "package.json": [ + "package.json" + ] + } + }, "files": [ "dist" ], diff --git a/packages/catalog-client/report-testUtils.api.md b/packages/catalog-client/report-testUtils.api.md new file mode 100644 index 0000000000..9341327554 --- /dev/null +++ b/packages/catalog-client/report-testUtils.api.md @@ -0,0 +1,88 @@ +## API Report File for "@backstage/catalog-client" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { AddLocationRequest } from '@backstage/catalog-client'; +import { AddLocationResponse } from '@backstage/catalog-client'; +import { CatalogApi } from '@backstage/catalog-client'; +import { CompoundEntityRef } from '@backstage/catalog-model'; +import { Entity } from '@backstage/catalog-model'; +import { GetEntitiesByRefsRequest } from '@backstage/catalog-client'; +import { GetEntitiesByRefsResponse } from '@backstage/catalog-client'; +import { GetEntitiesRequest } from '@backstage/catalog-client'; +import { GetEntitiesResponse } from '@backstage/catalog-client'; +import { GetEntityAncestorsRequest } from '@backstage/catalog-client'; +import { GetEntityAncestorsResponse } from '@backstage/catalog-client'; +import { GetEntityFacetsRequest } from '@backstage/catalog-client'; +import { GetEntityFacetsResponse } from '@backstage/catalog-client'; +import { Location as Location_2 } from '@backstage/catalog-client'; +import { QueryEntitiesRequest } from '@backstage/catalog-client'; +import { QueryEntitiesResponse } from '@backstage/catalog-client'; +import { ValidateEntityResponse } from '@backstage/catalog-client'; + +// @public +export class InMemoryCatalogClient implements CatalogApi { + constructor(options?: { entities?: Entity[] }); + // (undocumented) + addLocation(_location: AddLocationRequest): Promise; + // (undocumented) + getEntities(request?: GetEntitiesRequest): Promise; + // (undocumented) + getEntitiesByRefs( + request: GetEntitiesByRefsRequest, + ): Promise; + // (undocumented) + getEntityAncestors( + request: GetEntityAncestorsRequest, + ): Promise; + // (undocumented) + getEntityByRef( + entityRef: string | CompoundEntityRef, + ): Promise; + // (undocumented) + getEntityFacets( + request: GetEntityFacetsRequest, + ): Promise; + // (undocumented) + getLocationByEntity( + _entityRef: string | CompoundEntityRef, + ): Promise; + // (undocumented) + getLocationById(_id: string): Promise; + // (undocumented) + getLocationByRef(_locationRef: string): Promise; + // (undocumented) + queryEntities(request?: QueryEntitiesRequest): Promise; + // (undocumented) + refreshEntity(_entityRef: string): Promise; + // (undocumented) + removeEntityByUid(uid: string): Promise; + // (undocumented) + removeLocationById(_id: string): Promise; + // (undocumented) + validateEntity( + _entity: Entity, + _locationRef: string, + ): Promise; +} + +// Warnings were encountered during analysis: +// +// src/testUtils/InMemoryCatalogClient.d.ts:15:5 - (ae-undocumented) Missing documentation for "getEntities". +// src/testUtils/InMemoryCatalogClient.d.ts:16:5 - (ae-undocumented) Missing documentation for "getEntitiesByRefs". +// src/testUtils/InMemoryCatalogClient.d.ts:17:5 - (ae-undocumented) Missing documentation for "queryEntities". +// src/testUtils/InMemoryCatalogClient.d.ts:18:5 - (ae-undocumented) Missing documentation for "getEntityAncestors". +// src/testUtils/InMemoryCatalogClient.d.ts:19:5 - (ae-undocumented) Missing documentation for "getEntityByRef". +// src/testUtils/InMemoryCatalogClient.d.ts:20:5 - (ae-undocumented) Missing documentation for "removeEntityByUid". +// src/testUtils/InMemoryCatalogClient.d.ts:21:5 - (ae-undocumented) Missing documentation for "refreshEntity". +// src/testUtils/InMemoryCatalogClient.d.ts:22:5 - (ae-undocumented) Missing documentation for "getEntityFacets". +// src/testUtils/InMemoryCatalogClient.d.ts:23:5 - (ae-undocumented) Missing documentation for "getLocationById". +// src/testUtils/InMemoryCatalogClient.d.ts:24:5 - (ae-undocumented) Missing documentation for "getLocationByRef". +// src/testUtils/InMemoryCatalogClient.d.ts:25:5 - (ae-undocumented) Missing documentation for "addLocation". +// src/testUtils/InMemoryCatalogClient.d.ts:26:5 - (ae-undocumented) Missing documentation for "removeLocationById". +// src/testUtils/InMemoryCatalogClient.d.ts:27:5 - (ae-undocumented) Missing documentation for "getLocationByEntity". +// src/testUtils/InMemoryCatalogClient.d.ts:28:5 - (ae-undocumented) Missing documentation for "validateEntity". + +// (No @packageDocumentation comment for this package) +``` diff --git a/packages/catalog-client/api-report.md b/packages/catalog-client/report.api.md similarity index 92% rename from packages/catalog-client/api-report.md rename to packages/catalog-client/report.api.md index ce25990fd0..aba99961f0 100644 --- a/packages/catalog-client/api-report.md +++ b/packages/catalog-client/report.api.md @@ -269,6 +269,7 @@ export type QueryEntitiesCursorRequest = { export type QueryEntitiesInitialRequest = { fields?: string[]; limit?: number; + offset?: number; filter?: EntityFilterQuery; orderFields?: EntityOrderQuery; fullTextFilter?: { @@ -301,4 +302,13 @@ export type ValidateEntityResponse = valid: false; errors: SerializedError[]; }; + +// Warnings were encountered during analysis: +// +// src/CatalogClient.d.ts:50:5 - (ae-undocumented) Missing documentation for "getEntityByName". +// src/types/api.d.ts:154:5 - (ae-undocumented) Missing documentation for "items". +// src/types/api.d.ts:203:5 - (ae-undocumented) Missing documentation for "entityRef". +// src/types/api.d.ts:211:5 - (ae-undocumented) Missing documentation for "rootEntityRef". +// src/types/api.d.ts:212:5 - (ae-undocumented) Missing documentation for "items". +// src/types/api.d.ts:305:5 - (ae-undocumented) Missing documentation for "token". ``` diff --git a/packages/catalog-client/src/CatalogClient.ts b/packages/catalog-client/src/CatalogClient.ts index 2e7912b69a..4de314c1e8 100644 --- a/packages/catalog-client/src/CatalogClient.ts +++ b/packages/catalog-client/src/CatalogClient.ts @@ -191,6 +191,7 @@ export class CatalogClient implements CatalogApi { fields = [], filter, limit, + offset, orderFields, fullTextFilter, } = request; @@ -199,6 +200,9 @@ export class CatalogClient implements CatalogApi { if (limit !== undefined) { params.limit = limit; } + if (offset !== undefined) { + params.offset = offset; + } if (orderFields !== undefined) { params.orderField = ( Array.isArray(orderFields) ? orderFields : [orderFields] diff --git a/packages/catalog-client/src/generated/apis/DefaultApi.client.ts b/packages/catalog-client/src/generated/apis/DefaultApi.client.ts index 7619e69504..1f1c54d6f8 100644 --- a/packages/catalog-client/src/generated/apis/DefaultApi.client.ts +++ b/packages/catalog-client/src/generated/apis/DefaultApi.client.ts @@ -247,6 +247,7 @@ export class DefaultApiClient { query: { fields?: Array; limit?: number; + offset?: number; orderField?: Array; cursor?: string; filter?: Array; @@ -258,7 +259,7 @@ export class DefaultApiClient { ): Promise> { const baseUrl = await this.discoveryApi.getBaseUrl(pluginId); - const uriTemplate = `/entities/by-query{?fields,limit,orderField*,cursor,filter*,fullTextFilterTerm,fullTextFilterFields}`; + const uriTemplate = `/entities/by-query{?fields,limit,offset,orderField*,cursor,filter*,fullTextFilterTerm,fullTextFilterFields}`; const uri = parser.parse(uriTemplate).expand({ ...request.query, diff --git a/packages/catalog-client/src/testUtils.ts b/packages/catalog-client/src/testUtils.ts new file mode 100644 index 0000000000..15017c7fa0 --- /dev/null +++ b/packages/catalog-client/src/testUtils.ts @@ -0,0 +1,17 @@ +/* + * 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. + */ + +export { InMemoryCatalogClient } from './testUtils/InMemoryCatalogClient'; diff --git a/packages/catalog-client/src/testUtils/InMemoryCatalogClient.test.ts b/packages/catalog-client/src/testUtils/InMemoryCatalogClient.test.ts new file mode 100644 index 0000000000..3f3eaed477 --- /dev/null +++ b/packages/catalog-client/src/testUtils/InMemoryCatalogClient.test.ts @@ -0,0 +1,129 @@ +/* + * 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 { InMemoryCatalogClient } from './InMemoryCatalogClient'; +import { Entity } from '@backstage/catalog-model'; + +const entity1: Entity = { + apiVersion: 'v1', + kind: 'CustomKind', + metadata: { + namespace: 'default', + name: 'e1', + uid: 'u1', + }, +}; + +const entity2: Entity = { + apiVersion: 'v1', + kind: 'CustomKind', + metadata: { + namespace: 'default', + name: 'e2', + uid: 'u2', + }, +}; + +const entities = [entity1, entity2]; + +describe('InMemoryCatalogClient', () => { + it('getEntities', async () => { + const client = new InMemoryCatalogClient({ entities }); + await expect(client.getEntities()).resolves.toEqual({ items: entities }); + await expect( + client.getEntities({ filter: { 'metadata.uid': 'u2' } }), + ).resolves.toEqual({ items: [entity2] }); + }); + + it('getEntitiesByRefs', async () => { + const client = new InMemoryCatalogClient({ entities }); + await expect( + client.getEntitiesByRefs({ + entityRefs: [ + 'customkind:default/e2', + 'customkind:missing/missing', + 'customkind:default/e1', + ], + }), + ).resolves.toEqual({ items: [entity2, undefined, entity1] }); + await expect( + client.getEntitiesByRefs({ + entityRefs: [ + 'customkind:default/e2', + 'customkind:missing/missing', + 'customkind:default/e1', + ], + filter: { 'metadata.uid': 'u1' }, + }), + ).resolves.toEqual({ items: [undefined, undefined, entity1] }); + }); + + it('queryEntities', async () => { + const client = new InMemoryCatalogClient({ entities }); + await expect(client.queryEntities()).resolves.toEqual({ + items: entities, + totalItems: 2, + pageInfo: {}, + }); + await expect( + client.queryEntities({ filter: { 'metadata.uid': 'u2' } }), + ).resolves.toEqual({ + items: [entity2], + totalItems: 1, + pageInfo: {}, + }); + }); + + it('getEntityAncestors', async () => { + const client = new InMemoryCatalogClient({ entities }); + await expect( + client.getEntityAncestors({ entityRef: 'customkind:default/e2' }), + ).resolves.toEqual({ + rootEntityRef: 'customkind:default/e2', + items: [{ entity: entity2, parentEntityRefs: [] }], + }); + }); + + it('getEntityByRef', async () => { + const client = new InMemoryCatalogClient({ entities }); + await expect( + client.getEntityByRef('customkind:default/e2'), + ).resolves.toEqual(entity2); + await expect( + client.getEntityByRef('customkind:missing/missing'), + ).resolves.toBeUndefined(); + }); + + it('removeEntityByUid', async () => { + const client = new InMemoryCatalogClient({ entities }); + await expect(client.getEntities()).resolves.toEqual({ + items: expect.arrayContaining([entity2]), + }); + await expect( + client.removeEntityByUid(entity2.metadata.uid!), + ).resolves.toBeUndefined(); + await expect(client.getEntities()).resolves.not.toEqual({ + items: expect.arrayContaining([entity2]), + }); + }); + + it('refreshEntity', async () => { + const client = new InMemoryCatalogClient({ entities }); + await expect( + client.refreshEntity('customkind:default/e2'), + ).resolves.toBeUndefined(); + }); +}); diff --git a/packages/catalog-client/src/testUtils/InMemoryCatalogClient.ts b/packages/catalog-client/src/testUtils/InMemoryCatalogClient.ts new file mode 100644 index 0000000000..355a10bf0e --- /dev/null +++ b/packages/catalog-client/src/testUtils/InMemoryCatalogClient.ts @@ -0,0 +1,256 @@ +/* + * 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 { + AddLocationRequest, + AddLocationResponse, + CATALOG_FILTER_EXISTS, + CatalogApi, + EntityFilterQuery, + GetEntitiesByRefsRequest, + GetEntitiesByRefsResponse, + GetEntitiesRequest, + GetEntitiesResponse, + GetEntityAncestorsRequest, + GetEntityAncestorsResponse, + GetEntityFacetsRequest, + GetEntityFacetsResponse, + Location, + QueryEntitiesRequest, + QueryEntitiesResponse, + ValidateEntityResponse, +} from '@backstage/catalog-client'; +import { + CompoundEntityRef, + DEFAULT_NAMESPACE, + Entity, + parseEntityRef, + stringifyEntityRef, +} from '@backstage/catalog-model'; +import { NotFoundError, NotImplementedError } from '@backstage/errors'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { traverse } from '../../../../plugins/catalog-backend/src/database/operations/stitcher/buildEntitySearch'; + +function buildEntitySearch(entity: Entity) { + const rows = traverse(entity); + + if (entity.metadata?.name) { + rows.push({ key: 'metadata.name', value: entity.metadata.name }); + } + if (entity.metadata?.namespace) { + rows.push({ key: 'metadata.namespace', value: entity.metadata.namespace }); + } + if (entity.metadata?.uid) { + rows.push({ key: 'metadata.uid', value: entity.metadata.uid }); + } + + if (!entity.metadata.namespace) { + rows.push({ key: 'metadata.namespace', value: DEFAULT_NAMESPACE }); + } + + // Visit relations + for (const relation of entity.relations ?? []) { + rows.push({ + key: `relations.${relation.type}`, + value: relation.targetRef, + }); + } + + return rows; +} + +function createFilter( + filterOrFilters?: EntityFilterQuery, +): (entity: Entity) => boolean { + if (!filterOrFilters) { + return () => true; + } + + const filters = [filterOrFilters].flat(); + + return entity => { + const rows = buildEntitySearch(entity); + + return filters.some(filter => { + for (const [key, expectedValue] of Object.entries(filter)) { + const searchValues = rows + .filter(row => row.key === key.toLocaleLowerCase('en-US')) + .map(row => row.value?.toString().toLocaleLowerCase('en-US')); + + if (searchValues.length === 0) { + return false; + } + if (expectedValue === CATALOG_FILTER_EXISTS) { + continue; + } + if ( + !searchValues?.includes( + String(expectedValue).toLocaleLowerCase('en-US'), + ) + ) { + return false; + } + } + return true; + }); + }; +} + +/** + * Implements a VERY basic fake catalog client that stores entities in memory. + * It has severely limited functionality, and is only useful under certain + * circumstances in tests. + * + * @public + */ +export class InMemoryCatalogClient implements CatalogApi { + #entities: Entity[]; + + constructor(options?: { entities?: Entity[] }) { + this.#entities = options?.entities?.slice() ?? []; + } + + async getEntities( + request?: GetEntitiesRequest, + ): Promise { + const filter = createFilter(request?.filter); + return { items: this.#entities.filter(filter) }; + } + + async getEntitiesByRefs( + request: GetEntitiesByRefsRequest, + ): Promise { + const filter = createFilter(request.filter); + const refMap = this.#createEntityRefMap(); + return { + items: request.entityRefs + .map(ref => refMap.get(ref)) + .map(e => (e && filter(e) ? e : undefined)), + }; + } + + async queryEntities( + request?: QueryEntitiesRequest, + ): Promise { + if (request && 'cursor' in request) { + return { items: [], pageInfo: {}, totalItems: 0 }; + } + const filter = createFilter(request?.filter); + const items = this.#entities.filter(filter); + // TODO(Rugvip): Pagination + return { + items, + pageInfo: {}, + totalItems: items.length, + }; + } + + async getEntityAncestors( + request: GetEntityAncestorsRequest, + ): Promise { + const entity = this.#createEntityRefMap().get(request.entityRef); + if (!entity) { + throw new NotFoundError(`Entity with ref ${request.entityRef} not found`); + } + return { + items: [{ entity, parentEntityRefs: [] }], + rootEntityRef: request.entityRef, + }; + } + + async getEntityByRef( + entityRef: string | CompoundEntityRef, + ): Promise { + return this.#createEntityRefMap().get( + stringifyEntityRef(parseEntityRef(entityRef)), + ); + } + + async removeEntityByUid(uid: string): Promise { + const index = this.#entities.findIndex(e => e.metadata.uid === uid); + if (index !== -1) { + this.#entities.splice(index, 1); + } + } + + async refreshEntity(_entityRef: string): Promise {} + + async getEntityFacets( + request: GetEntityFacetsRequest, + ): Promise { + const filter = createFilter(request.filter); + const filteredEntities = this.#entities.filter(filter); + const facets = Object.fromEntries( + request.facets.map(facet => { + const facetValues = new Map(); + for (const entity of filteredEntities) { + const rows = buildEntitySearch(entity); + const value = rows.find( + row => row.key === facet.toLocaleLowerCase('en-US'), + )?.value; + if (value) { + facetValues.set( + String(value), + (facetValues.get(String(value)) ?? 0) + 1, + ); + } + } + const counts = Array.from(facetValues.entries()).map( + ([value, count]) => ({ value, count }), + ); + return [facet, counts]; + }), + ); + return { + facets, + }; + } + + async getLocationById(_id: string): Promise { + throw new NotImplementedError('Method not implemented.'); + } + + async getLocationByRef(_locationRef: string): Promise { + throw new NotImplementedError('Method not implemented.'); + } + + async addLocation( + _location: AddLocationRequest, + ): Promise { + throw new NotImplementedError('Method not implemented.'); + } + + async removeLocationById(_id: string): Promise { + throw new NotImplementedError('Method not implemented.'); + } + + async getLocationByEntity( + _entityRef: string | CompoundEntityRef, + ): Promise { + throw new NotImplementedError('Method not implemented.'); + } + + async validateEntity( + _entity: Entity, + _locationRef: string, + ): Promise { + throw new NotImplementedError('Method not implemented.'); + } + + #createEntityRefMap() { + return new Map(this.#entities.map(e => [stringifyEntityRef(e), e])); + } +} diff --git a/packages/catalog-client/src/types/api.ts b/packages/catalog-client/src/types/api.ts index 7eded50776..c8fbc7e7ac 100644 --- a/packages/catalog-client/src/types/api.ts +++ b/packages/catalog-client/src/types/api.ts @@ -412,6 +412,7 @@ export type QueryEntitiesRequest = export type QueryEntitiesInitialRequest = { fields?: string[]; limit?: number; + offset?: number; filter?: EntityFilterQuery; orderFields?: EntityOrderQuery; fullTextFilter?: { diff --git a/packages/catalog-client/src/utils.ts b/packages/catalog-client/src/utils.ts index de21cea0d4..9d51c34e71 100644 --- a/packages/catalog-client/src/utils.ts +++ b/packages/catalog-client/src/utils.ts @@ -17,7 +17,6 @@ import { QueryEntitiesCursorRequest, QueryEntitiesInitialRequest, - QueryEntitiesRequest, } from './types/api'; export function isQueryEntitiesInitialRequest( @@ -25,9 +24,3 @@ export function isQueryEntitiesInitialRequest( ): request is QueryEntitiesInitialRequest { return !(request as QueryEntitiesCursorRequest).cursor; } - -export function isQueryEntitiesCursorRequest( - request: QueryEntitiesRequest, -): request is QueryEntitiesCursorRequest { - return !isQueryEntitiesInitialRequest(request); -} diff --git a/packages/catalog-model/CHANGELOG.md b/packages/catalog-model/CHANGELOG.md index 1242c48f31..005fd75e58 100644 --- a/packages/catalog-model/CHANGELOG.md +++ b/packages/catalog-model/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/catalog-model +## 1.7.0 + +### Minor Changes + +- 74acf06: Add `dependencyOf` prop to catalog model for Component kind to enable building relationship graphs with both directions using `dependsOn` and `dependencyOf`. + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 1.6.0 ### Minor Changes diff --git a/packages/catalog-model/package.json b/packages/catalog-model/package.json index 150317aee1..6e26a011d9 100644 --- a/packages/catalog-model/package.json +++ b/packages/catalog-model/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/catalog-model", - "version": "1.6.0", + "version": "1.7.0", "description": "Types and validators that help describe the model of a Backstage Catalog", "backstage": { "role": "common-library" diff --git a/packages/catalog-model/api-report-alpha.md b/packages/catalog-model/report-alpha.api.md similarity index 100% rename from packages/catalog-model/api-report-alpha.md rename to packages/catalog-model/report-alpha.api.md diff --git a/packages/catalog-model/api-report.md b/packages/catalog-model/report.api.md similarity index 70% rename from packages/catalog-model/api-report.md rename to packages/catalog-model/report.api.md index de941e2502..07dc6affd7 100644 --- a/packages/catalog-model/api-report.md +++ b/packages/catalog-model/report.api.md @@ -87,6 +87,7 @@ interface ComponentEntityV1alpha1 extends Entity { providesApis?: string[]; consumesApis?: string[]; dependsOn?: string[]; + dependencyOf?: string[]; system?: string; }; } @@ -498,4 +499,52 @@ export type Validators = { isValidAnnotationValue(value: unknown): boolean; isValidTag(value: unknown): boolean; }; + +// Warnings were encountered during analysis: +// +// src/entity/conditions.d.ts:6:1 - (ae-undocumented) Missing documentation for "isApiEntity". +// src/entity/conditions.d.ts:10:1 - (ae-undocumented) Missing documentation for "isComponentEntity". +// src/entity/conditions.d.ts:14:1 - (ae-undocumented) Missing documentation for "isDomainEntity". +// src/entity/conditions.d.ts:18:1 - (ae-undocumented) Missing documentation for "isGroupEntity". +// src/entity/conditions.d.ts:22:1 - (ae-undocumented) Missing documentation for "isLocationEntity". +// src/entity/conditions.d.ts:26:1 - (ae-undocumented) Missing documentation for "isResourceEntity". +// src/entity/conditions.d.ts:30:1 - (ae-undocumented) Missing documentation for "isSystemEntity". +// src/entity/conditions.d.ts:34:1 - (ae-undocumented) Missing documentation for "isUserEntity". +// src/entity/policies/DefaultNamespaceEntityPolicy.d.ts:11:5 - (ae-undocumented) Missing documentation for "enforce". +// src/entity/policies/FieldFormatEntityPolicy.d.ts:17:5 - (ae-undocumented) Missing documentation for "enforce". +// src/entity/policies/GroupDefaultParentEntityPolicy.d.ts:14:5 - (ae-undocumented) Missing documentation for "enforce". +// src/entity/policies/NoForeignRootFieldsEntityPolicy.d.ts:11:5 - (ae-undocumented) Missing documentation for "enforce". +// src/entity/policies/SchemaValidEntityPolicy.d.ts:16:5 - (ae-undocumented) Missing documentation for "enforce". +// src/kinds/ApiEntityV1alpha1.d.ts:12:5 - (ae-undocumented) Missing documentation for "apiVersion". +// src/kinds/ApiEntityV1alpha1.d.ts:13:5 - (ae-undocumented) Missing documentation for "kind". +// src/kinds/ApiEntityV1alpha1.d.ts:14:5 - (ae-undocumented) Missing documentation for "spec". +// src/kinds/ComponentEntityV1alpha1.d.ts:12:5 - (ae-undocumented) Missing documentation for "apiVersion". +// src/kinds/ComponentEntityV1alpha1.d.ts:13:5 - (ae-undocumented) Missing documentation for "kind". +// src/kinds/ComponentEntityV1alpha1.d.ts:14:5 - (ae-undocumented) Missing documentation for "spec". +// src/kinds/DomainEntityV1alpha1.d.ts:12:5 - (ae-undocumented) Missing documentation for "apiVersion". +// src/kinds/DomainEntityV1alpha1.d.ts:13:5 - (ae-undocumented) Missing documentation for "kind". +// src/kinds/DomainEntityV1alpha1.d.ts:14:5 - (ae-undocumented) Missing documentation for "spec". +// src/kinds/GroupEntityV1alpha1.d.ts:8:5 - (ae-undocumented) Missing documentation for "apiVersion". +// src/kinds/GroupEntityV1alpha1.d.ts:9:5 - (ae-undocumented) Missing documentation for "kind". +// src/kinds/GroupEntityV1alpha1.d.ts:10:5 - (ae-undocumented) Missing documentation for "spec". +// src/kinds/LocationEntityV1alpha1.d.ts:8:5 - (ae-undocumented) Missing documentation for "apiVersion". +// src/kinds/LocationEntityV1alpha1.d.ts:9:5 - (ae-undocumented) Missing documentation for "kind". +// src/kinds/LocationEntityV1alpha1.d.ts:10:5 - (ae-undocumented) Missing documentation for "spec". +// src/kinds/ResourceEntityV1alpha1.d.ts:12:5 - (ae-undocumented) Missing documentation for "apiVersion". +// src/kinds/ResourceEntityV1alpha1.d.ts:13:5 - (ae-undocumented) Missing documentation for "kind". +// src/kinds/ResourceEntityV1alpha1.d.ts:14:5 - (ae-undocumented) Missing documentation for "spec". +// src/kinds/SystemEntityV1alpha1.d.ts:12:5 - (ae-undocumented) Missing documentation for "apiVersion". +// src/kinds/SystemEntityV1alpha1.d.ts:13:5 - (ae-undocumented) Missing documentation for "kind". +// src/kinds/SystemEntityV1alpha1.d.ts:14:5 - (ae-undocumented) Missing documentation for "spec". +// src/kinds/UserEntityV1alpha1.d.ts:8:5 - (ae-undocumented) Missing documentation for "apiVersion". +// src/kinds/UserEntityV1alpha1.d.ts:9:5 - (ae-undocumented) Missing documentation for "kind". +// src/kinds/UserEntityV1alpha1.d.ts:10:5 - (ae-undocumented) Missing documentation for "spec". +// src/validation/KubernetesValidatorFunctions.d.ts:11:5 - (ae-undocumented) Missing documentation for "isValidApiVersion". +// src/validation/KubernetesValidatorFunctions.d.ts:12:5 - (ae-undocumented) Missing documentation for "isValidKind". +// src/validation/KubernetesValidatorFunctions.d.ts:13:5 - (ae-undocumented) Missing documentation for "isValidObjectName". +// src/validation/KubernetesValidatorFunctions.d.ts:14:5 - (ae-undocumented) Missing documentation for "isValidNamespace". +// src/validation/KubernetesValidatorFunctions.d.ts:15:5 - (ae-undocumented) Missing documentation for "isValidLabelKey". +// src/validation/KubernetesValidatorFunctions.d.ts:16:5 - (ae-undocumented) Missing documentation for "isValidLabelValue". +// src/validation/KubernetesValidatorFunctions.d.ts:17:5 - (ae-undocumented) Missing documentation for "isValidAnnotationKey". +// src/validation/KubernetesValidatorFunctions.d.ts:18:5 - (ae-undocumented) Missing documentation for "isValidAnnotationValue". ``` diff --git a/packages/catalog-model/src/kinds/ComponentEntityV1alpha1.ts b/packages/catalog-model/src/kinds/ComponentEntityV1alpha1.ts index f931eab553..9a68d26cac 100644 --- a/packages/catalog-model/src/kinds/ComponentEntityV1alpha1.ts +++ b/packages/catalog-model/src/kinds/ComponentEntityV1alpha1.ts @@ -38,6 +38,7 @@ export interface ComponentEntityV1alpha1 extends Entity { providesApis?: string[]; consumesApis?: string[]; dependsOn?: string[]; + dependencyOf?: string[]; system?: string; }; } diff --git a/packages/cli-common/api-report.md b/packages/cli-common/report.api.md similarity index 100% rename from packages/cli-common/api-report.md rename to packages/cli-common/report.api.md diff --git a/packages/cli-node/CHANGELOG.md b/packages/cli-node/CHANGELOG.md index 21995e4812..289dd17304 100644 --- a/packages/cli-node/CHANGELOG.md +++ b/packages/cli-node/CHANGELOG.md @@ -1,5 +1,25 @@ # @backstage/cli-node +## 0.2.8 + +### Patch Changes + +- 0c70f43: Add definition for the new `backstage.inline` field in `package.json`. +- Updated dependencies + - @backstage/cli-common@0.1.14 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## 0.2.8-next.0 + +### Patch Changes + +- 0c70f43: Add definition for the new `backstage.inline` field in `package.json`. +- Updated dependencies + - @backstage/cli-common@0.1.14 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.2.7 ### Patch Changes diff --git a/packages/cli-node/package.json b/packages/cli-node/package.json index c727918510..7b13facb8b 100644 --- a/packages/cli-node/package.json +++ b/packages/cli-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/cli-node", - "version": "0.2.7", + "version": "0.2.8", "description": "Node.js library for Backstage CLIs", "backstage": { "role": "node-library" diff --git a/packages/cli-node/api-report.md b/packages/cli-node/report.api.md similarity index 67% rename from packages/cli-node/api-report.md rename to packages/cli-node/report.api.md index 9f7e525048..97dab9684d 100644 --- a/packages/cli-node/api-report.md +++ b/packages/cli-node/report.api.md @@ -18,6 +18,7 @@ export interface BackstagePackageJson { backstage?: { role?: PackageRole; moved?: string; + inline?: boolean; pluginId?: string | null; pluginPackage?: string; pluginPackages?: string[]; @@ -174,4 +175,28 @@ export class PackageRoles { static getRoleFromPackage(pkgJson: unknown): PackageRole | undefined; static getRoleInfo(role: string): PackageRoleInfo; } + +// Warnings were encountered during analysis: +// +// src/monorepo/PackageGraph.d.ts:10:5 - (ae-undocumented) Missing documentation for "name". +// src/monorepo/PackageGraph.d.ts:11:5 - (ae-undocumented) Missing documentation for "version". +// src/monorepo/PackageGraph.d.ts:12:5 - (ae-undocumented) Missing documentation for "private". +// src/monorepo/PackageGraph.d.ts:13:5 - (ae-undocumented) Missing documentation for "main". +// src/monorepo/PackageGraph.d.ts:14:5 - (ae-undocumented) Missing documentation for "module". +// src/monorepo/PackageGraph.d.ts:15:5 - (ae-undocumented) Missing documentation for "types". +// src/monorepo/PackageGraph.d.ts:16:5 - (ae-undocumented) Missing documentation for "scripts". +// src/monorepo/PackageGraph.d.ts:19:5 - (ae-undocumented) Missing documentation for "bundled". +// src/monorepo/PackageGraph.d.ts:20:5 - (ae-undocumented) Missing documentation for "backstage". +// src/monorepo/PackageGraph.d.ts:44:5 - (ae-undocumented) Missing documentation for "exports". +// src/monorepo/PackageGraph.d.ts:45:5 - (ae-undocumented) Missing documentation for "typesVersions". +// src/monorepo/PackageGraph.d.ts:46:5 - (ae-undocumented) Missing documentation for "files". +// src/monorepo/PackageGraph.d.ts:47:5 - (ae-undocumented) Missing documentation for "publishConfig". +// src/monorepo/PackageGraph.d.ts:52:5 - (ae-undocumented) Missing documentation for "repository". +// src/monorepo/PackageGraph.d.ts:57:5 - (ae-undocumented) Missing documentation for "dependencies". +// src/monorepo/PackageGraph.d.ts:60:5 - (ae-undocumented) Missing documentation for "peerDependencies". +// src/monorepo/PackageGraph.d.ts:63:5 - (ae-undocumented) Missing documentation for "devDependencies". +// src/monorepo/PackageGraph.d.ts:66:5 - (ae-undocumented) Missing documentation for "optionalDependencies". +// src/roles/types.d.ts:25:5 - (ae-undocumented) Missing documentation for "role". +// src/roles/types.d.ts:26:5 - (ae-undocumented) Missing documentation for "platform". +// src/roles/types.d.ts:27:5 - (ae-undocumented) Missing documentation for "output". ``` diff --git a/packages/cli-node/src/monorepo/Lockfile.test.ts b/packages/cli-node/src/monorepo/Lockfile.test.ts index 41beeb4408..4bc7a6d96e 100644 --- a/packages/cli-node/src/monorepo/Lockfile.test.ts +++ b/packages/cli-node/src/monorepo/Lockfile.test.ts @@ -277,7 +277,7 @@ d@^1: version: 0.0.0-use.local resolution: "@backstage/backend-app-api@workspace:packages/backend-app-api" dependencies: - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": "^0.25.0" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-tasks": "workspace:^" "@backstage/cli": "workspace:^" @@ -330,7 +330,7 @@ d@^1: version: 0.0.0-use.local resolution: "@backstage/backend-app-api@workspace:packages/backend-app-api" dependencies: - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": "^0.25.0" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-tasks": "workspace:^" "@backstage/cli": "workspace:^" diff --git a/packages/cli-node/src/monorepo/PackageGraph.ts b/packages/cli-node/src/monorepo/PackageGraph.ts index c8877803d5..69ec99c2dd 100644 --- a/packages/cli-node/src/monorepo/PackageGraph.ts +++ b/packages/cli-node/src/monorepo/PackageGraph.ts @@ -47,6 +47,15 @@ export interface BackstagePackageJson { role?: PackageRole; moved?: string; + /** + * If set to `true`, the package will be treated as an internal package + * where any imports will be inlined into the consuming package. + * + * When set to `true`, the top-level `private` field must be set to `true` + * as well. + */ + inline?: boolean; + /** * The ID of the plugin if this is a plugin package. Must always be set for plugin and module packages, and may be set for library packages. A `null` value means that the package is explicitly not a plugin package. */ diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index 05a9574f3a..341c8d1a2f 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,124 @@ # @backstage/cli +## 0.28.0-next.1 + +### Minor Changes + +- 55b8b84: **BREAKING**: The Jest configuration defined at `@backstage/cli/config/jest` no longer collects configuration defined in the `"jest"` field from all parent `package.json` files. Instead, it will only read and merge configuration from the `package.json` in the monorepo root if it exists, as well as the target package. In addition, configuration defined in the root `package.json` will now only be merged into each package configuration if it is a valid project-level configuration key. + +### Patch Changes + +- 03810d2: Remove unknown dependency `diff` +- cebee4f: Added support for a new experimental `EXPERIMENTAL_TRIM_NEXT_ENTRY` flag which removes any `./next` entry points present in packages when building and publishing. +- 55b8b84: The Jest configuration will now search for a `src/setupTests.*` file with any valid script extension, not only `.ts`. +- Updated dependencies + - @backstage/eslint-plugin@0.1.10-next.0 + - @backstage/integration@1.15.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.8 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/release-manifests@0.0.11 + - @backstage/types@1.1.1 + +## 0.28.0-next.0 + +### Minor Changes + +- 6129076: **BREAKING**: Removed the following deprecated commands: + + - `create`: Use `backstage-cli new` instead + - `create-plugin`: Use `backstage-cli new` instead + - `plugin:diff`: Use `backstage-cli fix` instead + - `test`: Use `backstage-cli repo test` or `backstage-cli package test` instead + - `versions:check`: Use `yarn dedupe` or `yarn-deduplicate` instead + - `clean`: Use `backstage-cli package clean` instead + + In addition, the experimental `install` and `onboard` commands have been removed since they have not received any updates since their introduction and we're expecting usage to be low. If you where relying on these commands, please let us know by opening an issue towards the main Backstage repository. + +### Patch Changes + +- 520a383: Added functionality to the prepack script that will append the default export type for entry points to the `exports` object before publishing. This is to help with identifying the declarative integration points for plugins without needing to fetch or run the plugins first. +- 094eaa3: Remove references to in-repo backend-common +- 79ba5a8: The `LEGACY_BACKEND_START` flag is now deprecated. +- Updated dependencies + - @backstage/catalog-model@1.7.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.8 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/eslint-plugin@0.1.9 + - @backstage/integration@1.15.0 + - @backstage/release-manifests@0.0.11 + - @backstage/types@1.1.1 + +## 0.27.1 + +### Patch Changes + +- d2d2313: Add `config.d.ts` files to the list of included file in `tsconfig.json`. + + This allows ESLint to detect issues or deprecations in those files. + +- 16ffdd6: Remove direct `vite` dependency +- 8069f4a: Update Scaffolder module template to add itself to the backend +- 97422b0: Update templates to not refer to backend-common +- 0e1a817: The app build process now outputs an additional `index.html.tmpl` file. This is an non-templated version of the `index.html` file, which can be used to delay templating until runtime. + + The new `index.html.tmpl` file also sets a `backstage-public-path` meta tag to be templated at runtime. The meta tag is in turn picked up by the new `@backstage/cli/config/webpack-public-path.js` entry point script, which uses it to set the runtime public path of the Webpack bundle. + +- 1b5c264: Add `checks: 'read'` for default GitHub app permissions +- b4685e7: Added `watchOptions` to frontend webpack config for compatibility with Yarn PnP +- d29fc1b: Updated dependency `@module-federation/enhanced` to `^0.6.0`. +- f865103: Updated dependency `esbuild` to `^0.23.0`. +- ab7713a: Updated dependency `eslint-plugin-jest` to `^28.0.0`. +- c78ff91: Updated dependency `@rollup/plugin-commonjs` to `^26.0.0`. +- 4ebf36f: Upgrade to `vite@v5` +- 2d3caaf: The build commands now support the new `backstage.inline` flag in `package.json`, which causes the contents of private packages to be inlined into the consuming package, rather than be treated as an external dependency. +- 569c3f0: Fixed an issue where published frontend packages would end up with an invalid import structure if a single module imported both `.css` and `.svg` files. +- 3d88455: Add support for `backstage:^` version ranges to versions:bump when using the experimental yarn plugin +- d10f6b6: Allow overriding minify flag with build repo command +- Updated dependencies + - @backstage/catalog-model@1.7.0 + - @backstage/cli-node@0.2.8 + - @backstage/integration@1.15.0 + - @backstage/config-loader@1.9.1 + - @backstage/eslint-plugin@0.1.9 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/release-manifests@0.0.11 + - @backstage/types@1.1.1 + +## 0.27.1-next.2 + +### Patch Changes + +- 16ffdd6: Remove direct `vite` dependency +- 8069f4a: Update Scaffolder module template to add itself to the backend +- 0e1a817: The app build process now outputs an additional `index.html.tmpl` file. This is an non-templated version of the `index.html` file, which can be used to delay templating until runtime. + + The new `index.html.tmpl` file also sets a `backstage-public-path` meta tag to be templated at runtime. The meta tag is in turn picked up by the new `@backstage/cli/config/webpack-public-path.js` entry point script, which uses it to set the runtime public path of the Webpack bundle. + +- d29fc1b: Updated dependency `@module-federation/enhanced` to `^0.6.0`. +- 4ebf36f: Upgrade to `vite@v5` +- 2d3caaf: The build commands now support the new `backstage.inline` flag in `package.json`, which causes the contents of private packages to be inlined into the consuming package, rather than be treated as an external dependency. +- 3d88455: Add support for `backstage:^` version ranges to versions:bump when using the experimental yarn plugin +- Updated dependencies + - @backstage/cli-node@0.2.8-next.0 + - @backstage/integration@1.15.0-next.0 + - @backstage/config-loader@1.9.1-next.0 + - @backstage/eslint-plugin@0.1.9-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/release-manifests@0.0.11 + - @backstage/types@1.1.1 + ## 0.27.1-next.1 ### Patch Changes diff --git a/packages/cli/cli-report.md b/packages/cli/cli-report.md index 980d305c12..2eb9bb8dea 100644 --- a/packages/cli/cli-report.md +++ b/packages/cli/cli-report.md @@ -13,7 +13,6 @@ Options: Commands: new [options] - test config:docs [options] config:print [options] config:check [options] @@ -23,7 +22,6 @@ Commands: migrate [command] versions:bump [options] versions:migrate [options] - clean build-workspace [options] [packages...] create-github-app info @@ -40,15 +38,6 @@ Options: -h, --help ``` -### `backstage-cli clean` - -``` -Usage: backstage-cli clean [options] - -Options: - -h, --help -``` - ### `backstage-cli config:check` ``` @@ -424,6 +413,7 @@ Usage: backstage-cli repo build [options] Options: --all --since + --minify -h, --help ``` @@ -480,120 +470,6 @@ Options: -h, --help ``` -### `backstage-cli test` - -``` -Usage: backstage-cli [--config=] [TestPathPattern] - -Options: - -h, --help - --version - --all - --automock - -b, --bail - --cache - --cacheDirectory - --changedFilesWithAncestor - --changedSince - --ci - --clearCache - --clearMocks - --collectCoverage - --collectCoverageFrom - --color - --colors - -c, --config - --coverage - --coverageDirectory - --coveragePathIgnorePatterns - --coverageProvider - --coverageReporters - --coverageThreshold - --debug - --detectLeaks - --detectOpenHandles - --env - --errorOnDeprecated - -e, --expand - --filter - --findRelatedTests - --forceExit - --globalSetup - --globalTeardown - --globals - --haste - --ignoreProjects - --init - --injectGlobals - --json - --lastCommit - --listTests - --logHeapUsage - --maxConcurrency - -w, --maxWorkers - --moduleDirectories - --moduleFileExtensions - --moduleNameMapper - --modulePathIgnorePatterns - --modulePaths - --noStackTrace - --notify - --notifyMode - -o, --onlyChanged - -f, --onlyFailures - --openHandlesTimeout - --outputFile - --passWithNoTests - --preset - --prettierPath - --projects - --randomize - --reporters - --resetMocks - --resetModules - --resolver - --restoreMocks - --rootDir - --roots - -i, --runInBand - --runTestsByPath - --runner - --seed - --selectProjects - --setupFiles - --setupFilesAfterEnv - --shard - --showConfig - --showSeed - --silent - --skipFilter - --snapshotSerializers - --testEnvironment - --testEnvironmentOptions - --testFailureExitCode - --testLocationInResults - --testMatch - -t, --testNamePattern - --testPathIgnorePatterns - --testPathPattern - --testRegex - --testResultsProcessor - --testRunner - --testSequencer - --testTimeout - --transform - --transformIgnorePatterns - --unmockedModulePathPatterns - -u, --updateSnapshot - --useStderr - --verbose - --watch - --watchAll - --watchPathIgnorePatterns - --watchman - --workerThreads -``` - ### `backstage-cli versions:bump` ``` diff --git a/packages/cli/config/jest.js b/packages/cli/config/jest.js index bef7b76f96..d99db11656 100644 --- a/packages/cli/config/jest.js +++ b/packages/cli/config/jest.js @@ -19,6 +19,9 @@ const path = require('path'); const crypto = require('crypto'); const glob = require('util').promisify(require('glob')); const { version } = require('../package.json'); +const paths = require('@backstage/cli-common').findPaths(process.cwd()); + +const SRC_EXTS = ['ts', 'js', 'tsx', 'jsx', 'mts', 'cts', 'mjs', 'cjs']; const envOptions = { oldTests: Boolean(process.env.BACKSTAGE_OLD_TESTS), @@ -31,6 +34,75 @@ try { /* ignored */ } +/** + * A list of config keys that are valid for project-level config. + * Jest will complain if we forward any other root configuration to the projects. + * + * @type {Array} + */ +const projectConfigKeys = [ + 'automock', + 'cache', + 'cacheDirectory', + 'clearMocks', + 'collectCoverageFrom', + 'coverageDirectory', + 'coveragePathIgnorePatterns', + 'cwd', + 'dependencyExtractor', + 'detectLeaks', + 'detectOpenHandles', + 'displayName', + 'errorOnDeprecated', + 'extensionsToTreatAsEsm', + 'fakeTimers', + 'filter', + 'forceCoverageMatch', + 'globalSetup', + 'globalTeardown', + 'globals', + 'haste', + 'id', + 'injectGlobals', + 'moduleDirectories', + 'moduleFileExtensions', + 'moduleNameMapper', + 'modulePathIgnorePatterns', + 'modulePaths', + 'openHandlesTimeout', + 'preset', + 'prettierPath', + 'resetMocks', + 'resetModules', + 'resolver', + 'restoreMocks', + 'rootDir', + 'roots', + 'runner', + 'runtime', + 'sandboxInjectedGlobals', + 'setupFiles', + 'setupFilesAfterEnv', + 'skipFilter', + 'skipNodeResolution', + 'slowTestThreshold', + 'snapshotResolver', + 'snapshotSerializers', + 'snapshotFormat', + 'testEnvironment', + 'testEnvironmentOptions', + 'testMatch', + 'testLocationInResults', + 'testPathIgnorePatterns', + 'testRegex', + 'testRunner', + 'transform', + 'transformIgnorePatterns', + 'watchPathIgnorePatterns', + 'unmockedModulePathPatterns', + 'workerIdleMemoryLimit', +]; + const transformIgnorePattern = [ '@material-ui', 'ajv', @@ -76,54 +148,11 @@ async function getProjectConfig(targetPath, extraConfig) { return require(configTsPath); } - // We read all "jest" config fields in package.json files all the way to the filesystem root. - // All configs are merged together to create the final config, with longer paths taking precedence. + // Jest config can be defined both in the root package.json and within each package. The root config + // gets forwarded to us through the `extraConfig` parameter, while the package config is read here. + // If they happen to be the same the keys will simply override each other. // The merging of the configs is shallow, meaning e.g. all transforms are replaced if new ones are defined. - const pkgJsonConfigs = []; - let closestPkgJson = undefined; - let currentPath = targetPath; - - // Some confidence check to avoid infinite loop - for (let i = 0; i < 100; i++) { - const packagePath = path.resolve(currentPath, 'package.json'); - const exists = fs.pathExistsSync(packagePath); - if (exists) { - try { - const data = fs.readJsonSync(packagePath); - if (!closestPkgJson) { - closestPkgJson = data; - } - if (data.jest) { - pkgJsonConfigs.unshift(data.jest); - } - } catch (error) { - throw new Error( - `Failed to parse package.json file reading jest configs, ${error}`, - ); - } - } - - const newPath = path.dirname(currentPath); - if (newPath === currentPath) { - break; - } - currentPath = newPath; - } - - // This is an old deprecated option that is no longer used. - const transformModules = pkgJsonConfigs - .flatMap(conf => { - const modules = conf.transformModules || []; - delete conf.transformModules; - return modules; - }) - .map(name => `${name}/`) - .join('|'); - if (transformModules.length > 0) { - console.warn( - 'The Backstage CLI jest transformModules option is no longer used and will be ignored. All modules are now always transformed.', - ); - } + const pkgJson = await fs.readJson(path.resolve(targetPath, 'package.json')); const options = { ...extraConfig, @@ -191,14 +220,14 @@ async function getProjectConfig(targetPath, extraConfig) { }, // A bit more opinionated - testMatch: ['**/*.test.{js,jsx,ts,tsx,mjs,cjs}'], + testMatch: [`**/*.test.{${SRC_EXTS.join(',')}}`], runtime: envOptions.oldTests ? undefined : require.resolve('./jestCachingModuleLoader'), transformIgnorePatterns: [`/node_modules/(?:${transformIgnorePattern})/`], - ...getRoleConfig(closestPkgJson?.backstage?.role), + ...getRoleConfig(pkgJson.backstage?.role), }; options.setupFilesAfterEnv = options.setupFilesAfterEnv || []; @@ -208,12 +237,15 @@ async function getProjectConfig(targetPath, extraConfig) { options.setupFilesAfterEnv.unshift(require.resolve('cross-fetch/polyfill')); } - // Use src/setupTests.ts as the default location for configuring test env - if (fs.existsSync(path.resolve(targetPath, 'src/setupTests.ts'))) { - options.setupFilesAfterEnv.push('/setupTests.ts'); + // Use src/setupTests.* as the default location for configuring test env + for (const ext of SRC_EXTS) { + if (fs.existsSync(path.resolve(targetPath, `src/setupTests.${ext}`))) { + options.setupFilesAfterEnv.push(`/setupTests.${ext}`); + break; + } } - const config = Object.assign(options, ...pkgJsonConfigs); + const config = Object.assign(options, pkgJson.jest); // The config id is a cache key that lets us share the jest cache across projects. // If no explicit id was configured, generated one based on the configuration. @@ -234,31 +266,44 @@ async function getProjectConfig(targetPath, extraConfig) { // configuration for the current package, or a collection of configurations for // the target workspace packages async function getRootConfig() { - const targetPath = process.cwd(); - const targetPackagePath = path.resolve(targetPath, 'package.json'); - const exists = await fs.pathExists(targetPackagePath); + const rootPkgJson = await fs.readJson( + paths.resolveTargetRoot('package.json'), + ); - const coverageConfig = { - coverageDirectory: path.resolve(targetPath, 'coverage'), + const baseCoverageConfig = { + coverageDirectory: paths.resolveTarget('coverage'), coverageProvider: envOptions.oldTests ? 'v8' : 'babel', collectCoverageFrom: ['**/*.{js,jsx,ts,tsx,mjs,cjs}', '!**/*.d.ts'], }; - if (!exists) { - return getProjectConfig(targetPath, coverageConfig); + const workspacePatterns = + rootPkgJson.workspaces && rootPkgJson.workspaces.packages; + + // Check if we're running within a specific monorepo package. In that case just get the single project config. + if (!workspacePatterns || paths.targetRoot !== paths.targetDir) { + return getProjectConfig(paths.targetDir, { + ...baseCoverageConfig, + ...(rootPkgJson.jest ?? {}), + }); } - // Check whether the current package is a workspace root or not - const data = await fs.readJson(targetPackagePath); - const workspacePatterns = data.workspaces && data.workspaces.packages; - if (!workspacePatterns) { - return getProjectConfig(targetPath, coverageConfig); + const globalRootConfig = { ...baseCoverageConfig }; + const globalProjectConfig = {}; + + for (const [key, value] of Object.entries(rootPkgJson.jest ?? {})) { + if (projectConfigKeys.includes(key)) { + globalProjectConfig[key] = value; + } else { + globalRootConfig[key] = value; + } } // If the target package is a workspace root, we find all packages in the // workspace and load those in as separate jest projects instead. const projectPaths = await Promise.all( - workspacePatterns.map(pattern => glob(path.join(targetPath, pattern))), + workspacePatterns.map(pattern => + glob(path.join(paths.targetRoot, pattern)), + ), ).then(_ => _.flat()); const configs = await Promise.all( @@ -277,6 +322,7 @@ async function getRootConfig() { testScript?.includes('backstage-cli package test'); if (testScript && isSupportedTestScript) { return await getProjectConfig(projectPath, { + ...globalProjectConfig, displayName: packageData.name, }); } @@ -286,9 +332,9 @@ async function getRootConfig() { ).then(cs => cs.filter(Boolean)); return { - rootDir: targetPath, + rootDir: paths.targetRoot, projects: configs, - ...coverageConfig, + ...globalRootConfig, }; } diff --git a/packages/cli/package.json b/packages/cli/package.json index 9d15efe9e4..67f69c988c 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/cli", - "version": "0.27.1-next.1", + "version": "0.28.0-next.1", "description": "CLI for developing Backstage plugins and apps", "backstage": { "role": "cli" @@ -53,13 +53,13 @@ "@backstage/release-manifests": "workspace:^", "@backstage/types": "workspace:^", "@manypkg/get-packages": "^1.1.3", - "@module-federation/enhanced": "^0.3.5", + "@module-federation/enhanced": "^0.6.0", "@octokit/graphql": "^5.0.0", "@octokit/graphql-schema": "^13.7.0", "@octokit/oauth-app": "^4.2.0", "@octokit/request": "^6.0.0", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.7", - "@rollup/plugin-commonjs": "^25.0.0", + "@rollup/plugin-commonjs": "^26.0.0", "@rollup/plugin-json": "^6.0.0", "@rollup/plugin-node-resolve": "^15.0.0", "@rollup/plugin-yaml": "^4.0.0", @@ -90,7 +90,6 @@ "cross-spawn": "^7.0.3", "css-loader": "^6.5.1", "ctrlc-windows": "^2.1.0", - "diff": "^5.0.0", "esbuild": "^0.23.0", "esbuild-loader": "^4.0.0", "eslint": "^8.6.0", @@ -98,7 +97,7 @@ "eslint-formatter-friendly": "^7.0.0", "eslint-plugin-deprecation": "^2.0.0", "eslint-plugin-import": "^2.25.4", - "eslint-plugin-jest": "^27.0.0", + "eslint-plugin-jest": "^28.0.0", "eslint-plugin-jsx-a11y": "^6.5.1", "eslint-plugin-react": "^7.28.0", "eslint-plugin-react-hooks": "^4.3.0", @@ -147,6 +146,7 @@ "swc-loader": "^0.2.3", "tar": "^6.1.12", "terser-webpack-plugin": "^5.1.3", + "ts-morph": "^23.0.0", "util": "^0.12.3", "webpack": "^5.70.0", "webpack-dev-server": "^5.0.0", @@ -157,7 +157,7 @@ "zod": "^3.22.4" }, "devDependencies": { - "@backstage/backend-common": "workspace:^", + "@backstage/backend-common": "^0.25.0", "@backstage/backend-plugin-api": "workspace:^", "@backstage/backend-test-utils": "workspace:^", "@backstage/config": "workspace:^", @@ -168,7 +168,6 @@ "@backstage/test-utils": "workspace:^", "@backstage/theme": "workspace:^", "@types/cross-spawn": "^6.0.2", - "@types/diff": "^5.0.0", "@types/ejs": "^3.1.3", "@types/express": "^4.17.6", "@types/fs-extra": "^11.0.0", @@ -183,18 +182,18 @@ "@types/tar": "^6.1.1", "@types/terser-webpack-plugin": "^5.0.4", "@types/yarnpkg__lockfile": "^1.1.4", - "@vitejs/plugin-react": "^4.0.4", + "@vitejs/plugin-react": "^4.3.1", "del": "^7.0.0", "msw": "^1.0.0", "nodemon": "^3.0.1", - "vite": "^4.4.9", - "vite-plugin-html": "^3.2.0", + "vite": "^5.0.0", + "vite-plugin-html": "^3.2.2", "vite-plugin-node-polyfills": "^0.22.0" }, "peerDependencies": { - "@vitejs/plugin-react": "^4.0.4", - "vite": "^4.4.9", - "vite-plugin-html": "^3.2.0", + "@vitejs/plugin-react": "^4.3.1", + "vite": "^5.0.0", + "vite-plugin-html": "^3.2.2", "vite-plugin-node-polyfills": "^0.22.0" }, "peerDependenciesMeta": { diff --git a/packages/cli/src/commands/build/buildBackend.ts b/packages/cli/src/commands/build/buildBackend.ts index 3609e40eb5..88d322d482 100644 --- a/packages/cli/src/commands/build/buildBackend.ts +++ b/packages/cli/src/commands/build/buildBackend.ts @@ -21,6 +21,7 @@ import tar, { CreateOptions } from 'tar'; import { createDistWorkspace } from '../../lib/packager'; import { getEnvironmentParallelism } from '../../lib/parallel'; import { buildPackage, Output } from '../../lib/builder'; +import { PackageGraph } from '@backstage/cli-node'; const BUNDLE_FILE = 'bundle.tar.gz'; const SKELETON_FILE = 'skeleton.tar.gz'; @@ -42,6 +43,7 @@ export async function buildBackend(options: BuildBackendOptions) { packageJson: pkg, outputs: new Set([Output.cjs]), minify, + workspacePackages: await PackageGraph.listTargetPackages(), }); const tmpDir = await fs.mkdtemp(resolvePath(os.tmpdir(), 'backstage-bundle')); diff --git a/packages/cli/src/commands/build/command.ts b/packages/cli/src/commands/build/command.ts index c0ad3c912b..a5f7f60971 100644 --- a/packages/cli/src/commands/build/command.ts +++ b/packages/cli/src/commands/build/command.ts @@ -17,7 +17,7 @@ import { OptionValues } from 'commander'; import { buildPackage, Output } from '../../lib/builder'; import { findRoleFromCommand } from '../../lib/role'; -import { PackageRoles } from '@backstage/cli-node'; +import { PackageGraph, PackageRoles } from '@backstage/cli-node'; import { paths } from '../../lib/paths'; import { buildFrontend } from './buildFrontend'; import { buildBackend } from './buildBackend'; @@ -82,5 +82,6 @@ export async function command(opts: OptionValues): Promise { return buildPackage({ outputs, minify: Boolean(opts.minify), + workspacePackages: await PackageGraph.listTargetPackages(), }); } diff --git a/packages/cli/src/commands/create-plugin/createPlugin.test.ts b/packages/cli/src/commands/create-plugin/createPlugin.test.ts deleted file mode 100644 index 84af6ebf69..0000000000 --- a/packages/cli/src/commands/create-plugin/createPlugin.test.ts +++ /dev/null @@ -1,40 +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 fs from 'fs-extra'; -import path from 'path'; -import { movePlugin } from './createPlugin'; -import { createMockDirectory } from '@backstage/backend-test-utils'; - -const id = 'testPluginMock'; - -describe('createPlugin', () => { - const mockDir = createMockDirectory(); - - describe('movePlugin', () => { - it('should move the temporary plugin directory to its final place', async () => { - mockDir.setContent({ - [id]: {}, - }); - const tempDir = mockDir.resolve(id); - const pluginDir = mockDir.resolve('test-temp/plugins', id); - - await movePlugin(tempDir, pluginDir, id); - await expect(fs.pathExists(pluginDir)).resolves.toBe(true); - expect(pluginDir).toMatch(path.join('', 'plugins', id)); - }); - }); -}); diff --git a/packages/cli/src/commands/create-plugin/createPlugin.ts b/packages/cli/src/commands/create-plugin/createPlugin.ts deleted file mode 100644 index f8d7e54e97..0000000000 --- a/packages/cli/src/commands/create-plugin/createPlugin.ts +++ /dev/null @@ -1,343 +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 fs from 'fs-extra'; -import { promisify } from 'util'; -import chalk from 'chalk'; -import inquirer, { Answers, Question } from 'inquirer'; -import { exec as execCb } from 'child_process'; -import { join as joinPath, resolve as resolvePath } from 'path'; -import camelCase from 'lodash/camelCase'; -import upperFirst from 'lodash/upperFirst'; -import os from 'os'; -import { OptionValues } from 'commander'; -import { assertError } from '@backstage/errors'; -import { - addCodeownersEntry, - getCodeownersFilePath, - parseOwnerIds, -} from '../../lib/codeowners'; -import { paths } from '../../lib/paths'; -import { Task, templatingTask } from '../../lib/tasks'; -import { Lockfile } from '../../lib/versioning'; -import { createPackageVersionProvider } from '../../lib/version'; - -const exec = promisify(execCb); - -async function checkExists(destination: string) { - await Task.forItem('checking', destination, async () => { - if (await fs.pathExists(destination)) { - const existing = chalk.cyan( - destination.replace(`${paths.targetRoot}/`, ''), - ); - throw new Error( - `A plugin with the same name already exists: ${existing}\nPlease try again with a different plugin ID`, - ); - } - }); -} - -const sortObjectByKeys = (obj: { [name in string]: string }) => { - return Object.keys(obj) - .sort() - .reduce((result, key: string) => { - result[key] = obj[key]; - return result; - }, {} as { [name in string]: string }); -}; - -export const capitalize = (str: string): string => - str.charAt(0).toUpperCase() + str.slice(1); - -export const addExportStatement = async ( - file: string, - exportStatement: string, -) => { - const newContents = fs - .readFileSync(file, 'utf8') - .split('\n') - .filter(Boolean) // get rid of empty lines - .concat([exportStatement]) - .concat(['']) // newline at end of file - .join('\n'); - - await fs.writeFile(file, newContents, 'utf8'); -}; - -export async function addPluginDependencyToApp( - rootDir: string, - pluginPackage: string, - versionStr: string, -) { - const packageFilePath = 'packages/app/package.json'; - const packageFile = resolvePath(rootDir, packageFilePath); - - await Task.forItem('processing', packageFilePath, async () => { - const packageFileContent = await fs.readFile(packageFile, 'utf-8'); - const packageFileJson = JSON.parse(packageFileContent); - const dependencies = packageFileJson.dependencies; - - if (dependencies[pluginPackage]) { - throw new Error( - `Plugin ${pluginPackage} already exists in ${packageFile}`, - ); - } - - dependencies[pluginPackage] = `^${versionStr}`; - packageFileJson.dependencies = sortObjectByKeys(dependencies); - const newContents = `${JSON.stringify(packageFileJson, null, 2)}\n`; - - await fs.writeFile(packageFile, newContents, 'utf-8').catch(error => { - throw new Error( - `Failed to add plugin as dependency to app: ${packageFile}: ${error.message}`, - ); - }); - }); -} - -export async function addPluginExtensionToApp( - pluginId: string, - extensionName: string, - pluginPackage: string, -) { - const pluginsFilePath = paths.resolveTargetRoot('packages/app/src/App.tsx'); - if (!(await fs.pathExists(pluginsFilePath))) { - return; - } - - await Task.forItem('processing', pluginsFilePath, async () => { - const content = await fs.readFile(pluginsFilePath, 'utf8'); - const revLines = content.split('\n').reverse(); - - const lastImportIndex = revLines.findIndex(line => - line.match(/ from ("|').*("|')/), - ); - const lastRouteIndex = revLines.findIndex(line => - line.match(/<\/FlatRoutes/), - ); - - if (lastImportIndex !== -1 && lastRouteIndex !== -1) { - revLines.splice( - lastImportIndex, - 0, - `import { ${extensionName} } from '${pluginPackage}';`, - ); - const [indentation] = revLines[lastRouteIndex + 1].match(/^\s*/) ?? []; - revLines.splice( - lastRouteIndex + 1, - 0, - `${indentation}}/>`, - ); - - const newContent = revLines.reverse().join('\n'); - await fs.writeFile(pluginsFilePath, newContent, 'utf8'); - } - }); -} - -async function cleanUp(tempDir: string) { - await Task.forItem('remove', 'temporary directory', async () => { - await fs.remove(tempDir); - }); -} - -async function buildPlugin(pluginFolder: string) { - const commands = [ - 'yarn install', - 'yarn lint --fix', - 'yarn tsc', - 'yarn build', - ]; - for (const command of commands) { - try { - await Task.forItem('executing', command, async () => { - process.chdir(pluginFolder); - await exec(command); - }).catch(error => { - process.stdout.write(error.stderr); - process.stdout.write(error.stdout); - throw new Error( - `Warning: Could not execute command ${chalk.cyan(command)}`, - ); - }); - } catch (error) { - assertError(error); - Task.error(error.message); - break; - } - } -} - -export async function movePlugin( - tempDir: string, - destination: string, - id: string, -) { - await Task.forItem('moving', id, async () => { - await fs.move(tempDir, destination).catch(error => { - throw new Error( - `Failed to move plugin from ${tempDir} to ${destination}: ${error.message}`, - ); - }); - }); -} - -export default async (opts: OptionValues) => { - const codeownersPath = await getCodeownersFilePath(paths.targetRoot); - - const questions: Question[] = [ - { - type: 'input', - name: 'id', - message: chalk.blue('Enter an ID for the plugin [required]'), - validate: (value: any) => { - if (!value) { - return chalk.red('Please enter an ID for the plugin'); - } else if (!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(value)) { - return chalk.red( - 'Plugin IDs must be lowercase and contain only letters, digits, and dashes.', - ); - } - return true; - }, - }, - ]; - - if (codeownersPath) { - questions.push({ - type: 'input', - name: 'owner', - message: chalk.blue( - 'Enter the owner(s) of the plugin. If specified, this will be added to CODEOWNERS for the plugin path. [optional]', - ), - validate: (value: any) => { - if (!value) { - return true; - } - - const ownerIds = parseOwnerIds(value); - if (!ownerIds) { - return chalk.red( - 'The owner must be a space separated list of team names (e.g. @org/team-name), usernames (e.g. @username), or the email addresses of users (e.g. user@example.com).', - ); - } - - return true; - }, - }); - } - - const answers: Answers = await inquirer.prompt(questions); - const pluginId = - opts.backend && !answers.id.endsWith('-backend') - ? `${answers.id}-backend` - : answers.id; - - const name = opts.scope - ? `@${opts.scope.replace(/^@/, '')}/plugin-${pluginId}` - : `plugin-${pluginId}`; - const pluginVar = `${camelCase(answers.id)}Plugin`; - const extensionName = `${upperFirst(camelCase(answers.id))}Page`; - const npmRegistry = opts.npmRegistry && opts.scope ? opts.npmRegistry : ''; - const privatePackage = opts.private === false ? false : true; - const isMonoRepo = await fs.pathExists(paths.resolveTargetRoot('lerna.json')); - const appPackage = paths.resolveTargetRoot('packages/app'); - const templateDir = paths.resolveOwn( - opts.backend - ? 'templates/default-backend-plugin' - : 'templates/default-plugin', - ); - const pluginDir = isMonoRepo - ? paths.resolveTargetRoot('plugins', pluginId) - : paths.resolveTargetRoot(pluginId); - const { version: pluginVersion } = isMonoRepo - ? await fs.readJson(paths.resolveTargetRoot('lerna.json')) - : { version: '0.1.0' }; - const license = opts.license ?? 'Apache-2.0'; - - let lockfile: Lockfile | undefined; - try { - lockfile = await Lockfile.load(paths.resolveTargetRoot('yarn.lock')); - } catch (error) { - console.warn(`No yarn.lock available, ${error}`); - } - - Task.log(); - Task.log('Creating the plugin...'); - - Task.section('Checking if the plugin ID is available'); - await checkExists(pluginDir); - - Task.section('Creating a temporary plugin directory'); - const tempDir = await fs.mkdtemp( - joinPath(os.tmpdir(), `backstage-plugin-${pluginId}`), - ); - - try { - Task.section('Preparing files'); - - await templatingTask( - templateDir, - tempDir, - { - ...answers, - pluginVar, - pluginVersion, - extensionName, - name, - privatePackage, - npmRegistry, - license, - }, - createPackageVersionProvider(lockfile), - isMonoRepo, - ); - - Task.section('Moving to final location'); - await movePlugin(tempDir, pluginDir, pluginId); - - Task.section('Building the plugin'); - await buildPlugin(pluginDir); - - if ((await fs.pathExists(appPackage)) && !opts.backend) { - Task.section('Adding plugin as dependency in app'); - await addPluginDependencyToApp(paths.targetRoot, name, pluginVersion); - - Task.section('Import plugin in app'); - await addPluginExtensionToApp(pluginId, extensionName, name); - } - - if (answers.owner) { - await addCodeownersEntry(`/plugins/${pluginId}`, answers.owner); - } - - Task.log(); - Task.log(`🥇 Successfully created ${chalk.cyan(`${name}`)}`); - Task.log(); - Task.exit(); - } catch (error) { - assertError(error); - Task.error(error.message); - - Task.log('It seems that something went wrong when creating the plugin 🤔'); - Task.log('We are going to clean up, and then you can try again.'); - - Task.section('Cleanup'); - await cleanUp(tempDir); - Task.error('🔥 Failed to create plugin!'); - Task.exit(1); - } -}; diff --git a/packages/cli/src/commands/index.ts b/packages/cli/src/commands/index.ts index 7c3192fb2e..7cc23300af 100644 --- a/packages/cli/src/commands/index.ts +++ b/packages/cli/src/commands/index.ts @@ -25,13 +25,6 @@ const configOption = [ Array(), ] as const; -export function registerOnboardCommand(program: Command) { - program - .command('onboard', { hidden: true }) - .description('Get help setting up your Backstage App.') - .action(lazy(() => import('./onboard').then(m => m.command))); -} - export function registerRepoCommand(program: Command) { const command = program .command('repo [command]') @@ -50,6 +43,10 @@ export function registerRepoCommand(program: Command) { '--since ', 'Only build packages and their dev dependents that changed since the specified ref', ) + .option( + '--minify', + 'Minify the generated code. Does not apply to app package (app is minified by default).', + ) .action(lazy(() => import('./repo/build').then(m => m.command))); command @@ -261,63 +258,6 @@ export function registerCommands(program: Command) { .option('--no-private', 'Do not mark new packages as private') .action(lazy(() => import('./new/new').then(m => m.default))); - program - .command('create', { hidden: true }) - .storeOptionsAsProperties(false) - .description( - 'Open up an interactive guide to creating new things in your app [DEPRECATED]', - ) - .option( - '--select ', - 'Select the thing you want to be creating upfront', - ) - .option( - '--option =', - 'Pre-fill options for the creation process', - (opt, arr: string[]) => [...arr, opt], - [], - ) - .option('--scope ', 'The scope to use for new packages') - .option( - '--npm-registry ', - 'The package registry to use for new packages', - ) - .option('--no-private', 'Do not mark new packages as private') - .action(lazy(() => import('./new/new').then(m => m.default))); - - program - .command('create-plugin', { hidden: true }) - .option( - '--backend', - 'Create plugin with the backend dependencies as default', - ) - .description('Creates a new plugin in the current repository [DEPRECATED]') - .option('--scope ', 'npm scope') - .option('--npm-registry ', 'npm registry URL') - .option('--no-private', 'Public npm package') - .action( - lazy(() => import('./create-plugin/createPlugin').then(m => m.default)), - ); - - program - .command('plugin:diff', { hidden: true }) - .option('--check', 'Fail if changes are required') - .option('--yes', 'Apply all changes') - .description( - 'Diff an existing plugin with the creation template [DEPRECATED]', - ) - .action(lazy(() => import('./plugin/diff').then(m => m.default))); - - // TODO(Rugvip): Deprecate in favor of package variant - program - .command('test') - .allowUnknownOption(true) // Allows the command to run, but we still need to parse raw args - .helpOption(', --backstage-cli-help') // Let Jest handle help - .description( - 'Run tests, forwarding args to Jest, defaulting to watch mode [DEPRECATED]', - ) - .action(lazy(() => import('./test').then(m => m.default))); - program .command('config:docs') .option( @@ -381,7 +321,6 @@ export function registerCommands(program: Command) { registerRepoCommand(program); registerScriptCommand(program); registerMigrateCommand(program); - registerOnboardCommand(program); program .command('versions:bump') @@ -399,12 +338,6 @@ export function registerCommands(program: Command) { .description('Bump Backstage packages to the latest versions') .action(lazy(() => import('./versions/bump').then(m => m.default))); - program - .command('versions:check', { hidden: true }) - .option('--fix', 'Fix any auto-fixable versioning problems') - .description('Check Backstage package versioning') - .action(lazy(() => import('./versions/lint').then(m => m.default))); - program .command('versions:migrate') .option( @@ -420,12 +353,6 @@ export function registerCommands(program: Command) { ) .action(lazy(() => import('./versions/migrate').then(m => m.default))); - // TODO(Rugvip): Deprecate in favor of package variant - program - .command('clean') - .description('Delete cache directories [DEPRECATED]') - .action(lazy(() => import('./clean/clean').then(m => m.default))); - program .command('build-workspace [packages...]') .option( @@ -445,14 +372,48 @@ export function registerCommands(program: Command) { .description('Show helpful information for debugging and reporting bugs') .action(lazy(() => import('./info').then(m => m.default))); + // Notifications for removed commands program - .command('install [plugin-id]', { hidden: true }) - .option( - '--from ', - 'Install from a local package.json containing the installation recipe', - ) - .description('Install a Backstage plugin [EXPERIMENTAL]') - .action(lazy(() => import('./install/install').then(m => m.default))); + .command('create') + .allowUnknownOption(true) + .action(removed("use 'backstage-cli new' instead")); + program + .command('create-plugin') + .allowUnknownOption(true) + .action(removed("use 'backstage-cli new' instead")); + program + .command('plugin:diff') + .allowUnknownOption(true) + .action(removed("use 'backstage-cli fix' instead")); + program + .command('test') + .allowUnknownOption(true) + .action( + removed( + "use 'backstage-cli repo test' or 'backstage-cli package test' instead", + ), + ); + program + .command('clean') + .allowUnknownOption(true) + .action(removed("use 'backstage-cli package clean' instead")); + program + .command('versions:check') + .allowUnknownOption(true) + .action(removed("use 'yarn dedupe' or 'yarn-deduplicate' instead")); + program.command('install').allowUnknownOption(true).action(removed()); + program.command('onboard').allowUnknownOption(true).action(removed()); +} + +function removed(message?: string) { + return () => { + console.error( + message + ? `This command has been removed, ${message}` + : 'This command has been removed', + ); + process.exit(1); + }; } // Wraps an action function so that it always exits and handles errors diff --git a/packages/cli/src/commands/install/install.ts b/packages/cli/src/commands/install/install.ts deleted file mode 100644 index e395088b3e..0000000000 --- a/packages/cli/src/commands/install/install.ts +++ /dev/null @@ -1,167 +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 { - Step, - PackageWithInstallRecipe, - PeerPluginDependencies, -} from './types'; -import { fetchPackageInfo } from '../../lib/versioning'; -import { NotFoundError } from '../../lib/errors'; -import * as stepDefinitionMap from './steps'; -import { OptionValues } from 'commander'; -import fs from 'fs-extra'; - -const stepDefinitions = Object.values(stepDefinitionMap); - -async function fetchPluginPackage( - id: string, -): Promise { - const searchNames = [`@backstage/plugin-${id}`, `backstage-plugin-${id}`, id]; - - for (const name of searchNames) { - try { - const packageInfo = (await fetchPackageInfo( - name, - )) as PackageWithInstallRecipe; - return packageInfo; - } catch (error) { - if (error.name !== 'NotFoundError') { - throw error; - } - } - } - - throw new NotFoundError( - `No matching package found for '${id}', tried ${searchNames.join(', ')}`, - ); -} - -type Steps = Array<{ - type: string; - step: Step; -}>; - -class PluginInstaller { - static async resolveSteps( - pkg: PackageWithInstallRecipe, - versionToInstall?: string, - ) { - const steps: Steps = []; - - // collectDependencies - // TODO: Deps mean the plugin package itself, and any other backstage plugins/packages it depends on, in its installation recipe. - const dependencies = []; - dependencies.push({ - target: 'packages/app', - type: 'dependencies' as const, - name: pkg.name, - query: versionToInstall || `^${pkg.version}`, - }); - steps.push({ - type: 'dependencies', - step: stepDefinitionMap.dependencies.create({ dependencies }), - }); - - for (const step of pkg.experimentalInstallationRecipe?.steps ?? []) { - const { type } = step; - - const definition = stepDefinitions.find(d => d.type === type); - if (definition) { - steps.push({ - type, - step: definition.deserialize(step, pkg), - }); - } else { - throw new Error(`Unsupported step type: ${type}`); - } - } - - return steps; - } - - constructor(private readonly steps: Steps) {} - - async run() { - for (const { type, step } of this.steps) { - // TODO(Rugvip): Add spinners, nicer message about the step. - console.log(`Running step ${type}`); - await step.run(); - } - } -} - -async function installPluginAndPeerPlugins(pkg: PackageWithInstallRecipe) { - const pluginDeps: PeerPluginDependencies = new Map(); - pluginDeps.set(pkg.name, { pkg }); - await loadPeerPluginDeps(pkg, pluginDeps); - - console.log(`Installing ${pkg.name} AND any peer plugin dependencies.`); - for (const [_pluginDepName, pluginDep] of pluginDeps.entries()) { - const { pkg: pluginDepPkg, versionToInstall } = pluginDep; - console.log( - `Installing plugin: ${pluginDepPkg.name}: ${ - versionToInstall || pluginDepPkg.version - }`, - ); - const steps = await PluginInstaller.resolveSteps( - pluginDepPkg, - versionToInstall, - ); - const installer = new PluginInstaller(steps); - await installer.run(); - } -} - -async function loadPackageJson( - plugin: string, -): Promise { - if (plugin.endsWith('package.json')) { - // Install from local package if pluginId is a package.json file - needs to be absolute path - return await fs.readJson(plugin); - } - return await fetchPluginPackage(plugin); -} - -async function loadPeerPluginDeps( - pkg: PackageWithInstallRecipe, - pluginMap: PeerPluginDependencies, -) { - for (const [pluginId, pluginVersion] of Object.entries( - pkg.experimentalInstallationRecipe?.peerPluginDependencies ?? {}, - )) { - const depPkg = await loadPackageJson(pluginId); - if (!pluginMap.get(depPkg.name)) { - pluginMap.set(depPkg.name, { - pkg: depPkg, - versionToInstall: pluginVersion, - }); - await loadPeerPluginDeps(depPkg, pluginMap); - } - } -} - -export default async (pluginId?: string, cmd?: OptionValues) => { - const from = pluginId || cmd?.from; - // TODO(himanshu): If no plugin id is provided, it should list all plugins available. Maybe in some other command? - if (!from) { - throw new Error( - 'Missing both or a package.json file path in the --from flag.', - ); - } - const pkg = await loadPackageJson(from); - await installPluginAndPeerPlugins(pkg); -}; diff --git a/packages/cli/src/commands/install/steps/appRoute.ts b/packages/cli/src/commands/install/steps/appRoute.ts deleted file mode 100644 index f89b7eedff..0000000000 --- a/packages/cli/src/commands/install/steps/appRoute.ts +++ /dev/null @@ -1,92 +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 fs from 'fs-extra'; -import { paths } from '../../../lib/paths'; -import { Step, createStepDefinition } from '../types'; - -type Data = { - path: string; - element: string; - packageName: string; -}; - -class AppRouteStep implements Step { - constructor(private readonly data: Data) {} - - async run() { - const { path, element, packageName } = this.data; - - const appTsxPath = paths.resolveTargetRoot('packages/app/src/App.tsx'); - const contents = await fs.readFile(appTsxPath, 'utf-8'); - let failed = false; - - // Add a new route just above the end of the FlatRoutes block - const contentsWithRoute = contents.replace( - /(\s*)<\/FlatRoutes>/, - `$1 $1`, - ); - if (contentsWithRoute === contents) { - failed = true; - } - - // Grab the component name from the element - const componentName = element.match(/[A-Za-z0-9]+/)?.[0]; - if (!componentName) { - throw new Error(`Could not find component name in ${element}`); - } - - // Add plugin import - // TODO(Rugvip): Attempt to add this among the other plugin imports - const contentsWithImport = contentsWithRoute.replace( - /^import /m, - `import { ${componentName} } from '${packageName}';\nimport `, - ); - if (contentsWithImport === contentsWithRoute) { - failed = true; - } - - if (failed) { - console.log( - 'Failed to automatically add a route to package/app/src/App.tsx', - ); - console.log(`Action needed, add the following:`); - console.log(`1. import { ${componentName} } from '${packageName}';`); - console.log(`2. `); - } else { - await fs.writeFile(appTsxPath, contentsWithImport); - } - } -} - -export const appRoute = createStepDefinition({ - type: 'app-route', - - deserialize(obj, pkg) { - const { path, element } = obj; - if (!path || typeof path !== 'string') { - throw new Error("Invalid install step, 'path' must be a string"); - } - if (!element || typeof element !== 'string') { - throw new Error("Invalid install step, 'element' must be a string"); - } - return new AppRouteStep({ path, element, packageName: pkg.name }); - }, - - create(data: Data) { - return new AppRouteStep(data); - }, -}); diff --git a/packages/cli/src/commands/install/steps/dependencies.ts b/packages/cli/src/commands/install/steps/dependencies.ts deleted file mode 100644 index 4381066159..0000000000 --- a/packages/cli/src/commands/install/steps/dependencies.ts +++ /dev/null @@ -1,82 +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 fs from 'fs-extra'; -import chalk from 'chalk'; -import sortBy from 'lodash/sortBy'; -import groupBy from 'lodash/groupBy'; -import { paths } from '../../../lib/paths'; -import { run } from '../../../lib/run'; -import { Step, createStepDefinition } from '../types'; - -type Data = { - dependencies: Array<{ - target: string; - type: 'dependencies'; - name: string; - query: string; - }>; -}; - -class DependenciesStep implements Step { - constructor(private readonly data: Data) {} - - async run() { - const { dependencies } = this.data; - // yarn --cwd packages/app add - const byTarget = groupBy(dependencies, 'target'); - - // Go through each target package and install the dependencies. - for (const [target, deps] of Object.entries(byTarget)) { - const pkgPath = paths.resolveTargetRoot(target, 'package.json'); - const pkgJson = await fs.readJson(pkgPath); - - // Populate each type of dependency object, dependencies, devDependencies, etc. - const depTypes = new Set(); - for (const dep of deps) { - depTypes.add(dep.type); - pkgJson[dep.type][dep.name] = dep.query; - } - - // Be nice and sort the dependencies alphabetically - for (const depType of depTypes) { - pkgJson[depType] = Object.fromEntries( - sortBy(Object.entries(pkgJson[depType]), ([key]) => key), - ); - } - await fs.writeJson(pkgPath, pkgJson, { spaces: 2 }); - } - - console.log(); - console.log( - `Running ${chalk.blue('yarn install')} to install new versions`, - ); - console.log(); - await run('yarn', ['install']); - } -} - -export const dependencies = createStepDefinition({ - type: 'dependencies', - - deserialize() { - throw new Error('The dependency step may not be defined in JSON'); - }, - - create(data: Data) { - return new DependenciesStep(data); - }, -}); diff --git a/packages/cli/src/commands/install/steps/index.ts b/packages/cli/src/commands/install/steps/index.ts deleted file mode 100644 index 590fba120f..0000000000 --- a/packages/cli/src/commands/install/steps/index.ts +++ /dev/null @@ -1,19 +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 { appRoute } from './appRoute'; -export { dependencies } from './dependencies'; -export { message } from './message'; diff --git a/packages/cli/src/commands/install/steps/message.ts b/packages/cli/src/commands/install/steps/message.ts deleted file mode 100644 index 5821c7d98b..0000000000 --- a/packages/cli/src/commands/install/steps/message.ts +++ /dev/null @@ -1,48 +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 { Step, createStepDefinition } from '../types'; - -type Data = { - message: string; -}; - -class MessageStep implements Step { - constructor(private readonly data: Data) {} - - async run() { - console.log(this.data.message); - } -} - -export const message = createStepDefinition({ - type: 'message', - - deserialize(obj) { - const { message: msg } = obj; - - if (!msg || (typeof msg !== 'string' && !Array.isArray(msg))) { - throw new Error( - "Invalid install step, 'message' must be a string or array", - ); - } - return new MessageStep({ message: [msg].flat().join('') }); - }, - - create(data: Data) { - return new MessageStep(data); - }, -}); diff --git a/packages/cli/src/commands/install/types.ts b/packages/cli/src/commands/install/types.ts deleted file mode 100644 index 1fa52a5e82..0000000000 --- a/packages/cli/src/commands/install/types.ts +++ /dev/null @@ -1,78 +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 { YarnInfoInspectData } from '../../lib/versioning'; -import { JsonObject } from '@backstage/types'; - -/** - * TODO: possible types - * - * frontend-deps: Install one or many frontend packages in a Backstage app - * backend-deps: Install one or many backend packages in a Backstage app - * app-config: Update app-config.yaml (and ask for inputs). E.g. Use local or docker for techdocs.builder - * frontend-route: Add a frontend route to the plugin homepage - * backend-route: Add a backend route to the plugin - * entity-page-tab: Add a tab on Catalog’s entity page - * sidebar-item: Add a sidebar item - * frontend-api: Add a custom API - */ - -/** A serialized install step as it appears in JSON */ -export type SerializedStep = { - type: string; -} & unknown; - -export type InstallationRecipe = { - type?: 'frontend' | 'backend'; - steps: SerializedStep[]; - peerPluginDependencies: { [pluginId: string]: string }; -}; - -/** package.json data */ -export type PackageWithInstallRecipe = YarnInfoInspectData & { - version: string; - experimentalInstallationRecipe?: InstallationRecipe; -}; - -export type PeerPluginDependencies = Map< - string, - { - pkg: PackageWithInstallRecipe; - versionToInstall?: string; - } ->; - -export interface Step { - run(): Promise; -} - -export interface StepDefinition { - /** The string identifying this type of step */ - type: string; - - /** Deserializes and validate a JSON description of the step data */ - deserialize(obj: JsonObject, pkg: PackageWithInstallRecipe): Step; - - /** Creates a step using known parameters */ - create(options: Options): Step; -} - -/** Creates a new step definition. Only used as a helper for type inference */ -export function createStepDefinition( - config: StepDefinition, -): StepDefinition { - return config; -} diff --git a/packages/cli/src/commands/onboard/README.md b/packages/cli/src/commands/onboard/README.md deleted file mode 100644 index 0fb4d22666..0000000000 --- a/packages/cli/src/commands/onboard/README.md +++ /dev/null @@ -1,22 +0,0 @@ -# onboard - -## Local dev - -# Create a new app - -```bash -cd .. -npx @backstage/create-app -cd new-backstage-app - -# Run the modded cli in the new app - -../RELATIVE_PATH_TO_PROJECT/backstage/packages/cli/bin/backstage-cli onboard -? Do you want to set up Authentication for this project? (Y/n) -... - -# Try the app with the new changes - -yarn dev - -``` diff --git a/packages/cli/src/commands/onboard/auth/index.ts b/packages/cli/src/commands/onboard/auth/index.ts deleted file mode 100644 index 0f4537b110..0000000000 --- a/packages/cli/src/commands/onboard/auth/index.ts +++ /dev/null @@ -1,63 +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 inquirer from 'inquirer'; -import { Task } from '../../../lib/tasks'; -import { github, Answers as GitHubAnswers } from './providers/github'; -import { gitlab, Answers as GitLabAnswers } from './providers/gitlab'; - -export { type GitHubAnswers, type GitLabAnswers }; - -export async function auth(): Promise<{ - provider: string; - answers: GitHubAnswers | GitLabAnswers; -}> { - const answers = await inquirer.prompt<{ - provider: string; - }>([ - { - type: 'list', - name: 'provider', - message: 'Please select an authentication provider:', - choices: ['GitHub', 'GitLab'], - }, - ]); - - const { provider } = answers; - - let providerAnswers; - switch (provider) { - case 'GitHub': { - providerAnswers = await github(); - break; - } - case 'GitLab': { - providerAnswers = await gitlab(); - break; - } - default: - throw new Error(`Provider ${provider} not implemented yet.`); - } - - Task.log(); - Task.log(`Done setting up ${provider} Authentication!`); - Task.log(); - - return { - provider, - answers: providerAnswers, - }; -} diff --git a/packages/cli/src/commands/onboard/auth/patch.ts b/packages/cli/src/commands/onboard/auth/patch.ts deleted file mode 100644 index d004eeb157..0000000000 --- a/packages/cli/src/commands/onboard/auth/patch.ts +++ /dev/null @@ -1,43 +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 * as fs from 'fs-extra'; -import * as path from 'path'; -import * as differ from 'diff'; -import { PATCH_FOLDER } from '../files'; -import { findPaths } from '@backstage/cli-common'; - -/* eslint-disable-next-line no-restricted-syntax */ -const { targetRoot } = findPaths(__dirname); - -export const patch = async (patchFile: string) => { - const patchContent = await fs.readFile( - path.join(PATCH_FOLDER, patchFile), - 'utf8', - ); - const targetName = patchContent.split('\n')[0].replace('--- a', ''); - const targetFile = path.join(targetRoot, targetName); - const oldContent = await fs.readFile(targetFile, 'utf8'); - const newContent = differ.applyPatch(oldContent, patchContent); - if (!newContent) { - throw new Error( - `Patch ${patchFile} was not applied correctly. - Did you change ${targetName} manually before running this command?`, - ); - } - - return await fs.writeFile(targetFile, newContent, 'utf8'); -}; diff --git a/packages/cli/src/commands/onboard/auth/patches/01-github.Add-SignInPage.patch b/packages/cli/src/commands/onboard/auth/patches/01-github.Add-SignInPage.patch deleted file mode 100644 index db9f5228e8..0000000000 --- a/packages/cli/src/commands/onboard/auth/patches/01-github.Add-SignInPage.patch +++ /dev/null @@ -1,25 +0,0 @@ ---- a/packages/app/src/App.tsx -+++ b/packages/app/src/App.tsx -@@ -30 +30,5 @@ import { Root } from './components/Root'; --import { AlertDisplay, OAuthRequestDialog } from '@backstage/core-components'; -+import { -+ AlertDisplay, -+ OAuthRequestDialog, -+ SignInPage, -+} from '@backstage/core-components'; -@@ -35,0 +40 @@ import { catalogEntityCreatePermission } from '@backstage/plugin-catalog-common/ -+import { githubAuthApiRef } from '@backstage/core-plugin-api'; -@@ -38,0 +44,14 @@ const app = createApp({ -+ components: { -+ SignInPage: props => ( -+ -+ ), -+ }, \ No newline at end of file diff --git a/packages/cli/src/commands/onboard/auth/patches/02-gitlab.Add-SignInPage.patch b/packages/cli/src/commands/onboard/auth/patches/02-gitlab.Add-SignInPage.patch deleted file mode 100644 index da849220b8..0000000000 --- a/packages/cli/src/commands/onboard/auth/patches/02-gitlab.Add-SignInPage.patch +++ /dev/null @@ -1,25 +0,0 @@ ---- a/packages/app/src/App.tsx -+++ b/packages/app/src/App.tsx -@@ -30 +30,5 @@ import { Root } from './components/Root'; --import { AlertDisplay, OAuthRequestDialog } from '@backstage/core-components'; -+import { -+ AlertDisplay, -+ OAuthRequestDialog, -+ SignInPage, -+} from '@backstage/core-components'; -@@ -35,0 +40 @@ import { catalogEntityCreatePermission } from '@backstage/plugin-catalog-common/ -+import { gitlabAuthApiRef } from '@backstage/core-plugin-api'; -@@ -38,0 +44,14 @@ const app = createApp({ -+ components: { -+ SignInPage: props => ( -+ -+ ), -+ }, \ No newline at end of file diff --git a/packages/cli/src/commands/onboard/auth/patches/03-gitlab.Change-signIn-resolver.patch b/packages/cli/src/commands/onboard/auth/patches/03-gitlab.Change-signIn-resolver.patch deleted file mode 100644 index 7a69669674..0000000000 --- a/packages/cli/src/commands/onboard/auth/patches/03-gitlab.Change-signIn-resolver.patch +++ /dev/null @@ -1,5 +0,0 @@ ---- a/packages/backend/src/plugins/auth.ts -+++ b/packages/backend/src/plugins/auth.ts -@@ -38 +38 @@ export default async function createPlugin( -- github: providers.github.create({ -+ gitlab: providers.gitlab.create({ \ No newline at end of file diff --git a/packages/cli/src/commands/onboard/auth/providers/github.ts b/packages/cli/src/commands/onboard/auth/providers/github.ts deleted file mode 100644 index 36c6b02038..0000000000 --- a/packages/cli/src/commands/onboard/auth/providers/github.ts +++ /dev/null @@ -1,147 +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 { OAuthApp } from '@octokit/oauth-app'; -import chalk from 'chalk'; -import * as fs from 'fs-extra'; -import inquirer from 'inquirer'; -import { Task } from '../../../../lib/tasks'; -import { updateConfigFile } from '../../config'; -import { APP_CONFIG_FILE, PATCH_FOLDER } from '../../files'; -import { patch } from '../patch'; - -export type Answers = { - clientSecret: string; - clientId: string; - hasEnterprise: boolean; - enterpriseInstanceUrl?: string; -}; - -const validateCredentials = async (clientId: string, clientSecret: string) => { - try { - const app = new OAuthApp({ - clientId, - clientSecret, - }); - await app.createToken({ - code: '%NOT-VALID-CODE%', - }); - } catch (error) { - // @octokit/request returns a error.response object when a request is rejected. - // We can check it to see what kind of error we received. - - // If error.response is successful we can double-check that the error itself was due to the bad code. - // If that's the case then we can assume that the client id and secret exists as we otherwise would - // have gotten a 400/404. - if ( - error.response.status !== 200 && - error.response.data.error !== 'bad_verification_code' - ) { - throw new Error(`Validating GitHub Credentials failed.`); - } - } -}; - -const getConfig = (answers: Answers) => { - const { clientId, clientSecret, hasEnterprise, enterpriseInstanceUrl } = - answers; - - return { - auth: { - providers: { - github: { - development: { - clientId, - clientSecret, - ...(hasEnterprise && { - enterpriseInstanceUrl, - }), - }, - }, - }, - }, - }; -}; - -export const github = async (): Promise => { - Task.log(` - To add GitHub authentication, you must create an OAuth App from the GitHub developer settings: ${chalk.blue( - 'https://github.com/settings/developers', - )} - The Homepage URL should point to Backstage's frontend, while the Authorization callback URL will point to the auth backend. - - Settings for local development: - ${chalk.cyan(` - Homepage URL: http://localhost:3000 - Authorization callback URL: http://localhost:7007/api/auth/github/handler/frame`)} - - You can find the full documentation page here: ${chalk.blue( - 'https://backstage.io/docs/auth/github/provider', - )} - `); - - const answers = await inquirer.prompt([ - { - type: 'input', - name: 'clientId', - message: 'What is your Client Id?', - validate: (input: string) => (input.length ? true : false), - }, - { - type: 'input', - name: 'clientSecret', - message: 'What is your Client Secret?', - validate: (input: string) => (input.length ? true : false), - }, - { - type: 'confirm', - name: 'hasEnterprise', - message: 'Are you using GitHub Enterprise?', - }, - { - type: 'input', - name: 'enterpriseInstanceUrl', - message: 'What is your URL for GitHub Enterprise?', - when: ({ hasEnterprise }) => hasEnterprise, - validate: (input: string) => Boolean(new URL(input)), - }, - ]); - - const { clientId, clientSecret } = answers; - const config = getConfig(answers); - - Task.log('Setting up GitHub Authentication for you...'); - - await Task.forItem( - 'Validating', - 'credentials', - async () => await validateCredentials(clientId, clientSecret), - ); - await Task.forItem( - 'Updating', - APP_CONFIG_FILE, - async () => await updateConfigFile(APP_CONFIG_FILE, config), - ); - - const patches = await fs.readdir(PATCH_FOLDER); - for (const patchFile of patches.filter(p => p.includes('github'))) { - await Task.forItem('Patching', patchFile, async () => { - await patch(patchFile); - }); - } - - return answers; -}; diff --git a/packages/cli/src/commands/onboard/auth/providers/gitlab.ts b/packages/cli/src/commands/onboard/auth/providers/gitlab.ts deleted file mode 100644 index bc5491111c..0000000000 --- a/packages/cli/src/commands/onboard/auth/providers/gitlab.ts +++ /dev/null @@ -1,115 +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 chalk from 'chalk'; -import * as fs from 'fs-extra'; -import inquirer from 'inquirer'; -import { Task } from '../../../../lib/tasks'; -import { updateConfigFile } from '../../config'; -import { APP_CONFIG_FILE, PATCH_FOLDER } from '../../files'; -import { patch } from '../patch'; - -const getConfig = (answers: Answers) => { - const { clientId, clientSecret, hasAudience, audience } = answers; - - return { - auth: { - providers: { - gitlab: { - development: { - clientId, - clientSecret, - ...(hasAudience && { - audience, - }), - }, - }, - }, - }, - }; -}; - -export type Answers = { - clientSecret: string; - clientId: string; - hasAudience: boolean; - audience?: string; -}; - -export const gitlab = async (): Promise => { - Task.log(` - To add GitLab authentication, you must create an Application from the GitLab Settings: ${chalk.blue( - 'https://gitlab.com/-/profile/applications', - )} - The Redirect URI should point to your Backstage backend auth handler. - - Settings for local development: - ${chalk.cyan(` - Name: Backstage (or your custom app name) - Redirect URI: http://localhost:7007/api/auth/gitlab/handler/frame - Scopes: read_api and read_user`)} - - You can find the full documentation page here: ${chalk.blue( - 'https://backstage.io/docs/auth/gitlab/provider', - )} - `); - - const answers = await inquirer.prompt([ - { - type: 'input', - name: 'clientId', - message: 'What is your Application Id?', - validate: (input: string) => (input.length ? true : false), - }, - { - type: 'input', - name: 'clientSecret', - message: 'What is your Application Secret?', - validate: (input: string) => (input.length ? true : false), - }, - { - type: 'confirm', - name: 'hasAudience', - message: 'Do you have a self-hosted instance of GitLab?', - }, - { - type: 'input', - name: 'audience', - message: 'What is the URL for your GitLab instance?', - when: ({ hasAudience }) => hasAudience, - validate: (input: string) => Boolean(new URL(input)), - }, - ]); - - const config = getConfig(answers); - - Task.log('Setting up GitLab Authentication for you...'); - - await Task.forItem( - 'Updating', - APP_CONFIG_FILE, - async () => await updateConfigFile(APP_CONFIG_FILE, config), - ); - - const patches = await fs.readdir(PATCH_FOLDER); - for (const patchFile of patches.filter(p => p.includes('gitlab'))) { - await Task.forItem('Patching', patchFile, async () => { - await patch(patchFile); - }); - } - - return answers; -}; diff --git a/packages/cli/src/commands/onboard/command.ts b/packages/cli/src/commands/onboard/command.ts deleted file mode 100644 index f68685f3e6..0000000000 --- a/packages/cli/src/commands/onboard/command.ts +++ /dev/null @@ -1,83 +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 chalk from 'chalk'; -import inquirer from 'inquirer'; -import { Task } from '../../lib/tasks'; -import { auth } from './auth'; -import { integrations } from './integrations'; -import { discover } from './discovery'; - -export async function command(): Promise { - const answers = await inquirer.prompt<{ - shouldSetupAuth: boolean; - shouldSetupScaffolder: boolean; - shouldDiscoverEntities: boolean; - }>([ - { - type: 'confirm', - name: 'shouldSetupAuth', - message: 'Do you want to set up Authentication for this project?', - default: true, - }, - { - type: 'confirm', - name: 'shouldSetupScaffolder', - message: 'Do you want to use Software Templates in this project?', - default: true, - }, - { - type: 'confirm', - name: 'shouldDiscoverEntities', - message: - 'Do you want to discover entities and add them to the Software Catalog?', - default: true, - }, - ]); - - const { shouldSetupAuth, shouldSetupScaffolder, shouldDiscoverEntities } = - answers; - - if (!shouldSetupAuth && !shouldSetupScaffolder && !shouldDiscoverEntities) { - Task.log( - chalk.yellow( - 'If you change your mind, feel free to re-run this command.', - ), - ); - return; - } - - let providerInfo; - if (shouldSetupAuth) { - providerInfo = await auth(); - } - - if (shouldSetupScaffolder) { - await integrations(providerInfo); - } - - if (shouldDiscoverEntities) { - await discover(providerInfo); - } - - Task.log(); - Task.log( - `You can now start your app with ${chalk.inverse( - chalk.italic('yarn dev'), - )}`, - ); - Task.log(); -} diff --git a/packages/cli/src/commands/onboard/config.ts b/packages/cli/src/commands/onboard/config.ts deleted file mode 100644 index cce3119fcc..0000000000 --- a/packages/cli/src/commands/onboard/config.ts +++ /dev/null @@ -1,45 +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 * as fs from 'fs-extra'; -import yaml from 'yaml'; - -const readYaml = async (file: string) => { - return yaml.parse(await fs.readFile(file, 'utf8')); -}; - -export const updateConfigFile = async (file: string, config: T) => { - const staticContent = - '# Backstage override configuration for your local development environment \n'; - - const content = fs.existsSync(file) - ? yaml.stringify( - { ...(await readYaml(file)), ...config }, - { - indent: 2, - }, - ) - : staticContent.concat( - yaml.stringify( - { ...config }, - { - indent: 2, - }, - ), - ); - - return await fs.writeFile(file, content, 'utf8'); -}; diff --git a/packages/cli/src/commands/onboard/discovery/Discovery.ts b/packages/cli/src/commands/onboard/discovery/Discovery.ts deleted file mode 100644 index b0db4255ad..0000000000 --- a/packages/cli/src/commands/onboard/discovery/Discovery.ts +++ /dev/null @@ -1,71 +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 chalk from 'chalk'; -import { Entity } from '@backstage/catalog-model'; -import { Analyzer } from './analyzers/types'; -import { Provider } from './providers/types'; -import { DefaultAnalysisOutputs } from './analyzers/DefaultAnalysisOutputs'; -import { Task } from '../../../lib/tasks'; - -export class Discovery { - readonly #providers: Provider[] = []; - readonly #analyzers: Analyzer[] = []; - - addProvider(provider: Provider) { - this.#providers.push(provider); - } - - addAnalyzer(analyzer: Analyzer) { - this.#analyzers.push(analyzer); - } - - async run(url: string): Promise<{ entities: Entity[] }> { - Task.log(`Running discovery for ${chalk.cyan(url)}`); - const result: Entity[] = []; - - for (const provider of this.#providers) { - const repositories = await provider.discover(url); - if (repositories && repositories.length) { - Task.log( - `Discovered ${chalk.cyan( - repositories.length, - )} repositories for ${chalk.cyan(provider.name())}`, - ); - - for (const repository of repositories) { - await Task.forItem('Analyzing', repository.name, async () => { - const output = new DefaultAnalysisOutputs(); - for (const analyzer of this.#analyzers) { - await analyzer.analyzeRepository({ repository, output }); - } - - output - .list() - .filter(entry => entry.type === 'entity') - .forEach(({ entity }) => result.push(entity)); - }); - } - - Task.log(`Produced ${chalk.cyan(result.length || 'no')} entities`); - } - } - - return { - entities: result, - }; - } -} diff --git a/packages/cli/src/commands/onboard/discovery/analyzers/BasicRepositoryAnalyzer.ts b/packages/cli/src/commands/onboard/discovery/analyzers/BasicRepositoryAnalyzer.ts deleted file mode 100644 index 82c8c2cdae..0000000000 --- a/packages/cli/src/commands/onboard/discovery/analyzers/BasicRepositoryAnalyzer.ts +++ /dev/null @@ -1,56 +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 { ComponentEntity } from '@backstage/catalog-model'; -import { AnalysisOutputs, Analyzer } from './types'; -import { Repository } from '../providers/types'; - -/** - * Naive analyzer that produces a single entity that represents the repository - * as a whole. - */ -export class BasicRepositoryAnalyzer implements Analyzer { - name(): string { - return BasicRepositoryAnalyzer.name; - } - - async analyzeRepository(options: { - repository: Repository; - output: AnalysisOutputs; - }): Promise { - const entity: ComponentEntity = { - apiVersion: 'backstage.io/v1alpha1', - kind: 'Component', - metadata: { - name: options.repository.name, - ...(options.repository.description - ? { description: options.repository.description } - : {}), - }, - spec: { - type: 'service', - lifecycle: 'production', - owner: 'user:guest', - }, - }; - - options.output.produce({ - type: 'entity', - path: '/', - entity: entity, - }); - } -} diff --git a/packages/cli/src/commands/onboard/discovery/analyzers/DefaultAnalysisOutputs.ts b/packages/cli/src/commands/onboard/discovery/analyzers/DefaultAnalysisOutputs.ts deleted file mode 100644 index a370b8f166..0000000000 --- a/packages/cli/src/commands/onboard/discovery/analyzers/DefaultAnalysisOutputs.ts +++ /dev/null @@ -1,29 +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 { AnalysisOutput, AnalysisOutputs } from './types'; - -export class DefaultAnalysisOutputs implements AnalysisOutputs { - readonly #outputs = new Map(); - - produce(output: AnalysisOutput) { - this.#outputs.set(output.entity.metadata.name, output); - } - - list() { - return Array.from(this.#outputs).map(([_, output]) => output); - } -} diff --git a/packages/cli/src/commands/onboard/discovery/analyzers/PackageJsonAnalyzer.ts b/packages/cli/src/commands/onboard/discovery/analyzers/PackageJsonAnalyzer.ts deleted file mode 100644 index 16dd4b9301..0000000000 --- a/packages/cli/src/commands/onboard/discovery/analyzers/PackageJsonAnalyzer.ts +++ /dev/null @@ -1,128 +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 { - ANNOTATION_SOURCE_LOCATION, - ComponentEntity, -} from '@backstage/catalog-model'; -import z from 'zod'; -import { AnalysisOutputs, Analyzer } from './types'; -import { Repository, RepositoryFile } from '../providers/types'; - -export class PackageJsonAnalyzer implements Analyzer { - name(): string { - return PackageJsonAnalyzer.name; - } - - async analyzeRepository(options: { - repository: Repository; - output: AnalysisOutputs; - }): Promise { - const packageJson = await options.repository.file('package.json'); - if (!packageJson) { - return; - } - - const content = await readPackageJson(packageJson); - if (!content) { - return; - } - - const name = sanitizeName(content?.name) ?? options.repository.name; - - const entity: ComponentEntity = { - apiVersion: 'backstage.io/v1alpha1', - kind: 'Component', - metadata: { - name, - ...(options.repository.description - ? { description: options.repository.description } - : {}), - tags: ['javascript'], - annotations: { - [ANNOTATION_SOURCE_LOCATION]: `url:${options.repository.url}`, - }, - }, - spec: { - type: 'website', - lifecycle: 'production', - owner: 'user:guest', - }, - }; - - const decorate = options.output - .list() - .find(entry => entry.entity.metadata.name === name); - - if (decorate) { - decorate.entity.spec = { - ...decorate.entity.spec, - type: 'website', - }; - - decorate.entity.metadata.tags = [ - ...(decorate.entity.metadata.tags ?? []), - 'javascript', - ]; - - decorate.entity.metadata.annotations = { - ...decorate.entity.metadata.annotations, - [ANNOTATION_SOURCE_LOCATION]: `url:${options.repository.url}`, - }; - - return; - } - - options.output.produce({ - type: 'entity', - path: '/', - entity, - }); - } -} - -const packageSchema = z.object({ - name: z.string().optional(), -}); - -/** - * Makes sure that a name retrieved from a package.json file - * is reasonable and conforms to the catalog naming format. - * - * Read more about the naming format here: - * ADR002: Default Software Catalog File Format - * https://backstage.io/docs/architecture-decisions/adrs-adr002/ - */ -function sanitizeName(name?: string) { - return name && name !== 'root' - ? name.replace(/[^a-z0-9A-Z]/g, '_').substring(0, 62) - : undefined; -} - -async function readPackageJson( - file: RepositoryFile, -): Promise | undefined> { - try { - const text = await file.text(); - const result = packageSchema.safeParse(JSON.parse(text)); - if (!result.success) { - return undefined; - } - return { name: result.data.name }; - } catch (e) { - return undefined; - } -} diff --git a/packages/cli/src/commands/onboard/discovery/analyzers/types.ts b/packages/cli/src/commands/onboard/discovery/analyzers/types.ts deleted file mode 100644 index 57b6f2152b..0000000000 --- a/packages/cli/src/commands/onboard/discovery/analyzers/types.ts +++ /dev/null @@ -1,37 +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 { Entity } from '@backstage/catalog-model'; -import { Repository } from '../providers/types'; - -export type AnalysisOutput = { - type: 'entity'; - path: string; - entity: Entity; -}; - -export interface AnalysisOutputs { - produce(output: AnalysisOutput): void; - list(): AnalysisOutput[]; -} - -export interface Analyzer { - name(): string; - analyzeRepository(options: { - repository: Repository; - output: AnalysisOutputs; - }): Promise; -} diff --git a/packages/cli/src/commands/onboard/discovery/index.ts b/packages/cli/src/commands/onboard/discovery/index.ts deleted file mode 100644 index 8b2a5b694a..0000000000 --- a/packages/cli/src/commands/onboard/discovery/index.ts +++ /dev/null @@ -1,141 +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 fs from 'fs-extra'; -import yaml from 'yaml'; -import inquirer from 'inquirer'; -import chalk from 'chalk'; -import { loadCliConfig } from '../../../lib/config'; -import { updateConfigFile } from '../config'; -import { APP_CONFIG_FILE, DISCOVERED_ENTITIES_FILE } from '../files'; -import { Discovery } from './Discovery'; -import { BasicRepositoryAnalyzer } from './analyzers/BasicRepositoryAnalyzer'; -import { PackageJsonAnalyzer } from './analyzers/PackageJsonAnalyzer'; -import { GithubDiscoveryProvider } from './providers/github/GithubDiscoveryProvider'; -import { GitlabDiscoveryProvider } from './providers/gitlab/GitlabDiscoveryProvider'; -import { GitHubAnswers, GitLabAnswers } from '../auth'; -import { Task } from '../../../lib/tasks'; - -export async function discover(providerInfo?: { - provider: string; - answers: GitHubAnswers | GitLabAnswers; -}) { - Task.log(` - Would you like to scan for - and create - Software Catalog entities? - - You will need to select which SCM (Source Code Management) provider you are using, - and then which repository or organization you want to scan. - - This will generate a new file in the root of your app containing discovered entities, - which will be included in the Software Catalog when you start up Backstage next time. - - Note that this command requires an access token, which can be either added through the integration config or - provided as an environment variable. - `); - - const answers = await inquirer.prompt<{ - shouldContinue: boolean; - provider: string; - url: string; - }>([ - { - type: 'confirm', - name: 'shouldContinue', - message: 'Do you want to continue?', - }, - { - type: 'list', - name: 'provider', - message: 'Please select which SCM provider you want to use:', - choices: ['GitHub', 'GitLab'], - default: providerInfo?.provider, - when: ({ shouldContinue }) => shouldContinue, - }, - { - type: 'input', - name: 'url', - message: `Which repository do you want to scan?`, - when: ({ shouldContinue }) => shouldContinue, - filter: (input, { provider }) => { - if (provider === 'GitLab') { - return `https://gitlab.com/${input}`; - } - if (provider === 'GitHub') { - return `https://github.com/${input}`; - } - return false; - }, - }, - ]); - - if (!answers.shouldContinue) { - Task.log( - chalk.yellow( - 'If you change your mind, feel free to re-run this command.', - ), - ); - return; - } - - const { fullConfig: config } = await loadCliConfig({ args: [] }); - - const discovery = new Discovery(); - - if (answers.provider === 'GitHub') { - discovery.addProvider(GithubDiscoveryProvider.fromConfig(config)); - } - if (answers.provider === 'GitLab') { - discovery.addProvider(GitlabDiscoveryProvider.fromConfig(config)); - } - - discovery.addAnalyzer(new BasicRepositoryAnalyzer()); - discovery.addAnalyzer(new PackageJsonAnalyzer()); - - const { entities } = await discovery.run(answers.url); - - if (!entities.length) { - Task.log( - chalk.yellow(` - We could not find enough information to be able to generate any Software Catalog entities for you. - Perhaps you can try again with a different repository?`), - ); - return; - } - - await Task.forItem('Creating', DISCOVERED_ENTITIES_FILE, async () => { - const payload: string[] = []; - for (const entity of entities) { - payload.push('---\n', yaml.stringify(entity)); - } - await fs.writeFile(DISCOVERED_ENTITIES_FILE, payload.join('')); - }); - - await Task.forItem( - 'Updating', - APP_CONFIG_FILE, - async () => - await updateConfigFile(APP_CONFIG_FILE, { - catalog: { - locations: [ - { - type: 'file', - target: DISCOVERED_ENTITIES_FILE, - }, - ], - }, - }), - ); -} diff --git a/packages/cli/src/commands/onboard/discovery/providers/github/GithubDiscoveryProvider.ts b/packages/cli/src/commands/onboard/discovery/providers/github/GithubDiscoveryProvider.ts deleted file mode 100644 index a24756edd7..0000000000 --- a/packages/cli/src/commands/onboard/discovery/providers/github/GithubDiscoveryProvider.ts +++ /dev/null @@ -1,163 +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 { Config } from '@backstage/config'; -import { - DefaultGithubCredentialsProvider, - GithubCredentialsProvider, - ScmIntegrations, -} from '@backstage/integration'; -import { graphql } from '@octokit/graphql'; -import { - Repository as GraphqlRepository, - Query as GraphqlQuery, -} from '@octokit/graphql-schema'; -import parseGitUrl from 'git-url-parse'; -import { Provider, Repository } from '../types'; -import { GithubRepository } from './GithubRepository'; - -export class GithubDiscoveryProvider implements Provider { - readonly #envToken: string | undefined; - readonly #scmIntegrations: ScmIntegrations; - readonly #credentialsProvider: GithubCredentialsProvider; - - static fromConfig(config: Config): GithubDiscoveryProvider { - const envToken = process.env.GITHUB_TOKEN || undefined; - const scmIntegrations = ScmIntegrations.fromConfig(config); - const credentialsProvider = - DefaultGithubCredentialsProvider.fromIntegrations(scmIntegrations); - return new GithubDiscoveryProvider( - envToken, - scmIntegrations, - credentialsProvider, - ); - } - - private constructor( - envToken: string | undefined, - integrations: ScmIntegrations, - credentialsProvider: GithubCredentialsProvider, - ) { - this.#envToken = envToken; - this.#scmIntegrations = integrations; - this.#credentialsProvider = credentialsProvider; - } - - name(): string { - return 'GitHub'; - } - - async discover(url: string): Promise { - if (!url.startsWith('https://github.com/')) { - return false; - } - - const scmIntegration = this.#scmIntegrations.github.byUrl(url); - if (!scmIntegration) { - throw new Error(`No GitHub integration found for ${url}`); - } - - const parsed = parseGitUrl(url); - const { name, organization } = parsed; - const org = organization || name; // depends on if it's a repo url or an org url... - - const client = graphql.defaults({ - baseUrl: scmIntegration.config.apiBaseUrl, - headers: await this.#getRequestHeaders(url), - }); - - const { repositories } = await this.#getOrganizationRepositories( - client, - org, - ); - - return repositories - .filter(repo => repo.url.startsWith(url)) - .map(repo => new GithubRepository(client, repo, org)); - } - - async #getRequestHeaders(url: string): Promise> { - const credentials = await this.#credentialsProvider.getCredentials({ - url, - }); - - if (credentials.headers) { - return credentials.headers; - } else if (credentials.token) { - return { authorization: `token ${credentials.token}` }; - } - - if (this.#envToken) { - return { authorization: `token ${this.#envToken}` }; - } - - throw new Error( - 'No token available for GitHub, please configure your integrations or set a GITHUB_TOKEN env variable', - ); - } - - async #getOrganizationRepositories(client: typeof graphql, org: string) { - const query = `query repositories($org: String!, $cursor: String) { - repositoryOwner(login: $org) { - login - repositories(first: 50, after: $cursor) { - nodes { - name - url - description - isArchived - isFork - } - pageInfo { - hasNextPage - endCursor - } - } - } - }`; - - const result: GraphqlRepository[] = []; - - let cursor: string | undefined | null = undefined; - let hasNextPage = true; - - while (hasNextPage) { - const response: GraphqlQuery = await client(query, { - org, - cursor, - }); - - const { repositories: connection } = response.repositoryOwner ?? {}; - - if (!connection) { - throw new Error(`Found no repositories for ${org}`); - } - - for (const repository of connection.nodes ?? []) { - if (repository && !repository.isArchived && !repository.isFork) { - result.push(repository); - } - } - - cursor = connection.pageInfo.endCursor; - hasNextPage = connection.pageInfo.hasNextPage; - } - - return { - repositories: result, - }; - } -} diff --git a/packages/cli/src/commands/onboard/discovery/providers/github/GithubFile.ts b/packages/cli/src/commands/onboard/discovery/providers/github/GithubFile.ts deleted file mode 100644 index 25279b0949..0000000000 --- a/packages/cli/src/commands/onboard/discovery/providers/github/GithubFile.ts +++ /dev/null @@ -1,35 +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 { RepositoryFile } from '../types'; - -export class GithubFile implements RepositoryFile { - readonly #path: string; - readonly #content: string; - - constructor(path: string, content: string) { - this.#path = path; - this.#content = content; - } - - get path(): string { - return this.#path; - } - - async text(): Promise { - return this.#content; - } -} diff --git a/packages/cli/src/commands/onboard/discovery/providers/github/GithubRepository.ts b/packages/cli/src/commands/onboard/discovery/providers/github/GithubRepository.ts deleted file mode 100644 index f3c68851a0..0000000000 --- a/packages/cli/src/commands/onboard/discovery/providers/github/GithubRepository.ts +++ /dev/null @@ -1,84 +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 { graphql } from '@octokit/graphql'; -import { - Repository as GraphqlRepository, - Blob as GraphqlBlob, -} from '@octokit/graphql-schema'; -import { Repository, RepositoryFile } from '../types'; -import { GithubFile } from './GithubFile'; - -export class GithubRepository implements Repository { - readonly #client: typeof graphql; - readonly #repo: GraphqlRepository; - readonly #org: string; - - constructor(client: typeof graphql, repo: GraphqlRepository, org: string) { - this.#client = client; - this.#repo = repo; - this.#org = org; - } - - get url(): string { - return this.#repo.url; - } - - get name(): string { - return this.#repo.name; - } - - get owner(): string { - return this.#org; - } - - get description(): string | undefined { - return this.#repo.description ?? undefined; - } - - async file(filename: string): Promise { - const content = await this.#getFileContent(filename); - if (!content || content.isBinary || !content.text) { - return undefined; - } - - return new GithubFile(filename, content.text ?? ''); - } - - async #getFileContent(filename: string) { - const query = `query RepoFiles($owner: String!, $name: String!, $expr: String!) { - repository(owner: $owner, name: $name) { - object(expression: $expr) { - ...on Blob { - text - isBinary - } - } - } - }`; - - const response = await this.#client<{ repository: GraphqlRepository }>( - query, - { - name: this.#repo.name, - owner: this.#org, - expr: `HEAD:${filename}`, - }, - ); - - return response.repository.object as GraphqlBlob; - } -} diff --git a/packages/cli/src/commands/onboard/discovery/providers/gitlab/GitlabDiscoveryProvider.ts b/packages/cli/src/commands/onboard/discovery/providers/gitlab/GitlabDiscoveryProvider.ts deleted file mode 100644 index df9ffa4206..0000000000 --- a/packages/cli/src/commands/onboard/discovery/providers/gitlab/GitlabDiscoveryProvider.ts +++ /dev/null @@ -1,106 +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 { Config } from '@backstage/config'; -import { - DefaultGitlabCredentialsProvider, - GitlabCredentialsProvider, - ScmIntegrations, -} from '@backstage/integration'; -import fetch from 'node-fetch'; -import { Provider } from '../types'; -import { GitlabProject, ProjectResponse } from './GitlabProject'; - -export class GitlabDiscoveryProvider implements Provider { - readonly #envToken: string | undefined; - readonly #scmIntegrations: ScmIntegrations; - readonly #credentialsProvider: GitlabCredentialsProvider; - - static fromConfig(config: Config): GitlabDiscoveryProvider { - const envToken = process.env.GITLAB_TOKEN || undefined; - const scmIntegrations = ScmIntegrations.fromConfig(config); - const credentialsProvider = - DefaultGitlabCredentialsProvider.fromIntegrations(scmIntegrations); - - return new GitlabDiscoveryProvider( - envToken, - scmIntegrations, - credentialsProvider, - ); - } - - private constructor( - envToken: string | undefined, - integrations: ScmIntegrations, - credentialsProvider: GitlabCredentialsProvider, - ) { - this.#envToken = envToken; - this.#scmIntegrations = integrations; - this.#credentialsProvider = credentialsProvider; - } - - name(): string { - return 'GitLab'; - } - - async discover(url: string): Promise { - const { origin, pathname } = new URL(url); - const [, user] = pathname.split('/'); - - const scmIntegration = this.#scmIntegrations.gitlab.byUrl(origin); - if (!scmIntegration) { - throw new Error(`No GitLab integration found for ${origin}`); - } - - const headers = await this.#getRequestHeaders(origin); - - const response = await fetch( - `${scmIntegration.config.apiBaseUrl}/users/${user}/projects`, - { headers }, - ); - - if (!response.ok) { - throw new Error(`${response.status} ${response.statusText}`); - } - - const projects: ProjectResponse[] = await response.json(); - - return projects.map( - project => - new GitlabProject(project, scmIntegration.config.apiBaseUrl, headers), - ); - } - - async #getRequestHeaders(url: string): Promise> { - const credentials = await this.#credentialsProvider.getCredentials({ - url, - }); - - if (credentials.headers) { - return credentials.headers; - } else if (credentials.token) { - return { authorization: `Bearer ${credentials.token}` }; - } - - if (this.#envToken) { - return { authorization: `Bearer ${this.#envToken}` }; - } - - throw new Error( - 'No token available for GitLab, please set a GITLAB_TOKEN env variable', - ); - } -} diff --git a/packages/cli/src/commands/onboard/discovery/providers/gitlab/GitlabFile.ts b/packages/cli/src/commands/onboard/discovery/providers/gitlab/GitlabFile.ts deleted file mode 100644 index 06f3189ba6..0000000000 --- a/packages/cli/src/commands/onboard/discovery/providers/gitlab/GitlabFile.ts +++ /dev/null @@ -1,38 +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 { RepositoryFile } from '../types'; - -/** - * A single file in a GitLab repository. - */ -export class GitlabFile implements RepositoryFile { - readonly #path: string; - readonly #content: string; - - constructor(path: string, content: string) { - this.#path = path; - this.#content = content; - } - - get path(): string { - return this.#path; - } - - async text(): Promise { - return this.#content; - } -} diff --git a/packages/cli/src/commands/onboard/discovery/providers/gitlab/GitlabProject.ts b/packages/cli/src/commands/onboard/discovery/providers/gitlab/GitlabProject.ts deleted file mode 100644 index 258e8176bb..0000000000 --- a/packages/cli/src/commands/onboard/discovery/providers/gitlab/GitlabProject.ts +++ /dev/null @@ -1,89 +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 fetch from 'node-fetch'; -import { GitlabFile } from './GitlabFile'; -import { Repository, RepositoryFile } from '../types'; - -export type ProjectResponse = { - id: string; - name: string; - description: string; - owner: { - username: string; - }; - web_url: string; -}; - -type BranchResponse = { - default: boolean; - name: string; -}; - -type FileContentResponse = { - content: string; -}; - -export class GitlabProject implements Repository { - constructor( - private readonly project: ProjectResponse, - private readonly apiBaseUrl: string, - private readonly headers: { [name: string]: string }, - ) {} - - get url(): string { - return this.project.web_url; - } - - get name(): string { - return this.project.name; - } - - get owner(): string { - return this.project.owner.username; - } - - get description(): string { - return this.project.description; - } - - async file(filename: string): Promise { - const mainBranch = await this.#getMainBranch(); - const content = await this.#getFileContent(filename, mainBranch); - - return new GitlabFile(filename, content); - } - - async #getFileContent(path: string, mainBranch: string): Promise { - const response = await fetch( - `${this.apiBaseUrl}/projects/${this.project.id}/repository/files/${path}?ref=${mainBranch}`, - { headers: this.headers }, - ); - const { content }: FileContentResponse = await response.json(); - - return Buffer.from(content, 'base64').toString('ascii'); - } - - async #getMainBranch(): Promise { - const response = await fetch( - `${this.apiBaseUrl}/projects/${this.project.id}/repository/branches`, - { headers: this.headers }, - ); - const branches: BranchResponse[] = await response.json(); - - return branches.find(branch => branch.default)?.name ?? 'main'; - } -} diff --git a/packages/cli/src/commands/onboard/discovery/providers/types.ts b/packages/cli/src/commands/onboard/discovery/providers/types.ts deleted file mode 100644 index 2d8ce70ecf..0000000000 --- a/packages/cli/src/commands/onboard/discovery/providers/types.ts +++ /dev/null @@ -1,53 +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. - */ - -/** - * Abstraction for a single repository. - */ -export interface Repository { - url: string; - - name: string; - - owner: string; - - description?: string; - - file(filename: string): Promise; -} - -/** - * Abstraction for a single repository file. - */ -export interface RepositoryFile { - /** - * The filepath of the data. - */ - path: string; - - /** - * The textual contents of the file. - */ - text(): Promise; -} - -/** - * One integration that supports discovery of repositories. - */ -export interface Provider { - name(): string; - discover(url: string): Promise; -} diff --git a/packages/cli/src/commands/onboard/files.ts b/packages/cli/src/commands/onboard/files.ts deleted file mode 100644 index febec35d4a..0000000000 --- a/packages/cli/src/commands/onboard/files.ts +++ /dev/null @@ -1,36 +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 { findPaths } from '@backstage/cli-common'; -import * as path from 'path'; - -/* eslint-disable-next-line no-restricted-syntax */ -const { targetRoot, ownDir } = findPaths(__dirname); - -export const APP_CONFIG_FILE = path.join(targetRoot, 'app-config.local.yaml'); -export const DISCOVERED_ENTITIES_FILE = path.join( - targetRoot, - 'examples', - 'discovered-entities.yaml', -); -export const PATCH_FOLDER = path.join( - ownDir, - 'src', - 'commands', - 'onboard', - 'auth', - 'patches', -); diff --git a/packages/cli/src/commands/onboard/integrations/github.ts b/packages/cli/src/commands/onboard/integrations/github.ts deleted file mode 100644 index a0538c7ace..0000000000 --- a/packages/cli/src/commands/onboard/integrations/github.ts +++ /dev/null @@ -1,136 +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 chalk from 'chalk'; -import inquirer from 'inquirer'; -import { Task } from '../../../lib/tasks'; -import { updateConfigFile } from '../config'; -import { APP_CONFIG_FILE } from '../files'; -import { GitHubAnswers } from '../auth'; - -type Answers = { - hasEnterprise: boolean; - enterpriseInstanceUrl: string; - apiBaseUrl: string; -}; - -const getConfig = ({ - hasEnterprise, - apiBaseUrl, - host, - token, -}: { - hasEnterprise: boolean; - apiBaseUrl: string; - host: string; - token: string; -}) => ({ - integrations: { - github: [ - { - host, - token, - ...(hasEnterprise && { - apiBaseUrl, - }), - }, - ], - }, -}); - -export const github = async (providerAnswers?: GitHubAnswers) => { - // TODO(tudi2d): Is GitHub Enterprise a valid setup if there is no Authentication? - const answers = await inquirer.prompt([ - { - type: 'confirm', - name: 'hasEnterprise', - message: 'Are you using GitHub Enterprise?', - when: () => typeof providerAnswers === 'undefined', - }, - { - type: 'input', - name: 'enterpriseInstanceUrl', - message: 'What is your URL for GitHub Enterprise?', - when: ({ hasEnterprise }) => hasEnterprise, - validate: (input: string) => Boolean(new URL(input)), - }, - { - type: 'input', - name: 'apiBaseUrl', - message: 'What is your GitHub Enterprise API path?', - default: '/api/v3', - when: ({ hasEnterprise }) => - hasEnterprise || providerAnswers?.hasEnterprise, - // TODO(tudi2d): Fetch API using OAuth Token if Auth was set up - }, - ]); - - const host = new URL( - providerAnswers?.enterpriseInstanceUrl ?? - answers?.enterpriseInstanceUrl ?? - 'http://github.com', - ); - - Task.log(` - To create new repositories in GitHub using Software Templates you first need to create a personal access token: ${chalk.blue( - `${host.origin}/settings/tokens/new`, - )} - - Select the following scopes: - - Reading software components:${chalk.cyan(` - - "repo"`)} - - Reading organization data:${chalk.cyan(` - - "read:org" - - "read:user" - - "user:email"`)} - - Publishing software templates:${chalk.cyan(` - - "repo" - - "workflow" (if templates include GitHub workflows) - `)} - - You can find the full documentation page here: ${chalk.blue( - 'https://backstage.io/docs/integrations/github/locations', - )} - `); - - const { token } = await inquirer.prompt<{ token: string }>([ - { - type: 'input', - name: 'token', - message: - 'Please insert your personal access token to setup the GitHub Integration', - // TODO(tudi2d): validate - }, - ]); - - const config = getConfig({ - hasEnterprise: providerAnswers?.hasEnterprise ?? answers.hasEnterprise, - apiBaseUrl: host.origin + answers.apiBaseUrl, - host: host.hostname, - token, - }); - - Task.log('Setting up Software Templates using GitHub integration for you...'); - - await Task.forItem( - 'Updating', - APP_CONFIG_FILE, - async () => await updateConfigFile(APP_CONFIG_FILE, config), - ); -}; diff --git a/packages/cli/src/commands/onboard/integrations/index.ts b/packages/cli/src/commands/onboard/integrations/index.ts deleted file mode 100644 index 5cb2f95b38..0000000000 --- a/packages/cli/src/commands/onboard/integrations/index.ts +++ /dev/null @@ -1,75 +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 inquirer from 'inquirer'; -import { Task } from '../../../lib/tasks'; -import { GitHubAnswers, GitLabAnswers } from '../auth'; -import { github } from './github'; - -enum Integration { - GITHUB = 'GitHub', -} - -const Integrations: Integration[] = [Integration.GITHUB]; - -export async function integrations(providerInfo?: { - provider: string; - answers: GitHubAnswers | GitLabAnswers; -}): Promise { - const answers = await inquirer.prompt<{ - integration?: Integration; - shouldUsePreviousProvider: boolean; - }>([ - { - type: 'confirm', - name: 'shouldUsePreviousProvider', - message: `Do you want to keep using ${providerInfo?.provider} as your provider when setting up Software Templates?`, - when: () => - providerInfo?.provider && - Object.values(Integrations).includes( - providerInfo!.provider as Integration, - ), - }, - { - // TODO(tudi2d): Let's start with one, but it should be multiple choice in the future - type: 'list', - name: 'integration', - message: 'Please select an integration provider:', - choices: Integrations, - when: ({ shouldUsePreviousProvider }) => !shouldUsePreviousProvider, - }, - ]); - - if (answers.shouldUsePreviousProvider) { - answers.integration = providerInfo!.provider as Integration; - } - - switch (answers.integration) { - case Integration.GITHUB: { - const providerAnswers = - providerInfo?.provider === 'GitHub' - ? (providerInfo!.answers as GitHubAnswers) - : undefined; - await github(providerAnswers); - break; - } - default: - } - - Task.log(); - Task.log(`Done setting up ${answers.integration} Integration!`); - Task.log(); -} diff --git a/packages/cli/src/commands/plugin/diff.ts b/packages/cli/src/commands/plugin/diff.ts deleted file mode 100644 index 07f2a94ea8..0000000000 --- a/packages/cli/src/commands/plugin/diff.ts +++ /dev/null @@ -1,102 +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 fs from 'fs-extra'; -import { OptionValues } from 'commander'; -import { - diffTemplateFiles, - handlers, - handleAllFiles, - inquirerPromptFunc, - makeCheckPromptFunc, - yesPromptFunc, -} from '../../lib/diff'; -import { paths } from '../../lib/paths'; - -export type PluginData = { - id: string; - name: string; - privatePackage: string; - pluginVersion: string; - npmRegistry: string; -}; - -const fileHandlers = [ - { - patterns: ['package.json'], - handler: handlers.packageJson, - }, - { - // make sure files in 1st level of src/ and dev/ exist - patterns: ['.eslintrc.js'], - handler: handlers.exists, - }, - { - patterns: ['README.md', 'tsconfig.json', /^src\//, /^dev\//], - handler: handlers.skip, - }, -]; - -export default async (opts: OptionValues) => { - let promptFunc = inquirerPromptFunc; - let finalize = () => {}; - - if (opts.check) { - [promptFunc, finalize] = makeCheckPromptFunc(); - } else if (opts.yes) { - promptFunc = yesPromptFunc; - } - - const data = await readPluginData(); - const templateFiles = await diffTemplateFiles('default-plugin', data); - await handleAllFiles(fileHandlers, templateFiles, promptFunc); - finalize(); -}; - -// Reads templating data from the existing plugin -async function readPluginData(): Promise { - let name: string; - let privatePackage: string; - let pluginVersion: string; - let npmRegistry: string; - try { - const pkg = require(paths.resolveTarget('package.json')); - name = pkg.name; - privatePackage = pkg.private; - pluginVersion = pkg.version; - const scope = name.split('/')[0]; - if (`${scope}:registry` in pkg.publishConfig) { - const registryURL = pkg.publishConfig[`${scope}:registry`]; - npmRegistry = `"${scope}:registry" : "${registryURL}"`; - } else npmRegistry = ''; - } catch (error) { - throw new Error(`Failed to read target package, ${error}`); - } - - const pluginTsContents = await fs.readFile( - paths.resolveTarget('src/plugin.ts'), - 'utf8', - ); - // TODO: replace with some proper parsing logic or plugin metadata file - const pluginIdMatch = pluginTsContents.match(/id: ['"`](.+?)['"`]/); - if (!pluginIdMatch) { - throw new Error(`Failed to parse plugin.ts, no plugin ID found`); - } - - const id = pluginIdMatch[1]; - - return { id, name, privatePackage, pluginVersion, npmRegistry }; -} diff --git a/packages/cli/src/commands/plugin/test.ts b/packages/cli/src/commands/plugin/test.ts deleted file mode 100644 index ca076ae6fc..0000000000 --- a/packages/cli/src/commands/plugin/test.ts +++ /dev/null @@ -1,31 +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 { OptionValues } from 'commander'; -import { run } from '../../lib/run'; - -export default async (opts: OptionValues) => { - const args = ['test']; - - if (opts.watch) { - args.push('--watch'); - } - if (opts.coverage) { - args.push('--coverage'); - } - - await run('web-scripts', args); -}; diff --git a/packages/cli/src/commands/remove-plugin/file-mocks.ts b/packages/cli/src/commands/remove-plugin/file-mocks.ts deleted file mode 100644 index 1264dc8f2e..0000000000 --- a/packages/cli/src/commands/remove-plugin/file-mocks.ts +++ /dev/null @@ -1,32 +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 const pluginsFileContent = ` -export { plugin as WelcomePlugin } from '@backstage/plugin-welcome'; -export { plugin as LighthousePlugin } from '@backstage/plugin-lighthouse';`; - -export const codeownersFileContent = ` -* @spotify/backstage-core -/docs/features/techdocs @spotify/techdocs-core -/plugins/cost-insights @spotify/silver-lining -`; - -export const packageFileContent = { - name: 'example-app', - version: '0.1.1', - dependencies: {}, - devDependencies: {}, - scripts: {}, -}; diff --git a/packages/cli/src/commands/repo/build.ts b/packages/cli/src/commands/repo/build.ts index 6d362c7d98..3ed528cd50 100644 --- a/packages/cli/src/commands/repo/build.ts +++ b/packages/cli/src/commands/repo/build.ts @@ -20,8 +20,8 @@ import { relative as relativePath } from 'path'; import { buildPackages, getOutputsForRole } from '../../lib/builder'; import { paths } from '../../lib/paths'; import { - PackageGraph, BackstagePackage, + PackageGraph, PackageRoles, } from '@backstage/cli-node'; import { runParallelWorkers } from '../../lib/parallel'; @@ -136,7 +136,8 @@ export async function command(opts: OptionValues, cmd: Command): Promise { packageJson: pkg.packageJson, outputs, logPrefix: `${chalk.cyan(relativePath(paths.targetRoot, pkg.dir))}: `, - minify: buildOptions.minify, + workspacePackages: packages, + minify: opts.minify ?? buildOptions.minify, }; }); @@ -179,7 +180,7 @@ export async function command(opts: OptionValues, cmd: Command): Promise { await buildBackend({ targetDir: pkg.dir, skipBuildDependencies: true, - minify: buildOptions.minify, + minify: opts.minify ?? buildOptions.minify, }); }, }); diff --git a/packages/cli/src/commands/start/startBackend.ts b/packages/cli/src/commands/start/startBackend.ts index 778a31e7e7..857e113b81 100644 --- a/packages/cli/src/commands/start/startBackend.ts +++ b/packages/cli/src/commands/start/startBackend.ts @@ -38,6 +38,10 @@ export async function startBackend(options: StartBackendOptions) { await waitForExit(); } else { + console.warn( + 'LEGACY_BACKEND_START is deprecated and will be removed in a future release', + ); + const waitForExit = await cleanDistAndServeBackend({ entry: 'src/index', checksEnabled: options.checksEnabled, @@ -55,15 +59,9 @@ export async function startBackendPlugin(options: StartBackendOptions) { const hasDevIndexEntry = await fs.pathExists( paths.resolveTarget('dev', 'index.ts'), ); - const hasSrcIndexEntry = await fs.pathExists( - paths.resolveTarget('src', 'run.ts'), - ); - - if (!hasDevIndexEntry && !hasSrcIndexEntry) { + if (!hasDevIndexEntry) { console.warn( - hasSrcIndexEntry - ? `The 'dev' directory is missing. The plugin might not be updated for the new backend system. To run, use "LEGACY_BACKEND_START=1 yarn start".` - : `The 'dev' directory is missing. Please create a proper dev/index.ts in order to start the plugin.`, + `The 'dev' directory is missing. Please create a proper dev/index.ts in order to start the plugin.`, ); return; } @@ -85,6 +83,9 @@ export async function startBackendPlugin(options: StartBackendOptions) { ); return; } + console.warn( + 'LEGACY_BACKEND_START is deprecated and will be removed in a future release', + ); const waitForExit = await cleanDistAndServeBackend({ entry: 'src/run', diff --git a/packages/cli/src/commands/versions/bump.ts b/packages/cli/src/commands/versions/bump.ts index 5b981d3890..e41bd98c49 100644 --- a/packages/cli/src/commands/versions/bump.ts +++ b/packages/cli/src/commands/versions/bump.ts @@ -25,6 +25,8 @@ import chalk from 'chalk'; import ora from 'ora'; import semver from 'semver'; import { OptionValues } from 'commander'; +import yaml from 'yaml'; +import z from 'zod'; import { isError, NotFoundError } from '@backstage/errors'; import { resolve as resolvePath } from 'path'; import { run } from '../../lib/run'; @@ -76,6 +78,8 @@ type PkgVersionInfo = { export default async (opts: OptionValues) => { const lockfilePath = paths.resolveTargetRoot('yarn.lock'); const lockfile = await Lockfile.load(lockfilePath); + const hasYarnPlugin = await getHasYarnPlugin(); + let pattern = opts.pattern; if (!pattern) { @@ -177,12 +181,34 @@ export default async (opts: OptionValues) => { for (const depType of DEP_TYPES) { if (depType in pkgJson && dep.name in pkgJson[depType]) { const oldRange = pkgJson[depType][dep.name]; - pkgJson[depType][dep.name] = dep.range; + + // backstage:^ are written to the lockfile as + // backstage:, so that updates to + // backstage.json can be detected during yarn install. In order to + // locate the corresponding lockfile entry for "backstage:^" + // versions, we need to perform the same transformation. + const oldLockfileRange = await asLockfileVersion(oldRange); + + const useBackstageRange = + hasYarnPlugin && + // Only use backstage:^ versions if the package is present in + // the manifest for the release we're bumping to. + releaseManifest.packages.find( + ({ name: manifestPackageName }) => + dep.name === manifestPackageName, + ) && + // Don't use backstage:^ versions for peerDependencies; they only + // support npm and workspace: versions. + depType !== 'peerDependencies'; + + const newRange = useBackstageRange ? 'backstage:^' : dep.range; + + pkgJson[depType][dep.name] = newRange; // Check if the update was at least a pre-v1 minor or post-v1 major release const lockfileEntry = lockfile .get(dep.name) - ?.find(entry => entry.range === oldRange); + ?.find(entry => entry.range === oldLockfileRange); if (lockfileEntry) { const from = lockfileEntry.version; const to = dep.target; @@ -266,6 +292,21 @@ export default async (opts: OptionValues) => { console.log(); } + if (hasYarnPlugin) { + console.log(); + console.log( + chalk.blue( + `${chalk.bold( + 'NOTE', + )}: this bump used backstage:^ versions in package.json files, since the Backstage ` + + `yarn plugin was detected in the repository. To migrate back to explicit npm versions, ` + + `remove the plugin by running "yarn plugin remove @yarnpkg/plugin-backstage", then ` + + `repeat this command.`, + ), + ); + console.log(); + } + console.log(chalk.green('Version bump complete!')); } @@ -354,16 +395,23 @@ export function createVersionFinder(options: { }; } -export async function bumpBackstageJsonVersion(version: string) { - const backstageJsonPath = paths.resolveTargetRoot(BACKSTAGE_JSON); - const backstageJson = await fs.readJSON(backstageJsonPath).catch(e => { +function getBackstageJsonPath() { + return paths.resolveTargetRoot(BACKSTAGE_JSON); +} + +async function getBackstageJson() { + const backstageJsonPath = getBackstageJsonPath(); + return fs.readJSON(backstageJsonPath).catch(e => { if (e.code === 'ENOENT') { // gracefully continue in case the file doesn't exist return; } throw e; }); +} +export async function bumpBackstageJsonVersion(version: string) { + const backstageJson = await getBackstageJson(); const prevVersion = backstageJson?.version; if (prevVersion === version) { @@ -394,7 +442,7 @@ export async function bumpBackstageJsonVersion(version: string) { } await fs.writeJson( - backstageJsonPath, + getBackstageJsonPath(), { ...backstageJson, version }, { spaces: 2, @@ -403,6 +451,53 @@ export async function bumpBackstageJsonVersion(version: string) { ); } +async function asLockfileVersion(version: string) { + if (version === 'backstage:^') { + return `backstage:${(await getBackstageJson())?.version}`; + } + + return version; +} + +const yarnRcSchema = z.object({ + plugins: z + .array( + z.object({ + path: z.string(), + }), + ) + .optional(), +}); + +async function getHasYarnPlugin() { + const yarnRcPath = paths.resolveTargetRoot('.yarnrc.yml'); + const yarnRcContent = await fs.readFile(yarnRcPath, 'utf-8').catch(e => { + if (e.code === 'ENOENT') { + // gracefully continue in case the file doesn't exist + return ''; + } + throw e; + }); + + if (!yarnRcContent) { + return false; + } + + const parseResult = yarnRcSchema.safeParse(yaml.parse(yarnRcContent)); + + if (!parseResult.success) { + throw new Error( + `Unexpected content in .yarnrc.yml: ${parseResult.error.toString()}`, + ); + } + + const yarnRc = parseResult.data; + + return yarnRc.plugins?.some( + plugin => plugin.path === '.yarn/plugins/@yarnpkg/plugin-backstage.cjs', + ); +} + export async function runYarnInstall() { const spinner = ora({ prefixText: `Running ${chalk.blue('yarn install')} to install new versions`, diff --git a/packages/cli/src/lib/__testUtils__/createFeatureEnvironment.ts b/packages/cli/src/lib/__testUtils__/createFeatureEnvironment.ts new file mode 100644 index 0000000000..a12a48c523 --- /dev/null +++ b/packages/cli/src/lib/__testUtils__/createFeatureEnvironment.ts @@ -0,0 +1,145 @@ +/* + * 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 { PackageRole } from '@backstage/cli-node'; +import { Project } from 'ts-morph'; +import { BackstagePackageFeatureType } from '../typeDistProject'; + +const mockEntryPoint = 'dist/index.d.ts'; + +type CreateFeatureEnvironmentOptions = { + $$type?: BackstagePackageFeatureType; + format?: + | 'DefaultExportAssignment' + | 'DefaultExportFromFile' + | 'DefaultExportFromFileAsDefault' + | 'DefaultExportFromFileWithSibling'; + role?: PackageRole; +}; + +type FeatureEnvironment = { + project: Project; + role: PackageRole; + dir: string; + entryPoint: string; +}; + +type File = { + path: string; + content: string; +}; + +const createTestType = ($$type: BackstagePackageFeatureType): File[] => [ + { + path: './dist/createTestType.d.ts', + content: ` +export interface TestType { + readonly $$type: '${$$type}'; +}; + +export function createTestType(): TestType { + return { + $$type: '${$$type}', + }; +}; + `, + }, +]; + +const createMockDefaultExportAssignment = (): File[] => [ + { + path: mockEntryPoint, + content: ` +declare const _default: import("./createTestType").TestType; +export default _default; + `, + }, +]; + +const createMockDefaultExportFromFile = (): File[] => [ + { + path: mockEntryPoint, + content: `export { default } from './linked';`, + }, + { + path: './dist/linked.d.ts', + content: ` +declare const _default: import("./createTestType").TestType; +export default _default; +`, + }, +]; + +const createMockDefaultExportFromFileAsDefault = (): File[] => [ + { + path: mockEntryPoint, + content: `export { test as default } from './linked';`, + }, + { + path: './dist/linked.d.ts', + content: ` +export declare const test: import("./createTestType").TestType; + `, + }, +]; + +const createMockDefaultExportFromFileWithSibling = (): File[] => [ + { + path: mockEntryPoint, + content: `export { default, test } from './linked';`, + }, + { + path: './dist/linked.d.ts', + content: ` +import { createTestType } from './createTestType'; + +export declare const test: import("./createTestType").TestType; +declare const _default: import("./createTestType").TestType; +export default _default; + `, + }, +]; + +const formatToFiles = { + DefaultExportAssignment: createMockDefaultExportAssignment, + DefaultExportFromFile: createMockDefaultExportFromFile, + DefaultExportFromFileAsDefault: createMockDefaultExportFromFileAsDefault, + DefaultExportFromFileWithSibling: createMockDefaultExportFromFileWithSibling, +}; + +export default function createFeatureEnvironment( + options?: CreateFeatureEnvironmentOptions, +): FeatureEnvironment { + const { + $$type = '@backstage/BackendFeature', + format = 'DefaultExportAssignment', + role = 'backend-plugin', + } = options ?? {}; + + const project = new Project(); + const files = [...createTestType($$type), ...formatToFiles[format]()]; + + for (const file of files) { + project.createSourceFile(file.path, file.content); + } + + return { + project, + role, + dir: project.getFileSystem().getCurrentDirectory(), + entryPoint: mockEntryPoint, + }; +} diff --git a/packages/cli/src/lib/builder/config.test.ts b/packages/cli/src/lib/builder/config.test.ts index 733c35fb55..e426e1ffa5 100644 --- a/packages/cli/src/lib/builder/config.test.ts +++ b/packages/cli/src/lib/builder/config.test.ts @@ -29,6 +29,7 @@ describe('makeRollupConfigs', () => { version: '0.0.0', main: './src/index.ts', }, + workspacePackages: [], }); const external = config.external as Exclude< ExternalOption, diff --git a/packages/cli/src/lib/builder/config.ts b/packages/cli/src/lib/builder/config.ts index a514158e9b..a11ffe8845 100644 --- a/packages/cli/src/lib/builder/config.ts +++ b/packages/cli/src/lib/builder/config.ts @@ -53,6 +53,21 @@ function isFileImport(source: string) { return false; } +function buildInternalImportPattern(options: BuildOptions) { + const inlinedPackages = options.workspacePackages.filter( + pkg => pkg.packageJson.backstage?.inline, + ); + for (const { packageJson } of inlinedPackages) { + if (!packageJson.private) { + throw new Error( + `Inlined package ${packageJson.name} must be marked as private`, + ); + } + } + const names = inlinedPackages.map(pkg => pkg.packageJson.name); + return new RegExp(`^(?:${names.join('|')})(?:$|/)`); +} + export async function makeRollupConfigs( options: BuildOptions, ): Promise { @@ -83,6 +98,19 @@ export async function makeRollupConfigs( SCRIPT_EXTS.includes(e.ext), ); + const internalImportPattern = buildInternalImportPattern(options); + const external = ( + source: string, + importer: string | undefined, + isResolved: boolean, + ) => + Boolean( + importer && + !isResolved && + !internalImportPattern.test(source) && + !isFileImport(source), + ); + if (options.outputs.has(Output.cjs) || options.outputs.has(Output.esm)) { const output = new Array(); const mainFields = ['module', 'main']; @@ -121,8 +149,7 @@ export async function makeRollupConfigs( makeAbsoluteExternalsRelative: false, preserveEntrySignatures: 'strict', // All module imports are always marked as external - external: (source, importer, isResolved) => - Boolean(importer && !isResolved && !isFileImport(source)), + external, plugins: [ resolve({ mainFields }), commonjs({ @@ -191,18 +218,11 @@ export async function makeRollupConfigs( chunkFileNames: `types/[name]-[hash].d.ts`, format: 'es', }, - external: [ - /\.css$/, - /\.scss$/, - /\.sass$/, - /\.svg$/, - /\.eot$/, - /\.woff$/, - /\.woff2$/, - /\.ttf$/, - ], + external: (source, importer, isResolved) => + /\.css|scss|sass|svg|eot|woff|woff2|ttf$/.test(source) || + external(source, importer, isResolved), onwarn, - plugins: [dts()], + plugins: [dts({ respectExternal: true })], }); } diff --git a/packages/cli/src/lib/builder/types.ts b/packages/cli/src/lib/builder/types.ts index 7d9c34fe29..937bd157c9 100644 --- a/packages/cli/src/lib/builder/types.ts +++ b/packages/cli/src/lib/builder/types.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { BackstagePackageJson } from '@backstage/cli-node'; +import { BackstagePackage, BackstagePackageJson } from '@backstage/cli-node'; export enum Output { esm, @@ -28,4 +28,5 @@ export type BuildOptions = { packageJson?: BackstagePackageJson; outputs: Set; minify?: boolean; + workspacePackages: BackstagePackage[]; }; diff --git a/packages/cli/src/lib/bundler/config.ts b/packages/cli/src/lib/bundler/config.ts index a64bc0fcd8..cc8a467bc2 100644 --- a/packages/cli/src/lib/bundler/config.ts +++ b/packages/cli/src/lib/bundler/config.ts @@ -347,6 +347,13 @@ export async function createConfig( return { mode, profile: false, + ...(isDev + ? { + watchOptions: { + ignored: /node_modules/, + }, + } + : {}), optimization, bail: false, performance: { diff --git a/packages/cli/src/lib/bundler/server.ts b/packages/cli/src/lib/bundler/server.ts index 259f3263eb..d73bcc662e 100644 --- a/packages/cli/src/lib/bundler/server.ts +++ b/packages/cli/src/lib/bundler/server.ts @@ -54,6 +54,7 @@ DEPRECATION WARNING: React Router Beta is deprecated and support for it will be const { name } = await fs.readJson(libPaths.resolveTarget('package.json')); let webpackServer: WebpackDevServer | undefined = undefined; + // @ts-ignore let viteServer: import('vite').ViteDevServer | undefined = undefined; let latestFrontendAppConfigs: AppConfig[] = []; diff --git a/packages/cli/src/lib/diff/handlers.ts b/packages/cli/src/lib/diff/handlers.ts deleted file mode 100644 index 55e9cddd3d..0000000000 --- a/packages/cli/src/lib/diff/handlers.ts +++ /dev/null @@ -1,354 +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 chalk from 'chalk'; -import { diffLines } from 'diff'; -import { sep, posix } from 'path'; -import { FileDiff, PromptFunc, FileHandler, WriteFileFunc } from './types'; - -function sortObjectKeys(obj: Record) { - const sortedKeys = Object.keys(obj).sort(); - for (const key of sortedKeys) { - const value = obj[key]; - delete obj[key]; - obj[key] = value; - } -} - -class PackageJsonHandler { - static async handler( - { path, write, missing, targetContents, templateContents }: FileDiff, - prompt: PromptFunc, - variant?: string, - ) { - console.log('Checking package.json'); - - if (missing) { - throw new Error(`${path} doesn't exist`); - } - - const pkg = JSON.parse(templateContents); - const targetPkg = JSON.parse(targetContents); - - const handler = new PackageJsonHandler( - write, - prompt, - pkg, - targetPkg, - variant, - ); - await handler.handle(); - } - - static async appHandler(file: FileDiff, prompt: PromptFunc) { - return PackageJsonHandler.handler(file, prompt, 'app'); - } - - constructor( - private readonly writeFunc: WriteFileFunc, - private readonly prompt: PromptFunc, - private readonly pkg: any, - private readonly targetPkg: any, - private readonly variant?: string, - ) {} - - async handle() { - await this.syncField('main'); - if (this.variant !== 'app') { - await this.syncField('main:src'); - } - await this.syncField('types'); - await this.syncFiles(); - await this.syncScripts(); - await this.syncPublishConfig(); - await this.syncDependencies('dependencies'); - await this.syncDependencies('peerDependencies', true); - await this.syncDependencies('devDependencies'); - await this.syncReactDeps(); - } - - // Make sure a field inside package.json is in sync. This mutates the targetObj and writes package.json on change. - private async syncField( - fieldName: string, - obj: any = this.pkg, - targetObj: any = this.targetPkg, - prefix?: string, - sort?: boolean, - optional?: boolean, - ) { - const fullFieldName = chalk.cyan( - prefix ? `${prefix}[${fieldName}]` : fieldName, - ); - const newValue = obj[fieldName]; - const coloredNewValue = chalk.cyan(JSON.stringify(newValue)); - - if (fieldName in targetObj) { - const oldValue = targetObj[fieldName]; - if (JSON.stringify(oldValue) === JSON.stringify(newValue)) { - return; - } - - const coloredOldValue = chalk.cyan(JSON.stringify(oldValue)); - const msg = `package.json has mismatched field, ${fullFieldName}, change from ${coloredOldValue} to ${coloredNewValue}?`; - if (await this.prompt(msg)) { - targetObj[fieldName] = newValue; - if (sort) { - sortObjectKeys(targetObj); - } - await this.write(); - } - } else if (fieldName in obj && optional !== true) { - if ( - await this.prompt( - `package.json is missing field ${fullFieldName}, set to ${coloredNewValue}?`, - ) - ) { - targetObj[fieldName] = newValue; - if (sort) { - sortObjectKeys(targetObj); - } - await this.write(); - } - } - } - - private async syncFiles() { - const { configSchema } = this.targetPkg; - const hasSchemaFile = typeof configSchema === 'string'; - - if (!this.targetPkg.files) { - const expected = hasSchemaFile ? ['dist', configSchema] : ['dist']; - if ( - await this.prompt( - `package.json is missing field "files", set to ${JSON.stringify( - expected, - )}?`, - ) - ) { - this.targetPkg.files = expected; - await this.write(); - } - } else { - const missing = []; - if (!this.targetPkg.files.includes('dist')) { - missing.push('dist'); - } - if (hasSchemaFile && !this.targetPkg.files.includes(configSchema)) { - missing.push(configSchema); - } - if (missing.length) { - if ( - await this.prompt( - `package.json is missing ${JSON.stringify( - missing, - )} in the "files" field, add?`, - ) - ) { - this.targetPkg.files.push(...missing); - await this.write(); - } - } - } - } - - private async syncScripts() { - const pkgScripts = this.pkg.scripts; - const targetScripts = (this.targetPkg.scripts = - this.targetPkg.scripts || {}); - - if (!pkgScripts) { - return; - } - - // Skip diffing package scripts that have been migrated to the new commands - const hasNewScript = Object.values(targetScripts).some(script => - String(script).includes('backstage-cli package '), - ); - if (hasNewScript) { - return; - } - - for (const key of Object.keys(pkgScripts)) { - await this.syncField(key, pkgScripts, targetScripts, 'scripts'); - } - } - - private async syncPublishConfig() { - const pkgPublishConf = this.pkg.publishConfig; - const targetPublishConf = this.targetPkg.publishConfig; - - // If template doesn't have a publish config we're done - if (!pkgPublishConf) { - return; - } - - // Publish config can be removed the the target, skip in that case - if (!targetPublishConf) { - if (await this.prompt('Missing publishConfig, do you want to add it?')) { - this.targetPkg.publishConfig = pkgPublishConf; - await this.write(); - } - return; - } - - for (const key of Object.keys(pkgPublishConf)) { - // Don't want to mess with peoples internal setup - if (!['access', 'registry'].includes(key)) { - await this.syncField( - key, - pkgPublishConf, - targetPublishConf, - 'publishConfig', - ); - } - } - } - - private async syncDependencies(fieldName: string, required: boolean = false) { - const pkgDeps = this.pkg[fieldName]; - const targetDeps = (this.targetPkg[fieldName] = - this.targetPkg[fieldName] || {}); - - if (!pkgDeps && !required) { - return; - } - - // Hardcoded removal of these during migration - await this.syncField('@backstage/core', {}, targetDeps, fieldName, true); - await this.syncField( - '@backstage/core-api', - {}, - targetDeps, - fieldName, - true, - ); - - for (const key of Object.keys(pkgDeps)) { - if (this.variant === 'app' && key.startsWith('plugin-')) { - continue; - } - - await this.syncField( - key, - pkgDeps, - targetDeps, - fieldName, - true, - !required, - ); - } - } - - private async syncReactDeps() { - const targetDeps = (this.targetPkg.dependencies = - this.targetPkg.dependencies || {}); - - // Remove these from from deps since they're now in peerDeps - await this.syncField('react', {}, targetDeps, 'dependencies'); - await this.syncField('react-dom', {}, targetDeps, 'dependencies'); - } - - private async write() { - await this.writeFunc(`${JSON.stringify(this.targetPkg, null, 2)}\n`); - } -} - -// Make sure the file is an exact match of the template -async function exactMatchHandler( - { path, write, missing, targetContents, templateContents }: FileDiff, - prompt: PromptFunc, -) { - console.log(`Checking ${path}`); - const coloredPath = chalk.cyan(path); - - if (missing) { - if (await prompt(`Missing ${coloredPath}, do you want to add it?`)) { - await write(templateContents); - } - return; - } - if (targetContents === templateContents) { - return; - } - - const diffs = diffLines(targetContents, templateContents); - for (const diff of diffs) { - if (diff.added) { - process.stdout.write(chalk.green(`+${diff.value}`)); - } else if (diff.removed) { - process.stdout.write(chalk.red(`-${diff.value}`)); - } else { - process.stdout.write(` ${diff.value}`); - } - } - - if ( - await prompt( - `Outdated ${coloredPath}, do you want to apply the above patch?`, - ) - ) { - await write(templateContents); - } -} - -// Adds the file if it is missing, but doesn't check existing files -async function existsHandler( - { path, write, missing, templateContents }: FileDiff, - prompt: PromptFunc, -) { - console.log(`Making sure ${path} exists`); - - const coloredPath = chalk.cyan(path); - - if (missing) { - if (await prompt(`Missing ${coloredPath}, do you want to add it?`)) { - await write(templateContents); - } - return; - } -} - -async function skipHandler({ path }: FileDiff) { - console.log(`Skipping ${path}`); -} - -export const handlers = { - skip: skipHandler, - exists: existsHandler, - exactMatch: exactMatchHandler, - packageJson: PackageJsonHandler.handler, - appPackageJson: PackageJsonHandler.appHandler, -}; - -export async function handleAllFiles( - fileHandlers: FileHandler[], - files: FileDiff[], - promptFunc: PromptFunc, -) { - for (const file of files) { - const path = file.path.split(sep).join(posix.sep); - const fileHandler = fileHandlers.find(handler => - handler.patterns.some(pattern => - typeof pattern === 'string' ? pattern === path : pattern.test(path), - ), - ); - if (fileHandler) { - await fileHandler.handler(file, promptFunc); - } else { - throw new Error(`No template file handler found for ${path}`); - } - } -} diff --git a/packages/cli/src/lib/diff/index.ts b/packages/cli/src/lib/diff/index.ts deleted file mode 100644 index 79a55f023e..0000000000 --- a/packages/cli/src/lib/diff/index.ts +++ /dev/null @@ -1,20 +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 * from './handlers'; -export * from './prompts'; -export * from './read'; -export * from './types'; diff --git a/packages/cli/src/lib/diff/prompts.ts b/packages/cli/src/lib/diff/prompts.ts deleted file mode 100644 index d2ddca5fc0..0000000000 --- a/packages/cli/src/lib/diff/prompts.ts +++ /dev/null @@ -1,53 +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 chalk from 'chalk'; -import inquirer from 'inquirer'; -import { PromptFunc } from './types'; - -export const inquirerPromptFunc: PromptFunc = async msg => { - const { result } = await inquirer.prompt({ - type: 'confirm', - name: 'result', - message: chalk.blue(msg), - }); - return result; -}; - -export const makeCheckPromptFunc = () => { - let failed = false; - - const promptFunc: PromptFunc = async msg => { - failed = true; - console.log(chalk.red(`[Check Failed] ${msg}`)); - return false; - }; - - const finalize = () => { - if (failed) { - throw new Error( - 'Check failed, the plugin is not in sync with the latest template', - ); - } - }; - - return [promptFunc, finalize] as const; -}; - -export const yesPromptFunc: PromptFunc = async msg => { - console.log(`Accepting: "${msg}"`); - return true; -}; diff --git a/packages/cli/src/lib/diff/read.ts b/packages/cli/src/lib/diff/read.ts deleted file mode 100644 index 95b0bed43d..0000000000 --- a/packages/cli/src/lib/diff/read.ts +++ /dev/null @@ -1,120 +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 fs from 'fs-extra'; -import { - dirname, - resolve as resolvePath, - relative as relativePath, -} from 'path'; -import handlebars from 'handlebars'; -import recursiveReadDir from 'recursive-readdir'; -import { paths } from '../paths'; -import { FileDiff } from './types'; -import { createPackageVersionProvider } from '../../lib/version'; - -export type TemplatedFile = { - path: string; - contents: string; -}; - -async function readTemplateFile( - templateFile: string, - templateVars: any, -): Promise { - const contents = await fs.readFile(templateFile, 'utf8'); - - if (!templateFile.endsWith('.hbs')) { - return contents; - } - const packageVersionProvider = createPackageVersionProvider(undefined); - - return handlebars.compile(contents)(templateVars, { - helpers: { - versionQuery(name: string, hint: string | unknown) { - return packageVersionProvider( - name, - typeof hint === 'string' ? hint : undefined, - ); - }, - }, - }); -} - -async function readTemplate( - templateDir: string, - templateVars: any, -): Promise { - const templateFilePaths = await recursiveReadDir(templateDir).catch(error => { - throw new Error(`Failed to read template directory: ${error.message}`); - }); - - const templatedFiles = new Array(); - for (const templateFile of templateFilePaths) { - const path = relativePath(templateDir, templateFile).replace(/\.hbs$/, ''); - const contents = await readTemplateFile(templateFile, templateVars); - - templatedFiles.push({ path, contents }); - } - - return templatedFiles; -} - -async function diffTemplatedFiles( - targetDir: string, - templatedFiles: TemplatedFile[], -): Promise { - const fileDiffs = new Array(); - for (const { path, contents: templateContents } of templatedFiles) { - const targetPath = resolvePath(targetDir, path); - const targetExists = await fs.pathExists(targetPath); - - const write = async (contents: string) => { - await fs.ensureDir(dirname(targetPath)); - await fs.writeFile(targetPath, contents, 'utf8'); - }; - - if (targetExists) { - const targetContents = await fs.readFile(targetPath, 'utf8'); - fileDiffs.push({ - path, - write, - missing: false, - targetContents, - templateContents, - }); - } else { - fileDiffs.push({ - path, - write, - missing: true, - targetContents: '', - templateContents, - }); - } - } - - return fileDiffs; -} - -// Read all template files for a given template, along with all matching files in the target dir -export async function diffTemplateFiles(template: string, templateData: any) { - const templateDir = paths.resolveOwn('templates', template); - - const templatedFiles = await readTemplate(templateDir, templateData); - const fileDiffs = await diffTemplatedFiles(paths.targetDir, templatedFiles); - return fileDiffs; -} diff --git a/packages/cli/src/lib/diff/types.ts b/packages/cli/src/lib/diff/types.ts deleted file mode 100644 index ba649f66ff..0000000000 --- a/packages/cli/src/lib/diff/types.ts +++ /dev/null @@ -1,39 +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 type WriteFileFunc = (contents: string) => Promise; - -export type FileDiff = { - // Relative path within the target directory - path: string; - // Whether the target file exists in the target directory. - missing: boolean; - // Contents of the file in the target directory, or an empty string if the file is missing. - targetContents: string; - // Contents of the compiled template file - templateContents: string; - // Write new contents to the target file - write: WriteFileFunc; -}; - -export type PromptFunc = (msg: string) => Promise; - -export type HandlerFunc = (file: FileDiff, prompt: PromptFunc) => Promise; - -export type FileHandler = { - patterns: Array; - handler: HandlerFunc; -}; diff --git a/packages/cli/src/lib/entryPoints.ts b/packages/cli/src/lib/entryPoints.ts index 1f6e2feec2..2cead6b41f 100644 --- a/packages/cli/src/lib/entryPoints.ts +++ b/packages/cli/src/lib/entryPoints.ts @@ -67,6 +67,11 @@ export function readEntryPoints(pkg: BackstagePackageJson): Array { ); } + // Setting the EXPERIMENTAL_TRIM_NEXT_ENTRY flag will remove any `./next` entry points + if (process.env.EXPERIMENTAL_TRIM_NEXT_ENTRY && mount === './next') { + continue; + } + entryPoints.push(parseEntryPoint(mount, path)); } diff --git a/packages/cli/src/lib/logging.ts b/packages/cli/src/lib/logging.ts deleted file mode 100644 index 59473d7f64..0000000000 --- a/packages/cli/src/lib/logging.ts +++ /dev/null @@ -1,58 +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 type LogFunc = (data: Buffer) => void; -export type LogPipe = (dst: NodeJS.WriteStream) => LogFunc; - -export type LogOptions = { - // If set, prefix each log message with this string - prefix?: string; - - // If true, clear terminal commands will be forwarded, otherwise they are removed - forwardClearTerm?: boolean; -}; - -// Creates a log pipe that binds to a destination stream and forwards logs with optional transforms. -// Use returned logPipe e.g. as follows: child.stdout.on('data', logPipe(process.stdout)) -export function createLogPipe(options: LogOptions = {}): LogPipe { - const { prefix = '', forwardClearTerm = false } = options; - - return (dst: NodeJS.WriteStream) => (data: Buffer | string) => { - let str = typeof data === 'string' ? data : data.toString('utf8'); - - if (!forwardClearTerm) { - str = trimClearTerm(str); - } - if (prefix) { - str = `${prefix}${str}`; - } - - dst.write(Buffer.from(str, 'utf8')); - }; -} - -// Wrapper around createLogPipe to avoid awkward immediate call of returned function -export function createLogFunc( - dst: NodeJS.WriteStream, - options: LogOptions = {}, -): LogFunc { - return createLogPipe(options)(dst); -} - -// Returns the string without terminal clear command if it was prefixed with one. -export function trimClearTerm(msg: string): string { - return msg.startsWith('\x1b\x63') ? msg.slice(2) : msg; -} diff --git a/packages/cli/src/lib/new/factories/backendPlugin.ts b/packages/cli/src/lib/new/factories/backendPlugin.ts index 9129a66075..050d05f0df 100644 --- a/packages/cli/src/lib/new/factories/backendPlugin.ts +++ b/packages/cli/src/lib/new/factories/backendPlugin.ts @@ -79,12 +79,12 @@ export const backendPlugin = createFactory({ }, ); }); - - await addToBackend(name, { - type: 'plugin', - }); } + await addToBackend(name, { + type: 'plugin', + }); + if (options.owner) { await addCodeownersEntry(`/plugins/${id}`, options.owner); } diff --git a/packages/cli/src/lib/new/factories/scaffolderModule.test.ts b/packages/cli/src/lib/new/factories/scaffolderModule.test.ts index c4b9d78fc1..60dade618a 100644 --- a/packages/cli/src/lib/new/factories/scaffolderModule.test.ts +++ b/packages/cli/src/lib/new/factories/scaffolderModule.test.ts @@ -26,6 +26,14 @@ import { import { scaffolderModule } from './scaffolderModule'; import { createMockDirectory } from '@backstage/backend-test-utils'; +const backendIndexTsContent = ` +import { createBackend } from '@backstage/backend-defaults'; + +const backend = createBackend(); + +backend.start(); +`; + describe('scaffolderModule factory', () => { const mockDir = createMockDirectory(); @@ -41,6 +49,14 @@ describe('scaffolderModule factory', () => { it('should create a scaffolder backend module package', async () => { mockDir.setContent({ + packages: { + backend: { + 'package.json': JSON.stringify({}), + src: { + 'index.ts': backendIndexTsContent, + }, + }, + }, plugins: {}, }); @@ -84,8 +100,29 @@ describe('scaffolderModule factory', () => { 'copying module.ts', 'Installing:', `moving plugins${sep}scaffolder-backend-module-test`, + 'backend adding dependency', + 'backend adding module', ]); + await expect( + fs.readFile(mockDir.resolve('packages/backend/src/index.ts'), 'utf8'), + ).resolves.toBe(` +import { createBackend } from '@backstage/backend-defaults'; + +const backend = createBackend(); + +backend.add(import('backstage-plugin-scaffolder-backend-module-test')); +backend.start(); +`); + + await expect( + fs.readJson(mockDir.resolve('packages/backend/package.json')), + ).resolves.toEqual({ + dependencies: { + 'backstage-plugin-scaffolder-backend-module-test': '^1.0.0', + }, + }); + await expect( fs.readJson( mockDir.resolve('plugins/scaffolder-backend-module-test/package.json'), diff --git a/packages/cli/src/lib/new/factories/scaffolderModule.ts b/packages/cli/src/lib/new/factories/scaffolderModule.ts index 4c279a49d4..6cea7a36ff 100644 --- a/packages/cli/src/lib/new/factories/scaffolderModule.ts +++ b/packages/cli/src/lib/new/factories/scaffolderModule.ts @@ -14,11 +14,12 @@ * limitations under the License. */ +import fs from 'fs-extra'; import chalk from 'chalk'; import { paths } from '../../paths'; import { addCodeownersEntry, getCodeownersFilePath } from '../../codeowners'; import { CreateContext, createFactory } from '../types'; -import { Task } from '../../tasks'; +import { addPackageDependency, addToBackend, Task } from '../../tasks'; import { ownerPrompt } from './common/prompts'; import { executePluginPackageTemplate } from './common/tasks'; import { resolvePackageName } from './common/util'; @@ -82,6 +83,23 @@ export const scaffolderModule = createFactory({ }, }); + if (await fs.pathExists(paths.resolveTargetRoot('packages/backend'))) { + await Task.forItem('backend', 'adding dependency', async () => { + await addPackageDependency( + paths.resolveTargetRoot('packages/backend/package.json'), + { + dependencies: { + [name]: `^${ctx.defaultVersion}`, + }, + }, + ); + }); + } + + await addToBackend(name, { + type: 'module', + }); + if (options.owner) { await addCodeownersEntry(`/plugins/${slug}`, options.owner); } diff --git a/packages/cli/src/lib/packager/createDistWorkspace.ts b/packages/cli/src/lib/packager/createDistWorkspace.ts index b966e23a85..7b7db43889 100644 --- a/packages/cli/src/lib/packager/createDistWorkspace.ts +++ b/packages/cli/src/lib/packager/createDistWorkspace.ts @@ -44,6 +44,7 @@ import { PackageGraphNode, } from '@backstage/cli-node'; import { runParallelWorkers } from '../parallel'; +import { createTypeDistProject } from '../typeDistProject'; // These packages aren't safe to pack in parallel since the CLI depends on them const UNSAFE_PACKAGES = [ @@ -211,6 +212,7 @@ export async function createDistWorkspace( outputs: outputs, logPrefix: `${chalk.cyan(relativePath(paths.targetRoot, pkg.dir))}: `, minify: options.minify, + workspacePackages: packages, }); } } @@ -286,6 +288,9 @@ async function moveToDistWorkspace( FAST_PACK_SCRIPTS.includes(pkg.packageJson.scripts?.prepack), ); + const tsMorphProject = + fastPackPackages.length > 0 ? await createTypeDistProject() : undefined; + // New an improved flow where we avoid calling `yarn pack` await Promise.all( fastPackPackages.map(async target => { @@ -296,6 +301,7 @@ async function moveToDistWorkspace( await productionPack({ packageDir: target.dir, targetDir: absoluteOutputPath, + project: tsMorphProject, }); }), ); diff --git a/packages/cli/src/lib/packager/productionPack.ts b/packages/cli/src/lib/packager/productionPack.ts index 3c2b5aa89e..85f50352cc 100644 --- a/packages/cli/src/lib/packager/productionPack.ts +++ b/packages/cli/src/lib/packager/productionPack.ts @@ -19,6 +19,11 @@ import npmPackList from 'npm-packlist'; import { resolve as resolvePath, posix as posixPath } from 'path'; import { BackstagePackageJson } from '@backstage/cli-node'; import { readEntryPoints } from '../entryPoints'; +import { + createTypeDistProject, + getEntryPointDefaultFeatureType, +} from '../typeDistProject'; +import { Project } from 'ts-morph'; const PKG_PATH = 'package.json'; const PKG_BACKUP_PATH = 'package.json-prepack'; @@ -29,6 +34,10 @@ const SCRIPT_EXTS = ['.js', '.jsx', '.ts', '.tsx']; interface ProductionPackOptions { packageDir: string; targetDir?: string; + /** + * A ts-morph project to share across packages + */ + project?: Project; } export async function productionPack(options: ProductionPackOptions) { @@ -46,6 +55,7 @@ export async function productionPack(options: ProductionPackOptions) { const writeCompatibilityEntryPoints = await prepareExportsEntryPoints( pkg, packageDir, + options.project, ); // TODO(Rugvip): Once exports are rolled out more broadly we should deprecate and remove this behavior @@ -134,6 +144,7 @@ const EXPORT_MAP = { async function prepareExportsEntryPoints( pkg: BackstagePackageJson, packageDir: string, + commonProject?: Project, ) { const distPath = resolvePath(packageDir, 'dist'); if (!(await fs.pathExists(distPath))) { @@ -147,20 +158,44 @@ async function prepareExportsEntryPoints( >(); const entryPoints = readEntryPoints(pkg); + const project = commonProject || (await createTypeDistProject()); + for (const entryPoint of entryPoints) { if (!SCRIPT_EXTS.includes(entryPoint.ext)) { outputExports[entryPoint.mount] = entryPoint.path; continue; } - const exp = {} as Record; + + let exp = {} as Record; + for (const [key, ext] of Object.entries(EXPORT_MAP)) { const name = `${entryPoint.name}${ext}`; if (distFiles.includes(name)) { exp[key] = `./${posixPath.join(`dist`, name)}`; } } + exp.default = exp.require ?? exp.import; + // Find the default export type for the entry point + if (exp.types) { + const defaultFeatureType = + pkg.backstage?.role && + getEntryPointDefaultFeatureType( + pkg.backstage?.role, + packageDir, + project, + exp.types, + ); + + if (defaultFeatureType) { + // This ensures that the `backstage` field is at the top of the + // `exports` field in the package.json because order is important. + // https://nodejs.org/docs/latest-v20.x/api/packages.html#conditional-exports + exp = { backstage: defaultFeatureType, ...exp }; + } + } + // This creates a directory with a lone package.json for backwards compatibility if (entryPoint.mount === '.') { if (exp.default) { diff --git a/packages/cli/src/lib/run.ts b/packages/cli/src/lib/run.ts index 1ef25cae62..e8602fcb18 100644 --- a/packages/cli/src/lib/run.ts +++ b/packages/cli/src/lib/run.ts @@ -22,11 +22,12 @@ import { } from 'child_process'; import { ExitCodeError } from './errors'; import { promisify } from 'util'; -import { LogFunc } from './logging'; import { assertError, ForwardedError } from '@backstage/errors'; export const execFile = promisify(execFileCb); +type LogFunc = (data: Buffer) => void; + type SpawnOptionsPartialEnv = Omit & { env?: Partial; // Pipe stdout to this log function diff --git a/packages/cli/src/lib/typeDistProject.test.ts b/packages/cli/src/lib/typeDistProject.test.ts new file mode 100644 index 0000000000..dfe3e68ec0 --- /dev/null +++ b/packages/cli/src/lib/typeDistProject.test.ts @@ -0,0 +1,131 @@ +/* + * 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 { PackageRole } from '@backstage/cli-node'; +import createFeatureEnvironment from './__testUtils__/createFeatureEnvironment'; +import { + getEntryPointDefaultFeatureType, + BackstagePackageFeatureType, +} from './typeDistProject'; + +describe('typeDistProject', () => { + describe('for package role', () => { + // This Record makes sure we're checking all package roles + const packageRoles: Record = { + // Allowed + 'backend-plugin': true, + 'backend-plugin-module': true, + 'frontend-plugin': true, + 'frontend-plugin-module': true, + 'web-library': true, + 'node-library': true, + // Disallowed + frontend: false, + backend: false, + cli: false, + 'common-library': false, + }; + + const allowedPackageRoles = Object.keys(packageRoles).filter( + role => packageRoles[role as PackageRole], + ); + + const disallowedPackageRoles = Object.keys(packageRoles).filter( + role => !packageRoles[role as PackageRole], + ); + + it.each(allowedPackageRoles)(`returns features for %s`, r => { + const { project, role, dir, entryPoint } = createFeatureEnvironment({ + role: r as PackageRole, + }); + + expect( + getEntryPointDefaultFeatureType(role, dir, project, entryPoint), + ).toEqual('@backstage/BackendFeature'); + }); + + it.each(disallowedPackageRoles)(`does not return features for %s`, r => { + const { project, role, dir, entryPoint } = createFeatureEnvironment({ + role: r as PackageRole, + }); + + expect( + getEntryPointDefaultFeatureType(role, dir, project, entryPoint), + ).toEqual(null); + }); + }); + + describe('for feature $$type', () => { + // This Record makes sure we're checking all feature types + const featureTypes: Record = + { + // Allowed + '@backstage/BackendFeature': true, + '@backstage/BackstagePlugin': true, + '@backstage/FrontendPlugin': true, + '@backstage/FrontendModule': true, + // Disallowed + '@backstage/Extension': false, + '@backstage/RouteRef': false, + }; + + const allowedFeatureTypes = Object.keys(featureTypes).filter( + $$type => featureTypes[$$type as BackstagePackageFeatureType], + ); + + const disallowedFeatureTypes = Object.keys(featureTypes).filter( + $$type => !featureTypes[$$type as BackstagePackageFeatureType], + ); + + it.each(allowedFeatureTypes)(`returns features for "%s" $$type`, $$type => { + const { project, role, dir, entryPoint } = createFeatureEnvironment({ + $$type: $$type as BackstagePackageFeatureType, + }); + + expect( + getEntryPointDefaultFeatureType(role, dir, project, entryPoint), + ).toEqual($$type); + }); + + it.each(disallowedFeatureTypes)( + `does not return features for "%s" $$type`, + $$type => { + const { project, role, dir, entryPoint } = createFeatureEnvironment({ + $$type: $$type as BackstagePackageFeatureType, + }); + + expect( + getEntryPointDefaultFeatureType(role, dir, project, entryPoint), + ).toEqual(null); + }, + ); + }); + + it.each([ + 'DefaultExportAssignment', + 'DefaultExportFromFile', + 'DefaultExportFromFileAsDefault', + 'DefaultExportFromFileWithSibling', + ] as const)('returns features for format "%s"', format => { + const { project, role, dir, entryPoint } = createFeatureEnvironment({ + format, + }); + + expect( + getEntryPointDefaultFeatureType(role, dir, project, entryPoint), + ).toEqual('@backstage/BackendFeature'); + }); +}); diff --git a/packages/cli/src/lib/typeDistProject.ts b/packages/cli/src/lib/typeDistProject.ts new file mode 100644 index 0000000000..59dc503f22 --- /dev/null +++ b/packages/cli/src/lib/typeDistProject.ts @@ -0,0 +1,151 @@ +/* + * 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 { PackageRole } from '@backstage/cli-node'; +import { resolve as resolvePath } from 'path'; +import { Project, SourceFile, SyntaxKind, ts, Type } from 'ts-morph'; +import { paths } from './paths'; + +export const createTypeDistProject = async () => { + return new Project({ + tsConfigFilePath: paths.resolveTargetRoot('tsconfig.json'), + skipAddingFilesFromTsConfig: true, + }); +}; + +// A list of the package roles we want to extract features for +const targetPackageRoles: PackageRole[] = [ + 'backend-plugin', + 'backend-plugin-module', + 'frontend-plugin', + 'frontend-plugin-module', + 'web-library', + 'node-library', +]; + +// A list of the feature types we want to extract from the project +// and include in the metadata +const targetFeatureTypes = [ + '@backstage/BackendFeature', + '@backstage/BackstagePlugin', + '@backstage/FrontendPlugin', + '@backstage/FrontendModule', +] as const; + +export type BackstagePackageFeatureType = (typeof targetFeatureTypes)[number]; + +export const getEntryPointDefaultFeatureType = ( + role: PackageRole, + packageDir: string, + project: Project, + entryPoint: string, +): BackstagePackageFeatureType | null => { + if (isTargetPackageRole(role)) { + const distPath = resolvePath(packageDir, entryPoint); + + try { + const defaultFeatureType = getSourceFileDefaultFeatureType( + project.addSourceFileAtPath(distPath), + ); + + if (defaultFeatureType) { + return defaultFeatureType; + } + } catch (error) { + console.error( + `Failed to extract default feature type from ${distPath}, ${error}. ` + + 'Your package will publish fine but it may be missing metadata about its default feature.', + ); + } + } + + return null; +}; + +// Returns all exports (default and named) from an entry point +// that are valid Backstage package features +function getSourceFileDefaultFeatureType( + sourceFile: SourceFile, +): BackstagePackageFeatureType | null { + for (const exportSymbol of sourceFile.getExportSymbols()) { + const declaration = exportSymbol.getDeclarations()[0]; + const exportName = declaration.getSymbol()?.getName(); + + if (exportName !== 'default') { + continue; + } + + let exportType: Type | undefined; + + if (declaration) { + if (declaration.isKind(SyntaxKind.ExportAssignment)) { + exportType = declaration.getExpression().getType(); + } else if (declaration.isKind(SyntaxKind.ExportSpecifier)) { + if (!declaration.isTypeOnly()) { + exportType = declaration.getType(); + } + } else if (declaration.isKind(SyntaxKind.VariableDeclaration)) { + exportType = declaration.getType(); + } + } + + if (exportName && exportType) { + const $$type = getBackstagePackageFeature$$TypeFromType(exportType); + + if ($$type) { + return $$type; + } + } + } + + return null; +} + +// Given a TS type, returns the Backstage package feature $$type value +function getBackstagePackageFeature$$TypeFromType( + type: Type, +): BackstagePackageFeatureType | null { + // Returns the concrete type of a generic type + const exportType = type.getTargetType() ?? type; + + for (const property of exportType.getProperties()) { + if (property.getName() === '$$type') { + const $$type = property + .getValueDeclaration() + ?.getText() + .match(/(\$\$type: '(?.+)')/)?.groups?.type; + + if ($$type && isTargetFeatureType($$type)) { + return $$type; + } + } + } + + return null; +} + +// Condition for a package role matches a target package role +function isTargetPackageRole(role: PackageRole): boolean { + return !!role && targetPackageRoles.includes(role); +} + +// Returns whether an export is a valid Backstage package feature type +function isTargetFeatureType( + type: string | BackstagePackageFeatureType, +): type is BackstagePackageFeatureType { + return ( + !!type && targetFeatureTypes.includes(type as BackstagePackageFeatureType) + ); +} diff --git a/packages/cli/src/lib/version.ts b/packages/cli/src/lib/version.ts index fb777f7502..b2b3ae23cf 100644 --- a/packages/cli/src/lib/version.ts +++ b/packages/cli/src/lib/version.ts @@ -32,7 +32,6 @@ This does not create an actual dependency on these packages and does not bring i Rollup will extract the value of the version field in each package at build time without leaving any imports in place. */ -import { version as backendCommon } from '../../../../packages/backend-common/package.json'; import { version as backendPluginApi } from '../../../../packages/backend-plugin-api/package.json'; import { version as backendTestUtils } from '../../../../packages/backend-test-utils/package.json'; import { version as cli } from '../../../../packages/cli/package.json'; @@ -49,7 +48,6 @@ import { version as theme } from '../../../../packages/theme/package.json'; import { version as backendDefaults } from '../../../../packages/backend-defaults/package.json'; export const packageVersions: Record = { - '@backstage/backend-common': backendCommon, '@backstage/backend-defaults': backendDefaults, '@backstage/backend-plugin-api': backendPluginApi, '@backstage/backend-test-utils': backendTestUtils, diff --git a/packages/cli/src/types.d.ts b/packages/cli/src/types.d.ts index 1222b2b4b8..058b37eb01 100644 --- a/packages/cli/src/types.d.ts +++ b/packages/cli/src/types.d.ts @@ -30,6 +30,11 @@ declare module '@svgr/rollup' { export default function svgr(options?: any): any; } +declare module 'rollup/parseAst' { + export function parseAst(code: string): any; + export function parseAstAsync(code: string): any; +} + declare module '@rollup/plugin-yaml'; declare module 'react-dev-utils/formatWebpackMessages' { export default function (stats: any): { diff --git a/packages/codemods/CHANGELOG.md b/packages/codemods/CHANGELOG.md index c93a71fe38..a72e2bf548 100644 --- a/packages/codemods/CHANGELOG.md +++ b/packages/codemods/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/codemods +## 0.1.50 + +### Patch Changes + +- 0894166: Updated dependency `jscodeshift` to `^0.16.0`. +- Updated dependencies + - @backstage/cli-common@0.1.14 + ## 0.1.50-next.0 ### Patch Changes diff --git a/packages/codemods/package.json b/packages/codemods/package.json index 38d32dfc74..746fb92022 100644 --- a/packages/codemods/package.json +++ b/packages/codemods/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/codemods", - "version": "0.1.50-next.0", + "version": "0.1.50", "description": "A collection of codemods for Backstage projects", "backstage": { "role": "cli" diff --git a/packages/config-loader/CHANGELOG.md b/packages/config-loader/CHANGELOG.md index a60e86a6c8..9107e5b104 100644 --- a/packages/config-loader/CHANGELOG.md +++ b/packages/config-loader/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/config-loader +## 1.9.1 + +### Patch Changes + +- ef3c507: Updated dependency `typescript-json-schema` to `^0.65.0`. +- Updated dependencies + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## 1.9.1-next.0 + +### Patch Changes + +- ef3c507: Updated dependency `typescript-json-schema` to `^0.65.0`. +- Updated dependencies + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 1.9.0 ### Minor Changes diff --git a/packages/config-loader/package.json b/packages/config-loader/package.json index 98d233b348..79a2eb5338 100644 --- a/packages/config-loader/package.json +++ b/packages/config-loader/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/config-loader", - "version": "1.9.0", + "version": "1.9.1", "description": "Config loading functionality used by Backstage backend, and CLI", "backstage": { "role": "node-library" @@ -50,7 +50,7 @@ "lodash": "^4.17.21", "minimist": "^1.2.5", "node-fetch": "^2.7.0", - "typescript-json-schema": "^0.63.0", + "typescript-json-schema": "^0.65.0", "yaml": "^2.0.0" }, "devDependencies": { diff --git a/packages/config-loader/api-report.md b/packages/config-loader/report.api.md similarity index 72% rename from packages/config-loader/api-report.md rename to packages/config-loader/report.api.md index e2741d609c..7d7047d493 100644 --- a/packages/config-loader/api-report.md +++ b/packages/config-loader/report.api.md @@ -284,4 +284,32 @@ export type TransformFunc = ( path: string; }, ) => T | undefined; + +// Warnings were encountered during analysis: +// +// src/loader.d.ts:6:1 - (ae-undocumented) Missing documentation for "ConfigTarget". +// src/loader.d.ts:15:1 - (ae-undocumented) Missing documentation for "LoadConfigOptionsWatch". +// src/loader.d.ts:29:1 - (ae-undocumented) Missing documentation for "LoadConfigOptionsRemote". +// src/sources/ConfigSources.d.ts:42:5 - (ae-undocumented) Missing documentation for "watch". +// src/sources/ConfigSources.d.ts:43:5 - (ae-undocumented) Missing documentation for "rootDir". +// src/sources/ConfigSources.d.ts:44:5 - (ae-undocumented) Missing documentation for "remote". +// src/sources/ConfigSources.d.ts:65:5 - (ae-undocumented) Missing documentation for "targets". +// src/sources/ConfigSources.d.ts:73:5 - (ae-undocumented) Missing documentation for "argv". +// src/sources/ConfigSources.d.ts:74:5 - (ae-undocumented) Missing documentation for "env". +// src/sources/EnvConfigSource.d.ts:46:5 - (ae-undocumented) Missing documentation for "readConfigData". +// src/sources/EnvConfigSource.d.ts:47:5 - (ae-undocumented) Missing documentation for "toString". +// src/sources/FileConfigSource.d.ts:44:5 - (ae-undocumented) Missing documentation for "readConfigData". +// src/sources/FileConfigSource.d.ts:45:5 - (ae-undocumented) Missing documentation for "toString". +// src/sources/MutableConfigSource.d.ts:9:5 - (ae-undocumented) Missing documentation for "data". +// src/sources/MutableConfigSource.d.ts:10:5 - (ae-undocumented) Missing documentation for "context". +// src/sources/MutableConfigSource.d.ts:27:5 - (ae-undocumented) Missing documentation for "readConfigData". +// src/sources/MutableConfigSource.d.ts:38:5 - (ae-undocumented) Missing documentation for "toString". +// src/sources/RemoteConfigSource.d.ts:43:5 - (ae-undocumented) Missing documentation for "readConfigData". +// src/sources/RemoteConfigSource.d.ts:44:5 - (ae-undocumented) Missing documentation for "toString". +// src/sources/StaticConfigSource.d.ts:9:5 - (ae-undocumented) Missing documentation for "data". +// src/sources/StaticConfigSource.d.ts:10:5 - (ae-undocumented) Missing documentation for "context". +// src/sources/StaticConfigSource.d.ts:28:5 - (ae-undocumented) Missing documentation for "readConfigData". +// src/sources/StaticConfigSource.d.ts:29:5 - (ae-undocumented) Missing documentation for "toString". +// src/sources/types.d.ts:20:5 - (ae-undocumented) Missing documentation for "signal". +// src/sources/types.d.ts:55:5 - (ae-undocumented) Missing documentation for "readConfigData". ``` diff --git a/packages/config/api-report.md b/packages/config/report.api.md similarity index 100% rename from packages/config/api-report.md rename to packages/config/report.api.md diff --git a/packages/core-app-api/CHANGELOG.md b/packages/core-app-api/CHANGELOG.md index 2ae26f8b97..c028e3c7bc 100644 --- a/packages/core-app-api/CHANGELOG.md +++ b/packages/core-app-api/CHANGELOG.md @@ -1,5 +1,56 @@ # @backstage/core-app-api +## 1.15.1-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/version-bridge@1.0.10-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## 1.15.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.9 + +## 1.15.0 + +### Minor Changes + +- ddbeace: Added the ability to explicitly disable routes through the `bindRoutes` option by passing `false` as the route target. This also fixes a bug where route bindings in config were incorrectly prioritized above the ones in code in certain situations. + +### Patch Changes + +- ea69e46: The `defaultConfigLoader` now also reads configuration from scripts tags with `type="backstage.io/config"`. The tag is expected to contain a JSON-serialized array of `AppConfig` objects. If any of these script tags are present, the injected runtime configuration in the static assets will no longer be used. +- b537bd7: Allow custom star icons to be provided via the `star` and `unstarred` icon overrides. See how to override existing icons in the [Backstage documentation](https://backstage.io/docs/getting-started/app-custom-theme/#custom-icons). +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.9.4 + - @backstage/version-bridge@1.0.9 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## 1.14.3-next.0 + +### Patch Changes + +- ea69e46: The `defaultConfigLoader` now also reads configuration from scripts tags with `type="backstage.io/config"`. The tag is expected to contain a JSON-serialized array of `AppConfig` objects. If any of these script tags are present, the injected runtime configuration in the static assets will no longer be used. +- b537bd7: Allow custom star icons to be provided via the `star` and `unstarred` icon overrides. See how to override existing icons in the [Backstage documentation](https://backstage.io/docs/getting-started/app-custom-theme/#custom-icons). +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/version-bridge@1.0.9-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + ## 1.14.2 ### Patch Changes diff --git a/packages/core-app-api/package.json b/packages/core-app-api/package.json index ad8b4b49c0..10a7c913a4 100644 --- a/packages/core-app-api/package.json +++ b/packages/core-app-api/package.json @@ -1,14 +1,30 @@ { "name": "@backstage/core-app-api", + "version": "1.15.1-next.1", "description": "Core app API used by Backstage apps", - "version": "1.14.2", + "backstage": { + "role": "web-library" + }, "publishConfig": { "access": "public" }, + "keywords": [ + "backstage" + ], + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "packages/core-app-api" + }, + "license": "Apache-2.0", + "sideEffects": false, "exports": { ".": "./src/index.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "package.json": [ @@ -16,30 +32,18 @@ ] } }, - "backstage": { - "role": "web-library" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "packages/core-app-api" - }, - "keywords": [ - "backstage" + "files": [ + "dist", + "config.d.ts" ], - "license": "Apache-2.0", - "main": "src/index.ts", - "types": "src/index.ts", - "sideEffects": false, "scripts": { "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean", - "start": "backstage-cli package start" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/config": "workspace:^", @@ -47,7 +51,6 @@ "@backstage/types": "workspace:^", "@backstage/version-bridge": "workspace:^", "@types/prop-types": "^15.7.3", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "history": "^5.0.0", "i18next": "^22.4.15", "lodash": "^4.17.21", @@ -56,29 +59,35 @@ "zen-observable": "^0.10.0", "zod": "^3.22.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/test-utils": "workspace:^", "@testing-library/dom": "^10.0.0", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^15.0.0", + "@testing-library/react": "^16.0.0", "@testing-library/react-hooks": "^8.0.0", "@testing-library/user-event": "^14.0.0", + "@types/react": "^18.0.0", "@types/zen-observable": "^0.8.0", "msw": "^1.0.0", + "react": "^18.0.2", + "react-dom": "^18.0.2", "react-router-beta": "npm:react-router@6.0.0-beta.0", + "react-router-dom": "^6.3.0", "react-router-dom-beta": "npm:react-router-dom@6.0.0-beta.0", "react-router-dom-stable": "npm:react-router-dom@^6.3.0", "react-router-stable": "npm:react-router@^6.3.0" }, - "files": [ - "dist", - "config.d.ts" - ], + "peerDependencies": { + "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + }, "configSchema": "config.d.ts" } diff --git a/packages/core-app-api/api-report.md b/packages/core-app-api/report.api.md similarity index 70% rename from packages/core-app-api/api-report.md rename to packages/core-app-api/report.api.md index 8b8cc991c8..a326555cc1 100644 --- a/packages/core-app-api/api-report.md +++ b/packages/core-app-api/report.api.md @@ -196,6 +196,8 @@ export type AppIcons = { techdocs: IconComponent; user: IconComponent; warning: IconComponent; + star: IconComponent; + unstarred: IconComponent; }; // @public @@ -681,4 +683,70 @@ export class WebStorage implements StorageApi { // (undocumented) snapshot(key: string): StorageValueSnapshot; } + +// Warnings were encountered during analysis: +// +// src/apis/implementations/AlertApi/AlertApiForwarder.d.ts:10:5 - (ae-undocumented) Missing documentation for "post". +// src/apis/implementations/AlertApi/AlertApiForwarder.d.ts:11:5 - (ae-undocumented) Missing documentation for "alert$". +// src/apis/implementations/AnalyticsApi/NoOpAnalyticsApi.d.ts:8:5 - (ae-undocumented) Missing documentation for "captureEvent". +// src/apis/implementations/AppThemeApi/AppThemeSelector.d.ts:11:5 - (ae-undocumented) Missing documentation for "createWithStorage". +// src/apis/implementations/AppThemeApi/AppThemeSelector.d.ts:15:5 - (ae-undocumented) Missing documentation for "getInstalledThemes". +// src/apis/implementations/AppThemeApi/AppThemeSelector.d.ts:16:5 - (ae-undocumented) Missing documentation for "activeThemeId$". +// src/apis/implementations/AppThemeApi/AppThemeSelector.d.ts:17:5 - (ae-undocumented) Missing documentation for "getActiveThemeId". +// src/apis/implementations/AppThemeApi/AppThemeSelector.d.ts:18:5 - (ae-undocumented) Missing documentation for "setActiveThemeId". +// src/apis/implementations/DiscoveryApi/FrontendHostDiscovery.d.ts:37:5 - (ae-undocumented) Missing documentation for "getBaseUrl". +// src/apis/implementations/DiscoveryApi/UrlPatternDiscovery.d.ts:19:5 - (ae-undocumented) Missing documentation for "getBaseUrl". +// src/apis/implementations/ErrorApi/ErrorAlerter.d.ts:12:5 - (ae-undocumented) Missing documentation for "post". +// src/apis/implementations/ErrorApi/ErrorAlerter.d.ts:13:5 - (ae-undocumented) Missing documentation for "error$". +// src/apis/implementations/ErrorApi/ErrorApiForwarder.d.ts:10:5 - (ae-undocumented) Missing documentation for "post". +// src/apis/implementations/ErrorApi/ErrorApiForwarder.d.ts:11:5 - (ae-undocumented) Missing documentation for "error$". +// src/apis/implementations/FeatureFlagsApi/LocalStorageFeatureFlags.d.ts:12:5 - (ae-undocumented) Missing documentation for "registerFlag". +// src/apis/implementations/FeatureFlagsApi/LocalStorageFeatureFlags.d.ts:13:5 - (ae-undocumented) Missing documentation for "getRegisteredFlags". +// src/apis/implementations/FeatureFlagsApi/LocalStorageFeatureFlags.d.ts:14:5 - (ae-undocumented) Missing documentation for "isActive". +// src/apis/implementations/FeatureFlagsApi/LocalStorageFeatureFlags.d.ts:15:5 - (ae-undocumented) Missing documentation for "save". +// src/apis/implementations/OAuthRequestApi/OAuthRequestManager.d.ts:16:5 - (ae-undocumented) Missing documentation for "createAuthRequester". +// src/apis/implementations/OAuthRequestApi/OAuthRequestManager.d.ts:18:5 - (ae-undocumented) Missing documentation for "authRequest$". +// src/apis/implementations/StorageApi/WebStorage.d.ts:14:5 - (ae-undocumented) Missing documentation for "create". +// src/apis/implementations/StorageApi/WebStorage.d.ts:19:5 - (ae-undocumented) Missing documentation for "get". +// src/apis/implementations/StorageApi/WebStorage.d.ts:20:5 - (ae-undocumented) Missing documentation for "snapshot". +// src/apis/implementations/StorageApi/WebStorage.d.ts:21:5 - (ae-undocumented) Missing documentation for "forBucket". +// src/apis/implementations/StorageApi/WebStorage.d.ts:22:5 - (ae-undocumented) Missing documentation for "set". +// src/apis/implementations/StorageApi/WebStorage.d.ts:23:5 - (ae-undocumented) Missing documentation for "remove". +// src/apis/implementations/StorageApi/WebStorage.d.ts:24:5 - (ae-undocumented) Missing documentation for "observe$". +// src/apis/implementations/auth/atlassian/AtlassianAuth.d.ts:9:5 - (ae-undocumented) Missing documentation for "create". +// src/apis/implementations/auth/bitbucket/BitbucketAuth.d.ts:18:5 - (ae-undocumented) Missing documentation for "create". +// src/apis/implementations/auth/bitbucketServer/BitbucketServerAuth.d.ts:17:5 - (ae-undocumented) Missing documentation for "create". +// src/apis/implementations/auth/github/GithubAuth.d.ts:9:5 - (ae-undocumented) Missing documentation for "create". +// src/apis/implementations/auth/gitlab/GitlabAuth.d.ts:9:5 - (ae-undocumented) Missing documentation for "create". +// src/apis/implementations/auth/google/GoogleAuth.d.ts:9:5 - (ae-undocumented) Missing documentation for "create". +// src/apis/implementations/auth/microsoft/MicrosoftAuth.d.ts:17:5 - (ae-undocumented) Missing documentation for "create". +// src/apis/implementations/auth/microsoft/MicrosoftAuth.d.ts:22:5 - (ae-undocumented) Missing documentation for "getAccessToken". +// src/apis/implementations/auth/microsoft/MicrosoftAuth.d.ts:23:5 - (ae-undocumented) Missing documentation for "getIdToken". +// src/apis/implementations/auth/microsoft/MicrosoftAuth.d.ts:24:5 - (ae-undocumented) Missing documentation for "getProfile". +// src/apis/implementations/auth/microsoft/MicrosoftAuth.d.ts:25:5 - (ae-undocumented) Missing documentation for "getBackstageIdentity". +// src/apis/implementations/auth/microsoft/MicrosoftAuth.d.ts:26:5 - (ae-undocumented) Missing documentation for "signIn". +// src/apis/implementations/auth/microsoft/MicrosoftAuth.d.ts:27:5 - (ae-undocumented) Missing documentation for "signOut". +// src/apis/implementations/auth/microsoft/MicrosoftAuth.d.ts:28:5 - (ae-undocumented) Missing documentation for "sessionState$". +// src/apis/implementations/auth/oauth2/OAuth2.d.ts:33:5 - (ae-undocumented) Missing documentation for "create". +// src/apis/implementations/auth/oauth2/OAuth2.d.ts:37:5 - (ae-undocumented) Missing documentation for "signIn". +// src/apis/implementations/auth/oauth2/OAuth2.d.ts:38:5 - (ae-undocumented) Missing documentation for "signOut". +// src/apis/implementations/auth/oauth2/OAuth2.d.ts:39:5 - (ae-undocumented) Missing documentation for "sessionState$". +// src/apis/implementations/auth/oauth2/OAuth2.d.ts:40:5 - (ae-undocumented) Missing documentation for "getAccessToken". +// src/apis/implementations/auth/oauth2/OAuth2.d.ts:41:5 - (ae-undocumented) Missing documentation for "getIdToken". +// src/apis/implementations/auth/oauth2/OAuth2.d.ts:42:5 - (ae-undocumented) Missing documentation for "getBackstageIdentity". +// src/apis/implementations/auth/oauth2/OAuth2.d.ts:43:5 - (ae-undocumented) Missing documentation for "getProfile". +// src/apis/implementations/auth/okta/OktaAuth.d.ts:9:5 - (ae-undocumented) Missing documentation for "create". +// src/apis/implementations/auth/onelogin/OneLoginAuth.d.ts:19:5 - (ae-undocumented) Missing documentation for "create". +// src/apis/implementations/auth/saml/SamlAuth.d.ts:15:5 - (ae-undocumented) Missing documentation for "create". +// src/apis/implementations/auth/saml/SamlAuth.d.ts:16:5 - (ae-undocumented) Missing documentation for "sessionState$". +// src/apis/implementations/auth/saml/SamlAuth.d.ts:18:5 - (ae-undocumented) Missing documentation for "signIn". +// src/apis/implementations/auth/saml/SamlAuth.d.ts:19:5 - (ae-undocumented) Missing documentation for "signOut". +// src/apis/implementations/auth/saml/SamlAuth.d.ts:20:5 - (ae-undocumented) Missing documentation for "getBackstageIdentity". +// src/apis/implementations/auth/saml/SamlAuth.d.ts:21:5 - (ae-undocumented) Missing documentation for "getProfile". +// src/apis/implementations/auth/vmwareCloud/VMwareCloudAuth.d.ts:9:5 - (ae-undocumented) Missing documentation for "create". +// src/apis/system/ApiFactoryRegistry.d.ts:29:5 - (ae-undocumented) Missing documentation for "get". +// src/apis/system/ApiFactoryRegistry.d.ts:32:5 - (ae-undocumented) Missing documentation for "getAllApis". +// src/apis/system/ApiResolver.d.ts:18:5 - (ae-undocumented) Missing documentation for "get". +// src/apis/system/types.d.ts:5:1 - (ae-undocumented) Missing documentation for "ApiFactoryHolder". +// src/app/AppRouter.d.ts:14:5 - (ae-undocumented) Missing documentation for "children". ``` diff --git a/packages/core-app-api/src/app/resolveRouteBindings.test.ts b/packages/core-app-api/src/app/resolveRouteBindings.test.ts index 7d5c649a34..fdc1a9e456 100644 --- a/packages/core-app-api/src/app/resolveRouteBindings.test.ts +++ b/packages/core-app-api/src/app/resolveRouteBindings.test.ts @@ -75,6 +75,55 @@ describe('resolveRouteBindings', () => { expect(result.get(mySource)).toBe(myTarget); }); + it('prioritizes callback routes over config', () => { + const mySource = createExternalRouteRef({ id: 'test', optional: true }); + const myTarget = createRouteRef({ id: 'test' }); + + expect( + resolveRouteBindings( + ({ bind }) => { + bind({ mySource }, { mySource: false }); + }, + new MockConfigApi({ + app: { routes: { bindings: { 'test.mySource': 'myTarget' } } }, + }), + [ + createPlugin({ + id: 'test', + routes: { + myTarget, + }, + externalRoutes: { + mySource, + }, + }), + ], + ).get(mySource), + ).toBe(undefined); + + expect( + resolveRouteBindings( + ({ bind }) => { + bind({ mySource }, { mySource: myTarget }); + }, + new MockConfigApi({ + app: { routes: { bindings: { 'test.mySource': false } } }, + }), + [ + createPlugin({ + id: 'test', + routes: { + myTarget, + }, + externalRoutes: { + mySource, + }, + }), + ], + ).get(mySource), + ).toBe(myTarget); + }); + it('throws on invalid config', () => { expect(() => resolveRouteBindings( diff --git a/packages/core-app-api/src/app/resolveRouteBindings.ts b/packages/core-app-api/src/app/resolveRouteBindings.ts index 07dfea43ee..41b88f2674 100644 --- a/packages/core-app-api/src/app/resolveRouteBindings.ts +++ b/packages/core-app-api/src/app/resolveRouteBindings.ts @@ -73,6 +73,7 @@ export function resolveRouteBindings( ) { const routesById = collectRouteIds(plugins); const result = new Map(); + const disabledExternalRefs = new Set(); // Perform callback bindings first with highest priority if (bindRoutes) { @@ -87,11 +88,15 @@ export function resolveRouteBindings( } if (!value && !externalRoute.optional) { throw new Error( - `External route ${key} is required but was undefined`, + `External route ${key} is required but was ${ + value === false ? 'disabled' : 'not provided' + }`, ); } if (value) { result.set(externalRoute, value); + } else if (value === false) { + disabledExternalRefs.add(externalRoute); } } }; @@ -102,7 +107,6 @@ export function resolveRouteBindings( const bindings = config .getOptionalConfig('app.routes.bindings') ?.get(); - const disabledExternalRefs = new Set(); if (bindings) { for (const [externalRefId, targetRefId] of Object.entries(bindings)) { if (!isValidTargetRefId(targetRefId)) { @@ -118,11 +122,14 @@ export function resolveRouteBindings( ); } + // Skip if binding was already defined in code + if (result.has(externalRef) || disabledExternalRefs.has(externalRef)) { + continue; + } + if (targetRefId === false) { disabledExternalRefs.add(externalRef); - - result.delete(externalRef); - } else if (!result.has(externalRef)) { + } else { const targetRef = routesById.routes.get(targetRefId); if (!targetRef) { throw new Error( diff --git a/packages/core-app-api/src/app/types.ts b/packages/core-app-api/src/app/types.ts index 9d2c77292c..1b33e9c05b 100644 --- a/packages/core-app-api/src/app/types.ts +++ b/packages/core-app-api/src/app/types.ts @@ -115,6 +115,8 @@ export type AppIcons = { techdocs: IconComponent; user: IconComponent; warning: IconComponent; + star: IconComponent; + unstarred: IconComponent; }; /** @@ -158,7 +160,7 @@ type TargetRouteMap< infer Params, any > - ? RouteRef | SubRouteRef + ? RouteRef | SubRouteRef | false : never; }; diff --git a/packages/core-compat-api/CHANGELOG.md b/packages/core-compat-api/CHANGELOG.md index 62a77898bd..91e51ce0ea 100644 --- a/packages/core-compat-api/CHANGELOG.md +++ b/packages/core-compat-api/CHANGELOG.md @@ -1,5 +1,51 @@ # @backstage/core-compat-api +## 0.3.1-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/version-bridge@1.0.10-next.0 + +## 0.3.1-next.0 + +### Patch Changes + +- 4a5ba19: Internal update to remove deprecated `BackstagePlugin` type and move to `FrontendPlugin` +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/version-bridge@1.0.9 + +## 0.3.0 + +### Minor Changes + +- 6db849e: **BREAKING**: The `namespace` parameter for API's is now defaulted to the `pluginId` which was discovered. This means that if you're overriding API's by using ID's directly, they might have changed to include the plugin ID too. + +### Patch Changes + +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. +- c816e2d: Added support for new `FrontendPlugin` and `FrontendModule` types. +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/version-bridge@1.0.9 + +## 0.3.0-next.2 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/frontend-plugin-api@0.8.0-next.2 + - @backstage/version-bridge@1.0.9-next.0 + ## 0.3.0-next.1 ### Minor Changes diff --git a/packages/core-compat-api/package.json b/packages/core-compat-api/package.json index a54cb8f20f..6379ed4ae2 100644 --- a/packages/core-compat-api/package.json +++ b/packages/core-compat-api/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/core-compat-api", - "version": "0.3.0-next.1", + "version": "0.3.1-next.1", "backstage": { "role": "web-library" }, @@ -34,7 +34,6 @@ "@backstage/core-plugin-api": "workspace:^", "@backstage/frontend-plugin-api": "workspace:^", "@backstage/version-bridge": "workspace:^", - "@types/react": "^16.13.1 || ^17.0.0", "lodash": "^4.17.21" }, "devDependencies": { @@ -46,12 +45,25 @@ "@backstage/frontend-test-utils": "workspace:^", "@backstage/plugin-catalog": "workspace:^", "@backstage/test-utils": "workspace:^", + "@backstage/types": "workspace:^", "@oriflame/backstage-plugin-score-card": "^0.8.0", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^15.0.0" + "@testing-library/react": "^16.0.0", + "@types/react": "^18.0.0", + "react": "^18.0.2", + "react-dom": "^18.0.2", + "react-router-dom": "^6.3.0", + "zod": "^3.22.4" }, "peerDependencies": { + "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } } diff --git a/packages/core-compat-api/api-report.md b/packages/core-compat-api/report.api.md similarity index 88% rename from packages/core-compat-api/api-report.md rename to packages/core-compat-api/report.api.md index ddb3bc6bf4..e6971975b2 100644 --- a/packages/core-compat-api/api-report.md +++ b/packages/core-compat-api/report.api.md @@ -113,5 +113,12 @@ export type ToNewRouteRef = ? ExternalRouteRef_2 : never; +// Warnings were encountered during analysis: +// +// src/apis/implementations/AnalyticsApi/NoOpAnalyticsApi.d.ts:9:5 - (ae-undocumented) Missing documentation for "captureEvent". +// src/convertLegacyApp.d.ts:4:1 - (ae-undocumented) Missing documentation for "convertLegacyApp". +// src/convertLegacyPageExtension.d.ts:4:1 - (ae-undocumented) Missing documentation for "convertLegacyPageExtension". +// src/convertLegacyPlugin.d.ts:4:1 - (ae-undocumented) Missing documentation for "convertLegacyPlugin". + // (No @packageDocumentation comment for this package) ``` diff --git a/packages/core-compat-api/src/collectLegacyRoutes.test.tsx b/packages/core-compat-api/src/collectLegacyRoutes.test.tsx index 0319628b14..a28bda6dea 100644 --- a/packages/core-compat-api/src/collectLegacyRoutes.test.tsx +++ b/packages/core-compat-api/src/collectLegacyRoutes.test.tsx @@ -27,11 +27,12 @@ import { PuppetDbPage } from '@backstage-community/plugin-puppetdb'; import { StackstormPage } from '@backstage-community/plugin-stackstorm'; import { ScoreBoardPage } from '@oriflame/backstage-plugin-score-card'; import React, { Fragment } from 'react'; +// TODO(rugvip): this should take into account that this is a test file, so these deps don't need to be in the dependencies +// eslint-disable-next-line @backstage/no-undeclared-imports +import { OpaqueFrontendPlugin } from '@internal/frontend'; import { Navigate, Route, Routes } from 'react-router-dom'; import { collectLegacyRoutes } from './collectLegacyRoutes'; -// eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { toInternalFrontendPlugin } from '../../frontend-plugin-api/src/wiring/createFrontendPlugin'; import { createPlugin, createRoutableExtension, @@ -55,7 +56,7 @@ describe('collectLegacyRoutes', () => { expect( collected.map(p => ({ id: p.id, - extensions: toInternalFrontendPlugin(p).extensions.map(e => ({ + extensions: OpaqueFrontendPlugin.toInternal(p).extensions.map(e => ({ id: e.id, attachTo: e.attachTo, disabled: e.disabled, @@ -158,7 +159,7 @@ describe('collectLegacyRoutes', () => { expect( collected.map(p => ({ id: p.id, - extensions: toInternalFrontendPlugin(p).extensions.map(e => ({ + extensions: OpaqueFrontendPlugin.toInternal(p).extensions.map(e => ({ id: e.id, attachTo: e.attachTo, disabled: e.disabled, diff --git a/packages/core-compat-api/src/collectLegacyRoutes.tsx b/packages/core-compat-api/src/collectLegacyRoutes.tsx index 43e66ce859..f3d94dc4b9 100644 --- a/packages/core-compat-api/src/collectLegacyRoutes.tsx +++ b/packages/core-compat-api/src/collectLegacyRoutes.tsx @@ -21,7 +21,7 @@ import { getComponentData, } from '@backstage/core-plugin-api'; import { - BackstagePlugin, + FrontendPlugin, ExtensionDefinition, coreExtensionData, createExtension, @@ -156,7 +156,7 @@ function visitRouteChildren(options: { /** @internal */ export function collectLegacyRoutes( flatRoutesElement: JSX.Element, -): BackstagePlugin[] { +): FrontendPlugin[] { const pluginExtensions = new Map< LegacyBackstagePlugin, ExtensionDefinition[] diff --git a/packages/core-compat-api/src/compatWrapper/compatWrapper.test.tsx b/packages/core-compat-api/src/compatWrapper/compatWrapper.test.tsx index fe4770a08c..94fc8705e6 100644 --- a/packages/core-compat-api/src/compatWrapper/compatWrapper.test.tsx +++ b/packages/core-compat-api/src/compatWrapper/compatWrapper.test.tsx @@ -76,7 +76,7 @@ describe('BackwardsCompatProvider', () => { expect(screen.getByTestId('ctx').textContent).toMatchInlineSnapshot(` "plugins: test, app components: NotFoundErrorPage, BootErrorPage, Progress, Router, ErrorBoundaryFallback - icons: brokenImage, catalog, scaffolder, techdocs, search, chat, dashboard, docs, email, github, group, help, kind:api, kind:component, kind:domain, kind:group, kind:location, kind:system, kind:user, kind:resource, kind:template, user, warning" + icons: brokenImage, catalog, scaffolder, techdocs, search, chat, dashboard, docs, email, github, group, help, kind:api, kind:component, kind:domain, kind:group, kind:location, kind:system, kind:user, kind:resource, kind:template, user, warning, star, unstarred, externalLink" `); }); @@ -120,7 +120,7 @@ describe('ForwardsCompatProvider', () => { expect(screen.getByTestId('ctx').textContent).toMatchInlineSnapshot(` "components: progress=true, notFoundErrorPage=true, errorBoundaryFallback=true - icons: kind:api, kind:component, kind:domain, kind:group, kind:location, kind:system, kind:user, kind:resource, kind:template, brokenImage, catalog, scaffolder, techdocs, search, chat, dashboard, docs, email, github, group, help, user, warning" + icons: kind:api, kind:component, kind:domain, kind:group, kind:location, kind:system, kind:user, kind:resource, kind:template, brokenImage, catalog, scaffolder, techdocs, search, chat, dashboard, docs, email, github, group, help, user, warning, star, unstarred" `); }); diff --git a/packages/core-compat-api/src/convertLegacyPlugin.test.tsx b/packages/core-compat-api/src/convertLegacyPlugin.test.tsx index 01266a35b7..68bb7cac3f 100644 --- a/packages/core-compat-api/src/convertLegacyPlugin.test.tsx +++ b/packages/core-compat-api/src/convertLegacyPlugin.test.tsx @@ -23,8 +23,9 @@ import { } from '@backstage/core-plugin-api'; import { convertLegacyPlugin } from './convertLegacyPlugin'; import { PageBlueprint } from '@backstage/frontend-plugin-api'; -// eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { toInternalFrontendPlugin } from '../../frontend-plugin-api/src/wiring/createFrontendPlugin'; +// TODO(rugvip): this should take into account that this is a test file, so these deps don't need to be in the dependencies +// eslint-disable-next-line @backstage/no-undeclared-imports +import { OpaqueFrontendPlugin } from '@internal/frontend'; describe('convertLegacyPlugin', () => { it('should convert a plain legacy plugin to a new plugin', () => { @@ -73,7 +74,7 @@ describe('convertLegacyPlugin', () => { }, ); - const internalConverted = toInternalFrontendPlugin(converted); + const internalConverted = OpaqueFrontendPlugin.toInternal(converted); expect(internalConverted.id).toBe('test'); expect(internalConverted.routes).toEqual({ diff --git a/packages/core-components/CHANGELOG.md b/packages/core-components/CHANGELOG.md index 72fe6e6692..fec8b746c8 100644 --- a/packages/core-components/CHANGELOG.md +++ b/packages/core-components/CHANGELOG.md @@ -1,5 +1,75 @@ # @backstage/core-components +## 0.15.1-next.1 + +### Patch Changes + +- 3f76d0e: Correct size of FavoriteToggle and inherit non-starred color from parent +- e969dc7: Move `@types/react` to a peer dependency. +- 83e2887: Fixed a bug in the `SidebarSubmenu` core component that caused the nested menu to overlap with the sidebar when the user hovers over the pinned sidebar. +- Updated dependencies + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/version-bridge@1.0.10-next.0 + - @backstage/theme@0.5.8-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## 0.15.1-next.0 + +### Patch Changes + +- 46b5a20: `Link` component now accepts `externalLinkIcon` prop +- Updated dependencies + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.7 + - @backstage/version-bridge@1.0.9 + +## 0.15.0 + +### Minor Changes + +- 9adc552: Added missing items to `overridableComponents` + + **BREAKING** Overridable component name for styling `OAuthRequestDialog` changed to `BackstageOAuthRequestDialog`. Overridable component name `BackstageMissingAnnotationEmptyState` that was previously deprecated has been removed. + +### Patch Changes + +- c891b69: Add `FavoriteToggle` in `core-components` to standardise favorite marking +- 0944334: Removed default title set to Unknown page on `ContentHeaderTitle` component to support usage of component without title prop. +- f325258: Use getOptionalString for optional app.support.items[].links[].title +- af4c146: Support menu items should not be buttons in favour of links +- 107a147: Fixed `Table` width being overridden by custom `style` prop. +- b537bd7: Allow custom star icons to be provided via the `star` and `unstarred` icon overrides. See how to override existing icons in the [Backstage documentation](https://backstage.io/docs/getting-started/app-custom-theme/#custom-icons). +- 06b8206: Added `titleComponent` prop to `SignInPage` component to allow further customization of the title using `ReactNode` +- dbbd93e: Internal update to match recent React types +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.9.4 + - @backstage/theme@0.5.7 + - @backstage/version-bridge@1.0.9 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## 0.14.11-next.1 + +### Patch Changes + +- c891b69: Add `FavoriteToggle` in `core-components` to standardise favorite marking +- 0944334: Removed default title set to Unknown page on `ContentHeaderTitle` component to support usage of component without title prop. +- f325258: Use getOptionalString for optional app.support.items[].links[].title +- af4c146: Support menu items should not be buttons in favour of links +- b537bd7: Allow custom star icons to be provided via the `star` and `unstarred` icon overrides. See how to override existing icons in the [Backstage documentation](https://backstage.io/docs/getting-started/app-custom-theme/#custom-icons). +- dbbd93e: Internal update to match recent React types +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/theme@0.5.7-next.0 + - @backstage/version-bridge@1.0.9-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + ## 0.14.11-next.0 ### Patch Changes diff --git a/packages/core-components/package.json b/packages/core-components/package.json index ba0634bfe9..e38adfea7c 100644 --- a/packages/core-components/package.json +++ b/packages/core-components/package.json @@ -1,13 +1,13 @@ { "name": "@backstage/core-components", + "version": "0.15.1-next.1", "description": "Core components used by Backstage plugins and apps", - "version": "0.14.11-next.0", - "publishConfig": { - "access": "public" - }, "backstage": { "role": "web-library" }, + "publishConfig": { + "access": "public" + }, "keywords": [ "backstage" ], @@ -65,7 +65,6 @@ "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.61", "@react-hookz/web": "^24.0.0", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "@types/react-sparklines": "^1.7.0", "ansi-regex": "^6.0.1", "classnames": "^2.2.6", @@ -99,7 +98,7 @@ "@backstage/test-utils": "workspace:^", "@testing-library/dom": "^10.0.0", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^15.0.0", + "@testing-library/react": "^16.0.0", "@testing-library/user-event": "^14.0.0", "@types/ansi-regex": "^5.0.0", "@types/classnames": "^2.2.9", @@ -108,6 +107,7 @@ "@types/d3-zoom": "^3.0.1", "@types/dagre": "^0.7.44", "@types/google-protobuf": "^3.7.2", + "@types/react": "^18.0.0", "@types/react-helmet": "^6.1.0", "@types/react-syntax-highlighter": "^15.0.0", "@types/react-virtualized-auto-sizer": "^1.0.1", @@ -115,12 +115,21 @@ "@types/zen-observable": "^0.8.0", "cross-fetch": "^4.0.0", "history": "^5.0.0", - "msw": "^1.0.0" + "msw": "^1.0.0", + "react": "^18.0.2", + "react-dom": "^18.0.2", + "react-router-dom": "^6.3.0" }, "peerDependencies": { + "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-router-dom": "6.0.0-beta.0 || ^6.3.0" }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + }, "configSchema": "config.d.ts" } diff --git a/packages/core-components/api-report-alpha.md b/packages/core-components/report-alpha.api.md similarity index 95% rename from packages/core-components/api-report-alpha.md rename to packages/core-components/report-alpha.api.md index 1f4b999232..ea44f92093 100644 --- a/packages/core-components/api-report-alpha.md +++ b/packages/core-components/report-alpha.api.md @@ -54,5 +54,9 @@ export const coreComponentsTranslationRef: TranslationRef< } >; +// Warnings were encountered during analysis: +// +// src/translation.d.ts:2:22 - (ae-undocumented) Missing documentation for "coreComponentsTranslationRef". + // (No @packageDocumentation comment for this package) ``` diff --git a/packages/core-components/api-report-testUtils.md b/packages/core-components/report-testUtils.api.md similarity index 100% rename from packages/core-components/api-report-testUtils.md rename to packages/core-components/report-testUtils.api.md diff --git a/packages/core-components/api-report.md b/packages/core-components/report.api.md similarity index 70% rename from packages/core-components/api-report.md rename to packages/core-components/report.api.md index 597b1a9abf..24c835f638 100644 --- a/packages/core-components/api-report.md +++ b/packages/core-components/report.api.md @@ -19,6 +19,7 @@ import { default as CSS_2 } from 'csstype'; import { CSSProperties } from 'react'; import { ElementType } from 'react'; import { ErrorInfo } from 'react'; +import IconButton from '@material-ui/core/IconButton'; import { IconComponent } from '@backstage/core-plugin-api'; import { Icons } from '@material-table/core'; import { IdentityApi } from '@backstage/core-plugin-api'; @@ -401,6 +402,24 @@ export type ErrorPanelProps = { title?: string; }; +// @public +export function FavoriteToggle( + props: ComponentProps & { + id: string; + title: string; + isFavorite: boolean; + onToggle: (value: boolean) => void; + }, +): React_2.JSX.Element; + +// @public +export function FavoriteToggleIcon(props: { + isFavorite: boolean; +}): React_2.JSX.Element; + +// @public (undocumented) +export type FavoriteToggleIconClassKey = 'icon' | 'iconBorder'; + // @public (undocumented) export type FeatureCalloutCircleClassKey = | '@keyframes pulsateSlightly' @@ -676,6 +695,9 @@ export const LinkButton: (props: LinkButtonProps) => JSX.Element; export type LinkButtonProps = ButtonProps_2 & Omit; +// @public (undocumented) +export type LinkClassKey = 'visuallyHidden' | 'externalLink'; + // Warning: (ae-missing-release-tag) "LinkProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -684,6 +706,7 @@ export type LinkProps = Omit & to: string; component?: ElementType; noTrack?: boolean; + externalLinkIcon?: boolean; }; // Warning: (ae-missing-release-tag) "LoginRequestListItemClassKey" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -778,9 +801,6 @@ export function MissingAnnotationEmptyState( props: Props_3, ): React_2.JSX.Element; -// @public @deprecated (undocumented) -export type MissingAnnotationEmptyStateClassKey = 'code'; - // @public export const MobileSidebar: ( props: MobileSidebarProps, @@ -1111,11 +1131,26 @@ export const SidebarSubmenu: ( props: SidebarSubmenuProps, ) => React_2.JSX.Element; +// @public (undocumented) +export type SidebarSubmenuClassKey = 'root' | 'drawer' | 'drawerOpen' | 'title'; + // @public export const SidebarSubmenuItem: ( props: SidebarSubmenuItemProps, ) => React_2.JSX.Element; +// @public (undocumented) +export type SidebarSubmenuItemClassKey = + | 'item' + | 'itemContainer' + | 'selected' + | 'label' + | 'subtitle' + | 'dropdownArrow' + | 'dropdown' + | 'dropdownItem' + | 'textContent'; + // @public export type SidebarSubmenuItemDropdownItem = { title: string; @@ -1186,6 +1221,12 @@ export function SimpleStepperStep( // @public (undocumented) export type SimpleStepperStepClassKey = 'end'; +// @public (undocumented) +export type StackDetailsClassKey = 'title'; + +// @public (undocumented) +export function StarIcon(props: IconComponentProps): React_2.JSX.Element; + // Warning: (ae-missing-release-tag) "StatusAborted" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -1455,6 +1496,9 @@ export function TrendLine( }, ): React_2.JSX.Element | null; +// @public (undocumented) +export function UnstarredIcon(props: IconComponentProps): React_2.JSX.Element; + // @public export function useContent(): { focusContent: () => void; @@ -1487,21 +1531,14 @@ export class UserIdentity implements IdentityApi { getIdToken?: () => Promise; signOut?: () => Promise; }): IdentityApi; - // (undocumented) getBackstageIdentity(): Promise; - // (undocumented) getCredentials(): Promise<{ token?: string | undefined; }>; - // (undocumented) getIdToken(): Promise; - // (undocumented) getProfile(): ProfileInfo; - // (undocumented) getProfileInfo(): Promise; - // (undocumented) getUserId(): string; - // (undocumented) signOut(): Promise; } @@ -1537,9 +1574,188 @@ export type WarningPanelClassKey = // Warnings were encountered during analysis: // +// src/components/AutoLogout/AutoLogout.d.ts:3:1 - (ae-undocumented) Missing documentation for "AutoLogoutProps". +// src/components/Avatar/Avatar.d.ts:3:1 - (ae-undocumented) Missing documentation for "AvatarClassKey". +// src/components/DependencyGraph/DefaultLabel.d.ts:4:1 - (ae-undocumented) Missing documentation for "DependencyGraphDefaultLabelClassKey". +// src/components/DependencyGraph/DefaultNode.d.ts:4:1 - (ae-undocumented) Missing documentation for "DependencyGraphDefaultNodeClassKey". +// src/components/DependencyGraph/Edge.d.ts:15:1 - (ae-undocumented) Missing documentation for "DependencyGraphEdgeClassKey". +// src/components/DependencyGraph/Node.d.ts:5:1 - (ae-undocumented) Missing documentation for "DependencyGraphNodeClassKey". // src/components/DependencyGraph/types.d.ts:22:9 - (ae-unresolved-link) The @link reference could not be resolved: The package "@backstage/core-components" does not have an export "DependencyNode" // src/components/DependencyGraph/types.d.ts:26:9 - (ae-unresolved-link) The @link reference could not be resolved: The package "@backstage/core-components" does not have an export "DependencyNode" +// src/components/DependencyGraph/types.d.ts:143:9 - (ae-undocumented) Missing documentation for "LEFT". +// src/components/DependencyGraph/types.d.ts:144:9 - (ae-undocumented) Missing documentation for "RIGHT". +// src/components/DependencyGraph/types.d.ts:145:9 - (ae-undocumented) Missing documentation for "CENTER". +// src/components/DismissableBanner/DismissableBanner.d.ts:3:1 - (ae-undocumented) Missing documentation for "DismissableBannerClassKey". +// src/components/DismissableBanner/DismissableBanner.d.ts:8:1 - (ae-undocumented) Missing documentation for "DismissbleBannerClassKey". +// src/components/DismissableBanner/DismissableBanner.d.ts:16:22 - (ae-undocumented) Missing documentation for "DismissableBanner". +// src/components/EmptyState/EmptyState.d.ts:3:1 - (ae-undocumented) Missing documentation for "EmptyStateClassKey". +// src/components/EmptyState/EmptyStateImage.d.ts:6:1 - (ae-undocumented) Missing documentation for "EmptyStateImageClassKey". +// src/components/EmptyState/MissingAnnotationEmptyState.d.ts:10:1 - (ae-undocumented) Missing documentation for "MissingAnnotationEmptyState". +// src/components/ErrorPanel/ErrorPanel.d.ts:3:1 - (ae-undocumented) Missing documentation for "ErrorPanelClassKey". +// src/components/ErrorPanel/ErrorPanel.d.ts:5:1 - (ae-undocumented) Missing documentation for "ErrorPanelProps". +// src/components/FavoriteToggle/FavoriteToggle.d.ts:6:1 - (ae-undocumented) Missing documentation for "FavoriteToggleIconClassKey". +// src/components/FeatureDiscovery/FeatureCalloutCircular.d.ts:3:1 - (ae-undocumented) Missing documentation for "FeatureCalloutCircleClassKey". +// src/components/HeaderIconLinkRow/HeaderIconLinkRow.d.ts:4:1 - (ae-undocumented) Missing documentation for "HeaderIconLinkRowClassKey". +// src/components/HeaderIconLinkRow/IconLinkVertical.d.ts:2:1 - (ae-undocumented) Missing documentation for "IconLinkVerticalProps". +// src/components/HeaderIconLinkRow/IconLinkVertical.d.ts:12:1 - (ae-undocumented) Missing documentation for "IconLinkVerticalClassKey". +// src/components/HeaderIconLinkRow/IconLinkVertical.d.ts:14:1 - (ae-undocumented) Missing documentation for "IconLinkVertical". +// src/components/HorizontalScrollGrid/HorizontalScrollGrid.d.ts:8:1 - (ae-undocumented) Missing documentation for "HorizontalScrollGridClassKey". +// src/components/Lifecycle/Lifecycle.d.ts:7:1 - (ae-undocumented) Missing documentation for "LifecycleClassKey". +// src/components/Lifecycle/Lifecycle.d.ts:8:1 - (ae-undocumented) Missing documentation for "Lifecycle". +// src/components/Link/Link.d.ts:6:1 - (ae-undocumented) Missing documentation for "LinkClassKey". +// src/components/Link/Link.d.ts:8:1 - (ae-undocumented) Missing documentation for "LinkProps". +// src/components/LinkButton/LinkButton.d.ts:24:22 - (ae-undocumented) Missing documentation for "Button". +// src/components/LinkButton/LinkButton.d.ts:29:1 - (ae-undocumented) Missing documentation for "ButtonProps". +// src/components/MarkdownContent/MarkdownContent.d.ts:3:1 - (ae-undocumented) Missing documentation for "MarkdownContentClassKey". +// src/components/OAuthRequestDialog/LoginRequestListItem.d.ts:3:1 - (ae-undocumented) Missing documentation for "LoginRequestListItemClassKey". +// src/components/OAuthRequestDialog/OAuthRequestDialog.d.ts:2:1 - (ae-undocumented) Missing documentation for "OAuthRequestDialogClassKey". +// src/components/OAuthRequestDialog/OAuthRequestDialog.d.ts:3:1 - (ae-undocumented) Missing documentation for "OAuthRequestDialog". +// src/components/OverflowTooltip/OverflowTooltip.d.ts:9:1 - (ae-undocumented) Missing documentation for "OverflowTooltipClassKey". +// src/components/OverflowTooltip/OverflowTooltip.d.ts:10:1 - (ae-undocumented) Missing documentation for "OverflowTooltip". +// src/components/Progress/Progress.d.ts:3:1 - (ae-undocumented) Missing documentation for "Progress". +// src/components/ProgressBars/Gauge.d.ts:4:1 - (ae-undocumented) Missing documentation for "GaugeClassKey". +// src/components/ProgressBars/Gauge.d.ts:6:1 - (ae-undocumented) Missing documentation for "GaugeProps". +// src/components/ProgressBars/Gauge.d.ts:19:1 - (ae-undocumented) Missing documentation for "GaugePropsGetColorOptions". +// src/components/ProgressBars/Gauge.d.ts:26:1 - (ae-undocumented) Missing documentation for "GaugePropsGetColor". +// src/components/ProgressBars/GaugeCard.d.ts:20:1 - (ae-undocumented) Missing documentation for "GaugeCardClassKey". +// src/components/ProgressBars/LinearGauge.d.ts:11:1 - (ae-undocumented) Missing documentation for "LinearGauge". +// src/components/ResponseErrorPanel/ResponseErrorPanel.d.ts:3:1 - (ae-undocumented) Missing documentation for "ResponseErrorPanelClassKey". +// src/components/Select/Select.d.ts:3:1 - (ae-undocumented) Missing documentation for "SelectInputBaseClassKey". +// src/components/Select/Select.d.ts:5:1 - (ae-undocumented) Missing documentation for "SelectClassKey". +// src/components/Select/Select.d.ts:7:1 - (ae-undocumented) Missing documentation for "SelectItem". +// src/components/Select/Select.d.ts:12:1 - (ae-undocumented) Missing documentation for "SelectedItems". +// src/components/Select/Select.d.ts:27:1 - (ae-undocumented) Missing documentation for "SelectComponent". +// src/components/Select/static/ClosedDropdown.d.ts:3:1 - (ae-undocumented) Missing documentation for "ClosedDropdownClassKey". +// src/components/Select/static/OpenedDropdown.d.ts:2:1 - (ae-undocumented) Missing documentation for "OpenedDropdownClassKey". +// src/components/SimpleStepper/SimpleStepper.d.ts:16:1 - (ae-undocumented) Missing documentation for "SimpleStepper". +// src/components/SimpleStepper/SimpleStepperFooter.d.ts:3:1 - (ae-undocumented) Missing documentation for "SimpleStepperFooterClassKey". +// src/components/SimpleStepper/SimpleStepperStep.d.ts:3:1 - (ae-undocumented) Missing documentation for "SimpleStepperStepClassKey". +// src/components/SimpleStepper/SimpleStepperStep.d.ts:4:1 - (ae-undocumented) Missing documentation for "SimpleStepperStep". +// src/components/Status/Status.d.ts:2:1 - (ae-undocumented) Missing documentation for "StatusClassKey". +// src/components/Status/Status.d.ts:3:1 - (ae-undocumented) Missing documentation for "StatusOK". +// src/components/Status/Status.d.ts:4:1 - (ae-undocumented) Missing documentation for "StatusWarning". +// src/components/Status/Status.d.ts:5:1 - (ae-undocumented) Missing documentation for "StatusError". +// src/components/Status/Status.d.ts:6:1 - (ae-undocumented) Missing documentation for "StatusPending". +// src/components/Status/Status.d.ts:7:1 - (ae-undocumented) Missing documentation for "StatusRunning". +// src/components/Status/Status.d.ts:8:1 - (ae-undocumented) Missing documentation for "StatusAborted". +// src/components/StructuredMetadataTable/MetadataTable.d.ts:3:1 - (ae-undocumented) Missing documentation for "MetadataTableTitleCellClassKey". +// src/components/StructuredMetadataTable/MetadataTable.d.ts:4:1 - (ae-undocumented) Missing documentation for "MetadataTableCellClassKey". +// src/components/StructuredMetadataTable/MetadataTable.d.ts:5:1 - (ae-undocumented) Missing documentation for "MetadataTableListClassKey". +// src/components/StructuredMetadataTable/MetadataTable.d.ts:6:1 - (ae-undocumented) Missing documentation for "MetadataTableListItemClassKey". +// src/components/StructuredMetadataTable/StructuredMetadataTable.d.ts:2:1 - (ae-undocumented) Missing documentation for "StructuredMetadataTableListClassKey". +// src/components/StructuredMetadataTable/StructuredMetadataTable.d.ts:3:1 - (ae-undocumented) Missing documentation for "StructuredMetadataTableNestedListClassKey". +// src/components/StructuredMetadataTable/StructuredMetadataTable.d.ts:5:1 - (ae-undocumented) Missing documentation for "StructuredMetadataTableProps". +// src/components/StructuredMetadataTable/StructuredMetadataTable.d.ts:6:5 - (ae-undocumented) Missing documentation for "metadata". +// src/components/StructuredMetadataTable/StructuredMetadataTable.d.ts:9:5 - (ae-undocumented) Missing documentation for "dense". +// src/components/StructuredMetadataTable/StructuredMetadataTable.d.ts:10:5 - (ae-undocumented) Missing documentation for "options". +// src/components/StructuredMetadataTable/StructuredMetadataTable.d.ts:21:1 - (ae-undocumented) Missing documentation for "StructuredMetadataTable". +// src/components/SupportButton/SupportButton.d.ts:8:1 - (ae-undocumented) Missing documentation for "SupportButtonClassKey". +// src/components/SupportButton/SupportButton.d.ts:9:1 - (ae-undocumented) Missing documentation for "SupportButton". +// src/components/TabbedLayout/RoutedTabs.d.ts:8:1 - (ae-undocumented) Missing documentation for "RoutedTabs". // src/components/TabbedLayout/RoutedTabs.d.ts:9:5 - (ae-forgotten-export) The symbol "SubRoute_2" needs to be exported by the entry point index.d.ts +// src/components/TabbedLayout/TabbedLayout.d.ts:29:1 - (ae-undocumented) Missing documentation for "TabbedLayout". +// src/components/TabbedLayout/TabbedLayout.d.ts:30:9 - (ae-undocumented) Missing documentation for "Route". +// src/components/Table/Filters.d.ts:3:1 - (ae-undocumented) Missing documentation for "TableFiltersClassKey". +// src/components/Table/SubvalueCell.d.ts:2:1 - (ae-undocumented) Missing documentation for "SubvalueCellClassKey". +// src/components/Table/SubvalueCell.d.ts:7:1 - (ae-undocumented) Missing documentation for "SubvalueCell". +// src/components/Table/Table.d.ts:4:1 - (ae-undocumented) Missing documentation for "TableHeaderClassKey". +// src/components/Table/Table.d.ts:5:1 - (ae-undocumented) Missing documentation for "TableToolbarClassKey". +// src/components/Table/Table.d.ts:7:1 - (ae-undocumented) Missing documentation for "FiltersContainerClassKey". +// src/components/Table/Table.d.ts:8:1 - (ae-undocumented) Missing documentation for "TableClassKey". +// src/components/Table/Table.d.ts:9:1 - (ae-undocumented) Missing documentation for "TableColumn". +// src/components/Table/Table.d.ts:10:5 - (ae-undocumented) Missing documentation for "highlight". +// src/components/Table/Table.d.ts:11:5 - (ae-undocumented) Missing documentation for "width". +// src/components/Table/Table.d.ts:13:1 - (ae-undocumented) Missing documentation for "TableFilter". +// src/components/Table/Table.d.ts:17:1 - (ae-undocumented) Missing documentation for "TableState". // src/components/Table/Table.d.ts:20:5 - (ae-forgotten-export) The symbol "SelectedFilters" needs to be exported by the entry point index.d.ts +// src/components/Table/Table.d.ts:22:1 - (ae-undocumented) Missing documentation for "TableProps". +// src/components/Table/Table.d.ts:23:5 - (ae-undocumented) Missing documentation for "columns". +// src/components/Table/Table.d.ts:24:5 - (ae-undocumented) Missing documentation for "subtitle". +// src/components/Table/Table.d.ts:25:5 - (ae-undocumented) Missing documentation for "filters". +// src/components/Table/Table.d.ts:26:5 - (ae-undocumented) Missing documentation for "initialState". +// src/components/Table/Table.d.ts:27:5 - (ae-undocumented) Missing documentation for "emptyContent". +// src/components/Table/Table.d.ts:28:5 - (ae-undocumented) Missing documentation for "isLoading". +// src/components/Table/Table.d.ts:29:5 - (ae-undocumented) Missing documentation for "onStateChange". +// src/components/Table/Table.d.ts:31:1 - (ae-undocumented) Missing documentation for "TableOptions". +// src/components/Table/Table.d.ts:44:1 - (ae-undocumented) Missing documentation for "Table". +// src/components/Table/Table.d.ts:45:1 - (ae-undocumented) Missing documentation for "Table". +// src/components/Table/Table.d.ts:46:9 - (ae-undocumented) Missing documentation for "icons". +// src/components/TrendLine/TrendLine.d.ts:3:1 - (ae-undocumented) Missing documentation for "TrendLine". +// src/components/WarningPanel/WarningPanel.d.ts:2:1 - (ae-undocumented) Missing documentation for "WarningPanelClassKey". +// src/hooks/useQueryParamState.d.ts:2:1 - (ae-undocumented) Missing documentation for "useQueryParamState". +// src/hooks/useSupportConfig.d.ts:1:1 - (ae-undocumented) Missing documentation for "SupportItemLink". +// src/hooks/useSupportConfig.d.ts:5:1 - (ae-undocumented) Missing documentation for "SupportItem". +// src/hooks/useSupportConfig.d.ts:10:1 - (ae-undocumented) Missing documentation for "SupportConfig". +// src/hooks/useSupportConfig.d.ts:14:1 - (ae-undocumented) Missing documentation for "useSupportConfig". +// src/icons/icons.d.ts:27:1 - (ae-undocumented) Missing documentation for "CatalogIcon". +// src/icons/icons.d.ts:29:1 - (ae-undocumented) Missing documentation for "ChatIcon". +// src/icons/icons.d.ts:31:1 - (ae-undocumented) Missing documentation for "DashboardIcon". +// src/icons/icons.d.ts:33:1 - (ae-undocumented) Missing documentation for "DocsIcon". +// src/icons/icons.d.ts:35:1 - (ae-undocumented) Missing documentation for "EmailIcon". +// src/icons/icons.d.ts:37:1 - (ae-undocumented) Missing documentation for "GitHubIcon". +// src/icons/icons.d.ts:39:1 - (ae-undocumented) Missing documentation for "GroupIcon". +// src/icons/icons.d.ts:41:1 - (ae-undocumented) Missing documentation for "HelpIcon". +// src/icons/icons.d.ts:43:1 - (ae-undocumented) Missing documentation for "UserIcon". +// src/icons/icons.d.ts:45:1 - (ae-undocumented) Missing documentation for "WarningIcon". +// src/icons/icons.d.ts:47:1 - (ae-undocumented) Missing documentation for "StarIcon". +// src/icons/icons.d.ts:49:1 - (ae-undocumented) Missing documentation for "UnstarredIcon". +// src/layout/BottomLink/BottomLink.d.ts:3:1 - (ae-undocumented) Missing documentation for "BottomLinkClassKey". +// src/layout/BottomLink/BottomLink.d.ts:5:1 - (ae-undocumented) Missing documentation for "BottomLinkProps". +// src/layout/Breadcrumbs/Breadcrumbs.d.ts:5:1 - (ae-undocumented) Missing documentation for "BreadcrumbsClickableTextClassKey". +// src/layout/Breadcrumbs/Breadcrumbs.d.ts:7:1 - (ae-undocumented) Missing documentation for "BreadcrumbsStyledBoxClassKey". +// src/layout/Breadcrumbs/Breadcrumbs.d.ts:9:1 - (ae-undocumented) Missing documentation for "BreadcrumbsCurrentPageClassKey". +// src/layout/Content/Content.d.ts:3:1 - (ae-undocumented) Missing documentation for "BackstageContentClassKey". +// src/layout/ContentHeader/ContentHeader.d.ts:6:1 - (ae-undocumented) Missing documentation for "ContentHeaderClassKey". +// src/layout/ErrorBoundary/ErrorBoundary.d.ts:7:1 - (ae-undocumented) Missing documentation for "ErrorBoundaryProps". // src/layout/ErrorBoundary/ErrorBoundary.d.ts:8:5 - (ae-forgotten-export) The symbol "SlackChannel" needs to be exported by the entry point index.d.ts +// src/layout/ErrorBoundary/ErrorBoundary.d.ts:16:22 - (ae-undocumented) Missing documentation for "ErrorBoundary". +// src/layout/ErrorPage/ErrorPage.d.ts:10:1 - (ae-undocumented) Missing documentation for "ErrorPageClassKey". +// src/layout/ErrorPage/MicDrop.d.ts:2:1 - (ae-undocumented) Missing documentation for "MicDropClassKey". +// src/layout/ErrorPage/StackDetails.d.ts:6:1 - (ae-undocumented) Missing documentation for "StackDetailsClassKey". +// src/layout/Header/Header.d.ts:3:1 - (ae-undocumented) Missing documentation for "HeaderClassKey". +// src/layout/HeaderActionMenu/HeaderActionMenu.d.ts:6:1 - (ae-undocumented) Missing documentation for "HeaderActionMenuItem". +// src/layout/HeaderActionMenu/HeaderActionMenu.d.ts:16:1 - (ae-undocumented) Missing documentation for "HeaderActionMenuProps". +// src/layout/HeaderActionMenu/HeaderActionMenu.d.ts:22:1 - (ae-undocumented) Missing documentation for "HeaderActionMenu". +// src/layout/HeaderLabel/HeaderLabel.d.ts:3:1 - (ae-undocumented) Missing documentation for "HeaderLabelClassKey". +// src/layout/HeaderTabs/HeaderTabs.d.ts:4:1 - (ae-undocumented) Missing documentation for "HeaderTabsClassKey". +// src/layout/HeaderTabs/HeaderTabs.d.ts:5:1 - (ae-undocumented) Missing documentation for "Tab". +// src/layout/InfoCard/InfoCard.d.ts:6:1 - (ae-undocumented) Missing documentation for "InfoCardClassKey". +// src/layout/InfoCard/InfoCard.d.ts:8:1 - (ae-undocumented) Missing documentation for "CardActionsTopRightClassKey". +// src/layout/InfoCard/InfoCard.d.ts:10:1 - (ae-undocumented) Missing documentation for "InfoCardVariants". +// src/layout/ItemCard/ItemCardGrid.d.ts:4:1 - (ae-undocumented) Missing documentation for "ItemCardGridClassKey". +// src/layout/ItemCard/ItemCardGrid.d.ts:7:1 - (ae-undocumented) Missing documentation for "ItemCardGridProps". +// src/layout/ItemCard/ItemCardHeader.d.ts:4:1 - (ae-undocumented) Missing documentation for "ItemCardHeaderClassKey". +// src/layout/ItemCard/ItemCardHeader.d.ts:7:1 - (ae-undocumented) Missing documentation for "ItemCardHeaderProps". +// src/layout/Page/Page.d.ts:2:1 - (ae-undocumented) Missing documentation for "PageClassKey". +// src/layout/Page/Page.d.ts:7:1 - (ae-undocumented) Missing documentation for "Page". +// src/layout/Page/PageWithHeader.d.ts:6:1 - (ae-undocumented) Missing documentation for "PageWithHeader". +// src/layout/Sidebar/Bar.d.ts:4:1 - (ae-undocumented) Missing documentation for "SidebarClassKey". +// src/layout/Sidebar/Bar.d.ts:6:1 - (ae-undocumented) Missing documentation for "SidebarProps". +// src/layout/Sidebar/Items.d.ts:6:1 - (ae-undocumented) Missing documentation for "SidebarItemClassKey". +// src/layout/Sidebar/Items.d.ts:53:1 - (ae-undocumented) Missing documentation for "SidebarSearchField". +// src/layout/Sidebar/Items.d.ts:54:1 - (ae-undocumented) Missing documentation for "SidebarSpaceClassKey". +// src/layout/Sidebar/Items.d.ts:55:22 - (ae-undocumented) Missing documentation for "SidebarSpace". +// src/layout/Sidebar/Items.d.ts:56:1 - (ae-undocumented) Missing documentation for "SidebarSpacerClassKey". +// src/layout/Sidebar/Items.d.ts:57:22 - (ae-undocumented) Missing documentation for "SidebarSpacer". +// src/layout/Sidebar/Items.d.ts:58:1 - (ae-undocumented) Missing documentation for "SidebarDividerClassKey". +// src/layout/Sidebar/Items.d.ts:59:22 - (ae-undocumented) Missing documentation for "SidebarDivider". +// src/layout/Sidebar/Items.d.ts:60:22 - (ae-undocumented) Missing documentation for "SidebarScrollWrapper". +// src/layout/Sidebar/Page.d.ts:2:1 - (ae-undocumented) Missing documentation for "SidebarPageClassKey". +// src/layout/Sidebar/Page.d.ts:11:1 - (ae-undocumented) Missing documentation for "SidebarPage". +// src/layout/Sidebar/SidebarSubmenu.d.ts:3:1 - (ae-undocumented) Missing documentation for "SidebarSubmenuClassKey". +// src/layout/Sidebar/SidebarSubmenuItem.d.ts:4:1 - (ae-undocumented) Missing documentation for "SidebarSubmenuItemClassKey". +// src/layout/Sidebar/config.d.ts:3:1 - (ae-undocumented) Missing documentation for "SidebarOptions". +// src/layout/Sidebar/config.d.ts:8:1 - (ae-undocumented) Missing documentation for "SubmenuOptions". +// src/layout/Sidebar/config.d.ts:12:22 - (ae-undocumented) Missing documentation for "sidebarConfig". +// src/layout/Sidebar/config.d.ts:52:22 - (ae-undocumented) Missing documentation for "SIDEBAR_INTRO_LOCAL_STORAGE". +// src/layout/SignInPage/SignInPage.d.ts:17:1 - (ae-undocumented) Missing documentation for "SignInPage". +// src/layout/SignInPage/customProvider.d.ts:3:1 - (ae-undocumented) Missing documentation for "CustomProviderClassKey". +// src/layout/SignInPage/styles.d.ts:2:1 - (ae-undocumented) Missing documentation for "SignInPageClassKey". +// src/layout/SignInPage/types.d.ts:3:1 - (ae-undocumented) Missing documentation for "SignInProviderConfig". +// src/layout/SignInPage/types.d.ts:10:1 - (ae-undocumented) Missing documentation for "IdentityProviders". +// src/layout/TabbedCard/TabbedCard.d.ts:5:1 - (ae-undocumented) Missing documentation for "TabbedCardClassKey". +// src/layout/TabbedCard/TabbedCard.d.ts:7:1 - (ae-undocumented) Missing documentation for "BoldHeaderClassKey". +// src/layout/TabbedCard/TabbedCard.d.ts:18:1 - (ae-undocumented) Missing documentation for "TabbedCard". +// src/layout/TabbedCard/TabbedCard.d.ts:20:1 - (ae-undocumented) Missing documentation for "CardTabClassKey". +// src/overridableComponents.d.ts:83:1 - (ae-undocumented) Missing documentation for "BackstageOverrides". ``` diff --git a/packages/core-components/src/components/CodeSnippet/CodeSnippet.stories.tsx b/packages/core-components/src/components/CodeSnippet/CodeSnippet.stories.tsx index a266c8c6cb..c4ed5ae072 100644 --- a/packages/core-components/src/components/CodeSnippet/CodeSnippet.stories.tsx +++ b/packages/core-components/src/components/CodeSnippet/CodeSnippet.stories.tsx @@ -52,7 +52,7 @@ greet(world) export const Default = () => ( - + ); diff --git a/packages/core-components/src/components/EmptyState/MissingAnnotationEmptyState.tsx b/packages/core-components/src/components/EmptyState/MissingAnnotationEmptyState.tsx index e185dff8a6..31168b4ac7 100644 --- a/packages/core-components/src/components/EmptyState/MissingAnnotationEmptyState.tsx +++ b/packages/core-components/src/components/EmptyState/MissingAnnotationEmptyState.tsx @@ -49,12 +49,6 @@ type Props = { readMoreUrl?: string; }; -/** - * @public - * @deprecated This component is deprecated, please use {@link @backstage/plugin-catalog-react#MissingAnnotationEmptyStateClassKey} instead - */ -export type MissingAnnotationEmptyStateClassKey = 'code'; - const useStyles = makeStyles( theme => ({ code: { diff --git a/packages/core-components/src/components/EmptyState/index.ts b/packages/core-components/src/components/EmptyState/index.ts index 2696fba850..70e113833a 100644 --- a/packages/core-components/src/components/EmptyState/index.ts +++ b/packages/core-components/src/components/EmptyState/index.ts @@ -18,4 +18,3 @@ export { EmptyState } from './EmptyState'; export type { EmptyStateClassKey } from './EmptyState'; export type { EmptyStateImageClassKey } from './EmptyStateImage'; export { MissingAnnotationEmptyState } from './MissingAnnotationEmptyState'; -export type { MissingAnnotationEmptyStateClassKey } from './MissingAnnotationEmptyState'; diff --git a/packages/core-components/src/components/FavoriteToggle/FavoriteToggle.stories.tsx b/packages/core-components/src/components/FavoriteToggle/FavoriteToggle.stories.tsx new file mode 100644 index 0000000000..e531e9b254 --- /dev/null +++ b/packages/core-components/src/components/FavoriteToggle/FavoriteToggle.stories.tsx @@ -0,0 +1,72 @@ +/* + * 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, { ComponentType, PropsWithChildren } from 'react'; +import { FavoriteToggle } from './FavoriteToggle'; +import { + UnifiedThemeProvider, + createBaseThemeOptions, + createUnifiedTheme, + palettes, +} from '@backstage/theme'; +import { wrapInTestApp } from '@backstage/test-utils'; + +export default { + title: 'Core/FavoriteToggle', + component: FavoriteToggle, + decorators: [ + (Story: ComponentType>) => wrapInTestApp(), + ], +}; + +export const Default = () => { + const [isFavorite, setFavorite] = React.useState(false); + return ( + + ); +}; + +const theme = createUnifiedTheme({ + ...createBaseThemeOptions({ + palette: palettes.dark, + }), + components: { + BackstageFavoriteToggleIcon: { + styleOverrides: { + icon: () => ({ color: 'aqua' }), + iconBorder: () => ({ color: 'white' }), + }, + }, + }, +}); + +export const WithThemeOverride = () => { + const [isFavorite, setFavorite] = React.useState(false); + return ( + + + + ); +}; diff --git a/packages/core-components/src/components/FavoriteToggle/FavoriteToggle.test.tsx b/packages/core-components/src/components/FavoriteToggle/FavoriteToggle.test.tsx new file mode 100644 index 0000000000..66b420b467 --- /dev/null +++ b/packages/core-components/src/components/FavoriteToggle/FavoriteToggle.test.tsx @@ -0,0 +1,57 @@ +/* + * 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 { renderInTestApp } from '@backstage/test-utils'; +import { FavoriteToggle } from './FavoriteToggle'; +import React from 'react'; +import userEvent from '@testing-library/user-event'; + +describe('', () => { + const onToggle = jest.fn(); + + const props = { + title: 'Favorite this thing', + id: 'some-thing-favorite', + onToggle, + isFavorite: true, + }; + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('renders with valid props', async () => { + const { getByRole } = await renderInTestApp(); + + expect(getByRole('button', { name: props.title })).toBeInTheDocument(); + }); + + it('should return inverted value on toggle', async () => { + const { getByRole } = await renderInTestApp(); + + await userEvent.click(getByRole('button', { name: props.title })); + expect(onToggle).toHaveBeenCalledWith(!props.isFavorite); + }); + + it('should show accessible tooltip', async () => { + const { findByRole, getByRole } = await renderInTestApp( + , + ); + + await userEvent.hover(getByRole('button', { name: props.title })); + + expect(await findByRole('tooltip')).toHaveTextContent(props.title); + }); +}); diff --git a/packages/core-components/src/components/FavoriteToggle/FavoriteToggle.tsx b/packages/core-components/src/components/FavoriteToggle/FavoriteToggle.tsx new file mode 100644 index 0000000000..ba7b4edb99 --- /dev/null +++ b/packages/core-components/src/components/FavoriteToggle/FavoriteToggle.tsx @@ -0,0 +1,101 @@ +/* + * 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, { ComponentProps } from 'react'; +import IconButton from '@material-ui/core/IconButton'; +import Tooltip from '@material-ui/core/Tooltip'; +import Typography from '@material-ui/core/Typography'; +import { Theme, makeStyles } from '@material-ui/core/styles'; +import { StarIcon, UnstarredIcon } from '../../icons'; + +const useStyles = makeStyles( + () => ({ + icon: { + color: '#f3ba37', + cursor: 'pointer', + display: 'inline-flex', + }, + iconBorder: { + color: 'inherit', + cursor: 'pointer', + display: 'inline-flex', + }, + }), + { name: 'BackstageFavoriteToggleIcon' }, +); + +/** + * @public + */ +export type FavoriteToggleIconClassKey = 'icon' | 'iconBorder'; + +/** + * Icon used in FavoriteToggle component. + * + * Can be used independently, useful when used as {@link @material-table/core#MaterialTableProps.actions} in {@link @material-table/core#MaterialTable} + * + * @public + */ +export function FavoriteToggleIcon(props: { isFavorite: boolean }) { + const { isFavorite } = props; + const classes = useStyles(); + + return ( + + {isFavorite ? : } + + ); +} + +/** + * Toggle encapsulating logic for marking something as favorite, + * primarily used in various instances of entity lists and cards but can be used elsewhere. + * + * This component can only be used in as a controlled toggle and does not keep internal state. + * + * @public + */ +export function FavoriteToggle( + props: ComponentProps & { + id: string; + title: string; + isFavorite: boolean; + onToggle: (value: boolean) => void; + }, +) { + const { + id, + title, + isFavorite: value, + onToggle: onChange, + ...iconButtonProps + } = props; + return ( + + onChange(!value)} + color="inherit" + {...iconButtonProps} + > + + + + ); +} diff --git a/packages/core-components/src/components/FavoriteToggle/index.ts b/packages/core-components/src/components/FavoriteToggle/index.ts new file mode 100644 index 0000000000..460b162bdf --- /dev/null +++ b/packages/core-components/src/components/FavoriteToggle/index.ts @@ -0,0 +1,18 @@ +/* + * 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. + */ + +export { FavoriteToggle, FavoriteToggleIcon } from './FavoriteToggle'; +export type { FavoriteToggleIconClassKey } from './FavoriteToggle'; diff --git a/packages/core-components/src/components/Link/Link.test.tsx b/packages/core-components/src/components/Link/Link.test.tsx index 42668b54c9..fe616299c3 100644 --- a/packages/core-components/src/components/Link/Link.test.tsx +++ b/packages/core-components/src/components/Link/Link.test.tsx @@ -45,6 +45,30 @@ describe('', () => { }); }); + it('does not render external link icon if externalLinkIcon prop is not passed', async () => { + const { container } = await renderInTestApp( + External Link, + ); + const externalLink = screen.getByRole('link', { + name: 'External Link , Opens in a new window', + }); + const externalLinkIcon = container.querySelector('svg'); + expect(externalLink).not.toContainElement(externalLinkIcon); + }); + + it('renders external link icon if externalLinkIcon prop is passed', async () => { + const { container } = await renderInTestApp( + + External Link + , + ); + const externalLink = screen.getByRole('link', { + name: 'External Link , Opens in a new window', + }); + const externalLinkIcon = container.querySelector('svg'); + expect(externalLink).toContainElement(externalLinkIcon); + }); + it('captures click using analytics api', async () => { const linkText = 'Navigate!'; const analyticsApi = new MockAnalyticsApi(); diff --git a/packages/core-components/src/components/Link/Link.tsx b/packages/core-components/src/components/Link/Link.tsx index e957390da8..0008a9ff2c 100644 --- a/packages/core-components/src/components/Link/Link.tsx +++ b/packages/core-components/src/components/Link/Link.tsx @@ -29,14 +29,19 @@ import { LinkProps as RouterLinkProps, Route, } from 'react-router-dom'; +import OpenInNew from '@material-ui/icons/OpenInNew'; +import { useApp } from '@backstage/core-plugin-api'; export function isReactRouterBeta(): boolean { const [obj] = createRoutesFromChildren(} />); return !obj.index; } +/** @public */ +export type LinkClassKey = 'visuallyHidden' | 'externalLink'; + const useStyles = makeStyles( - { + theme => ({ visuallyHidden: { clip: 'rect(0 0 0 0)', clipPath: 'inset(50%)', @@ -50,10 +55,21 @@ const useStyles = makeStyles( externalLink: { position: 'relative', }, - }, + externalLinkIcon: { + verticalAlign: 'bottom', + marginLeft: theme.spacing(0.5), + }, + }), { name: 'Link' }, ); +const ExternalLinkIcon = () => { + const app = useApp(); + const Icon = app.getSystemIcon('externalLink') || OpenInNew; + const classes = useStyles(); + return ; +}; + export const isExternalUri = (uri: string) => /^([a-z+.-]+):/.test(uri); // See https://github.com/facebook/react/blob/f0cf832e1d0c8544c36aa8b310960885a11a847c/packages/react-dom-bindings/src/shared/sanitizeURL.js @@ -87,6 +103,7 @@ export type LinkProps = Omit & to: string; component?: ElementType; noTrack?: boolean; + externalLinkIcon?: boolean; }; /** @@ -158,7 +175,7 @@ const getNodeText = (node: React.ReactNode): string => { * - Captures Link clicks as analytics events. */ export const Link = React.forwardRef( - ({ onClick, noTrack, ...props }, ref) => { + ({ onClick, noTrack, externalLinkIcon, ...props }, ref) => { const classes = useStyles(); const analytics = useAnalytics(); @@ -198,6 +215,7 @@ export const Link = React.forwardRef( className={classnames(classes.externalLink, props.className)} > {props.children} + {externalLinkIcon && } , Opens in a new window diff --git a/packages/core-components/src/components/Link/index.ts b/packages/core-components/src/components/Link/index.ts index 2160508451..cfae332b17 100644 --- a/packages/core-components/src/components/Link/index.ts +++ b/packages/core-components/src/components/Link/index.ts @@ -15,4 +15,4 @@ */ export { Link } from './Link'; -export type { LinkProps } from './Link'; +export type { LinkProps, LinkClassKey } from './Link'; diff --git a/packages/core-components/src/components/SupportButton/SupportButton.tsx b/packages/core-components/src/components/SupportButton/SupportButton.tsx index 8626353dd1..9e51e23119 100644 --- a/packages/core-components/src/components/SupportButton/SupportButton.tsx +++ b/packages/core-components/src/components/SupportButton/SupportButton.tsx @@ -67,7 +67,7 @@ const SupportLink = ({ link }: { link: SupportItemLink }) => ( const SupportListItem = ({ item }: { item: SupportItem }) => { return ( - + @@ -161,6 +161,7 @@ export function SupportButton(props: SupportButtonProps) { )} {React.Children.map(children, (child, i) => ( ), - Check: forwardRef((props, ref) => ), - Clear: forwardRef((props, ref) => ), - Delete: forwardRef((props, ref) => ), - DetailPanel: forwardRef((props, ref) => ( + Add: forwardRef((props, ref) => ( + + )), + Check: forwardRef((props, ref) => ( + + )), + Clear: forwardRef((props, ref) => ( + + )), + Delete: forwardRef((props, ref) => ( + + )), + DetailPanel: forwardRef((props, ref) => ( )), - Edit: forwardRef((props, ref) => ), - Export: forwardRef((props, ref) => ), - Filter: forwardRef((props, ref) => ), - FirstPage: forwardRef((props, ref) => ), - LastPage: forwardRef((props, ref) => ), - NextPage: forwardRef((props, ref) => ), - PreviousPage: forwardRef((props, ref) => ( + Edit: forwardRef((props, ref) => ( + + )), + Export: forwardRef((props, ref) => ( + + )), + Filter: forwardRef((props, ref) => ( + + )), + FirstPage: forwardRef((props, ref) => ( + + )), + LastPage: forwardRef((props, ref) => ( + + )), + NextPage: forwardRef((props, ref) => ( + + )), + PreviousPage: forwardRef((props, ref) => ( )), - ResetSearch: forwardRef((props, ref) => ), - Search: forwardRef((props, ref) => ), - SortArrow: forwardRef((props, ref) => ), - ThirdStateCheck: forwardRef((props, ref) => ), - ViewColumn: forwardRef((props, ref) => ), + ResetSearch: forwardRef((props, ref) => ( + + )), + Search: forwardRef((props, ref) => ( + + )), + SortArrow: forwardRef((props, ref) => ( + + )), + ThirdStateCheck: forwardRef((props, ref) => ( + + )), + ViewColumn: forwardRef((props, ref) => ( + + )), }; // TODO: Material table might already have such a function internally that we can use? @@ -320,6 +350,7 @@ export function Table(props: TableProps) { onStateChange, components, isLoading: loading, + style, ...restProps } = props; const tableClasses = useTableStyles(); @@ -453,7 +484,7 @@ export function Table(props: TableProps) { } data={tableData} - style={{ width: '100%' }} + style={{ width: '100%', ...style }} localization={{ toolbar: { searchPlaceholder: 'Filter', searchTooltip: 'Filter' }, ...localization, diff --git a/packages/core-components/src/components/index.ts b/packages/core-components/src/components/index.ts index a58208fabb..828df3ec03 100644 --- a/packages/core-components/src/components/index.ts +++ b/packages/core-components/src/components/index.ts @@ -25,6 +25,7 @@ export * from './DependencyGraph'; export * from './DismissableBanner'; export * from './EmptyState'; export * from './ErrorPanel'; +export * from './FavoriteToggle'; export * from './ResponseErrorPanel'; export * from './FeatureDiscovery'; export * from './HeaderIconLinkRow'; @@ -47,3 +48,4 @@ export * from './TabbedLayout'; export * from './Table'; export * from './TrendLine'; export * from './WarningPanel'; +export * from './FavoriteToggle'; diff --git a/packages/core-components/src/hooks/useSupportConfig.ts b/packages/core-components/src/hooks/useSupportConfig.ts index 2b969d8b4d..d388728956 100644 --- a/packages/core-components/src/hooks/useSupportConfig.ts +++ b/packages/core-components/src/hooks/useSupportConfig.ts @@ -72,7 +72,7 @@ export function useSupportConfig(): SupportConfig { links: (itemConf.getOptionalConfigArray('links') ?? []).flatMap( linkConf => ({ url: linkConf.getString('url'), - title: linkConf.getString('title'), + title: linkConf.getOptionalString('title') ?? '', }), ), })), diff --git a/packages/core-components/src/icons/icons.tsx b/packages/core-components/src/icons/icons.tsx index ca3b6fa76a..bd1bf9e86e 100644 --- a/packages/core-components/src/icons/icons.tsx +++ b/packages/core-components/src/icons/icons.tsx @@ -95,3 +95,11 @@ export function UserIcon(props: IconComponentProps) { export function WarningIcon(props: IconComponentProps) { return ; } +/** @public */ +export function StarIcon(props: IconComponentProps) { + return ; +} +/** @public */ +export function UnstarredIcon(props: IconComponentProps) { + return ; +} diff --git a/packages/core-components/src/layout/ContentHeader/ContentHeader.test.tsx b/packages/core-components/src/layout/ContentHeader/ContentHeader.test.tsx index 37059766a8..5ae2efb806 100644 --- a/packages/core-components/src/layout/ContentHeader/ContentHeader.test.tsx +++ b/packages/core-components/src/layout/ContentHeader/ContentHeader.test.tsx @@ -30,6 +30,13 @@ describe('', () => { rendered.getByText('Title'); }); + it('should render without title', async () => { + const rendered = await renderInTestApp( + content, + ); + rendered.getByText('content'); + }); + it('should render with titleComponent', async () => { const title = 'Custom title'; const titleComponent =

{title}

; diff --git a/packages/core-components/src/layout/ContentHeader/ContentHeader.tsx b/packages/core-components/src/layout/ContentHeader/ContentHeader.tsx index 381919a170..e2a6e70620 100644 --- a/packages/core-components/src/layout/ContentHeader/ContentHeader.tsx +++ b/packages/core-components/src/layout/ContentHeader/ContentHeader.tsx @@ -73,10 +73,7 @@ type ContentHeaderTitleProps = { className?: string; }; -const ContentHeaderTitle = ({ - title = 'Unknown page', - className, -}: ContentHeaderTitleProps) => ( +const ContentHeaderTitle = ({ title, className }: ContentHeaderTitleProps) => ( ({ title: { diff --git a/packages/core-components/src/layout/ErrorPage/index.ts b/packages/core-components/src/layout/ErrorPage/index.ts index 429b467444..c89692ceb8 100644 --- a/packages/core-components/src/layout/ErrorPage/index.ts +++ b/packages/core-components/src/layout/ErrorPage/index.ts @@ -17,3 +17,4 @@ export { ErrorPage } from './ErrorPage'; export type { ErrorPageClassKey } from './ErrorPage'; export type { MicDropClassKey } from './MicDrop'; +export type { StackDetailsClassKey } from './StackDetails'; diff --git a/packages/core-components/src/layout/Sidebar/SidebarSubmenu.tsx b/packages/core-components/src/layout/Sidebar/SidebarSubmenu.tsx index e05cc90fa9..4c8ca2e0bf 100644 --- a/packages/core-components/src/layout/Sidebar/SidebarSubmenu.tsx +++ b/packages/core-components/src/layout/Sidebar/SidebarSubmenu.tsx @@ -27,6 +27,9 @@ import { } from './config'; import { useSidebarOpenState } from './SidebarOpenStateContext'; +/** @public */ +export type SidebarSubmenuClassKey = 'root' | 'drawer' | 'drawerOpen' | 'title'; + const useStyles = makeStyles< Theme, { submenuConfig: SubmenuConfig; left: number } @@ -43,11 +46,12 @@ const useStyles = makeStyles< flexFlow: 'column nowrap', alignItems: 'flex-start', position: 'fixed', + opacity: 0, [theme.breakpoints.up('sm')]: { marginLeft: props.left, - transition: theme.transitions.create('margin-left', { + transition: theme.transitions.create(['margin-left', 'opacity'], { easing: theme.transitions.easing.sharp, - duration: theme.transitions.duration.shortest, + duration: props.submenuConfig.defaultOpenDelayMs, }), }, top: 0, @@ -68,6 +72,8 @@ const useStyles = makeStyles< }, }), drawerOpen: props => ({ + marginLeft: props.left, + opacity: 1, width: props.submenuConfig.drawerWidthOpen, [theme.breakpoints.down('xs')]: { width: '100%', diff --git a/packages/core-components/src/layout/Sidebar/SidebarSubmenuItem.tsx b/packages/core-components/src/layout/Sidebar/SidebarSubmenuItem.tsx index 19834268f9..0ed8aedcaf 100644 --- a/packages/core-components/src/layout/Sidebar/SidebarSubmenuItem.tsx +++ b/packages/core-components/src/layout/Sidebar/SidebarSubmenuItem.tsx @@ -29,6 +29,18 @@ import { isLocationMatch } from './utils'; import Box from '@material-ui/core/Box'; import Button from '@material-ui/core/Button'; +/** @public */ +export type SidebarSubmenuItemClassKey = + | 'item' + | 'itemContainer' + | 'selected' + | 'label' + | 'subtitle' + | 'dropdownArrow' + | 'dropdown' + | 'dropdownItem' + | 'textContent'; + const useStyles = makeStyles( theme => ({ item: { diff --git a/packages/core-components/src/layout/Sidebar/index.ts b/packages/core-components/src/layout/Sidebar/index.ts index b614d50feb..b3d88fd031 100644 --- a/packages/core-components/src/layout/Sidebar/index.ts +++ b/packages/core-components/src/layout/Sidebar/index.ts @@ -21,10 +21,14 @@ export { SidebarGroup } from './SidebarGroup'; export type { SidebarGroupProps } from './SidebarGroup'; export { SidebarSubmenuItem } from './SidebarSubmenuItem'; export { SidebarSubmenu } from './SidebarSubmenu'; -export type { SidebarSubmenuProps } from './SidebarSubmenu'; +export type { + SidebarSubmenuProps, + SidebarSubmenuClassKey, +} from './SidebarSubmenu'; export type { SidebarSubmenuItemProps, SidebarSubmenuItemDropdownItem, + SidebarSubmenuItemClassKey, } from './SidebarSubmenuItem'; export type { SidebarClassKey, SidebarProps } from './Bar'; export { SidebarPage, useContent } from './Page'; diff --git a/packages/core-components/src/overridableComponents.ts b/packages/core-components/src/overridableComponents.ts index 85e9dc96a8..df6db52094 100644 --- a/packages/core-components/src/overridableComponents.ts +++ b/packages/core-components/src/overridableComponents.ts @@ -25,7 +25,6 @@ import { DismissableBannerClassKey, EmptyStateClassKey, EmptyStateImageClassKey, - MissingAnnotationEmptyStateClassKey, ErrorPanelClassKey, FeatureCalloutCircleClassKey, HeaderIconLinkRowClassKey, @@ -61,6 +60,8 @@ import { FiltersContainerClassKey, TableClassKey, WarningPanelClassKey, + LinkClassKey, + FavoriteToggleIconClassKey, } from './components'; import { @@ -90,6 +91,10 @@ import { TabbedCardClassKey, BoldHeaderClassKey, CardTabClassKey, + SidebarSubmenuClassKey, + SidebarSubmenuItemClassKey, + StackDetailsClassKey, + BreadcrumbsCurrentPageClassKey, } from './layout'; type BackstageComponentsNameToClassKey = { @@ -101,7 +106,6 @@ type BackstageComponentsNameToClassKey = { BackstageDismissableBanner: DismissableBannerClassKey; BackstageEmptyState: EmptyStateClassKey; BackstageEmptyStateImage: EmptyStateImageClassKey; - BackstageMissingAnnotationEmptyState: MissingAnnotationEmptyStateClassKey; BackstageErrorPanel: ErrorPanelClassKey; BackstageFeatureCalloutCircular: FeatureCalloutCircleClassKey; BackstageHeaderIconLinkRow: HeaderIconLinkRowClassKey; @@ -111,7 +115,7 @@ type BackstageComponentsNameToClassKey = { BackstageMarkdownContent: MarkdownContentClassKey; BackstageLoginRequestListItem: LoginRequestListItemClassKey; BackstageLogViewer: LogViewerClassKey; - OAuthRequestDialog: OAuthRequestDialogClassKey; + BackstageOAuthRequestDialog: OAuthRequestDialogClassKey; BackstageOverflowTooltip: OverflowTooltipClassKey; BackstageGauge: GaugeClassKey; BackstageGaugeCard: GaugeCardClassKey; @@ -140,10 +144,12 @@ type BackstageComponentsNameToClassKey = { BackstageBottomLink: BottomLinkClassKey; BackstageBreadcrumbsClickableText: BreadcrumbsClickableTextClassKey; BackstageBreadcrumbsStyledBox: BreadcrumbsStyledBoxClassKey; + BreadcrumbsCurrentPage: BreadcrumbsCurrentPageClassKey; BackstageContent: BackstageContentClassKey; BackstageContentHeader: ContentHeaderClassKey; BackstageErrorPage: ErrorPageClassKey; BackstageErrorPageMicDrop: MicDropClassKey; + BackstageErrorPageStackDetails: StackDetailsClassKey; BackstageHeader: HeaderClassKey; BackstageHeaderLabel: HeaderLabelClassKey; BackstageHeaderTabs: HeaderTabsClassKey; @@ -157,12 +163,16 @@ type BackstageComponentsNameToClassKey = { BackstageSidebarSpacer: SidebarSpacerClassKey; BackstageSidebarDivider: SidebarDividerClassKey; BackstageSidebarItem: SidebarItemClassKey; + BackstageSidebarSubmenu: SidebarSubmenuClassKey; + BackstageSidebarSubmenuItem: SidebarSubmenuItemClassKey; BackstageSidebarPage: SidebarPageClassKey; BackstageCustomProvider: CustomProviderClassKey; BackstageSignInPage: SignInPageClassKey; BackstageTabbedCard: TabbedCardClassKey; BackstageTabbedCardBoldHeader: BoldHeaderClassKey; BackstageCardTab: CardTabClassKey; + BackstageLink: LinkClassKey; + BackstageFavoriteToggleIcon: FavoriteToggleIconClassKey; }; /** @public */ diff --git a/packages/core-plugin-api/CHANGELOG.md b/packages/core-plugin-api/CHANGELOG.md index 9546a747ca..614feda711 100644 --- a/packages/core-plugin-api/CHANGELOG.md +++ b/packages/core-plugin-api/CHANGELOG.md @@ -1,5 +1,54 @@ # @backstage/core-plugin-api +## 1.10.0-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/version-bridge@1.0.10-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## 1.10.0-next.0 + +### Minor Changes + +- bfd4bec: **BREAKING PRODUCERS**: The `IconComponent` no longer accepts `fontSize="default"`. This has effectively been removed from Material-UI since its last two major versions, and has not worked properly for them in a long time. + + This change should not have an effect on neither users of MUI4 nor MUI5/6, since the updated interface should still let you send the respective `SvgIcon` types into interfaces where relevant (e.g. as app icons). + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.9 + +## 1.9.4 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/version-bridge@1.0.9 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## 1.9.4-next.0 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/version-bridge@1.0.9-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 1.9.3 ### Patch Changes diff --git a/packages/core-plugin-api/package.json b/packages/core-plugin-api/package.json index 34d626afd9..dc08e132c1 100644 --- a/packages/core-plugin-api/package.json +++ b/packages/core-plugin-api/package.json @@ -1,15 +1,31 @@ { "name": "@backstage/core-plugin-api", + "version": "1.10.0-next.1", "description": "Core API used by Backstage plugins", - "version": "1.9.3", + "backstage": { + "role": "web-library" + }, "publishConfig": { "access": "public" }, + "keywords": [ + "backstage" + ], + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "packages/core-plugin-api" + }, + "license": "Apache-2.0", + "sideEffects": false, "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -20,54 +36,47 @@ ] } }, - "backstage": { - "role": "web-library" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "packages/core-plugin-api" - }, - "keywords": [ - "backstage" + "files": [ + "dist" ], - "license": "Apache-2.0", - "main": "src/index.ts", - "types": "src/index.ts", - "sideEffects": false, "scripts": { "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean", - "start": "backstage-cli package start" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/config": "workspace:^", "@backstage/errors": "workspace:^", "@backstage/types": "workspace:^", "@backstage/version-bridge": "workspace:^", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "history": "^5.0.0" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/core-app-api": "workspace:^", "@backstage/test-utils": "workspace:^", "@testing-library/dom": "^10.0.0", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^15.0.0", - "@testing-library/user-event": "^14.0.0" + "@testing-library/react": "^16.0.0", + "@testing-library/user-event": "^14.0.0", + "@types/react": "^18.0.0", + "react": "^18.0.2", + "react-dom": "^18.0.2", + "react-router-dom": "^6.3.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } } diff --git a/packages/core-plugin-api/api-report-alpha.md b/packages/core-plugin-api/report-alpha.api.md similarity index 64% rename from packages/core-plugin-api/api-report-alpha.md rename to packages/core-plugin-api/report-alpha.api.md index c0f0d02535..260e0365a7 100644 --- a/packages/core-plugin-api/api-report-alpha.md +++ b/packages/core-plugin-api/report-alpha.api.md @@ -239,5 +239,36 @@ export const useTranslationRef: < t: TranslationFunction; }; +// Warnings were encountered during analysis: +// +// src/apis/definitions/AppLanguageApi.d.ts:4:1 - (ae-undocumented) Missing documentation for "AppLanguageApi". +// src/apis/definitions/AppLanguageApi.d.ts:19:22 - (ae-undocumented) Missing documentation for "appLanguageApiRef". +// src/apis/definitions/TranslationApi.d.ts:228:1 - (ae-undocumented) Missing documentation for "TranslationFunction". +// src/apis/definitions/TranslationApi.d.ts:231:5 - (ae-undocumented) Missing documentation for "__call". +// src/apis/definitions/TranslationApi.d.ts:234:1 - (ae-undocumented) Missing documentation for "TranslationSnapshot". +// src/apis/definitions/TranslationApi.d.ts:243:1 - (ae-undocumented) Missing documentation for "TranslationApi". +// src/apis/definitions/TranslationApi.d.ts:254:22 - (ae-undocumented) Missing documentation for "translationApiRef". +// src/translation/TranslationMessages.d.ts:17:5 - (ae-undocumented) Missing documentation for "$$type". +// src/translation/TranslationMessages.d.ts:33:5 - (ae-undocumented) Missing documentation for "ref". +// src/translation/TranslationMessages.d.ts:34:5 - (ae-undocumented) Missing documentation for "full". +// src/translation/TranslationMessages.d.ts:35:5 - (ae-undocumented) Missing documentation for "messages". +// src/translation/TranslationRef.d.ts:2:1 - (ae-undocumented) Missing documentation for "TranslationRef". +// src/translation/TranslationRef.d.ts:7:5 - (ae-undocumented) Missing documentation for "$$type". +// src/translation/TranslationRef.d.ts:8:5 - (ae-undocumented) Missing documentation for "id". +// src/translation/TranslationRef.d.ts:9:5 - (ae-undocumented) Missing documentation for "T". +// src/translation/TranslationRef.d.ts:30:1 - (ae-undocumented) Missing documentation for "TranslationRefOptions". +// src/translation/TranslationRef.d.ts:37:5 - (ae-undocumented) Missing documentation for "id". +// src/translation/TranslationRef.d.ts:38:5 - (ae-undocumented) Missing documentation for "messages". +// src/translation/TranslationRef.d.ts:39:5 - (ae-undocumented) Missing documentation for "translations". +// src/translation/TranslationRef.d.ts:42:1 - (ae-undocumented) Missing documentation for "createTranslationRef". +// src/translation/TranslationResource.d.ts:3:1 - (ae-undocumented) Missing documentation for "TranslationResource". +// src/translation/TranslationResource.d.ts:4:5 - (ae-undocumented) Missing documentation for "$$type". +// src/translation/TranslationResource.d.ts:5:5 - (ae-undocumented) Missing documentation for "id". +// src/translation/TranslationResource.d.ts:8:1 - (ae-undocumented) Missing documentation for "TranslationResourceOptions". +// src/translation/TranslationResource.d.ts:17:5 - (ae-undocumented) Missing documentation for "ref". +// src/translation/TranslationResource.d.ts:18:5 - (ae-undocumented) Missing documentation for "translations". +// src/translation/TranslationResource.d.ts:21:1 - (ae-undocumented) Missing documentation for "createTranslationResource". +// src/translation/useTranslationRef.d.ts:4:22 - (ae-undocumented) Missing documentation for "useTranslationRef". + // (No @packageDocumentation comment for this package) ``` diff --git a/packages/core-plugin-api/api-report.md b/packages/core-plugin-api/report.api.md similarity index 98% rename from packages/core-plugin-api/api-report.md rename to packages/core-plugin-api/report.api.md index 134b338c92..06333c1fb4 100644 --- a/packages/core-plugin-api/api-report.md +++ b/packages/core-plugin-api/report.api.md @@ -505,14 +505,9 @@ export const googleAuthApiRef: ApiRef< >; // @public -export type IconComponent = ComponentType< - | { - fontSize?: 'large' | 'small' | 'default' | 'inherit'; - } - | { - fontSize?: 'medium' | 'large' | 'small' | 'inherit'; - } ->; +export type IconComponent = ComponentType<{ + fontSize?: 'medium' | 'large' | 'small' | 'inherit'; +}>; // @public export type IdentityApi = { @@ -797,4 +792,8 @@ export function withApis( ): React_2.JSX.Element; displayName: string; }; + +// Warnings were encountered during analysis: +// +// src/routing/types.d.ts:13:1 - (ae-undocumented) Missing documentation for "AnyParams". ``` diff --git a/packages/core-plugin-api/src/icons/types.test.ts b/packages/core-plugin-api/src/icons/types.test.ts new file mode 100644 index 0000000000..fd01e176c9 --- /dev/null +++ b/packages/core-plugin-api/src/icons/types.test.ts @@ -0,0 +1,73 @@ +/* + * 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 * as React from 'react'; +import { type IconComponent } from './types'; + +// Emulate the MUI4 icon type +type Mui4Icon = (props: { + fontSize?: 'default' | 'inherit' | 'large' | 'medium' | 'small'; + otherProp?: string; +}) => JSX.Element; + +// Emulate the MUI5 icon type +type Mui5Icon = (props: { + fontSize?: 'inherit' | 'large' | 'medium' | 'small'; + otherProp?: string; +}) => JSX.Element; + +// Emulate the MUI6 icon type +interface OverridableComponent

{ + ( + props: { + /** + * The component used for the root node. + * Either a string to use a HTML element or a component. + */ + component: RootComponent; + } & { stuff: number }, + ): React.JSX.Element | null; + (props: P): React.JSX.Element | null; +} +type Mui6Icon = OverridableComponent<{ + fontSize?: 'inherit' | 'large' | 'medium' | 'small'; + otherProp?: string; +}>; + +type NotAnIcon1 = (props: { + fontSize?: 'foo'; + otherProp?: string; +}) => JSX.Element; + +type NotAnIcon2 = (props: { + fontSize?: number; + otherProp?: string; +}) => JSX.Element; + +describe('IconComponent', () => { + // eslint-disable-next-line jest/expect-expect + it('should be a component type', () => { + // @ts-ignore + let icon: IconComponent; + icon = {} as Mui4Icon; + icon = {} as Mui5Icon; + icon = {} as Mui6Icon; + // @ts-expect-error + icon = {} as NotAnIcon1; + // @ts-expect-error + icon = {} as NotAnIcon2; + }); +}); diff --git a/packages/core-plugin-api/src/icons/types.ts b/packages/core-plugin-api/src/icons/types.ts index 4d54629de2..2b00e1456f 100644 --- a/packages/core-plugin-api/src/icons/types.ts +++ b/packages/core-plugin-api/src/icons/types.ts @@ -22,7 +22,7 @@ import { ComponentType } from 'react'; * * @remarks * - * The type is based on SvgIcon from Material UI, but both do not what the plugin-api + * The type is based on SvgIcon from Material UI, but we do not want the plugin-api * package to have a dependency on Material UI, nor do we want the props to be as broad * as the SvgIconProps interface. * @@ -32,14 +32,6 @@ import { ComponentType } from 'react'; * * @public */ - -export type IconComponent = ComponentType< - /* Material UI v4 */ - | { - fontSize?: 'large' | 'small' | 'default' | 'inherit'; - } - /* Material UI v5: https://mui.com/material-ui/migration/v5-component-changes/#icon */ - | { - fontSize?: 'medium' | 'large' | 'small' | 'inherit'; - } ->; +export type IconComponent = ComponentType<{ + fontSize?: 'medium' | 'large' | 'small' | 'inherit'; +}>; diff --git a/packages/create-app/CHANGELOG.md b/packages/create-app/CHANGELOG.md index 1ab0f13fd1..8d55ec220c 100644 --- a/packages/create-app/CHANGELOG.md +++ b/packages/create-app/CHANGELOG.md @@ -1,5 +1,46 @@ # @backstage/create-app +## 0.5.21-next.1 + +### Patch Changes + +- Bumped create-app version. +- Updated dependencies + - @backstage/cli-common@0.1.14 + +## 0.5.21-next.0 + +### Patch Changes + +- a7674d6: Fixed lack of `.yarnrc.yml` in the template. +- Updated dependencies + - @backstage/cli-common@0.1.14 + +## 0.5.19 + +### Patch Changes + +- d2d2313: Add `config.d.ts` files to the list of included file in `tsconfig.json`. + + This allows ESLint to detect issues or deprecations in those files. + +- 4975e63: Yarn 4 is now the default for `create-app`. Also updated `yarn dev` script to use `yarn workspaces foreach` and removed unused Lerna and Concurrently dependencies. +- 4735881: Bumped create-app version. +- 97422b0: Update templates to not refer to backend-common +- 019d9ad: Minor dockerfile syntax update +- e03acd8: Updated Dockerfile base image to `node:20-bookworm-slim` from `node:18-bookworm-slim` +- bf370c2: Remove references to the `@backstage/backend-tasks` in versions of the `create-app` package, as it has been deprecated. +- Updated dependencies + - @backstage/cli-common@0.1.14 + +## 0.5.19-next.2 + +### Patch Changes + +- Bumped create-app version. +- Updated dependencies + - @backstage/cli-common@0.1.14 + ## 0.5.19-next.1 ### Patch Changes diff --git a/packages/create-app/package.json b/packages/create-app/package.json index 0fad58446e..2d22249012 100644 --- a/packages/create-app/package.json +++ b/packages/create-app/package.json @@ -1,36 +1,46 @@ { "name": "@backstage/create-app", + "version": "0.5.21-next.1", "description": "A CLI that helps you create your own Backstage app", - "version": "0.5.19-next.1", - "publishConfig": { - "access": "public" - }, "backstage": { "role": "cli" }, + "publishConfig": { + "access": "public" + }, + "keywords": [ + "backstage" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "packages/create-app" }, - "keywords": [ - "backstage" - ], "license": "Apache-2.0", "main": "dist/index.cjs.js", "bin": { "backstage-create-app": "bin/backstage-create-app" }, + "files": [ + "bin", + "dist", + "templates" + ], "scripts": { + "add-lock-seed": "node scripts/add-lock-seed.js", "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", "prepack": "node scripts/prepack.js", "postpack": "node scripts/postpack.js", "start": "yarn nodemon --", - "add-lock-seed": "node scripts/add-lock-seed.js" + "test": "backstage-cli package test" + }, + "nodemonConfig": { + "exec": "bin/backstage-create-app", + "ext": "ts", + "watch": "./src" }, "dependencies": { "@backstage/cli-common": "workspace:^", @@ -53,15 +63,5 @@ "@types/recursive-readdir": "^2.2.0", "msw": "^1.0.0", "nodemon": "^3.0.1" - }, - "nodemonConfig": { - "watch": "./src", - "exec": "bin/backstage-create-app", - "ext": "ts" - }, - "files": [ - "bin", - "dist", - "templates" - ] + } } diff --git a/packages/create-app/src/lib/tasks.test.ts b/packages/create-app/src/lib/tasks.test.ts index ae87cd4ed6..41c20854be 100644 --- a/packages/create-app/src/lib/tasks.test.ts +++ b/packages/create-app/src/lib/tasks.test.ts @@ -209,45 +209,19 @@ describe('tasks', () => { await expect(buildAppTask(appDir)).resolves.not.toThrow(); expect(mockChdir).toHaveBeenCalledTimes(1); expect(mockChdir).toHaveBeenNthCalledWith(1, appDir); - expect(mockExec).toHaveBeenCalledTimes(3); + expect(mockExec).toHaveBeenCalledTimes(2); expect(mockExec).toHaveBeenNthCalledWith( 1, - 'yarn --version', - expect.any(Function), - ); - expect(mockExec).toHaveBeenNthCalledWith( - 2, 'yarn install', expect.any(Function), ); expect(mockExec).toHaveBeenNthCalledWith( - 3, + 2, 'yarn tsc', expect.any(Function), ); }); - it('should error out on incorrect yarn version', async () => { - // requires callback implementation to support `promisify` wrapper - // https://stackoverflow.com/a/60579617/10044859 - mockExec.mockImplementation((_command, callback) => { - callback(null, { stdout: '3.2.1', stderr: 'standard error' }); - }); - - const appDir = 'projects/dir'; - await expect(buildAppTask(appDir)).rejects.toThrow( - /^@backstage\/create-app requires Yarn v1, found '3\.2\.1'/, - ); - expect(mockChdir).toHaveBeenCalledTimes(1); - expect(mockChdir).toHaveBeenNthCalledWith(1, appDir); - expect(mockExec).toHaveBeenCalledTimes(1); - expect(mockExec).toHaveBeenNthCalledWith( - 1, - 'yarn --version', - expect.any(Function), - ); - }); - it('should fail if project directory does not exist', async () => { const appDir = 'projects/missingProject'; await expect(buildAppTask(appDir)).rejects.toThrow( diff --git a/packages/create-app/src/lib/tasks.ts b/packages/create-app/src/lib/tasks.ts index d366bd5cc7..a47f5f2cb9 100644 --- a/packages/create-app/src/lib/tasks.ts +++ b/packages/create-app/src/lib/tasks.ts @@ -187,17 +187,6 @@ export async function checkPathExistsTask(path: string) { export async function buildAppTask(appDir: string) { process.chdir(appDir); - await Task.forItem('determining', 'yarn version', async () => { - const result = await exec('yarn --version'); - const yarnVersion = result.stdout?.trim(); - - if (yarnVersion && !yarnVersion.startsWith('1.')) { - throw new Error( - `@backstage/create-app requires Yarn v1, found '${yarnVersion}'. You can migrate the project to Yarn 3 after creation using https://backstage.io/docs/tutorials/yarn-migration`, - ); - } - }); - const runCmd = async (cmd: string) => { await Task.forItem('executing', cmd, async () => { await exec(cmd).catch(error => { diff --git a/packages/create-app/templates/default-app/.gitignore.hbs b/packages/create-app/templates/default-app/.gitignore.hbs index fbf813909c..77ad56d128 100644 --- a/packages/create-app/templates/default-app/.gitignore.hbs +++ b/packages/create-app/templates/default-app/.gitignore.hbs @@ -15,7 +15,7 @@ coverage # Dependencies node_modules/ -# Yarn 3 files +# Yarn files .pnp.* .yarn/* !.yarn/patches diff --git a/packages/create-app/templates/default-app/.yarn/releases/yarn-4.4.1.cjs b/packages/create-app/templates/default-app/.yarn/releases/yarn-4.4.1.cjs new file mode 100755 index 0000000000..e94c2cba6d --- /dev/null +++ b/packages/create-app/templates/default-app/.yarn/releases/yarn-4.4.1.cjs @@ -0,0 +1,925 @@ +#!/usr/bin/env node +/* eslint-disable */ +//prettier-ignore +(()=>{var t_e=Object.create;var vR=Object.defineProperty;var r_e=Object.getOwnPropertyDescriptor;var n_e=Object.getOwnPropertyNames;var i_e=Object.getPrototypeOf,s_e=Object.prototype.hasOwnProperty;var ve=(t=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(t,{get:(e,r)=>(typeof require<"u"?require:e)[r]}):t)(function(t){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+t+'" is not supported')});var Et=(t,e)=>()=>(t&&(e=t(t=0)),e);var _=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports),Vt=(t,e)=>{for(var r in e)vR(t,r,{get:e[r],enumerable:!0})},o_e=(t,e,r,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of n_e(e))!s_e.call(t,a)&&a!==r&&vR(t,a,{get:()=>e[a],enumerable:!(o=r_e(e,a))||o.enumerable});return t};var Ze=(t,e,r)=>(r=t!=null?t_e(i_e(t)):{},o_e(e||!t||!t.__esModule?vR(r,"default",{value:t,enumerable:!0}):r,t));var Bi={};Vt(Bi,{SAFE_TIME:()=>D7,S_IFDIR:()=>iD,S_IFLNK:()=>sD,S_IFMT:()=>Uu,S_IFREG:()=>Dw});var Uu,iD,Dw,sD,D7,P7=Et(()=>{Uu=61440,iD=16384,Dw=32768,sD=40960,D7=456789e3});var nr={};Vt(nr,{EBADF:()=>Io,EBUSY:()=>a_e,EEXIST:()=>p_e,EINVAL:()=>c_e,EISDIR:()=>f_e,ENOENT:()=>u_e,ENOSYS:()=>l_e,ENOTDIR:()=>A_e,ENOTEMPTY:()=>g_e,EOPNOTSUPP:()=>d_e,EROFS:()=>h_e,ERR_DIR_CLOSED:()=>DR});function Tl(t,e){return Object.assign(new Error(`${t}: ${e}`),{code:t})}function a_e(t){return Tl("EBUSY",t)}function l_e(t,e){return Tl("ENOSYS",`${t}, ${e}`)}function c_e(t){return Tl("EINVAL",`invalid argument, ${t}`)}function Io(t){return Tl("EBADF",`bad file descriptor, ${t}`)}function u_e(t){return Tl("ENOENT",`no such file or directory, ${t}`)}function A_e(t){return Tl("ENOTDIR",`not a directory, ${t}`)}function f_e(t){return Tl("EISDIR",`illegal operation on a directory, ${t}`)}function p_e(t){return Tl("EEXIST",`file already exists, ${t}`)}function h_e(t){return Tl("EROFS",`read-only filesystem, ${t}`)}function g_e(t){return Tl("ENOTEMPTY",`directory not empty, ${t}`)}function d_e(t){return Tl("EOPNOTSUPP",`operation not supported, ${t}`)}function DR(){return Tl("ERR_DIR_CLOSED","Directory handle was closed")}var oD=Et(()=>{});var wa={};Vt(wa,{BigIntStatsEntry:()=>qd,DEFAULT_MODE:()=>SR,DirEntry:()=>PR,StatEntry:()=>Hd,areStatsEqual:()=>xR,clearStats:()=>aD,convertToBigIntStats:()=>y_e,makeDefaultStats:()=>b7,makeEmptyStats:()=>m_e});function b7(){return new Hd}function m_e(){return aD(b7())}function aD(t){for(let e in t)if(Object.hasOwn(t,e)){let r=t[e];typeof r=="number"?t[e]=0:typeof r=="bigint"?t[e]=BigInt(0):bR.types.isDate(r)&&(t[e]=new Date(0))}return t}function y_e(t){let e=new qd;for(let r in t)if(Object.hasOwn(t,r)){let o=t[r];typeof o=="number"?e[r]=BigInt(o):bR.types.isDate(o)&&(e[r]=new Date(o))}return e.atimeNs=e.atimeMs*BigInt(1e6),e.mtimeNs=e.mtimeMs*BigInt(1e6),e.ctimeNs=e.ctimeMs*BigInt(1e6),e.birthtimeNs=e.birthtimeMs*BigInt(1e6),e}function xR(t,e){if(t.atimeMs!==e.atimeMs||t.birthtimeMs!==e.birthtimeMs||t.blksize!==e.blksize||t.blocks!==e.blocks||t.ctimeMs!==e.ctimeMs||t.dev!==e.dev||t.gid!==e.gid||t.ino!==e.ino||t.isBlockDevice()!==e.isBlockDevice()||t.isCharacterDevice()!==e.isCharacterDevice()||t.isDirectory()!==e.isDirectory()||t.isFIFO()!==e.isFIFO()||t.isFile()!==e.isFile()||t.isSocket()!==e.isSocket()||t.isSymbolicLink()!==e.isSymbolicLink()||t.mode!==e.mode||t.mtimeMs!==e.mtimeMs||t.nlink!==e.nlink||t.rdev!==e.rdev||t.size!==e.size||t.uid!==e.uid)return!1;let r=t,o=e;return!(r.atimeNs!==o.atimeNs||r.mtimeNs!==o.mtimeNs||r.ctimeNs!==o.ctimeNs||r.birthtimeNs!==o.birthtimeNs)}var bR,SR,PR,Hd,qd,kR=Et(()=>{bR=Ze(ve("util")),SR=33188,PR=class{constructor(){this.name="";this.path="";this.mode=0}isBlockDevice(){return!1}isCharacterDevice(){return!1}isDirectory(){return(this.mode&61440)===16384}isFIFO(){return!1}isFile(){return(this.mode&61440)===32768}isSocket(){return!1}isSymbolicLink(){return(this.mode&61440)===40960}},Hd=class{constructor(){this.uid=0;this.gid=0;this.size=0;this.blksize=0;this.atimeMs=0;this.mtimeMs=0;this.ctimeMs=0;this.birthtimeMs=0;this.atime=new Date(0);this.mtime=new Date(0);this.ctime=new Date(0);this.birthtime=new Date(0);this.dev=0;this.ino=0;this.mode=SR;this.nlink=1;this.rdev=0;this.blocks=1}isBlockDevice(){return!1}isCharacterDevice(){return!1}isDirectory(){return(this.mode&61440)===16384}isFIFO(){return!1}isFile(){return(this.mode&61440)===32768}isSocket(){return!1}isSymbolicLink(){return(this.mode&61440)===40960}},qd=class{constructor(){this.uid=BigInt(0);this.gid=BigInt(0);this.size=BigInt(0);this.blksize=BigInt(0);this.atimeMs=BigInt(0);this.mtimeMs=BigInt(0);this.ctimeMs=BigInt(0);this.birthtimeMs=BigInt(0);this.atimeNs=BigInt(0);this.mtimeNs=BigInt(0);this.ctimeNs=BigInt(0);this.birthtimeNs=BigInt(0);this.atime=new Date(0);this.mtime=new Date(0);this.ctime=new Date(0);this.birthtime=new Date(0);this.dev=BigInt(0);this.ino=BigInt(0);this.mode=BigInt(SR);this.nlink=BigInt(1);this.rdev=BigInt(0);this.blocks=BigInt(1)}isBlockDevice(){return!1}isCharacterDevice(){return!1}isDirectory(){return(this.mode&BigInt(61440))===BigInt(16384)}isFIFO(){return!1}isFile(){return(this.mode&BigInt(61440))===BigInt(32768)}isSocket(){return!1}isSymbolicLink(){return(this.mode&BigInt(61440))===BigInt(40960)}}});function B_e(t){let e,r;if(e=t.match(w_e))t=e[1];else if(r=t.match(I_e))t=`\\\\${r[1]?".\\":""}${r[2]}`;else return t;return t.replace(/\//g,"\\")}function v_e(t){t=t.replace(/\\/g,"/");let e,r;return(e=t.match(E_e))?t=`/${e[1]}`:(r=t.match(C_e))&&(t=`/unc/${r[1]?".dot/":""}${r[2]}`),t}function lD(t,e){return t===ue?x7(e):QR(e)}var Pw,It,dr,ue,V,S7,E_e,C_e,w_e,I_e,QR,x7,Ia=Et(()=>{Pw=Ze(ve("path")),It={root:"/",dot:".",parent:".."},dr={home:"~",nodeModules:"node_modules",manifest:"package.json",lockfile:"yarn.lock",virtual:"__virtual__",pnpJs:".pnp.js",pnpCjs:".pnp.cjs",pnpData:".pnp.data.json",pnpEsmLoader:".pnp.loader.mjs",rc:".yarnrc.yml",env:".env"},ue=Object.create(Pw.default),V=Object.create(Pw.default.posix);ue.cwd=()=>process.cwd();V.cwd=process.platform==="win32"?()=>QR(process.cwd()):process.cwd;process.platform==="win32"&&(V.resolve=(...t)=>t.length>0&&V.isAbsolute(t[0])?Pw.default.posix.resolve(...t):Pw.default.posix.resolve(V.cwd(),...t));S7=function(t,e,r){return e=t.normalize(e),r=t.normalize(r),e===r?".":(e.endsWith(t.sep)||(e=e+t.sep),r.startsWith(e)?r.slice(e.length):null)};ue.contains=(t,e)=>S7(ue,t,e);V.contains=(t,e)=>S7(V,t,e);E_e=/^([a-zA-Z]:.*)$/,C_e=/^\/\/(\.\/)?(.*)$/,w_e=/^\/([a-zA-Z]:.*)$/,I_e=/^\/unc\/(\.dot\/)?(.*)$/;QR=process.platform==="win32"?v_e:t=>t,x7=process.platform==="win32"?B_e:t=>t;ue.fromPortablePath=x7;ue.toPortablePath=QR});async function cD(t,e){let r="0123456789abcdef";await t.mkdirPromise(e.indexPath,{recursive:!0});let o=[];for(let a of r)for(let n of r)o.push(t.mkdirPromise(t.pathUtils.join(e.indexPath,`${a}${n}`),{recursive:!0}));return await Promise.all(o),e.indexPath}async function k7(t,e,r,o,a){let n=t.pathUtils.normalize(e),u=r.pathUtils.normalize(o),A=[],p=[],{atime:h,mtime:E}=a.stableTime?{atime:R0,mtime:R0}:await r.lstatPromise(u);await t.mkdirpPromise(t.pathUtils.dirname(e),{utimes:[h,E]}),await FR(A,p,t,n,r,u,{...a,didParentExist:!0});for(let I of A)await I();await Promise.all(p.map(I=>I()))}async function FR(t,e,r,o,a,n,u){let A=u.didParentExist?await Q7(r,o):null,p=await a.lstatPromise(n),{atime:h,mtime:E}=u.stableTime?{atime:R0,mtime:R0}:p,I;switch(!0){case p.isDirectory():I=await P_e(t,e,r,o,A,a,n,p,u);break;case p.isFile():I=await x_e(t,e,r,o,A,a,n,p,u);break;case p.isSymbolicLink():I=await k_e(t,e,r,o,A,a,n,p,u);break;default:throw new Error(`Unsupported file type (${p.mode})`)}return(u.linkStrategy?.type!=="HardlinkFromIndex"||!p.isFile())&&((I||A?.mtime?.getTime()!==E.getTime()||A?.atime?.getTime()!==h.getTime())&&(e.push(()=>r.lutimesPromise(o,h,E)),I=!0),(A===null||(A.mode&511)!==(p.mode&511))&&(e.push(()=>r.chmodPromise(o,p.mode&511)),I=!0)),I}async function Q7(t,e){try{return await t.lstatPromise(e)}catch{return null}}async function P_e(t,e,r,o,a,n,u,A,p){if(a!==null&&!a.isDirectory())if(p.overwrite)t.push(async()=>r.removePromise(o)),a=null;else return!1;let h=!1;a===null&&(t.push(async()=>{try{await r.mkdirPromise(o,{mode:A.mode})}catch(v){if(v.code!=="EEXIST")throw v}}),h=!0);let E=await n.readdirPromise(u),I=p.didParentExist&&!a?{...p,didParentExist:!1}:p;if(p.stableSort)for(let v of E.sort())await FR(t,e,r,r.pathUtils.join(o,v),n,n.pathUtils.join(u,v),I)&&(h=!0);else(await Promise.all(E.map(async x=>{await FR(t,e,r,r.pathUtils.join(o,x),n,n.pathUtils.join(u,x),I)}))).some(x=>x)&&(h=!0);return h}async function b_e(t,e,r,o,a,n,u,A,p,h){let E=await n.checksumFilePromise(u,{algorithm:"sha1"}),I=420,v=A.mode&511,x=`${E}${v!==I?v.toString(8):""}`,C=r.pathUtils.join(h.indexPath,E.slice(0,2),`${x}.dat`),R;(ce=>(ce[ce.Lock=0]="Lock",ce[ce.Rename=1]="Rename"))(R||={});let L=1,U=await Q7(r,C);if(a){let ae=U&&a.dev===U.dev&&a.ino===U.ino,le=U?.mtimeMs!==D_e;if(ae&&le&&h.autoRepair&&(L=0,U=null),!ae)if(p.overwrite)t.push(async()=>r.removePromise(o)),a=null;else return!1}let z=!U&&L===1?`${C}.${Math.floor(Math.random()*4294967296).toString(16).padStart(8,"0")}`:null,te=!1;return t.push(async()=>{if(!U&&(L===0&&await r.lockPromise(C,async()=>{let ae=await n.readFilePromise(u);await r.writeFilePromise(C,ae)}),L===1&&z)){let ae=await n.readFilePromise(u);await r.writeFilePromise(z,ae);try{await r.linkPromise(z,C)}catch(le){if(le.code==="EEXIST")te=!0,await r.unlinkPromise(z);else throw le}}a||await r.linkPromise(C,o)}),e.push(async()=>{U||(await r.lutimesPromise(C,R0,R0),v!==I&&await r.chmodPromise(C,v)),z&&!te&&await r.unlinkPromise(z)}),!1}async function S_e(t,e,r,o,a,n,u,A,p){if(a!==null)if(p.overwrite)t.push(async()=>r.removePromise(o)),a=null;else return!1;return t.push(async()=>{let h=await n.readFilePromise(u);await r.writeFilePromise(o,h)}),!0}async function x_e(t,e,r,o,a,n,u,A,p){return p.linkStrategy?.type==="HardlinkFromIndex"?b_e(t,e,r,o,a,n,u,A,p,p.linkStrategy):S_e(t,e,r,o,a,n,u,A,p)}async function k_e(t,e,r,o,a,n,u,A,p){if(a!==null)if(p.overwrite)t.push(async()=>r.removePromise(o)),a=null;else return!1;return t.push(async()=>{await r.symlinkPromise(lD(r.pathUtils,await n.readlinkPromise(u)),o)}),!0}var R0,D_e,RR=Et(()=>{Ia();R0=new Date(456789e3*1e3),D_e=R0.getTime()});function uD(t,e,r,o){let a=()=>{let n=r.shift();if(typeof n>"u")return null;let u=t.pathUtils.join(e,n);return Object.assign(t.statSync(u),{name:n,path:void 0})};return new bw(e,a,o)}var bw,F7=Et(()=>{oD();bw=class{constructor(e,r,o={}){this.path=e;this.nextDirent=r;this.opts=o;this.closed=!1}throwIfClosed(){if(this.closed)throw DR()}async*[Symbol.asyncIterator](){try{let e;for(;(e=await this.read())!==null;)yield e}finally{await this.close()}}read(e){let r=this.readSync();return typeof e<"u"?e(null,r):Promise.resolve(r)}readSync(){return this.throwIfClosed(),this.nextDirent()}close(e){return this.closeSync(),typeof e<"u"?e(null):Promise.resolve()}closeSync(){this.throwIfClosed(),this.opts.onClose?.(),this.closed=!0}}});function R7(t,e){if(t!==e)throw new Error(`Invalid StatWatcher status: expected '${e}', got '${t}'`)}var T7,AD,N7=Et(()=>{T7=ve("events");kR();AD=class t extends T7.EventEmitter{constructor(r,o,{bigint:a=!1}={}){super();this.status="ready";this.changeListeners=new Map;this.startTimeout=null;this.fakeFs=r,this.path=o,this.bigint=a,this.lastStats=this.stat()}static create(r,o,a){let n=new t(r,o,a);return n.start(),n}start(){R7(this.status,"ready"),this.status="running",this.startTimeout=setTimeout(()=>{this.startTimeout=null,this.fakeFs.existsSync(this.path)||this.emit("change",this.lastStats,this.lastStats)},3)}stop(){R7(this.status,"running"),this.status="stopped",this.startTimeout!==null&&(clearTimeout(this.startTimeout),this.startTimeout=null),this.emit("stop")}stat(){try{return this.fakeFs.statSync(this.path,{bigint:this.bigint})}catch{let o=this.bigint?new qd:new Hd;return aD(o)}}makeInterval(r){let o=setInterval(()=>{let a=this.stat(),n=this.lastStats;xR(a,n)||(this.lastStats=a,this.emit("change",a,n))},r.interval);return r.persistent?o:o.unref()}registerChangeListener(r,o){this.addListener("change",r),this.changeListeners.set(r,this.makeInterval(o))}unregisterChangeListener(r){this.removeListener("change",r);let o=this.changeListeners.get(r);typeof o<"u"&&clearInterval(o),this.changeListeners.delete(r)}unregisterAllChangeListeners(){for(let r of this.changeListeners.keys())this.unregisterChangeListener(r)}hasChangeListeners(){return this.changeListeners.size>0}ref(){for(let r of this.changeListeners.values())r.ref();return this}unref(){for(let r of this.changeListeners.values())r.unref();return this}}});function jd(t,e,r,o){let a,n,u,A;switch(typeof r){case"function":a=!1,n=!0,u=5007,A=r;break;default:({bigint:a=!1,persistent:n=!0,interval:u=5007}=r),A=o;break}let p=fD.get(t);typeof p>"u"&&fD.set(t,p=new Map);let h=p.get(e);return typeof h>"u"&&(h=AD.create(t,e,{bigint:a}),p.set(e,h)),h.registerChangeListener(A,{persistent:n,interval:u}),h}function T0(t,e,r){let o=fD.get(t);if(typeof o>"u")return;let a=o.get(e);typeof a>"u"||(typeof r>"u"?a.unregisterAllChangeListeners():a.unregisterChangeListener(r),a.hasChangeListeners()||(a.stop(),o.delete(e)))}function N0(t){let e=fD.get(t);if(!(typeof e>"u"))for(let r of e.keys())T0(t,r)}var fD,TR=Et(()=>{N7();fD=new WeakMap});function Q_e(t){let e=t.match(/\r?\n/g);if(e===null)return M7.EOL;let r=e.filter(a=>a===`\r +`).length,o=e.length-r;return r>o?`\r +`:` +`}function L0(t,e){return e.replace(/\r?\n/g,Q_e(t))}var L7,M7,hf,_u,M0=Et(()=>{L7=ve("crypto"),M7=ve("os");RR();Ia();hf=class{constructor(e){this.pathUtils=e}async*genTraversePromise(e,{stableSort:r=!1}={}){let o=[e];for(;o.length>0;){let a=o.shift();if((await this.lstatPromise(a)).isDirectory()){let u=await this.readdirPromise(a);if(r)for(let A of u.sort())o.push(this.pathUtils.join(a,A));else throw new Error("Not supported")}else yield a}}async checksumFilePromise(e,{algorithm:r="sha512"}={}){let o=await this.openPromise(e,"r");try{let n=Buffer.allocUnsafeSlow(65536),u=(0,L7.createHash)(r),A=0;for(;(A=await this.readPromise(o,n,0,65536))!==0;)u.update(A===65536?n:n.slice(0,A));return u.digest("hex")}finally{await this.closePromise(o)}}async removePromise(e,{recursive:r=!0,maxRetries:o=5}={}){let a;try{a=await this.lstatPromise(e)}catch(n){if(n.code==="ENOENT")return;throw n}if(a.isDirectory()){if(r){let n=await this.readdirPromise(e);await Promise.all(n.map(u=>this.removePromise(this.pathUtils.resolve(e,u))))}for(let n=0;n<=o;n++)try{await this.rmdirPromise(e);break}catch(u){if(u.code!=="EBUSY"&&u.code!=="ENOTEMPTY")throw u;nsetTimeout(A,n*100))}}else await this.unlinkPromise(e)}removeSync(e,{recursive:r=!0}={}){let o;try{o=this.lstatSync(e)}catch(a){if(a.code==="ENOENT")return;throw a}if(o.isDirectory()){if(r)for(let a of this.readdirSync(e))this.removeSync(this.pathUtils.resolve(e,a));this.rmdirSync(e)}else this.unlinkSync(e)}async mkdirpPromise(e,{chmod:r,utimes:o}={}){if(e=this.resolve(e),e===this.pathUtils.dirname(e))return;let a=e.split(this.pathUtils.sep),n;for(let u=2;u<=a.length;++u){let A=a.slice(0,u).join(this.pathUtils.sep);if(!this.existsSync(A)){try{await this.mkdirPromise(A)}catch(p){if(p.code==="EEXIST")continue;throw p}if(n??=A,r!=null&&await this.chmodPromise(A,r),o!=null)await this.utimesPromise(A,o[0],o[1]);else{let p=await this.statPromise(this.pathUtils.dirname(A));await this.utimesPromise(A,p.atime,p.mtime)}}}return n}mkdirpSync(e,{chmod:r,utimes:o}={}){if(e=this.resolve(e),e===this.pathUtils.dirname(e))return;let a=e.split(this.pathUtils.sep),n;for(let u=2;u<=a.length;++u){let A=a.slice(0,u).join(this.pathUtils.sep);if(!this.existsSync(A)){try{this.mkdirSync(A)}catch(p){if(p.code==="EEXIST")continue;throw p}if(n??=A,r!=null&&this.chmodSync(A,r),o!=null)this.utimesSync(A,o[0],o[1]);else{let p=this.statSync(this.pathUtils.dirname(A));this.utimesSync(A,p.atime,p.mtime)}}}return n}async copyPromise(e,r,{baseFs:o=this,overwrite:a=!0,stableSort:n=!1,stableTime:u=!1,linkStrategy:A=null}={}){return await k7(this,e,o,r,{overwrite:a,stableSort:n,stableTime:u,linkStrategy:A})}copySync(e,r,{baseFs:o=this,overwrite:a=!0}={}){let n=o.lstatSync(r),u=this.existsSync(e);if(n.isDirectory()){this.mkdirpSync(e);let p=o.readdirSync(r);for(let h of p)this.copySync(this.pathUtils.join(e,h),o.pathUtils.join(r,h),{baseFs:o,overwrite:a})}else if(n.isFile()){if(!u||a){u&&this.removeSync(e);let p=o.readFileSync(r);this.writeFileSync(e,p)}}else if(n.isSymbolicLink()){if(!u||a){u&&this.removeSync(e);let p=o.readlinkSync(r);this.symlinkSync(lD(this.pathUtils,p),e)}}else throw new Error(`Unsupported file type (file: ${r}, mode: 0o${n.mode.toString(8).padStart(6,"0")})`);let A=n.mode&511;this.chmodSync(e,A)}async changeFilePromise(e,r,o={}){return Buffer.isBuffer(r)?this.changeFileBufferPromise(e,r,o):this.changeFileTextPromise(e,r,o)}async changeFileBufferPromise(e,r,{mode:o}={}){let a=Buffer.alloc(0);try{a=await this.readFilePromise(e)}catch{}Buffer.compare(a,r)!==0&&await this.writeFilePromise(e,r,{mode:o})}async changeFileTextPromise(e,r,{automaticNewlines:o,mode:a}={}){let n="";try{n=await this.readFilePromise(e,"utf8")}catch{}let u=o?L0(n,r):r;n!==u&&await this.writeFilePromise(e,u,{mode:a})}changeFileSync(e,r,o={}){return Buffer.isBuffer(r)?this.changeFileBufferSync(e,r,o):this.changeFileTextSync(e,r,o)}changeFileBufferSync(e,r,{mode:o}={}){let a=Buffer.alloc(0);try{a=this.readFileSync(e)}catch{}Buffer.compare(a,r)!==0&&this.writeFileSync(e,r,{mode:o})}changeFileTextSync(e,r,{automaticNewlines:o=!1,mode:a}={}){let n="";try{n=this.readFileSync(e,"utf8")}catch{}let u=o?L0(n,r):r;n!==u&&this.writeFileSync(e,u,{mode:a})}async movePromise(e,r){try{await this.renamePromise(e,r)}catch(o){if(o.code==="EXDEV")await this.copyPromise(r,e),await this.removePromise(e);else throw o}}moveSync(e,r){try{this.renameSync(e,r)}catch(o){if(o.code==="EXDEV")this.copySync(r,e),this.removeSync(e);else throw o}}async lockPromise(e,r){let o=`${e}.flock`,a=1e3/60,n=Date.now(),u=null,A=async()=>{let p;try{[p]=await this.readJsonPromise(o)}catch{return Date.now()-n<500}try{return process.kill(p,0),!0}catch{return!1}};for(;u===null;)try{u=await this.openPromise(o,"wx")}catch(p){if(p.code==="EEXIST"){if(!await A())try{await this.unlinkPromise(o);continue}catch{}if(Date.now()-n<60*1e3)await new Promise(h=>setTimeout(h,a));else throw new Error(`Couldn't acquire a lock in a reasonable time (via ${o})`)}else throw p}await this.writePromise(u,JSON.stringify([process.pid]));try{return await r()}finally{try{await this.closePromise(u),await this.unlinkPromise(o)}catch{}}}async readJsonPromise(e){let r=await this.readFilePromise(e,"utf8");try{return JSON.parse(r)}catch(o){throw o.message+=` (in ${e})`,o}}readJsonSync(e){let r=this.readFileSync(e,"utf8");try{return JSON.parse(r)}catch(o){throw o.message+=` (in ${e})`,o}}async writeJsonPromise(e,r,{compact:o=!1}={}){let a=o?0:2;return await this.writeFilePromise(e,`${JSON.stringify(r,null,a)} +`)}writeJsonSync(e,r,{compact:o=!1}={}){let a=o?0:2;return this.writeFileSync(e,`${JSON.stringify(r,null,a)} +`)}async preserveTimePromise(e,r){let o=await this.lstatPromise(e),a=await r();typeof a<"u"&&(e=a),await this.lutimesPromise(e,o.atime,o.mtime)}async preserveTimeSync(e,r){let o=this.lstatSync(e),a=r();typeof a<"u"&&(e=a),this.lutimesSync(e,o.atime,o.mtime)}},_u=class extends hf{constructor(){super(V)}}});var Ss,gf=Et(()=>{M0();Ss=class extends hf{getExtractHint(e){return this.baseFs.getExtractHint(e)}resolve(e){return this.mapFromBase(this.baseFs.resolve(this.mapToBase(e)))}getRealPath(){return this.mapFromBase(this.baseFs.getRealPath())}async openPromise(e,r,o){return this.baseFs.openPromise(this.mapToBase(e),r,o)}openSync(e,r,o){return this.baseFs.openSync(this.mapToBase(e),r,o)}async opendirPromise(e,r){return Object.assign(await this.baseFs.opendirPromise(this.mapToBase(e),r),{path:e})}opendirSync(e,r){return Object.assign(this.baseFs.opendirSync(this.mapToBase(e),r),{path:e})}async readPromise(e,r,o,a,n){return await this.baseFs.readPromise(e,r,o,a,n)}readSync(e,r,o,a,n){return this.baseFs.readSync(e,r,o,a,n)}async writePromise(e,r,o,a,n){return typeof r=="string"?await this.baseFs.writePromise(e,r,o):await this.baseFs.writePromise(e,r,o,a,n)}writeSync(e,r,o,a,n){return typeof r=="string"?this.baseFs.writeSync(e,r,o):this.baseFs.writeSync(e,r,o,a,n)}async closePromise(e){return this.baseFs.closePromise(e)}closeSync(e){this.baseFs.closeSync(e)}createReadStream(e,r){return this.baseFs.createReadStream(e!==null?this.mapToBase(e):e,r)}createWriteStream(e,r){return this.baseFs.createWriteStream(e!==null?this.mapToBase(e):e,r)}async realpathPromise(e){return this.mapFromBase(await this.baseFs.realpathPromise(this.mapToBase(e)))}realpathSync(e){return this.mapFromBase(this.baseFs.realpathSync(this.mapToBase(e)))}async existsPromise(e){return this.baseFs.existsPromise(this.mapToBase(e))}existsSync(e){return this.baseFs.existsSync(this.mapToBase(e))}accessSync(e,r){return this.baseFs.accessSync(this.mapToBase(e),r)}async accessPromise(e,r){return this.baseFs.accessPromise(this.mapToBase(e),r)}async statPromise(e,r){return this.baseFs.statPromise(this.mapToBase(e),r)}statSync(e,r){return this.baseFs.statSync(this.mapToBase(e),r)}async fstatPromise(e,r){return this.baseFs.fstatPromise(e,r)}fstatSync(e,r){return this.baseFs.fstatSync(e,r)}lstatPromise(e,r){return this.baseFs.lstatPromise(this.mapToBase(e),r)}lstatSync(e,r){return this.baseFs.lstatSync(this.mapToBase(e),r)}async fchmodPromise(e,r){return this.baseFs.fchmodPromise(e,r)}fchmodSync(e,r){return this.baseFs.fchmodSync(e,r)}async chmodPromise(e,r){return this.baseFs.chmodPromise(this.mapToBase(e),r)}chmodSync(e,r){return this.baseFs.chmodSync(this.mapToBase(e),r)}async fchownPromise(e,r,o){return this.baseFs.fchownPromise(e,r,o)}fchownSync(e,r,o){return this.baseFs.fchownSync(e,r,o)}async chownPromise(e,r,o){return this.baseFs.chownPromise(this.mapToBase(e),r,o)}chownSync(e,r,o){return this.baseFs.chownSync(this.mapToBase(e),r,o)}async renamePromise(e,r){return this.baseFs.renamePromise(this.mapToBase(e),this.mapToBase(r))}renameSync(e,r){return this.baseFs.renameSync(this.mapToBase(e),this.mapToBase(r))}async copyFilePromise(e,r,o=0){return this.baseFs.copyFilePromise(this.mapToBase(e),this.mapToBase(r),o)}copyFileSync(e,r,o=0){return this.baseFs.copyFileSync(this.mapToBase(e),this.mapToBase(r),o)}async appendFilePromise(e,r,o){return this.baseFs.appendFilePromise(this.fsMapToBase(e),r,o)}appendFileSync(e,r,o){return this.baseFs.appendFileSync(this.fsMapToBase(e),r,o)}async writeFilePromise(e,r,o){return this.baseFs.writeFilePromise(this.fsMapToBase(e),r,o)}writeFileSync(e,r,o){return this.baseFs.writeFileSync(this.fsMapToBase(e),r,o)}async unlinkPromise(e){return this.baseFs.unlinkPromise(this.mapToBase(e))}unlinkSync(e){return this.baseFs.unlinkSync(this.mapToBase(e))}async utimesPromise(e,r,o){return this.baseFs.utimesPromise(this.mapToBase(e),r,o)}utimesSync(e,r,o){return this.baseFs.utimesSync(this.mapToBase(e),r,o)}async lutimesPromise(e,r,o){return this.baseFs.lutimesPromise(this.mapToBase(e),r,o)}lutimesSync(e,r,o){return this.baseFs.lutimesSync(this.mapToBase(e),r,o)}async mkdirPromise(e,r){return this.baseFs.mkdirPromise(this.mapToBase(e),r)}mkdirSync(e,r){return this.baseFs.mkdirSync(this.mapToBase(e),r)}async rmdirPromise(e,r){return this.baseFs.rmdirPromise(this.mapToBase(e),r)}rmdirSync(e,r){return this.baseFs.rmdirSync(this.mapToBase(e),r)}async rmPromise(e,r){return this.baseFs.rmPromise(this.mapToBase(e),r)}rmSync(e,r){return this.baseFs.rmSync(this.mapToBase(e),r)}async linkPromise(e,r){return this.baseFs.linkPromise(this.mapToBase(e),this.mapToBase(r))}linkSync(e,r){return this.baseFs.linkSync(this.mapToBase(e),this.mapToBase(r))}async symlinkPromise(e,r,o){let a=this.mapToBase(r);if(this.pathUtils.isAbsolute(e))return this.baseFs.symlinkPromise(this.mapToBase(e),a,o);let n=this.mapToBase(this.pathUtils.join(this.pathUtils.dirname(r),e)),u=this.baseFs.pathUtils.relative(this.baseFs.pathUtils.dirname(a),n);return this.baseFs.symlinkPromise(u,a,o)}symlinkSync(e,r,o){let a=this.mapToBase(r);if(this.pathUtils.isAbsolute(e))return this.baseFs.symlinkSync(this.mapToBase(e),a,o);let n=this.mapToBase(this.pathUtils.join(this.pathUtils.dirname(r),e)),u=this.baseFs.pathUtils.relative(this.baseFs.pathUtils.dirname(a),n);return this.baseFs.symlinkSync(u,a,o)}async readFilePromise(e,r){return this.baseFs.readFilePromise(this.fsMapToBase(e),r)}readFileSync(e,r){return this.baseFs.readFileSync(this.fsMapToBase(e),r)}readdirPromise(e,r){return this.baseFs.readdirPromise(this.mapToBase(e),r)}readdirSync(e,r){return this.baseFs.readdirSync(this.mapToBase(e),r)}async readlinkPromise(e){return this.mapFromBase(await this.baseFs.readlinkPromise(this.mapToBase(e)))}readlinkSync(e){return this.mapFromBase(this.baseFs.readlinkSync(this.mapToBase(e)))}async truncatePromise(e,r){return this.baseFs.truncatePromise(this.mapToBase(e),r)}truncateSync(e,r){return this.baseFs.truncateSync(this.mapToBase(e),r)}async ftruncatePromise(e,r){return this.baseFs.ftruncatePromise(e,r)}ftruncateSync(e,r){return this.baseFs.ftruncateSync(e,r)}watch(e,r,o){return this.baseFs.watch(this.mapToBase(e),r,o)}watchFile(e,r,o){return this.baseFs.watchFile(this.mapToBase(e),r,o)}unwatchFile(e,r){return this.baseFs.unwatchFile(this.mapToBase(e),r)}fsMapToBase(e){return typeof e=="number"?e:this.mapToBase(e)}}});var Hu,O7=Et(()=>{gf();Hu=class extends Ss{constructor(e,{baseFs:r,pathUtils:o}){super(o),this.target=e,this.baseFs=r}getRealPath(){return this.target}getBaseFs(){return this.baseFs}mapFromBase(e){return e}mapToBase(e){return e}}});function U7(t){let e=t;return typeof t.path=="string"&&(e.path=ue.toPortablePath(t.path)),e}var _7,Tn,O0=Et(()=>{_7=Ze(ve("fs"));M0();Ia();Tn=class extends _u{constructor(e=_7.default){super(),this.realFs=e}getExtractHint(){return!1}getRealPath(){return It.root}resolve(e){return V.resolve(e)}async openPromise(e,r,o){return await new Promise((a,n)=>{this.realFs.open(ue.fromPortablePath(e),r,o,this.makeCallback(a,n))})}openSync(e,r,o){return this.realFs.openSync(ue.fromPortablePath(e),r,o)}async opendirPromise(e,r){return await new Promise((o,a)=>{typeof r<"u"?this.realFs.opendir(ue.fromPortablePath(e),r,this.makeCallback(o,a)):this.realFs.opendir(ue.fromPortablePath(e),this.makeCallback(o,a))}).then(o=>{let a=o;return Object.defineProperty(a,"path",{value:e,configurable:!0,writable:!0}),a})}opendirSync(e,r){let a=typeof r<"u"?this.realFs.opendirSync(ue.fromPortablePath(e),r):this.realFs.opendirSync(ue.fromPortablePath(e));return Object.defineProperty(a,"path",{value:e,configurable:!0,writable:!0}),a}async readPromise(e,r,o=0,a=0,n=-1){return await new Promise((u,A)=>{this.realFs.read(e,r,o,a,n,(p,h)=>{p?A(p):u(h)})})}readSync(e,r,o,a,n){return this.realFs.readSync(e,r,o,a,n)}async writePromise(e,r,o,a,n){return await new Promise((u,A)=>typeof r=="string"?this.realFs.write(e,r,o,this.makeCallback(u,A)):this.realFs.write(e,r,o,a,n,this.makeCallback(u,A)))}writeSync(e,r,o,a,n){return typeof r=="string"?this.realFs.writeSync(e,r,o):this.realFs.writeSync(e,r,o,a,n)}async closePromise(e){await new Promise((r,o)=>{this.realFs.close(e,this.makeCallback(r,o))})}closeSync(e){this.realFs.closeSync(e)}createReadStream(e,r){let o=e!==null?ue.fromPortablePath(e):e;return this.realFs.createReadStream(o,r)}createWriteStream(e,r){let o=e!==null?ue.fromPortablePath(e):e;return this.realFs.createWriteStream(o,r)}async realpathPromise(e){return await new Promise((r,o)=>{this.realFs.realpath(ue.fromPortablePath(e),{},this.makeCallback(r,o))}).then(r=>ue.toPortablePath(r))}realpathSync(e){return ue.toPortablePath(this.realFs.realpathSync(ue.fromPortablePath(e),{}))}async existsPromise(e){return await new Promise(r=>{this.realFs.exists(ue.fromPortablePath(e),r)})}accessSync(e,r){return this.realFs.accessSync(ue.fromPortablePath(e),r)}async accessPromise(e,r){return await new Promise((o,a)=>{this.realFs.access(ue.fromPortablePath(e),r,this.makeCallback(o,a))})}existsSync(e){return this.realFs.existsSync(ue.fromPortablePath(e))}async statPromise(e,r){return await new Promise((o,a)=>{r?this.realFs.stat(ue.fromPortablePath(e),r,this.makeCallback(o,a)):this.realFs.stat(ue.fromPortablePath(e),this.makeCallback(o,a))})}statSync(e,r){return r?this.realFs.statSync(ue.fromPortablePath(e),r):this.realFs.statSync(ue.fromPortablePath(e))}async fstatPromise(e,r){return await new Promise((o,a)=>{r?this.realFs.fstat(e,r,this.makeCallback(o,a)):this.realFs.fstat(e,this.makeCallback(o,a))})}fstatSync(e,r){return r?this.realFs.fstatSync(e,r):this.realFs.fstatSync(e)}async lstatPromise(e,r){return await new Promise((o,a)=>{r?this.realFs.lstat(ue.fromPortablePath(e),r,this.makeCallback(o,a)):this.realFs.lstat(ue.fromPortablePath(e),this.makeCallback(o,a))})}lstatSync(e,r){return r?this.realFs.lstatSync(ue.fromPortablePath(e),r):this.realFs.lstatSync(ue.fromPortablePath(e))}async fchmodPromise(e,r){return await new Promise((o,a)=>{this.realFs.fchmod(e,r,this.makeCallback(o,a))})}fchmodSync(e,r){return this.realFs.fchmodSync(e,r)}async chmodPromise(e,r){return await new Promise((o,a)=>{this.realFs.chmod(ue.fromPortablePath(e),r,this.makeCallback(o,a))})}chmodSync(e,r){return this.realFs.chmodSync(ue.fromPortablePath(e),r)}async fchownPromise(e,r,o){return await new Promise((a,n)=>{this.realFs.fchown(e,r,o,this.makeCallback(a,n))})}fchownSync(e,r,o){return this.realFs.fchownSync(e,r,o)}async chownPromise(e,r,o){return await new Promise((a,n)=>{this.realFs.chown(ue.fromPortablePath(e),r,o,this.makeCallback(a,n))})}chownSync(e,r,o){return this.realFs.chownSync(ue.fromPortablePath(e),r,o)}async renamePromise(e,r){return await new Promise((o,a)=>{this.realFs.rename(ue.fromPortablePath(e),ue.fromPortablePath(r),this.makeCallback(o,a))})}renameSync(e,r){return this.realFs.renameSync(ue.fromPortablePath(e),ue.fromPortablePath(r))}async copyFilePromise(e,r,o=0){return await new Promise((a,n)=>{this.realFs.copyFile(ue.fromPortablePath(e),ue.fromPortablePath(r),o,this.makeCallback(a,n))})}copyFileSync(e,r,o=0){return this.realFs.copyFileSync(ue.fromPortablePath(e),ue.fromPortablePath(r),o)}async appendFilePromise(e,r,o){return await new Promise((a,n)=>{let u=typeof e=="string"?ue.fromPortablePath(e):e;o?this.realFs.appendFile(u,r,o,this.makeCallback(a,n)):this.realFs.appendFile(u,r,this.makeCallback(a,n))})}appendFileSync(e,r,o){let a=typeof e=="string"?ue.fromPortablePath(e):e;o?this.realFs.appendFileSync(a,r,o):this.realFs.appendFileSync(a,r)}async writeFilePromise(e,r,o){return await new Promise((a,n)=>{let u=typeof e=="string"?ue.fromPortablePath(e):e;o?this.realFs.writeFile(u,r,o,this.makeCallback(a,n)):this.realFs.writeFile(u,r,this.makeCallback(a,n))})}writeFileSync(e,r,o){let a=typeof e=="string"?ue.fromPortablePath(e):e;o?this.realFs.writeFileSync(a,r,o):this.realFs.writeFileSync(a,r)}async unlinkPromise(e){return await new Promise((r,o)=>{this.realFs.unlink(ue.fromPortablePath(e),this.makeCallback(r,o))})}unlinkSync(e){return this.realFs.unlinkSync(ue.fromPortablePath(e))}async utimesPromise(e,r,o){return await new Promise((a,n)=>{this.realFs.utimes(ue.fromPortablePath(e),r,o,this.makeCallback(a,n))})}utimesSync(e,r,o){this.realFs.utimesSync(ue.fromPortablePath(e),r,o)}async lutimesPromise(e,r,o){return await new Promise((a,n)=>{this.realFs.lutimes(ue.fromPortablePath(e),r,o,this.makeCallback(a,n))})}lutimesSync(e,r,o){this.realFs.lutimesSync(ue.fromPortablePath(e),r,o)}async mkdirPromise(e,r){return await new Promise((o,a)=>{this.realFs.mkdir(ue.fromPortablePath(e),r,this.makeCallback(o,a))})}mkdirSync(e,r){return this.realFs.mkdirSync(ue.fromPortablePath(e),r)}async rmdirPromise(e,r){return await new Promise((o,a)=>{r?this.realFs.rmdir(ue.fromPortablePath(e),r,this.makeCallback(o,a)):this.realFs.rmdir(ue.fromPortablePath(e),this.makeCallback(o,a))})}rmdirSync(e,r){return this.realFs.rmdirSync(ue.fromPortablePath(e),r)}async rmPromise(e,r){return await new Promise((o,a)=>{r?this.realFs.rm(ue.fromPortablePath(e),r,this.makeCallback(o,a)):this.realFs.rm(ue.fromPortablePath(e),this.makeCallback(o,a))})}rmSync(e,r){return this.realFs.rmSync(ue.fromPortablePath(e),r)}async linkPromise(e,r){return await new Promise((o,a)=>{this.realFs.link(ue.fromPortablePath(e),ue.fromPortablePath(r),this.makeCallback(o,a))})}linkSync(e,r){return this.realFs.linkSync(ue.fromPortablePath(e),ue.fromPortablePath(r))}async symlinkPromise(e,r,o){return await new Promise((a,n)=>{this.realFs.symlink(ue.fromPortablePath(e.replace(/\/+$/,"")),ue.fromPortablePath(r),o,this.makeCallback(a,n))})}symlinkSync(e,r,o){return this.realFs.symlinkSync(ue.fromPortablePath(e.replace(/\/+$/,"")),ue.fromPortablePath(r),o)}async readFilePromise(e,r){return await new Promise((o,a)=>{let n=typeof e=="string"?ue.fromPortablePath(e):e;this.realFs.readFile(n,r,this.makeCallback(o,a))})}readFileSync(e,r){let o=typeof e=="string"?ue.fromPortablePath(e):e;return this.realFs.readFileSync(o,r)}async readdirPromise(e,r){return await new Promise((o,a)=>{r?r.recursive&&process.platform==="win32"?r.withFileTypes?this.realFs.readdir(ue.fromPortablePath(e),r,this.makeCallback(n=>o(n.map(U7)),a)):this.realFs.readdir(ue.fromPortablePath(e),r,this.makeCallback(n=>o(n.map(ue.toPortablePath)),a)):this.realFs.readdir(ue.fromPortablePath(e),r,this.makeCallback(o,a)):this.realFs.readdir(ue.fromPortablePath(e),this.makeCallback(o,a))})}readdirSync(e,r){return r?r.recursive&&process.platform==="win32"?r.withFileTypes?this.realFs.readdirSync(ue.fromPortablePath(e),r).map(U7):this.realFs.readdirSync(ue.fromPortablePath(e),r).map(ue.toPortablePath):this.realFs.readdirSync(ue.fromPortablePath(e),r):this.realFs.readdirSync(ue.fromPortablePath(e))}async readlinkPromise(e){return await new Promise((r,o)=>{this.realFs.readlink(ue.fromPortablePath(e),this.makeCallback(r,o))}).then(r=>ue.toPortablePath(r))}readlinkSync(e){return ue.toPortablePath(this.realFs.readlinkSync(ue.fromPortablePath(e)))}async truncatePromise(e,r){return await new Promise((o,a)=>{this.realFs.truncate(ue.fromPortablePath(e),r,this.makeCallback(o,a))})}truncateSync(e,r){return this.realFs.truncateSync(ue.fromPortablePath(e),r)}async ftruncatePromise(e,r){return await new Promise((o,a)=>{this.realFs.ftruncate(e,r,this.makeCallback(o,a))})}ftruncateSync(e,r){return this.realFs.ftruncateSync(e,r)}watch(e,r,o){return this.realFs.watch(ue.fromPortablePath(e),r,o)}watchFile(e,r,o){return this.realFs.watchFile(ue.fromPortablePath(e),r,o)}unwatchFile(e,r){return this.realFs.unwatchFile(ue.fromPortablePath(e),r)}makeCallback(e,r){return(o,a)=>{o?r(o):e(a)}}}});var gn,H7=Et(()=>{O0();gf();Ia();gn=class extends Ss{constructor(e,{baseFs:r=new Tn}={}){super(V),this.target=this.pathUtils.normalize(e),this.baseFs=r}getRealPath(){return this.pathUtils.resolve(this.baseFs.getRealPath(),this.target)}resolve(e){return this.pathUtils.isAbsolute(e)?V.normalize(e):this.baseFs.resolve(V.join(this.target,e))}mapFromBase(e){return e}mapToBase(e){return this.pathUtils.isAbsolute(e)?e:this.pathUtils.join(this.target,e)}}});var q7,qu,j7=Et(()=>{O0();gf();Ia();q7=It.root,qu=class extends Ss{constructor(e,{baseFs:r=new Tn}={}){super(V),this.target=this.pathUtils.resolve(It.root,e),this.baseFs=r}getRealPath(){return this.pathUtils.resolve(this.baseFs.getRealPath(),this.pathUtils.relative(It.root,this.target))}getTarget(){return this.target}getBaseFs(){return this.baseFs}mapToBase(e){let r=this.pathUtils.normalize(e);if(this.pathUtils.isAbsolute(e))return this.pathUtils.resolve(this.target,this.pathUtils.relative(q7,e));if(r.match(/^\.\.\/?/))throw new Error(`Resolving this path (${e}) would escape the jail`);return this.pathUtils.resolve(this.target,e)}mapFromBase(e){return this.pathUtils.resolve(q7,this.pathUtils.relative(this.target,e))}}});var Gd,G7=Et(()=>{gf();Gd=class extends Ss{constructor(r,o){super(o);this.instance=null;this.factory=r}get baseFs(){return this.instance||(this.instance=this.factory()),this.instance}set baseFs(r){this.instance=r}mapFromBase(r){return r}mapToBase(r){return r}}});var U0,Ba,Op,Y7=Et(()=>{U0=ve("fs");M0();O0();TR();oD();Ia();Ba=4278190080,Op=class extends _u{constructor({baseFs:r=new Tn,filter:o=null,magicByte:a=42,maxOpenFiles:n=1/0,useCache:u=!0,maxAge:A=5e3,typeCheck:p=U0.constants.S_IFREG,getMountPoint:h,factoryPromise:E,factorySync:I}){if(Math.floor(a)!==a||!(a>1&&a<=127))throw new Error("The magic byte must be set to a round value between 1 and 127 included");super();this.fdMap=new Map;this.nextFd=3;this.isMount=new Set;this.notMount=new Set;this.realPaths=new Map;this.limitOpenFilesTimeout=null;this.baseFs=r,this.mountInstances=u?new Map:null,this.factoryPromise=E,this.factorySync=I,this.filter=o,this.getMountPoint=h,this.magic=a<<24,this.maxAge=A,this.maxOpenFiles=n,this.typeCheck=p}getExtractHint(r){return this.baseFs.getExtractHint(r)}getRealPath(){return this.baseFs.getRealPath()}saveAndClose(){if(N0(this),this.mountInstances)for(let[r,{childFs:o}]of this.mountInstances.entries())o.saveAndClose?.(),this.mountInstances.delete(r)}discardAndClose(){if(N0(this),this.mountInstances)for(let[r,{childFs:o}]of this.mountInstances.entries())o.discardAndClose?.(),this.mountInstances.delete(r)}resolve(r){return this.baseFs.resolve(r)}remapFd(r,o){let a=this.nextFd++|this.magic;return this.fdMap.set(a,[r,o]),a}async openPromise(r,o,a){return await this.makeCallPromise(r,async()=>await this.baseFs.openPromise(r,o,a),async(n,{subPath:u})=>this.remapFd(n,await n.openPromise(u,o,a)))}openSync(r,o,a){return this.makeCallSync(r,()=>this.baseFs.openSync(r,o,a),(n,{subPath:u})=>this.remapFd(n,n.openSync(u,o,a)))}async opendirPromise(r,o){return await this.makeCallPromise(r,async()=>await this.baseFs.opendirPromise(r,o),async(a,{subPath:n})=>await a.opendirPromise(n,o),{requireSubpath:!1})}opendirSync(r,o){return this.makeCallSync(r,()=>this.baseFs.opendirSync(r,o),(a,{subPath:n})=>a.opendirSync(n,o),{requireSubpath:!1})}async readPromise(r,o,a,n,u){if((r&Ba)!==this.magic)return await this.baseFs.readPromise(r,o,a,n,u);let A=this.fdMap.get(r);if(typeof A>"u")throw Io("read");let[p,h]=A;return await p.readPromise(h,o,a,n,u)}readSync(r,o,a,n,u){if((r&Ba)!==this.magic)return this.baseFs.readSync(r,o,a,n,u);let A=this.fdMap.get(r);if(typeof A>"u")throw Io("readSync");let[p,h]=A;return p.readSync(h,o,a,n,u)}async writePromise(r,o,a,n,u){if((r&Ba)!==this.magic)return typeof o=="string"?await this.baseFs.writePromise(r,o,a):await this.baseFs.writePromise(r,o,a,n,u);let A=this.fdMap.get(r);if(typeof A>"u")throw Io("write");let[p,h]=A;return typeof o=="string"?await p.writePromise(h,o,a):await p.writePromise(h,o,a,n,u)}writeSync(r,o,a,n,u){if((r&Ba)!==this.magic)return typeof o=="string"?this.baseFs.writeSync(r,o,a):this.baseFs.writeSync(r,o,a,n,u);let A=this.fdMap.get(r);if(typeof A>"u")throw Io("writeSync");let[p,h]=A;return typeof o=="string"?p.writeSync(h,o,a):p.writeSync(h,o,a,n,u)}async closePromise(r){if((r&Ba)!==this.magic)return await this.baseFs.closePromise(r);let o=this.fdMap.get(r);if(typeof o>"u")throw Io("close");this.fdMap.delete(r);let[a,n]=o;return await a.closePromise(n)}closeSync(r){if((r&Ba)!==this.magic)return this.baseFs.closeSync(r);let o=this.fdMap.get(r);if(typeof o>"u")throw Io("closeSync");this.fdMap.delete(r);let[a,n]=o;return a.closeSync(n)}createReadStream(r,o){return r===null?this.baseFs.createReadStream(r,o):this.makeCallSync(r,()=>this.baseFs.createReadStream(r,o),(a,{archivePath:n,subPath:u})=>{let A=a.createReadStream(u,o);return A.path=ue.fromPortablePath(this.pathUtils.join(n,u)),A})}createWriteStream(r,o){return r===null?this.baseFs.createWriteStream(r,o):this.makeCallSync(r,()=>this.baseFs.createWriteStream(r,o),(a,{subPath:n})=>a.createWriteStream(n,o))}async realpathPromise(r){return await this.makeCallPromise(r,async()=>await this.baseFs.realpathPromise(r),async(o,{archivePath:a,subPath:n})=>{let u=this.realPaths.get(a);return typeof u>"u"&&(u=await this.baseFs.realpathPromise(a),this.realPaths.set(a,u)),this.pathUtils.join(u,this.pathUtils.relative(It.root,await o.realpathPromise(n)))})}realpathSync(r){return this.makeCallSync(r,()=>this.baseFs.realpathSync(r),(o,{archivePath:a,subPath:n})=>{let u=this.realPaths.get(a);return typeof u>"u"&&(u=this.baseFs.realpathSync(a),this.realPaths.set(a,u)),this.pathUtils.join(u,this.pathUtils.relative(It.root,o.realpathSync(n)))})}async existsPromise(r){return await this.makeCallPromise(r,async()=>await this.baseFs.existsPromise(r),async(o,{subPath:a})=>await o.existsPromise(a))}existsSync(r){return this.makeCallSync(r,()=>this.baseFs.existsSync(r),(o,{subPath:a})=>o.existsSync(a))}async accessPromise(r,o){return await this.makeCallPromise(r,async()=>await this.baseFs.accessPromise(r,o),async(a,{subPath:n})=>await a.accessPromise(n,o))}accessSync(r,o){return this.makeCallSync(r,()=>this.baseFs.accessSync(r,o),(a,{subPath:n})=>a.accessSync(n,o))}async statPromise(r,o){return await this.makeCallPromise(r,async()=>await this.baseFs.statPromise(r,o),async(a,{subPath:n})=>await a.statPromise(n,o))}statSync(r,o){return this.makeCallSync(r,()=>this.baseFs.statSync(r,o),(a,{subPath:n})=>a.statSync(n,o))}async fstatPromise(r,o){if((r&Ba)!==this.magic)return this.baseFs.fstatPromise(r,o);let a=this.fdMap.get(r);if(typeof a>"u")throw Io("fstat");let[n,u]=a;return n.fstatPromise(u,o)}fstatSync(r,o){if((r&Ba)!==this.magic)return this.baseFs.fstatSync(r,o);let a=this.fdMap.get(r);if(typeof a>"u")throw Io("fstatSync");let[n,u]=a;return n.fstatSync(u,o)}async lstatPromise(r,o){return await this.makeCallPromise(r,async()=>await this.baseFs.lstatPromise(r,o),async(a,{subPath:n})=>await a.lstatPromise(n,o))}lstatSync(r,o){return this.makeCallSync(r,()=>this.baseFs.lstatSync(r,o),(a,{subPath:n})=>a.lstatSync(n,o))}async fchmodPromise(r,o){if((r&Ba)!==this.magic)return this.baseFs.fchmodPromise(r,o);let a=this.fdMap.get(r);if(typeof a>"u")throw Io("fchmod");let[n,u]=a;return n.fchmodPromise(u,o)}fchmodSync(r,o){if((r&Ba)!==this.magic)return this.baseFs.fchmodSync(r,o);let a=this.fdMap.get(r);if(typeof a>"u")throw Io("fchmodSync");let[n,u]=a;return n.fchmodSync(u,o)}async chmodPromise(r,o){return await this.makeCallPromise(r,async()=>await this.baseFs.chmodPromise(r,o),async(a,{subPath:n})=>await a.chmodPromise(n,o))}chmodSync(r,o){return this.makeCallSync(r,()=>this.baseFs.chmodSync(r,o),(a,{subPath:n})=>a.chmodSync(n,o))}async fchownPromise(r,o,a){if((r&Ba)!==this.magic)return this.baseFs.fchownPromise(r,o,a);let n=this.fdMap.get(r);if(typeof n>"u")throw Io("fchown");let[u,A]=n;return u.fchownPromise(A,o,a)}fchownSync(r,o,a){if((r&Ba)!==this.magic)return this.baseFs.fchownSync(r,o,a);let n=this.fdMap.get(r);if(typeof n>"u")throw Io("fchownSync");let[u,A]=n;return u.fchownSync(A,o,a)}async chownPromise(r,o,a){return await this.makeCallPromise(r,async()=>await this.baseFs.chownPromise(r,o,a),async(n,{subPath:u})=>await n.chownPromise(u,o,a))}chownSync(r,o,a){return this.makeCallSync(r,()=>this.baseFs.chownSync(r,o,a),(n,{subPath:u})=>n.chownSync(u,o,a))}async renamePromise(r,o){return await this.makeCallPromise(r,async()=>await this.makeCallPromise(o,async()=>await this.baseFs.renamePromise(r,o),async()=>{throw Object.assign(new Error("EEXDEV: cross-device link not permitted"),{code:"EEXDEV"})}),async(a,{subPath:n})=>await this.makeCallPromise(o,async()=>{throw Object.assign(new Error("EEXDEV: cross-device link not permitted"),{code:"EEXDEV"})},async(u,{subPath:A})=>{if(a!==u)throw Object.assign(new Error("EEXDEV: cross-device link not permitted"),{code:"EEXDEV"});return await a.renamePromise(n,A)}))}renameSync(r,o){return this.makeCallSync(r,()=>this.makeCallSync(o,()=>this.baseFs.renameSync(r,o),()=>{throw Object.assign(new Error("EEXDEV: cross-device link not permitted"),{code:"EEXDEV"})}),(a,{subPath:n})=>this.makeCallSync(o,()=>{throw Object.assign(new Error("EEXDEV: cross-device link not permitted"),{code:"EEXDEV"})},(u,{subPath:A})=>{if(a!==u)throw Object.assign(new Error("EEXDEV: cross-device link not permitted"),{code:"EEXDEV"});return a.renameSync(n,A)}))}async copyFilePromise(r,o,a=0){let n=async(u,A,p,h)=>{if(a&U0.constants.COPYFILE_FICLONE_FORCE)throw Object.assign(new Error(`EXDEV: cross-device clone not permitted, copyfile '${A}' -> ${h}'`),{code:"EXDEV"});if(a&U0.constants.COPYFILE_EXCL&&await this.existsPromise(A))throw Object.assign(new Error(`EEXIST: file already exists, copyfile '${A}' -> '${h}'`),{code:"EEXIST"});let E;try{E=await u.readFilePromise(A)}catch{throw Object.assign(new Error(`EINVAL: invalid argument, copyfile '${A}' -> '${h}'`),{code:"EINVAL"})}await p.writeFilePromise(h,E)};return await this.makeCallPromise(r,async()=>await this.makeCallPromise(o,async()=>await this.baseFs.copyFilePromise(r,o,a),async(u,{subPath:A})=>await n(this.baseFs,r,u,A)),async(u,{subPath:A})=>await this.makeCallPromise(o,async()=>await n(u,A,this.baseFs,o),async(p,{subPath:h})=>u!==p?await n(u,A,p,h):await u.copyFilePromise(A,h,a)))}copyFileSync(r,o,a=0){let n=(u,A,p,h)=>{if(a&U0.constants.COPYFILE_FICLONE_FORCE)throw Object.assign(new Error(`EXDEV: cross-device clone not permitted, copyfile '${A}' -> ${h}'`),{code:"EXDEV"});if(a&U0.constants.COPYFILE_EXCL&&this.existsSync(A))throw Object.assign(new Error(`EEXIST: file already exists, copyfile '${A}' -> '${h}'`),{code:"EEXIST"});let E;try{E=u.readFileSync(A)}catch{throw Object.assign(new Error(`EINVAL: invalid argument, copyfile '${A}' -> '${h}'`),{code:"EINVAL"})}p.writeFileSync(h,E)};return this.makeCallSync(r,()=>this.makeCallSync(o,()=>this.baseFs.copyFileSync(r,o,a),(u,{subPath:A})=>n(this.baseFs,r,u,A)),(u,{subPath:A})=>this.makeCallSync(o,()=>n(u,A,this.baseFs,o),(p,{subPath:h})=>u!==p?n(u,A,p,h):u.copyFileSync(A,h,a)))}async appendFilePromise(r,o,a){return await this.makeCallPromise(r,async()=>await this.baseFs.appendFilePromise(r,o,a),async(n,{subPath:u})=>await n.appendFilePromise(u,o,a))}appendFileSync(r,o,a){return this.makeCallSync(r,()=>this.baseFs.appendFileSync(r,o,a),(n,{subPath:u})=>n.appendFileSync(u,o,a))}async writeFilePromise(r,o,a){return await this.makeCallPromise(r,async()=>await this.baseFs.writeFilePromise(r,o,a),async(n,{subPath:u})=>await n.writeFilePromise(u,o,a))}writeFileSync(r,o,a){return this.makeCallSync(r,()=>this.baseFs.writeFileSync(r,o,a),(n,{subPath:u})=>n.writeFileSync(u,o,a))}async unlinkPromise(r){return await this.makeCallPromise(r,async()=>await this.baseFs.unlinkPromise(r),async(o,{subPath:a})=>await o.unlinkPromise(a))}unlinkSync(r){return this.makeCallSync(r,()=>this.baseFs.unlinkSync(r),(o,{subPath:a})=>o.unlinkSync(a))}async utimesPromise(r,o,a){return await this.makeCallPromise(r,async()=>await this.baseFs.utimesPromise(r,o,a),async(n,{subPath:u})=>await n.utimesPromise(u,o,a))}utimesSync(r,o,a){return this.makeCallSync(r,()=>this.baseFs.utimesSync(r,o,a),(n,{subPath:u})=>n.utimesSync(u,o,a))}async lutimesPromise(r,o,a){return await this.makeCallPromise(r,async()=>await this.baseFs.lutimesPromise(r,o,a),async(n,{subPath:u})=>await n.lutimesPromise(u,o,a))}lutimesSync(r,o,a){return this.makeCallSync(r,()=>this.baseFs.lutimesSync(r,o,a),(n,{subPath:u})=>n.lutimesSync(u,o,a))}async mkdirPromise(r,o){return await this.makeCallPromise(r,async()=>await this.baseFs.mkdirPromise(r,o),async(a,{subPath:n})=>await a.mkdirPromise(n,o))}mkdirSync(r,o){return this.makeCallSync(r,()=>this.baseFs.mkdirSync(r,o),(a,{subPath:n})=>a.mkdirSync(n,o))}async rmdirPromise(r,o){return await this.makeCallPromise(r,async()=>await this.baseFs.rmdirPromise(r,o),async(a,{subPath:n})=>await a.rmdirPromise(n,o))}rmdirSync(r,o){return this.makeCallSync(r,()=>this.baseFs.rmdirSync(r,o),(a,{subPath:n})=>a.rmdirSync(n,o))}async rmPromise(r,o){return await this.makeCallPromise(r,async()=>await this.baseFs.rmPromise(r,o),async(a,{subPath:n})=>await a.rmPromise(n,o))}rmSync(r,o){return this.makeCallSync(r,()=>this.baseFs.rmSync(r,o),(a,{subPath:n})=>a.rmSync(n,o))}async linkPromise(r,o){return await this.makeCallPromise(o,async()=>await this.baseFs.linkPromise(r,o),async(a,{subPath:n})=>await a.linkPromise(r,n))}linkSync(r,o){return this.makeCallSync(o,()=>this.baseFs.linkSync(r,o),(a,{subPath:n})=>a.linkSync(r,n))}async symlinkPromise(r,o,a){return await this.makeCallPromise(o,async()=>await this.baseFs.symlinkPromise(r,o,a),async(n,{subPath:u})=>await n.symlinkPromise(r,u))}symlinkSync(r,o,a){return this.makeCallSync(o,()=>this.baseFs.symlinkSync(r,o,a),(n,{subPath:u})=>n.symlinkSync(r,u))}async readFilePromise(r,o){return this.makeCallPromise(r,async()=>await this.baseFs.readFilePromise(r,o),async(a,{subPath:n})=>await a.readFilePromise(n,o))}readFileSync(r,o){return this.makeCallSync(r,()=>this.baseFs.readFileSync(r,o),(a,{subPath:n})=>a.readFileSync(n,o))}async readdirPromise(r,o){return await this.makeCallPromise(r,async()=>await this.baseFs.readdirPromise(r,o),async(a,{subPath:n})=>await a.readdirPromise(n,o),{requireSubpath:!1})}readdirSync(r,o){return this.makeCallSync(r,()=>this.baseFs.readdirSync(r,o),(a,{subPath:n})=>a.readdirSync(n,o),{requireSubpath:!1})}async readlinkPromise(r){return await this.makeCallPromise(r,async()=>await this.baseFs.readlinkPromise(r),async(o,{subPath:a})=>await o.readlinkPromise(a))}readlinkSync(r){return this.makeCallSync(r,()=>this.baseFs.readlinkSync(r),(o,{subPath:a})=>o.readlinkSync(a))}async truncatePromise(r,o){return await this.makeCallPromise(r,async()=>await this.baseFs.truncatePromise(r,o),async(a,{subPath:n})=>await a.truncatePromise(n,o))}truncateSync(r,o){return this.makeCallSync(r,()=>this.baseFs.truncateSync(r,o),(a,{subPath:n})=>a.truncateSync(n,o))}async ftruncatePromise(r,o){if((r&Ba)!==this.magic)return this.baseFs.ftruncatePromise(r,o);let a=this.fdMap.get(r);if(typeof a>"u")throw Io("ftruncate");let[n,u]=a;return n.ftruncatePromise(u,o)}ftruncateSync(r,o){if((r&Ba)!==this.magic)return this.baseFs.ftruncateSync(r,o);let a=this.fdMap.get(r);if(typeof a>"u")throw Io("ftruncateSync");let[n,u]=a;return n.ftruncateSync(u,o)}watch(r,o,a){return this.makeCallSync(r,()=>this.baseFs.watch(r,o,a),(n,{subPath:u})=>n.watch(u,o,a))}watchFile(r,o,a){return this.makeCallSync(r,()=>this.baseFs.watchFile(r,o,a),()=>jd(this,r,o,a))}unwatchFile(r,o){return this.makeCallSync(r,()=>this.baseFs.unwatchFile(r,o),()=>T0(this,r,o))}async makeCallPromise(r,o,a,{requireSubpath:n=!0}={}){if(typeof r!="string")return await o();let u=this.resolve(r),A=this.findMount(u);return A?n&&A.subPath==="/"?await o():await this.getMountPromise(A.archivePath,async p=>await a(p,A)):await o()}makeCallSync(r,o,a,{requireSubpath:n=!0}={}){if(typeof r!="string")return o();let u=this.resolve(r),A=this.findMount(u);return!A||n&&A.subPath==="/"?o():this.getMountSync(A.archivePath,p=>a(p,A))}findMount(r){if(this.filter&&!this.filter.test(r))return null;let o="";for(;;){let a=r.substring(o.length),n=this.getMountPoint(a,o);if(!n)return null;if(o=this.pathUtils.join(o,n),!this.isMount.has(o)){if(this.notMount.has(o))continue;try{if(this.typeCheck!==null&&(this.baseFs.lstatSync(o).mode&U0.constants.S_IFMT)!==this.typeCheck){this.notMount.add(o);continue}}catch{return null}this.isMount.add(o)}return{archivePath:o,subPath:this.pathUtils.join(It.root,r.substring(o.length))}}}limitOpenFiles(r){if(this.mountInstances===null)return;let o=Date.now(),a=o+this.maxAge,n=r===null?0:this.mountInstances.size-r;for(let[u,{childFs:A,expiresAt:p,refCount:h}]of this.mountInstances.entries())if(!(h!==0||A.hasOpenFileHandles?.())){if(o>=p){A.saveAndClose?.(),this.mountInstances.delete(u),n-=1;continue}else if(r===null||n<=0){a=p;break}A.saveAndClose?.(),this.mountInstances.delete(u),n-=1}this.limitOpenFilesTimeout===null&&(r===null&&this.mountInstances.size>0||r!==null)&&isFinite(a)&&(this.limitOpenFilesTimeout=setTimeout(()=>{this.limitOpenFilesTimeout=null,this.limitOpenFiles(null)},a-o).unref())}async getMountPromise(r,o){if(this.mountInstances){let a=this.mountInstances.get(r);if(!a){let n=await this.factoryPromise(this.baseFs,r);a=this.mountInstances.get(r),a||(a={childFs:n(),expiresAt:0,refCount:0})}this.mountInstances.delete(r),this.limitOpenFiles(this.maxOpenFiles-1),this.mountInstances.set(r,a),a.expiresAt=Date.now()+this.maxAge,a.refCount+=1;try{return await o(a.childFs)}finally{a.refCount-=1}}else{let a=(await this.factoryPromise(this.baseFs,r))();try{return await o(a)}finally{a.saveAndClose?.()}}}getMountSync(r,o){if(this.mountInstances){let a=this.mountInstances.get(r);return a||(a={childFs:this.factorySync(this.baseFs,r),expiresAt:0,refCount:0}),this.mountInstances.delete(r),this.limitOpenFiles(this.maxOpenFiles-1),this.mountInstances.set(r,a),a.expiresAt=Date.now()+this.maxAge,o(a.childFs)}else{let a=this.factorySync(this.baseFs,r);try{return o(a)}finally{a.saveAndClose?.()}}}}});var Zt,pD,W7=Et(()=>{M0();Ia();Zt=()=>Object.assign(new Error("ENOSYS: unsupported filesystem access"),{code:"ENOSYS"}),pD=class t extends hf{static{this.instance=new t}constructor(){super(V)}getExtractHint(){throw Zt()}getRealPath(){throw Zt()}resolve(){throw Zt()}async openPromise(){throw Zt()}openSync(){throw Zt()}async opendirPromise(){throw Zt()}opendirSync(){throw Zt()}async readPromise(){throw Zt()}readSync(){throw Zt()}async writePromise(){throw Zt()}writeSync(){throw Zt()}async closePromise(){throw Zt()}closeSync(){throw Zt()}createWriteStream(){throw Zt()}createReadStream(){throw Zt()}async realpathPromise(){throw Zt()}realpathSync(){throw Zt()}async readdirPromise(){throw Zt()}readdirSync(){throw Zt()}async existsPromise(e){throw Zt()}existsSync(e){throw Zt()}async accessPromise(){throw Zt()}accessSync(){throw Zt()}async statPromise(){throw Zt()}statSync(){throw Zt()}async fstatPromise(e){throw Zt()}fstatSync(e){throw Zt()}async lstatPromise(e){throw Zt()}lstatSync(e){throw Zt()}async fchmodPromise(){throw Zt()}fchmodSync(){throw Zt()}async chmodPromise(){throw Zt()}chmodSync(){throw Zt()}async fchownPromise(){throw Zt()}fchownSync(){throw Zt()}async chownPromise(){throw Zt()}chownSync(){throw Zt()}async mkdirPromise(){throw Zt()}mkdirSync(){throw Zt()}async rmdirPromise(){throw Zt()}rmdirSync(){throw Zt()}async rmPromise(){throw Zt()}rmSync(){throw Zt()}async linkPromise(){throw Zt()}linkSync(){throw Zt()}async symlinkPromise(){throw Zt()}symlinkSync(){throw Zt()}async renamePromise(){throw Zt()}renameSync(){throw Zt()}async copyFilePromise(){throw Zt()}copyFileSync(){throw Zt()}async appendFilePromise(){throw Zt()}appendFileSync(){throw Zt()}async writeFilePromise(){throw Zt()}writeFileSync(){throw Zt()}async unlinkPromise(){throw Zt()}unlinkSync(){throw Zt()}async utimesPromise(){throw Zt()}utimesSync(){throw Zt()}async lutimesPromise(){throw Zt()}lutimesSync(){throw Zt()}async readFilePromise(){throw Zt()}readFileSync(){throw Zt()}async readlinkPromise(){throw Zt()}readlinkSync(){throw Zt()}async truncatePromise(){throw Zt()}truncateSync(){throw Zt()}async ftruncatePromise(e,r){throw Zt()}ftruncateSync(e,r){throw Zt()}watch(){throw Zt()}watchFile(){throw Zt()}unwatchFile(){throw Zt()}}});var Up,K7=Et(()=>{gf();Ia();Up=class extends Ss{constructor(e){super(ue),this.baseFs=e}mapFromBase(e){return ue.fromPortablePath(e)}mapToBase(e){return ue.toPortablePath(e)}}});var F_e,NR,R_e,zs,V7=Et(()=>{O0();gf();Ia();F_e=/^[0-9]+$/,NR=/^(\/(?:[^/]+\/)*?(?:\$\$virtual|__virtual__))((?:\/((?:[^/]+-)?[a-f0-9]+)(?:\/([^/]+))?)?((?:\/.*)?))$/,R_e=/^([^/]+-)?[a-f0-9]+$/,zs=class t extends Ss{static makeVirtualPath(e,r,o){if(V.basename(e)!=="__virtual__")throw new Error('Assertion failed: Virtual folders must be named "__virtual__"');if(!V.basename(r).match(R_e))throw new Error("Assertion failed: Virtual components must be ended by an hexadecimal hash");let n=V.relative(V.dirname(e),o).split("/"),u=0;for(;u{LR=Ze(ve("buffer")),z7=ve("url"),J7=ve("util");gf();Ia();hD=class extends Ss{constructor(e){super(ue),this.baseFs=e}mapFromBase(e){return e}mapToBase(e){if(typeof e=="string")return e;if(e instanceof URL)return(0,z7.fileURLToPath)(e);if(Buffer.isBuffer(e)){let r=e.toString();if(!T_e(e,r))throw new Error("Non-utf8 buffers are not supported at the moment. Please upvote the following issue if you encounter this error: https://github.com/yarnpkg/berry/issues/4942");return r}throw new Error(`Unsupported path type: ${(0,J7.inspect)(e)}`)}}});var rY,Bo,df,_p,gD,dD,Yd,Nc,Lc,Z7,$7,eY,tY,Sw,nY=Et(()=>{rY=ve("readline"),Bo=Symbol("kBaseFs"),df=Symbol("kFd"),_p=Symbol("kClosePromise"),gD=Symbol("kCloseResolve"),dD=Symbol("kCloseReject"),Yd=Symbol("kRefs"),Nc=Symbol("kRef"),Lc=Symbol("kUnref"),Sw=class{constructor(e,r){this[tY]=1;this[eY]=void 0;this[$7]=void 0;this[Z7]=void 0;this[Bo]=r,this[df]=e}get fd(){return this[df]}async appendFile(e,r){try{this[Nc](this.appendFile);let o=(typeof r=="string"?r:r?.encoding)??void 0;return await this[Bo].appendFilePromise(this.fd,e,o?{encoding:o}:void 0)}finally{this[Lc]()}}async chown(e,r){try{return this[Nc](this.chown),await this[Bo].fchownPromise(this.fd,e,r)}finally{this[Lc]()}}async chmod(e){try{return this[Nc](this.chmod),await this[Bo].fchmodPromise(this.fd,e)}finally{this[Lc]()}}createReadStream(e){return this[Bo].createReadStream(null,{...e,fd:this.fd})}createWriteStream(e){return this[Bo].createWriteStream(null,{...e,fd:this.fd})}datasync(){throw new Error("Method not implemented.")}sync(){throw new Error("Method not implemented.")}async read(e,r,o,a){try{this[Nc](this.read);let n;return Buffer.isBuffer(e)?n=e:(e??={},n=e.buffer??Buffer.alloc(16384),r=e.offset||0,o=e.length??n.byteLength,a=e.position??null),r??=0,o??=0,o===0?{bytesRead:o,buffer:n}:{bytesRead:await this[Bo].readPromise(this.fd,n,r,o,a),buffer:n}}finally{this[Lc]()}}async readFile(e){try{this[Nc](this.readFile);let r=(typeof e=="string"?e:e?.encoding)??void 0;return await this[Bo].readFilePromise(this.fd,r)}finally{this[Lc]()}}readLines(e){return(0,rY.createInterface)({input:this.createReadStream(e),crlfDelay:1/0})}async stat(e){try{return this[Nc](this.stat),await this[Bo].fstatPromise(this.fd,e)}finally{this[Lc]()}}async truncate(e){try{return this[Nc](this.truncate),await this[Bo].ftruncatePromise(this.fd,e)}finally{this[Lc]()}}utimes(e,r){throw new Error("Method not implemented.")}async writeFile(e,r){try{this[Nc](this.writeFile);let o=(typeof r=="string"?r:r?.encoding)??void 0;await this[Bo].writeFilePromise(this.fd,e,o)}finally{this[Lc]()}}async write(...e){try{if(this[Nc](this.write),ArrayBuffer.isView(e[0])){let[r,o,a,n]=e;return{bytesWritten:await this[Bo].writePromise(this.fd,r,o??void 0,a??void 0,n??void 0),buffer:r}}else{let[r,o,a]=e;return{bytesWritten:await this[Bo].writePromise(this.fd,r,o,a),buffer:r}}}finally{this[Lc]()}}async writev(e,r){try{this[Nc](this.writev);let o=0;if(typeof r<"u")for(let a of e){let n=await this.write(a,void 0,void 0,r);o+=n.bytesWritten,r+=n.bytesWritten}else for(let a of e){let n=await this.write(a);o+=n.bytesWritten}return{buffers:e,bytesWritten:o}}finally{this[Lc]()}}readv(e,r){throw new Error("Method not implemented.")}close(){if(this[df]===-1)return Promise.resolve();if(this[_p])return this[_p];if(this[Yd]--,this[Yd]===0){let e=this[df];this[df]=-1,this[_p]=this[Bo].closePromise(e).finally(()=>{this[_p]=void 0})}else this[_p]=new Promise((e,r)=>{this[gD]=e,this[dD]=r}).finally(()=>{this[_p]=void 0,this[dD]=void 0,this[gD]=void 0});return this[_p]}[(Bo,df,tY=Yd,eY=_p,$7=gD,Z7=dD,Nc)](e){if(this[df]===-1){let r=new Error("file closed");throw r.code="EBADF",r.syscall=e.name,r}this[Yd]++}[Lc](){if(this[Yd]--,this[Yd]===0){let e=this[df];this[df]=-1,this[Bo].closePromise(e).then(this[gD],this[dD])}}}});function xw(t,e){e=new hD(e);let r=(o,a,n)=>{let u=o[a];o[a]=n,typeof u?.[Wd.promisify.custom]<"u"&&(n[Wd.promisify.custom]=u[Wd.promisify.custom])};{r(t,"exists",(o,...a)=>{let u=typeof a[a.length-1]=="function"?a.pop():()=>{};process.nextTick(()=>{e.existsPromise(o).then(A=>{u(A)},()=>{u(!1)})})}),r(t,"read",(...o)=>{let[a,n,u,A,p,h]=o;if(o.length<=3){let E={};o.length<3?h=o[1]:(E=o[1],h=o[2]),{buffer:n=Buffer.alloc(16384),offset:u=0,length:A=n.byteLength,position:p}=E}if(u==null&&(u=0),A|=0,A===0){process.nextTick(()=>{h(null,0,n)});return}p==null&&(p=-1),process.nextTick(()=>{e.readPromise(a,n,u,A,p).then(E=>{h(null,E,n)},E=>{h(E,0,n)})})});for(let o of iY){let a=o.replace(/Promise$/,"");if(typeof t[a]>"u")continue;let n=e[o];if(typeof n>"u")continue;r(t,a,(...A)=>{let h=typeof A[A.length-1]=="function"?A.pop():()=>{};process.nextTick(()=>{n.apply(e,A).then(E=>{h(null,E)},E=>{h(E)})})})}t.realpath.native=t.realpath}{r(t,"existsSync",o=>{try{return e.existsSync(o)}catch{return!1}}),r(t,"readSync",(...o)=>{let[a,n,u,A,p]=o;return o.length<=3&&({offset:u=0,length:A=n.byteLength,position:p}=o[2]||{}),u==null&&(u=0),A|=0,A===0?0:(p==null&&(p=-1),e.readSync(a,n,u,A,p))});for(let o of N_e){let a=o;if(typeof t[a]>"u")continue;let n=e[o];typeof n>"u"||r(t,a,n.bind(e))}t.realpathSync.native=t.realpathSync}{let o=t.promises;for(let a of iY){let n=a.replace(/Promise$/,"");if(typeof o[n]>"u")continue;let u=e[a];typeof u>"u"||a!=="open"&&r(o,n,(A,...p)=>A instanceof Sw?A[n].apply(A,p):u.call(e,A,...p))}r(o,"open",async(...a)=>{let n=await e.openPromise(...a);return new Sw(n,e)})}t.read[Wd.promisify.custom]=async(o,a,...n)=>({bytesRead:await e.readPromise(o,a,...n),buffer:a}),t.write[Wd.promisify.custom]=async(o,a,...n)=>({bytesWritten:await e.writePromise(o,a,...n),buffer:a})}function mD(t,e){let r=Object.create(t);return xw(r,e),r}var Wd,N_e,iY,sY=Et(()=>{Wd=ve("util");X7();nY();N_e=new Set(["accessSync","appendFileSync","createReadStream","createWriteStream","chmodSync","fchmodSync","chownSync","fchownSync","closeSync","copyFileSync","linkSync","lstatSync","fstatSync","lutimesSync","mkdirSync","openSync","opendirSync","readlinkSync","readFileSync","readdirSync","readlinkSync","realpathSync","renameSync","rmdirSync","rmSync","statSync","symlinkSync","truncateSync","ftruncateSync","unlinkSync","unwatchFile","utimesSync","watch","watchFile","writeFileSync","writeSync"]),iY=new Set(["accessPromise","appendFilePromise","fchmodPromise","chmodPromise","fchownPromise","chownPromise","closePromise","copyFilePromise","linkPromise","fstatPromise","lstatPromise","lutimesPromise","mkdirPromise","openPromise","opendirPromise","readdirPromise","realpathPromise","readFilePromise","readdirPromise","readlinkPromise","renamePromise","rmdirPromise","rmPromise","statPromise","symlinkPromise","truncatePromise","ftruncatePromise","unlinkPromise","utimesPromise","writeFilePromise","writeSync"])});function oY(t){let e=Math.ceil(Math.random()*4294967296).toString(16).padStart(8,"0");return`${t}${e}`}function aY(){if(MR)return MR;let t=ue.toPortablePath(lY.default.tmpdir()),e=oe.realpathSync(t);return process.once("exit",()=>{oe.rmtempSync()}),MR={tmpdir:t,realTmpdir:e}}var lY,Mc,MR,oe,cY=Et(()=>{lY=Ze(ve("os"));O0();Ia();Mc=new Set,MR=null;oe=Object.assign(new Tn,{detachTemp(t){Mc.delete(t)},mktempSync(t){let{tmpdir:e,realTmpdir:r}=aY();for(;;){let o=oY("xfs-");try{this.mkdirSync(V.join(e,o))}catch(n){if(n.code==="EEXIST")continue;throw n}let a=V.join(r,o);if(Mc.add(a),typeof t>"u")return a;try{return t(a)}finally{if(Mc.has(a)){Mc.delete(a);try{this.removeSync(a)}catch{}}}}},async mktempPromise(t){let{tmpdir:e,realTmpdir:r}=aY();for(;;){let o=oY("xfs-");try{await this.mkdirPromise(V.join(e,o))}catch(n){if(n.code==="EEXIST")continue;throw n}let a=V.join(r,o);if(Mc.add(a),typeof t>"u")return a;try{return await t(a)}finally{if(Mc.has(a)){Mc.delete(a);try{await this.removePromise(a)}catch{}}}}},async rmtempPromise(){await Promise.all(Array.from(Mc.values()).map(async t=>{try{await oe.removePromise(t,{maxRetries:0}),Mc.delete(t)}catch{}}))},rmtempSync(){for(let t of Mc)try{oe.removeSync(t),Mc.delete(t)}catch{}}})});var kw={};Vt(kw,{AliasFS:()=>Hu,BasePortableFakeFS:()=>_u,CustomDir:()=>bw,CwdFS:()=>gn,FakeFS:()=>hf,Filename:()=>dr,JailFS:()=>qu,LazyFS:()=>Gd,MountFS:()=>Op,NoFS:()=>pD,NodeFS:()=>Tn,PortablePath:()=>It,PosixFS:()=>Up,ProxiedFS:()=>Ss,VirtualFS:()=>zs,constants:()=>Bi,errors:()=>nr,extendFs:()=>mD,normalizeLineEndings:()=>L0,npath:()=>ue,opendir:()=>uD,patchFs:()=>xw,ppath:()=>V,setupCopyIndex:()=>cD,statUtils:()=>wa,unwatchAllFiles:()=>N0,unwatchFile:()=>T0,watchFile:()=>jd,xfs:()=>oe});var Pt=Et(()=>{P7();oD();kR();RR();F7();TR();M0();Ia();Ia();O7();M0();H7();j7();G7();Y7();W7();O0();K7();gf();V7();sY();cY()});var hY=_((fSt,pY)=>{pY.exports=fY;fY.sync=M_e;var uY=ve("fs");function L_e(t,e){var r=e.pathExt!==void 0?e.pathExt:process.env.PATHEXT;if(!r||(r=r.split(";"),r.indexOf("")!==-1))return!0;for(var o=0;o{yY.exports=dY;dY.sync=O_e;var gY=ve("fs");function dY(t,e,r){gY.stat(t,function(o,a){r(o,o?!1:mY(a,e))})}function O_e(t,e){return mY(gY.statSync(t),e)}function mY(t,e){return t.isFile()&&U_e(t,e)}function U_e(t,e){var r=t.mode,o=t.uid,a=t.gid,n=e.uid!==void 0?e.uid:process.getuid&&process.getuid(),u=e.gid!==void 0?e.gid:process.getgid&&process.getgid(),A=parseInt("100",8),p=parseInt("010",8),h=parseInt("001",8),E=A|p,I=r&h||r&p&&a===u||r&A&&o===n||r&E&&n===0;return I}});var wY=_((gSt,CY)=>{var hSt=ve("fs"),yD;process.platform==="win32"||global.TESTING_WINDOWS?yD=hY():yD=EY();CY.exports=OR;OR.sync=__e;function OR(t,e,r){if(typeof e=="function"&&(r=e,e={}),!r){if(typeof Promise!="function")throw new TypeError("callback not provided");return new Promise(function(o,a){OR(t,e||{},function(n,u){n?a(n):o(u)})})}yD(t,e||{},function(o,a){o&&(o.code==="EACCES"||e&&e.ignoreErrors)&&(o=null,a=!1),r(o,a)})}function __e(t,e){try{return yD.sync(t,e||{})}catch(r){if(e&&e.ignoreErrors||r.code==="EACCES")return!1;throw r}}});var SY=_((dSt,bY)=>{var Kd=process.platform==="win32"||process.env.OSTYPE==="cygwin"||process.env.OSTYPE==="msys",IY=ve("path"),H_e=Kd?";":":",BY=wY(),vY=t=>Object.assign(new Error(`not found: ${t}`),{code:"ENOENT"}),DY=(t,e)=>{let r=e.colon||H_e,o=t.match(/\//)||Kd&&t.match(/\\/)?[""]:[...Kd?[process.cwd()]:[],...(e.path||process.env.PATH||"").split(r)],a=Kd?e.pathExt||process.env.PATHEXT||".EXE;.CMD;.BAT;.COM":"",n=Kd?a.split(r):[""];return Kd&&t.indexOf(".")!==-1&&n[0]!==""&&n.unshift(""),{pathEnv:o,pathExt:n,pathExtExe:a}},PY=(t,e,r)=>{typeof e=="function"&&(r=e,e={}),e||(e={});let{pathEnv:o,pathExt:a,pathExtExe:n}=DY(t,e),u=[],A=h=>new Promise((E,I)=>{if(h===o.length)return e.all&&u.length?E(u):I(vY(t));let v=o[h],x=/^".*"$/.test(v)?v.slice(1,-1):v,C=IY.join(x,t),R=!x&&/^\.[\\\/]/.test(t)?t.slice(0,2)+C:C;E(p(R,h,0))}),p=(h,E,I)=>new Promise((v,x)=>{if(I===a.length)return v(A(E+1));let C=a[I];BY(h+C,{pathExt:n},(R,L)=>{if(!R&&L)if(e.all)u.push(h+C);else return v(h+C);return v(p(h,E,I+1))})});return r?A(0).then(h=>r(null,h),r):A(0)},q_e=(t,e)=>{e=e||{};let{pathEnv:r,pathExt:o,pathExtExe:a}=DY(t,e),n=[];for(let u=0;u{"use strict";var xY=(t={})=>{let e=t.env||process.env;return(t.platform||process.platform)!=="win32"?"PATH":Object.keys(e).reverse().find(o=>o.toUpperCase()==="PATH")||"Path"};UR.exports=xY;UR.exports.default=xY});var TY=_((ySt,RY)=>{"use strict";var QY=ve("path"),j_e=SY(),G_e=kY();function FY(t,e){let r=t.options.env||process.env,o=process.cwd(),a=t.options.cwd!=null,n=a&&process.chdir!==void 0&&!process.chdir.disabled;if(n)try{process.chdir(t.options.cwd)}catch{}let u;try{u=j_e.sync(t.command,{path:r[G_e({env:r})],pathExt:e?QY.delimiter:void 0})}catch{}finally{n&&process.chdir(o)}return u&&(u=QY.resolve(a?t.options.cwd:"",u)),u}function Y_e(t){return FY(t)||FY(t,!0)}RY.exports=Y_e});var NY=_((ESt,HR)=>{"use strict";var _R=/([()\][%!^"`<>&|;, *?])/g;function W_e(t){return t=t.replace(_R,"^$1"),t}function K_e(t,e){return t=`${t}`,t=t.replace(/(\\*)"/g,'$1$1\\"'),t=t.replace(/(\\*)$/,"$1$1"),t=`"${t}"`,t=t.replace(_R,"^$1"),e&&(t=t.replace(_R,"^$1")),t}HR.exports.command=W_e;HR.exports.argument=K_e});var MY=_((CSt,LY)=>{"use strict";LY.exports=/^#!(.*)/});var UY=_((wSt,OY)=>{"use strict";var V_e=MY();OY.exports=(t="")=>{let e=t.match(V_e);if(!e)return null;let[r,o]=e[0].replace(/#! ?/,"").split(" "),a=r.split("/").pop();return a==="env"?o:o?`${a} ${o}`:a}});var HY=_((ISt,_Y)=>{"use strict";var qR=ve("fs"),z_e=UY();function J_e(t){let r=Buffer.alloc(150),o;try{o=qR.openSync(t,"r"),qR.readSync(o,r,0,150,0),qR.closeSync(o)}catch{}return z_e(r.toString())}_Y.exports=J_e});var YY=_((BSt,GY)=>{"use strict";var X_e=ve("path"),qY=TY(),jY=NY(),Z_e=HY(),$_e=process.platform==="win32",e8e=/\.(?:com|exe)$/i,t8e=/node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i;function r8e(t){t.file=qY(t);let e=t.file&&Z_e(t.file);return e?(t.args.unshift(t.file),t.command=e,qY(t)):t.file}function n8e(t){if(!$_e)return t;let e=r8e(t),r=!e8e.test(e);if(t.options.forceShell||r){let o=t8e.test(e);t.command=X_e.normalize(t.command),t.command=jY.command(t.command),t.args=t.args.map(n=>jY.argument(n,o));let a=[t.command].concat(t.args).join(" ");t.args=["/d","/s","/c",`"${a}"`],t.command=process.env.comspec||"cmd.exe",t.options.windowsVerbatimArguments=!0}return t}function i8e(t,e,r){e&&!Array.isArray(e)&&(r=e,e=null),e=e?e.slice(0):[],r=Object.assign({},r);let o={command:t,args:e,options:r,file:void 0,original:{command:t,args:e}};return r.shell?o:n8e(o)}GY.exports=i8e});var VY=_((vSt,KY)=>{"use strict";var jR=process.platform==="win32";function GR(t,e){return Object.assign(new Error(`${e} ${t.command} ENOENT`),{code:"ENOENT",errno:"ENOENT",syscall:`${e} ${t.command}`,path:t.command,spawnargs:t.args})}function s8e(t,e){if(!jR)return;let r=t.emit;t.emit=function(o,a){if(o==="exit"){let n=WY(a,e,"spawn");if(n)return r.call(t,"error",n)}return r.apply(t,arguments)}}function WY(t,e){return jR&&t===1&&!e.file?GR(e.original,"spawn"):null}function o8e(t,e){return jR&&t===1&&!e.file?GR(e.original,"spawnSync"):null}KY.exports={hookChildProcess:s8e,verifyENOENT:WY,verifyENOENTSync:o8e,notFoundError:GR}});var KR=_((DSt,Vd)=>{"use strict";var zY=ve("child_process"),YR=YY(),WR=VY();function JY(t,e,r){let o=YR(t,e,r),a=zY.spawn(o.command,o.args,o.options);return WR.hookChildProcess(a,o),a}function a8e(t,e,r){let o=YR(t,e,r),a=zY.spawnSync(o.command,o.args,o.options);return a.error=a.error||WR.verifyENOENTSync(a.status,o),a}Vd.exports=JY;Vd.exports.spawn=JY;Vd.exports.sync=a8e;Vd.exports._parse=YR;Vd.exports._enoent=WR});var ZY=_((PSt,XY)=>{"use strict";function l8e(t,e){function r(){this.constructor=t}r.prototype=e.prototype,t.prototype=new r}function _0(t,e,r,o){this.message=t,this.expected=e,this.found=r,this.location=o,this.name="SyntaxError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,_0)}l8e(_0,Error);_0.buildMessage=function(t,e){var r={literal:function(h){return'"'+a(h.text)+'"'},class:function(h){var E="",I;for(I=0;I0){for(I=1,v=1;I>",b=Br(">>",!1),y=">&",F=Br(">&",!1),J=">",X=Br(">",!1),$="<<<",ie=Br("<<<",!1),Se="<&",Re=Br("<&",!1),at="<",dt=Br("<",!1),jt=function(N){return{type:"argument",segments:[].concat(...N)}},tr=function(N){return N},bt="$'",ln=Br("$'",!1),kr="'",mr=Br("'",!1),Sr=function(N){return[{type:"text",text:N}]},Kr='""',Kn=Br('""',!1),Ms=function(){return{type:"text",text:""}},Ri='"',gs=Br('"',!1),io=function(N){return N},Pi=function(N){return{type:"arithmetic",arithmetic:N,quoted:!0}},Os=function(N){return{type:"shell",shell:N,quoted:!0}},so=function(N){return{type:"variable",...N,quoted:!0}},uc=function(N){return{type:"text",text:N}},Au=function(N){return{type:"arithmetic",arithmetic:N,quoted:!1}},sp=function(N){return{type:"shell",shell:N,quoted:!1}},op=function(N){return{type:"variable",...N,quoted:!1}},Us=function(N){return{type:"glob",pattern:N}},Dn=/^[^']/,oo=Is(["'"],!0,!1),_s=function(N){return N.join("")},ml=/^[^$"]/,yl=Is(["$",'"'],!0,!1),ao=`\\ +`,Vn=Br(`\\ +`,!1),Mn=function(){return""},Ti="\\",On=Br("\\",!1),_i=/^[\\$"`]/,ir=Is(["\\","$",'"',"`"],!1,!1),Me=function(N){return N},ii="\\a",Ha=Br("\\a",!1),hr=function(){return"a"},Ac="\\b",fu=Br("\\b",!1),fc=function(){return"\b"},El=/^[Ee]/,vA=Is(["E","e"],!1,!1),pu=function(){return"\x1B"},Ie="\\f",Tt=Br("\\f",!1),pc=function(){return"\f"},Hi="\\n",hu=Br("\\n",!1),Yt=function(){return` +`},Cl="\\r",DA=Br("\\r",!1),ap=function(){return"\r"},hc="\\t",PA=Br("\\t",!1),Qn=function(){return" "},hi="\\v",gc=Br("\\v",!1),bA=function(){return"\v"},aa=/^[\\'"?]/,Ni=Is(["\\","'",'"',"?"],!1,!1),_o=function(N){return String.fromCharCode(parseInt(N,16))},Xe="\\x",lo=Br("\\x",!1),dc="\\u",gu=Br("\\u",!1),qi="\\U",du=Br("\\U",!1),SA=function(N){return String.fromCodePoint(parseInt(N,16))},qa=/^[0-7]/,mc=Is([["0","7"]],!1,!1),ds=/^[0-9a-fA-f]/,Ht=Is([["0","9"],["a","f"],["A","f"]],!1,!1),Fn=o0(),Ei="{}",la=Br("{}",!1),co=function(){return"{}"},Hs="-",ca=Br("-",!1),ua="+",Ho=Br("+",!1),Ci=".",ms=Br(".",!1),ys=function(N,K,re){return{type:"number",value:(N==="-"?-1:1)*parseFloat(K.join("")+"."+re.join(""))}},Es=function(N,K){return{type:"number",value:(N==="-"?-1:1)*parseInt(K.join(""))}},qs=function(N){return{type:"variable",...N}},Un=function(N){return{type:"variable",name:N}},Pn=function(N){return N},Cs="*",We=Br("*",!1),tt="/",Bt=Br("/",!1),or=function(N,K,re){return{type:K==="*"?"multiplication":"division",right:re}},ee=function(N,K){return K.reduce((re,he)=>({left:re,...he}),N)},ye=function(N,K,re){return{type:K==="+"?"addition":"subtraction",right:re}},Le="$((",ft=Br("$((",!1),pt="))",Nt=Br("))",!1),rr=function(N){return N},$r="$(",ji=Br("$(",!1),rs=function(N){return N},bi="${",qo=Br("${",!1),xA=":-",kA=Br(":-",!1),lp=function(N,K){return{name:N,defaultValue:K}},e0=":-}",mu=Br(":-}",!1),t0=function(N){return{name:N,defaultValue:[]}},yu=":+",uo=Br(":+",!1),QA=function(N,K){return{name:N,alternativeValue:K}},yc=":+}",Aa=Br(":+}",!1),r0=function(N){return{name:N,alternativeValue:[]}},Ec=function(N){return{name:N}},hd="$",n0=Br("$",!1),$n=function(N){return e.isGlobPattern(N)},cp=function(N){return N},i0=/^[a-zA-Z0-9_]/,FA=Is([["a","z"],["A","Z"],["0","9"],"_"],!1,!1),js=function(){return s0()},Eu=/^[$@*?#a-zA-Z0-9_\-]/,ja=Is(["$","@","*","?","#",["a","z"],["A","Z"],["0","9"],"_","-"],!1,!1),Gi=/^[()}<>$|&; \t"']/,fa=Is(["(",")","}","<",">","$","|","&",";"," "," ",'"',"'"],!1,!1),Cu=/^[<>&; \t"']/,ws=Is(["<",">","&",";"," "," ",'"',"'"],!1,!1),Cc=/^[ \t]/,wc=Is([" "," "],!1,!1),Y=0,Dt=0,wl=[{line:1,column:1}],Si=0,Ic=[],ct=0,wu;if("startRule"in e){if(!(e.startRule in o))throw new Error(`Can't start parsing from rule "`+e.startRule+'".');a=o[e.startRule]}function s0(){return t.substring(Dt,Y)}function tw(){return Bc(Dt,Y)}function RA(N,K){throw K=K!==void 0?K:Bc(Dt,Y),c0([l0(N)],t.substring(Dt,Y),K)}function up(N,K){throw K=K!==void 0?K:Bc(Dt,Y),gd(N,K)}function Br(N,K){return{type:"literal",text:N,ignoreCase:K}}function Is(N,K,re){return{type:"class",parts:N,inverted:K,ignoreCase:re}}function o0(){return{type:"any"}}function a0(){return{type:"end"}}function l0(N){return{type:"other",description:N}}function Ap(N){var K=wl[N],re;if(K)return K;for(re=N-1;!wl[re];)re--;for(K=wl[re],K={line:K.line,column:K.column};reSi&&(Si=Y,Ic=[]),Ic.push(N))}function gd(N,K){return new _0(N,null,null,K)}function c0(N,K,re){return new _0(_0.buildMessage(N,K),N,K,re)}function u0(){var N,K,re;for(N=Y,K=[],re=Qt();re!==r;)K.push(re),re=Qt();return K!==r?(re=Iu(),re===r&&(re=null),re!==r?(Dt=N,K=n(re),N=K):(Y=N,N=r)):(Y=N,N=r),N}function Iu(){var N,K,re,he,ze;if(N=Y,K=Bu(),K!==r){for(re=[],he=Qt();he!==r;)re.push(he),he=Qt();re!==r?(he=A0(),he!==r?(ze=dd(),ze===r&&(ze=null),ze!==r?(Dt=N,K=u(K,he,ze),N=K):(Y=N,N=r)):(Y=N,N=r)):(Y=N,N=r)}else Y=N,N=r;if(N===r)if(N=Y,K=Bu(),K!==r){for(re=[],he=Qt();he!==r;)re.push(he),he=Qt();re!==r?(he=A0(),he===r&&(he=null),he!==r?(Dt=N,K=A(K,he),N=K):(Y=N,N=r)):(Y=N,N=r)}else Y=N,N=r;return N}function dd(){var N,K,re,he,ze;for(N=Y,K=[],re=Qt();re!==r;)K.push(re),re=Qt();if(K!==r)if(re=Iu(),re!==r){for(he=[],ze=Qt();ze!==r;)he.push(ze),ze=Qt();he!==r?(Dt=N,K=p(re),N=K):(Y=N,N=r)}else Y=N,N=r;else Y=N,N=r;return N}function A0(){var N;return t.charCodeAt(Y)===59?(N=h,Y++):(N=r,ct===0&&Ct(E)),N===r&&(t.charCodeAt(Y)===38?(N=I,Y++):(N=r,ct===0&&Ct(v))),N}function Bu(){var N,K,re;return N=Y,K=pa(),K!==r?(re=rw(),re===r&&(re=null),re!==r?(Dt=N,K=x(K,re),N=K):(Y=N,N=r)):(Y=N,N=r),N}function rw(){var N,K,re,he,ze,mt,fr;for(N=Y,K=[],re=Qt();re!==r;)K.push(re),re=Qt();if(K!==r)if(re=md(),re!==r){for(he=[],ze=Qt();ze!==r;)he.push(ze),ze=Qt();if(he!==r)if(ze=Bu(),ze!==r){for(mt=[],fr=Qt();fr!==r;)mt.push(fr),fr=Qt();mt!==r?(Dt=N,K=C(re,ze),N=K):(Y=N,N=r)}else Y=N,N=r;else Y=N,N=r}else Y=N,N=r;else Y=N,N=r;return N}function md(){var N;return t.substr(Y,2)===R?(N=R,Y+=2):(N=r,ct===0&&Ct(L)),N===r&&(t.substr(Y,2)===U?(N=U,Y+=2):(N=r,ct===0&&Ct(z))),N}function pa(){var N,K,re;return N=Y,K=f0(),K!==r?(re=vc(),re===r&&(re=null),re!==r?(Dt=N,K=te(K,re),N=K):(Y=N,N=r)):(Y=N,N=r),N}function vc(){var N,K,re,he,ze,mt,fr;for(N=Y,K=[],re=Qt();re!==r;)K.push(re),re=Qt();if(K!==r)if(re=Il(),re!==r){for(he=[],ze=Qt();ze!==r;)he.push(ze),ze=Qt();if(he!==r)if(ze=pa(),ze!==r){for(mt=[],fr=Qt();fr!==r;)mt.push(fr),fr=Qt();mt!==r?(Dt=N,K=ae(re,ze),N=K):(Y=N,N=r)}else Y=N,N=r;else Y=N,N=r}else Y=N,N=r;else Y=N,N=r;return N}function Il(){var N;return t.substr(Y,2)===le?(N=le,Y+=2):(N=r,ct===0&&Ct(ce)),N===r&&(t.charCodeAt(Y)===124?(N=Ce,Y++):(N=r,ct===0&&Ct(de))),N}function vu(){var N,K,re,he,ze,mt;if(N=Y,K=d0(),K!==r)if(t.charCodeAt(Y)===61?(re=Be,Y++):(re=r,ct===0&&Ct(Ee)),re!==r)if(he=jo(),he!==r){for(ze=[],mt=Qt();mt!==r;)ze.push(mt),mt=Qt();ze!==r?(Dt=N,K=g(K,he),N=K):(Y=N,N=r)}else Y=N,N=r;else Y=N,N=r;else Y=N,N=r;if(N===r)if(N=Y,K=d0(),K!==r)if(t.charCodeAt(Y)===61?(re=Be,Y++):(re=r,ct===0&&Ct(Ee)),re!==r){for(he=[],ze=Qt();ze!==r;)he.push(ze),ze=Qt();he!==r?(Dt=N,K=me(K),N=K):(Y=N,N=r)}else Y=N,N=r;else Y=N,N=r;return N}function f0(){var N,K,re,he,ze,mt,fr,Cr,yn,oi,Li;for(N=Y,K=[],re=Qt();re!==r;)K.push(re),re=Qt();if(K!==r)if(t.charCodeAt(Y)===40?(re=we,Y++):(re=r,ct===0&&Ct(Ae)),re!==r){for(he=[],ze=Qt();ze!==r;)he.push(ze),ze=Qt();if(he!==r)if(ze=Iu(),ze!==r){for(mt=[],fr=Qt();fr!==r;)mt.push(fr),fr=Qt();if(mt!==r)if(t.charCodeAt(Y)===41?(fr=ne,Y++):(fr=r,ct===0&&Ct(Z)),fr!==r){for(Cr=[],yn=Qt();yn!==r;)Cr.push(yn),yn=Qt();if(Cr!==r){for(yn=[],oi=Ga();oi!==r;)yn.push(oi),oi=Ga();if(yn!==r){for(oi=[],Li=Qt();Li!==r;)oi.push(Li),Li=Qt();oi!==r?(Dt=N,K=xe(ze,yn),N=K):(Y=N,N=r)}else Y=N,N=r}else Y=N,N=r}else Y=N,N=r;else Y=N,N=r}else Y=N,N=r;else Y=N,N=r}else Y=N,N=r;else Y=N,N=r;if(N===r){for(N=Y,K=[],re=Qt();re!==r;)K.push(re),re=Qt();if(K!==r)if(t.charCodeAt(Y)===123?(re=Ne,Y++):(re=r,ct===0&&Ct(ht)),re!==r){for(he=[],ze=Qt();ze!==r;)he.push(ze),ze=Qt();if(he!==r)if(ze=Iu(),ze!==r){for(mt=[],fr=Qt();fr!==r;)mt.push(fr),fr=Qt();if(mt!==r)if(t.charCodeAt(Y)===125?(fr=H,Y++):(fr=r,ct===0&&Ct(rt)),fr!==r){for(Cr=[],yn=Qt();yn!==r;)Cr.push(yn),yn=Qt();if(Cr!==r){for(yn=[],oi=Ga();oi!==r;)yn.push(oi),oi=Ga();if(yn!==r){for(oi=[],Li=Qt();Li!==r;)oi.push(Li),Li=Qt();oi!==r?(Dt=N,K=Te(ze,yn),N=K):(Y=N,N=r)}else Y=N,N=r}else Y=N,N=r}else Y=N,N=r;else Y=N,N=r}else Y=N,N=r;else Y=N,N=r}else Y=N,N=r;else Y=N,N=r;if(N===r){for(N=Y,K=[],re=Qt();re!==r;)K.push(re),re=Qt();if(K!==r){for(re=[],he=vu();he!==r;)re.push(he),he=vu();if(re!==r){for(he=[],ze=Qt();ze!==r;)he.push(ze),ze=Qt();if(he!==r){if(ze=[],mt=fp(),mt!==r)for(;mt!==r;)ze.push(mt),mt=fp();else ze=r;if(ze!==r){for(mt=[],fr=Qt();fr!==r;)mt.push(fr),fr=Qt();mt!==r?(Dt=N,K=Fe(re,ze),N=K):(Y=N,N=r)}else Y=N,N=r}else Y=N,N=r}else Y=N,N=r}else Y=N,N=r;if(N===r){for(N=Y,K=[],re=Qt();re!==r;)K.push(re),re=Qt();if(K!==r){if(re=[],he=vu(),he!==r)for(;he!==r;)re.push(he),he=vu();else re=r;if(re!==r){for(he=[],ze=Qt();ze!==r;)he.push(ze),ze=Qt();he!==r?(Dt=N,K=ke(re),N=K):(Y=N,N=r)}else Y=N,N=r}else Y=N,N=r}}}return N}function TA(){var N,K,re,he,ze;for(N=Y,K=[],re=Qt();re!==r;)K.push(re),re=Qt();if(K!==r){if(re=[],he=pp(),he!==r)for(;he!==r;)re.push(he),he=pp();else re=r;if(re!==r){for(he=[],ze=Qt();ze!==r;)he.push(ze),ze=Qt();he!==r?(Dt=N,K=Ye(re),N=K):(Y=N,N=r)}else Y=N,N=r}else Y=N,N=r;return N}function fp(){var N,K,re;for(N=Y,K=[],re=Qt();re!==r;)K.push(re),re=Qt();if(K!==r?(re=Ga(),re!==r?(Dt=N,K=be(re),N=K):(Y=N,N=r)):(Y=N,N=r),N===r){for(N=Y,K=[],re=Qt();re!==r;)K.push(re),re=Qt();K!==r?(re=pp(),re!==r?(Dt=N,K=be(re),N=K):(Y=N,N=r)):(Y=N,N=r)}return N}function Ga(){var N,K,re,he,ze;for(N=Y,K=[],re=Qt();re!==r;)K.push(re),re=Qt();return K!==r?(et.test(t.charAt(Y))?(re=t.charAt(Y),Y++):(re=r,ct===0&&Ct(Ue)),re===r&&(re=null),re!==r?(he=p0(),he!==r?(ze=pp(),ze!==r?(Dt=N,K=S(re,he,ze),N=K):(Y=N,N=r)):(Y=N,N=r)):(Y=N,N=r)):(Y=N,N=r),N}function p0(){var N;return t.substr(Y,2)===w?(N=w,Y+=2):(N=r,ct===0&&Ct(b)),N===r&&(t.substr(Y,2)===y?(N=y,Y+=2):(N=r,ct===0&&Ct(F)),N===r&&(t.charCodeAt(Y)===62?(N=J,Y++):(N=r,ct===0&&Ct(X)),N===r&&(t.substr(Y,3)===$?(N=$,Y+=3):(N=r,ct===0&&Ct(ie)),N===r&&(t.substr(Y,2)===Se?(N=Se,Y+=2):(N=r,ct===0&&Ct(Re)),N===r&&(t.charCodeAt(Y)===60?(N=at,Y++):(N=r,ct===0&&Ct(dt))))))),N}function pp(){var N,K,re;for(N=Y,K=[],re=Qt();re!==r;)K.push(re),re=Qt();return K!==r?(re=jo(),re!==r?(Dt=N,K=be(re),N=K):(Y=N,N=r)):(Y=N,N=r),N}function jo(){var N,K,re;if(N=Y,K=[],re=Bs(),re!==r)for(;re!==r;)K.push(re),re=Bs();else K=r;return K!==r&&(Dt=N,K=jt(K)),N=K,N}function Bs(){var N,K;return N=Y,K=wi(),K!==r&&(Dt=N,K=tr(K)),N=K,N===r&&(N=Y,K=yd(),K!==r&&(Dt=N,K=tr(K)),N=K,N===r&&(N=Y,K=Ed(),K!==r&&(Dt=N,K=tr(K)),N=K,N===r&&(N=Y,K=Go(),K!==r&&(Dt=N,K=tr(K)),N=K))),N}function wi(){var N,K,re,he;return N=Y,t.substr(Y,2)===bt?(K=bt,Y+=2):(K=r,ct===0&&Ct(ln)),K!==r?(re=cn(),re!==r?(t.charCodeAt(Y)===39?(he=kr,Y++):(he=r,ct===0&&Ct(mr)),he!==r?(Dt=N,K=Sr(re),N=K):(Y=N,N=r)):(Y=N,N=r)):(Y=N,N=r),N}function yd(){var N,K,re,he;return N=Y,t.charCodeAt(Y)===39?(K=kr,Y++):(K=r,ct===0&&Ct(mr)),K!==r?(re=gp(),re!==r?(t.charCodeAt(Y)===39?(he=kr,Y++):(he=r,ct===0&&Ct(mr)),he!==r?(Dt=N,K=Sr(re),N=K):(Y=N,N=r)):(Y=N,N=r)):(Y=N,N=r),N}function Ed(){var N,K,re,he;if(N=Y,t.substr(Y,2)===Kr?(K=Kr,Y+=2):(K=r,ct===0&&Ct(Kn)),K!==r&&(Dt=N,K=Ms()),N=K,N===r)if(N=Y,t.charCodeAt(Y)===34?(K=Ri,Y++):(K=r,ct===0&&Ct(gs)),K!==r){for(re=[],he=NA();he!==r;)re.push(he),he=NA();re!==r?(t.charCodeAt(Y)===34?(he=Ri,Y++):(he=r,ct===0&&Ct(gs)),he!==r?(Dt=N,K=io(re),N=K):(Y=N,N=r)):(Y=N,N=r)}else Y=N,N=r;return N}function Go(){var N,K,re;if(N=Y,K=[],re=hp(),re!==r)for(;re!==r;)K.push(re),re=hp();else K=r;return K!==r&&(Dt=N,K=io(K)),N=K,N}function NA(){var N,K;return N=Y,K=Yr(),K!==r&&(Dt=N,K=Pi(K)),N=K,N===r&&(N=Y,K=dp(),K!==r&&(Dt=N,K=Os(K)),N=K,N===r&&(N=Y,K=Pc(),K!==r&&(Dt=N,K=so(K)),N=K,N===r&&(N=Y,K=h0(),K!==r&&(Dt=N,K=uc(K)),N=K))),N}function hp(){var N,K;return N=Y,K=Yr(),K!==r&&(Dt=N,K=Au(K)),N=K,N===r&&(N=Y,K=dp(),K!==r&&(Dt=N,K=sp(K)),N=K,N===r&&(N=Y,K=Pc(),K!==r&&(Dt=N,K=op(K)),N=K,N===r&&(N=Y,K=nw(),K!==r&&(Dt=N,K=Us(K)),N=K,N===r&&(N=Y,K=ga(),K!==r&&(Dt=N,K=uc(K)),N=K)))),N}function gp(){var N,K,re;for(N=Y,K=[],Dn.test(t.charAt(Y))?(re=t.charAt(Y),Y++):(re=r,ct===0&&Ct(oo));re!==r;)K.push(re),Dn.test(t.charAt(Y))?(re=t.charAt(Y),Y++):(re=r,ct===0&&Ct(oo));return K!==r&&(Dt=N,K=_s(K)),N=K,N}function h0(){var N,K,re;if(N=Y,K=[],re=ha(),re===r&&(ml.test(t.charAt(Y))?(re=t.charAt(Y),Y++):(re=r,ct===0&&Ct(yl))),re!==r)for(;re!==r;)K.push(re),re=ha(),re===r&&(ml.test(t.charAt(Y))?(re=t.charAt(Y),Y++):(re=r,ct===0&&Ct(yl)));else K=r;return K!==r&&(Dt=N,K=_s(K)),N=K,N}function ha(){var N,K,re;return N=Y,t.substr(Y,2)===ao?(K=ao,Y+=2):(K=r,ct===0&&Ct(Vn)),K!==r&&(Dt=N,K=Mn()),N=K,N===r&&(N=Y,t.charCodeAt(Y)===92?(K=Ti,Y++):(K=r,ct===0&&Ct(On)),K!==r?(_i.test(t.charAt(Y))?(re=t.charAt(Y),Y++):(re=r,ct===0&&Ct(ir)),re!==r?(Dt=N,K=Me(re),N=K):(Y=N,N=r)):(Y=N,N=r)),N}function cn(){var N,K,re;for(N=Y,K=[],re=Ao(),re===r&&(Dn.test(t.charAt(Y))?(re=t.charAt(Y),Y++):(re=r,ct===0&&Ct(oo)));re!==r;)K.push(re),re=Ao(),re===r&&(Dn.test(t.charAt(Y))?(re=t.charAt(Y),Y++):(re=r,ct===0&&Ct(oo)));return K!==r&&(Dt=N,K=_s(K)),N=K,N}function Ao(){var N,K,re;return N=Y,t.substr(Y,2)===ii?(K=ii,Y+=2):(K=r,ct===0&&Ct(Ha)),K!==r&&(Dt=N,K=hr()),N=K,N===r&&(N=Y,t.substr(Y,2)===Ac?(K=Ac,Y+=2):(K=r,ct===0&&Ct(fu)),K!==r&&(Dt=N,K=fc()),N=K,N===r&&(N=Y,t.charCodeAt(Y)===92?(K=Ti,Y++):(K=r,ct===0&&Ct(On)),K!==r?(El.test(t.charAt(Y))?(re=t.charAt(Y),Y++):(re=r,ct===0&&Ct(vA)),re!==r?(Dt=N,K=pu(),N=K):(Y=N,N=r)):(Y=N,N=r),N===r&&(N=Y,t.substr(Y,2)===Ie?(K=Ie,Y+=2):(K=r,ct===0&&Ct(Tt)),K!==r&&(Dt=N,K=pc()),N=K,N===r&&(N=Y,t.substr(Y,2)===Hi?(K=Hi,Y+=2):(K=r,ct===0&&Ct(hu)),K!==r&&(Dt=N,K=Yt()),N=K,N===r&&(N=Y,t.substr(Y,2)===Cl?(K=Cl,Y+=2):(K=r,ct===0&&Ct(DA)),K!==r&&(Dt=N,K=ap()),N=K,N===r&&(N=Y,t.substr(Y,2)===hc?(K=hc,Y+=2):(K=r,ct===0&&Ct(PA)),K!==r&&(Dt=N,K=Qn()),N=K,N===r&&(N=Y,t.substr(Y,2)===hi?(K=hi,Y+=2):(K=r,ct===0&&Ct(gc)),K!==r&&(Dt=N,K=bA()),N=K,N===r&&(N=Y,t.charCodeAt(Y)===92?(K=Ti,Y++):(K=r,ct===0&&Ct(On)),K!==r?(aa.test(t.charAt(Y))?(re=t.charAt(Y),Y++):(re=r,ct===0&&Ct(Ni)),re!==r?(Dt=N,K=Me(re),N=K):(Y=N,N=r)):(Y=N,N=r),N===r&&(N=LA()))))))))),N}function LA(){var N,K,re,he,ze,mt,fr,Cr,yn,oi,Li,y0;return N=Y,t.charCodeAt(Y)===92?(K=Ti,Y++):(K=r,ct===0&&Ct(On)),K!==r?(re=Ya(),re!==r?(Dt=N,K=_o(re),N=K):(Y=N,N=r)):(Y=N,N=r),N===r&&(N=Y,t.substr(Y,2)===Xe?(K=Xe,Y+=2):(K=r,ct===0&&Ct(lo)),K!==r?(re=Y,he=Y,ze=Ya(),ze!==r?(mt=si(),mt!==r?(ze=[ze,mt],he=ze):(Y=he,he=r)):(Y=he,he=r),he===r&&(he=Ya()),he!==r?re=t.substring(re,Y):re=he,re!==r?(Dt=N,K=_o(re),N=K):(Y=N,N=r)):(Y=N,N=r),N===r&&(N=Y,t.substr(Y,2)===dc?(K=dc,Y+=2):(K=r,ct===0&&Ct(gu)),K!==r?(re=Y,he=Y,ze=si(),ze!==r?(mt=si(),mt!==r?(fr=si(),fr!==r?(Cr=si(),Cr!==r?(ze=[ze,mt,fr,Cr],he=ze):(Y=he,he=r)):(Y=he,he=r)):(Y=he,he=r)):(Y=he,he=r),he!==r?re=t.substring(re,Y):re=he,re!==r?(Dt=N,K=_o(re),N=K):(Y=N,N=r)):(Y=N,N=r),N===r&&(N=Y,t.substr(Y,2)===qi?(K=qi,Y+=2):(K=r,ct===0&&Ct(du)),K!==r?(re=Y,he=Y,ze=si(),ze!==r?(mt=si(),mt!==r?(fr=si(),fr!==r?(Cr=si(),Cr!==r?(yn=si(),yn!==r?(oi=si(),oi!==r?(Li=si(),Li!==r?(y0=si(),y0!==r?(ze=[ze,mt,fr,Cr,yn,oi,Li,y0],he=ze):(Y=he,he=r)):(Y=he,he=r)):(Y=he,he=r)):(Y=he,he=r)):(Y=he,he=r)):(Y=he,he=r)):(Y=he,he=r)):(Y=he,he=r),he!==r?re=t.substring(re,Y):re=he,re!==r?(Dt=N,K=SA(re),N=K):(Y=N,N=r)):(Y=N,N=r)))),N}function Ya(){var N;return qa.test(t.charAt(Y))?(N=t.charAt(Y),Y++):(N=r,ct===0&&Ct(mc)),N}function si(){var N;return ds.test(t.charAt(Y))?(N=t.charAt(Y),Y++):(N=r,ct===0&&Ct(Ht)),N}function ga(){var N,K,re,he,ze;if(N=Y,K=[],re=Y,t.charCodeAt(Y)===92?(he=Ti,Y++):(he=r,ct===0&&Ct(On)),he!==r?(t.length>Y?(ze=t.charAt(Y),Y++):(ze=r,ct===0&&Ct(Fn)),ze!==r?(Dt=re,he=Me(ze),re=he):(Y=re,re=r)):(Y=re,re=r),re===r&&(re=Y,t.substr(Y,2)===Ei?(he=Ei,Y+=2):(he=r,ct===0&&Ct(la)),he!==r&&(Dt=re,he=co()),re=he,re===r&&(re=Y,he=Y,ct++,ze=Cd(),ct--,ze===r?he=void 0:(Y=he,he=r),he!==r?(t.length>Y?(ze=t.charAt(Y),Y++):(ze=r,ct===0&&Ct(Fn)),ze!==r?(Dt=re,he=Me(ze),re=he):(Y=re,re=r)):(Y=re,re=r))),re!==r)for(;re!==r;)K.push(re),re=Y,t.charCodeAt(Y)===92?(he=Ti,Y++):(he=r,ct===0&&Ct(On)),he!==r?(t.length>Y?(ze=t.charAt(Y),Y++):(ze=r,ct===0&&Ct(Fn)),ze!==r?(Dt=re,he=Me(ze),re=he):(Y=re,re=r)):(Y=re,re=r),re===r&&(re=Y,t.substr(Y,2)===Ei?(he=Ei,Y+=2):(he=r,ct===0&&Ct(la)),he!==r&&(Dt=re,he=co()),re=he,re===r&&(re=Y,he=Y,ct++,ze=Cd(),ct--,ze===r?he=void 0:(Y=he,he=r),he!==r?(t.length>Y?(ze=t.charAt(Y),Y++):(ze=r,ct===0&&Ct(Fn)),ze!==r?(Dt=re,he=Me(ze),re=he):(Y=re,re=r)):(Y=re,re=r)));else K=r;return K!==r&&(Dt=N,K=_s(K)),N=K,N}function Dc(){var N,K,re,he,ze,mt;if(N=Y,t.charCodeAt(Y)===45?(K=Hs,Y++):(K=r,ct===0&&Ct(ca)),K===r&&(t.charCodeAt(Y)===43?(K=ua,Y++):(K=r,ct===0&&Ct(Ho))),K===r&&(K=null),K!==r){if(re=[],et.test(t.charAt(Y))?(he=t.charAt(Y),Y++):(he=r,ct===0&&Ct(Ue)),he!==r)for(;he!==r;)re.push(he),et.test(t.charAt(Y))?(he=t.charAt(Y),Y++):(he=r,ct===0&&Ct(Ue));else re=r;if(re!==r)if(t.charCodeAt(Y)===46?(he=Ci,Y++):(he=r,ct===0&&Ct(ms)),he!==r){if(ze=[],et.test(t.charAt(Y))?(mt=t.charAt(Y),Y++):(mt=r,ct===0&&Ct(Ue)),mt!==r)for(;mt!==r;)ze.push(mt),et.test(t.charAt(Y))?(mt=t.charAt(Y),Y++):(mt=r,ct===0&&Ct(Ue));else ze=r;ze!==r?(Dt=N,K=ys(K,re,ze),N=K):(Y=N,N=r)}else Y=N,N=r;else Y=N,N=r}else Y=N,N=r;if(N===r){if(N=Y,t.charCodeAt(Y)===45?(K=Hs,Y++):(K=r,ct===0&&Ct(ca)),K===r&&(t.charCodeAt(Y)===43?(K=ua,Y++):(K=r,ct===0&&Ct(Ho))),K===r&&(K=null),K!==r){if(re=[],et.test(t.charAt(Y))?(he=t.charAt(Y),Y++):(he=r,ct===0&&Ct(Ue)),he!==r)for(;he!==r;)re.push(he),et.test(t.charAt(Y))?(he=t.charAt(Y),Y++):(he=r,ct===0&&Ct(Ue));else re=r;re!==r?(Dt=N,K=Es(K,re),N=K):(Y=N,N=r)}else Y=N,N=r;if(N===r&&(N=Y,K=Pc(),K!==r&&(Dt=N,K=qs(K)),N=K,N===r&&(N=Y,K=Wa(),K!==r&&(Dt=N,K=Un(K)),N=K,N===r)))if(N=Y,t.charCodeAt(Y)===40?(K=we,Y++):(K=r,ct===0&&Ct(Ae)),K!==r){for(re=[],he=Qt();he!==r;)re.push(he),he=Qt();if(re!==r)if(he=ns(),he!==r){for(ze=[],mt=Qt();mt!==r;)ze.push(mt),mt=Qt();ze!==r?(t.charCodeAt(Y)===41?(mt=ne,Y++):(mt=r,ct===0&&Ct(Z)),mt!==r?(Dt=N,K=Pn(he),N=K):(Y=N,N=r)):(Y=N,N=r)}else Y=N,N=r;else Y=N,N=r}else Y=N,N=r}return N}function Bl(){var N,K,re,he,ze,mt,fr,Cr;if(N=Y,K=Dc(),K!==r){for(re=[],he=Y,ze=[],mt=Qt();mt!==r;)ze.push(mt),mt=Qt();if(ze!==r)if(t.charCodeAt(Y)===42?(mt=Cs,Y++):(mt=r,ct===0&&Ct(We)),mt===r&&(t.charCodeAt(Y)===47?(mt=tt,Y++):(mt=r,ct===0&&Ct(Bt))),mt!==r){for(fr=[],Cr=Qt();Cr!==r;)fr.push(Cr),Cr=Qt();fr!==r?(Cr=Dc(),Cr!==r?(Dt=he,ze=or(K,mt,Cr),he=ze):(Y=he,he=r)):(Y=he,he=r)}else Y=he,he=r;else Y=he,he=r;for(;he!==r;){for(re.push(he),he=Y,ze=[],mt=Qt();mt!==r;)ze.push(mt),mt=Qt();if(ze!==r)if(t.charCodeAt(Y)===42?(mt=Cs,Y++):(mt=r,ct===0&&Ct(We)),mt===r&&(t.charCodeAt(Y)===47?(mt=tt,Y++):(mt=r,ct===0&&Ct(Bt))),mt!==r){for(fr=[],Cr=Qt();Cr!==r;)fr.push(Cr),Cr=Qt();fr!==r?(Cr=Dc(),Cr!==r?(Dt=he,ze=or(K,mt,Cr),he=ze):(Y=he,he=r)):(Y=he,he=r)}else Y=he,he=r;else Y=he,he=r}re!==r?(Dt=N,K=ee(K,re),N=K):(Y=N,N=r)}else Y=N,N=r;return N}function ns(){var N,K,re,he,ze,mt,fr,Cr;if(N=Y,K=Bl(),K!==r){for(re=[],he=Y,ze=[],mt=Qt();mt!==r;)ze.push(mt),mt=Qt();if(ze!==r)if(t.charCodeAt(Y)===43?(mt=ua,Y++):(mt=r,ct===0&&Ct(Ho)),mt===r&&(t.charCodeAt(Y)===45?(mt=Hs,Y++):(mt=r,ct===0&&Ct(ca))),mt!==r){for(fr=[],Cr=Qt();Cr!==r;)fr.push(Cr),Cr=Qt();fr!==r?(Cr=Bl(),Cr!==r?(Dt=he,ze=ye(K,mt,Cr),he=ze):(Y=he,he=r)):(Y=he,he=r)}else Y=he,he=r;else Y=he,he=r;for(;he!==r;){for(re.push(he),he=Y,ze=[],mt=Qt();mt!==r;)ze.push(mt),mt=Qt();if(ze!==r)if(t.charCodeAt(Y)===43?(mt=ua,Y++):(mt=r,ct===0&&Ct(Ho)),mt===r&&(t.charCodeAt(Y)===45?(mt=Hs,Y++):(mt=r,ct===0&&Ct(ca))),mt!==r){for(fr=[],Cr=Qt();Cr!==r;)fr.push(Cr),Cr=Qt();fr!==r?(Cr=Bl(),Cr!==r?(Dt=he,ze=ye(K,mt,Cr),he=ze):(Y=he,he=r)):(Y=he,he=r)}else Y=he,he=r;else Y=he,he=r}re!==r?(Dt=N,K=ee(K,re),N=K):(Y=N,N=r)}else Y=N,N=r;return N}function Yr(){var N,K,re,he,ze,mt;if(N=Y,t.substr(Y,3)===Le?(K=Le,Y+=3):(K=r,ct===0&&Ct(ft)),K!==r){for(re=[],he=Qt();he!==r;)re.push(he),he=Qt();if(re!==r)if(he=ns(),he!==r){for(ze=[],mt=Qt();mt!==r;)ze.push(mt),mt=Qt();ze!==r?(t.substr(Y,2)===pt?(mt=pt,Y+=2):(mt=r,ct===0&&Ct(Nt)),mt!==r?(Dt=N,K=rr(he),N=K):(Y=N,N=r)):(Y=N,N=r)}else Y=N,N=r;else Y=N,N=r}else Y=N,N=r;return N}function dp(){var N,K,re,he;return N=Y,t.substr(Y,2)===$r?(K=$r,Y+=2):(K=r,ct===0&&Ct(ji)),K!==r?(re=Iu(),re!==r?(t.charCodeAt(Y)===41?(he=ne,Y++):(he=r,ct===0&&Ct(Z)),he!==r?(Dt=N,K=rs(re),N=K):(Y=N,N=r)):(Y=N,N=r)):(Y=N,N=r),N}function Pc(){var N,K,re,he,ze,mt;return N=Y,t.substr(Y,2)===bi?(K=bi,Y+=2):(K=r,ct===0&&Ct(qo)),K!==r?(re=Wa(),re!==r?(t.substr(Y,2)===xA?(he=xA,Y+=2):(he=r,ct===0&&Ct(kA)),he!==r?(ze=TA(),ze!==r?(t.charCodeAt(Y)===125?(mt=H,Y++):(mt=r,ct===0&&Ct(rt)),mt!==r?(Dt=N,K=lp(re,ze),N=K):(Y=N,N=r)):(Y=N,N=r)):(Y=N,N=r)):(Y=N,N=r)):(Y=N,N=r),N===r&&(N=Y,t.substr(Y,2)===bi?(K=bi,Y+=2):(K=r,ct===0&&Ct(qo)),K!==r?(re=Wa(),re!==r?(t.substr(Y,3)===e0?(he=e0,Y+=3):(he=r,ct===0&&Ct(mu)),he!==r?(Dt=N,K=t0(re),N=K):(Y=N,N=r)):(Y=N,N=r)):(Y=N,N=r),N===r&&(N=Y,t.substr(Y,2)===bi?(K=bi,Y+=2):(K=r,ct===0&&Ct(qo)),K!==r?(re=Wa(),re!==r?(t.substr(Y,2)===yu?(he=yu,Y+=2):(he=r,ct===0&&Ct(uo)),he!==r?(ze=TA(),ze!==r?(t.charCodeAt(Y)===125?(mt=H,Y++):(mt=r,ct===0&&Ct(rt)),mt!==r?(Dt=N,K=QA(re,ze),N=K):(Y=N,N=r)):(Y=N,N=r)):(Y=N,N=r)):(Y=N,N=r)):(Y=N,N=r),N===r&&(N=Y,t.substr(Y,2)===bi?(K=bi,Y+=2):(K=r,ct===0&&Ct(qo)),K!==r?(re=Wa(),re!==r?(t.substr(Y,3)===yc?(he=yc,Y+=3):(he=r,ct===0&&Ct(Aa)),he!==r?(Dt=N,K=r0(re),N=K):(Y=N,N=r)):(Y=N,N=r)):(Y=N,N=r),N===r&&(N=Y,t.substr(Y,2)===bi?(K=bi,Y+=2):(K=r,ct===0&&Ct(qo)),K!==r?(re=Wa(),re!==r?(t.charCodeAt(Y)===125?(he=H,Y++):(he=r,ct===0&&Ct(rt)),he!==r?(Dt=N,K=Ec(re),N=K):(Y=N,N=r)):(Y=N,N=r)):(Y=N,N=r),N===r&&(N=Y,t.charCodeAt(Y)===36?(K=hd,Y++):(K=r,ct===0&&Ct(n0)),K!==r?(re=Wa(),re!==r?(Dt=N,K=Ec(re),N=K):(Y=N,N=r)):(Y=N,N=r)))))),N}function nw(){var N,K,re;return N=Y,K=g0(),K!==r?(Dt=Y,re=$n(K),re?re=void 0:re=r,re!==r?(Dt=N,K=cp(K),N=K):(Y=N,N=r)):(Y=N,N=r),N}function g0(){var N,K,re,he,ze;if(N=Y,K=[],re=Y,he=Y,ct++,ze=m0(),ct--,ze===r?he=void 0:(Y=he,he=r),he!==r?(t.length>Y?(ze=t.charAt(Y),Y++):(ze=r,ct===0&&Ct(Fn)),ze!==r?(Dt=re,he=Me(ze),re=he):(Y=re,re=r)):(Y=re,re=r),re!==r)for(;re!==r;)K.push(re),re=Y,he=Y,ct++,ze=m0(),ct--,ze===r?he=void 0:(Y=he,he=r),he!==r?(t.length>Y?(ze=t.charAt(Y),Y++):(ze=r,ct===0&&Ct(Fn)),ze!==r?(Dt=re,he=Me(ze),re=he):(Y=re,re=r)):(Y=re,re=r);else K=r;return K!==r&&(Dt=N,K=_s(K)),N=K,N}function d0(){var N,K,re;if(N=Y,K=[],i0.test(t.charAt(Y))?(re=t.charAt(Y),Y++):(re=r,ct===0&&Ct(FA)),re!==r)for(;re!==r;)K.push(re),i0.test(t.charAt(Y))?(re=t.charAt(Y),Y++):(re=r,ct===0&&Ct(FA));else K=r;return K!==r&&(Dt=N,K=js()),N=K,N}function Wa(){var N,K,re;if(N=Y,K=[],Eu.test(t.charAt(Y))?(re=t.charAt(Y),Y++):(re=r,ct===0&&Ct(ja)),re!==r)for(;re!==r;)K.push(re),Eu.test(t.charAt(Y))?(re=t.charAt(Y),Y++):(re=r,ct===0&&Ct(ja));else K=r;return K!==r&&(Dt=N,K=js()),N=K,N}function Cd(){var N;return Gi.test(t.charAt(Y))?(N=t.charAt(Y),Y++):(N=r,ct===0&&Ct(fa)),N}function m0(){var N;return Cu.test(t.charAt(Y))?(N=t.charAt(Y),Y++):(N=r,ct===0&&Ct(ws)),N}function Qt(){var N,K;if(N=[],Cc.test(t.charAt(Y))?(K=t.charAt(Y),Y++):(K=r,ct===0&&Ct(wc)),K!==r)for(;K!==r;)N.push(K),Cc.test(t.charAt(Y))?(K=t.charAt(Y),Y++):(K=r,ct===0&&Ct(wc));else N=r;return N}if(wu=a(),wu!==r&&Y===t.length)return wu;throw wu!==r&&Y!1}){try{return(0,$Y.parse)(t,e)}catch(r){throw r.location&&(r.message=r.message.replace(/(\.)?$/,` (line ${r.location.start.line}, column ${r.location.start.column})$1`)),r}}function zd(t,{endSemicolon:e=!1}={}){return t.map(({command:r,type:o},a)=>`${wD(r)}${o===";"?a!==t.length-1||e?";":"":" &"}`).join(" ")}function wD(t){return`${Jd(t.chain)}${t.then?` ${VR(t.then)}`:""}`}function VR(t){return`${t.type} ${wD(t.line)}`}function Jd(t){return`${JR(t)}${t.then?` ${zR(t.then)}`:""}`}function zR(t){return`${t.type} ${Jd(t.chain)}`}function JR(t){switch(t.type){case"command":return`${t.envs.length>0?`${t.envs.map(e=>ED(e)).join(" ")} `:""}${t.args.map(e=>XR(e)).join(" ")}`;case"subshell":return`(${zd(t.subshell)})${t.args.length>0?` ${t.args.map(e=>Qw(e)).join(" ")}`:""}`;case"group":return`{ ${zd(t.group,{endSemicolon:!0})} }${t.args.length>0?` ${t.args.map(e=>Qw(e)).join(" ")}`:""}`;case"envs":return t.envs.map(e=>ED(e)).join(" ");default:throw new Error(`Unsupported command type: "${t.type}"`)}}function ED(t){return`${t.name}=${t.args[0]?H0(t.args[0]):""}`}function XR(t){switch(t.type){case"redirection":return Qw(t);case"argument":return H0(t);default:throw new Error(`Unsupported argument type: "${t.type}"`)}}function Qw(t){return`${t.subtype} ${t.args.map(e=>H0(e)).join(" ")}`}function H0(t){return t.segments.map(e=>ZR(e)).join("")}function ZR(t){let e=(o,a)=>a?`"${o}"`:o,r=o=>o===""?"''":o.match(/[()}<>$|&;"'\n\t ]/)?o.match(/['\t\p{C}]/u)?o.match(/'/)?`"${o.replace(/["$\t\p{C}]/u,A8e)}"`:`$'${o.replace(/[\t\p{C}]/u,tW)}'`:`'${o}'`:o;switch(t.type){case"text":return r(t.text);case"glob":return t.pattern;case"shell":return e(`$(${zd(t.shell)})`,t.quoted);case"variable":return e(typeof t.defaultValue>"u"?typeof t.alternativeValue>"u"?`\${${t.name}}`:t.alternativeValue.length===0?`\${${t.name}:+}`:`\${${t.name}:+${t.alternativeValue.map(o=>H0(o)).join(" ")}}`:t.defaultValue.length===0?`\${${t.name}:-}`:`\${${t.name}:-${t.defaultValue.map(o=>H0(o)).join(" ")}}`,t.quoted);case"arithmetic":return`$(( ${ID(t.arithmetic)} ))`;default:throw new Error(`Unsupported argument segment type: "${t.type}"`)}}function ID(t){let e=a=>{switch(a){case"addition":return"+";case"subtraction":return"-";case"multiplication":return"*";case"division":return"/";default:throw new Error(`Can't extract operator from arithmetic expression of type "${a}"`)}},r=(a,n)=>n?`( ${a} )`:a,o=a=>r(ID(a),!["number","variable"].includes(a.type));switch(t.type){case"number":return String(t.value);case"variable":return t.name;default:return`${o(t.left)} ${e(t.type)} ${o(t.right)}`}}var $Y,eW,u8e,tW,A8e,rW=Et(()=>{$Y=Ze(ZY());eW=new Map([["\f","\\f"],[` +`,"\\n"],["\r","\\r"],[" ","\\t"],["\v","\\v"],["\0","\\0"]]),u8e=new Map([["\\","\\\\"],["$","\\$"],['"','\\"'],...Array.from(eW,([t,e])=>[t,`"$'${e}'"`])]),tW=t=>eW.get(t)??`\\x${t.charCodeAt(0).toString(16).padStart(2,"0")}`,A8e=t=>u8e.get(t)??`"$'${tW(t)}'"`});var iW=_((_St,nW)=>{"use strict";function f8e(t,e){function r(){this.constructor=t}r.prototype=e.prototype,t.prototype=new r}function q0(t,e,r,o){this.message=t,this.expected=e,this.found=r,this.location=o,this.name="SyntaxError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,q0)}f8e(q0,Error);q0.buildMessage=function(t,e){var r={literal:function(h){return'"'+a(h.text)+'"'},class:function(h){var E="",I;for(I=0;I0){for(I=1,v=1;Ile&&(le=z,ce=[]),ce.push(Ue))}function rt(Ue,S){return new q0(Ue,null,null,S)}function Te(Ue,S,w){return new q0(q0.buildMessage(Ue,S),Ue,S,w)}function Fe(){var Ue,S,w,b;return Ue=z,S=ke(),S!==r?(t.charCodeAt(z)===47?(w=n,z++):(w=r,Ce===0&&H(u)),w!==r?(b=ke(),b!==r?(te=Ue,S=A(S,b),Ue=S):(z=Ue,Ue=r)):(z=Ue,Ue=r)):(z=Ue,Ue=r),Ue===r&&(Ue=z,S=ke(),S!==r&&(te=Ue,S=p(S)),Ue=S),Ue}function ke(){var Ue,S,w,b;return Ue=z,S=Ye(),S!==r?(t.charCodeAt(z)===64?(w=h,z++):(w=r,Ce===0&&H(E)),w!==r?(b=et(),b!==r?(te=Ue,S=I(S,b),Ue=S):(z=Ue,Ue=r)):(z=Ue,Ue=r)):(z=Ue,Ue=r),Ue===r&&(Ue=z,S=Ye(),S!==r&&(te=Ue,S=v(S)),Ue=S),Ue}function Ye(){var Ue,S,w,b,y;return Ue=z,t.charCodeAt(z)===64?(S=h,z++):(S=r,Ce===0&&H(E)),S!==r?(w=be(),w!==r?(t.charCodeAt(z)===47?(b=n,z++):(b=r,Ce===0&&H(u)),b!==r?(y=be(),y!==r?(te=Ue,S=x(),Ue=S):(z=Ue,Ue=r)):(z=Ue,Ue=r)):(z=Ue,Ue=r)):(z=Ue,Ue=r),Ue===r&&(Ue=z,S=be(),S!==r&&(te=Ue,S=x()),Ue=S),Ue}function be(){var Ue,S,w;if(Ue=z,S=[],C.test(t.charAt(z))?(w=t.charAt(z),z++):(w=r,Ce===0&&H(R)),w!==r)for(;w!==r;)S.push(w),C.test(t.charAt(z))?(w=t.charAt(z),z++):(w=r,Ce===0&&H(R));else S=r;return S!==r&&(te=Ue,S=x()),Ue=S,Ue}function et(){var Ue,S,w;if(Ue=z,S=[],L.test(t.charAt(z))?(w=t.charAt(z),z++):(w=r,Ce===0&&H(U)),w!==r)for(;w!==r;)S.push(w),L.test(t.charAt(z))?(w=t.charAt(z),z++):(w=r,Ce===0&&H(U));else S=r;return S!==r&&(te=Ue,S=x()),Ue=S,Ue}if(de=a(),de!==r&&z===t.length)return de;throw de!==r&&z{sW=Ze(iW())});var G0=_((qSt,j0)=>{"use strict";function aW(t){return typeof t>"u"||t===null}function h8e(t){return typeof t=="object"&&t!==null}function g8e(t){return Array.isArray(t)?t:aW(t)?[]:[t]}function d8e(t,e){var r,o,a,n;if(e)for(n=Object.keys(e),r=0,o=n.length;r{"use strict";function Fw(t,e){Error.call(this),this.name="YAMLException",this.reason=t,this.mark=e,this.message=(this.reason||"(unknown reason)")+(this.mark?" "+this.mark.toString():""),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=new Error().stack||""}Fw.prototype=Object.create(Error.prototype);Fw.prototype.constructor=Fw;Fw.prototype.toString=function(e){var r=this.name+": ";return r+=this.reason||"(unknown reason)",!e&&this.mark&&(r+=" "+this.mark.toString()),r};lW.exports=Fw});var AW=_((GSt,uW)=>{"use strict";var cW=G0();function $R(t,e,r,o,a){this.name=t,this.buffer=e,this.position=r,this.line=o,this.column=a}$R.prototype.getSnippet=function(e,r){var o,a,n,u,A;if(!this.buffer)return null;for(e=e||4,r=r||75,o="",a=this.position;a>0&&`\0\r +\x85\u2028\u2029`.indexOf(this.buffer.charAt(a-1))===-1;)if(a-=1,this.position-a>r/2-1){o=" ... ",a+=5;break}for(n="",u=this.position;ur/2-1){n=" ... ",u-=5;break}return A=this.buffer.slice(a,u),cW.repeat(" ",e)+o+A+n+` +`+cW.repeat(" ",e+this.position-a+o.length)+"^"};$R.prototype.toString=function(e){var r,o="";return this.name&&(o+='in "'+this.name+'" '),o+="at line "+(this.line+1)+", column "+(this.column+1),e||(r=this.getSnippet(),r&&(o+=`: +`+r)),o};uW.exports=$R});var ls=_((YSt,pW)=>{"use strict";var fW=Xd(),E8e=["kind","resolve","construct","instanceOf","predicate","represent","defaultStyle","styleAliases"],C8e=["scalar","sequence","mapping"];function w8e(t){var e={};return t!==null&&Object.keys(t).forEach(function(r){t[r].forEach(function(o){e[String(o)]=r})}),e}function I8e(t,e){if(e=e||{},Object.keys(e).forEach(function(r){if(E8e.indexOf(r)===-1)throw new fW('Unknown option "'+r+'" is met in definition of "'+t+'" YAML type.')}),this.tag=t,this.kind=e.kind||null,this.resolve=e.resolve||function(){return!0},this.construct=e.construct||function(r){return r},this.instanceOf=e.instanceOf||null,this.predicate=e.predicate||null,this.represent=e.represent||null,this.defaultStyle=e.defaultStyle||null,this.styleAliases=w8e(e.styleAliases||null),C8e.indexOf(this.kind)===-1)throw new fW('Unknown kind "'+this.kind+'" is specified for "'+t+'" YAML type.')}pW.exports=I8e});var Y0=_((WSt,gW)=>{"use strict";var hW=G0(),DD=Xd(),B8e=ls();function eT(t,e,r){var o=[];return t.include.forEach(function(a){r=eT(a,e,r)}),t[e].forEach(function(a){r.forEach(function(n,u){n.tag===a.tag&&n.kind===a.kind&&o.push(u)}),r.push(a)}),r.filter(function(a,n){return o.indexOf(n)===-1})}function v8e(){var t={scalar:{},sequence:{},mapping:{},fallback:{}},e,r;function o(a){t[a.kind][a.tag]=t.fallback[a.tag]=a}for(e=0,r=arguments.length;e{"use strict";var D8e=ls();dW.exports=new D8e("tag:yaml.org,2002:str",{kind:"scalar",construct:function(t){return t!==null?t:""}})});var EW=_((VSt,yW)=>{"use strict";var P8e=ls();yW.exports=new P8e("tag:yaml.org,2002:seq",{kind:"sequence",construct:function(t){return t!==null?t:[]}})});var wW=_((zSt,CW)=>{"use strict";var b8e=ls();CW.exports=new b8e("tag:yaml.org,2002:map",{kind:"mapping",construct:function(t){return t!==null?t:{}}})});var PD=_((JSt,IW)=>{"use strict";var S8e=Y0();IW.exports=new S8e({explicit:[mW(),EW(),wW()]})});var vW=_((XSt,BW)=>{"use strict";var x8e=ls();function k8e(t){if(t===null)return!0;var e=t.length;return e===1&&t==="~"||e===4&&(t==="null"||t==="Null"||t==="NULL")}function Q8e(){return null}function F8e(t){return t===null}BW.exports=new x8e("tag:yaml.org,2002:null",{kind:"scalar",resolve:k8e,construct:Q8e,predicate:F8e,represent:{canonical:function(){return"~"},lowercase:function(){return"null"},uppercase:function(){return"NULL"},camelcase:function(){return"Null"}},defaultStyle:"lowercase"})});var PW=_((ZSt,DW)=>{"use strict";var R8e=ls();function T8e(t){if(t===null)return!1;var e=t.length;return e===4&&(t==="true"||t==="True"||t==="TRUE")||e===5&&(t==="false"||t==="False"||t==="FALSE")}function N8e(t){return t==="true"||t==="True"||t==="TRUE"}function L8e(t){return Object.prototype.toString.call(t)==="[object Boolean]"}DW.exports=new R8e("tag:yaml.org,2002:bool",{kind:"scalar",resolve:T8e,construct:N8e,predicate:L8e,represent:{lowercase:function(t){return t?"true":"false"},uppercase:function(t){return t?"TRUE":"FALSE"},camelcase:function(t){return t?"True":"False"}},defaultStyle:"lowercase"})});var SW=_(($St,bW)=>{"use strict";var M8e=G0(),O8e=ls();function U8e(t){return 48<=t&&t<=57||65<=t&&t<=70||97<=t&&t<=102}function _8e(t){return 48<=t&&t<=55}function H8e(t){return 48<=t&&t<=57}function q8e(t){if(t===null)return!1;var e=t.length,r=0,o=!1,a;if(!e)return!1;if(a=t[r],(a==="-"||a==="+")&&(a=t[++r]),a==="0"){if(r+1===e)return!0;if(a=t[++r],a==="b"){for(r++;r=0?"0b"+t.toString(2):"-0b"+t.toString(2).slice(1)},octal:function(t){return t>=0?"0"+t.toString(8):"-0"+t.toString(8).slice(1)},decimal:function(t){return t.toString(10)},hexadecimal:function(t){return t>=0?"0x"+t.toString(16).toUpperCase():"-0x"+t.toString(16).toUpperCase().slice(1)}},defaultStyle:"decimal",styleAliases:{binary:[2,"bin"],octal:[8,"oct"],decimal:[10,"dec"],hexadecimal:[16,"hex"]}})});var QW=_((ext,kW)=>{"use strict";var xW=G0(),Y8e=ls(),W8e=new RegExp("^(?:[-+]?(?:0|[1-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$");function K8e(t){return!(t===null||!W8e.test(t)||t[t.length-1]==="_")}function V8e(t){var e,r,o,a;return e=t.replace(/_/g,"").toLowerCase(),r=e[0]==="-"?-1:1,a=[],"+-".indexOf(e[0])>=0&&(e=e.slice(1)),e===".inf"?r===1?Number.POSITIVE_INFINITY:Number.NEGATIVE_INFINITY:e===".nan"?NaN:e.indexOf(":")>=0?(e.split(":").forEach(function(n){a.unshift(parseFloat(n,10))}),e=0,o=1,a.forEach(function(n){e+=n*o,o*=60}),r*e):r*parseFloat(e,10)}var z8e=/^[-+]?[0-9]+e/;function J8e(t,e){var r;if(isNaN(t))switch(e){case"lowercase":return".nan";case"uppercase":return".NAN";case"camelcase":return".NaN"}else if(Number.POSITIVE_INFINITY===t)switch(e){case"lowercase":return".inf";case"uppercase":return".INF";case"camelcase":return".Inf"}else if(Number.NEGATIVE_INFINITY===t)switch(e){case"lowercase":return"-.inf";case"uppercase":return"-.INF";case"camelcase":return"-.Inf"}else if(xW.isNegativeZero(t))return"-0.0";return r=t.toString(10),z8e.test(r)?r.replace("e",".e"):r}function X8e(t){return Object.prototype.toString.call(t)==="[object Number]"&&(t%1!==0||xW.isNegativeZero(t))}kW.exports=new Y8e("tag:yaml.org,2002:float",{kind:"scalar",resolve:K8e,construct:V8e,predicate:X8e,represent:J8e,defaultStyle:"lowercase"})});var tT=_((txt,FW)=>{"use strict";var Z8e=Y0();FW.exports=new Z8e({include:[PD()],implicit:[vW(),PW(),SW(),QW()]})});var rT=_((rxt,RW)=>{"use strict";var $8e=Y0();RW.exports=new $8e({include:[tT()]})});var MW=_((nxt,LW)=>{"use strict";var eHe=ls(),TW=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])$"),NW=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:[Tt]|[ \\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \\t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?$");function tHe(t){return t===null?!1:TW.exec(t)!==null||NW.exec(t)!==null}function rHe(t){var e,r,o,a,n,u,A,p=0,h=null,E,I,v;if(e=TW.exec(t),e===null&&(e=NW.exec(t)),e===null)throw new Error("Date resolve error");if(r=+e[1],o=+e[2]-1,a=+e[3],!e[4])return new Date(Date.UTC(r,o,a));if(n=+e[4],u=+e[5],A=+e[6],e[7]){for(p=e[7].slice(0,3);p.length<3;)p+="0";p=+p}return e[9]&&(E=+e[10],I=+(e[11]||0),h=(E*60+I)*6e4,e[9]==="-"&&(h=-h)),v=new Date(Date.UTC(r,o,a,n,u,A,p)),h&&v.setTime(v.getTime()-h),v}function nHe(t){return t.toISOString()}LW.exports=new eHe("tag:yaml.org,2002:timestamp",{kind:"scalar",resolve:tHe,construct:rHe,instanceOf:Date,represent:nHe})});var UW=_((ixt,OW)=>{"use strict";var iHe=ls();function sHe(t){return t==="<<"||t===null}OW.exports=new iHe("tag:yaml.org,2002:merge",{kind:"scalar",resolve:sHe})});var qW=_((sxt,HW)=>{"use strict";var W0;try{_W=ve,W0=_W("buffer").Buffer}catch{}var _W,oHe=ls(),nT=`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/= +\r`;function aHe(t){if(t===null)return!1;var e,r,o=0,a=t.length,n=nT;for(r=0;r64)){if(e<0)return!1;o+=6}return o%8===0}function lHe(t){var e,r,o=t.replace(/[\r\n=]/g,""),a=o.length,n=nT,u=0,A=[];for(e=0;e>16&255),A.push(u>>8&255),A.push(u&255)),u=u<<6|n.indexOf(o.charAt(e));return r=a%4*6,r===0?(A.push(u>>16&255),A.push(u>>8&255),A.push(u&255)):r===18?(A.push(u>>10&255),A.push(u>>2&255)):r===12&&A.push(u>>4&255),W0?W0.from?W0.from(A):new W0(A):A}function cHe(t){var e="",r=0,o,a,n=t.length,u=nT;for(o=0;o>18&63],e+=u[r>>12&63],e+=u[r>>6&63],e+=u[r&63]),r=(r<<8)+t[o];return a=n%3,a===0?(e+=u[r>>18&63],e+=u[r>>12&63],e+=u[r>>6&63],e+=u[r&63]):a===2?(e+=u[r>>10&63],e+=u[r>>4&63],e+=u[r<<2&63],e+=u[64]):a===1&&(e+=u[r>>2&63],e+=u[r<<4&63],e+=u[64],e+=u[64]),e}function uHe(t){return W0&&W0.isBuffer(t)}HW.exports=new oHe("tag:yaml.org,2002:binary",{kind:"scalar",resolve:aHe,construct:lHe,predicate:uHe,represent:cHe})});var GW=_((axt,jW)=>{"use strict";var AHe=ls(),fHe=Object.prototype.hasOwnProperty,pHe=Object.prototype.toString;function hHe(t){if(t===null)return!0;var e=[],r,o,a,n,u,A=t;for(r=0,o=A.length;r{"use strict";var dHe=ls(),mHe=Object.prototype.toString;function yHe(t){if(t===null)return!0;var e,r,o,a,n,u=t;for(n=new Array(u.length),e=0,r=u.length;e{"use strict";var CHe=ls(),wHe=Object.prototype.hasOwnProperty;function IHe(t){if(t===null)return!0;var e,r=t;for(e in r)if(wHe.call(r,e)&&r[e]!==null)return!1;return!0}function BHe(t){return t!==null?t:{}}KW.exports=new CHe("tag:yaml.org,2002:set",{kind:"mapping",resolve:IHe,construct:BHe})});var $d=_((uxt,zW)=>{"use strict";var vHe=Y0();zW.exports=new vHe({include:[rT()],implicit:[MW(),UW()],explicit:[qW(),GW(),WW(),VW()]})});var XW=_((Axt,JW)=>{"use strict";var DHe=ls();function PHe(){return!0}function bHe(){}function SHe(){return""}function xHe(t){return typeof t>"u"}JW.exports=new DHe("tag:yaml.org,2002:js/undefined",{kind:"scalar",resolve:PHe,construct:bHe,predicate:xHe,represent:SHe})});var $W=_((fxt,ZW)=>{"use strict";var kHe=ls();function QHe(t){if(t===null||t.length===0)return!1;var e=t,r=/\/([gim]*)$/.exec(t),o="";return!(e[0]==="/"&&(r&&(o=r[1]),o.length>3||e[e.length-o.length-1]!=="/"))}function FHe(t){var e=t,r=/\/([gim]*)$/.exec(t),o="";return e[0]==="/"&&(r&&(o=r[1]),e=e.slice(1,e.length-o.length-1)),new RegExp(e,o)}function RHe(t){var e="/"+t.source+"/";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),e}function THe(t){return Object.prototype.toString.call(t)==="[object RegExp]"}ZW.exports=new kHe("tag:yaml.org,2002:js/regexp",{kind:"scalar",resolve:QHe,construct:FHe,predicate:THe,represent:RHe})});var rK=_((pxt,tK)=>{"use strict";var bD;try{eK=ve,bD=eK("esprima")}catch{typeof window<"u"&&(bD=window.esprima)}var eK,NHe=ls();function LHe(t){if(t===null)return!1;try{var e="("+t+")",r=bD.parse(e,{range:!0});return!(r.type!=="Program"||r.body.length!==1||r.body[0].type!=="ExpressionStatement"||r.body[0].expression.type!=="ArrowFunctionExpression"&&r.body[0].expression.type!=="FunctionExpression")}catch{return!1}}function MHe(t){var e="("+t+")",r=bD.parse(e,{range:!0}),o=[],a;if(r.type!=="Program"||r.body.length!==1||r.body[0].type!=="ExpressionStatement"||r.body[0].expression.type!=="ArrowFunctionExpression"&&r.body[0].expression.type!=="FunctionExpression")throw new Error("Failed to resolve function");return r.body[0].expression.params.forEach(function(n){o.push(n.name)}),a=r.body[0].expression.body.range,r.body[0].expression.body.type==="BlockStatement"?new Function(o,e.slice(a[0]+1,a[1]-1)):new Function(o,"return "+e.slice(a[0],a[1]))}function OHe(t){return t.toString()}function UHe(t){return Object.prototype.toString.call(t)==="[object Function]"}tK.exports=new NHe("tag:yaml.org,2002:js/function",{kind:"scalar",resolve:LHe,construct:MHe,predicate:UHe,represent:OHe})});var Rw=_((gxt,iK)=>{"use strict";var nK=Y0();iK.exports=nK.DEFAULT=new nK({include:[$d()],explicit:[XW(),$W(),rK()]})});var BK=_((dxt,Tw)=>{"use strict";var mf=G0(),AK=Xd(),_He=AW(),fK=$d(),HHe=Rw(),qp=Object.prototype.hasOwnProperty,SD=1,pK=2,hK=3,xD=4,iT=1,qHe=2,sK=3,jHe=/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/,GHe=/[\x85\u2028\u2029]/,YHe=/[,\[\]\{\}]/,gK=/^(?:!|!!|![a-z\-]+!)$/i,dK=/^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i;function oK(t){return Object.prototype.toString.call(t)}function ju(t){return t===10||t===13}function V0(t){return t===9||t===32}function va(t){return t===9||t===32||t===10||t===13}function em(t){return t===44||t===91||t===93||t===123||t===125}function WHe(t){var e;return 48<=t&&t<=57?t-48:(e=t|32,97<=e&&e<=102?e-97+10:-1)}function KHe(t){return t===120?2:t===117?4:t===85?8:0}function VHe(t){return 48<=t&&t<=57?t-48:-1}function aK(t){return t===48?"\0":t===97?"\x07":t===98?"\b":t===116||t===9?" ":t===110?` +`:t===118?"\v":t===102?"\f":t===114?"\r":t===101?"\x1B":t===32?" ":t===34?'"':t===47?"/":t===92?"\\":t===78?"\x85":t===95?"\xA0":t===76?"\u2028":t===80?"\u2029":""}function zHe(t){return t<=65535?String.fromCharCode(t):String.fromCharCode((t-65536>>10)+55296,(t-65536&1023)+56320)}var mK=new Array(256),yK=new Array(256);for(K0=0;K0<256;K0++)mK[K0]=aK(K0)?1:0,yK[K0]=aK(K0);var K0;function JHe(t,e){this.input=t,this.filename=e.filename||null,this.schema=e.schema||HHe,this.onWarning=e.onWarning||null,this.legacy=e.legacy||!1,this.json=e.json||!1,this.listener=e.listener||null,this.implicitTypes=this.schema.compiledImplicit,this.typeMap=this.schema.compiledTypeMap,this.length=t.length,this.position=0,this.line=0,this.lineStart=0,this.lineIndent=0,this.documents=[]}function EK(t,e){return new AK(e,new _He(t.filename,t.input,t.position,t.line,t.position-t.lineStart))}function br(t,e){throw EK(t,e)}function kD(t,e){t.onWarning&&t.onWarning.call(null,EK(t,e))}var lK={YAML:function(e,r,o){var a,n,u;e.version!==null&&br(e,"duplication of %YAML directive"),o.length!==1&&br(e,"YAML directive accepts exactly one argument"),a=/^([0-9]+)\.([0-9]+)$/.exec(o[0]),a===null&&br(e,"ill-formed argument of the YAML directive"),n=parseInt(a[1],10),u=parseInt(a[2],10),n!==1&&br(e,"unacceptable YAML version of the document"),e.version=o[0],e.checkLineBreaks=u<2,u!==1&&u!==2&&kD(e,"unsupported YAML version of the document")},TAG:function(e,r,o){var a,n;o.length!==2&&br(e,"TAG directive accepts exactly two arguments"),a=o[0],n=o[1],gK.test(a)||br(e,"ill-formed tag handle (first argument) of the TAG directive"),qp.call(e.tagMap,a)&&br(e,'there is a previously declared suffix for "'+a+'" tag handle'),dK.test(n)||br(e,"ill-formed tag prefix (second argument) of the TAG directive"),e.tagMap[a]=n}};function Hp(t,e,r,o){var a,n,u,A;if(e1&&(t.result+=mf.repeat(` +`,e-1))}function XHe(t,e,r){var o,a,n,u,A,p,h,E,I=t.kind,v=t.result,x;if(x=t.input.charCodeAt(t.position),va(x)||em(x)||x===35||x===38||x===42||x===33||x===124||x===62||x===39||x===34||x===37||x===64||x===96||(x===63||x===45)&&(a=t.input.charCodeAt(t.position+1),va(a)||r&&em(a)))return!1;for(t.kind="scalar",t.result="",n=u=t.position,A=!1;x!==0;){if(x===58){if(a=t.input.charCodeAt(t.position+1),va(a)||r&&em(a))break}else if(x===35){if(o=t.input.charCodeAt(t.position-1),va(o))break}else{if(t.position===t.lineStart&&QD(t)||r&&em(x))break;if(ju(x))if(p=t.line,h=t.lineStart,E=t.lineIndent,Wi(t,!1,-1),t.lineIndent>=e){A=!0,x=t.input.charCodeAt(t.position);continue}else{t.position=u,t.line=p,t.lineStart=h,t.lineIndent=E;break}}A&&(Hp(t,n,u,!1),oT(t,t.line-p),n=u=t.position,A=!1),V0(x)||(u=t.position+1),x=t.input.charCodeAt(++t.position)}return Hp(t,n,u,!1),t.result?!0:(t.kind=I,t.result=v,!1)}function ZHe(t,e){var r,o,a;if(r=t.input.charCodeAt(t.position),r!==39)return!1;for(t.kind="scalar",t.result="",t.position++,o=a=t.position;(r=t.input.charCodeAt(t.position))!==0;)if(r===39)if(Hp(t,o,t.position,!0),r=t.input.charCodeAt(++t.position),r===39)o=t.position,t.position++,a=t.position;else return!0;else ju(r)?(Hp(t,o,a,!0),oT(t,Wi(t,!1,e)),o=a=t.position):t.position===t.lineStart&&QD(t)?br(t,"unexpected end of the document within a single quoted scalar"):(t.position++,a=t.position);br(t,"unexpected end of the stream within a single quoted scalar")}function $He(t,e){var r,o,a,n,u,A;if(A=t.input.charCodeAt(t.position),A!==34)return!1;for(t.kind="scalar",t.result="",t.position++,r=o=t.position;(A=t.input.charCodeAt(t.position))!==0;){if(A===34)return Hp(t,r,t.position,!0),t.position++,!0;if(A===92){if(Hp(t,r,t.position,!0),A=t.input.charCodeAt(++t.position),ju(A))Wi(t,!1,e);else if(A<256&&mK[A])t.result+=yK[A],t.position++;else if((u=KHe(A))>0){for(a=u,n=0;a>0;a--)A=t.input.charCodeAt(++t.position),(u=WHe(A))>=0?n=(n<<4)+u:br(t,"expected hexadecimal character");t.result+=zHe(n),t.position++}else br(t,"unknown escape sequence");r=o=t.position}else ju(A)?(Hp(t,r,o,!0),oT(t,Wi(t,!1,e)),r=o=t.position):t.position===t.lineStart&&QD(t)?br(t,"unexpected end of the document within a double quoted scalar"):(t.position++,o=t.position)}br(t,"unexpected end of the stream within a double quoted scalar")}function e6e(t,e){var r=!0,o,a=t.tag,n,u=t.anchor,A,p,h,E,I,v={},x,C,R,L;if(L=t.input.charCodeAt(t.position),L===91)p=93,I=!1,n=[];else if(L===123)p=125,I=!0,n={};else return!1;for(t.anchor!==null&&(t.anchorMap[t.anchor]=n),L=t.input.charCodeAt(++t.position);L!==0;){if(Wi(t,!0,e),L=t.input.charCodeAt(t.position),L===p)return t.position++,t.tag=a,t.anchor=u,t.kind=I?"mapping":"sequence",t.result=n,!0;r||br(t,"missed comma between flow collection entries"),C=x=R=null,h=E=!1,L===63&&(A=t.input.charCodeAt(t.position+1),va(A)&&(h=E=!0,t.position++,Wi(t,!0,e))),o=t.line,rm(t,e,SD,!1,!0),C=t.tag,x=t.result,Wi(t,!0,e),L=t.input.charCodeAt(t.position),(E||t.line===o)&&L===58&&(h=!0,L=t.input.charCodeAt(++t.position),Wi(t,!0,e),rm(t,e,SD,!1,!0),R=t.result),I?tm(t,n,v,C,x,R):h?n.push(tm(t,null,v,C,x,R)):n.push(x),Wi(t,!0,e),L=t.input.charCodeAt(t.position),L===44?(r=!0,L=t.input.charCodeAt(++t.position)):r=!1}br(t,"unexpected end of the stream within a flow collection")}function t6e(t,e){var r,o,a=iT,n=!1,u=!1,A=e,p=0,h=!1,E,I;if(I=t.input.charCodeAt(t.position),I===124)o=!1;else if(I===62)o=!0;else return!1;for(t.kind="scalar",t.result="";I!==0;)if(I=t.input.charCodeAt(++t.position),I===43||I===45)iT===a?a=I===43?sK:qHe:br(t,"repeat of a chomping mode identifier");else if((E=VHe(I))>=0)E===0?br(t,"bad explicit indentation width of a block scalar; it cannot be less than one"):u?br(t,"repeat of an indentation width identifier"):(A=e+E-1,u=!0);else break;if(V0(I)){do I=t.input.charCodeAt(++t.position);while(V0(I));if(I===35)do I=t.input.charCodeAt(++t.position);while(!ju(I)&&I!==0)}for(;I!==0;){for(sT(t),t.lineIndent=0,I=t.input.charCodeAt(t.position);(!u||t.lineIndentA&&(A=t.lineIndent),ju(I)){p++;continue}if(t.lineIndente)&&p!==0)br(t,"bad indentation of a sequence entry");else if(t.lineIndente)&&(rm(t,e,xD,!0,a)&&(C?v=t.result:x=t.result),C||(tm(t,h,E,I,v,x,n,u),I=v=x=null),Wi(t,!0,-1),L=t.input.charCodeAt(t.position)),t.lineIndent>e&&L!==0)br(t,"bad indentation of a mapping entry");else if(t.lineIndente?p=1:t.lineIndent===e?p=0:t.lineIndente?p=1:t.lineIndent===e?p=0:t.lineIndent tag; it should be "scalar", not "'+t.kind+'"'),I=0,v=t.implicitTypes.length;I tag; it should be "'+x.kind+'", not "'+t.kind+'"'),x.resolve(t.result)?(t.result=x.construct(t.result),t.anchor!==null&&(t.anchorMap[t.anchor]=t.result)):br(t,"cannot resolve a node with !<"+t.tag+"> explicit tag")):br(t,"unknown tag !<"+t.tag+">");return t.listener!==null&&t.listener("close",t),t.tag!==null||t.anchor!==null||E}function o6e(t){var e=t.position,r,o,a,n=!1,u;for(t.version=null,t.checkLineBreaks=t.legacy,t.tagMap={},t.anchorMap={};(u=t.input.charCodeAt(t.position))!==0&&(Wi(t,!0,-1),u=t.input.charCodeAt(t.position),!(t.lineIndent>0||u!==37));){for(n=!0,u=t.input.charCodeAt(++t.position),r=t.position;u!==0&&!va(u);)u=t.input.charCodeAt(++t.position);for(o=t.input.slice(r,t.position),a=[],o.length<1&&br(t,"directive name must not be less than one character in length");u!==0;){for(;V0(u);)u=t.input.charCodeAt(++t.position);if(u===35){do u=t.input.charCodeAt(++t.position);while(u!==0&&!ju(u));break}if(ju(u))break;for(r=t.position;u!==0&&!va(u);)u=t.input.charCodeAt(++t.position);a.push(t.input.slice(r,t.position))}u!==0&&sT(t),qp.call(lK,o)?lK[o](t,o,a):kD(t,'unknown document directive "'+o+'"')}if(Wi(t,!0,-1),t.lineIndent===0&&t.input.charCodeAt(t.position)===45&&t.input.charCodeAt(t.position+1)===45&&t.input.charCodeAt(t.position+2)===45?(t.position+=3,Wi(t,!0,-1)):n&&br(t,"directives end mark is expected"),rm(t,t.lineIndent-1,xD,!1,!0),Wi(t,!0,-1),t.checkLineBreaks&&GHe.test(t.input.slice(e,t.position))&&kD(t,"non-ASCII line breaks are interpreted as content"),t.documents.push(t.result),t.position===t.lineStart&&QD(t)){t.input.charCodeAt(t.position)===46&&(t.position+=3,Wi(t,!0,-1));return}if(t.position"u"&&(r=e,e=null);var o=CK(t,r);if(typeof e!="function")return o;for(var a=0,n=o.length;a"u"&&(r=e,e=null),wK(t,e,mf.extend({schema:fK},r))}function l6e(t,e){return IK(t,mf.extend({schema:fK},e))}Tw.exports.loadAll=wK;Tw.exports.load=IK;Tw.exports.safeLoadAll=a6e;Tw.exports.safeLoad=l6e});var WK=_((mxt,uT)=>{"use strict";var Lw=G0(),Mw=Xd(),c6e=Rw(),u6e=$d(),QK=Object.prototype.toString,FK=Object.prototype.hasOwnProperty,A6e=9,Nw=10,f6e=13,p6e=32,h6e=33,g6e=34,RK=35,d6e=37,m6e=38,y6e=39,E6e=42,TK=44,C6e=45,NK=58,w6e=61,I6e=62,B6e=63,v6e=64,LK=91,MK=93,D6e=96,OK=123,P6e=124,UK=125,vo={};vo[0]="\\0";vo[7]="\\a";vo[8]="\\b";vo[9]="\\t";vo[10]="\\n";vo[11]="\\v";vo[12]="\\f";vo[13]="\\r";vo[27]="\\e";vo[34]='\\"';vo[92]="\\\\";vo[133]="\\N";vo[160]="\\_";vo[8232]="\\L";vo[8233]="\\P";var b6e=["y","Y","yes","Yes","YES","on","On","ON","n","N","no","No","NO","off","Off","OFF"];function S6e(t,e){var r,o,a,n,u,A,p;if(e===null)return{};for(r={},o=Object.keys(e),a=0,n=o.length;a0?t.charCodeAt(n-1):null,v=v&&PK(u,A)}else{for(n=0;no&&t[I+1]!==" ",I=n);else if(!nm(u))return FD;A=n>0?t.charCodeAt(n-1):null,v=v&&PK(u,A)}h=h||E&&n-I-1>o&&t[I+1]!==" "}return!p&&!h?v&&!a(t)?HK:qK:r>9&&_K(t)?FD:h?GK:jK}function T6e(t,e,r,o){t.dump=function(){if(e.length===0)return"''";if(!t.noCompatMode&&b6e.indexOf(e)!==-1)return"'"+e+"'";var a=t.indent*Math.max(1,r),n=t.lineWidth===-1?-1:Math.max(Math.min(t.lineWidth,40),t.lineWidth-a),u=o||t.flowLevel>-1&&r>=t.flowLevel;function A(p){return k6e(t,p)}switch(R6e(e,u,t.indent,n,A)){case HK:return e;case qK:return"'"+e.replace(/'/g,"''")+"'";case jK:return"|"+bK(e,t.indent)+SK(DK(e,a));case GK:return">"+bK(e,t.indent)+SK(DK(N6e(e,n),a));case FD:return'"'+L6e(e,n)+'"';default:throw new Mw("impossible error: invalid scalar style")}}()}function bK(t,e){var r=_K(t)?String(e):"",o=t[t.length-1]===` +`,a=o&&(t[t.length-2]===` +`||t===` +`),n=a?"+":o?"":"-";return r+n+` +`}function SK(t){return t[t.length-1]===` +`?t.slice(0,-1):t}function N6e(t,e){for(var r=/(\n+)([^\n]*)/g,o=function(){var h=t.indexOf(` +`);return h=h!==-1?h:t.length,r.lastIndex=h,xK(t.slice(0,h),e)}(),a=t[0]===` +`||t[0]===" ",n,u;u=r.exec(t);){var A=u[1],p=u[2];n=p[0]===" ",o+=A+(!a&&!n&&p!==""?` +`:"")+xK(p,e),a=n}return o}function xK(t,e){if(t===""||t[0]===" ")return t;for(var r=/ [^ ]/g,o,a=0,n,u=0,A=0,p="";o=r.exec(t);)A=o.index,A-a>e&&(n=u>a?u:A,p+=` +`+t.slice(a,n),a=n+1),u=A;return p+=` +`,t.length-a>e&&u>a?p+=t.slice(a,u)+` +`+t.slice(u+1):p+=t.slice(a),p.slice(1)}function L6e(t){for(var e="",r,o,a,n=0;n=55296&&r<=56319&&(o=t.charCodeAt(n+1),o>=56320&&o<=57343)){e+=vK((r-55296)*1024+o-56320+65536),n++;continue}a=vo[r],e+=!a&&nm(r)?t[n]:a||vK(r)}return e}function M6e(t,e,r){var o="",a=t.tag,n,u;for(n=0,u=r.length;n1024&&(E+="? "),E+=t.dump+(t.condenseFlow?'"':"")+":"+(t.condenseFlow?"":" "),z0(t,e,h,!1,!1)&&(E+=t.dump,o+=E));t.tag=a,t.dump="{"+o+"}"}function _6e(t,e,r,o){var a="",n=t.tag,u=Object.keys(r),A,p,h,E,I,v;if(t.sortKeys===!0)u.sort();else if(typeof t.sortKeys=="function")u.sort(t.sortKeys);else if(t.sortKeys)throw new Mw("sortKeys must be a boolean or a function");for(A=0,p=u.length;A1024,I&&(t.dump&&Nw===t.dump.charCodeAt(0)?v+="?":v+="? "),v+=t.dump,I&&(v+=aT(t,e)),z0(t,e+1,E,!0,I)&&(t.dump&&Nw===t.dump.charCodeAt(0)?v+=":":v+=": ",v+=t.dump,a+=v));t.tag=n,t.dump=a||"{}"}function kK(t,e,r){var o,a,n,u,A,p;for(a=r?t.explicitTypes:t.implicitTypes,n=0,u=a.length;n tag resolver accepts not "'+p+'" style');t.dump=o}return!0}return!1}function z0(t,e,r,o,a,n){t.tag=null,t.dump=r,kK(t,r,!1)||kK(t,r,!0);var u=QK.call(t.dump);o&&(o=t.flowLevel<0||t.flowLevel>e);var A=u==="[object Object]"||u==="[object Array]",p,h;if(A&&(p=t.duplicates.indexOf(r),h=p!==-1),(t.tag!==null&&t.tag!=="?"||h||t.indent!==2&&e>0)&&(a=!1),h&&t.usedDuplicates[p])t.dump="*ref_"+p;else{if(A&&h&&!t.usedDuplicates[p]&&(t.usedDuplicates[p]=!0),u==="[object Object]")o&&Object.keys(t.dump).length!==0?(_6e(t,e,t.dump,a),h&&(t.dump="&ref_"+p+t.dump)):(U6e(t,e,t.dump),h&&(t.dump="&ref_"+p+" "+t.dump));else if(u==="[object Array]"){var E=t.noArrayIndent&&e>0?e-1:e;o&&t.dump.length!==0?(O6e(t,E,t.dump,a),h&&(t.dump="&ref_"+p+t.dump)):(M6e(t,E,t.dump),h&&(t.dump="&ref_"+p+" "+t.dump))}else if(u==="[object String]")t.tag!=="?"&&T6e(t,t.dump,e,n);else{if(t.skipInvalid)return!1;throw new Mw("unacceptable kind of an object to dump "+u)}t.tag!==null&&t.tag!=="?"&&(t.dump="!<"+t.tag+"> "+t.dump)}return!0}function H6e(t,e){var r=[],o=[],a,n;for(lT(t,r,o),a=0,n=o.length;a{"use strict";var RD=BK(),KK=WK();function TD(t){return function(){throw new Error("Function "+t+" is deprecated and cannot be used.")}}xi.exports.Type=ls();xi.exports.Schema=Y0();xi.exports.FAILSAFE_SCHEMA=PD();xi.exports.JSON_SCHEMA=tT();xi.exports.CORE_SCHEMA=rT();xi.exports.DEFAULT_SAFE_SCHEMA=$d();xi.exports.DEFAULT_FULL_SCHEMA=Rw();xi.exports.load=RD.load;xi.exports.loadAll=RD.loadAll;xi.exports.safeLoad=RD.safeLoad;xi.exports.safeLoadAll=RD.safeLoadAll;xi.exports.dump=KK.dump;xi.exports.safeDump=KK.safeDump;xi.exports.YAMLException=Xd();xi.exports.MINIMAL_SCHEMA=PD();xi.exports.SAFE_SCHEMA=$d();xi.exports.DEFAULT_SCHEMA=Rw();xi.exports.scan=TD("scan");xi.exports.parse=TD("parse");xi.exports.compose=TD("compose");xi.exports.addConstructor=TD("addConstructor")});var JK=_((Ext,zK)=>{"use strict";var j6e=VK();zK.exports=j6e});var ZK=_((Cxt,XK)=>{"use strict";function G6e(t,e){function r(){this.constructor=t}r.prototype=e.prototype,t.prototype=new r}function J0(t,e,r,o){this.message=t,this.expected=e,this.found=r,this.location=o,this.name="SyntaxError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,J0)}G6e(J0,Error);J0.buildMessage=function(t,e){var r={literal:function(h){return'"'+a(h.text)+'"'},class:function(h){var E="",I;for(I=0;I0){for(I=1,v=1;I({[ft]:Le})))},le=function(ee){return ee},ce=function(ee){return ee},Ce=aa("correct indentation"),de=" ",Be=Qn(" ",!1),Ee=function(ee){return ee.length===or*Bt},g=function(ee){return ee.length===(or+1)*Bt},me=function(){return or++,!0},we=function(){return or--,!0},Ae=function(){return DA()},ne=aa("pseudostring"),Z=/^[^\r\n\t ?:,\][{}#&*!|>'"%@`\-]/,xe=hi(["\r",` +`," "," ","?",":",",","]","[","{","}","#","&","*","!","|",">","'",'"',"%","@","`","-"],!0,!1),Ne=/^[^\r\n\t ,\][{}:#"']/,ht=hi(["\r",` +`," "," ",",","]","[","{","}",":","#",'"',"'"],!0,!1),H=function(){return DA().replace(/^ *| *$/g,"")},rt="--",Te=Qn("--",!1),Fe=/^[a-zA-Z\/0-9]/,ke=hi([["a","z"],["A","Z"],"/",["0","9"]],!1,!1),Ye=/^[^\r\n\t :,]/,be=hi(["\r",` +`," "," ",":",","],!0,!1),et="null",Ue=Qn("null",!1),S=function(){return null},w="true",b=Qn("true",!1),y=function(){return!0},F="false",J=Qn("false",!1),X=function(){return!1},$=aa("string"),ie='"',Se=Qn('"',!1),Re=function(){return""},at=function(ee){return ee},dt=function(ee){return ee.join("")},jt=/^[^"\\\0-\x1F\x7F]/,tr=hi(['"',"\\",["\0",""],"\x7F"],!0,!1),bt='\\"',ln=Qn('\\"',!1),kr=function(){return'"'},mr="\\\\",Sr=Qn("\\\\",!1),Kr=function(){return"\\"},Kn="\\/",Ms=Qn("\\/",!1),Ri=function(){return"/"},gs="\\b",io=Qn("\\b",!1),Pi=function(){return"\b"},Os="\\f",so=Qn("\\f",!1),uc=function(){return"\f"},Au="\\n",sp=Qn("\\n",!1),op=function(){return` +`},Us="\\r",Dn=Qn("\\r",!1),oo=function(){return"\r"},_s="\\t",ml=Qn("\\t",!1),yl=function(){return" "},ao="\\u",Vn=Qn("\\u",!1),Mn=function(ee,ye,Le,ft){return String.fromCharCode(parseInt(`0x${ee}${ye}${Le}${ft}`))},Ti=/^[0-9a-fA-F]/,On=hi([["0","9"],["a","f"],["A","F"]],!1,!1),_i=aa("blank space"),ir=/^[ \t]/,Me=hi([" "," "],!1,!1),ii=aa("white space"),Ha=/^[ \t\n\r]/,hr=hi([" "," ",` +`,"\r"],!1,!1),Ac=`\r +`,fu=Qn(`\r +`,!1),fc=` +`,El=Qn(` +`,!1),vA="\r",pu=Qn("\r",!1),Ie=0,Tt=0,pc=[{line:1,column:1}],Hi=0,hu=[],Yt=0,Cl;if("startRule"in e){if(!(e.startRule in o))throw new Error(`Can't start parsing from rule "`+e.startRule+'".');a=o[e.startRule]}function DA(){return t.substring(Tt,Ie)}function ap(){return _o(Tt,Ie)}function hc(ee,ye){throw ye=ye!==void 0?ye:_o(Tt,Ie),dc([aa(ee)],t.substring(Tt,Ie),ye)}function PA(ee,ye){throw ye=ye!==void 0?ye:_o(Tt,Ie),lo(ee,ye)}function Qn(ee,ye){return{type:"literal",text:ee,ignoreCase:ye}}function hi(ee,ye,Le){return{type:"class",parts:ee,inverted:ye,ignoreCase:Le}}function gc(){return{type:"any"}}function bA(){return{type:"end"}}function aa(ee){return{type:"other",description:ee}}function Ni(ee){var ye=pc[ee],Le;if(ye)return ye;for(Le=ee-1;!pc[Le];)Le--;for(ye=pc[Le],ye={line:ye.line,column:ye.column};LeHi&&(Hi=Ie,hu=[]),hu.push(ee))}function lo(ee,ye){return new J0(ee,null,null,ye)}function dc(ee,ye,Le){return new J0(J0.buildMessage(ee,ye),ee,ye,Le)}function gu(){var ee;return ee=SA(),ee}function qi(){var ee,ye,Le;for(ee=Ie,ye=[],Le=du();Le!==r;)ye.push(Le),Le=du();return ye!==r&&(Tt=ee,ye=n(ye)),ee=ye,ee}function du(){var ee,ye,Le,ft,pt;return ee=Ie,ye=ds(),ye!==r?(t.charCodeAt(Ie)===45?(Le=u,Ie++):(Le=r,Yt===0&&Xe(A)),Le!==r?(ft=Pn(),ft!==r?(pt=mc(),pt!==r?(Tt=ee,ye=p(pt),ee=ye):(Ie=ee,ee=r)):(Ie=ee,ee=r)):(Ie=ee,ee=r)):(Ie=ee,ee=r),ee}function SA(){var ee,ye,Le;for(ee=Ie,ye=[],Le=qa();Le!==r;)ye.push(Le),Le=qa();return ye!==r&&(Tt=ee,ye=h(ye)),ee=ye,ee}function qa(){var ee,ye,Le,ft,pt,Nt,rr,$r,ji;if(ee=Ie,ye=Pn(),ye===r&&(ye=null),ye!==r){if(Le=Ie,t.charCodeAt(Ie)===35?(ft=E,Ie++):(ft=r,Yt===0&&Xe(I)),ft!==r){if(pt=[],Nt=Ie,rr=Ie,Yt++,$r=tt(),Yt--,$r===r?rr=void 0:(Ie=rr,rr=r),rr!==r?(t.length>Ie?($r=t.charAt(Ie),Ie++):($r=r,Yt===0&&Xe(v)),$r!==r?(rr=[rr,$r],Nt=rr):(Ie=Nt,Nt=r)):(Ie=Nt,Nt=r),Nt!==r)for(;Nt!==r;)pt.push(Nt),Nt=Ie,rr=Ie,Yt++,$r=tt(),Yt--,$r===r?rr=void 0:(Ie=rr,rr=r),rr!==r?(t.length>Ie?($r=t.charAt(Ie),Ie++):($r=r,Yt===0&&Xe(v)),$r!==r?(rr=[rr,$r],Nt=rr):(Ie=Nt,Nt=r)):(Ie=Nt,Nt=r);else pt=r;pt!==r?(ft=[ft,pt],Le=ft):(Ie=Le,Le=r)}else Ie=Le,Le=r;if(Le===r&&(Le=null),Le!==r){if(ft=[],pt=We(),pt!==r)for(;pt!==r;)ft.push(pt),pt=We();else ft=r;ft!==r?(Tt=ee,ye=x(),ee=ye):(Ie=ee,ee=r)}else Ie=ee,ee=r}else Ie=ee,ee=r;if(ee===r&&(ee=Ie,ye=ds(),ye!==r?(Le=la(),Le!==r?(ft=Pn(),ft===r&&(ft=null),ft!==r?(t.charCodeAt(Ie)===58?(pt=C,Ie++):(pt=r,Yt===0&&Xe(R)),pt!==r?(Nt=Pn(),Nt===r&&(Nt=null),Nt!==r?(rr=mc(),rr!==r?(Tt=ee,ye=L(Le,rr),ee=ye):(Ie=ee,ee=r)):(Ie=ee,ee=r)):(Ie=ee,ee=r)):(Ie=ee,ee=r)):(Ie=ee,ee=r)):(Ie=ee,ee=r),ee===r&&(ee=Ie,ye=ds(),ye!==r?(Le=co(),Le!==r?(ft=Pn(),ft===r&&(ft=null),ft!==r?(t.charCodeAt(Ie)===58?(pt=C,Ie++):(pt=r,Yt===0&&Xe(R)),pt!==r?(Nt=Pn(),Nt===r&&(Nt=null),Nt!==r?(rr=mc(),rr!==r?(Tt=ee,ye=L(Le,rr),ee=ye):(Ie=ee,ee=r)):(Ie=ee,ee=r)):(Ie=ee,ee=r)):(Ie=ee,ee=r)):(Ie=ee,ee=r)):(Ie=ee,ee=r),ee===r))){if(ee=Ie,ye=ds(),ye!==r)if(Le=co(),Le!==r)if(ft=Pn(),ft!==r)if(pt=ca(),pt!==r){if(Nt=[],rr=We(),rr!==r)for(;rr!==r;)Nt.push(rr),rr=We();else Nt=r;Nt!==r?(Tt=ee,ye=L(Le,pt),ee=ye):(Ie=ee,ee=r)}else Ie=ee,ee=r;else Ie=ee,ee=r;else Ie=ee,ee=r;else Ie=ee,ee=r;if(ee===r)if(ee=Ie,ye=ds(),ye!==r)if(Le=co(),Le!==r){if(ft=[],pt=Ie,Nt=Pn(),Nt===r&&(Nt=null),Nt!==r?(t.charCodeAt(Ie)===44?(rr=U,Ie++):(rr=r,Yt===0&&Xe(z)),rr!==r?($r=Pn(),$r===r&&($r=null),$r!==r?(ji=co(),ji!==r?(Tt=pt,Nt=te(Le,ji),pt=Nt):(Ie=pt,pt=r)):(Ie=pt,pt=r)):(Ie=pt,pt=r)):(Ie=pt,pt=r),pt!==r)for(;pt!==r;)ft.push(pt),pt=Ie,Nt=Pn(),Nt===r&&(Nt=null),Nt!==r?(t.charCodeAt(Ie)===44?(rr=U,Ie++):(rr=r,Yt===0&&Xe(z)),rr!==r?($r=Pn(),$r===r&&($r=null),$r!==r?(ji=co(),ji!==r?(Tt=pt,Nt=te(Le,ji),pt=Nt):(Ie=pt,pt=r)):(Ie=pt,pt=r)):(Ie=pt,pt=r)):(Ie=pt,pt=r);else ft=r;ft!==r?(pt=Pn(),pt===r&&(pt=null),pt!==r?(t.charCodeAt(Ie)===58?(Nt=C,Ie++):(Nt=r,Yt===0&&Xe(R)),Nt!==r?(rr=Pn(),rr===r&&(rr=null),rr!==r?($r=mc(),$r!==r?(Tt=ee,ye=ae(Le,ft,$r),ee=ye):(Ie=ee,ee=r)):(Ie=ee,ee=r)):(Ie=ee,ee=r)):(Ie=ee,ee=r)):(Ie=ee,ee=r)}else Ie=ee,ee=r;else Ie=ee,ee=r}return ee}function mc(){var ee,ye,Le,ft,pt,Nt,rr;if(ee=Ie,ye=Ie,Yt++,Le=Ie,ft=tt(),ft!==r?(pt=Ht(),pt!==r?(t.charCodeAt(Ie)===45?(Nt=u,Ie++):(Nt=r,Yt===0&&Xe(A)),Nt!==r?(rr=Pn(),rr!==r?(ft=[ft,pt,Nt,rr],Le=ft):(Ie=Le,Le=r)):(Ie=Le,Le=r)):(Ie=Le,Le=r)):(Ie=Le,Le=r),Yt--,Le!==r?(Ie=ye,ye=void 0):ye=r,ye!==r?(Le=We(),Le!==r?(ft=Fn(),ft!==r?(pt=qi(),pt!==r?(Nt=Ei(),Nt!==r?(Tt=ee,ye=le(pt),ee=ye):(Ie=ee,ee=r)):(Ie=ee,ee=r)):(Ie=ee,ee=r)):(Ie=ee,ee=r)):(Ie=ee,ee=r),ee===r&&(ee=Ie,ye=tt(),ye!==r?(Le=Fn(),Le!==r?(ft=SA(),ft!==r?(pt=Ei(),pt!==r?(Tt=ee,ye=le(ft),ee=ye):(Ie=ee,ee=r)):(Ie=ee,ee=r)):(Ie=ee,ee=r)):(Ie=ee,ee=r),ee===r))if(ee=Ie,ye=Hs(),ye!==r){if(Le=[],ft=We(),ft!==r)for(;ft!==r;)Le.push(ft),ft=We();else Le=r;Le!==r?(Tt=ee,ye=ce(ye),ee=ye):(Ie=ee,ee=r)}else Ie=ee,ee=r;return ee}function ds(){var ee,ye,Le;for(Yt++,ee=Ie,ye=[],t.charCodeAt(Ie)===32?(Le=de,Ie++):(Le=r,Yt===0&&Xe(Be));Le!==r;)ye.push(Le),t.charCodeAt(Ie)===32?(Le=de,Ie++):(Le=r,Yt===0&&Xe(Be));return ye!==r?(Tt=Ie,Le=Ee(ye),Le?Le=void 0:Le=r,Le!==r?(ye=[ye,Le],ee=ye):(Ie=ee,ee=r)):(Ie=ee,ee=r),Yt--,ee===r&&(ye=r,Yt===0&&Xe(Ce)),ee}function Ht(){var ee,ye,Le;for(ee=Ie,ye=[],t.charCodeAt(Ie)===32?(Le=de,Ie++):(Le=r,Yt===0&&Xe(Be));Le!==r;)ye.push(Le),t.charCodeAt(Ie)===32?(Le=de,Ie++):(Le=r,Yt===0&&Xe(Be));return ye!==r?(Tt=Ie,Le=g(ye),Le?Le=void 0:Le=r,Le!==r?(ye=[ye,Le],ee=ye):(Ie=ee,ee=r)):(Ie=ee,ee=r),ee}function Fn(){var ee;return Tt=Ie,ee=me(),ee?ee=void 0:ee=r,ee}function Ei(){var ee;return Tt=Ie,ee=we(),ee?ee=void 0:ee=r,ee}function la(){var ee;return ee=ys(),ee===r&&(ee=ua()),ee}function co(){var ee,ye,Le;if(ee=ys(),ee===r){if(ee=Ie,ye=[],Le=Ho(),Le!==r)for(;Le!==r;)ye.push(Le),Le=Ho();else ye=r;ye!==r&&(Tt=ee,ye=Ae()),ee=ye}return ee}function Hs(){var ee;return ee=Ci(),ee===r&&(ee=ms(),ee===r&&(ee=ys(),ee===r&&(ee=ua()))),ee}function ca(){var ee;return ee=Ci(),ee===r&&(ee=ys(),ee===r&&(ee=Ho())),ee}function ua(){var ee,ye,Le,ft,pt,Nt;if(Yt++,ee=Ie,Z.test(t.charAt(Ie))?(ye=t.charAt(Ie),Ie++):(ye=r,Yt===0&&Xe(xe)),ye!==r){for(Le=[],ft=Ie,pt=Pn(),pt===r&&(pt=null),pt!==r?(Ne.test(t.charAt(Ie))?(Nt=t.charAt(Ie),Ie++):(Nt=r,Yt===0&&Xe(ht)),Nt!==r?(pt=[pt,Nt],ft=pt):(Ie=ft,ft=r)):(Ie=ft,ft=r);ft!==r;)Le.push(ft),ft=Ie,pt=Pn(),pt===r&&(pt=null),pt!==r?(Ne.test(t.charAt(Ie))?(Nt=t.charAt(Ie),Ie++):(Nt=r,Yt===0&&Xe(ht)),Nt!==r?(pt=[pt,Nt],ft=pt):(Ie=ft,ft=r)):(Ie=ft,ft=r);Le!==r?(Tt=ee,ye=H(),ee=ye):(Ie=ee,ee=r)}else Ie=ee,ee=r;return Yt--,ee===r&&(ye=r,Yt===0&&Xe(ne)),ee}function Ho(){var ee,ye,Le,ft,pt;if(ee=Ie,t.substr(Ie,2)===rt?(ye=rt,Ie+=2):(ye=r,Yt===0&&Xe(Te)),ye===r&&(ye=null),ye!==r)if(Fe.test(t.charAt(Ie))?(Le=t.charAt(Ie),Ie++):(Le=r,Yt===0&&Xe(ke)),Le!==r){for(ft=[],Ye.test(t.charAt(Ie))?(pt=t.charAt(Ie),Ie++):(pt=r,Yt===0&&Xe(be));pt!==r;)ft.push(pt),Ye.test(t.charAt(Ie))?(pt=t.charAt(Ie),Ie++):(pt=r,Yt===0&&Xe(be));ft!==r?(Tt=ee,ye=H(),ee=ye):(Ie=ee,ee=r)}else Ie=ee,ee=r;else Ie=ee,ee=r;return ee}function Ci(){var ee,ye;return ee=Ie,t.substr(Ie,4)===et?(ye=et,Ie+=4):(ye=r,Yt===0&&Xe(Ue)),ye!==r&&(Tt=ee,ye=S()),ee=ye,ee}function ms(){var ee,ye;return ee=Ie,t.substr(Ie,4)===w?(ye=w,Ie+=4):(ye=r,Yt===0&&Xe(b)),ye!==r&&(Tt=ee,ye=y()),ee=ye,ee===r&&(ee=Ie,t.substr(Ie,5)===F?(ye=F,Ie+=5):(ye=r,Yt===0&&Xe(J)),ye!==r&&(Tt=ee,ye=X()),ee=ye),ee}function ys(){var ee,ye,Le,ft;return Yt++,ee=Ie,t.charCodeAt(Ie)===34?(ye=ie,Ie++):(ye=r,Yt===0&&Xe(Se)),ye!==r?(t.charCodeAt(Ie)===34?(Le=ie,Ie++):(Le=r,Yt===0&&Xe(Se)),Le!==r?(Tt=ee,ye=Re(),ee=ye):(Ie=ee,ee=r)):(Ie=ee,ee=r),ee===r&&(ee=Ie,t.charCodeAt(Ie)===34?(ye=ie,Ie++):(ye=r,Yt===0&&Xe(Se)),ye!==r?(Le=Es(),Le!==r?(t.charCodeAt(Ie)===34?(ft=ie,Ie++):(ft=r,Yt===0&&Xe(Se)),ft!==r?(Tt=ee,ye=at(Le),ee=ye):(Ie=ee,ee=r)):(Ie=ee,ee=r)):(Ie=ee,ee=r)),Yt--,ee===r&&(ye=r,Yt===0&&Xe($)),ee}function Es(){var ee,ye,Le;if(ee=Ie,ye=[],Le=qs(),Le!==r)for(;Le!==r;)ye.push(Le),Le=qs();else ye=r;return ye!==r&&(Tt=ee,ye=dt(ye)),ee=ye,ee}function qs(){var ee,ye,Le,ft,pt,Nt;return jt.test(t.charAt(Ie))?(ee=t.charAt(Ie),Ie++):(ee=r,Yt===0&&Xe(tr)),ee===r&&(ee=Ie,t.substr(Ie,2)===bt?(ye=bt,Ie+=2):(ye=r,Yt===0&&Xe(ln)),ye!==r&&(Tt=ee,ye=kr()),ee=ye,ee===r&&(ee=Ie,t.substr(Ie,2)===mr?(ye=mr,Ie+=2):(ye=r,Yt===0&&Xe(Sr)),ye!==r&&(Tt=ee,ye=Kr()),ee=ye,ee===r&&(ee=Ie,t.substr(Ie,2)===Kn?(ye=Kn,Ie+=2):(ye=r,Yt===0&&Xe(Ms)),ye!==r&&(Tt=ee,ye=Ri()),ee=ye,ee===r&&(ee=Ie,t.substr(Ie,2)===gs?(ye=gs,Ie+=2):(ye=r,Yt===0&&Xe(io)),ye!==r&&(Tt=ee,ye=Pi()),ee=ye,ee===r&&(ee=Ie,t.substr(Ie,2)===Os?(ye=Os,Ie+=2):(ye=r,Yt===0&&Xe(so)),ye!==r&&(Tt=ee,ye=uc()),ee=ye,ee===r&&(ee=Ie,t.substr(Ie,2)===Au?(ye=Au,Ie+=2):(ye=r,Yt===0&&Xe(sp)),ye!==r&&(Tt=ee,ye=op()),ee=ye,ee===r&&(ee=Ie,t.substr(Ie,2)===Us?(ye=Us,Ie+=2):(ye=r,Yt===0&&Xe(Dn)),ye!==r&&(Tt=ee,ye=oo()),ee=ye,ee===r&&(ee=Ie,t.substr(Ie,2)===_s?(ye=_s,Ie+=2):(ye=r,Yt===0&&Xe(ml)),ye!==r&&(Tt=ee,ye=yl()),ee=ye,ee===r&&(ee=Ie,t.substr(Ie,2)===ao?(ye=ao,Ie+=2):(ye=r,Yt===0&&Xe(Vn)),ye!==r?(Le=Un(),Le!==r?(ft=Un(),ft!==r?(pt=Un(),pt!==r?(Nt=Un(),Nt!==r?(Tt=ee,ye=Mn(Le,ft,pt,Nt),ee=ye):(Ie=ee,ee=r)):(Ie=ee,ee=r)):(Ie=ee,ee=r)):(Ie=ee,ee=r)):(Ie=ee,ee=r)))))))))),ee}function Un(){var ee;return Ti.test(t.charAt(Ie))?(ee=t.charAt(Ie),Ie++):(ee=r,Yt===0&&Xe(On)),ee}function Pn(){var ee,ye;if(Yt++,ee=[],ir.test(t.charAt(Ie))?(ye=t.charAt(Ie),Ie++):(ye=r,Yt===0&&Xe(Me)),ye!==r)for(;ye!==r;)ee.push(ye),ir.test(t.charAt(Ie))?(ye=t.charAt(Ie),Ie++):(ye=r,Yt===0&&Xe(Me));else ee=r;return Yt--,ee===r&&(ye=r,Yt===0&&Xe(_i)),ee}function Cs(){var ee,ye;if(Yt++,ee=[],Ha.test(t.charAt(Ie))?(ye=t.charAt(Ie),Ie++):(ye=r,Yt===0&&Xe(hr)),ye!==r)for(;ye!==r;)ee.push(ye),Ha.test(t.charAt(Ie))?(ye=t.charAt(Ie),Ie++):(ye=r,Yt===0&&Xe(hr));else ee=r;return Yt--,ee===r&&(ye=r,Yt===0&&Xe(ii)),ee}function We(){var ee,ye,Le,ft,pt,Nt;if(ee=Ie,ye=tt(),ye!==r){for(Le=[],ft=Ie,pt=Pn(),pt===r&&(pt=null),pt!==r?(Nt=tt(),Nt!==r?(pt=[pt,Nt],ft=pt):(Ie=ft,ft=r)):(Ie=ft,ft=r);ft!==r;)Le.push(ft),ft=Ie,pt=Pn(),pt===r&&(pt=null),pt!==r?(Nt=tt(),Nt!==r?(pt=[pt,Nt],ft=pt):(Ie=ft,ft=r)):(Ie=ft,ft=r);Le!==r?(ye=[ye,Le],ee=ye):(Ie=ee,ee=r)}else Ie=ee,ee=r;return ee}function tt(){var ee;return t.substr(Ie,2)===Ac?(ee=Ac,Ie+=2):(ee=r,Yt===0&&Xe(fu)),ee===r&&(t.charCodeAt(Ie)===10?(ee=fc,Ie++):(ee=r,Yt===0&&Xe(El)),ee===r&&(t.charCodeAt(Ie)===13?(ee=vA,Ie++):(ee=r,Yt===0&&Xe(pu)))),ee}let Bt=2,or=0;if(Cl=a(),Cl!==r&&Ie===t.length)return Cl;throw Cl!==r&&Ie"u"?!0:typeof t=="object"&&t!==null&&!Array.isArray(t)?Object.keys(t).every(e=>rV(t[e])):!1}function AT(t,e,r){if(t===null)return`null +`;if(typeof t=="number"||typeof t=="boolean")return`${t.toString()} +`;if(typeof t=="string")return`${eV(t)} +`;if(Array.isArray(t)){if(t.length===0)return`[] +`;let o=" ".repeat(e);return` +${t.map(n=>`${o}- ${AT(n,e+1,!1)}`).join("")}`}if(typeof t=="object"&&t){let[o,a]=t instanceof ND?[t.data,!1]:[t,!0],n=" ".repeat(e),u=Object.keys(o);a&&u.sort((p,h)=>{let E=$K.indexOf(p),I=$K.indexOf(h);return E===-1&&I===-1?ph?1:0:E!==-1&&I===-1?-1:E===-1&&I!==-1?1:E-I});let A=u.filter(p=>!rV(o[p])).map((p,h)=>{let E=o[p],I=eV(p),v=AT(E,e+1,!0),x=h>0||r?n:"",C=I.length>1024?`? ${I} +${x}:`:`${I}:`,R=v.startsWith(` +`)?v:` ${v}`;return`${x}${C}${R}`}).join(e===0?` +`:"")||` +`;return r?` +${A}`:`${A}`}throw new Error(`Unsupported value type (${t})`)}function Da(t){try{let e=AT(t,0,!1);return e!==` +`?e:""}catch(e){throw e.location&&(e.message=e.message.replace(/(\.)?$/,` (line ${e.location.start.line}, column ${e.location.start.column})$1`)),e}}function K6e(t){return t.endsWith(` +`)||(t+=` +`),(0,tV.parse)(t)}function z6e(t){if(V6e.test(t))return K6e(t);let e=(0,LD.safeLoad)(t,{schema:LD.FAILSAFE_SCHEMA,json:!0});if(e==null)return{};if(typeof e!="object")throw new Error(`Expected an indexed object, got a ${typeof e} instead. Does your file follow Yaml's rules?`);if(Array.isArray(e))throw new Error("Expected an indexed object, got an array instead. Does your file follow Yaml's rules?");return e}function Ki(t){return z6e(t)}var LD,tV,W6e,$K,ND,V6e,nV=Et(()=>{LD=Ze(JK()),tV=Ze(ZK()),W6e=/^(?![-?:,\][{}#&*!|>'"%@` \t\r\n]).([ \t]*(?![,\][{}:# \t\r\n]).)*$/,$K=["__metadata","version","resolution","dependencies","peerDependencies","dependenciesMeta","peerDependenciesMeta","binaries"],ND=class{constructor(e){this.data=e}};Da.PreserveOrdering=ND;V6e=/^(#.*(\r?\n))*?#\s+yarn\s+lockfile\s+v1\r?\n/i});var Ow={};Vt(Ow,{parseResolution:()=>BD,parseShell:()=>CD,parseSyml:()=>Ki,stringifyArgument:()=>XR,stringifyArgumentSegment:()=>ZR,stringifyArithmeticExpression:()=>ID,stringifyCommand:()=>JR,stringifyCommandChain:()=>Jd,stringifyCommandChainThen:()=>zR,stringifyCommandLine:()=>wD,stringifyCommandLineThen:()=>VR,stringifyEnvSegment:()=>ED,stringifyRedirectArgument:()=>Qw,stringifyResolution:()=>vD,stringifyShell:()=>zd,stringifyShellLine:()=>zd,stringifySyml:()=>Da,stringifyValueArgument:()=>H0});var Nl=Et(()=>{rW();oW();nV()});var sV=_((Dxt,fT)=>{"use strict";var J6e=t=>{let e=!1,r=!1,o=!1;for(let a=0;a{if(!(typeof t=="string"||Array.isArray(t)))throw new TypeError("Expected the input to be `string | string[]`");e=Object.assign({pascalCase:!1},e);let r=a=>e.pascalCase?a.charAt(0).toUpperCase()+a.slice(1):a;return Array.isArray(t)?t=t.map(a=>a.trim()).filter(a=>a.length).join("-"):t=t.trim(),t.length===0?"":t.length===1?e.pascalCase?t.toUpperCase():t.toLowerCase():(t!==t.toLowerCase()&&(t=J6e(t)),t=t.replace(/^[_.\- ]+/,"").toLowerCase().replace(/[_.\- ]+(\w|$)/g,(a,n)=>n.toUpperCase()).replace(/\d+(\w|$)/g,a=>a.toUpperCase()),r(t))};fT.exports=iV;fT.exports.default=iV});var oV=_((Pxt,X6e)=>{X6e.exports=[{name:"Agola CI",constant:"AGOLA",env:"AGOLA_GIT_REF",pr:"AGOLA_PULL_REQUEST_ID"},{name:"Appcircle",constant:"APPCIRCLE",env:"AC_APPCIRCLE"},{name:"AppVeyor",constant:"APPVEYOR",env:"APPVEYOR",pr:"APPVEYOR_PULL_REQUEST_NUMBER"},{name:"AWS CodeBuild",constant:"CODEBUILD",env:"CODEBUILD_BUILD_ARN"},{name:"Azure Pipelines",constant:"AZURE_PIPELINES",env:"TF_BUILD",pr:{BUILD_REASON:"PullRequest"}},{name:"Bamboo",constant:"BAMBOO",env:"bamboo_planKey"},{name:"Bitbucket Pipelines",constant:"BITBUCKET",env:"BITBUCKET_COMMIT",pr:"BITBUCKET_PR_ID"},{name:"Bitrise",constant:"BITRISE",env:"BITRISE_IO",pr:"BITRISE_PULL_REQUEST"},{name:"Buddy",constant:"BUDDY",env:"BUDDY_WORKSPACE_ID",pr:"BUDDY_EXECUTION_PULL_REQUEST_ID"},{name:"Buildkite",constant:"BUILDKITE",env:"BUILDKITE",pr:{env:"BUILDKITE_PULL_REQUEST",ne:"false"}},{name:"CircleCI",constant:"CIRCLE",env:"CIRCLECI",pr:"CIRCLE_PULL_REQUEST"},{name:"Cirrus CI",constant:"CIRRUS",env:"CIRRUS_CI",pr:"CIRRUS_PR"},{name:"Codefresh",constant:"CODEFRESH",env:"CF_BUILD_ID",pr:{any:["CF_PULL_REQUEST_NUMBER","CF_PULL_REQUEST_ID"]}},{name:"Codemagic",constant:"CODEMAGIC",env:"CM_BUILD_ID",pr:"CM_PULL_REQUEST"},{name:"Codeship",constant:"CODESHIP",env:{CI_NAME:"codeship"}},{name:"Drone",constant:"DRONE",env:"DRONE",pr:{DRONE_BUILD_EVENT:"pull_request"}},{name:"dsari",constant:"DSARI",env:"DSARI"},{name:"Earthly",constant:"EARTHLY",env:"EARTHLY_CI"},{name:"Expo Application Services",constant:"EAS",env:"EAS_BUILD"},{name:"Gerrit",constant:"GERRIT",env:"GERRIT_PROJECT"},{name:"Gitea Actions",constant:"GITEA_ACTIONS",env:"GITEA_ACTIONS"},{name:"GitHub Actions",constant:"GITHUB_ACTIONS",env:"GITHUB_ACTIONS",pr:{GITHUB_EVENT_NAME:"pull_request"}},{name:"GitLab CI",constant:"GITLAB",env:"GITLAB_CI",pr:"CI_MERGE_REQUEST_ID"},{name:"GoCD",constant:"GOCD",env:"GO_PIPELINE_LABEL"},{name:"Google Cloud Build",constant:"GOOGLE_CLOUD_BUILD",env:"BUILDER_OUTPUT"},{name:"Harness CI",constant:"HARNESS",env:"HARNESS_BUILD_ID"},{name:"Heroku",constant:"HEROKU",env:{env:"NODE",includes:"/app/.heroku/node/bin/node"}},{name:"Hudson",constant:"HUDSON",env:"HUDSON_URL"},{name:"Jenkins",constant:"JENKINS",env:["JENKINS_URL","BUILD_ID"],pr:{any:["ghprbPullId","CHANGE_ID"]}},{name:"LayerCI",constant:"LAYERCI",env:"LAYERCI",pr:"LAYERCI_PULL_REQUEST"},{name:"Magnum CI",constant:"MAGNUM",env:"MAGNUM"},{name:"Netlify CI",constant:"NETLIFY",env:"NETLIFY",pr:{env:"PULL_REQUEST",ne:"false"}},{name:"Nevercode",constant:"NEVERCODE",env:"NEVERCODE",pr:{env:"NEVERCODE_PULL_REQUEST",ne:"false"}},{name:"Prow",constant:"PROW",env:"PROW_JOB_ID"},{name:"ReleaseHub",constant:"RELEASEHUB",env:"RELEASE_BUILD_ID"},{name:"Render",constant:"RENDER",env:"RENDER",pr:{IS_PULL_REQUEST:"true"}},{name:"Sail CI",constant:"SAIL",env:"SAILCI",pr:"SAIL_PULL_REQUEST_NUMBER"},{name:"Screwdriver",constant:"SCREWDRIVER",env:"SCREWDRIVER",pr:{env:"SD_PULL_REQUEST",ne:"false"}},{name:"Semaphore",constant:"SEMAPHORE",env:"SEMAPHORE",pr:"PULL_REQUEST_NUMBER"},{name:"Sourcehut",constant:"SOURCEHUT",env:{CI_NAME:"sourcehut"}},{name:"Strider CD",constant:"STRIDER",env:"STRIDER"},{name:"TaskCluster",constant:"TASKCLUSTER",env:["TASK_ID","RUN_ID"]},{name:"TeamCity",constant:"TEAMCITY",env:"TEAMCITY_VERSION"},{name:"Travis CI",constant:"TRAVIS",env:"TRAVIS",pr:{env:"TRAVIS_PULL_REQUEST",ne:"false"}},{name:"Vela",constant:"VELA",env:"VELA",pr:{VELA_PULL_REQUEST:"1"}},{name:"Vercel",constant:"VERCEL",env:{any:["NOW_BUILDER","VERCEL"]},pr:"VERCEL_GIT_PULL_REQUEST_ID"},{name:"Visual Studio App Center",constant:"APPCENTER",env:"APPCENTER_BUILD_ID"},{name:"Woodpecker",constant:"WOODPECKER",env:{CI:"woodpecker"},pr:{CI_BUILD_EVENT:"pull_request"}},{name:"Xcode Cloud",constant:"XCODE_CLOUD",env:"CI_XCODE_PROJECT",pr:"CI_PULL_REQUEST_NUMBER"},{name:"Xcode Server",constant:"XCODE_SERVER",env:"XCS"}]});var X0=_($a=>{"use strict";var lV=oV(),cs=process.env;Object.defineProperty($a,"_vendors",{value:lV.map(function(t){return t.constant})});$a.name=null;$a.isPR=null;lV.forEach(function(t){let r=(Array.isArray(t.env)?t.env:[t.env]).every(function(o){return aV(o)});if($a[t.constant]=r,!!r)switch($a.name=t.name,typeof t.pr){case"string":$a.isPR=!!cs[t.pr];break;case"object":"env"in t.pr?$a.isPR=t.pr.env in cs&&cs[t.pr.env]!==t.pr.ne:"any"in t.pr?$a.isPR=t.pr.any.some(function(o){return!!cs[o]}):$a.isPR=aV(t.pr);break;default:$a.isPR=null}});$a.isCI=!!(cs.CI!=="false"&&(cs.BUILD_ID||cs.BUILD_NUMBER||cs.CI||cs.CI_APP_ID||cs.CI_BUILD_ID||cs.CI_BUILD_NUMBER||cs.CI_NAME||cs.CONTINUOUS_INTEGRATION||cs.RUN_ID||$a.name));function aV(t){return typeof t=="string"?!!cs[t]:"env"in t?cs[t.env]&&cs[t.env].includes(t.includes):"any"in t?t.any.some(function(e){return!!cs[e]}):Object.keys(t).every(function(e){return cs[e]===t[e]})}});var Hn,un,Z0,pT,MD,cV,hT,gT,OD=Et(()=>{(function(t){t.StartOfInput="\0",t.EndOfInput="",t.EndOfPartialInput=""})(Hn||(Hn={}));(function(t){t[t.InitialNode=0]="InitialNode",t[t.SuccessNode=1]="SuccessNode",t[t.ErrorNode=2]="ErrorNode",t[t.CustomNode=3]="CustomNode"})(un||(un={}));Z0=-1,pT=/^(-h|--help)(?:=([0-9]+))?$/,MD=/^(--[a-z]+(?:-[a-z]+)*|-[a-zA-Z]+)$/,cV=/^-[a-zA-Z]{2,}$/,hT=/^([^=]+)=([\s\S]*)$/,gT=process.env.DEBUG_CLI==="1"});var st,im,UD,dT,_D=Et(()=>{OD();st=class extends Error{constructor(e){super(e),this.clipanion={type:"usage"},this.name="UsageError"}},im=class extends Error{constructor(e,r){if(super(),this.input=e,this.candidates=r,this.clipanion={type:"none"},this.name="UnknownSyntaxError",this.candidates.length===0)this.message="Command not found, but we're not sure what's the alternative.";else if(this.candidates.every(o=>o.reason!==null&&o.reason===r[0].reason)){let[{reason:o}]=this.candidates;this.message=`${o} + +${this.candidates.map(({usage:a})=>`$ ${a}`).join(` +`)}`}else if(this.candidates.length===1){let[{usage:o}]=this.candidates;this.message=`Command not found; did you mean: + +$ ${o} +${dT(e)}`}else this.message=`Command not found; did you mean one of: + +${this.candidates.map(({usage:o},a)=>`${`${a}.`.padStart(4)} ${o}`).join(` +`)} + +${dT(e)}`}},UD=class extends Error{constructor(e,r){super(),this.input=e,this.usages=r,this.clipanion={type:"none"},this.name="AmbiguousSyntaxError",this.message=`Cannot find which to pick amongst the following alternatives: + +${this.usages.map((o,a)=>`${`${a}.`.padStart(4)} ${o}`).join(` +`)} + +${dT(e)}`}},dT=t=>`While running ${t.filter(e=>e!==Hn.EndOfInput&&e!==Hn.EndOfPartialInput).map(e=>{let r=JSON.stringify(e);return e.match(/\s/)||e.length===0||r!==`"${e}"`?r:e}).join(" ")}`});function Z6e(t){let e=t.split(` +`),r=e.filter(a=>a.match(/\S/)),o=r.length>0?r.reduce((a,n)=>Math.min(a,n.length-n.trimStart().length),Number.MAX_VALUE):0;return e.map(a=>a.slice(o).trimRight()).join(` +`)}function Do(t,{format:e,paragraphs:r}){return t=t.replace(/\r\n?/g,` +`),t=Z6e(t),t=t.replace(/^\n+|\n+$/g,""),t=t.replace(/^(\s*)-([^\n]*?)\n+/gm,`$1-$2 + +`),t=t.replace(/\n(\n)?\n*/g,(o,a)=>a||" "),r&&(t=t.split(/\n/).map(o=>{let a=o.match(/^\s*[*-][\t ]+(.*)/);if(!a)return o.match(/(.{1,80})(?: |$)/g).join(` +`);let n=o.length-o.trimStart().length;return a[1].match(new RegExp(`(.{1,${78-n}})(?: |$)`,"g")).map((u,A)=>" ".repeat(n)+(A===0?"- ":" ")+u).join(` +`)}).join(` + +`)),t=t.replace(/(`+)((?:.|[\n])*?)\1/g,(o,a,n)=>e.code(a+n+a)),t=t.replace(/(\*\*)((?:.|[\n])*?)\1/g,(o,a,n)=>e.bold(a+n+a)),t?`${t} +`:""}var mT,uV,AV,yT=Et(()=>{mT=Array(80).fill("\u2501");for(let t=0;t<=24;++t)mT[mT.length-t]=`\x1B[38;5;${232+t}m\u2501`;uV={header:t=>`\x1B[1m\u2501\u2501\u2501 ${t}${t.length<75?` ${mT.slice(t.length+5).join("")}`:":"}\x1B[0m`,bold:t=>`\x1B[1m${t}\x1B[22m`,error:t=>`\x1B[31m\x1B[1m${t}\x1B[22m\x1B[39m`,code:t=>`\x1B[36m${t}\x1B[39m`},AV={header:t=>t,bold:t=>t,error:t=>t,code:t=>t}});function Ko(t){return{...t,[Uw]:!0}}function Gu(t,e){return typeof t>"u"?[t,e]:typeof t=="object"&&t!==null&&!Array.isArray(t)?[void 0,t]:[t,e]}function HD(t,{mergeName:e=!1}={}){let r=t.match(/^([^:]+): (.*)$/m);if(!r)return"validation failed";let[,o,a]=r;return e&&(a=a[0].toLowerCase()+a.slice(1)),a=o!=="."||!e?`${o.replace(/^\.(\[|$)/,"$1")}: ${a}`:`: ${a}`,a}function _w(t,e){return e.length===1?new st(`${t}${HD(e[0],{mergeName:!0})}`):new st(`${t}: +${e.map(r=>` +- ${HD(r)}`).join("")}`)}function $0(t,e,r){if(typeof r>"u")return e;let o=[],a=[],n=A=>{let p=e;return e=A,n.bind(null,p)};if(!r(e,{errors:o,coercions:a,coercion:n}))throw _w(`Invalid value for ${t}`,o);for(let[,A]of a)A();return e}var Uw,yf=Et(()=>{_D();Uw=Symbol("clipanion/isOption")});var Vo={};Vt(Vo,{KeyRelationship:()=>Yu,TypeAssertionError:()=>Gp,applyCascade:()=>jw,as:()=>mqe,assert:()=>hqe,assertWithErrors:()=>gqe,cascade:()=>YD,fn:()=>yqe,hasAtLeastOneKey:()=>DT,hasExactLength:()=>dV,hasForbiddenKeys:()=>Mqe,hasKeyRelationship:()=>Yw,hasMaxLength:()=>Cqe,hasMinLength:()=>Eqe,hasMutuallyExclusiveKeys:()=>Oqe,hasRequiredKeys:()=>Lqe,hasUniqueItems:()=>wqe,isArray:()=>qD,isAtLeast:()=>BT,isAtMost:()=>vqe,isBase64:()=>Fqe,isBoolean:()=>oqe,isDate:()=>lqe,isDict:()=>Aqe,isEnum:()=>Js,isHexColor:()=>Qqe,isISO8601:()=>kqe,isInExclusiveRange:()=>Pqe,isInInclusiveRange:()=>Dqe,isInstanceOf:()=>pqe,isInteger:()=>vT,isJSON:()=>Rqe,isLiteral:()=>pV,isLowerCase:()=>bqe,isMap:()=>uqe,isNegative:()=>Iqe,isNullable:()=>Nqe,isNumber:()=>wT,isObject:()=>hV,isOneOf:()=>IT,isOptional:()=>Tqe,isPartial:()=>fqe,isPayload:()=>aqe,isPositive:()=>Bqe,isRecord:()=>GD,isSet:()=>cqe,isString:()=>om,isTuple:()=>jD,isUUID4:()=>xqe,isUnknown:()=>CT,isUpperCase:()=>Sqe,makeTrait:()=>gV,makeValidator:()=>Hr,matchesRegExp:()=>qw,softAssert:()=>dqe});function qn(t){return t===null?"null":t===void 0?"undefined":t===""?"an empty string":typeof t=="symbol"?`<${t.toString()}>`:Array.isArray(t)?"an array":JSON.stringify(t)}function sm(t,e){if(t.length===0)return"nothing";if(t.length===1)return qn(t[0]);let r=t.slice(0,-1),o=t[t.length-1],a=t.length>2?`, ${e} `:` ${e} `;return`${r.map(n=>qn(n)).join(", ")}${a}${qn(o)}`}function jp(t,e){var r,o,a;return typeof e=="number"?`${(r=t?.p)!==null&&r!==void 0?r:"."}[${e}]`:$6e.test(e)?`${(o=t?.p)!==null&&o!==void 0?o:""}.${e}`:`${(a=t?.p)!==null&&a!==void 0?a:"."}[${JSON.stringify(e)}]`}function ET(t,e,r){return t===1?e:r}function pr({errors:t,p:e}={},r){return t?.push(`${e??"."}: ${r}`),!1}function iqe(t,e){return r=>{t[e]=r}}function Wu(t,e){return r=>{let o=t[e];return t[e]=r,Wu(t,e).bind(null,o)}}function Hw(t,e,r){let o=()=>(t(r()),a),a=()=>(t(e),o);return o}function CT(){return Hr({test:(t,e)=>!0})}function pV(t){return Hr({test:(e,r)=>e!==t?pr(r,`Expected ${qn(t)} (got ${qn(e)})`):!0})}function om(){return Hr({test:(t,e)=>typeof t!="string"?pr(e,`Expected a string (got ${qn(t)})`):!0})}function Js(t){let e=Array.isArray(t)?t:Object.values(t),r=e.every(a=>typeof a=="string"||typeof a=="number"),o=new Set(e);return o.size===1?pV([...o][0]):Hr({test:(a,n)=>o.has(a)?!0:r?pr(n,`Expected one of ${sm(e,"or")} (got ${qn(a)})`):pr(n,`Expected a valid enumeration value (got ${qn(a)})`)})}function oqe(){return Hr({test:(t,e)=>{var r;if(typeof t!="boolean"){if(typeof e?.coercions<"u"){if(typeof e?.coercion>"u")return pr(e,"Unbound coercion result");let o=sqe.get(t);if(typeof o<"u")return e.coercions.push([(r=e.p)!==null&&r!==void 0?r:".",e.coercion.bind(null,o)]),!0}return pr(e,`Expected a boolean (got ${qn(t)})`)}return!0}})}function wT(){return Hr({test:(t,e)=>{var r;if(typeof t!="number"){if(typeof e?.coercions<"u"){if(typeof e?.coercion>"u")return pr(e,"Unbound coercion result");let o;if(typeof t=="string"){let a;try{a=JSON.parse(t)}catch{}if(typeof a=="number")if(JSON.stringify(a)===t)o=a;else return pr(e,`Received a number that can't be safely represented by the runtime (${t})`)}if(typeof o<"u")return e.coercions.push([(r=e.p)!==null&&r!==void 0?r:".",e.coercion.bind(null,o)]),!0}return pr(e,`Expected a number (got ${qn(t)})`)}return!0}})}function aqe(t){return Hr({test:(e,r)=>{var o;if(typeof r?.coercions>"u")return pr(r,"The isPayload predicate can only be used with coercion enabled");if(typeof r.coercion>"u")return pr(r,"Unbound coercion result");if(typeof e!="string")return pr(r,`Expected a string (got ${qn(e)})`);let a;try{a=JSON.parse(e)}catch{return pr(r,`Expected a JSON string (got ${qn(e)})`)}let n={value:a};return t(a,Object.assign(Object.assign({},r),{coercion:Wu(n,"value")}))?(r.coercions.push([(o=r.p)!==null&&o!==void 0?o:".",r.coercion.bind(null,n.value)]),!0):!1}})}function lqe(){return Hr({test:(t,e)=>{var r;if(!(t instanceof Date)){if(typeof e?.coercions<"u"){if(typeof e?.coercion>"u")return pr(e,"Unbound coercion result");let o;if(typeof t=="string"&&fV.test(t))o=new Date(t);else{let a;if(typeof t=="string"){let n;try{n=JSON.parse(t)}catch{}typeof n=="number"&&(a=n)}else typeof t=="number"&&(a=t);if(typeof a<"u")if(Number.isSafeInteger(a)||!Number.isSafeInteger(a*1e3))o=new Date(a*1e3);else return pr(e,`Received a timestamp that can't be safely represented by the runtime (${t})`)}if(typeof o<"u")return e.coercions.push([(r=e.p)!==null&&r!==void 0?r:".",e.coercion.bind(null,o)]),!0}return pr(e,`Expected a date (got ${qn(t)})`)}return!0}})}function qD(t,{delimiter:e}={}){return Hr({test:(r,o)=>{var a;let n=r;if(typeof r=="string"&&typeof e<"u"&&typeof o?.coercions<"u"){if(typeof o?.coercion>"u")return pr(o,"Unbound coercion result");r=r.split(e)}if(!Array.isArray(r))return pr(o,`Expected an array (got ${qn(r)})`);let u=!0;for(let A=0,p=r.length;A{var n,u;if(Object.getPrototypeOf(o).toString()==="[object Set]")if(typeof a?.coercions<"u"){if(typeof a?.coercion>"u")return pr(a,"Unbound coercion result");let A=[...o],p=[...o];if(!r(p,Object.assign(Object.assign({},a),{coercion:void 0})))return!1;let h=()=>p.some((E,I)=>E!==A[I])?new Set(p):o;return a.coercions.push([(n=a.p)!==null&&n!==void 0?n:".",Hw(a.coercion,o,h)]),!0}else{let A=!0;for(let p of o)if(A=t(p,Object.assign({},a))&&A,!A&&a?.errors==null)break;return A}if(typeof a?.coercions<"u"){if(typeof a?.coercion>"u")return pr(a,"Unbound coercion result");let A={value:o};return r(o,Object.assign(Object.assign({},a),{coercion:Wu(A,"value")}))?(a.coercions.push([(u=a.p)!==null&&u!==void 0?u:".",Hw(a.coercion,o,()=>new Set(A.value))]),!0):!1}return pr(a,`Expected a set (got ${qn(o)})`)}})}function uqe(t,e){let r=qD(jD([t,e])),o=GD(e,{keys:t});return Hr({test:(a,n)=>{var u,A,p;if(Object.getPrototypeOf(a).toString()==="[object Map]")if(typeof n?.coercions<"u"){if(typeof n?.coercion>"u")return pr(n,"Unbound coercion result");let h=[...a],E=[...a];if(!r(E,Object.assign(Object.assign({},n),{coercion:void 0})))return!1;let I=()=>E.some((v,x)=>v[0]!==h[x][0]||v[1]!==h[x][1])?new Map(E):a;return n.coercions.push([(u=n.p)!==null&&u!==void 0?u:".",Hw(n.coercion,a,I)]),!0}else{let h=!0;for(let[E,I]of a)if(h=t(E,Object.assign({},n))&&h,!h&&n?.errors==null||(h=e(I,Object.assign(Object.assign({},n),{p:jp(n,E)}))&&h,!h&&n?.errors==null))break;return h}if(typeof n?.coercions<"u"){if(typeof n?.coercion>"u")return pr(n,"Unbound coercion result");let h={value:a};return Array.isArray(a)?r(a,Object.assign(Object.assign({},n),{coercion:void 0}))?(n.coercions.push([(A=n.p)!==null&&A!==void 0?A:".",Hw(n.coercion,a,()=>new Map(h.value))]),!0):!1:o(a,Object.assign(Object.assign({},n),{coercion:Wu(h,"value")}))?(n.coercions.push([(p=n.p)!==null&&p!==void 0?p:".",Hw(n.coercion,a,()=>new Map(Object.entries(h.value)))]),!0):!1}return pr(n,`Expected a map (got ${qn(a)})`)}})}function jD(t,{delimiter:e}={}){let r=dV(t.length);return Hr({test:(o,a)=>{var n;if(typeof o=="string"&&typeof e<"u"&&typeof a?.coercions<"u"){if(typeof a?.coercion>"u")return pr(a,"Unbound coercion result");o=o.split(e),a.coercions.push([(n=a.p)!==null&&n!==void 0?n:".",a.coercion.bind(null,o)])}if(!Array.isArray(o))return pr(a,`Expected a tuple (got ${qn(o)})`);let u=r(o,Object.assign({},a));for(let A=0,p=o.length;A{var n;if(Array.isArray(o)&&typeof a?.coercions<"u")return typeof a?.coercion>"u"?pr(a,"Unbound coercion result"):r(o,Object.assign(Object.assign({},a),{coercion:void 0}))?(o=Object.fromEntries(o),a.coercions.push([(n=a.p)!==null&&n!==void 0?n:".",a.coercion.bind(null,o)]),!0):!1;if(typeof o!="object"||o===null)return pr(a,`Expected an object (got ${qn(o)})`);let u=Object.keys(o),A=!0;for(let p=0,h=u.length;p{if(typeof a!="object"||a===null)return pr(n,`Expected an object (got ${qn(a)})`);let u=new Set([...r,...Object.keys(a)]),A={},p=!0;for(let h of u){if(h==="constructor"||h==="__proto__")p=pr(Object.assign(Object.assign({},n),{p:jp(n,h)}),"Unsafe property name");else{let E=Object.prototype.hasOwnProperty.call(t,h)?t[h]:void 0,I=Object.prototype.hasOwnProperty.call(a,h)?a[h]:void 0;typeof E<"u"?p=E(I,Object.assign(Object.assign({},n),{p:jp(n,h),coercion:Wu(a,h)}))&&p:e===null?p=pr(Object.assign(Object.assign({},n),{p:jp(n,h)}),`Extraneous property (got ${qn(I)})`):Object.defineProperty(A,h,{enumerable:!0,get:()=>I,set:iqe(a,h)})}if(!p&&n?.errors==null)break}return e!==null&&(p||n?.errors!=null)&&(p=e(A,n)&&p),p}});return Object.assign(o,{properties:t})}function fqe(t){return hV(t,{extra:GD(CT())})}function gV(t){return()=>t}function Hr({test:t}){return gV(t)()}function hqe(t,e){if(!e(t))throw new Gp}function gqe(t,e){let r=[];if(!e(t,{errors:r}))throw new Gp({errors:r})}function dqe(t,e){}function mqe(t,e,{coerce:r=!1,errors:o,throw:a}={}){let n=o?[]:void 0;if(!r){if(e(t,{errors:n}))return a?t:{value:t,errors:void 0};if(a)throw new Gp({errors:n});return{value:void 0,errors:n??!0}}let u={value:t},A=Wu(u,"value"),p=[];if(!e(t,{errors:n,coercion:A,coercions:p})){if(a)throw new Gp({errors:n});return{value:void 0,errors:n??!0}}for(let[,h]of p)h();return a?u.value:{value:u.value,errors:void 0}}function yqe(t,e){let r=jD(t);return(...o)=>{if(!r(o))throw new Gp;return e(...o)}}function Eqe(t){return Hr({test:(e,r)=>e.length>=t?!0:pr(r,`Expected to have a length of at least ${t} elements (got ${e.length})`)})}function Cqe(t){return Hr({test:(e,r)=>e.length<=t?!0:pr(r,`Expected to have a length of at most ${t} elements (got ${e.length})`)})}function dV(t){return Hr({test:(e,r)=>e.length!==t?pr(r,`Expected to have a length of exactly ${t} elements (got ${e.length})`):!0})}function wqe({map:t}={}){return Hr({test:(e,r)=>{let o=new Set,a=new Set;for(let n=0,u=e.length;nt<=0?!0:pr(e,`Expected to be negative (got ${t})`)})}function Bqe(){return Hr({test:(t,e)=>t>=0?!0:pr(e,`Expected to be positive (got ${t})`)})}function BT(t){return Hr({test:(e,r)=>e>=t?!0:pr(r,`Expected to be at least ${t} (got ${e})`)})}function vqe(t){return Hr({test:(e,r)=>e<=t?!0:pr(r,`Expected to be at most ${t} (got ${e})`)})}function Dqe(t,e){return Hr({test:(r,o)=>r>=t&&r<=e?!0:pr(o,`Expected to be in the [${t}; ${e}] range (got ${r})`)})}function Pqe(t,e){return Hr({test:(r,o)=>r>=t&&re!==Math.round(e)?pr(r,`Expected to be an integer (got ${e})`):!t&&!Number.isSafeInteger(e)?pr(r,`Expected to be a safe integer (got ${e})`):!0})}function qw(t){return Hr({test:(e,r)=>t.test(e)?!0:pr(r,`Expected to match the pattern ${t.toString()} (got ${qn(e)})`)})}function bqe(){return Hr({test:(t,e)=>t!==t.toLowerCase()?pr(e,`Expected to be all-lowercase (got ${t})`):!0})}function Sqe(){return Hr({test:(t,e)=>t!==t.toUpperCase()?pr(e,`Expected to be all-uppercase (got ${t})`):!0})}function xqe(){return Hr({test:(t,e)=>nqe.test(t)?!0:pr(e,`Expected to be a valid UUID v4 (got ${qn(t)})`)})}function kqe(){return Hr({test:(t,e)=>fV.test(t)?!0:pr(e,`Expected to be a valid ISO 8601 date string (got ${qn(t)})`)})}function Qqe({alpha:t=!1}){return Hr({test:(e,r)=>(t?eqe.test(e):tqe.test(e))?!0:pr(r,`Expected to be a valid hexadecimal color string (got ${qn(e)})`)})}function Fqe(){return Hr({test:(t,e)=>rqe.test(t)?!0:pr(e,`Expected to be a valid base 64 string (got ${qn(t)})`)})}function Rqe(t=CT()){return Hr({test:(e,r)=>{let o;try{o=JSON.parse(e)}catch{return pr(r,`Expected to be a valid JSON string (got ${qn(e)})`)}return t(o,r)}})}function YD(t,...e){let r=Array.isArray(e[0])?e[0]:e;return Hr({test:(o,a)=>{var n,u;let A={value:o},p=typeof a?.coercions<"u"?Wu(A,"value"):void 0,h=typeof a?.coercions<"u"?[]:void 0;if(!t(o,Object.assign(Object.assign({},a),{coercion:p,coercions:h})))return!1;let E=[];if(typeof h<"u")for(let[,I]of h)E.push(I());try{if(typeof a?.coercions<"u"){if(A.value!==o){if(typeof a?.coercion>"u")return pr(a,"Unbound coercion result");a.coercions.push([(n=a.p)!==null&&n!==void 0?n:".",a.coercion.bind(null,A.value)])}(u=a?.coercions)===null||u===void 0||u.push(...h)}return r.every(I=>I(A.value,a))}finally{for(let I of E)I()}}})}function jw(t,...e){let r=Array.isArray(e[0])?e[0]:e;return YD(t,r)}function Tqe(t){return Hr({test:(e,r)=>typeof e>"u"?!0:t(e,r)})}function Nqe(t){return Hr({test:(e,r)=>e===null?!0:t(e,r)})}function Lqe(t,e){var r;let o=new Set(t),a=Gw[(r=e?.missingIf)!==null&&r!==void 0?r:"missing"];return Hr({test:(n,u)=>{let A=new Set(Object.keys(n)),p=[];for(let h of o)a(A,h,n)||p.push(h);return p.length>0?pr(u,`Missing required ${ET(p.length,"property","properties")} ${sm(p,"and")}`):!0}})}function DT(t,e){var r;let o=new Set(t),a=Gw[(r=e?.missingIf)!==null&&r!==void 0?r:"missing"];return Hr({test:(n,u)=>Object.keys(n).some(h=>a(o,h,n))?!0:pr(u,`Missing at least one property from ${sm(Array.from(o),"or")}`)})}function Mqe(t,e){var r;let o=new Set(t),a=Gw[(r=e?.missingIf)!==null&&r!==void 0?r:"missing"];return Hr({test:(n,u)=>{let A=new Set(Object.keys(n)),p=[];for(let h of o)a(A,h,n)&&p.push(h);return p.length>0?pr(u,`Forbidden ${ET(p.length,"property","properties")} ${sm(p,"and")}`):!0}})}function Oqe(t,e){var r;let o=new Set(t),a=Gw[(r=e?.missingIf)!==null&&r!==void 0?r:"missing"];return Hr({test:(n,u)=>{let A=new Set(Object.keys(n)),p=[];for(let h of o)a(A,h,n)&&p.push(h);return p.length>1?pr(u,`Mutually exclusive properties ${sm(p,"and")}`):!0}})}function Yw(t,e,r,o){var a,n;let u=new Set((a=o?.ignore)!==null&&a!==void 0?a:[]),A=Gw[(n=o?.missingIf)!==null&&n!==void 0?n:"missing"],p=new Set(r),h=Uqe[e],E=e===Yu.Forbids?"or":"and";return Hr({test:(I,v)=>{let x=new Set(Object.keys(I));if(!A(x,t,I)||u.has(I[t]))return!0;let C=[];for(let R of p)(A(x,R,I)&&!u.has(I[R]))!==h.expect&&C.push(R);return C.length>=1?pr(v,`Property "${t}" ${h.message} ${ET(C.length,"property","properties")} ${sm(C,E)}`):!0}})}var $6e,eqe,tqe,rqe,nqe,fV,sqe,pqe,IT,Gp,Gw,Yu,Uqe,el=Et(()=>{$6e=/^[a-zA-Z_][a-zA-Z0-9_]*$/;eqe=/^#[0-9a-f]{6}$/i,tqe=/^#[0-9a-f]{6}([0-9a-f]{2})?$/i,rqe=/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/,nqe=/^[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12}$/i,fV=/^(?:[1-9]\d{3}(-?)(?:(?:0[1-9]|1[0-2])\1(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])\1(?:29|30)|(?:0[13578]|1[02])(?:\1)31|00[1-9]|0[1-9]\d|[12]\d{2}|3(?:[0-5]\d|6[0-5]))|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)(?:(-?)02(?:\2)29|-?366))T(?:[01]\d|2[0-3])(:?)[0-5]\d(?:\3[0-5]\d)?(?:Z|[+-][01]\d(?:\3[0-5]\d)?)$/;sqe=new Map([["true",!0],["True",!0],["1",!0],[1,!0],["false",!1],["False",!1],["0",!1],[0,!1]]);pqe=t=>Hr({test:(e,r)=>e instanceof t?!0:pr(r,`Expected an instance of ${t.name} (got ${qn(e)})`)}),IT=(t,{exclusive:e=!1}={})=>Hr({test:(r,o)=>{var a,n,u;let A=[],p=typeof o?.errors<"u"?[]:void 0;for(let h=0,E=t.length;h1?pr(o,`Expected to match exactly a single predicate (matched ${A.join(", ")})`):(u=o?.errors)===null||u===void 0||u.push(...p),!1}});Gp=class extends Error{constructor({errors:e}={}){let r="Type mismatch";if(e&&e.length>0){r+=` +`;for(let o of e)r+=` +- ${o}`}super(r)}};Gw={missing:(t,e)=>t.has(e),undefined:(t,e,r)=>t.has(e)&&typeof r[e]<"u",nil:(t,e,r)=>t.has(e)&&r[e]!=null,falsy:(t,e,r)=>t.has(e)&&!!r[e]};(function(t){t.Forbids="Forbids",t.Requires="Requires"})(Yu||(Yu={}));Uqe={[Yu.Forbids]:{expect:!1,message:"forbids using"},[Yu.Requires]:{expect:!0,message:"requires using"}}});var it,Yp=Et(()=>{yf();it=class{constructor(){this.help=!1}static Usage(e){return e}async catch(e){throw e}async validateAndExecute(){let r=this.constructor.schema;if(Array.isArray(r)){let{isDict:a,isUnknown:n,applyCascade:u}=await Promise.resolve().then(()=>(el(),Vo)),A=u(a(n()),r),p=[],h=[];if(!A(this,{errors:p,coercions:h}))throw _w("Invalid option schema",p);for(let[,I]of h)I()}else if(r!=null)throw new Error("Invalid command schema");let o=await this.execute();return typeof o<"u"?o:0}};it.isOption=Uw;it.Default=[]});function Pa(t){gT&&console.log(t)}function yV(){let t={nodes:[]};for(let e=0;e{if(e.has(o))return;e.add(o);let a=t.nodes[o];for(let u of Object.values(a.statics))for(let{to:A}of u)r(A);for(let[,{to:u}]of a.dynamics)r(u);for(let{to:u}of a.shortcuts)r(u);let n=new Set(a.shortcuts.map(({to:u})=>u));for(;a.shortcuts.length>0;){let{to:u}=a.shortcuts.shift(),A=t.nodes[u];for(let[p,h]of Object.entries(A.statics)){let E=Object.prototype.hasOwnProperty.call(a.statics,p)?a.statics[p]:a.statics[p]=[];for(let I of h)E.some(({to:v})=>I.to===v)||E.push(I)}for(let[p,h]of A.dynamics)a.dynamics.some(([E,{to:I}])=>p===E&&h.to===I)||a.dynamics.push([p,h]);for(let p of A.shortcuts)n.has(p.to)||(a.shortcuts.push(p),n.add(p.to))}};r(un.InitialNode)}function qqe(t,{prefix:e=""}={}){if(gT){Pa(`${e}Nodes are:`);for(let r=0;rE!==un.ErrorNode).map(({state:E})=>({usage:E.candidateUsage,reason:null})));if(h.every(({node:E})=>E===un.ErrorNode))throw new im(e,h.map(({state:E})=>({usage:E.candidateUsage,reason:E.errorMessage})));o=Yqe(h)}if(o.length>0){Pa(" Results:");for(let n of o)Pa(` - ${n.node} -> ${JSON.stringify(n.state)}`)}else Pa(" No results");return o}function Gqe(t,e,{endToken:r=Hn.EndOfInput}={}){let o=jqe(t,[...e,r]);return Wqe(e,o.map(({state:a})=>a))}function Yqe(t){let e=0;for(let{state:r}of t)r.path.length>e&&(e=r.path.length);return t.filter(({state:r})=>r.path.length===e)}function Wqe(t,e){let r=e.filter(v=>v.selectedIndex!==null),o=r.filter(v=>!v.partial);if(o.length>0&&(r=o),r.length===0)throw new Error;let a=r.filter(v=>v.selectedIndex===Z0||v.requiredOptions.every(x=>x.some(C=>v.options.find(R=>R.name===C))));if(a.length===0)throw new im(t,r.map(v=>({usage:v.candidateUsage,reason:null})));let n=0;for(let v of a)v.path.length>n&&(n=v.path.length);let u=a.filter(v=>v.path.length===n),A=v=>v.positionals.filter(({extra:x})=>!x).length+v.options.length,p=u.map(v=>({state:v,positionalCount:A(v)})),h=0;for(let{positionalCount:v}of p)v>h&&(h=v);let E=p.filter(({positionalCount:v})=>v===h).map(({state:v})=>v),I=Kqe(E);if(I.length>1)throw new UD(t,I.map(v=>v.candidateUsage));return I[0]}function Kqe(t){let e=[],r=[];for(let o of t)o.selectedIndex===Z0?r.push(o):e.push(o);return r.length>0&&e.push({...mV,path:EV(...r.map(o=>o.path)),options:r.reduce((o,a)=>o.concat(a.options),[])}),e}function EV(t,e,...r){return e===void 0?Array.from(t):EV(t.filter((o,a)=>o===e[a]),...r)}function tl(){return{dynamics:[],shortcuts:[],statics:{}}}function CV(t){return t===un.SuccessNode||t===un.ErrorNode}function PT(t,e=0){return{to:CV(t.to)?t.to:t.to>=un.CustomNode?t.to+e-un.CustomNode+1:t.to+e,reducer:t.reducer}}function Vqe(t,e=0){let r=tl();for(let[o,a]of t.dynamics)r.dynamics.push([o,PT(a,e)]);for(let o of t.shortcuts)r.shortcuts.push(PT(o,e));for(let[o,a]of Object.entries(t.statics))r.statics[o]=a.map(n=>PT(n,e));return r}function xs(t,e,r,o,a){t.nodes[e].dynamics.push([r,{to:o,reducer:a}])}function am(t,e,r,o){t.nodes[e].shortcuts.push({to:r,reducer:o})}function zo(t,e,r,o,a){(Object.prototype.hasOwnProperty.call(t.nodes[e].statics,r)?t.nodes[e].statics[r]:t.nodes[e].statics[r]=[]).push({to:o,reducer:a})}function WD(t,e,r,o,a){if(Array.isArray(e)){let[n,...u]=e;return t[n](r,o,a,...u)}else return t[e](r,o,a)}var mV,zqe,bT,rl,ST,KD,VD=Et(()=>{OD();_D();mV={candidateUsage:null,requiredOptions:[],errorMessage:null,ignoreOptions:!1,path:[],positionals:[],options:[],remainder:null,selectedIndex:Z0,partial:!1,tokens:[]};zqe={always:()=>!0,isOptionLike:(t,e)=>!t.ignoreOptions&&e!=="-"&&e.startsWith("-"),isNotOptionLike:(t,e)=>t.ignoreOptions||e==="-"||!e.startsWith("-"),isOption:(t,e,r,o)=>!t.ignoreOptions&&e===o,isBatchOption:(t,e,r,o)=>!t.ignoreOptions&&cV.test(e)&&[...e.slice(1)].every(a=>o.has(`-${a}`)),isBoundOption:(t,e,r,o,a)=>{let n=e.match(hT);return!t.ignoreOptions&&!!n&&MD.test(n[1])&&o.has(n[1])&&a.filter(u=>u.nameSet.includes(n[1])).every(u=>u.allowBinding)},isNegatedOption:(t,e,r,o)=>!t.ignoreOptions&&e===`--no-${o.slice(2)}`,isHelp:(t,e)=>!t.ignoreOptions&&pT.test(e),isUnsupportedOption:(t,e,r,o)=>!t.ignoreOptions&&e.startsWith("-")&&MD.test(e)&&!o.has(e),isInvalidOption:(t,e)=>!t.ignoreOptions&&e.startsWith("-")&&!MD.test(e)},bT={setCandidateState:(t,e,r,o)=>({...t,...o}),setSelectedIndex:(t,e,r,o)=>({...t,selectedIndex:o}),setPartialIndex:(t,e,r,o)=>({...t,selectedIndex:o,partial:!0}),pushBatch:(t,e,r,o)=>{let a=t.options.slice(),n=t.tokens.slice();for(let u=1;u{let[,o,a]=e.match(hT),n=t.options.concat({name:o,value:a}),u=t.tokens.concat([{segmentIndex:r,type:"option",slice:[0,o.length],option:o},{segmentIndex:r,type:"assign",slice:[o.length,o.length+1]},{segmentIndex:r,type:"value",slice:[o.length+1,o.length+a.length+1]}]);return{...t,options:n,tokens:u}},pushPath:(t,e,r)=>{let o=t.path.concat(e),a=t.tokens.concat({segmentIndex:r,type:"path"});return{...t,path:o,tokens:a}},pushPositional:(t,e,r)=>{let o=t.positionals.concat({value:e,extra:!1}),a=t.tokens.concat({segmentIndex:r,type:"positional"});return{...t,positionals:o,tokens:a}},pushExtra:(t,e,r)=>{let o=t.positionals.concat({value:e,extra:!0}),a=t.tokens.concat({segmentIndex:r,type:"positional"});return{...t,positionals:o,tokens:a}},pushExtraNoLimits:(t,e,r)=>{let o=t.positionals.concat({value:e,extra:rl}),a=t.tokens.concat({segmentIndex:r,type:"positional"});return{...t,positionals:o,tokens:a}},pushTrue:(t,e,r,o)=>{let a=t.options.concat({name:o,value:!0}),n=t.tokens.concat({segmentIndex:r,type:"option",option:o});return{...t,options:a,tokens:n}},pushFalse:(t,e,r,o)=>{let a=t.options.concat({name:o,value:!1}),n=t.tokens.concat({segmentIndex:r,type:"option",option:o});return{...t,options:a,tokens:n}},pushUndefined:(t,e,r,o)=>{let a=t.options.concat({name:e,value:void 0}),n=t.tokens.concat({segmentIndex:r,type:"option",option:e});return{...t,options:a,tokens:n}},pushStringValue:(t,e,r)=>{var o;let a=t.options[t.options.length-1],n=t.options.slice(),u=t.tokens.concat({segmentIndex:r,type:"value"});return a.value=((o=a.value)!==null&&o!==void 0?o:[]).concat([e]),{...t,options:n,tokens:u}},setStringValue:(t,e,r)=>{let o=t.options[t.options.length-1],a=t.options.slice(),n=t.tokens.concat({segmentIndex:r,type:"value"});return o.value=e,{...t,options:a,tokens:n}},inhibateOptions:t=>({...t,ignoreOptions:!0}),useHelp:(t,e,r,o)=>{let[,,a]=e.match(pT);return typeof a<"u"?{...t,options:[{name:"-c",value:String(o)},{name:"-i",value:a}]}:{...t,options:[{name:"-c",value:String(o)}]}},setError:(t,e,r,o)=>e===Hn.EndOfInput||e===Hn.EndOfPartialInput?{...t,errorMessage:`${o}.`}:{...t,errorMessage:`${o} ("${e}").`},setOptionArityError:(t,e)=>{let r=t.options[t.options.length-1];return{...t,errorMessage:`Not enough arguments to option ${r.name}.`}}},rl=Symbol(),ST=class{constructor(e,r){this.allOptionNames=new Map,this.arity={leading:[],trailing:[],extra:[],proxy:!1},this.options=[],this.paths=[],this.cliIndex=e,this.cliOpts=r}addPath(e){this.paths.push(e)}setArity({leading:e=this.arity.leading,trailing:r=this.arity.trailing,extra:o=this.arity.extra,proxy:a=this.arity.proxy}){Object.assign(this.arity,{leading:e,trailing:r,extra:o,proxy:a})}addPositional({name:e="arg",required:r=!0}={}){if(!r&&this.arity.extra===rl)throw new Error("Optional parameters cannot be declared when using .rest() or .proxy()");if(!r&&this.arity.trailing.length>0)throw new Error("Optional parameters cannot be declared after the required trailing positional arguments");!r&&this.arity.extra!==rl?this.arity.extra.push(e):this.arity.extra!==rl&&this.arity.extra.length===0?this.arity.leading.push(e):this.arity.trailing.push(e)}addRest({name:e="arg",required:r=0}={}){if(this.arity.extra===rl)throw new Error("Infinite lists cannot be declared multiple times in the same command");if(this.arity.trailing.length>0)throw new Error("Infinite lists cannot be declared after the required trailing positional arguments");for(let o=0;o1)throw new Error("The arity cannot be higher than 1 when the option only supports the --arg=value syntax");if(!Number.isInteger(o))throw new Error(`The arity must be an integer, got ${o}`);if(o<0)throw new Error(`The arity must be positive, got ${o}`);let A=e.reduce((p,h)=>h.length>p.length?h:p,"");for(let p of e)this.allOptionNames.set(p,A);this.options.push({preferredName:A,nameSet:e,description:r,arity:o,hidden:a,required:n,allowBinding:u})}setContext(e){this.context=e}usage({detailed:e=!0,inlineOptions:r=!0}={}){let o=[this.cliOpts.binaryName],a=[];if(this.paths.length>0&&o.push(...this.paths[0]),e){for(let{preferredName:u,nameSet:A,arity:p,hidden:h,description:E,required:I}of this.options){if(h)continue;let v=[];for(let C=0;C`:`[${x}]`)}o.push(...this.arity.leading.map(u=>`<${u}>`)),this.arity.extra===rl?o.push("..."):o.push(...this.arity.extra.map(u=>`[${u}]`)),o.push(...this.arity.trailing.map(u=>`<${u}>`))}return{usage:o.join(" "),options:a}}compile(){if(typeof this.context>"u")throw new Error("Assertion failed: No context attached");let e=yV(),r=un.InitialNode,o=this.usage().usage,a=this.options.filter(A=>A.required).map(A=>A.nameSet);r=Oc(e,tl()),zo(e,un.InitialNode,Hn.StartOfInput,r,["setCandidateState",{candidateUsage:o,requiredOptions:a}]);let n=this.arity.proxy?"always":"isNotOptionLike",u=this.paths.length>0?this.paths:[[]];for(let A of u){let p=r;if(A.length>0){let v=Oc(e,tl());am(e,p,v),this.registerOptions(e,v),p=v}for(let v=0;v0||!this.arity.proxy){let v=Oc(e,tl());xs(e,p,"isHelp",v,["useHelp",this.cliIndex]),xs(e,v,"always",v,"pushExtra"),zo(e,v,Hn.EndOfInput,un.SuccessNode,["setSelectedIndex",Z0]),this.registerOptions(e,p)}this.arity.leading.length>0&&(zo(e,p,Hn.EndOfInput,un.ErrorNode,["setError","Not enough positional arguments"]),zo(e,p,Hn.EndOfPartialInput,un.SuccessNode,["setPartialIndex",this.cliIndex]));let h=p;for(let v=0;v0||v+1!==this.arity.leading.length)&&(zo(e,x,Hn.EndOfInput,un.ErrorNode,["setError","Not enough positional arguments"]),zo(e,x,Hn.EndOfPartialInput,un.SuccessNode,["setPartialIndex",this.cliIndex])),xs(e,h,"isNotOptionLike",x,"pushPositional"),h=x}let E=h;if(this.arity.extra===rl||this.arity.extra.length>0){let v=Oc(e,tl());if(am(e,h,v),this.arity.extra===rl){let x=Oc(e,tl());this.arity.proxy||this.registerOptions(e,x),xs(e,h,n,x,"pushExtraNoLimits"),xs(e,x,n,x,"pushExtraNoLimits"),am(e,x,v)}else for(let x=0;x0)&&this.registerOptions(e,C),xs(e,E,n,C,"pushExtra"),am(e,C,v),E=C}E=v}this.arity.trailing.length>0&&(zo(e,E,Hn.EndOfInput,un.ErrorNode,["setError","Not enough positional arguments"]),zo(e,E,Hn.EndOfPartialInput,un.SuccessNode,["setPartialIndex",this.cliIndex]));let I=E;for(let v=0;v=0&&e{let u=n?Hn.EndOfPartialInput:Hn.EndOfInput;return Gqe(o,a,{endToken:u})}}}}});function IV(){return zD.default&&"getColorDepth"in zD.default.WriteStream.prototype?zD.default.WriteStream.prototype.getColorDepth():process.env.FORCE_COLOR==="0"?1:process.env.FORCE_COLOR==="1"||typeof process.stdout<"u"&&process.stdout.isTTY?8:1}function BV(t){let e=wV;if(typeof e>"u"){if(t.stdout===process.stdout&&t.stderr===process.stderr)return null;let{AsyncLocalStorage:r}=ve("async_hooks");e=wV=new r;let o=process.stdout._write;process.stdout._write=function(n,u,A){let p=e.getStore();return typeof p>"u"?o.call(this,n,u,A):p.stdout.write(n,u,A)};let a=process.stderr._write;process.stderr._write=function(n,u,A){let p=e.getStore();return typeof p>"u"?a.call(this,n,u,A):p.stderr.write(n,u,A)}}return r=>e.run(t,r)}var zD,wV,vV=Et(()=>{zD=Ze(ve("tty"),1)});var JD,DV=Et(()=>{Yp();JD=class t extends it{constructor(e){super(),this.contexts=e,this.commands=[]}static from(e,r){let o=new t(r);o.path=e.path;for(let a of e.options)switch(a.name){case"-c":o.commands.push(Number(a.value));break;case"-i":o.index=Number(a.value);break}return o}async execute(){let e=this.commands;if(typeof this.index<"u"&&this.index>=0&&this.index1){this.context.stdout.write(`Multiple commands match your selection: +`),this.context.stdout.write(` +`);let r=0;for(let o of this.commands)this.context.stdout.write(this.cli.usage(this.contexts[o].commandClass,{prefix:`${r++}. `.padStart(5)}));this.context.stdout.write(` +`),this.context.stdout.write(`Run again with -h= to see the longer details of any of those commands. +`)}}}});async function SV(...t){let{resolvedOptions:e,resolvedCommandClasses:r,resolvedArgv:o,resolvedContext:a}=kV(t);return Jo.from(r,e).runExit(o,a)}async function xV(...t){let{resolvedOptions:e,resolvedCommandClasses:r,resolvedArgv:o,resolvedContext:a}=kV(t);return Jo.from(r,e).run(o,a)}function kV(t){let e,r,o,a;switch(typeof process<"u"&&typeof process.argv<"u"&&(o=process.argv.slice(2)),t.length){case 1:r=t[0];break;case 2:t[0]&&t[0].prototype instanceof it||Array.isArray(t[0])?(r=t[0],Array.isArray(t[1])?o=t[1]:a=t[1]):(e=t[0],r=t[1]);break;case 3:Array.isArray(t[2])?(e=t[0],r=t[1],o=t[2]):t[0]&&t[0].prototype instanceof it||Array.isArray(t[0])?(r=t[0],o=t[1],a=t[2]):(e=t[0],r=t[1],a=t[2]);break;default:e=t[0],r=t[1],o=t[2],a=t[3];break}if(typeof o>"u")throw new Error("The argv parameter must be provided when running Clipanion outside of a Node context");return{resolvedOptions:e,resolvedCommandClasses:r,resolvedArgv:o,resolvedContext:a}}function bV(t){return t()}var PV,Jo,QV=Et(()=>{OD();VD();yT();vV();Yp();DV();PV=Symbol("clipanion/errorCommand");Jo=class t{constructor({binaryLabel:e,binaryName:r="...",binaryVersion:o,enableCapture:a=!1,enableColors:n}={}){this.registrations=new Map,this.builder=new KD({binaryName:r}),this.binaryLabel=e,this.binaryName=r,this.binaryVersion=o,this.enableCapture=a,this.enableColors=n}static from(e,r={}){let o=new t(r),a=Array.isArray(e)?e:[e];for(let n of a)o.register(n);return o}register(e){var r;let o=new Map,a=new e;for(let p in a){let h=a[p];typeof h=="object"&&h!==null&&h[it.isOption]&&o.set(p,h)}let n=this.builder.command(),u=n.cliIndex,A=(r=e.paths)!==null&&r!==void 0?r:a.paths;if(typeof A<"u")for(let p of A)n.addPath(p);this.registrations.set(e,{specs:o,builder:n,index:u});for(let[p,{definition:h}]of o.entries())h(n,p);n.setContext({commandClass:e})}process(e,r){let{input:o,context:a,partial:n}=typeof e=="object"&&Array.isArray(e)?{input:e,context:r}:e,{contexts:u,process:A}=this.builder.compile(),p=A(o,{partial:n}),h={...t.defaultContext,...a};switch(p.selectedIndex){case Z0:{let E=JD.from(p,u);return E.context=h,E.tokens=p.tokens,E}default:{let{commandClass:E}=u[p.selectedIndex],I=this.registrations.get(E);if(typeof I>"u")throw new Error("Assertion failed: Expected the command class to have been registered.");let v=new E;v.context=h,v.tokens=p.tokens,v.path=p.path;try{for(let[x,{transformer:C}]of I.specs.entries())v[x]=C(I.builder,x,p,h);return v}catch(x){throw x[PV]=v,x}}break}}async run(e,r){var o,a;let n,u={...t.defaultContext,...r},A=(o=this.enableColors)!==null&&o!==void 0?o:u.colorDepth>1;if(!Array.isArray(e))n=e;else try{n=this.process(e,u)}catch(E){return u.stdout.write(this.error(E,{colored:A})),1}if(n.help)return u.stdout.write(this.usage(n,{colored:A,detailed:!0})),0;n.context=u,n.cli={binaryLabel:this.binaryLabel,binaryName:this.binaryName,binaryVersion:this.binaryVersion,enableCapture:this.enableCapture,enableColors:this.enableColors,definitions:()=>this.definitions(),definition:E=>this.definition(E),error:(E,I)=>this.error(E,I),format:E=>this.format(E),process:(E,I)=>this.process(E,{...u,...I}),run:(E,I)=>this.run(E,{...u,...I}),usage:(E,I)=>this.usage(E,I)};let p=this.enableCapture&&(a=BV(u))!==null&&a!==void 0?a:bV,h;try{h=await p(()=>n.validateAndExecute().catch(E=>n.catch(E).then(()=>0)))}catch(E){return u.stdout.write(this.error(E,{colored:A,command:n})),1}return h}async runExit(e,r){process.exitCode=await this.run(e,r)}definition(e,{colored:r=!1}={}){if(!e.usage)return null;let{usage:o}=this.getUsageByRegistration(e,{detailed:!1}),{usage:a,options:n}=this.getUsageByRegistration(e,{detailed:!0,inlineOptions:!1}),u=typeof e.usage.category<"u"?Do(e.usage.category,{format:this.format(r),paragraphs:!1}):void 0,A=typeof e.usage.description<"u"?Do(e.usage.description,{format:this.format(r),paragraphs:!1}):void 0,p=typeof e.usage.details<"u"?Do(e.usage.details,{format:this.format(r),paragraphs:!0}):void 0,h=typeof e.usage.examples<"u"?e.usage.examples.map(([E,I])=>[Do(E,{format:this.format(r),paragraphs:!1}),I.replace(/\$0/g,this.binaryName)]):void 0;return{path:o,usage:a,category:u,description:A,details:p,examples:h,options:n}}definitions({colored:e=!1}={}){let r=[];for(let o of this.registrations.keys()){let a=this.definition(o,{colored:e});a&&r.push(a)}return r}usage(e=null,{colored:r,detailed:o=!1,prefix:a="$ "}={}){var n;if(e===null){for(let p of this.registrations.keys()){let h=p.paths,E=typeof p.usage<"u";if(!h||h.length===0||h.length===1&&h[0].length===0||((n=h?.some(x=>x.length===0))!==null&&n!==void 0?n:!1))if(e){e=null;break}else e=p;else if(E){e=null;continue}}e&&(o=!0)}let u=e!==null&&e instanceof it?e.constructor:e,A="";if(u)if(o){let{description:p="",details:h="",examples:E=[]}=u.usage||{};p!==""&&(A+=Do(p,{format:this.format(r),paragraphs:!1}).replace(/^./,x=>x.toUpperCase()),A+=` +`),(h!==""||E.length>0)&&(A+=`${this.format(r).header("Usage")} +`,A+=` +`);let{usage:I,options:v}=this.getUsageByRegistration(u,{inlineOptions:!1});if(A+=`${this.format(r).bold(a)}${I} +`,v.length>0){A+=` +`,A+=`${this.format(r).header("Options")} +`;let x=v.reduce((C,R)=>Math.max(C,R.definition.length),0);A+=` +`;for(let{definition:C,description:R}of v)A+=` ${this.format(r).bold(C.padEnd(x))} ${Do(R,{format:this.format(r),paragraphs:!1})}`}if(h!==""&&(A+=` +`,A+=`${this.format(r).header("Details")} +`,A+=` +`,A+=Do(h,{format:this.format(r),paragraphs:!0})),E.length>0){A+=` +`,A+=`${this.format(r).header("Examples")} +`;for(let[x,C]of E)A+=` +`,A+=Do(x,{format:this.format(r),paragraphs:!1}),A+=`${C.replace(/^/m,` ${this.format(r).bold(a)}`).replace(/\$0/g,this.binaryName)} +`}}else{let{usage:p}=this.getUsageByRegistration(u);A+=`${this.format(r).bold(a)}${p} +`}else{let p=new Map;for(let[v,{index:x}]of this.registrations.entries()){if(typeof v.usage>"u")continue;let C=typeof v.usage.category<"u"?Do(v.usage.category,{format:this.format(r),paragraphs:!1}):null,R=p.get(C);typeof R>"u"&&p.set(C,R=[]);let{usage:L}=this.getUsageByIndex(x);R.push({commandClass:v,usage:L})}let h=Array.from(p.keys()).sort((v,x)=>v===null?-1:x===null?1:v.localeCompare(x,"en",{usage:"sort",caseFirst:"upper"})),E=typeof this.binaryLabel<"u",I=typeof this.binaryVersion<"u";E||I?(E&&I?A+=`${this.format(r).header(`${this.binaryLabel} - ${this.binaryVersion}`)} + +`:E?A+=`${this.format(r).header(`${this.binaryLabel}`)} +`:A+=`${this.format(r).header(`${this.binaryVersion}`)} +`,A+=` ${this.format(r).bold(a)}${this.binaryName} +`):A+=`${this.format(r).bold(a)}${this.binaryName} +`;for(let v of h){let x=p.get(v).slice().sort((R,L)=>R.usage.localeCompare(L.usage,"en",{usage:"sort",caseFirst:"upper"})),C=v!==null?v.trim():"General commands";A+=` +`,A+=`${this.format(r).header(`${C}`)} +`;for(let{commandClass:R,usage:L}of x){let U=R.usage.description||"undocumented";A+=` +`,A+=` ${this.format(r).bold(L)} +`,A+=` ${Do(U,{format:this.format(r),paragraphs:!1})}`}}A+=` +`,A+=Do("You can also print more details about any of these commands by calling them with the `-h,--help` flag right after the command name.",{format:this.format(r),paragraphs:!0})}return A}error(e,r){var o,{colored:a,command:n=(o=e[PV])!==null&&o!==void 0?o:null}=r===void 0?{}:r;(!e||typeof e!="object"||!("stack"in e))&&(e=new Error(`Execution failed with a non-error rejection (rejected value: ${JSON.stringify(e)})`));let u="",A=e.name.replace(/([a-z])([A-Z])/g,"$1 $2");A==="Error"&&(A="Internal Error"),u+=`${this.format(a).error(A)}: ${e.message} +`;let p=e.clipanion;return typeof p<"u"?p.type==="usage"&&(u+=` +`,u+=this.usage(n)):e.stack&&(u+=`${e.stack.replace(/^.*\n/,"")} +`),u}format(e){var r;return((r=e??this.enableColors)!==null&&r!==void 0?r:t.defaultContext.colorDepth>1)?uV:AV}getUsageByRegistration(e,r){let o=this.registrations.get(e);if(typeof o>"u")throw new Error("Assertion failed: Unregistered command");return this.getUsageByIndex(o.index,r)}getUsageByIndex(e,r){return this.builder.getBuilderByIndex(e).usage(r)}};Jo.defaultContext={env:process.env,stdin:process.stdin,stdout:process.stdout,stderr:process.stderr,colorDepth:IV()}});var Ww,FV=Et(()=>{Yp();Ww=class extends it{async execute(){this.context.stdout.write(`${JSON.stringify(this.cli.definitions(),null,2)} +`)}};Ww.paths=[["--clipanion=definitions"]]});var Kw,RV=Et(()=>{Yp();Kw=class extends it{async execute(){this.context.stdout.write(this.cli.usage())}};Kw.paths=[["-h"],["--help"]]});function XD(t={}){return Ko({definition(e,r){var o;e.addProxy({name:(o=t.name)!==null&&o!==void 0?o:r,required:t.required})},transformer(e,r,o){return o.positionals.map(({value:a})=>a)}})}var xT=Et(()=>{yf()});var Vw,TV=Et(()=>{Yp();xT();Vw=class extends it{constructor(){super(...arguments),this.args=XD()}async execute(){this.context.stdout.write(`${JSON.stringify(this.cli.process(this.args).tokens,null,2)} +`)}};Vw.paths=[["--clipanion=tokens"]]});var zw,NV=Et(()=>{Yp();zw=class extends it{async execute(){var e;this.context.stdout.write(`${(e=this.cli.binaryVersion)!==null&&e!==void 0?e:""} +`)}};zw.paths=[["-v"],["--version"]]});var kT={};Vt(kT,{DefinitionsCommand:()=>Ww,HelpCommand:()=>Kw,TokensCommand:()=>Vw,VersionCommand:()=>zw});var LV=Et(()=>{FV();RV();TV();NV()});function MV(t,e,r){let[o,a]=Gu(e,r??{}),{arity:n=1}=a,u=t.split(","),A=new Set(u);return Ko({definition(p){p.addOption({names:u,arity:n,hidden:a?.hidden,description:a?.description,required:a.required})},transformer(p,h,E){let I,v=typeof o<"u"?[...o]:void 0;for(let{name:x,value:C}of E.options)A.has(x)&&(I=x,v=v??[],v.push(C));return typeof v<"u"?$0(I??h,v,a.validator):v}})}var OV=Et(()=>{yf()});function UV(t,e,r){let[o,a]=Gu(e,r??{}),n=t.split(","),u=new Set(n);return Ko({definition(A){A.addOption({names:n,allowBinding:!1,arity:0,hidden:a.hidden,description:a.description,required:a.required})},transformer(A,p,h){let E=o;for(let{name:I,value:v}of h.options)u.has(I)&&(E=v);return E}})}var _V=Et(()=>{yf()});function HV(t,e,r){let[o,a]=Gu(e,r??{}),n=t.split(","),u=new Set(n);return Ko({definition(A){A.addOption({names:n,allowBinding:!1,arity:0,hidden:a.hidden,description:a.description,required:a.required})},transformer(A,p,h){let E=o;for(let{name:I,value:v}of h.options)u.has(I)&&(E??(E=0),v?E+=1:E=0);return E}})}var qV=Et(()=>{yf()});function jV(t={}){return Ko({definition(e,r){var o;e.addRest({name:(o=t.name)!==null&&o!==void 0?o:r,required:t.required})},transformer(e,r,o){let a=u=>{let A=o.positionals[u];return A.extra===rl||A.extra===!1&&uu)}})}var GV=Et(()=>{VD();yf()});function Jqe(t,e,r){let[o,a]=Gu(e,r??{}),{arity:n=1}=a,u=t.split(","),A=new Set(u);return Ko({definition(p){p.addOption({names:u,arity:a.tolerateBoolean?0:n,hidden:a.hidden,description:a.description,required:a.required})},transformer(p,h,E,I){let v,x=o;typeof a.env<"u"&&I.env[a.env]&&(v=a.env,x=I.env[a.env]);for(let{name:C,value:R}of E.options)A.has(C)&&(v=C,x=R);return typeof x=="string"?$0(v??h,x,a.validator):x}})}function Xqe(t={}){let{required:e=!0}=t;return Ko({definition(r,o){var a;r.addPositional({name:(a=t.name)!==null&&a!==void 0?a:o,required:t.required})},transformer(r,o,a){var n;for(let u=0;u{VD();yf()});var ge={};Vt(ge,{Array:()=>MV,Boolean:()=>UV,Counter:()=>HV,Proxy:()=>XD,Rest:()=>jV,String:()=>YV,applyValidator:()=>$0,cleanValidationError:()=>HD,formatError:()=>_w,isOptionSymbol:()=>Uw,makeCommandOption:()=>Ko,rerouteArguments:()=>Gu});var KV=Et(()=>{yf();xT();OV();_V();qV();GV();WV()});var Jw={};Vt(Jw,{Builtins:()=>kT,Cli:()=>Jo,Command:()=>it,Option:()=>ge,UsageError:()=>st,formatMarkdownish:()=>Do,run:()=>xV,runExit:()=>SV});var qt=Et(()=>{_D();yT();Yp();QV();LV();KV()});var VV=_((Rkt,Zqe)=>{Zqe.exports={name:"dotenv",version:"16.3.1",description:"Loads environment variables from .env file",main:"lib/main.js",types:"lib/main.d.ts",exports:{".":{types:"./lib/main.d.ts",require:"./lib/main.js",default:"./lib/main.js"},"./config":"./config.js","./config.js":"./config.js","./lib/env-options":"./lib/env-options.js","./lib/env-options.js":"./lib/env-options.js","./lib/cli-options":"./lib/cli-options.js","./lib/cli-options.js":"./lib/cli-options.js","./package.json":"./package.json"},scripts:{"dts-check":"tsc --project tests/types/tsconfig.json",lint:"standard","lint-readme":"standard-markdown",pretest:"npm run lint && npm run dts-check",test:"tap tests/*.js --100 -Rspec",prerelease:"npm test",release:"standard-version"},repository:{type:"git",url:"git://github.com/motdotla/dotenv.git"},funding:"https://github.com/motdotla/dotenv?sponsor=1",keywords:["dotenv","env",".env","environment","variables","config","settings"],readmeFilename:"README.md",license:"BSD-2-Clause",devDependencies:{"@definitelytyped/dtslint":"^0.0.133","@types/node":"^18.11.3",decache:"^4.6.1",sinon:"^14.0.1",standard:"^17.0.0","standard-markdown":"^7.1.0","standard-version":"^9.5.0",tap:"^16.3.0",tar:"^6.1.11",typescript:"^4.8.4"},engines:{node:">=12"},browser:{fs:!1}}});var ZV=_((Tkt,Ef)=>{var zV=ve("fs"),FT=ve("path"),$qe=ve("os"),eje=ve("crypto"),tje=VV(),RT=tje.version,rje=/(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg;function nje(t){let e={},r=t.toString();r=r.replace(/\r\n?/mg,` +`);let o;for(;(o=rje.exec(r))!=null;){let a=o[1],n=o[2]||"";n=n.trim();let u=n[0];n=n.replace(/^(['"`])([\s\S]*)\1$/mg,"$2"),u==='"'&&(n=n.replace(/\\n/g,` +`),n=n.replace(/\\r/g,"\r")),e[a]=n}return e}function ije(t){let e=XV(t),r=ks.configDotenv({path:e});if(!r.parsed)throw new Error(`MISSING_DATA: Cannot parse ${e} for an unknown reason`);let o=JV(t).split(","),a=o.length,n;for(let u=0;u=a)throw A}return ks.parse(n)}function sje(t){console.log(`[dotenv@${RT}][INFO] ${t}`)}function oje(t){console.log(`[dotenv@${RT}][WARN] ${t}`)}function QT(t){console.log(`[dotenv@${RT}][DEBUG] ${t}`)}function JV(t){return t&&t.DOTENV_KEY&&t.DOTENV_KEY.length>0?t.DOTENV_KEY:process.env.DOTENV_KEY&&process.env.DOTENV_KEY.length>0?process.env.DOTENV_KEY:""}function aje(t,e){let r;try{r=new URL(e)}catch(A){throw A.code==="ERR_INVALID_URL"?new Error("INVALID_DOTENV_KEY: Wrong format. Must be in valid uri format like dotenv://:key_1234@dotenv.org/vault/.env.vault?environment=development"):A}let o=r.password;if(!o)throw new Error("INVALID_DOTENV_KEY: Missing key part");let a=r.searchParams.get("environment");if(!a)throw new Error("INVALID_DOTENV_KEY: Missing environment part");let n=`DOTENV_VAULT_${a.toUpperCase()}`,u=t.parsed[n];if(!u)throw new Error(`NOT_FOUND_DOTENV_ENVIRONMENT: Cannot locate environment ${n} in your .env.vault file.`);return{ciphertext:u,key:o}}function XV(t){let e=FT.resolve(process.cwd(),".env");return t&&t.path&&t.path.length>0&&(e=t.path),e.endsWith(".vault")?e:`${e}.vault`}function lje(t){return t[0]==="~"?FT.join($qe.homedir(),t.slice(1)):t}function cje(t){sje("Loading env from encrypted .env.vault");let e=ks._parseVault(t),r=process.env;return t&&t.processEnv!=null&&(r=t.processEnv),ks.populate(r,e,t),{parsed:e}}function uje(t){let e=FT.resolve(process.cwd(),".env"),r="utf8",o=!!(t&&t.debug);t&&(t.path!=null&&(e=lje(t.path)),t.encoding!=null&&(r=t.encoding));try{let a=ks.parse(zV.readFileSync(e,{encoding:r})),n=process.env;return t&&t.processEnv!=null&&(n=t.processEnv),ks.populate(n,a,t),{parsed:a}}catch(a){return o&&QT(`Failed to load ${e} ${a.message}`),{error:a}}}function Aje(t){let e=XV(t);return JV(t).length===0?ks.configDotenv(t):zV.existsSync(e)?ks._configVault(t):(oje(`You set DOTENV_KEY but you are missing a .env.vault file at ${e}. Did you forget to build it?`),ks.configDotenv(t))}function fje(t,e){let r=Buffer.from(e.slice(-64),"hex"),o=Buffer.from(t,"base64"),a=o.slice(0,12),n=o.slice(-16);o=o.slice(12,-16);try{let u=eje.createDecipheriv("aes-256-gcm",r,a);return u.setAuthTag(n),`${u.update(o)}${u.final()}`}catch(u){let A=u instanceof RangeError,p=u.message==="Invalid key length",h=u.message==="Unsupported state or unable to authenticate data";if(A||p){let E="INVALID_DOTENV_KEY: It must be 64 characters long (or more)";throw new Error(E)}else if(h){let E="DECRYPTION_FAILED: Please check your DOTENV_KEY";throw new Error(E)}else throw console.error("Error: ",u.code),console.error("Error: ",u.message),u}}function pje(t,e,r={}){let o=!!(r&&r.debug),a=!!(r&&r.override);if(typeof e!="object")throw new Error("OBJECT_REQUIRED: Please check the processEnv argument being passed to populate");for(let n of Object.keys(e))Object.prototype.hasOwnProperty.call(t,n)?(a===!0&&(t[n]=e[n]),o&&QT(a===!0?`"${n}" is already defined and WAS overwritten`:`"${n}" is already defined and was NOT overwritten`)):t[n]=e[n]}var ks={configDotenv:uje,_configVault:cje,_parseVault:ije,config:Aje,decrypt:fje,parse:nje,populate:pje};Ef.exports.configDotenv=ks.configDotenv;Ef.exports._configVault=ks._configVault;Ef.exports._parseVault=ks._parseVault;Ef.exports.config=ks.config;Ef.exports.decrypt=ks.decrypt;Ef.exports.parse=ks.parse;Ef.exports.populate=ks.populate;Ef.exports=ks});var ez=_((Nkt,$V)=>{"use strict";$V.exports=(t,...e)=>new Promise(r=>{r(t(...e))})});var eg=_((Lkt,TT)=>{"use strict";var hje=ez(),tz=t=>{if(t<1)throw new TypeError("Expected `concurrency` to be a number from 1 and up");let e=[],r=0,o=()=>{r--,e.length>0&&e.shift()()},a=(A,p,...h)=>{r++;let E=hje(A,...h);p(E),E.then(o,o)},n=(A,p,...h)=>{rnew Promise(h=>n(A,h,...p));return Object.defineProperties(u,{activeCount:{get:()=>r},pendingCount:{get:()=>e.length}}),u};TT.exports=tz;TT.exports.default=tz});function Ku(t){return`YN${t.toString(10).padStart(4,"0")}`}function ZD(t){let e=Number(t.slice(2));if(typeof wr[e]>"u")throw new Error(`Unknown message name: "${t}"`);return e}var wr,$D=Et(()=>{wr=(Me=>(Me[Me.UNNAMED=0]="UNNAMED",Me[Me.EXCEPTION=1]="EXCEPTION",Me[Me.MISSING_PEER_DEPENDENCY=2]="MISSING_PEER_DEPENDENCY",Me[Me.CYCLIC_DEPENDENCIES=3]="CYCLIC_DEPENDENCIES",Me[Me.DISABLED_BUILD_SCRIPTS=4]="DISABLED_BUILD_SCRIPTS",Me[Me.BUILD_DISABLED=5]="BUILD_DISABLED",Me[Me.SOFT_LINK_BUILD=6]="SOFT_LINK_BUILD",Me[Me.MUST_BUILD=7]="MUST_BUILD",Me[Me.MUST_REBUILD=8]="MUST_REBUILD",Me[Me.BUILD_FAILED=9]="BUILD_FAILED",Me[Me.RESOLVER_NOT_FOUND=10]="RESOLVER_NOT_FOUND",Me[Me.FETCHER_NOT_FOUND=11]="FETCHER_NOT_FOUND",Me[Me.LINKER_NOT_FOUND=12]="LINKER_NOT_FOUND",Me[Me.FETCH_NOT_CACHED=13]="FETCH_NOT_CACHED",Me[Me.YARN_IMPORT_FAILED=14]="YARN_IMPORT_FAILED",Me[Me.REMOTE_INVALID=15]="REMOTE_INVALID",Me[Me.REMOTE_NOT_FOUND=16]="REMOTE_NOT_FOUND",Me[Me.RESOLUTION_PACK=17]="RESOLUTION_PACK",Me[Me.CACHE_CHECKSUM_MISMATCH=18]="CACHE_CHECKSUM_MISMATCH",Me[Me.UNUSED_CACHE_ENTRY=19]="UNUSED_CACHE_ENTRY",Me[Me.MISSING_LOCKFILE_ENTRY=20]="MISSING_LOCKFILE_ENTRY",Me[Me.WORKSPACE_NOT_FOUND=21]="WORKSPACE_NOT_FOUND",Me[Me.TOO_MANY_MATCHING_WORKSPACES=22]="TOO_MANY_MATCHING_WORKSPACES",Me[Me.CONSTRAINTS_MISSING_DEPENDENCY=23]="CONSTRAINTS_MISSING_DEPENDENCY",Me[Me.CONSTRAINTS_INCOMPATIBLE_DEPENDENCY=24]="CONSTRAINTS_INCOMPATIBLE_DEPENDENCY",Me[Me.CONSTRAINTS_EXTRANEOUS_DEPENDENCY=25]="CONSTRAINTS_EXTRANEOUS_DEPENDENCY",Me[Me.CONSTRAINTS_INVALID_DEPENDENCY=26]="CONSTRAINTS_INVALID_DEPENDENCY",Me[Me.CANT_SUGGEST_RESOLUTIONS=27]="CANT_SUGGEST_RESOLUTIONS",Me[Me.FROZEN_LOCKFILE_EXCEPTION=28]="FROZEN_LOCKFILE_EXCEPTION",Me[Me.CROSS_DRIVE_VIRTUAL_LOCAL=29]="CROSS_DRIVE_VIRTUAL_LOCAL",Me[Me.FETCH_FAILED=30]="FETCH_FAILED",Me[Me.DANGEROUS_NODE_MODULES=31]="DANGEROUS_NODE_MODULES",Me[Me.NODE_GYP_INJECTED=32]="NODE_GYP_INJECTED",Me[Me.AUTHENTICATION_NOT_FOUND=33]="AUTHENTICATION_NOT_FOUND",Me[Me.INVALID_CONFIGURATION_KEY=34]="INVALID_CONFIGURATION_KEY",Me[Me.NETWORK_ERROR=35]="NETWORK_ERROR",Me[Me.LIFECYCLE_SCRIPT=36]="LIFECYCLE_SCRIPT",Me[Me.CONSTRAINTS_MISSING_FIELD=37]="CONSTRAINTS_MISSING_FIELD",Me[Me.CONSTRAINTS_INCOMPATIBLE_FIELD=38]="CONSTRAINTS_INCOMPATIBLE_FIELD",Me[Me.CONSTRAINTS_EXTRANEOUS_FIELD=39]="CONSTRAINTS_EXTRANEOUS_FIELD",Me[Me.CONSTRAINTS_INVALID_FIELD=40]="CONSTRAINTS_INVALID_FIELD",Me[Me.AUTHENTICATION_INVALID=41]="AUTHENTICATION_INVALID",Me[Me.PROLOG_UNKNOWN_ERROR=42]="PROLOG_UNKNOWN_ERROR",Me[Me.PROLOG_SYNTAX_ERROR=43]="PROLOG_SYNTAX_ERROR",Me[Me.PROLOG_EXISTENCE_ERROR=44]="PROLOG_EXISTENCE_ERROR",Me[Me.STACK_OVERFLOW_RESOLUTION=45]="STACK_OVERFLOW_RESOLUTION",Me[Me.AUTOMERGE_FAILED_TO_PARSE=46]="AUTOMERGE_FAILED_TO_PARSE",Me[Me.AUTOMERGE_IMMUTABLE=47]="AUTOMERGE_IMMUTABLE",Me[Me.AUTOMERGE_SUCCESS=48]="AUTOMERGE_SUCCESS",Me[Me.AUTOMERGE_REQUIRED=49]="AUTOMERGE_REQUIRED",Me[Me.DEPRECATED_CLI_SETTINGS=50]="DEPRECATED_CLI_SETTINGS",Me[Me.PLUGIN_NAME_NOT_FOUND=51]="PLUGIN_NAME_NOT_FOUND",Me[Me.INVALID_PLUGIN_REFERENCE=52]="INVALID_PLUGIN_REFERENCE",Me[Me.CONSTRAINTS_AMBIGUITY=53]="CONSTRAINTS_AMBIGUITY",Me[Me.CACHE_OUTSIDE_PROJECT=54]="CACHE_OUTSIDE_PROJECT",Me[Me.IMMUTABLE_INSTALL=55]="IMMUTABLE_INSTALL",Me[Me.IMMUTABLE_CACHE=56]="IMMUTABLE_CACHE",Me[Me.INVALID_MANIFEST=57]="INVALID_MANIFEST",Me[Me.PACKAGE_PREPARATION_FAILED=58]="PACKAGE_PREPARATION_FAILED",Me[Me.INVALID_RANGE_PEER_DEPENDENCY=59]="INVALID_RANGE_PEER_DEPENDENCY",Me[Me.INCOMPATIBLE_PEER_DEPENDENCY=60]="INCOMPATIBLE_PEER_DEPENDENCY",Me[Me.DEPRECATED_PACKAGE=61]="DEPRECATED_PACKAGE",Me[Me.INCOMPATIBLE_OS=62]="INCOMPATIBLE_OS",Me[Me.INCOMPATIBLE_CPU=63]="INCOMPATIBLE_CPU",Me[Me.FROZEN_ARTIFACT_EXCEPTION=64]="FROZEN_ARTIFACT_EXCEPTION",Me[Me.TELEMETRY_NOTICE=65]="TELEMETRY_NOTICE",Me[Me.PATCH_HUNK_FAILED=66]="PATCH_HUNK_FAILED",Me[Me.INVALID_CONFIGURATION_VALUE=67]="INVALID_CONFIGURATION_VALUE",Me[Me.UNUSED_PACKAGE_EXTENSION=68]="UNUSED_PACKAGE_EXTENSION",Me[Me.REDUNDANT_PACKAGE_EXTENSION=69]="REDUNDANT_PACKAGE_EXTENSION",Me[Me.AUTO_NM_SUCCESS=70]="AUTO_NM_SUCCESS",Me[Me.NM_CANT_INSTALL_EXTERNAL_SOFT_LINK=71]="NM_CANT_INSTALL_EXTERNAL_SOFT_LINK",Me[Me.NM_PRESERVE_SYMLINKS_REQUIRED=72]="NM_PRESERVE_SYMLINKS_REQUIRED",Me[Me.UPDATE_LOCKFILE_ONLY_SKIP_LINK=73]="UPDATE_LOCKFILE_ONLY_SKIP_LINK",Me[Me.NM_HARDLINKS_MODE_DOWNGRADED=74]="NM_HARDLINKS_MODE_DOWNGRADED",Me[Me.PROLOG_INSTANTIATION_ERROR=75]="PROLOG_INSTANTIATION_ERROR",Me[Me.INCOMPATIBLE_ARCHITECTURE=76]="INCOMPATIBLE_ARCHITECTURE",Me[Me.GHOST_ARCHITECTURE=77]="GHOST_ARCHITECTURE",Me[Me.RESOLUTION_MISMATCH=78]="RESOLUTION_MISMATCH",Me[Me.PROLOG_LIMIT_EXCEEDED=79]="PROLOG_LIMIT_EXCEEDED",Me[Me.NETWORK_DISABLED=80]="NETWORK_DISABLED",Me[Me.NETWORK_UNSAFE_HTTP=81]="NETWORK_UNSAFE_HTTP",Me[Me.RESOLUTION_FAILED=82]="RESOLUTION_FAILED",Me[Me.AUTOMERGE_GIT_ERROR=83]="AUTOMERGE_GIT_ERROR",Me[Me.CONSTRAINTS_CHECK_FAILED=84]="CONSTRAINTS_CHECK_FAILED",Me[Me.UPDATED_RESOLUTION_RECORD=85]="UPDATED_RESOLUTION_RECORD",Me[Me.EXPLAIN_PEER_DEPENDENCIES_CTA=86]="EXPLAIN_PEER_DEPENDENCIES_CTA",Me[Me.MIGRATION_SUCCESS=87]="MIGRATION_SUCCESS",Me[Me.VERSION_NOTICE=88]="VERSION_NOTICE",Me[Me.TIPS_NOTICE=89]="TIPS_NOTICE",Me[Me.OFFLINE_MODE_ENABLED=90]="OFFLINE_MODE_ENABLED",Me))(wr||{})});var Xw=_((Okt,rz)=>{var gje="2.0.0",dje=Number.MAX_SAFE_INTEGER||9007199254740991,mje=16,yje=250,Eje=["major","premajor","minor","preminor","patch","prepatch","prerelease"];rz.exports={MAX_LENGTH:256,MAX_SAFE_COMPONENT_LENGTH:mje,MAX_SAFE_BUILD_LENGTH:yje,MAX_SAFE_INTEGER:dje,RELEASE_TYPES:Eje,SEMVER_SPEC_VERSION:gje,FLAG_INCLUDE_PRERELEASE:1,FLAG_LOOSE:2}});var Zw=_((Ukt,nz)=>{var Cje=typeof process=="object"&&process.env&&process.env.NODE_DEBUG&&/\bsemver\b/i.test(process.env.NODE_DEBUG)?(...t)=>console.error("SEMVER",...t):()=>{};nz.exports=Cje});var lm=_((Cf,iz)=>{var{MAX_SAFE_COMPONENT_LENGTH:NT,MAX_SAFE_BUILD_LENGTH:wje,MAX_LENGTH:Ije}=Xw(),Bje=Zw();Cf=iz.exports={};var vje=Cf.re=[],Dje=Cf.safeRe=[],$t=Cf.src=[],er=Cf.t={},Pje=0,LT="[a-zA-Z0-9-]",bje=[["\\s",1],["\\d",Ije],[LT,wje]],Sje=t=>{for(let[e,r]of bje)t=t.split(`${e}*`).join(`${e}{0,${r}}`).split(`${e}+`).join(`${e}{1,${r}}`);return t},jr=(t,e,r)=>{let o=Sje(e),a=Pje++;Bje(t,a,e),er[t]=a,$t[a]=e,vje[a]=new RegExp(e,r?"g":void 0),Dje[a]=new RegExp(o,r?"g":void 0)};jr("NUMERICIDENTIFIER","0|[1-9]\\d*");jr("NUMERICIDENTIFIERLOOSE","\\d+");jr("NONNUMERICIDENTIFIER",`\\d*[a-zA-Z-]${LT}*`);jr("MAINVERSION",`(${$t[er.NUMERICIDENTIFIER]})\\.(${$t[er.NUMERICIDENTIFIER]})\\.(${$t[er.NUMERICIDENTIFIER]})`);jr("MAINVERSIONLOOSE",`(${$t[er.NUMERICIDENTIFIERLOOSE]})\\.(${$t[er.NUMERICIDENTIFIERLOOSE]})\\.(${$t[er.NUMERICIDENTIFIERLOOSE]})`);jr("PRERELEASEIDENTIFIER",`(?:${$t[er.NUMERICIDENTIFIER]}|${$t[er.NONNUMERICIDENTIFIER]})`);jr("PRERELEASEIDENTIFIERLOOSE",`(?:${$t[er.NUMERICIDENTIFIERLOOSE]}|${$t[er.NONNUMERICIDENTIFIER]})`);jr("PRERELEASE",`(?:-(${$t[er.PRERELEASEIDENTIFIER]}(?:\\.${$t[er.PRERELEASEIDENTIFIER]})*))`);jr("PRERELEASELOOSE",`(?:-?(${$t[er.PRERELEASEIDENTIFIERLOOSE]}(?:\\.${$t[er.PRERELEASEIDENTIFIERLOOSE]})*))`);jr("BUILDIDENTIFIER",`${LT}+`);jr("BUILD",`(?:\\+(${$t[er.BUILDIDENTIFIER]}(?:\\.${$t[er.BUILDIDENTIFIER]})*))`);jr("FULLPLAIN",`v?${$t[er.MAINVERSION]}${$t[er.PRERELEASE]}?${$t[er.BUILD]}?`);jr("FULL",`^${$t[er.FULLPLAIN]}$`);jr("LOOSEPLAIN",`[v=\\s]*${$t[er.MAINVERSIONLOOSE]}${$t[er.PRERELEASELOOSE]}?${$t[er.BUILD]}?`);jr("LOOSE",`^${$t[er.LOOSEPLAIN]}$`);jr("GTLT","((?:<|>)?=?)");jr("XRANGEIDENTIFIERLOOSE",`${$t[er.NUMERICIDENTIFIERLOOSE]}|x|X|\\*`);jr("XRANGEIDENTIFIER",`${$t[er.NUMERICIDENTIFIER]}|x|X|\\*`);jr("XRANGEPLAIN",`[v=\\s]*(${$t[er.XRANGEIDENTIFIER]})(?:\\.(${$t[er.XRANGEIDENTIFIER]})(?:\\.(${$t[er.XRANGEIDENTIFIER]})(?:${$t[er.PRERELEASE]})?${$t[er.BUILD]}?)?)?`);jr("XRANGEPLAINLOOSE",`[v=\\s]*(${$t[er.XRANGEIDENTIFIERLOOSE]})(?:\\.(${$t[er.XRANGEIDENTIFIERLOOSE]})(?:\\.(${$t[er.XRANGEIDENTIFIERLOOSE]})(?:${$t[er.PRERELEASELOOSE]})?${$t[er.BUILD]}?)?)?`);jr("XRANGE",`^${$t[er.GTLT]}\\s*${$t[er.XRANGEPLAIN]}$`);jr("XRANGELOOSE",`^${$t[er.GTLT]}\\s*${$t[er.XRANGEPLAINLOOSE]}$`);jr("COERCEPLAIN",`(^|[^\\d])(\\d{1,${NT}})(?:\\.(\\d{1,${NT}}))?(?:\\.(\\d{1,${NT}}))?`);jr("COERCE",`${$t[er.COERCEPLAIN]}(?:$|[^\\d])`);jr("COERCEFULL",$t[er.COERCEPLAIN]+`(?:${$t[er.PRERELEASE]})?(?:${$t[er.BUILD]})?(?:$|[^\\d])`);jr("COERCERTL",$t[er.COERCE],!0);jr("COERCERTLFULL",$t[er.COERCEFULL],!0);jr("LONETILDE","(?:~>?)");jr("TILDETRIM",`(\\s*)${$t[er.LONETILDE]}\\s+`,!0);Cf.tildeTrimReplace="$1~";jr("TILDE",`^${$t[er.LONETILDE]}${$t[er.XRANGEPLAIN]}$`);jr("TILDELOOSE",`^${$t[er.LONETILDE]}${$t[er.XRANGEPLAINLOOSE]}$`);jr("LONECARET","(?:\\^)");jr("CARETTRIM",`(\\s*)${$t[er.LONECARET]}\\s+`,!0);Cf.caretTrimReplace="$1^";jr("CARET",`^${$t[er.LONECARET]}${$t[er.XRANGEPLAIN]}$`);jr("CARETLOOSE",`^${$t[er.LONECARET]}${$t[er.XRANGEPLAINLOOSE]}$`);jr("COMPARATORLOOSE",`^${$t[er.GTLT]}\\s*(${$t[er.LOOSEPLAIN]})$|^$`);jr("COMPARATOR",`^${$t[er.GTLT]}\\s*(${$t[er.FULLPLAIN]})$|^$`);jr("COMPARATORTRIM",`(\\s*)${$t[er.GTLT]}\\s*(${$t[er.LOOSEPLAIN]}|${$t[er.XRANGEPLAIN]})`,!0);Cf.comparatorTrimReplace="$1$2$3";jr("HYPHENRANGE",`^\\s*(${$t[er.XRANGEPLAIN]})\\s+-\\s+(${$t[er.XRANGEPLAIN]})\\s*$`);jr("HYPHENRANGELOOSE",`^\\s*(${$t[er.XRANGEPLAINLOOSE]})\\s+-\\s+(${$t[er.XRANGEPLAINLOOSE]})\\s*$`);jr("STAR","(<|>)?=?\\s*\\*");jr("GTE0","^\\s*>=\\s*0\\.0\\.0\\s*$");jr("GTE0PRE","^\\s*>=\\s*0\\.0\\.0-0\\s*$")});var eP=_((_kt,sz)=>{var xje=Object.freeze({loose:!0}),kje=Object.freeze({}),Qje=t=>t?typeof t!="object"?xje:t:kje;sz.exports=Qje});var MT=_((Hkt,lz)=>{var oz=/^[0-9]+$/,az=(t,e)=>{let r=oz.test(t),o=oz.test(e);return r&&o&&(t=+t,e=+e),t===e?0:r&&!o?-1:o&&!r?1:taz(e,t);lz.exports={compareIdentifiers:az,rcompareIdentifiers:Fje}});var Po=_((qkt,fz)=>{var tP=Zw(),{MAX_LENGTH:cz,MAX_SAFE_INTEGER:rP}=Xw(),{safeRe:uz,t:Az}=lm(),Rje=eP(),{compareIdentifiers:cm}=MT(),OT=class t{constructor(e,r){if(r=Rje(r),e instanceof t){if(e.loose===!!r.loose&&e.includePrerelease===!!r.includePrerelease)return e;e=e.version}else if(typeof e!="string")throw new TypeError(`Invalid version. Must be a string. Got type "${typeof e}".`);if(e.length>cz)throw new TypeError(`version is longer than ${cz} characters`);tP("SemVer",e,r),this.options=r,this.loose=!!r.loose,this.includePrerelease=!!r.includePrerelease;let o=e.trim().match(r.loose?uz[Az.LOOSE]:uz[Az.FULL]);if(!o)throw new TypeError(`Invalid Version: ${e}`);if(this.raw=e,this.major=+o[1],this.minor=+o[2],this.patch=+o[3],this.major>rP||this.major<0)throw new TypeError("Invalid major version");if(this.minor>rP||this.minor<0)throw new TypeError("Invalid minor version");if(this.patch>rP||this.patch<0)throw new TypeError("Invalid patch version");o[4]?this.prerelease=o[4].split(".").map(a=>{if(/^[0-9]+$/.test(a)){let n=+a;if(n>=0&&n=0;)typeof this.prerelease[n]=="number"&&(this.prerelease[n]++,n=-2);if(n===-1){if(r===this.prerelease.join(".")&&o===!1)throw new Error("invalid increment argument: identifier already exists");this.prerelease.push(a)}}if(r){let n=[r,a];o===!1&&(n=[r]),cm(this.prerelease[0],r)===0?isNaN(this.prerelease[1])&&(this.prerelease=n):this.prerelease=n}break}default:throw new Error(`invalid increment argument: ${e}`)}return this.raw=this.format(),this.build.length&&(this.raw+=`+${this.build.join(".")}`),this}};fz.exports=OT});var tg=_((jkt,hz)=>{var pz=Po(),Tje=(t,e,r=!1)=>{if(t instanceof pz)return t;try{return new pz(t,e)}catch(o){if(!r)return null;throw o}};hz.exports=Tje});var dz=_((Gkt,gz)=>{var Nje=tg(),Lje=(t,e)=>{let r=Nje(t,e);return r?r.version:null};gz.exports=Lje});var yz=_((Ykt,mz)=>{var Mje=tg(),Oje=(t,e)=>{let r=Mje(t.trim().replace(/^[=v]+/,""),e);return r?r.version:null};mz.exports=Oje});var wz=_((Wkt,Cz)=>{var Ez=Po(),Uje=(t,e,r,o,a)=>{typeof r=="string"&&(a=o,o=r,r=void 0);try{return new Ez(t instanceof Ez?t.version:t,r).inc(e,o,a).version}catch{return null}};Cz.exports=Uje});var vz=_((Kkt,Bz)=>{var Iz=tg(),_je=(t,e)=>{let r=Iz(t,null,!0),o=Iz(e,null,!0),a=r.compare(o);if(a===0)return null;let n=a>0,u=n?r:o,A=n?o:r,p=!!u.prerelease.length;if(!!A.prerelease.length&&!p)return!A.patch&&!A.minor?"major":u.patch?"patch":u.minor?"minor":"major";let E=p?"pre":"";return r.major!==o.major?E+"major":r.minor!==o.minor?E+"minor":r.patch!==o.patch?E+"patch":"prerelease"};Bz.exports=_je});var Pz=_((Vkt,Dz)=>{var Hje=Po(),qje=(t,e)=>new Hje(t,e).major;Dz.exports=qje});var Sz=_((zkt,bz)=>{var jje=Po(),Gje=(t,e)=>new jje(t,e).minor;bz.exports=Gje});var kz=_((Jkt,xz)=>{var Yje=Po(),Wje=(t,e)=>new Yje(t,e).patch;xz.exports=Wje});var Fz=_((Xkt,Qz)=>{var Kje=tg(),Vje=(t,e)=>{let r=Kje(t,e);return r&&r.prerelease.length?r.prerelease:null};Qz.exports=Vje});var Ll=_((Zkt,Tz)=>{var Rz=Po(),zje=(t,e,r)=>new Rz(t,r).compare(new Rz(e,r));Tz.exports=zje});var Lz=_(($kt,Nz)=>{var Jje=Ll(),Xje=(t,e,r)=>Jje(e,t,r);Nz.exports=Xje});var Oz=_((eQt,Mz)=>{var Zje=Ll(),$je=(t,e)=>Zje(t,e,!0);Mz.exports=$je});var nP=_((tQt,_z)=>{var Uz=Po(),e5e=(t,e,r)=>{let o=new Uz(t,r),a=new Uz(e,r);return o.compare(a)||o.compareBuild(a)};_z.exports=e5e});var qz=_((rQt,Hz)=>{var t5e=nP(),r5e=(t,e)=>t.sort((r,o)=>t5e(r,o,e));Hz.exports=r5e});var Gz=_((nQt,jz)=>{var n5e=nP(),i5e=(t,e)=>t.sort((r,o)=>n5e(o,r,e));jz.exports=i5e});var $w=_((iQt,Yz)=>{var s5e=Ll(),o5e=(t,e,r)=>s5e(t,e,r)>0;Yz.exports=o5e});var iP=_((sQt,Wz)=>{var a5e=Ll(),l5e=(t,e,r)=>a5e(t,e,r)<0;Wz.exports=l5e});var UT=_((oQt,Kz)=>{var c5e=Ll(),u5e=(t,e,r)=>c5e(t,e,r)===0;Kz.exports=u5e});var _T=_((aQt,Vz)=>{var A5e=Ll(),f5e=(t,e,r)=>A5e(t,e,r)!==0;Vz.exports=f5e});var sP=_((lQt,zz)=>{var p5e=Ll(),h5e=(t,e,r)=>p5e(t,e,r)>=0;zz.exports=h5e});var oP=_((cQt,Jz)=>{var g5e=Ll(),d5e=(t,e,r)=>g5e(t,e,r)<=0;Jz.exports=d5e});var HT=_((uQt,Xz)=>{var m5e=UT(),y5e=_T(),E5e=$w(),C5e=sP(),w5e=iP(),I5e=oP(),B5e=(t,e,r,o)=>{switch(e){case"===":return typeof t=="object"&&(t=t.version),typeof r=="object"&&(r=r.version),t===r;case"!==":return typeof t=="object"&&(t=t.version),typeof r=="object"&&(r=r.version),t!==r;case"":case"=":case"==":return m5e(t,r,o);case"!=":return y5e(t,r,o);case">":return E5e(t,r,o);case">=":return C5e(t,r,o);case"<":return w5e(t,r,o);case"<=":return I5e(t,r,o);default:throw new TypeError(`Invalid operator: ${e}`)}};Xz.exports=B5e});var $z=_((AQt,Zz)=>{var v5e=Po(),D5e=tg(),{safeRe:aP,t:lP}=lm(),P5e=(t,e)=>{if(t instanceof v5e)return t;if(typeof t=="number"&&(t=String(t)),typeof t!="string")return null;e=e||{};let r=null;if(!e.rtl)r=t.match(e.includePrerelease?aP[lP.COERCEFULL]:aP[lP.COERCE]);else{let p=e.includePrerelease?aP[lP.COERCERTLFULL]:aP[lP.COERCERTL],h;for(;(h=p.exec(t))&&(!r||r.index+r[0].length!==t.length);)(!r||h.index+h[0].length!==r.index+r[0].length)&&(r=h),p.lastIndex=h.index+h[1].length+h[2].length;p.lastIndex=-1}if(r===null)return null;let o=r[2],a=r[3]||"0",n=r[4]||"0",u=e.includePrerelease&&r[5]?`-${r[5]}`:"",A=e.includePrerelease&&r[6]?`+${r[6]}`:"";return D5e(`${o}.${a}.${n}${u}${A}`,e)};Zz.exports=P5e});var tJ=_((fQt,eJ)=>{"use strict";eJ.exports=function(t){t.prototype[Symbol.iterator]=function*(){for(let e=this.head;e;e=e.next)yield e.value}}});var cP=_((pQt,rJ)=>{"use strict";rJ.exports=Cn;Cn.Node=rg;Cn.create=Cn;function Cn(t){var e=this;if(e instanceof Cn||(e=new Cn),e.tail=null,e.head=null,e.length=0,t&&typeof t.forEach=="function")t.forEach(function(a){e.push(a)});else if(arguments.length>0)for(var r=0,o=arguments.length;r1)r=e;else if(this.head)o=this.head.next,r=this.head.value;else throw new TypeError("Reduce of empty list with no initial value");for(var a=0;o!==null;a++)r=t(r,o.value,a),o=o.next;return r};Cn.prototype.reduceReverse=function(t,e){var r,o=this.tail;if(arguments.length>1)r=e;else if(this.tail)o=this.tail.prev,r=this.tail.value;else throw new TypeError("Reduce of empty list with no initial value");for(var a=this.length-1;o!==null;a--)r=t(r,o.value,a),o=o.prev;return r};Cn.prototype.toArray=function(){for(var t=new Array(this.length),e=0,r=this.head;r!==null;e++)t[e]=r.value,r=r.next;return t};Cn.prototype.toArrayReverse=function(){for(var t=new Array(this.length),e=0,r=this.tail;r!==null;e++)t[e]=r.value,r=r.prev;return t};Cn.prototype.slice=function(t,e){e=e||this.length,e<0&&(e+=this.length),t=t||0,t<0&&(t+=this.length);var r=new Cn;if(ethis.length&&(e=this.length);for(var o=0,a=this.head;a!==null&&othis.length&&(e=this.length);for(var o=this.length,a=this.tail;a!==null&&o>e;o--)a=a.prev;for(;a!==null&&o>t;o--,a=a.prev)r.push(a.value);return r};Cn.prototype.splice=function(t,e,...r){t>this.length&&(t=this.length-1),t<0&&(t=this.length+t);for(var o=0,a=this.head;a!==null&&o{"use strict";var k5e=cP(),ng=Symbol("max"),If=Symbol("length"),um=Symbol("lengthCalculator"),tI=Symbol("allowStale"),ig=Symbol("maxAge"),wf=Symbol("dispose"),nJ=Symbol("noDisposeOnSet"),Qs=Symbol("lruList"),Uc=Symbol("cache"),sJ=Symbol("updateAgeOnGet"),qT=()=>1,GT=class{constructor(e){if(typeof e=="number"&&(e={max:e}),e||(e={}),e.max&&(typeof e.max!="number"||e.max<0))throw new TypeError("max must be a non-negative number");let r=this[ng]=e.max||1/0,o=e.length||qT;if(this[um]=typeof o!="function"?qT:o,this[tI]=e.stale||!1,e.maxAge&&typeof e.maxAge!="number")throw new TypeError("maxAge must be a number");this[ig]=e.maxAge||0,this[wf]=e.dispose,this[nJ]=e.noDisposeOnSet||!1,this[sJ]=e.updateAgeOnGet||!1,this.reset()}set max(e){if(typeof e!="number"||e<0)throw new TypeError("max must be a non-negative number");this[ng]=e||1/0,eI(this)}get max(){return this[ng]}set allowStale(e){this[tI]=!!e}get allowStale(){return this[tI]}set maxAge(e){if(typeof e!="number")throw new TypeError("maxAge must be a non-negative number");this[ig]=e,eI(this)}get maxAge(){return this[ig]}set lengthCalculator(e){typeof e!="function"&&(e=qT),e!==this[um]&&(this[um]=e,this[If]=0,this[Qs].forEach(r=>{r.length=this[um](r.value,r.key),this[If]+=r.length})),eI(this)}get lengthCalculator(){return this[um]}get length(){return this[If]}get itemCount(){return this[Qs].length}rforEach(e,r){r=r||this;for(let o=this[Qs].tail;o!==null;){let a=o.prev;iJ(this,e,o,r),o=a}}forEach(e,r){r=r||this;for(let o=this[Qs].head;o!==null;){let a=o.next;iJ(this,e,o,r),o=a}}keys(){return this[Qs].toArray().map(e=>e.key)}values(){return this[Qs].toArray().map(e=>e.value)}reset(){this[wf]&&this[Qs]&&this[Qs].length&&this[Qs].forEach(e=>this[wf](e.key,e.value)),this[Uc]=new Map,this[Qs]=new k5e,this[If]=0}dump(){return this[Qs].map(e=>uP(this,e)?!1:{k:e.key,v:e.value,e:e.now+(e.maxAge||0)}).toArray().filter(e=>e)}dumpLru(){return this[Qs]}set(e,r,o){if(o=o||this[ig],o&&typeof o!="number")throw new TypeError("maxAge must be a number");let a=o?Date.now():0,n=this[um](r,e);if(this[Uc].has(e)){if(n>this[ng])return Am(this,this[Uc].get(e)),!1;let p=this[Uc].get(e).value;return this[wf]&&(this[nJ]||this[wf](e,p.value)),p.now=a,p.maxAge=o,p.value=r,this[If]+=n-p.length,p.length=n,this.get(e),eI(this),!0}let u=new YT(e,r,n,a,o);return u.length>this[ng]?(this[wf]&&this[wf](e,r),!1):(this[If]+=u.length,this[Qs].unshift(u),this[Uc].set(e,this[Qs].head),eI(this),!0)}has(e){if(!this[Uc].has(e))return!1;let r=this[Uc].get(e).value;return!uP(this,r)}get(e){return jT(this,e,!0)}peek(e){return jT(this,e,!1)}pop(){let e=this[Qs].tail;return e?(Am(this,e),e.value):null}del(e){Am(this,this[Uc].get(e))}load(e){this.reset();let r=Date.now();for(let o=e.length-1;o>=0;o--){let a=e[o],n=a.e||0;if(n===0)this.set(a.k,a.v);else{let u=n-r;u>0&&this.set(a.k,a.v,u)}}}prune(){this[Uc].forEach((e,r)=>jT(this,r,!1))}},jT=(t,e,r)=>{let o=t[Uc].get(e);if(o){let a=o.value;if(uP(t,a)){if(Am(t,o),!t[tI])return}else r&&(t[sJ]&&(o.value.now=Date.now()),t[Qs].unshiftNode(o));return a.value}},uP=(t,e)=>{if(!e||!e.maxAge&&!t[ig])return!1;let r=Date.now()-e.now;return e.maxAge?r>e.maxAge:t[ig]&&r>t[ig]},eI=t=>{if(t[If]>t[ng])for(let e=t[Qs].tail;t[If]>t[ng]&&e!==null;){let r=e.prev;Am(t,e),e=r}},Am=(t,e)=>{if(e){let r=e.value;t[wf]&&t[wf](r.key,r.value),t[If]-=r.length,t[Uc].delete(r.key),t[Qs].removeNode(e)}},YT=class{constructor(e,r,o,a,n){this.key=e,this.value=r,this.length=o,this.now=a,this.maxAge=n||0}},iJ=(t,e,r,o)=>{let a=r.value;uP(t,a)&&(Am(t,r),t[tI]||(a=void 0)),a&&e.call(o,a.value,a.key,t)};oJ.exports=GT});var Ml=_((gQt,AJ)=>{var WT=class t{constructor(e,r){if(r=F5e(r),e instanceof t)return e.loose===!!r.loose&&e.includePrerelease===!!r.includePrerelease?e:new t(e.raw,r);if(e instanceof KT)return this.raw=e.value,this.set=[[e]],this.format(),this;if(this.options=r,this.loose=!!r.loose,this.includePrerelease=!!r.includePrerelease,this.raw=e.trim().split(/\s+/).join(" "),this.set=this.raw.split("||").map(o=>this.parseRange(o.trim())).filter(o=>o.length),!this.set.length)throw new TypeError(`Invalid SemVer Range: ${this.raw}`);if(this.set.length>1){let o=this.set[0];if(this.set=this.set.filter(a=>!cJ(a[0])),this.set.length===0)this.set=[o];else if(this.set.length>1){for(let a of this.set)if(a.length===1&&U5e(a[0])){this.set=[a];break}}}this.format()}format(){return this.range=this.set.map(e=>e.join(" ").trim()).join("||").trim(),this.range}toString(){return this.range}parseRange(e){let o=((this.options.includePrerelease&&M5e)|(this.options.loose&&O5e))+":"+e,a=lJ.get(o);if(a)return a;let n=this.options.loose,u=n?ba[Xo.HYPHENRANGELOOSE]:ba[Xo.HYPHENRANGE];e=e.replace(u,z5e(this.options.includePrerelease)),ci("hyphen replace",e),e=e.replace(ba[Xo.COMPARATORTRIM],T5e),ci("comparator trim",e),e=e.replace(ba[Xo.TILDETRIM],N5e),ci("tilde trim",e),e=e.replace(ba[Xo.CARETTRIM],L5e),ci("caret trim",e);let A=e.split(" ").map(I=>_5e(I,this.options)).join(" ").split(/\s+/).map(I=>V5e(I,this.options));n&&(A=A.filter(I=>(ci("loose invalid filter",I,this.options),!!I.match(ba[Xo.COMPARATORLOOSE])))),ci("range list",A);let p=new Map,h=A.map(I=>new KT(I,this.options));for(let I of h){if(cJ(I))return[I];p.set(I.value,I)}p.size>1&&p.has("")&&p.delete("");let E=[...p.values()];return lJ.set(o,E),E}intersects(e,r){if(!(e instanceof t))throw new TypeError("a Range is required");return this.set.some(o=>uJ(o,r)&&e.set.some(a=>uJ(a,r)&&o.every(n=>a.every(u=>n.intersects(u,r)))))}test(e){if(!e)return!1;if(typeof e=="string")try{e=new R5e(e,this.options)}catch{return!1}for(let r=0;rt.value==="<0.0.0-0",U5e=t=>t.value==="",uJ=(t,e)=>{let r=!0,o=t.slice(),a=o.pop();for(;r&&o.length;)r=o.every(n=>a.intersects(n,e)),a=o.pop();return r},_5e=(t,e)=>(ci("comp",t,e),t=j5e(t,e),ci("caret",t),t=H5e(t,e),ci("tildes",t),t=Y5e(t,e),ci("xrange",t),t=K5e(t,e),ci("stars",t),t),Zo=t=>!t||t.toLowerCase()==="x"||t==="*",H5e=(t,e)=>t.trim().split(/\s+/).map(r=>q5e(r,e)).join(" "),q5e=(t,e)=>{let r=e.loose?ba[Xo.TILDELOOSE]:ba[Xo.TILDE];return t.replace(r,(o,a,n,u,A)=>{ci("tilde",t,o,a,n,u,A);let p;return Zo(a)?p="":Zo(n)?p=`>=${a}.0.0 <${+a+1}.0.0-0`:Zo(u)?p=`>=${a}.${n}.0 <${a}.${+n+1}.0-0`:A?(ci("replaceTilde pr",A),p=`>=${a}.${n}.${u}-${A} <${a}.${+n+1}.0-0`):p=`>=${a}.${n}.${u} <${a}.${+n+1}.0-0`,ci("tilde return",p),p})},j5e=(t,e)=>t.trim().split(/\s+/).map(r=>G5e(r,e)).join(" "),G5e=(t,e)=>{ci("caret",t,e);let r=e.loose?ba[Xo.CARETLOOSE]:ba[Xo.CARET],o=e.includePrerelease?"-0":"";return t.replace(r,(a,n,u,A,p)=>{ci("caret",t,a,n,u,A,p);let h;return Zo(n)?h="":Zo(u)?h=`>=${n}.0.0${o} <${+n+1}.0.0-0`:Zo(A)?n==="0"?h=`>=${n}.${u}.0${o} <${n}.${+u+1}.0-0`:h=`>=${n}.${u}.0${o} <${+n+1}.0.0-0`:p?(ci("replaceCaret pr",p),n==="0"?u==="0"?h=`>=${n}.${u}.${A}-${p} <${n}.${u}.${+A+1}-0`:h=`>=${n}.${u}.${A}-${p} <${n}.${+u+1}.0-0`:h=`>=${n}.${u}.${A}-${p} <${+n+1}.0.0-0`):(ci("no pr"),n==="0"?u==="0"?h=`>=${n}.${u}.${A}${o} <${n}.${u}.${+A+1}-0`:h=`>=${n}.${u}.${A}${o} <${n}.${+u+1}.0-0`:h=`>=${n}.${u}.${A} <${+n+1}.0.0-0`),ci("caret return",h),h})},Y5e=(t,e)=>(ci("replaceXRanges",t,e),t.split(/\s+/).map(r=>W5e(r,e)).join(" ")),W5e=(t,e)=>{t=t.trim();let r=e.loose?ba[Xo.XRANGELOOSE]:ba[Xo.XRANGE];return t.replace(r,(o,a,n,u,A,p)=>{ci("xRange",t,o,a,n,u,A,p);let h=Zo(n),E=h||Zo(u),I=E||Zo(A),v=I;return a==="="&&v&&(a=""),p=e.includePrerelease?"-0":"",h?a===">"||a==="<"?o="<0.0.0-0":o="*":a&&v?(E&&(u=0),A=0,a===">"?(a=">=",E?(n=+n+1,u=0,A=0):(u=+u+1,A=0)):a==="<="&&(a="<",E?n=+n+1:u=+u+1),a==="<"&&(p="-0"),o=`${a+n}.${u}.${A}${p}`):E?o=`>=${n}.0.0${p} <${+n+1}.0.0-0`:I&&(o=`>=${n}.${u}.0${p} <${n}.${+u+1}.0-0`),ci("xRange return",o),o})},K5e=(t,e)=>(ci("replaceStars",t,e),t.trim().replace(ba[Xo.STAR],"")),V5e=(t,e)=>(ci("replaceGTE0",t,e),t.trim().replace(ba[e.includePrerelease?Xo.GTE0PRE:Xo.GTE0],"")),z5e=t=>(e,r,o,a,n,u,A,p,h,E,I,v,x)=>(Zo(o)?r="":Zo(a)?r=`>=${o}.0.0${t?"-0":""}`:Zo(n)?r=`>=${o}.${a}.0${t?"-0":""}`:u?r=`>=${r}`:r=`>=${r}${t?"-0":""}`,Zo(h)?p="":Zo(E)?p=`<${+h+1}.0.0-0`:Zo(I)?p=`<${h}.${+E+1}.0-0`:v?p=`<=${h}.${E}.${I}-${v}`:t?p=`<${h}.${E}.${+I+1}-0`:p=`<=${p}`,`${r} ${p}`.trim()),J5e=(t,e,r)=>{for(let o=0;o0){let a=t[o].semver;if(a.major===e.major&&a.minor===e.minor&&a.patch===e.patch)return!0}return!1}return!0}});var rI=_((dQt,mJ)=>{var nI=Symbol("SemVer ANY"),JT=class t{static get ANY(){return nI}constructor(e,r){if(r=fJ(r),e instanceof t){if(e.loose===!!r.loose)return e;e=e.value}e=e.trim().split(/\s+/).join(" "),zT("comparator",e,r),this.options=r,this.loose=!!r.loose,this.parse(e),this.semver===nI?this.value="":this.value=this.operator+this.semver.version,zT("comp",this)}parse(e){let r=this.options.loose?pJ[hJ.COMPARATORLOOSE]:pJ[hJ.COMPARATOR],o=e.match(r);if(!o)throw new TypeError(`Invalid comparator: ${e}`);this.operator=o[1]!==void 0?o[1]:"",this.operator==="="&&(this.operator=""),o[2]?this.semver=new gJ(o[2],this.options.loose):this.semver=nI}toString(){return this.value}test(e){if(zT("Comparator.test",e,this.options.loose),this.semver===nI||e===nI)return!0;if(typeof e=="string")try{e=new gJ(e,this.options)}catch{return!1}return VT(e,this.operator,this.semver,this.options)}intersects(e,r){if(!(e instanceof t))throw new TypeError("a Comparator is required");return this.operator===""?this.value===""?!0:new dJ(e.value,r).test(this.value):e.operator===""?e.value===""?!0:new dJ(this.value,r).test(e.semver):(r=fJ(r),r.includePrerelease&&(this.value==="<0.0.0-0"||e.value==="<0.0.0-0")||!r.includePrerelease&&(this.value.startsWith("<0.0.0")||e.value.startsWith("<0.0.0"))?!1:!!(this.operator.startsWith(">")&&e.operator.startsWith(">")||this.operator.startsWith("<")&&e.operator.startsWith("<")||this.semver.version===e.semver.version&&this.operator.includes("=")&&e.operator.includes("=")||VT(this.semver,"<",e.semver,r)&&this.operator.startsWith(">")&&e.operator.startsWith("<")||VT(this.semver,">",e.semver,r)&&this.operator.startsWith("<")&&e.operator.startsWith(">")))}};mJ.exports=JT;var fJ=eP(),{safeRe:pJ,t:hJ}=lm(),VT=HT(),zT=Zw(),gJ=Po(),dJ=Ml()});var iI=_((mQt,yJ)=>{var X5e=Ml(),Z5e=(t,e,r)=>{try{e=new X5e(e,r)}catch{return!1}return e.test(t)};yJ.exports=Z5e});var CJ=_((yQt,EJ)=>{var $5e=Ml(),eGe=(t,e)=>new $5e(t,e).set.map(r=>r.map(o=>o.value).join(" ").trim().split(" "));EJ.exports=eGe});var IJ=_((EQt,wJ)=>{var tGe=Po(),rGe=Ml(),nGe=(t,e,r)=>{let o=null,a=null,n=null;try{n=new rGe(e,r)}catch{return null}return t.forEach(u=>{n.test(u)&&(!o||a.compare(u)===-1)&&(o=u,a=new tGe(o,r))}),o};wJ.exports=nGe});var vJ=_((CQt,BJ)=>{var iGe=Po(),sGe=Ml(),oGe=(t,e,r)=>{let o=null,a=null,n=null;try{n=new sGe(e,r)}catch{return null}return t.forEach(u=>{n.test(u)&&(!o||a.compare(u)===1)&&(o=u,a=new iGe(o,r))}),o};BJ.exports=oGe});var bJ=_((wQt,PJ)=>{var XT=Po(),aGe=Ml(),DJ=$w(),lGe=(t,e)=>{t=new aGe(t,e);let r=new XT("0.0.0");if(t.test(r)||(r=new XT("0.0.0-0"),t.test(r)))return r;r=null;for(let o=0;o{let A=new XT(u.semver.version);switch(u.operator){case">":A.prerelease.length===0?A.patch++:A.prerelease.push(0),A.raw=A.format();case"":case">=":(!n||DJ(A,n))&&(n=A);break;case"<":case"<=":break;default:throw new Error(`Unexpected operation: ${u.operator}`)}}),n&&(!r||DJ(r,n))&&(r=n)}return r&&t.test(r)?r:null};PJ.exports=lGe});var xJ=_((IQt,SJ)=>{var cGe=Ml(),uGe=(t,e)=>{try{return new cGe(t,e).range||"*"}catch{return null}};SJ.exports=uGe});var AP=_((BQt,RJ)=>{var AGe=Po(),FJ=rI(),{ANY:fGe}=FJ,pGe=Ml(),hGe=iI(),kJ=$w(),QJ=iP(),gGe=oP(),dGe=sP(),mGe=(t,e,r,o)=>{t=new AGe(t,o),e=new pGe(e,o);let a,n,u,A,p;switch(r){case">":a=kJ,n=gGe,u=QJ,A=">",p=">=";break;case"<":a=QJ,n=dGe,u=kJ,A="<",p="<=";break;default:throw new TypeError('Must provide a hilo val of "<" or ">"')}if(hGe(t,e,o))return!1;for(let h=0;h{x.semver===fGe&&(x=new FJ(">=0.0.0")),I=I||x,v=v||x,a(x.semver,I.semver,o)?I=x:u(x.semver,v.semver,o)&&(v=x)}),I.operator===A||I.operator===p||(!v.operator||v.operator===A)&&n(t,v.semver))return!1;if(v.operator===p&&u(t,v.semver))return!1}return!0};RJ.exports=mGe});var NJ=_((vQt,TJ)=>{var yGe=AP(),EGe=(t,e,r)=>yGe(t,e,">",r);TJ.exports=EGe});var MJ=_((DQt,LJ)=>{var CGe=AP(),wGe=(t,e,r)=>CGe(t,e,"<",r);LJ.exports=wGe});var _J=_((PQt,UJ)=>{var OJ=Ml(),IGe=(t,e,r)=>(t=new OJ(t,r),e=new OJ(e,r),t.intersects(e,r));UJ.exports=IGe});var qJ=_((bQt,HJ)=>{var BGe=iI(),vGe=Ll();HJ.exports=(t,e,r)=>{let o=[],a=null,n=null,u=t.sort((E,I)=>vGe(E,I,r));for(let E of u)BGe(E,e,r)?(n=E,a||(a=E)):(n&&o.push([a,n]),n=null,a=null);a&&o.push([a,null]);let A=[];for(let[E,I]of o)E===I?A.push(E):!I&&E===u[0]?A.push("*"):I?E===u[0]?A.push(`<=${I}`):A.push(`${E} - ${I}`):A.push(`>=${E}`);let p=A.join(" || "),h=typeof e.raw=="string"?e.raw:String(e);return p.length{var jJ=Ml(),$T=rI(),{ANY:ZT}=$T,sI=iI(),eN=Ll(),DGe=(t,e,r={})=>{if(t===e)return!0;t=new jJ(t,r),e=new jJ(e,r);let o=!1;e:for(let a of t.set){for(let n of e.set){let u=bGe(a,n,r);if(o=o||u!==null,u)continue e}if(o)return!1}return!0},PGe=[new $T(">=0.0.0-0")],GJ=[new $T(">=0.0.0")],bGe=(t,e,r)=>{if(t===e)return!0;if(t.length===1&&t[0].semver===ZT){if(e.length===1&&e[0].semver===ZT)return!0;r.includePrerelease?t=PGe:t=GJ}if(e.length===1&&e[0].semver===ZT){if(r.includePrerelease)return!0;e=GJ}let o=new Set,a,n;for(let x of t)x.operator===">"||x.operator===">="?a=YJ(a,x,r):x.operator==="<"||x.operator==="<="?n=WJ(n,x,r):o.add(x.semver);if(o.size>1)return null;let u;if(a&&n){if(u=eN(a.semver,n.semver,r),u>0)return null;if(u===0&&(a.operator!==">="||n.operator!=="<="))return null}for(let x of o){if(a&&!sI(x,String(a),r)||n&&!sI(x,String(n),r))return null;for(let C of e)if(!sI(x,String(C),r))return!1;return!0}let A,p,h,E,I=n&&!r.includePrerelease&&n.semver.prerelease.length?n.semver:!1,v=a&&!r.includePrerelease&&a.semver.prerelease.length?a.semver:!1;I&&I.prerelease.length===1&&n.operator==="<"&&I.prerelease[0]===0&&(I=!1);for(let x of e){if(E=E||x.operator===">"||x.operator===">=",h=h||x.operator==="<"||x.operator==="<=",a){if(v&&x.semver.prerelease&&x.semver.prerelease.length&&x.semver.major===v.major&&x.semver.minor===v.minor&&x.semver.patch===v.patch&&(v=!1),x.operator===">"||x.operator===">="){if(A=YJ(a,x,r),A===x&&A!==a)return!1}else if(a.operator===">="&&!sI(a.semver,String(x),r))return!1}if(n){if(I&&x.semver.prerelease&&x.semver.prerelease.length&&x.semver.major===I.major&&x.semver.minor===I.minor&&x.semver.patch===I.patch&&(I=!1),x.operator==="<"||x.operator==="<="){if(p=WJ(n,x,r),p===x&&p!==n)return!1}else if(n.operator==="<="&&!sI(n.semver,String(x),r))return!1}if(!x.operator&&(n||a)&&u!==0)return!1}return!(a&&h&&!n&&u!==0||n&&E&&!a&&u!==0||v||I)},YJ=(t,e,r)=>{if(!t)return e;let o=eN(t.semver,e.semver,r);return o>0?t:o<0||e.operator===">"&&t.operator===">="?e:t},WJ=(t,e,r)=>{if(!t)return e;let o=eN(t.semver,e.semver,r);return o<0?t:o>0||e.operator==="<"&&t.operator==="<="?e:t};KJ.exports=DGe});var Jn=_((xQt,XJ)=>{var tN=lm(),zJ=Xw(),SGe=Po(),JJ=MT(),xGe=tg(),kGe=dz(),QGe=yz(),FGe=wz(),RGe=vz(),TGe=Pz(),NGe=Sz(),LGe=kz(),MGe=Fz(),OGe=Ll(),UGe=Lz(),_Ge=Oz(),HGe=nP(),qGe=qz(),jGe=Gz(),GGe=$w(),YGe=iP(),WGe=UT(),KGe=_T(),VGe=sP(),zGe=oP(),JGe=HT(),XGe=$z(),ZGe=rI(),$Ge=Ml(),e9e=iI(),t9e=CJ(),r9e=IJ(),n9e=vJ(),i9e=bJ(),s9e=xJ(),o9e=AP(),a9e=NJ(),l9e=MJ(),c9e=_J(),u9e=qJ(),A9e=VJ();XJ.exports={parse:xGe,valid:kGe,clean:QGe,inc:FGe,diff:RGe,major:TGe,minor:NGe,patch:LGe,prerelease:MGe,compare:OGe,rcompare:UGe,compareLoose:_Ge,compareBuild:HGe,sort:qGe,rsort:jGe,gt:GGe,lt:YGe,eq:WGe,neq:KGe,gte:VGe,lte:zGe,cmp:JGe,coerce:XGe,Comparator:ZGe,Range:$Ge,satisfies:e9e,toComparators:t9e,maxSatisfying:r9e,minSatisfying:n9e,minVersion:i9e,validRange:s9e,outside:o9e,gtr:a9e,ltr:l9e,intersects:c9e,simplifyRange:u9e,subset:A9e,SemVer:SGe,re:tN.re,src:tN.src,tokens:tN.t,SEMVER_SPEC_VERSION:zJ.SEMVER_SPEC_VERSION,RELEASE_TYPES:zJ.RELEASE_TYPES,compareIdentifiers:JJ.compareIdentifiers,rcompareIdentifiers:JJ.rcompareIdentifiers}});var $J=_((kQt,ZJ)=>{"use strict";function f9e(t,e){function r(){this.constructor=t}r.prototype=e.prototype,t.prototype=new r}function sg(t,e,r,o){this.message=t,this.expected=e,this.found=r,this.location=o,this.name="SyntaxError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,sg)}f9e(sg,Error);sg.buildMessage=function(t,e){var r={literal:function(h){return'"'+a(h.text)+'"'},class:function(h){var E="",I;for(I=0;I0){for(I=1,v=1;I{switch(Re[1]){case"|":return Se|Re[3];case"&":return Se&Re[3];case"^":return Se^Re[3]}},$)},v="!",x=Te("!",!1),C=function($){return!$},R="(",L=Te("(",!1),U=")",z=Te(")",!1),te=function($){return $},ae=/^[^ \t\n\r()!|&\^]/,le=Fe([" "," ",` +`,"\r","(",")","!","|","&","^"],!0,!1),ce=function($){return e.queryPattern.test($)},Ce=function($){return e.checkFn($)},de=be("whitespace"),Be=/^[ \t\n\r]/,Ee=Fe([" "," ",` +`,"\r"],!1,!1),g=0,me=0,we=[{line:1,column:1}],Ae=0,ne=[],Z=0,xe;if("startRule"in e){if(!(e.startRule in o))throw new Error(`Can't start parsing from rule "`+e.startRule+'".');a=o[e.startRule]}function Ne(){return t.substring(me,g)}function ht(){return Ue(me,g)}function H($,ie){throw ie=ie!==void 0?ie:Ue(me,g),b([be($)],t.substring(me,g),ie)}function rt($,ie){throw ie=ie!==void 0?ie:Ue(me,g),w($,ie)}function Te($,ie){return{type:"literal",text:$,ignoreCase:ie}}function Fe($,ie,Se){return{type:"class",parts:$,inverted:ie,ignoreCase:Se}}function ke(){return{type:"any"}}function Ye(){return{type:"end"}}function be($){return{type:"other",description:$}}function et($){var ie=we[$],Se;if(ie)return ie;for(Se=$-1;!we[Se];)Se--;for(ie=we[Se],ie={line:ie.line,column:ie.column};Se<$;)t.charCodeAt(Se)===10?(ie.line++,ie.column=1):ie.column++,Se++;return we[$]=ie,ie}function Ue($,ie){var Se=et($),Re=et(ie);return{start:{offset:$,line:Se.line,column:Se.column},end:{offset:ie,line:Re.line,column:Re.column}}}function S($){gAe&&(Ae=g,ne=[]),ne.push($))}function w($,ie){return new sg($,null,null,ie)}function b($,ie,Se){return new sg(sg.buildMessage($,ie),$,ie,Se)}function y(){var $,ie,Se,Re,at,dt,jt,tr;if($=g,ie=F(),ie!==r){for(Se=[],Re=g,at=X(),at!==r?(t.charCodeAt(g)===124?(dt=n,g++):(dt=r,Z===0&&S(u)),dt===r&&(t.charCodeAt(g)===38?(dt=A,g++):(dt=r,Z===0&&S(p)),dt===r&&(t.charCodeAt(g)===94?(dt=h,g++):(dt=r,Z===0&&S(E)))),dt!==r?(jt=X(),jt!==r?(tr=F(),tr!==r?(at=[at,dt,jt,tr],Re=at):(g=Re,Re=r)):(g=Re,Re=r)):(g=Re,Re=r)):(g=Re,Re=r);Re!==r;)Se.push(Re),Re=g,at=X(),at!==r?(t.charCodeAt(g)===124?(dt=n,g++):(dt=r,Z===0&&S(u)),dt===r&&(t.charCodeAt(g)===38?(dt=A,g++):(dt=r,Z===0&&S(p)),dt===r&&(t.charCodeAt(g)===94?(dt=h,g++):(dt=r,Z===0&&S(E)))),dt!==r?(jt=X(),jt!==r?(tr=F(),tr!==r?(at=[at,dt,jt,tr],Re=at):(g=Re,Re=r)):(g=Re,Re=r)):(g=Re,Re=r)):(g=Re,Re=r);Se!==r?(me=$,ie=I(ie,Se),$=ie):(g=$,$=r)}else g=$,$=r;return $}function F(){var $,ie,Se,Re,at,dt;return $=g,t.charCodeAt(g)===33?(ie=v,g++):(ie=r,Z===0&&S(x)),ie!==r?(Se=F(),Se!==r?(me=$,ie=C(Se),$=ie):(g=$,$=r)):(g=$,$=r),$===r&&($=g,t.charCodeAt(g)===40?(ie=R,g++):(ie=r,Z===0&&S(L)),ie!==r?(Se=X(),Se!==r?(Re=y(),Re!==r?(at=X(),at!==r?(t.charCodeAt(g)===41?(dt=U,g++):(dt=r,Z===0&&S(z)),dt!==r?(me=$,ie=te(Re),$=ie):(g=$,$=r)):(g=$,$=r)):(g=$,$=r)):(g=$,$=r)):(g=$,$=r),$===r&&($=J())),$}function J(){var $,ie,Se,Re,at;if($=g,ie=X(),ie!==r){if(Se=g,Re=[],ae.test(t.charAt(g))?(at=t.charAt(g),g++):(at=r,Z===0&&S(le)),at!==r)for(;at!==r;)Re.push(at),ae.test(t.charAt(g))?(at=t.charAt(g),g++):(at=r,Z===0&&S(le));else Re=r;Re!==r?Se=t.substring(Se,g):Se=Re,Se!==r?(me=g,Re=ce(Se),Re?Re=void 0:Re=r,Re!==r?(me=$,ie=Ce(Se),$=ie):(g=$,$=r)):(g=$,$=r)}else g=$,$=r;return $}function X(){var $,ie;for(Z++,$=[],Be.test(t.charAt(g))?(ie=t.charAt(g),g++):(ie=r,Z===0&&S(Ee));ie!==r;)$.push(ie),Be.test(t.charAt(g))?(ie=t.charAt(g),g++):(ie=r,Z===0&&S(Ee));return Z--,$===r&&(ie=r,Z===0&&S(de)),$}if(xe=a(),xe!==r&&g===t.length)return xe;throw xe!==r&&g{var{parse:h9e}=$J();fP.makeParser=(t=/[a-z]+/)=>(e,r)=>h9e(e,{queryPattern:t,checkFn:r});fP.parse=fP.makeParser()});var rX=_((FQt,tX)=>{"use strict";tX.exports={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]}});var rN=_((RQt,iX)=>{var oI=rX(),nX={};for(let t of Object.keys(oI))nX[oI[t]]=t;var Ar={rgb:{channels:3,labels:"rgb"},hsl:{channels:3,labels:"hsl"},hsv:{channels:3,labels:"hsv"},hwb:{channels:3,labels:"hwb"},cmyk:{channels:4,labels:"cmyk"},xyz:{channels:3,labels:"xyz"},lab:{channels:3,labels:"lab"},lch:{channels:3,labels:"lch"},hex:{channels:1,labels:["hex"]},keyword:{channels:1,labels:["keyword"]},ansi16:{channels:1,labels:["ansi16"]},ansi256:{channels:1,labels:["ansi256"]},hcg:{channels:3,labels:["h","c","g"]},apple:{channels:3,labels:["r16","g16","b16"]},gray:{channels:1,labels:["gray"]}};iX.exports=Ar;for(let t of Object.keys(Ar)){if(!("channels"in Ar[t]))throw new Error("missing channels property: "+t);if(!("labels"in Ar[t]))throw new Error("missing channel labels property: "+t);if(Ar[t].labels.length!==Ar[t].channels)throw new Error("channel and label counts mismatch: "+t);let{channels:e,labels:r}=Ar[t];delete Ar[t].channels,delete Ar[t].labels,Object.defineProperty(Ar[t],"channels",{value:e}),Object.defineProperty(Ar[t],"labels",{value:r})}Ar.rgb.hsl=function(t){let e=t[0]/255,r=t[1]/255,o=t[2]/255,a=Math.min(e,r,o),n=Math.max(e,r,o),u=n-a,A,p;n===a?A=0:e===n?A=(r-o)/u:r===n?A=2+(o-e)/u:o===n&&(A=4+(e-r)/u),A=Math.min(A*60,360),A<0&&(A+=360);let h=(a+n)/2;return n===a?p=0:h<=.5?p=u/(n+a):p=u/(2-n-a),[A,p*100,h*100]};Ar.rgb.hsv=function(t){let e,r,o,a,n,u=t[0]/255,A=t[1]/255,p=t[2]/255,h=Math.max(u,A,p),E=h-Math.min(u,A,p),I=function(v){return(h-v)/6/E+1/2};return E===0?(a=0,n=0):(n=E/h,e=I(u),r=I(A),o=I(p),u===h?a=o-r:A===h?a=1/3+e-o:p===h&&(a=2/3+r-e),a<0?a+=1:a>1&&(a-=1)),[a*360,n*100,h*100]};Ar.rgb.hwb=function(t){let e=t[0],r=t[1],o=t[2],a=Ar.rgb.hsl(t)[0],n=1/255*Math.min(e,Math.min(r,o));return o=1-1/255*Math.max(e,Math.max(r,o)),[a,n*100,o*100]};Ar.rgb.cmyk=function(t){let e=t[0]/255,r=t[1]/255,o=t[2]/255,a=Math.min(1-e,1-r,1-o),n=(1-e-a)/(1-a)||0,u=(1-r-a)/(1-a)||0,A=(1-o-a)/(1-a)||0;return[n*100,u*100,A*100,a*100]};function g9e(t,e){return(t[0]-e[0])**2+(t[1]-e[1])**2+(t[2]-e[2])**2}Ar.rgb.keyword=function(t){let e=nX[t];if(e)return e;let r=1/0,o;for(let a of Object.keys(oI)){let n=oI[a],u=g9e(t,n);u.04045?((e+.055)/1.055)**2.4:e/12.92,r=r>.04045?((r+.055)/1.055)**2.4:r/12.92,o=o>.04045?((o+.055)/1.055)**2.4:o/12.92;let a=e*.4124+r*.3576+o*.1805,n=e*.2126+r*.7152+o*.0722,u=e*.0193+r*.1192+o*.9505;return[a*100,n*100,u*100]};Ar.rgb.lab=function(t){let e=Ar.rgb.xyz(t),r=e[0],o=e[1],a=e[2];r/=95.047,o/=100,a/=108.883,r=r>.008856?r**(1/3):7.787*r+16/116,o=o>.008856?o**(1/3):7.787*o+16/116,a=a>.008856?a**(1/3):7.787*a+16/116;let n=116*o-16,u=500*(r-o),A=200*(o-a);return[n,u,A]};Ar.hsl.rgb=function(t){let e=t[0]/360,r=t[1]/100,o=t[2]/100,a,n,u;if(r===0)return u=o*255,[u,u,u];o<.5?a=o*(1+r):a=o+r-o*r;let A=2*o-a,p=[0,0,0];for(let h=0;h<3;h++)n=e+1/3*-(h-1),n<0&&n++,n>1&&n--,6*n<1?u=A+(a-A)*6*n:2*n<1?u=a:3*n<2?u=A+(a-A)*(2/3-n)*6:u=A,p[h]=u*255;return p};Ar.hsl.hsv=function(t){let e=t[0],r=t[1]/100,o=t[2]/100,a=r,n=Math.max(o,.01);o*=2,r*=o<=1?o:2-o,a*=n<=1?n:2-n;let u=(o+r)/2,A=o===0?2*a/(n+a):2*r/(o+r);return[e,A*100,u*100]};Ar.hsv.rgb=function(t){let e=t[0]/60,r=t[1]/100,o=t[2]/100,a=Math.floor(e)%6,n=e-Math.floor(e),u=255*o*(1-r),A=255*o*(1-r*n),p=255*o*(1-r*(1-n));switch(o*=255,a){case 0:return[o,p,u];case 1:return[A,o,u];case 2:return[u,o,p];case 3:return[u,A,o];case 4:return[p,u,o];case 5:return[o,u,A]}};Ar.hsv.hsl=function(t){let e=t[0],r=t[1]/100,o=t[2]/100,a=Math.max(o,.01),n,u;u=(2-r)*o;let A=(2-r)*a;return n=r*a,n/=A<=1?A:2-A,n=n||0,u/=2,[e,n*100,u*100]};Ar.hwb.rgb=function(t){let e=t[0]/360,r=t[1]/100,o=t[2]/100,a=r+o,n;a>1&&(r/=a,o/=a);let u=Math.floor(6*e),A=1-o;n=6*e-u,u&1&&(n=1-n);let p=r+n*(A-r),h,E,I;switch(u){default:case 6:case 0:h=A,E=p,I=r;break;case 1:h=p,E=A,I=r;break;case 2:h=r,E=A,I=p;break;case 3:h=r,E=p,I=A;break;case 4:h=p,E=r,I=A;break;case 5:h=A,E=r,I=p;break}return[h*255,E*255,I*255]};Ar.cmyk.rgb=function(t){let e=t[0]/100,r=t[1]/100,o=t[2]/100,a=t[3]/100,n=1-Math.min(1,e*(1-a)+a),u=1-Math.min(1,r*(1-a)+a),A=1-Math.min(1,o*(1-a)+a);return[n*255,u*255,A*255]};Ar.xyz.rgb=function(t){let e=t[0]/100,r=t[1]/100,o=t[2]/100,a,n,u;return a=e*3.2406+r*-1.5372+o*-.4986,n=e*-.9689+r*1.8758+o*.0415,u=e*.0557+r*-.204+o*1.057,a=a>.0031308?1.055*a**(1/2.4)-.055:a*12.92,n=n>.0031308?1.055*n**(1/2.4)-.055:n*12.92,u=u>.0031308?1.055*u**(1/2.4)-.055:u*12.92,a=Math.min(Math.max(0,a),1),n=Math.min(Math.max(0,n),1),u=Math.min(Math.max(0,u),1),[a*255,n*255,u*255]};Ar.xyz.lab=function(t){let e=t[0],r=t[1],o=t[2];e/=95.047,r/=100,o/=108.883,e=e>.008856?e**(1/3):7.787*e+16/116,r=r>.008856?r**(1/3):7.787*r+16/116,o=o>.008856?o**(1/3):7.787*o+16/116;let a=116*r-16,n=500*(e-r),u=200*(r-o);return[a,n,u]};Ar.lab.xyz=function(t){let e=t[0],r=t[1],o=t[2],a,n,u;n=(e+16)/116,a=r/500+n,u=n-o/200;let A=n**3,p=a**3,h=u**3;return n=A>.008856?A:(n-16/116)/7.787,a=p>.008856?p:(a-16/116)/7.787,u=h>.008856?h:(u-16/116)/7.787,a*=95.047,n*=100,u*=108.883,[a,n,u]};Ar.lab.lch=function(t){let e=t[0],r=t[1],o=t[2],a;a=Math.atan2(o,r)*360/2/Math.PI,a<0&&(a+=360);let u=Math.sqrt(r*r+o*o);return[e,u,a]};Ar.lch.lab=function(t){let e=t[0],r=t[1],a=t[2]/360*2*Math.PI,n=r*Math.cos(a),u=r*Math.sin(a);return[e,n,u]};Ar.rgb.ansi16=function(t,e=null){let[r,o,a]=t,n=e===null?Ar.rgb.hsv(t)[2]:e;if(n=Math.round(n/50),n===0)return 30;let u=30+(Math.round(a/255)<<2|Math.round(o/255)<<1|Math.round(r/255));return n===2&&(u+=60),u};Ar.hsv.ansi16=function(t){return Ar.rgb.ansi16(Ar.hsv.rgb(t),t[2])};Ar.rgb.ansi256=function(t){let e=t[0],r=t[1],o=t[2];return e===r&&r===o?e<8?16:e>248?231:Math.round((e-8)/247*24)+232:16+36*Math.round(e/255*5)+6*Math.round(r/255*5)+Math.round(o/255*5)};Ar.ansi16.rgb=function(t){let e=t%10;if(e===0||e===7)return t>50&&(e+=3.5),e=e/10.5*255,[e,e,e];let r=(~~(t>50)+1)*.5,o=(e&1)*r*255,a=(e>>1&1)*r*255,n=(e>>2&1)*r*255;return[o,a,n]};Ar.ansi256.rgb=function(t){if(t>=232){let n=(t-232)*10+8;return[n,n,n]}t-=16;let e,r=Math.floor(t/36)/5*255,o=Math.floor((e=t%36)/6)/5*255,a=e%6/5*255;return[r,o,a]};Ar.rgb.hex=function(t){let r=(((Math.round(t[0])&255)<<16)+((Math.round(t[1])&255)<<8)+(Math.round(t[2])&255)).toString(16).toUpperCase();return"000000".substring(r.length)+r};Ar.hex.rgb=function(t){let e=t.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);if(!e)return[0,0,0];let r=e[0];e[0].length===3&&(r=r.split("").map(A=>A+A).join(""));let o=parseInt(r,16),a=o>>16&255,n=o>>8&255,u=o&255;return[a,n,u]};Ar.rgb.hcg=function(t){let e=t[0]/255,r=t[1]/255,o=t[2]/255,a=Math.max(Math.max(e,r),o),n=Math.min(Math.min(e,r),o),u=a-n,A,p;return u<1?A=n/(1-u):A=0,u<=0?p=0:a===e?p=(r-o)/u%6:a===r?p=2+(o-e)/u:p=4+(e-r)/u,p/=6,p%=1,[p*360,u*100,A*100]};Ar.hsl.hcg=function(t){let e=t[1]/100,r=t[2]/100,o=r<.5?2*e*r:2*e*(1-r),a=0;return o<1&&(a=(r-.5*o)/(1-o)),[t[0],o*100,a*100]};Ar.hsv.hcg=function(t){let e=t[1]/100,r=t[2]/100,o=e*r,a=0;return o<1&&(a=(r-o)/(1-o)),[t[0],o*100,a*100]};Ar.hcg.rgb=function(t){let e=t[0]/360,r=t[1]/100,o=t[2]/100;if(r===0)return[o*255,o*255,o*255];let a=[0,0,0],n=e%1*6,u=n%1,A=1-u,p=0;switch(Math.floor(n)){case 0:a[0]=1,a[1]=u,a[2]=0;break;case 1:a[0]=A,a[1]=1,a[2]=0;break;case 2:a[0]=0,a[1]=1,a[2]=u;break;case 3:a[0]=0,a[1]=A,a[2]=1;break;case 4:a[0]=u,a[1]=0,a[2]=1;break;default:a[0]=1,a[1]=0,a[2]=A}return p=(1-r)*o,[(r*a[0]+p)*255,(r*a[1]+p)*255,(r*a[2]+p)*255]};Ar.hcg.hsv=function(t){let e=t[1]/100,r=t[2]/100,o=e+r*(1-e),a=0;return o>0&&(a=e/o),[t[0],a*100,o*100]};Ar.hcg.hsl=function(t){let e=t[1]/100,o=t[2]/100*(1-e)+.5*e,a=0;return o>0&&o<.5?a=e/(2*o):o>=.5&&o<1&&(a=e/(2*(1-o))),[t[0],a*100,o*100]};Ar.hcg.hwb=function(t){let e=t[1]/100,r=t[2]/100,o=e+r*(1-e);return[t[0],(o-e)*100,(1-o)*100]};Ar.hwb.hcg=function(t){let e=t[1]/100,o=1-t[2]/100,a=o-e,n=0;return a<1&&(n=(o-a)/(1-a)),[t[0],a*100,n*100]};Ar.apple.rgb=function(t){return[t[0]/65535*255,t[1]/65535*255,t[2]/65535*255]};Ar.rgb.apple=function(t){return[t[0]/255*65535,t[1]/255*65535,t[2]/255*65535]};Ar.gray.rgb=function(t){return[t[0]/100*255,t[0]/100*255,t[0]/100*255]};Ar.gray.hsl=function(t){return[0,0,t[0]]};Ar.gray.hsv=Ar.gray.hsl;Ar.gray.hwb=function(t){return[0,100,t[0]]};Ar.gray.cmyk=function(t){return[0,0,0,t[0]]};Ar.gray.lab=function(t){return[t[0],0,0]};Ar.gray.hex=function(t){let e=Math.round(t[0]/100*255)&255,o=((e<<16)+(e<<8)+e).toString(16).toUpperCase();return"000000".substring(o.length)+o};Ar.rgb.gray=function(t){return[(t[0]+t[1]+t[2])/3/255*100]}});var oX=_((TQt,sX)=>{var pP=rN();function d9e(){let t={},e=Object.keys(pP);for(let r=e.length,o=0;o{var nN=rN(),C9e=oX(),fm={},w9e=Object.keys(nN);function I9e(t){let e=function(...r){let o=r[0];return o==null?o:(o.length>1&&(r=o),t(r))};return"conversion"in t&&(e.conversion=t.conversion),e}function B9e(t){let e=function(...r){let o=r[0];if(o==null)return o;o.length>1&&(r=o);let a=t(r);if(typeof a=="object")for(let n=a.length,u=0;u{fm[t]={},Object.defineProperty(fm[t],"channels",{value:nN[t].channels}),Object.defineProperty(fm[t],"labels",{value:nN[t].labels});let e=C9e(t);Object.keys(e).forEach(o=>{let a=e[o];fm[t][o]=B9e(a),fm[t][o].raw=I9e(a)})});aX.exports=fm});var aI=_((LQt,pX)=>{"use strict";var cX=(t,e)=>(...r)=>`\x1B[${t(...r)+e}m`,uX=(t,e)=>(...r)=>{let o=t(...r);return`\x1B[${38+e};5;${o}m`},AX=(t,e)=>(...r)=>{let o=t(...r);return`\x1B[${38+e};2;${o[0]};${o[1]};${o[2]}m`},hP=t=>t,fX=(t,e,r)=>[t,e,r],pm=(t,e,r)=>{Object.defineProperty(t,e,{get:()=>{let o=r();return Object.defineProperty(t,e,{value:o,enumerable:!0,configurable:!0}),o},enumerable:!0,configurable:!0})},iN,hm=(t,e,r,o)=>{iN===void 0&&(iN=lX());let a=o?10:0,n={};for(let[u,A]of Object.entries(iN)){let p=u==="ansi16"?"ansi":u;u===e?n[p]=t(r,a):typeof A=="object"&&(n[p]=t(A[e],a))}return n};function v9e(){let t=new Map,e={modifier:{reset:[0,0],bold:[1,22],dim:[2,22],italic:[3,23],underline:[4,24],inverse:[7,27],hidden:[8,28],strikethrough:[9,29]},color:{black:[30,39],red:[31,39],green:[32,39],yellow:[33,39],blue:[34,39],magenta:[35,39],cyan:[36,39],white:[37,39],blackBright:[90,39],redBright:[91,39],greenBright:[92,39],yellowBright:[93,39],blueBright:[94,39],magentaBright:[95,39],cyanBright:[96,39],whiteBright:[97,39]},bgColor:{bgBlack:[40,49],bgRed:[41,49],bgGreen:[42,49],bgYellow:[43,49],bgBlue:[44,49],bgMagenta:[45,49],bgCyan:[46,49],bgWhite:[47,49],bgBlackBright:[100,49],bgRedBright:[101,49],bgGreenBright:[102,49],bgYellowBright:[103,49],bgBlueBright:[104,49],bgMagentaBright:[105,49],bgCyanBright:[106,49],bgWhiteBright:[107,49]}};e.color.gray=e.color.blackBright,e.bgColor.bgGray=e.bgColor.bgBlackBright,e.color.grey=e.color.blackBright,e.bgColor.bgGrey=e.bgColor.bgBlackBright;for(let[r,o]of Object.entries(e)){for(let[a,n]of Object.entries(o))e[a]={open:`\x1B[${n[0]}m`,close:`\x1B[${n[1]}m`},o[a]=e[a],t.set(n[0],n[1]);Object.defineProperty(e,r,{value:o,enumerable:!1})}return Object.defineProperty(e,"codes",{value:t,enumerable:!1}),e.color.close="\x1B[39m",e.bgColor.close="\x1B[49m",pm(e.color,"ansi",()=>hm(cX,"ansi16",hP,!1)),pm(e.color,"ansi256",()=>hm(uX,"ansi256",hP,!1)),pm(e.color,"ansi16m",()=>hm(AX,"rgb",fX,!1)),pm(e.bgColor,"ansi",()=>hm(cX,"ansi16",hP,!0)),pm(e.bgColor,"ansi256",()=>hm(uX,"ansi256",hP,!0)),pm(e.bgColor,"ansi16m",()=>hm(AX,"rgb",fX,!0)),e}Object.defineProperty(pX,"exports",{enumerable:!0,get:v9e})});var gX=_((MQt,hX)=>{"use strict";hX.exports=(t,e=process.argv)=>{let r=t.startsWith("-")?"":t.length===1?"-":"--",o=e.indexOf(r+t),a=e.indexOf("--");return o!==-1&&(a===-1||o{"use strict";var D9e=ve("os"),dX=ve("tty"),Ol=gX(),{env:us}=process,Wp;Ol("no-color")||Ol("no-colors")||Ol("color=false")||Ol("color=never")?Wp=0:(Ol("color")||Ol("colors")||Ol("color=true")||Ol("color=always"))&&(Wp=1);"FORCE_COLOR"in us&&(us.FORCE_COLOR==="true"?Wp=1:us.FORCE_COLOR==="false"?Wp=0:Wp=us.FORCE_COLOR.length===0?1:Math.min(parseInt(us.FORCE_COLOR,10),3));function sN(t){return t===0?!1:{level:t,hasBasic:!0,has256:t>=2,has16m:t>=3}}function oN(t,e){if(Wp===0)return 0;if(Ol("color=16m")||Ol("color=full")||Ol("color=truecolor"))return 3;if(Ol("color=256"))return 2;if(t&&!e&&Wp===void 0)return 0;let r=Wp||0;if(us.TERM==="dumb")return r;if(process.platform==="win32"){let o=D9e.release().split(".");return Number(o[0])>=10&&Number(o[2])>=10586?Number(o[2])>=14931?3:2:1}if("CI"in us)return["TRAVIS","CIRCLECI","APPVEYOR","GITLAB_CI"].some(o=>o in us)||us.CI_NAME==="codeship"?1:r;if("TEAMCITY_VERSION"in us)return/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(us.TEAMCITY_VERSION)?1:0;if("GITHUB_ACTIONS"in us)return 1;if(us.COLORTERM==="truecolor")return 3;if("TERM_PROGRAM"in us){let o=parseInt((us.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(us.TERM_PROGRAM){case"iTerm.app":return o>=3?3:2;case"Apple_Terminal":return 2}}return/-256(color)?$/i.test(us.TERM)?2:/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(us.TERM)||"COLORTERM"in us?1:r}function P9e(t){let e=oN(t,t&&t.isTTY);return sN(e)}mX.exports={supportsColor:P9e,stdout:sN(oN(!0,dX.isatty(1))),stderr:sN(oN(!0,dX.isatty(2)))}});var EX=_((UQt,yX)=>{"use strict";var b9e=(t,e,r)=>{let o=t.indexOf(e);if(o===-1)return t;let a=e.length,n=0,u="";do u+=t.substr(n,o-n)+e+r,n=o+a,o=t.indexOf(e,n);while(o!==-1);return u+=t.substr(n),u},S9e=(t,e,r,o)=>{let a=0,n="";do{let u=t[o-1]==="\r";n+=t.substr(a,(u?o-1:o)-a)+e+(u?`\r +`:` +`)+r,a=o+1,o=t.indexOf(` +`,a)}while(o!==-1);return n+=t.substr(a),n};yX.exports={stringReplaceAll:b9e,stringEncaseCRLFWithFirstIndex:S9e}});var vX=_((_Qt,BX)=>{"use strict";var x9e=/(?:\\(u(?:[a-f\d]{4}|\{[a-f\d]{1,6}\})|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi,CX=/(?:^|\.)(\w+)(?:\(([^)]*)\))?/g,k9e=/^(['"])((?:\\.|(?!\1)[^\\])*)\1$/,Q9e=/\\(u(?:[a-f\d]{4}|\{[a-f\d]{1,6}\})|x[a-f\d]{2}|.)|([^\\])/gi,F9e=new Map([["n",` +`],["r","\r"],["t"," "],["b","\b"],["f","\f"],["v","\v"],["0","\0"],["\\","\\"],["e","\x1B"],["a","\x07"]]);function IX(t){let e=t[0]==="u",r=t[1]==="{";return e&&!r&&t.length===5||t[0]==="x"&&t.length===3?String.fromCharCode(parseInt(t.slice(1),16)):e&&r?String.fromCodePoint(parseInt(t.slice(2,-1),16)):F9e.get(t)||t}function R9e(t,e){let r=[],o=e.trim().split(/\s*,\s*/g),a;for(let n of o){let u=Number(n);if(!Number.isNaN(u))r.push(u);else if(a=n.match(k9e))r.push(a[2].replace(Q9e,(A,p,h)=>p?IX(p):h));else throw new Error(`Invalid Chalk template style argument: ${n} (in style '${t}')`)}return r}function T9e(t){CX.lastIndex=0;let e=[],r;for(;(r=CX.exec(t))!==null;){let o=r[1];if(r[2]){let a=R9e(o,r[2]);e.push([o].concat(a))}else e.push([o])}return e}function wX(t,e){let r={};for(let a of e)for(let n of a.styles)r[n[0]]=a.inverse?null:n.slice(1);let o=t;for(let[a,n]of Object.entries(r))if(Array.isArray(n)){if(!(a in o))throw new Error(`Unknown Chalk style: ${a}`);o=n.length>0?o[a](...n):o[a]}return o}BX.exports=(t,e)=>{let r=[],o=[],a=[];if(e.replace(x9e,(n,u,A,p,h,E)=>{if(u)a.push(IX(u));else if(p){let I=a.join("");a=[],o.push(r.length===0?I:wX(t,r)(I)),r.push({inverse:A,styles:T9e(p)})}else if(h){if(r.length===0)throw new Error("Found extraneous } in Chalk template literal");o.push(wX(t,r)(a.join(""))),a=[],r.pop()}else a.push(E)}),o.push(a.join("")),r.length>0){let n=`Chalk template literal is missing ${r.length} closing bracket${r.length===1?"":"s"} (\`}\`)`;throw new Error(n)}return o.join("")}});var pN=_((HQt,SX)=>{"use strict";var lI=aI(),{stdout:cN,stderr:uN}=aN(),{stringReplaceAll:N9e,stringEncaseCRLFWithFirstIndex:L9e}=EX(),DX=["ansi","ansi","ansi256","ansi16m"],gm=Object.create(null),M9e=(t,e={})=>{if(e.level>3||e.level<0)throw new Error("The `level` option should be an integer from 0 to 3");let r=cN?cN.level:0;t.level=e.level===void 0?r:e.level},AN=class{constructor(e){return PX(e)}},PX=t=>{let e={};return M9e(e,t),e.template=(...r)=>_9e(e.template,...r),Object.setPrototypeOf(e,gP.prototype),Object.setPrototypeOf(e.template,e),e.template.constructor=()=>{throw new Error("`chalk.constructor()` is deprecated. Use `new chalk.Instance()` instead.")},e.template.Instance=AN,e.template};function gP(t){return PX(t)}for(let[t,e]of Object.entries(lI))gm[t]={get(){let r=dP(this,fN(e.open,e.close,this._styler),this._isEmpty);return Object.defineProperty(this,t,{value:r}),r}};gm.visible={get(){let t=dP(this,this._styler,!0);return Object.defineProperty(this,"visible",{value:t}),t}};var bX=["rgb","hex","keyword","hsl","hsv","hwb","ansi","ansi256"];for(let t of bX)gm[t]={get(){let{level:e}=this;return function(...r){let o=fN(lI.color[DX[e]][t](...r),lI.color.close,this._styler);return dP(this,o,this._isEmpty)}}};for(let t of bX){let e="bg"+t[0].toUpperCase()+t.slice(1);gm[e]={get(){let{level:r}=this;return function(...o){let a=fN(lI.bgColor[DX[r]][t](...o),lI.bgColor.close,this._styler);return dP(this,a,this._isEmpty)}}}}var O9e=Object.defineProperties(()=>{},{...gm,level:{enumerable:!0,get(){return this._generator.level},set(t){this._generator.level=t}}}),fN=(t,e,r)=>{let o,a;return r===void 0?(o=t,a=e):(o=r.openAll+t,a=e+r.closeAll),{open:t,close:e,openAll:o,closeAll:a,parent:r}},dP=(t,e,r)=>{let o=(...a)=>U9e(o,a.length===1?""+a[0]:a.join(" "));return o.__proto__=O9e,o._generator=t,o._styler=e,o._isEmpty=r,o},U9e=(t,e)=>{if(t.level<=0||!e)return t._isEmpty?"":e;let r=t._styler;if(r===void 0)return e;let{openAll:o,closeAll:a}=r;if(e.indexOf("\x1B")!==-1)for(;r!==void 0;)e=N9e(e,r.close,r.open),r=r.parent;let n=e.indexOf(` +`);return n!==-1&&(e=L9e(e,a,o,n)),o+e+a},lN,_9e=(t,...e)=>{let[r]=e;if(!Array.isArray(r))return e.join(" ");let o=e.slice(1),a=[r.raw[0]];for(let n=1;n{"use strict";Ul.isInteger=t=>typeof t=="number"?Number.isInteger(t):typeof t=="string"&&t.trim()!==""?Number.isInteger(Number(t)):!1;Ul.find=(t,e)=>t.nodes.find(r=>r.type===e);Ul.exceedsLimit=(t,e,r=1,o)=>o===!1||!Ul.isInteger(t)||!Ul.isInteger(e)?!1:(Number(e)-Number(t))/Number(r)>=o;Ul.escapeNode=(t,e=0,r)=>{let o=t.nodes[e];o&&(r&&o.type===r||o.type==="open"||o.type==="close")&&o.escaped!==!0&&(o.value="\\"+o.value,o.escaped=!0)};Ul.encloseBrace=t=>t.type!=="brace"||t.commas>>0+t.ranges>>0?!1:(t.invalid=!0,!0);Ul.isInvalidBrace=t=>t.type!=="brace"?!1:t.invalid===!0||t.dollar?!0:!(t.commas>>0+t.ranges>>0)||t.open!==!0||t.close!==!0?(t.invalid=!0,!0):!1;Ul.isOpenOrClose=t=>t.type==="open"||t.type==="close"?!0:t.open===!0||t.close===!0;Ul.reduce=t=>t.reduce((e,r)=>(r.type==="text"&&e.push(r.value),r.type==="range"&&(r.type="text"),e),[]);Ul.flatten=(...t)=>{let e=[],r=o=>{for(let a=0;a{"use strict";var xX=mP();kX.exports=(t,e={})=>{let r=(o,a={})=>{let n=e.escapeInvalid&&xX.isInvalidBrace(a),u=o.invalid===!0&&e.escapeInvalid===!0,A="";if(o.value)return(n||u)&&xX.isOpenOrClose(o)?"\\"+o.value:o.value;if(o.value)return o.value;if(o.nodes)for(let p of o.nodes)A+=r(p);return A};return r(t)}});var FX=_((GQt,QX)=>{"use strict";QX.exports=function(t){return typeof t=="number"?t-t===0:typeof t=="string"&&t.trim()!==""?Number.isFinite?Number.isFinite(+t):isFinite(+t):!1}});var HX=_((YQt,_X)=>{"use strict";var RX=FX(),og=(t,e,r)=>{if(RX(t)===!1)throw new TypeError("toRegexRange: expected the first argument to be a number");if(e===void 0||t===e)return String(t);if(RX(e)===!1)throw new TypeError("toRegexRange: expected the second argument to be a number.");let o={relaxZeros:!0,...r};typeof o.strictZeros=="boolean"&&(o.relaxZeros=o.strictZeros===!1);let a=String(o.relaxZeros),n=String(o.shorthand),u=String(o.capture),A=String(o.wrap),p=t+":"+e+"="+a+n+u+A;if(og.cache.hasOwnProperty(p))return og.cache[p].result;let h=Math.min(t,e),E=Math.max(t,e);if(Math.abs(h-E)===1){let R=t+"|"+e;return o.capture?`(${R})`:o.wrap===!1?R:`(?:${R})`}let I=UX(t)||UX(e),v={min:t,max:e,a:h,b:E},x=[],C=[];if(I&&(v.isPadded=I,v.maxLen=String(v.max).length),h<0){let R=E<0?Math.abs(E):1;C=TX(R,Math.abs(h),v,o),h=v.a=0}return E>=0&&(x=TX(h,E,v,o)),v.negatives=C,v.positives=x,v.result=H9e(C,x,o),o.capture===!0?v.result=`(${v.result})`:o.wrap!==!1&&x.length+C.length>1&&(v.result=`(?:${v.result})`),og.cache[p]=v,v.result};function H9e(t,e,r){let o=hN(t,e,"-",!1,r)||[],a=hN(e,t,"",!1,r)||[],n=hN(t,e,"-?",!0,r)||[];return o.concat(n).concat(a).join("|")}function q9e(t,e){let r=1,o=1,a=LX(t,r),n=new Set([e]);for(;t<=a&&a<=e;)n.add(a),r+=1,a=LX(t,r);for(a=MX(e+1,o)-1;t1&&A.count.pop(),A.count.push(E.count[0]),A.string=A.pattern+OX(A.count),u=h+1;continue}r.isPadded&&(I=K9e(h,r,o)),E.string=I+E.pattern+OX(E.count),n.push(E),u=h+1,A=E}return n}function hN(t,e,r,o,a){let n=[];for(let u of t){let{string:A}=u;!o&&!NX(e,"string",A)&&n.push(r+A),o&&NX(e,"string",A)&&n.push(r+A)}return n}function G9e(t,e){let r=[];for(let o=0;oe?1:e>t?-1:0}function NX(t,e,r){return t.some(o=>o[e]===r)}function LX(t,e){return Number(String(t).slice(0,-e)+"9".repeat(e))}function MX(t,e){return t-t%Math.pow(10,e)}function OX(t){let[e=0,r=""]=t;return r||e>1?`{${e+(r?","+r:"")}}`:""}function W9e(t,e,r){return`[${t}${e-t===1?"":"-"}${e}]`}function UX(t){return/^-?(0+)\d/.test(t)}function K9e(t,e,r){if(!e.isPadded)return t;let o=Math.abs(e.maxLen-String(t).length),a=r.relaxZeros!==!1;switch(o){case 0:return"";case 1:return a?"0?":"0";case 2:return a?"0{0,2}":"00";default:return a?`0{0,${o}}`:`0{${o}}`}}og.cache={};og.clearCache=()=>og.cache={};_X.exports=og});var mN=_((WQt,zX)=>{"use strict";var V9e=ve("util"),GX=HX(),qX=t=>t!==null&&typeof t=="object"&&!Array.isArray(t),z9e=t=>e=>t===!0?Number(e):String(e),gN=t=>typeof t=="number"||typeof t=="string"&&t!=="",uI=t=>Number.isInteger(+t),dN=t=>{let e=`${t}`,r=-1;if(e[0]==="-"&&(e=e.slice(1)),e==="0")return!1;for(;e[++r]==="0";);return r>0},J9e=(t,e,r)=>typeof t=="string"||typeof e=="string"?!0:r.stringify===!0,X9e=(t,e,r)=>{if(e>0){let o=t[0]==="-"?"-":"";o&&(t=t.slice(1)),t=o+t.padStart(o?e-1:e,"0")}return r===!1?String(t):t},jX=(t,e)=>{let r=t[0]==="-"?"-":"";for(r&&(t=t.slice(1),e--);t.length{t.negatives.sort((u,A)=>uA?1:0),t.positives.sort((u,A)=>uA?1:0);let r=e.capture?"":"?:",o="",a="",n;return t.positives.length&&(o=t.positives.join("|")),t.negatives.length&&(a=`-(${r}${t.negatives.join("|")})`),o&&a?n=`${o}|${a}`:n=o||a,e.wrap?`(${r}${n})`:n},YX=(t,e,r,o)=>{if(r)return GX(t,e,{wrap:!1,...o});let a=String.fromCharCode(t);if(t===e)return a;let n=String.fromCharCode(e);return`[${a}-${n}]`},WX=(t,e,r)=>{if(Array.isArray(t)){let o=r.wrap===!0,a=r.capture?"":"?:";return o?`(${a}${t.join("|")})`:t.join("|")}return GX(t,e,r)},KX=(...t)=>new RangeError("Invalid range arguments: "+V9e.inspect(...t)),VX=(t,e,r)=>{if(r.strictRanges===!0)throw KX([t,e]);return[]},$9e=(t,e)=>{if(e.strictRanges===!0)throw new TypeError(`Expected step "${t}" to be a number`);return[]},e7e=(t,e,r=1,o={})=>{let a=Number(t),n=Number(e);if(!Number.isInteger(a)||!Number.isInteger(n)){if(o.strictRanges===!0)throw KX([t,e]);return[]}a===0&&(a=0),n===0&&(n=0);let u=a>n,A=String(t),p=String(e),h=String(r);r=Math.max(Math.abs(r),1);let E=dN(A)||dN(p)||dN(h),I=E?Math.max(A.length,p.length,h.length):0,v=E===!1&&J9e(t,e,o)===!1,x=o.transform||z9e(v);if(o.toRegex&&r===1)return YX(jX(t,I),jX(e,I),!0,o);let C={negatives:[],positives:[]},R=z=>C[z<0?"negatives":"positives"].push(Math.abs(z)),L=[],U=0;for(;u?a>=n:a<=n;)o.toRegex===!0&&r>1?R(a):L.push(X9e(x(a,U),I,v)),a=u?a-r:a+r,U++;return o.toRegex===!0?r>1?Z9e(C,o):WX(L,null,{wrap:!1,...o}):L},t7e=(t,e,r=1,o={})=>{if(!uI(t)&&t.length>1||!uI(e)&&e.length>1)return VX(t,e,o);let a=o.transform||(v=>String.fromCharCode(v)),n=`${t}`.charCodeAt(0),u=`${e}`.charCodeAt(0),A=n>u,p=Math.min(n,u),h=Math.max(n,u);if(o.toRegex&&r===1)return YX(p,h,!1,o);let E=[],I=0;for(;A?n>=u:n<=u;)E.push(a(n,I)),n=A?n-r:n+r,I++;return o.toRegex===!0?WX(E,null,{wrap:!1,options:o}):E},EP=(t,e,r,o={})=>{if(e==null&&gN(t))return[t];if(!gN(t)||!gN(e))return VX(t,e,o);if(typeof r=="function")return EP(t,e,1,{transform:r});if(qX(r))return EP(t,e,0,r);let a={...o};return a.capture===!0&&(a.wrap=!0),r=r||a.step||1,uI(r)?uI(t)&&uI(e)?e7e(t,e,r,a):t7e(t,e,Math.max(Math.abs(r),1),a):r!=null&&!qX(r)?$9e(r,a):EP(t,e,1,r)};zX.exports=EP});var ZX=_((KQt,XX)=>{"use strict";var r7e=mN(),JX=mP(),n7e=(t,e={})=>{let r=(o,a={})=>{let n=JX.isInvalidBrace(a),u=o.invalid===!0&&e.escapeInvalid===!0,A=n===!0||u===!0,p=e.escapeInvalid===!0?"\\":"",h="";if(o.isOpen===!0||o.isClose===!0)return p+o.value;if(o.type==="open")return A?p+o.value:"(";if(o.type==="close")return A?p+o.value:")";if(o.type==="comma")return o.prev.type==="comma"?"":A?o.value:"|";if(o.value)return o.value;if(o.nodes&&o.ranges>0){let E=JX.reduce(o.nodes),I=r7e(...E,{...e,wrap:!1,toRegex:!0});if(I.length!==0)return E.length>1&&I.length>1?`(${I})`:I}if(o.nodes)for(let E of o.nodes)h+=r(E,o);return h};return r(t)};XX.exports=n7e});var tZ=_((VQt,eZ)=>{"use strict";var i7e=mN(),$X=yP(),dm=mP(),ag=(t="",e="",r=!1)=>{let o=[];if(t=[].concat(t),e=[].concat(e),!e.length)return t;if(!t.length)return r?dm.flatten(e).map(a=>`{${a}}`):e;for(let a of t)if(Array.isArray(a))for(let n of a)o.push(ag(n,e,r));else for(let n of e)r===!0&&typeof n=="string"&&(n=`{${n}}`),o.push(Array.isArray(n)?ag(a,n,r):a+n);return dm.flatten(o)},s7e=(t,e={})=>{let r=e.rangeLimit===void 0?1e3:e.rangeLimit,o=(a,n={})=>{a.queue=[];let u=n,A=n.queue;for(;u.type!=="brace"&&u.type!=="root"&&u.parent;)u=u.parent,A=u.queue;if(a.invalid||a.dollar){A.push(ag(A.pop(),$X(a,e)));return}if(a.type==="brace"&&a.invalid!==!0&&a.nodes.length===2){A.push(ag(A.pop(),["{}"]));return}if(a.nodes&&a.ranges>0){let I=dm.reduce(a.nodes);if(dm.exceedsLimit(...I,e.step,r))throw new RangeError("expanded array length exceeds range limit. Use options.rangeLimit to increase or disable the limit.");let v=i7e(...I,e);v.length===0&&(v=$X(a,e)),A.push(ag(A.pop(),v)),a.nodes=[];return}let p=dm.encloseBrace(a),h=a.queue,E=a;for(;E.type!=="brace"&&E.type!=="root"&&E.parent;)E=E.parent,h=E.queue;for(let I=0;I{"use strict";rZ.exports={MAX_LENGTH:1024*64,CHAR_0:"0",CHAR_9:"9",CHAR_UPPERCASE_A:"A",CHAR_LOWERCASE_A:"a",CHAR_UPPERCASE_Z:"Z",CHAR_LOWERCASE_Z:"z",CHAR_LEFT_PARENTHESES:"(",CHAR_RIGHT_PARENTHESES:")",CHAR_ASTERISK:"*",CHAR_AMPERSAND:"&",CHAR_AT:"@",CHAR_BACKSLASH:"\\",CHAR_BACKTICK:"`",CHAR_CARRIAGE_RETURN:"\r",CHAR_CIRCUMFLEX_ACCENT:"^",CHAR_COLON:":",CHAR_COMMA:",",CHAR_DOLLAR:"$",CHAR_DOT:".",CHAR_DOUBLE_QUOTE:'"',CHAR_EQUAL:"=",CHAR_EXCLAMATION_MARK:"!",CHAR_FORM_FEED:"\f",CHAR_FORWARD_SLASH:"/",CHAR_HASH:"#",CHAR_HYPHEN_MINUS:"-",CHAR_LEFT_ANGLE_BRACKET:"<",CHAR_LEFT_CURLY_BRACE:"{",CHAR_LEFT_SQUARE_BRACKET:"[",CHAR_LINE_FEED:` +`,CHAR_NO_BREAK_SPACE:"\xA0",CHAR_PERCENT:"%",CHAR_PLUS:"+",CHAR_QUESTION_MARK:"?",CHAR_RIGHT_ANGLE_BRACKET:">",CHAR_RIGHT_CURLY_BRACE:"}",CHAR_RIGHT_SQUARE_BRACKET:"]",CHAR_SEMICOLON:";",CHAR_SINGLE_QUOTE:"'",CHAR_SPACE:" ",CHAR_TAB:" ",CHAR_UNDERSCORE:"_",CHAR_VERTICAL_LINE:"|",CHAR_ZERO_WIDTH_NOBREAK_SPACE:"\uFEFF"}});var lZ=_((JQt,aZ)=>{"use strict";var o7e=yP(),{MAX_LENGTH:iZ,CHAR_BACKSLASH:yN,CHAR_BACKTICK:a7e,CHAR_COMMA:l7e,CHAR_DOT:c7e,CHAR_LEFT_PARENTHESES:u7e,CHAR_RIGHT_PARENTHESES:A7e,CHAR_LEFT_CURLY_BRACE:f7e,CHAR_RIGHT_CURLY_BRACE:p7e,CHAR_LEFT_SQUARE_BRACKET:sZ,CHAR_RIGHT_SQUARE_BRACKET:oZ,CHAR_DOUBLE_QUOTE:h7e,CHAR_SINGLE_QUOTE:g7e,CHAR_NO_BREAK_SPACE:d7e,CHAR_ZERO_WIDTH_NOBREAK_SPACE:m7e}=nZ(),y7e=(t,e={})=>{if(typeof t!="string")throw new TypeError("Expected a string");let r=e||{},o=typeof r.maxLength=="number"?Math.min(iZ,r.maxLength):iZ;if(t.length>o)throw new SyntaxError(`Input length (${t.length}), exceeds max characters (${o})`);let a={type:"root",input:t,nodes:[]},n=[a],u=a,A=a,p=0,h=t.length,E=0,I=0,v,x={},C=()=>t[E++],R=L=>{if(L.type==="text"&&A.type==="dot"&&(A.type="text"),A&&A.type==="text"&&L.type==="text"){A.value+=L.value;return}return u.nodes.push(L),L.parent=u,L.prev=A,A=L,L};for(R({type:"bos"});E0){if(u.ranges>0){u.ranges=0;let L=u.nodes.shift();u.nodes=[L,{type:"text",value:o7e(u)}]}R({type:"comma",value:v}),u.commas++;continue}if(v===c7e&&I>0&&u.commas===0){let L=u.nodes;if(I===0||L.length===0){R({type:"text",value:v});continue}if(A.type==="dot"){if(u.range=[],A.value+=v,A.type="range",u.nodes.length!==3&&u.nodes.length!==5){u.invalid=!0,u.ranges=0,A.type="text";continue}u.ranges++,u.args=[];continue}if(A.type==="range"){L.pop();let U=L[L.length-1];U.value+=A.value+v,A=U,u.ranges--;continue}R({type:"dot",value:v});continue}R({type:"text",value:v})}do if(u=n.pop(),u.type!=="root"){u.nodes.forEach(z=>{z.nodes||(z.type==="open"&&(z.isOpen=!0),z.type==="close"&&(z.isClose=!0),z.nodes||(z.type="text"),z.invalid=!0)});let L=n[n.length-1],U=L.nodes.indexOf(u);L.nodes.splice(U,1,...u.nodes)}while(n.length>0);return R({type:"eos"}),a};aZ.exports=y7e});var AZ=_((XQt,uZ)=>{"use strict";var cZ=yP(),E7e=ZX(),C7e=tZ(),w7e=lZ(),nl=(t,e={})=>{let r=[];if(Array.isArray(t))for(let o of t){let a=nl.create(o,e);Array.isArray(a)?r.push(...a):r.push(a)}else r=[].concat(nl.create(t,e));return e&&e.expand===!0&&e.nodupes===!0&&(r=[...new Set(r)]),r};nl.parse=(t,e={})=>w7e(t,e);nl.stringify=(t,e={})=>cZ(typeof t=="string"?nl.parse(t,e):t,e);nl.compile=(t,e={})=>(typeof t=="string"&&(t=nl.parse(t,e)),E7e(t,e));nl.expand=(t,e={})=>{typeof t=="string"&&(t=nl.parse(t,e));let r=C7e(t,e);return e.noempty===!0&&(r=r.filter(Boolean)),e.nodupes===!0&&(r=[...new Set(r)]),r};nl.create=(t,e={})=>t===""||t.length<3?[t]:e.expand!==!0?nl.compile(t,e):nl.expand(t,e);uZ.exports=nl});var AI=_((ZQt,dZ)=>{"use strict";var I7e=ve("path"),Vu="\\\\/",fZ=`[^${Vu}]`,Bf="\\.",B7e="\\+",v7e="\\?",CP="\\/",D7e="(?=.)",pZ="[^/]",EN=`(?:${CP}|$)`,hZ=`(?:^|${CP})`,CN=`${Bf}{1,2}${EN}`,P7e=`(?!${Bf})`,b7e=`(?!${hZ}${CN})`,S7e=`(?!${Bf}{0,1}${EN})`,x7e=`(?!${CN})`,k7e=`[^.${CP}]`,Q7e=`${pZ}*?`,gZ={DOT_LITERAL:Bf,PLUS_LITERAL:B7e,QMARK_LITERAL:v7e,SLASH_LITERAL:CP,ONE_CHAR:D7e,QMARK:pZ,END_ANCHOR:EN,DOTS_SLASH:CN,NO_DOT:P7e,NO_DOTS:b7e,NO_DOT_SLASH:S7e,NO_DOTS_SLASH:x7e,QMARK_NO_DOT:k7e,STAR:Q7e,START_ANCHOR:hZ},F7e={...gZ,SLASH_LITERAL:`[${Vu}]`,QMARK:fZ,STAR:`${fZ}*?`,DOTS_SLASH:`${Bf}{1,2}(?:[${Vu}]|$)`,NO_DOT:`(?!${Bf})`,NO_DOTS:`(?!(?:^|[${Vu}])${Bf}{1,2}(?:[${Vu}]|$))`,NO_DOT_SLASH:`(?!${Bf}{0,1}(?:[${Vu}]|$))`,NO_DOTS_SLASH:`(?!${Bf}{1,2}(?:[${Vu}]|$))`,QMARK_NO_DOT:`[^.${Vu}]`,START_ANCHOR:`(?:^|[${Vu}])`,END_ANCHOR:`(?:[${Vu}]|$)`},R7e={alnum:"a-zA-Z0-9",alpha:"a-zA-Z",ascii:"\\x00-\\x7F",blank:" \\t",cntrl:"\\x00-\\x1F\\x7F",digit:"0-9",graph:"\\x21-\\x7E",lower:"a-z",print:"\\x20-\\x7E ",punct:"\\-!\"#$%&'()\\*+,./:;<=>?@[\\]^_`{|}~",space:" \\t\\r\\n\\v\\f",upper:"A-Z",word:"A-Za-z0-9_",xdigit:"A-Fa-f0-9"};dZ.exports={MAX_LENGTH:1024*64,POSIX_REGEX_SOURCE:R7e,REGEX_BACKSLASH:/\\(?![*+?^${}(|)[\]])/g,REGEX_NON_SPECIAL_CHARS:/^[^@![\].,$*+?^{}()|\\/]+/,REGEX_SPECIAL_CHARS:/[-*+?.^${}(|)[\]]/,REGEX_SPECIAL_CHARS_BACKREF:/(\\?)((\W)(\3*))/g,REGEX_SPECIAL_CHARS_GLOBAL:/([-*+?.^${}(|)[\]])/g,REGEX_REMOVE_BACKSLASH:/(?:\[.*?[^\\]\]|\\(?=.))/g,REPLACEMENTS:{"***":"*","**/**":"**","**/**/**":"**"},CHAR_0:48,CHAR_9:57,CHAR_UPPERCASE_A:65,CHAR_LOWERCASE_A:97,CHAR_UPPERCASE_Z:90,CHAR_LOWERCASE_Z:122,CHAR_LEFT_PARENTHESES:40,CHAR_RIGHT_PARENTHESES:41,CHAR_ASTERISK:42,CHAR_AMPERSAND:38,CHAR_AT:64,CHAR_BACKWARD_SLASH:92,CHAR_CARRIAGE_RETURN:13,CHAR_CIRCUMFLEX_ACCENT:94,CHAR_COLON:58,CHAR_COMMA:44,CHAR_DOT:46,CHAR_DOUBLE_QUOTE:34,CHAR_EQUAL:61,CHAR_EXCLAMATION_MARK:33,CHAR_FORM_FEED:12,CHAR_FORWARD_SLASH:47,CHAR_GRAVE_ACCENT:96,CHAR_HASH:35,CHAR_HYPHEN_MINUS:45,CHAR_LEFT_ANGLE_BRACKET:60,CHAR_LEFT_CURLY_BRACE:123,CHAR_LEFT_SQUARE_BRACKET:91,CHAR_LINE_FEED:10,CHAR_NO_BREAK_SPACE:160,CHAR_PERCENT:37,CHAR_PLUS:43,CHAR_QUESTION_MARK:63,CHAR_RIGHT_ANGLE_BRACKET:62,CHAR_RIGHT_CURLY_BRACE:125,CHAR_RIGHT_SQUARE_BRACKET:93,CHAR_SEMICOLON:59,CHAR_SINGLE_QUOTE:39,CHAR_SPACE:32,CHAR_TAB:9,CHAR_UNDERSCORE:95,CHAR_VERTICAL_LINE:124,CHAR_ZERO_WIDTH_NOBREAK_SPACE:65279,SEP:I7e.sep,extglobChars(t){return{"!":{type:"negate",open:"(?:(?!(?:",close:`))${t.STAR})`},"?":{type:"qmark",open:"(?:",close:")?"},"+":{type:"plus",open:"(?:",close:")+"},"*":{type:"star",open:"(?:",close:")*"},"@":{type:"at",open:"(?:",close:")"}}},globChars(t){return t===!0?F7e:gZ}}});var fI=_(Sa=>{"use strict";var T7e=ve("path"),N7e=process.platform==="win32",{REGEX_BACKSLASH:L7e,REGEX_REMOVE_BACKSLASH:M7e,REGEX_SPECIAL_CHARS:O7e,REGEX_SPECIAL_CHARS_GLOBAL:U7e}=AI();Sa.isObject=t=>t!==null&&typeof t=="object"&&!Array.isArray(t);Sa.hasRegexChars=t=>O7e.test(t);Sa.isRegexChar=t=>t.length===1&&Sa.hasRegexChars(t);Sa.escapeRegex=t=>t.replace(U7e,"\\$1");Sa.toPosixSlashes=t=>t.replace(L7e,"/");Sa.removeBackslashes=t=>t.replace(M7e,e=>e==="\\"?"":e);Sa.supportsLookbehinds=()=>{let t=process.version.slice(1).split(".").map(Number);return t.length===3&&t[0]>=9||t[0]===8&&t[1]>=10};Sa.isWindows=t=>t&&typeof t.windows=="boolean"?t.windows:N7e===!0||T7e.sep==="\\";Sa.escapeLast=(t,e,r)=>{let o=t.lastIndexOf(e,r);return o===-1?t:t[o-1]==="\\"?Sa.escapeLast(t,e,o-1):`${t.slice(0,o)}\\${t.slice(o)}`};Sa.removePrefix=(t,e={})=>{let r=t;return r.startsWith("./")&&(r=r.slice(2),e.prefix="./"),r};Sa.wrapOutput=(t,e={},r={})=>{let o=r.contains?"":"^",a=r.contains?"":"$",n=`${o}(?:${t})${a}`;return e.negated===!0&&(n=`(?:^(?!${n}).*$)`),n}});var vZ=_((eFt,BZ)=>{"use strict";var mZ=fI(),{CHAR_ASTERISK:wN,CHAR_AT:_7e,CHAR_BACKWARD_SLASH:pI,CHAR_COMMA:H7e,CHAR_DOT:IN,CHAR_EXCLAMATION_MARK:BN,CHAR_FORWARD_SLASH:IZ,CHAR_LEFT_CURLY_BRACE:vN,CHAR_LEFT_PARENTHESES:DN,CHAR_LEFT_SQUARE_BRACKET:q7e,CHAR_PLUS:j7e,CHAR_QUESTION_MARK:yZ,CHAR_RIGHT_CURLY_BRACE:G7e,CHAR_RIGHT_PARENTHESES:EZ,CHAR_RIGHT_SQUARE_BRACKET:Y7e}=AI(),CZ=t=>t===IZ||t===pI,wZ=t=>{t.isPrefix!==!0&&(t.depth=t.isGlobstar?1/0:1)},W7e=(t,e)=>{let r=e||{},o=t.length-1,a=r.parts===!0||r.scanToEnd===!0,n=[],u=[],A=[],p=t,h=-1,E=0,I=0,v=!1,x=!1,C=!1,R=!1,L=!1,U=!1,z=!1,te=!1,ae=!1,le=!1,ce=0,Ce,de,Be={value:"",depth:0,isGlob:!1},Ee=()=>h>=o,g=()=>p.charCodeAt(h+1),me=()=>(Ce=de,p.charCodeAt(++h));for(;h0&&(Ae=p.slice(0,E),p=p.slice(E),I-=E),we&&C===!0&&I>0?(we=p.slice(0,I),ne=p.slice(I)):C===!0?(we="",ne=p):we=p,we&&we!==""&&we!=="/"&&we!==p&&CZ(we.charCodeAt(we.length-1))&&(we=we.slice(0,-1)),r.unescape===!0&&(ne&&(ne=mZ.removeBackslashes(ne)),we&&z===!0&&(we=mZ.removeBackslashes(we)));let Z={prefix:Ae,input:t,start:E,base:we,glob:ne,isBrace:v,isBracket:x,isGlob:C,isExtglob:R,isGlobstar:L,negated:te,negatedExtglob:ae};if(r.tokens===!0&&(Z.maxDepth=0,CZ(de)||u.push(Be),Z.tokens=u),r.parts===!0||r.tokens===!0){let xe;for(let Ne=0;Ne{"use strict";var wP=AI(),il=fI(),{MAX_LENGTH:IP,POSIX_REGEX_SOURCE:K7e,REGEX_NON_SPECIAL_CHARS:V7e,REGEX_SPECIAL_CHARS_BACKREF:z7e,REPLACEMENTS:DZ}=wP,J7e=(t,e)=>{if(typeof e.expandRange=="function")return e.expandRange(...t,e);t.sort();let r=`[${t.join("-")}]`;try{new RegExp(r)}catch{return t.map(a=>il.escapeRegex(a)).join("..")}return r},mm=(t,e)=>`Missing ${t}: "${e}" - use "\\\\${e}" to match literal characters`,PN=(t,e)=>{if(typeof t!="string")throw new TypeError("Expected a string");t=DZ[t]||t;let r={...e},o=typeof r.maxLength=="number"?Math.min(IP,r.maxLength):IP,a=t.length;if(a>o)throw new SyntaxError(`Input length: ${a}, exceeds maximum allowed length: ${o}`);let n={type:"bos",value:"",output:r.prepend||""},u=[n],A=r.capture?"":"?:",p=il.isWindows(e),h=wP.globChars(p),E=wP.extglobChars(h),{DOT_LITERAL:I,PLUS_LITERAL:v,SLASH_LITERAL:x,ONE_CHAR:C,DOTS_SLASH:R,NO_DOT:L,NO_DOT_SLASH:U,NO_DOTS_SLASH:z,QMARK:te,QMARK_NO_DOT:ae,STAR:le,START_ANCHOR:ce}=h,Ce=S=>`(${A}(?:(?!${ce}${S.dot?R:I}).)*?)`,de=r.dot?"":L,Be=r.dot?te:ae,Ee=r.bash===!0?Ce(r):le;r.capture&&(Ee=`(${Ee})`),typeof r.noext=="boolean"&&(r.noextglob=r.noext);let g={input:t,index:-1,start:0,dot:r.dot===!0,consumed:"",output:"",prefix:"",backtrack:!1,negated:!1,brackets:0,braces:0,parens:0,quotes:0,globstar:!1,tokens:u};t=il.removePrefix(t,g),a=t.length;let me=[],we=[],Ae=[],ne=n,Z,xe=()=>g.index===a-1,Ne=g.peek=(S=1)=>t[g.index+S],ht=g.advance=()=>t[++g.index]||"",H=()=>t.slice(g.index+1),rt=(S="",w=0)=>{g.consumed+=S,g.index+=w},Te=S=>{g.output+=S.output!=null?S.output:S.value,rt(S.value)},Fe=()=>{let S=1;for(;Ne()==="!"&&(Ne(2)!=="("||Ne(3)==="?");)ht(),g.start++,S++;return S%2===0?!1:(g.negated=!0,g.start++,!0)},ke=S=>{g[S]++,Ae.push(S)},Ye=S=>{g[S]--,Ae.pop()},be=S=>{if(ne.type==="globstar"){let w=g.braces>0&&(S.type==="comma"||S.type==="brace"),b=S.extglob===!0||me.length&&(S.type==="pipe"||S.type==="paren");S.type!=="slash"&&S.type!=="paren"&&!w&&!b&&(g.output=g.output.slice(0,-ne.output.length),ne.type="star",ne.value="*",ne.output=Ee,g.output+=ne.output)}if(me.length&&S.type!=="paren"&&(me[me.length-1].inner+=S.value),(S.value||S.output)&&Te(S),ne&&ne.type==="text"&&S.type==="text"){ne.value+=S.value,ne.output=(ne.output||"")+S.value;return}S.prev=ne,u.push(S),ne=S},et=(S,w)=>{let b={...E[w],conditions:1,inner:""};b.prev=ne,b.parens=g.parens,b.output=g.output;let y=(r.capture?"(":"")+b.open;ke("parens"),be({type:S,value:w,output:g.output?"":C}),be({type:"paren",extglob:!0,value:ht(),output:y}),me.push(b)},Ue=S=>{let w=S.close+(r.capture?")":""),b;if(S.type==="negate"){let y=Ee;if(S.inner&&S.inner.length>1&&S.inner.includes("/")&&(y=Ce(r)),(y!==Ee||xe()||/^\)+$/.test(H()))&&(w=S.close=`)$))${y}`),S.inner.includes("*")&&(b=H())&&/^\.[^\\/.]+$/.test(b)){let F=PN(b,{...e,fastpaths:!1}).output;w=S.close=`)${F})${y})`}S.prev.type==="bos"&&(g.negatedExtglob=!0)}be({type:"paren",extglob:!0,value:Z,output:w}),Ye("parens")};if(r.fastpaths!==!1&&!/(^[*!]|[/()[\]{}"])/.test(t)){let S=!1,w=t.replace(z7e,(b,y,F,J,X,$)=>J==="\\"?(S=!0,b):J==="?"?y?y+J+(X?te.repeat(X.length):""):$===0?Be+(X?te.repeat(X.length):""):te.repeat(F.length):J==="."?I.repeat(F.length):J==="*"?y?y+J+(X?Ee:""):Ee:y?b:`\\${b}`);return S===!0&&(r.unescape===!0?w=w.replace(/\\/g,""):w=w.replace(/\\+/g,b=>b.length%2===0?"\\\\":b?"\\":"")),w===t&&r.contains===!0?(g.output=t,g):(g.output=il.wrapOutput(w,g,e),g)}for(;!xe();){if(Z=ht(),Z==="\0")continue;if(Z==="\\"){let b=Ne();if(b==="/"&&r.bash!==!0||b==="."||b===";")continue;if(!b){Z+="\\",be({type:"text",value:Z});continue}let y=/^\\+/.exec(H()),F=0;if(y&&y[0].length>2&&(F=y[0].length,g.index+=F,F%2!==0&&(Z+="\\")),r.unescape===!0?Z=ht():Z+=ht(),g.brackets===0){be({type:"text",value:Z});continue}}if(g.brackets>0&&(Z!=="]"||ne.value==="["||ne.value==="[^")){if(r.posix!==!1&&Z===":"){let b=ne.value.slice(1);if(b.includes("[")&&(ne.posix=!0,b.includes(":"))){let y=ne.value.lastIndexOf("["),F=ne.value.slice(0,y),J=ne.value.slice(y+2),X=K7e[J];if(X){ne.value=F+X,g.backtrack=!0,ht(),!n.output&&u.indexOf(ne)===1&&(n.output=C);continue}}}(Z==="["&&Ne()!==":"||Z==="-"&&Ne()==="]")&&(Z=`\\${Z}`),Z==="]"&&(ne.value==="["||ne.value==="[^")&&(Z=`\\${Z}`),r.posix===!0&&Z==="!"&&ne.value==="["&&(Z="^"),ne.value+=Z,Te({value:Z});continue}if(g.quotes===1&&Z!=='"'){Z=il.escapeRegex(Z),ne.value+=Z,Te({value:Z});continue}if(Z==='"'){g.quotes=g.quotes===1?0:1,r.keepQuotes===!0&&be({type:"text",value:Z});continue}if(Z==="("){ke("parens"),be({type:"paren",value:Z});continue}if(Z===")"){if(g.parens===0&&r.strictBrackets===!0)throw new SyntaxError(mm("opening","("));let b=me[me.length-1];if(b&&g.parens===b.parens+1){Ue(me.pop());continue}be({type:"paren",value:Z,output:g.parens?")":"\\)"}),Ye("parens");continue}if(Z==="["){if(r.nobracket===!0||!H().includes("]")){if(r.nobracket!==!0&&r.strictBrackets===!0)throw new SyntaxError(mm("closing","]"));Z=`\\${Z}`}else ke("brackets");be({type:"bracket",value:Z});continue}if(Z==="]"){if(r.nobracket===!0||ne&&ne.type==="bracket"&&ne.value.length===1){be({type:"text",value:Z,output:`\\${Z}`});continue}if(g.brackets===0){if(r.strictBrackets===!0)throw new SyntaxError(mm("opening","["));be({type:"text",value:Z,output:`\\${Z}`});continue}Ye("brackets");let b=ne.value.slice(1);if(ne.posix!==!0&&b[0]==="^"&&!b.includes("/")&&(Z=`/${Z}`),ne.value+=Z,Te({value:Z}),r.literalBrackets===!1||il.hasRegexChars(b))continue;let y=il.escapeRegex(ne.value);if(g.output=g.output.slice(0,-ne.value.length),r.literalBrackets===!0){g.output+=y,ne.value=y;continue}ne.value=`(${A}${y}|${ne.value})`,g.output+=ne.value;continue}if(Z==="{"&&r.nobrace!==!0){ke("braces");let b={type:"brace",value:Z,output:"(",outputIndex:g.output.length,tokensIndex:g.tokens.length};we.push(b),be(b);continue}if(Z==="}"){let b=we[we.length-1];if(r.nobrace===!0||!b){be({type:"text",value:Z,output:Z});continue}let y=")";if(b.dots===!0){let F=u.slice(),J=[];for(let X=F.length-1;X>=0&&(u.pop(),F[X].type!=="brace");X--)F[X].type!=="dots"&&J.unshift(F[X].value);y=J7e(J,r),g.backtrack=!0}if(b.comma!==!0&&b.dots!==!0){let F=g.output.slice(0,b.outputIndex),J=g.tokens.slice(b.tokensIndex);b.value=b.output="\\{",Z=y="\\}",g.output=F;for(let X of J)g.output+=X.output||X.value}be({type:"brace",value:Z,output:y}),Ye("braces"),we.pop();continue}if(Z==="|"){me.length>0&&me[me.length-1].conditions++,be({type:"text",value:Z});continue}if(Z===","){let b=Z,y=we[we.length-1];y&&Ae[Ae.length-1]==="braces"&&(y.comma=!0,b="|"),be({type:"comma",value:Z,output:b});continue}if(Z==="/"){if(ne.type==="dot"&&g.index===g.start+1){g.start=g.index+1,g.consumed="",g.output="",u.pop(),ne=n;continue}be({type:"slash",value:Z,output:x});continue}if(Z==="."){if(g.braces>0&&ne.type==="dot"){ne.value==="."&&(ne.output=I);let b=we[we.length-1];ne.type="dots",ne.output+=Z,ne.value+=Z,b.dots=!0;continue}if(g.braces+g.parens===0&&ne.type!=="bos"&&ne.type!=="slash"){be({type:"text",value:Z,output:I});continue}be({type:"dot",value:Z,output:I});continue}if(Z==="?"){if(!(ne&&ne.value==="(")&&r.noextglob!==!0&&Ne()==="("&&Ne(2)!=="?"){et("qmark",Z);continue}if(ne&&ne.type==="paren"){let y=Ne(),F=Z;if(y==="<"&&!il.supportsLookbehinds())throw new Error("Node.js v10 or higher is required for regex lookbehinds");(ne.value==="("&&!/[!=<:]/.test(y)||y==="<"&&!/<([!=]|\w+>)/.test(H()))&&(F=`\\${Z}`),be({type:"text",value:Z,output:F});continue}if(r.dot!==!0&&(ne.type==="slash"||ne.type==="bos")){be({type:"qmark",value:Z,output:ae});continue}be({type:"qmark",value:Z,output:te});continue}if(Z==="!"){if(r.noextglob!==!0&&Ne()==="("&&(Ne(2)!=="?"||!/[!=<:]/.test(Ne(3)))){et("negate",Z);continue}if(r.nonegate!==!0&&g.index===0){Fe();continue}}if(Z==="+"){if(r.noextglob!==!0&&Ne()==="("&&Ne(2)!=="?"){et("plus",Z);continue}if(ne&&ne.value==="("||r.regex===!1){be({type:"plus",value:Z,output:v});continue}if(ne&&(ne.type==="bracket"||ne.type==="paren"||ne.type==="brace")||g.parens>0){be({type:"plus",value:Z});continue}be({type:"plus",value:v});continue}if(Z==="@"){if(r.noextglob!==!0&&Ne()==="("&&Ne(2)!=="?"){be({type:"at",extglob:!0,value:Z,output:""});continue}be({type:"text",value:Z});continue}if(Z!=="*"){(Z==="$"||Z==="^")&&(Z=`\\${Z}`);let b=V7e.exec(H());b&&(Z+=b[0],g.index+=b[0].length),be({type:"text",value:Z});continue}if(ne&&(ne.type==="globstar"||ne.star===!0)){ne.type="star",ne.star=!0,ne.value+=Z,ne.output=Ee,g.backtrack=!0,g.globstar=!0,rt(Z);continue}let S=H();if(r.noextglob!==!0&&/^\([^?]/.test(S)){et("star",Z);continue}if(ne.type==="star"){if(r.noglobstar===!0){rt(Z);continue}let b=ne.prev,y=b.prev,F=b.type==="slash"||b.type==="bos",J=y&&(y.type==="star"||y.type==="globstar");if(r.bash===!0&&(!F||S[0]&&S[0]!=="/")){be({type:"star",value:Z,output:""});continue}let X=g.braces>0&&(b.type==="comma"||b.type==="brace"),$=me.length&&(b.type==="pipe"||b.type==="paren");if(!F&&b.type!=="paren"&&!X&&!$){be({type:"star",value:Z,output:""});continue}for(;S.slice(0,3)==="/**";){let ie=t[g.index+4];if(ie&&ie!=="/")break;S=S.slice(3),rt("/**",3)}if(b.type==="bos"&&xe()){ne.type="globstar",ne.value+=Z,ne.output=Ce(r),g.output=ne.output,g.globstar=!0,rt(Z);continue}if(b.type==="slash"&&b.prev.type!=="bos"&&!J&&xe()){g.output=g.output.slice(0,-(b.output+ne.output).length),b.output=`(?:${b.output}`,ne.type="globstar",ne.output=Ce(r)+(r.strictSlashes?")":"|$)"),ne.value+=Z,g.globstar=!0,g.output+=b.output+ne.output,rt(Z);continue}if(b.type==="slash"&&b.prev.type!=="bos"&&S[0]==="/"){let ie=S[1]!==void 0?"|$":"";g.output=g.output.slice(0,-(b.output+ne.output).length),b.output=`(?:${b.output}`,ne.type="globstar",ne.output=`${Ce(r)}${x}|${x}${ie})`,ne.value+=Z,g.output+=b.output+ne.output,g.globstar=!0,rt(Z+ht()),be({type:"slash",value:"/",output:""});continue}if(b.type==="bos"&&S[0]==="/"){ne.type="globstar",ne.value+=Z,ne.output=`(?:^|${x}|${Ce(r)}${x})`,g.output=ne.output,g.globstar=!0,rt(Z+ht()),be({type:"slash",value:"/",output:""});continue}g.output=g.output.slice(0,-ne.output.length),ne.type="globstar",ne.output=Ce(r),ne.value+=Z,g.output+=ne.output,g.globstar=!0,rt(Z);continue}let w={type:"star",value:Z,output:Ee};if(r.bash===!0){w.output=".*?",(ne.type==="bos"||ne.type==="slash")&&(w.output=de+w.output),be(w);continue}if(ne&&(ne.type==="bracket"||ne.type==="paren")&&r.regex===!0){w.output=Z,be(w);continue}(g.index===g.start||ne.type==="slash"||ne.type==="dot")&&(ne.type==="dot"?(g.output+=U,ne.output+=U):r.dot===!0?(g.output+=z,ne.output+=z):(g.output+=de,ne.output+=de),Ne()!=="*"&&(g.output+=C,ne.output+=C)),be(w)}for(;g.brackets>0;){if(r.strictBrackets===!0)throw new SyntaxError(mm("closing","]"));g.output=il.escapeLast(g.output,"["),Ye("brackets")}for(;g.parens>0;){if(r.strictBrackets===!0)throw new SyntaxError(mm("closing",")"));g.output=il.escapeLast(g.output,"("),Ye("parens")}for(;g.braces>0;){if(r.strictBrackets===!0)throw new SyntaxError(mm("closing","}"));g.output=il.escapeLast(g.output,"{"),Ye("braces")}if(r.strictSlashes!==!0&&(ne.type==="star"||ne.type==="bracket")&&be({type:"maybe_slash",value:"",output:`${x}?`}),g.backtrack===!0){g.output="";for(let S of g.tokens)g.output+=S.output!=null?S.output:S.value,S.suffix&&(g.output+=S.suffix)}return g};PN.fastpaths=(t,e)=>{let r={...e},o=typeof r.maxLength=="number"?Math.min(IP,r.maxLength):IP,a=t.length;if(a>o)throw new SyntaxError(`Input length: ${a}, exceeds maximum allowed length: ${o}`);t=DZ[t]||t;let n=il.isWindows(e),{DOT_LITERAL:u,SLASH_LITERAL:A,ONE_CHAR:p,DOTS_SLASH:h,NO_DOT:E,NO_DOTS:I,NO_DOTS_SLASH:v,STAR:x,START_ANCHOR:C}=wP.globChars(n),R=r.dot?I:E,L=r.dot?v:E,U=r.capture?"":"?:",z={negated:!1,prefix:""},te=r.bash===!0?".*?":x;r.capture&&(te=`(${te})`);let ae=de=>de.noglobstar===!0?te:`(${U}(?:(?!${C}${de.dot?h:u}).)*?)`,le=de=>{switch(de){case"*":return`${R}${p}${te}`;case".*":return`${u}${p}${te}`;case"*.*":return`${R}${te}${u}${p}${te}`;case"*/*":return`${R}${te}${A}${p}${L}${te}`;case"**":return R+ae(r);case"**/*":return`(?:${R}${ae(r)}${A})?${L}${p}${te}`;case"**/*.*":return`(?:${R}${ae(r)}${A})?${L}${te}${u}${p}${te}`;case"**/.*":return`(?:${R}${ae(r)}${A})?${u}${p}${te}`;default:{let Be=/^(.*?)\.(\w+)$/.exec(de);if(!Be)return;let Ee=le(Be[1]);return Ee?Ee+u+Be[2]:void 0}}},ce=il.removePrefix(t,z),Ce=le(ce);return Ce&&r.strictSlashes!==!0&&(Ce+=`${A}?`),Ce};PZ.exports=PN});var xZ=_((rFt,SZ)=>{"use strict";var X7e=ve("path"),Z7e=vZ(),bN=bZ(),SN=fI(),$7e=AI(),eYe=t=>t&&typeof t=="object"&&!Array.isArray(t),Mi=(t,e,r=!1)=>{if(Array.isArray(t)){let E=t.map(v=>Mi(v,e,r));return v=>{for(let x of E){let C=x(v);if(C)return C}return!1}}let o=eYe(t)&&t.tokens&&t.input;if(t===""||typeof t!="string"&&!o)throw new TypeError("Expected pattern to be a non-empty string");let a=e||{},n=SN.isWindows(e),u=o?Mi.compileRe(t,e):Mi.makeRe(t,e,!1,!0),A=u.state;delete u.state;let p=()=>!1;if(a.ignore){let E={...e,ignore:null,onMatch:null,onResult:null};p=Mi(a.ignore,E,r)}let h=(E,I=!1)=>{let{isMatch:v,match:x,output:C}=Mi.test(E,u,e,{glob:t,posix:n}),R={glob:t,state:A,regex:u,posix:n,input:E,output:C,match:x,isMatch:v};return typeof a.onResult=="function"&&a.onResult(R),v===!1?(R.isMatch=!1,I?R:!1):p(E)?(typeof a.onIgnore=="function"&&a.onIgnore(R),R.isMatch=!1,I?R:!1):(typeof a.onMatch=="function"&&a.onMatch(R),I?R:!0)};return r&&(h.state=A),h};Mi.test=(t,e,r,{glob:o,posix:a}={})=>{if(typeof t!="string")throw new TypeError("Expected input to be a string");if(t==="")return{isMatch:!1,output:""};let n=r||{},u=n.format||(a?SN.toPosixSlashes:null),A=t===o,p=A&&u?u(t):t;return A===!1&&(p=u?u(t):t,A=p===o),(A===!1||n.capture===!0)&&(n.matchBase===!0||n.basename===!0?A=Mi.matchBase(t,e,r,a):A=e.exec(p)),{isMatch:!!A,match:A,output:p}};Mi.matchBase=(t,e,r,o=SN.isWindows(r))=>(e instanceof RegExp?e:Mi.makeRe(e,r)).test(X7e.basename(t));Mi.isMatch=(t,e,r)=>Mi(e,r)(t);Mi.parse=(t,e)=>Array.isArray(t)?t.map(r=>Mi.parse(r,e)):bN(t,{...e,fastpaths:!1});Mi.scan=(t,e)=>Z7e(t,e);Mi.compileRe=(t,e,r=!1,o=!1)=>{if(r===!0)return t.output;let a=e||{},n=a.contains?"":"^",u=a.contains?"":"$",A=`${n}(?:${t.output})${u}`;t&&t.negated===!0&&(A=`^(?!${A}).*$`);let p=Mi.toRegex(A,e);return o===!0&&(p.state=t),p};Mi.makeRe=(t,e={},r=!1,o=!1)=>{if(!t||typeof t!="string")throw new TypeError("Expected a non-empty string");let a={negated:!1,fastpaths:!0};return e.fastpaths!==!1&&(t[0]==="."||t[0]==="*")&&(a.output=bN.fastpaths(t,e)),a.output||(a=bN(t,e)),Mi.compileRe(a,e,r,o)};Mi.toRegex=(t,e)=>{try{let r=e||{};return new RegExp(t,r.flags||(r.nocase?"i":""))}catch(r){if(e&&e.debug===!0)throw r;return/$^/}};Mi.constants=$7e;SZ.exports=Mi});var QZ=_((nFt,kZ)=>{"use strict";kZ.exports=xZ()});var $o=_((iFt,NZ)=>{"use strict";var RZ=ve("util"),TZ=AZ(),zu=QZ(),xN=fI(),FZ=t=>t===""||t==="./",mi=(t,e,r)=>{e=[].concat(e),t=[].concat(t);let o=new Set,a=new Set,n=new Set,u=0,A=E=>{n.add(E.output),r&&r.onResult&&r.onResult(E)};for(let E=0;E!o.has(E));if(r&&h.length===0){if(r.failglob===!0)throw new Error(`No matches found for "${e.join(", ")}"`);if(r.nonull===!0||r.nullglob===!0)return r.unescape?e.map(E=>E.replace(/\\/g,"")):e}return h};mi.match=mi;mi.matcher=(t,e)=>zu(t,e);mi.isMatch=(t,e,r)=>zu(e,r)(t);mi.any=mi.isMatch;mi.not=(t,e,r={})=>{e=[].concat(e).map(String);let o=new Set,a=[],n=A=>{r.onResult&&r.onResult(A),a.push(A.output)},u=new Set(mi(t,e,{...r,onResult:n}));for(let A of a)u.has(A)||o.add(A);return[...o]};mi.contains=(t,e,r)=>{if(typeof t!="string")throw new TypeError(`Expected a string: "${RZ.inspect(t)}"`);if(Array.isArray(e))return e.some(o=>mi.contains(t,o,r));if(typeof e=="string"){if(FZ(t)||FZ(e))return!1;if(t.includes(e)||t.startsWith("./")&&t.slice(2).includes(e))return!0}return mi.isMatch(t,e,{...r,contains:!0})};mi.matchKeys=(t,e,r)=>{if(!xN.isObject(t))throw new TypeError("Expected the first argument to be an object");let o=mi(Object.keys(t),e,r),a={};for(let n of o)a[n]=t[n];return a};mi.some=(t,e,r)=>{let o=[].concat(t);for(let a of[].concat(e)){let n=zu(String(a),r);if(o.some(u=>n(u)))return!0}return!1};mi.every=(t,e,r)=>{let o=[].concat(t);for(let a of[].concat(e)){let n=zu(String(a),r);if(!o.every(u=>n(u)))return!1}return!0};mi.all=(t,e,r)=>{if(typeof t!="string")throw new TypeError(`Expected a string: "${RZ.inspect(t)}"`);return[].concat(e).every(o=>zu(o,r)(t))};mi.capture=(t,e,r)=>{let o=xN.isWindows(r),n=zu.makeRe(String(t),{...r,capture:!0}).exec(o?xN.toPosixSlashes(e):e);if(n)return n.slice(1).map(u=>u===void 0?"":u)};mi.makeRe=(...t)=>zu.makeRe(...t);mi.scan=(...t)=>zu.scan(...t);mi.parse=(t,e)=>{let r=[];for(let o of[].concat(t||[]))for(let a of TZ(String(o),e))r.push(zu.parse(a,e));return r};mi.braces=(t,e)=>{if(typeof t!="string")throw new TypeError("Expected a string");return e&&e.nobrace===!0||!/\{.*\}/.test(t)?[t]:TZ(t,e)};mi.braceExpand=(t,e)=>{if(typeof t!="string")throw new TypeError("Expected a string");return mi.braces(t,{...e,expand:!0})};NZ.exports=mi});var MZ=_((sFt,LZ)=>{"use strict";LZ.exports=({onlyFirst:t=!1}={})=>{let e=["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)","(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))"].join("|");return new RegExp(e,t?void 0:"g")}});var BP=_((oFt,OZ)=>{"use strict";var tYe=MZ();OZ.exports=t=>typeof t=="string"?t.replace(tYe(),""):t});var _Z=_((aFt,UZ)=>{function rYe(){this.__data__=[],this.size=0}UZ.exports=rYe});var ym=_((lFt,HZ)=>{function nYe(t,e){return t===e||t!==t&&e!==e}HZ.exports=nYe});var hI=_((cFt,qZ)=>{var iYe=ym();function sYe(t,e){for(var r=t.length;r--;)if(iYe(t[r][0],e))return r;return-1}qZ.exports=sYe});var GZ=_((uFt,jZ)=>{var oYe=hI(),aYe=Array.prototype,lYe=aYe.splice;function cYe(t){var e=this.__data__,r=oYe(e,t);if(r<0)return!1;var o=e.length-1;return r==o?e.pop():lYe.call(e,r,1),--this.size,!0}jZ.exports=cYe});var WZ=_((AFt,YZ)=>{var uYe=hI();function AYe(t){var e=this.__data__,r=uYe(e,t);return r<0?void 0:e[r][1]}YZ.exports=AYe});var VZ=_((fFt,KZ)=>{var fYe=hI();function pYe(t){return fYe(this.__data__,t)>-1}KZ.exports=pYe});var JZ=_((pFt,zZ)=>{var hYe=hI();function gYe(t,e){var r=this.__data__,o=hYe(r,t);return o<0?(++this.size,r.push([t,e])):r[o][1]=e,this}zZ.exports=gYe});var gI=_((hFt,XZ)=>{var dYe=_Z(),mYe=GZ(),yYe=WZ(),EYe=VZ(),CYe=JZ();function Em(t){var e=-1,r=t==null?0:t.length;for(this.clear();++e{var wYe=gI();function IYe(){this.__data__=new wYe,this.size=0}ZZ.exports=IYe});var t$=_((dFt,e$)=>{function BYe(t){var e=this.__data__,r=e.delete(t);return this.size=e.size,r}e$.exports=BYe});var n$=_((mFt,r$)=>{function vYe(t){return this.__data__.get(t)}r$.exports=vYe});var s$=_((yFt,i$)=>{function DYe(t){return this.__data__.has(t)}i$.exports=DYe});var kN=_((EFt,o$)=>{var PYe=typeof global=="object"&&global&&global.Object===Object&&global;o$.exports=PYe});var _l=_((CFt,a$)=>{var bYe=kN(),SYe=typeof self=="object"&&self&&self.Object===Object&&self,xYe=bYe||SYe||Function("return this")();a$.exports=xYe});var lg=_((wFt,l$)=>{var kYe=_l(),QYe=kYe.Symbol;l$.exports=QYe});var f$=_((IFt,A$)=>{var c$=lg(),u$=Object.prototype,FYe=u$.hasOwnProperty,RYe=u$.toString,dI=c$?c$.toStringTag:void 0;function TYe(t){var e=FYe.call(t,dI),r=t[dI];try{t[dI]=void 0;var o=!0}catch{}var a=RYe.call(t);return o&&(e?t[dI]=r:delete t[dI]),a}A$.exports=TYe});var h$=_((BFt,p$)=>{var NYe=Object.prototype,LYe=NYe.toString;function MYe(t){return LYe.call(t)}p$.exports=MYe});var cg=_((vFt,m$)=>{var g$=lg(),OYe=f$(),UYe=h$(),_Ye="[object Null]",HYe="[object Undefined]",d$=g$?g$.toStringTag:void 0;function qYe(t){return t==null?t===void 0?HYe:_Ye:d$&&d$ in Object(t)?OYe(t):UYe(t)}m$.exports=qYe});var sl=_((DFt,y$)=>{function jYe(t){var e=typeof t;return t!=null&&(e=="object"||e=="function")}y$.exports=jYe});var vP=_((PFt,E$)=>{var GYe=cg(),YYe=sl(),WYe="[object AsyncFunction]",KYe="[object Function]",VYe="[object GeneratorFunction]",zYe="[object Proxy]";function JYe(t){if(!YYe(t))return!1;var e=GYe(t);return e==KYe||e==VYe||e==WYe||e==zYe}E$.exports=JYe});var w$=_((bFt,C$)=>{var XYe=_l(),ZYe=XYe["__core-js_shared__"];C$.exports=ZYe});var v$=_((SFt,B$)=>{var QN=w$(),I$=function(){var t=/[^.]+$/.exec(QN&&QN.keys&&QN.keys.IE_PROTO||"");return t?"Symbol(src)_1."+t:""}();function $Ye(t){return!!I$&&I$ in t}B$.exports=$Ye});var FN=_((xFt,D$)=>{var eWe=Function.prototype,tWe=eWe.toString;function rWe(t){if(t!=null){try{return tWe.call(t)}catch{}try{return t+""}catch{}}return""}D$.exports=rWe});var b$=_((kFt,P$)=>{var nWe=vP(),iWe=v$(),sWe=sl(),oWe=FN(),aWe=/[\\^$.*+?()[\]{}|]/g,lWe=/^\[object .+?Constructor\]$/,cWe=Function.prototype,uWe=Object.prototype,AWe=cWe.toString,fWe=uWe.hasOwnProperty,pWe=RegExp("^"+AWe.call(fWe).replace(aWe,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");function hWe(t){if(!sWe(t)||iWe(t))return!1;var e=nWe(t)?pWe:lWe;return e.test(oWe(t))}P$.exports=hWe});var x$=_((QFt,S$)=>{function gWe(t,e){return t?.[e]}S$.exports=gWe});var Kp=_((FFt,k$)=>{var dWe=b$(),mWe=x$();function yWe(t,e){var r=mWe(t,e);return dWe(r)?r:void 0}k$.exports=yWe});var DP=_((RFt,Q$)=>{var EWe=Kp(),CWe=_l(),wWe=EWe(CWe,"Map");Q$.exports=wWe});var mI=_((TFt,F$)=>{var IWe=Kp(),BWe=IWe(Object,"create");F$.exports=BWe});var N$=_((NFt,T$)=>{var R$=mI();function vWe(){this.__data__=R$?R$(null):{},this.size=0}T$.exports=vWe});var M$=_((LFt,L$)=>{function DWe(t){var e=this.has(t)&&delete this.__data__[t];return this.size-=e?1:0,e}L$.exports=DWe});var U$=_((MFt,O$)=>{var PWe=mI(),bWe="__lodash_hash_undefined__",SWe=Object.prototype,xWe=SWe.hasOwnProperty;function kWe(t){var e=this.__data__;if(PWe){var r=e[t];return r===bWe?void 0:r}return xWe.call(e,t)?e[t]:void 0}O$.exports=kWe});var H$=_((OFt,_$)=>{var QWe=mI(),FWe=Object.prototype,RWe=FWe.hasOwnProperty;function TWe(t){var e=this.__data__;return QWe?e[t]!==void 0:RWe.call(e,t)}_$.exports=TWe});var j$=_((UFt,q$)=>{var NWe=mI(),LWe="__lodash_hash_undefined__";function MWe(t,e){var r=this.__data__;return this.size+=this.has(t)?0:1,r[t]=NWe&&e===void 0?LWe:e,this}q$.exports=MWe});var Y$=_((_Ft,G$)=>{var OWe=N$(),UWe=M$(),_We=U$(),HWe=H$(),qWe=j$();function Cm(t){var e=-1,r=t==null?0:t.length;for(this.clear();++e{var W$=Y$(),jWe=gI(),GWe=DP();function YWe(){this.size=0,this.__data__={hash:new W$,map:new(GWe||jWe),string:new W$}}K$.exports=YWe});var J$=_((qFt,z$)=>{function WWe(t){var e=typeof t;return e=="string"||e=="number"||e=="symbol"||e=="boolean"?t!=="__proto__":t===null}z$.exports=WWe});var yI=_((jFt,X$)=>{var KWe=J$();function VWe(t,e){var r=t.__data__;return KWe(e)?r[typeof e=="string"?"string":"hash"]:r.map}X$.exports=VWe});var $$=_((GFt,Z$)=>{var zWe=yI();function JWe(t){var e=zWe(this,t).delete(t);return this.size-=e?1:0,e}Z$.exports=JWe});var tee=_((YFt,eee)=>{var XWe=yI();function ZWe(t){return XWe(this,t).get(t)}eee.exports=ZWe});var nee=_((WFt,ree)=>{var $We=yI();function eKe(t){return $We(this,t).has(t)}ree.exports=eKe});var see=_((KFt,iee)=>{var tKe=yI();function rKe(t,e){var r=tKe(this,t),o=r.size;return r.set(t,e),this.size+=r.size==o?0:1,this}iee.exports=rKe});var PP=_((VFt,oee)=>{var nKe=V$(),iKe=$$(),sKe=tee(),oKe=nee(),aKe=see();function wm(t){var e=-1,r=t==null?0:t.length;for(this.clear();++e{var lKe=gI(),cKe=DP(),uKe=PP(),AKe=200;function fKe(t,e){var r=this.__data__;if(r instanceof lKe){var o=r.__data__;if(!cKe||o.length{var pKe=gI(),hKe=$Z(),gKe=t$(),dKe=n$(),mKe=s$(),yKe=lee();function Im(t){var e=this.__data__=new pKe(t);this.size=e.size}Im.prototype.clear=hKe;Im.prototype.delete=gKe;Im.prototype.get=dKe;Im.prototype.has=mKe;Im.prototype.set=yKe;cee.exports=Im});var Aee=_((XFt,uee)=>{var EKe="__lodash_hash_undefined__";function CKe(t){return this.__data__.set(t,EKe),this}uee.exports=CKe});var pee=_((ZFt,fee)=>{function wKe(t){return this.__data__.has(t)}fee.exports=wKe});var gee=_(($Ft,hee)=>{var IKe=PP(),BKe=Aee(),vKe=pee();function SP(t){var e=-1,r=t==null?0:t.length;for(this.__data__=new IKe;++e{function DKe(t,e){for(var r=-1,o=t==null?0:t.length;++r{function PKe(t,e){return t.has(e)}yee.exports=PKe});var RN=_((rRt,Cee)=>{var bKe=gee(),SKe=mee(),xKe=Eee(),kKe=1,QKe=2;function FKe(t,e,r,o,a,n){var u=r&kKe,A=t.length,p=e.length;if(A!=p&&!(u&&p>A))return!1;var h=n.get(t),E=n.get(e);if(h&&E)return h==e&&E==t;var I=-1,v=!0,x=r&QKe?new bKe:void 0;for(n.set(t,e),n.set(e,t);++I{var RKe=_l(),TKe=RKe.Uint8Array;wee.exports=TKe});var Bee=_((iRt,Iee)=>{function NKe(t){var e=-1,r=Array(t.size);return t.forEach(function(o,a){r[++e]=[a,o]}),r}Iee.exports=NKe});var Dee=_((sRt,vee)=>{function LKe(t){var e=-1,r=Array(t.size);return t.forEach(function(o){r[++e]=o}),r}vee.exports=LKe});var kee=_((oRt,xee)=>{var Pee=lg(),bee=TN(),MKe=ym(),OKe=RN(),UKe=Bee(),_Ke=Dee(),HKe=1,qKe=2,jKe="[object Boolean]",GKe="[object Date]",YKe="[object Error]",WKe="[object Map]",KKe="[object Number]",VKe="[object RegExp]",zKe="[object Set]",JKe="[object String]",XKe="[object Symbol]",ZKe="[object ArrayBuffer]",$Ke="[object DataView]",See=Pee?Pee.prototype:void 0,NN=See?See.valueOf:void 0;function eVe(t,e,r,o,a,n,u){switch(r){case $Ke:if(t.byteLength!=e.byteLength||t.byteOffset!=e.byteOffset)return!1;t=t.buffer,e=e.buffer;case ZKe:return!(t.byteLength!=e.byteLength||!n(new bee(t),new bee(e)));case jKe:case GKe:case KKe:return MKe(+t,+e);case YKe:return t.name==e.name&&t.message==e.message;case VKe:case JKe:return t==e+"";case WKe:var A=UKe;case zKe:var p=o&HKe;if(A||(A=_Ke),t.size!=e.size&&!p)return!1;var h=u.get(t);if(h)return h==e;o|=qKe,u.set(t,e);var E=OKe(A(t),A(e),o,a,n,u);return u.delete(t),E;case XKe:if(NN)return NN.call(t)==NN.call(e)}return!1}xee.exports=eVe});var xP=_((aRt,Qee)=>{function tVe(t,e){for(var r=-1,o=e.length,a=t.length;++r{var rVe=Array.isArray;Fee.exports=rVe});var LN=_((cRt,Ree)=>{var nVe=xP(),iVe=Hl();function sVe(t,e,r){var o=e(t);return iVe(t)?o:nVe(o,r(t))}Ree.exports=sVe});var Nee=_((uRt,Tee)=>{function oVe(t,e){for(var r=-1,o=t==null?0:t.length,a=0,n=[];++r{function aVe(){return[]}Lee.exports=aVe});var kP=_((fRt,Oee)=>{var lVe=Nee(),cVe=MN(),uVe=Object.prototype,AVe=uVe.propertyIsEnumerable,Mee=Object.getOwnPropertySymbols,fVe=Mee?function(t){return t==null?[]:(t=Object(t),lVe(Mee(t),function(e){return AVe.call(t,e)}))}:cVe;Oee.exports=fVe});var _ee=_((pRt,Uee)=>{function pVe(t,e){for(var r=-1,o=Array(t);++r{function hVe(t){return t!=null&&typeof t=="object"}Hee.exports=hVe});var jee=_((gRt,qee)=>{var gVe=cg(),dVe=Ju(),mVe="[object Arguments]";function yVe(t){return dVe(t)&&gVe(t)==mVe}qee.exports=yVe});var EI=_((dRt,Wee)=>{var Gee=jee(),EVe=Ju(),Yee=Object.prototype,CVe=Yee.hasOwnProperty,wVe=Yee.propertyIsEnumerable,IVe=Gee(function(){return arguments}())?Gee:function(t){return EVe(t)&&CVe.call(t,"callee")&&!wVe.call(t,"callee")};Wee.exports=IVe});var Vee=_((mRt,Kee)=>{function BVe(){return!1}Kee.exports=BVe});var wI=_((CI,Bm)=>{var vVe=_l(),DVe=Vee(),Xee=typeof CI=="object"&&CI&&!CI.nodeType&&CI,zee=Xee&&typeof Bm=="object"&&Bm&&!Bm.nodeType&&Bm,PVe=zee&&zee.exports===Xee,Jee=PVe?vVe.Buffer:void 0,bVe=Jee?Jee.isBuffer:void 0,SVe=bVe||DVe;Bm.exports=SVe});var II=_((yRt,Zee)=>{var xVe=9007199254740991,kVe=/^(?:0|[1-9]\d*)$/;function QVe(t,e){var r=typeof t;return e=e??xVe,!!e&&(r=="number"||r!="symbol"&&kVe.test(t))&&t>-1&&t%1==0&&t{var FVe=9007199254740991;function RVe(t){return typeof t=="number"&&t>-1&&t%1==0&&t<=FVe}$ee.exports=RVe});var tte=_((CRt,ete)=>{var TVe=cg(),NVe=QP(),LVe=Ju(),MVe="[object Arguments]",OVe="[object Array]",UVe="[object Boolean]",_Ve="[object Date]",HVe="[object Error]",qVe="[object Function]",jVe="[object Map]",GVe="[object Number]",YVe="[object Object]",WVe="[object RegExp]",KVe="[object Set]",VVe="[object String]",zVe="[object WeakMap]",JVe="[object ArrayBuffer]",XVe="[object DataView]",ZVe="[object Float32Array]",$Ve="[object Float64Array]",eze="[object Int8Array]",tze="[object Int16Array]",rze="[object Int32Array]",nze="[object Uint8Array]",ize="[object Uint8ClampedArray]",sze="[object Uint16Array]",oze="[object Uint32Array]",ui={};ui[ZVe]=ui[$Ve]=ui[eze]=ui[tze]=ui[rze]=ui[nze]=ui[ize]=ui[sze]=ui[oze]=!0;ui[MVe]=ui[OVe]=ui[JVe]=ui[UVe]=ui[XVe]=ui[_Ve]=ui[HVe]=ui[qVe]=ui[jVe]=ui[GVe]=ui[YVe]=ui[WVe]=ui[KVe]=ui[VVe]=ui[zVe]=!1;function aze(t){return LVe(t)&&NVe(t.length)&&!!ui[TVe(t)]}ete.exports=aze});var FP=_((wRt,rte)=>{function lze(t){return function(e){return t(e)}}rte.exports=lze});var RP=_((BI,vm)=>{var cze=kN(),nte=typeof BI=="object"&&BI&&!BI.nodeType&&BI,vI=nte&&typeof vm=="object"&&vm&&!vm.nodeType&&vm,uze=vI&&vI.exports===nte,ON=uze&&cze.process,Aze=function(){try{var t=vI&&vI.require&&vI.require("util").types;return t||ON&&ON.binding&&ON.binding("util")}catch{}}();vm.exports=Aze});var TP=_((IRt,ote)=>{var fze=tte(),pze=FP(),ite=RP(),ste=ite&&ite.isTypedArray,hze=ste?pze(ste):fze;ote.exports=hze});var UN=_((BRt,ate)=>{var gze=_ee(),dze=EI(),mze=Hl(),yze=wI(),Eze=II(),Cze=TP(),wze=Object.prototype,Ize=wze.hasOwnProperty;function Bze(t,e){var r=mze(t),o=!r&&dze(t),a=!r&&!o&&yze(t),n=!r&&!o&&!a&&Cze(t),u=r||o||a||n,A=u?gze(t.length,String):[],p=A.length;for(var h in t)(e||Ize.call(t,h))&&!(u&&(h=="length"||a&&(h=="offset"||h=="parent")||n&&(h=="buffer"||h=="byteLength"||h=="byteOffset")||Eze(h,p)))&&A.push(h);return A}ate.exports=Bze});var NP=_((vRt,lte)=>{var vze=Object.prototype;function Dze(t){var e=t&&t.constructor,r=typeof e=="function"&&e.prototype||vze;return t===r}lte.exports=Dze});var _N=_((DRt,cte)=>{function Pze(t,e){return function(r){return t(e(r))}}cte.exports=Pze});var Ate=_((PRt,ute)=>{var bze=_N(),Sze=bze(Object.keys,Object);ute.exports=Sze});var pte=_((bRt,fte)=>{var xze=NP(),kze=Ate(),Qze=Object.prototype,Fze=Qze.hasOwnProperty;function Rze(t){if(!xze(t))return kze(t);var e=[];for(var r in Object(t))Fze.call(t,r)&&r!="constructor"&&e.push(r);return e}fte.exports=Rze});var DI=_((SRt,hte)=>{var Tze=vP(),Nze=QP();function Lze(t){return t!=null&&Nze(t.length)&&!Tze(t)}hte.exports=Lze});var LP=_((xRt,gte)=>{var Mze=UN(),Oze=pte(),Uze=DI();function _ze(t){return Uze(t)?Mze(t):Oze(t)}gte.exports=_ze});var HN=_((kRt,dte)=>{var Hze=LN(),qze=kP(),jze=LP();function Gze(t){return Hze(t,jze,qze)}dte.exports=Gze});var Ete=_((QRt,yte)=>{var mte=HN(),Yze=1,Wze=Object.prototype,Kze=Wze.hasOwnProperty;function Vze(t,e,r,o,a,n){var u=r&Yze,A=mte(t),p=A.length,h=mte(e),E=h.length;if(p!=E&&!u)return!1;for(var I=p;I--;){var v=A[I];if(!(u?v in e:Kze.call(e,v)))return!1}var x=n.get(t),C=n.get(e);if(x&&C)return x==e&&C==t;var R=!0;n.set(t,e),n.set(e,t);for(var L=u;++I{var zze=Kp(),Jze=_l(),Xze=zze(Jze,"DataView");Cte.exports=Xze});var Bte=_((RRt,Ite)=>{var Zze=Kp(),$ze=_l(),eJe=Zze($ze,"Promise");Ite.exports=eJe});var Dte=_((TRt,vte)=>{var tJe=Kp(),rJe=_l(),nJe=tJe(rJe,"Set");vte.exports=nJe});var bte=_((NRt,Pte)=>{var iJe=Kp(),sJe=_l(),oJe=iJe(sJe,"WeakMap");Pte.exports=oJe});var PI=_((LRt,Tte)=>{var qN=wte(),jN=DP(),GN=Bte(),YN=Dte(),WN=bte(),Rte=cg(),Dm=FN(),Ste="[object Map]",aJe="[object Object]",xte="[object Promise]",kte="[object Set]",Qte="[object WeakMap]",Fte="[object DataView]",lJe=Dm(qN),cJe=Dm(jN),uJe=Dm(GN),AJe=Dm(YN),fJe=Dm(WN),ug=Rte;(qN&&ug(new qN(new ArrayBuffer(1)))!=Fte||jN&&ug(new jN)!=Ste||GN&&ug(GN.resolve())!=xte||YN&&ug(new YN)!=kte||WN&&ug(new WN)!=Qte)&&(ug=function(t){var e=Rte(t),r=e==aJe?t.constructor:void 0,o=r?Dm(r):"";if(o)switch(o){case lJe:return Fte;case cJe:return Ste;case uJe:return xte;case AJe:return kte;case fJe:return Qte}return e});Tte.exports=ug});var qte=_((MRt,Hte)=>{var KN=bP(),pJe=RN(),hJe=kee(),gJe=Ete(),Nte=PI(),Lte=Hl(),Mte=wI(),dJe=TP(),mJe=1,Ote="[object Arguments]",Ute="[object Array]",MP="[object Object]",yJe=Object.prototype,_te=yJe.hasOwnProperty;function EJe(t,e,r,o,a,n){var u=Lte(t),A=Lte(e),p=u?Ute:Nte(t),h=A?Ute:Nte(e);p=p==Ote?MP:p,h=h==Ote?MP:h;var E=p==MP,I=h==MP,v=p==h;if(v&&Mte(t)){if(!Mte(e))return!1;u=!0,E=!1}if(v&&!E)return n||(n=new KN),u||dJe(t)?pJe(t,e,r,o,a,n):hJe(t,e,p,r,o,a,n);if(!(r&mJe)){var x=E&&_te.call(t,"__wrapped__"),C=I&&_te.call(e,"__wrapped__");if(x||C){var R=x?t.value():t,L=C?e.value():e;return n||(n=new KN),a(R,L,r,o,n)}}return v?(n||(n=new KN),gJe(t,e,r,o,a,n)):!1}Hte.exports=EJe});var Wte=_((ORt,Yte)=>{var CJe=qte(),jte=Ju();function Gte(t,e,r,o,a){return t===e?!0:t==null||e==null||!jte(t)&&!jte(e)?t!==t&&e!==e:CJe(t,e,r,o,Gte,a)}Yte.exports=Gte});var Vte=_((URt,Kte)=>{var wJe=Wte();function IJe(t,e){return wJe(t,e)}Kte.exports=IJe});var VN=_((_Rt,zte)=>{var BJe=Kp(),vJe=function(){try{var t=BJe(Object,"defineProperty");return t({},"",{}),t}catch{}}();zte.exports=vJe});var OP=_((HRt,Xte)=>{var Jte=VN();function DJe(t,e,r){e=="__proto__"&&Jte?Jte(t,e,{configurable:!0,enumerable:!0,value:r,writable:!0}):t[e]=r}Xte.exports=DJe});var zN=_((qRt,Zte)=>{var PJe=OP(),bJe=ym();function SJe(t,e,r){(r!==void 0&&!bJe(t[e],r)||r===void 0&&!(e in t))&&PJe(t,e,r)}Zte.exports=SJe});var ere=_((jRt,$te)=>{function xJe(t){return function(e,r,o){for(var a=-1,n=Object(e),u=o(e),A=u.length;A--;){var p=u[t?A:++a];if(r(n[p],p,n)===!1)break}return e}}$te.exports=xJe});var rre=_((GRt,tre)=>{var kJe=ere(),QJe=kJe();tre.exports=QJe});var JN=_((bI,Pm)=>{var FJe=_l(),ore=typeof bI=="object"&&bI&&!bI.nodeType&&bI,nre=ore&&typeof Pm=="object"&&Pm&&!Pm.nodeType&&Pm,RJe=nre&&nre.exports===ore,ire=RJe?FJe.Buffer:void 0,sre=ire?ire.allocUnsafe:void 0;function TJe(t,e){if(e)return t.slice();var r=t.length,o=sre?sre(r):new t.constructor(r);return t.copy(o),o}Pm.exports=TJe});var UP=_((YRt,lre)=>{var are=TN();function NJe(t){var e=new t.constructor(t.byteLength);return new are(e).set(new are(t)),e}lre.exports=NJe});var XN=_((WRt,cre)=>{var LJe=UP();function MJe(t,e){var r=e?LJe(t.buffer):t.buffer;return new t.constructor(r,t.byteOffset,t.length)}cre.exports=MJe});var _P=_((KRt,ure)=>{function OJe(t,e){var r=-1,o=t.length;for(e||(e=Array(o));++r{var UJe=sl(),Are=Object.create,_Je=function(){function t(){}return function(e){if(!UJe(e))return{};if(Are)return Are(e);t.prototype=e;var r=new t;return t.prototype=void 0,r}}();fre.exports=_Je});var HP=_((zRt,hre)=>{var HJe=_N(),qJe=HJe(Object.getPrototypeOf,Object);hre.exports=qJe});var ZN=_((JRt,gre)=>{var jJe=pre(),GJe=HP(),YJe=NP();function WJe(t){return typeof t.constructor=="function"&&!YJe(t)?jJe(GJe(t)):{}}gre.exports=WJe});var mre=_((XRt,dre)=>{var KJe=DI(),VJe=Ju();function zJe(t){return VJe(t)&&KJe(t)}dre.exports=zJe});var $N=_((ZRt,Ere)=>{var JJe=cg(),XJe=HP(),ZJe=Ju(),$Je="[object Object]",eXe=Function.prototype,tXe=Object.prototype,yre=eXe.toString,rXe=tXe.hasOwnProperty,nXe=yre.call(Object);function iXe(t){if(!ZJe(t)||JJe(t)!=$Je)return!1;var e=XJe(t);if(e===null)return!0;var r=rXe.call(e,"constructor")&&e.constructor;return typeof r=="function"&&r instanceof r&&yre.call(r)==nXe}Ere.exports=iXe});var eL=_(($Rt,Cre)=>{function sXe(t,e){if(!(e==="constructor"&&typeof t[e]=="function")&&e!="__proto__")return t[e]}Cre.exports=sXe});var qP=_((eTt,wre)=>{var oXe=OP(),aXe=ym(),lXe=Object.prototype,cXe=lXe.hasOwnProperty;function uXe(t,e,r){var o=t[e];(!(cXe.call(t,e)&&aXe(o,r))||r===void 0&&!(e in t))&&oXe(t,e,r)}wre.exports=uXe});var Ag=_((tTt,Ire)=>{var AXe=qP(),fXe=OP();function pXe(t,e,r,o){var a=!r;r||(r={});for(var n=-1,u=e.length;++n{function hXe(t){var e=[];if(t!=null)for(var r in Object(t))e.push(r);return e}Bre.exports=hXe});var Pre=_((nTt,Dre)=>{var gXe=sl(),dXe=NP(),mXe=vre(),yXe=Object.prototype,EXe=yXe.hasOwnProperty;function CXe(t){if(!gXe(t))return mXe(t);var e=dXe(t),r=[];for(var o in t)o=="constructor"&&(e||!EXe.call(t,o))||r.push(o);return r}Dre.exports=CXe});var bm=_((iTt,bre)=>{var wXe=UN(),IXe=Pre(),BXe=DI();function vXe(t){return BXe(t)?wXe(t,!0):IXe(t)}bre.exports=vXe});var xre=_((sTt,Sre)=>{var DXe=Ag(),PXe=bm();function bXe(t){return DXe(t,PXe(t))}Sre.exports=bXe});var Nre=_((oTt,Tre)=>{var kre=zN(),SXe=JN(),xXe=XN(),kXe=_P(),QXe=ZN(),Qre=EI(),Fre=Hl(),FXe=mre(),RXe=wI(),TXe=vP(),NXe=sl(),LXe=$N(),MXe=TP(),Rre=eL(),OXe=xre();function UXe(t,e,r,o,a,n,u){var A=Rre(t,r),p=Rre(e,r),h=u.get(p);if(h){kre(t,r,h);return}var E=n?n(A,p,r+"",t,e,u):void 0,I=E===void 0;if(I){var v=Fre(p),x=!v&&RXe(p),C=!v&&!x&&MXe(p);E=p,v||x||C?Fre(A)?E=A:FXe(A)?E=kXe(A):x?(I=!1,E=SXe(p,!0)):C?(I=!1,E=xXe(p,!0)):E=[]:LXe(p)||Qre(p)?(E=A,Qre(A)?E=OXe(A):(!NXe(A)||TXe(A))&&(E=QXe(p))):I=!1}I&&(u.set(p,E),a(E,p,o,n,u),u.delete(p)),kre(t,r,E)}Tre.exports=UXe});var Ore=_((aTt,Mre)=>{var _Xe=bP(),HXe=zN(),qXe=rre(),jXe=Nre(),GXe=sl(),YXe=bm(),WXe=eL();function Lre(t,e,r,o,a){t!==e&&qXe(e,function(n,u){if(a||(a=new _Xe),GXe(n))jXe(t,e,u,r,Lre,o,a);else{var A=o?o(WXe(t,u),n,u+"",t,e,a):void 0;A===void 0&&(A=n),HXe(t,u,A)}},YXe)}Mre.exports=Lre});var tL=_((lTt,Ure)=>{function KXe(t){return t}Ure.exports=KXe});var Hre=_((cTt,_re)=>{function VXe(t,e,r){switch(r.length){case 0:return t.call(e);case 1:return t.call(e,r[0]);case 2:return t.call(e,r[0],r[1]);case 3:return t.call(e,r[0],r[1],r[2])}return t.apply(e,r)}_re.exports=VXe});var rL=_((uTt,jre)=>{var zXe=Hre(),qre=Math.max;function JXe(t,e,r){return e=qre(e===void 0?t.length-1:e,0),function(){for(var o=arguments,a=-1,n=qre(o.length-e,0),u=Array(n);++a{function XXe(t){return function(){return t}}Gre.exports=XXe});var Vre=_((fTt,Kre)=>{var ZXe=Yre(),Wre=VN(),$Xe=tL(),eZe=Wre?function(t,e){return Wre(t,"toString",{configurable:!0,enumerable:!1,value:ZXe(e),writable:!0})}:$Xe;Kre.exports=eZe});var Jre=_((pTt,zre)=>{var tZe=800,rZe=16,nZe=Date.now;function iZe(t){var e=0,r=0;return function(){var o=nZe(),a=rZe-(o-r);if(r=o,a>0){if(++e>=tZe)return arguments[0]}else e=0;return t.apply(void 0,arguments)}}zre.exports=iZe});var nL=_((hTt,Xre)=>{var sZe=Vre(),oZe=Jre(),aZe=oZe(sZe);Xre.exports=aZe});var $re=_((gTt,Zre)=>{var lZe=tL(),cZe=rL(),uZe=nL();function AZe(t,e){return uZe(cZe(t,e,lZe),t+"")}Zre.exports=AZe});var tne=_((dTt,ene)=>{var fZe=ym(),pZe=DI(),hZe=II(),gZe=sl();function dZe(t,e,r){if(!gZe(r))return!1;var o=typeof e;return(o=="number"?pZe(r)&&hZe(e,r.length):o=="string"&&e in r)?fZe(r[e],t):!1}ene.exports=dZe});var nne=_((mTt,rne)=>{var mZe=$re(),yZe=tne();function EZe(t){return mZe(function(e,r){var o=-1,a=r.length,n=a>1?r[a-1]:void 0,u=a>2?r[2]:void 0;for(n=t.length>3&&typeof n=="function"?(a--,n):void 0,u&&yZe(r[0],r[1],u)&&(n=a<3?void 0:n,a=1),e=Object(e);++o{var CZe=Ore(),wZe=nne(),IZe=wZe(function(t,e,r,o){CZe(t,e,r,o)});ine.exports=IZe});var He={};Vt(He,{AsyncActions:()=>oL,BufferStream:()=>sL,CachingStrategy:()=>mne,DefaultStream:()=>aL,allSettledSafe:()=>_c,assertNever:()=>cL,bufferStream:()=>km,buildIgnorePattern:()=>xZe,convertMapsToIndexableObjects:()=>GP,dynamicRequire:()=>vf,escapeRegExp:()=>vZe,getArrayWithDefault:()=>xI,getFactoryWithDefault:()=>al,getMapWithDefault:()=>kI,getSetWithDefault:()=>Sm,groupBy:()=>FZe,isIndexableObject:()=>iL,isPathLike:()=>kZe,isTaggedYarnVersion:()=>BZe,makeDeferred:()=>hne,mapAndFilter:()=>ol,mapAndFind:()=>Vp,mergeIntoTarget:()=>Ene,overrideType:()=>DZe,parseBoolean:()=>QI,parseInt:()=>Qm,parseOptionalBoolean:()=>yne,plural:()=>jP,prettifyAsyncErrors:()=>xm,prettifySyncErrors:()=>uL,releaseAfterUseAsync:()=>bZe,replaceEnvVariables:()=>YP,sortMap:()=>Fs,toMerged:()=>QZe,tryParseOptionalBoolean:()=>AL,validateEnum:()=>PZe});function BZe(t){return!!(Ane.default.valid(t)&&t.match(/^[^-]+(-rc\.[0-9]+)?$/))}function jP(t,{one:e,more:r,zero:o=r}){return t===0?o:t===1?e:r}function vZe(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function DZe(t){}function cL(t){throw new Error(`Assertion failed: Unexpected object '${t}'`)}function PZe(t,e){let r=Object.values(t);if(!r.includes(e))throw new st(`Invalid value for enumeration: ${JSON.stringify(e)} (expected one of ${r.map(o=>JSON.stringify(o)).join(", ")})`);return e}function ol(t,e){let r=[];for(let o of t){let a=e(o);a!==fne&&r.push(a)}return r}function Vp(t,e){for(let r of t){let o=e(r);if(o!==pne)return o}}function iL(t){return typeof t=="object"&&t!==null}async function _c(t){let e=await Promise.allSettled(t),r=[];for(let o of e){if(o.status==="rejected")throw o.reason;r.push(o.value)}return r}function GP(t){if(t instanceof Map&&(t=Object.fromEntries(t)),iL(t))for(let e of Object.keys(t)){let r=t[e];iL(r)&&(t[e]=GP(r))}return t}function al(t,e,r){let o=t.get(e);return typeof o>"u"&&t.set(e,o=r()),o}function xI(t,e){let r=t.get(e);return typeof r>"u"&&t.set(e,r=[]),r}function Sm(t,e){let r=t.get(e);return typeof r>"u"&&t.set(e,r=new Set),r}function kI(t,e){let r=t.get(e);return typeof r>"u"&&t.set(e,r=new Map),r}async function bZe(t,e){if(e==null)return await t();try{return await t()}finally{await e()}}async function xm(t,e){try{return await t()}catch(r){throw r.message=e(r.message),r}}function uL(t,e){try{return t()}catch(r){throw r.message=e(r.message),r}}async function km(t){return await new Promise((e,r)=>{let o=[];t.on("error",a=>{r(a)}),t.on("data",a=>{o.push(a)}),t.on("end",()=>{e(Buffer.concat(o))})})}function hne(){let t,e;return{promise:new Promise((o,a)=>{t=o,e=a}),resolve:t,reject:e}}function gne(t){return SI(ue.fromPortablePath(t))}function dne(path){let physicalPath=ue.fromPortablePath(path),currentCacheEntry=SI.cache[physicalPath];delete SI.cache[physicalPath];let result;try{result=gne(physicalPath);let freshCacheEntry=SI.cache[physicalPath],dynamicModule=eval("module"),freshCacheIndex=dynamicModule.children.indexOf(freshCacheEntry);freshCacheIndex!==-1&&dynamicModule.children.splice(freshCacheIndex,1)}finally{SI.cache[physicalPath]=currentCacheEntry}return result}function SZe(t){let e=one.get(t),r=oe.statSync(t);if(e?.mtime===r.mtimeMs)return e.instance;let o=dne(t);return one.set(t,{mtime:r.mtimeMs,instance:o}),o}function vf(t,{cachingStrategy:e=2}={}){switch(e){case 0:return dne(t);case 1:return SZe(t);case 2:return gne(t);default:throw new Error("Unsupported caching strategy")}}function Fs(t,e){let r=Array.from(t);Array.isArray(e)||(e=[e]);let o=[];for(let n of e)o.push(r.map(u=>n(u)));let a=r.map((n,u)=>u);return a.sort((n,u)=>{for(let A of o){let p=A[n]A[u]?1:0;if(p!==0)return p}return 0}),a.map(n=>r[n])}function xZe(t){return t.length===0?null:t.map(e=>`(${cne.default.makeRe(e,{windows:!1,dot:!0}).source})`).join("|")}function YP(t,{env:e}){let r=/\${(?[\d\w_]+)(?:)?(?:-(?[^}]*))?}/g;return t.replace(r,(...o)=>{let{variableName:a,colon:n,fallback:u}=o[o.length-1],A=Object.hasOwn(e,a),p=e[a];if(p||A&&!n)return p;if(u!=null)return u;throw new st(`Environment variable not found (${a})`)})}function QI(t){switch(t){case"true":case"1":case 1:case!0:return!0;case"false":case"0":case 0:case!1:return!1;default:throw new Error(`Couldn't parse "${t}" as a boolean`)}}function yne(t){return typeof t>"u"?t:QI(t)}function AL(t){try{return yne(t)}catch{return null}}function kZe(t){return!!(ue.isAbsolute(t)||t.match(/^(\.{1,2}|~)\//))}function Ene(t,...e){let r=u=>({value:u}),o=r(t),a=e.map(u=>r(u)),{value:n}=(0,lne.default)(o,...a,(u,A)=>{if(Array.isArray(u)&&Array.isArray(A)){for(let p of A)u.find(h=>(0,ane.default)(h,p))||u.push(p);return u}});return n}function QZe(...t){return Ene({},...t)}function FZe(t,e){let r=Object.create(null);for(let o of t){let a=o[e];r[a]??=[],r[a].push(o)}return r}function Qm(t){return typeof t=="string"?Number.parseInt(t,10):t}var ane,lne,cne,une,Ane,lL,fne,pne,sL,oL,aL,SI,one,mne,ql=Et(()=>{Pt();qt();ane=Ze(Vte()),lne=Ze(sne()),cne=Ze($o()),une=Ze(eg()),Ane=Ze(Jn()),lL=ve("stream");fne=Symbol();ol.skip=fne;pne=Symbol();Vp.skip=pne;sL=class extends lL.Transform{constructor(){super(...arguments);this.chunks=[]}_transform(r,o,a){if(o!=="buffer"||!Buffer.isBuffer(r))throw new Error("Assertion failed: BufferStream only accept buffers");this.chunks.push(r),a(null,null)}_flush(r){r(null,Buffer.concat(this.chunks))}};oL=class{constructor(e){this.deferred=new Map;this.promises=new Map;this.limit=(0,une.default)(e)}set(e,r){let o=this.deferred.get(e);typeof o>"u"&&this.deferred.set(e,o=hne());let a=this.limit(()=>r());return this.promises.set(e,a),a.then(()=>{this.promises.get(e)===a&&o.resolve()},n=>{this.promises.get(e)===a&&o.reject(n)}),o.promise}reduce(e,r){let o=this.promises.get(e)??Promise.resolve();this.set(e,()=>r(o))}async wait(){await Promise.all(this.promises.values())}},aL=class extends lL.Transform{constructor(r=Buffer.alloc(0)){super();this.active=!0;this.ifEmpty=r}_transform(r,o,a){if(o!=="buffer"||!Buffer.isBuffer(r))throw new Error("Assertion failed: DefaultStream only accept buffers");this.active=!1,a(null,r)}_flush(r){this.active&&this.ifEmpty.length>0?r(null,this.ifEmpty):r(null)}},SI=eval("require");one=new Map;mne=(o=>(o[o.NoCache=0]="NoCache",o[o.FsTime=1]="FsTime",o[o.Node=2]="Node",o))(mne||{})});var Fm,fL,pL,Cne=Et(()=>{Fm=(r=>(r.HARD="HARD",r.SOFT="SOFT",r))(Fm||{}),fL=(o=>(o.Dependency="Dependency",o.PeerDependency="PeerDependency",o.PeerDependencyMeta="PeerDependencyMeta",o))(fL||{}),pL=(o=>(o.Inactive="inactive",o.Redundant="redundant",o.Active="active",o))(pL||{})});var pe={};Vt(pe,{LogLevel:()=>JP,Style:()=>KP,Type:()=>yt,addLogFilterSupport:()=>TI,applyColor:()=>Xs,applyHyperlink:()=>Tm,applyStyle:()=>fg,json:()=>pg,jsonOrPretty:()=>NZe,mark:()=>yL,pretty:()=>Ot,prettyField:()=>Xu,prettyList:()=>mL,prettyTruncatedLocatorList:()=>zP,stripAnsi:()=>Rm.default,supportsColor:()=>VP,supportsHyperlinks:()=>dL,tuple:()=>Hc});function wne(t){let e=["KiB","MiB","GiB","TiB"],r=e.length;for(;r>1&&t<1024**r;)r-=1;let o=1024**r;return`${Math.floor(t*100/o)/100} ${e[r-1]}`}function Hc(t,e){return[e,t]}function fg(t,e,r){return t.get("enableColors")&&r&2&&(e=RI.default.bold(e)),e}function Xs(t,e,r){if(!t.get("enableColors"))return e;let o=RZe.get(r);if(o===null)return e;let a=typeof o>"u"?r:gL.level>=3?o[0]:o[1],n=typeof a=="number"?hL.ansi256(a):a.startsWith("#")?hL.hex(a):hL[a];if(typeof n!="function")throw new Error(`Invalid format type ${a}`);return n(e)}function Tm(t,e,r){return t.get("enableHyperlinks")?TZe?`\x1B]8;;${r}\x1B\\${e}\x1B]8;;\x1B\\`:`\x1B]8;;${r}\x07${e}\x1B]8;;\x07`:e}function Ot(t,e,r){if(e===null)return Xs(t,"null",yt.NULL);if(Object.hasOwn(WP,r))return WP[r].pretty(t,e);if(typeof e!="string")throw new Error(`Assertion failed: Expected the value to be a string, got ${typeof e}`);return Xs(t,e,r)}function mL(t,e,r,{separator:o=", "}={}){return[...e].map(a=>Ot(t,a,r)).join(o)}function pg(t,e){if(t===null)return null;if(Object.hasOwn(WP,e))return WP[e].json(t);if(typeof t!="string")throw new Error(`Assertion failed: Expected the value to be a string, got ${typeof t}`);return t}function NZe(t,e,[r,o]){return t?pg(r,o):Ot(e,r,o)}function yL(t){return{Check:Xs(t,"\u2713","green"),Cross:Xs(t,"\u2718","red"),Question:Xs(t,"?","cyan")}}function Xu(t,{label:e,value:[r,o]}){return`${Ot(t,e,yt.CODE)}: ${Ot(t,r,o)}`}function zP(t,e,r){let o=[],a=[...e],n=r;for(;a.length>0;){let h=a[0],E=`${qr(t,h)}, `,I=EL(h).length+2;if(o.length>0&&nh).join("").slice(0,-2);let u="X".repeat(a.length.toString().length),A=`and ${u} more.`,p=a.length;for(;o.length>1&&nh).join(""),A.replace(u,Ot(t,p,yt.NUMBER))].join("")}function TI(t,{configuration:e}){let r=e.get("logFilters"),o=new Map,a=new Map,n=[];for(let I of r){let v=I.get("level");if(typeof v>"u")continue;let x=I.get("code");typeof x<"u"&&o.set(x,v);let C=I.get("text");typeof C<"u"&&a.set(C,v);let R=I.get("pattern");typeof R<"u"&&n.push([Ine.default.matcher(R,{contains:!0}),v])}n.reverse();let u=(I,v,x)=>{if(I===null||I===0)return x;let C=a.size>0||n.length>0?(0,Rm.default)(v):v;if(a.size>0){let R=a.get(C);if(typeof R<"u")return R??x}if(n.length>0){for(let[R,L]of n)if(R(C))return L??x}if(o.size>0){let R=o.get(Ku(I));if(typeof R<"u")return R??x}return x},A=t.reportInfo,p=t.reportWarning,h=t.reportError,E=function(I,v,x,C){switch(u(v,x,C)){case"info":A.call(I,v,x);break;case"warning":p.call(I,v??0,x);break;case"error":h.call(I,v??0,x);break}};t.reportInfo=function(...I){return E(this,...I,"info")},t.reportWarning=function(...I){return E(this,...I,"warning")},t.reportError=function(...I){return E(this,...I,"error")}}var RI,FI,Ine,Rm,Bne,yt,KP,gL,VP,dL,hL,RZe,bo,WP,TZe,JP,jl=Et(()=>{Pt();RI=Ze(pN()),FI=Ze(X0());qt();Ine=Ze($o()),Rm=Ze(BP()),Bne=ve("util");$D();So();yt={NO_HINT:"NO_HINT",ID:"ID",NULL:"NULL",SCOPE:"SCOPE",NAME:"NAME",RANGE:"RANGE",REFERENCE:"REFERENCE",NUMBER:"NUMBER",PATH:"PATH",URL:"URL",ADDED:"ADDED",REMOVED:"REMOVED",CODE:"CODE",INSPECT:"INSPECT",DURATION:"DURATION",SIZE:"SIZE",SIZE_DIFF:"SIZE_DIFF",IDENT:"IDENT",DESCRIPTOR:"DESCRIPTOR",LOCATOR:"LOCATOR",RESOLUTION:"RESOLUTION",DEPENDENT:"DEPENDENT",PACKAGE_EXTENSION:"PACKAGE_EXTENSION",SETTING:"SETTING",MARKDOWN:"MARKDOWN",MARKDOWN_INLINE:"MARKDOWN_INLINE"},KP=(e=>(e[e.BOLD=2]="BOLD",e))(KP||{}),gL=FI.default.GITHUB_ACTIONS?{level:2}:RI.default.supportsColor?{level:RI.default.supportsColor.level}:{level:0},VP=gL.level!==0,dL=VP&&!FI.default.GITHUB_ACTIONS&&!FI.default.CIRCLE&&!FI.default.GITLAB,hL=new RI.default.Instance(gL),RZe=new Map([[yt.NO_HINT,null],[yt.NULL,["#a853b5",129]],[yt.SCOPE,["#d75f00",166]],[yt.NAME,["#d7875f",173]],[yt.RANGE,["#00afaf",37]],[yt.REFERENCE,["#87afff",111]],[yt.NUMBER,["#ffd700",220]],[yt.PATH,["#d75fd7",170]],[yt.URL,["#d75fd7",170]],[yt.ADDED,["#5faf00",70]],[yt.REMOVED,["#ff3131",160]],[yt.CODE,["#87afff",111]],[yt.SIZE,["#ffd700",220]]]),bo=t=>t;WP={[yt.ID]:bo({pretty:(t,e)=>typeof e=="number"?Xs(t,`${e}`,yt.NUMBER):Xs(t,e,yt.CODE),json:t=>t}),[yt.INSPECT]:bo({pretty:(t,e)=>(0,Bne.inspect)(e,{depth:1/0,colors:t.get("enableColors"),compact:!0,breakLength:1/0}),json:t=>t}),[yt.NUMBER]:bo({pretty:(t,e)=>Xs(t,`${e}`,yt.NUMBER),json:t=>t}),[yt.IDENT]:bo({pretty:(t,e)=>Oi(t,e),json:t=>rn(t)}),[yt.LOCATOR]:bo({pretty:(t,e)=>qr(t,e),json:t=>ka(t)}),[yt.DESCRIPTOR]:bo({pretty:(t,e)=>jn(t,e),json:t=>xa(t)}),[yt.RESOLUTION]:bo({pretty:(t,{descriptor:e,locator:r})=>NI(t,e,r),json:({descriptor:t,locator:e})=>({descriptor:xa(t),locator:e!==null?ka(e):null})}),[yt.DEPENDENT]:bo({pretty:(t,{locator:e,descriptor:r})=>CL(t,e,r),json:({locator:t,descriptor:e})=>({locator:ka(t),descriptor:xa(e)})}),[yt.PACKAGE_EXTENSION]:bo({pretty:(t,e)=>{switch(e.type){case"Dependency":return`${Oi(t,e.parentDescriptor)} \u27A4 ${Xs(t,"dependencies",yt.CODE)} \u27A4 ${Oi(t,e.descriptor)}`;case"PeerDependency":return`${Oi(t,e.parentDescriptor)} \u27A4 ${Xs(t,"peerDependencies",yt.CODE)} \u27A4 ${Oi(t,e.descriptor)}`;case"PeerDependencyMeta":return`${Oi(t,e.parentDescriptor)} \u27A4 ${Xs(t,"peerDependenciesMeta",yt.CODE)} \u27A4 ${Oi(t,ea(e.selector))} \u27A4 ${Xs(t,e.key,yt.CODE)}`;default:throw new Error(`Assertion failed: Unsupported package extension type: ${e.type}`)}},json:t=>{switch(t.type){case"Dependency":return`${rn(t.parentDescriptor)} > ${rn(t.descriptor)}`;case"PeerDependency":return`${rn(t.parentDescriptor)} >> ${rn(t.descriptor)}`;case"PeerDependencyMeta":return`${rn(t.parentDescriptor)} >> ${t.selector} / ${t.key}`;default:throw new Error(`Assertion failed: Unsupported package extension type: ${t.type}`)}}}),[yt.SETTING]:bo({pretty:(t,e)=>(t.get(e),Tm(t,Xs(t,e,yt.CODE),`https://yarnpkg.com/configuration/yarnrc#${e}`)),json:t=>t}),[yt.DURATION]:bo({pretty:(t,e)=>{if(e>1e3*60){let r=Math.floor(e/1e3/60),o=Math.ceil((e-r*60*1e3)/1e3);return o===0?`${r}m`:`${r}m ${o}s`}else{let r=Math.floor(e/1e3),o=e-r*1e3;return o===0?`${r}s`:`${r}s ${o}ms`}},json:t=>t}),[yt.SIZE]:bo({pretty:(t,e)=>Xs(t,wne(e),yt.NUMBER),json:t=>t}),[yt.SIZE_DIFF]:bo({pretty:(t,e)=>{let r=e>=0?"+":"-",o=r==="+"?yt.REMOVED:yt.ADDED;return Xs(t,`${r} ${wne(Math.max(Math.abs(e),1))}`,o)},json:t=>t}),[yt.PATH]:bo({pretty:(t,e)=>Xs(t,ue.fromPortablePath(e),yt.PATH),json:t=>ue.fromPortablePath(t)}),[yt.MARKDOWN]:bo({pretty:(t,{text:e,format:r,paragraphs:o})=>Do(e,{format:r,paragraphs:o}),json:({text:t})=>t}),[yt.MARKDOWN_INLINE]:bo({pretty:(t,e)=>(e=e.replace(/(`+)((?:.|[\n])*?)\1/g,(r,o,a)=>Ot(t,o+a+o,yt.CODE)),e=e.replace(/(\*\*)((?:.|[\n])*?)\1/g,(r,o,a)=>fg(t,a,2)),e),json:t=>t})};TZe=!!process.env.KONSOLE_VERSION;JP=(a=>(a.Error="error",a.Warning="warning",a.Info="info",a.Discard="discard",a))(JP||{})});var vne=_(Nm=>{"use strict";Object.defineProperty(Nm,"__esModule",{value:!0});Nm.splitWhen=Nm.flatten=void 0;function LZe(t){return t.reduce((e,r)=>[].concat(e,r),[])}Nm.flatten=LZe;function MZe(t,e){let r=[[]],o=0;for(let a of t)e(a)?(o++,r[o]=[]):r[o].push(a);return r}Nm.splitWhen=MZe});var Dne=_(XP=>{"use strict";Object.defineProperty(XP,"__esModule",{value:!0});XP.isEnoentCodeError=void 0;function OZe(t){return t.code==="ENOENT"}XP.isEnoentCodeError=OZe});var Pne=_(ZP=>{"use strict";Object.defineProperty(ZP,"__esModule",{value:!0});ZP.createDirentFromStats=void 0;var wL=class{constructor(e,r){this.name=e,this.isBlockDevice=r.isBlockDevice.bind(r),this.isCharacterDevice=r.isCharacterDevice.bind(r),this.isDirectory=r.isDirectory.bind(r),this.isFIFO=r.isFIFO.bind(r),this.isFile=r.isFile.bind(r),this.isSocket=r.isSocket.bind(r),this.isSymbolicLink=r.isSymbolicLink.bind(r)}};function UZe(t,e){return new wL(t,e)}ZP.createDirentFromStats=UZe});var kne=_(Vi=>{"use strict";Object.defineProperty(Vi,"__esModule",{value:!0});Vi.convertPosixPathToPattern=Vi.convertWindowsPathToPattern=Vi.convertPathToPattern=Vi.escapePosixPath=Vi.escapeWindowsPath=Vi.escape=Vi.removeLeadingDotSegment=Vi.makeAbsolute=Vi.unixify=void 0;var _Ze=ve("os"),HZe=ve("path"),bne=_Ze.platform()==="win32",qZe=2,jZe=/(\\?)([()*?[\]{|}]|^!|[!+@](?=\()|\\(?![!()*+?@[\]{|}]))/g,GZe=/(\\?)([()[\]{}]|^!|[!+@](?=\())/g,YZe=/^\\\\([.?])/,WZe=/\\(?![!()+@[\]{}])/g;function KZe(t){return t.replace(/\\/g,"/")}Vi.unixify=KZe;function VZe(t,e){return HZe.resolve(t,e)}Vi.makeAbsolute=VZe;function zZe(t){if(t.charAt(0)==="."){let e=t.charAt(1);if(e==="/"||e==="\\")return t.slice(qZe)}return t}Vi.removeLeadingDotSegment=zZe;Vi.escape=bne?IL:BL;function IL(t){return t.replace(GZe,"\\$2")}Vi.escapeWindowsPath=IL;function BL(t){return t.replace(jZe,"\\$2")}Vi.escapePosixPath=BL;Vi.convertPathToPattern=bne?Sne:xne;function Sne(t){return IL(t).replace(YZe,"//$1").replace(WZe,"/")}Vi.convertWindowsPathToPattern=Sne;function xne(t){return BL(t)}Vi.convertPosixPathToPattern=xne});var Fne=_((RTt,Qne)=>{Qne.exports=function(e){if(typeof e!="string"||e==="")return!1;for(var r;r=/(\\).|([@?!+*]\(.*\))/g.exec(e);){if(r[2])return!0;e=e.slice(r.index+r[0].length)}return!1}});var Nne=_((TTt,Tne)=>{var JZe=Fne(),Rne={"{":"}","(":")","[":"]"},XZe=function(t){if(t[0]==="!")return!0;for(var e=0,r=-2,o=-2,a=-2,n=-2,u=-2;ee&&(u===-1||u>o||(u=t.indexOf("\\",e),u===-1||u>o)))||a!==-1&&t[e]==="{"&&t[e+1]!=="}"&&(a=t.indexOf("}",e),a>e&&(u=t.indexOf("\\",e),u===-1||u>a))||n!==-1&&t[e]==="("&&t[e+1]==="?"&&/[:!=]/.test(t[e+2])&&t[e+3]!==")"&&(n=t.indexOf(")",e),n>e&&(u=t.indexOf("\\",e),u===-1||u>n))||r!==-1&&t[e]==="("&&t[e+1]!=="|"&&(rr&&(u=t.indexOf("\\",r),u===-1||u>n))))return!0;if(t[e]==="\\"){var A=t[e+1];e+=2;var p=Rne[A];if(p){var h=t.indexOf(p,e);h!==-1&&(e=h+1)}if(t[e]==="!")return!0}else e++}return!1},ZZe=function(t){if(t[0]==="!")return!0;for(var e=0;e{"use strict";var $Ze=Nne(),e$e=ve("path").posix.dirname,t$e=ve("os").platform()==="win32",vL="/",r$e=/\\/g,n$e=/[\{\[].*[\}\]]$/,i$e=/(^|[^\\])([\{\[]|\([^\)]+$)/,s$e=/\\([\!\*\?\|\[\]\(\)\{\}])/g;Lne.exports=function(e,r){var o=Object.assign({flipBackslashes:!0},r);o.flipBackslashes&&t$e&&e.indexOf(vL)<0&&(e=e.replace(r$e,vL)),n$e.test(e)&&(e+=vL),e+="a";do e=e$e(e);while($Ze(e)||i$e.test(e));return e.replace(s$e,"$1")}});var Yne=_(Nr=>{"use strict";Object.defineProperty(Nr,"__esModule",{value:!0});Nr.removeDuplicateSlashes=Nr.matchAny=Nr.convertPatternsToRe=Nr.makeRe=Nr.getPatternParts=Nr.expandBraceExpansion=Nr.expandPatternsWithBraceExpansion=Nr.isAffectDepthOfReadingPattern=Nr.endsWithSlashGlobStar=Nr.hasGlobStar=Nr.getBaseDirectory=Nr.isPatternRelatedToParentDirectory=Nr.getPatternsOutsideCurrentDirectory=Nr.getPatternsInsideCurrentDirectory=Nr.getPositivePatterns=Nr.getNegativePatterns=Nr.isPositivePattern=Nr.isNegativePattern=Nr.convertToNegativePattern=Nr.convertToPositivePattern=Nr.isDynamicPattern=Nr.isStaticPattern=void 0;var o$e=ve("path"),a$e=Mne(),DL=$o(),One="**",l$e="\\",c$e=/[*?]|^!/,u$e=/\[[^[]*]/,A$e=/(?:^|[^!*+?@])\([^(]*\|[^|]*\)/,f$e=/[!*+?@]\([^(]*\)/,p$e=/,|\.\./,h$e=/(?!^)\/{2,}/g;function Une(t,e={}){return!_ne(t,e)}Nr.isStaticPattern=Une;function _ne(t,e={}){return t===""?!1:!!(e.caseSensitiveMatch===!1||t.includes(l$e)||c$e.test(t)||u$e.test(t)||A$e.test(t)||e.extglob!==!1&&f$e.test(t)||e.braceExpansion!==!1&&g$e(t))}Nr.isDynamicPattern=_ne;function g$e(t){let e=t.indexOf("{");if(e===-1)return!1;let r=t.indexOf("}",e+1);if(r===-1)return!1;let o=t.slice(e,r);return p$e.test(o)}function d$e(t){return $P(t)?t.slice(1):t}Nr.convertToPositivePattern=d$e;function m$e(t){return"!"+t}Nr.convertToNegativePattern=m$e;function $P(t){return t.startsWith("!")&&t[1]!=="("}Nr.isNegativePattern=$P;function Hne(t){return!$P(t)}Nr.isPositivePattern=Hne;function y$e(t){return t.filter($P)}Nr.getNegativePatterns=y$e;function E$e(t){return t.filter(Hne)}Nr.getPositivePatterns=E$e;function C$e(t){return t.filter(e=>!PL(e))}Nr.getPatternsInsideCurrentDirectory=C$e;function w$e(t){return t.filter(PL)}Nr.getPatternsOutsideCurrentDirectory=w$e;function PL(t){return t.startsWith("..")||t.startsWith("./..")}Nr.isPatternRelatedToParentDirectory=PL;function I$e(t){return a$e(t,{flipBackslashes:!1})}Nr.getBaseDirectory=I$e;function B$e(t){return t.includes(One)}Nr.hasGlobStar=B$e;function qne(t){return t.endsWith("/"+One)}Nr.endsWithSlashGlobStar=qne;function v$e(t){let e=o$e.basename(t);return qne(t)||Une(e)}Nr.isAffectDepthOfReadingPattern=v$e;function D$e(t){return t.reduce((e,r)=>e.concat(jne(r)),[])}Nr.expandPatternsWithBraceExpansion=D$e;function jne(t){let e=DL.braces(t,{expand:!0,nodupes:!0,keepEscaping:!0});return e.sort((r,o)=>r.length-o.length),e.filter(r=>r!=="")}Nr.expandBraceExpansion=jne;function P$e(t,e){let{parts:r}=DL.scan(t,Object.assign(Object.assign({},e),{parts:!0}));return r.length===0&&(r=[t]),r[0].startsWith("/")&&(r[0]=r[0].slice(1),r.unshift("")),r}Nr.getPatternParts=P$e;function Gne(t,e){return DL.makeRe(t,e)}Nr.makeRe=Gne;function b$e(t,e){return t.map(r=>Gne(r,e))}Nr.convertPatternsToRe=b$e;function S$e(t,e){return e.some(r=>r.test(t))}Nr.matchAny=S$e;function x$e(t){return t.replace(h$e,"/")}Nr.removeDuplicateSlashes=x$e});var zne=_((MTt,Vne)=>{"use strict";var k$e=ve("stream"),Wne=k$e.PassThrough,Q$e=Array.prototype.slice;Vne.exports=F$e;function F$e(){let t=[],e=Q$e.call(arguments),r=!1,o=e[e.length-1];o&&!Array.isArray(o)&&o.pipe==null?e.pop():o={};let a=o.end!==!1,n=o.pipeError===!0;o.objectMode==null&&(o.objectMode=!0),o.highWaterMark==null&&(o.highWaterMark=64*1024);let u=Wne(o);function A(){for(let E=0,I=arguments.length;E0||(r=!1,p())}function x(C){function R(){C.removeListener("merge2UnpipeEnd",R),C.removeListener("end",R),n&&C.removeListener("error",L),v()}function L(U){u.emit("error",U)}if(C._readableState.endEmitted)return v();C.on("merge2UnpipeEnd",R),C.on("end",R),n&&C.on("error",L),C.pipe(u,{end:!1}),C.resume()}for(let C=0;C{"use strict";Object.defineProperty(eb,"__esModule",{value:!0});eb.merge=void 0;var R$e=zne();function T$e(t){let e=R$e(t);return t.forEach(r=>{r.once("error",o=>e.emit("error",o))}),e.once("close",()=>Jne(t)),e.once("end",()=>Jne(t)),e}eb.merge=T$e;function Jne(t){t.forEach(e=>e.emit("close"))}});var Zne=_(Lm=>{"use strict";Object.defineProperty(Lm,"__esModule",{value:!0});Lm.isEmpty=Lm.isString=void 0;function N$e(t){return typeof t=="string"}Lm.isString=N$e;function L$e(t){return t===""}Lm.isEmpty=L$e});var Df=_(xo=>{"use strict";Object.defineProperty(xo,"__esModule",{value:!0});xo.string=xo.stream=xo.pattern=xo.path=xo.fs=xo.errno=xo.array=void 0;var M$e=vne();xo.array=M$e;var O$e=Dne();xo.errno=O$e;var U$e=Pne();xo.fs=U$e;var _$e=kne();xo.path=_$e;var H$e=Yne();xo.pattern=H$e;var q$e=Xne();xo.stream=q$e;var j$e=Zne();xo.string=j$e});var rie=_(ko=>{"use strict";Object.defineProperty(ko,"__esModule",{value:!0});ko.convertPatternGroupToTask=ko.convertPatternGroupsToTasks=ko.groupPatternsByBaseDirectory=ko.getNegativePatternsAsPositive=ko.getPositivePatterns=ko.convertPatternsToTasks=ko.generate=void 0;var qc=Df();function G$e(t,e){let r=$ne(t,e),o=$ne(e.ignore,e),a=eie(r),n=tie(r,o),u=a.filter(E=>qc.pattern.isStaticPattern(E,e)),A=a.filter(E=>qc.pattern.isDynamicPattern(E,e)),p=bL(u,n,!1),h=bL(A,n,!0);return p.concat(h)}ko.generate=G$e;function $ne(t,e){let r=t;return e.braceExpansion&&(r=qc.pattern.expandPatternsWithBraceExpansion(r)),e.baseNameMatch&&(r=r.map(o=>o.includes("/")?o:`**/${o}`)),r.map(o=>qc.pattern.removeDuplicateSlashes(o))}function bL(t,e,r){let o=[],a=qc.pattern.getPatternsOutsideCurrentDirectory(t),n=qc.pattern.getPatternsInsideCurrentDirectory(t),u=SL(a),A=SL(n);return o.push(...xL(u,e,r)),"."in A?o.push(kL(".",n,e,r)):o.push(...xL(A,e,r)),o}ko.convertPatternsToTasks=bL;function eie(t){return qc.pattern.getPositivePatterns(t)}ko.getPositivePatterns=eie;function tie(t,e){return qc.pattern.getNegativePatterns(t).concat(e).map(qc.pattern.convertToPositivePattern)}ko.getNegativePatternsAsPositive=tie;function SL(t){let e={};return t.reduce((r,o)=>{let a=qc.pattern.getBaseDirectory(o);return a in r?r[a].push(o):r[a]=[o],r},e)}ko.groupPatternsByBaseDirectory=SL;function xL(t,e,r){return Object.keys(t).map(o=>kL(o,t[o],e,r))}ko.convertPatternGroupsToTasks=xL;function kL(t,e,r,o){return{dynamic:o,positive:e,negative:r,base:t,patterns:[].concat(e,r.map(qc.pattern.convertToNegativePattern))}}ko.convertPatternGroupToTask=kL});var iie=_(tb=>{"use strict";Object.defineProperty(tb,"__esModule",{value:!0});tb.read=void 0;function Y$e(t,e,r){e.fs.lstat(t,(o,a)=>{if(o!==null){nie(r,o);return}if(!a.isSymbolicLink()||!e.followSymbolicLink){QL(r,a);return}e.fs.stat(t,(n,u)=>{if(n!==null){if(e.throwErrorOnBrokenSymbolicLink){nie(r,n);return}QL(r,a);return}e.markSymbolicLink&&(u.isSymbolicLink=()=>!0),QL(r,u)})})}tb.read=Y$e;function nie(t,e){t(e)}function QL(t,e){t(null,e)}});var sie=_(rb=>{"use strict";Object.defineProperty(rb,"__esModule",{value:!0});rb.read=void 0;function W$e(t,e){let r=e.fs.lstatSync(t);if(!r.isSymbolicLink()||!e.followSymbolicLink)return r;try{let o=e.fs.statSync(t);return e.markSymbolicLink&&(o.isSymbolicLink=()=>!0),o}catch(o){if(!e.throwErrorOnBrokenSymbolicLink)return r;throw o}}rb.read=W$e});var oie=_(zp=>{"use strict";Object.defineProperty(zp,"__esModule",{value:!0});zp.createFileSystemAdapter=zp.FILE_SYSTEM_ADAPTER=void 0;var nb=ve("fs");zp.FILE_SYSTEM_ADAPTER={lstat:nb.lstat,stat:nb.stat,lstatSync:nb.lstatSync,statSync:nb.statSync};function K$e(t){return t===void 0?zp.FILE_SYSTEM_ADAPTER:Object.assign(Object.assign({},zp.FILE_SYSTEM_ADAPTER),t)}zp.createFileSystemAdapter=K$e});var aie=_(RL=>{"use strict";Object.defineProperty(RL,"__esModule",{value:!0});var V$e=oie(),FL=class{constructor(e={}){this._options=e,this.followSymbolicLink=this._getValue(this._options.followSymbolicLink,!0),this.fs=V$e.createFileSystemAdapter(this._options.fs),this.markSymbolicLink=this._getValue(this._options.markSymbolicLink,!1),this.throwErrorOnBrokenSymbolicLink=this._getValue(this._options.throwErrorOnBrokenSymbolicLink,!0)}_getValue(e,r){return e??r}};RL.default=FL});var hg=_(Jp=>{"use strict";Object.defineProperty(Jp,"__esModule",{value:!0});Jp.statSync=Jp.stat=Jp.Settings=void 0;var lie=iie(),z$e=sie(),TL=aie();Jp.Settings=TL.default;function J$e(t,e,r){if(typeof e=="function"){lie.read(t,NL(),e);return}lie.read(t,NL(e),r)}Jp.stat=J$e;function X$e(t,e){let r=NL(e);return z$e.read(t,r)}Jp.statSync=X$e;function NL(t={}){return t instanceof TL.default?t:new TL.default(t)}});var Aie=_((KTt,uie)=>{var cie;uie.exports=typeof queueMicrotask=="function"?queueMicrotask.bind(typeof window<"u"?window:global):t=>(cie||(cie=Promise.resolve())).then(t).catch(e=>setTimeout(()=>{throw e},0))});var pie=_((VTt,fie)=>{fie.exports=$$e;var Z$e=Aie();function $$e(t,e){let r,o,a,n=!0;Array.isArray(t)?(r=[],o=t.length):(a=Object.keys(t),r={},o=a.length);function u(p){function h(){e&&e(p,r),e=null}n?Z$e(h):h()}function A(p,h,E){r[p]=E,(--o===0||h)&&u(h)}o?a?a.forEach(function(p){t[p](function(h,E){A(p,h,E)})}):t.forEach(function(p,h){p(function(E,I){A(h,E,I)})}):u(null),n=!1}});var LL=_(sb=>{"use strict";Object.defineProperty(sb,"__esModule",{value:!0});sb.IS_SUPPORT_READDIR_WITH_FILE_TYPES=void 0;var ib=process.versions.node.split(".");if(ib[0]===void 0||ib[1]===void 0)throw new Error(`Unexpected behavior. The 'process.versions.node' variable has invalid value: ${process.versions.node}`);var hie=Number.parseInt(ib[0],10),eet=Number.parseInt(ib[1],10),gie=10,tet=10,ret=hie>gie,net=hie===gie&&eet>=tet;sb.IS_SUPPORT_READDIR_WITH_FILE_TYPES=ret||net});var die=_(ob=>{"use strict";Object.defineProperty(ob,"__esModule",{value:!0});ob.createDirentFromStats=void 0;var ML=class{constructor(e,r){this.name=e,this.isBlockDevice=r.isBlockDevice.bind(r),this.isCharacterDevice=r.isCharacterDevice.bind(r),this.isDirectory=r.isDirectory.bind(r),this.isFIFO=r.isFIFO.bind(r),this.isFile=r.isFile.bind(r),this.isSocket=r.isSocket.bind(r),this.isSymbolicLink=r.isSymbolicLink.bind(r)}};function iet(t,e){return new ML(t,e)}ob.createDirentFromStats=iet});var OL=_(ab=>{"use strict";Object.defineProperty(ab,"__esModule",{value:!0});ab.fs=void 0;var set=die();ab.fs=set});var UL=_(lb=>{"use strict";Object.defineProperty(lb,"__esModule",{value:!0});lb.joinPathSegments=void 0;function oet(t,e,r){return t.endsWith(r)?t+e:t+r+e}lb.joinPathSegments=oet});var Iie=_(Xp=>{"use strict";Object.defineProperty(Xp,"__esModule",{value:!0});Xp.readdir=Xp.readdirWithFileTypes=Xp.read=void 0;var aet=hg(),mie=pie(),cet=LL(),yie=OL(),Eie=UL();function uet(t,e,r){if(!e.stats&&cet.IS_SUPPORT_READDIR_WITH_FILE_TYPES){Cie(t,e,r);return}wie(t,e,r)}Xp.read=uet;function Cie(t,e,r){e.fs.readdir(t,{withFileTypes:!0},(o,a)=>{if(o!==null){ub(r,o);return}let n=a.map(A=>({dirent:A,name:A.name,path:Eie.joinPathSegments(t,A.name,e.pathSegmentSeparator)}));if(!e.followSymbolicLinks){_L(r,n);return}let u=n.map(A=>Aet(A,e));mie(u,(A,p)=>{if(A!==null){ub(r,A);return}_L(r,p)})})}Xp.readdirWithFileTypes=Cie;function Aet(t,e){return r=>{if(!t.dirent.isSymbolicLink()){r(null,t);return}e.fs.stat(t.path,(o,a)=>{if(o!==null){if(e.throwErrorOnBrokenSymbolicLink){r(o);return}r(null,t);return}t.dirent=yie.fs.createDirentFromStats(t.name,a),r(null,t)})}}function wie(t,e,r){e.fs.readdir(t,(o,a)=>{if(o!==null){ub(r,o);return}let n=a.map(u=>{let A=Eie.joinPathSegments(t,u,e.pathSegmentSeparator);return p=>{aet.stat(A,e.fsStatSettings,(h,E)=>{if(h!==null){p(h);return}let I={name:u,path:A,dirent:yie.fs.createDirentFromStats(u,E)};e.stats&&(I.stats=E),p(null,I)})}});mie(n,(u,A)=>{if(u!==null){ub(r,u);return}_L(r,A)})})}Xp.readdir=wie;function ub(t,e){t(e)}function _L(t,e){t(null,e)}});var bie=_(Zp=>{"use strict";Object.defineProperty(Zp,"__esModule",{value:!0});Zp.readdir=Zp.readdirWithFileTypes=Zp.read=void 0;var fet=hg(),pet=LL(),Bie=OL(),vie=UL();function het(t,e){return!e.stats&&pet.IS_SUPPORT_READDIR_WITH_FILE_TYPES?Die(t,e):Pie(t,e)}Zp.read=het;function Die(t,e){return e.fs.readdirSync(t,{withFileTypes:!0}).map(o=>{let a={dirent:o,name:o.name,path:vie.joinPathSegments(t,o.name,e.pathSegmentSeparator)};if(a.dirent.isSymbolicLink()&&e.followSymbolicLinks)try{let n=e.fs.statSync(a.path);a.dirent=Bie.fs.createDirentFromStats(a.name,n)}catch(n){if(e.throwErrorOnBrokenSymbolicLink)throw n}return a})}Zp.readdirWithFileTypes=Die;function Pie(t,e){return e.fs.readdirSync(t).map(o=>{let a=vie.joinPathSegments(t,o,e.pathSegmentSeparator),n=fet.statSync(a,e.fsStatSettings),u={name:o,path:a,dirent:Bie.fs.createDirentFromStats(o,n)};return e.stats&&(u.stats=n),u})}Zp.readdir=Pie});var Sie=_($p=>{"use strict";Object.defineProperty($p,"__esModule",{value:!0});$p.createFileSystemAdapter=$p.FILE_SYSTEM_ADAPTER=void 0;var Mm=ve("fs");$p.FILE_SYSTEM_ADAPTER={lstat:Mm.lstat,stat:Mm.stat,lstatSync:Mm.lstatSync,statSync:Mm.statSync,readdir:Mm.readdir,readdirSync:Mm.readdirSync};function get(t){return t===void 0?$p.FILE_SYSTEM_ADAPTER:Object.assign(Object.assign({},$p.FILE_SYSTEM_ADAPTER),t)}$p.createFileSystemAdapter=get});var xie=_(qL=>{"use strict";Object.defineProperty(qL,"__esModule",{value:!0});var det=ve("path"),met=hg(),yet=Sie(),HL=class{constructor(e={}){this._options=e,this.followSymbolicLinks=this._getValue(this._options.followSymbolicLinks,!1),this.fs=yet.createFileSystemAdapter(this._options.fs),this.pathSegmentSeparator=this._getValue(this._options.pathSegmentSeparator,det.sep),this.stats=this._getValue(this._options.stats,!1),this.throwErrorOnBrokenSymbolicLink=this._getValue(this._options.throwErrorOnBrokenSymbolicLink,!0),this.fsStatSettings=new met.Settings({followSymbolicLink:this.followSymbolicLinks,fs:this.fs,throwErrorOnBrokenSymbolicLink:this.throwErrorOnBrokenSymbolicLink})}_getValue(e,r){return e??r}};qL.default=HL});var Ab=_(eh=>{"use strict";Object.defineProperty(eh,"__esModule",{value:!0});eh.Settings=eh.scandirSync=eh.scandir=void 0;var kie=Iie(),Eet=bie(),jL=xie();eh.Settings=jL.default;function Cet(t,e,r){if(typeof e=="function"){kie.read(t,YL(),e);return}kie.read(t,YL(e),r)}eh.scandir=Cet;function wet(t,e){let r=YL(e);return Eet.read(t,r)}eh.scandirSync=wet;function YL(t={}){return t instanceof jL.default?t:new jL.default(t)}});var Fie=_((iNt,Qie)=>{"use strict";function Iet(t){var e=new t,r=e;function o(){var n=e;return n.next?e=n.next:(e=new t,r=e),n.next=null,n}function a(n){r.next=n,r=n}return{get:o,release:a}}Qie.exports=Iet});var Tie=_((sNt,WL)=>{"use strict";var Bet=Fie();function Rie(t,e,r){if(typeof t=="function"&&(r=e,e=t,t=null),!(r>=1))throw new Error("fastqueue concurrency must be equal to or greater than 1");var o=Bet(vet),a=null,n=null,u=0,A=null,p={push:R,drain:Gl,saturated:Gl,pause:E,paused:!1,get concurrency(){return r},set concurrency(le){if(!(le>=1))throw new Error("fastqueue concurrency must be equal to or greater than 1");if(r=le,!p.paused)for(;a&&u=r||p.paused?n?(n.next=Ce,n=Ce):(a=Ce,n=Ce,p.saturated()):(u++,e.call(t,Ce.value,Ce.worked))}function L(le,ce){var Ce=o.get();Ce.context=t,Ce.release=U,Ce.value=le,Ce.callback=ce||Gl,Ce.errorHandler=A,u>=r||p.paused?a?(Ce.next=a,a=Ce):(a=Ce,n=Ce,p.saturated()):(u++,e.call(t,Ce.value,Ce.worked))}function U(le){le&&o.release(le);var ce=a;ce&&u<=r?p.paused?u--:(n===a&&(n=null),a=ce.next,ce.next=null,e.call(t,ce.value,ce.worked),n===null&&p.empty()):--u===0&&p.drain()}function z(){a=null,n=null,p.drain=Gl}function te(){a=null,n=null,p.drain(),p.drain=Gl}function ae(le){A=le}}function Gl(){}function vet(){this.value=null,this.callback=Gl,this.next=null,this.release=Gl,this.context=null,this.errorHandler=null;var t=this;this.worked=function(r,o){var a=t.callback,n=t.errorHandler,u=t.value;t.value=null,t.callback=Gl,t.errorHandler&&n(r,u),a.call(t.context,r,o),t.release(t)}}function Det(t,e,r){typeof t=="function"&&(r=e,e=t,t=null);function o(E,I){e.call(this,E).then(function(v){I(null,v)},I)}var a=Rie(t,o,r),n=a.push,u=a.unshift;return a.push=A,a.unshift=p,a.drained=h,a;function A(E){var I=new Promise(function(v,x){n(E,function(C,R){if(C){x(C);return}v(R)})});return I.catch(Gl),I}function p(E){var I=new Promise(function(v,x){u(E,function(C,R){if(C){x(C);return}v(R)})});return I.catch(Gl),I}function h(){if(a.idle())return new Promise(function(v){v()});var E=a.drain,I=new Promise(function(v){a.drain=function(){E(),v()}});return I}}WL.exports=Rie;WL.exports.promise=Det});var fb=_(Zu=>{"use strict";Object.defineProperty(Zu,"__esModule",{value:!0});Zu.joinPathSegments=Zu.replacePathSegmentSeparator=Zu.isAppliedFilter=Zu.isFatalError=void 0;function Pet(t,e){return t.errorFilter===null?!0:!t.errorFilter(e)}Zu.isFatalError=Pet;function bet(t,e){return t===null||t(e)}Zu.isAppliedFilter=bet;function xet(t,e){return t.split(/[/\\]/).join(e)}Zu.replacePathSegmentSeparator=xet;function ket(t,e,r){return t===""?e:t.endsWith(r)?t+e:t+r+e}Zu.joinPathSegments=ket});var zL=_(VL=>{"use strict";Object.defineProperty(VL,"__esModule",{value:!0});var Qet=fb(),KL=class{constructor(e,r){this._root=e,this._settings=r,this._root=Qet.replacePathSegmentSeparator(e,r.pathSegmentSeparator)}};VL.default=KL});var ZL=_(XL=>{"use strict";Object.defineProperty(XL,"__esModule",{value:!0});var Fet=ve("events"),Ret=Ab(),Tet=Tie(),pb=fb(),Net=zL(),JL=class extends Net.default{constructor(e,r){super(e,r),this._settings=r,this._scandir=Ret.scandir,this._emitter=new Fet.EventEmitter,this._queue=Tet(this._worker.bind(this),this._settings.concurrency),this._isFatalError=!1,this._isDestroyed=!1,this._queue.drain=()=>{this._isFatalError||this._emitter.emit("end")}}read(){return this._isFatalError=!1,this._isDestroyed=!1,setImmediate(()=>{this._pushToQueue(this._root,this._settings.basePath)}),this._emitter}get isDestroyed(){return this._isDestroyed}destroy(){if(this._isDestroyed)throw new Error("The reader is already destroyed");this._isDestroyed=!0,this._queue.killAndDrain()}onEntry(e){this._emitter.on("entry",e)}onError(e){this._emitter.once("error",e)}onEnd(e){this._emitter.once("end",e)}_pushToQueue(e,r){let o={directory:e,base:r};this._queue.push(o,a=>{a!==null&&this._handleError(a)})}_worker(e,r){this._scandir(e.directory,this._settings.fsScandirSettings,(o,a)=>{if(o!==null){r(o,void 0);return}for(let n of a)this._handleEntry(n,e.base);r(null,void 0)})}_handleError(e){this._isDestroyed||!pb.isFatalError(this._settings,e)||(this._isFatalError=!0,this._isDestroyed=!0,this._emitter.emit("error",e))}_handleEntry(e,r){if(this._isDestroyed||this._isFatalError)return;let o=e.path;r!==void 0&&(e.path=pb.joinPathSegments(r,e.name,this._settings.pathSegmentSeparator)),pb.isAppliedFilter(this._settings.entryFilter,e)&&this._emitEntry(e),e.dirent.isDirectory()&&pb.isAppliedFilter(this._settings.deepFilter,e)&&this._pushToQueue(o,r===void 0?void 0:e.path)}_emitEntry(e){this._emitter.emit("entry",e)}};XL.default=JL});var Nie=_(eM=>{"use strict";Object.defineProperty(eM,"__esModule",{value:!0});var Let=ZL(),$L=class{constructor(e,r){this._root=e,this._settings=r,this._reader=new Let.default(this._root,this._settings),this._storage=[]}read(e){this._reader.onError(r=>{Met(e,r)}),this._reader.onEntry(r=>{this._storage.push(r)}),this._reader.onEnd(()=>{Oet(e,this._storage)}),this._reader.read()}};eM.default=$L;function Met(t,e){t(e)}function Oet(t,e){t(null,e)}});var Lie=_(rM=>{"use strict";Object.defineProperty(rM,"__esModule",{value:!0});var Uet=ve("stream"),_et=ZL(),tM=class{constructor(e,r){this._root=e,this._settings=r,this._reader=new _et.default(this._root,this._settings),this._stream=new Uet.Readable({objectMode:!0,read:()=>{},destroy:()=>{this._reader.isDestroyed||this._reader.destroy()}})}read(){return this._reader.onError(e=>{this._stream.emit("error",e)}),this._reader.onEntry(e=>{this._stream.push(e)}),this._reader.onEnd(()=>{this._stream.push(null)}),this._reader.read(),this._stream}};rM.default=tM});var Mie=_(iM=>{"use strict";Object.defineProperty(iM,"__esModule",{value:!0});var Het=Ab(),hb=fb(),qet=zL(),nM=class extends qet.default{constructor(){super(...arguments),this._scandir=Het.scandirSync,this._storage=[],this._queue=new Set}read(){return this._pushToQueue(this._root,this._settings.basePath),this._handleQueue(),this._storage}_pushToQueue(e,r){this._queue.add({directory:e,base:r})}_handleQueue(){for(let e of this._queue.values())this._handleDirectory(e.directory,e.base)}_handleDirectory(e,r){try{let o=this._scandir(e,this._settings.fsScandirSettings);for(let a of o)this._handleEntry(a,r)}catch(o){this._handleError(o)}}_handleError(e){if(hb.isFatalError(this._settings,e))throw e}_handleEntry(e,r){let o=e.path;r!==void 0&&(e.path=hb.joinPathSegments(r,e.name,this._settings.pathSegmentSeparator)),hb.isAppliedFilter(this._settings.entryFilter,e)&&this._pushToStorage(e),e.dirent.isDirectory()&&hb.isAppliedFilter(this._settings.deepFilter,e)&&this._pushToQueue(o,r===void 0?void 0:e.path)}_pushToStorage(e){this._storage.push(e)}};iM.default=nM});var Oie=_(oM=>{"use strict";Object.defineProperty(oM,"__esModule",{value:!0});var jet=Mie(),sM=class{constructor(e,r){this._root=e,this._settings=r,this._reader=new jet.default(this._root,this._settings)}read(){return this._reader.read()}};oM.default=sM});var Uie=_(lM=>{"use strict";Object.defineProperty(lM,"__esModule",{value:!0});var Get=ve("path"),Yet=Ab(),aM=class{constructor(e={}){this._options=e,this.basePath=this._getValue(this._options.basePath,void 0),this.concurrency=this._getValue(this._options.concurrency,Number.POSITIVE_INFINITY),this.deepFilter=this._getValue(this._options.deepFilter,null),this.entryFilter=this._getValue(this._options.entryFilter,null),this.errorFilter=this._getValue(this._options.errorFilter,null),this.pathSegmentSeparator=this._getValue(this._options.pathSegmentSeparator,Get.sep),this.fsScandirSettings=new Yet.Settings({followSymbolicLinks:this._options.followSymbolicLinks,fs:this._options.fs,pathSegmentSeparator:this._options.pathSegmentSeparator,stats:this._options.stats,throwErrorOnBrokenSymbolicLink:this._options.throwErrorOnBrokenSymbolicLink})}_getValue(e,r){return e??r}};lM.default=aM});var db=_($u=>{"use strict";Object.defineProperty($u,"__esModule",{value:!0});$u.Settings=$u.walkStream=$u.walkSync=$u.walk=void 0;var _ie=Nie(),Wet=Lie(),Ket=Oie(),cM=Uie();$u.Settings=cM.default;function Vet(t,e,r){if(typeof e=="function"){new _ie.default(t,gb()).read(e);return}new _ie.default(t,gb(e)).read(r)}$u.walk=Vet;function zet(t,e){let r=gb(e);return new Ket.default(t,r).read()}$u.walkSync=zet;function Jet(t,e){let r=gb(e);return new Wet.default(t,r).read()}$u.walkStream=Jet;function gb(t={}){return t instanceof cM.default?t:new cM.default(t)}});var mb=_(AM=>{"use strict";Object.defineProperty(AM,"__esModule",{value:!0});var Xet=ve("path"),Zet=hg(),Hie=Df(),uM=class{constructor(e){this._settings=e,this._fsStatSettings=new Zet.Settings({followSymbolicLink:this._settings.followSymbolicLinks,fs:this._settings.fs,throwErrorOnBrokenSymbolicLink:this._settings.followSymbolicLinks})}_getFullEntryPath(e){return Xet.resolve(this._settings.cwd,e)}_makeEntry(e,r){let o={name:r,path:r,dirent:Hie.fs.createDirentFromStats(r,e)};return this._settings.stats&&(o.stats=e),o}_isFatalError(e){return!Hie.errno.isEnoentCodeError(e)&&!this._settings.suppressErrors}};AM.default=uM});var hM=_(pM=>{"use strict";Object.defineProperty(pM,"__esModule",{value:!0});var $et=ve("stream"),ett=hg(),ttt=db(),rtt=mb(),fM=class extends rtt.default{constructor(){super(...arguments),this._walkStream=ttt.walkStream,this._stat=ett.stat}dynamic(e,r){return this._walkStream(e,r)}static(e,r){let o=e.map(this._getFullEntryPath,this),a=new $et.PassThrough({objectMode:!0});a._write=(n,u,A)=>this._getEntry(o[n],e[n],r).then(p=>{p!==null&&r.entryFilter(p)&&a.push(p),n===o.length-1&&a.end(),A()}).catch(A);for(let n=0;nthis._makeEntry(a,r)).catch(a=>{if(o.errorFilter(a))return null;throw a})}_getStat(e){return new Promise((r,o)=>{this._stat(e,this._fsStatSettings,(a,n)=>a===null?r(n):o(a))})}};pM.default=fM});var qie=_(dM=>{"use strict";Object.defineProperty(dM,"__esModule",{value:!0});var ntt=db(),itt=mb(),stt=hM(),gM=class extends itt.default{constructor(){super(...arguments),this._walkAsync=ntt.walk,this._readerStream=new stt.default(this._settings)}dynamic(e,r){return new Promise((o,a)=>{this._walkAsync(e,r,(n,u)=>{n===null?o(u):a(n)})})}async static(e,r){let o=[],a=this._readerStream.static(e,r);return new Promise((n,u)=>{a.once("error",u),a.on("data",A=>o.push(A)),a.once("end",()=>n(o))})}};dM.default=gM});var jie=_(yM=>{"use strict";Object.defineProperty(yM,"__esModule",{value:!0});var LI=Df(),mM=class{constructor(e,r,o){this._patterns=e,this._settings=r,this._micromatchOptions=o,this._storage=[],this._fillStorage()}_fillStorage(){for(let e of this._patterns){let r=this._getPatternSegments(e),o=this._splitSegmentsIntoSections(r);this._storage.push({complete:o.length<=1,pattern:e,segments:r,sections:o})}}_getPatternSegments(e){return LI.pattern.getPatternParts(e,this._micromatchOptions).map(o=>LI.pattern.isDynamicPattern(o,this._settings)?{dynamic:!0,pattern:o,patternRe:LI.pattern.makeRe(o,this._micromatchOptions)}:{dynamic:!1,pattern:o})}_splitSegmentsIntoSections(e){return LI.array.splitWhen(e,r=>r.dynamic&&LI.pattern.hasGlobStar(r.pattern))}};yM.default=mM});var Gie=_(CM=>{"use strict";Object.defineProperty(CM,"__esModule",{value:!0});var ott=jie(),EM=class extends ott.default{match(e){let r=e.split("/"),o=r.length,a=this._storage.filter(n=>!n.complete||n.segments.length>o);for(let n of a){let u=n.sections[0];if(!n.complete&&o>u.length||r.every((p,h)=>{let E=n.segments[h];return!!(E.dynamic&&E.patternRe.test(p)||!E.dynamic&&E.pattern===p)}))return!0}return!1}};CM.default=EM});var Yie=_(IM=>{"use strict";Object.defineProperty(IM,"__esModule",{value:!0});var yb=Df(),att=Gie(),wM=class{constructor(e,r){this._settings=e,this._micromatchOptions=r}getFilter(e,r,o){let a=this._getMatcher(r),n=this._getNegativePatternsRe(o);return u=>this._filter(e,u,a,n)}_getMatcher(e){return new att.default(e,this._settings,this._micromatchOptions)}_getNegativePatternsRe(e){let r=e.filter(yb.pattern.isAffectDepthOfReadingPattern);return yb.pattern.convertPatternsToRe(r,this._micromatchOptions)}_filter(e,r,o,a){if(this._isSkippedByDeep(e,r.path)||this._isSkippedSymbolicLink(r))return!1;let n=yb.path.removeLeadingDotSegment(r.path);return this._isSkippedByPositivePatterns(n,o)?!1:this._isSkippedByNegativePatterns(n,a)}_isSkippedByDeep(e,r){return this._settings.deep===1/0?!1:this._getEntryLevel(e,r)>=this._settings.deep}_getEntryLevel(e,r){let o=r.split("/").length;if(e==="")return o;let a=e.split("/").length;return o-a}_isSkippedSymbolicLink(e){return!this._settings.followSymbolicLinks&&e.dirent.isSymbolicLink()}_isSkippedByPositivePatterns(e,r){return!this._settings.baseNameMatch&&!r.match(e)}_isSkippedByNegativePatterns(e,r){return!yb.pattern.matchAny(e,r)}};IM.default=wM});var Wie=_(vM=>{"use strict";Object.defineProperty(vM,"__esModule",{value:!0});var gg=Df(),BM=class{constructor(e,r){this._settings=e,this._micromatchOptions=r,this.index=new Map}getFilter(e,r){let o=gg.pattern.convertPatternsToRe(e,this._micromatchOptions),a=gg.pattern.convertPatternsToRe(r,Object.assign(Object.assign({},this._micromatchOptions),{dot:!0}));return n=>this._filter(n,o,a)}_filter(e,r,o){let a=gg.path.removeLeadingDotSegment(e.path);if(this._settings.unique&&this._isDuplicateEntry(a)||this._onlyFileFilter(e)||this._onlyDirectoryFilter(e)||this._isSkippedByAbsoluteNegativePatterns(a,o))return!1;let n=e.dirent.isDirectory(),u=this._isMatchToPatterns(a,r,n)&&!this._isMatchToPatterns(a,o,n);return this._settings.unique&&u&&this._createIndexRecord(a),u}_isDuplicateEntry(e){return this.index.has(e)}_createIndexRecord(e){this.index.set(e,void 0)}_onlyFileFilter(e){return this._settings.onlyFiles&&!e.dirent.isFile()}_onlyDirectoryFilter(e){return this._settings.onlyDirectories&&!e.dirent.isDirectory()}_isSkippedByAbsoluteNegativePatterns(e,r){if(!this._settings.absolute)return!1;let o=gg.path.makeAbsolute(this._settings.cwd,e);return gg.pattern.matchAny(o,r)}_isMatchToPatterns(e,r,o){let a=gg.pattern.matchAny(e,r);return!a&&o?gg.pattern.matchAny(e+"/",r):a}};vM.default=BM});var Kie=_(PM=>{"use strict";Object.defineProperty(PM,"__esModule",{value:!0});var ltt=Df(),DM=class{constructor(e){this._settings=e}getFilter(){return e=>this._isNonFatalError(e)}_isNonFatalError(e){return ltt.errno.isEnoentCodeError(e)||this._settings.suppressErrors}};PM.default=DM});var zie=_(SM=>{"use strict";Object.defineProperty(SM,"__esModule",{value:!0});var Vie=Df(),bM=class{constructor(e){this._settings=e}getTransformer(){return e=>this._transform(e)}_transform(e){let r=e.path;return this._settings.absolute&&(r=Vie.path.makeAbsolute(this._settings.cwd,r),r=Vie.path.unixify(r)),this._settings.markDirectories&&e.dirent.isDirectory()&&(r+="/"),this._settings.objectMode?Object.assign(Object.assign({},e),{path:r}):r}};SM.default=bM});var Eb=_(kM=>{"use strict";Object.defineProperty(kM,"__esModule",{value:!0});var ctt=ve("path"),utt=Yie(),Att=Wie(),ftt=Kie(),ptt=zie(),xM=class{constructor(e){this._settings=e,this.errorFilter=new ftt.default(this._settings),this.entryFilter=new Att.default(this._settings,this._getMicromatchOptions()),this.deepFilter=new utt.default(this._settings,this._getMicromatchOptions()),this.entryTransformer=new ptt.default(this._settings)}_getRootDirectory(e){return ctt.resolve(this._settings.cwd,e.base)}_getReaderOptions(e){let r=e.base==="."?"":e.base;return{basePath:r,pathSegmentSeparator:"/",concurrency:this._settings.concurrency,deepFilter:this.deepFilter.getFilter(r,e.positive,e.negative),entryFilter:this.entryFilter.getFilter(e.positive,e.negative),errorFilter:this.errorFilter.getFilter(),followSymbolicLinks:this._settings.followSymbolicLinks,fs:this._settings.fs,stats:this._settings.stats,throwErrorOnBrokenSymbolicLink:this._settings.throwErrorOnBrokenSymbolicLink,transform:this.entryTransformer.getTransformer()}}_getMicromatchOptions(){return{dot:this._settings.dot,matchBase:this._settings.baseNameMatch,nobrace:!this._settings.braceExpansion,nocase:!this._settings.caseSensitiveMatch,noext:!this._settings.extglob,noglobstar:!this._settings.globstar,posix:!0,strictSlashes:!1}}};kM.default=xM});var Jie=_(FM=>{"use strict";Object.defineProperty(FM,"__esModule",{value:!0});var htt=qie(),gtt=Eb(),QM=class extends gtt.default{constructor(){super(...arguments),this._reader=new htt.default(this._settings)}async read(e){let r=this._getRootDirectory(e),o=this._getReaderOptions(e);return(await this.api(r,e,o)).map(n=>o.transform(n))}api(e,r,o){return r.dynamic?this._reader.dynamic(e,o):this._reader.static(r.patterns,o)}};FM.default=QM});var Xie=_(TM=>{"use strict";Object.defineProperty(TM,"__esModule",{value:!0});var dtt=ve("stream"),mtt=hM(),ytt=Eb(),RM=class extends ytt.default{constructor(){super(...arguments),this._reader=new mtt.default(this._settings)}read(e){let r=this._getRootDirectory(e),o=this._getReaderOptions(e),a=this.api(r,e,o),n=new dtt.Readable({objectMode:!0,read:()=>{}});return a.once("error",u=>n.emit("error",u)).on("data",u=>n.emit("data",o.transform(u))).once("end",()=>n.emit("end")),n.once("close",()=>a.destroy()),n}api(e,r,o){return r.dynamic?this._reader.dynamic(e,o):this._reader.static(r.patterns,o)}};TM.default=RM});var Zie=_(LM=>{"use strict";Object.defineProperty(LM,"__esModule",{value:!0});var Ett=hg(),Ctt=db(),wtt=mb(),NM=class extends wtt.default{constructor(){super(...arguments),this._walkSync=Ctt.walkSync,this._statSync=Ett.statSync}dynamic(e,r){return this._walkSync(e,r)}static(e,r){let o=[];for(let a of e){let n=this._getFullEntryPath(a),u=this._getEntry(n,a,r);u===null||!r.entryFilter(u)||o.push(u)}return o}_getEntry(e,r,o){try{let a=this._getStat(e);return this._makeEntry(a,r)}catch(a){if(o.errorFilter(a))return null;throw a}}_getStat(e){return this._statSync(e,this._fsStatSettings)}};LM.default=NM});var $ie=_(OM=>{"use strict";Object.defineProperty(OM,"__esModule",{value:!0});var Itt=Zie(),Btt=Eb(),MM=class extends Btt.default{constructor(){super(...arguments),this._reader=new Itt.default(this._settings)}read(e){let r=this._getRootDirectory(e),o=this._getReaderOptions(e);return this.api(r,e,o).map(o.transform)}api(e,r,o){return r.dynamic?this._reader.dynamic(e,o):this._reader.static(r.patterns,o)}};OM.default=MM});var ese=_(Um=>{"use strict";Object.defineProperty(Um,"__esModule",{value:!0});Um.DEFAULT_FILE_SYSTEM_ADAPTER=void 0;var Om=ve("fs"),vtt=ve("os"),Dtt=Math.max(vtt.cpus().length,1);Um.DEFAULT_FILE_SYSTEM_ADAPTER={lstat:Om.lstat,lstatSync:Om.lstatSync,stat:Om.stat,statSync:Om.statSync,readdir:Om.readdir,readdirSync:Om.readdirSync};var UM=class{constructor(e={}){this._options=e,this.absolute=this._getValue(this._options.absolute,!1),this.baseNameMatch=this._getValue(this._options.baseNameMatch,!1),this.braceExpansion=this._getValue(this._options.braceExpansion,!0),this.caseSensitiveMatch=this._getValue(this._options.caseSensitiveMatch,!0),this.concurrency=this._getValue(this._options.concurrency,Dtt),this.cwd=this._getValue(this._options.cwd,process.cwd()),this.deep=this._getValue(this._options.deep,1/0),this.dot=this._getValue(this._options.dot,!1),this.extglob=this._getValue(this._options.extglob,!0),this.followSymbolicLinks=this._getValue(this._options.followSymbolicLinks,!0),this.fs=this._getFileSystemMethods(this._options.fs),this.globstar=this._getValue(this._options.globstar,!0),this.ignore=this._getValue(this._options.ignore,[]),this.markDirectories=this._getValue(this._options.markDirectories,!1),this.objectMode=this._getValue(this._options.objectMode,!1),this.onlyDirectories=this._getValue(this._options.onlyDirectories,!1),this.onlyFiles=this._getValue(this._options.onlyFiles,!0),this.stats=this._getValue(this._options.stats,!1),this.suppressErrors=this._getValue(this._options.suppressErrors,!1),this.throwErrorOnBrokenSymbolicLink=this._getValue(this._options.throwErrorOnBrokenSymbolicLink,!1),this.unique=this._getValue(this._options.unique,!0),this.onlyDirectories&&(this.onlyFiles=!1),this.stats&&(this.objectMode=!0),this.ignore=[].concat(this.ignore)}_getValue(e,r){return e===void 0?r:e}_getFileSystemMethods(e={}){return Object.assign(Object.assign({},Um.DEFAULT_FILE_SYSTEM_ADAPTER),e)}};Um.default=UM});var Cb=_((kNt,rse)=>{"use strict";var tse=rie(),Ptt=Jie(),btt=Xie(),Stt=$ie(),_M=ese(),Yl=Df();async function HM(t,e){jc(t);let r=qM(t,Ptt.default,e),o=await Promise.all(r);return Yl.array.flatten(o)}(function(t){t.glob=t,t.globSync=e,t.globStream=r,t.async=t;function e(h,E){jc(h);let I=qM(h,Stt.default,E);return Yl.array.flatten(I)}t.sync=e;function r(h,E){jc(h);let I=qM(h,btt.default,E);return Yl.stream.merge(I)}t.stream=r;function o(h,E){jc(h);let I=[].concat(h),v=new _M.default(E);return tse.generate(I,v)}t.generateTasks=o;function a(h,E){jc(h);let I=new _M.default(E);return Yl.pattern.isDynamicPattern(h,I)}t.isDynamicPattern=a;function n(h){return jc(h),Yl.path.escape(h)}t.escapePath=n;function u(h){return jc(h),Yl.path.convertPathToPattern(h)}t.convertPathToPattern=u;let A;(function(h){function E(v){return jc(v),Yl.path.escapePosixPath(v)}h.escapePath=E;function I(v){return jc(v),Yl.path.convertPosixPathToPattern(v)}h.convertPathToPattern=I})(A=t.posix||(t.posix={}));let p;(function(h){function E(v){return jc(v),Yl.path.escapeWindowsPath(v)}h.escapePath=E;function I(v){return jc(v),Yl.path.convertWindowsPathToPattern(v)}h.convertPathToPattern=I})(p=t.win32||(t.win32={}))})(HM||(HM={}));function qM(t,e,r){let o=[].concat(t),a=new _M.default(r),n=tse.generate(o,a),u=new e(a);return n.map(u.read,u)}function jc(t){if(![].concat(t).every(o=>Yl.string.isString(o)&&!Yl.string.isEmpty(o)))throw new TypeError("Patterns must be a string (non empty) or an array of strings")}rse.exports=HM});var wn={};Vt(wn,{checksumFile:()=>Ib,checksumPattern:()=>Bb,makeHash:()=>zi});function zi(...t){let e=(0,wb.createHash)("sha512"),r="";for(let o of t)typeof o=="string"?r+=o:o&&(r&&(e.update(r),r=""),e.update(o));return r&&e.update(r),e.digest("hex")}async function Ib(t,{baseFs:e,algorithm:r}={baseFs:oe,algorithm:"sha512"}){let o=await e.openPromise(t,"r");try{let n=Buffer.allocUnsafeSlow(65536),u=(0,wb.createHash)(r),A=0;for(;(A=await e.readPromise(o,n,0,65536))!==0;)u.update(A===65536?n:n.slice(0,A));return u.digest("hex")}finally{await e.closePromise(o)}}async function Bb(t,{cwd:e}){let o=(await(0,jM.default)(t,{cwd:ue.fromPortablePath(e),onlyDirectories:!0})).map(A=>`${A}/**/*`),a=await(0,jM.default)([t,...o],{cwd:ue.fromPortablePath(e),onlyFiles:!1});a.sort();let n=await Promise.all(a.map(async A=>{let p=[Buffer.from(A)],h=V.join(e,ue.toPortablePath(A)),E=await oe.lstatPromise(h);return E.isSymbolicLink()?p.push(Buffer.from(await oe.readlinkPromise(h))):E.isFile()&&p.push(await oe.readFilePromise(h)),p.join("\0")})),u=(0,wb.createHash)("sha512");for(let A of n)u.update(A);return u.digest("hex")}var wb,jM,th=Et(()=>{Pt();wb=ve("crypto"),jM=Ze(Cb())});var G={};Vt(G,{allPeerRequests:()=>WI,areDescriptorsEqual:()=>ase,areIdentsEqual:()=>HI,areLocatorsEqual:()=>qI,areVirtualPackagesEquivalent:()=>Mtt,bindDescriptor:()=>Ntt,bindLocator:()=>Ltt,convertDescriptorToLocator:()=>vb,convertLocatorToDescriptor:()=>YM,convertPackageToLocator:()=>Ftt,convertToIdent:()=>Qtt,convertToManifestRange:()=>Ktt,copyPackage:()=>OI,devirtualizeDescriptor:()=>UI,devirtualizeLocator:()=>_I,ensureDevirtualizedDescriptor:()=>Rtt,ensureDevirtualizedLocator:()=>Ttt,getIdentVendorPath:()=>zM,isPackageCompatible:()=>xb,isVirtualDescriptor:()=>Pf,isVirtualLocator:()=>Gc,makeDescriptor:()=>In,makeIdent:()=>eA,makeLocator:()=>Rs,makeRange:()=>bb,parseDescriptor:()=>rh,parseFileStyleRange:()=>Ytt,parseIdent:()=>ea,parseLocator:()=>bf,parseRange:()=>dg,prettyDependent:()=>CL,prettyDescriptor:()=>jn,prettyIdent:()=>Oi,prettyLocator:()=>qr,prettyLocatorNoColors:()=>EL,prettyRange:()=>qm,prettyReference:()=>GI,prettyResolution:()=>NI,prettyWorkspace:()=>YI,renamePackage:()=>WM,slugifyIdent:()=>GM,slugifyLocator:()=>Hm,sortDescriptors:()=>jm,stringifyDescriptor:()=>xa,stringifyIdent:()=>rn,stringifyLocator:()=>ka,tryParseDescriptor:()=>jI,tryParseIdent:()=>lse,tryParseLocator:()=>Pb,tryParseRange:()=>Gtt,virtualizeDescriptor:()=>KM,virtualizePackage:()=>VM});function eA(t,e){if(t?.startsWith("@"))throw new Error("Invalid scope: don't prefix it with '@'");return{identHash:zi(t,e),scope:t,name:e}}function In(t,e){return{identHash:t.identHash,scope:t.scope,name:t.name,descriptorHash:zi(t.identHash,e),range:e}}function Rs(t,e){return{identHash:t.identHash,scope:t.scope,name:t.name,locatorHash:zi(t.identHash,e),reference:e}}function Qtt(t){return{identHash:t.identHash,scope:t.scope,name:t.name}}function vb(t){return{identHash:t.identHash,scope:t.scope,name:t.name,locatorHash:t.descriptorHash,reference:t.range}}function YM(t){return{identHash:t.identHash,scope:t.scope,name:t.name,descriptorHash:t.locatorHash,range:t.reference}}function Ftt(t){return{identHash:t.identHash,scope:t.scope,name:t.name,locatorHash:t.locatorHash,reference:t.reference}}function WM(t,e){return{identHash:e.identHash,scope:e.scope,name:e.name,locatorHash:e.locatorHash,reference:e.reference,version:t.version,languageName:t.languageName,linkType:t.linkType,conditions:t.conditions,dependencies:new Map(t.dependencies),peerDependencies:new Map(t.peerDependencies),dependenciesMeta:new Map(t.dependenciesMeta),peerDependenciesMeta:new Map(t.peerDependenciesMeta),bin:new Map(t.bin)}}function OI(t){return WM(t,t)}function KM(t,e){if(e.includes("#"))throw new Error("Invalid entropy");return In(t,`virtual:${e}#${t.range}`)}function VM(t,e){if(e.includes("#"))throw new Error("Invalid entropy");return WM(t,Rs(t,`virtual:${e}#${t.reference}`))}function Pf(t){return t.range.startsWith(MI)}function Gc(t){return t.reference.startsWith(MI)}function UI(t){if(!Pf(t))throw new Error("Not a virtual descriptor");return In(t,t.range.replace(Db,""))}function _I(t){if(!Gc(t))throw new Error("Not a virtual descriptor");return Rs(t,t.reference.replace(Db,""))}function Rtt(t){return Pf(t)?In(t,t.range.replace(Db,"")):t}function Ttt(t){return Gc(t)?Rs(t,t.reference.replace(Db,"")):t}function Ntt(t,e){return t.range.includes("::")?t:In(t,`${t.range}::${_m.default.stringify(e)}`)}function Ltt(t,e){return t.reference.includes("::")?t:Rs(t,`${t.reference}::${_m.default.stringify(e)}`)}function HI(t,e){return t.identHash===e.identHash}function ase(t,e){return t.descriptorHash===e.descriptorHash}function qI(t,e){return t.locatorHash===e.locatorHash}function Mtt(t,e){if(!Gc(t))throw new Error("Invalid package type");if(!Gc(e))throw new Error("Invalid package type");if(!HI(t,e)||t.dependencies.size!==e.dependencies.size)return!1;for(let r of t.dependencies.values()){let o=e.dependencies.get(r.identHash);if(!o||!ase(r,o))return!1}return!0}function ea(t){let e=lse(t);if(!e)throw new Error(`Invalid ident (${t})`);return e}function lse(t){let e=t.match(Ott);if(!e)return null;let[,r,o]=e;return eA(typeof r<"u"?r:null,o)}function rh(t,e=!1){let r=jI(t,e);if(!r)throw new Error(`Invalid descriptor (${t})`);return r}function jI(t,e=!1){let r=e?t.match(Utt):t.match(_tt);if(!r)return null;let[,o,a,n]=r;if(n==="unknown")throw new Error(`Invalid range (${t})`);let u=typeof o<"u"?o:null,A=typeof n<"u"?n:"unknown";return In(eA(u,a),A)}function bf(t,e=!1){let r=Pb(t,e);if(!r)throw new Error(`Invalid locator (${t})`);return r}function Pb(t,e=!1){let r=e?t.match(Htt):t.match(qtt);if(!r)return null;let[,o,a,n]=r;if(n==="unknown")throw new Error(`Invalid reference (${t})`);let u=typeof o<"u"?o:null,A=typeof n<"u"?n:"unknown";return Rs(eA(u,a),A)}function dg(t,e){let r=t.match(jtt);if(r===null)throw new Error(`Invalid range (${t})`);let o=typeof r[1]<"u"?r[1]:null;if(typeof e?.requireProtocol=="string"&&o!==e.requireProtocol)throw new Error(`Invalid protocol (${o})`);if(e?.requireProtocol&&o===null)throw new Error(`Missing protocol (${o})`);let a=typeof r[3]<"u"?decodeURIComponent(r[2]):null;if(e?.requireSource&&a===null)throw new Error(`Missing source (${t})`);let n=typeof r[3]<"u"?decodeURIComponent(r[3]):decodeURIComponent(r[2]),u=e?.parseSelector?_m.default.parse(n):n,A=typeof r[4]<"u"?_m.default.parse(r[4]):null;return{protocol:o,source:a,selector:u,params:A}}function Gtt(t,e){try{return dg(t,e)}catch{return null}}function Ytt(t,{protocol:e}){let{selector:r,params:o}=dg(t,{requireProtocol:e,requireBindings:!0});if(typeof o.locator!="string")throw new Error(`Assertion failed: Invalid bindings for ${t}`);return{parentLocator:bf(o.locator,!0),path:r}}function nse(t){return t=t.replaceAll("%","%25"),t=t.replaceAll(":","%3A"),t=t.replaceAll("#","%23"),t}function Wtt(t){return t===null?!1:Object.entries(t).length>0}function bb({protocol:t,source:e,selector:r,params:o}){let a="";return t!==null&&(a+=`${t}`),e!==null&&(a+=`${nse(e)}#`),a+=nse(r),Wtt(o)&&(a+=`::${_m.default.stringify(o)}`),a}function Ktt(t){let{params:e,protocol:r,source:o,selector:a}=dg(t);for(let n in e)n.startsWith("__")&&delete e[n];return bb({protocol:r,source:o,params:e,selector:a})}function rn(t){return t.scope?`@${t.scope}/${t.name}`:`${t.name}`}function xa(t){return t.scope?`@${t.scope}/${t.name}@${t.range}`:`${t.name}@${t.range}`}function ka(t){return t.scope?`@${t.scope}/${t.name}@${t.reference}`:`${t.name}@${t.reference}`}function GM(t){return t.scope!==null?`@${t.scope}-${t.name}`:t.name}function Hm(t){let{protocol:e,selector:r}=dg(t.reference),o=e!==null?e.replace(Vtt,""):"exotic",a=ise.default.valid(r),n=a!==null?`${o}-${a}`:`${o}`,u=10;return t.scope?`${GM(t)}-${n}-${t.locatorHash.slice(0,u)}`:`${GM(t)}-${n}-${t.locatorHash.slice(0,u)}`}function Oi(t,e){return e.scope?`${Ot(t,`@${e.scope}/`,yt.SCOPE)}${Ot(t,e.name,yt.NAME)}`:`${Ot(t,e.name,yt.NAME)}`}function Sb(t){if(t.startsWith(MI)){let e=Sb(t.substring(t.indexOf("#")+1)),r=t.substring(MI.length,MI.length+xtt);return`${e} [${r}]`}else return t.replace(ztt,"?[...]")}function qm(t,e){return`${Ot(t,Sb(e),yt.RANGE)}`}function jn(t,e){return`${Oi(t,e)}${Ot(t,"@",yt.RANGE)}${qm(t,e.range)}`}function GI(t,e){return`${Ot(t,Sb(e),yt.REFERENCE)}`}function qr(t,e){return`${Oi(t,e)}${Ot(t,"@",yt.REFERENCE)}${GI(t,e.reference)}`}function EL(t){return`${rn(t)}@${Sb(t.reference)}`}function jm(t){return Fs(t,[e=>rn(e),e=>e.range])}function YI(t,e){return Oi(t,e.anchoredLocator)}function NI(t,e,r){let o=Pf(e)?UI(e):e;return r===null?`${jn(t,o)} \u2192 ${yL(t).Cross}`:o.identHash===r.identHash?`${jn(t,o)} \u2192 ${GI(t,r.reference)}`:`${jn(t,o)} \u2192 ${qr(t,r)}`}function CL(t,e,r){return r===null?`${qr(t,e)}`:`${qr(t,e)} (via ${qm(t,r.range)})`}function zM(t){return`node_modules/${rn(t)}`}function xb(t,e){return t.conditions?ktt(t.conditions,r=>{let[,o,a]=r.match(ose),n=e[o];return n?n.includes(a):!0}):!0}function WI(t){let e=new Set;if("children"in t)e.add(t);else for(let r of t.requests.values())e.add(r);for(let r of e)for(let o of r.children.values())e.add(o);return e}var _m,ise,sse,MI,xtt,ose,ktt,Db,Ott,Utt,_tt,Htt,qtt,jtt,Vtt,ztt,So=Et(()=>{_m=Ze(ve("querystring")),ise=Ze(Jn()),sse=Ze(eX());jl();th();ql();So();MI="virtual:",xtt=5,ose=/(os|cpu|libc)=([a-z0-9_-]+)/,ktt=(0,sse.makeParser)(ose);Db=/^[^#]*#/;Ott=/^(?:@([^/]+?)\/)?([^@/]+)$/;Utt=/^(?:@([^/]+?)\/)?([^@/]+?)(?:@(.+))$/,_tt=/^(?:@([^/]+?)\/)?([^@/]+?)(?:@(.+))?$/;Htt=/^(?:@([^/]+?)\/)?([^@/]+?)(?:@(.+))$/,qtt=/^(?:@([^/]+?)\/)?([^@/]+?)(?:@(.+))?$/;jtt=/^([^#:]*:)?((?:(?!::)[^#])*)(?:#((?:(?!::).)*))?(?:::(.*))?$/;Vtt=/:$/;ztt=/\?.*/});var cse,use=Et(()=>{So();cse={hooks:{reduceDependency:(t,e,r,o,{resolver:a,resolveOptions:n})=>{for(let{pattern:u,reference:A}of e.topLevelWorkspace.manifest.resolutions){if(u.from&&(u.from.fullName!==rn(r)||e.configuration.normalizeLocator(Rs(ea(u.from.fullName),u.from.description??r.reference)).locatorHash!==r.locatorHash)||u.descriptor.fullName!==rn(t)||e.configuration.normalizeDependency(In(bf(u.descriptor.fullName),u.descriptor.description??t.range)).descriptorHash!==t.descriptorHash)continue;return a.bindDescriptor(e.configuration.normalizeDependency(In(t,A)),e.topLevelWorkspace.anchoredLocator,n)}return t},validateProject:async(t,e)=>{for(let r of t.workspaces){let o=YI(t.configuration,r);await t.configuration.triggerHook(a=>a.validateWorkspace,r,{reportWarning:(a,n)=>e.reportWarning(a,`${o}: ${n}`),reportError:(a,n)=>e.reportError(a,`${o}: ${n}`)})}},validateWorkspace:async(t,e)=>{let{manifest:r}=t;r.resolutions.length&&t.cwd!==t.project.cwd&&r.errors.push(new Error("Resolutions field will be ignored"));for(let o of r.errors)e.reportWarning(57,o.message)}}}});var ei,mg=Et(()=>{ei=class t{static{this.protocol="workspace:"}supportsDescriptor(e,r){return!!(e.range.startsWith(t.protocol)||r.project.tryWorkspaceByDescriptor(e)!==null)}supportsLocator(e,r){return!!e.reference.startsWith(t.protocol)}shouldPersistResolution(e,r){return!1}bindDescriptor(e,r,o){return e}getResolutionDependencies(e,r){return{}}async getCandidates(e,r,o){return[o.project.getWorkspaceByDescriptor(e).anchoredLocator]}async getSatisfying(e,r,o,a){let[n]=await this.getCandidates(e,r,a);return{locators:o.filter(u=>u.locatorHash===n.locatorHash),sorted:!1}}async resolve(e,r){let o=r.project.getWorkspaceByCwd(e.reference.slice(t.protocol.length));return{...e,version:o.manifest.version||"0.0.0",languageName:"unknown",linkType:"SOFT",conditions:null,dependencies:r.project.configuration.normalizeDependencyMap(new Map([...o.manifest.dependencies,...o.manifest.devDependencies])),peerDependencies:new Map([...o.manifest.peerDependencies]),dependenciesMeta:o.manifest.dependenciesMeta,peerDependenciesMeta:o.manifest.peerDependenciesMeta,bin:o.manifest.bin}}}});var Lr={};Vt(Lr,{SemVer:()=>gse.SemVer,clean:()=>Xtt,getComparator:()=>pse,mergeComparators:()=>JM,satisfiesWithPrereleases:()=>tA,simplifyRanges:()=>XM,stringifyComparator:()=>hse,validRange:()=>Qa});function tA(t,e,r=!1){if(!t)return!1;let o=`${e}${r}`,a=Ase.get(o);if(typeof a>"u")try{a=new nh.default.Range(e,{includePrerelease:!0,loose:r})}catch{return!1}finally{Ase.set(o,a||null)}else if(a===null)return!1;let n;try{n=new nh.default.SemVer(t,a)}catch{return!1}return a.test(n)?!0:(n.prerelease&&(n.prerelease=[]),a.set.some(u=>{for(let A of u)A.semver.prerelease&&(A.semver.prerelease=[]);return u.every(A=>A.test(n))}))}function Qa(t){if(t.indexOf(":")!==-1)return null;let e=fse.get(t);if(typeof e<"u")return e;try{e=new nh.default.Range(t)}catch{e=null}return fse.set(t,e),e}function Xtt(t){let e=Jtt.exec(t);return e?e[1]:null}function pse(t){if(t.semver===nh.default.Comparator.ANY)return{gt:null,lt:null};switch(t.operator){case"":return{gt:[">=",t.semver],lt:["<=",t.semver]};case">":case">=":return{gt:[t.operator,t.semver],lt:null};case"<":case"<=":return{gt:null,lt:[t.operator,t.semver]};default:throw new Error(`Assertion failed: Unexpected comparator operator (${t.operator})`)}}function JM(t){if(t.length===0)return null;let e=null,r=null;for(let o of t){if(o.gt){let a=e!==null?nh.default.compare(o.gt[1],e[1]):null;(a===null||a>0||a===0&&o.gt[0]===">")&&(e=o.gt)}if(o.lt){let a=r!==null?nh.default.compare(o.lt[1],r[1]):null;(a===null||a<0||a===0&&o.lt[0]==="<")&&(r=o.lt)}}if(e&&r){let o=nh.default.compare(e[1],r[1]);if(o===0&&(e[0]===">"||r[0]==="<")||o>0)return null}return{gt:e,lt:r}}function hse(t){if(t.gt&&t.lt){if(t.gt[0]===">="&&t.lt[0]==="<="&&t.gt[1].version===t.lt[1].version)return t.gt[1].version;if(t.gt[0]===">="&&t.lt[0]==="<"){if(t.lt[1].version===`${t.gt[1].major+1}.0.0-0`)return`^${t.gt[1].version}`;if(t.lt[1].version===`${t.gt[1].major}.${t.gt[1].minor+1}.0-0`)return`~${t.gt[1].version}`}}let e=[];return t.gt&&e.push(t.gt[0]+t.gt[1].version),t.lt&&e.push(t.lt[0]+t.lt[1].version),e.length?e.join(" "):"*"}function XM(t){let e=t.map(o=>Qa(o).set.map(a=>a.map(n=>pse(n)))),r=e.shift().map(o=>JM(o)).filter(o=>o!==null);for(let o of e){let a=[];for(let n of r)for(let u of o){let A=JM([n,...u]);A!==null&&a.push(A)}r=a}return r.length===0?null:r.map(o=>hse(o)).join(" || ")}var nh,gse,Ase,fse,Jtt,Sf=Et(()=>{nh=Ze(Jn()),gse=Ze(Jn()),Ase=new Map;fse=new Map;Jtt=/^(?:[\sv=]*?)((0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?)(?:\s*)$/});function dse(t){let e=t.match(/^[ \t]+/m);return e?e[0]:" "}function mse(t){return t.charCodeAt(0)===65279?t.slice(1):t}function ta(t){return t.replace(/\\/g,"/")}function kb(t,{yamlCompatibilityMode:e}){return e?AL(t):typeof t>"u"||typeof t=="boolean"?t:null}function yse(t,e){let r=e.search(/[^!]/);if(r===-1)return"invalid";let o=r%2===0?"":"!",a=e.slice(r);return`${o}${t}=${a}`}function ZM(t,e){return e.length===1?yse(t,e[0]):`(${e.map(r=>yse(t,r)).join(" | ")})`}var Ese,Ut,Gm=Et(()=>{Pt();Nl();Ese=Ze(Jn());mg();ql();Sf();So();Ut=class t{constructor(){this.indent=" ";this.name=null;this.version=null;this.os=null;this.cpu=null;this.libc=null;this.type=null;this.packageManager=null;this.private=!1;this.license=null;this.main=null;this.module=null;this.browser=null;this.languageName=null;this.bin=new Map;this.scripts=new Map;this.dependencies=new Map;this.devDependencies=new Map;this.peerDependencies=new Map;this.workspaceDefinitions=[];this.dependenciesMeta=new Map;this.peerDependenciesMeta=new Map;this.resolutions=[];this.files=null;this.publishConfig=null;this.installConfig=null;this.preferUnplugged=null;this.raw={};this.errors=[]}static{this.fileName="package.json"}static{this.allDependencies=["dependencies","devDependencies","peerDependencies"]}static{this.hardDependencies=["dependencies","devDependencies"]}static async tryFind(e,{baseFs:r=new Tn}={}){let o=V.join(e,"package.json");try{return await t.fromFile(o,{baseFs:r})}catch(a){if(a.code==="ENOENT")return null;throw a}}static async find(e,{baseFs:r}={}){let o=await t.tryFind(e,{baseFs:r});if(o===null)throw new Error("Manifest not found");return o}static async fromFile(e,{baseFs:r=new Tn}={}){let o=new t;return await o.loadFile(e,{baseFs:r}),o}static fromText(e){let r=new t;return r.loadFromText(e),r}loadFromText(e){let r;try{r=JSON.parse(mse(e)||"{}")}catch(o){throw o.message+=` (when parsing ${e})`,o}this.load(r),this.indent=dse(e)}async loadFile(e,{baseFs:r=new Tn}){let o=await r.readFilePromise(e,"utf8"),a;try{a=JSON.parse(mse(o)||"{}")}catch(n){throw n.message+=` (when parsing ${e})`,n}this.load(a),this.indent=dse(o)}load(e,{yamlCompatibilityMode:r=!1}={}){if(typeof e!="object"||e===null)throw new Error(`Utterly invalid manifest data (${e})`);this.raw=e;let o=[];if(this.name=null,typeof e.name=="string")try{this.name=ea(e.name)}catch{o.push(new Error("Parsing failed for the 'name' field"))}if(typeof e.version=="string"?this.version=e.version:this.version=null,Array.isArray(e.os)){let n=[];this.os=n;for(let u of e.os)typeof u!="string"?o.push(new Error("Parsing failed for the 'os' field")):n.push(u)}else this.os=null;if(Array.isArray(e.cpu)){let n=[];this.cpu=n;for(let u of e.cpu)typeof u!="string"?o.push(new Error("Parsing failed for the 'cpu' field")):n.push(u)}else this.cpu=null;if(Array.isArray(e.libc)){let n=[];this.libc=n;for(let u of e.libc)typeof u!="string"?o.push(new Error("Parsing failed for the 'libc' field")):n.push(u)}else this.libc=null;if(typeof e.type=="string"?this.type=e.type:this.type=null,typeof e.packageManager=="string"?this.packageManager=e.packageManager:this.packageManager=null,typeof e.private=="boolean"?this.private=e.private:this.private=!1,typeof e.license=="string"?this.license=e.license:this.license=null,typeof e.languageName=="string"?this.languageName=e.languageName:this.languageName=null,typeof e.main=="string"?this.main=ta(e.main):this.main=null,typeof e.module=="string"?this.module=ta(e.module):this.module=null,e.browser!=null)if(typeof e.browser=="string")this.browser=ta(e.browser);else{this.browser=new Map;for(let[n,u]of Object.entries(e.browser))this.browser.set(ta(n),typeof u=="string"?ta(u):u)}else this.browser=null;if(this.bin=new Map,typeof e.bin=="string")e.bin.trim()===""?o.push(new Error("Invalid bin field")):this.name!==null?this.bin.set(this.name.name,ta(e.bin)):o.push(new Error("String bin field, but no attached package name"));else if(typeof e.bin=="object"&&e.bin!==null)for(let[n,u]of Object.entries(e.bin)){if(typeof u!="string"||u.trim()===""){o.push(new Error(`Invalid bin definition for '${n}'`));continue}let A=ea(n);this.bin.set(A.name,ta(u))}if(this.scripts=new Map,typeof e.scripts=="object"&&e.scripts!==null)for(let[n,u]of Object.entries(e.scripts)){if(typeof u!="string"){o.push(new Error(`Invalid script definition for '${n}'`));continue}this.scripts.set(n,u)}if(this.dependencies=new Map,typeof e.dependencies=="object"&&e.dependencies!==null)for(let[n,u]of Object.entries(e.dependencies)){if(typeof u!="string"){o.push(new Error(`Invalid dependency range for '${n}'`));continue}let A;try{A=ea(n)}catch{o.push(new Error(`Parsing failed for the dependency name '${n}'`));continue}let p=In(A,u);this.dependencies.set(p.identHash,p)}if(this.devDependencies=new Map,typeof e.devDependencies=="object"&&e.devDependencies!==null)for(let[n,u]of Object.entries(e.devDependencies)){if(typeof u!="string"){o.push(new Error(`Invalid dependency range for '${n}'`));continue}let A;try{A=ea(n)}catch{o.push(new Error(`Parsing failed for the dependency name '${n}'`));continue}let p=In(A,u);this.devDependencies.set(p.identHash,p)}if(this.peerDependencies=new Map,typeof e.peerDependencies=="object"&&e.peerDependencies!==null)for(let[n,u]of Object.entries(e.peerDependencies)){let A;try{A=ea(n)}catch{o.push(new Error(`Parsing failed for the dependency name '${n}'`));continue}(typeof u!="string"||!u.startsWith(ei.protocol)&&!Qa(u))&&(o.push(new Error(`Invalid dependency range for '${n}'`)),u="*");let p=In(A,u);this.peerDependencies.set(p.identHash,p)}typeof e.workspaces=="object"&&e.workspaces!==null&&e.workspaces.nohoist&&o.push(new Error("'nohoist' is deprecated, please use 'installConfig.hoistingLimits' instead"));let a=Array.isArray(e.workspaces)?e.workspaces:typeof e.workspaces=="object"&&e.workspaces!==null&&Array.isArray(e.workspaces.packages)?e.workspaces.packages:[];this.workspaceDefinitions=[];for(let n of a){if(typeof n!="string"){o.push(new Error(`Invalid workspace definition for '${n}'`));continue}this.workspaceDefinitions.push({pattern:n})}if(this.dependenciesMeta=new Map,typeof e.dependenciesMeta=="object"&&e.dependenciesMeta!==null)for(let[n,u]of Object.entries(e.dependenciesMeta)){if(typeof u!="object"||u===null){o.push(new Error(`Invalid meta field for '${n}`));continue}let A=rh(n),p=this.ensureDependencyMeta(A),h=kb(u.built,{yamlCompatibilityMode:r});if(h===null){o.push(new Error(`Invalid built meta field for '${n}'`));continue}let E=kb(u.optional,{yamlCompatibilityMode:r});if(E===null){o.push(new Error(`Invalid optional meta field for '${n}'`));continue}let I=kb(u.unplugged,{yamlCompatibilityMode:r});if(I===null){o.push(new Error(`Invalid unplugged meta field for '${n}'`));continue}Object.assign(p,{built:h,optional:E,unplugged:I})}if(this.peerDependenciesMeta=new Map,typeof e.peerDependenciesMeta=="object"&&e.peerDependenciesMeta!==null)for(let[n,u]of Object.entries(e.peerDependenciesMeta)){if(typeof u!="object"||u===null){o.push(new Error(`Invalid meta field for '${n}'`));continue}let A=rh(n),p=this.ensurePeerDependencyMeta(A),h=kb(u.optional,{yamlCompatibilityMode:r});if(h===null){o.push(new Error(`Invalid optional meta field for '${n}'`));continue}Object.assign(p,{optional:h})}if(this.resolutions=[],typeof e.resolutions=="object"&&e.resolutions!==null)for(let[n,u]of Object.entries(e.resolutions)){if(typeof u!="string"){o.push(new Error(`Invalid resolution entry for '${n}'`));continue}try{this.resolutions.push({pattern:BD(n),reference:u})}catch(A){o.push(A);continue}}if(Array.isArray(e.files)){this.files=new Set;for(let n of e.files){if(typeof n!="string"){o.push(new Error(`Invalid files entry for '${n}'`));continue}this.files.add(n)}}else this.files=null;if(typeof e.publishConfig=="object"&&e.publishConfig!==null){if(this.publishConfig={},typeof e.publishConfig.access=="string"&&(this.publishConfig.access=e.publishConfig.access),typeof e.publishConfig.main=="string"&&(this.publishConfig.main=ta(e.publishConfig.main)),typeof e.publishConfig.module=="string"&&(this.publishConfig.module=ta(e.publishConfig.module)),e.publishConfig.browser!=null)if(typeof e.publishConfig.browser=="string")this.publishConfig.browser=ta(e.publishConfig.browser);else{this.publishConfig.browser=new Map;for(let[n,u]of Object.entries(e.publishConfig.browser))this.publishConfig.browser.set(ta(n),typeof u=="string"?ta(u):u)}if(typeof e.publishConfig.registry=="string"&&(this.publishConfig.registry=e.publishConfig.registry),typeof e.publishConfig.bin=="string")this.name!==null?this.publishConfig.bin=new Map([[this.name.name,ta(e.publishConfig.bin)]]):o.push(new Error("String bin field, but no attached package name"));else if(typeof e.publishConfig.bin=="object"&&e.publishConfig.bin!==null){this.publishConfig.bin=new Map;for(let[n,u]of Object.entries(e.publishConfig.bin)){if(typeof u!="string"){o.push(new Error(`Invalid bin definition for '${n}'`));continue}this.publishConfig.bin.set(n,ta(u))}}if(Array.isArray(e.publishConfig.executableFiles)){this.publishConfig.executableFiles=new Set;for(let n of e.publishConfig.executableFiles){if(typeof n!="string"){o.push(new Error("Invalid executable file definition"));continue}this.publishConfig.executableFiles.add(ta(n))}}}else this.publishConfig=null;if(typeof e.installConfig=="object"&&e.installConfig!==null){this.installConfig={};for(let n of Object.keys(e.installConfig))n==="hoistingLimits"?typeof e.installConfig.hoistingLimits=="string"?this.installConfig.hoistingLimits=e.installConfig.hoistingLimits:o.push(new Error("Invalid hoisting limits definition")):n=="selfReferences"?typeof e.installConfig.selfReferences=="boolean"?this.installConfig.selfReferences=e.installConfig.selfReferences:o.push(new Error("Invalid selfReferences definition, must be a boolean value")):o.push(new Error(`Unrecognized installConfig key: ${n}`))}else this.installConfig=null;if(typeof e.optionalDependencies=="object"&&e.optionalDependencies!==null)for(let[n,u]of Object.entries(e.optionalDependencies)){if(typeof u!="string"){o.push(new Error(`Invalid dependency range for '${n}'`));continue}let A;try{A=ea(n)}catch{o.push(new Error(`Parsing failed for the dependency name '${n}'`));continue}let p=In(A,u);this.dependencies.set(p.identHash,p);let h=In(A,"unknown"),E=this.ensureDependencyMeta(h);Object.assign(E,{optional:!0})}typeof e.preferUnplugged=="boolean"?this.preferUnplugged=e.preferUnplugged:this.preferUnplugged=null,this.errors=o}getForScope(e){switch(e){case"dependencies":return this.dependencies;case"devDependencies":return this.devDependencies;case"peerDependencies":return this.peerDependencies;default:throw new Error(`Unsupported value ("${e}")`)}}hasConsumerDependency(e){return!!(this.dependencies.has(e.identHash)||this.peerDependencies.has(e.identHash))}hasHardDependency(e){return!!(this.dependencies.has(e.identHash)||this.devDependencies.has(e.identHash))}hasSoftDependency(e){return!!this.peerDependencies.has(e.identHash)}hasDependency(e){return!!(this.hasHardDependency(e)||this.hasSoftDependency(e))}getConditions(){let e=[];return this.os&&this.os.length>0&&e.push(ZM("os",this.os)),this.cpu&&this.cpu.length>0&&e.push(ZM("cpu",this.cpu)),this.libc&&this.libc.length>0&&e.push(ZM("libc",this.libc)),e.length>0?e.join(" & "):null}ensureDependencyMeta(e){if(e.range!=="unknown"&&!Ese.default.valid(e.range))throw new Error(`Invalid meta field range for '${xa(e)}'`);let r=rn(e),o=e.range!=="unknown"?e.range:null,a=this.dependenciesMeta.get(r);a||this.dependenciesMeta.set(r,a=new Map);let n=a.get(o);return n||a.set(o,n={}),n}ensurePeerDependencyMeta(e){if(e.range!=="unknown")throw new Error(`Invalid meta field range for '${xa(e)}'`);let r=rn(e),o=this.peerDependenciesMeta.get(r);return o||this.peerDependenciesMeta.set(r,o={}),o}setRawField(e,r,{after:o=[]}={}){let a=new Set(o.filter(n=>Object.hasOwn(this.raw,n)));if(a.size===0||Object.hasOwn(this.raw,e))this.raw[e]=r;else{let n=this.raw,u=this.raw={},A=!1;for(let p of Object.keys(n))u[p]=n[p],A||(a.delete(p),a.size===0&&(u[e]=r,A=!0))}}exportTo(e,{compatibilityMode:r=!0}={}){if(Object.assign(e,this.raw),this.name!==null?e.name=rn(this.name):delete e.name,this.version!==null?e.version=this.version:delete e.version,this.os!==null?e.os=this.os:delete e.os,this.cpu!==null?e.cpu=this.cpu:delete e.cpu,this.type!==null?e.type=this.type:delete e.type,this.packageManager!==null?e.packageManager=this.packageManager:delete e.packageManager,this.private?e.private=!0:delete e.private,this.license!==null?e.license=this.license:delete e.license,this.languageName!==null?e.languageName=this.languageName:delete e.languageName,this.main!==null?e.main=this.main:delete e.main,this.module!==null?e.module=this.module:delete e.module,this.browser!==null){let n=this.browser;typeof n=="string"?e.browser=n:n instanceof Map&&(e.browser=Object.assign({},...Array.from(n.keys()).sort().map(u=>({[u]:n.get(u)}))))}else delete e.browser;this.bin.size===1&&this.name!==null&&this.bin.has(this.name.name)?e.bin=this.bin.get(this.name.name):this.bin.size>0?e.bin=Object.assign({},...Array.from(this.bin.keys()).sort().map(n=>({[n]:this.bin.get(n)}))):delete e.bin,this.workspaceDefinitions.length>0?this.raw.workspaces&&!Array.isArray(this.raw.workspaces)?e.workspaces={...this.raw.workspaces,packages:this.workspaceDefinitions.map(({pattern:n})=>n)}:e.workspaces=this.workspaceDefinitions.map(({pattern:n})=>n):this.raw.workspaces&&!Array.isArray(this.raw.workspaces)&&Object.keys(this.raw.workspaces).length>0?e.workspaces=this.raw.workspaces:delete e.workspaces;let o=[],a=[];for(let n of this.dependencies.values()){let u=this.dependenciesMeta.get(rn(n)),A=!1;if(r&&u){let p=u.get(null);p&&p.optional&&(A=!0)}A?a.push(n):o.push(n)}o.length>0?e.dependencies=Object.assign({},...jm(o).map(n=>({[rn(n)]:n.range}))):delete e.dependencies,a.length>0?e.optionalDependencies=Object.assign({},...jm(a).map(n=>({[rn(n)]:n.range}))):delete e.optionalDependencies,this.devDependencies.size>0?e.devDependencies=Object.assign({},...jm(this.devDependencies.values()).map(n=>({[rn(n)]:n.range}))):delete e.devDependencies,this.peerDependencies.size>0?e.peerDependencies=Object.assign({},...jm(this.peerDependencies.values()).map(n=>({[rn(n)]:n.range}))):delete e.peerDependencies,e.dependenciesMeta={};for(let[n,u]of Fs(this.dependenciesMeta.entries(),([A,p])=>A))for(let[A,p]of Fs(u.entries(),([h,E])=>h!==null?`0${h}`:"1")){let h=A!==null?xa(In(ea(n),A)):n,E={...p};r&&A===null&&delete E.optional,Object.keys(E).length!==0&&(e.dependenciesMeta[h]=E)}if(Object.keys(e.dependenciesMeta).length===0&&delete e.dependenciesMeta,this.peerDependenciesMeta.size>0?e.peerDependenciesMeta=Object.assign({},...Fs(this.peerDependenciesMeta.entries(),([n,u])=>n).map(([n,u])=>({[n]:u}))):delete e.peerDependenciesMeta,this.resolutions.length>0?e.resolutions=Object.assign({},...this.resolutions.map(({pattern:n,reference:u})=>({[vD(n)]:u}))):delete e.resolutions,this.files!==null?e.files=Array.from(this.files):delete e.files,this.preferUnplugged!==null?e.preferUnplugged=this.preferUnplugged:delete e.preferUnplugged,this.scripts!==null&&this.scripts.size>0){e.scripts??={};for(let n of Object.keys(e.scripts))this.scripts.has(n)||delete e.scripts[n];for(let[n,u]of this.scripts.entries())e.scripts[n]=u}else delete e.scripts;return e}}});var wse=_((YNt,Cse)=>{var Ztt=_l(),$tt=function(){return Ztt.Date.now()};Cse.exports=$tt});var Bse=_((WNt,Ise)=>{var ert=/\s/;function trt(t){for(var e=t.length;e--&&ert.test(t.charAt(e)););return e}Ise.exports=trt});var Dse=_((KNt,vse)=>{var rrt=Bse(),nrt=/^\s+/;function irt(t){return t&&t.slice(0,rrt(t)+1).replace(nrt,"")}vse.exports=irt});var Ym=_((VNt,Pse)=>{var srt=cg(),ort=Ju(),art="[object Symbol]";function lrt(t){return typeof t=="symbol"||ort(t)&&srt(t)==art}Pse.exports=lrt});var kse=_((zNt,xse)=>{var crt=Dse(),bse=sl(),urt=Ym(),Sse=NaN,Art=/^[-+]0x[0-9a-f]+$/i,frt=/^0b[01]+$/i,prt=/^0o[0-7]+$/i,hrt=parseInt;function grt(t){if(typeof t=="number")return t;if(urt(t))return Sse;if(bse(t)){var e=typeof t.valueOf=="function"?t.valueOf():t;t=bse(e)?e+"":e}if(typeof t!="string")return t===0?t:+t;t=crt(t);var r=frt.test(t);return r||prt.test(t)?hrt(t.slice(2),r?2:8):Art.test(t)?Sse:+t}xse.exports=grt});var Rse=_((JNt,Fse)=>{var drt=sl(),$M=wse(),Qse=kse(),mrt="Expected a function",yrt=Math.max,Ert=Math.min;function Crt(t,e,r){var o,a,n,u,A,p,h=0,E=!1,I=!1,v=!0;if(typeof t!="function")throw new TypeError(mrt);e=Qse(e)||0,drt(r)&&(E=!!r.leading,I="maxWait"in r,n=I?yrt(Qse(r.maxWait)||0,e):n,v="trailing"in r?!!r.trailing:v);function x(ce){var Ce=o,de=a;return o=a=void 0,h=ce,u=t.apply(de,Ce),u}function C(ce){return h=ce,A=setTimeout(U,e),E?x(ce):u}function R(ce){var Ce=ce-p,de=ce-h,Be=e-Ce;return I?Ert(Be,n-de):Be}function L(ce){var Ce=ce-p,de=ce-h;return p===void 0||Ce>=e||Ce<0||I&&de>=n}function U(){var ce=$M();if(L(ce))return z(ce);A=setTimeout(U,R(ce))}function z(ce){return A=void 0,v&&o?x(ce):(o=a=void 0,u)}function te(){A!==void 0&&clearTimeout(A),h=0,o=p=a=A=void 0}function ae(){return A===void 0?u:z($M())}function le(){var ce=$M(),Ce=L(ce);if(o=arguments,a=this,p=ce,Ce){if(A===void 0)return C(p);if(I)return clearTimeout(A),A=setTimeout(U,e),x(p)}return A===void 0&&(A=setTimeout(U,e)),u}return le.cancel=te,le.flush=ae,le}Fse.exports=Crt});var eO=_((XNt,Tse)=>{var wrt=Rse(),Irt=sl(),Brt="Expected a function";function vrt(t,e,r){var o=!0,a=!0;if(typeof t!="function")throw new TypeError(Brt);return Irt(r)&&(o="leading"in r?!!r.leading:o,a="trailing"in r?!!r.trailing:a),wrt(t,e,{leading:o,maxWait:e,trailing:a})}Tse.exports=vrt});function Prt(t){return typeof t.reportCode<"u"}var Nse,Lse,Mse,Drt,Jt,Zs,Wl=Et(()=>{Nse=Ze(eO()),Lse=ve("stream"),Mse=ve("string_decoder"),Drt=15,Jt=class extends Error{constructor(r,o,a){super(o);this.reportExtra=a;this.reportCode=r}};Zs=class{constructor(){this.cacheHits=new Set;this.cacheMisses=new Set;this.reportedInfos=new Set;this.reportedWarnings=new Set;this.reportedErrors=new Set}getRecommendedLength(){return 180}reportCacheHit(e){this.cacheHits.add(e.locatorHash)}reportCacheMiss(e,r){this.cacheMisses.add(e.locatorHash)}static progressViaCounter(e){let r=0,o,a=new Promise(p=>{o=p}),n=p=>{let h=o;a=new Promise(E=>{o=E}),r=p,h()},u=(p=0)=>{n(r+1)},A=async function*(){for(;r{r=u}),a=(0,Nse.default)(u=>{let A=r;o=new Promise(p=>{r=p}),e=u,A()},1e3/Drt),n=async function*(){for(;;)await o,yield{title:e}}();return{[Symbol.asyncIterator](){return n},hasProgress:!1,hasTitle:!0,setTitle:a}}async startProgressPromise(e,r){let o=this.reportProgress(e);try{return await r(e)}finally{o.stop()}}startProgressSync(e,r){let o=this.reportProgress(e);try{return r(e)}finally{o.stop()}}reportInfoOnce(e,r,o){let a=o&&o.key?o.key:r;this.reportedInfos.has(a)||(this.reportedInfos.add(a),this.reportInfo(e,r),o?.reportExtra?.(this))}reportWarningOnce(e,r,o){let a=o&&o.key?o.key:r;this.reportedWarnings.has(a)||(this.reportedWarnings.add(a),this.reportWarning(e,r),o?.reportExtra?.(this))}reportErrorOnce(e,r,o){let a=o&&o.key?o.key:r;this.reportedErrors.has(a)||(this.reportedErrors.add(a),this.reportError(e,r),o?.reportExtra?.(this))}reportExceptionOnce(e){Prt(e)?this.reportErrorOnce(e.reportCode,e.message,{key:e,reportExtra:e.reportExtra}):this.reportErrorOnce(1,e.stack||e.message,{key:e})}createStreamReporter(e=null){let r=new Lse.PassThrough,o=new Mse.StringDecoder,a="";return r.on("data",n=>{let u=o.write(n),A;do if(A=u.indexOf(` +`),A!==-1){let p=a+u.substring(0,A);u=u.substring(A+1),a="",e!==null?this.reportInfo(null,`${e} ${p}`):this.reportInfo(null,p)}while(A!==-1);a+=u}),r.on("end",()=>{let n=o.end();n!==""&&(e!==null?this.reportInfo(null,`${e} ${n}`):this.reportInfo(null,n))}),r}}});var Wm,tO=Et(()=>{Wl();So();Wm=class{constructor(e){this.fetchers=e}supports(e,r){return!!this.tryFetcher(e,r)}getLocalPath(e,r){return this.getFetcher(e,r).getLocalPath(e,r)}async fetch(e,r){return await this.getFetcher(e,r).fetch(e,r)}tryFetcher(e,r){let o=this.fetchers.find(a=>a.supports(e,r));return o||null}getFetcher(e,r){let o=this.fetchers.find(a=>a.supports(e,r));if(!o)throw new Jt(11,`${qr(r.project.configuration,e)} isn't supported by any available fetcher`);return o}}});var yg,rO=Et(()=>{So();yg=class{constructor(e){this.resolvers=e.filter(r=>r)}supportsDescriptor(e,r){return!!this.tryResolverByDescriptor(e,r)}supportsLocator(e,r){return!!this.tryResolverByLocator(e,r)}shouldPersistResolution(e,r){return this.getResolverByLocator(e,r).shouldPersistResolution(e,r)}bindDescriptor(e,r,o){return this.getResolverByDescriptor(e,o).bindDescriptor(e,r,o)}getResolutionDependencies(e,r){return this.getResolverByDescriptor(e,r).getResolutionDependencies(e,r)}async getCandidates(e,r,o){return await this.getResolverByDescriptor(e,o).getCandidates(e,r,o)}async getSatisfying(e,r,o,a){return this.getResolverByDescriptor(e,a).getSatisfying(e,r,o,a)}async resolve(e,r){return await this.getResolverByLocator(e,r).resolve(e,r)}tryResolverByDescriptor(e,r){let o=this.resolvers.find(a=>a.supportsDescriptor(e,r));return o||null}getResolverByDescriptor(e,r){let o=this.resolvers.find(a=>a.supportsDescriptor(e,r));if(!o)throw new Error(`${jn(r.project.configuration,e)} isn't supported by any available resolver`);return o}tryResolverByLocator(e,r){let o=this.resolvers.find(a=>a.supportsLocator(e,r));return o||null}getResolverByLocator(e,r){let o=this.resolvers.find(a=>a.supportsLocator(e,r));if(!o)throw new Error(`${qr(r.project.configuration,e)} isn't supported by any available resolver`);return o}}});var Km,nO=Et(()=>{Pt();So();Km=class{supports(e){return!!e.reference.startsWith("virtual:")}getLocalPath(e,r){let o=e.reference.indexOf("#");if(o===-1)throw new Error("Invalid virtual package reference");let a=e.reference.slice(o+1),n=Rs(e,a);return r.fetcher.getLocalPath(n,r)}async fetch(e,r){let o=e.reference.indexOf("#");if(o===-1)throw new Error("Invalid virtual package reference");let a=e.reference.slice(o+1),n=Rs(e,a),u=await r.fetcher.fetch(n,r);return await this.ensureVirtualLink(e,u,r)}getLocatorFilename(e){return Hm(e)}async ensureVirtualLink(e,r,o){let a=r.packageFs.getRealPath(),n=o.project.configuration.get("virtualFolder"),u=this.getLocatorFilename(e),A=zs.makeVirtualPath(n,u,a),p=new Hu(A,{baseFs:r.packageFs,pathUtils:V});return{...r,packageFs:p}}}});var Qb,Ose=Et(()=>{Qb=class t{static{this.protocol="virtual:"}static isVirtualDescriptor(e){return!!e.range.startsWith(t.protocol)}static isVirtualLocator(e){return!!e.reference.startsWith(t.protocol)}supportsDescriptor(e,r){return t.isVirtualDescriptor(e)}supportsLocator(e,r){return t.isVirtualLocator(e)}shouldPersistResolution(e,r){return!1}bindDescriptor(e,r,o){throw new Error('Assertion failed: calling "bindDescriptor" on a virtual descriptor is unsupported')}getResolutionDependencies(e,r){throw new Error('Assertion failed: calling "getResolutionDependencies" on a virtual descriptor is unsupported')}async getCandidates(e,r,o){throw new Error('Assertion failed: calling "getCandidates" on a virtual descriptor is unsupported')}async getSatisfying(e,r,o,a){throw new Error('Assertion failed: calling "getSatisfying" on a virtual descriptor is unsupported')}async resolve(e,r){throw new Error('Assertion failed: calling "resolve" on a virtual locator is unsupported')}}});var Vm,iO=Et(()=>{Pt();mg();Vm=class{supports(e){return!!e.reference.startsWith(ei.protocol)}getLocalPath(e,r){return this.getWorkspace(e,r).cwd}async fetch(e,r){let o=this.getWorkspace(e,r).cwd;return{packageFs:new gn(o),prefixPath:It.dot,localPath:o}}getWorkspace(e,r){return r.project.getWorkspaceByCwd(e.reference.slice(ei.protocol.length))}}});function KI(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function Use(t){return typeof t>"u"?3:KI(t)?0:Array.isArray(t)?1:2}function aO(t,e){return Object.hasOwn(t,e)}function Srt(t){return KI(t)&&aO(t,"onConflict")&&typeof t.onConflict=="string"}function xrt(t){if(typeof t>"u")return{onConflict:"default",value:t};if(!Srt(t))return{onConflict:"default",value:t};if(aO(t,"value"))return t;let{onConflict:e,...r}=t;return{onConflict:e,value:r}}function _se(t,e){let r=KI(t)&&aO(t,e)?t[e]:void 0;return xrt(r)}function zm(t,e){return[t,e,Hse]}function lO(t){return Array.isArray(t)?t[2]===Hse:!1}function sO(t,e){if(KI(t)){let r={};for(let o of Object.keys(t))r[o]=sO(t[o],e);return zm(e,r)}return Array.isArray(t)?zm(e,t.map(r=>sO(r,e))):zm(e,t)}function oO(t,e,r,o,a){let n,u=[],A=a,p=0;for(let E=a-1;E>=o;--E){let[I,v]=t[E],{onConflict:x,value:C}=_se(v,r),R=Use(C);if(R!==3){if(n??=R,R!==n||x==="hardReset"){p=A;break}if(R===2)return zm(I,C);if(u.unshift([I,C]),x==="reset"){p=E;break}x==="extend"&&E===o&&(o=0),A=E}}if(typeof n>"u")return null;let h=u.map(([E])=>E).join(", ");switch(n){case 1:return zm(h,new Array().concat(...u.map(([E,I])=>I.map(v=>sO(v,E)))));case 0:{let E=Object.assign({},...u.map(([,R])=>R)),I=Object.keys(E),v={},x=t.map(([R,L])=>[R,_se(L,r).value]),C=brt(x,([R,L])=>{let U=Use(L);return U!==0&&U!==3});if(C!==-1){let R=x.slice(C+1);for(let L of I)v[L]=oO(R,e,L,0,R.length)}else for(let R of I)v[R]=oO(x,e,R,p,x.length);return zm(h,v)}default:throw new Error("Assertion failed: Non-extendable value type")}}function qse(t){return oO(t.map(([e,r])=>[e,{".":r}]),[],".",0,t.length)}function VI(t){return lO(t)?t[1]:t}function Fb(t){let e=lO(t)?t[1]:t;if(Array.isArray(e))return e.map(r=>Fb(r));if(KI(e)){let r={};for(let[o,a]of Object.entries(e))r[o]=Fb(a);return r}return e}function cO(t){return lO(t)?t[0]:null}var brt,Hse,jse=Et(()=>{brt=(t,e,r)=>{let o=[...t];return o.reverse(),o.findIndex(e,r)};Hse=Symbol()});var Rb={};Vt(Rb,{getDefaultGlobalFolder:()=>AO,getHomeFolder:()=>Jm,isFolderInside:()=>fO});function AO(){if(process.platform==="win32"){let t=ue.toPortablePath(process.env.LOCALAPPDATA||ue.join((0,uO.homedir)(),"AppData","Local"));return V.resolve(t,"Yarn/Berry")}if(process.env.XDG_DATA_HOME){let t=ue.toPortablePath(process.env.XDG_DATA_HOME);return V.resolve(t,"yarn/berry")}return V.resolve(Jm(),".yarn/berry")}function Jm(){return ue.toPortablePath((0,uO.homedir)()||"/usr/local/share")}function fO(t,e){let r=V.relative(e,t);return r&&!r.startsWith("..")&&!V.isAbsolute(r)}var uO,Tb=Et(()=>{Pt();uO=ve("os")});var Kse=_(Xm=>{"use strict";var uLt=ve("net"),Qrt=ve("tls"),pO=ve("http"),Gse=ve("https"),Frt=ve("events"),ALt=ve("assert"),Rrt=ve("util");Xm.httpOverHttp=Trt;Xm.httpsOverHttp=Nrt;Xm.httpOverHttps=Lrt;Xm.httpsOverHttps=Mrt;function Trt(t){var e=new xf(t);return e.request=pO.request,e}function Nrt(t){var e=new xf(t);return e.request=pO.request,e.createSocket=Yse,e.defaultPort=443,e}function Lrt(t){var e=new xf(t);return e.request=Gse.request,e}function Mrt(t){var e=new xf(t);return e.request=Gse.request,e.createSocket=Yse,e.defaultPort=443,e}function xf(t){var e=this;e.options=t||{},e.proxyOptions=e.options.proxy||{},e.maxSockets=e.options.maxSockets||pO.Agent.defaultMaxSockets,e.requests=[],e.sockets=[],e.on("free",function(o,a,n,u){for(var A=Wse(a,n,u),p=0,h=e.requests.length;p=this.maxSockets){n.requests.push(u);return}n.createSocket(u,function(A){A.on("free",p),A.on("close",h),A.on("agentRemove",h),e.onSocket(A);function p(){n.emit("free",A,u)}function h(E){n.removeSocket(A),A.removeListener("free",p),A.removeListener("close",h),A.removeListener("agentRemove",h)}})};xf.prototype.createSocket=function(e,r){var o=this,a={};o.sockets.push(a);var n=hO({},o.proxyOptions,{method:"CONNECT",path:e.host+":"+e.port,agent:!1,headers:{host:e.host+":"+e.port}});e.localAddress&&(n.localAddress=e.localAddress),n.proxyAuth&&(n.headers=n.headers||{},n.headers["Proxy-Authorization"]="Basic "+new Buffer(n.proxyAuth).toString("base64")),ih("making CONNECT request");var u=o.request(n);u.useChunkedEncodingByDefault=!1,u.once("response",A),u.once("upgrade",p),u.once("connect",h),u.once("error",E),u.end();function A(I){I.upgrade=!0}function p(I,v,x){process.nextTick(function(){h(I,v,x)})}function h(I,v,x){if(u.removeAllListeners(),v.removeAllListeners(),I.statusCode!==200){ih("tunneling socket could not be established, statusCode=%d",I.statusCode),v.destroy();var C=new Error("tunneling socket could not be established, statusCode="+I.statusCode);C.code="ECONNRESET",e.request.emit("error",C),o.removeSocket(a);return}if(x.length>0){ih("got illegal response body from proxy"),v.destroy();var C=new Error("got illegal response body from proxy");C.code="ECONNRESET",e.request.emit("error",C),o.removeSocket(a);return}return ih("tunneling connection has established"),o.sockets[o.sockets.indexOf(a)]=v,r(v)}function E(I){u.removeAllListeners(),ih(`tunneling socket could not be established, cause=%s +`,I.message,I.stack);var v=new Error("tunneling socket could not be established, cause="+I.message);v.code="ECONNRESET",e.request.emit("error",v),o.removeSocket(a)}};xf.prototype.removeSocket=function(e){var r=this.sockets.indexOf(e);if(r!==-1){this.sockets.splice(r,1);var o=this.requests.shift();o&&this.createSocket(o,function(a){o.request.onSocket(a)})}};function Yse(t,e){var r=this;xf.prototype.createSocket.call(r,t,function(o){var a=t.request.getHeader("host"),n=hO({},r.options,{socket:o,servername:a?a.replace(/:.*$/,""):t.host}),u=Qrt.connect(0,n);r.sockets[r.sockets.indexOf(o)]=u,e(u)})}function Wse(t,e,r){return typeof t=="string"?{host:t,port:e,localAddress:r}:t}function hO(t){for(var e=1,r=arguments.length;e{Vse.exports=Kse()});var Qf=_((kf,Nb)=>{"use strict";Object.defineProperty(kf,"__esModule",{value:!0});var Jse=["Int8Array","Uint8Array","Uint8ClampedArray","Int16Array","Uint16Array","Int32Array","Uint32Array","Float32Array","Float64Array","BigInt64Array","BigUint64Array"];function Ort(t){return Jse.includes(t)}var Urt=["Function","Generator","AsyncGenerator","GeneratorFunction","AsyncGeneratorFunction","AsyncFunction","Observable","Array","Buffer","Blob","Object","RegExp","Date","Error","Map","Set","WeakMap","WeakSet","ArrayBuffer","SharedArrayBuffer","DataView","Promise","URL","FormData","URLSearchParams","HTMLElement",...Jse];function _rt(t){return Urt.includes(t)}var Hrt=["null","undefined","string","number","bigint","boolean","symbol"];function qrt(t){return Hrt.includes(t)}function Zm(t){return e=>typeof e===t}var{toString:Xse}=Object.prototype,zI=t=>{let e=Xse.call(t).slice(8,-1);if(/HTML\w+Element/.test(e)&&Pe.domElement(t))return"HTMLElement";if(_rt(e))return e},Xn=t=>e=>zI(e)===t;function Pe(t){if(t===null)return"null";switch(typeof t){case"undefined":return"undefined";case"string":return"string";case"number":return"number";case"boolean":return"boolean";case"function":return"Function";case"bigint":return"bigint";case"symbol":return"symbol";default:}if(Pe.observable(t))return"Observable";if(Pe.array(t))return"Array";if(Pe.buffer(t))return"Buffer";let e=zI(t);if(e)return e;if(t instanceof String||t instanceof Boolean||t instanceof Number)throw new TypeError("Please don't use object wrappers for primitive types");return"Object"}Pe.undefined=Zm("undefined");Pe.string=Zm("string");var jrt=Zm("number");Pe.number=t=>jrt(t)&&!Pe.nan(t);Pe.bigint=Zm("bigint");Pe.function_=Zm("function");Pe.null_=t=>t===null;Pe.class_=t=>Pe.function_(t)&&t.toString().startsWith("class ");Pe.boolean=t=>t===!0||t===!1;Pe.symbol=Zm("symbol");Pe.numericString=t=>Pe.string(t)&&!Pe.emptyStringOrWhitespace(t)&&!Number.isNaN(Number(t));Pe.array=(t,e)=>Array.isArray(t)?Pe.function_(e)?t.every(e):!0:!1;Pe.buffer=t=>{var e,r,o,a;return(a=(o=(r=(e=t)===null||e===void 0?void 0:e.constructor)===null||r===void 0?void 0:r.isBuffer)===null||o===void 0?void 0:o.call(r,t))!==null&&a!==void 0?a:!1};Pe.blob=t=>Xn("Blob")(t);Pe.nullOrUndefined=t=>Pe.null_(t)||Pe.undefined(t);Pe.object=t=>!Pe.null_(t)&&(typeof t=="object"||Pe.function_(t));Pe.iterable=t=>{var e;return Pe.function_((e=t)===null||e===void 0?void 0:e[Symbol.iterator])};Pe.asyncIterable=t=>{var e;return Pe.function_((e=t)===null||e===void 0?void 0:e[Symbol.asyncIterator])};Pe.generator=t=>{var e,r;return Pe.iterable(t)&&Pe.function_((e=t)===null||e===void 0?void 0:e.next)&&Pe.function_((r=t)===null||r===void 0?void 0:r.throw)};Pe.asyncGenerator=t=>Pe.asyncIterable(t)&&Pe.function_(t.next)&&Pe.function_(t.throw);Pe.nativePromise=t=>Xn("Promise")(t);var Grt=t=>{var e,r;return Pe.function_((e=t)===null||e===void 0?void 0:e.then)&&Pe.function_((r=t)===null||r===void 0?void 0:r.catch)};Pe.promise=t=>Pe.nativePromise(t)||Grt(t);Pe.generatorFunction=Xn("GeneratorFunction");Pe.asyncGeneratorFunction=t=>zI(t)==="AsyncGeneratorFunction";Pe.asyncFunction=t=>zI(t)==="AsyncFunction";Pe.boundFunction=t=>Pe.function_(t)&&!t.hasOwnProperty("prototype");Pe.regExp=Xn("RegExp");Pe.date=Xn("Date");Pe.error=Xn("Error");Pe.map=t=>Xn("Map")(t);Pe.set=t=>Xn("Set")(t);Pe.weakMap=t=>Xn("WeakMap")(t);Pe.weakSet=t=>Xn("WeakSet")(t);Pe.int8Array=Xn("Int8Array");Pe.uint8Array=Xn("Uint8Array");Pe.uint8ClampedArray=Xn("Uint8ClampedArray");Pe.int16Array=Xn("Int16Array");Pe.uint16Array=Xn("Uint16Array");Pe.int32Array=Xn("Int32Array");Pe.uint32Array=Xn("Uint32Array");Pe.float32Array=Xn("Float32Array");Pe.float64Array=Xn("Float64Array");Pe.bigInt64Array=Xn("BigInt64Array");Pe.bigUint64Array=Xn("BigUint64Array");Pe.arrayBuffer=Xn("ArrayBuffer");Pe.sharedArrayBuffer=Xn("SharedArrayBuffer");Pe.dataView=Xn("DataView");Pe.enumCase=(t,e)=>Object.values(e).includes(t);Pe.directInstanceOf=(t,e)=>Object.getPrototypeOf(t)===e.prototype;Pe.urlInstance=t=>Xn("URL")(t);Pe.urlString=t=>{if(!Pe.string(t))return!1;try{return new URL(t),!0}catch{return!1}};Pe.truthy=t=>!!t;Pe.falsy=t=>!t;Pe.nan=t=>Number.isNaN(t);Pe.primitive=t=>Pe.null_(t)||qrt(typeof t);Pe.integer=t=>Number.isInteger(t);Pe.safeInteger=t=>Number.isSafeInteger(t);Pe.plainObject=t=>{if(Xse.call(t)!=="[object Object]")return!1;let e=Object.getPrototypeOf(t);return e===null||e===Object.getPrototypeOf({})};Pe.typedArray=t=>Ort(zI(t));var Yrt=t=>Pe.safeInteger(t)&&t>=0;Pe.arrayLike=t=>!Pe.nullOrUndefined(t)&&!Pe.function_(t)&&Yrt(t.length);Pe.inRange=(t,e)=>{if(Pe.number(e))return t>=Math.min(0,e)&&t<=Math.max(e,0);if(Pe.array(e)&&e.length===2)return t>=Math.min(...e)&&t<=Math.max(...e);throw new TypeError(`Invalid range: ${JSON.stringify(e)}`)};var Wrt=1,Krt=["innerHTML","ownerDocument","style","attributes","nodeValue"];Pe.domElement=t=>Pe.object(t)&&t.nodeType===Wrt&&Pe.string(t.nodeName)&&!Pe.plainObject(t)&&Krt.every(e=>e in t);Pe.observable=t=>{var e,r,o,a;return t?t===((r=(e=t)[Symbol.observable])===null||r===void 0?void 0:r.call(e))||t===((a=(o=t)["@@observable"])===null||a===void 0?void 0:a.call(o)):!1};Pe.nodeStream=t=>Pe.object(t)&&Pe.function_(t.pipe)&&!Pe.observable(t);Pe.infinite=t=>t===1/0||t===-1/0;var Zse=t=>e=>Pe.integer(e)&&Math.abs(e%2)===t;Pe.evenInteger=Zse(0);Pe.oddInteger=Zse(1);Pe.emptyArray=t=>Pe.array(t)&&t.length===0;Pe.nonEmptyArray=t=>Pe.array(t)&&t.length>0;Pe.emptyString=t=>Pe.string(t)&&t.length===0;var Vrt=t=>Pe.string(t)&&!/\S/.test(t);Pe.emptyStringOrWhitespace=t=>Pe.emptyString(t)||Vrt(t);Pe.nonEmptyString=t=>Pe.string(t)&&t.length>0;Pe.nonEmptyStringAndNotWhitespace=t=>Pe.string(t)&&!Pe.emptyStringOrWhitespace(t);Pe.emptyObject=t=>Pe.object(t)&&!Pe.map(t)&&!Pe.set(t)&&Object.keys(t).length===0;Pe.nonEmptyObject=t=>Pe.object(t)&&!Pe.map(t)&&!Pe.set(t)&&Object.keys(t).length>0;Pe.emptySet=t=>Pe.set(t)&&t.size===0;Pe.nonEmptySet=t=>Pe.set(t)&&t.size>0;Pe.emptyMap=t=>Pe.map(t)&&t.size===0;Pe.nonEmptyMap=t=>Pe.map(t)&&t.size>0;Pe.propertyKey=t=>Pe.any([Pe.string,Pe.number,Pe.symbol],t);Pe.formData=t=>Xn("FormData")(t);Pe.urlSearchParams=t=>Xn("URLSearchParams")(t);var $se=(t,e,r)=>{if(!Pe.function_(e))throw new TypeError(`Invalid predicate: ${JSON.stringify(e)}`);if(r.length===0)throw new TypeError("Invalid number of values");return t.call(r,e)};Pe.any=(t,...e)=>(Pe.array(t)?t:[t]).some(o=>$se(Array.prototype.some,o,e));Pe.all=(t,...e)=>$se(Array.prototype.every,t,e);var Mt=(t,e,r,o={})=>{if(!t){let{multipleValues:a}=o,n=a?`received values of types ${[...new Set(r.map(u=>`\`${Pe(u)}\``))].join(", ")}`:`received value of type \`${Pe(r)}\``;throw new TypeError(`Expected value which is \`${e}\`, ${n}.`)}};kf.assert={undefined:t=>Mt(Pe.undefined(t),"undefined",t),string:t=>Mt(Pe.string(t),"string",t),number:t=>Mt(Pe.number(t),"number",t),bigint:t=>Mt(Pe.bigint(t),"bigint",t),function_:t=>Mt(Pe.function_(t),"Function",t),null_:t=>Mt(Pe.null_(t),"null",t),class_:t=>Mt(Pe.class_(t),"Class",t),boolean:t=>Mt(Pe.boolean(t),"boolean",t),symbol:t=>Mt(Pe.symbol(t),"symbol",t),numericString:t=>Mt(Pe.numericString(t),"string with a number",t),array:(t,e)=>{Mt(Pe.array(t),"Array",t),e&&t.forEach(e)},buffer:t=>Mt(Pe.buffer(t),"Buffer",t),blob:t=>Mt(Pe.blob(t),"Blob",t),nullOrUndefined:t=>Mt(Pe.nullOrUndefined(t),"null or undefined",t),object:t=>Mt(Pe.object(t),"Object",t),iterable:t=>Mt(Pe.iterable(t),"Iterable",t),asyncIterable:t=>Mt(Pe.asyncIterable(t),"AsyncIterable",t),generator:t=>Mt(Pe.generator(t),"Generator",t),asyncGenerator:t=>Mt(Pe.asyncGenerator(t),"AsyncGenerator",t),nativePromise:t=>Mt(Pe.nativePromise(t),"native Promise",t),promise:t=>Mt(Pe.promise(t),"Promise",t),generatorFunction:t=>Mt(Pe.generatorFunction(t),"GeneratorFunction",t),asyncGeneratorFunction:t=>Mt(Pe.asyncGeneratorFunction(t),"AsyncGeneratorFunction",t),asyncFunction:t=>Mt(Pe.asyncFunction(t),"AsyncFunction",t),boundFunction:t=>Mt(Pe.boundFunction(t),"Function",t),regExp:t=>Mt(Pe.regExp(t),"RegExp",t),date:t=>Mt(Pe.date(t),"Date",t),error:t=>Mt(Pe.error(t),"Error",t),map:t=>Mt(Pe.map(t),"Map",t),set:t=>Mt(Pe.set(t),"Set",t),weakMap:t=>Mt(Pe.weakMap(t),"WeakMap",t),weakSet:t=>Mt(Pe.weakSet(t),"WeakSet",t),int8Array:t=>Mt(Pe.int8Array(t),"Int8Array",t),uint8Array:t=>Mt(Pe.uint8Array(t),"Uint8Array",t),uint8ClampedArray:t=>Mt(Pe.uint8ClampedArray(t),"Uint8ClampedArray",t),int16Array:t=>Mt(Pe.int16Array(t),"Int16Array",t),uint16Array:t=>Mt(Pe.uint16Array(t),"Uint16Array",t),int32Array:t=>Mt(Pe.int32Array(t),"Int32Array",t),uint32Array:t=>Mt(Pe.uint32Array(t),"Uint32Array",t),float32Array:t=>Mt(Pe.float32Array(t),"Float32Array",t),float64Array:t=>Mt(Pe.float64Array(t),"Float64Array",t),bigInt64Array:t=>Mt(Pe.bigInt64Array(t),"BigInt64Array",t),bigUint64Array:t=>Mt(Pe.bigUint64Array(t),"BigUint64Array",t),arrayBuffer:t=>Mt(Pe.arrayBuffer(t),"ArrayBuffer",t),sharedArrayBuffer:t=>Mt(Pe.sharedArrayBuffer(t),"SharedArrayBuffer",t),dataView:t=>Mt(Pe.dataView(t),"DataView",t),enumCase:(t,e)=>Mt(Pe.enumCase(t,e),"EnumCase",t),urlInstance:t=>Mt(Pe.urlInstance(t),"URL",t),urlString:t=>Mt(Pe.urlString(t),"string with a URL",t),truthy:t=>Mt(Pe.truthy(t),"truthy",t),falsy:t=>Mt(Pe.falsy(t),"falsy",t),nan:t=>Mt(Pe.nan(t),"NaN",t),primitive:t=>Mt(Pe.primitive(t),"primitive",t),integer:t=>Mt(Pe.integer(t),"integer",t),safeInteger:t=>Mt(Pe.safeInteger(t),"integer",t),plainObject:t=>Mt(Pe.plainObject(t),"plain object",t),typedArray:t=>Mt(Pe.typedArray(t),"TypedArray",t),arrayLike:t=>Mt(Pe.arrayLike(t),"array-like",t),domElement:t=>Mt(Pe.domElement(t),"HTMLElement",t),observable:t=>Mt(Pe.observable(t),"Observable",t),nodeStream:t=>Mt(Pe.nodeStream(t),"Node.js Stream",t),infinite:t=>Mt(Pe.infinite(t),"infinite number",t),emptyArray:t=>Mt(Pe.emptyArray(t),"empty array",t),nonEmptyArray:t=>Mt(Pe.nonEmptyArray(t),"non-empty array",t),emptyString:t=>Mt(Pe.emptyString(t),"empty string",t),emptyStringOrWhitespace:t=>Mt(Pe.emptyStringOrWhitespace(t),"empty string or whitespace",t),nonEmptyString:t=>Mt(Pe.nonEmptyString(t),"non-empty string",t),nonEmptyStringAndNotWhitespace:t=>Mt(Pe.nonEmptyStringAndNotWhitespace(t),"non-empty string and not whitespace",t),emptyObject:t=>Mt(Pe.emptyObject(t),"empty object",t),nonEmptyObject:t=>Mt(Pe.nonEmptyObject(t),"non-empty object",t),emptySet:t=>Mt(Pe.emptySet(t),"empty set",t),nonEmptySet:t=>Mt(Pe.nonEmptySet(t),"non-empty set",t),emptyMap:t=>Mt(Pe.emptyMap(t),"empty map",t),nonEmptyMap:t=>Mt(Pe.nonEmptyMap(t),"non-empty map",t),propertyKey:t=>Mt(Pe.propertyKey(t),"PropertyKey",t),formData:t=>Mt(Pe.formData(t),"FormData",t),urlSearchParams:t=>Mt(Pe.urlSearchParams(t),"URLSearchParams",t),evenInteger:t=>Mt(Pe.evenInteger(t),"even integer",t),oddInteger:t=>Mt(Pe.oddInteger(t),"odd integer",t),directInstanceOf:(t,e)=>Mt(Pe.directInstanceOf(t,e),"T",t),inRange:(t,e)=>Mt(Pe.inRange(t,e),"in range",t),any:(t,...e)=>Mt(Pe.any(t,...e),"predicate returns truthy for any value",e,{multipleValues:!0}),all:(t,...e)=>Mt(Pe.all(t,...e),"predicate returns truthy for all values",e,{multipleValues:!0})};Object.defineProperties(Pe,{class:{value:Pe.class_},function:{value:Pe.function_},null:{value:Pe.null_}});Object.defineProperties(kf.assert,{class:{value:kf.assert.class_},function:{value:kf.assert.function_},null:{value:kf.assert.null_}});kf.default=Pe;Nb.exports=Pe;Nb.exports.default=Pe;Nb.exports.assert=kf.assert});var eoe=_((hLt,gO)=>{"use strict";var Lb=class extends Error{constructor(e){super(e||"Promise was canceled"),this.name="CancelError"}get isCanceled(){return!0}},Mb=class t{static fn(e){return(...r)=>new t((o,a,n)=>{r.push(n),e(...r).then(o,a)})}constructor(e){this._cancelHandlers=[],this._isPending=!0,this._isCanceled=!1,this._rejectOnCancel=!0,this._promise=new Promise((r,o)=>{this._reject=o;let a=A=>{this._isPending=!1,r(A)},n=A=>{this._isPending=!1,o(A)},u=A=>{if(!this._isPending)throw new Error("The `onCancel` handler was attached after the promise settled.");this._cancelHandlers.push(A)};return Object.defineProperties(u,{shouldReject:{get:()=>this._rejectOnCancel,set:A=>{this._rejectOnCancel=A}}}),e(a,n,u)})}then(e,r){return this._promise.then(e,r)}catch(e){return this._promise.catch(e)}finally(e){return this._promise.finally(e)}cancel(e){if(!(!this._isPending||this._isCanceled)){if(this._cancelHandlers.length>0)try{for(let r of this._cancelHandlers)r()}catch(r){this._reject(r)}this._isCanceled=!0,this._rejectOnCancel&&this._reject(new Lb(e))}}get isCanceled(){return this._isCanceled}};Object.setPrototypeOf(Mb.prototype,Promise.prototype);gO.exports=Mb;gO.exports.CancelError=Lb});var toe=_((mO,yO)=>{"use strict";Object.defineProperty(mO,"__esModule",{value:!0});function zrt(t){return t.encrypted}var dO=(t,e)=>{let r;typeof e=="function"?r={connect:e}:r=e;let o=typeof r.connect=="function",a=typeof r.secureConnect=="function",n=typeof r.close=="function",u=()=>{o&&r.connect(),zrt(t)&&a&&(t.authorized?r.secureConnect():t.authorizationError||t.once("secureConnect",r.secureConnect)),n&&t.once("close",r.close)};t.writable&&!t.connecting?u():t.connecting?t.once("connect",u):t.destroyed&&n&&r.close(t._hadError)};mO.default=dO;yO.exports=dO;yO.exports.default=dO});var roe=_((CO,wO)=>{"use strict";Object.defineProperty(CO,"__esModule",{value:!0});var Jrt=toe(),Xrt=Number(process.versions.node.split(".")[0]),EO=t=>{let e={start:Date.now(),socket:void 0,lookup:void 0,connect:void 0,secureConnect:void 0,upload:void 0,response:void 0,end:void 0,error:void 0,abort:void 0,phases:{wait:void 0,dns:void 0,tcp:void 0,tls:void 0,request:void 0,firstByte:void 0,download:void 0,total:void 0}};t.timings=e;let r=u=>{let A=u.emit.bind(u);u.emit=(p,...h)=>(p==="error"&&(e.error=Date.now(),e.phases.total=e.error-e.start,u.emit=A),A(p,...h))};r(t),t.prependOnceListener("abort",()=>{e.abort=Date.now(),(!e.response||Xrt>=13)&&(e.phases.total=Date.now()-e.start)});let o=u=>{e.socket=Date.now(),e.phases.wait=e.socket-e.start;let A=()=>{e.lookup=Date.now(),e.phases.dns=e.lookup-e.socket};u.prependOnceListener("lookup",A),Jrt.default(u,{connect:()=>{e.connect=Date.now(),e.lookup===void 0&&(u.removeListener("lookup",A),e.lookup=e.connect,e.phases.dns=e.lookup-e.socket),e.phases.tcp=e.connect-e.lookup},secureConnect:()=>{e.secureConnect=Date.now(),e.phases.tls=e.secureConnect-e.connect}})};t.socket?o(t.socket):t.prependOnceListener("socket",o);let a=()=>{var u;e.upload=Date.now(),e.phases.request=e.upload-(u=e.secureConnect,u??e.connect)};return(typeof t.writableFinished=="boolean"?t.writableFinished:t.finished&&t.outputSize===0&&(!t.socket||t.socket.writableLength===0))?a():t.prependOnceListener("finish",a),t.prependOnceListener("response",u=>{e.response=Date.now(),e.phases.firstByte=e.response-e.upload,u.timings=e,r(u),u.prependOnceListener("end",()=>{e.end=Date.now(),e.phases.download=e.end-e.response,e.phases.total=e.end-e.start})}),e};CO.default=EO;wO.exports=EO;wO.exports.default=EO});var coe=_((gLt,vO)=>{"use strict";var{V4MAPPED:Zrt,ADDRCONFIG:$rt,ALL:loe,promises:{Resolver:noe},lookup:ent}=ve("dns"),{promisify:IO}=ve("util"),tnt=ve("os"),$m=Symbol("cacheableLookupCreateConnection"),BO=Symbol("cacheableLookupInstance"),ioe=Symbol("expires"),rnt=typeof loe=="number",soe=t=>{if(!(t&&typeof t.createConnection=="function"))throw new Error("Expected an Agent instance as the first argument")},nnt=t=>{for(let e of t)e.family!==6&&(e.address=`::ffff:${e.address}`,e.family=6)},ooe=()=>{let t=!1,e=!1;for(let r of Object.values(tnt.networkInterfaces()))for(let o of r)if(!o.internal&&(o.family==="IPv6"?e=!0:t=!0,t&&e))return{has4:t,has6:e};return{has4:t,has6:e}},int=t=>Symbol.iterator in t,aoe={ttl:!0},snt={all:!0},Ob=class{constructor({cache:e=new Map,maxTtl:r=1/0,fallbackDuration:o=3600,errorTtl:a=.15,resolver:n=new noe,lookup:u=ent}={}){if(this.maxTtl=r,this.errorTtl=a,this._cache=e,this._resolver=n,this._dnsLookup=IO(u),this._resolver instanceof noe?(this._resolve4=this._resolver.resolve4.bind(this._resolver),this._resolve6=this._resolver.resolve6.bind(this._resolver)):(this._resolve4=IO(this._resolver.resolve4.bind(this._resolver)),this._resolve6=IO(this._resolver.resolve6.bind(this._resolver))),this._iface=ooe(),this._pending={},this._nextRemovalTime=!1,this._hostnamesToFallback=new Set,o<1)this._fallback=!1;else{this._fallback=!0;let A=setInterval(()=>{this._hostnamesToFallback.clear()},o*1e3);A.unref&&A.unref()}this.lookup=this.lookup.bind(this),this.lookupAsync=this.lookupAsync.bind(this)}set servers(e){this.clear(),this._resolver.setServers(e)}get servers(){return this._resolver.getServers()}lookup(e,r,o){if(typeof r=="function"?(o=r,r={}):typeof r=="number"&&(r={family:r}),!o)throw new Error("Callback must be a function.");this.lookupAsync(e,r).then(a=>{r.all?o(null,a):o(null,a.address,a.family,a.expires,a.ttl)},o)}async lookupAsync(e,r={}){typeof r=="number"&&(r={family:r});let o=await this.query(e);if(r.family===6){let a=o.filter(n=>n.family===6);r.hints&Zrt&&(rnt&&r.hints&loe||a.length===0)?nnt(o):o=a}else r.family===4&&(o=o.filter(a=>a.family===4));if(r.hints&$rt){let{_iface:a}=this;o=o.filter(n=>n.family===6?a.has6:a.has4)}if(o.length===0){let a=new Error(`cacheableLookup ENOTFOUND ${e}`);throw a.code="ENOTFOUND",a.hostname=e,a}return r.all?o:o[0]}async query(e){let r=await this._cache.get(e);if(!r){let o=this._pending[e];if(o)r=await o;else{let a=this.queryAndCache(e);this._pending[e]=a,r=await a}}return r=r.map(o=>({...o})),r}async _resolve(e){let r=async h=>{try{return await h}catch(E){if(E.code==="ENODATA"||E.code==="ENOTFOUND")return[];throw E}},[o,a]=await Promise.all([this._resolve4(e,aoe),this._resolve6(e,aoe)].map(h=>r(h))),n=0,u=0,A=0,p=Date.now();for(let h of o)h.family=4,h.expires=p+h.ttl*1e3,n=Math.max(n,h.ttl);for(let h of a)h.family=6,h.expires=p+h.ttl*1e3,u=Math.max(u,h.ttl);return o.length>0?a.length>0?A=Math.min(n,u):A=n:A=u,{entries:[...o,...a],cacheTtl:A}}async _lookup(e){try{return{entries:await this._dnsLookup(e,{all:!0}),cacheTtl:0}}catch{return{entries:[],cacheTtl:0}}}async _set(e,r,o){if(this.maxTtl>0&&o>0){o=Math.min(o,this.maxTtl)*1e3,r[ioe]=Date.now()+o;try{await this._cache.set(e,r,o)}catch(a){this.lookupAsync=async()=>{let n=new Error("Cache Error. Please recreate the CacheableLookup instance.");throw n.cause=a,n}}int(this._cache)&&this._tick(o)}}async queryAndCache(e){if(this._hostnamesToFallback.has(e))return this._dnsLookup(e,snt);try{let r=await this._resolve(e);r.entries.length===0&&this._fallback&&(r=await this._lookup(e),r.entries.length!==0&&this._hostnamesToFallback.add(e));let o=r.entries.length===0?this.errorTtl:r.cacheTtl;return await this._set(e,r.entries,o),delete this._pending[e],r.entries}catch(r){throw delete this._pending[e],r}}_tick(e){let r=this._nextRemovalTime;(!r||e{this._nextRemovalTime=!1;let o=1/0,a=Date.now();for(let[n,u]of this._cache){let A=u[ioe];a>=A?this._cache.delete(n):A("lookup"in r||(r.lookup=this.lookup),e[$m](r,o))}uninstall(e){if(soe(e),e[$m]){if(e[BO]!==this)throw new Error("The agent is not owned by this CacheableLookup instance");e.createConnection=e[$m],delete e[$m],delete e[BO]}}updateInterfaceInfo(){let{_iface:e}=this;this._iface=ooe(),(e.has4&&!this._iface.has4||e.has6&&!this._iface.has6)&&this._cache.clear()}clear(e){if(e){this._cache.delete(e);return}this._cache.clear()}};vO.exports=Ob;vO.exports.default=Ob});var foe=_((dLt,DO)=>{"use strict";var ont=typeof URL>"u"?ve("url").URL:URL,ant="text/plain",lnt="us-ascii",uoe=(t,e)=>e.some(r=>r instanceof RegExp?r.test(t):r===t),cnt=(t,{stripHash:e})=>{let r=t.match(/^data:([^,]*?),([^#]*?)(?:#(.*))?$/);if(!r)throw new Error(`Invalid URL: ${t}`);let o=r[1].split(";"),a=r[2],n=e?"":r[3],u=!1;o[o.length-1]==="base64"&&(o.pop(),u=!0);let A=(o.shift()||"").toLowerCase(),h=[...o.map(E=>{let[I,v=""]=E.split("=").map(x=>x.trim());return I==="charset"&&(v=v.toLowerCase(),v===lnt)?"":`${I}${v?`=${v}`:""}`}).filter(Boolean)];return u&&h.push("base64"),(h.length!==0||A&&A!==ant)&&h.unshift(A),`data:${h.join(";")},${u?a.trim():a}${n?`#${n}`:""}`},Aoe=(t,e)=>{if(e={defaultProtocol:"http:",normalizeProtocol:!0,forceHttp:!1,forceHttps:!1,stripAuthentication:!0,stripHash:!1,stripWWW:!0,removeQueryParameters:[/^utm_\w+/i],removeTrailingSlash:!0,removeDirectoryIndex:!1,sortQueryParameters:!0,...e},Reflect.has(e,"normalizeHttps"))throw new Error("options.normalizeHttps is renamed to options.forceHttp");if(Reflect.has(e,"normalizeHttp"))throw new Error("options.normalizeHttp is renamed to options.forceHttps");if(Reflect.has(e,"stripFragment"))throw new Error("options.stripFragment is renamed to options.stripHash");if(t=t.trim(),/^data:/i.test(t))return cnt(t,e);let r=t.startsWith("//");!r&&/^\.*\//.test(t)||(t=t.replace(/^(?!(?:\w+:)?\/\/)|^\/\//,e.defaultProtocol));let a=new ont(t);if(e.forceHttp&&e.forceHttps)throw new Error("The `forceHttp` and `forceHttps` options cannot be used together");if(e.forceHttp&&a.protocol==="https:"&&(a.protocol="http:"),e.forceHttps&&a.protocol==="http:"&&(a.protocol="https:"),e.stripAuthentication&&(a.username="",a.password=""),e.stripHash&&(a.hash=""),a.pathname&&(a.pathname=a.pathname.replace(/((?!:).|^)\/{2,}/g,(n,u)=>/^(?!\/)/g.test(u)?`${u}/`:"/")),a.pathname&&(a.pathname=decodeURI(a.pathname)),e.removeDirectoryIndex===!0&&(e.removeDirectoryIndex=[/^index\.[a-z]+$/]),Array.isArray(e.removeDirectoryIndex)&&e.removeDirectoryIndex.length>0){let n=a.pathname.split("/"),u=n[n.length-1];uoe(u,e.removeDirectoryIndex)&&(n=n.slice(0,n.length-1),a.pathname=n.slice(1).join("/")+"/")}if(a.hostname&&(a.hostname=a.hostname.replace(/\.$/,""),e.stripWWW&&/^www\.([a-z\-\d]{2,63})\.([a-z.]{2,5})$/.test(a.hostname)&&(a.hostname=a.hostname.replace(/^www\./,""))),Array.isArray(e.removeQueryParameters))for(let n of[...a.searchParams.keys()])uoe(n,e.removeQueryParameters)&&a.searchParams.delete(n);return e.sortQueryParameters&&a.searchParams.sort(),e.removeTrailingSlash&&(a.pathname=a.pathname.replace(/\/$/,"")),t=a.toString(),(e.removeTrailingSlash||a.pathname==="/")&&a.hash===""&&(t=t.replace(/\/$/,"")),r&&!e.normalizeProtocol&&(t=t.replace(/^http:\/\//,"//")),e.stripProtocol&&(t=t.replace(/^(?:https?:)?\/\//,"")),t};DO.exports=Aoe;DO.exports.default=Aoe});var goe=_((mLt,hoe)=>{hoe.exports=poe;function poe(t,e){if(t&&e)return poe(t)(e);if(typeof t!="function")throw new TypeError("need wrapper function");return Object.keys(t).forEach(function(o){r[o]=t[o]}),r;function r(){for(var o=new Array(arguments.length),a=0;a{var doe=goe();PO.exports=doe(Ub);PO.exports.strict=doe(moe);Ub.proto=Ub(function(){Object.defineProperty(Function.prototype,"once",{value:function(){return Ub(this)},configurable:!0}),Object.defineProperty(Function.prototype,"onceStrict",{value:function(){return moe(this)},configurable:!0})});function Ub(t){var e=function(){return e.called?e.value:(e.called=!0,e.value=t.apply(this,arguments))};return e.called=!1,e}function moe(t){var e=function(){if(e.called)throw new Error(e.onceError);return e.called=!0,e.value=t.apply(this,arguments)},r=t.name||"Function wrapped with `once`";return e.onceError=r+" shouldn't be called more than once",e.called=!1,e}});var SO=_((ELt,Eoe)=>{var unt=bO(),Ant=function(){},fnt=function(t){return t.setHeader&&typeof t.abort=="function"},pnt=function(t){return t.stdio&&Array.isArray(t.stdio)&&t.stdio.length===3},yoe=function(t,e,r){if(typeof e=="function")return yoe(t,null,e);e||(e={}),r=unt(r||Ant);var o=t._writableState,a=t._readableState,n=e.readable||e.readable!==!1&&t.readable,u=e.writable||e.writable!==!1&&t.writable,A=function(){t.writable||p()},p=function(){u=!1,n||r.call(t)},h=function(){n=!1,u||r.call(t)},E=function(C){r.call(t,C?new Error("exited with error code: "+C):null)},I=function(C){r.call(t,C)},v=function(){if(n&&!(a&&a.ended))return r.call(t,new Error("premature close"));if(u&&!(o&&o.ended))return r.call(t,new Error("premature close"))},x=function(){t.req.on("finish",p)};return fnt(t)?(t.on("complete",p),t.on("abort",v),t.req?x():t.on("request",x)):u&&!o&&(t.on("end",A),t.on("close",A)),pnt(t)&&t.on("exit",E),t.on("end",h),t.on("finish",p),e.error!==!1&&t.on("error",I),t.on("close",v),function(){t.removeListener("complete",p),t.removeListener("abort",v),t.removeListener("request",x),t.req&&t.req.removeListener("finish",p),t.removeListener("end",A),t.removeListener("close",A),t.removeListener("finish",p),t.removeListener("exit",E),t.removeListener("end",h),t.removeListener("error",I),t.removeListener("close",v)}};Eoe.exports=yoe});var Ioe=_((CLt,woe)=>{var hnt=bO(),gnt=SO(),xO=ve("fs"),JI=function(){},dnt=/^v?\.0/.test(process.version),_b=function(t){return typeof t=="function"},mnt=function(t){return!dnt||!xO?!1:(t instanceof(xO.ReadStream||JI)||t instanceof(xO.WriteStream||JI))&&_b(t.close)},ynt=function(t){return t.setHeader&&_b(t.abort)},Ent=function(t,e,r,o){o=hnt(o);var a=!1;t.on("close",function(){a=!0}),gnt(t,{readable:e,writable:r},function(u){if(u)return o(u);a=!0,o()});var n=!1;return function(u){if(!a&&!n){if(n=!0,mnt(t))return t.close(JI);if(ynt(t))return t.abort();if(_b(t.destroy))return t.destroy();o(u||new Error("stream was destroyed"))}}},Coe=function(t){t()},Cnt=function(t,e){return t.pipe(e)},wnt=function(){var t=Array.prototype.slice.call(arguments),e=_b(t[t.length-1]||JI)&&t.pop()||JI;if(Array.isArray(t[0])&&(t=t[0]),t.length<2)throw new Error("pump requires two streams per minimum");var r,o=t.map(function(a,n){var u=n0;return Ent(a,u,A,function(p){r||(r=p),p&&o.forEach(Coe),!u&&(o.forEach(Coe),e(r))})});return t.reduce(Cnt)};woe.exports=wnt});var voe=_((wLt,Boe)=>{"use strict";var{PassThrough:Int}=ve("stream");Boe.exports=t=>{t={...t};let{array:e}=t,{encoding:r}=t,o=r==="buffer",a=!1;e?a=!(r||o):r=r||"utf8",o&&(r=null);let n=new Int({objectMode:a});r&&n.setEncoding(r);let u=0,A=[];return n.on("data",p=>{A.push(p),a?u=A.length:u+=p.length}),n.getBufferedValue=()=>e?A:o?Buffer.concat(A,u):A.join(""),n.getBufferedLength=()=>u,n}});var Doe=_((ILt,ey)=>{"use strict";var Bnt=Ioe(),vnt=voe(),Hb=class extends Error{constructor(){super("maxBuffer exceeded"),this.name="MaxBufferError"}};async function qb(t,e){if(!t)return Promise.reject(new Error("Expected a stream"));e={maxBuffer:1/0,...e};let{maxBuffer:r}=e,o;return await new Promise((a,n)=>{let u=A=>{A&&(A.bufferedData=o.getBufferedValue()),n(A)};o=Bnt(t,vnt(e),A=>{if(A){u(A);return}a()}),o.on("data",()=>{o.getBufferedLength()>r&&u(new Hb)})}),o.getBufferedValue()}ey.exports=qb;ey.exports.default=qb;ey.exports.buffer=(t,e)=>qb(t,{...e,encoding:"buffer"});ey.exports.array=(t,e)=>qb(t,{...e,array:!0});ey.exports.MaxBufferError=Hb});var boe=_((vLt,Poe)=>{"use strict";var Dnt=new Set([200,203,204,206,300,301,308,404,405,410,414,501]),Pnt=new Set([200,203,204,300,301,302,303,307,308,404,405,410,414,501]),bnt=new Set([500,502,503,504]),Snt={date:!0,connection:!0,"keep-alive":!0,"proxy-authenticate":!0,"proxy-authorization":!0,te:!0,trailer:!0,"transfer-encoding":!0,upgrade:!0},xnt={"content-length":!0,"content-encoding":!0,"transfer-encoding":!0,"content-range":!0};function Eg(t){let e=parseInt(t,10);return isFinite(e)?e:0}function knt(t){return t?bnt.has(t.status):!0}function kO(t){let e={};if(!t)return e;let r=t.trim().split(/,/);for(let o of r){let[a,n]=o.split(/=/,2);e[a.trim()]=n===void 0?!0:n.trim().replace(/^"|"$/g,"")}return e}function Qnt(t){let e=[];for(let r in t){let o=t[r];e.push(o===!0?r:r+"="+o)}if(e.length)return e.join(", ")}Poe.exports=class{constructor(e,r,{shared:o,cacheHeuristic:a,immutableMinTimeToLive:n,ignoreCargoCult:u,_fromObject:A}={}){if(A){this._fromObject(A);return}if(!r||!r.headers)throw Error("Response headers missing");this._assertRequestHasHeaders(e),this._responseTime=this.now(),this._isShared=o!==!1,this._cacheHeuristic=a!==void 0?a:.1,this._immutableMinTtl=n!==void 0?n:24*3600*1e3,this._status="status"in r?r.status:200,this._resHeaders=r.headers,this._rescc=kO(r.headers["cache-control"]),this._method="method"in e?e.method:"GET",this._url=e.url,this._host=e.headers.host,this._noAuthorization=!e.headers.authorization,this._reqHeaders=r.headers.vary?e.headers:null,this._reqcc=kO(e.headers["cache-control"]),u&&"pre-check"in this._rescc&&"post-check"in this._rescc&&(delete this._rescc["pre-check"],delete this._rescc["post-check"],delete this._rescc["no-cache"],delete this._rescc["no-store"],delete this._rescc["must-revalidate"],this._resHeaders=Object.assign({},this._resHeaders,{"cache-control":Qnt(this._rescc)}),delete this._resHeaders.expires,delete this._resHeaders.pragma),r.headers["cache-control"]==null&&/no-cache/.test(r.headers.pragma)&&(this._rescc["no-cache"]=!0)}now(){return Date.now()}storable(){return!!(!this._reqcc["no-store"]&&(this._method==="GET"||this._method==="HEAD"||this._method==="POST"&&this._hasExplicitExpiration())&&Pnt.has(this._status)&&!this._rescc["no-store"]&&(!this._isShared||!this._rescc.private)&&(!this._isShared||this._noAuthorization||this._allowsStoringAuthenticated())&&(this._resHeaders.expires||this._rescc["max-age"]||this._isShared&&this._rescc["s-maxage"]||this._rescc.public||Dnt.has(this._status)))}_hasExplicitExpiration(){return this._isShared&&this._rescc["s-maxage"]||this._rescc["max-age"]||this._resHeaders.expires}_assertRequestHasHeaders(e){if(!e||!e.headers)throw Error("Request headers missing")}satisfiesWithoutRevalidation(e){this._assertRequestHasHeaders(e);let r=kO(e.headers["cache-control"]);return r["no-cache"]||/no-cache/.test(e.headers.pragma)||r["max-age"]&&this.age()>r["max-age"]||r["min-fresh"]&&this.timeToLive()<1e3*r["min-fresh"]||this.stale()&&!(r["max-stale"]&&!this._rescc["must-revalidate"]&&(r["max-stale"]===!0||r["max-stale"]>this.age()-this.maxAge()))?!1:this._requestMatches(e,!1)}_requestMatches(e,r){return(!this._url||this._url===e.url)&&this._host===e.headers.host&&(!e.method||this._method===e.method||r&&e.method==="HEAD")&&this._varyMatches(e)}_allowsStoringAuthenticated(){return this._rescc["must-revalidate"]||this._rescc.public||this._rescc["s-maxage"]}_varyMatches(e){if(!this._resHeaders.vary)return!0;if(this._resHeaders.vary==="*")return!1;let r=this._resHeaders.vary.trim().toLowerCase().split(/\s*,\s*/);for(let o of r)if(e.headers[o]!==this._reqHeaders[o])return!1;return!0}_copyWithoutHopByHopHeaders(e){let r={};for(let o in e)Snt[o]||(r[o]=e[o]);if(e.connection){let o=e.connection.trim().split(/\s*,\s*/);for(let a of o)delete r[a]}if(r.warning){let o=r.warning.split(/,/).filter(a=>!/^\s*1[0-9][0-9]/.test(a));o.length?r.warning=o.join(",").trim():delete r.warning}return r}responseHeaders(){let e=this._copyWithoutHopByHopHeaders(this._resHeaders),r=this.age();return r>3600*24&&!this._hasExplicitExpiration()&&this.maxAge()>3600*24&&(e.warning=(e.warning?`${e.warning}, `:"")+'113 - "rfc7234 5.5.4"'),e.age=`${Math.round(r)}`,e.date=new Date(this.now()).toUTCString(),e}date(){let e=Date.parse(this._resHeaders.date);return isFinite(e)?e:this._responseTime}age(){let e=this._ageValue(),r=(this.now()-this._responseTime)/1e3;return e+r}_ageValue(){return Eg(this._resHeaders.age)}maxAge(){if(!this.storable()||this._rescc["no-cache"]||this._isShared&&this._resHeaders["set-cookie"]&&!this._rescc.public&&!this._rescc.immutable||this._resHeaders.vary==="*")return 0;if(this._isShared){if(this._rescc["proxy-revalidate"])return 0;if(this._rescc["s-maxage"])return Eg(this._rescc["s-maxage"])}if(this._rescc["max-age"])return Eg(this._rescc["max-age"]);let e=this._rescc.immutable?this._immutableMinTtl:0,r=this.date();if(this._resHeaders.expires){let o=Date.parse(this._resHeaders.expires);return Number.isNaN(o)||oo)return Math.max(e,(r-o)/1e3*this._cacheHeuristic)}return e}timeToLive(){let e=this.maxAge()-this.age(),r=e+Eg(this._rescc["stale-if-error"]),o=e+Eg(this._rescc["stale-while-revalidate"]);return Math.max(0,e,r,o)*1e3}stale(){return this.maxAge()<=this.age()}_useStaleIfError(){return this.maxAge()+Eg(this._rescc["stale-if-error"])>this.age()}useStaleWhileRevalidate(){return this.maxAge()+Eg(this._rescc["stale-while-revalidate"])>this.age()}static fromObject(e){return new this(void 0,void 0,{_fromObject:e})}_fromObject(e){if(this._responseTime)throw Error("Reinitialized");if(!e||e.v!==1)throw Error("Invalid serialization");this._responseTime=e.t,this._isShared=e.sh,this._cacheHeuristic=e.ch,this._immutableMinTtl=e.imm!==void 0?e.imm:24*3600*1e3,this._status=e.st,this._resHeaders=e.resh,this._rescc=e.rescc,this._method=e.m,this._url=e.u,this._host=e.h,this._noAuthorization=e.a,this._reqHeaders=e.reqh,this._reqcc=e.reqcc}toObject(){return{v:1,t:this._responseTime,sh:this._isShared,ch:this._cacheHeuristic,imm:this._immutableMinTtl,st:this._status,resh:this._resHeaders,rescc:this._rescc,m:this._method,u:this._url,h:this._host,a:this._noAuthorization,reqh:this._reqHeaders,reqcc:this._reqcc}}revalidationHeaders(e){this._assertRequestHasHeaders(e);let r=this._copyWithoutHopByHopHeaders(e.headers);if(delete r["if-range"],!this._requestMatches(e,!0)||!this.storable())return delete r["if-none-match"],delete r["if-modified-since"],r;if(this._resHeaders.etag&&(r["if-none-match"]=r["if-none-match"]?`${r["if-none-match"]}, ${this._resHeaders.etag}`:this._resHeaders.etag),r["accept-ranges"]||r["if-match"]||r["if-unmodified-since"]||this._method&&this._method!="GET"){if(delete r["if-modified-since"],r["if-none-match"]){let a=r["if-none-match"].split(/,/).filter(n=>!/^\s*W\//.test(n));a.length?r["if-none-match"]=a.join(",").trim():delete r["if-none-match"]}}else this._resHeaders["last-modified"]&&!r["if-modified-since"]&&(r["if-modified-since"]=this._resHeaders["last-modified"]);return r}revalidatedPolicy(e,r){if(this._assertRequestHasHeaders(e),this._useStaleIfError()&&knt(r))return{modified:!1,matches:!1,policy:this};if(!r||!r.headers)throw Error("Response headers missing");let o=!1;if(r.status!==void 0&&r.status!=304?o=!1:r.headers.etag&&!/^\s*W\//.test(r.headers.etag)?o=this._resHeaders.etag&&this._resHeaders.etag.replace(/^\s*W\//,"")===r.headers.etag:this._resHeaders.etag&&r.headers.etag?o=this._resHeaders.etag.replace(/^\s*W\//,"")===r.headers.etag.replace(/^\s*W\//,""):this._resHeaders["last-modified"]?o=this._resHeaders["last-modified"]===r.headers["last-modified"]:!this._resHeaders.etag&&!this._resHeaders["last-modified"]&&!r.headers.etag&&!r.headers["last-modified"]&&(o=!0),!o)return{policy:new this.constructor(e,r),modified:r.status!=304,matches:!1};let a={};for(let u in this._resHeaders)a[u]=u in r.headers&&!xnt[u]?r.headers[u]:this._resHeaders[u];let n=Object.assign({},r,{status:this._status,method:this._method,headers:a});return{policy:new this.constructor(e,n,{shared:this._isShared,cacheHeuristic:this._cacheHeuristic,immutableMinTimeToLive:this._immutableMinTtl}),modified:!1,matches:!0}}}});var jb=_((DLt,Soe)=>{"use strict";Soe.exports=t=>{let e={};for(let[r,o]of Object.entries(t))e[r.toLowerCase()]=o;return e}});var koe=_((PLt,xoe)=>{"use strict";var Fnt=ve("stream").Readable,Rnt=jb(),QO=class extends Fnt{constructor(e,r,o,a){if(typeof e!="number")throw new TypeError("Argument `statusCode` should be a number");if(typeof r!="object")throw new TypeError("Argument `headers` should be an object");if(!(o instanceof Buffer))throw new TypeError("Argument `body` should be a buffer");if(typeof a!="string")throw new TypeError("Argument `url` should be a string");super(),this.statusCode=e,this.headers=Rnt(r),this.body=o,this.url=a}_read(){this.push(this.body),this.push(null)}};xoe.exports=QO});var Foe=_((bLt,Qoe)=>{"use strict";var Tnt=["destroy","setTimeout","socket","headers","trailers","rawHeaders","statusCode","httpVersion","httpVersionMinor","httpVersionMajor","rawTrailers","statusMessage"];Qoe.exports=(t,e)=>{let r=new Set(Object.keys(t).concat(Tnt));for(let o of r)o in e||(e[o]=typeof t[o]=="function"?t[o].bind(t):t[o])}});var Toe=_((SLt,Roe)=>{"use strict";var Nnt=ve("stream").PassThrough,Lnt=Foe(),Mnt=t=>{if(!(t&&t.pipe))throw new TypeError("Parameter `response` must be a response stream.");let e=new Nnt;return Lnt(t,e),t.pipe(e)};Roe.exports=Mnt});var Noe=_(FO=>{FO.stringify=function t(e){if(typeof e>"u")return e;if(e&&Buffer.isBuffer(e))return JSON.stringify(":base64:"+e.toString("base64"));if(e&&e.toJSON&&(e=e.toJSON()),e&&typeof e=="object"){var r="",o=Array.isArray(e);r=o?"[":"{";var a=!0;for(var n in e){var u=typeof e[n]=="function"||!o&&typeof e[n]>"u";Object.hasOwnProperty.call(e,n)&&!u&&(a||(r+=","),a=!1,o?e[n]==null?r+="null":r+=t(e[n]):e[n]!==void 0&&(r+=t(n)+":"+t(e[n])))}return r+=o?"]":"}",r}else return typeof e=="string"?JSON.stringify(/^:/.test(e)?":"+e:e):typeof e>"u"?"null":JSON.stringify(e)};FO.parse=function(t){return JSON.parse(t,function(e,r){return typeof r=="string"?/^:base64:/.test(r)?Buffer.from(r.substring(8),"base64"):/^:/.test(r)?r.substring(1):r:r})}});var Uoe=_((kLt,Ooe)=>{"use strict";var Ont=ve("events"),Loe=Noe(),Unt=t=>{let e={redis:"@keyv/redis",rediss:"@keyv/redis",mongodb:"@keyv/mongo",mongo:"@keyv/mongo",sqlite:"@keyv/sqlite",postgresql:"@keyv/postgres",postgres:"@keyv/postgres",mysql:"@keyv/mysql",etcd:"@keyv/etcd",offline:"@keyv/offline",tiered:"@keyv/tiered"};if(t.adapter||t.uri){let r=t.adapter||/^[^:+]*/.exec(t.uri)[0];return new(ve(e[r]))(t)}return new Map},Moe=["sqlite","postgres","mysql","mongo","redis","tiered"],RO=class extends Ont{constructor(e,{emitErrors:r=!0,...o}={}){if(super(),this.opts={namespace:"keyv",serialize:Loe.stringify,deserialize:Loe.parse,...typeof e=="string"?{uri:e}:e,...o},!this.opts.store){let n={...this.opts};this.opts.store=Unt(n)}if(this.opts.compression){let n=this.opts.compression;this.opts.serialize=n.serialize.bind(n),this.opts.deserialize=n.deserialize.bind(n)}typeof this.opts.store.on=="function"&&r&&this.opts.store.on("error",n=>this.emit("error",n)),this.opts.store.namespace=this.opts.namespace;let a=n=>async function*(){for await(let[u,A]of typeof n=="function"?n(this.opts.store.namespace):n){let p=await this.opts.deserialize(A);if(!(this.opts.store.namespace&&!u.includes(this.opts.store.namespace))){if(typeof p.expires=="number"&&Date.now()>p.expires){this.delete(u);continue}yield[this._getKeyUnprefix(u),p.value]}}};typeof this.opts.store[Symbol.iterator]=="function"&&this.opts.store instanceof Map?this.iterator=a(this.opts.store):typeof this.opts.store.iterator=="function"&&this.opts.store.opts&&this._checkIterableAdaptar()&&(this.iterator=a(this.opts.store.iterator.bind(this.opts.store)))}_checkIterableAdaptar(){return Moe.includes(this.opts.store.opts.dialect)||Moe.findIndex(e=>this.opts.store.opts.url.includes(e))>=0}_getKeyPrefix(e){return`${this.opts.namespace}:${e}`}_getKeyPrefixArray(e){return e.map(r=>`${this.opts.namespace}:${r}`)}_getKeyUnprefix(e){return e.split(":").splice(1).join(":")}get(e,r){let{store:o}=this.opts,a=Array.isArray(e),n=a?this._getKeyPrefixArray(e):this._getKeyPrefix(e);if(a&&o.getMany===void 0){let u=[];for(let A of n)u.push(Promise.resolve().then(()=>o.get(A)).then(p=>typeof p=="string"?this.opts.deserialize(p):this.opts.compression?this.opts.deserialize(p):p).then(p=>{if(p!=null)return typeof p.expires=="number"&&Date.now()>p.expires?this.delete(A).then(()=>{}):r&&r.raw?p:p.value}));return Promise.allSettled(u).then(A=>{let p=[];for(let h of A)p.push(h.value);return p})}return Promise.resolve().then(()=>a?o.getMany(n):o.get(n)).then(u=>typeof u=="string"?this.opts.deserialize(u):this.opts.compression?this.opts.deserialize(u):u).then(u=>{if(u!=null)return a?u.map((A,p)=>{if(typeof A=="string"&&(A=this.opts.deserialize(A)),A!=null){if(typeof A.expires=="number"&&Date.now()>A.expires){this.delete(e[p]).then(()=>{});return}return r&&r.raw?A:A.value}}):typeof u.expires=="number"&&Date.now()>u.expires?this.delete(e).then(()=>{}):r&&r.raw?u:u.value})}set(e,r,o){let a=this._getKeyPrefix(e);typeof o>"u"&&(o=this.opts.ttl),o===0&&(o=void 0);let{store:n}=this.opts;return Promise.resolve().then(()=>{let u=typeof o=="number"?Date.now()+o:null;return typeof r=="symbol"&&this.emit("error","symbol cannot be serialized"),r={value:r,expires:u},this.opts.serialize(r)}).then(u=>n.set(a,u,o)).then(()=>!0)}delete(e){let{store:r}=this.opts;if(Array.isArray(e)){let a=this._getKeyPrefixArray(e);if(r.deleteMany===void 0){let n=[];for(let u of a)n.push(r.delete(u));return Promise.allSettled(n).then(u=>u.every(A=>A.value===!0))}return Promise.resolve().then(()=>r.deleteMany(a))}let o=this._getKeyPrefix(e);return Promise.resolve().then(()=>r.delete(o))}clear(){let{store:e}=this.opts;return Promise.resolve().then(()=>e.clear())}has(e){let r=this._getKeyPrefix(e),{store:o}=this.opts;return Promise.resolve().then(async()=>typeof o.has=="function"?o.has(r):await o.get(r)!==void 0)}disconnect(){let{store:e}=this.opts;if(typeof e.disconnect=="function")return e.disconnect()}};Ooe.exports=RO});var qoe=_((FLt,Hoe)=>{"use strict";var _nt=ve("events"),Gb=ve("url"),Hnt=foe(),qnt=Doe(),TO=boe(),_oe=koe(),jnt=jb(),Gnt=Toe(),Ynt=Uoe(),XI=class t{constructor(e,r){if(typeof e!="function")throw new TypeError("Parameter `request` must be a function");return this.cache=new Ynt({uri:typeof r=="string"&&r,store:typeof r!="string"&&r,namespace:"cacheable-request"}),this.createCacheableRequest(e)}createCacheableRequest(e){return(r,o)=>{let a;if(typeof r=="string")a=NO(Gb.parse(r)),r={};else if(r instanceof Gb.URL)a=NO(Gb.parse(r.toString())),r={};else{let[I,...v]=(r.path||"").split("?"),x=v.length>0?`?${v.join("?")}`:"";a=NO({...r,pathname:I,search:x})}r={headers:{},method:"GET",cache:!0,strictTtl:!1,automaticFailover:!1,...r,...Wnt(a)},r.headers=jnt(r.headers);let n=new _nt,u=Hnt(Gb.format(a),{stripWWW:!1,removeTrailingSlash:!1,stripAuthentication:!1}),A=`${r.method}:${u}`,p=!1,h=!1,E=I=>{h=!0;let v=!1,x,C=new Promise(L=>{x=()=>{v||(v=!0,L())}}),R=L=>{if(p&&!I.forceRefresh){L.status=L.statusCode;let z=TO.fromObject(p.cachePolicy).revalidatedPolicy(I,L);if(!z.modified){let te=z.policy.responseHeaders();L=new _oe(p.statusCode,te,p.body,p.url),L.cachePolicy=z.policy,L.fromCache=!0}}L.fromCache||(L.cachePolicy=new TO(I,L,I),L.fromCache=!1);let U;I.cache&&L.cachePolicy.storable()?(U=Gnt(L),(async()=>{try{let z=qnt.buffer(L);if(await Promise.race([C,new Promise(ce=>L.once("end",ce))]),v)return;let te=await z,ae={cachePolicy:L.cachePolicy.toObject(),url:L.url,statusCode:L.fromCache?p.statusCode:L.statusCode,body:te},le=I.strictTtl?L.cachePolicy.timeToLive():void 0;I.maxTtl&&(le=le?Math.min(le,I.maxTtl):I.maxTtl),await this.cache.set(A,ae,le)}catch(z){n.emit("error",new t.CacheError(z))}})()):I.cache&&p&&(async()=>{try{await this.cache.delete(A)}catch(z){n.emit("error",new t.CacheError(z))}})(),n.emit("response",U||L),typeof o=="function"&&o(U||L)};try{let L=e(I,R);L.once("error",x),L.once("abort",x),n.emit("request",L)}catch(L){n.emit("error",new t.RequestError(L))}};return(async()=>{let I=async x=>{await Promise.resolve();let C=x.cache?await this.cache.get(A):void 0;if(typeof C>"u")return E(x);let R=TO.fromObject(C.cachePolicy);if(R.satisfiesWithoutRevalidation(x)&&!x.forceRefresh){let L=R.responseHeaders(),U=new _oe(C.statusCode,L,C.body,C.url);U.cachePolicy=R,U.fromCache=!0,n.emit("response",U),typeof o=="function"&&o(U)}else p=C,x.headers=R.revalidationHeaders(x),E(x)},v=x=>n.emit("error",new t.CacheError(x));this.cache.once("error",v),n.on("response",()=>this.cache.removeListener("error",v));try{await I(r)}catch(x){r.automaticFailover&&!h&&E(r),n.emit("error",new t.CacheError(x))}})(),n}}};function Wnt(t){let e={...t};return e.path=`${t.pathname||"/"}${t.search||""}`,delete e.pathname,delete e.search,e}function NO(t){return{protocol:t.protocol,auth:t.auth,hostname:t.hostname||t.host||"localhost",port:t.port,pathname:t.pathname,search:t.search}}XI.RequestError=class extends Error{constructor(t){super(t.message),this.name="RequestError",Object.assign(this,t)}};XI.CacheError=class extends Error{constructor(t){super(t.message),this.name="CacheError",Object.assign(this,t)}};Hoe.exports=XI});var Goe=_((NLt,joe)=>{"use strict";var Knt=["aborted","complete","headers","httpVersion","httpVersionMinor","httpVersionMajor","method","rawHeaders","rawTrailers","setTimeout","socket","statusCode","statusMessage","trailers","url"];joe.exports=(t,e)=>{if(e._readableState.autoDestroy)throw new Error("The second stream must have the `autoDestroy` option set to `false`");let r=new Set(Object.keys(t).concat(Knt)),o={};for(let a of r)a in e||(o[a]={get(){let n=t[a];return typeof n=="function"?n.bind(t):n},set(n){t[a]=n},enumerable:!0,configurable:!1});return Object.defineProperties(e,o),t.once("aborted",()=>{e.destroy(),e.emit("aborted")}),t.once("close",()=>{t.complete&&e.readable?e.once("end",()=>{e.emit("close")}):e.emit("close")}),e}});var Woe=_((LLt,Yoe)=>{"use strict";var{Transform:Vnt,PassThrough:znt}=ve("stream"),LO=ve("zlib"),Jnt=Goe();Yoe.exports=t=>{let e=(t.headers["content-encoding"]||"").toLowerCase();if(!["gzip","deflate","br"].includes(e))return t;let r=e==="br";if(r&&typeof LO.createBrotliDecompress!="function")return t.destroy(new Error("Brotli is not supported on Node.js < 12")),t;let o=!0,a=new Vnt({transform(A,p,h){o=!1,h(null,A)},flush(A){A()}}),n=new znt({autoDestroy:!1,destroy(A,p){t.destroy(),p(A)}}),u=r?LO.createBrotliDecompress():LO.createUnzip();return u.once("error",A=>{if(o&&!t.readable){n.end();return}n.destroy(A)}),Jnt(t,n),t.pipe(a).pipe(u).pipe(n),n}});var OO=_((MLt,Koe)=>{"use strict";var MO=class{constructor(e={}){if(!(e.maxSize&&e.maxSize>0))throw new TypeError("`maxSize` must be a number greater than 0");this.maxSize=e.maxSize,this.onEviction=e.onEviction,this.cache=new Map,this.oldCache=new Map,this._size=0}_set(e,r){if(this.cache.set(e,r),this._size++,this._size>=this.maxSize){if(this._size=0,typeof this.onEviction=="function")for(let[o,a]of this.oldCache.entries())this.onEviction(o,a);this.oldCache=this.cache,this.cache=new Map}}get(e){if(this.cache.has(e))return this.cache.get(e);if(this.oldCache.has(e)){let r=this.oldCache.get(e);return this.oldCache.delete(e),this._set(e,r),r}}set(e,r){return this.cache.has(e)?this.cache.set(e,r):this._set(e,r),this}has(e){return this.cache.has(e)||this.oldCache.has(e)}peek(e){if(this.cache.has(e))return this.cache.get(e);if(this.oldCache.has(e))return this.oldCache.get(e)}delete(e){let r=this.cache.delete(e);return r&&this._size--,this.oldCache.delete(e)||r}clear(){this.cache.clear(),this.oldCache.clear(),this._size=0}*keys(){for(let[e]of this)yield e}*values(){for(let[,e]of this)yield e}*[Symbol.iterator](){for(let e of this.cache)yield e;for(let e of this.oldCache){let[r]=e;this.cache.has(r)||(yield e)}}get size(){let e=0;for(let r of this.oldCache.keys())this.cache.has(r)||e++;return Math.min(this._size+e,this.maxSize)}};Koe.exports=MO});var _O=_((OLt,Xoe)=>{"use strict";var Xnt=ve("events"),Znt=ve("tls"),$nt=ve("http2"),eit=OO(),ra=Symbol("currentStreamsCount"),Voe=Symbol("request"),Kl=Symbol("cachedOriginSet"),ty=Symbol("gracefullyClosing"),tit=["maxDeflateDynamicTableSize","maxSessionMemory","maxHeaderListPairs","maxOutstandingPings","maxReservedRemoteStreams","maxSendHeaderBlockLength","paddingStrategy","localAddress","path","rejectUnauthorized","minDHSize","ca","cert","clientCertEngine","ciphers","key","pfx","servername","minVersion","maxVersion","secureProtocol","crl","honorCipherOrder","ecdhCurve","dhparam","secureOptions","sessionIdContext"],rit=(t,e,r)=>{let o=0,a=t.length;for(;o>>1;r(t[n],e)?o=n+1:a=n}return o},nit=(t,e)=>t.remoteSettings.maxConcurrentStreams>e.remoteSettings.maxConcurrentStreams,UO=(t,e)=>{for(let r of t)r[Kl].lengthe[Kl].includes(o))&&r[ra]+e[ra]<=e.remoteSettings.maxConcurrentStreams&&Joe(r)},iit=(t,e)=>{for(let r of t)e[Kl].lengthr[Kl].includes(o))&&e[ra]+r[ra]<=r.remoteSettings.maxConcurrentStreams&&Joe(e)},zoe=({agent:t,isFree:e})=>{let r={};for(let o in t.sessions){let n=t.sessions[o].filter(u=>{let A=u[Cg.kCurrentStreamsCount]{t[ty]=!0,t[ra]===0&&t.close()},Cg=class t extends Xnt{constructor({timeout:e=6e4,maxSessions:r=1/0,maxFreeSessions:o=10,maxCachedTlsSessions:a=100}={}){super(),this.sessions={},this.queue={},this.timeout=e,this.maxSessions=r,this.maxFreeSessions=o,this._freeSessionsCount=0,this._sessionsCount=0,this.settings={enablePush:!1},this.tlsSessionCache=new eit({maxSize:a})}static normalizeOrigin(e,r){return typeof e=="string"&&(e=new URL(e)),r&&e.hostname!==r&&(e.hostname=r),e.origin}normalizeOptions(e){let r="";if(e)for(let o of tit)e[o]&&(r+=`:${e[o]}`);return r}_tryToCreateNewSession(e,r){if(!(e in this.queue)||!(r in this.queue[e]))return;let o=this.queue[e][r];this._sessionsCount{Array.isArray(o)?(o=[...o],a()):o=[{resolve:a,reject:n}];let u=this.normalizeOptions(r),A=t.normalizeOrigin(e,r&&r.servername);if(A===void 0){for(let{reject:E}of o)E(new TypeError("The `origin` argument needs to be a string or an URL object"));return}if(u in this.sessions){let E=this.sessions[u],I=-1,v=-1,x;for(let C of E){let R=C.remoteSettings.maxConcurrentStreams;if(R=R||C[ty]||C.destroyed)continue;x||(I=R),L>v&&(x=C,v=L)}}if(x){if(o.length!==1){for(let{reject:C}of o){let R=new Error(`Expected the length of listeners to be 1, got ${o.length}. +Please report this to https://github.com/szmarczak/http2-wrapper/`);C(R)}return}o[0].resolve(x);return}}if(u in this.queue){if(A in this.queue[u]){this.queue[u][A].listeners.push(...o),this._tryToCreateNewSession(u,A);return}}else this.queue[u]={};let p=()=>{u in this.queue&&this.queue[u][A]===h&&(delete this.queue[u][A],Object.keys(this.queue[u]).length===0&&delete this.queue[u])},h=()=>{let E=`${A}:${u}`,I=!1;try{let v=$nt.connect(e,{createConnection:this.createConnection,settings:this.settings,session:this.tlsSessionCache.get(E),...r});v[ra]=0,v[ty]=!1;let x=()=>v[ra]{this.tlsSessionCache.set(E,L)}),v.once("error",L=>{for(let{reject:U}of o)U(L);this.tlsSessionCache.delete(E)}),v.setTimeout(this.timeout,()=>{v.destroy()}),v.once("close",()=>{if(I){C&&this._freeSessionsCount--,this._sessionsCount--;let L=this.sessions[u];L.splice(L.indexOf(v),1),L.length===0&&delete this.sessions[u]}else{let L=new Error("Session closed without receiving a SETTINGS frame");L.code="HTTP2WRAPPER_NOSETTINGS";for(let{reject:U}of o)U(L);p()}this._tryToCreateNewSession(u,A)});let R=()=>{if(!(!(u in this.queue)||!x())){for(let L of v[Kl])if(L in this.queue[u]){let{listeners:U}=this.queue[u][L];for(;U.length!==0&&x();)U.shift().resolve(v);let z=this.queue[u];if(z[L].listeners.length===0&&(delete z[L],Object.keys(z).length===0)){delete this.queue[u];break}if(!x())break}}};v.on("origin",()=>{v[Kl]=v.originSet,x()&&(R(),UO(this.sessions[u],v))}),v.once("remoteSettings",()=>{if(v.ref(),v.unref(),this._sessionsCount++,h.destroyed){let L=new Error("Agent has been destroyed");for(let U of o)U.reject(L);v.destroy();return}v[Kl]=v.originSet;{let L=this.sessions;if(u in L){let U=L[u];U.splice(rit(U,v,nit),0,v)}else L[u]=[v]}this._freeSessionsCount+=1,I=!0,this.emit("session",v),R(),p(),v[ra]===0&&this._freeSessionsCount>this.maxFreeSessions&&v.close(),o.length!==0&&(this.getSession(A,r,o),o.length=0),v.on("remoteSettings",()=>{R(),UO(this.sessions[u],v)})}),v[Voe]=v.request,v.request=(L,U)=>{if(v[ty])throw new Error("The session is gracefully closing. No new streams are allowed.");let z=v[Voe](L,U);return v.ref(),++v[ra],v[ra]===v.remoteSettings.maxConcurrentStreams&&this._freeSessionsCount--,z.once("close",()=>{if(C=x(),--v[ra],!v.destroyed&&!v.closed&&(iit(this.sessions[u],v),x()&&!v.closed)){C||(this._freeSessionsCount++,C=!0);let te=v[ra]===0;te&&v.unref(),te&&(this._freeSessionsCount>this.maxFreeSessions||v[ty])?v.close():(UO(this.sessions[u],v),R())}}),z}}catch(v){for(let x of o)x.reject(v);p()}};h.listeners=o,h.completed=!1,h.destroyed=!1,this.queue[u][A]=h,this._tryToCreateNewSession(u,A)})}request(e,r,o,a){return new Promise((n,u)=>{this.getSession(e,r,[{reject:u,resolve:A=>{try{n(A.request(o,a))}catch(p){u(p)}}}])})}createConnection(e,r){return t.connect(e,r)}static connect(e,r){r.ALPNProtocols=["h2"];let o=e.port||443,a=e.hostname||e.host;return typeof r.servername>"u"&&(r.servername=a),Znt.connect(o,a,r)}closeFreeSessions(){for(let e of Object.values(this.sessions))for(let r of e)r[ra]===0&&r.close()}destroy(e){for(let r of Object.values(this.sessions))for(let o of r)o.destroy(e);for(let r of Object.values(this.queue))for(let o of Object.values(r))o.destroyed=!0;this.queue={}}get freeSessions(){return zoe({agent:this,isFree:!0})}get busySessions(){return zoe({agent:this,isFree:!1})}};Cg.kCurrentStreamsCount=ra;Cg.kGracefullyClosing=ty;Xoe.exports={Agent:Cg,globalAgent:new Cg}});var qO=_((ULt,Zoe)=>{"use strict";var{Readable:sit}=ve("stream"),HO=class extends sit{constructor(e,r){super({highWaterMark:r,autoDestroy:!1}),this.statusCode=null,this.statusMessage="",this.httpVersion="2.0",this.httpVersionMajor=2,this.httpVersionMinor=0,this.headers={},this.trailers={},this.req=null,this.aborted=!1,this.complete=!1,this.upgrade=null,this.rawHeaders=[],this.rawTrailers=[],this.socket=e,this.connection=e,this._dumped=!1}_destroy(e){this.req._request.destroy(e)}setTimeout(e,r){return this.req.setTimeout(e,r),this}_dump(){this._dumped||(this._dumped=!0,this.removeAllListeners("data"),this.resume())}_read(){this.req&&this.req._request.resume()}};Zoe.exports=HO});var jO=_((_Lt,$oe)=>{"use strict";$oe.exports=t=>{let e={protocol:t.protocol,hostname:typeof t.hostname=="string"&&t.hostname.startsWith("[")?t.hostname.slice(1,-1):t.hostname,host:t.host,hash:t.hash,search:t.search,pathname:t.pathname,href:t.href,path:`${t.pathname||""}${t.search||""}`};return typeof t.port=="string"&&t.port.length!==0&&(e.port=Number(t.port)),(t.username||t.password)&&(e.auth=`${t.username||""}:${t.password||""}`),e}});var tae=_((HLt,eae)=>{"use strict";eae.exports=(t,e,r)=>{for(let o of r)t.on(o,(...a)=>e.emit(o,...a))}});var nae=_((qLt,rae)=>{"use strict";rae.exports=t=>{switch(t){case":method":case":scheme":case":authority":case":path":return!0;default:return!1}}});var sae=_((GLt,iae)=>{"use strict";var ry=(t,e,r)=>{iae.exports[e]=class extends t{constructor(...a){super(typeof r=="string"?r:r(a)),this.name=`${super.name} [${e}]`,this.code=e}}};ry(TypeError,"ERR_INVALID_ARG_TYPE",t=>{let e=t[0].includes(".")?"property":"argument",r=t[1],o=Array.isArray(r);return o&&(r=`${r.slice(0,-1).join(", ")} or ${r.slice(-1)}`),`The "${t[0]}" ${e} must be ${o?"one of":"of"} type ${r}. Received ${typeof t[2]}`});ry(TypeError,"ERR_INVALID_PROTOCOL",t=>`Protocol "${t[0]}" not supported. Expected "${t[1]}"`);ry(Error,"ERR_HTTP_HEADERS_SENT",t=>`Cannot ${t[0]} headers after they are sent to the client`);ry(TypeError,"ERR_INVALID_HTTP_TOKEN",t=>`${t[0]} must be a valid HTTP token [${t[1]}]`);ry(TypeError,"ERR_HTTP_INVALID_HEADER_VALUE",t=>`Invalid value "${t[0]} for header "${t[1]}"`);ry(TypeError,"ERR_INVALID_CHAR",t=>`Invalid character in ${t[0]} [${t[1]}]`)});var VO=_((YLt,fae)=>{"use strict";var oit=ve("http2"),{Writable:ait}=ve("stream"),{Agent:oae,globalAgent:lit}=_O(),cit=qO(),uit=jO(),Ait=tae(),fit=nae(),{ERR_INVALID_ARG_TYPE:GO,ERR_INVALID_PROTOCOL:pit,ERR_HTTP_HEADERS_SENT:aae,ERR_INVALID_HTTP_TOKEN:hit,ERR_HTTP_INVALID_HEADER_VALUE:git,ERR_INVALID_CHAR:dit}=sae(),{HTTP2_HEADER_STATUS:lae,HTTP2_HEADER_METHOD:cae,HTTP2_HEADER_PATH:uae,HTTP2_METHOD_CONNECT:mit}=oit.constants,Qo=Symbol("headers"),YO=Symbol("origin"),WO=Symbol("session"),Aae=Symbol("options"),Yb=Symbol("flushedHeaders"),ZI=Symbol("jobs"),yit=/^[\^`\-\w!#$%&*+.|~]+$/,Eit=/[^\t\u0020-\u007E\u0080-\u00FF]/,KO=class extends ait{constructor(e,r,o){super({autoDestroy:!1});let a=typeof e=="string"||e instanceof URL;if(a&&(e=uit(e instanceof URL?e:new URL(e))),typeof r=="function"||r===void 0?(o=r,r=a?e:{...e}):r={...e,...r},r.h2session)this[WO]=r.h2session;else if(r.agent===!1)this.agent=new oae({maxFreeSessions:0});else if(typeof r.agent>"u"||r.agent===null)typeof r.createConnection=="function"?(this.agent=new oae({maxFreeSessions:0}),this.agent.createConnection=r.createConnection):this.agent=lit;else if(typeof r.agent.request=="function")this.agent=r.agent;else throw new GO("options.agent",["Agent-like Object","undefined","false"],r.agent);if(r.protocol&&r.protocol!=="https:")throw new pit(r.protocol,"https:");let n=r.port||r.defaultPort||this.agent&&this.agent.defaultPort||443,u=r.hostname||r.host||"localhost";delete r.hostname,delete r.host,delete r.port;let{timeout:A}=r;if(r.timeout=void 0,this[Qo]=Object.create(null),this[ZI]=[],this.socket=null,this.connection=null,this.method=r.method||"GET",this.path=r.path,this.res=null,this.aborted=!1,this.reusedSocket=!1,r.headers)for(let[p,h]of Object.entries(r.headers))this.setHeader(p,h);r.auth&&!("authorization"in this[Qo])&&(this[Qo].authorization="Basic "+Buffer.from(r.auth).toString("base64")),r.session=r.tlsSession,r.path=r.socketPath,this[Aae]=r,n===443?(this[YO]=`https://${u}`,":authority"in this[Qo]||(this[Qo][":authority"]=u)):(this[YO]=`https://${u}:${n}`,":authority"in this[Qo]||(this[Qo][":authority"]=`${u}:${n}`)),A&&this.setTimeout(A),o&&this.once("response",o),this[Yb]=!1}get method(){return this[Qo][cae]}set method(e){e&&(this[Qo][cae]=e.toUpperCase())}get path(){return this[Qo][uae]}set path(e){e&&(this[Qo][uae]=e)}get _mustNotHaveABody(){return this.method==="GET"||this.method==="HEAD"||this.method==="DELETE"}_write(e,r,o){if(this._mustNotHaveABody){o(new Error("The GET, HEAD and DELETE methods must NOT have a body"));return}this.flushHeaders();let a=()=>this._request.write(e,r,o);this._request?a():this[ZI].push(a)}_final(e){if(this.destroyed)return;this.flushHeaders();let r=()=>{if(this._mustNotHaveABody){e();return}this._request.end(e)};this._request?r():this[ZI].push(r)}abort(){this.res&&this.res.complete||(this.aborted||process.nextTick(()=>this.emit("abort")),this.aborted=!0,this.destroy())}_destroy(e,r){this.res&&this.res._dump(),this._request&&this._request.destroy(),r(e)}async flushHeaders(){if(this[Yb]||this.destroyed)return;this[Yb]=!0;let e=this.method===mit,r=o=>{if(this._request=o,this.destroyed){o.destroy();return}e||Ait(o,this,["timeout","continue","close","error"]);let a=u=>(...A)=>{!this.writable&&!this.destroyed?u(...A):this.once("finish",()=>{u(...A)})};o.once("response",a((u,A,p)=>{let h=new cit(this.socket,o.readableHighWaterMark);this.res=h,h.req=this,h.statusCode=u[lae],h.headers=u,h.rawHeaders=p,h.once("end",()=>{this.aborted?(h.aborted=!0,h.emit("aborted")):(h.complete=!0,h.socket=null,h.connection=null)}),e?(h.upgrade=!0,this.emit("connect",h,o,Buffer.alloc(0))?this.emit("close"):o.destroy()):(o.on("data",E=>{!h._dumped&&!h.push(E)&&o.pause()}),o.once("end",()=>{h.push(null)}),this.emit("response",h)||h._dump())})),o.once("headers",a(u=>this.emit("information",{statusCode:u[lae]}))),o.once("trailers",a((u,A,p)=>{let{res:h}=this;h.trailers=u,h.rawTrailers=p}));let{socket:n}=o.session;this.socket=n,this.connection=n;for(let u of this[ZI])u();this.emit("socket",this.socket)};if(this[WO])try{r(this[WO].request(this[Qo]))}catch(o){this.emit("error",o)}else{this.reusedSocket=!0;try{r(await this.agent.request(this[YO],this[Aae],this[Qo]))}catch(o){this.emit("error",o)}}}getHeader(e){if(typeof e!="string")throw new GO("name","string",e);return this[Qo][e.toLowerCase()]}get headersSent(){return this[Yb]}removeHeader(e){if(typeof e!="string")throw new GO("name","string",e);if(this.headersSent)throw new aae("remove");delete this[Qo][e.toLowerCase()]}setHeader(e,r){if(this.headersSent)throw new aae("set");if(typeof e!="string"||!yit.test(e)&&!fit(e))throw new hit("Header name",e);if(typeof r>"u")throw new git(r,e);if(Eit.test(r))throw new dit("header content",e);this[Qo][e.toLowerCase()]=r}setNoDelay(){}setSocketKeepAlive(){}setTimeout(e,r){let o=()=>this._request.setTimeout(e,r);return this._request?o():this[ZI].push(o),this}get maxHeadersCount(){if(!this.destroyed&&this._request)return this._request.session.localSettings.maxHeaderListSize}set maxHeadersCount(e){}};fae.exports=KO});var hae=_((WLt,pae)=>{"use strict";var Cit=ve("tls");pae.exports=(t={},e=Cit.connect)=>new Promise((r,o)=>{let a=!1,n,u=async()=>{await p,n.off("timeout",A),n.off("error",o),t.resolveSocket?(r({alpnProtocol:n.alpnProtocol,socket:n,timeout:a}),a&&(await Promise.resolve(),n.emit("timeout"))):(n.destroy(),r({alpnProtocol:n.alpnProtocol,timeout:a}))},A=async()=>{a=!0,u()},p=(async()=>{try{n=await e(t,u),n.on("error",o),n.once("timeout",A)}catch(h){o(h)}})()})});var dae=_((KLt,gae)=>{"use strict";var wit=ve("net");gae.exports=t=>{let e=t.host,r=t.headers&&t.headers.host;return r&&(r.startsWith("[")?r.indexOf("]")===-1?e=r:e=r.slice(1,-1):e=r.split(":",1)[0]),wit.isIP(e)?"":e}});var Eae=_((VLt,JO)=>{"use strict";var mae=ve("http"),zO=ve("https"),Iit=hae(),Bit=OO(),vit=VO(),Dit=dae(),Pit=jO(),Wb=new Bit({maxSize:100}),$I=new Map,yae=(t,e,r)=>{e._httpMessage={shouldKeepAlive:!0};let o=()=>{t.emit("free",e,r)};e.on("free",o);let a=()=>{t.removeSocket(e,r)};e.on("close",a);let n=()=>{t.removeSocket(e,r),e.off("close",a),e.off("free",o),e.off("agentRemove",n)};e.on("agentRemove",n),t.emit("free",e,r)},bit=async t=>{let e=`${t.host}:${t.port}:${t.ALPNProtocols.sort()}`;if(!Wb.has(e)){if($I.has(e))return(await $I.get(e)).alpnProtocol;let{path:r,agent:o}=t;t.path=t.socketPath;let a=Iit(t);$I.set(e,a);try{let{socket:n,alpnProtocol:u}=await a;if(Wb.set(e,u),t.path=r,u==="h2")n.destroy();else{let{globalAgent:A}=zO,p=zO.Agent.prototype.createConnection;o?o.createConnection===p?yae(o,n,t):n.destroy():A.createConnection===p?yae(A,n,t):n.destroy()}return $I.delete(e),u}catch(n){throw $I.delete(e),n}}return Wb.get(e)};JO.exports=async(t,e,r)=>{if((typeof t=="string"||t instanceof URL)&&(t=Pit(new URL(t))),typeof e=="function"&&(r=e,e=void 0),e={ALPNProtocols:["h2","http/1.1"],...t,...e,resolveSocket:!0},!Array.isArray(e.ALPNProtocols)||e.ALPNProtocols.length===0)throw new Error("The `ALPNProtocols` option must be an Array with at least one entry");e.protocol=e.protocol||"https:";let o=e.protocol==="https:";e.host=e.hostname||e.host||"localhost",e.session=e.tlsSession,e.servername=e.servername||Dit(e),e.port=e.port||(o?443:80),e._defaultAgent=o?zO.globalAgent:mae.globalAgent;let a=e.agent;if(a){if(a.addRequest)throw new Error("The `options.agent` object can contain only `http`, `https` or `http2` properties");e.agent=a[o?"https":"http"]}return o&&await bit(e)==="h2"?(a&&(e.agent=a.http2),new vit(e,r)):mae.request(e,r)};JO.exports.protocolCache=Wb});var wae=_((zLt,Cae)=>{"use strict";var Sit=ve("http2"),xit=_O(),XO=VO(),kit=qO(),Qit=Eae(),Fit=(t,e,r)=>new XO(t,e,r),Rit=(t,e,r)=>{let o=new XO(t,e,r);return o.end(),o};Cae.exports={...Sit,ClientRequest:XO,IncomingMessage:kit,...xit,request:Fit,get:Rit,auto:Qit}});var $O=_(ZO=>{"use strict";Object.defineProperty(ZO,"__esModule",{value:!0});var Iae=Qf();ZO.default=t=>Iae.default.nodeStream(t)&&Iae.default.function_(t.getBoundary)});var Pae=_(e4=>{"use strict";Object.defineProperty(e4,"__esModule",{value:!0});var vae=ve("fs"),Dae=ve("util"),Bae=Qf(),Tit=$O(),Nit=Dae.promisify(vae.stat);e4.default=async(t,e)=>{if(e&&"content-length"in e)return Number(e["content-length"]);if(!t)return 0;if(Bae.default.string(t))return Buffer.byteLength(t);if(Bae.default.buffer(t))return t.length;if(Tit.default(t))return Dae.promisify(t.getLength.bind(t))();if(t instanceof vae.ReadStream){let{size:r}=await Nit(t.path);return r===0?void 0:r}}});var r4=_(t4=>{"use strict";Object.defineProperty(t4,"__esModule",{value:!0});function Lit(t,e,r){let o={};for(let a of r)o[a]=(...n)=>{e.emit(a,...n)},t.on(a,o[a]);return()=>{for(let a of r)t.off(a,o[a])}}t4.default=Lit});var bae=_(n4=>{"use strict";Object.defineProperty(n4,"__esModule",{value:!0});n4.default=()=>{let t=[];return{once(e,r,o){e.once(r,o),t.push({origin:e,event:r,fn:o})},unhandleAll(){for(let e of t){let{origin:r,event:o,fn:a}=e;r.removeListener(o,a)}t.length=0}}}});var xae=_(e1=>{"use strict";Object.defineProperty(e1,"__esModule",{value:!0});e1.TimeoutError=void 0;var Mit=ve("net"),Oit=bae(),Sae=Symbol("reentry"),Uit=()=>{},Kb=class extends Error{constructor(e,r){super(`Timeout awaiting '${r}' for ${e}ms`),this.event=r,this.name="TimeoutError",this.code="ETIMEDOUT"}};e1.TimeoutError=Kb;e1.default=(t,e,r)=>{if(Sae in t)return Uit;t[Sae]=!0;let o=[],{once:a,unhandleAll:n}=Oit.default(),u=(I,v,x)=>{var C;let R=setTimeout(v,I,I,x);(C=R.unref)===null||C===void 0||C.call(R);let L=()=>{clearTimeout(R)};return o.push(L),L},{host:A,hostname:p}=r,h=(I,v)=>{t.destroy(new Kb(I,v))},E=()=>{for(let I of o)I();n()};if(t.once("error",I=>{if(E(),t.listenerCount("error")===0)throw I}),t.once("close",E),a(t,"response",I=>{a(I,"end",E)}),typeof e.request<"u"&&u(e.request,h,"request"),typeof e.socket<"u"){let I=()=>{h(e.socket,"socket")};t.setTimeout(e.socket,I),o.push(()=>{t.removeListener("timeout",I)})}return a(t,"socket",I=>{var v;let{socketPath:x}=t;if(I.connecting){let C=!!(x??Mit.isIP((v=p??A)!==null&&v!==void 0?v:"")!==0);if(typeof e.lookup<"u"&&!C&&typeof I.address().address>"u"){let R=u(e.lookup,h,"lookup");a(I,"lookup",R)}if(typeof e.connect<"u"){let R=()=>u(e.connect,h,"connect");C?a(I,"connect",R()):a(I,"lookup",L=>{L===null&&a(I,"connect",R())})}typeof e.secureConnect<"u"&&r.protocol==="https:"&&a(I,"connect",()=>{let R=u(e.secureConnect,h,"secureConnect");a(I,"secureConnect",R)})}if(typeof e.send<"u"){let C=()=>u(e.send,h,"send");I.connecting?a(I,"connect",()=>{a(t,"upload-complete",C())}):a(t,"upload-complete",C())}}),typeof e.response<"u"&&a(t,"upload-complete",()=>{let I=u(e.response,h,"response");a(t,"response",I)}),E}});var Qae=_(i4=>{"use strict";Object.defineProperty(i4,"__esModule",{value:!0});var kae=Qf();i4.default=t=>{t=t;let e={protocol:t.protocol,hostname:kae.default.string(t.hostname)&&t.hostname.startsWith("[")?t.hostname.slice(1,-1):t.hostname,host:t.host,hash:t.hash,search:t.search,pathname:t.pathname,href:t.href,path:`${t.pathname||""}${t.search||""}`};return kae.default.string(t.port)&&t.port.length>0&&(e.port=Number(t.port)),(t.username||t.password)&&(e.auth=`${t.username||""}:${t.password||""}`),e}});var Fae=_(s4=>{"use strict";Object.defineProperty(s4,"__esModule",{value:!0});var _it=ve("url"),Hit=["protocol","host","hostname","port","pathname","search"];s4.default=(t,e)=>{var r,o;if(e.path){if(e.pathname)throw new TypeError("Parameters `path` and `pathname` are mutually exclusive.");if(e.search)throw new TypeError("Parameters `path` and `search` are mutually exclusive.");if(e.searchParams)throw new TypeError("Parameters `path` and `searchParams` are mutually exclusive.")}if(e.search&&e.searchParams)throw new TypeError("Parameters `search` and `searchParams` are mutually exclusive.");if(!t){if(!e.protocol)throw new TypeError("No URL protocol specified");t=`${e.protocol}//${(o=(r=e.hostname)!==null&&r!==void 0?r:e.host)!==null&&o!==void 0?o:""}`}let a=new _it.URL(t);if(e.path){let n=e.path.indexOf("?");n===-1?e.pathname=e.path:(e.pathname=e.path.slice(0,n),e.search=e.path.slice(n+1)),delete e.path}for(let n of Hit)e[n]&&(a[n]=e[n].toString());return a}});var Rae=_(a4=>{"use strict";Object.defineProperty(a4,"__esModule",{value:!0});var o4=class{constructor(){this.weakMap=new WeakMap,this.map=new Map}set(e,r){typeof e=="object"?this.weakMap.set(e,r):this.map.set(e,r)}get(e){return typeof e=="object"?this.weakMap.get(e):this.map.get(e)}has(e){return typeof e=="object"?this.weakMap.has(e):this.map.has(e)}};a4.default=o4});var c4=_(l4=>{"use strict";Object.defineProperty(l4,"__esModule",{value:!0});var qit=async t=>{let e=[],r=0;for await(let o of t)e.push(o),r+=Buffer.byteLength(o);return Buffer.isBuffer(e[0])?Buffer.concat(e,r):Buffer.from(e.join(""))};l4.default=qit});var Nae=_(wg=>{"use strict";Object.defineProperty(wg,"__esModule",{value:!0});wg.dnsLookupIpVersionToFamily=wg.isDnsLookupIpVersion=void 0;var Tae={auto:0,ipv4:4,ipv6:6};wg.isDnsLookupIpVersion=t=>t in Tae;wg.dnsLookupIpVersionToFamily=t=>{if(wg.isDnsLookupIpVersion(t))return Tae[t];throw new Error("Invalid DNS lookup IP version")}});var u4=_(Vb=>{"use strict";Object.defineProperty(Vb,"__esModule",{value:!0});Vb.isResponseOk=void 0;Vb.isResponseOk=t=>{let{statusCode:e}=t,r=t.request.options.followRedirect?299:399;return e>=200&&e<=r||e===304}});var Mae=_(A4=>{"use strict";Object.defineProperty(A4,"__esModule",{value:!0});var Lae=new Set;A4.default=t=>{Lae.has(t)||(Lae.add(t),process.emitWarning(`Got: ${t}`,{type:"DeprecationWarning"}))}});var Oae=_(f4=>{"use strict";Object.defineProperty(f4,"__esModule",{value:!0});var Ai=Qf(),jit=(t,e)=>{if(Ai.default.null_(t.encoding))throw new TypeError("To get a Buffer, set `options.responseType` to `buffer` instead");Ai.assert.any([Ai.default.string,Ai.default.undefined],t.encoding),Ai.assert.any([Ai.default.boolean,Ai.default.undefined],t.resolveBodyOnly),Ai.assert.any([Ai.default.boolean,Ai.default.undefined],t.methodRewriting),Ai.assert.any([Ai.default.boolean,Ai.default.undefined],t.isStream),Ai.assert.any([Ai.default.string,Ai.default.undefined],t.responseType),t.responseType===void 0&&(t.responseType="text");let{retry:r}=t;if(e?t.retry={...e.retry}:t.retry={calculateDelay:o=>o.computedValue,limit:0,methods:[],statusCodes:[],errorCodes:[],maxRetryAfter:void 0},Ai.default.object(r)?(t.retry={...t.retry,...r},t.retry.methods=[...new Set(t.retry.methods.map(o=>o.toUpperCase()))],t.retry.statusCodes=[...new Set(t.retry.statusCodes)],t.retry.errorCodes=[...new Set(t.retry.errorCodes)]):Ai.default.number(r)&&(t.retry.limit=r),Ai.default.undefined(t.retry.maxRetryAfter)&&(t.retry.maxRetryAfter=Math.min(...[t.timeout.request,t.timeout.connect].filter(Ai.default.number))),Ai.default.object(t.pagination)){e&&(t.pagination={...e.pagination,...t.pagination});let{pagination:o}=t;if(!Ai.default.function_(o.transform))throw new Error("`options.pagination.transform` must be implemented");if(!Ai.default.function_(o.shouldContinue))throw new Error("`options.pagination.shouldContinue` must be implemented");if(!Ai.default.function_(o.filter))throw new TypeError("`options.pagination.filter` must be implemented");if(!Ai.default.function_(o.paginate))throw new Error("`options.pagination.paginate` must be implemented")}return t.responseType==="json"&&t.headers.accept===void 0&&(t.headers.accept="application/json"),t};f4.default=jit});var Uae=_(t1=>{"use strict";Object.defineProperty(t1,"__esModule",{value:!0});t1.retryAfterStatusCodes=void 0;t1.retryAfterStatusCodes=new Set([413,429,503]);var Git=({attemptCount:t,retryOptions:e,error:r,retryAfter:o})=>{if(t>e.limit)return 0;let a=e.methods.includes(r.options.method),n=e.errorCodes.includes(r.code),u=r.response&&e.statusCodes.includes(r.response.statusCode);if(!a||!n&&!u)return 0;if(r.response){if(o)return e.maxRetryAfter===void 0||o>e.maxRetryAfter?0:o;if(r.response.statusCode===413)return 0}let A=Math.random()*100;return 2**(t-1)*1e3+A};t1.default=Git});var i1=_(Bn=>{"use strict";Object.defineProperty(Bn,"__esModule",{value:!0});Bn.UnsupportedProtocolError=Bn.ReadError=Bn.TimeoutError=Bn.UploadError=Bn.CacheError=Bn.HTTPError=Bn.MaxRedirectsError=Bn.RequestError=Bn.setNonEnumerableProperties=Bn.knownHookEvents=Bn.withoutBody=Bn.kIsNormalizedAlready=void 0;var _ae=ve("util"),Hae=ve("stream"),Yit=ve("fs"),sh=ve("url"),qae=ve("http"),p4=ve("http"),Wit=ve("https"),Kit=roe(),Vit=coe(),jae=qoe(),zit=Woe(),Jit=wae(),Xit=jb(),ot=Qf(),Zit=Pae(),Gae=$O(),$it=r4(),Yae=xae(),est=Qae(),Wae=Fae(),tst=Rae(),rst=c4(),Kae=Nae(),nst=u4(),oh=Mae(),ist=Oae(),sst=Uae(),h4,$s=Symbol("request"),Xb=Symbol("response"),ny=Symbol("responseSize"),iy=Symbol("downloadedSize"),sy=Symbol("bodySize"),oy=Symbol("uploadedSize"),zb=Symbol("serverResponsesPiped"),Vae=Symbol("unproxyEvents"),zae=Symbol("isFromCache"),g4=Symbol("cancelTimeouts"),Jae=Symbol("startedReading"),ay=Symbol("stopReading"),Jb=Symbol("triggerRead"),ah=Symbol("body"),r1=Symbol("jobs"),Xae=Symbol("originalResponse"),Zae=Symbol("retryTimeout");Bn.kIsNormalizedAlready=Symbol("isNormalizedAlready");var ost=ot.default.string(process.versions.brotli);Bn.withoutBody=new Set(["GET","HEAD"]);Bn.knownHookEvents=["init","beforeRequest","beforeRedirect","beforeError","beforeRetry","afterResponse"];function ast(t){for(let e in t){let r=t[e];if(!ot.default.string(r)&&!ot.default.number(r)&&!ot.default.boolean(r)&&!ot.default.null_(r)&&!ot.default.undefined(r))throw new TypeError(`The \`searchParams\` value '${String(r)}' must be a string, number, boolean or null`)}}function lst(t){return ot.default.object(t)&&!("statusCode"in t)}var d4=new tst.default,cst=async t=>new Promise((e,r)=>{let o=a=>{r(a)};t.pending||e(),t.once("error",o),t.once("ready",()=>{t.off("error",o),e()})}),ust=new Set([300,301,302,303,304,307,308]),Ast=["context","body","json","form"];Bn.setNonEnumerableProperties=(t,e)=>{let r={};for(let o of t)if(o)for(let a of Ast)a in o&&(r[a]={writable:!0,configurable:!0,enumerable:!1,value:o[a]});Object.defineProperties(e,r)};var Ji=class extends Error{constructor(e,r,o){var a;if(super(e),Error.captureStackTrace(this,this.constructor),this.name="RequestError",this.code=r.code,o instanceof iS?(Object.defineProperty(this,"request",{enumerable:!1,value:o}),Object.defineProperty(this,"response",{enumerable:!1,value:o[Xb]}),Object.defineProperty(this,"options",{enumerable:!1,value:o.options})):Object.defineProperty(this,"options",{enumerable:!1,value:o}),this.timings=(a=this.request)===null||a===void 0?void 0:a.timings,ot.default.string(r.stack)&&ot.default.string(this.stack)){let n=this.stack.indexOf(this.message)+this.message.length,u=this.stack.slice(n).split(` +`).reverse(),A=r.stack.slice(r.stack.indexOf(r.message)+r.message.length).split(` +`).reverse();for(;A.length!==0&&A[0]===u[0];)u.shift();this.stack=`${this.stack.slice(0,n)}${u.reverse().join(` +`)}${A.reverse().join(` +`)}`}}};Bn.RequestError=Ji;var Zb=class extends Ji{constructor(e){super(`Redirected ${e.options.maxRedirects} times. Aborting.`,{},e),this.name="MaxRedirectsError"}};Bn.MaxRedirectsError=Zb;var $b=class extends Ji{constructor(e){super(`Response code ${e.statusCode} (${e.statusMessage})`,{},e.request),this.name="HTTPError"}};Bn.HTTPError=$b;var eS=class extends Ji{constructor(e,r){super(e.message,e,r),this.name="CacheError"}};Bn.CacheError=eS;var tS=class extends Ji{constructor(e,r){super(e.message,e,r),this.name="UploadError"}};Bn.UploadError=tS;var rS=class extends Ji{constructor(e,r,o){super(e.message,e,o),this.name="TimeoutError",this.event=e.event,this.timings=r}};Bn.TimeoutError=rS;var n1=class extends Ji{constructor(e,r){super(e.message,e,r),this.name="ReadError"}};Bn.ReadError=n1;var nS=class extends Ji{constructor(e){super(`Unsupported protocol "${e.url.protocol}"`,{},e),this.name="UnsupportedProtocolError"}};Bn.UnsupportedProtocolError=nS;var fst=["socket","connect","continue","information","upgrade","timeout"],iS=class extends Hae.Duplex{constructor(e,r={},o){super({autoDestroy:!1,highWaterMark:0}),this[iy]=0,this[oy]=0,this.requestInitialized=!1,this[zb]=new Set,this.redirects=[],this[ay]=!1,this[Jb]=!1,this[r1]=[],this.retryCount=0,this._progressCallbacks=[];let a=()=>this._unlockWrite(),n=()=>this._lockWrite();this.on("pipe",h=>{h.prependListener("data",a),h.on("data",n),h.prependListener("end",a),h.on("end",n)}),this.on("unpipe",h=>{h.off("data",a),h.off("data",n),h.off("end",a),h.off("end",n)}),this.on("pipe",h=>{h instanceof p4.IncomingMessage&&(this.options.headers={...h.headers,...this.options.headers})});let{json:u,body:A,form:p}=r;if((u||A||p)&&this._lockWrite(),Bn.kIsNormalizedAlready in r)this.options=r;else try{this.options=this.constructor.normalizeArguments(e,r,o)}catch(h){ot.default.nodeStream(r.body)&&r.body.destroy(),this.destroy(h);return}(async()=>{var h;try{this.options.body instanceof Yit.ReadStream&&await cst(this.options.body);let{url:E}=this.options;if(!E)throw new TypeError("Missing `url` property");if(this.requestUrl=E.toString(),decodeURI(this.requestUrl),await this._finalizeBody(),await this._makeRequest(),this.destroyed){(h=this[$s])===null||h===void 0||h.destroy();return}for(let I of this[r1])I();this[r1].length=0,this.requestInitialized=!0}catch(E){if(E instanceof Ji){this._beforeError(E);return}this.destroyed||this.destroy(E)}})()}static normalizeArguments(e,r,o){var a,n,u,A,p;let h=r;if(ot.default.object(e)&&!ot.default.urlInstance(e))r={...o,...e,...r};else{if(e&&r&&r.url!==void 0)throw new TypeError("The `url` option is mutually exclusive with the `input` argument");r={...o,...r},e!==void 0&&(r.url=e),ot.default.urlInstance(r.url)&&(r.url=new sh.URL(r.url.toString()))}if(r.cache===!1&&(r.cache=void 0),r.dnsCache===!1&&(r.dnsCache=void 0),ot.assert.any([ot.default.string,ot.default.undefined],r.method),ot.assert.any([ot.default.object,ot.default.undefined],r.headers),ot.assert.any([ot.default.string,ot.default.urlInstance,ot.default.undefined],r.prefixUrl),ot.assert.any([ot.default.object,ot.default.undefined],r.cookieJar),ot.assert.any([ot.default.object,ot.default.string,ot.default.undefined],r.searchParams),ot.assert.any([ot.default.object,ot.default.string,ot.default.undefined],r.cache),ot.assert.any([ot.default.object,ot.default.number,ot.default.undefined],r.timeout),ot.assert.any([ot.default.object,ot.default.undefined],r.context),ot.assert.any([ot.default.object,ot.default.undefined],r.hooks),ot.assert.any([ot.default.boolean,ot.default.undefined],r.decompress),ot.assert.any([ot.default.boolean,ot.default.undefined],r.ignoreInvalidCookies),ot.assert.any([ot.default.boolean,ot.default.undefined],r.followRedirect),ot.assert.any([ot.default.number,ot.default.undefined],r.maxRedirects),ot.assert.any([ot.default.boolean,ot.default.undefined],r.throwHttpErrors),ot.assert.any([ot.default.boolean,ot.default.undefined],r.http2),ot.assert.any([ot.default.boolean,ot.default.undefined],r.allowGetBody),ot.assert.any([ot.default.string,ot.default.undefined],r.localAddress),ot.assert.any([Kae.isDnsLookupIpVersion,ot.default.undefined],r.dnsLookupIpVersion),ot.assert.any([ot.default.object,ot.default.undefined],r.https),ot.assert.any([ot.default.boolean,ot.default.undefined],r.rejectUnauthorized),r.https&&(ot.assert.any([ot.default.boolean,ot.default.undefined],r.https.rejectUnauthorized),ot.assert.any([ot.default.function_,ot.default.undefined],r.https.checkServerIdentity),ot.assert.any([ot.default.string,ot.default.object,ot.default.array,ot.default.undefined],r.https.certificateAuthority),ot.assert.any([ot.default.string,ot.default.object,ot.default.array,ot.default.undefined],r.https.key),ot.assert.any([ot.default.string,ot.default.object,ot.default.array,ot.default.undefined],r.https.certificate),ot.assert.any([ot.default.string,ot.default.undefined],r.https.passphrase),ot.assert.any([ot.default.string,ot.default.buffer,ot.default.array,ot.default.undefined],r.https.pfx)),ot.assert.any([ot.default.object,ot.default.undefined],r.cacheOptions),ot.default.string(r.method)?r.method=r.method.toUpperCase():r.method="GET",r.headers===o?.headers?r.headers={...r.headers}:r.headers=Xit({...o?.headers,...r.headers}),"slashes"in r)throw new TypeError("The legacy `url.Url` has been deprecated. Use `URL` instead.");if("auth"in r)throw new TypeError("Parameter `auth` is deprecated. Use `username` / `password` instead.");if("searchParams"in r&&r.searchParams&&r.searchParams!==o?.searchParams){let x;if(ot.default.string(r.searchParams)||r.searchParams instanceof sh.URLSearchParams)x=new sh.URLSearchParams(r.searchParams);else{ast(r.searchParams),x=new sh.URLSearchParams;for(let C in r.searchParams){let R=r.searchParams[C];R===null?x.append(C,""):R!==void 0&&x.append(C,R)}}(a=o?.searchParams)===null||a===void 0||a.forEach((C,R)=>{x.has(R)||x.append(R,C)}),r.searchParams=x}if(r.username=(n=r.username)!==null&&n!==void 0?n:"",r.password=(u=r.password)!==null&&u!==void 0?u:"",ot.default.undefined(r.prefixUrl)?r.prefixUrl=(A=o?.prefixUrl)!==null&&A!==void 0?A:"":(r.prefixUrl=r.prefixUrl.toString(),r.prefixUrl!==""&&!r.prefixUrl.endsWith("/")&&(r.prefixUrl+="/")),ot.default.string(r.url)){if(r.url.startsWith("/"))throw new Error("`input` must not start with a slash when using `prefixUrl`");r.url=Wae.default(r.prefixUrl+r.url,r)}else(ot.default.undefined(r.url)&&r.prefixUrl!==""||r.protocol)&&(r.url=Wae.default(r.prefixUrl,r));if(r.url){"port"in r&&delete r.port;let{prefixUrl:x}=r;Object.defineProperty(r,"prefixUrl",{set:R=>{let L=r.url;if(!L.href.startsWith(R))throw new Error(`Cannot change \`prefixUrl\` from ${x} to ${R}: ${L.href}`);r.url=new sh.URL(R+L.href.slice(x.length)),x=R},get:()=>x});let{protocol:C}=r.url;if(C==="unix:"&&(C="http:",r.url=new sh.URL(`http://unix${r.url.pathname}${r.url.search}`)),r.searchParams&&(r.url.search=r.searchParams.toString()),C!=="http:"&&C!=="https:")throw new nS(r);r.username===""?r.username=r.url.username:r.url.username=r.username,r.password===""?r.password=r.url.password:r.url.password=r.password}let{cookieJar:E}=r;if(E){let{setCookie:x,getCookieString:C}=E;ot.assert.function_(x),ot.assert.function_(C),x.length===4&&C.length===0&&(x=_ae.promisify(x.bind(r.cookieJar)),C=_ae.promisify(C.bind(r.cookieJar)),r.cookieJar={setCookie:x,getCookieString:C})}let{cache:I}=r;if(I&&(d4.has(I)||d4.set(I,new jae((x,C)=>{let R=x[$s](x,C);return ot.default.promise(R)&&(R.once=(L,U)=>{if(L==="error")R.catch(U);else if(L==="abort")(async()=>{try{(await R).once("abort",U)}catch{}})();else throw new Error(`Unknown HTTP2 promise event: ${L}`);return R}),R},I))),r.cacheOptions={...r.cacheOptions},r.dnsCache===!0)h4||(h4=new Vit.default),r.dnsCache=h4;else if(!ot.default.undefined(r.dnsCache)&&!r.dnsCache.lookup)throw new TypeError(`Parameter \`dnsCache\` must be a CacheableLookup instance or a boolean, got ${ot.default(r.dnsCache)}`);ot.default.number(r.timeout)?r.timeout={request:r.timeout}:o&&r.timeout!==o.timeout?r.timeout={...o.timeout,...r.timeout}:r.timeout={...r.timeout},r.context||(r.context={});let v=r.hooks===o?.hooks;r.hooks={...r.hooks};for(let x of Bn.knownHookEvents)if(x in r.hooks)if(ot.default.array(r.hooks[x]))r.hooks[x]=[...r.hooks[x]];else throw new TypeError(`Parameter \`${x}\` must be an Array, got ${ot.default(r.hooks[x])}`);else r.hooks[x]=[];if(o&&!v)for(let x of Bn.knownHookEvents)o.hooks[x].length>0&&(r.hooks[x]=[...o.hooks[x],...r.hooks[x]]);if("family"in r&&oh.default('"options.family" was never documented, please use "options.dnsLookupIpVersion"'),o?.https&&(r.https={...o.https,...r.https}),"rejectUnauthorized"in r&&oh.default('"options.rejectUnauthorized" is now deprecated, please use "options.https.rejectUnauthorized"'),"checkServerIdentity"in r&&oh.default('"options.checkServerIdentity" was never documented, please use "options.https.checkServerIdentity"'),"ca"in r&&oh.default('"options.ca" was never documented, please use "options.https.certificateAuthority"'),"key"in r&&oh.default('"options.key" was never documented, please use "options.https.key"'),"cert"in r&&oh.default('"options.cert" was never documented, please use "options.https.certificate"'),"passphrase"in r&&oh.default('"options.passphrase" was never documented, please use "options.https.passphrase"'),"pfx"in r&&oh.default('"options.pfx" was never documented, please use "options.https.pfx"'),"followRedirects"in r)throw new TypeError("The `followRedirects` option does not exist. Use `followRedirect` instead.");if(r.agent){for(let x in r.agent)if(x!=="http"&&x!=="https"&&x!=="http2")throw new TypeError(`Expected the \`options.agent\` properties to be \`http\`, \`https\` or \`http2\`, got \`${x}\``)}return r.maxRedirects=(p=r.maxRedirects)!==null&&p!==void 0?p:0,Bn.setNonEnumerableProperties([o,h],r),ist.default(r,o)}_lockWrite(){let e=()=>{throw new TypeError("The payload has been already provided")};this.write=e,this.end=e}_unlockWrite(){this.write=super.write,this.end=super.end}async _finalizeBody(){let{options:e}=this,{headers:r}=e,o=!ot.default.undefined(e.form),a=!ot.default.undefined(e.json),n=!ot.default.undefined(e.body),u=o||a||n,A=Bn.withoutBody.has(e.method)&&!(e.method==="GET"&&e.allowGetBody);if(this._cannotHaveBody=A,u){if(A)throw new TypeError(`The \`${e.method}\` method cannot be used with a body`);if([n,o,a].filter(p=>p).length>1)throw new TypeError("The `body`, `json` and `form` options are mutually exclusive");if(n&&!(e.body instanceof Hae.Readable)&&!ot.default.string(e.body)&&!ot.default.buffer(e.body)&&!Gae.default(e.body))throw new TypeError("The `body` option must be a stream.Readable, string or Buffer");if(o&&!ot.default.object(e.form))throw new TypeError("The `form` option must be an Object");{let p=!ot.default.string(r["content-type"]);n?(Gae.default(e.body)&&p&&(r["content-type"]=`multipart/form-data; boundary=${e.body.getBoundary()}`),this[ah]=e.body):o?(p&&(r["content-type"]="application/x-www-form-urlencoded"),this[ah]=new sh.URLSearchParams(e.form).toString()):(p&&(r["content-type"]="application/json"),this[ah]=e.stringifyJson(e.json));let h=await Zit.default(this[ah],e.headers);ot.default.undefined(r["content-length"])&&ot.default.undefined(r["transfer-encoding"])&&!A&&!ot.default.undefined(h)&&(r["content-length"]=String(h))}}else A?this._lockWrite():this._unlockWrite();this[sy]=Number(r["content-length"])||void 0}async _onResponseBase(e){let{options:r}=this,{url:o}=r;this[Xae]=e,r.decompress&&(e=zit(e));let a=e.statusCode,n=e;n.statusMessage=n.statusMessage?n.statusMessage:qae.STATUS_CODES[a],n.url=r.url.toString(),n.requestUrl=this.requestUrl,n.redirectUrls=this.redirects,n.request=this,n.isFromCache=e.fromCache||!1,n.ip=this.ip,n.retryCount=this.retryCount,this[zae]=n.isFromCache,this[ny]=Number(e.headers["content-length"])||void 0,this[Xb]=e,e.once("end",()=>{this[ny]=this[iy],this.emit("downloadProgress",this.downloadProgress)}),e.once("error",A=>{e.destroy(),this._beforeError(new n1(A,this))}),e.once("aborted",()=>{this._beforeError(new n1({name:"Error",message:"The server aborted pending request",code:"ECONNRESET"},this))}),this.emit("downloadProgress",this.downloadProgress);let u=e.headers["set-cookie"];if(ot.default.object(r.cookieJar)&&u){let A=u.map(async p=>r.cookieJar.setCookie(p,o.toString()));r.ignoreInvalidCookies&&(A=A.map(async p=>p.catch(()=>{})));try{await Promise.all(A)}catch(p){this._beforeError(p);return}}if(r.followRedirect&&e.headers.location&&ust.has(a)){if(e.resume(),this[$s]&&(this[g4](),delete this[$s],this[Vae]()),(a===303&&r.method!=="GET"&&r.method!=="HEAD"||!r.methodRewriting)&&(r.method="GET","body"in r&&delete r.body,"json"in r&&delete r.json,"form"in r&&delete r.form,this[ah]=void 0,delete r.headers["content-length"]),this.redirects.length>=r.maxRedirects){this._beforeError(new Zb(this));return}try{let p=Buffer.from(e.headers.location,"binary").toString(),h=new sh.URL(p,o),E=h.toString();decodeURI(E),h.hostname!==o.hostname||h.port!==o.port?("host"in r.headers&&delete r.headers.host,"cookie"in r.headers&&delete r.headers.cookie,"authorization"in r.headers&&delete r.headers.authorization,(r.username||r.password)&&(r.username="",r.password="")):(h.username=r.username,h.password=r.password),this.redirects.push(E),r.url=h;for(let I of r.hooks.beforeRedirect)await I(r,n);this.emit("redirect",n,r),await this._makeRequest()}catch(p){this._beforeError(p);return}return}if(r.isStream&&r.throwHttpErrors&&!nst.isResponseOk(n)){this._beforeError(new $b(n));return}e.on("readable",()=>{this[Jb]&&this._read()}),this.on("resume",()=>{e.resume()}),this.on("pause",()=>{e.pause()}),e.once("end",()=>{this.push(null)}),this.emit("response",e);for(let A of this[zb])if(!A.headersSent){for(let p in e.headers){let h=r.decompress?p!=="content-encoding":!0,E=e.headers[p];h&&A.setHeader(p,E)}A.statusCode=a}}async _onResponse(e){try{await this._onResponseBase(e)}catch(r){this._beforeError(r)}}_onRequest(e){let{options:r}=this,{timeout:o,url:a}=r;Kit.default(e),this[g4]=Yae.default(e,o,a);let n=r.cache?"cacheableResponse":"response";e.once(n,p=>{this._onResponse(p)}),e.once("error",p=>{var h;e.destroy(),(h=e.res)===null||h===void 0||h.removeAllListeners("end"),p=p instanceof Yae.TimeoutError?new rS(p,this.timings,this):new Ji(p.message,p,this),this._beforeError(p)}),this[Vae]=$it.default(e,this,fst),this[$s]=e,this.emit("uploadProgress",this.uploadProgress);let u=this[ah],A=this.redirects.length===0?this:e;ot.default.nodeStream(u)?(u.pipe(A),u.once("error",p=>{this._beforeError(new tS(p,this))})):(this._unlockWrite(),ot.default.undefined(u)?(this._cannotHaveBody||this._noPipe)&&(A.end(),this._lockWrite()):(this._writeRequest(u,void 0,()=>{}),A.end(),this._lockWrite())),this.emit("request",e)}async _createCacheableRequest(e,r){return new Promise((o,a)=>{Object.assign(r,est.default(e)),delete r.url;let n,u=d4.get(r.cache)(r,async A=>{A._readableState.autoDestroy=!1,n&&(await n).emit("cacheableResponse",A),o(A)});r.url=e,u.once("error",a),u.once("request",async A=>{n=A,o(n)})})}async _makeRequest(){var e,r,o,a,n;let{options:u}=this,{headers:A}=u;for(let U in A)if(ot.default.undefined(A[U]))delete A[U];else if(ot.default.null_(A[U]))throw new TypeError(`Use \`undefined\` instead of \`null\` to delete the \`${U}\` header`);if(u.decompress&&ot.default.undefined(A["accept-encoding"])&&(A["accept-encoding"]=ost?"gzip, deflate, br":"gzip, deflate"),u.cookieJar){let U=await u.cookieJar.getCookieString(u.url.toString());ot.default.nonEmptyString(U)&&(u.headers.cookie=U)}for(let U of u.hooks.beforeRequest){let z=await U(u);if(!ot.default.undefined(z)){u.request=()=>z;break}}u.body&&this[ah]!==u.body&&(this[ah]=u.body);let{agent:p,request:h,timeout:E,url:I}=u;if(u.dnsCache&&!("lookup"in u)&&(u.lookup=u.dnsCache.lookup),I.hostname==="unix"){let U=/(?.+?):(?.+)/.exec(`${I.pathname}${I.search}`);if(U?.groups){let{socketPath:z,path:te}=U.groups;Object.assign(u,{socketPath:z,path:te,host:""})}}let v=I.protocol==="https:",x;u.http2?x=Jit.auto:x=v?Wit.request:qae.request;let C=(e=u.request)!==null&&e!==void 0?e:x,R=u.cache?this._createCacheableRequest:C;p&&!u.http2&&(u.agent=p[v?"https":"http"]),u[$s]=C,delete u.request,delete u.timeout;let L=u;if(L.shared=(r=u.cacheOptions)===null||r===void 0?void 0:r.shared,L.cacheHeuristic=(o=u.cacheOptions)===null||o===void 0?void 0:o.cacheHeuristic,L.immutableMinTimeToLive=(a=u.cacheOptions)===null||a===void 0?void 0:a.immutableMinTimeToLive,L.ignoreCargoCult=(n=u.cacheOptions)===null||n===void 0?void 0:n.ignoreCargoCult,u.dnsLookupIpVersion!==void 0)try{L.family=Kae.dnsLookupIpVersionToFamily(u.dnsLookupIpVersion)}catch{throw new Error("Invalid `dnsLookupIpVersion` option value")}u.https&&("rejectUnauthorized"in u.https&&(L.rejectUnauthorized=u.https.rejectUnauthorized),u.https.checkServerIdentity&&(L.checkServerIdentity=u.https.checkServerIdentity),u.https.certificateAuthority&&(L.ca=u.https.certificateAuthority),u.https.certificate&&(L.cert=u.https.certificate),u.https.key&&(L.key=u.https.key),u.https.passphrase&&(L.passphrase=u.https.passphrase),u.https.pfx&&(L.pfx=u.https.pfx));try{let U=await R(I,L);ot.default.undefined(U)&&(U=x(I,L)),u.request=h,u.timeout=E,u.agent=p,u.https&&("rejectUnauthorized"in u.https&&delete L.rejectUnauthorized,u.https.checkServerIdentity&&delete L.checkServerIdentity,u.https.certificateAuthority&&delete L.ca,u.https.certificate&&delete L.cert,u.https.key&&delete L.key,u.https.passphrase&&delete L.passphrase,u.https.pfx&&delete L.pfx),lst(U)?this._onRequest(U):this.writable?(this.once("finish",()=>{this._onResponse(U)}),this._unlockWrite(),this.end(),this._lockWrite()):this._onResponse(U)}catch(U){throw U instanceof jae.CacheError?new eS(U,this):new Ji(U.message,U,this)}}async _error(e){try{for(let r of this.options.hooks.beforeError)e=await r(e)}catch(r){e=new Ji(r.message,r,this)}this.destroy(e)}_beforeError(e){if(this[ay])return;let{options:r}=this,o=this.retryCount+1;this[ay]=!0,e instanceof Ji||(e=new Ji(e.message,e,this));let a=e,{response:n}=a;(async()=>{if(n&&!n.body){n.setEncoding(this._readableState.encoding);try{n.rawBody=await rst.default(n),n.body=n.rawBody.toString()}catch{}}if(this.listenerCount("retry")!==0){let u;try{let A;n&&"retry-after"in n.headers&&(A=Number(n.headers["retry-after"]),Number.isNaN(A)?(A=Date.parse(n.headers["retry-after"])-Date.now(),A<=0&&(A=1)):A*=1e3),u=await r.retry.calculateDelay({attemptCount:o,retryOptions:r.retry,error:a,retryAfter:A,computedValue:sst.default({attemptCount:o,retryOptions:r.retry,error:a,retryAfter:A,computedValue:0})})}catch(A){this._error(new Ji(A.message,A,this));return}if(u){let A=async()=>{try{for(let p of this.options.hooks.beforeRetry)await p(this.options,a,o)}catch(p){this._error(new Ji(p.message,e,this));return}this.destroyed||(this.destroy(),this.emit("retry",o,e))};this[Zae]=setTimeout(A,u);return}}this._error(a)})()}_read(){this[Jb]=!0;let e=this[Xb];if(e&&!this[ay]){e.readableLength&&(this[Jb]=!1);let r;for(;(r=e.read())!==null;){this[iy]+=r.length,this[Jae]=!0;let o=this.downloadProgress;o.percent<1&&this.emit("downloadProgress",o),this.push(r)}}}_write(e,r,o){let a=()=>{this._writeRequest(e,r,o)};this.requestInitialized?a():this[r1].push(a)}_writeRequest(e,r,o){this[$s].destroyed||(this._progressCallbacks.push(()=>{this[oy]+=Buffer.byteLength(e,r);let a=this.uploadProgress;a.percent<1&&this.emit("uploadProgress",a)}),this[$s].write(e,r,a=>{!a&&this._progressCallbacks.length>0&&this._progressCallbacks.shift()(),o(a)}))}_final(e){let r=()=>{for(;this._progressCallbacks.length!==0;)this._progressCallbacks.shift()();if(!($s in this)){e();return}if(this[$s].destroyed){e();return}this[$s].end(o=>{o||(this[sy]=this[oy],this.emit("uploadProgress",this.uploadProgress),this[$s].emit("upload-complete")),e(o)})};this.requestInitialized?r():this[r1].push(r)}_destroy(e,r){var o;this[ay]=!0,clearTimeout(this[Zae]),$s in this&&(this[g4](),!((o=this[Xb])===null||o===void 0)&&o.complete||this[$s].destroy()),e!==null&&!ot.default.undefined(e)&&!(e instanceof Ji)&&(e=new Ji(e.message,e,this)),r(e)}get _isAboutToError(){return this[ay]}get ip(){var e;return(e=this.socket)===null||e===void 0?void 0:e.remoteAddress}get aborted(){var e,r,o;return((r=(e=this[$s])===null||e===void 0?void 0:e.destroyed)!==null&&r!==void 0?r:this.destroyed)&&!(!((o=this[Xae])===null||o===void 0)&&o.complete)}get socket(){var e,r;return(r=(e=this[$s])===null||e===void 0?void 0:e.socket)!==null&&r!==void 0?r:void 0}get downloadProgress(){let e;return this[ny]?e=this[iy]/this[ny]:this[ny]===this[iy]?e=1:e=0,{percent:e,transferred:this[iy],total:this[ny]}}get uploadProgress(){let e;return this[sy]?e=this[oy]/this[sy]:this[sy]===this[oy]?e=1:e=0,{percent:e,transferred:this[oy],total:this[sy]}}get timings(){var e;return(e=this[$s])===null||e===void 0?void 0:e.timings}get isFromCache(){return this[zae]}pipe(e,r){if(this[Jae])throw new Error("Failed to pipe. The response has been emitted already.");return e instanceof p4.ServerResponse&&this[zb].add(e),super.pipe(e,r)}unpipe(e){return e instanceof p4.ServerResponse&&this[zb].delete(e),super.unpipe(e),this}};Bn.default=iS});var s1=_(Yc=>{"use strict";var pst=Yc&&Yc.__createBinding||(Object.create?function(t,e,r,o){o===void 0&&(o=r),Object.defineProperty(t,o,{enumerable:!0,get:function(){return e[r]}})}:function(t,e,r,o){o===void 0&&(o=r),t[o]=e[r]}),hst=Yc&&Yc.__exportStar||function(t,e){for(var r in t)r!=="default"&&!Object.prototype.hasOwnProperty.call(e,r)&&pst(e,t,r)};Object.defineProperty(Yc,"__esModule",{value:!0});Yc.CancelError=Yc.ParseError=void 0;var $ae=i1(),m4=class extends $ae.RequestError{constructor(e,r){let{options:o}=r.request;super(`${e.message} in "${o.url.toString()}"`,e,r.request),this.name="ParseError"}};Yc.ParseError=m4;var y4=class extends $ae.RequestError{constructor(e){super("Promise was canceled",{},e),this.name="CancelError"}get isCanceled(){return!0}};Yc.CancelError=y4;hst(i1(),Yc)});var tle=_(E4=>{"use strict";Object.defineProperty(E4,"__esModule",{value:!0});var ele=s1(),gst=(t,e,r,o)=>{let{rawBody:a}=t;try{if(e==="text")return a.toString(o);if(e==="json")return a.length===0?"":r(a.toString());if(e==="buffer")return a;throw new ele.ParseError({message:`Unknown body type '${e}'`,name:"Error"},t)}catch(n){throw new ele.ParseError(n,t)}};E4.default=gst});var C4=_(lh=>{"use strict";var dst=lh&&lh.__createBinding||(Object.create?function(t,e,r,o){o===void 0&&(o=r),Object.defineProperty(t,o,{enumerable:!0,get:function(){return e[r]}})}:function(t,e,r,o){o===void 0&&(o=r),t[o]=e[r]}),mst=lh&&lh.__exportStar||function(t,e){for(var r in t)r!=="default"&&!Object.prototype.hasOwnProperty.call(e,r)&&dst(e,t,r)};Object.defineProperty(lh,"__esModule",{value:!0});var yst=ve("events"),Est=Qf(),Cst=eoe(),sS=s1(),rle=tle(),nle=i1(),wst=r4(),Ist=c4(),ile=u4(),Bst=["request","response","redirect","uploadProgress","downloadProgress"];function sle(t){let e,r,o=new yst.EventEmitter,a=new Cst((u,A,p)=>{let h=E=>{let I=new nle.default(void 0,t);I.retryCount=E,I._noPipe=!0,p(()=>I.destroy()),p.shouldReject=!1,p(()=>A(new sS.CancelError(I))),e=I,I.once("response",async C=>{var R;if(C.retryCount=E,C.request.aborted)return;let L;try{L=await Ist.default(I),C.rawBody=L}catch{return}if(I._isAboutToError)return;let U=((R=C.headers["content-encoding"])!==null&&R!==void 0?R:"").toLowerCase(),z=["gzip","deflate","br"].includes(U),{options:te}=I;if(z&&!te.decompress)C.body=L;else try{C.body=rle.default(C,te.responseType,te.parseJson,te.encoding)}catch(ae){if(C.body=L.toString(),ile.isResponseOk(C)){I._beforeError(ae);return}}try{for(let[ae,le]of te.hooks.afterResponse.entries())C=await le(C,async ce=>{let Ce=nle.default.normalizeArguments(void 0,{...ce,retry:{calculateDelay:()=>0},throwHttpErrors:!1,resolveBodyOnly:!1},te);Ce.hooks.afterResponse=Ce.hooks.afterResponse.slice(0,ae);for(let Be of Ce.hooks.beforeRetry)await Be(Ce);let de=sle(Ce);return p(()=>{de.catch(()=>{}),de.cancel()}),de})}catch(ae){I._beforeError(new sS.RequestError(ae.message,ae,I));return}if(!ile.isResponseOk(C)){I._beforeError(new sS.HTTPError(C));return}r=C,u(I.options.resolveBodyOnly?C.body:C)});let v=C=>{if(a.isCanceled)return;let{options:R}=I;if(C instanceof sS.HTTPError&&!R.throwHttpErrors){let{response:L}=C;u(I.options.resolveBodyOnly?L.body:L);return}A(C)};I.once("error",v);let x=I.options.body;I.once("retry",(C,R)=>{var L,U;if(x===((L=R.request)===null||L===void 0?void 0:L.options.body)&&Est.default.nodeStream((U=R.request)===null||U===void 0?void 0:U.options.body)){v(R);return}h(C)}),wst.default(I,o,Bst)};h(0)});a.on=(u,A)=>(o.on(u,A),a);let n=u=>{let A=(async()=>{await a;let{options:p}=r.request;return rle.default(r,u,p.parseJson,p.encoding)})();return Object.defineProperties(A,Object.getOwnPropertyDescriptors(a)),A};return a.json=()=>{let{headers:u}=e.options;return!e.writableFinished&&u.accept===void 0&&(u.accept="application/json"),n("json")},a.buffer=()=>n("buffer"),a.text=()=>n("text"),a}lh.default=sle;mst(s1(),lh)});var ole=_(w4=>{"use strict";Object.defineProperty(w4,"__esModule",{value:!0});var vst=s1();function Dst(t,...e){let r=(async()=>{if(t instanceof vst.RequestError)try{for(let a of e)if(a)for(let n of a)t=await n(t)}catch(a){t=a}throw t})(),o=()=>r;return r.json=o,r.text=o,r.buffer=o,r.on=o,r}w4.default=Dst});var cle=_(I4=>{"use strict";Object.defineProperty(I4,"__esModule",{value:!0});var ale=Qf();function lle(t){for(let e of Object.values(t))(ale.default.plainObject(e)||ale.default.array(e))&&lle(e);return Object.freeze(t)}I4.default=lle});var Ale=_(ule=>{"use strict";Object.defineProperty(ule,"__esModule",{value:!0})});var B4=_(zl=>{"use strict";var Pst=zl&&zl.__createBinding||(Object.create?function(t,e,r,o){o===void 0&&(o=r),Object.defineProperty(t,o,{enumerable:!0,get:function(){return e[r]}})}:function(t,e,r,o){o===void 0&&(o=r),t[o]=e[r]}),bst=zl&&zl.__exportStar||function(t,e){for(var r in t)r!=="default"&&!Object.prototype.hasOwnProperty.call(e,r)&&Pst(e,t,r)};Object.defineProperty(zl,"__esModule",{value:!0});zl.defaultHandler=void 0;var fle=Qf(),Vl=C4(),Sst=ole(),aS=i1(),xst=cle(),kst={RequestError:Vl.RequestError,CacheError:Vl.CacheError,ReadError:Vl.ReadError,HTTPError:Vl.HTTPError,MaxRedirectsError:Vl.MaxRedirectsError,TimeoutError:Vl.TimeoutError,ParseError:Vl.ParseError,CancelError:Vl.CancelError,UnsupportedProtocolError:Vl.UnsupportedProtocolError,UploadError:Vl.UploadError},Qst=async t=>new Promise(e=>{setTimeout(e,t)}),{normalizeArguments:oS}=aS.default,ple=(...t)=>{let e;for(let r of t)e=oS(void 0,r,e);return e},Fst=t=>t.isStream?new aS.default(void 0,t):Vl.default(t),Rst=t=>"defaults"in t&&"options"in t.defaults,Tst=["get","post","put","patch","head","delete"];zl.defaultHandler=(t,e)=>e(t);var hle=(t,e)=>{if(t)for(let r of t)r(e)},gle=t=>{t._rawHandlers=t.handlers,t.handlers=t.handlers.map(o=>(a,n)=>{let u,A=o(a,p=>(u=n(p),u));if(A!==u&&!a.isStream&&u){let p=A,{then:h,catch:E,finally:I}=p;Object.setPrototypeOf(p,Object.getPrototypeOf(u)),Object.defineProperties(p,Object.getOwnPropertyDescriptors(u)),p.then=h,p.catch=E,p.finally=I}return A});let e=(o,a={},n)=>{var u,A;let p=0,h=E=>t.handlers[p++](E,p===t.handlers.length?Fst:h);if(fle.default.plainObject(o)){let E={...o,...a};aS.setNonEnumerableProperties([o,a],E),a=E,o=void 0}try{let E;try{hle(t.options.hooks.init,a),hle((u=a.hooks)===null||u===void 0?void 0:u.init,a)}catch(v){E=v}let I=oS(o,a,n??t.options);if(I[aS.kIsNormalizedAlready]=!0,E)throw new Vl.RequestError(E.message,E,I);return h(I)}catch(E){if(a.isStream)throw E;return Sst.default(E,t.options.hooks.beforeError,(A=a.hooks)===null||A===void 0?void 0:A.beforeError)}};e.extend=(...o)=>{let a=[t.options],n=[...t._rawHandlers],u;for(let A of o)Rst(A)?(a.push(A.defaults.options),n.push(...A.defaults._rawHandlers),u=A.defaults.mutableDefaults):(a.push(A),"handlers"in A&&n.push(...A.handlers),u=A.mutableDefaults);return n=n.filter(A=>A!==zl.defaultHandler),n.length===0&&n.push(zl.defaultHandler),gle({options:ple(...a),handlers:n,mutableDefaults:!!u})};let r=async function*(o,a){let n=oS(o,a,t.options);n.resolveBodyOnly=!1;let u=n.pagination;if(!fle.default.object(u))throw new TypeError("`options.pagination` must be implemented");let A=[],{countLimit:p}=u,h=0;for(;h{let n=[];for await(let u of r(o,a))n.push(u);return n},e.paginate.each=r,e.stream=(o,a)=>e(o,{...a,isStream:!0});for(let o of Tst)e[o]=(a,n)=>e(a,{...n,method:o}),e.stream[o]=(a,n)=>e(a,{...n,method:o,isStream:!0});return Object.assign(e,kst),Object.defineProperty(e,"defaults",{value:t.mutableDefaults?t:xst.default(t),writable:t.mutableDefaults,configurable:t.mutableDefaults,enumerable:!0}),e.mergeOptions=ple,e};zl.default=gle;bst(Ale(),zl)});var yle=_((Ff,lS)=>{"use strict";var Nst=Ff&&Ff.__createBinding||(Object.create?function(t,e,r,o){o===void 0&&(o=r),Object.defineProperty(t,o,{enumerable:!0,get:function(){return e[r]}})}:function(t,e,r,o){o===void 0&&(o=r),t[o]=e[r]}),dle=Ff&&Ff.__exportStar||function(t,e){for(var r in t)r!=="default"&&!Object.prototype.hasOwnProperty.call(e,r)&&Nst(e,t,r)};Object.defineProperty(Ff,"__esModule",{value:!0});var Lst=ve("url"),mle=B4(),Mst={options:{method:"GET",retry:{limit:2,methods:["GET","PUT","HEAD","DELETE","OPTIONS","TRACE"],statusCodes:[408,413,429,500,502,503,504,521,522,524],errorCodes:["ETIMEDOUT","ECONNRESET","EADDRINUSE","ECONNREFUSED","EPIPE","ENOTFOUND","ENETUNREACH","EAI_AGAIN"],maxRetryAfter:void 0,calculateDelay:({computedValue:t})=>t},timeout:{},headers:{"user-agent":"got (https://github.com/sindresorhus/got)"},hooks:{init:[],beforeRequest:[],beforeRedirect:[],beforeRetry:[],beforeError:[],afterResponse:[]},cache:void 0,dnsCache:void 0,decompress:!0,throwHttpErrors:!0,followRedirect:!0,isStream:!1,responseType:"text",resolveBodyOnly:!1,maxRedirects:10,prefixUrl:"",methodRewriting:!0,ignoreInvalidCookies:!1,context:{},http2:!1,allowGetBody:!1,https:void 0,pagination:{transform:t=>t.request.options.responseType==="json"?t.body:JSON.parse(t.body),paginate:t=>{if(!Reflect.has(t.headers,"link"))return!1;let e=t.headers.link.split(","),r;for(let o of e){let a=o.split(";");if(a[1].includes("next")){r=a[0].trimStart().trim(),r=r.slice(1,-1);break}}return r?{url:new Lst.URL(r)}:!1},filter:()=>!0,shouldContinue:()=>!0,countLimit:1/0,backoff:0,requestLimit:1e4,stackAllItems:!0},parseJson:t=>JSON.parse(t),stringifyJson:t=>JSON.stringify(t),cacheOptions:{}},handlers:[mle.defaultHandler],mutableDefaults:!1},v4=mle.default(Mst);Ff.default=v4;lS.exports=v4;lS.exports.default=v4;lS.exports.__esModule=!0;dle(B4(),Ff);dle(C4(),Ff)});var sn={};Vt(sn,{Method:()=>Dle,del:()=>qst,get:()=>S4,getNetworkSettings:()=>vle,post:()=>x4,put:()=>Hst,request:()=>o1});function wle(t){let e=new URL(t),r={host:e.hostname,headers:{}};return e.port&&(r.port=Number(e.port)),e.username&&e.password&&(r.proxyAuth=`${e.username}:${e.password}`),{proxy:r}}async function D4(t){return al(Cle,t,()=>oe.readFilePromise(t).then(e=>(Cle.set(t,e),e)))}function _st({statusCode:t,statusMessage:e},r){let o=Ot(r,t,yt.NUMBER),a=`https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/${t}`;return Tm(r,`${o}${e?` (${e})`:""}`,a)}async function cS(t,{configuration:e,customErrorMessage:r}){try{return await t}catch(o){if(o.name!=="HTTPError")throw o;let a=r?.(o,e)??o.response.body?.error;a==null&&(o.message.startsWith("Response code")?a="The remote server failed to provide the requested resource":a=o.message),o.code==="ETIMEDOUT"&&o.event==="socket"&&(a+=`(can be increased via ${Ot(e,"httpTimeout",yt.SETTING)})`);let n=new Jt(35,a,u=>{o.response&&u.reportError(35,` ${Xu(e,{label:"Response Code",value:Hc(yt.NO_HINT,_st(o.response,e))})}`),o.request&&(u.reportError(35,` ${Xu(e,{label:"Request Method",value:Hc(yt.NO_HINT,o.request.options.method)})}`),u.reportError(35,` ${Xu(e,{label:"Request URL",value:Hc(yt.URL,o.request.requestUrl)})}`)),o.request.redirects.length>0&&u.reportError(35,` ${Xu(e,{label:"Request Redirects",value:Hc(yt.NO_HINT,mL(e,o.request.redirects,yt.URL))})}`),o.request.retryCount===o.request.options.retry.limit&&u.reportError(35,` ${Xu(e,{label:"Request Retry Count",value:Hc(yt.NO_HINT,`${Ot(e,o.request.retryCount,yt.NUMBER)} (can be increased via ${Ot(e,"httpRetry",yt.SETTING)})`)})}`)});throw n.originalError=o,n}}function vle(t,e){let r=[...e.configuration.get("networkSettings")].sort(([u],[A])=>A.length-u.length),o={enableNetwork:void 0,httpsCaFilePath:void 0,httpProxy:void 0,httpsProxy:void 0,httpsKeyFilePath:void 0,httpsCertFilePath:void 0},a=Object.keys(o),n=typeof t=="string"?new URL(t):t;for(let[u,A]of r)if(b4.default.isMatch(n.hostname,u))for(let p of a){let h=A.get(p);h!==null&&typeof o[p]>"u"&&(o[p]=h)}for(let u of a)typeof o[u]>"u"&&(o[u]=e.configuration.get(u));return o}async function o1(t,e,{configuration:r,headers:o,jsonRequest:a,jsonResponse:n,method:u="GET",wrapNetworkRequest:A}){let p={target:t,body:e,configuration:r,headers:o,jsonRequest:a,jsonResponse:n,method:u},h=async()=>await jst(t,e,p),E=typeof A<"u"?await A(h,p):h;return await(await r.reduceHook(v=>v.wrapNetworkRequest,E,p))()}async function S4(t,{configuration:e,jsonResponse:r,customErrorMessage:o,wrapNetworkRequest:a,...n}){let u=()=>cS(o1(t,null,{configuration:e,wrapNetworkRequest:a,...n}),{configuration:e,customErrorMessage:o}).then(p=>p.body),A=await(typeof a<"u"?u():al(Ele,t,()=>u().then(p=>(Ele.set(t,p),p))));return r?JSON.parse(A.toString()):A}async function Hst(t,e,{customErrorMessage:r,...o}){return(await cS(o1(t,e,{...o,method:"PUT"}),{customErrorMessage:r,configuration:o.configuration})).body}async function x4(t,e,{customErrorMessage:r,...o}){return(await cS(o1(t,e,{...o,method:"POST"}),{customErrorMessage:r,configuration:o.configuration})).body}async function qst(t,{customErrorMessage:e,...r}){return(await cS(o1(t,null,{...r,method:"DELETE"}),{customErrorMessage:e,configuration:r.configuration})).body}async function jst(t,e,{configuration:r,headers:o,jsonRequest:a,jsonResponse:n,method:u="GET"}){let A=typeof t=="string"?new URL(t):t,p=vle(A,{configuration:r});if(p.enableNetwork===!1)throw new Jt(80,`Request to '${A.href}' has been blocked because of your configuration settings`);if(A.protocol==="http:"&&!b4.default.isMatch(A.hostname,r.get("unsafeHttpWhitelist")))throw new Jt(81,`Unsafe http requests must be explicitly whitelisted in your configuration (${A.hostname})`);let E={agent:{http:p.httpProxy?P4.default.httpOverHttp(wle(p.httpProxy)):Ost,https:p.httpsProxy?P4.default.httpsOverHttp(wle(p.httpsProxy)):Ust},headers:o,method:u};E.responseType=n?"json":"buffer",e!==null&&(Buffer.isBuffer(e)||!a&&typeof e=="string"?E.body=e:E.json=e);let I=r.get("httpTimeout"),v=r.get("httpRetry"),x=r.get("enableStrictSsl"),C=p.httpsCaFilePath,R=p.httpsCertFilePath,L=p.httpsKeyFilePath,{default:U}=await Promise.resolve().then(()=>Ze(yle())),z=C?await D4(C):void 0,te=R?await D4(R):void 0,ae=L?await D4(L):void 0,le=U.extend({timeout:{socket:I},retry:v,https:{rejectUnauthorized:x,certificateAuthority:z,certificate:te,key:ae},...E});return r.getLimit("networkConcurrency")(()=>le(A))}var Ile,Ble,b4,P4,Ele,Cle,Ost,Ust,Dle,uS=Et(()=>{Pt();Ile=ve("https"),Ble=ve("http"),b4=Ze($o()),P4=Ze(zse());Wl();jl();ql();Ele=new Map,Cle=new Map,Ost=new Ble.Agent({keepAlive:!0}),Ust=new Ile.Agent({keepAlive:!0});Dle=(a=>(a.GET="GET",a.PUT="PUT",a.POST="POST",a.DELETE="DELETE",a))(Dle||{})});var Xi={};Vt(Xi,{availableParallelism:()=>Q4,getArchitecture:()=>a1,getArchitectureName:()=>Vst,getArchitectureSet:()=>k4,getCaller:()=>Zst,major:()=>Gst,openUrl:()=>Yst});function Kst(){if(process.platform==="darwin"||process.platform==="win32")return null;let t;try{t=oe.readFileSync(Wst)}catch{}if(typeof t<"u"){if(t&&(t.includes("GLIBC")||t.includes("libc")))return"glibc";if(t&&t.includes("musl"))return"musl"}let r=(process.report?.getReport()??{}).sharedObjects??[],o=/\/(?:(ld-linux-|[^/]+-linux-gnu\/)|(libc.musl-|ld-musl-))/;return Vp(r,a=>{let n=a.match(o);if(!n)return Vp.skip;if(n[1])return"glibc";if(n[2])return"musl";throw new Error("Assertion failed: Expected the libc variant to have been detected")})??null}function a1(){return ble=ble??{os:process.platform,cpu:process.arch,libc:Kst()}}function Vst(t=a1()){return t.libc?`${t.os}-${t.cpu}-${t.libc}`:`${t.os}-${t.cpu}`}function k4(){let t=a1();return Sle=Sle??{os:[t.os],cpu:[t.cpu],libc:t.libc?[t.libc]:[]}}function Xst(t){let e=zst.exec(t);if(!e)return null;let r=e[2]&&e[2].indexOf("native")===0,o=e[2]&&e[2].indexOf("eval")===0,a=Jst.exec(e[2]);return o&&a!=null&&(e[2]=a[1],e[3]=a[2],e[4]=a[3]),{file:r?null:e[2],methodName:e[1]||"",arguments:r?[e[2]]:[],line:e[3]?+e[3]:null,column:e[4]?+e[4]:null}}function Zst(){let e=new Error().stack.split(` +`)[3];return Xst(e)}function Q4(){return typeof AS.default.availableParallelism<"u"?AS.default.availableParallelism():Math.max(1,AS.default.cpus().length)}var AS,Gst,Ple,Yst,Wst,ble,Sle,zst,Jst,fS=Et(()=>{Pt();AS=Ze(ve("os"));pS();ql();Gst=Number(process.versions.node.split(".")[0]),Ple=new Map([["darwin","open"],["linux","xdg-open"],["win32","explorer.exe"]]).get(process.platform),Yst=typeof Ple<"u"?async t=>{try{return await F4(Ple,[t],{cwd:V.cwd()}),!0}catch{return!1}}:void 0,Wst="/usr/bin/ldd";zst=/^\s*at (.*?) ?\(((?:file|https?|blob|chrome-extension|native|eval|webpack||\/|[a-z]:\\|\\\\).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i,Jst=/\((\S*)(?::(\d+))(?::(\d+))\)/});function M4(t,e,r,o,a){let n=VI(r);if(o.isArray||o.type==="ANY"&&Array.isArray(n))return Array.isArray(n)?n.map((u,A)=>R4(t,`${e}[${A}]`,u,o,a)):String(n).split(/,/).map(u=>R4(t,e,u,o,a));if(Array.isArray(n))throw new Error(`Non-array configuration settings "${e}" cannot be an array`);return R4(t,e,r,o,a)}function R4(t,e,r,o,a){let n=VI(r);switch(o.type){case"ANY":return Fb(n);case"SHAPE":return rot(t,e,r,o,a);case"MAP":return not(t,e,r,o,a)}if(n===null&&!o.isNullable&&o.default!==null)throw new Error(`Non-nullable configuration settings "${e}" cannot be set to null`);if(o.values?.includes(n))return n;let A=(()=>{if(o.type==="BOOLEAN"&&typeof n!="string")return QI(n);if(typeof n!="string")throw new Error(`Expected configuration setting "${e}" to be a string, got ${typeof n}`);let p=YP(n,{env:t.env});switch(o.type){case"ABSOLUTE_PATH":{let h=a,E=cO(r);return E&&E[0]!=="<"&&(h=V.dirname(E)),V.resolve(h,ue.toPortablePath(p))}case"LOCATOR_LOOSE":return bf(p,!1);case"NUMBER":return parseInt(p);case"LOCATOR":return bf(p);case"BOOLEAN":return QI(p);default:return p}})();if(o.values&&!o.values.includes(A))throw new Error(`Invalid value, expected one of ${o.values.join(", ")}`);return A}function rot(t,e,r,o,a){let n=VI(r);if(typeof n!="object"||Array.isArray(n))throw new st(`Object configuration settings "${e}" must be an object`);let u=O4(t,o,{ignoreArrays:!0});if(n===null)return u;for(let[A,p]of Object.entries(n)){let h=`${e}.${A}`;if(!o.properties[A])throw new st(`Unrecognized configuration settings found: ${e}.${A} - run "yarn config -v" to see the list of settings supported in Yarn`);u.set(A,M4(t,h,p,o.properties[A],a))}return u}function not(t,e,r,o,a){let n=VI(r),u=new Map;if(typeof n!="object"||Array.isArray(n))throw new st(`Map configuration settings "${e}" must be an object`);if(n===null)return u;for(let[A,p]of Object.entries(n)){let h=o.normalizeKeys?o.normalizeKeys(A):A,E=`${e}['${h}']`,I=o.valueDefinition;u.set(h,M4(t,E,p,I,a))}return u}function O4(t,e,{ignoreArrays:r=!1}={}){switch(e.type){case"SHAPE":{if(e.isArray&&!r)return[];let o=new Map;for(let[a,n]of Object.entries(e.properties))o.set(a,O4(t,n));return o}case"MAP":return e.isArray&&!r?[]:new Map;case"ABSOLUTE_PATH":return e.default===null?null:t.projectCwd===null?Array.isArray(e.default)?e.default.map(o=>V.normalize(o)):V.isAbsolute(e.default)?V.normalize(e.default):e.isNullable?null:void 0:Array.isArray(e.default)?e.default.map(o=>V.resolve(t.projectCwd,o)):V.resolve(t.projectCwd,e.default);default:return e.default}}function gS(t,e,r){if(e.type==="SECRET"&&typeof t=="string"&&r.hideSecrets)return tot;if(e.type==="ABSOLUTE_PATH"&&typeof t=="string"&&r.getNativePaths)return ue.fromPortablePath(t);if(e.isArray&&Array.isArray(t)){let o=[];for(let a of t)o.push(gS(a,e,r));return o}if(e.type==="MAP"&&t instanceof Map){if(t.size===0)return;let o=new Map;for(let[a,n]of t.entries()){let u=gS(n,e.valueDefinition,r);typeof u<"u"&&o.set(a,u)}return o}if(e.type==="SHAPE"&&t instanceof Map){if(t.size===0)return;let o=new Map;for(let[a,n]of t.entries()){let u=e.properties[a],A=gS(n,u,r);typeof A<"u"&&o.set(a,A)}return o}return t}function iot(){let t={};for(let[e,r]of Object.entries(process.env))e=e.toLowerCase(),e.startsWith(dS)&&(e=(0,kle.default)(e.slice(dS.length)),t[e]=r);return t}function N4(){let t=`${dS}rc_filename`;for(let[e,r]of Object.entries(process.env))if(e.toLowerCase()===t&&typeof r=="string")return r;return L4}async function xle(t){try{return await oe.readFilePromise(t)}catch{return Buffer.of()}}async function sot(t,e){return Buffer.compare(...await Promise.all([xle(t),xle(e)]))===0}async function oot(t,e){let[r,o]=await Promise.all([oe.statPromise(t),oe.statPromise(e)]);return r.dev===o.dev&&r.ino===o.ino}async function lot({configuration:t,selfPath:e}){let r=t.get("yarnPath");return t.get("ignorePath")||r===null||r===e||await aot(r,e)?null:r}var kle,Rf,Qle,Fle,Rle,T4,$st,l1,eot,ly,dS,L4,tot,c1,Tle,mS,hS,aot,Ke,u1=Et(()=>{Pt();Nl();kle=Ze(sV()),Rf=Ze(X0());qt();Qle=Ze(ZV()),Fle=ve("module"),Rle=Ze(eg()),T4=ve("stream");use();Gm();tO();rO();nO();Ose();iO();mg();jse();Tb();jl();th();uS();ql();fS();Sf();So();$st=function(){if(!Rf.GITHUB_ACTIONS||!process.env.GITHUB_EVENT_PATH)return!1;let t=ue.toPortablePath(process.env.GITHUB_EVENT_PATH),e;try{e=oe.readJsonSync(t)}catch{return!1}return!(!("repository"in e)||!e.repository||(e.repository.private??!0))}(),l1=new Set(["@yarnpkg/plugin-constraints","@yarnpkg/plugin-exec","@yarnpkg/plugin-interactive-tools","@yarnpkg/plugin-stage","@yarnpkg/plugin-typescript","@yarnpkg/plugin-version","@yarnpkg/plugin-workspace-tools"]),eot=new Set(["isTestEnv","injectNpmUser","injectNpmPassword","injectNpm2FaToken","zipDataEpilogue","cacheCheckpointOverride","cacheVersionOverride","lockfileVersionOverride","binFolder","version","flags","profile","gpg","ignoreNode","wrapOutput","home","confDir","registry","ignoreCwd"]),ly=/^(?!v)[a-z0-9._-]+$/i,dS="yarn_",L4=".yarnrc.yml",tot="********",c1=(E=>(E.ANY="ANY",E.BOOLEAN="BOOLEAN",E.ABSOLUTE_PATH="ABSOLUTE_PATH",E.LOCATOR="LOCATOR",E.LOCATOR_LOOSE="LOCATOR_LOOSE",E.NUMBER="NUMBER",E.STRING="STRING",E.SECRET="SECRET",E.SHAPE="SHAPE",E.MAP="MAP",E))(c1||{}),Tle=yt,mS=(r=>(r.JUNCTIONS="junctions",r.SYMLINKS="symlinks",r))(mS||{}),hS={lastUpdateCheck:{description:"Last timestamp we checked whether new Yarn versions were available",type:"STRING",default:null},yarnPath:{description:"Path to the local executable that must be used over the global one",type:"ABSOLUTE_PATH",default:null},ignorePath:{description:"If true, the local executable will be ignored when using the global one",type:"BOOLEAN",default:!1},globalFolder:{description:"Folder where all system-global files are stored",type:"ABSOLUTE_PATH",default:AO()},cacheFolder:{description:"Folder where the cache files must be written",type:"ABSOLUTE_PATH",default:"./.yarn/cache"},compressionLevel:{description:"Zip files compression level, from 0 to 9 or mixed (a variant of 9, which stores some files uncompressed, when compression doesn't yield good results)",type:"NUMBER",values:["mixed",0,1,2,3,4,5,6,7,8,9],default:0},virtualFolder:{description:"Folder where the virtual packages (cf doc) will be mapped on the disk (must be named __virtual__)",type:"ABSOLUTE_PATH",default:"./.yarn/__virtual__"},installStatePath:{description:"Path of the file where the install state will be persisted",type:"ABSOLUTE_PATH",default:"./.yarn/install-state.gz"},immutablePatterns:{description:"Array of glob patterns; files matching them won't be allowed to change during immutable installs",type:"STRING",default:[],isArray:!0},rcFilename:{description:"Name of the files where the configuration can be found",type:"STRING",default:N4()},enableGlobalCache:{description:"If true, the system-wide cache folder will be used regardless of `cache-folder`",type:"BOOLEAN",default:!0},cacheMigrationMode:{description:"Defines the conditions under which Yarn upgrades should cause the cache archives to be regenerated.",type:"STRING",values:["always","match-spec","required-only"],default:"always"},enableColors:{description:"If true, the CLI is allowed to use colors in its output",type:"BOOLEAN",default:VP,defaultText:""},enableHyperlinks:{description:"If true, the CLI is allowed to use hyperlinks in its output",type:"BOOLEAN",default:dL,defaultText:""},enableInlineBuilds:{description:"If true, the CLI will print the build output on the command line",type:"BOOLEAN",default:Rf.isCI,defaultText:""},enableMessageNames:{description:"If true, the CLI will prefix most messages with codes suitable for search engines",type:"BOOLEAN",default:!0},enableProgressBars:{description:"If true, the CLI is allowed to show a progress bar for long-running events",type:"BOOLEAN",default:!Rf.isCI,defaultText:""},enableTimers:{description:"If true, the CLI is allowed to print the time spent executing commands",type:"BOOLEAN",default:!0},enableTips:{description:"If true, installs will print a helpful message every day of the week",type:"BOOLEAN",default:!Rf.isCI,defaultText:""},preferInteractive:{description:"If true, the CLI will automatically use the interactive mode when called from a TTY",type:"BOOLEAN",default:!1},preferTruncatedLines:{description:"If true, the CLI will truncate lines that would go beyond the size of the terminal",type:"BOOLEAN",default:!1},progressBarStyle:{description:"Which style of progress bar should be used (only when progress bars are enabled)",type:"STRING",default:void 0,defaultText:""},defaultLanguageName:{description:"Default language mode that should be used when a package doesn't offer any insight",type:"STRING",default:"node"},defaultProtocol:{description:"Default resolution protocol used when resolving pure semver and tag ranges",type:"STRING",default:"npm:"},enableTransparentWorkspaces:{description:"If false, Yarn won't automatically resolve workspace dependencies unless they use the `workspace:` protocol",type:"BOOLEAN",default:!0},supportedArchitectures:{description:"Architectures that Yarn will fetch and inject into the resolver",type:"SHAPE",properties:{os:{description:"Array of supported process.platform strings, or null to target them all",type:"STRING",isArray:!0,isNullable:!0,default:["current"]},cpu:{description:"Array of supported process.arch strings, or null to target them all",type:"STRING",isArray:!0,isNullable:!0,default:["current"]},libc:{description:"Array of supported libc libraries, or null to target them all",type:"STRING",isArray:!0,isNullable:!0,default:["current"]}}},enableMirror:{description:"If true, the downloaded packages will be retrieved and stored in both the local and global folders",type:"BOOLEAN",default:!0},enableNetwork:{description:"If false, Yarn will refuse to use the network if required to",type:"BOOLEAN",default:!0},enableOfflineMode:{description:"If true, Yarn will attempt to retrieve files and metadata from the global cache rather than the network",type:"BOOLEAN",default:!1},httpProxy:{description:"URL of the http proxy that must be used for outgoing http requests",type:"STRING",default:null},httpsProxy:{description:"URL of the http proxy that must be used for outgoing https requests",type:"STRING",default:null},unsafeHttpWhitelist:{description:"List of the hostnames for which http queries are allowed (glob patterns are supported)",type:"STRING",default:[],isArray:!0},httpTimeout:{description:"Timeout of each http request in milliseconds",type:"NUMBER",default:6e4},httpRetry:{description:"Retry times on http failure",type:"NUMBER",default:3},networkConcurrency:{description:"Maximal number of concurrent requests",type:"NUMBER",default:50},taskPoolConcurrency:{description:"Maximal amount of concurrent heavy task processing",type:"NUMBER",default:Q4()},taskPoolMode:{description:"Execution strategy for heavy tasks",type:"STRING",values:["async","workers"],default:"workers"},networkSettings:{description:"Network settings per hostname (glob patterns are supported)",type:"MAP",valueDefinition:{description:"",type:"SHAPE",properties:{httpsCaFilePath:{description:"Path to file containing one or multiple Certificate Authority signing certificates",type:"ABSOLUTE_PATH",default:null},enableNetwork:{description:"If false, the package manager will refuse to use the network if required to",type:"BOOLEAN",default:null},httpProxy:{description:"URL of the http proxy that must be used for outgoing http requests",type:"STRING",default:null},httpsProxy:{description:"URL of the http proxy that must be used for outgoing https requests",type:"STRING",default:null},httpsKeyFilePath:{description:"Path to file containing private key in PEM format",type:"ABSOLUTE_PATH",default:null},httpsCertFilePath:{description:"Path to file containing certificate chain in PEM format",type:"ABSOLUTE_PATH",default:null}}}},httpsCaFilePath:{description:"A path to a file containing one or multiple Certificate Authority signing certificates",type:"ABSOLUTE_PATH",default:null},httpsKeyFilePath:{description:"Path to file containing private key in PEM format",type:"ABSOLUTE_PATH",default:null},httpsCertFilePath:{description:"Path to file containing certificate chain in PEM format",type:"ABSOLUTE_PATH",default:null},enableStrictSsl:{description:"If false, SSL certificate errors will be ignored",type:"BOOLEAN",default:!0},logFilters:{description:"Overrides for log levels",type:"SHAPE",isArray:!0,concatenateValues:!0,properties:{code:{description:"Code of the messages covered by this override",type:"STRING",default:void 0},text:{description:"Code of the texts covered by this override",type:"STRING",default:void 0},pattern:{description:"Code of the patterns covered by this override",type:"STRING",default:void 0},level:{description:"Log level override, set to null to remove override",type:"STRING",values:Object.values(JP),isNullable:!0,default:void 0}}},enableTelemetry:{description:"If true, telemetry will be periodically sent, following the rules in https://yarnpkg.com/advanced/telemetry",type:"BOOLEAN",default:!0},telemetryInterval:{description:"Minimal amount of time between two telemetry uploads, in days",type:"NUMBER",default:7},telemetryUserId:{description:"If you desire to tell us which project you are, you can set this field. Completely optional and opt-in.",type:"STRING",default:null},enableHardenedMode:{description:"If true, automatically enable --check-resolutions --refresh-lockfile on installs",type:"BOOLEAN",default:Rf.isPR&&$st,defaultText:""},enableScripts:{description:"If true, packages are allowed to have install scripts by default",type:"BOOLEAN",default:!0},enableStrictSettings:{description:"If true, unknown settings will cause Yarn to abort",type:"BOOLEAN",default:!0},enableImmutableCache:{description:"If true, the cache is reputed immutable and actions that would modify it will throw",type:"BOOLEAN",default:!1},checksumBehavior:{description:"Enumeration defining what to do when a checksum doesn't match expectations",type:"STRING",default:"throw"},injectEnvironmentFiles:{description:"List of all the environment files that Yarn should inject inside the process when it starts",type:"ABSOLUTE_PATH",default:[".env.yarn?"],isArray:!0},packageExtensions:{description:"Map of package corrections to apply on the dependency tree",type:"MAP",valueDefinition:{description:"The extension that will be applied to any package whose version matches the specified range",type:"SHAPE",properties:{dependencies:{description:"The set of dependencies that must be made available to the current package in order for it to work properly",type:"MAP",valueDefinition:{description:"A range",type:"STRING"}},peerDependencies:{description:"Inherited dependencies - the consumer of the package will be tasked to provide them",type:"MAP",valueDefinition:{description:"A semver range",type:"STRING"}},peerDependenciesMeta:{description:"Extra information related to the dependencies listed in the peerDependencies field",type:"MAP",valueDefinition:{description:"The peerDependency meta",type:"SHAPE",properties:{optional:{description:"If true, the selected peer dependency will be marked as optional by the package manager and the consumer omitting it won't be reported as an error",type:"BOOLEAN",default:!1}}}}}}}};aot=process.platform==="win32"?sot:oot;Ke=class t{constructor(e){this.isCI=Rf.isCI;this.projectCwd=null;this.plugins=new Map;this.settings=new Map;this.values=new Map;this.sources=new Map;this.invalid=new Map;this.env={};this.limits=new Map;this.packageExtensions=null;this.startingCwd=e}static{this.deleteProperty=Symbol()}static{this.telemetry=null}static create(e,r,o){let a=new t(e);typeof r<"u"&&!(r instanceof Map)&&(a.projectCwd=r),a.importSettings(hS);let n=typeof o<"u"?o:r instanceof Map?r:new Map;for(let[u,A]of n)a.activatePlugin(u,A);return a}static async find(e,r,{strict:o=!0,usePathCheck:a=null,useRc:n=!0}={}){let u=iot();delete u.rcFilename;let A=new t(e),p=await t.findRcFiles(e),h=await t.findFolderRcFile(Jm());h&&(p.find(Ce=>Ce.path===h.path)||p.unshift(h));let E=qse(p.map(ce=>[ce.path,ce.data])),I=It.dot,v=new Set(Object.keys(hS)),x=({yarnPath:ce,ignorePath:Ce,injectEnvironmentFiles:de})=>({yarnPath:ce,ignorePath:Ce,injectEnvironmentFiles:de}),C=({yarnPath:ce,ignorePath:Ce,injectEnvironmentFiles:de,...Be})=>{let Ee={};for(let[g,me]of Object.entries(Be))v.has(g)&&(Ee[g]=me);return Ee},R=({yarnPath:ce,ignorePath:Ce,...de})=>{let Be={};for(let[Ee,g]of Object.entries(de))v.has(Ee)||(Be[Ee]=g);return Be};if(A.importSettings(x(hS)),A.useWithSource("",x(u),e,{strict:!1}),E){let[ce,Ce]=E;A.useWithSource(ce,x(Ce),I,{strict:!1})}if(a){if(await lot({configuration:A,selfPath:a})!==null)return A;A.useWithSource("",{ignorePath:!0},e,{strict:!1,overwrite:!0})}let L=await t.findProjectCwd(e);A.startingCwd=e,A.projectCwd=L;let U=Object.assign(Object.create(null),process.env);A.env=U;let z=await Promise.all(A.get("injectEnvironmentFiles").map(async ce=>{let Ce=ce.endsWith("?")?await oe.readFilePromise(ce.slice(0,-1),"utf8").catch(()=>""):await oe.readFilePromise(ce,"utf8");return(0,Qle.parse)(Ce)}));for(let ce of z)for(let[Ce,de]of Object.entries(ce))A.env[Ce]=YP(de,{env:U});if(A.importSettings(C(hS)),A.useWithSource("",C(u),e,{strict:o}),E){let[ce,Ce]=E;A.useWithSource(ce,C(Ce),I,{strict:o})}let te=ce=>"default"in ce?ce.default:ce,ae=new Map([["@@core",cse]]);if(r!==null)for(let ce of r.plugins.keys())ae.set(ce,te(r.modules.get(ce)));for(let[ce,Ce]of ae)A.activatePlugin(ce,Ce);let le=new Map([]);if(r!==null){let ce=new Map;for(let Be of Fle.builtinModules)ce.set(Be,()=>vf(Be));for(let[Be,Ee]of r.modules)ce.set(Be,()=>Ee);let Ce=new Set,de=async(Be,Ee)=>{let{factory:g,name:me}=vf(Be);if(!g||Ce.has(me))return;let we=new Map(ce),Ae=Z=>{if(we.has(Z))return we.get(Z)();throw new st(`This plugin cannot access the package referenced via ${Z} which is neither a builtin, nor an exposed entry`)},ne=await xm(async()=>te(await g(Ae)),Z=>`${Z} (when initializing ${me}, defined in ${Ee})`);ce.set(me,()=>ne),Ce.add(me),le.set(me,ne)};if(u.plugins)for(let Be of u.plugins.split(";")){let Ee=V.resolve(e,ue.toPortablePath(Be));await de(Ee,"")}for(let{path:Be,cwd:Ee,data:g}of p)if(n&&Array.isArray(g.plugins))for(let me of g.plugins){let we=typeof me!="string"?me.path:me,Ae=me?.spec??"",ne=me?.checksum??"";if(l1.has(Ae))continue;let Z=V.resolve(Ee,ue.toPortablePath(we));if(!await oe.existsPromise(Z)){if(!Ae){let ht=Ot(A,V.basename(Z,".cjs"),yt.NAME),H=Ot(A,".gitignore",yt.NAME),rt=Ot(A,A.values.get("rcFilename"),yt.NAME),Te=Ot(A,"https://yarnpkg.com/getting-started/qa#which-files-should-be-gitignored",yt.URL);throw new st(`Missing source for the ${ht} plugin - please try to remove the plugin from ${rt} then reinstall it manually. This error usually occurs because ${H} is incorrect, check ${Te} to make sure your plugin folder isn't gitignored.`)}if(!Ae.match(/^https?:/)){let ht=Ot(A,V.basename(Z,".cjs"),yt.NAME),H=Ot(A,A.values.get("rcFilename"),yt.NAME);throw new st(`Failed to recognize the source for the ${ht} plugin - please try to delete the plugin from ${H} then reinstall it manually.`)}let xe=await S4(Ae,{configuration:A}),Ne=zi(xe);if(ne&&ne!==Ne){let ht=Ot(A,V.basename(Z,".cjs"),yt.NAME),H=Ot(A,A.values.get("rcFilename"),yt.NAME),rt=Ot(A,`yarn plugin import ${Ae}`,yt.CODE);throw new st(`Failed to fetch the ${ht} plugin from its remote location: its checksum seems to have changed. If this is expected, please remove the plugin from ${H} then run ${rt} to reimport it.`)}await oe.mkdirPromise(V.dirname(Z),{recursive:!0}),await oe.writeFilePromise(Z,xe)}await de(Z,Be)}}for(let[ce,Ce]of le)A.activatePlugin(ce,Ce);if(A.useWithSource("",R(u),e,{strict:o}),E){let[ce,Ce]=E;A.useWithSource(ce,R(Ce),I,{strict:o})}return A.get("enableGlobalCache")&&(A.values.set("cacheFolder",`${A.get("globalFolder")}/cache`),A.sources.set("cacheFolder","")),A}static async findRcFiles(e){let r=N4(),o=[],a=e,n=null;for(;a!==n;){n=a;let u=V.join(n,r);if(oe.existsSync(u)){let A=await oe.readFilePromise(u,"utf8"),p;try{p=Ki(A)}catch{let E="";throw A.match(/^\s+(?!-)[^:]+\s+\S+/m)&&(E=" (in particular, make sure you list the colons after each key name)"),new st(`Parse error when loading ${u}; please check it's proper Yaml${E}`)}o.unshift({path:u,cwd:n,data:p})}a=V.dirname(n)}return o}static async findFolderRcFile(e){let r=V.join(e,dr.rc),o;try{o=await oe.readFilePromise(r,"utf8")}catch(n){if(n.code==="ENOENT")return null;throw n}let a=Ki(o);return{path:r,cwd:e,data:a}}static async findProjectCwd(e){let r=null,o=e,a=null;for(;o!==a;){if(a=o,oe.existsSync(V.join(a,dr.lockfile)))return a;oe.existsSync(V.join(a,dr.manifest))&&(r=a),o=V.dirname(a)}return r}static async updateConfiguration(e,r,o={}){let a=N4(),n=V.join(e,a),u=oe.existsSync(n)?Ki(await oe.readFilePromise(n,"utf8")):{},A=!1,p;if(typeof r=="function"){try{p=r(u)}catch{p=r({})}if(p===u)return!1}else{p=u;for(let h of Object.keys(r)){let E=u[h],I=r[h],v;if(typeof I=="function")try{v=I(E)}catch{v=I(void 0)}else v=I;E!==v&&(v===t.deleteProperty?delete p[h]:p[h]=v,A=!0)}if(!A)return!1}return await oe.changeFilePromise(n,Da(p),{automaticNewlines:!0}),!0}static async addPlugin(e,r){r.length!==0&&await t.updateConfiguration(e,o=>{let a=o.plugins??[];if(a.length===0)return{...o,plugins:r};let n=[],u=[...r];for(let A of a){let p=typeof A!="string"?A.path:A,h=u.find(E=>E.path===p);h?(n.push(h),u=u.filter(E=>E!==h)):n.push(A)}return n.push(...u),{...o,plugins:n}})}static async updateHomeConfiguration(e){let r=Jm();return await t.updateConfiguration(r,e)}activatePlugin(e,r){this.plugins.set(e,r),typeof r.configuration<"u"&&this.importSettings(r.configuration)}importSettings(e){for(let[r,o]of Object.entries(e))if(o!=null){if(this.settings.has(r))throw new Error(`Cannot redefine settings "${r}"`);this.settings.set(r,o),this.values.set(r,O4(this,o))}}useWithSource(e,r,o,a){try{this.use(e,r,o,a)}catch(n){throw n.message+=` (in ${Ot(this,e,yt.PATH)})`,n}}use(e,r,o,{strict:a=!0,overwrite:n=!1}={}){a=a&&this.get("enableStrictSettings");for(let u of["enableStrictSettings",...Object.keys(r)]){let A=r[u],p=cO(A);if(p&&(e=p),typeof A>"u"||u==="plugins"||e===""&&eot.has(u))continue;if(u==="rcFilename")throw new st(`The rcFilename settings can only be set via ${`${dS}RC_FILENAME`.toUpperCase()}, not via a rc file`);let h=this.settings.get(u);if(!h){let I=Jm(),v=e[0]!=="<"?V.dirname(e):null;if(a&&!(v!==null?I===v:!1))throw new st(`Unrecognized or legacy configuration settings found: ${u} - run "yarn config -v" to see the list of settings supported in Yarn`);this.invalid.set(u,e);continue}if(this.sources.has(u)&&!(n||h.type==="MAP"||h.isArray&&h.concatenateValues))continue;let E;try{E=M4(this,u,A,h,o)}catch(I){throw I.message+=` in ${Ot(this,e,yt.PATH)}`,I}if(u==="enableStrictSettings"&&e!==""){a=E;continue}if(h.type==="MAP"){let I=this.values.get(u);this.values.set(u,new Map(n?[...I,...E]:[...E,...I])),this.sources.set(u,`${this.sources.get(u)}, ${e}`)}else if(h.isArray&&h.concatenateValues){let I=this.values.get(u);this.values.set(u,n?[...I,...E]:[...E,...I]),this.sources.set(u,`${this.sources.get(u)}, ${e}`)}else this.values.set(u,E),this.sources.set(u,e)}}get(e){if(!this.values.has(e))throw new Error(`Invalid configuration key "${e}"`);return this.values.get(e)}getSpecial(e,{hideSecrets:r=!1,getNativePaths:o=!1}){let a=this.get(e),n=this.settings.get(e);if(typeof n>"u")throw new st(`Couldn't find a configuration settings named "${e}"`);return gS(a,n,{hideSecrets:r,getNativePaths:o})}getSubprocessStreams(e,{header:r,prefix:o,report:a}){let n,u,A=oe.createWriteStream(e);if(this.get("enableInlineBuilds")){let p=a.createStreamReporter(`${o} ${Ot(this,"STDOUT","green")}`),h=a.createStreamReporter(`${o} ${Ot(this,"STDERR","red")}`);n=new T4.PassThrough,n.pipe(p),n.pipe(A),u=new T4.PassThrough,u.pipe(h),u.pipe(A)}else n=A,u=A,typeof r<"u"&&n.write(`${r} +`);return{stdout:n,stderr:u}}makeResolver(){let e=[];for(let r of this.plugins.values())for(let o of r.resolvers||[])e.push(new o);return new yg([new Qb,new ei,...e])}makeFetcher(){let e=[];for(let r of this.plugins.values())for(let o of r.fetchers||[])e.push(new o);return new Wm([new Km,new Vm,...e])}getLinkers(){let e=[];for(let r of this.plugins.values())for(let o of r.linkers||[])e.push(new o);return e}getSupportedArchitectures(){let e=a1(),r=this.get("supportedArchitectures"),o=r.get("os");o!==null&&(o=o.map(u=>u==="current"?e.os:u));let a=r.get("cpu");a!==null&&(a=a.map(u=>u==="current"?e.cpu:u));let n=r.get("libc");return n!==null&&(n=ol(n,u=>u==="current"?e.libc??ol.skip:u)),{os:o,cpu:a,libc:n}}isInteractive({interactive:e,stdout:r}){return r.isTTY?e??this.get("preferInteractive"):!1}async getPackageExtensions(){if(this.packageExtensions!==null)return this.packageExtensions;this.packageExtensions=new Map;let e=this.packageExtensions,r=(o,a,{userProvided:n=!1}={})=>{if(!Qa(o.range))throw new Error("Only semver ranges are allowed as keys for the packageExtensions setting");let u=new Ut;u.load(a,{yamlCompatibilityMode:!0});let A=xI(e,o.identHash),p=[];A.push([o.range,p]);let h={status:"inactive",userProvided:n,parentDescriptor:o};for(let E of u.dependencies.values())p.push({...h,type:"Dependency",descriptor:E});for(let E of u.peerDependencies.values())p.push({...h,type:"PeerDependency",descriptor:E});for(let[E,I]of u.peerDependenciesMeta)for(let[v,x]of Object.entries(I))p.push({...h,type:"PeerDependencyMeta",selector:E,key:v,value:x})};await this.triggerHook(o=>o.registerPackageExtensions,this,r);for(let[o,a]of this.get("packageExtensions"))r(rh(o,!0),GP(a),{userProvided:!0});return e}normalizeLocator(e){return Qa(e.reference)?Rs(e,`${this.get("defaultProtocol")}${e.reference}`):ly.test(e.reference)?Rs(e,`${this.get("defaultProtocol")}${e.reference}`):e}normalizeDependency(e){return Qa(e.range)?In(e,`${this.get("defaultProtocol")}${e.range}`):ly.test(e.range)?In(e,`${this.get("defaultProtocol")}${e.range}`):e}normalizeDependencyMap(e){return new Map([...e].map(([r,o])=>[r,this.normalizeDependency(o)]))}normalizePackage(e,{packageExtensions:r}){let o=OI(e),a=r.get(e.identHash);if(typeof a<"u"){let u=e.version;if(u!==null){for(let[A,p]of a)if(tA(u,A))for(let h of p)switch(h.status==="inactive"&&(h.status="redundant"),h.type){case"Dependency":typeof o.dependencies.get(h.descriptor.identHash)>"u"&&(h.status="active",o.dependencies.set(h.descriptor.identHash,this.normalizeDependency(h.descriptor)));break;case"PeerDependency":typeof o.peerDependencies.get(h.descriptor.identHash)>"u"&&(h.status="active",o.peerDependencies.set(h.descriptor.identHash,h.descriptor));break;case"PeerDependencyMeta":{let E=o.peerDependenciesMeta.get(h.selector);(typeof E>"u"||!Object.hasOwn(E,h.key)||E[h.key]!==h.value)&&(h.status="active",al(o.peerDependenciesMeta,h.selector,()=>({}))[h.key]=h.value)}break;default:cL(h)}}}let n=u=>u.scope?`${u.scope}__${u.name}`:`${u.name}`;for(let u of o.peerDependenciesMeta.keys()){let A=ea(u);o.peerDependencies.has(A.identHash)||o.peerDependencies.set(A.identHash,In(A,"*"))}for(let u of o.peerDependencies.values()){if(u.scope==="types")continue;let A=n(u),p=eA("types",A),h=rn(p);o.peerDependencies.has(p.identHash)||o.peerDependenciesMeta.has(h)||(o.peerDependencies.set(p.identHash,In(p,"*")),o.peerDependenciesMeta.set(h,{optional:!0}))}return o.dependencies=new Map(Fs(o.dependencies,([,u])=>xa(u))),o.peerDependencies=new Map(Fs(o.peerDependencies,([,u])=>xa(u))),o}getLimit(e){return al(this.limits,e,()=>(0,Rle.default)(this.get(e)))}async triggerHook(e,...r){for(let o of this.plugins.values()){let a=o.hooks;if(!a)continue;let n=e(a);n&&await n(...r)}}async triggerMultipleHooks(e,r){for(let o of r)await this.triggerHook(e,...o)}async reduceHook(e,r,...o){let a=r;for(let n of this.plugins.values()){let u=n.hooks;if(!u)continue;let A=e(u);A&&(a=await A(a,...o))}return a}async firstHook(e,...r){for(let o of this.plugins.values()){let a=o.hooks;if(!a)continue;let n=e(a);if(!n)continue;let u=await n(...r);if(typeof u<"u")return u}return null}}});var Ur={};Vt(Ur,{EndStrategy:()=>q4,ExecError:()=>yS,PipeError:()=>A1,execvp:()=>F4,pipevp:()=>Wc});function Ig(t){return t!==null&&typeof t.fd=="number"}function U4(){}function _4(){for(let t of Bg)t.kill()}async function Wc(t,e,{cwd:r,env:o=process.env,strict:a=!1,stdin:n=null,stdout:u,stderr:A,end:p=2}){let h=["pipe","pipe","pipe"];n===null?h[0]="ignore":Ig(n)&&(h[0]=n),Ig(u)&&(h[1]=u),Ig(A)&&(h[2]=A);let E=(0,H4.default)(t,e,{cwd:ue.fromPortablePath(r),env:{...o,PWD:ue.fromPortablePath(r)},stdio:h});Bg.add(E),Bg.size===1&&(process.on("SIGINT",U4),process.on("SIGTERM",_4)),!Ig(n)&&n!==null&&n.pipe(E.stdin),Ig(u)||E.stdout.pipe(u,{end:!1}),Ig(A)||E.stderr.pipe(A,{end:!1});let I=()=>{for(let v of new Set([u,A]))Ig(v)||v.end()};return new Promise((v,x)=>{E.on("error",C=>{Bg.delete(E),Bg.size===0&&(process.off("SIGINT",U4),process.off("SIGTERM",_4)),(p===2||p===1)&&I(),x(C)}),E.on("close",(C,R)=>{Bg.delete(E),Bg.size===0&&(process.off("SIGINT",U4),process.off("SIGTERM",_4)),(p===2||p===1&&C!==0)&&I(),C===0||!a?v({code:j4(C,R)}):x(new A1({fileName:t,code:C,signal:R}))})})}async function F4(t,e,{cwd:r,env:o=process.env,encoding:a="utf8",strict:n=!1}){let u=["ignore","pipe","pipe"],A=[],p=[],h=ue.fromPortablePath(r);typeof o.PWD<"u"&&(o={...o,PWD:h});let E=(0,H4.default)(t,e,{cwd:h,env:o,stdio:u});return E.stdout.on("data",I=>{A.push(I)}),E.stderr.on("data",I=>{p.push(I)}),await new Promise((I,v)=>{E.on("error",x=>{let C=Ke.create(r),R=Ot(C,t,yt.PATH);v(new Jt(1,`Process ${R} failed to spawn`,L=>{L.reportError(1,` ${Xu(C,{label:"Thrown Error",value:Hc(yt.NO_HINT,x.message)})}`)}))}),E.on("close",(x,C)=>{let R=a==="buffer"?Buffer.concat(A):Buffer.concat(A).toString(a),L=a==="buffer"?Buffer.concat(p):Buffer.concat(p).toString(a);x===0||!n?I({code:j4(x,C),stdout:R,stderr:L}):v(new yS({fileName:t,code:x,signal:C,stdout:R,stderr:L}))})})}function j4(t,e){let r=cot.get(e);return typeof r<"u"?128+r:t??1}function uot(t,e,{configuration:r,report:o}){o.reportError(1,` ${Xu(r,t!==null?{label:"Exit Code",value:Hc(yt.NUMBER,t)}:{label:"Exit Signal",value:Hc(yt.CODE,e)})}`)}var H4,q4,A1,yS,Bg,cot,pS=Et(()=>{Pt();H4=Ze(KR());u1();Wl();jl();q4=(o=>(o[o.Never=0]="Never",o[o.ErrorCode=1]="ErrorCode",o[o.Always=2]="Always",o))(q4||{}),A1=class extends Jt{constructor({fileName:e,code:r,signal:o}){let a=Ke.create(V.cwd()),n=Ot(a,e,yt.PATH);super(1,`Child ${n} reported an error`,u=>{uot(r,o,{configuration:a,report:u})}),this.code=j4(r,o)}},yS=class extends A1{constructor({fileName:e,code:r,signal:o,stdout:a,stderr:n}){super({fileName:e,code:r,signal:o}),this.stdout=a,this.stderr=n}};Bg=new Set;cot=new Map([["SIGINT",2],["SIGQUIT",3],["SIGKILL",9],["SIGTERM",15]])});function Lle(t){Nle=t}function f1(){return typeof G4>"u"&&(G4=Nle()),G4}var G4,Nle,Y4=Et(()=>{Nle=()=>{throw new Error("Assertion failed: No libzip instance is available, and no factory was configured")}});var Mle=_((ES,K4)=>{var Aot=Object.assign({},ve("fs")),W4=function(){var t=typeof document<"u"&&document.currentScript?document.currentScript.src:void 0;return typeof __filename<"u"&&(t=t||__filename),function(e){e=e||{};var r=typeof e<"u"?e:{},o,a;r.ready=new Promise(function(We,tt){o=We,a=tt});var n={},u;for(u in r)r.hasOwnProperty(u)&&(n[u]=r[u]);var A=[],p="./this.program",h=function(We,tt){throw tt},E=!1,I=!0,v="";function x(We){return r.locateFile?r.locateFile(We,v):v+We}var C,R,L,U;I&&(E?v=ve("path").dirname(v)+"/":v=__dirname+"/",C=function(tt,Bt){var or=ii(tt);return or?Bt?or:or.toString():(L||(L=Aot),U||(U=ve("path")),tt=U.normalize(tt),L.readFileSync(tt,Bt?null:"utf8"))},R=function(tt){var Bt=C(tt,!0);return Bt.buffer||(Bt=new Uint8Array(Bt)),me(Bt.buffer),Bt},process.argv.length>1&&(p=process.argv[1].replace(/\\/g,"/")),A=process.argv.slice(2),h=function(We){process.exit(We)},r.inspect=function(){return"[Emscripten Module object]"});var z=r.print||console.log.bind(console),te=r.printErr||console.warn.bind(console);for(u in n)n.hasOwnProperty(u)&&(r[u]=n[u]);n=null,r.arguments&&(A=r.arguments),r.thisProgram&&(p=r.thisProgram),r.quit&&(h=r.quit);var ae=0,le=function(We){ae=We},ce;r.wasmBinary&&(ce=r.wasmBinary);var Ce=r.noExitRuntime||!0;typeof WebAssembly!="object"&&Ri("no native wasm support detected");function de(We,tt,Bt){switch(tt=tt||"i8",tt.charAt(tt.length-1)==="*"&&(tt="i32"),tt){case"i1":return Ye[We>>0];case"i8":return Ye[We>>0];case"i16":return op((We>>1)*2);case"i32":return Us((We>>2)*4);case"i64":return Us((We>>2)*4);case"float":return Au((We>>2)*4);case"double":return sp((We>>3)*8);default:Ri("invalid type for getValue: "+tt)}return null}var Be,Ee=!1,g;function me(We,tt){We||Ri("Assertion failed: "+tt)}function we(We){var tt=r["_"+We];return me(tt,"Cannot call unknown function "+We+", make sure it is exported"),tt}function Ae(We,tt,Bt,or,ee){var ye={string:function(rs){var bi=0;if(rs!=null&&rs!==0){var qo=(rs.length<<2)+1;bi=Un(qo),ht(rs,bi,qo)}return bi},array:function(rs){var bi=Un(rs.length);return Te(rs,bi),bi}};function Le(rs){return tt==="string"?xe(rs):tt==="boolean"?!!rs:rs}var ft=we(We),pt=[],Nt=0;if(or)for(var rr=0;rr=Bt)&&be[or];)++or;return Z.decode(be.subarray(We,or))}function Ne(We,tt,Bt,or){if(!(or>0))return 0;for(var ee=Bt,ye=Bt+or-1,Le=0;Le=55296&&ft<=57343){var pt=We.charCodeAt(++Le);ft=65536+((ft&1023)<<10)|pt&1023}if(ft<=127){if(Bt>=ye)break;tt[Bt++]=ft}else if(ft<=2047){if(Bt+1>=ye)break;tt[Bt++]=192|ft>>6,tt[Bt++]=128|ft&63}else if(ft<=65535){if(Bt+2>=ye)break;tt[Bt++]=224|ft>>12,tt[Bt++]=128|ft>>6&63,tt[Bt++]=128|ft&63}else{if(Bt+3>=ye)break;tt[Bt++]=240|ft>>18,tt[Bt++]=128|ft>>12&63,tt[Bt++]=128|ft>>6&63,tt[Bt++]=128|ft&63}}return tt[Bt]=0,Bt-ee}function ht(We,tt,Bt){return Ne(We,be,tt,Bt)}function H(We){for(var tt=0,Bt=0;Bt=55296&&or<=57343&&(or=65536+((or&1023)<<10)|We.charCodeAt(++Bt)&1023),or<=127?++tt:or<=2047?tt+=2:or<=65535?tt+=3:tt+=4}return tt}function rt(We){var tt=H(We)+1,Bt=Ni(tt);return Bt&&Ne(We,Ye,Bt,tt),Bt}function Te(We,tt){Ye.set(We,tt)}function Fe(We,tt){return We%tt>0&&(We+=tt-We%tt),We}var ke,Ye,be,et,Ue,S,w,b,y,F;function J(We){ke=We,r.HEAP_DATA_VIEW=F=new DataView(We),r.HEAP8=Ye=new Int8Array(We),r.HEAP16=et=new Int16Array(We),r.HEAP32=S=new Int32Array(We),r.HEAPU8=be=new Uint8Array(We),r.HEAPU16=Ue=new Uint16Array(We),r.HEAPU32=w=new Uint32Array(We),r.HEAPF32=b=new Float32Array(We),r.HEAPF64=y=new Float64Array(We)}var X=r.INITIAL_MEMORY||16777216,$,ie=[],Se=[],Re=[],at=!1;function dt(){if(r.preRun)for(typeof r.preRun=="function"&&(r.preRun=[r.preRun]);r.preRun.length;)bt(r.preRun.shift());oo(ie)}function jt(){at=!0,oo(Se)}function tr(){if(r.postRun)for(typeof r.postRun=="function"&&(r.postRun=[r.postRun]);r.postRun.length;)kr(r.postRun.shift());oo(Re)}function bt(We){ie.unshift(We)}function ln(We){Se.unshift(We)}function kr(We){Re.unshift(We)}var mr=0,Sr=null,Kr=null;function Kn(We){mr++,r.monitorRunDependencies&&r.monitorRunDependencies(mr)}function Ms(We){if(mr--,r.monitorRunDependencies&&r.monitorRunDependencies(mr),mr==0&&(Sr!==null&&(clearInterval(Sr),Sr=null),Kr)){var tt=Kr;Kr=null,tt()}}r.preloadedImages={},r.preloadedAudios={};function Ri(We){r.onAbort&&r.onAbort(We),We+="",te(We),Ee=!0,g=1,We="abort("+We+"). Build with -s ASSERTIONS=1 for more info.";var tt=new WebAssembly.RuntimeError(We);throw a(tt),tt}var gs="data:application/octet-stream;base64,";function io(We){return We.startsWith(gs)}var Pi="data:application/octet-stream;base64,AGFzbQEAAAAB/wEkYAN/f38Bf2ABfwF/YAJ/fwF/YAF/AGAEf39/fwF/YAN/f38AYAV/f39/fwF/YAJ/fwBgBH9/f38AYAABf2AFf39/fn8BfmAEf35/fwF/YAR/f35/AX5gAn9+AX9gA398fwBgA39/fgF/YAF/AX5gBn9/f39/fwF/YAN/fn8Bf2AEf39/fwF+YAV/f35/fwF/YAR/f35/AX9gA39/fgF+YAJ/fgBgAn9/AX5gBX9/f39/AGADf35/AX5gBX5+f35/AX5gA39/fwF+YAZ/fH9/f38Bf2AAAGAHf35/f39+fwF/YAV/fn9/fwF/YAV/f39/fwF+YAJ+fwF/YAJ/fAACJQYBYQFhAAMBYQFiAAEBYQFjAAABYQFkAAEBYQFlAAIBYQFmAAED5wHlAQMAAwEDAwEHDAgDFgcNEgEDDRcFAQ8DEAUQAwIBAhgECxkEAQMBBQsFAwMDARACBAMAAggLBwEAAwADGgQDGwYGABwBBgMTFBEHBwcVCx4ABAgHBAICAgAfAQICAgIGFSAAIQAiAAIBBgIHAg0LEw0FAQUCACMDAQAUAAAGBQECBQUDCwsSAgEDBQIHAQEICAACCQQEAQABCAEBCQoBAwkBAQEBBgEGBgYABAIEBAQGEQQEAAARAAEDCQEJAQAJCQkBAQECCgoAAAMPAQEBAwACAgICBQIABwAKBgwHAAADAgICBQEEBQFwAT8/BQcBAYACgIACBgkBfwFBgInBAgsH+gEzAWcCAAFoAFQBaQDqAQFqALsBAWsAwQEBbACpAQFtAKgBAW4ApwEBbwClAQFwAKMBAXEAoAEBcgCbAQFzAMABAXQAugEBdQC5AQF2AEsBdwDiAQF4AMgBAXkAxwEBegDCAQFBAMkBAUIAuAEBQwAGAUQACQFFAKYBAUYAtwEBRwC2AQFIALUBAUkAtAEBSgCzAQFLALIBAUwAsQEBTQCwAQFOAK8BAU8AvAEBUACuAQFRAK0BAVIArAEBUwAaAVQACwFVAKQBAVYAMgFXAQABWACrAQFZAKoBAVoAxgEBXwDFAQEkAMQBAmFhAL8BAmJhAL4BAmNhAL0BCXgBAEEBCz6iAeMBjgGQAVpbjwFYnwGdAVeeAV1coQFZVlWcAZoBmQGYAZcBlgGVAZQBkwGSAZEB6QHoAecB5gHlAeQB4QHfAeAB3gHdAdwB2gHbAYUB2QHYAdcB1gHVAdQB0wHSAdEB0AHPAc4BzQHMAcsBygE4wwEK1N8G5QHMDAEHfwJAIABFDQAgAEEIayIDIABBBGsoAgAiAUF4cSIAaiEFAkAgAUEBcQ0AIAFBA3FFDQEgAyADKAIAIgFrIgNBxIQBKAIASQ0BIAAgAWohACADQciEASgCAEcEQCABQf8BTQRAIAMoAggiAiABQQN2IgRBA3RB3IQBakYaIAIgAygCDCIBRgRAQbSEAUG0hAEoAgBBfiAEd3E2AgAMAwsgAiABNgIMIAEgAjYCCAwCCyADKAIYIQYCQCADIAMoAgwiAUcEQCADKAIIIgIgATYCDCABIAI2AggMAQsCQCADQRRqIgIoAgAiBA0AIANBEGoiAigCACIEDQBBACEBDAELA0AgAiEHIAQiAUEUaiICKAIAIgQNACABQRBqIQIgASgCECIEDQALIAdBADYCAAsgBkUNAQJAIAMgAygCHCICQQJ0QeSGAWoiBCgCAEYEQCAEIAE2AgAgAQ0BQbiEAUG4hAEoAgBBfiACd3E2AgAMAwsgBkEQQRQgBigCECADRhtqIAE2AgAgAUUNAgsgASAGNgIYIAMoAhAiAgRAIAEgAjYCECACIAE2AhgLIAMoAhQiAkUNASABIAI2AhQgAiABNgIYDAELIAUoAgQiAUEDcUEDRw0AQbyEASAANgIAIAUgAUF+cTYCBCADIABBAXI2AgQgACADaiAANgIADwsgAyAFTw0AIAUoAgQiAUEBcUUNAAJAIAFBAnFFBEAgBUHMhAEoAgBGBEBBzIQBIAM2AgBBwIQBQcCEASgCACAAaiIANgIAIAMgAEEBcjYCBCADQciEASgCAEcNA0G8hAFBADYCAEHIhAFBADYCAA8LIAVByIQBKAIARgRAQciEASADNgIAQbyEAUG8hAEoAgAgAGoiADYCACADIABBAXI2AgQgACADaiAANgIADwsgAUF4cSAAaiEAAkAgAUH/AU0EQCAFKAIIIgIgAUEDdiIEQQN0QdyEAWpGGiACIAUoAgwiAUYEQEG0hAFBtIQBKAIAQX4gBHdxNgIADAILIAIgATYCDCABIAI2AggMAQsgBSgCGCEGAkAgBSAFKAIMIgFHBEAgBSgCCCICQcSEASgCAEkaIAIgATYCDCABIAI2AggMAQsCQCAFQRRqIgIoAgAiBA0AIAVBEGoiAigCACIEDQBBACEBDAELA0AgAiEHIAQiAUEUaiICKAIAIgQNACABQRBqIQIgASgCECIEDQALIAdBADYCAAsgBkUNAAJAIAUgBSgCHCICQQJ0QeSGAWoiBCgCAEYEQCAEIAE2AgAgAQ0BQbiEAUG4hAEoAgBBfiACd3E2AgAMAgsgBkEQQRQgBigCECAFRhtqIAE2AgAgAUUNAQsgASAGNgIYIAUoAhAiAgRAIAEgAjYCECACIAE2AhgLIAUoAhQiAkUNACABIAI2AhQgAiABNgIYCyADIABBAXI2AgQgACADaiAANgIAIANByIQBKAIARw0BQbyEASAANgIADwsgBSABQX5xNgIEIAMgAEEBcjYCBCAAIANqIAA2AgALIABB/wFNBEAgAEEDdiIBQQN0QdyEAWohAAJ/QbSEASgCACICQQEgAXQiAXFFBEBBtIQBIAEgAnI2AgAgAAwBCyAAKAIICyECIAAgAzYCCCACIAM2AgwgAyAANgIMIAMgAjYCCA8LQR8hAiADQgA3AhAgAEH///8HTQRAIABBCHYiASABQYD+P2pBEHZBCHEiAXQiAiACQYDgH2pBEHZBBHEiAnQiBCAEQYCAD2pBEHZBAnEiBHRBD3YgASACciAEcmsiAUEBdCAAIAFBFWp2QQFxckEcaiECCyADIAI2AhwgAkECdEHkhgFqIQECQAJAAkBBuIQBKAIAIgRBASACdCIHcUUEQEG4hAEgBCAHcjYCACABIAM2AgAgAyABNgIYDAELIABBAEEZIAJBAXZrIAJBH0YbdCECIAEoAgAhAQNAIAEiBCgCBEF4cSAARg0CIAJBHXYhASACQQF0IQIgBCABQQRxaiIHQRBqKAIAIgENAAsgByADNgIQIAMgBDYCGAsgAyADNgIMIAMgAzYCCAwBCyAEKAIIIgAgAzYCDCAEIAM2AgggA0EANgIYIAMgBDYCDCADIAA2AggLQdSEAUHUhAEoAgBBAWsiAEF/IAAbNgIACwuDBAEDfyACQYAETwRAIAAgASACEAIaIAAPCyAAIAJqIQMCQCAAIAFzQQNxRQRAAkAgAEEDcUUEQCAAIQIMAQsgAkEBSARAIAAhAgwBCyAAIQIDQCACIAEtAAA6AAAgAUEBaiEBIAJBAWoiAkEDcUUNASACIANJDQALCwJAIANBfHEiBEHAAEkNACACIARBQGoiBUsNAANAIAIgASgCADYCACACIAEoAgQ2AgQgAiABKAIINgIIIAIgASgCDDYCDCACIAEoAhA2AhAgAiABKAIUNgIUIAIgASgCGDYCGCACIAEoAhw2AhwgAiABKAIgNgIgIAIgASgCJDYCJCACIAEoAig2AiggAiABKAIsNgIsIAIgASgCMDYCMCACIAEoAjQ2AjQgAiABKAI4NgI4IAIgASgCPDYCPCABQUBrIQEgAkFAayICIAVNDQALCyACIARPDQEDQCACIAEoAgA2AgAgAUEEaiEBIAJBBGoiAiAESQ0ACwwBCyADQQRJBEAgACECDAELIAAgA0EEayIESwRAIAAhAgwBCyAAIQIDQCACIAEtAAA6AAAgAiABLQABOgABIAIgAS0AAjoAAiACIAEtAAM6AAMgAUEEaiEBIAJBBGoiAiAETQ0ACwsgAiADSQRAA0AgAiABLQAAOgAAIAFBAWohASACQQFqIgIgA0cNAAsLIAALGgAgAARAIAAtAAEEQCAAKAIEEAYLIAAQBgsLoi4BDH8jAEEQayIMJAACQAJAAkACQAJAAkACQAJAAkACQAJAAkAgAEH0AU0EQEG0hAEoAgAiBUEQIABBC2pBeHEgAEELSRsiCEEDdiICdiIBQQNxBEAgAUF/c0EBcSACaiIDQQN0IgFB5IQBaigCACIEQQhqIQACQCAEKAIIIgIgAUHchAFqIgFGBEBBtIQBIAVBfiADd3E2AgAMAQsgAiABNgIMIAEgAjYCCAsgBCADQQN0IgFBA3I2AgQgASAEaiIBIAEoAgRBAXI2AgQMDQsgCEG8hAEoAgAiCk0NASABBEACQEECIAJ0IgBBACAAa3IgASACdHEiAEEAIABrcUEBayIAIABBDHZBEHEiAnYiAUEFdkEIcSIAIAJyIAEgAHYiAUECdkEEcSIAciABIAB2IgFBAXZBAnEiAHIgASAAdiIBQQF2QQFxIgByIAEgAHZqIgNBA3QiAEHkhAFqKAIAIgQoAggiASAAQdyEAWoiAEYEQEG0hAEgBUF+IAN3cSIFNgIADAELIAEgADYCDCAAIAE2AggLIARBCGohACAEIAhBA3I2AgQgBCAIaiICIANBA3QiASAIayIDQQFyNgIEIAEgBGogAzYCACAKBEAgCkEDdiIBQQN0QdyEAWohB0HIhAEoAgAhBAJ/IAVBASABdCIBcUUEQEG0hAEgASAFcjYCACAHDAELIAcoAggLIQEgByAENgIIIAEgBDYCDCAEIAc2AgwgBCABNgIIC0HIhAEgAjYCAEG8hAEgAzYCAAwNC0G4hAEoAgAiBkUNASAGQQAgBmtxQQFrIgAgAEEMdkEQcSICdiIBQQV2QQhxIgAgAnIgASAAdiIBQQJ2QQRxIgByIAEgAHYiAUEBdkECcSIAciABIAB2IgFBAXZBAXEiAHIgASAAdmpBAnRB5IYBaigCACIBKAIEQXhxIAhrIQMgASECA0ACQCACKAIQIgBFBEAgAigCFCIARQ0BCyAAKAIEQXhxIAhrIgIgAyACIANJIgIbIQMgACABIAIbIQEgACECDAELCyABIAhqIgkgAU0NAiABKAIYIQsgASABKAIMIgRHBEAgASgCCCIAQcSEASgCAEkaIAAgBDYCDCAEIAA2AggMDAsgAUEUaiICKAIAIgBFBEAgASgCECIARQ0EIAFBEGohAgsDQCACIQcgACIEQRRqIgIoAgAiAA0AIARBEGohAiAEKAIQIgANAAsgB0EANgIADAsLQX8hCCAAQb9/Sw0AIABBC2oiAEF4cSEIQbiEASgCACIJRQ0AQQAgCGshAwJAAkACQAJ/QQAgCEGAAkkNABpBHyAIQf///wdLDQAaIABBCHYiACAAQYD+P2pBEHZBCHEiAnQiACAAQYDgH2pBEHZBBHEiAXQiACAAQYCAD2pBEHZBAnEiAHRBD3YgASACciAAcmsiAEEBdCAIIABBFWp2QQFxckEcagsiBUECdEHkhgFqKAIAIgJFBEBBACEADAELQQAhACAIQQBBGSAFQQF2ayAFQR9GG3QhAQNAAkAgAigCBEF4cSAIayIHIANPDQAgAiEEIAciAw0AQQAhAyACIQAMAwsgACACKAIUIgcgByACIAFBHXZBBHFqKAIQIgJGGyAAIAcbIQAgAUEBdCEBIAINAAsLIAAgBHJFBEBBAiAFdCIAQQAgAGtyIAlxIgBFDQMgAEEAIABrcUEBayIAIABBDHZBEHEiAnYiAUEFdkEIcSIAIAJyIAEgAHYiAUECdkEEcSIAciABIAB2IgFBAXZBAnEiAHIgASAAdiIBQQF2QQFxIgByIAEgAHZqQQJ0QeSGAWooAgAhAAsgAEUNAQsDQCAAKAIEQXhxIAhrIgEgA0khAiABIAMgAhshAyAAIAQgAhshBCAAKAIQIgEEfyABBSAAKAIUCyIADQALCyAERQ0AIANBvIQBKAIAIAhrTw0AIAQgCGoiBiAETQ0BIAQoAhghBSAEIAQoAgwiAUcEQCAEKAIIIgBBxIQBKAIASRogACABNgIMIAEgADYCCAwKCyAEQRRqIgIoAgAiAEUEQCAEKAIQIgBFDQQgBEEQaiECCwNAIAIhByAAIgFBFGoiAigCACIADQAgAUEQaiECIAEoAhAiAA0ACyAHQQA2AgAMCQsgCEG8hAEoAgAiAk0EQEHIhAEoAgAhAwJAIAIgCGsiAUEQTwRAQbyEASABNgIAQciEASADIAhqIgA2AgAgACABQQFyNgIEIAIgA2ogATYCACADIAhBA3I2AgQMAQtByIQBQQA2AgBBvIQBQQA2AgAgAyACQQNyNgIEIAIgA2oiACAAKAIEQQFyNgIECyADQQhqIQAMCwsgCEHAhAEoAgAiBkkEQEHAhAEgBiAIayIBNgIAQcyEAUHMhAEoAgAiAiAIaiIANgIAIAAgAUEBcjYCBCACIAhBA3I2AgQgAkEIaiEADAsLQQAhACAIQS9qIgkCf0GMiAEoAgAEQEGUiAEoAgAMAQtBmIgBQn83AgBBkIgBQoCggICAgAQ3AgBBjIgBIAxBDGpBcHFB2KrVqgVzNgIAQaCIAUEANgIAQfCHAUEANgIAQYAgCyIBaiIFQQAgAWsiB3EiAiAITQ0KQeyHASgCACIEBEBB5IcBKAIAIgMgAmoiASADTQ0LIAEgBEsNCwtB8IcBLQAAQQRxDQUCQAJAQcyEASgCACIDBEBB9IcBIQADQCADIAAoAgAiAU8EQCABIAAoAgRqIANLDQMLIAAoAggiAA0ACwtBABApIgFBf0YNBiACIQVBkIgBKAIAIgNBAWsiACABcQRAIAIgAWsgACABakEAIANrcWohBQsgBSAITQ0GIAVB/v///wdLDQZB7IcBKAIAIgQEQEHkhwEoAgAiAyAFaiIAIANNDQcgACAESw0HCyAFECkiACABRw0BDAgLIAUgBmsgB3EiBUH+////B0sNBSAFECkiASAAKAIAIAAoAgRqRg0EIAEhAAsCQCAAQX9GDQAgCEEwaiAFTQ0AQZSIASgCACIBIAkgBWtqQQAgAWtxIgFB/v///wdLBEAgACEBDAgLIAEQKUF/RwRAIAEgBWohBSAAIQEMCAtBACAFaxApGgwFCyAAIgFBf0cNBgwECwALQQAhBAwHC0EAIQEMBQsgAUF/Rw0CC0HwhwFB8IcBKAIAQQRyNgIACyACQf7///8HSw0BIAIQKSEBQQAQKSEAIAFBf0YNASAAQX9GDQEgACABTQ0BIAAgAWsiBSAIQShqTQ0BC0HkhwFB5IcBKAIAIAVqIgA2AgBB6IcBKAIAIABJBEBB6IcBIAA2AgALAkACQAJAQcyEASgCACIHBEBB9IcBIQADQCABIAAoAgAiAyAAKAIEIgJqRg0CIAAoAggiAA0ACwwCC0HEhAEoAgAiAEEAIAAgAU0bRQRAQcSEASABNgIAC0EAIQBB+IcBIAU2AgBB9IcBIAE2AgBB1IQBQX82AgBB2IQBQYyIASgCADYCAEGAiAFBADYCAANAIABBA3QiA0HkhAFqIANB3IQBaiICNgIAIANB6IQBaiACNgIAIABBAWoiAEEgRw0AC0HAhAEgBUEoayIDQXggAWtBB3FBACABQQhqQQdxGyIAayICNgIAQcyEASAAIAFqIgA2AgAgACACQQFyNgIEIAEgA2pBKDYCBEHQhAFBnIgBKAIANgIADAILIAAtAAxBCHENACADIAdLDQAgASAHTQ0AIAAgAiAFajYCBEHMhAEgB0F4IAdrQQdxQQAgB0EIakEHcRsiAGoiAjYCAEHAhAFBwIQBKAIAIAVqIgEgAGsiADYCACACIABBAXI2AgQgASAHakEoNgIEQdCEAUGciAEoAgA2AgAMAQtBxIQBKAIAIAFLBEBBxIQBIAE2AgALIAEgBWohAkH0hwEhAAJAAkACQAJAAkACQANAIAIgACgCAEcEQCAAKAIIIgANAQwCCwsgAC0ADEEIcUUNAQtB9IcBIQADQCAHIAAoAgAiAk8EQCACIAAoAgRqIgQgB0sNAwsgACgCCCEADAALAAsgACABNgIAIAAgACgCBCAFajYCBCABQXggAWtBB3FBACABQQhqQQdxG2oiCSAIQQNyNgIEIAJBeCACa0EHcUEAIAJBCGpBB3EbaiIFIAggCWoiBmshAiAFIAdGBEBBzIQBIAY2AgBBwIQBQcCEASgCACACaiIANgIAIAYgAEEBcjYCBAwDCyAFQciEASgCAEYEQEHIhAEgBjYCAEG8hAFBvIQBKAIAIAJqIgA2AgAgBiAAQQFyNgIEIAAgBmogADYCAAwDCyAFKAIEIgBBA3FBAUYEQCAAQXhxIQcCQCAAQf8BTQRAIAUoAggiAyAAQQN2IgBBA3RB3IQBakYaIAMgBSgCDCIBRgRAQbSEAUG0hAEoAgBBfiAAd3E2AgAMAgsgAyABNgIMIAEgAzYCCAwBCyAFKAIYIQgCQCAFIAUoAgwiAUcEQCAFKAIIIgAgATYCDCABIAA2AggMAQsCQCAFQRRqIgAoAgAiAw0AIAVBEGoiACgCACIDDQBBACEBDAELA0AgACEEIAMiAUEUaiIAKAIAIgMNACABQRBqIQAgASgCECIDDQALIARBADYCAAsgCEUNAAJAIAUgBSgCHCIDQQJ0QeSGAWoiACgCAEYEQCAAIAE2AgAgAQ0BQbiEAUG4hAEoAgBBfiADd3E2AgAMAgsgCEEQQRQgCCgCECAFRhtqIAE2AgAgAUUNAQsgASAINgIYIAUoAhAiAARAIAEgADYCECAAIAE2AhgLIAUoAhQiAEUNACABIAA2AhQgACABNgIYCyAFIAdqIQUgAiAHaiECCyAFIAUoAgRBfnE2AgQgBiACQQFyNgIEIAIgBmogAjYCACACQf8BTQRAIAJBA3YiAEEDdEHchAFqIQICf0G0hAEoAgAiAUEBIAB0IgBxRQRAQbSEASAAIAFyNgIAIAIMAQsgAigCCAshACACIAY2AgggACAGNgIMIAYgAjYCDCAGIAA2AggMAwtBHyEAIAJB////B00EQCACQQh2IgAgAEGA/j9qQRB2QQhxIgN0IgAgAEGA4B9qQRB2QQRxIgF0IgAgAEGAgA9qQRB2QQJxIgB0QQ92IAEgA3IgAHJrIgBBAXQgAiAAQRVqdkEBcXJBHGohAAsgBiAANgIcIAZCADcCECAAQQJ0QeSGAWohBAJAQbiEASgCACIDQQEgAHQiAXFFBEBBuIQBIAEgA3I2AgAgBCAGNgIAIAYgBDYCGAwBCyACQQBBGSAAQQF2ayAAQR9GG3QhACAEKAIAIQEDQCABIgMoAgRBeHEgAkYNAyAAQR12IQEgAEEBdCEAIAMgAUEEcWoiBCgCECIBDQALIAQgBjYCECAGIAM2AhgLIAYgBjYCDCAGIAY2AggMAgtBwIQBIAVBKGsiA0F4IAFrQQdxQQAgAUEIakEHcRsiAGsiAjYCAEHMhAEgACABaiIANgIAIAAgAkEBcjYCBCABIANqQSg2AgRB0IQBQZyIASgCADYCACAHIARBJyAEa0EHcUEAIARBJ2tBB3EbakEvayIAIAAgB0EQakkbIgJBGzYCBCACQfyHASkCADcCECACQfSHASkCADcCCEH8hwEgAkEIajYCAEH4hwEgBTYCAEH0hwEgATYCAEGAiAFBADYCACACQRhqIQADQCAAQQc2AgQgAEEIaiEBIABBBGohACABIARJDQALIAIgB0YNAyACIAIoAgRBfnE2AgQgByACIAdrIgRBAXI2AgQgAiAENgIAIARB/wFNBEAgBEEDdiIAQQN0QdyEAWohAgJ/QbSEASgCACIBQQEgAHQiAHFFBEBBtIQBIAAgAXI2AgAgAgwBCyACKAIICyEAIAIgBzYCCCAAIAc2AgwgByACNgIMIAcgADYCCAwEC0EfIQAgB0IANwIQIARB////B00EQCAEQQh2IgAgAEGA/j9qQRB2QQhxIgJ0IgAgAEGA4B9qQRB2QQRxIgF0IgAgAEGAgA9qQRB2QQJxIgB0QQ92IAEgAnIgAHJrIgBBAXQgBCAAQRVqdkEBcXJBHGohAAsgByAANgIcIABBAnRB5IYBaiEDAkBBuIQBKAIAIgJBASAAdCIBcUUEQEG4hAEgASACcjYCACADIAc2AgAgByADNgIYDAELIARBAEEZIABBAXZrIABBH0YbdCEAIAMoAgAhAQNAIAEiAigCBEF4cSAERg0EIABBHXYhASAAQQF0IQAgAiABQQRxaiIDKAIQIgENAAsgAyAHNgIQIAcgAjYCGAsgByAHNgIMIAcgBzYCCAwDCyADKAIIIgAgBjYCDCADIAY2AgggBkEANgIYIAYgAzYCDCAGIAA2AggLIAlBCGohAAwFCyACKAIIIgAgBzYCDCACIAc2AgggB0EANgIYIAcgAjYCDCAHIAA2AggLQcCEASgCACIAIAhNDQBBwIQBIAAgCGsiATYCAEHMhAFBzIQBKAIAIgIgCGoiADYCACAAIAFBAXI2AgQgAiAIQQNyNgIEIAJBCGohAAwDC0GEhAFBMDYCAEEAIQAMAgsCQCAFRQ0AAkAgBCgCHCICQQJ0QeSGAWoiACgCACAERgRAIAAgATYCACABDQFBuIQBIAlBfiACd3EiCTYCAAwCCyAFQRBBFCAFKAIQIARGG2ogATYCACABRQ0BCyABIAU2AhggBCgCECIABEAgASAANgIQIAAgATYCGAsgBCgCFCIARQ0AIAEgADYCFCAAIAE2AhgLAkAgA0EPTQRAIAQgAyAIaiIAQQNyNgIEIAAgBGoiACAAKAIEQQFyNgIEDAELIAQgCEEDcjYCBCAGIANBAXI2AgQgAyAGaiADNgIAIANB/wFNBEAgA0EDdiIAQQN0QdyEAWohAgJ/QbSEASgCACIBQQEgAHQiAHFFBEBBtIQBIAAgAXI2AgAgAgwBCyACKAIICyEAIAIgBjYCCCAAIAY2AgwgBiACNgIMIAYgADYCCAwBC0EfIQAgA0H///8HTQRAIANBCHYiACAAQYD+P2pBEHZBCHEiAnQiACAAQYDgH2pBEHZBBHEiAXQiACAAQYCAD2pBEHZBAnEiAHRBD3YgASACciAAcmsiAEEBdCADIABBFWp2QQFxckEcaiEACyAGIAA2AhwgBkIANwIQIABBAnRB5IYBaiECAkACQCAJQQEgAHQiAXFFBEBBuIQBIAEgCXI2AgAgAiAGNgIAIAYgAjYCGAwBCyADQQBBGSAAQQF2ayAAQR9GG3QhACACKAIAIQgDQCAIIgEoAgRBeHEgA0YNAiAAQR12IQIgAEEBdCEAIAEgAkEEcWoiAigCECIIDQALIAIgBjYCECAGIAE2AhgLIAYgBjYCDCAGIAY2AggMAQsgASgCCCIAIAY2AgwgASAGNgIIIAZBADYCGCAGIAE2AgwgBiAANgIICyAEQQhqIQAMAQsCQCALRQ0AAkAgASgCHCICQQJ0QeSGAWoiACgCACABRgRAIAAgBDYCACAEDQFBuIQBIAZBfiACd3E2AgAMAgsgC0EQQRQgCygCECABRhtqIAQ2AgAgBEUNAQsgBCALNgIYIAEoAhAiAARAIAQgADYCECAAIAQ2AhgLIAEoAhQiAEUNACAEIAA2AhQgACAENgIYCwJAIANBD00EQCABIAMgCGoiAEEDcjYCBCAAIAFqIgAgACgCBEEBcjYCBAwBCyABIAhBA3I2AgQgCSADQQFyNgIEIAMgCWogAzYCACAKBEAgCkEDdiIAQQN0QdyEAWohBEHIhAEoAgAhAgJ/QQEgAHQiACAFcUUEQEG0hAEgACAFcjYCACAEDAELIAQoAggLIQAgBCACNgIIIAAgAjYCDCACIAQ2AgwgAiAANgIIC0HIhAEgCTYCAEG8hAEgAzYCAAsgAUEIaiEACyAMQRBqJAAgAAuJAQEDfyAAKAIcIgEQMAJAIAAoAhAiAiABKAIQIgMgAiADSRsiAkUNACAAKAIMIAEoAgggAhAHGiAAIAAoAgwgAmo2AgwgASABKAIIIAJqNgIIIAAgACgCFCACajYCFCAAIAAoAhAgAms2AhAgASABKAIQIAJrIgA2AhAgAA0AIAEgASgCBDYCCAsLzgEBBX8CQCAARQ0AIAAoAjAiAQRAIAAgAUEBayIBNgIwIAENAQsgACgCIARAIABBATYCICAAEBoaCyAAKAIkQQFGBEAgABBDCwJAIAAoAiwiAUUNACAALQAoDQACQCABKAJEIgNFDQAgASgCTCEEA0AgACAEIAJBAnRqIgUoAgBHBEAgAyACQQFqIgJHDQEMAgsLIAUgBCADQQFrIgJBAnRqKAIANgIAIAEgAjYCRAsLIABBAEIAQQUQDhogACgCACIBBEAgARALCyAAEAYLC1oCAn4BfwJ/AkACQCAALQAARQ0AIAApAxAiAUJ9Vg0AIAFCAnwiAiAAKQMIWA0BCyAAQQA6AABBAAwBC0EAIAAoAgQiA0UNABogACACNwMQIAMgAadqLwAACwthAgJ+AX8CQAJAIAAtAABFDQAgACkDECICQn1WDQAgAkICfCIDIAApAwhYDQELIABBADoAAA8LIAAoAgQiBEUEQA8LIAAgAzcDECAEIAKnaiIAIAFBCHY6AAEgACABOgAAC8wCAQJ/IwBBEGsiBCQAAkAgACkDGCADrYinQQFxRQRAIABBDGoiAARAIABBADYCBCAAQRw2AgALQn8hAgwBCwJ+IAAoAgAiBUUEQCAAKAIIIAEgAiADIAAoAgQRDAAMAQsgBSAAKAIIIAEgAiADIAAoAgQRCgALIgJCf1UNAAJAIANBBGsOCwEAAAAAAAAAAAABAAsCQAJAIAAtABhBEHFFBEAgAEEMaiIBBEAgAUEANgIEIAFBHDYCAAsMAQsCfiAAKAIAIgFFBEAgACgCCCAEQQhqQghBBCAAKAIEEQwADAELIAEgACgCCCAEQQhqQghBBCAAKAIEEQoAC0J/VQ0BCyAAQQxqIgAEQCAAQQA2AgQgAEEUNgIACwwBCyAEKAIIIQEgBCgCDCEDIABBDGoiAARAIAAgAzYCBCAAIAE2AgALCyAEQRBqJAAgAguTFQIOfwN+AkACQAJAAkACQAJAAkACQAJAAkACQCAAKALwLQRAIAAoAogBQQFIDQEgACgCACIEKAIsQQJHDQQgAC8B5AENAyAALwHoAQ0DIAAvAewBDQMgAC8B8AENAyAALwH0AQ0DIAAvAfgBDQMgAC8B/AENAyAALwGcAg0DIAAvAaACDQMgAC8BpAINAyAALwGoAg0DIAAvAawCDQMgAC8BsAINAyAALwG0Ag0DIAAvAbgCDQMgAC8BvAINAyAALwHAAg0DIAAvAcQCDQMgAC8ByAINAyAALwHUAg0DIAAvAdgCDQMgAC8B3AINAyAALwHgAg0DIAAvAYgCDQIgAC8BjAINAiAALwGYAg0CQSAhBgNAIAAgBkECdCIFai8B5AENAyAAIAVBBHJqLwHkAQ0DIAAgBUEIcmovAeQBDQMgACAFQQxyai8B5AENAyAGQQRqIgZBgAJHDQALDAMLIABBBzYC/C0gAkF8Rw0FIAFFDQUMBgsgAkEFaiIEIQcMAwtBASEHCyAEIAc2AiwLIAAgAEHoFmoQUSAAIABB9BZqEFEgAC8B5gEhBCAAIABB7BZqKAIAIgxBAnRqQf//AzsB6gEgAEGQFmohECAAQZQWaiERIABBjBZqIQdBACEGIAxBAE4EQEEHQYoBIAQbIQ1BBEEDIAQbIQpBfyEJA0AgBCEIIAAgCyIOQQFqIgtBAnRqLwHmASEEAkACQCAGQQFqIgVB//8DcSIPIA1B//8DcU8NACAEIAhHDQAgBSEGDAELAn8gACAIQQJ0akHMFWogCkH//wNxIA9LDQAaIAgEQEEBIQUgByAIIAlGDQEaIAAgCEECdGpBzBVqIgYgBi8BAEEBajsBACAHDAELQQEhBSAQIBEgBkH//wNxQQpJGwsiBiAGLwEAIAVqOwEAQQAhBgJ/IARFBEBBAyEKQYoBDAELQQNBBCAEIAhGIgUbIQpBBkEHIAUbCyENIAghCQsgDCAORw0ACwsgAEHaE2ovAQAhBCAAIABB+BZqKAIAIgxBAnRqQd4TakH//wM7AQBBACEGIAxBAE4EQEEHQYoBIAQbIQ1BBEEDIAQbIQpBfyEJQQAhCwNAIAQhCCAAIAsiDkEBaiILQQJ0akHaE2ovAQAhBAJAAkAgBkEBaiIFQf//A3EiDyANQf//A3FPDQAgBCAIRw0AIAUhBgwBCwJ/IAAgCEECdGpBzBVqIApB//8DcSAPSw0AGiAIBEBBASEFIAcgCCAJRg0BGiAAIAhBAnRqQcwVaiIGIAYvAQBBAWo7AQAgBwwBC0EBIQUgECARIAZB//8DcUEKSRsLIgYgBi8BACAFajsBAEEAIQYCfyAERQRAQQMhCkGKAQwBC0EDQQQgBCAIRiIFGyEKQQZBByAFGwshDSAIIQkLIAwgDkcNAAsLIAAgAEGAF2oQUSAAIAAoAvgtAn9BEiAAQYoWai8BAA0AGkERIABB0hVqLwEADQAaQRAgAEGGFmovAQANABpBDyAAQdYVai8BAA0AGkEOIABBghZqLwEADQAaQQ0gAEHaFWovAQANABpBDCAAQf4Vai8BAA0AGkELIABB3hVqLwEADQAaQQogAEH6FWovAQANABpBCSAAQeIVai8BAA0AGkEIIABB9hVqLwEADQAaQQcgAEHmFWovAQANABpBBiAAQfIVai8BAA0AGkEFIABB6hVqLwEADQAaQQQgAEHuFWovAQANABpBA0ECIABBzhVqLwEAGwsiBkEDbGoiBEERajYC+C0gACgC/C1BCmpBA3YiByAEQRtqQQN2IgRNBEAgByEEDAELIAAoAowBQQRHDQAgByEECyAEIAJBBGpPQQAgARsNASAEIAdHDQQLIANBAmqtIRIgACkDmC4hFCAAKAKgLiIBQQNqIgdBP0sNASASIAGthiAUhCESDAILIAAgASACIAMQOQwDCyABQcAARgRAIAAoAgQgACgCEGogFDcAACAAIAAoAhBBCGo2AhBBAyEHDAELIAAoAgQgACgCEGogEiABrYYgFIQ3AAAgACAAKAIQQQhqNgIQIAFBPWshByASQcAAIAFrrYghEgsgACASNwOYLiAAIAc2AqAuIABBgMEAQYDKABCHAQwBCyADQQRqrSESIAApA5guIRQCQCAAKAKgLiIBQQNqIgRBP00EQCASIAGthiAUhCESDAELIAFBwABGBEAgACgCBCAAKAIQaiAUNwAAIAAgACgCEEEIajYCEEEDIQQMAQsgACgCBCAAKAIQaiASIAGthiAUhDcAACAAIAAoAhBBCGo2AhAgAUE9ayEEIBJBwAAgAWutiCESCyAAIBI3A5guIAAgBDYCoC4gAEHsFmooAgAiC6xCgAJ9IRMgAEH4FmooAgAhCQJAAkACfwJ+AkACfwJ/IARBOk0EQCATIASthiAShCETIARBBWoMAQsgBEHAAEYEQCAAKAIEIAAoAhBqIBI3AAAgACAAKAIQQQhqNgIQIAmsIRJCBSEUQQoMAgsgACgCBCAAKAIQaiATIASthiAShDcAACAAIAAoAhBBCGo2AhAgE0HAACAEa62IIRMgBEE7awshBSAJrCESIAVBOksNASAFrSEUIAVBBWoLIQcgEiAUhiAThAwBCyAFQcAARgRAIAAoAgQgACgCEGogEzcAACAAIAAoAhBBCGo2AhAgBq1CA30hE0IFIRRBCQwCCyAAKAIEIAAoAhBqIBIgBa2GIBOENwAAIAAgACgCEEEIajYCECAFQTtrIQcgEkHAACAFa62ICyESIAatQgN9IRMgB0E7Sw0BIAetIRQgB0EEagshBCATIBSGIBKEIRMMAQsgB0HAAEYEQCAAKAIEIAAoAhBqIBI3AAAgACAAKAIQQQhqNgIQQQQhBAwBCyAAKAIEIAAoAhBqIBMgB62GIBKENwAAIAAgACgCEEEIajYCECAHQTxrIQQgE0HAACAHa62IIRMLQQAhBQNAIAAgBSIBQZDWAGotAABBAnRqQc4VajMBACEUAn8gBEE8TQRAIBQgBK2GIBOEIRMgBEEDagwBCyAEQcAARgRAIAAoAgQgACgCEGogEzcAACAAIAAoAhBBCGo2AhAgFCETQQMMAQsgACgCBCAAKAIQaiAUIASthiAThDcAACAAIAAoAhBBCGo2AhAgFEHAACAEa62IIRMgBEE9awshBCABQQFqIQUgASAGRw0ACyAAIAQ2AqAuIAAgEzcDmC4gACAAQeQBaiICIAsQhgEgACAAQdgTaiIBIAkQhgEgACACIAEQhwELIAAQiAEgAwRAAkAgACgCoC4iBEE5TgRAIAAoAgQgACgCEGogACkDmC43AAAgACAAKAIQQQhqNgIQDAELIARBGU4EQCAAKAIEIAAoAhBqIAApA5guPgAAIAAgAEGcLmo1AgA3A5guIAAgACgCEEEEajYCECAAIAAoAqAuQSBrIgQ2AqAuCyAEQQlOBH8gACgCBCAAKAIQaiAAKQOYLj0AACAAIAAoAhBBAmo2AhAgACAAKQOYLkIQiDcDmC4gACgCoC5BEGsFIAQLQQFIDQAgACAAKAIQIgFBAWo2AhAgASAAKAIEaiAAKQOYLjwAAAsgAEEANgKgLiAAQgA3A5guCwsZACAABEAgACgCABAGIAAoAgwQBiAAEAYLC6wBAQJ+Qn8hAwJAIAAtACgNAAJAAkAgACgCIEUNACACQgBTDQAgAlANASABDQELIABBDGoiAARAIABBADYCBCAAQRI2AgALQn8PCyAALQA1DQBCACEDIAAtADQNACACUA0AA0AgACABIAOnaiACIAN9QQEQDiIEQn9XBEAgAEEBOgA1Qn8gAyADUBsPCyAEUEUEQCADIAR8IgMgAloNAgwBCwsgAEEBOgA0CyADC3UCAn4BfwJAAkAgAC0AAEUNACAAKQMQIgJCe1YNACACQgR8IgMgACkDCFgNAQsgAEEAOgAADwsgACgCBCIERQRADwsgACADNwMQIAQgAqdqIgAgAUEYdjoAAyAAIAFBEHY6AAIgACABQQh2OgABIAAgAToAAAtUAgF+AX8CQAJAIAAtAABFDQAgASAAKQMQIgF8IgIgAVQNACACIAApAwhYDQELIABBADoAAEEADwsgACgCBCIDRQRAQQAPCyAAIAI3AxAgAyABp2oLdwECfyMAQRBrIgMkAEF/IQQCQCAALQAoDQAgACgCIEEAIAJBA0kbRQRAIABBDGoiAARAIABBADYCBCAAQRI2AgALDAELIAMgAjYCCCADIAE3AwAgACADQhBBBhAOQgBTDQBBACEEIABBADoANAsgA0EQaiQAIAQLVwICfgF/AkACQCAALQAARQ0AIAApAxAiAUJ7Vg0AIAFCBHwiAiAAKQMIWA0BCyAAQQA6AABBAA8LIAAoAgQiA0UEQEEADwsgACACNwMQIAMgAadqKAAAC1UCAX4BfyAABEACQCAAKQMIUA0AQgEhAQNAIAAoAgAgAkEEdGoQPiABIAApAwhaDQEgAachAiABQgF8IQEMAAsACyAAKAIAEAYgACgCKBAQIAAQBgsLZAECfwJAAkACQCAARQRAIAGnEAkiA0UNAkEYEAkiAkUNAQwDCyAAIQNBGBAJIgINAkEADwsgAxAGC0EADwsgAkIANwMQIAIgATcDCCACIAM2AgQgAkEBOgAAIAIgAEU6AAEgAgudAQICfgF/AkACQCAALQAARQ0AIAApAxAiAkJ3Vg0AIAJCCHwiAyAAKQMIWA0BCyAAQQA6AAAPCyAAKAIEIgRFBEAPCyAAIAM3AxAgBCACp2oiACABQjiIPAAHIAAgAUIwiDwABiAAIAFCKIg8AAUgACABQiCIPAAEIAAgAUIYiDwAAyAAIAFCEIg8AAIgACABQgiIPAABIAAgATwAAAvwAgICfwF+AkAgAkUNACAAIAJqIgNBAWsgAToAACAAIAE6AAAgAkEDSQ0AIANBAmsgAToAACAAIAE6AAEgA0EDayABOgAAIAAgAToAAiACQQdJDQAgA0EEayABOgAAIAAgAToAAyACQQlJDQAgAEEAIABrQQNxIgRqIgMgAUH/AXFBgYKECGwiADYCACADIAIgBGtBfHEiAmoiAUEEayAANgIAIAJBCUkNACADIAA2AgggAyAANgIEIAFBCGsgADYCACABQQxrIAA2AgAgAkEZSQ0AIAMgADYCGCADIAA2AhQgAyAANgIQIAMgADYCDCABQRBrIAA2AgAgAUEUayAANgIAIAFBGGsgADYCACABQRxrIAA2AgAgAiADQQRxQRhyIgFrIgJBIEkNACAArUKBgICAEH4hBSABIANqIQEDQCABIAU3AxggASAFNwMQIAEgBTcDCCABIAU3AwAgAUEgaiEBIAJBIGsiAkEfSw0ACwsLbwEDfyAAQQxqIQICQAJ/IAAoAiAiAUUEQEF/IQFBEgwBCyAAIAFBAWsiAzYCIEEAIQEgAw0BIABBAEIAQQIQDhogACgCACIARQ0BIAAQGkF/Sg0BQRQLIQAgAgRAIAJBADYCBCACIAA2AgALCyABC58BAgF/AX4CfwJAAn4gACgCACIDKAIkQQFGQQAgAkJ/VRtFBEAgA0EMaiIBBEAgAUEANgIEIAFBEjYCAAtCfwwBCyADIAEgAkELEA4LIgRCf1cEQCAAKAIAIQEgAEEIaiIABEAgACABKAIMNgIAIAAgASgCEDYCBAsMAQtBACACIARRDQEaIABBCGoEQCAAQRs2AgwgAEEGNgIICwtBfwsLJAEBfyAABEADQCAAKAIAIQEgACgCDBAGIAAQBiABIgANAAsLC5gBAgJ+AX8CQAJAIAAtAABFDQAgACkDECIBQndWDQAgAUIIfCICIAApAwhYDQELIABBADoAAEIADwsgACgCBCIDRQRAQgAPCyAAIAI3AxAgAyABp2oiADEABkIwhiAAMQAHQjiGhCAAMQAFQiiGhCAAMQAEQiCGhCAAMQADQhiGhCAAMQACQhCGhCAAMQABQgiGhCAAMQAAfAsjACAAQShGBEAgAhAGDwsgAgRAIAEgAkEEaygCACAAEQcACwsyACAAKAIkQQFHBEAgAEEMaiIABEAgAEEANgIEIABBEjYCAAtCfw8LIABBAEIAQQ0QDgsPACAABEAgABA2IAAQBgsLgAEBAX8gAC0AKAR/QX8FIAFFBEAgAEEMagRAIABBADYCECAAQRI2AgwLQX8PCyABECoCQCAAKAIAIgJFDQAgAiABECFBf0oNACAAKAIAIQEgAEEMaiIABEAgACABKAIMNgIAIAAgASgCEDYCBAtBfw8LIAAgAUI4QQMQDkI/h6cLC38BA38gACEBAkAgAEEDcQRAA0AgAS0AAEUNAiABQQFqIgFBA3ENAAsLA0AgASICQQRqIQEgAigCACIDQX9zIANBgYKECGtxQYCBgoR4cUUNAAsgA0H/AXFFBEAgAiAAaw8LA0AgAi0AASEDIAJBAWoiASECIAMNAAsLIAEgAGsL3wIBCH8gAEUEQEEBDwsCQCAAKAIIIgINAEEBIQQgAC8BBCIHRQRAQQEhAgwBCyAAKAIAIQgDQAJAIAMgCGoiBS0AACICQSBPBEAgAkEYdEEYdUF/Sg0BCyACQQ1NQQBBASACdEGAzABxGw0AAn8CfyACQeABcUHAAUYEQEEBIQYgA0EBagwBCyACQfABcUHgAUYEQCADQQJqIQNBACEGQQEMAgsgAkH4AXFB8AFHBEBBBCECDAULQQAhBiADQQNqCyEDQQALIQlBBCECIAMgB08NAiAFLQABQcABcUGAAUcNAkEDIQQgBg0AIAUtAAJBwAFxQYABRw0CIAkNACAFLQADQcABcUGAAUcNAgsgBCECIANBAWoiAyAHSQ0ACwsgACACNgIIAn8CQCABRQ0AAkAgAUECRw0AIAJBA0cNAEECIQIgAEECNgIICyABIAJGDQBBBSACQQFHDQEaCyACCwtIAgJ+An8jAEEQayIEIAE2AgxCASAArYYhAgNAIAQgAUEEaiIANgIMIAIiA0IBIAEoAgAiBa2GhCECIAAhASAFQX9KDQALIAMLhwUBB38CQAJAIABFBEBBxRQhAiABRQ0BIAFBADYCAEHFFA8LIAJBwABxDQEgACgCCEUEQCAAQQAQIxoLIAAoAgghBAJAIAJBgAFxBEAgBEEBa0ECTw0BDAMLIARBBEcNAgsCQCAAKAIMIgINACAAAn8gACgCACEIIABBEGohCUEAIQICQAJAAkACQCAALwEEIgUEQEEBIQQgBUEBcSEHIAVBAUcNAQwCCyAJRQ0CIAlBADYCAEEADAQLIAVBfnEhBgNAIARBAUECQQMgAiAIai0AAEEBdEHQFGovAQAiCkGAEEkbIApBgAFJG2pBAUECQQMgCCACQQFyai0AAEEBdEHQFGovAQAiBEGAEEkbIARBgAFJG2ohBCACQQJqIQIgBkECayIGDQALCwJ/IAcEQCAEQQFBAkEDIAIgCGotAABBAXRB0BRqLwEAIgJBgBBJGyACQYABSRtqIQQLIAQLEAkiB0UNASAFQQEgBUEBSxshCkEAIQVBACEGA0AgBSAHaiEDAn8gBiAIai0AAEEBdEHQFGovAQAiAkH/AE0EQCADIAI6AAAgBUEBagwBCyACQf8PTQRAIAMgAkE/cUGAAXI6AAEgAyACQQZ2QcABcjoAACAFQQJqDAELIAMgAkE/cUGAAXI6AAIgAyACQQx2QeABcjoAACADIAJBBnZBP3FBgAFyOgABIAVBA2oLIQUgBkEBaiIGIApHDQALIAcgBEEBayICakEAOgAAIAlFDQAgCSACNgIACyAHDAELIAMEQCADQQA2AgQgA0EONgIAC0EACyICNgIMIAINAEEADwsgAUUNACABIAAoAhA2AgALIAIPCyABBEAgASAALwEENgIACyAAKAIAC4MBAQR/QRIhBQJAAkAgACkDMCABWA0AIAGnIQYgACgCQCEEIAJBCHEiB0UEQCAEIAZBBHRqKAIEIgINAgsgBCAGQQR0aiIEKAIAIgJFDQAgBC0ADEUNAUEXIQUgBw0BC0EAIQIgAyAAQQhqIAMbIgAEQCAAQQA2AgQgACAFNgIACwsgAgtuAQF/IwBBgAJrIgUkAAJAIARBgMAEcQ0AIAIgA0wNACAFIAFB/wFxIAIgA2siAkGAAiACQYACSSIBGxAZIAFFBEADQCAAIAVBgAIQLiACQYACayICQf8BSw0ACwsgACAFIAIQLgsgBUGAAmokAAuBAQEBfyMAQRBrIgQkACACIANsIQICQCAAQSdGBEAgBEEMaiACEIwBIQBBACAEKAIMIAAbIQAMAQsgAUEBIAJBxABqIAARAAAiAUUEQEEAIQAMAQtBwAAgAUE/cWsiACABakHAAEEAIABBBEkbaiIAQQRrIAE2AAALIARBEGokACAAC1IBAn9BhIEBKAIAIgEgAEEDakF8cSICaiEAAkAgAkEAIAAgAU0bDQAgAD8AQRB0SwRAIAAQA0UNAQtBhIEBIAA2AgAgAQ8LQYSEAUEwNgIAQX8LNwAgAEJ/NwMQIABBADYCCCAAQgA3AwAgAEEANgIwIABC/////w83AyggAEIANwMYIABCADcDIAulAQEBf0HYABAJIgFFBEBBAA8LAkAgAARAIAEgAEHYABAHGgwBCyABQgA3AyAgAUEANgIYIAFC/////w83AxAgAUEAOwEMIAFBv4YoNgIIIAFBAToABiABQQA6AAQgAUIANwNIIAFBgIDYjXg2AkQgAUIANwMoIAFCADcDMCABQgA3AzggAUFAa0EAOwEAIAFCADcDUAsgAUEBOgAFIAFBADYCACABC1gCAn4BfwJAAkAgAC0AAEUNACAAKQMQIgMgAq18IgQgA1QNACAEIAApAwhYDQELIABBADoAAA8LIAAoAgQiBUUEQA8LIAAgBDcDECAFIAOnaiABIAIQBxoLlgEBAn8CQAJAIAJFBEAgAacQCSIFRQ0BQRgQCSIEDQIgBRAGDAELIAIhBUEYEAkiBA0BCyADBEAgA0EANgIEIANBDjYCAAtBAA8LIARCADcDECAEIAE3AwggBCAFNgIEIARBAToAACAEIAJFOgABIAAgBSABIAMQZUEASAR/IAQtAAEEQCAEKAIEEAYLIAQQBkEABSAECwubAgEDfyAALQAAQSBxRQRAAkAgASEDAkAgAiAAIgEoAhAiAAR/IAAFAn8gASABLQBKIgBBAWsgAHI6AEogASgCACIAQQhxBEAgASAAQSByNgIAQX8MAQsgAUIANwIEIAEgASgCLCIANgIcIAEgADYCFCABIAAgASgCMGo2AhBBAAsNASABKAIQCyABKAIUIgVrSwRAIAEgAyACIAEoAiQRAAAaDAILAn8gASwAS0F/SgRAIAIhAANAIAIgACIERQ0CGiADIARBAWsiAGotAABBCkcNAAsgASADIAQgASgCJBEAACAESQ0CIAMgBGohAyABKAIUIQUgAiAEawwBCyACCyEAIAUgAyAAEAcaIAEgASgCFCAAajYCFAsLCwvNBQEGfyAAKAIwIgNBhgJrIQYgACgCPCECIAMhAQNAIAAoAkQgAiAAKAJoIgRqayECIAEgBmogBE0EQCAAKAJIIgEgASADaiADEAcaAkAgAyAAKAJsIgFNBEAgACABIANrNgJsDAELIABCADcCbAsgACAAKAJoIANrIgE2AmggACAAKAJYIANrNgJYIAEgACgChC5JBEAgACABNgKELgsgAEH8gAEoAgARAwAgAiADaiECCwJAIAAoAgAiASgCBCIERQ0AIAAoAjwhBSAAIAIgBCACIARJGyICBH8gACgCSCAAKAJoaiAFaiEFIAEgBCACazYCBAJAAkACQAJAIAEoAhwiBCgCFEEBaw4CAQACCyAEQaABaiAFIAEoAgAgAkHcgAEoAgARCAAMAgsgASABKAIwIAUgASgCACACQcSAASgCABEEADYCMAwBCyAFIAEoAgAgAhAHGgsgASABKAIAIAJqNgIAIAEgASgCCCACajYCCCAAKAI8BSAFCyACaiICNgI8AkAgACgChC4iASACakEDSQ0AIAAoAmggAWshAQJAIAAoAnRBgQhPBEAgACAAIAAoAkggAWoiAi0AACACLQABIAAoAnwRAAA2AlQMAQsgAUUNACAAIAFBAWsgACgChAERAgAaCyAAKAKELiAAKAI8IgJBAUZrIgRFDQAgACABIAQgACgCgAERBQAgACAAKAKELiAEazYChC4gACgCPCECCyACQYUCSw0AIAAoAgAoAgRFDQAgACgCMCEBDAELCwJAIAAoAkQiAiAAKAJAIgNNDQAgAAJ/IAAoAjwgACgCaGoiASADSwRAIAAoAkggAWpBACACIAFrIgNBggIgA0GCAkkbIgMQGSABIANqDAELIAFBggJqIgEgA00NASAAKAJIIANqQQAgAiADayICIAEgA2siAyACIANJGyIDEBkgACgCQCADags2AkALC50CAQF/AkAgAAJ/IAAoAqAuIgFBwABGBEAgACgCBCAAKAIQaiAAKQOYLjcAACAAQgA3A5guIAAgACgCEEEIajYCEEEADAELIAFBIE4EQCAAKAIEIAAoAhBqIAApA5guPgAAIAAgAEGcLmo1AgA3A5guIAAgACgCEEEEajYCECAAIAAoAqAuQSBrIgE2AqAuCyABQRBOBEAgACgCBCAAKAIQaiAAKQOYLj0AACAAIAAoAhBBAmo2AhAgACAAKQOYLkIQiDcDmC4gACAAKAKgLkEQayIBNgKgLgsgAUEISA0BIAAgACgCECIBQQFqNgIQ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KAJUIgEEfyABQQAgARAiEBkgACgCVAVBAAsQBiAAQQA2AlQLC9wMAgl/AX4jAEFAaiIGJAACQAJAAkACQAJAIAEoAjBBABAjIgVBAkZBACABKAI4QQAQIyIEQQFGGw0AIAVBAUZBACAEQQJGGw0AIAVBAkciAw0BIARBAkcNAQsgASABLwEMQYAQcjsBDEEAIQMMAQsgASABLwEMQf/vA3E7AQxBACEFIANFBEBB9eABIAEoAjAgAEEIahBpIgVFDQILIAJBgAJxBEAgBSEDDAELIARBAkcEQCAFIQMMAQtB9cYBIAEoAjggAEEIahBpIgNFBEAgBRAcDAILIAMgBTYCAAsgASABLwEMQf7/A3EgAS8BUiIFQQBHcjsBDAJAAkACQAJAAn8CQAJAIAEpAyhC/v///w9WDQAgASkDIEL+////D1YNACACQYAEcUUNASABKQNIQv////8PVA0BCyAFQYECa0H//wNxQQNJIQdBAQwBCyAFQYECa0H//wNxIQQgAkGACnFBgApHDQEgBEEDSSEHQQALIQkgBkIcEBciBEUEQCAAQQhqIgAEQCAAQQA2AgQgAEEONgIACyADEBwMBQsgAkGACHEhBQJAAkAgAkGAAnEEQAJAIAUNACABKQMgQv////8PVg0AIAEpAyhCgICAgBBUDQMLIAQgASkDKBAYIAEpAyAhDAwBCwJAAkACQCAFDQAgASkDIEL/////D1YNACABKQMoIgxC/////w9WDQEgASkDSEKAgICAEFQNBAsgASkDKCIMQv////8PVA0BCyAEIAwQGAsgASkDICIMQv////8PWgRAIAQgDBAYCyABKQNIIgxC/////w9UDQELIAQgDBAYCyAELQAARQRAIABBCGoiAARAIABBADYCBCAAQRQ2AgALIAQQCCADEBwMBQtBASEKQQEgBC0AAAR+IAQpAxAFQgALp0H//wNxIAYQRyEFIAQQCCAFIAM2AgAgBw0BDAILIAMhBSAEQQJLDQELIAZCBxAXIgRFBEAgAEEIaiIABEAgAEEANgIEIABBDjYCAAsgBRAcDAMLIARBAhANIARBhxJBAhAsIAQgAS0AUhBwIAQgAS8BEBANIAQtAABFBEAgAEEIaiIABEAgAEEANgIEIABBFDYCAAsgBBAIDAILQYGyAkEHIAYQRyEDIAQQCCADIAU2AgBBASEL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NgIEIABB7A42AhggGiEdDAMLIARB/wFxIgJBwABxRQRAIAggDSADLwECQQJ0aiAdp0F/IAJ0QX9zcUECdGoiAy0AASICayEIIB0gAq2IIR0gAy0AACIERQ0HDAELCyAEQSBxBEAgB0G//gA2AgQgASECDAgLIAdB0f4ANgIEIABB0A42AhggASECDAcLIB1BfyAGdEF/c62DIBt8IhunIQUgCCAEQQ9xIgNrIQggGiAErUIPg4ghHSABIBdrIgYgAjMBAiAaQX8gA3RBf3Otg3ynIgRPDQIgBCAGayIGIBlNDQEgBygCjEdFDQEgB0HR/gA2AgQgAEG5DDYCGAsgASECIAshBQwFCwJAIA5FBEAgDCARIAZraiEDDAELIAYgDk0EQCAMIA4gBmtqIQMMAQsgDCARIAYgDmsiBmtqIQMgBSAGTQ0AIAUgBmshBQJAAkAgASADTSABIA8gAWusIhogBq0iGyAaIBtUGyIapyIGaiICIANLcQ0AIAMgBmogAUsgASADT3ENACABIAMgBhAHGiACIQEMAQsgASADIAMgAWsiASABQR91IgFqIAFzIgIQByACaiEBIBogAq0iHn0iHFANACACIANqIQIDQAJAIBwgHiAcIB5UGyIbQiBUBEAgGyEaDAELIBsiGkIgfSIgQgWIQgF8QgODIh9QRQRAA0AgASACKQAANwAAIAEgAikAGDcAGCABIAIpABA3ABAgASACKQAINwAIIBpCIH0hGiACQSBqIQIgAUEgaiEBIB9CAX0iH0IAUg0ACwsgIELgAFQNAANAIAEgAikAADcAACABIAIpABg3ABggASACKQAQNwAQIAEgAikACDcACCABIAIpADg3ADggASACKQAwNwAwIAEgAikAKDcAKCABIAIpACA3ACAgASACKQBYNwBYIAEgAikAUDcAUCABIAIpAEg3AEggASACKQBANwBAIAEgAikAYDcAYCABIAIpAGg3AGggASACKQBwNwBwIAEgAikAeDcAeCACQYABaiECIAFBgAFqIQEgGkKAAX0iGkIfVg0ACwsgGkIQWgRAIAEgAikAADcAACABIAIpAAg3AAggGkIQfSEaIAJBEGohAiABQRBqIQELIBpCCFoEQCABIAIpAAA3AAAgGkIIfSEaIAJBCGohAiABQQhqIQELIBpCBFoEQCABIAIoAAA2AAAgGkIEfSEaIAJBBGohAiABQQRqIQELIBpCAloEQCABIAIvAAA7AAAgGkICfSEaIAJBAmohAiABQQJqIQELIBwgG30hHCAaUEUEQCABIAItAAA6AAAgAkEBaiECIAFBAWohAQsgHEIAUg0ACwsgDiEGIAwhAwsgBSAGSwRAAkACQCABIANNIAEgDyABa6wiGiAGrSIbIBogG1QbIhqnIglqIgIgA0txDQAgAyAJaiABSyABIANPcQ0AIAEgAyAJEAcaDAELIAEgAyADIAFrIgEgAUEfdSIBaiABcyIBEAcgAWohAiAaIAGtIh59IhxQDQAgASADaiEBA0ACQCAcIB4gHCAeVBsiG0IgVARAIBshGgwBCyAbIhpCIH0iIEIFiEIBfEIDgyIfUEUEQANAIAIgASkAADcAACACIAEpABg3ABggAiABKQAQNwAQIAIgASkACDcACCAaQiB9IRogAUEgaiEBIAJBIGohAiAfQgF9Ih9CAFINAAsLICBC4ABUDQADQCACIAEpAAA3AAAgAiABKQAYNwAYIAIgASkAEDcAECACIAEpAAg3AAggAiABKQA4NwA4IAIgASkAMDcAMCACIAEpACg3ACggAiABKQAgNwAgIAIgASkAWDcAWCACIAEpAFA3AFAgAiABKQBINwBIIAIgASkAQDcAQCACIAEpAGA3AGAgAiABKQBoNwBoIAIgASkAcDcAcCACIAEpAHg3AHggAUGAAWohASACQYABaiECIBpCgAF9IhpCH1YNAAsLIBpCEFoEQCACIAEpAAA3AAAgAiABKQAINwAIIBpCEH0hGiACQRBqIQIgAUEQaiEBCyAaQghaBEAgAiABKQAANwAAIBpCCH0hGiACQQhqIQIgAUEIaiEBCyAaQgRaBEAgAiABKAAANgAAIBpCBH0hGiACQQRqIQIgAUEEaiEBCyAaQgJaBEAgAiABLwAAOwAAIBpCAn0hGiACQQJqIQIgAUECaiEBCyAcIBt9IRwgGlBFBEAgAiABLQAAOgAAIAJBAWohAiABQQFqIQELIBxCAFINAAsLIAUgBmshAUEAIARrIQUCQCAEQQdLBEAgBCEDDAELIAEgBE0EQCAEIQMMAQsgAiAEayEFA0ACQCACIAUpAAA3AAAgBEEBdCEDIAEgBGshASACIARqIQIgBEEDSw0AIAMhBCABIANLDQELC0EAIANrIQULIAIgBWohBAJAIAUgDyACa6wiGiABrSIbIBogG1QbIhqnIgFIIAVBf0pxDQAgBUEBSCABIARqIAJLcQ0AIAIgBCABEAcgAWohAgwDCyACIAQgAyADQR91IgFqIAFzIgEQByABaiECIBogAa0iHn0iHFANAiABIARqIQEDQAJAIBwgHiAcIB5UGyIbQiBUBEAgGyEaDAELIBsiGkIgfSIgQgWIQgF8QgODIh9QRQRAA0AgAiABKQAANwAAIAIgASkAGDcAGCACIAEpABA3ABAgAiABKQAINwAIIBpCIH0hGiABQSBqIQEgAkEgaiECIB9CAX0iH0IAUg0ACwsgIELgAFQNAANAIAIgASkAADcAACACIAEpABg3ABggAiABKQAQNwAQIAIgASkACDcACCACIAEpADg3ADggAiABKQAwNwAwIAIgASkAKDcAKCACIAEpACA3ACAgAiABKQBYNwBYIAIgASkAUDcAUCACIAEpAEg3AEggAiABKQBANwBAIAIgASkAYDcAYCACIAEpAGg3AGggAiABKQBwNwBwIAIgASkAeDcAeCABQYABaiEBIAJBgAFqIQIgGkKAAX0iGkIfVg0ACwsgGkIQWgRAIAIgASkAADcAACACIAEpAAg3AAggGkIQfSEaIAJBEGohAiABQRBqIQELIBpCCFoEQCACIAEpAAA3AAAgGkIIfSEaIAJBCGohAiABQQhqIQELIBpCBFoEQCACIAEoAAA2AAAgGkIEfSEaIAJBBGohAiABQQRqIQELIBpCAloEQCACIAEvAAA7AAAgGkICfSEaIAJBAmohAiABQQJqIQELIBwgG30hHCAaUEUEQCACIAEtAAA6AAAgAkEBaiECIAFBAWohAQsgHFBFDQALDAILAkAgASADTSABIA8gAWusIhogBa0iGyAaIBtUGyIapyIEaiICIANLcQ0AIAMgBGogAUsgASADT3ENACABIAMgBBAHGgwCCyABIAMgAyABayIBIAFBH3UiAWogAXMiARAHIAFqIQIgGiABrSIefSIcUA0BIAEgA2ohAQNAAkAgHCAeIBwgHlQbIhtCIFQEQCAbIRoMAQsgGyIaQiB9IiBCBYhCAXxCA4MiH1BFBEADQCACIAEpAAA3AAAgAiABKQAYNwAYIAIgASkAEDcAECACIAEpAAg3AAggGkIgfSEaIAFBIGohASACQSBqIQIgH0IBfSIfQgBSDQALCyAgQuAAVA0AA0AgAiABKQAANwAAIAIgASkAGDcAGCACIAEpABA3ABAgAiABKQAINwAIIAIgASkAODcAOCACIAEpADA3ADAgAiABKQAoNwAoIAIgASkAIDcAICACIAEpAFg3AFggAiABKQBQNwBQIAIgASkASDcASCACIAEpAEA3AEAgAiABKQBgNwBgIAIgASkAaDcAaCACIAEpAHA3AHAgAiABKQB4NwB4IAFBgAFqIQEgAkGAAWohAiAaQoABfSIaQh9WDQALCyAaQhBaBEAgAiABKQAANwAAIAIgASkACDcACCAaQhB9IRogAkEQaiECIAFBEGohAQsgGkIIWgRAIAIgASkAADcAACAaQgh9IRogAkEIaiECIAFBCGohAQsgGkIEWgRAIAIgASgAADYAACAaQgR9IRogAkEEaiECIAFBBGohAQsgGkICWgRAIAIgAS8AADsAACAaQgJ9IRogAkECaiECIAFBAmohAQsgHCAbfSEcIBpQRQRAIAIgAS0AADoAACACQQFqIQIgAUEBaiEBCyAcUEUNAAsMAQsCQAJAIBYEQAJAIAQgBUkEQCAHKAKYRyAESw0BCyABIARrIQMCQEEAIARrIgVBf0ogDyABa6wiGiAbIBogG1QbIhqnIgIgBUpxDQAgBUEBSCACIANqIAFLcQ0AIAEgAyACEAcgAmohAgwFCyABIAMgBCAEQR91IgFqIAFzIgEQByABaiECIBogAa0iHn0iHFANBCABIANqIQEDQAJAIBwgHiAcIB5UGyIbQiBUBEAgGyEaDAELIBsiGkIgfSIgQgWIQgF8QgODIh9QRQRAA0AgAiABKQAANwAAIAIgASkAGDcAGCACIAEpABA3ABAgAiABKQAINwAIIBpCIH0hGiABQSBqIQEgAkEgaiECIB9CAX0iH0IAUg0ACwsgIELgAFQNAANAIAIgASkAADcAACACIAEpABg3ABggAiABKQAQNwAQIAIgASkACDcACCACIAEpADg3ADggAiABKQAwNwAwIAIgASkAKDcAKCACIAEpACA3ACAgAiABKQBYNwBYIAIgASkAUDcAUCACIAEpAEg3AEggAiABKQBANwBAIAIgASkAYDcAYCACIAEpAGg3AGggAiABKQBwNwBwIAIgASkAeDcAeCABQYABaiEBIAJBgAFqIQIgGkKAAX0iGkIfVg0ACwsgGkIQWgRAIAIgASkAADcAACACIAEpAAg3AAggGkIQfSEaIAJBEGohAiABQRBqIQELIBpCCFoEQCACIAEpAAA3AAAgGkIIfSEaIAJBCGohAiABQQhqIQELIBpCBFoEQCACIAEoAAA2AAAgGkIEfSEaIAJBBGohAiABQQRqIQELIBpCAloEQCACIAEvAAA7AAAgGkICfSEaIAJBAmohAiABQQJqIQELIBwgG30hHCAaUEUEQCACIAEtAAA6AAAgAkEBaiECIAFBAWohAQsgHFBFDQALDAQLIBAgAWsiCUEBaiIGIAUgBSAGSxshAyABIARrIQIgAUEHcUUNAiADRQ0CIAEgAi0AADoAACACQQFqIQIgAUEBaiIGQQdxQQAgA0EBayIFGw0BIAYhASAFIQMgCSEGDAILAkAgBCAFSQRAIAcoAphHIARLDQELIAEgASAEayIGKQAANwAAIAEgBUEBa0EHcUEBaiIDaiECIAUgA2siBEUNAyADIAZqIQEDQCACIAEpAAA3AAAgAUEIaiEBIAJBCGohAiAEQQhrIgQNAAsMAwsgASAEIAUQPyECDAILIAEgAi0AADoAASAJQQFrIQYgA0ECayEFIAJBAWohAgJAIAFBAmoiCkEHcUUNACAFRQ0AIAEgAi0AADoAAiAJQQJrIQYgA0EDayEFIAJBAWohAgJAIAFBA2oiCkEHcUUNACAFRQ0AIAEgAi0AADoAAyAJQQNrIQYgA0EEayEFIAJBAWohAgJAIAFBBGoiCkEHcUUNACAFRQ0AIAEgAi0AADoABCAJQQRrIQYgA0EFayEFIAJBAWohAgJAIAFBBWoiCkEHcUUNACAFRQ0AIAEgAi0AADoABSAJQQVrIQYgA0EGayEFIAJBAWohAgJAIAFBBmoiCkEHcUUNACAFRQ0AIAEgAi0AADoABiAJQQZrIQYgA0EHayEFIAJBAWohAgJAIAFBB2oiCkEHcUUNACAFRQ0AIAEgAi0AADoAByAJQQdrIQYgA0EIayEDIAFBCGohASACQQFqIQIMBgsgCiEBIAUhAwwFCyAKIQEgBSEDDAQLIAohASAFIQMMAwsgCiEBIAUhAwwCCyAKIQEgBSEDDAELIAohASAFIQMLAkACQCAGQRdNBEAgA0UNASADQQFrIQUgA0EHcSIEBEADQCABIAItAAA6AAAgA0EBayEDIAFBAWohASACQQFqIQIgBEEBayIEDQALCyAFQQdJDQEDQCABIAItAAA6AAAgASACLQABOgABIAEgAi0AAjoAAiABIAItAAM6AAMgASACLQAEOgAEIAEgAi0ABToABSABIAItAAY6AAYgASACLQAHOgAHIAFBCGohASACQQhqIQIgA0EIayIDDQALDAELIAMNAQsgASECDAELIAEgBCADED8hAgsgCyEFDAELIAEgAy0AAjoAACABQQFqIQILIAUgFE8NACACIBNJDQELCyAAIAI2AgwgACAFIAhBA3ZrIgE2AgAgACATIAJrQYMCajYCECAAIBQgAWtBDmo2AgQgByAIQQdxIgA2AogBIAcgHUJ/IACthkJ/hYM+AoQBC+cFAQR/IAMgAiACIANLGyEEIAAgAWshAgJAIABBB3FFDQAgBEUNACAAIAItAAA6AAAgA0EBayEGIAJBAWohAiAAQQFqIgdBB3FBACAEQQFrIgUbRQRAIAchACAFIQQgBiEDDAELIAAgAi0AADoAASADQQJrIQYgBEECayEFIAJBAWohAgJAIABBAmoiB0EHcUUNACAFRQ0AIAAgAi0AADoAAiADQQNrIQYgBEEDayEFIAJBAWohAgJAIABBA2oiB0EHcUUNACAFRQ0AIAAgAi0AADoAAyADQQRrIQYgBEEEayEFIAJBAWohAgJAIABBBGoiB0EHcUUNACAFRQ0AIAAgAi0AADoABCADQQVrIQYgBEEFayEFIAJBAWohAgJAIABBBWoiB0EHcUUNACAFRQ0AIAAgAi0AADoABSADQQZrIQYgBEEGayEFIAJBAWohAgJAIABBBmoiB0EHcUUNACAFRQ0AIAAgAi0AADoABiADQQdrIQYgBEEHayEFIAJBAWohAgJAIABBB2oiB0EHcUUNACAFRQ0AIAAgAi0AADoAByADQQhrIQMgBEEIayEEIABBCGohACACQQFqIQIMBgsgByEAIAUhBCAGIQMMBQsgByEAIAUhBCAGIQMMBAsgByEAIAUhBCAGIQMMAwsgByEAIAUhBCAGIQMMAgsgByEAIAUhBCAGIQMMAQsgByEAIAUhBCAGIQMLAkAgA0EXTQRAIARFDQEgBEEBayEBIARBB3EiAwRAA0AgACACLQAAOgAAIARBAWshBCAAQQFqIQAgAkEBaiECIANBAWsi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CyAAIAMtAAAEfiADKQMQBUIAC6dB//8DcSADKAIEEEcLIQUgAxAICyAEQRBqJAAgBQvgAQICfwF+QTAQCSICRQRAIAEEQCABQQA2AgQgAUEONgIAC0EADwsgAkIANwMIIAJBADYCACACQgA3AxAgAkIANwMYIAJCADcDICACQgA3ACUgAFAEQCACDwsCQCAAQv////8AVg0AIACnQQR0EAkiA0UNACACIAM2AgBBACEBQgEhBANAIAMgAUEEdGoiAUIANwIAIAFCADcABSAAIARSBEAgBKchASAEQgF8IQQMAQsLIAIgADcDCCACIAA3AxAgAg8LIAEEQCABQQA2AgQgAUEONgIAC0EAEBAgAhAGQQAL7gECA38BfiMAQRBrIgQkAAJAIARBDGpCBBAXIgNFBEBBfyECDAELAkAgAQRAIAJBgAZxIQUDQAJAIAUgASgCBHFFDQACQCADKQMIQgBUBEAgA0EAOgAADAELIANCADcDECADQQE6AAALIAMgAS8BCBANIAMgAS8BChANIAMtAABFBEAgAEEIaiIABEAgAEEANgIEIABBFDYCAAtBfyECDAQLQX8hAiAAIARBDGpCBBAbQQBIDQMgATMBCiIGUA0AIAAgASgCDCAGEBtBAEgNAwsgASgCACIBDQALC0EAIQILIAMQCAsgBEEQaiQAIAILPAEBfyAABEAgAUGABnEhAQNAIAEgACgCBHEEQCACIAAvAQpqQQRqIQILIAAoAgAiAA0ACwsgAkH//wNxC5wBAQN/IABFBEBBAA8LIAAhAwNAAn8CQAJAIAAvAQgiAUH04AFNBEAgAUEBRg0BIAFB9cYBRg0BDAILIAFBgbICRg0AIAFB9eABRw0BCyAAKAIAIQEgAEEANgIAIAAoAgwQBiAAEAYgASADIAAgA0YbIQMCQCACRQRAQQAhAgwBCyACIAE2AgALIAEMAQsgACICKAIACyIADQALIAMLsgQCBX8BfgJAAkACQCAAIAGtEBciAQRAIAEtAAANAUEAIQAMAgsgBARAIARBADYCBCAEQQ42AgALQQAPC0EAIQADQCABLQAABH4gASkDCCABKQMQfQVCAAtCBFQNASABEAwhByABIAEQDCIGrRATIghFBEBBACECIAQEQCAEQQA2AgQgBEEVNgIACyABEAggAEUNAwNAIAAoAgAhASAAKAIMEAYgABAGIAEiAA0ACwwDCwJAAkBBEBAJIgUEQCAFIAY7AQogBSAHOwEIIAUgAjYCBCAFQQA2AgAgBkUNASAFIAggBhBjIgY2AgwgBg0CIAUQBgtBACECIAQEQCAEQQA2AgQgBEEONgIACyABEAggAEUNBANAIAAoAgAhASAAKAIMEAYgABAGIAEiAA0ACwwECyAFQQA2AgwLAkAgAEUEQCAFIQAMAQsgCSAFNgIACyAFIQkgAS0AAA0ACwsCQCABLQAABH8gASkDECABKQMIUQVBAAsNACABIAEtAAAEfiABKQMIIAEpAxB9BUIACyIKQv////8PgxATIQICQCAKpyIFQQNLDQAgAkUNACACQcEUIAUQPUUNAQtBACECIAQEQCAEQQA2AgQgBEEVNgIACyABEAggAEUNAQNAIAAoAgAhASAAKAIMEAYgABAGIAEiAA0ACwwBCyABEAggAwRAIAMgADYCAEEBDwtBASECIABFDQADQCAAKAIAIQEgACgCDBAGIAAQBiABIgANAAsLIAILvgEBBX8gAAR/IAAhAgNAIAIiBCgCACICDQALIAEEQANAIAEiAy8BCCEGIAMoAgAhASAAIQICQAJAA0ACQCACLwEIIAZHDQAgAi8BCiIFIAMvAQpHDQAgBUUNAiACKAIMIAMoAgwgBRA9RQ0CCyACKAIAIgINAAsgA0EANgIAIAQgAzYCACADIQQMAQsgAiACKAIEIAMoAgRBgAZxcjYCBCADQQA2AgAgAygCDBAGIAMQBgsgAQ0ACwsgAAUgAQsLVQICfgF/AkACQCAALQAARQ0AIAApAxAiAkIBfCIDIAJUDQAgAyAAKQMIWA0BCyAAQQA6AAAPCyAAKAIEIgRFBEAPCyAAIAM3AxAgBCACp2ogAToAAAt9AQN/IwBBEGsiAiQAIAIgATYCDEF/IQMCQCAALQAoDQACQCAAKAIAIgRFDQAgBCABEHFBf0oNACAAKAIAIQEgAEEMaiIABEAgACABKAIMNgIAIAAgASgCEDYCBAsMAQsgACACQQxqQgRBExAOQj+HpyEDCyACQRBqJAAgAwvdAQEDfyABIAApAzBaBEAgAEEIagRAIABBADYCDCAAQRI2AggLQX8PCyAAQQhqIQIgAC0AGEECcQRAIAIEQCACQQA2AgQgAkEZNgIAC0F/DwtBfyEDAkAgACABQQAgAhBTIgRFDQAgACgCUCAEIAIQfkUNAAJ/IAEgACkDMFoEQCAAQQhqBEAgAEEANgIMIABBEjYCCAtBfwwBCyABp0EEdCICIAAoAkBqKAIEECAgACgCQCACaiICQQA2AgQgAhBAQQALDQAgACgCQCABp0EEdGpBAToADEEAIQMLIAMLpgIBBX9BfyEFAkAgACABQQBBABAmRQ0AIAAtABhBAnEEQCAAQQhqIgAEQCAAQQA2AgQgAEEZNgIAC0F/DwsCfyAAKAJAIgQgAaciBkEEdGooAgAiBUUEQCADQYCA2I14RyEHQQMMAQsgBSgCRCADRyEHIAUtAAkLIQggBCAGQQR0aiIEIQYgBCgCBCEEQQAgAiAIRiAHG0UEQAJAIAQNACAGIAUQKyIENgIEIAQNACAAQQhqIgAEQCAAQQA2AgQgAEEONgIAC0F/DwsgBCADNgJEIAQgAjoACSAEIAQoAgBBEHI2AgBBAA8LQQAhBSAERQ0AIAQgBCgCAEFvcSIANgIAIABFBEAgBBAgIAZBADYCBEEADwsgBCADNgJEIAQgCDoACQsgBQvjCAIFfwR+IAAtABhBAnEEQCAAQQhqBEAgAEEANgIMIABBGTYCCAtCfw8LIAApAzAhCwJAIANBgMAAcQRAIAAgASADQQAQTCIJQn9SDQELAn4CQAJAIAApAzAiCUIBfCIMIAApAzgiClQEQCAAKAJAIQQMAQsgCkIBhiIJQoAIIAlCgAhUGyIJQhAgCUIQVhsgCnwiCadBBHQiBK0gCkIEhkLw////D4NUDQEgACgCQCAEEDQiBEUNASAAIAk3AzggACAENgJAIAApAzAiCUIBfCEMCyAAIAw3AzAgBCAJp0EEdGoiBEIANwIAIARCADcABSAJDAELIABBCGoEQCAAQQA2AgwgAEEONgIIC0J/CyIJQgBZDQBCfw8LAkAgAUUNAAJ/QQAhBCAJIAApAzBaBEAgAEEIagRAIABBADYCDCAAQRI2AggLQX8MAQsgAC0AGEECcQRAIABBCGoEQCAAQQA2AgwgAEEZNgIIC0F/DAELAkAgAUUNACABLQAARQ0AQX8gASABECJB//8DcSADIABBCGoQNSIERQ0BGiADQYAwcQ0AIARBABAjQQNHDQAgBEECNgIICwJAIAAgAUEAQQAQTCIKQgBTIgENACAJIApRDQAgBBAQIABBCGoEQCAAQQA2AgwgAEEKNgIIC0F/DAELAkAgAUEBIAkgClEbRQ0AAkACfwJAIAAoAkAiASAJpyIFQQR0aiIGKAIAIgMEQCADKAIwIAQQYg0BCyAEIAYoAgQNARogBiAGKAIAECsiAzYCBCAEIAMNARogAEEIagRAIABBADYCDCAAQQ42AggLDAILQQEhByAGKAIAKAIwC0EAQQAgAEEIaiIDECUiCEUNAAJAAkAgASAFQQR0aiIFKAIEIgENACAGKAIAIgENAEEAIQEMAQsgASgCMCIBRQRAQQAhAQwBCyABQQBBACADECUiAUUNAQsgACgCUCAIIAlBACADEE1FDQAgAQRAIAAoAlAgAUEAEH4aCyAFKAIEIQMgBwRAIANFDQIgAy0AAEECcUUNAiADKAIwEBAgBSgCBCIBIAEoAgBBfXEiAzYCACADRQRAIAEQICAFQQA2AgQgBBAQQQAMBAsgASAGKAIAKAIwNgIwIAQQEEEADAMLIAMoAgAiAUECcQRAIAMoAjAQECAFKAIEIgMoAgAhAQsgAyAENgIwIAMgAUECcjYCAEEADAILIAQQEEF/DAELIAQQEEEAC0UNACALIAApAzBRBEBCfw8LIAAoAkAgCadBBHRqED4gACALNwMwQn8PCyAJpyIGQQR0IgEgACgCQGoQQAJAAkAgACgCQCIEIAFqIgMoAgAiBUUNAAJAIAMoAgQiAwRAIAMoAgAiAEEBcUUNAQwCCyAFECshAyAAKAJAIgQgBkEEdGogAzYCBCADRQ0CIAMoAgAhAAsgA0F+NgIQIAMgAEEBcjYCAAsgASAEaiACNgIIIAkPCyAAQQhqBEAgAEEANgIMIABBDjYCCAtCfwteAQF/IwBBEGsiAiQAAn8gACgCJEEBRwRAIABBDGoiAARAIABBADYCBCAAQRI2AgALQX8MAQsgAkEANgIIIAIgATcDACAAIAJCEEEMEA5CP4enCyEAIAJBEGokACAAC9oDAQZ/IwBBEGsiBSQAIAUgAjYCDCMAQaABayIEJAAgBEEIakHA8ABBkAEQBxogBCAANgI0IAQgADYCHCAEQX4gAGsiA0H/////ByADQf////8HSRsiBjYCOCAEIAAgBmoiADYCJCAEIAA2AhggBEEIaiEAIwBB0AFrIgMkACADIAI2AswBIANBoAFqQQBBKBAZIAMgAygCzAE2AsgBAkBBACABIANByAFqIANB0ABqIANBoAFqEEpBAEgNACAAKAJMQQBOIQcgACgCACECIAAsAEpBAEwEQCAAIAJBX3E2AgALIAJBIHEhCAJ/IAAoAjAEQCAAIAEgA0HIAWogA0HQAGogA0GgAWoQSgwBCyAAQdAANgIwIAAgA0HQAGo2AhAgACADNgIcIAAgAzYCFCAAKAIsIQIgACADNgIsIAAgASADQcgBaiADQdAAaiADQaABahBKIAJFDQAaIABBAEEAIAAoAiQRAAAaIABBADYCMCAAIAI2AiwgAEEANgIcIABBADYCECAAKAIUGiAAQQA2AhRBAAsaIAAgACgCACAIcjYCACAHRQ0ACyADQdABaiQAIAYEQCAEKAIcIgAgACAEKAIYRmtBADoAAAsgBEGgAWokACAFQRBqJAALUwEDfwJAIAAoAgAsAABBMGtBCk8NAANAIAAoAgAiAiwAACEDIAAgAkEBajYCACABIANqQTBrIQEgAiwAAUEwa0EKTw0BIAFBCmwhAQwACwALIAELuwIAAkAgAUEUSw0AAkACQAJAAkACQAJAAkACQAJAAkAgAUEJaw4KAAECAwQFBgcICQoLIAIgAigCACIBQQRqNgIAIAAgASgCADYCAA8LIAIgAigCACIBQQRqNgIAIAAgATQCADcDAA8LIAIgAigCACIBQQRqNgIAIAAgATUCADcDAA8LIAIgAigCAEEHakF4cSIBQQhqNgIAIAAgASkDADcDAA8LIAIgAigCACIBQQRqNgIAIAAgATIBADcDAA8LIAIgAigCACIBQQRqNgIAIAAgATMBADcDAA8LIAIgAigCACIBQQRqNgIAIAAgATAAADcDAA8LIAIgAigCACIBQQRqNgIAIAAgATEAADcDAA8LIAIgAigCAEEHakF4cSIBQQhqNgIAIAAgASsDADkDAA8LIAAgAkEAEQcACwubAgAgAEUEQEEADwsCfwJAIAAEfyABQf8ATQ0BAkBB9IIBKAIAKAIARQRAIAFBgH9xQYC/A0YNAwwBCyABQf8PTQRAIAAgAUE/cUGAAXI6AAEgACABQQZ2QcABcjoAAEECDAQLIAFBgLADT0EAIAFBgEBxQYDAA0cbRQRAIAAgAUE/cUGAAXI6AAIgACABQQx2QeABcjoAACAAIAFBBnZBP3FBgAFyOgABQQMMBAsgAUGAgARrQf//P00EQCAAIAFBP3FBgAFyOgADIAAgAUESdkHwAXI6AAAgACABQQZ2QT9xQYABcjoAAiAAIAFBDHZBP3FBgAFyOgABQQQMBAsLQYSEAUEZNgIAQX8FQQELDAELIAAgAToAAEEBCwvjAQECfyACQQBHIQMCQAJAAkAgAEEDcUUNACACRQ0AIAFB/wFxIQQDQCAALQAAIARGDQIgAkEBayICQQBHIQMgAEEBaiIAQQNxRQ0BIAINAAsLIANFDQELAkAgAC0AACABQf8BcUYNACACQQRJDQAgAUH/AXFBgYKECGwhAwNAIAAoAgAgA3MiBEF/cyAEQYGChAhrcUGAgYKEeHENASAAQQRqIQAgAkEEayICQQNLDQALCyACRQ0AIAFB/wFxIQEDQCABIAAtAABGBEAgAA8LIABBAWohACACQQFrIgINAAsLQQALeQEBfAJAIABFDQAgACsDECAAKwMgIgIgAUQAAAAAAAAAACABRAAAAAAAAAAAZBsiAUQAAAAAAADwPyABRAAAAAAAAPA/YxsgACsDKCACoaKgIgEgACsDGKFjRQ0AIAAoAgAgASAAKAIMIAAoAgQRDgAgACABOQMYCwtIAQF8AkAgAEUNACAAKwMQIAArAyAiASAAKwMoIAGhoCIBIAArAxihY0UNACAAKAIAIAEgACgCDCAAKAIEEQ4AIAAgATkDGAsLWgICfgF/An8CQAJAIAAtAABFDQAgACkDECIBQgF8IgIgAVQNACACIAApAwhYDQELIABBADoAAEEADAELQQAgACgCBCIDRQ0AGiAAIAI3AxAgAyABp2otAAALC4IEAgZ/AX4gAEEAIAEbRQRAIAIEQCACQQA2AgQgAkESNgIAC0EADwsCQAJAIAApAwhQDQAgACgCECABLQAAIgQEf0Kl6wohCSABIQMDQCAJIAStQv8Bg3whCSADLQABIgQEQCADQQFqIQMgCUL/////D4NCIX4hCQwBCwsgCacFQYUqCyIEIAAoAgBwQQJ0aiIGKAIAIgNFDQADQAJAIAMoAhwgBEcNACABIAMoAgAQOA0AAkAgAykDCEJ/UQRAIAMoAhghAQJAIAUEQCAFIAE2AhgMAQsgBiABNgIACyADEAYgACAAKQMIQgF9Igk3AwggCbogACgCACIBuER7FK5H4XqEP6JjRQ0BIAFBgQJJDQECf0EAIQMgACgCACIGIAFBAXYiBUcEQCAFEDwiB0UEQCACBEAgAkEANgIEIAJBDjYCAAtBAAwCCwJAIAApAwhCACAGG1AEQCAAKAIQIQQMAQsgACgCECEEA0AgBCADQQJ0aigCACIBBEADQCABKAIYIQIgASAHIAEoAhwgBXBBAnRqIggoAgA2AhggCCABNgIAIAIiAQ0ACwsgA0EBaiIDIAZHDQALCyAEEAYgACAFNgIAIAAgBzYCEAtBAQsNAQwFCyADQn83AxALQQEPCyADIgUoAhgiAw0ACwsgAgRAIAJBADYCBCACQQk2AgALC0EAC6UGAgl/AX4jAEHwAGsiBSQAAkACQCAARQ0AAkAgAQRAIAEpAzAgAlYNAQtBACEDIABBCGoEQCAAQQA2AgwgAEESNgIICwwCCwJAIANBCHENACABKAJAIAKnQQR0aiIGKAIIRQRAIAYtAAxFDQELQQAhAyAAQQhqBEAgAEEANgIMIABBDzYCCAsMAgsgASACIANBCHIgBUE4ahCKAUF/TARAQQAhAyAAQQhqBEAgAEEANgIMIABBFDYCCAsMAgsgA0EDdkEEcSADciIGQQRxIQcgBSkDUCEOIAUvAWghCQJAIANBIHFFIAUvAWpBAEdxIgtFDQAgBA0AIAAoAhwiBA0AQQAhAyAAQQhqBEAgAEEANgIMIABBGjYCCAsMAgsgBSkDWFAEQCAAQQBCAEEAEFIhAwwCCwJAIAdFIgwgCUEAR3EiDUEBckUEQEEAIQMgBUEAOwEwIAUgDjcDICAFIA43AxggBSAFKAJgNgIoIAVC3AA3AwAgASgCACAOIAVBACABIAIgAEEIahBeIgYNAQwDC0EAIQMgASACIAYgAEEIaiIGECYiB0UNAiABKAIAIAUpA1ggBUE4aiAHLwEMQQF2QQNxIAEgAiAGEF4iBkUNAgsCfyAGIAE2AiwCQCABKAJEIghBAWoiCiABKAJIIgdJBEAgASgCTCEHDAELIAEoAkwgB0EKaiIIQQJ0EDQiB0UEQCABQQhqBEAgAUEANgIMIAFBDjYCCAtBfwwCCyABIAc2AkwgASAINgJIIAEoAkQiCEEBaiEKCyABIAo2AkQgByAIQQJ0aiAGNgIAQQALQX9MBEAgBhALDAELAkAgC0UEQCAGIQEMAQtBJkEAIAUvAWpBAUYbIgFFBEAgAEEIagRAIABBADYCDCAAQRg2AggLDAMLIAAgBiAFLwFqQQAgBCABEQYAIQEgBhALIAFFDQILAkAgDUUEQCABIQMMAQsgACABIAUvAWgQgQEhAyABEAsgA0UNAQsCQCAJRSAMckUEQCADIQEMAQsgACADQQEQgAEhASADEAsgAUUNAQsgASEDDAELQQAhAwsgBUHwAGokACADC4UBAQF/IAFFBEAgAEEIaiIABEAgAEEANgIEIABBEjYCAAtBAA8LQTgQCSIDRQRAIABBCGoiAARAIABBADYCBCAAQQ42AgALQQAPCyADQQA2AhAgA0IANwIIIANCADcDKCADQQA2AgQgAyACNgIAIANCADcDGCADQQA2AjAgACABQTsgAxBCCw8AIAAgASACQQBBABCCAQusAgECfyABRQRAIABBCGoiAARAIABBADYCBCAAQRI2AgALQQAPCwJAIAJBfUsNACACQf//A3FBCEYNACAAQQhqIgAEQCAAQQA2AgQgAEEQNgIAC0EADwsCQEGwwAAQCSIFBEAgBUEANgIIIAVCADcCACAFQYiBAUGogQEgAxs2AqhAIAUgAjYCFCAFIAM6ABAgBUEAOgAPIAVBADsBDCAFIAMgAkF9SyIGcToADiAFQQggAiAGG0H//wNxIAQgBUGIgQFBqIEBIAMbKAIAEQAAIgI2AqxAIAINASAFEDEgBRAGCyAAQQhqIgAEQCAAQQA2AgQgAEEONgIAC0EADwsgACABQTogBRBCIgAEfyAABSAFKAKsQCAFKAKoQCgCBBEDACAFEDEgBRAGQQALC6ABAQF/IAIgACgCBCIDIAIgA0kbIgIEQCAAIAMgAms2AgQCQAJAAkACQCAAKAIcIgMoAhRBAWsOAgEAAgsgA0GgAWogASAAKAIAIAJB3IABKAIAEQgADAILIAAgACgCMCABIAAoAgAgAkHEgAEoAgARBAA2AjAMAQsgASAAKAIAIAIQBxoLIAAgACgCACACajYCACAAIAAoAgggAmo2AggLC7cCAQR/QX4hAgJAIABFDQAgACgCIEUNACAAKAIkIgRFDQAgACgCHCIBRQ0AIAEoAgAgAEcNAAJAAkAgASgCICIDQTlrDjkBAgICAgICAgICAgIBAgICAQICAgICAgICAgICAgICAgICAQICAgICAgICAgICAQICAgICAgICAgEACyADQZoFRg0AIANBKkcN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DCABajYCDCAGIAYoAgggAWo2AgggBSAFKAIUIAFqNgIUIAUgBSgCECABazYCECAGIAYoAhAgAWsiATYCECABDQAgBiAGKAIENgIIC0EAIQRBACEJIAMoAhBFDQAMCgsgAygCHCgCJCEGIAMgAygCGCIBQQFqNgIYIAEgBmotAAAhASADIARBAWo2AhAgAygCBCAEaiABOgAAIAEEQCADKAIQIQQMAQsLIAMoAhwoAixFDQAgAygCECIGIAlNDQAgBQJ/IAUoAjAhBEEAIAMoAgQgCWoiAUUNABogBCABIAYgCWtB1IABKAIAEQAACzYCMAsgA0HnADYCIAsCQCADKAIcKAIsBEAgAygCDCADKAIQIgFBAmpJBH8gBRAKIAMoAhANAkEABSABCyADKAIEaiAFKAIwOwAAIAMgAygCEEECajYCECADQaABakHkgAEoAgARAQAaCyADQfEANgIgIAUQCiADKAIQRQ0BDAcLDAYLIAUoAgQNAQsgAygCPA0AIApFDQEgAygCIEGaBUYNAQsCfyADKAKIASIBRQRAIAMgChCFAQwBCwJAAkACQCADKAKMAUECaw4CAAECCwJ/AkADQAJAAkAgAygCPA0AIAMQLyADKAI8DQAgCg0BQQAMBAsgAygCSCADKAJoai0AACEEIAMgAygC8C0iAUEBajYC8C0gASADKALsLWpBADoAACADIAMoAvAtIgFBAWo2AvAtIAEgAygC7C1qQQA6AAAgAyADKALwLSIBQQFqNgLwLSABIAMoAuwtaiAEOgAAIAMgBEECdGoiASABLwHkAUEBajsB5AEgAyADKAI8QQFrNgI8IAMgAygCaEEBaiIBNgJoIAMoAvAtIAMoAvQtRw0BQQAhBCADIAMoAlgiBkEATgR/IAMoAkggBmoFQQALIAEgBmtBABAPIAMgAygCaDYCWCADKAIAEAogAygCACgCEA0BDAILCyADQQA2AoQuIApBBEYEQCADIAMoAlgiAUEATgR/IAMoAkggAWoFQQALIAMoAmggAWtBARAPIAMgAygCaDYCWCADKAIAEApBA0ECIAMoAgAoAhAbDAILIAMoAvAtBEBBACEEIAMgAygCWCIBQQBOBH8gAygCSCABagVBAAsgAygCaCABa0EAEA8gAyADKAJoNgJYIAMoAgAQCiADKAIAKAIQRQ0BC0EBIQQLIAQL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bGl0ZXJhbC9sZW5ndGhzIHNldABpbnZhbGlkIGNvZGUgbGVuZ3RocyBzZXQAdW5rbm93biBoZWFkZXIgZmxhZ3Mgc2V0AGludmFsaWQgZGlzdGFuY2VzIHNldABpbnZhbGlkIGJpdCBsZW5ndGggcmVwZWF0AEZpbGUgYWxyZWFkeSBleGlzdHMAdG9vIG1hbnkgbGVuZ3RoIG9yIGRpc3RhbmNlIHN5bWJvbHMAaW52YWxpZCBzdG9yZWQgYmxvY2sgbGVuZ3RocwAlcyVzJXMAYnVmZmVyIGVycm9yAE5vIGVycm9yAHN0cmVhbSBlcnJvcgBUZWxsIGVycm9yAEludGVybmFsIGVycm9yAFNlZWsgZXJyb3IAV3JpdGUgZXJyb3IAZmlsZSBlcnJvcgBSZWFkIGVycm9yAFpsaWIgZXJyb3IAZGF0YSBlcnJvcgBDUkMgZXJyb3IAaW5jb21wYXRpYmxlIHZlcnNpb24AaW52YWxpZCBjb2RlIC0tIG1pc3NpbmcgZW5kLW9mLWJsb2NrAGluY29ycmVjdCBoZWFkZXIgY2hlY2sAaW5jb3JyZWN0IGxlbmd0aCBjaGVjawBpbmNvcnJlY3QgZGF0YSBjaGVjawBpbnZhbGlkIGRpc3RhbmNlIHRvbyBmYXIgYmFjawBoZWFkZXIgY3JjIG1pc21hdGNoADEuMi4xMy56bGliLW5nAGludmFsaWQgd2luZG93IHNpemUAUmVhZC1vbmx5IGFyY2hpdmUATm90IGEgemlwIGFyY2hpdmUAUmVzb3VyY2Ugc3RpbGwgaW4gdXNlAE1hbGxvYyBmYWlsdXJlAGludmFsaWQgYmxvY2sgdHlwZQBGYWlsdXJlIHRvIGNyZWF0ZSB0ZW1wb3JhcnkgZmlsZQBDYW4ndCBvcGVuIGZpbGUATm8gc3VjaCBmaWxlAFByZW1hdHVyZSBlbmQgb2YgZmlsZQBDYW4ndCByZW1vdmUgZmlsZQBpbnZhbGlkIGxpdGVyYWwvbGVuZ3RoIGNvZGUAaW52YWxpZCBkaXN0YW5jZSBjb2RlAHVua25vd24gY29tcHJlc3Npb24gbWV0aG9kAHN0cmVhbSBlbmQAQ29tcHJlc3NlZCBkYXRhIGludmFsaWQATXVsdGktZGlzayB6aXAgYXJjaGl2ZXMgbm90IHN1cHBvcnRlZABPcGVyYXRpb24gbm90IHN1cHBvcnRlZABFbmNyeXB0aW9uIG1ldGhvZCBub3Qgc3VwcG9ydGVkAENvbXByZXNzaW9uIG1ldGhvZCBub3Qgc3VwcG9ydGVkAEVudHJ5IGhhcyBiZWVuIGRlbGV0ZWQAQ29udGFpbmluZyB6aXAgYXJjaGl2ZSB3YXMgY2xvc2VkAENsb3NpbmcgemlwIGFyY2hpdmUgZmFpbGVkAFJlbmFtaW5nIHRlbXBvcmFyeSBmaWxlIGZhaWxlZABFbnRyeSBoYXMgYmVlbiBjaGFuZ2VkAE5vIHBhc3N3b3JkIHByb3ZpZGVkAFdyb25nIHBhc3N3b3JkIHByb3ZpZGVkAFVua25vd24gZXJyb3IgJWQAQUUAKG51bGwpADogAFBLBgcAUEsGBgBQSwUGAFBLAwQAUEsBAgAAAAA/BQAAwAcAAJMIAAB4CAAAbwUAAJEFAAB6BQAAsgUAAFYIAAAbBwAA1gQAAAsHAADqBgAAnAUAAMgGAACyCAAAHggAACgHAABHBAAAoAYAAGAFAAAuBAAAPgcAAD8IAAD+BwAAjgYAAMkIAADeCAAA5gcAALIGAABVBQAAqAcAACAAQcgTCxEBAAAAAQAAAAEAAAABAAAAAQBB7BMLCQEAAAABAAAAAgBBmBQLAQEAQbgUCwEBAEHSFAukLDomOyZlJmYmYyZgJiIg2CXLJdklQiZAJmomayY8JrolxCWVITwgtgCnAKwlqCGRIZMhkiGQIR8ilCGyJbwlIAAhACIAIwAkACUAJgAnACgAKQAqACsALAAtAC4ALwAwADEAMgAzADQANQA2ADcAOAA5ADoAOwA8AD0APgA/AEAAQQBCAEMARABFAEYARwBIAEkASgBLAEwATQBOAE8AUABRAFIAUwBUAFUAVgBXAFgAWQBaAFsAXABdAF4AXwBgAGEAYgBjAGQAZQBmAGcAaABpAGoAawBsAG0AbgBvAHAAcQByAHMAdAB1AHYAdwB4AHkAegB7AHwAfQB+AAIjxwD8AOkA4gDkAOAA5QDnAOoA6wDoAO8A7gDsAMQAxQDJAOYAxgD0APYA8gD7APkA/wDWANwAogCjAKUApyCSAeEA7QDzAPoA8QDRAKoAugC/ABAjrAC9ALwAoQCrALsAkSWSJZMlAiUkJWElYiVWJVUlYyVRJVclXSVcJVslECUUJTQlLCUcJQAlPCVeJV8lWiVUJWklZiVgJVAlbCVnJWglZCVlJVklWCVSJVMlayVqJRglDCWIJYQljCWQJYAlsQPfAJMDwAOjA8MDtQDEA6YDmAOpA7QDHiLGA7UDKSJhIrEAZSJkIiAjISP3AEgisAAZIrcAGiJ/ILIAoCWgAAAAAACWMAd3LGEO7rpRCZkZxG0Hj/RqcDWlY+mjlWSeMojbDqS43Hke6dXgiNnSlytMtgm9fLF+By2455Edv5BkELcd8iCwakhxufPeQb6EfdTaGuvk3W1RtdT0x4XTg1aYbBPAqGtkevli/ezJZYpPXAEU2WwGY2M9D/r1DQiNyCBuO14QaUzkQWDVcnFnotHkAzxH1ARL/YUN0mu1CqX6qLU1bJiyQtbJu9tA+bys42zYMnVc30XPDdbcWT3Rq6ww2SY6AN5RgFHXyBZh0L+19LQhI8SzVpmVus8Ppb24nrgCKAiIBV+y2QzGJOkLsYd8by8RTGhYqx1hwT0tZraQQdx2BnHbAbwg0pgqENXviYWxcR+1tgal5L+fM9S46KLJB3g0+QAPjqgJlhiYDuG7DWp/LT1tCJdsZJEBXGPm9FFra2JhbBzYMGWFTgBi8u2VBmx7pQEbwfQIglfED/XG2bBlUOm3Euq4vot8iLn83x3dYkkt2hXzfNOMZUzU+1hhsk3OUbU6dAC8o+Iwu9RBpd9K15XYPW3E0aT79NbTaulpQ/zZbjRGiGet0Lhg2nMtBETlHQMzX0wKqsl8Dd08cQVQqkECJxAQC76GIAzJJbVoV7OFbyAJ1Ga5n+Rhzg753l6YydkpIpjQsLSo18cXPbNZgQ20LjtcvbetbLrAIIO47bazv5oM4rYDmtKxdDlH1eqvd9KdFSbbBIMW3HMSC2PjhDtklD5qbQ2oWmp6C88O5J3/CZMnrgAKsZ4HfUSTD/DSowiHaPIBHv7CBmldV2L3y2dlgHE2bBnnBmtudhvU/uAr04laetoQzErdZ2/fufn5776OQ763F9WOsGDoo9bWfpPRocTC2DhS8t9P8We70WdXvKbdBrU/SzaySNorDdhMGwqv9koDNmB6BEHD72DfVd9nqO+ObjF5vmlGjLNhyxqDZryg0m8lNuJoUpV3DMwDRwu7uRYCIi8mBVW+O7rFKAu9spJatCsEarNcp//XwjHP0LWLntksHa7eW7DCZJsm8mPsnKNqdQqTbQKpBgmcPzYO64VnB3ITVwAFgkq/lRR6uOKuK7F7OBu2DJuO0pINvtXlt+/cfCHf2wvU0tOGQuLU8fiz3Whug9ofzRa+gVsmufbhd7Bvd0e3GOZaCIhwag//yjsGZlwLARH/nmWPaa5i+NP/a2FFz2wWeOIKoO7SDddUgwROwrMDOWEmZ6f3FmDQTUdpSdt3bj5KatGu3FrW2WYL30DwO9g3U668qcWeu95/z7JH6f+1MBzyvb2KwrrKMJOzU6ajtCQFNtC6kwbXzSlX3lS/Z9kjLnpms7hKYcQCG2hdlCtvKje+C7ShjgzDG98FWo3vAi0AAAAARjtnZYx2zsrKTamvWevtTh/QiivVnSOEk6ZE4bLW25307bz4PqAVV3ibcjLrPTbTrQZRtmdL+BkhcJ98JavG4GOQoYWp3Qgq7+ZvT3xAK646e0zL8DblZLYNggGXfR190UZ6GBsL07ddMLTSzpbwM4itl1ZC4D75BNtZnAtQ/BpNa5t/hyYy0MEdVbVSuxFUFIB2Md7N356Y9rj7uYYnh/+9QOI18OlNc8uOKOBtysmmVq2sbBsEAyogY2Yu+zr6aMBdn6KN9DDktpNVdxDXtDErsNH7Zhl+vV1+G5wt4WfaFoYCEFsvrVZgSMjFxgwpg/1rTEmwwuMPi6WGFqD4NVCbn1Ca1jb/3O1Rmk9LFXsJcHIewz3bsYUGvNSkdiOo4k1EzSgA7WJuO4oH/Z3O5rumqYNx6wAsN9BnSTMLPtV1MFmwv33wH/lGl3pq4NObLNu0/uaWHVGgrXo0gd3lSMfmgi0NqyuCS5BM59g2CAaeDW9jVEDGzBJ7oakd8AQvW8tjSpGGyuXXva2ARBvpYQIgjgTIbSerjlZAzq8m37LpHbjXI1AReGVrdh32zTL8sPZVmXq7/DY8gJtTOFvCz35gpaq0LQwF8hZrYGGwL4Eni0jk7cbhS6v9hi6KjRlSzLZ+Nwb715hAwLD902b0HJVdk3lfEDrWGStdsyxA8Wtqe5YOoDY/oeYNWMR1qxwlM5B7QPnd0u+/5rWKnpYq9titTZMS4OQ8VNuDWcd9x7iBRqDdSwsJcg0wbhcJ6zeLT9BQ7oWd+UHDpp4kUADaxRY7vaDcdhQPmk1zars97Bb9BotzN0si3HFwRbni1gFYpO1mPW6gz5Iom6j3JxANcWErahSrZsO77V2k3n774D84wIda8o0u9bS2SZCVxtbs0/2xiRmwGCZfi39DzC07oooWXMdAW/VoBmCSDQK7y5FEgKz0js0FW8j2Yj5bUCbfHWtButcm6BWRHY9wsG0QDPZWd2k8G97GeiC5o+mG/UKvvZonZfAziCPLVO064AlefNtuO7aWx5TwraDxYwvkECUwg3XvfSraqUZNv4g20sPODbWmBEAcCUJ7e2zR3T+Nl+ZY6F2r8UcbkJYiH0vPvllwqNuTPQF01QZmEUagIvAAm0WVytbsOozti1+tnRQj66ZzRiHr2uln0L2M9Hb5bbJNngh4ADenPjtQwjGw9UR3i5IhvcY7jvv9XOtoWxgKLmB/b+Qt1sCiFrGlg2Yu2cVdSbwPEOATSSuHdtqNw5ectqTyVvsNXRDAajgUGzOkUiBUwZht/W7eVpoLTfDe6gvLuY/BhhAgh713RabN6Dng9o9cKrsm82yAQZb/JgV3uR1iEnNQy701a6zYAAAAAFiA4tfxBrR0qYZWo+INaOm6jYo+EwvcnUuLPkqFHaEJ3Z1D3nQbFX0sm/eqZxDJ4D+QKzeWFn2UzpafQwo7QhNSu6DE+z32Z6O9FLDoNir6sLbILRkwno5BsHxZjybjGtemAc1+IFduJqC1uW0ri/M1q2kknC0/h8St3VAUdoQmTPZm8eVwMFK98NKF9nvsz677DhgHfVi7X/26bJFrJS/J68f4YG2RWzjtc4xzZk3GK+avEYJg+bLa4BtlHk3GNUbNJOLvS3JBt8uQlvxArtykwEwLDUYaqFXG+H+bUGc8w9CF62pW00gy1jGfeV0P1SHd7QKIW7uh0NtZdijsCE1wbOqa2eq8OYFqXu7K4WCkkmGCczvn1NBjZzYHrfGpRPVxS5Nc9x0wBHf/50/8wa0XfCN6vvp12eZ6lw4i10peeleoidPR/iqLURz9wNoit5hawGAx3JbDaVx0FKfK61f/SgmAVsxfIw5MvfRFx4O+HUdhabTBN8rsQdUdPJqMa2QabrzNnDgflRzayN6X5IKGFwZVL5FQ9ncRsiG5hy1i4QfPtUiBmRYQAXvBW4pFiwMKp1yqjPH/8gwTKDahznhuISyvx6d6DJ8nmNvUrKaRjCxERiWqEuV9KvAys7xvces8jaZCutsFGjo50lGxB5gJMeVPoLez7Pg3UTtQ2BGaCFjzTaHepe75Xkc5stV5c+pVm6RD080HG1Mv0NXFsJONRVJEJMME53xD5jA3yNh6b0g6rcbObA6eTo7ZWuNTiQJjsV6r5ef982UFKrjuO2Dgbtm3SeiPFBFobcPf/vKAh34QVy74RvR2eKQjPfOaaWVzeL7M9S4dlHXMykSulbwcLndrtaghyO0owx+mo/1V/iMfglelSSEPJav2wbM0tZkz1mIwtYDBaDViFiO+XFx7Pr6L0rjoKIo4Cv9OldevFhU1eL+TY9vnE4EMrJi/RvQYXZFdngsyBR7p5cuIdqaTCJRxOo7C0mIOIAUphR5PcQX8mNiDqjuAA0jseDQZ1yC0+wCJMq2j0bJPdJo5cT7CuZPpaz/FSjO/J539KbjepalaCQwvDKpUr+59HyTQN0ekMuDuImRDtqKGlHIPW8Qqj7kTgwnvsNuJDWeQAjMtyILR+mEEh1k5hGWO9xL6za+SGBoGFE65XpSsbhUfkiRNn3Dz5BkmULyZxIdsQp3xNMJ/Jp1EKYXFxMtSjk/1GNbPF89/SUFsJ8mju+lfPPix394vGFmIjEDZalsLUlQRU9K2xvpU4GWi1AKyZnnf4j75PTWXf2uWz/+JQYR0twvc9FXcdXIDfy3y4ajjZH7ru+ScPBJiyp9K4ihIAWkWAlnp9NXwb6J2qO9AoQAAAADhtlLvg2vUBWLdhuoG16gL52H65IW8fA5kCi7hDK5RF+0YA/iPxYUSbnPX/Qp5+Rzrz6vziRItGWikf/YYXKMu+erxwZs3dyt6gSXEHosLJf89Wcqd4N8gfFaNzxTy8jn1RKDWl5kmPHYvdNMSJVoy85MI3ZFOjjdw+NzYMLhGXdEOFLKz05JYUmXAtzZv7lbX2by5tQQ6U1SyaLw8FhdK3aBFpb99w09ey5GgOsG/Qdt37a65qmtEWBw5qyjk5XPJUrecq48xdko5Y5kuM014z4Ufl61YmX1M7suSJEq0ZMX85ounIWBhRpcyjiKdHG/DK06AofbIakBAmoVgcI26gcbfVeMbWb8CrQtQZqclsYcRd17lzPG0BHqjW2ze3K2NaI5C77UIqA4DWkdqCXSmi78mSelioKMI1PJMeCwulJmafHv7R/qRGvGofn77hp+fTdRw/ZBSmhwmAHV0gn+DlTQtbPfpq4YWX/lpclXXiJPjhWfxPgONEIhRYlDIy+exfpkI06Mf4jIVTQ1WH2Pst6kxA9V0t+k0wuUGXGaa8L3QyB/fDU71PrscGlqxMvu7B2AU2drm/jhstBFIlGjJqSI6Jsv/vMwqSe4jTkPAwq/1ki3NKBTHLJ5GKEQ6Od6ljGsxx1Ht2ybnvzRC7ZHVo1vDOsGGRdAgMBc/geZrrmBQOUECjb+r4zvtRIcxw6Vmh5FKBFoXoOXsRU+NSDq5bP5oVg4j7rzvlbxTi5+SsmopwF0I9Ea36UIUWJm6yIB4DJpvGtEchftnTmqfbWCLftsyZBwGtI79sOZhlRSZl3Siy3gWf02S98kffZPDMZxydWNzEKjlmfEet3axXi3zUOh/HDI1+fbTg6sZt4mF+FY/1xc04lH91VQDEr3wfORcRi4LPpuo4d8t+g67J9TvWpGGADhMAOrZ+lIFqQKO3Ui03DIqaVrYy98IN6/VJtZOY3Q5LL7y080IoDylrN/KRBqNJSbHC8/HcVkgo3t3wULNJS4gEKPEwabxK+GW5hQAILT7Yv0yEYNLYP7nQU4fBvcc8GQqmhqFnMj17Ti3AwyO5exuU2MGj+Ux6evvHwgKWU3naITLDYkymeL5ykU6GHwX1XqhkT+bF8PQ/x3tMR6rv958djk0ncBr2/VkFC0U0kbCdg/AKJe5ksfzs7wmEgXuyXDYaCORbjrM0S6gSTCY8qZSRXRMs/Mmo9f5CEI2T1qtVJLcR7UkjqjdgPFePDajsV7rJVu/XXe021dZVTrhC7pYPI1QuYrfv8lyA2coxFGIShnXYquvhY3PpatsLhP5g0zOf2mteC2GxdxScCRqAJ9Gt4Z1pwHUmsML+nsivaiUQGAufqHWfJEAAAAAQ8umh8eQPNSEW5pTzycIc4zsrvQItzSnS3ySIJ5PEObdhLZhWd8sMhoUirVRaBiVEqO+Epb4JEHVM4LGfZlRFz5S95C6CW3D+cLLRLK+WWTxdf/jdS5lsDblwzfj1kHxoB3ndiRGfSVnjduiLPFJgm867wXrYXVWqKrT0foyoy65+QWpPaKf+n5pOX01Fatddt4N2vKFl4mxTjEOZH2zyCe2FU+j7Y8c4CYpm6tau7vokR08bMqHby8BIeiHq/I5xGBUvkA7zu0D8GhqSIz6SgtHXM2PHMaezNdgGRnk4t9aL0RY3nTeC52/eIzWw+qslQhMKxFT1nhSmHD/9GVGXbeu4Noz9XqJcD7cDjtCTi54ieip/NJy+r8Z1H1qKla7KeHwPK26am/ucczopQ1eyObG+E9inWIcIVbEm4n8F0rKN7HNTmwrng2njRlG2x85BRC5voFLI+3CgIVqF7MHrFR4oSvQIzt4k+id/9iUD9+bX6lYHwQzC1zPlYwOV+VzTZxD9MnH2aeKDH8gwXDtAIK7S4cG4NHURSt3U5AY9ZXT01MSV4jJQRRDb8ZfP/3mHPRbYZivwTLbZGe1c860ZDAFEuO0Xoiw95UuN7zpvBf/IhqQe3mAwziyJkTtgaSCrkoCBSoRmFZp2j7RIqas8WFtCnblNpAlpv02oujLjLqrACo9L1uwbmyQFukn7ITJZCciTuB8uB2jtx6adoScXDVPOtuxFKCI8t8GD7mjlC/6aDKofjOo+z34DnyVUt2t1pl7KlLC4XkRCUf+WnXV3hm+c1md5ekK3i5PjQsdzUtI1mvMzI3xn49GVxjEOsU4h/FjvwOq+exAYV9rEvkvlFEyiRPVaRNAlqK1x93eJ+eeFYFgGk4bM1mFvbSMtj9yz32Z9UsmA6YI7aUhQ5E3AQBakYaEAQvVx8qtUm9gfoMsq9gEqPBCV+s75NCgR3bw44zQd2fXSiQkHOyj8S9uZbLkyOI2v1KxdXT0Nj4IZhZ9w8CR+ZhawrpT/EUcrsrnX2VsYNs+9jOY9VC004nClJBCZBMUGf5AV9JYx4Lh2gHBKnyGRXHm1Qa6QFJNxtJyDg109YpW7qbJnUghYTeb8CL8PXemp6ck5WwBo64Qk4Pt2zUEaYCvVypLCdD/eIsWvLMtkTjot8J7IxFFMF+DZXOUJeL3z7+xtAQZNuacacmlV89OIQxVHWLH85opu2G6anDHPe4rXW6t4PvpeNN5LzsY36i/Q0X7/IjjfLf0cVz0P9fbcGRNiDOv6w+bBTje2M6eWVyVBAofXqKNVCIwrRfpliqTsgx50Hmq/gVKKDhGgY6/wtoU7IERsmvKbSBLiaaGzA39HJ9ONroYFAQAAJ0HAAAsCQAAhgUAAEgFAACnBQAAAAQAADIFAAC8BQAALAkAQYDBAAv3CQwACACMAAgATAAIAMwACAAsAAgArAAIAGwACADsAAgAHAAIAJwACABcAAgA3AAIADwACAC8AAgAfAAIAPwACAACAAgAggAIAEIACADCAAgAIgAIAKIACABiAAgA4gAIABIACACSAAgAUgAIANIACAAyAAgAsgAIAHIACADyAAgACgAIAIoACABKAAgAygAIACoACACqAAgAagAIAOoACAAaAAgAmgAIAFoACADaAAgAOgAIALoACAB6AAgA+gAIAAYACACGAAgARgAIAMYACAAmAAgApgAIAGYACADmAAgAFgAIAJYACABWAAgA1gAIADYACAC2AAgAdgAIAPYACAAOAAgAjgAIAE4ACADOAAgALgAIAK4ACABuAAgA7gAIAB4ACACeAAgAXgAIAN4ACAA+AAgAvgAIAH4ACAD+AAgAAQAIAIEACABBAAgAwQAIACEACAChAAgAYQAIAOEACAARAAgAkQAIAFEACADRAAgAMQAIALEACABxAAgA8QAIAAkACACJAAgASQAIAMkACAApAAgAqQAIAGkACADpAAgAGQAIAJkACABZAAgA2QAIADkACAC5AAgAeQAIAPkACAAFAAgAhQAIAEUACADFAAgAJQAIAKUACABlAAgA5QAIABUACACVAAgAVQAIANUACAA1AAgAtQAIAHUACAD1AAgADQAIAI0ACABNAAgAzQAIAC0ACACtAAgAbQAIAO0ACAAdAAgAnQAIAF0ACADdAAgAPQAIAL0ACAB9AAgA/QAIABMACQATAQkAkwAJAJMBCQBTAAkAUwEJANMACQDTAQkAMwAJADMBCQCzAAkAswEJAHMACQBzAQkA8wAJAPMBCQALAAkACwEJAIsACQCLAQkASwAJAEsBCQDLAAkAywEJACsACQArAQkAqwAJAKsBCQBrAAkAawEJAOsACQDrAQkAGwAJABsBCQCbAAkAmwEJAFsACQBbAQkA2wAJANsBCQA7AAkAOwEJALsACQC7AQkAewAJAHsBCQD7AAkA+wEJAAcACQAHAQkAhwAJAIcBCQBHAAkARwEJAMcACQDHAQkAJwAJACcBCQCnAAkApwEJAGcACQBnAQkA5wAJAOcBCQAXAAkAFwEJAJcACQCXAQkAVwAJAFcBCQDXAAkA1wEJADcACQA3AQkAtwAJALcBCQB3AAkAdwEJAPcACQD3AQkADwAJAA8BCQCPAAkAjwEJAE8ACQBPAQkAzwAJAM8BCQAvAAkALwEJAK8ACQCvAQkAbwAJAG8BCQDvAAkA7wEJAB8ACQAfAQkAnwAJAJ8BCQBfAAkAXwEJAN8ACQDfAQkAPwAJAD8BCQC/AAkA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SXMgYSBkaXJlY3RvcnkAVGV4dCBmaWxlIGJ1c3kARXhlYyBmb3JtYXQgZXJyb3IASW52YWxpZCBhcmd1bWVudABBcmd1bWVudCBsaXN0IHRvbyBsb25nAFN5bWJvbGljIGxpbmsgbG9vcABGaWxlbmFtZSB0b28gbG9uZwBUb28gbWFueSBvcGVuIGZpbGVzIGluIHN5c3RlbQBObyBmaWxlIGRlc2NyaXB0b3JzIGF2YWlsYWJsZQBCYWQgZmlsZSBkZXNjcmlwdG9yAE5vIGNoaWxkIHByb2Nlc3MAQmFkIGFkZHJlc3MARmlsZSB0b28gbGFyZ2UAVG9vIG1hbnkgbGlua3MATm8gbG9ja3MgYXZhaWxhYmxlAFJlc291cmNlIGRlYWRsb2NrIHdvdWxkIG9jY3VyAFN0YXRlIG5vdCByZWNvdmVyYWJsZQBQcmV2aW91cyBvd25lciBkaWVkAE9wZXJhdGlvbiBjYW5jZWxlZABGdW5jdGlvbiBub3QgaW1wbGVtZW50ZWQATm8gbWVzc2FnZSBvZiBkZXNpcmVkIHR5cGUASWRlbnRpZmllciByZW1vdmVkAERldmljZSBub3QgYSBzdHJlYW0ATm8gZGF0YSBhdmFpbGFibGUARGV2aWNlIHRpbWVvdXQAT3V0IG9mIHN0cmVhbXMgcmVzb3VyY2VzAExpbmsgaGFzIGJlZW4gc2V2ZXJlZABQcm90b2NvbCBlcnJvcgBCYWQgbWVzc2FnZQBGaWxlIGRlc2NyaXB0b3IgaW4gYmFkIHN0YXRlAE5vdCBhIHNvY2tldABEZXN0aW5hdGlvbiBhZGRyZXNzIHJlcXVpcmVkAE1lc3NhZ2UgdG9vIGxhcmdlAFByb3RvY29sIHdyb25nIHR5cGUgZm9yIHNvY2tldABQcm90b2NvbCBub3QgYXZhaWxhYmxlAFByb3RvY29sIG5vdCBzdXBwb3J0ZWQAU29ja2V0IHR5cGUgbm90IHN1cHBvcnRlZABOb3Qgc3VwcG9ydGVkAFByb3RvY29sIGZhbWlseSBub3Qgc3VwcG9ydGVkAEFkZHJlc3MgZmFtaWx5IG5vdCBzdXBwb3J0ZWQgYnkgcHJvdG9jb2wAQWRkcmVzcyBub3QgYXZhaWxhYmxlAE5ldHdvcmsgaXMgZG93bgBOZXR3b3JrIHVucmVhY2hhYmxlAENvbm5lY3Rpb24gcmVzZXQgYnkgbmV0d29yawBDb25uZWN0aW9uIGFib3J0ZWQATm8gYnVmZmVyIHNwYWNlIGF2YWlsYWJsZQBTb2NrZXQgaXMgY29ubmVjdGVkAFNvY2tldCBub3QgY29ubmVjdGVkAENhbm5vdCBzZW5kIGFmdGVyIHNvY2tldCBzaHV0ZG93bgBPcGVyYXRpb24gYWxyZWFkeSBpbiBwcm9ncmVzcwBPcGVyYXRpb24gaW4gcHJvZ3Jlc3MAU3RhbGUgZmlsZSBoYW5kbGUAUmVtb3RlIEkvTyBlcnJvcgBRdW90YSBleGNlZWRlZABObyBtZWRpdW0gZm91bmQAV3JvbmcgbWVkaXVtIHR5cGUATm8gZXJyb3IgaW5mb3JtYXRpb24AQcCAAQuFARMAAAAUAAAAFQAAABYAAAAXAAAAGAAAABkAAAAaAAAAGwAAABwAAAAdAAAAHgAAAB8AAAAgAAAAIQAAACIAAAAjAAAAgERQADEAAAAyAAAAMwAAADQAAAA1AAAANgAAADcAAAA4AAAAOQAAADIAAAAzAAAANAAAADUAAAA2AAAANwAAADgAQfSCAQsCXEQAQbCDAQsQ/////////////////////w==";io(Pi)||(Pi=x(Pi));function Os(We){try{if(We==Pi&&ce)return new Uint8Array(ce);var tt=ii(We);if(tt)return tt;if(R)return R(We);throw"sync fetching of the wasm failed: you can preload it to Module['wasmBinary'] manually, or emcc.py will do that for you when generating HTML (but not JS)"}catch(Bt){Ri(Bt)}}function so(We,tt){var Bt,or,ee;try{ee=Os(We),or=new WebAssembly.Module(ee),Bt=new WebAssembly.Instance(or,tt)}catch(Le){var ye=Le.toString();throw te("failed to compile wasm module: "+ye),(ye.includes("imported Memory")||ye.includes("memory import"))&&te("Memory size incompatibility issues may be due to changing INITIAL_MEMORY at runtime to something too large. Use ALLOW_MEMORY_GROWTH to allow any size memory (and also make sure not to set INITIAL_MEMORY at runtime to something smaller than it was at compile time)."),Le}return[Bt,or]}function uc(){var We={a:Ha};function tt(ee,ye){var Le=ee.exports;r.asm=Le,Be=r.asm.g,J(Be.buffer),$=r.asm.W,ln(r.asm.h),Ms("wasm-instantiate")}if(Kn("wasm-instantiate"),r.instantiateWasm)try{var Bt=r.instantiateWasm(We,tt);return Bt}catch(ee){return te("Module.instantiateWasm callback failed with error: "+ee),!1}var or=so(Pi,We);return tt(or[0]),r.asm}function Au(We){return F.getFloat32(We,!0)}function sp(We){return F.getFloat64(We,!0)}function op(We){return F.getInt16(We,!0)}function Us(We){return F.getInt32(We,!0)}function Dn(We,tt){F.setInt32(We,tt,!0)}function oo(We){for(;We.length>0;){var tt=We.shift();if(typeof tt=="function"){tt(r);continue}var Bt=tt.func;typeof Bt=="number"?tt.arg===void 0?$.get(Bt)():$.get(Bt)(tt.arg):Bt(tt.arg===void 0?null:tt.arg)}}function _s(We,tt){var Bt=new Date(Us((We>>2)*4)*1e3);Dn((tt>>2)*4,Bt.getUTCSeconds()),Dn((tt+4>>2)*4,Bt.getUTCMinutes()),Dn((tt+8>>2)*4,Bt.getUTCHours()),Dn((tt+12>>2)*4,Bt.getUTCDate()),Dn((tt+16>>2)*4,Bt.getUTCMonth()),Dn((tt+20>>2)*4,Bt.getUTCFullYear()-1900),Dn((tt+24>>2)*4,Bt.getUTCDay()),Dn((tt+36>>2)*4,0),Dn((tt+32>>2)*4,0);var or=Date.UTC(Bt.getUTCFullYear(),0,1,0,0,0,0),ee=(Bt.getTime()-or)/(1e3*60*60*24)|0;return Dn((tt+28>>2)*4,ee),_s.GMTString||(_s.GMTString=rt("GMT")),Dn((tt+40>>2)*4,_s.GMTString),tt}function ml(We,tt){return _s(We,tt)}function yl(We,tt,Bt){be.copyWithin(We,tt,tt+Bt)}function ao(We){try{return Be.grow(We-ke.byteLength+65535>>>16),J(Be.buffer),1}catch{}}function Vn(We){var tt=be.length;We=We>>>0;var Bt=2147483648;if(We>Bt)return!1;for(var or=1;or<=4;or*=2){var ee=tt*(1+.2/or);ee=Math.min(ee,We+100663296);var ye=Math.min(Bt,Fe(Math.max(We,ee),65536)),Le=ao(ye);if(Le)return!0}return!1}function Mn(We){le(We)}function Ti(We){var tt=Date.now()/1e3|0;return We&&Dn((We>>2)*4,tt),tt}function On(){if(On.called)return;On.called=!0;var We=new Date().getFullYear(),tt=new Date(We,0,1),Bt=new Date(We,6,1),or=tt.getTimezoneOffset(),ee=Bt.getTimezoneOffset(),ye=Math.max(or,ee);Dn((ys()>>2)*4,ye*60),Dn((ms()>>2)*4,+(or!=ee));function Le($r){var ji=$r.toTimeString().match(/\(([A-Za-z ]+)\)$/);return ji?ji[1]:"GMT"}var ft=Le(tt),pt=Le(Bt),Nt=rt(ft),rr=rt(pt);ee>2)*4,Nt),Dn((Ci()+4>>2)*4,rr)):(Dn((Ci()>>2)*4,rr),Dn((Ci()+4>>2)*4,Nt))}function _i(We){On();var tt=Date.UTC(Us((We+20>>2)*4)+1900,Us((We+16>>2)*4),Us((We+12>>2)*4),Us((We+8>>2)*4),Us((We+4>>2)*4),Us((We>>2)*4),0),Bt=new Date(tt);Dn((We+24>>2)*4,Bt.getUTCDay());var or=Date.UTC(Bt.getUTCFullYear(),0,1,0,0,0,0),ee=(Bt.getTime()-or)/(1e3*60*60*24)|0;return Dn((We+28>>2)*4,ee),Bt.getTime()/1e3|0}var ir=typeof atob=="function"?atob:function(We){var tt="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",Bt="",or,ee,ye,Le,ft,pt,Nt,rr=0;We=We.replace(/[^A-Za-z0-9\+\/\=]/g,"");do Le=tt.indexOf(We.charAt(rr++)),ft=tt.indexOf(We.charAt(rr++)),pt=tt.indexOf(We.charAt(rr++)),Nt=tt.indexOf(We.charAt(rr++)),or=Le<<2|ft>>4,ee=(ft&15)<<4|pt>>2,ye=(pt&3)<<6|Nt,Bt=Bt+String.fromCharCode(or),pt!==64&&(Bt=Bt+String.fromCharCode(ee)),Nt!==64&&(Bt=Bt+String.fromCharCode(ye));while(rr0||(dt(),mr>0))return;function tt(){Pn||(Pn=!0,r.calledRun=!0,!Ee&&(jt(),o(r),r.onRuntimeInitialized&&r.onRuntimeInitialized(),tr()))}r.setStatus?(r.setStatus("Running..."),setTimeout(function(){setTimeout(function(){r.setStatus("")},1),tt()},1)):tt()}if(r.run=Cs,r.preInit)for(typeof r.preInit=="function"&&(r.preInit=[r.preInit]);r.preInit.length>0;)r.preInit.pop()();return Cs(),e}}();typeof ES=="object"&&typeof K4=="object"?K4.exports=W4:typeof define=="function"&&define.amd?define([],function(){return W4}):typeof ES=="object"&&(ES.createModule=W4)});var Tf,Ole,Ule,_le=Et(()=>{Tf=["number","number"],Ole=(Z=>(Z[Z.ZIP_ER_OK=0]="ZIP_ER_OK",Z[Z.ZIP_ER_MULTIDISK=1]="ZIP_ER_MULTIDISK",Z[Z.ZIP_ER_RENAME=2]="ZIP_ER_RENAME",Z[Z.ZIP_ER_CLOSE=3]="ZIP_ER_CLOSE",Z[Z.ZIP_ER_SEEK=4]="ZIP_ER_SEEK",Z[Z.ZIP_ER_READ=5]="ZIP_ER_READ",Z[Z.ZIP_ER_WRITE=6]="ZIP_ER_WRITE",Z[Z.ZIP_ER_CRC=7]="ZIP_ER_CRC",Z[Z.ZIP_ER_ZIPCLOSED=8]="ZIP_ER_ZIPCLOSED",Z[Z.ZIP_ER_NOENT=9]="ZIP_ER_NOENT",Z[Z.ZIP_ER_EXISTS=10]="ZIP_ER_EXISTS",Z[Z.ZIP_ER_OPEN=11]="ZIP_ER_OPEN",Z[Z.ZIP_ER_TMPOPEN=12]="ZIP_ER_TMPOPEN",Z[Z.ZIP_ER_ZLIB=13]="ZIP_ER_ZLIB",Z[Z.ZIP_ER_MEMORY=14]="ZIP_ER_MEMORY",Z[Z.ZIP_ER_CHANGED=15]="ZIP_ER_CHANGED",Z[Z.ZIP_ER_COMPNOTSUPP=16]="ZIP_ER_COMPNOTSUPP",Z[Z.ZIP_ER_EOF=17]="ZIP_ER_EOF",Z[Z.ZIP_ER_INVAL=18]="ZIP_ER_INVAL",Z[Z.ZIP_ER_NOZIP=19]="ZIP_ER_NOZIP",Z[Z.ZIP_ER_INTERNAL=20]="ZIP_ER_INTERNAL",Z[Z.ZIP_ER_INCONS=21]="ZIP_ER_INCONS",Z[Z.ZIP_ER_REMOVE=22]="ZIP_ER_REMOVE",Z[Z.ZIP_ER_DELETED=23]="ZIP_ER_DELETED",Z[Z.ZIP_ER_ENCRNOTSUPP=24]="ZIP_ER_ENCRNOTSUPP",Z[Z.ZIP_ER_RDONLY=25]="ZIP_ER_RDONLY",Z[Z.ZIP_ER_NOPASSWD=26]="ZIP_ER_NOPASSWD",Z[Z.ZIP_ER_WRONGPASSWD=27]="ZIP_ER_WRONGPASSWD",Z[Z.ZIP_ER_OPNOTSUPP=28]="ZIP_ER_OPNOTSUPP",Z[Z.ZIP_ER_INUSE=29]="ZIP_ER_INUSE",Z[Z.ZIP_ER_TELL=30]="ZIP_ER_TELL",Z[Z.ZIP_ER_COMPRESSED_DATA=31]="ZIP_ER_COMPRESSED_DATA",Z))(Ole||{}),Ule=t=>({get HEAPU8(){return t.HEAPU8},errors:Ole,SEEK_SET:0,SEEK_CUR:1,SEEK_END:2,ZIP_CHECKCONS:4,ZIP_EXCL:2,ZIP_RDONLY:16,ZIP_FL_OVERWRITE:8192,ZIP_FL_COMPRESSED:4,ZIP_OPSYS_DOS:0,ZIP_OPSYS_AMIGA:1,ZIP_OPSYS_OPENVMS:2,ZIP_OPSYS_UNIX:3,ZIP_OPSYS_VM_CMS:4,ZIP_OPSYS_ATARI_ST:5,ZIP_OPSYS_OS_2:6,ZIP_OPSYS_MACINTOSH:7,ZIP_OPSYS_Z_SYSTEM:8,ZIP_OPSYS_CPM:9,ZIP_OPSYS_WINDOWS_NTFS:10,ZIP_OPSYS_MVS:11,ZIP_OPSYS_VSE:12,ZIP_OPSYS_ACORN_RISC:13,ZIP_OPSYS_VFAT:14,ZIP_OPSYS_ALTERNATE_MVS:15,ZIP_OPSYS_BEOS:16,ZIP_OPSYS_TANDEM:17,ZIP_OPSYS_OS_400:18,ZIP_OPSYS_OS_X:19,ZIP_CM_DEFAULT:-1,ZIP_CM_STORE:0,ZIP_CM_DEFLATE:8,uint08S:t._malloc(1),uint32S:t._malloc(4),malloc:t._malloc,free:t._free,getValue:t.getValue,openFromSource:t.cwrap("zip_open_from_source","number",["number","number","number"]),close:t.cwrap("zip_close","number",["number"]),discard:t.cwrap("zip_discard",null,["number"]),getError:t.cwrap("zip_get_error","number",["number"]),getName:t.cwrap("zip_get_name","string",["number","number","number"]),getNumEntries:t.cwrap("zip_get_num_entries","number",["number","number"]),delete:t.cwrap("zip_delete","number",["number","number"]),statIndex:t.cwrap("zip_stat_index","number",["number",...Tf,"number","number"]),fopenIndex:t.cwrap("zip_fopen_index","number",["number",...Tf,"number"]),fread:t.cwrap("zip_fread","number",["number","number","number","number"]),fclose:t.cwrap("zip_fclose","number",["number"]),dir:{add:t.cwrap("zip_dir_add","number",["number","string"])},file:{add:t.cwrap("zip_file_add","number",["number","string","number","number"]),getError:t.cwrap("zip_file_get_error","number",["number"]),getExternalAttributes:t.cwrap("zip_file_get_external_attributes","number",["number",...Tf,"number","number","number"]),setExternalAttributes:t.cwrap("zip_file_set_external_attributes","number",["number",...Tf,"number","number","number"]),setMtime:t.cwrap("zip_file_set_mtime","number",["number",...Tf,"number","number"]),setCompression:t.cwrap("zip_set_file_compression","number",["number",...Tf,"number","number"])},ext:{countSymlinks:t.cwrap("zip_ext_count_symlinks","number",["number"])},error:{initWithCode:t.cwrap("zip_error_init_with_code",null,["number","number"]),strerror:t.cwrap("zip_error_strerror","string",["number"])},name:{locate:t.cwrap("zip_name_locate","number",["number","string","number"])},source:{fromUnattachedBuffer:t.cwrap("zip_source_buffer_create","number",["number",...Tf,"number","number"]),fromBuffer:t.cwrap("zip_source_buffer","number",["number","number",...Tf,"number"]),free:t.cwrap("zip_source_free",null,["number"]),keep:t.cwrap("zip_source_keep",null,["number"]),open:t.cwrap("zip_source_open","number",["number"]),close:t.cwrap("zip_source_close","number",["number"]),seek:t.cwrap("zip_source_seek","number",["number",...Tf,"number"]),tell:t.cwrap("zip_source_tell","number",["number"]),read:t.cwrap("zip_source_read","number",["number","number","number"]),error:t.cwrap("zip_source_error","number",["number"])},struct:{statS:t.cwrap("zipstruct_statS","number",[]),statSize:t.cwrap("zipstruct_stat_size","number",["number"]),statCompSize:t.cwrap("zipstruct_stat_comp_size","number",["number"]),statCompMethod:t.cwrap("zipstruct_stat_comp_method","number",["number"]),statMtime:t.cwrap("zipstruct_stat_mtime","number",["number"]),statCrc:t.cwrap("zipstruct_stat_crc","number",["number"]),errorS:t.cwrap("zipstruct_errorS","number",[]),errorCodeZip:t.cwrap("zipstruct_error_code_zip","number",["number"])}})});function V4(t,e){let r=t.indexOf(e);if(r<=0)return null;let o=r;for(;r>=0&&(o=r+e.length,t[o]!==V.sep);){if(t[r-1]===V.sep)return null;r=t.indexOf(e,o)}return t.length>o&&t[o]!==V.sep?null:t.slice(0,o)}var rA,Hle=Et(()=>{Pt();Pt();nA();rA=class t extends Op{static async openPromise(e,r){let o=new t(r);try{return await e(o)}finally{o.saveAndClose()}}constructor(e={}){let r=e.fileExtensions,o=e.readOnlyArchives,a=typeof r>"u"?A=>V4(A,".zip"):A=>{for(let p of r){let h=V4(A,p);if(h)return h}return null},n=(A,p)=>new Zi(p,{baseFs:A,readOnly:o,stats:A.statSync(p)}),u=async(A,p)=>{let h={baseFs:A,readOnly:o,stats:await A.statPromise(p)};return()=>new Zi(p,h)};super({...e,factorySync:n,factoryPromise:u,getMountPoint:a})}}});function fot(t){if(typeof t=="string"&&String(+t)===t)return+t;if(typeof t=="number"&&Number.isFinite(t))return t<0?Date.now()/1e3:t;if(qle.types.isDate(t))return t.getTime()/1e3;throw new Error("Invalid time")}function CS(){return Buffer.from([80,75,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0])}var na,z4,qle,J4,jle,wS,Zi,X4=Et(()=>{Pt();Pt();Pt();Pt();Pt();Pt();na=ve("fs"),z4=ve("stream"),qle=ve("util"),J4=Ze(ve("zlib"));Y4();jle="mixed";wS=class extends Error{constructor(e,r){super(e),this.name="Libzip Error",this.code=r}},Zi=class extends _u{constructor(r,o={}){super();this.listings=new Map;this.entries=new Map;this.fileSources=new Map;this.fds=new Map;this.nextFd=0;this.ready=!1;this.readOnly=!1;let a=o;if(this.level=typeof a.level<"u"?a.level:jle,r??=CS(),typeof r=="string"){let{baseFs:A=new Tn}=a;this.baseFs=A,this.path=r}else this.path=null,this.baseFs=null;if(o.stats)this.stats=o.stats;else if(typeof r=="string")try{this.stats=this.baseFs.statSync(r)}catch(A){if(A.code==="ENOENT"&&a.create)this.stats=wa.makeDefaultStats();else throw A}else this.stats=wa.makeDefaultStats();this.libzip=f1();let n=this.libzip.malloc(4);try{let A=0;o.readOnly&&(A|=this.libzip.ZIP_RDONLY,this.readOnly=!0),typeof r=="string"&&(r=a.create?CS():this.baseFs.readFileSync(r));let p=this.allocateUnattachedSource(r);try{this.zip=this.libzip.openFromSource(p,A,n),this.lzSource=p}catch(h){throw this.libzip.source.free(p),h}if(this.zip===0){let h=this.libzip.struct.errorS();throw this.libzip.error.initWithCode(h,this.libzip.getValue(n,"i32")),this.makeLibzipError(h)}}finally{this.libzip.free(n)}this.listings.set(It.root,new Set);let u=this.libzip.getNumEntries(this.zip,0);for(let A=0;Ar)throw new Error("Overread");let n=Buffer.from(this.libzip.HEAPU8.subarray(o,o+r));return process.env.YARN_IS_TEST_ENV&&process.env.YARN_ZIP_DATA_EPILOGUE&&(n=Buffer.concat([n,Buffer.from(process.env.YARN_ZIP_DATA_EPILOGUE)])),n}finally{this.libzip.free(o)}}finally{this.libzip.source.close(this.lzSource),this.libzip.source.free(this.lzSource),this.ready=!1}}discardAndClose(){this.prepareClose(),this.libzip.discard(this.zip),this.ready=!1}saveAndClose(){if(!this.path||!this.baseFs)throw new Error("ZipFS cannot be saved and must be discarded when loaded from a buffer");if(this.readOnly){this.discardAndClose();return}let r=this.baseFs.existsSync(this.path)||this.stats.mode===wa.DEFAULT_MODE?void 0:this.stats.mode;this.baseFs.writeFileSync(this.path,this.getBufferAndClose(),{mode:r}),this.ready=!1}resolve(r){return V.resolve(It.root,r)}async openPromise(r,o,a){return this.openSync(r,o,a)}openSync(r,o,a){let n=this.nextFd++;return this.fds.set(n,{cursor:0,p:r}),n}hasOpenFileHandles(){return!!this.fds.size}async opendirPromise(r,o){return this.opendirSync(r,o)}opendirSync(r,o={}){let a=this.resolveFilename(`opendir '${r}'`,r);if(!this.entries.has(a)&&!this.listings.has(a))throw nr.ENOENT(`opendir '${r}'`);let n=this.listings.get(a);if(!n)throw nr.ENOTDIR(`opendir '${r}'`);let u=[...n],A=this.openSync(a,"r");return uD(this,a,u,{onClose:()=>{this.closeSync(A)}})}async readPromise(r,o,a,n,u){return this.readSync(r,o,a,n,u)}readSync(r,o,a=0,n=o.byteLength,u=-1){let A=this.fds.get(r);if(typeof A>"u")throw nr.EBADF("read");let p=u===-1||u===null?A.cursor:u,h=this.readFileSync(A.p);h.copy(o,a,p,p+n);let E=Math.max(0,Math.min(h.length-p,n));return(u===-1||u===null)&&(A.cursor+=E),E}async writePromise(r,o,a,n,u){return typeof o=="string"?this.writeSync(r,o,u):this.writeSync(r,o,a,n,u)}writeSync(r,o,a,n,u){throw typeof this.fds.get(r)>"u"?nr.EBADF("read"):new Error("Unimplemented")}async closePromise(r){return this.closeSync(r)}closeSync(r){if(typeof this.fds.get(r)>"u")throw nr.EBADF("read");this.fds.delete(r)}createReadStream(r,{encoding:o}={}){if(r===null)throw new Error("Unimplemented");let a=this.openSync(r,"r"),n=Object.assign(new z4.PassThrough({emitClose:!0,autoDestroy:!0,destroy:(A,p)=>{clearImmediate(u),this.closeSync(a),p(A)}}),{close(){n.destroy()},bytesRead:0,path:r,pending:!1}),u=setImmediate(async()=>{try{let A=await this.readFilePromise(r,o);n.bytesRead=A.length,n.end(A)}catch(A){n.destroy(A)}});return n}createWriteStream(r,{encoding:o}={}){if(this.readOnly)throw nr.EROFS(`open '${r}'`);if(r===null)throw new Error("Unimplemented");let a=[],n=this.openSync(r,"w"),u=Object.assign(new z4.PassThrough({autoDestroy:!0,emitClose:!0,destroy:(A,p)=>{try{A?p(A):(this.writeFileSync(r,Buffer.concat(a),o),p(null))}catch(h){p(h)}finally{this.closeSync(n)}}}),{close(){u.destroy()},bytesWritten:0,path:r,pending:!1});return u.on("data",A=>{let p=Buffer.from(A);u.bytesWritten+=p.length,a.push(p)}),u}async realpathPromise(r){return this.realpathSync(r)}realpathSync(r){let o=this.resolveFilename(`lstat '${r}'`,r);if(!this.entries.has(o)&&!this.listings.has(o))throw nr.ENOENT(`lstat '${r}'`);return o}async existsPromise(r){return this.existsSync(r)}existsSync(r){if(!this.ready)throw nr.EBUSY(`archive closed, existsSync '${r}'`);if(this.symlinkCount===0){let a=V.resolve(It.root,r);return this.entries.has(a)||this.listings.has(a)}let o;try{o=this.resolveFilename(`stat '${r}'`,r,void 0,!1)}catch{return!1}return o===void 0?!1:this.entries.has(o)||this.listings.has(o)}async accessPromise(r,o){return this.accessSync(r,o)}accessSync(r,o=na.constants.F_OK){let a=this.resolveFilename(`access '${r}'`,r);if(!this.entries.has(a)&&!this.listings.has(a))throw nr.ENOENT(`access '${r}'`);if(this.readOnly&&o&na.constants.W_OK)throw nr.EROFS(`access '${r}'`)}async statPromise(r,o={bigint:!1}){return o.bigint?this.statSync(r,{bigint:!0}):this.statSync(r)}statSync(r,o={bigint:!1,throwIfNoEntry:!0}){let a=this.resolveFilename(`stat '${r}'`,r,void 0,o.throwIfNoEntry);if(a!==void 0){if(!this.entries.has(a)&&!this.listings.has(a)){if(o.throwIfNoEntry===!1)return;throw nr.ENOENT(`stat '${r}'`)}if(r[r.length-1]==="/"&&!this.listings.has(a))throw nr.ENOTDIR(`stat '${r}'`);return this.statImpl(`stat '${r}'`,a,o)}}async fstatPromise(r,o){return this.fstatSync(r,o)}fstatSync(r,o){let a=this.fds.get(r);if(typeof a>"u")throw nr.EBADF("fstatSync");let{p:n}=a,u=this.resolveFilename(`stat '${n}'`,n);if(!this.entries.has(u)&&!this.listings.has(u))throw nr.ENOENT(`stat '${n}'`);if(n[n.length-1]==="/"&&!this.listings.has(u))throw nr.ENOTDIR(`stat '${n}'`);return this.statImpl(`fstat '${n}'`,u,o)}async lstatPromise(r,o={bigint:!1}){return o.bigint?this.lstatSync(r,{bigint:!0}):this.lstatSync(r)}lstatSync(r,o={bigint:!1,throwIfNoEntry:!0}){let a=this.resolveFilename(`lstat '${r}'`,r,!1,o.throwIfNoEntry);if(a!==void 0){if(!this.entries.has(a)&&!this.listings.has(a)){if(o.throwIfNoEntry===!1)return;throw nr.ENOENT(`lstat '${r}'`)}if(r[r.length-1]==="/"&&!this.listings.has(a))throw nr.ENOTDIR(`lstat '${r}'`);return this.statImpl(`lstat '${r}'`,a,o)}}statImpl(r,o,a={}){let n=this.entries.get(o);if(typeof n<"u"){let u=this.libzip.struct.statS();if(this.libzip.statIndex(this.zip,n,0,0,u)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip));let p=this.stats.uid,h=this.stats.gid,E=this.libzip.struct.statSize(u)>>>0,I=512,v=Math.ceil(E/I),x=(this.libzip.struct.statMtime(u)>>>0)*1e3,C=x,R=x,L=x,U=new Date(C),z=new Date(R),te=new Date(L),ae=new Date(x),le=this.listings.has(o)?na.constants.S_IFDIR:this.isSymbolicLink(n)?na.constants.S_IFLNK:na.constants.S_IFREG,ce=le===na.constants.S_IFDIR?493:420,Ce=le|this.getUnixMode(n,ce)&511,de=this.libzip.struct.statCrc(u),Be=Object.assign(new wa.StatEntry,{uid:p,gid:h,size:E,blksize:I,blocks:v,atime:U,birthtime:z,ctime:te,mtime:ae,atimeMs:C,birthtimeMs:R,ctimeMs:L,mtimeMs:x,mode:Ce,crc:de});return a.bigint===!0?wa.convertToBigIntStats(Be):Be}if(this.listings.has(o)){let u=this.stats.uid,A=this.stats.gid,p=0,h=512,E=0,I=this.stats.mtimeMs,v=this.stats.mtimeMs,x=this.stats.mtimeMs,C=this.stats.mtimeMs,R=new Date(I),L=new Date(v),U=new Date(x),z=new Date(C),te=na.constants.S_IFDIR|493,le=Object.assign(new wa.StatEntry,{uid:u,gid:A,size:p,blksize:h,blocks:E,atime:R,birthtime:L,ctime:U,mtime:z,atimeMs:I,birthtimeMs:v,ctimeMs:x,mtimeMs:C,mode:te,crc:0});return a.bigint===!0?wa.convertToBigIntStats(le):le}throw new Error("Unreachable")}getUnixMode(r,o){if(this.libzip.file.getExternalAttributes(this.zip,r,0,0,this.libzip.uint08S,this.libzip.uint32S)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip));return this.libzip.getValue(this.libzip.uint08S,"i8")>>>0!==this.libzip.ZIP_OPSYS_UNIX?o:this.libzip.getValue(this.libzip.uint32S,"i32")>>>16}registerListing(r){let o=this.listings.get(r);if(o)return o;this.registerListing(V.dirname(r)).add(V.basename(r));let n=new Set;return this.listings.set(r,n),n}registerEntry(r,o){this.registerListing(V.dirname(r)).add(V.basename(r)),this.entries.set(r,o)}unregisterListing(r){this.listings.delete(r),this.listings.get(V.dirname(r))?.delete(V.basename(r))}unregisterEntry(r){this.unregisterListing(r);let o=this.entries.get(r);this.entries.delete(r),!(typeof o>"u")&&(this.fileSources.delete(o),this.isSymbolicLink(o)&&this.symlinkCount--)}deleteEntry(r,o){if(this.unregisterEntry(r),this.libzip.delete(this.zip,o)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip))}resolveFilename(r,o,a=!0,n=!0){if(!this.ready)throw nr.EBUSY(`archive closed, ${r}`);let u=V.resolve(It.root,o);if(u==="/")return It.root;let A=this.entries.get(u);if(a&&A!==void 0)if(this.symlinkCount!==0&&this.isSymbolicLink(A)){let p=this.getFileSource(A).toString();return this.resolveFilename(r,V.resolve(V.dirname(u),p),!0,n)}else return u;for(;;){let p=this.resolveFilename(r,V.dirname(u),!0,n);if(p===void 0)return p;let h=this.listings.has(p),E=this.entries.has(p);if(!h&&!E){if(n===!1)return;throw nr.ENOENT(r)}if(!h)throw nr.ENOTDIR(r);if(u=V.resolve(p,V.basename(u)),!a||this.symlinkCount===0)break;let I=this.libzip.name.locate(this.zip,u.slice(1),0);if(I===-1)break;if(this.isSymbolicLink(I)){let v=this.getFileSource(I).toString();u=V.resolve(V.dirname(u),v)}else break}return u}allocateBuffer(r){Buffer.isBuffer(r)||(r=Buffer.from(r));let o=this.libzip.malloc(r.byteLength);if(!o)throw new Error("Couldn't allocate enough memory");return new Uint8Array(this.libzip.HEAPU8.buffer,o,r.byteLength).set(r),{buffer:o,byteLength:r.byteLength}}allocateUnattachedSource(r){let o=this.libzip.struct.errorS(),{buffer:a,byteLength:n}=this.allocateBuffer(r),u=this.libzip.source.fromUnattachedBuffer(a,n,0,1,o);if(u===0)throw this.libzip.free(o),this.makeLibzipError(o);return u}allocateSource(r){let{buffer:o,byteLength:a}=this.allocateBuffer(r),n=this.libzip.source.fromBuffer(this.zip,o,a,0,1);if(n===0)throw this.libzip.free(o),this.makeLibzipError(this.libzip.getError(this.zip));return n}setFileSource(r,o){let a=Buffer.isBuffer(o)?o:Buffer.from(o),n=V.relative(It.root,r),u=this.allocateSource(o);try{let A=this.libzip.file.add(this.zip,n,u,this.libzip.ZIP_FL_OVERWRITE);if(A===-1)throw this.makeLibzipError(this.libzip.getError(this.zip));if(this.level!=="mixed"){let p=this.level===0?this.libzip.ZIP_CM_STORE:this.libzip.ZIP_CM_DEFLATE;if(this.libzip.file.setCompression(this.zip,A,0,p,this.level)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip))}return this.fileSources.set(A,a),A}catch(A){throw this.libzip.source.free(u),A}}isSymbolicLink(r){if(this.symlinkCount===0)return!1;if(this.libzip.file.getExternalAttributes(this.zip,r,0,0,this.libzip.uint08S,this.libzip.uint32S)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip));return this.libzip.getValue(this.libzip.uint08S,"i8")>>>0!==this.libzip.ZIP_OPSYS_UNIX?!1:(this.libzip.getValue(this.libzip.uint32S,"i32")>>>16&na.constants.S_IFMT)===na.constants.S_IFLNK}getFileSource(r,o={asyncDecompress:!1}){let a=this.fileSources.get(r);if(typeof a<"u")return a;let n=this.libzip.struct.statS();if(this.libzip.statIndex(this.zip,r,0,0,n)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip));let A=this.libzip.struct.statCompSize(n),p=this.libzip.struct.statCompMethod(n),h=this.libzip.malloc(A);try{let E=this.libzip.fopenIndex(this.zip,r,0,this.libzip.ZIP_FL_COMPRESSED);if(E===0)throw this.makeLibzipError(this.libzip.getError(this.zip));try{let I=this.libzip.fread(E,h,A,0);if(I===-1)throw this.makeLibzipError(this.libzip.file.getError(E));if(IA)throw new Error("Overread");let v=this.libzip.HEAPU8.subarray(h,h+A),x=Buffer.from(v);if(p===0)return this.fileSources.set(r,x),x;if(o.asyncDecompress)return new Promise((C,R)=>{J4.default.inflateRaw(x,(L,U)=>{L?R(L):(this.fileSources.set(r,U),C(U))})});{let C=J4.default.inflateRawSync(x);return this.fileSources.set(r,C),C}}finally{this.libzip.fclose(E)}}finally{this.libzip.free(h)}}async fchmodPromise(r,o){return this.chmodPromise(this.fdToPath(r,"fchmod"),o)}fchmodSync(r,o){return this.chmodSync(this.fdToPath(r,"fchmodSync"),o)}async chmodPromise(r,o){return this.chmodSync(r,o)}chmodSync(r,o){if(this.readOnly)throw nr.EROFS(`chmod '${r}'`);o&=493;let a=this.resolveFilename(`chmod '${r}'`,r,!1),n=this.entries.get(a);if(typeof n>"u")throw new Error(`Assertion failed: The entry should have been registered (${a})`);let A=this.getUnixMode(n,na.constants.S_IFREG|0)&-512|o;if(this.libzip.file.setExternalAttributes(this.zip,n,0,0,this.libzip.ZIP_OPSYS_UNIX,A<<16)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip))}async fchownPromise(r,o,a){return this.chownPromise(this.fdToPath(r,"fchown"),o,a)}fchownSync(r,o,a){return this.chownSync(this.fdToPath(r,"fchownSync"),o,a)}async chownPromise(r,o,a){return this.chownSync(r,o,a)}chownSync(r,o,a){throw new Error("Unimplemented")}async renamePromise(r,o){return this.renameSync(r,o)}renameSync(r,o){throw new Error("Unimplemented")}async copyFilePromise(r,o,a){let{indexSource:n,indexDest:u,resolvedDestP:A}=this.prepareCopyFile(r,o,a),p=await this.getFileSource(n,{asyncDecompress:!0}),h=this.setFileSource(A,p);h!==u&&this.registerEntry(A,h)}copyFileSync(r,o,a=0){let{indexSource:n,indexDest:u,resolvedDestP:A}=this.prepareCopyFile(r,o,a),p=this.getFileSource(n),h=this.setFileSource(A,p);h!==u&&this.registerEntry(A,h)}prepareCopyFile(r,o,a=0){if(this.readOnly)throw nr.EROFS(`copyfile '${r} -> '${o}'`);if(a&na.constants.COPYFILE_FICLONE_FORCE)throw nr.ENOSYS("unsupported clone operation",`copyfile '${r}' -> ${o}'`);let n=this.resolveFilename(`copyfile '${r} -> ${o}'`,r),u=this.entries.get(n);if(typeof u>"u")throw nr.EINVAL(`copyfile '${r}' -> '${o}'`);let A=this.resolveFilename(`copyfile '${r}' -> ${o}'`,o),p=this.entries.get(A);if(a&(na.constants.COPYFILE_EXCL|na.constants.COPYFILE_FICLONE_FORCE)&&typeof p<"u")throw nr.EEXIST(`copyfile '${r}' -> '${o}'`);return{indexSource:u,resolvedDestP:A,indexDest:p}}async appendFilePromise(r,o,a){if(this.readOnly)throw nr.EROFS(`open '${r}'`);return typeof a>"u"?a={flag:"a"}:typeof a=="string"?a={flag:"a",encoding:a}:typeof a.flag>"u"&&(a={flag:"a",...a}),this.writeFilePromise(r,o,a)}appendFileSync(r,o,a={}){if(this.readOnly)throw nr.EROFS(`open '${r}'`);return typeof a>"u"?a={flag:"a"}:typeof a=="string"?a={flag:"a",encoding:a}:typeof a.flag>"u"&&(a={flag:"a",...a}),this.writeFileSync(r,o,a)}fdToPath(r,o){let a=this.fds.get(r)?.p;if(typeof a>"u")throw nr.EBADF(o);return a}async writeFilePromise(r,o,a){let{encoding:n,mode:u,index:A,resolvedP:p}=this.prepareWriteFile(r,a);A!==void 0&&typeof a=="object"&&a.flag&&a.flag.includes("a")&&(o=Buffer.concat([await this.getFileSource(A,{asyncDecompress:!0}),Buffer.from(o)])),n!==null&&(o=o.toString(n));let h=this.setFileSource(p,o);h!==A&&this.registerEntry(p,h),u!==null&&await this.chmodPromise(p,u)}writeFileSync(r,o,a){let{encoding:n,mode:u,index:A,resolvedP:p}=this.prepareWriteFile(r,a);A!==void 0&&typeof a=="object"&&a.flag&&a.flag.includes("a")&&(o=Buffer.concat([this.getFileSource(A),Buffer.from(o)])),n!==null&&(o=o.toString(n));let h=this.setFileSource(p,o);h!==A&&this.registerEntry(p,h),u!==null&&this.chmodSync(p,u)}prepareWriteFile(r,o){if(typeof r=="number"&&(r=this.fdToPath(r,"read")),this.readOnly)throw nr.EROFS(`open '${r}'`);let a=this.resolveFilename(`open '${r}'`,r);if(this.listings.has(a))throw nr.EISDIR(`open '${r}'`);let n=null,u=null;typeof o=="string"?n=o:typeof o=="object"&&({encoding:n=null,mode:u=null}=o);let A=this.entries.get(a);return{encoding:n,mode:u,resolvedP:a,index:A}}async unlinkPromise(r){return this.unlinkSync(r)}unlinkSync(r){if(this.readOnly)throw nr.EROFS(`unlink '${r}'`);let o=this.resolveFilename(`unlink '${r}'`,r);if(this.listings.has(o))throw nr.EISDIR(`unlink '${r}'`);let a=this.entries.get(o);if(typeof a>"u")throw nr.EINVAL(`unlink '${r}'`);this.deleteEntry(o,a)}async utimesPromise(r,o,a){return this.utimesSync(r,o,a)}utimesSync(r,o,a){if(this.readOnly)throw nr.EROFS(`utimes '${r}'`);let n=this.resolveFilename(`utimes '${r}'`,r);this.utimesImpl(n,a)}async lutimesPromise(r,o,a){return this.lutimesSync(r,o,a)}lutimesSync(r,o,a){if(this.readOnly)throw nr.EROFS(`lutimes '${r}'`);let n=this.resolveFilename(`utimes '${r}'`,r,!1);this.utimesImpl(n,a)}utimesImpl(r,o){this.listings.has(r)&&(this.entries.has(r)||this.hydrateDirectory(r));let a=this.entries.get(r);if(a===void 0)throw new Error("Unreachable");if(this.libzip.file.setMtime(this.zip,a,0,fot(o),0)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip))}async mkdirPromise(r,o){return this.mkdirSync(r,o)}mkdirSync(r,{mode:o=493,recursive:a=!1}={}){if(a)return this.mkdirpSync(r,{chmod:o});if(this.readOnly)throw nr.EROFS(`mkdir '${r}'`);let n=this.resolveFilename(`mkdir '${r}'`,r);if(this.entries.has(n)||this.listings.has(n))throw nr.EEXIST(`mkdir '${r}'`);this.hydrateDirectory(n),this.chmodSync(n,o)}async rmdirPromise(r,o){return this.rmdirSync(r,o)}rmdirSync(r,{recursive:o=!1}={}){if(this.readOnly)throw nr.EROFS(`rmdir '${r}'`);if(o){this.removeSync(r);return}let a=this.resolveFilename(`rmdir '${r}'`,r),n=this.listings.get(a);if(!n)throw nr.ENOTDIR(`rmdir '${r}'`);if(n.size>0)throw nr.ENOTEMPTY(`rmdir '${r}'`);let u=this.entries.get(a);if(typeof u>"u")throw nr.EINVAL(`rmdir '${r}'`);this.deleteEntry(r,u)}async rmPromise(r,o){return this.rmSync(r,o)}rmSync(r,{recursive:o=!1}={}){if(this.readOnly)throw nr.EROFS(`rm '${r}'`);if(o){this.removeSync(r);return}let a=this.resolveFilename(`rm '${r}'`,r),n=this.listings.get(a);if(!n)throw nr.ENOTDIR(`rm '${r}'`);if(n.size>0)throw nr.ENOTEMPTY(`rm '${r}'`);let u=this.entries.get(a);if(typeof u>"u")throw nr.EINVAL(`rm '${r}'`);this.deleteEntry(r,u)}hydrateDirectory(r){let o=this.libzip.dir.add(this.zip,V.relative(It.root,r));if(o===-1)throw this.makeLibzipError(this.libzip.getError(this.zip));return this.registerListing(r),this.registerEntry(r,o),o}async linkPromise(r,o){return this.linkSync(r,o)}linkSync(r,o){throw nr.EOPNOTSUPP(`link '${r}' -> '${o}'`)}async symlinkPromise(r,o){return this.symlinkSync(r,o)}symlinkSync(r,o){if(this.readOnly)throw nr.EROFS(`symlink '${r}' -> '${o}'`);let a=this.resolveFilename(`symlink '${r}' -> '${o}'`,o);if(this.listings.has(a))throw nr.EISDIR(`symlink '${r}' -> '${o}'`);if(this.entries.has(a))throw nr.EEXIST(`symlink '${r}' -> '${o}'`);let n=this.setFileSource(a,r);if(this.registerEntry(a,n),this.libzip.file.setExternalAttributes(this.zip,n,0,0,this.libzip.ZIP_OPSYS_UNIX,(na.constants.S_IFLNK|511)<<16)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip));this.symlinkCount+=1}async readFilePromise(r,o){typeof o=="object"&&(o=o?o.encoding:void 0);let a=await this.readFileBuffer(r,{asyncDecompress:!0});return o?a.toString(o):a}readFileSync(r,o){typeof o=="object"&&(o=o?o.encoding:void 0);let a=this.readFileBuffer(r);return o?a.toString(o):a}readFileBuffer(r,o={asyncDecompress:!1}){typeof r=="number"&&(r=this.fdToPath(r,"read"));let a=this.resolveFilename(`open '${r}'`,r);if(!this.entries.has(a)&&!this.listings.has(a))throw nr.ENOENT(`open '${r}'`);if(r[r.length-1]==="/"&&!this.listings.has(a))throw nr.ENOTDIR(`open '${r}'`);if(this.listings.has(a))throw nr.EISDIR("read");let n=this.entries.get(a);if(n===void 0)throw new Error("Unreachable");return this.getFileSource(n,o)}async readdirPromise(r,o){return this.readdirSync(r,o)}readdirSync(r,o){let a=this.resolveFilename(`scandir '${r}'`,r);if(!this.entries.has(a)&&!this.listings.has(a))throw nr.ENOENT(`scandir '${r}'`);let n=this.listings.get(a);if(!n)throw nr.ENOTDIR(`scandir '${r}'`);if(o?.recursive)if(o?.withFileTypes){let u=Array.from(n,A=>Object.assign(this.statImpl("lstat",V.join(r,A)),{name:A,path:It.dot}));for(let A of u){if(!A.isDirectory())continue;let p=V.join(A.path,A.name),h=this.listings.get(V.join(a,p));for(let E of h)u.push(Object.assign(this.statImpl("lstat",V.join(r,p,E)),{name:E,path:p}))}return u}else{let u=[...n];for(let A of u){let p=this.listings.get(V.join(a,A));if(!(typeof p>"u"))for(let h of p)u.push(V.join(A,h))}return u}else return o?.withFileTypes?Array.from(n,u=>Object.assign(this.statImpl("lstat",V.join(r,u)),{name:u,path:void 0})):[...n]}async readlinkPromise(r){let o=this.prepareReadlink(r);return(await this.getFileSource(o,{asyncDecompress:!0})).toString()}readlinkSync(r){let o=this.prepareReadlink(r);return this.getFileSource(o).toString()}prepareReadlink(r){let o=this.resolveFilename(`readlink '${r}'`,r,!1);if(!this.entries.has(o)&&!this.listings.has(o))throw nr.ENOENT(`readlink '${r}'`);if(r[r.length-1]==="/"&&!this.listings.has(o))throw nr.ENOTDIR(`open '${r}'`);if(this.listings.has(o))throw nr.EINVAL(`readlink '${r}'`);let a=this.entries.get(o);if(a===void 0)throw new Error("Unreachable");if(!this.isSymbolicLink(a))throw nr.EINVAL(`readlink '${r}'`);return a}async truncatePromise(r,o=0){let a=this.resolveFilename(`open '${r}'`,r),n=this.entries.get(a);if(typeof n>"u")throw nr.EINVAL(`open '${r}'`);let u=await this.getFileSource(n,{asyncDecompress:!0}),A=Buffer.alloc(o,0);return u.copy(A),await this.writeFilePromise(r,A)}truncateSync(r,o=0){let a=this.resolveFilename(`open '${r}'`,r),n=this.entries.get(a);if(typeof n>"u")throw nr.EINVAL(`open '${r}'`);let u=this.getFileSource(n),A=Buffer.alloc(o,0);return u.copy(A),this.writeFileSync(r,A)}async ftruncatePromise(r,o){return this.truncatePromise(this.fdToPath(r,"ftruncate"),o)}ftruncateSync(r,o){return this.truncateSync(this.fdToPath(r,"ftruncateSync"),o)}watch(r,o,a){let n;switch(typeof o){case"function":case"string":case"undefined":n=!0;break;default:({persistent:n=!0}=o);break}if(!n)return{on:()=>{},close:()=>{}};let u=setInterval(()=>{},24*60*60*1e3);return{on:()=>{},close:()=>{clearInterval(u)}}}watchFile(r,o,a){let n=V.resolve(It.root,r);return jd(this,n,o,a)}unwatchFile(r,o){let a=V.resolve(It.root,r);return T0(this,a,o)}}});function Yle(t,e,r=Buffer.alloc(0),o){let a=new Zi(r),n=I=>I===e||I.startsWith(`${e}/`)?I.slice(0,e.length):null,u=async(I,v)=>()=>a,A=(I,v)=>a,p={...t},h=new Tn(p),E=new Op({baseFs:h,getMountPoint:n,factoryPromise:u,factorySync:A,magicByte:21,maxAge:1/0,typeCheck:o?.typeCheck});return xw(Gle.default,new Up(E)),a}var Gle,Wle=Et(()=>{Pt();Gle=Ze(ve("fs"));X4()});var Kle=Et(()=>{Hle();X4();Wle()});var p1={};Vt(p1,{DEFAULT_COMPRESSION_LEVEL:()=>jle,LibzipError:()=>wS,ZipFS:()=>Zi,ZipOpenFS:()=>rA,getArchivePart:()=>V4,getLibzipPromise:()=>hot,getLibzipSync:()=>pot,makeEmptyArchive:()=>CS,mountMemoryDrive:()=>Yle});function pot(){return f1()}async function hot(){return f1()}var Vle,nA=Et(()=>{Y4();Vle=Ze(Mle());_le();Kle();Lle(()=>{let t=(0,Vle.default)();return Ule(t)})});var h1,zle=Et(()=>{Pt();qt();g1();h1=class extends it{constructor(){super(...arguments);this.cwd=ge.String("--cwd",process.cwd(),{description:"The directory to run the command in"});this.commandName=ge.String();this.args=ge.Proxy()}static{this.usage={description:"run a command using yarn's portable shell",details:` + This command will run a command using Yarn's portable shell. + + Make sure to escape glob patterns, redirections, and other features that might be expanded by your own shell. + + Note: To escape something from Yarn's shell, you might have to escape it twice, the first time from your own shell. + + Note: Don't use this command in Yarn scripts, as Yarn's shell is automatically used. + + For a list of features, visit: https://github.com/yarnpkg/berry/blob/master/packages/yarnpkg-shell/README.md. + `,examples:[["Run a simple command","$0 echo Hello"],["Run a command with a glob pattern","$0 echo '*.js'"],["Run a command with a redirection","$0 echo Hello World '>' hello.txt"],["Run a command with an escaped glob pattern (The double escape is needed in Unix shells)",`$0 echo '"*.js"'`],["Run a command with a variable (Double quotes are needed in Unix shells, to prevent them from expanding the variable)",'$0 "GREETING=Hello echo $GREETING World"']]}}async execute(){let r=this.args.length>0?`${this.commandName} ${this.args.join(" ")}`:this.commandName;return await cy(r,[],{cwd:ue.toPortablePath(this.cwd),stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr})}}});var ll,Jle=Et(()=>{ll=class extends Error{constructor(e){super(e),this.name="ShellError"}}});var vS={};Vt(vS,{fastGlobOptions:()=>$le,isBraceExpansion:()=>Z4,isGlobPattern:()=>got,match:()=>dot,micromatchOptions:()=>BS});function got(t){if(!IS.default.scan(t,BS).isGlob)return!1;try{IS.default.parse(t,BS)}catch{return!1}return!0}function dot(t,{cwd:e,baseFs:r}){return(0,Xle.default)(t,{...$le,cwd:ue.fromPortablePath(e),fs:mD(Zle.default,new Up(r))})}function Z4(t){return IS.default.scan(t,BS).isBrace}var Xle,Zle,IS,BS,$le,ece=Et(()=>{Pt();Xle=Ze(Cb()),Zle=Ze(ve("fs")),IS=Ze($o()),BS={strictBrackets:!0},$le={onlyDirectories:!1,onlyFiles:!1}});function $4(){}function eU(){for(let t of vg)t.kill()}function ice(t,e,r,o){return a=>{let n=a[0]instanceof iA.Transform?"pipe":a[0],u=a[1]instanceof iA.Transform?"pipe":a[1],A=a[2]instanceof iA.Transform?"pipe":a[2],p=(0,rce.default)(t,e,{...o,stdio:[n,u,A]});return vg.add(p),vg.size===1&&(process.on("SIGINT",$4),process.on("SIGTERM",eU)),a[0]instanceof iA.Transform&&a[0].pipe(p.stdin),a[1]instanceof iA.Transform&&p.stdout.pipe(a[1],{end:!1}),a[2]instanceof iA.Transform&&p.stderr.pipe(a[2],{end:!1}),{stdin:p.stdin,promise:new Promise(h=>{p.on("error",E=>{switch(vg.delete(p),vg.size===0&&(process.off("SIGINT",$4),process.off("SIGTERM",eU)),E.code){case"ENOENT":a[2].write(`command not found: ${t} +`),h(127);break;case"EACCES":a[2].write(`permission denied: ${t} +`),h(128);break;default:a[2].write(`uncaught error: ${E.message} +`),h(1);break}}),p.on("close",E=>{vg.delete(p),vg.size===0&&(process.off("SIGINT",$4),process.off("SIGTERM",eU)),h(E!==null?E:129)})})}}}function sce(t){return e=>{let r=e[0]==="pipe"?new iA.PassThrough:e[0];return{stdin:r,promise:Promise.resolve().then(()=>t({stdin:r,stdout:e[1],stderr:e[2]}))}}}function DS(t,e){return rU.start(t,e)}function tce(t,e=null){let r=new iA.PassThrough,o=new nce.StringDecoder,a="";return r.on("data",n=>{let u=o.write(n),A;do if(A=u.indexOf(` +`),A!==-1){let p=a+u.substring(0,A);u=u.substring(A+1),a="",t(e!==null?`${e} ${p}`:p)}while(A!==-1);a+=u}),r.on("end",()=>{let n=o.end();n!==""&&t(e!==null?`${e} ${n}`:n)}),r}function oce(t,{prefix:e}){return{stdout:tce(r=>t.stdout.write(`${r} +`),t.stdout.isTTY?e:null),stderr:tce(r=>t.stderr.write(`${r} +`),t.stderr.isTTY?e:null)}}var rce,iA,nce,vg,Jl,tU,rU,nU=Et(()=>{rce=Ze(KR()),iA=ve("stream"),nce=ve("string_decoder"),vg=new Set;Jl=class{constructor(e){this.stream=e}close(){}get(){return this.stream}},tU=class{constructor(){this.stream=null}close(){if(this.stream===null)throw new Error("Assertion failed: No stream attached");this.stream.end()}attach(e){this.stream=e}get(){if(this.stream===null)throw new Error("Assertion failed: No stream attached");return this.stream}},rU=class t{constructor(e,r){this.stdin=null;this.stdout=null;this.stderr=null;this.pipe=null;this.ancestor=e,this.implementation=r}static start(e,{stdin:r,stdout:o,stderr:a}){let n=new t(null,e);return n.stdin=r,n.stdout=o,n.stderr=a,n}pipeTo(e,r=1){let o=new t(this,e),a=new tU;return o.pipe=a,o.stdout=this.stdout,o.stderr=this.stderr,(r&1)===1?this.stdout=a:this.ancestor!==null&&(this.stderr=this.ancestor.stdout),(r&2)===2?this.stderr=a:this.ancestor!==null&&(this.stderr=this.ancestor.stderr),o}async exec(){let e=["ignore","ignore","ignore"];if(this.pipe)e[0]="pipe";else{if(this.stdin===null)throw new Error("Assertion failed: No input stream registered");e[0]=this.stdin.get()}let r;if(this.stdout===null)throw new Error("Assertion failed: No output stream registered");r=this.stdout,e[1]=r.get();let o;if(this.stderr===null)throw new Error("Assertion failed: No error stream registered");o=this.stderr,e[2]=o.get();let a=this.implementation(e);return this.pipe&&this.pipe.attach(a.stdin),await a.promise.then(n=>(r.close(),o.close(),n))}async run(){let e=[];for(let o=this;o;o=o.ancestor)e.push(o.exec());return(await Promise.all(e))[0]}}});var E1={};Vt(E1,{EntryCommand:()=>h1,ShellError:()=>ll,execute:()=>cy,globUtils:()=>vS});function ace(t,e,r){let o=new cl.PassThrough({autoDestroy:!0});switch(t){case 0:(e&1)===1&&r.stdin.pipe(o,{end:!1}),(e&2)===2&&r.stdin instanceof cl.Writable&&o.pipe(r.stdin,{end:!1});break;case 1:(e&1)===1&&r.stdout.pipe(o,{end:!1}),(e&2)===2&&o.pipe(r.stdout,{end:!1});break;case 2:(e&1)===1&&r.stderr.pipe(o,{end:!1}),(e&2)===2&&o.pipe(r.stderr,{end:!1});break;default:throw new ll(`Bad file descriptor: "${t}"`)}return o}function bS(t,e={}){let r={...t,...e};return r.environment={...t.environment,...e.environment},r.variables={...t.variables,...e.variables},r}async function yot(t,e,r){let o=[],a=new cl.PassThrough;return a.on("data",n=>o.push(n)),await SS(t,e,bS(r,{stdout:a})),Buffer.concat(o).toString().replace(/[\r\n]+$/,"")}async function lce(t,e,r){let o=t.map(async n=>{let u=await Dg(n.args,e,r);return{name:n.name,value:u.join(" ")}});return(await Promise.all(o)).reduce((n,u)=>(n[u.name]=u.value,n),{})}function PS(t){return t.match(/[^ \r\n\t]+/g)||[]}async function hce(t,e,r,o,a=o){switch(t.name){case"$":o(String(process.pid));break;case"#":o(String(e.args.length));break;case"@":if(t.quoted)for(let n of e.args)a(n);else for(let n of e.args){let u=PS(n);for(let A=0;A=0&&n"u"&&(t.defaultValue?u=(await Dg(t.defaultValue,e,r)).join(" "):t.alternativeValue&&(u="")),typeof u>"u")throw A?new ll(`Unbound argument #${n}`):new ll(`Unbound variable "${t.name}"`);if(t.quoted)o(u);else{let p=PS(u);for(let E=0;Eo.push(n));let a=Number(o.join(" "));return Number.isNaN(a)?d1({type:"variable",name:o.join(" ")},e,r):d1({type:"number",value:a},e,r)}else return Eot[t.type](await d1(t.left,e,r),await d1(t.right,e,r))}async function Dg(t,e,r){let o=new Map,a=[],n=[],u=E=>{n.push(E)},A=()=>{n.length>0&&a.push(n.join("")),n=[]},p=E=>{u(E),A()},h=(E,I,v)=>{let x=JSON.stringify({type:E,fd:I}),C=o.get(x);typeof C>"u"&&o.set(x,C=[]),C.push(v)};for(let E of t){let I=!1;switch(E.type){case"redirection":{let v=await Dg(E.args,e,r);for(let x of v)h(E.subtype,E.fd,x)}break;case"argument":for(let v of E.segments)switch(v.type){case"text":u(v.text);break;case"glob":u(v.pattern),I=!0;break;case"shell":{let x=await yot(v.shell,e,r);if(v.quoted)u(x);else{let C=PS(x);for(let R=0;R"u")throw new Error("Assertion failed: Expected a glob pattern to have been set");let x=await e.glob.match(v,{cwd:r.cwd,baseFs:e.baseFs});if(x.length===0){let C=Z4(v)?". Note: Brace expansion of arbitrary strings isn't currently supported. For more details, please read this issue: https://github.com/yarnpkg/berry/issues/22":"";throw new ll(`No matches found: "${v}"${C}`)}for(let C of x.sort())p(C)}}if(o.size>0){let E=[];for(let[I,v]of o.entries())E.splice(E.length,0,I,String(v.length),...v);a.splice(0,0,"__ysh_set_redirects",...E,"--")}return a}function m1(t,e,r){e.builtins.has(t[0])||(t=["command",...t]);let o=ue.fromPortablePath(r.cwd),a=r.environment;typeof a.PWD<"u"&&(a={...a,PWD:o});let[n,...u]=t;if(n==="command")return ice(u[0],u.slice(1),e,{cwd:o,env:a});let A=e.builtins.get(n);if(typeof A>"u")throw new Error(`Assertion failed: A builtin should exist for "${n}"`);return sce(async({stdin:p,stdout:h,stderr:E})=>{let{stdin:I,stdout:v,stderr:x}=r;r.stdin=p,r.stdout=h,r.stderr=E;try{return await A(u,e,r)}finally{r.stdin=I,r.stdout=v,r.stderr=x}})}function Cot(t,e,r){return o=>{let a=new cl.PassThrough,n=SS(t,e,bS(r,{stdin:a}));return{stdin:a,promise:n}}}function wot(t,e,r){return o=>{let a=new cl.PassThrough,n=SS(t,e,r);return{stdin:a,promise:n}}}function cce(t,e,r,o){if(e.length===0)return t;{let a;do a=String(Math.random());while(Object.hasOwn(o.procedures,a));return o.procedures={...o.procedures},o.procedures[a]=t,m1([...e,"__ysh_run_procedure",a],r,o)}}async function uce(t,e,r){let o=t,a=null,n=null;for(;o;){let u=o.then?{...r}:r,A;switch(o.type){case"command":{let p=await Dg(o.args,e,r),h=await lce(o.envs,e,r);A=o.envs.length?m1(p,e,bS(u,{environment:h})):m1(p,e,u)}break;case"subshell":{let p=await Dg(o.args,e,r),h=Cot(o.subshell,e,u);A=cce(h,p,e,u)}break;case"group":{let p=await Dg(o.args,e,r),h=wot(o.group,e,u);A=cce(h,p,e,u)}break;case"envs":{let p=await lce(o.envs,e,r);u.environment={...u.environment,...p},A=m1(["true"],e,u)}break}if(typeof A>"u")throw new Error("Assertion failed: An action should have been generated");if(a===null)n=DS(A,{stdin:new Jl(u.stdin),stdout:new Jl(u.stdout),stderr:new Jl(u.stderr)});else{if(n===null)throw new Error("Assertion failed: The execution pipeline should have been setup");switch(a){case"|":n=n.pipeTo(A,1);break;case"|&":n=n.pipeTo(A,3);break}}o.then?(a=o.then.type,o=o.then.chain):o=null}if(n===null)throw new Error("Assertion failed: The execution pipeline should have been setup");return await n.run()}async function Iot(t,e,r,{background:o=!1}={}){function a(n){let u=["#2E86AB","#A23B72","#F18F01","#C73E1D","#CCE2A3"],A=u[n%u.length];return Ace.default.hex(A)}if(o){let n=r.nextBackgroundJobIndex++,u=a(n),A=`[${n}]`,p=u(A),{stdout:h,stderr:E}=oce(r,{prefix:p});return r.backgroundJobs.push(uce(t,e,bS(r,{stdout:h,stderr:E})).catch(I=>E.write(`${I.message} +`)).finally(()=>{r.stdout.isTTY&&r.stdout.write(`Job ${p}, '${u(Jd(t))}' has ended +`)})),0}return await uce(t,e,r)}async function Bot(t,e,r,{background:o=!1}={}){let a,n=A=>{a=A,r.variables["?"]=String(A)},u=async A=>{try{return await Iot(A.chain,e,r,{background:o&&typeof A.then>"u"})}catch(p){if(!(p instanceof ll))throw p;return r.stderr.write(`${p.message} +`),1}};for(n(await u(t));t.then;){if(r.exitCode!==null)return r.exitCode;switch(t.then.type){case"&&":a===0&&n(await u(t.then.line));break;case"||":a!==0&&n(await u(t.then.line));break;default:throw new Error(`Assertion failed: Unsupported command type: "${t.then.type}"`)}t=t.then.line}return a}async function SS(t,e,r){let o=r.backgroundJobs;r.backgroundJobs=[];let a=0;for(let{command:n,type:u}of t){if(a=await Bot(n,e,r,{background:u==="&"}),r.exitCode!==null)return r.exitCode;r.variables["?"]=String(a)}return await Promise.all(r.backgroundJobs),r.backgroundJobs=o,a}function gce(t){switch(t.type){case"variable":return t.name==="@"||t.name==="#"||t.name==="*"||Number.isFinite(parseInt(t.name,10))||"defaultValue"in t&&!!t.defaultValue&&t.defaultValue.some(e=>y1(e))||"alternativeValue"in t&&!!t.alternativeValue&&t.alternativeValue.some(e=>y1(e));case"arithmetic":return iU(t.arithmetic);case"shell":return sU(t.shell);default:return!1}}function y1(t){switch(t.type){case"redirection":return t.args.some(e=>y1(e));case"argument":return t.segments.some(e=>gce(e));default:throw new Error(`Assertion failed: Unsupported argument type: "${t.type}"`)}}function iU(t){switch(t.type){case"variable":return gce(t);case"number":return!1;default:return iU(t.left)||iU(t.right)}}function sU(t){return t.some(({command:e})=>{for(;e;){let r=e.chain;for(;r;){let o;switch(r.type){case"subshell":o=sU(r.subshell);break;case"command":o=r.envs.some(a=>a.args.some(n=>y1(n)))||r.args.some(a=>y1(a));break}if(o)return!0;if(!r.then)break;r=r.then.chain}if(!e.then)break;e=e.then.line}return!1})}async function cy(t,e=[],{baseFs:r=new Tn,builtins:o={},cwd:a=ue.toPortablePath(process.cwd()),env:n=process.env,stdin:u=process.stdin,stdout:A=process.stdout,stderr:p=process.stderr,variables:h={},glob:E=vS}={}){let I={};for(let[C,R]of Object.entries(n))typeof R<"u"&&(I[C]=R);let v=new Map(mot);for(let[C,R]of Object.entries(o))v.set(C,R);u===null&&(u=new cl.PassThrough,u.end());let x=CD(t,E);if(!sU(x)&&x.length>0&&e.length>0){let{command:C}=x[x.length-1];for(;C.then;)C=C.then.line;let R=C.chain;for(;R.then;)R=R.then.chain;R.type==="command"&&(R.args=R.args.concat(e.map(L=>({type:"argument",segments:[{type:"text",text:L}]}))))}return await SS(x,{args:e,baseFs:r,builtins:v,initialStdin:u,initialStdout:A,initialStderr:p,glob:E},{cwd:a,environment:I,exitCode:null,procedures:{},stdin:u,stdout:A,stderr:p,variables:Object.assign({},h,{"?":0}),nextBackgroundJobIndex:1,backgroundJobs:[]})}var Ace,fce,cl,pce,mot,Eot,g1=Et(()=>{Pt();Nl();Ace=Ze(pN()),fce=ve("os"),cl=ve("stream"),pce=ve("timers/promises");zle();Jle();ece();nU();nU();mot=new Map([["cd",async([t=(0,fce.homedir)(),...e],r,o)=>{let a=V.resolve(o.cwd,ue.toPortablePath(t));if(!(await r.baseFs.statPromise(a).catch(u=>{throw u.code==="ENOENT"?new ll(`cd: no such file or directory: ${t}`):u})).isDirectory())throw new ll(`cd: not a directory: ${t}`);return o.cwd=a,0}],["pwd",async(t,e,r)=>(r.stdout.write(`${ue.fromPortablePath(r.cwd)} +`),0)],[":",async(t,e,r)=>0],["true",async(t,e,r)=>0],["false",async(t,e,r)=>1],["exit",async([t,...e],r,o)=>o.exitCode=parseInt(t??o.variables["?"],10)],["echo",async(t,e,r)=>(r.stdout.write(`${t.join(" ")} +`),0)],["sleep",async([t],e,r)=>{if(typeof t>"u")throw new ll("sleep: missing operand");let o=Number(t);if(Number.isNaN(o))throw new ll(`sleep: invalid time interval '${t}'`);return await(0,pce.setTimeout)(1e3*o,0)}],["__ysh_run_procedure",async(t,e,r)=>{let o=r.procedures[t[0]];return await DS(o,{stdin:new Jl(r.stdin),stdout:new Jl(r.stdout),stderr:new Jl(r.stderr)}).run()}],["__ysh_set_redirects",async(t,e,r)=>{let o=r.stdin,a=r.stdout,n=r.stderr,u=[],A=[],p=[],h=0;for(;t[h]!=="--";){let I=t[h++],{type:v,fd:x}=JSON.parse(I),C=z=>{switch(x){case null:case 0:u.push(z);break;default:throw new Error(`Unsupported file descriptor: "${x}"`)}},R=z=>{switch(x){case null:case 1:A.push(z);break;case 2:p.push(z);break;default:throw new Error(`Unsupported file descriptor: "${x}"`)}},L=Number(t[h++]),U=h+L;for(let z=h;ze.baseFs.createReadStream(V.resolve(r.cwd,ue.toPortablePath(t[z]))));break;case"<<<":C(()=>{let te=new cl.PassThrough;return process.nextTick(()=>{te.write(`${t[z]} +`),te.end()}),te});break;case"<&":C(()=>ace(Number(t[z]),1,r));break;case">":case">>":{let te=V.resolve(r.cwd,ue.toPortablePath(t[z]));R(te==="/dev/null"?new cl.Writable({autoDestroy:!0,emitClose:!0,write(ae,le,ce){setImmediate(ce)}}):e.baseFs.createWriteStream(te,v===">>"?{flags:"a"}:void 0))}break;case">&":R(ace(Number(t[z]),2,r));break;default:throw new Error(`Assertion failed: Unsupported redirection type: "${v}"`)}}if(u.length>0){let I=new cl.PassThrough;o=I;let v=x=>{if(x===u.length)I.end();else{let C=u[x]();C.pipe(I,{end:!1}),C.on("end",()=>{v(x+1)})}};v(0)}if(A.length>0){let I=new cl.PassThrough;a=I;for(let v of A)I.pipe(v)}if(p.length>0){let I=new cl.PassThrough;n=I;for(let v of p)I.pipe(v)}let E=await DS(m1(t.slice(h+1),e,r),{stdin:new Jl(o),stdout:new Jl(a),stderr:new Jl(n)}).run();return await Promise.all(A.map(I=>new Promise((v,x)=>{I.on("error",C=>{x(C)}),I.on("close",()=>{v()}),I.end()}))),await Promise.all(p.map(I=>new Promise((v,x)=>{I.on("error",C=>{x(C)}),I.on("close",()=>{v()}),I.end()}))),E}]]);Eot={addition:(t,e)=>t+e,subtraction:(t,e)=>t-e,multiplication:(t,e)=>t*e,division:(t,e)=>Math.trunc(t/e)}});var xS=_((l4t,dce)=>{function vot(t,e){for(var r=-1,o=t==null?0:t.length,a=Array(o);++r{var mce=lg(),Dot=xS(),Pot=Hl(),bot=Ym(),Sot=1/0,yce=mce?mce.prototype:void 0,Ece=yce?yce.toString:void 0;function Cce(t){if(typeof t=="string")return t;if(Pot(t))return Dot(t,Cce)+"";if(bot(t))return Ece?Ece.call(t):"";var e=t+"";return e=="0"&&1/t==-Sot?"-0":e}wce.exports=Cce});var C1=_((u4t,Bce)=>{var xot=Ice();function kot(t){return t==null?"":xot(t)}Bce.exports=kot});var oU=_((A4t,vce)=>{function Qot(t,e,r){var o=-1,a=t.length;e<0&&(e=-e>a?0:a+e),r=r>a?a:r,r<0&&(r+=a),a=e>r?0:r-e>>>0,e>>>=0;for(var n=Array(a);++o{var Fot=oU();function Rot(t,e,r){var o=t.length;return r=r===void 0?o:r,!e&&r>=o?t:Fot(t,e,r)}Dce.exports=Rot});var aU=_((p4t,bce)=>{var Tot="\\ud800-\\udfff",Not="\\u0300-\\u036f",Lot="\\ufe20-\\ufe2f",Mot="\\u20d0-\\u20ff",Oot=Not+Lot+Mot,Uot="\\ufe0e\\ufe0f",_ot="\\u200d",Hot=RegExp("["+_ot+Tot+Oot+Uot+"]");function qot(t){return Hot.test(t)}bce.exports=qot});var xce=_((h4t,Sce)=>{function jot(t){return t.split("")}Sce.exports=jot});var Mce=_((g4t,Lce)=>{var kce="\\ud800-\\udfff",Got="\\u0300-\\u036f",Yot="\\ufe20-\\ufe2f",Wot="\\u20d0-\\u20ff",Kot=Got+Yot+Wot,Vot="\\ufe0e\\ufe0f",zot="["+kce+"]",lU="["+Kot+"]",cU="\\ud83c[\\udffb-\\udfff]",Jot="(?:"+lU+"|"+cU+")",Qce="[^"+kce+"]",Fce="(?:\\ud83c[\\udde6-\\uddff]){2}",Rce="[\\ud800-\\udbff][\\udc00-\\udfff]",Xot="\\u200d",Tce=Jot+"?",Nce="["+Vot+"]?",Zot="(?:"+Xot+"(?:"+[Qce,Fce,Rce].join("|")+")"+Nce+Tce+")*",$ot=Nce+Tce+Zot,eat="(?:"+[Qce+lU+"?",lU,Fce,Rce,zot].join("|")+")",tat=RegExp(cU+"(?="+cU+")|"+eat+$ot,"g");function rat(t){return t.match(tat)||[]}Lce.exports=rat});var Uce=_((d4t,Oce)=>{var nat=xce(),iat=aU(),sat=Mce();function oat(t){return iat(t)?sat(t):nat(t)}Oce.exports=oat});var Hce=_((m4t,_ce)=>{var aat=Pce(),lat=aU(),cat=Uce(),uat=C1();function Aat(t){return function(e){e=uat(e);var r=lat(e)?cat(e):void 0,o=r?r[0]:e.charAt(0),a=r?aat(r,1).join(""):e.slice(1);return o[t]()+a}}_ce.exports=Aat});var jce=_((y4t,qce)=>{var fat=Hce(),pat=fat("toUpperCase");qce.exports=pat});var uU=_((E4t,Gce)=>{var hat=C1(),gat=jce();function dat(t){return gat(hat(t).toLowerCase())}Gce.exports=dat});var Yce=_((C4t,kS)=>{function mat(){var t=0,e=1,r=2,o=3,a=4,n=5,u=6,A=7,p=8,h=9,E=10,I=11,v=12,x=13,C=14,R=15,L=16,U=17,z=0,te=1,ae=2,le=3,ce=4;function Ce(g,me){return 55296<=g.charCodeAt(me)&&g.charCodeAt(me)<=56319&&56320<=g.charCodeAt(me+1)&&g.charCodeAt(me+1)<=57343}function de(g,me){me===void 0&&(me=0);var we=g.charCodeAt(me);if(55296<=we&&we<=56319&&me=1){var Ae=g.charCodeAt(me-1),ne=we;return 55296<=Ae&&Ae<=56319?(Ae-55296)*1024+(ne-56320)+65536:ne}return we}function Be(g,me,we){var Ae=[g].concat(me).concat([we]),ne=Ae[Ae.length-2],Z=we,xe=Ae.lastIndexOf(C);if(xe>1&&Ae.slice(1,xe).every(function(H){return H==o})&&[o,x,U].indexOf(g)==-1)return ae;var Ne=Ae.lastIndexOf(a);if(Ne>0&&Ae.slice(1,Ne).every(function(H){return H==a})&&[v,a].indexOf(ne)==-1)return Ae.filter(function(H){return H==a}).length%2==1?le:ce;if(ne==t&&Z==e)return z;if(ne==r||ne==t||ne==e)return Z==C&&me.every(function(H){return H==o})?ae:te;if(Z==r||Z==t||Z==e)return te;if(ne==u&&(Z==u||Z==A||Z==h||Z==E))return z;if((ne==h||ne==A)&&(Z==A||Z==p))return z;if((ne==E||ne==p)&&Z==p)return z;if(Z==o||Z==R)return z;if(Z==n)return z;if(ne==v)return z;var ht=Ae.indexOf(o)!=-1?Ae.lastIndexOf(o)-1:Ae.length-2;return[x,U].indexOf(Ae[ht])!=-1&&Ae.slice(ht+1,-1).every(function(H){return H==o})&&Z==C||ne==R&&[L,U].indexOf(Z)!=-1?z:me.indexOf(a)!=-1?ae:ne==a&&Z==a?z:te}this.nextBreak=function(g,me){if(me===void 0&&(me=0),me<0)return 0;if(me>=g.length-1)return g.length;for(var we=Ee(de(g,me)),Ae=[],ne=me+1;ne{var yat=/^(.*?)(\x1b\[[^m]+m|\x1b\]8;;.*?(\x1b\\|\u0007))/,QS;function Eat(){if(QS)return QS;if(typeof Intl.Segmenter<"u"){let t=new Intl.Segmenter("en",{granularity:"grapheme"});return QS=e=>Array.from(t.segment(e),({segment:r})=>r)}else{let t=Yce(),e=new t;return QS=r=>e.splitGraphemes(r)}}Wce.exports=(t,e=0,r=t.length)=>{if(e<0||r<0)throw new RangeError("Negative indices aren't supported by this implementation");let o=r-e,a="",n=0,u=0;for(;t.length>0;){let A=t.match(yat)||[t,t,void 0],p=Eat()(A[1]),h=Math.min(e-n,p.length);p=p.slice(h);let E=Math.min(o-u,p.length);a+=p.slice(0,E).join(""),n+=h,u+=E,typeof A[2]<"u"&&(a+=A[2]),t=t.slice(A[0].length)}return a}});var nn,w1=Et(()=>{nn=process.env.YARN_IS_TEST_ENV?"0.0.0":"4.4.1"});function $ce(t,{configuration:e,json:r}){if(!e.get("enableMessageNames"))return"";let a=Ku(t===null?0:t);return!r&&t===null?Ot(e,a,"grey"):a}function AU(t,{configuration:e,json:r}){let o=$ce(t,{configuration:e,json:r});if(!o||t===null||t===0)return o;let a=wr[t],n=`https://yarnpkg.com/advanced/error-codes#${o}---${a}`.toLowerCase();return Tm(e,o,n)}async function uy({configuration:t,stdout:e,forceError:r},o){let a=await Rt.start({configuration:t,stdout:e,includeFooter:!1},async n=>{let u=!1,A=!1;for(let p of o)typeof p.option<"u"&&(p.error||r?(A=!0,n.reportError(50,p.message)):(u=!0,n.reportWarning(50,p.message)),p.callback?.());u&&!A&&n.reportSeparator()});return a.hasErrors()?a.exitCode():null}var Xce,RS,Cat,Vce,zce,ch,Zce,Jce,wat,Iat,TS,Bat,Rt,I1=Et(()=>{Xce=Ze(Kce()),RS=Ze(X0());$D();Wl();w1();jl();Cat="\xB7",Vce=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],zce=80,ch=RS.default.GITHUB_ACTIONS?{start:t=>`::group::${t} +`,end:t=>`::endgroup:: +`}:RS.default.TRAVIS?{start:t=>`travis_fold:start:${t} +`,end:t=>`travis_fold:end:${t} +`}:RS.default.GITLAB?{start:t=>`section_start:${Math.floor(Date.now()/1e3)}:${t.toLowerCase().replace(/\W+/g,"_")}[collapsed=true]\r\x1B[0K${t} +`,end:t=>`section_end:${Math.floor(Date.now()/1e3)}:${t.toLowerCase().replace(/\W+/g,"_")}\r\x1B[0K`}:null,Zce=ch!==null,Jce=new Date,wat=["iTerm.app","Apple_Terminal","WarpTerminal","vscode"].includes(process.env.TERM_PROGRAM)||!!process.env.WT_SESSION,Iat=t=>t,TS=Iat({patrick:{date:[17,3],chars:["\u{1F340}","\u{1F331}"],size:40},simba:{date:[19,7],chars:["\u{1F981}","\u{1F334}"],size:40},jack:{date:[31,10],chars:["\u{1F383}","\u{1F987}"],size:40},hogsfather:{date:[31,12],chars:["\u{1F389}","\u{1F384}"],size:40},default:{chars:["=","-"],size:80}}),Bat=wat&&Object.keys(TS).find(t=>{let e=TS[t];return!(e.date&&(e.date[0]!==Jce.getDate()||e.date[1]!==Jce.getMonth()+1))})||"default";Rt=class extends Zs{constructor({configuration:r,stdout:o,json:a=!1,forceSectionAlignment:n=!1,includeNames:u=!0,includePrefix:A=!0,includeFooter:p=!0,includeLogs:h=!a,includeInfos:E=h,includeWarnings:I=h}){super();this.uncommitted=new Set;this.warningCount=0;this.errorCount=0;this.timerFooter=[];this.startTime=Date.now();this.indent=0;this.level=0;this.progress=new Map;this.progressTime=0;this.progressFrame=0;this.progressTimeout=null;this.progressStyle=null;this.progressMaxScaledSize=null;if(TI(this,{configuration:r}),this.configuration=r,this.forceSectionAlignment=n,this.includeNames=u,this.includePrefix=A,this.includeFooter=p,this.includeInfos=E,this.includeWarnings=I,this.json=a,this.stdout=o,r.get("enableProgressBars")&&!a&&o.isTTY&&o.columns>22){let v=r.get("progressBarStyle")||Bat;if(!Object.hasOwn(TS,v))throw new Error("Assertion failed: Invalid progress bar style");this.progressStyle=TS[v];let x=Math.min(this.getRecommendedLength(),80);this.progressMaxScaledSize=Math.floor(this.progressStyle.size*x/80)}}static async start(r,o){let a=new this(r),n=process.emitWarning;process.emitWarning=(u,A)=>{if(typeof u!="string"){let h=u;u=h.message,A=A??h.name}let p=typeof A<"u"?`${A}: ${u}`:u;a.reportWarning(0,p)},r.includeVersion&&a.reportInfo(0,fg(r.configuration,`Yarn ${nn}`,2));try{await o(a)}catch(u){a.reportExceptionOnce(u)}finally{await a.finalize(),process.emitWarning=n}return a}hasErrors(){return this.errorCount>0}exitCode(){return this.hasErrors()?1:0}getRecommendedLength(){let o=this.progressStyle!==null?this.stdout.columns-1:super.getRecommendedLength();return Math.max(40,o-12-this.indent*2)}startSectionSync({reportHeader:r,reportFooter:o,skipIfEmpty:a},n){let u={committed:!1,action:()=>{r?.()}};a?this.uncommitted.add(u):(u.action(),u.committed=!0);let A=Date.now();try{return n()}catch(p){throw this.reportExceptionOnce(p),p}finally{let p=Date.now();this.uncommitted.delete(u),u.committed&&o?.(p-A)}}async startSectionPromise({reportHeader:r,reportFooter:o,skipIfEmpty:a},n){let u={committed:!1,action:()=>{r?.()}};a?this.uncommitted.add(u):(u.action(),u.committed=!0);let A=Date.now();try{return await n()}catch(p){throw this.reportExceptionOnce(p),p}finally{let p=Date.now();this.uncommitted.delete(u),u.committed&&o?.(p-A)}}startTimerImpl(r,o,a){return{cb:typeof o=="function"?o:a,reportHeader:()=>{this.level+=1,this.reportInfo(null,`\u250C ${r}`),this.indent+=1,ch!==null&&!this.json&&this.includeInfos&&this.stdout.write(ch.start(r))},reportFooter:A=>{if(this.indent-=1,ch!==null&&!this.json&&this.includeInfos){this.stdout.write(ch.end(r));for(let p of this.timerFooter)p()}this.configuration.get("enableTimers")&&A>200?this.reportInfo(null,`\u2514 Completed in ${Ot(this.configuration,A,yt.DURATION)}`):this.reportInfo(null,"\u2514 Completed"),this.level-=1},skipIfEmpty:(typeof o=="function"?{}:o).skipIfEmpty}}startTimerSync(r,o,a){let{cb:n,...u}=this.startTimerImpl(r,o,a);return this.startSectionSync(u,n)}async startTimerPromise(r,o,a){let{cb:n,...u}=this.startTimerImpl(r,o,a);return this.startSectionPromise(u,n)}reportSeparator(){this.indent===0?this.writeLine(""):this.reportInfo(null,"")}reportInfo(r,o){if(!this.includeInfos)return;this.commit();let a=this.formatNameWithHyperlink(r),n=a?`${a}: `:"",u=`${this.formatPrefix(n,"blueBright")}${o}`;this.json?this.reportJson({type:"info",name:r,displayName:this.formatName(r),indent:this.formatIndent(),data:o}):this.writeLine(u)}reportWarning(r,o){if(this.warningCount+=1,!this.includeWarnings)return;this.commit();let a=this.formatNameWithHyperlink(r),n=a?`${a}: `:"";this.json?this.reportJson({type:"warning",name:r,displayName:this.formatName(r),indent:this.formatIndent(),data:o}):this.writeLine(`${this.formatPrefix(n,"yellowBright")}${o}`)}reportError(r,o){this.errorCount+=1,this.timerFooter.push(()=>this.reportErrorImpl(r,o)),this.reportErrorImpl(r,o)}reportErrorImpl(r,o){this.commit();let a=this.formatNameWithHyperlink(r),n=a?`${a}: `:"";this.json?this.reportJson({type:"error",name:r,displayName:this.formatName(r),indent:this.formatIndent(),data:o}):this.writeLine(`${this.formatPrefix(n,"redBright")}${o}`,{truncate:!1})}reportFold(r,o){if(!ch)return;let a=`${ch.start(r)}${o}${ch.end(r)}`;this.timerFooter.push(()=>this.stdout.write(a))}reportProgress(r){if(this.progressStyle===null)return{...Promise.resolve(),stop:()=>{}};if(r.hasProgress&&r.hasTitle)throw new Error("Unimplemented: Progress bars can't have both progress and titles.");let o=!1,a=Promise.resolve().then(async()=>{let u={progress:r.hasProgress?0:void 0,title:r.hasTitle?"":void 0};this.progress.set(r,{definition:u,lastScaledSize:r.hasProgress?-1:void 0,lastTitle:void 0}),this.refreshProgress({delta:-1});for await(let{progress:A,title:p}of r)o||u.progress===A&&u.title===p||(u.progress=A,u.title=p,this.refreshProgress());n()}),n=()=>{o||(o=!0,this.progress.delete(r),this.refreshProgress({delta:1}))};return{...a,stop:n}}reportJson(r){this.json&&this.writeLine(`${JSON.stringify(r)}`)}async finalize(){if(!this.includeFooter)return;let r="";this.errorCount>0?r="Failed with errors":this.warningCount>0?r="Done with warnings":r="Done";let o=Ot(this.configuration,Date.now()-this.startTime,yt.DURATION),a=this.configuration.get("enableTimers")?`${r} in ${o}`:r;this.errorCount>0?this.reportError(0,a):this.warningCount>0?this.reportWarning(0,a):this.reportInfo(0,a)}writeLine(r,{truncate:o}={}){this.clearProgress({clear:!0}),this.stdout.write(`${this.truncate(r,{truncate:o})} +`),this.writeProgress()}writeLines(r,{truncate:o}={}){this.clearProgress({delta:r.length});for(let a of r)this.stdout.write(`${this.truncate(a,{truncate:o})} +`);this.writeProgress()}commit(){let r=this.uncommitted;this.uncommitted=new Set;for(let o of r)o.committed=!0,o.action()}clearProgress({delta:r=0,clear:o=!1}){this.progressStyle!==null&&this.progress.size+r>0&&(this.stdout.write(`\x1B[${this.progress.size+r}A`),(r>0||o)&&this.stdout.write("\x1B[0J"))}writeProgress(){if(this.progressStyle===null||(this.progressTimeout!==null&&clearTimeout(this.progressTimeout),this.progressTimeout=null,this.progress.size===0))return;let r=Date.now();r-this.progressTime>zce&&(this.progressFrame=(this.progressFrame+1)%Vce.length,this.progressTime=r);let o=Vce[this.progressFrame];for(let a of this.progress.values()){let n="";if(typeof a.lastScaledSize<"u"){let h=this.progressStyle.chars[0].repeat(a.lastScaledSize),E=this.progressStyle.chars[1].repeat(this.progressMaxScaledSize-a.lastScaledSize);n=` ${h}${E}`}let u=this.formatName(null),A=u?`${u}: `:"",p=a.definition.title?` ${a.definition.title}`:"";this.stdout.write(`${Ot(this.configuration,"\u27A4","blueBright")} ${A}${o}${n}${p} +`)}this.progressTimeout=setTimeout(()=>{this.refreshProgress({force:!0})},zce)}refreshProgress({delta:r=0,force:o=!1}={}){let a=!1,n=!1;if(o||this.progress.size===0)a=!0;else for(let u of this.progress.values()){let A=typeof u.definition.progress<"u"?Math.trunc(this.progressMaxScaledSize*u.definition.progress):void 0,p=u.lastScaledSize;u.lastScaledSize=A;let h=u.lastTitle;if(u.lastTitle=u.definition.title,A!==p||(n=h!==u.definition.title)){a=!0;break}}a&&(this.clearProgress({delta:r,clear:n}),this.writeProgress())}truncate(r,{truncate:o}={}){return this.progressStyle===null&&(o=!1),typeof o>"u"&&(o=this.configuration.get("preferTruncatedLines")),o&&(r=(0,Xce.default)(r,0,this.stdout.columns-1)),r}formatName(r){return this.includeNames?$ce(r,{configuration:this.configuration,json:this.json}):""}formatPrefix(r,o){return this.includePrefix?`${Ot(this.configuration,"\u27A4",o)} ${r}${this.formatIndent()}`:""}formatNameWithHyperlink(r){return this.includeNames?AU(r,{configuration:this.configuration,json:this.json}):""}formatIndent(){return this.level>0||!this.forceSectionAlignment?"\u2502 ".repeat(this.indent):`${Cat} `}}});var An={};Vt(An,{PackageManager:()=>rue,detectPackageManager:()=>nue,executePackageAccessibleBinary:()=>lue,executePackageScript:()=>NS,executePackageShellcode:()=>fU,executeWorkspaceAccessibleBinary:()=>kat,executeWorkspaceLifecycleScript:()=>oue,executeWorkspaceScript:()=>sue,getPackageAccessibleBinaries:()=>LS,getWorkspaceAccessibleBinaries:()=>aue,hasPackageScript:()=>bat,hasWorkspaceScript:()=>pU,isNodeScript:()=>hU,makeScriptEnv:()=>B1,maybeExecuteWorkspaceLifecycleScript:()=>xat,prepareExternalProject:()=>Pat});async function uh(t,e,r,o=[]){if(process.platform==="win32"){let a=`@goto #_undefined_# 2>NUL || @title %COMSPEC% & @setlocal & @"${r}" ${o.map(n=>`"${n.replace('"','""')}"`).join(" ")} %*`;await oe.writeFilePromise(V.format({dir:t,name:e,ext:".cmd"}),a)}await oe.writeFilePromise(V.join(t,e),`#!/bin/sh +exec "${r}" ${o.map(a=>`'${a.replace(/'/g,`'"'"'`)}'`).join(" ")} "$@" +`,{mode:493})}async function nue(t){let e=await Ut.tryFind(t);if(e?.packageManager){let o=Pb(e.packageManager);if(o?.name){let a=`found ${JSON.stringify({packageManager:e.packageManager})} in manifest`,[n]=o.reference.split(".");switch(o.name){case"yarn":return{packageManagerField:!0,packageManager:Number(n)===1?"Yarn Classic":"Yarn",reason:a};case"npm":return{packageManagerField:!0,packageManager:"npm",reason:a};case"pnpm":return{packageManagerField:!0,packageManager:"pnpm",reason:a}}}}let r;try{r=await oe.readFilePromise(V.join(t,dr.lockfile),"utf8")}catch{}return r!==void 0?r.match(/^__metadata:$/m)?{packageManager:"Yarn",reason:'"__metadata" key found in yarn.lock'}:{packageManager:"Yarn Classic",reason:'"__metadata" key not found in yarn.lock, must be a Yarn classic lockfile'}:oe.existsSync(V.join(t,"package-lock.json"))?{packageManager:"npm",reason:`found npm's "package-lock.json" lockfile`}:oe.existsSync(V.join(t,"pnpm-lock.yaml"))?{packageManager:"pnpm",reason:`found pnpm's "pnpm-lock.yaml" lockfile`}:null}async function B1({project:t,locator:e,binFolder:r,ignoreCorepack:o,lifecycleScript:a,baseEnv:n=t?.configuration.env??process.env}){let u={};for(let[E,I]of Object.entries(n))typeof I<"u"&&(u[E.toLowerCase()!=="path"?E:"PATH"]=I);let A=ue.fromPortablePath(r);u.BERRY_BIN_FOLDER=ue.fromPortablePath(A);let p=process.env.COREPACK_ROOT&&!o?ue.join(process.env.COREPACK_ROOT,"dist/yarn.js"):process.argv[1];if(await Promise.all([uh(r,"node",process.execPath),...nn!==null?[uh(r,"run",process.execPath,[p,"run"]),uh(r,"yarn",process.execPath,[p]),uh(r,"yarnpkg",process.execPath,[p]),uh(r,"node-gyp",process.execPath,[p,"run","--top-level","node-gyp"])]:[]]),t&&(u.INIT_CWD=ue.fromPortablePath(t.configuration.startingCwd),u.PROJECT_CWD=ue.fromPortablePath(t.cwd)),u.PATH=u.PATH?`${A}${ue.delimiter}${u.PATH}`:`${A}`,u.npm_execpath=`${A}${ue.sep}yarn`,u.npm_node_execpath=`${A}${ue.sep}node`,e){if(!t)throw new Error("Assertion failed: Missing project");let E=t.tryWorkspaceByLocator(e),I=E?E.manifest.version??"":t.storedPackages.get(e.locatorHash).version??"";u.npm_package_name=rn(e),u.npm_package_version=I;let v;if(E)v=E.cwd;else{let x=t.storedPackages.get(e.locatorHash);if(!x)throw new Error(`Package for ${qr(t.configuration,e)} not found in the project`);let C=t.configuration.getLinkers(),R={project:t,report:new Rt({stdout:new Ah.PassThrough,configuration:t.configuration})},L=C.find(U=>U.supportsPackage(x,R));if(!L)throw new Error(`The package ${qr(t.configuration,x)} isn't supported by any of the available linkers`);v=await L.findPackageLocation(x,R)}u.npm_package_json=ue.fromPortablePath(V.join(v,dr.manifest))}let h=nn!==null?`yarn/${nn}`:`yarn/${vf("@yarnpkg/core").version}-core`;return u.npm_config_user_agent=`${h} npm/? node/${process.version} ${process.platform} ${process.arch}`,a&&(u.npm_lifecycle_event=a),t&&await t.configuration.triggerHook(E=>E.setupScriptEnvironment,t,u,async(E,I,v)=>await uh(r,E,I,v)),u}async function Pat(t,e,{configuration:r,report:o,workspace:a=null,locator:n=null}){await Dat(async()=>{await oe.mktempPromise(async u=>{let A=V.join(u,"pack.log"),p=null,{stdout:h,stderr:E}=r.getSubprocessStreams(A,{prefix:ue.fromPortablePath(t),report:o}),I=n&&Gc(n)?_I(n):n,v=I?ka(I):"an external project";h.write(`Packing ${v} from sources +`);let x=await nue(t),C;x!==null?(h.write(`Using ${x.packageManager} for bootstrap. Reason: ${x.reason} + +`),C=x.packageManager):(h.write(`No package manager configuration detected; defaulting to Yarn + +`),C="Yarn");let R=C==="Yarn"&&!x?.packageManagerField;await oe.mktempPromise(async L=>{let U=await B1({binFolder:L,ignoreCorepack:R}),te=new Map([["Yarn Classic",async()=>{let le=a!==null?["workspace",a]:[],ce=V.join(t,dr.manifest),Ce=await oe.readFilePromise(ce),de=await Wc(process.execPath,[process.argv[1],"set","version","classic","--only-if-needed","--yarn-path"],{cwd:t,env:U,stdin:p,stdout:h,stderr:E,end:1});if(de.code!==0)return de.code;await oe.writeFilePromise(ce,Ce),await oe.appendFilePromise(V.join(t,".npmignore"),`/.yarn +`),h.write(` +`),delete U.NODE_ENV;let Be=await Wc("yarn",["install"],{cwd:t,env:U,stdin:p,stdout:h,stderr:E,end:1});if(Be.code!==0)return Be.code;h.write(` +`);let Ee=await Wc("yarn",[...le,"pack","--filename",ue.fromPortablePath(e)],{cwd:t,env:U,stdin:p,stdout:h,stderr:E});return Ee.code!==0?Ee.code:0}],["Yarn",async()=>{let le=a!==null?["workspace",a]:[];U.YARN_ENABLE_INLINE_BUILDS="1";let ce=V.join(t,dr.lockfile);await oe.existsPromise(ce)||await oe.writeFilePromise(ce,"");let Ce=await Wc("yarn",[...le,"pack","--install-if-needed","--filename",ue.fromPortablePath(e)],{cwd:t,env:U,stdin:p,stdout:h,stderr:E});return Ce.code!==0?Ce.code:0}],["npm",async()=>{if(a!==null){let me=new Ah.PassThrough,we=km(me);me.pipe(h,{end:!1});let Ae=await Wc("npm",["--version"],{cwd:t,env:U,stdin:p,stdout:me,stderr:E,end:0});if(me.end(),Ae.code!==0)return h.end(),E.end(),Ae.code;let ne=(await we).toString().trim();if(!tA(ne,">=7.x")){let Z=eA(null,"npm"),xe=In(Z,ne),Ne=In(Z,">=7.x");throw new Error(`Workspaces aren't supported by ${jn(r,xe)}; please upgrade to ${jn(r,Ne)} (npm has been detected as the primary package manager for ${Ot(r,t,yt.PATH)})`)}}let le=a!==null?["--workspace",a]:[];delete U.npm_config_user_agent,delete U.npm_config_production,delete U.NPM_CONFIG_PRODUCTION,delete U.NODE_ENV;let ce=await Wc("npm",["install","--legacy-peer-deps"],{cwd:t,env:U,stdin:p,stdout:h,stderr:E,end:1});if(ce.code!==0)return ce.code;let Ce=new Ah.PassThrough,de=km(Ce);Ce.pipe(h);let Be=await Wc("npm",["pack","--silent",...le],{cwd:t,env:U,stdin:p,stdout:Ce,stderr:E});if(Be.code!==0)return Be.code;let Ee=(await de).toString().trim().replace(/^.*\n/s,""),g=V.resolve(t,ue.toPortablePath(Ee));return await oe.renamePromise(g,e),0}]]).get(C);if(typeof te>"u")throw new Error("Assertion failed: Unsupported workflow");let ae=await te();if(!(ae===0||typeof ae>"u"))throw oe.detachTemp(u),new Jt(58,`Packing the package failed (exit code ${ae}, logs can be found here: ${Ot(r,A,yt.PATH)})`)})})})}async function bat(t,e,{project:r}){let o=r.tryWorkspaceByLocator(t);if(o!==null)return pU(o,e);let a=r.storedPackages.get(t.locatorHash);if(!a)throw new Error(`Package for ${qr(r.configuration,t)} not found in the project`);return await rA.openPromise(async n=>{let u=r.configuration,A=r.configuration.getLinkers(),p={project:r,report:new Rt({stdout:new Ah.PassThrough,configuration:u})},h=A.find(x=>x.supportsPackage(a,p));if(!h)throw new Error(`The package ${qr(r.configuration,a)} isn't supported by any of the available linkers`);let E=await h.findPackageLocation(a,p),I=new gn(E,{baseFs:n});return(await Ut.find(It.dot,{baseFs:I})).scripts.has(e)})}async function NS(t,e,r,{cwd:o,project:a,stdin:n,stdout:u,stderr:A}){return await oe.mktempPromise(async p=>{let{manifest:h,env:E,cwd:I}=await iue(t,{project:a,binFolder:p,cwd:o,lifecycleScript:e}),v=h.scripts.get(e);if(typeof v>"u")return 1;let x=async()=>await cy(v,r,{cwd:I,env:E,stdin:n,stdout:u,stderr:A});return await(await a.configuration.reduceHook(R=>R.wrapScriptExecution,x,a,t,e,{script:v,args:r,cwd:I,env:E,stdin:n,stdout:u,stderr:A}))()})}async function fU(t,e,r,{cwd:o,project:a,stdin:n,stdout:u,stderr:A}){return await oe.mktempPromise(async p=>{let{env:h,cwd:E}=await iue(t,{project:a,binFolder:p,cwd:o});return await cy(e,r,{cwd:E,env:h,stdin:n,stdout:u,stderr:A})})}async function Sat(t,{binFolder:e,cwd:r,lifecycleScript:o}){let a=await B1({project:t.project,locator:t.anchoredLocator,binFolder:e,lifecycleScript:o});return await gU(e,await aue(t)),typeof r>"u"&&(r=V.dirname(await oe.realpathPromise(V.join(t.cwd,"package.json")))),{manifest:t.manifest,binFolder:e,env:a,cwd:r}}async function iue(t,{project:e,binFolder:r,cwd:o,lifecycleScript:a}){let n=e.tryWorkspaceByLocator(t);if(n!==null)return Sat(n,{binFolder:r,cwd:o,lifecycleScript:a});let u=e.storedPackages.get(t.locatorHash);if(!u)throw new Error(`Package for ${qr(e.configuration,t)} not found in the project`);return await rA.openPromise(async A=>{let p=e.configuration,h=e.configuration.getLinkers(),E={project:e,report:new Rt({stdout:new Ah.PassThrough,configuration:p})},I=h.find(L=>L.supportsPackage(u,E));if(!I)throw new Error(`The package ${qr(e.configuration,u)} isn't supported by any of the available linkers`);let v=await B1({project:e,locator:t,binFolder:r,lifecycleScript:a});await gU(r,await LS(t,{project:e}));let x=await I.findPackageLocation(u,E),C=new gn(x,{baseFs:A}),R=await Ut.find(It.dot,{baseFs:C});return typeof o>"u"&&(o=x),{manifest:R,binFolder:r,env:v,cwd:o}})}async function sue(t,e,r,{cwd:o,stdin:a,stdout:n,stderr:u}){return await NS(t.anchoredLocator,e,r,{cwd:o,project:t.project,stdin:a,stdout:n,stderr:u})}function pU(t,e){return t.manifest.scripts.has(e)}async function oue(t,e,{cwd:r,report:o}){let{configuration:a}=t.project,n=null;await oe.mktempPromise(async u=>{let A=V.join(u,`${e}.log`),p=`# This file contains the result of Yarn calling the "${e}" lifecycle script inside a workspace ("${ue.fromPortablePath(t.cwd)}") +`,{stdout:h,stderr:E}=a.getSubprocessStreams(A,{report:o,prefix:qr(a,t.anchoredLocator),header:p});o.reportInfo(36,`Calling the "${e}" lifecycle script`);let I=await sue(t,e,[],{cwd:r,stdin:n,stdout:h,stderr:E});if(h.end(),E.end(),I!==0)throw oe.detachTemp(u),new Jt(36,`${(0,eue.default)(e)} script failed (exit code ${Ot(a,I,yt.NUMBER)}, logs can be found here: ${Ot(a,A,yt.PATH)}); run ${Ot(a,`yarn ${e}`,yt.CODE)} to investigate`)})}async function xat(t,e,r){pU(t,e)&&await oue(t,e,r)}function hU(t){let e=V.extname(t);if(e.match(/\.[cm]?[jt]sx?$/))return!0;if(e===".exe"||e===".bin")return!1;let r=Buffer.alloc(4),o;try{o=oe.openSync(t,"r")}catch{return!0}try{oe.readSync(o,r,0,r.length,0)}finally{oe.closeSync(o)}let a=r.readUint32BE();return!(a===3405691582||a===3489328638||a===2135247942||(a&4294901760)===1297743872)}async function LS(t,{project:e}){let r=e.configuration,o=new Map,a=e.storedPackages.get(t.locatorHash);if(!a)throw new Error(`Package for ${qr(r,t)} not found in the project`);let n=new Ah.Writable,u=r.getLinkers(),A={project:e,report:new Rt({configuration:r,stdout:n})},p=new Set([t.locatorHash]);for(let E of a.dependencies.values()){let I=e.storedResolutions.get(E.descriptorHash);if(!I)throw new Error(`Assertion failed: The resolution (${jn(r,E)}) should have been registered`);p.add(I)}let h=await Promise.all(Array.from(p,async E=>{let I=e.storedPackages.get(E);if(!I)throw new Error(`Assertion failed: The package (${E}) should have been registered`);if(I.bin.size===0)return ol.skip;let v=u.find(C=>C.supportsPackage(I,A));if(!v)return ol.skip;let x=null;try{x=await v.findPackageLocation(I,A)}catch(C){if(C.code==="LOCATOR_NOT_INSTALLED")return ol.skip;throw C}return{dependency:I,packageLocation:x}}));for(let E of h){if(E===ol.skip)continue;let{dependency:I,packageLocation:v}=E;for(let[x,C]of I.bin){let R=V.resolve(v,C);o.set(x,[I,ue.fromPortablePath(R),hU(R)])}}return o}async function aue(t){return await LS(t.anchoredLocator,{project:t.project})}async function gU(t,e){await Promise.all(Array.from(e,([r,[,o,a]])=>a?uh(t,r,process.execPath,[o]):uh(t,r,o,[])))}async function lue(t,e,r,{cwd:o,project:a,stdin:n,stdout:u,stderr:A,nodeArgs:p=[],packageAccessibleBinaries:h}){h??=await LS(t,{project:a});let E=h.get(e);if(!E)throw new Error(`Binary not found (${e}) for ${qr(a.configuration,t)}`);return await oe.mktempPromise(async I=>{let[,v]=E,x=await B1({project:a,locator:t,binFolder:I});await gU(x.BERRY_BIN_FOLDER,h);let C=hU(ue.toPortablePath(v))?Wc(process.execPath,[...p,v,...r],{cwd:o,env:x,stdin:n,stdout:u,stderr:A}):Wc(v,r,{cwd:o,env:x,stdin:n,stdout:u,stderr:A}),R;try{R=await C}finally{await oe.removePromise(x.BERRY_BIN_FOLDER)}return R.code})}async function kat(t,e,r,{cwd:o,stdin:a,stdout:n,stderr:u,packageAccessibleBinaries:A}){return await lue(t.anchoredLocator,e,r,{project:t.project,cwd:o,stdin:a,stdout:n,stderr:u,packageAccessibleBinaries:A})}var eue,tue,Ah,rue,vat,Dat,dU=Et(()=>{Pt();Pt();nA();g1();eue=Ze(uU()),tue=Ze(eg()),Ah=ve("stream");Gm();Wl();I1();w1();pS();jl();ql();Sf();So();rue=(a=>(a.Yarn1="Yarn Classic",a.Yarn2="Yarn",a.Npm="npm",a.Pnpm="pnpm",a))(rue||{});vat=2,Dat=(0,tue.default)(vat)});var Ay=_((q4t,uue)=>{"use strict";var cue=new Map([["C","cwd"],["f","file"],["z","gzip"],["P","preservePaths"],["U","unlink"],["strip-components","strip"],["stripComponents","strip"],["keep-newer","newer"],["keepNewer","newer"],["keep-newer-files","newer"],["keepNewerFiles","newer"],["k","keep"],["keep-existing","keep"],["keepExisting","keep"],["m","noMtime"],["no-mtime","noMtime"],["p","preserveOwner"],["L","follow"],["h","follow"]]);uue.exports=t=>t?Object.keys(t).map(e=>[cue.has(e)?cue.get(e):e,t[e]]).reduce((e,r)=>(e[r[0]]=r[1],e),Object.create(null)):{}});var py=_((j4t,Eue)=>{"use strict";var Aue=typeof process=="object"&&process?process:{stdout:null,stderr:null},Qat=ve("events"),fue=ve("stream"),pue=ve("string_decoder").StringDecoder,Nf=Symbol("EOF"),Lf=Symbol("maybeEmitEnd"),fh=Symbol("emittedEnd"),MS=Symbol("emittingEnd"),v1=Symbol("emittedError"),OS=Symbol("closed"),hue=Symbol("read"),US=Symbol("flush"),gue=Symbol("flushChunk"),Fa=Symbol("encoding"),Mf=Symbol("decoder"),_S=Symbol("flowing"),D1=Symbol("paused"),fy=Symbol("resume"),Ts=Symbol("bufferLength"),mU=Symbol("bufferPush"),yU=Symbol("bufferShift"),Fo=Symbol("objectMode"),Ro=Symbol("destroyed"),EU=Symbol("emitData"),due=Symbol("emitEnd"),CU=Symbol("emitEnd2"),Of=Symbol("async"),P1=t=>Promise.resolve().then(t),mue=global._MP_NO_ITERATOR_SYMBOLS_!=="1",Fat=mue&&Symbol.asyncIterator||Symbol("asyncIterator not implemented"),Rat=mue&&Symbol.iterator||Symbol("iterator not implemented"),Tat=t=>t==="end"||t==="finish"||t==="prefinish",Nat=t=>t instanceof ArrayBuffer||typeof t=="object"&&t.constructor&&t.constructor.name==="ArrayBuffer"&&t.byteLength>=0,Lat=t=>!Buffer.isBuffer(t)&&ArrayBuffer.isView(t),HS=class{constructor(e,r,o){this.src=e,this.dest=r,this.opts=o,this.ondrain=()=>e[fy](),r.on("drain",this.ondrain)}unpipe(){this.dest.removeListener("drain",this.ondrain)}proxyErrors(){}end(){this.unpipe(),this.opts.end&&this.dest.end()}},wU=class extends HS{unpipe(){this.src.removeListener("error",this.proxyErrors),super.unpipe()}constructor(e,r,o){super(e,r,o),this.proxyErrors=a=>r.emit("error",a),e.on("error",this.proxyErrors)}};Eue.exports=class yue extends fue{constructor(e){super(),this[_S]=!1,this[D1]=!1,this.pipes=[],this.buffer=[],this[Fo]=e&&e.objectMode||!1,this[Fo]?this[Fa]=null:this[Fa]=e&&e.encoding||null,this[Fa]==="buffer"&&(this[Fa]=null),this[Of]=e&&!!e.async||!1,this[Mf]=this[Fa]?new pue(this[Fa]):null,this[Nf]=!1,this[fh]=!1,this[MS]=!1,this[OS]=!1,this[v1]=null,this.writable=!0,this.readable=!0,this[Ts]=0,this[Ro]=!1}get bufferLength(){return this[Ts]}get encoding(){return this[Fa]}set encoding(e){if(this[Fo])throw new Error("cannot set encoding in objectMode");if(this[Fa]&&e!==this[Fa]&&(this[Mf]&&this[Mf].lastNeed||this[Ts]))throw new Error("cannot change encoding");this[Fa]!==e&&(this[Mf]=e?new pue(e):null,this.buffer.length&&(this.buffer=this.buffer.map(r=>this[Mf].write(r)))),this[Fa]=e}setEncoding(e){this.encoding=e}get objectMode(){return this[Fo]}set objectMode(e){this[Fo]=this[Fo]||!!e}get async(){return this[Of]}set async(e){this[Of]=this[Of]||!!e}write(e,r,o){if(this[Nf])throw new Error("write after end");if(this[Ro])return this.emit("error",Object.assign(new Error("Cannot call write after a stream was destroyed"),{code:"ERR_STREAM_DESTROYED"})),!0;typeof r=="function"&&(o=r,r="utf8"),r||(r="utf8");let a=this[Of]?P1:n=>n();return!this[Fo]&&!Buffer.isBuffer(e)&&(Lat(e)?e=Buffer.from(e.buffer,e.byteOffset,e.byteLength):Nat(e)?e=Buffer.from(e):typeof e!="string"&&(this.objectMode=!0)),this[Fo]?(this.flowing&&this[Ts]!==0&&this[US](!0),this.flowing?this.emit("data",e):this[mU](e),this[Ts]!==0&&this.emit("readable"),o&&a(o),this.flowing):e.length?(typeof e=="string"&&!(r===this[Fa]&&!this[Mf].lastNeed)&&(e=Buffer.from(e,r)),Buffer.isBuffer(e)&&this[Fa]&&(e=this[Mf].write(e)),this.flowing&&this[Ts]!==0&&this[US](!0),this.flowing?this.emit("data",e):this[mU](e),this[Ts]!==0&&this.emit("readable"),o&&a(o),this.flowing):(this[Ts]!==0&&this.emit("readable"),o&&a(o),this.flowing)}read(e){if(this[Ro])return null;if(this[Ts]===0||e===0||e>this[Ts])return this[Lf](),null;this[Fo]&&(e=null),this.buffer.length>1&&!this[Fo]&&(this.encoding?this.buffer=[this.buffer.join("")]:this.buffer=[Buffer.concat(this.buffer,this[Ts])]);let r=this[hue](e||null,this.buffer[0]);return this[Lf](),r}[hue](e,r){return e===r.length||e===null?this[yU]():(this.buffer[0]=r.slice(e),r=r.slice(0,e),this[Ts]-=e),this.emit("data",r),!this.buffer.length&&!this[Nf]&&this.emit("drain"),r}end(e,r,o){return typeof e=="function"&&(o=e,e=null),typeof r=="function"&&(o=r,r="utf8"),e&&this.write(e,r),o&&this.once("end",o),this[Nf]=!0,this.writable=!1,(this.flowing||!this[D1])&&this[Lf](),this}[fy](){this[Ro]||(this[D1]=!1,this[_S]=!0,this.emit("resume"),this.buffer.length?this[US]():this[Nf]?this[Lf]():this.emit("drain"))}resume(){return this[fy]()}pause(){this[_S]=!1,this[D1]=!0}get destroyed(){return this[Ro]}get flowing(){return this[_S]}get paused(){return this[D1]}[mU](e){this[Fo]?this[Ts]+=1:this[Ts]+=e.length,this.buffer.push(e)}[yU](){return this.buffer.length&&(this[Fo]?this[Ts]-=1:this[Ts]-=this.buffer[0].length),this.buffer.shift()}[US](e){do;while(this[gue](this[yU]()));!e&&!this.buffer.length&&!this[Nf]&&this.emit("drain")}[gue](e){return e?(this.emit("data",e),this.flowing):!1}pipe(e,r){if(this[Ro])return;let o=this[fh];return r=r||{},e===Aue.stdout||e===Aue.stderr?r.end=!1:r.end=r.end!==!1,r.proxyErrors=!!r.proxyErrors,o?r.end&&e.end():(this.pipes.push(r.proxyErrors?new wU(this,e,r):new HS(this,e,r)),this[Of]?P1(()=>this[fy]()):this[fy]()),e}unpipe(e){let r=this.pipes.find(o=>o.dest===e);r&&(this.pipes.splice(this.pipes.indexOf(r),1),r.unpipe())}addListener(e,r){return this.on(e,r)}on(e,r){let o=super.on(e,r);return e==="data"&&!this.pipes.length&&!this.flowing?this[fy]():e==="readable"&&this[Ts]!==0?super.emit("readable"):Tat(e)&&this[fh]?(super.emit(e),this.removeAllListeners(e)):e==="error"&&this[v1]&&(this[Of]?P1(()=>r.call(this,this[v1])):r.call(this,this[v1])),o}get emittedEnd(){return this[fh]}[Lf](){!this[MS]&&!this[fh]&&!this[Ro]&&this.buffer.length===0&&this[Nf]&&(this[MS]=!0,this.emit("end"),this.emit("prefinish"),this.emit("finish"),this[OS]&&this.emit("close"),this[MS]=!1)}emit(e,r,...o){if(e!=="error"&&e!=="close"&&e!==Ro&&this[Ro])return;if(e==="data")return r?this[Of]?P1(()=>this[EU](r)):this[EU](r):!1;if(e==="end")return this[due]();if(e==="close"){if(this[OS]=!0,!this[fh]&&!this[Ro])return;let n=super.emit("close");return this.removeAllListeners("close"),n}else if(e==="error"){this[v1]=r;let n=super.emit("error",r);return this[Lf](),n}else if(e==="resume"){let n=super.emit("resume");return this[Lf](),n}else if(e==="finish"||e==="prefinish"){let n=super.emit(e);return this.removeAllListeners(e),n}let a=super.emit(e,r,...o);return this[Lf](),a}[EU](e){for(let o of this.pipes)o.dest.write(e)===!1&&this.pause();let r=super.emit("data",e);return this[Lf](),r}[due](){this[fh]||(this[fh]=!0,this.readable=!1,this[Of]?P1(()=>this[CU]()):this[CU]())}[CU](){if(this[Mf]){let r=this[Mf].end();if(r){for(let o of this.pipes)o.dest.write(r);super.emit("data",r)}}for(let r of this.pipes)r.end();let e=super.emit("end");return this.removeAllListeners("end"),e}collect(){let e=[];this[Fo]||(e.dataLength=0);let r=this.promise();return this.on("data",o=>{e.push(o),this[Fo]||(e.dataLength+=o.length)}),r.then(()=>e)}concat(){return this[Fo]?Promise.reject(new Error("cannot concat in objectMode")):this.collect().then(e=>this[Fo]?Promise.reject(new Error("cannot concat in objectMode")):this[Fa]?e.join(""):Buffer.concat(e,e.dataLength))}promise(){return new Promise((e,r)=>{this.on(Ro,()=>r(new Error("stream destroyed"))),this.on("error",o=>r(o)),this.on("end",()=>e())})}[Fat](){return{next:()=>{let r=this.read();if(r!==null)return Promise.resolve({done:!1,value:r});if(this[Nf])return Promise.resolve({done:!0});let o=null,a=null,n=h=>{this.removeListener("data",u),this.removeListener("end",A),a(h)},u=h=>{this.removeListener("error",n),this.removeListener("end",A),this.pause(),o({value:h,done:!!this[Nf]})},A=()=>{this.removeListener("error",n),this.removeListener("data",u),o({done:!0})},p=()=>n(new Error("stream destroyed"));return new Promise((h,E)=>{a=E,o=h,this.once(Ro,p),this.once("error",n),this.once("end",A),this.once("data",u)})}}}[Rat](){return{next:()=>{let r=this.read();return{value:r,done:r===null}}}}destroy(e){return this[Ro]?(e?this.emit("error",e):this.emit(Ro),this):(this[Ro]=!0,this.buffer.length=0,this[Ts]=0,typeof this.close=="function"&&!this[OS]&&this.close(),e?this.emit("error",e):this.emit(Ro),this)}static isStream(e){return!!e&&(e instanceof yue||e instanceof fue||e instanceof Qat&&(typeof e.pipe=="function"||typeof e.write=="function"&&typeof e.end=="function"))}}});var wue=_((G4t,Cue)=>{var Mat=ve("zlib").constants||{ZLIB_VERNUM:4736};Cue.exports=Object.freeze(Object.assign(Object.create(null),{Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_MEM_ERROR:-4,Z_BUF_ERROR:-5,Z_VERSION_ERROR:-6,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,DEFLATE:1,INFLATE:2,GZIP:3,GUNZIP:4,DEFLATERAW:5,INFLATERAW:6,UNZIP:7,BROTLI_DECODE:8,BROTLI_ENCODE:9,Z_MIN_WINDOWBITS:8,Z_MAX_WINDOWBITS:15,Z_DEFAULT_WINDOWBITS:15,Z_MIN_CHUNK:64,Z_MAX_CHUNK:1/0,Z_DEFAULT_CHUNK:16384,Z_MIN_MEMLEVEL:1,Z_MAX_MEMLEVEL:9,Z_DEFAULT_MEMLEVEL:8,Z_MIN_LEVEL:-1,Z_MAX_LEVEL:9,Z_DEFAULT_LEVEL:-1,BROTLI_OPERATION_PROCESS:0,BROTLI_OPERATION_FLUSH:1,BROTLI_OPERATION_FINISH:2,BROTLI_OPERATION_EMIT_METADATA:3,BROTLI_MODE_GENERIC:0,BROTLI_MODE_TEXT:1,BROTLI_MODE_FONT:2,BROTLI_DEFAULT_MODE:0,BROTLI_MIN_QUALITY:0,BROTLI_MAX_QUALITY:11,BROTLI_DEFAULT_QUALITY:11,BROTLI_MIN_WINDOW_BITS:10,BROTLI_MAX_WINDOW_BITS:24,BROTLI_LARGE_MAX_WINDOW_BITS:30,BROTLI_DEFAULT_WINDOW:22,BROTLI_MIN_INPUT_BLOCK_BITS:16,BROTLI_MAX_INPUT_BLOCK_BITS:24,BROTLI_PARAM_MODE:0,BROTLI_PARAM_QUALITY:1,BROTLI_PARAM_LGWIN:2,BROTLI_PARAM_LGBLOCK:3,BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING:4,BROTLI_PARAM_SIZE_HINT:5,BROTLI_PARAM_LARGE_WINDOW:6,BROTLI_PARAM_NPOSTFIX:7,BROTLI_PARAM_NDIRECT:8,BROTLI_DECODER_RESULT_ERROR:0,BROTLI_DECODER_RESULT_SUCCESS:1,BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT:2,BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT:3,BROTLI_DECODER_PARAM_DISABLE_RING_BUFFER_REALLOCATION:0,BROTLI_DECODER_PARAM_LARGE_WINDOW:1,BROTLI_DECODER_NO_ERROR:0,BROTLI_DECODER_SUCCESS:1,BROTLI_DECODER_NEEDS_MORE_INPUT:2,BROTLI_DECODER_NEEDS_MORE_OUTPUT:3,BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_NIBBLE:-1,BROTLI_DECODER_ERROR_FORMAT_RESERVED:-2,BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_META_NIBBLE:-3,BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_ALPHABET:-4,BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_SAME:-5,BROTLI_DECODER_ERROR_FORMAT_CL_SPACE:-6,BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE:-7,BROTLI_DECODER_ERROR_FORMAT_CONTEXT_MAP_REPEAT:-8,BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_1:-9,BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_2:-10,BROTLI_DECODER_ERROR_FORMAT_TRANSFORM:-11,BROTLI_DECODER_ERROR_FORMAT_DICTIONARY:-12,BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS:-13,BROTLI_DECODER_ERROR_FORMAT_PADDING_1:-14,BROTLI_DECODER_ERROR_FORMAT_PADDING_2:-15,BROTLI_DECODER_ERROR_FORMAT_DISTANCE:-16,BROTLI_DECODER_ERROR_DICTIONARY_NOT_SET:-19,BROTLI_DECODER_ERROR_INVALID_ARGUMENTS:-20,BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MODES:-21,BROTLI_DECODER_ERROR_ALLOC_TREE_GROUPS:-22,BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MAP:-25,BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_1:-26,BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_2:-27,BROTLI_DECODER_ERROR_ALLOC_BLOCK_TYPE_TREES:-30,BROTLI_DECODER_ERROR_UNREACHABLE:-31},Mat))});var MU=_(ul=>{"use strict";var PU=ve("assert"),ph=ve("buffer").Buffer,vue=ve("zlib"),Pg=ul.constants=wue(),Oat=py(),Iue=ph.concat,bg=Symbol("_superWrite"),gy=class extends Error{constructor(e){super("zlib: "+e.message),this.code=e.code,this.errno=e.errno,this.code||(this.code="ZLIB_ERROR"),this.message="zlib: "+e.message,Error.captureStackTrace(this,this.constructor)}get name(){return"ZlibError"}},Uat=Symbol("opts"),b1=Symbol("flushFlag"),Bue=Symbol("finishFlushFlag"),LU=Symbol("fullFlushFlag"),ti=Symbol("handle"),qS=Symbol("onError"),hy=Symbol("sawError"),IU=Symbol("level"),BU=Symbol("strategy"),vU=Symbol("ended"),Y4t=Symbol("_defaultFullFlush"),jS=class extends Oat{constructor(e,r){if(!e||typeof e!="object")throw new TypeError("invalid options for ZlibBase constructor");super(e),this[hy]=!1,this[vU]=!1,this[Uat]=e,this[b1]=e.flush,this[Bue]=e.finishFlush;try{this[ti]=new vue[r](e)}catch(o){throw new gy(o)}this[qS]=o=>{this[hy]||(this[hy]=!0,this.close(),this.emit("error",o))},this[ti].on("error",o=>this[qS](new gy(o))),this.once("end",()=>this.close)}close(){this[ti]&&(this[ti].close(),this[ti]=null,this.emit("close"))}reset(){if(!this[hy])return PU(this[ti],"zlib binding closed"),this[ti].reset()}flush(e){this.ended||(typeof e!="number"&&(e=this[LU]),this.write(Object.assign(ph.alloc(0),{[b1]:e})))}end(e,r,o){return e&&this.write(e,r),this.flush(this[Bue]),this[vU]=!0,super.end(null,null,o)}get ended(){return this[vU]}write(e,r,o){if(typeof r=="function"&&(o=r,r="utf8"),typeof e=="string"&&(e=ph.from(e,r)),this[hy])return;PU(this[ti],"zlib binding closed");let a=this[ti]._handle,n=a.close;a.close=()=>{};let u=this[ti].close;this[ti].close=()=>{},ph.concat=h=>h;let A;try{let h=typeof e[b1]=="number"?e[b1]:this[b1];A=this[ti]._processChunk(e,h),ph.concat=Iue}catch(h){ph.concat=Iue,this[qS](new gy(h))}finally{this[ti]&&(this[ti]._handle=a,a.close=n,this[ti].close=u,this[ti].removeAllListeners("error"))}this[ti]&&this[ti].on("error",h=>this[qS](new gy(h)));let p;if(A)if(Array.isArray(A)&&A.length>0){p=this[bg](ph.from(A[0]));for(let h=1;h{this.flush(a),n()};try{this[ti].params(e,r)}finally{this[ti].flush=o}this[ti]&&(this[IU]=e,this[BU]=r)}}}},bU=class extends Uf{constructor(e){super(e,"Deflate")}},SU=class extends Uf{constructor(e){super(e,"Inflate")}},DU=Symbol("_portable"),xU=class extends Uf{constructor(e){super(e,"Gzip"),this[DU]=e&&!!e.portable}[bg](e){return this[DU]?(this[DU]=!1,e[9]=255,super[bg](e)):super[bg](e)}},kU=class extends Uf{constructor(e){super(e,"Gunzip")}},QU=class extends Uf{constructor(e){super(e,"DeflateRaw")}},FU=class extends Uf{constructor(e){super(e,"InflateRaw")}},RU=class extends Uf{constructor(e){super(e,"Unzip")}},GS=class extends jS{constructor(e,r){e=e||{},e.flush=e.flush||Pg.BROTLI_OPERATION_PROCESS,e.finishFlush=e.finishFlush||Pg.BROTLI_OPERATION_FINISH,super(e,r),this[LU]=Pg.BROTLI_OPERATION_FLUSH}},TU=class extends GS{constructor(e){super(e,"BrotliCompress")}},NU=class extends GS{constructor(e){super(e,"BrotliDecompress")}};ul.Deflate=bU;ul.Inflate=SU;ul.Gzip=xU;ul.Gunzip=kU;ul.DeflateRaw=QU;ul.InflateRaw=FU;ul.Unzip=RU;typeof vue.BrotliCompress=="function"?(ul.BrotliCompress=TU,ul.BrotliDecompress=NU):ul.BrotliCompress=ul.BrotliDecompress=class{constructor(){throw new Error("Brotli is not supported in this version of Node.js")}}});var dy=_((V4t,Due)=>{var _at=process.env.TESTING_TAR_FAKE_PLATFORM||process.platform;Due.exports=_at!=="win32"?t=>t:t=>t&&t.replace(/\\/g,"/")});var YS=_((J4t,Pue)=>{"use strict";var Hat=py(),OU=dy(),UU=Symbol("slurp");Pue.exports=class extends Hat{constructor(e,r,o){switch(super(),this.pause(),this.extended=r,this.globalExtended=o,this.header=e,this.startBlockSize=512*Math.ceil(e.size/512),this.blockRemain=this.startBlockSize,this.remain=e.size,this.type=e.type,this.meta=!1,this.ignore=!1,this.type){case"File":case"OldFile":case"Link":case"SymbolicLink":case"CharacterDevice":case"BlockDevice":case"Directory":case"FIFO":case"ContiguousFile":case"GNUDumpDir":break;case"NextFileHasLongLinkpath":case"NextFileHasLongPath":case"OldGnuLongPath":case"GlobalExtendedHeader":case"ExtendedHeader":case"OldExtendedHeader":this.meta=!0;break;default:this.ignore=!0}this.path=OU(e.path),this.mode=e.mode,this.mode&&(this.mode=this.mode&4095),this.uid=e.uid,this.gid=e.gid,this.uname=e.uname,this.gname=e.gname,this.size=e.size,this.mtime=e.mtime,this.atime=e.atime,this.ctime=e.ctime,this.linkpath=OU(e.linkpath),this.uname=e.uname,this.gname=e.gname,r&&this[UU](r),o&&this[UU](o,!0)}write(e){let r=e.length;if(r>this.blockRemain)throw new Error("writing more to entry than is appropriate");let o=this.remain,a=this.blockRemain;return this.remain=Math.max(0,o-r),this.blockRemain=Math.max(0,a-r),this.ignore?!0:o>=r?super.write(e):super.write(e.slice(0,o))}[UU](e,r){for(let o in e)e[o]!==null&&e[o]!==void 0&&!(r&&o==="path")&&(this[o]=o==="path"||o==="linkpath"?OU(e[o]):e[o])}}});var _U=_(WS=>{"use strict";WS.name=new Map([["0","File"],["","OldFile"],["1","Link"],["2","SymbolicLink"],["3","CharacterDevice"],["4","BlockDevice"],["5","Directory"],["6","FIFO"],["7","ContiguousFile"],["g","GlobalExtendedHeader"],["x","ExtendedHeader"],["A","SolarisACL"],["D","GNUDumpDir"],["I","Inode"],["K","NextFileHasLongLinkpath"],["L","NextFileHasLongPath"],["M","ContinuationFile"],["N","OldGnuLongPath"],["S","SparseFile"],["V","TapeVolumeHeader"],["X","OldExtendedHeader"]]);WS.code=new Map(Array.from(WS.name).map(t=>[t[1],t[0]]))});var kue=_((Z4t,xue)=>{"use strict";var qat=(t,e)=>{if(Number.isSafeInteger(t))t<0?Gat(t,e):jat(t,e);else throw Error("cannot encode number outside of javascript safe integer range");return e},jat=(t,e)=>{e[0]=128;for(var r=e.length;r>1;r--)e[r-1]=t&255,t=Math.floor(t/256)},Gat=(t,e)=>{e[0]=255;var r=!1;t=t*-1;for(var o=e.length;o>1;o--){var a=t&255;t=Math.floor(t/256),r?e[o-1]=bue(a):a===0?e[o-1]=0:(r=!0,e[o-1]=Sue(a))}},Yat=t=>{let e=t[0],r=e===128?Kat(t.slice(1,t.length)):e===255?Wat(t):null;if(r===null)throw Error("invalid base256 encoding");if(!Number.isSafeInteger(r))throw Error("parsed number outside of javascript safe integer range");return r},Wat=t=>{for(var e=t.length,r=0,o=!1,a=e-1;a>-1;a--){var n=t[a],u;o?u=bue(n):n===0?u=n:(o=!0,u=Sue(n)),u!==0&&(r-=u*Math.pow(256,e-a-1))}return r},Kat=t=>{for(var e=t.length,r=0,o=e-1;o>-1;o--){var a=t[o];a!==0&&(r+=a*Math.pow(256,e-o-1))}return r},bue=t=>(255^t)&255,Sue=t=>(255^t)+1&255;xue.exports={encode:qat,parse:Yat}});var yy=_(($4t,Fue)=>{"use strict";var HU=_U(),my=ve("path").posix,Que=kue(),qU=Symbol("slurp"),Al=Symbol("type"),YU=class{constructor(e,r,o,a){this.cksumValid=!1,this.needPax=!1,this.nullBlock=!1,this.block=null,this.path=null,this.mode=null,this.uid=null,this.gid=null,this.size=null,this.mtime=null,this.cksum=null,this[Al]="0",this.linkpath=null,this.uname=null,this.gname=null,this.devmaj=0,this.devmin=0,this.atime=null,this.ctime=null,Buffer.isBuffer(e)?this.decode(e,r||0,o,a):e&&this.set(e)}decode(e,r,o,a){if(r||(r=0),!e||!(e.length>=r+512))throw new Error("need 512 bytes for header");if(this.path=Sg(e,r,100),this.mode=hh(e,r+100,8),this.uid=hh(e,r+108,8),this.gid=hh(e,r+116,8),this.size=hh(e,r+124,12),this.mtime=jU(e,r+136,12),this.cksum=hh(e,r+148,12),this[qU](o),this[qU](a,!0),this[Al]=Sg(e,r+156,1),this[Al]===""&&(this[Al]="0"),this[Al]==="0"&&this.path.substr(-1)==="/"&&(this[Al]="5"),this[Al]==="5"&&(this.size=0),this.linkpath=Sg(e,r+157,100),e.slice(r+257,r+265).toString()==="ustar\x0000")if(this.uname=Sg(e,r+265,32),this.gname=Sg(e,r+297,32),this.devmaj=hh(e,r+329,8),this.devmin=hh(e,r+337,8),e[r+475]!==0){let u=Sg(e,r+345,155);this.path=u+"/"+this.path}else{let u=Sg(e,r+345,130);u&&(this.path=u+"/"+this.path),this.atime=jU(e,r+476,12),this.ctime=jU(e,r+488,12)}let n=8*32;for(let u=r;u=r+512))throw new Error("need 512 bytes for header");let o=this.ctime||this.atime?130:155,a=Vat(this.path||"",o),n=a[0],u=a[1];this.needPax=a[2],this.needPax=xg(e,r,100,n)||this.needPax,this.needPax=gh(e,r+100,8,this.mode)||this.needPax,this.needPax=gh(e,r+108,8,this.uid)||this.needPax,this.needPax=gh(e,r+116,8,this.gid)||this.needPax,this.needPax=gh(e,r+124,12,this.size)||this.needPax,this.needPax=GU(e,r+136,12,this.mtime)||this.needPax,e[r+156]=this[Al].charCodeAt(0),this.needPax=xg(e,r+157,100,this.linkpath)||this.needPax,e.write("ustar\x0000",r+257,8),this.needPax=xg(e,r+265,32,this.uname)||this.needPax,this.needPax=xg(e,r+297,32,this.gname)||this.needPax,this.needPax=gh(e,r+329,8,this.devmaj)||this.needPax,this.needPax=gh(e,r+337,8,this.devmin)||this.needPax,this.needPax=xg(e,r+345,o,u)||this.needPax,e[r+475]!==0?this.needPax=xg(e,r+345,155,u)||this.needPax:(this.needPax=xg(e,r+345,130,u)||this.needPax,this.needPax=GU(e,r+476,12,this.atime)||this.needPax,this.needPax=GU(e,r+488,12,this.ctime)||this.needPax);let A=8*32;for(let p=r;p{let o=t,a="",n,u=my.parse(t).root||".";if(Buffer.byteLength(o)<100)n=[o,a,!1];else{a=my.dirname(o),o=my.basename(o);do Buffer.byteLength(o)<=100&&Buffer.byteLength(a)<=e?n=[o,a,!1]:Buffer.byteLength(o)>100&&Buffer.byteLength(a)<=e?n=[o.substr(0,99),a,!0]:(o=my.join(my.basename(a),o),a=my.dirname(a));while(a!==u&&!n);n||(n=[t.substr(0,99),"",!0])}return n},Sg=(t,e,r)=>t.slice(e,e+r).toString("utf8").replace(/\0.*/,""),jU=(t,e,r)=>zat(hh(t,e,r)),zat=t=>t===null?null:new Date(t*1e3),hh=(t,e,r)=>t[e]&128?Que.parse(t.slice(e,e+r)):Xat(t,e,r),Jat=t=>isNaN(t)?null:t,Xat=(t,e,r)=>Jat(parseInt(t.slice(e,e+r).toString("utf8").replace(/\0.*$/,"").trim(),8)),Zat={12:8589934591,8:2097151},gh=(t,e,r,o)=>o===null?!1:o>Zat[r]||o<0?(Que.encode(o,t.slice(e,e+r)),!0):($at(t,e,r,o),!1),$at=(t,e,r,o)=>t.write(elt(o,r),e,r,"ascii"),elt=(t,e)=>tlt(Math.floor(t).toString(8),e),tlt=(t,e)=>(t.length===e-1?t:new Array(e-t.length-1).join("0")+t+" ")+"\0",GU=(t,e,r,o)=>o===null?!1:gh(t,e,r,o.getTime()/1e3),rlt=new Array(156).join("\0"),xg=(t,e,r,o)=>o===null?!1:(t.write(o+rlt,e,r,"utf8"),o.length!==Buffer.byteLength(o)||o.length>r);Fue.exports=YU});var KS=_((eUt,Rue)=>{"use strict";var nlt=yy(),ilt=ve("path"),S1=class{constructor(e,r){this.atime=e.atime||null,this.charset=e.charset||null,this.comment=e.comment||null,this.ctime=e.ctime||null,this.gid=e.gid||null,this.gname=e.gname||null,this.linkpath=e.linkpath||null,this.mtime=e.mtime||null,this.path=e.path||null,this.size=e.size||null,this.uid=e.uid||null,this.uname=e.uname||null,this.dev=e.dev||null,this.ino=e.ino||null,this.nlink=e.nlink||null,this.global=r||!1}encode(){let e=this.encodeBody();if(e==="")return null;let r=Buffer.byteLength(e),o=512*Math.ceil(1+r/512),a=Buffer.allocUnsafe(o);for(let n=0;n<512;n++)a[n]=0;new nlt({path:("PaxHeader/"+ilt.basename(this.path)).slice(0,99),mode:this.mode||420,uid:this.uid||null,gid:this.gid||null,size:r,mtime:this.mtime||null,type:this.global?"GlobalExtendedHeader":"ExtendedHeader",linkpath:"",uname:this.uname||"",gname:this.gname||"",devmaj:0,devmin:0,atime:this.atime||null,ctime:this.ctime||null}).encode(a),a.write(e,512,r,"utf8");for(let n=r+512;n=Math.pow(10,n)&&(n+=1),n+a+o}};S1.parse=(t,e,r)=>new S1(slt(olt(t),e),r);var slt=(t,e)=>e?Object.keys(t).reduce((r,o)=>(r[o]=t[o],r),e):t,olt=t=>t.replace(/\n$/,"").split(` +`).reduce(alt,Object.create(null)),alt=(t,e)=>{let r=parseInt(e,10);if(r!==Buffer.byteLength(e)+1)return t;e=e.substr((r+" ").length);let o=e.split("="),a=o.shift().replace(/^SCHILY\.(dev|ino|nlink)/,"$1");if(!a)return t;let n=o.join("=");return t[a]=/^([A-Z]+\.)?([mac]|birth|creation)time$/.test(a)?new Date(n*1e3):/^[0-9]+$/.test(n)?+n:n,t};Rue.exports=S1});var Ey=_((tUt,Tue)=>{Tue.exports=t=>{let e=t.length-1,r=-1;for(;e>-1&&t.charAt(e)==="/";)r=e,e--;return r===-1?t:t.slice(0,r)}});var VS=_((rUt,Nue)=>{"use strict";Nue.exports=t=>class extends t{warn(e,r,o={}){this.file&&(o.file=this.file),this.cwd&&(o.cwd=this.cwd),o.code=r instanceof Error&&r.code||e,o.tarCode=e,!this.strict&&o.recoverable!==!1?(r instanceof Error&&(o=Object.assign(r,o),r=r.message),this.emit("warn",o.tarCode,r,o)):r instanceof Error?this.emit("error",Object.assign(r,o)):this.emit("error",Object.assign(new Error(`${e}: ${r}`),o))}}});var KU=_((iUt,Lue)=>{"use strict";var zS=["|","<",">","?",":"],WU=zS.map(t=>String.fromCharCode(61440+t.charCodeAt(0))),llt=new Map(zS.map((t,e)=>[t,WU[e]])),clt=new Map(WU.map((t,e)=>[t,zS[e]]));Lue.exports={encode:t=>zS.reduce((e,r)=>e.split(r).join(llt.get(r)),t),decode:t=>WU.reduce((e,r)=>e.split(r).join(clt.get(r)),t)}});var VU=_((sUt,Oue)=>{var{isAbsolute:ult,parse:Mue}=ve("path").win32;Oue.exports=t=>{let e="",r=Mue(t);for(;ult(t)||r.root;){let o=t.charAt(0)==="/"&&t.slice(0,4)!=="//?/"?"/":r.root;t=t.substr(o.length),e+=o,r=Mue(t)}return[e,t]}});var _ue=_((oUt,Uue)=>{"use strict";Uue.exports=(t,e,r)=>(t&=4095,r&&(t=(t|384)&-19),e&&(t&256&&(t|=64),t&32&&(t|=8),t&4&&(t|=1)),t)});var i3=_((cUt,eAe)=>{"use strict";var Kue=py(),Vue=KS(),zue=yy(),oA=ve("fs"),Hue=ve("path"),sA=dy(),Alt=Ey(),Jue=(t,e)=>e?(t=sA(t).replace(/^\.(\/|$)/,""),Alt(e)+"/"+t):sA(t),flt=16*1024*1024,que=Symbol("process"),jue=Symbol("file"),Gue=Symbol("directory"),JU=Symbol("symlink"),Yue=Symbol("hardlink"),x1=Symbol("header"),JS=Symbol("read"),XU=Symbol("lstat"),XS=Symbol("onlstat"),ZU=Symbol("onread"),$U=Symbol("onreadlink"),e3=Symbol("openfile"),t3=Symbol("onopenfile"),dh=Symbol("close"),ZS=Symbol("mode"),r3=Symbol("awaitDrain"),zU=Symbol("ondrain"),aA=Symbol("prefix"),Wue=Symbol("hadError"),Xue=VS(),plt=KU(),Zue=VU(),$ue=_ue(),$S=Xue(class extends Kue{constructor(e,r){if(r=r||{},super(r),typeof e!="string")throw new TypeError("path is required");this.path=sA(e),this.portable=!!r.portable,this.myuid=process.getuid&&process.getuid()||0,this.myuser=process.env.USER||"",this.maxReadSize=r.maxReadSize||flt,this.linkCache=r.linkCache||new Map,this.statCache=r.statCache||new Map,this.preservePaths=!!r.preservePaths,this.cwd=sA(r.cwd||process.cwd()),this.strict=!!r.strict,this.noPax=!!r.noPax,this.noMtime=!!r.noMtime,this.mtime=r.mtime||null,this.prefix=r.prefix?sA(r.prefix):null,this.fd=null,this.blockLen=null,this.blockRemain=null,this.buf=null,this.offset=null,this.length=null,this.pos=null,this.remain=null,typeof r.onwarn=="function"&&this.on("warn",r.onwarn);let o=!1;if(!this.preservePaths){let[a,n]=Zue(this.path);a&&(this.path=n,o=a)}this.win32=!!r.win32||process.platform==="win32",this.win32&&(this.path=plt.decode(this.path.replace(/\\/g,"/")),e=e.replace(/\\/g,"/")),this.absolute=sA(r.absolute||Hue.resolve(this.cwd,e)),this.path===""&&(this.path="./"),o&&this.warn("TAR_ENTRY_INFO",`stripping ${o} from absolute path`,{entry:this,path:o+this.path}),this.statCache.has(this.absolute)?this[XS](this.statCache.get(this.absolute)):this[XU]()}emit(e,...r){return e==="error"&&(this[Wue]=!0),super.emit(e,...r)}[XU](){oA.lstat(this.absolute,(e,r)=>{if(e)return this.emit("error",e);this[XS](r)})}[XS](e){this.statCache.set(this.absolute,e),this.stat=e,e.isFile()||(e.size=0),this.type=glt(e),this.emit("stat",e),this[que]()}[que](){switch(this.type){case"File":return this[jue]();case"Directory":return this[Gue]();case"SymbolicLink":return this[JU]();default:return this.end()}}[ZS](e){return $ue(e,this.type==="Directory",this.portable)}[aA](e){return Jue(e,this.prefix)}[x1](){this.type==="Directory"&&this.portable&&(this.noMtime=!0),this.header=new zue({path:this[aA](this.path),linkpath:this.type==="Link"?this[aA](this.linkpath):this.linkpath,mode:this[ZS](this.stat.mode),uid:this.portable?null:this.stat.uid,gid:this.portable?null:this.stat.gid,size:this.stat.size,mtime:this.noMtime?null:this.mtime||this.stat.mtime,type:this.type,uname:this.portable?null:this.stat.uid===this.myuid?this.myuser:"",atime:this.portable?null:this.stat.atime,ctime:this.portable?null:this.stat.ctime}),this.header.encode()&&!this.noPax&&super.write(new Vue({atime:this.portable?null:this.header.atime,ctime:this.portable?null:this.header.ctime,gid:this.portable?null:this.header.gid,mtime:this.noMtime?null:this.mtime||this.header.mtime,path:this[aA](this.path),linkpath:this.type==="Link"?this[aA](this.linkpath):this.linkpath,size:this.header.size,uid:this.portable?null:this.header.uid,uname:this.portable?null:this.header.uname,dev:this.portable?null:this.stat.dev,ino:this.portable?null:this.stat.ino,nlink:this.portable?null:this.stat.nlink}).encode()),super.write(this.header.block)}[Gue](){this.path.substr(-1)!=="/"&&(this.path+="/"),this.stat.size=0,this[x1](),this.end()}[JU](){oA.readlink(this.absolute,(e,r)=>{if(e)return this.emit("error",e);this[$U](r)})}[$U](e){this.linkpath=sA(e),this[x1](),this.end()}[Yue](e){this.type="Link",this.linkpath=sA(Hue.relative(this.cwd,e)),this.stat.size=0,this[x1](),this.end()}[jue](){if(this.stat.nlink>1){let e=this.stat.dev+":"+this.stat.ino;if(this.linkCache.has(e)){let r=this.linkCache.get(e);if(r.indexOf(this.cwd)===0)return this[Yue](r)}this.linkCache.set(e,this.absolute)}if(this[x1](),this.stat.size===0)return this.end();this[e3]()}[e3](){oA.open(this.absolute,"r",(e,r)=>{if(e)return this.emit("error",e);this[t3](r)})}[t3](e){if(this.fd=e,this[Wue])return this[dh]();this.blockLen=512*Math.ceil(this.stat.size/512),this.blockRemain=this.blockLen;let r=Math.min(this.blockLen,this.maxReadSize);this.buf=Buffer.allocUnsafe(r),this.offset=0,this.pos=0,this.remain=this.stat.size,this.length=this.buf.length,this[JS]()}[JS](){let{fd:e,buf:r,offset:o,length:a,pos:n}=this;oA.read(e,r,o,a,n,(u,A)=>{if(u)return this[dh](()=>this.emit("error",u));this[ZU](A)})}[dh](e){oA.close(this.fd,e)}[ZU](e){if(e<=0&&this.remain>0){let a=new Error("encountered unexpected EOF");return a.path=this.absolute,a.syscall="read",a.code="EOF",this[dh](()=>this.emit("error",a))}if(e>this.remain){let a=new Error("did not encounter expected EOF");return a.path=this.absolute,a.syscall="read",a.code="EOF",this[dh](()=>this.emit("error",a))}if(e===this.remain)for(let a=e;athis[zU]())}[r3](e){this.once("drain",e)}write(e){if(this.blockRemaine?this.emit("error",e):this.end());this.offset>=this.length&&(this.buf=Buffer.allocUnsafe(Math.min(this.blockRemain,this.buf.length)),this.offset=0),this.length=this.buf.length-this.offset,this[JS]()}}),n3=class extends $S{[XU](){this[XS](oA.lstatSync(this.absolute))}[JU](){this[$U](oA.readlinkSync(this.absolute))}[e3](){this[t3](oA.openSync(this.absolute,"r"))}[JS](){let e=!0;try{let{fd:r,buf:o,offset:a,length:n,pos:u}=this,A=oA.readSync(r,o,a,n,u);this[ZU](A),e=!1}finally{if(e)try{this[dh](()=>{})}catch{}}}[r3](e){e()}[dh](e){oA.closeSync(this.fd),e()}},hlt=Xue(class extends Kue{constructor(e,r){r=r||{},super(r),this.preservePaths=!!r.preservePaths,this.portable=!!r.portable,this.strict=!!r.strict,this.noPax=!!r.noPax,this.noMtime=!!r.noMtime,this.readEntry=e,this.type=e.type,this.type==="Directory"&&this.portable&&(this.noMtime=!0),this.prefix=r.prefix||null,this.path=sA(e.path),this.mode=this[ZS](e.mode),this.uid=this.portable?null:e.uid,this.gid=this.portable?null:e.gid,this.uname=this.portable?null:e.uname,this.gname=this.portable?null:e.gname,this.size=e.size,this.mtime=this.noMtime?null:r.mtime||e.mtime,this.atime=this.portable?null:e.atime,this.ctime=this.portable?null:e.ctime,this.linkpath=sA(e.linkpath),typeof r.onwarn=="function"&&this.on("warn",r.onwarn);let o=!1;if(!this.preservePaths){let[a,n]=Zue(this.path);a&&(this.path=n,o=a)}this.remain=e.size,this.blockRemain=e.startBlockSize,this.header=new zue({path:this[aA](this.path),linkpath:this.type==="Link"?this[aA](this.linkpath):this.linkpath,mode:this.mode,uid:this.portable?null:this.uid,gid:this.portable?null:this.gid,size:this.size,mtime:this.noMtime?null:this.mtime,type:this.type,uname:this.portable?null:this.uname,atime:this.portable?null:this.atime,ctime:this.portable?null:this.ctime}),o&&this.warn("TAR_ENTRY_INFO",`stripping ${o} from absolute path`,{entry:this,path:o+this.path}),this.header.encode()&&!this.noPax&&super.write(new Vue({atime:this.portable?null:this.atime,ctime:this.portable?null:this.ctime,gid:this.portable?null:this.gid,mtime:this.noMtime?null:this.mtime,path:this[aA](this.path),linkpath:this.type==="Link"?this[aA](this.linkpath):this.linkpath,size:this.size,uid:this.portable?null:this.uid,uname:this.portable?null:this.uname,dev:this.portable?null:this.readEntry.dev,ino:this.portable?null:this.readEntry.ino,nlink:this.portable?null:this.readEntry.nlink}).encode()),super.write(this.header.block),e.pipe(this)}[aA](e){return Jue(e,this.prefix)}[ZS](e){return $ue(e,this.type==="Directory",this.portable)}write(e){let r=e.length;if(r>this.blockRemain)throw new Error("writing more to entry than is appropriate");return this.blockRemain-=r,super.write(e)}end(){return this.blockRemain&&super.write(Buffer.alloc(this.blockRemain)),super.end()}});$S.Sync=n3;$S.Tar=hlt;var glt=t=>t.isFile()?"File":t.isDirectory()?"Directory":t.isSymbolicLink()?"SymbolicLink":"Unsupported";eAe.exports=$S});var lx=_((AUt,aAe)=>{"use strict";var ox=class{constructor(e,r){this.path=e||"./",this.absolute=r,this.entry=null,this.stat=null,this.readdir=null,this.pending=!1,this.ignore=!1,this.piped=!1}},dlt=py(),mlt=MU(),ylt=YS(),p3=i3(),Elt=p3.Sync,Clt=p3.Tar,wlt=cP(),tAe=Buffer.alloc(1024),rx=Symbol("onStat"),ex=Symbol("ended"),lA=Symbol("queue"),Cy=Symbol("current"),kg=Symbol("process"),tx=Symbol("processing"),rAe=Symbol("processJob"),cA=Symbol("jobs"),s3=Symbol("jobDone"),nx=Symbol("addFSEntry"),nAe=Symbol("addTarEntry"),c3=Symbol("stat"),u3=Symbol("readdir"),ix=Symbol("onreaddir"),sx=Symbol("pipe"),iAe=Symbol("entry"),o3=Symbol("entryOpt"),A3=Symbol("writeEntryClass"),oAe=Symbol("write"),a3=Symbol("ondrain"),ax=ve("fs"),sAe=ve("path"),Ilt=VS(),l3=dy(),h3=Ilt(class extends dlt{constructor(e){super(e),e=e||Object.create(null),this.opt=e,this.file=e.file||"",this.cwd=e.cwd||process.cwd(),this.maxReadSize=e.maxReadSize,this.preservePaths=!!e.preservePaths,this.strict=!!e.strict,this.noPax=!!e.noPax,this.prefix=l3(e.prefix||""),this.linkCache=e.linkCache||new Map,this.statCache=e.statCache||new Map,this.readdirCache=e.readdirCache||new Map,this[A3]=p3,typeof e.onwarn=="function"&&this.on("warn",e.onwarn),this.portable=!!e.portable,this.zip=null,e.gzip?(typeof e.gzip!="object"&&(e.gzip={}),this.portable&&(e.gzip.portable=!0),this.zip=new mlt.Gzip(e.gzip),this.zip.on("data",r=>super.write(r)),this.zip.on("end",r=>super.end()),this.zip.on("drain",r=>this[a3]()),this.on("resume",r=>this.zip.resume())):this.on("drain",this[a3]),this.noDirRecurse=!!e.noDirRecurse,this.follow=!!e.follow,this.noMtime=!!e.noMtime,this.mtime=e.mtime||null,this.filter=typeof e.filter=="function"?e.filter:r=>!0,this[lA]=new wlt,this[cA]=0,this.jobs=+e.jobs||4,this[tx]=!1,this[ex]=!1}[oAe](e){return super.write(e)}add(e){return this.write(e),this}end(e){return e&&this.write(e),this[ex]=!0,this[kg](),this}write(e){if(this[ex])throw new Error("write after end");return e instanceof ylt?this[nAe](e):this[nx](e),this.flowing}[nAe](e){let r=l3(sAe.resolve(this.cwd,e.path));if(!this.filter(e.path,e))e.resume();else{let o=new ox(e.path,r,!1);o.entry=new Clt(e,this[o3](o)),o.entry.on("end",a=>this[s3](o)),this[cA]+=1,this[lA].push(o)}this[kg]()}[nx](e){let r=l3(sAe.resolve(this.cwd,e));this[lA].push(new ox(e,r)),this[kg]()}[c3](e){e.pending=!0,this[cA]+=1;let r=this.follow?"stat":"lstat";ax[r](e.absolute,(o,a)=>{e.pending=!1,this[cA]-=1,o?this.emit("error",o):this[rx](e,a)})}[rx](e,r){this.statCache.set(e.absolute,r),e.stat=r,this.filter(e.path,r)||(e.ignore=!0),this[kg]()}[u3](e){e.pending=!0,this[cA]+=1,ax.readdir(e.absolute,(r,o)=>{if(e.pending=!1,this[cA]-=1,r)return this.emit("error",r);this[ix](e,o)})}[ix](e,r){this.readdirCache.set(e.absolute,r),e.readdir=r,this[kg]()}[kg](){if(!this[tx]){this[tx]=!0;for(let e=this[lA].head;e!==null&&this[cA]this.warn(r,o,a),noPax:this.noPax,cwd:this.cwd,absolute:e.absolute,preservePaths:this.preservePaths,maxReadSize:this.maxReadSize,strict:this.strict,portable:this.portable,linkCache:this.linkCache,statCache:this.statCache,noMtime:this.noMtime,mtime:this.mtime,prefix:this.prefix}}[iAe](e){this[cA]+=1;try{return new this[A3](e.path,this[o3](e)).on("end",()=>this[s3](e)).on("error",r=>this.emit("error",r))}catch(r){this.emit("error",r)}}[a3](){this[Cy]&&this[Cy].entry&&this[Cy].entry.resume()}[sx](e){e.piped=!0,e.readdir&&e.readdir.forEach(a=>{let n=e.path,u=n==="./"?"":n.replace(/\/*$/,"/");this[nx](u+a)});let r=e.entry,o=this.zip;o?r.on("data",a=>{o.write(a)||r.pause()}):r.on("data",a=>{super.write(a)||r.pause()})}pause(){return this.zip&&this.zip.pause(),super.pause()}}),f3=class extends h3{constructor(e){super(e),this[A3]=Elt}pause(){}resume(){}[c3](e){let r=this.follow?"statSync":"lstatSync";this[rx](e,ax[r](e.absolute))}[u3](e,r){this[ix](e,ax.readdirSync(e.absolute))}[sx](e){let r=e.entry,o=this.zip;e.readdir&&e.readdir.forEach(a=>{let n=e.path,u=n==="./"?"":n.replace(/\/*$/,"/");this[nx](u+a)}),o?r.on("data",a=>{o.write(a)}):r.on("data",a=>{super[oAe](a)})}};h3.Sync=f3;aAe.exports=h3});var Sy=_(Q1=>{"use strict";var Blt=py(),vlt=ve("events").EventEmitter,Ra=ve("fs"),m3=Ra.writev;if(!m3){let t=process.binding("fs"),e=t.FSReqWrap||t.FSReqCallback;m3=(r,o,a,n)=>{let u=(p,h)=>n(p,h,o),A=new e;A.oncomplete=u,t.writeBuffers(r,o,a,A)}}var Py=Symbol("_autoClose"),Kc=Symbol("_close"),k1=Symbol("_ended"),Gn=Symbol("_fd"),lAe=Symbol("_finished"),yh=Symbol("_flags"),g3=Symbol("_flush"),y3=Symbol("_handleChunk"),E3=Symbol("_makeBuf"),px=Symbol("_mode"),cx=Symbol("_needDrain"),vy=Symbol("_onerror"),by=Symbol("_onopen"),d3=Symbol("_onread"),Iy=Symbol("_onwrite"),Eh=Symbol("_open"),_f=Symbol("_path"),Qg=Symbol("_pos"),uA=Symbol("_queue"),By=Symbol("_read"),cAe=Symbol("_readSize"),mh=Symbol("_reading"),ux=Symbol("_remain"),uAe=Symbol("_size"),Ax=Symbol("_write"),wy=Symbol("_writing"),fx=Symbol("_defaultFlag"),Dy=Symbol("_errored"),hx=class extends Blt{constructor(e,r){if(r=r||{},super(r),this.readable=!0,this.writable=!1,typeof e!="string")throw new TypeError("path must be a string");this[Dy]=!1,this[Gn]=typeof r.fd=="number"?r.fd:null,this[_f]=e,this[cAe]=r.readSize||16*1024*1024,this[mh]=!1,this[uAe]=typeof r.size=="number"?r.size:1/0,this[ux]=this[uAe],this[Py]=typeof r.autoClose=="boolean"?r.autoClose:!0,typeof this[Gn]=="number"?this[By]():this[Eh]()}get fd(){return this[Gn]}get path(){return this[_f]}write(){throw new TypeError("this is a readable stream")}end(){throw new TypeError("this is a readable stream")}[Eh](){Ra.open(this[_f],"r",(e,r)=>this[by](e,r))}[by](e,r){e?this[vy](e):(this[Gn]=r,this.emit("open",r),this[By]())}[E3](){return Buffer.allocUnsafe(Math.min(this[cAe],this[ux]))}[By](){if(!this[mh]){this[mh]=!0;let e=this[E3]();if(e.length===0)return process.nextTick(()=>this[d3](null,0,e));Ra.read(this[Gn],e,0,e.length,null,(r,o,a)=>this[d3](r,o,a))}}[d3](e,r,o){this[mh]=!1,e?this[vy](e):this[y3](r,o)&&this[By]()}[Kc](){if(this[Py]&&typeof this[Gn]=="number"){let e=this[Gn];this[Gn]=null,Ra.close(e,r=>r?this.emit("error",r):this.emit("close"))}}[vy](e){this[mh]=!0,this[Kc](),this.emit("error",e)}[y3](e,r){let o=!1;return this[ux]-=e,e>0&&(o=super.write(ethis[by](e,r))}[by](e,r){this[fx]&&this[yh]==="r+"&&e&&e.code==="ENOENT"?(this[yh]="w",this[Eh]()):e?this[vy](e):(this[Gn]=r,this.emit("open",r),this[g3]())}end(e,r){return e&&this.write(e,r),this[k1]=!0,!this[wy]&&!this[uA].length&&typeof this[Gn]=="number"&&this[Iy](null,0),this}write(e,r){return typeof e=="string"&&(e=Buffer.from(e,r)),this[k1]?(this.emit("error",new Error("write() after end()")),!1):this[Gn]===null||this[wy]||this[uA].length?(this[uA].push(e),this[cx]=!0,!1):(this[wy]=!0,this[Ax](e),!0)}[Ax](e){Ra.write(this[Gn],e,0,e.length,this[Qg],(r,o)=>this[Iy](r,o))}[Iy](e,r){e?this[vy](e):(this[Qg]!==null&&(this[Qg]+=r),this[uA].length?this[g3]():(this[wy]=!1,this[k1]&&!this[lAe]?(this[lAe]=!0,this[Kc](),this.emit("finish")):this[cx]&&(this[cx]=!1,this.emit("drain"))))}[g3](){if(this[uA].length===0)this[k1]&&this[Iy](null,0);else if(this[uA].length===1)this[Ax](this[uA].pop());else{let e=this[uA];this[uA]=[],m3(this[Gn],e,this[Qg],(r,o)=>this[Iy](r,o))}}[Kc](){if(this[Py]&&typeof this[Gn]=="number"){let e=this[Gn];this[Gn]=null,Ra.close(e,r=>r?this.emit("error",r):this.emit("close"))}}},w3=class extends gx{[Eh](){let e;if(this[fx]&&this[yh]==="r+")try{e=Ra.openSync(this[_f],this[yh],this[px])}catch(r){if(r.code==="ENOENT")return this[yh]="w",this[Eh]();throw r}else e=Ra.openSync(this[_f],this[yh],this[px]);this[by](null,e)}[Kc](){if(this[Py]&&typeof this[Gn]=="number"){let e=this[Gn];this[Gn]=null,Ra.closeSync(e),this.emit("close")}}[Ax](e){let r=!0;try{this[Iy](null,Ra.writeSync(this[Gn],e,0,e.length,this[Qg])),r=!1}finally{if(r)try{this[Kc]()}catch{}}}};Q1.ReadStream=hx;Q1.ReadStreamSync=C3;Q1.WriteStream=gx;Q1.WriteStreamSync=w3});var Ix=_((hUt,mAe)=>{"use strict";var Dlt=VS(),Plt=yy(),blt=ve("events"),Slt=cP(),xlt=1024*1024,klt=YS(),AAe=KS(),Qlt=MU(),I3=Buffer.from([31,139]),Xl=Symbol("state"),Fg=Symbol("writeEntry"),Hf=Symbol("readEntry"),B3=Symbol("nextEntry"),fAe=Symbol("processEntry"),Zl=Symbol("extendedHeader"),F1=Symbol("globalExtendedHeader"),Ch=Symbol("meta"),pAe=Symbol("emitMeta"),fi=Symbol("buffer"),qf=Symbol("queue"),Rg=Symbol("ended"),hAe=Symbol("emittedEnd"),Tg=Symbol("emit"),Ta=Symbol("unzip"),dx=Symbol("consumeChunk"),mx=Symbol("consumeChunkSub"),v3=Symbol("consumeBody"),gAe=Symbol("consumeMeta"),dAe=Symbol("consumeHeader"),yx=Symbol("consuming"),D3=Symbol("bufferConcat"),P3=Symbol("maybeEnd"),R1=Symbol("writing"),wh=Symbol("aborted"),Ex=Symbol("onDone"),Ng=Symbol("sawValidEntry"),Cx=Symbol("sawNullBlock"),wx=Symbol("sawEOF"),Flt=t=>!0;mAe.exports=Dlt(class extends blt{constructor(e){e=e||{},super(e),this.file=e.file||"",this[Ng]=null,this.on(Ex,r=>{(this[Xl]==="begin"||this[Ng]===!1)&&this.warn("TAR_BAD_ARCHIVE","Unrecognized archive format")}),e.ondone?this.on(Ex,e.ondone):this.on(Ex,r=>{this.emit("prefinish"),this.emit("finish"),this.emit("end"),this.emit("close")}),this.strict=!!e.strict,this.maxMetaEntrySize=e.maxMetaEntrySize||xlt,this.filter=typeof e.filter=="function"?e.filter:Flt,this.writable=!0,this.readable=!1,this[qf]=new Slt,this[fi]=null,this[Hf]=null,this[Fg]=null,this[Xl]="begin",this[Ch]="",this[Zl]=null,this[F1]=null,this[Rg]=!1,this[Ta]=null,this[wh]=!1,this[Cx]=!1,this[wx]=!1,typeof e.onwarn=="function"&&this.on("warn",e.onwarn),typeof e.onentry=="function"&&this.on("entry",e.onentry)}[dAe](e,r){this[Ng]===null&&(this[Ng]=!1);let o;try{o=new Plt(e,r,this[Zl],this[F1])}catch(a){return this.warn("TAR_ENTRY_INVALID",a)}if(o.nullBlock)this[Cx]?(this[wx]=!0,this[Xl]==="begin"&&(this[Xl]="header"),this[Tg]("eof")):(this[Cx]=!0,this[Tg]("nullBlock"));else if(this[Cx]=!1,!o.cksumValid)this.warn("TAR_ENTRY_INVALID","checksum failure",{header:o});else if(!o.path)this.warn("TAR_ENTRY_INVALID","path is required",{header:o});else{let a=o.type;if(/^(Symbolic)?Link$/.test(a)&&!o.linkpath)this.warn("TAR_ENTRY_INVALID","linkpath required",{header:o});else if(!/^(Symbolic)?Link$/.test(a)&&o.linkpath)this.warn("TAR_ENTRY_INVALID","linkpath forbidden",{header:o});else{let n=this[Fg]=new klt(o,this[Zl],this[F1]);if(!this[Ng])if(n.remain){let u=()=>{n.invalid||(this[Ng]=!0)};n.on("end",u)}else this[Ng]=!0;n.meta?n.size>this.maxMetaEntrySize?(n.ignore=!0,this[Tg]("ignoredEntry",n),this[Xl]="ignore",n.resume()):n.size>0&&(this[Ch]="",n.on("data",u=>this[Ch]+=u),this[Xl]="meta"):(this[Zl]=null,n.ignore=n.ignore||!this.filter(n.path,n),n.ignore?(this[Tg]("ignoredEntry",n),this[Xl]=n.remain?"ignore":"header",n.resume()):(n.remain?this[Xl]="body":(this[Xl]="header",n.end()),this[Hf]?this[qf].push(n):(this[qf].push(n),this[B3]())))}}}[fAe](e){let r=!0;return e?Array.isArray(e)?this.emit.apply(this,e):(this[Hf]=e,this.emit("entry",e),e.emittedEnd||(e.on("end",o=>this[B3]()),r=!1)):(this[Hf]=null,r=!1),r}[B3](){do;while(this[fAe](this[qf].shift()));if(!this[qf].length){let e=this[Hf];!e||e.flowing||e.size===e.remain?this[R1]||this.emit("drain"):e.once("drain",o=>this.emit("drain"))}}[v3](e,r){let o=this[Fg],a=o.blockRemain,n=a>=e.length&&r===0?e:e.slice(r,r+a);return o.write(n),o.blockRemain||(this[Xl]="header",this[Fg]=null,o.end()),n.length}[gAe](e,r){let o=this[Fg],a=this[v3](e,r);return this[Fg]||this[pAe](o),a}[Tg](e,r,o){!this[qf].length&&!this[Hf]?this.emit(e,r,o):this[qf].push([e,r,o])}[pAe](e){switch(this[Tg]("meta",this[Ch]),e.type){case"ExtendedHeader":case"OldExtendedHeader":this[Zl]=AAe.parse(this[Ch],this[Zl],!1);break;case"GlobalExtendedHeader":this[F1]=AAe.parse(this[Ch],this[F1],!0);break;case"NextFileHasLongPath":case"OldGnuLongPath":this[Zl]=this[Zl]||Object.create(null),this[Zl].path=this[Ch].replace(/\0.*/,"");break;case"NextFileHasLongLinkpath":this[Zl]=this[Zl]||Object.create(null),this[Zl].linkpath=this[Ch].replace(/\0.*/,"");break;default:throw new Error("unknown meta: "+e.type)}}abort(e){this[wh]=!0,this.emit("abort",e),this.warn("TAR_ABORT",e,{recoverable:!1})}write(e){if(this[wh])return;if(this[Ta]===null&&e){if(this[fi]&&(e=Buffer.concat([this[fi],e]),this[fi]=null),e.lengththis[dx](n)),this[Ta].on("error",n=>this.abort(n)),this[Ta].on("end",n=>{this[Rg]=!0,this[dx]()}),this[R1]=!0;let a=this[Ta][o?"end":"write"](e);return this[R1]=!1,a}}this[R1]=!0,this[Ta]?this[Ta].write(e):this[dx](e),this[R1]=!1;let r=this[qf].length?!1:this[Hf]?this[Hf].flowing:!0;return!r&&!this[qf].length&&this[Hf].once("drain",o=>this.emit("drain")),r}[D3](e){e&&!this[wh]&&(this[fi]=this[fi]?Buffer.concat([this[fi],e]):e)}[P3](){if(this[Rg]&&!this[hAe]&&!this[wh]&&!this[yx]){this[hAe]=!0;let e=this[Fg];if(e&&e.blockRemain){let r=this[fi]?this[fi].length:0;this.warn("TAR_BAD_ARCHIVE",`Truncated input (needed ${e.blockRemain} more bytes, only ${r} available)`,{entry:e}),this[fi]&&e.write(this[fi]),e.end()}this[Tg](Ex)}}[dx](e){if(this[yx])this[D3](e);else if(!e&&!this[fi])this[P3]();else{if(this[yx]=!0,this[fi]){this[D3](e);let r=this[fi];this[fi]=null,this[mx](r)}else this[mx](e);for(;this[fi]&&this[fi].length>=512&&!this[wh]&&!this[wx];){let r=this[fi];this[fi]=null,this[mx](r)}this[yx]=!1}(!this[fi]||this[Rg])&&this[P3]()}[mx](e){let r=0,o=e.length;for(;r+512<=o&&!this[wh]&&!this[wx];)switch(this[Xl]){case"begin":case"header":this[dAe](e,r),r+=512;break;case"ignore":case"body":r+=this[v3](e,r);break;case"meta":r+=this[gAe](e,r);break;default:throw new Error("invalid state: "+this[Xl])}r{"use strict";var Rlt=Ay(),EAe=Ix(),xy=ve("fs"),Tlt=Sy(),yAe=ve("path"),b3=Ey();wAe.exports=(t,e,r)=>{typeof t=="function"?(r=t,e=null,t={}):Array.isArray(t)&&(e=t,t={}),typeof e=="function"&&(r=e,e=null),e?e=Array.from(e):e=[];let o=Rlt(t);if(o.sync&&typeof r=="function")throw new TypeError("callback not supported for sync tar functions");if(!o.file&&typeof r=="function")throw new TypeError("callback only supported with file option");return e.length&&Llt(o,e),o.noResume||Nlt(o),o.file&&o.sync?Mlt(o):o.file?Olt(o,r):CAe(o)};var Nlt=t=>{let e=t.onentry;t.onentry=e?r=>{e(r),r.resume()}:r=>r.resume()},Llt=(t,e)=>{let r=new Map(e.map(n=>[b3(n),!0])),o=t.filter,a=(n,u)=>{let A=u||yAe.parse(n).root||".",p=n===A?!1:r.has(n)?r.get(n):a(yAe.dirname(n),A);return r.set(n,p),p};t.filter=o?(n,u)=>o(n,u)&&a(b3(n)):n=>a(b3(n))},Mlt=t=>{let e=CAe(t),r=t.file,o=!0,a;try{let n=xy.statSync(r),u=t.maxReadSize||16*1024*1024;if(n.size{let r=new EAe(t),o=t.maxReadSize||16*1024*1024,a=t.file,n=new Promise((u,A)=>{r.on("error",A),r.on("end",u),xy.stat(a,(p,h)=>{if(p)A(p);else{let E=new Tlt.ReadStream(a,{readSize:o,size:h.size});E.on("error",A),E.pipe(r)}})});return e?n.then(e,e):n},CAe=t=>new EAe(t)});var bAe=_((dUt,PAe)=>{"use strict";var Ult=Ay(),vx=lx(),IAe=Sy(),BAe=Bx(),vAe=ve("path");PAe.exports=(t,e,r)=>{if(typeof e=="function"&&(r=e),Array.isArray(t)&&(e=t,t={}),!e||!Array.isArray(e)||!e.length)throw new TypeError("no files or directories specified");e=Array.from(e);let o=Ult(t);if(o.sync&&typeof r=="function")throw new TypeError("callback not supported for sync tar functions");if(!o.file&&typeof r=="function")throw new TypeError("callback only supported with file option");return o.file&&o.sync?_lt(o,e):o.file?Hlt(o,e,r):o.sync?qlt(o,e):jlt(o,e)};var _lt=(t,e)=>{let r=new vx.Sync(t),o=new IAe.WriteStreamSync(t.file,{mode:t.mode||438});r.pipe(o),DAe(r,e)},Hlt=(t,e,r)=>{let o=new vx(t),a=new IAe.WriteStream(t.file,{mode:t.mode||438});o.pipe(a);let n=new Promise((u,A)=>{a.on("error",A),a.on("close",u),o.on("error",A)});return S3(o,e),r?n.then(r,r):n},DAe=(t,e)=>{e.forEach(r=>{r.charAt(0)==="@"?BAe({file:vAe.resolve(t.cwd,r.substr(1)),sync:!0,noResume:!0,onentry:o=>t.add(o)}):t.add(r)}),t.end()},S3=(t,e)=>{for(;e.length;){let r=e.shift();if(r.charAt(0)==="@")return BAe({file:vAe.resolve(t.cwd,r.substr(1)),noResume:!0,onentry:o=>t.add(o)}).then(o=>S3(t,e));t.add(r)}t.end()},qlt=(t,e)=>{let r=new vx.Sync(t);return DAe(r,e),r},jlt=(t,e)=>{let r=new vx(t);return S3(r,e),r}});var x3=_((mUt,TAe)=>{"use strict";var Glt=Ay(),SAe=lx(),fl=ve("fs"),xAe=Sy(),kAe=Bx(),QAe=ve("path"),FAe=yy();TAe.exports=(t,e,r)=>{let o=Glt(t);if(!o.file)throw new TypeError("file is required");if(o.gzip)throw new TypeError("cannot append to compressed archives");if(!e||!Array.isArray(e)||!e.length)throw new TypeError("no files or directories specified");return e=Array.from(e),o.sync?Ylt(o,e):Klt(o,e,r)};var Ylt=(t,e)=>{let r=new SAe.Sync(t),o=!0,a,n;try{try{a=fl.openSync(t.file,"r+")}catch(p){if(p.code==="ENOENT")a=fl.openSync(t.file,"w+");else throw p}let u=fl.fstatSync(a),A=Buffer.alloc(512);e:for(n=0;nu.size)break;n+=h,t.mtimeCache&&t.mtimeCache.set(p.path,p.mtime)}o=!1,Wlt(t,r,n,a,e)}finally{if(o)try{fl.closeSync(a)}catch{}}},Wlt=(t,e,r,o,a)=>{let n=new xAe.WriteStreamSync(t.file,{fd:o,start:r});e.pipe(n),Vlt(e,a)},Klt=(t,e,r)=>{e=Array.from(e);let o=new SAe(t),a=(u,A,p)=>{let h=(C,R)=>{C?fl.close(u,L=>p(C)):p(null,R)},E=0;if(A===0)return h(null,0);let I=0,v=Buffer.alloc(512),x=(C,R)=>{if(C)return h(C);if(I+=R,I<512&&R)return fl.read(u,v,I,v.length-I,E+I,x);if(E===0&&v[0]===31&&v[1]===139)return h(new Error("cannot append to compressed archives"));if(I<512)return h(null,E);let L=new FAe(v);if(!L.cksumValid)return h(null,E);let U=512*Math.ceil(L.size/512);if(E+U+512>A||(E+=U+512,E>=A))return h(null,E);t.mtimeCache&&t.mtimeCache.set(L.path,L.mtime),I=0,fl.read(u,v,0,512,E,x)};fl.read(u,v,0,512,E,x)},n=new Promise((u,A)=>{o.on("error",A);let p="r+",h=(E,I)=>{if(E&&E.code==="ENOENT"&&p==="r+")return p="w+",fl.open(t.file,p,h);if(E)return A(E);fl.fstat(I,(v,x)=>{if(v)return fl.close(I,()=>A(v));a(I,x.size,(C,R)=>{if(C)return A(C);let L=new xAe.WriteStream(t.file,{fd:I,start:R});o.pipe(L),L.on("error",A),L.on("close",u),RAe(o,e)})})};fl.open(t.file,p,h)});return r?n.then(r,r):n},Vlt=(t,e)=>{e.forEach(r=>{r.charAt(0)==="@"?kAe({file:QAe.resolve(t.cwd,r.substr(1)),sync:!0,noResume:!0,onentry:o=>t.add(o)}):t.add(r)}),t.end()},RAe=(t,e)=>{for(;e.length;){let r=e.shift();if(r.charAt(0)==="@")return kAe({file:QAe.resolve(t.cwd,r.substr(1)),noResume:!0,onentry:o=>t.add(o)}).then(o=>RAe(t,e));t.add(r)}t.end()}});var LAe=_((yUt,NAe)=>{"use strict";var zlt=Ay(),Jlt=x3();NAe.exports=(t,e,r)=>{let o=zlt(t);if(!o.file)throw new TypeError("file is required");if(o.gzip)throw new TypeError("cannot append to compressed archives");if(!e||!Array.isArray(e)||!e.length)throw new TypeError("no files or directories specified");return e=Array.from(e),Xlt(o),Jlt(o,e,r)};var Xlt=t=>{let e=t.filter;t.mtimeCache||(t.mtimeCache=new Map),t.filter=e?(r,o)=>e(r,o)&&!(t.mtimeCache.get(r)>o.mtime):(r,o)=>!(t.mtimeCache.get(r)>o.mtime)}});var UAe=_((EUt,OAe)=>{var{promisify:MAe}=ve("util"),Ih=ve("fs"),Zlt=t=>{if(!t)t={mode:511,fs:Ih};else if(typeof t=="object")t={mode:511,fs:Ih,...t};else if(typeof t=="number")t={mode:t,fs:Ih};else if(typeof t=="string")t={mode:parseInt(t,8),fs:Ih};else throw new TypeError("invalid options argument");return t.mkdir=t.mkdir||t.fs.mkdir||Ih.mkdir,t.mkdirAsync=MAe(t.mkdir),t.stat=t.stat||t.fs.stat||Ih.stat,t.statAsync=MAe(t.stat),t.statSync=t.statSync||t.fs.statSync||Ih.statSync,t.mkdirSync=t.mkdirSync||t.fs.mkdirSync||Ih.mkdirSync,t};OAe.exports=Zlt});var HAe=_((CUt,_Ae)=>{var $lt=process.platform,{resolve:ect,parse:tct}=ve("path"),rct=t=>{if(/\0/.test(t))throw Object.assign(new TypeError("path must be a string without null bytes"),{path:t,code:"ERR_INVALID_ARG_VALUE"});if(t=ect(t),$lt==="win32"){let e=/[*|"<>?:]/,{root:r}=tct(t);if(e.test(t.substr(r.length)))throw Object.assign(new Error("Illegal characters in path."),{path:t,code:"EINVAL"})}return t};_Ae.exports=rct});var WAe=_((wUt,YAe)=>{var{dirname:qAe}=ve("path"),jAe=(t,e,r=void 0)=>r===e?Promise.resolve():t.statAsync(e).then(o=>o.isDirectory()?r:void 0,o=>o.code==="ENOENT"?jAe(t,qAe(e),e):void 0),GAe=(t,e,r=void 0)=>{if(r!==e)try{return t.statSync(e).isDirectory()?r:void 0}catch(o){return o.code==="ENOENT"?GAe(t,qAe(e),e):void 0}};YAe.exports={findMade:jAe,findMadeSync:GAe}});var F3=_((IUt,VAe)=>{var{dirname:KAe}=ve("path"),k3=(t,e,r)=>{e.recursive=!1;let o=KAe(t);return o===t?e.mkdirAsync(t,e).catch(a=>{if(a.code!=="EISDIR")throw a}):e.mkdirAsync(t,e).then(()=>r||t,a=>{if(a.code==="ENOENT")return k3(o,e).then(n=>k3(t,e,n));if(a.code!=="EEXIST"&&a.code!=="EROFS")throw a;return e.statAsync(t).then(n=>{if(n.isDirectory())return r;throw a},()=>{throw a})})},Q3=(t,e,r)=>{let o=KAe(t);if(e.recursive=!1,o===t)try{return e.mkdirSync(t,e)}catch(a){if(a.code!=="EISDIR")throw a;return}try{return e.mkdirSync(t,e),r||t}catch(a){if(a.code==="ENOENT")return Q3(t,e,Q3(o,e,r));if(a.code!=="EEXIST"&&a.code!=="EROFS")throw a;try{if(!e.statSync(t).isDirectory())throw a}catch{throw a}}};VAe.exports={mkdirpManual:k3,mkdirpManualSync:Q3}});var XAe=_((BUt,JAe)=>{var{dirname:zAe}=ve("path"),{findMade:nct,findMadeSync:ict}=WAe(),{mkdirpManual:sct,mkdirpManualSync:oct}=F3(),act=(t,e)=>(e.recursive=!0,zAe(t)===t?e.mkdirAsync(t,e):nct(e,t).then(o=>e.mkdirAsync(t,e).then(()=>o).catch(a=>{if(a.code==="ENOENT")return sct(t,e);throw a}))),lct=(t,e)=>{if(e.recursive=!0,zAe(t)===t)return e.mkdirSync(t,e);let o=ict(e,t);try{return e.mkdirSync(t,e),o}catch(a){if(a.code==="ENOENT")return oct(t,e);throw a}};JAe.exports={mkdirpNative:act,mkdirpNativeSync:lct}});var tfe=_((vUt,efe)=>{var ZAe=ve("fs"),cct=process.version,R3=cct.replace(/^v/,"").split("."),$Ae=+R3[0]>10||+R3[0]==10&&+R3[1]>=12,uct=$Ae?t=>t.mkdir===ZAe.mkdir:()=>!1,Act=$Ae?t=>t.mkdirSync===ZAe.mkdirSync:()=>!1;efe.exports={useNative:uct,useNativeSync:Act}});var afe=_((DUt,ofe)=>{var ky=UAe(),Qy=HAe(),{mkdirpNative:rfe,mkdirpNativeSync:nfe}=XAe(),{mkdirpManual:ife,mkdirpManualSync:sfe}=F3(),{useNative:fct,useNativeSync:pct}=tfe(),Fy=(t,e)=>(t=Qy(t),e=ky(e),fct(e)?rfe(t,e):ife(t,e)),hct=(t,e)=>(t=Qy(t),e=ky(e),pct(e)?nfe(t,e):sfe(t,e));Fy.sync=hct;Fy.native=(t,e)=>rfe(Qy(t),ky(e));Fy.manual=(t,e)=>ife(Qy(t),ky(e));Fy.nativeSync=(t,e)=>nfe(Qy(t),ky(e));Fy.manualSync=(t,e)=>sfe(Qy(t),ky(e));ofe.exports=Fy});var hfe=_((PUt,pfe)=>{"use strict";var $l=ve("fs"),Lg=ve("path"),gct=$l.lchown?"lchown":"chown",dct=$l.lchownSync?"lchownSync":"chownSync",cfe=$l.lchown&&!process.version.match(/v1[1-9]+\./)&&!process.version.match(/v10\.[6-9]/),lfe=(t,e,r)=>{try{return $l[dct](t,e,r)}catch(o){if(o.code!=="ENOENT")throw o}},mct=(t,e,r)=>{try{return $l.chownSync(t,e,r)}catch(o){if(o.code!=="ENOENT")throw o}},yct=cfe?(t,e,r,o)=>a=>{!a||a.code!=="EISDIR"?o(a):$l.chown(t,e,r,o)}:(t,e,r,o)=>o,T3=cfe?(t,e,r)=>{try{return lfe(t,e,r)}catch(o){if(o.code!=="EISDIR")throw o;mct(t,e,r)}}:(t,e,r)=>lfe(t,e,r),Ect=process.version,ufe=(t,e,r)=>$l.readdir(t,e,r),Cct=(t,e)=>$l.readdirSync(t,e);/^v4\./.test(Ect)&&(ufe=(t,e,r)=>$l.readdir(t,r));var Dx=(t,e,r,o)=>{$l[gct](t,e,r,yct(t,e,r,a=>{o(a&&a.code!=="ENOENT"?a:null)}))},Afe=(t,e,r,o,a)=>{if(typeof e=="string")return $l.lstat(Lg.resolve(t,e),(n,u)=>{if(n)return a(n.code!=="ENOENT"?n:null);u.name=e,Afe(t,u,r,o,a)});if(e.isDirectory())N3(Lg.resolve(t,e.name),r,o,n=>{if(n)return a(n);let u=Lg.resolve(t,e.name);Dx(u,r,o,a)});else{let n=Lg.resolve(t,e.name);Dx(n,r,o,a)}},N3=(t,e,r,o)=>{ufe(t,{withFileTypes:!0},(a,n)=>{if(a){if(a.code==="ENOENT")return o();if(a.code!=="ENOTDIR"&&a.code!=="ENOTSUP")return o(a)}if(a||!n.length)return Dx(t,e,r,o);let u=n.length,A=null,p=h=>{if(!A){if(h)return o(A=h);if(--u===0)return Dx(t,e,r,o)}};n.forEach(h=>Afe(t,h,e,r,p))})},wct=(t,e,r,o)=>{if(typeof e=="string")try{let a=$l.lstatSync(Lg.resolve(t,e));a.name=e,e=a}catch(a){if(a.code==="ENOENT")return;throw a}e.isDirectory()&&ffe(Lg.resolve(t,e.name),r,o),T3(Lg.resolve(t,e.name),r,o)},ffe=(t,e,r)=>{let o;try{o=Cct(t,{withFileTypes:!0})}catch(a){if(a.code==="ENOENT")return;if(a.code==="ENOTDIR"||a.code==="ENOTSUP")return T3(t,e,r);throw a}return o&&o.length&&o.forEach(a=>wct(t,a,e,r)),T3(t,e,r)};pfe.exports=N3;N3.sync=ffe});var yfe=_((bUt,L3)=>{"use strict";var gfe=afe(),ec=ve("fs"),Px=ve("path"),dfe=hfe(),Vc=dy(),bx=class extends Error{constructor(e,r){super("Cannot extract through symbolic link"),this.path=r,this.symlink=e}get name(){return"SylinkError"}},Sx=class extends Error{constructor(e,r){super(r+": Cannot cd into '"+e+"'"),this.path=e,this.code=r}get name(){return"CwdError"}},xx=(t,e)=>t.get(Vc(e)),T1=(t,e,r)=>t.set(Vc(e),r),Ict=(t,e)=>{ec.stat(t,(r,o)=>{(r||!o.isDirectory())&&(r=new Sx(t,r&&r.code||"ENOTDIR")),e(r)})};L3.exports=(t,e,r)=>{t=Vc(t);let o=e.umask,a=e.mode|448,n=(a&o)!==0,u=e.uid,A=e.gid,p=typeof u=="number"&&typeof A=="number"&&(u!==e.processUid||A!==e.processGid),h=e.preserve,E=e.unlink,I=e.cache,v=Vc(e.cwd),x=(L,U)=>{L?r(L):(T1(I,t,!0),U&&p?dfe(U,u,A,z=>x(z)):n?ec.chmod(t,a,r):r())};if(I&&xx(I,t)===!0)return x();if(t===v)return Ict(t,x);if(h)return gfe(t,{mode:a}).then(L=>x(null,L),x);let R=Vc(Px.relative(v,t)).split("/");kx(v,R,a,I,E,v,null,x)};var kx=(t,e,r,o,a,n,u,A)=>{if(!e.length)return A(null,u);let p=e.shift(),h=Vc(Px.resolve(t+"/"+p));if(xx(o,h))return kx(h,e,r,o,a,n,u,A);ec.mkdir(h,r,mfe(h,e,r,o,a,n,u,A))},mfe=(t,e,r,o,a,n,u,A)=>p=>{p?ec.lstat(t,(h,E)=>{if(h)h.path=h.path&&Vc(h.path),A(h);else if(E.isDirectory())kx(t,e,r,o,a,n,u,A);else if(a)ec.unlink(t,I=>{if(I)return A(I);ec.mkdir(t,r,mfe(t,e,r,o,a,n,u,A))});else{if(E.isSymbolicLink())return A(new bx(t,t+"/"+e.join("/")));A(p)}}):(u=u||t,kx(t,e,r,o,a,n,u,A))},Bct=t=>{let e=!1,r="ENOTDIR";try{e=ec.statSync(t).isDirectory()}catch(o){r=o.code}finally{if(!e)throw new Sx(t,r)}};L3.exports.sync=(t,e)=>{t=Vc(t);let r=e.umask,o=e.mode|448,a=(o&r)!==0,n=e.uid,u=e.gid,A=typeof n=="number"&&typeof u=="number"&&(n!==e.processUid||u!==e.processGid),p=e.preserve,h=e.unlink,E=e.cache,I=Vc(e.cwd),v=L=>{T1(E,t,!0),L&&A&&dfe.sync(L,n,u),a&&ec.chmodSync(t,o)};if(E&&xx(E,t)===!0)return v();if(t===I)return Bct(I),v();if(p)return v(gfe.sync(t,o));let C=Vc(Px.relative(I,t)).split("/"),R=null;for(let L=C.shift(),U=I;L&&(U+="/"+L);L=C.shift())if(U=Vc(Px.resolve(U)),!xx(E,U))try{ec.mkdirSync(U,o),R=R||U,T1(E,U,!0)}catch{let te=ec.lstatSync(U);if(te.isDirectory()){T1(E,U,!0);continue}else if(h){ec.unlinkSync(U),ec.mkdirSync(U,o),R=R||U,T1(E,U,!0);continue}else if(te.isSymbolicLink())return new bx(U,U+"/"+C.join("/"))}return v(R)}});var O3=_((SUt,Efe)=>{var M3=Object.create(null),{hasOwnProperty:vct}=Object.prototype;Efe.exports=t=>(vct.call(M3,t)||(M3[t]=t.normalize("NFKD")),M3[t])});var Bfe=_((xUt,Ife)=>{var Cfe=ve("assert"),Dct=O3(),Pct=Ey(),{join:wfe}=ve("path"),bct=process.env.TESTING_TAR_FAKE_PLATFORM||process.platform,Sct=bct==="win32";Ife.exports=()=>{let t=new Map,e=new Map,r=h=>h.split("/").slice(0,-1).reduce((I,v)=>(I.length&&(v=wfe(I[I.length-1],v)),I.push(v||"/"),I),[]),o=new Set,a=h=>{let E=e.get(h);if(!E)throw new Error("function does not have any path reservations");return{paths:E.paths.map(I=>t.get(I)),dirs:[...E.dirs].map(I=>t.get(I))}},n=h=>{let{paths:E,dirs:I}=a(h);return E.every(v=>v[0]===h)&&I.every(v=>v[0]instanceof Set&&v[0].has(h))},u=h=>o.has(h)||!n(h)?!1:(o.add(h),h(()=>A(h)),!0),A=h=>{if(!o.has(h))return!1;let{paths:E,dirs:I}=e.get(h),v=new Set;return E.forEach(x=>{let C=t.get(x);Cfe.equal(C[0],h),C.length===1?t.delete(x):(C.shift(),typeof C[0]=="function"?v.add(C[0]):C[0].forEach(R=>v.add(R)))}),I.forEach(x=>{let C=t.get(x);Cfe(C[0]instanceof Set),C[0].size===1&&C.length===1?t.delete(x):C[0].size===1?(C.shift(),v.add(C[0])):C[0].delete(h)}),o.delete(h),v.forEach(x=>u(x)),!0};return{check:n,reserve:(h,E)=>{h=Sct?["win32 parallelization disabled"]:h.map(v=>Dct(Pct(wfe(v))).toLowerCase());let I=new Set(h.map(v=>r(v)).reduce((v,x)=>v.concat(x)));return e.set(E,{dirs:I,paths:h}),h.forEach(v=>{let x=t.get(v);x?x.push(E):t.set(v,[E])}),I.forEach(v=>{let x=t.get(v);x?x[x.length-1]instanceof Set?x[x.length-1].add(E):x.push(new Set([E])):t.set(v,[new Set([E])])}),u(E)}}}});var Pfe=_((kUt,Dfe)=>{var xct=process.platform,kct=xct==="win32",Qct=global.__FAKE_TESTING_FS__||ve("fs"),{O_CREAT:Fct,O_TRUNC:Rct,O_WRONLY:Tct,UV_FS_O_FILEMAP:vfe=0}=Qct.constants,Nct=kct&&!!vfe,Lct=512*1024,Mct=vfe|Rct|Fct|Tct;Dfe.exports=Nct?t=>t"w"});var K3=_((QUt,_fe)=>{"use strict";var Oct=ve("assert"),Uct=Ix(),vn=ve("fs"),_ct=Sy(),jf=ve("path"),Mfe=yfe(),bfe=KU(),Hct=Bfe(),qct=VU(),pl=dy(),jct=Ey(),Gct=O3(),Sfe=Symbol("onEntry"),H3=Symbol("checkFs"),xfe=Symbol("checkFs2"),Rx=Symbol("pruneCache"),q3=Symbol("isReusable"),tc=Symbol("makeFs"),j3=Symbol("file"),G3=Symbol("directory"),Tx=Symbol("link"),kfe=Symbol("symlink"),Qfe=Symbol("hardlink"),Ffe=Symbol("unsupported"),Rfe=Symbol("checkPath"),Bh=Symbol("mkdir"),To=Symbol("onError"),Qx=Symbol("pending"),Tfe=Symbol("pend"),Ry=Symbol("unpend"),U3=Symbol("ended"),_3=Symbol("maybeClose"),Y3=Symbol("skip"),N1=Symbol("doChown"),L1=Symbol("uid"),M1=Symbol("gid"),O1=Symbol("checkedCwd"),Ofe=ve("crypto"),Ufe=Pfe(),Yct=process.env.TESTING_TAR_FAKE_PLATFORM||process.platform,U1=Yct==="win32",Wct=(t,e)=>{if(!U1)return vn.unlink(t,e);let r=t+".DELETE."+Ofe.randomBytes(16).toString("hex");vn.rename(t,r,o=>{if(o)return e(o);vn.unlink(r,e)})},Kct=t=>{if(!U1)return vn.unlinkSync(t);let e=t+".DELETE."+Ofe.randomBytes(16).toString("hex");vn.renameSync(t,e),vn.unlinkSync(e)},Nfe=(t,e,r)=>t===t>>>0?t:e===e>>>0?e:r,Lfe=t=>Gct(jct(pl(t))).toLowerCase(),Vct=(t,e)=>{e=Lfe(e);for(let r of t.keys()){let o=Lfe(r);(o===e||o.indexOf(e+"/")===0)&&t.delete(r)}},zct=t=>{for(let e of t.keys())t.delete(e)},_1=class extends Uct{constructor(e){if(e||(e={}),e.ondone=r=>{this[U3]=!0,this[_3]()},super(e),this[O1]=!1,this.reservations=Hct(),this.transform=typeof e.transform=="function"?e.transform:null,this.writable=!0,this.readable=!1,this[Qx]=0,this[U3]=!1,this.dirCache=e.dirCache||new Map,typeof e.uid=="number"||typeof e.gid=="number"){if(typeof e.uid!="number"||typeof e.gid!="number")throw new TypeError("cannot set owner without number uid and gid");if(e.preserveOwner)throw new TypeError("cannot preserve owner in archive and also set owner explicitly");this.uid=e.uid,this.gid=e.gid,this.setOwner=!0}else this.uid=null,this.gid=null,this.setOwner=!1;e.preserveOwner===void 0&&typeof e.uid!="number"?this.preserveOwner=process.getuid&&process.getuid()===0:this.preserveOwner=!!e.preserveOwner,this.processUid=(this.preserveOwner||this.setOwner)&&process.getuid?process.getuid():null,this.processGid=(this.preserveOwner||this.setOwner)&&process.getgid?process.getgid():null,this.forceChown=e.forceChown===!0,this.win32=!!e.win32||U1,this.newer=!!e.newer,this.keep=!!e.keep,this.noMtime=!!e.noMtime,this.preservePaths=!!e.preservePaths,this.unlink=!!e.unlink,this.cwd=pl(jf.resolve(e.cwd||process.cwd())),this.strip=+e.strip||0,this.processUmask=e.noChmod?0:process.umask(),this.umask=typeof e.umask=="number"?e.umask:this.processUmask,this.dmode=e.dmode||511&~this.umask,this.fmode=e.fmode||438&~this.umask,this.on("entry",r=>this[Sfe](r))}warn(e,r,o={}){return(e==="TAR_BAD_ARCHIVE"||e==="TAR_ABORT")&&(o.recoverable=!1),super.warn(e,r,o)}[_3](){this[U3]&&this[Qx]===0&&(this.emit("prefinish"),this.emit("finish"),this.emit("end"),this.emit("close"))}[Rfe](e){if(this.strip){let r=pl(e.path).split("/");if(r.length=this.strip)e.linkpath=o.slice(this.strip).join("/");else return!1}}if(!this.preservePaths){let r=pl(e.path),o=r.split("/");if(o.includes("..")||U1&&/^[a-z]:\.\.$/i.test(o[0]))return this.warn("TAR_ENTRY_ERROR","path contains '..'",{entry:e,path:r}),!1;let[a,n]=qct(r);a&&(e.path=n,this.warn("TAR_ENTRY_INFO",`stripping ${a} from absolute path`,{entry:e,path:r}))}if(jf.isAbsolute(e.path)?e.absolute=pl(jf.resolve(e.path)):e.absolute=pl(jf.resolve(this.cwd,e.path)),!this.preservePaths&&e.absolute.indexOf(this.cwd+"/")!==0&&e.absolute!==this.cwd)return this.warn("TAR_ENTRY_ERROR","path escaped extraction target",{entry:e,path:pl(e.path),resolvedPath:e.absolute,cwd:this.cwd}),!1;if(e.absolute===this.cwd&&e.type!=="Directory"&&e.type!=="GNUDumpDir")return!1;if(this.win32){let{root:r}=jf.win32.parse(e.absolute);e.absolute=r+bfe.encode(e.absolute.substr(r.length));let{root:o}=jf.win32.parse(e.path);e.path=o+bfe.encode(e.path.substr(o.length))}return!0}[Sfe](e){if(!this[Rfe](e))return e.resume();switch(Oct.equal(typeof e.absolute,"string"),e.type){case"Directory":case"GNUDumpDir":e.mode&&(e.mode=e.mode|448);case"File":case"OldFile":case"ContiguousFile":case"Link":case"SymbolicLink":return this[H3](e);case"CharacterDevice":case"BlockDevice":case"FIFO":default:return this[Ffe](e)}}[To](e,r){e.name==="CwdError"?this.emit("error",e):(this.warn("TAR_ENTRY_ERROR",e,{entry:r}),this[Ry](),r.resume())}[Bh](e,r,o){Mfe(pl(e),{uid:this.uid,gid:this.gid,processUid:this.processUid,processGid:this.processGid,umask:this.processUmask,preserve:this.preservePaths,unlink:this.unlink,cache:this.dirCache,cwd:this.cwd,mode:r,noChmod:this.noChmod},o)}[N1](e){return this.forceChown||this.preserveOwner&&(typeof e.uid=="number"&&e.uid!==this.processUid||typeof e.gid=="number"&&e.gid!==this.processGid)||typeof this.uid=="number"&&this.uid!==this.processUid||typeof this.gid=="number"&&this.gid!==this.processGid}[L1](e){return Nfe(this.uid,e.uid,this.processUid)}[M1](e){return Nfe(this.gid,e.gid,this.processGid)}[j3](e,r){let o=e.mode&4095||this.fmode,a=new _ct.WriteStream(e.absolute,{flags:Ufe(e.size),mode:o,autoClose:!1});a.on("error",p=>{a.fd&&vn.close(a.fd,()=>{}),a.write=()=>!0,this[To](p,e),r()});let n=1,u=p=>{if(p){a.fd&&vn.close(a.fd,()=>{}),this[To](p,e),r();return}--n===0&&vn.close(a.fd,h=>{h?this[To](h,e):this[Ry](),r()})};a.on("finish",p=>{let h=e.absolute,E=a.fd;if(e.mtime&&!this.noMtime){n++;let I=e.atime||new Date,v=e.mtime;vn.futimes(E,I,v,x=>x?vn.utimes(h,I,v,C=>u(C&&x)):u())}if(this[N1](e)){n++;let I=this[L1](e),v=this[M1](e);vn.fchown(E,I,v,x=>x?vn.chown(h,I,v,C=>u(C&&x)):u())}u()});let A=this.transform&&this.transform(e)||e;A!==e&&(A.on("error",p=>{this[To](p,e),r()}),e.pipe(A)),A.pipe(a)}[G3](e,r){let o=e.mode&4095||this.dmode;this[Bh](e.absolute,o,a=>{if(a){this[To](a,e),r();return}let n=1,u=A=>{--n===0&&(r(),this[Ry](),e.resume())};e.mtime&&!this.noMtime&&(n++,vn.utimes(e.absolute,e.atime||new Date,e.mtime,u)),this[N1](e)&&(n++,vn.chown(e.absolute,this[L1](e),this[M1](e),u)),u()})}[Ffe](e){e.unsupported=!0,this.warn("TAR_ENTRY_UNSUPPORTED",`unsupported entry type: ${e.type}`,{entry:e}),e.resume()}[kfe](e,r){this[Tx](e,e.linkpath,"symlink",r)}[Qfe](e,r){let o=pl(jf.resolve(this.cwd,e.linkpath));this[Tx](e,o,"link",r)}[Tfe](){this[Qx]++}[Ry](){this[Qx]--,this[_3]()}[Y3](e){this[Ry](),e.resume()}[q3](e,r){return e.type==="File"&&!this.unlink&&r.isFile()&&r.nlink<=1&&!U1}[H3](e){this[Tfe]();let r=[e.path];e.linkpath&&r.push(e.linkpath),this.reservations.reserve(r,o=>this[xfe](e,o))}[Rx](e){e.type==="SymbolicLink"?zct(this.dirCache):e.type!=="Directory"&&Vct(this.dirCache,e.absolute)}[xfe](e,r){this[Rx](e);let o=A=>{this[Rx](e),r(A)},a=()=>{this[Bh](this.cwd,this.dmode,A=>{if(A){this[To](A,e),o();return}this[O1]=!0,n()})},n=()=>{if(e.absolute!==this.cwd){let A=pl(jf.dirname(e.absolute));if(A!==this.cwd)return this[Bh](A,this.dmode,p=>{if(p){this[To](p,e),o();return}u()})}u()},u=()=>{vn.lstat(e.absolute,(A,p)=>{if(p&&(this.keep||this.newer&&p.mtime>e.mtime)){this[Y3](e),o();return}if(A||this[q3](e,p))return this[tc](null,e,o);if(p.isDirectory()){if(e.type==="Directory"){let h=!this.noChmod&&e.mode&&(p.mode&4095)!==e.mode,E=I=>this[tc](I,e,o);return h?vn.chmod(e.absolute,e.mode,E):E()}if(e.absolute!==this.cwd)return vn.rmdir(e.absolute,h=>this[tc](h,e,o))}if(e.absolute===this.cwd)return this[tc](null,e,o);Wct(e.absolute,h=>this[tc](h,e,o))})};this[O1]?n():a()}[tc](e,r,o){if(e){this[To](e,r),o();return}switch(r.type){case"File":case"OldFile":case"ContiguousFile":return this[j3](r,o);case"Link":return this[Qfe](r,o);case"SymbolicLink":return this[kfe](r,o);case"Directory":case"GNUDumpDir":return this[G3](r,o)}}[Tx](e,r,o,a){vn[o](r,e.absolute,n=>{n?this[To](n,e):(this[Ry](),e.resume()),a()})}},Fx=t=>{try{return[null,t()]}catch(e){return[e,null]}},W3=class extends _1{[tc](e,r){return super[tc](e,r,()=>{})}[H3](e){if(this[Rx](e),!this[O1]){let n=this[Bh](this.cwd,this.dmode);if(n)return this[To](n,e);this[O1]=!0}if(e.absolute!==this.cwd){let n=pl(jf.dirname(e.absolute));if(n!==this.cwd){let u=this[Bh](n,this.dmode);if(u)return this[To](u,e)}}let[r,o]=Fx(()=>vn.lstatSync(e.absolute));if(o&&(this.keep||this.newer&&o.mtime>e.mtime))return this[Y3](e);if(r||this[q3](e,o))return this[tc](null,e);if(o.isDirectory()){if(e.type==="Directory"){let u=!this.noChmod&&e.mode&&(o.mode&4095)!==e.mode,[A]=u?Fx(()=>{vn.chmodSync(e.absolute,e.mode)}):[];return this[tc](A,e)}let[n]=Fx(()=>vn.rmdirSync(e.absolute));this[tc](n,e)}let[a]=e.absolute===this.cwd?[]:Fx(()=>Kct(e.absolute));this[tc](a,e)}[j3](e,r){let o=e.mode&4095||this.fmode,a=A=>{let p;try{vn.closeSync(n)}catch(h){p=h}(A||p)&&this[To](A||p,e),r()},n;try{n=vn.openSync(e.absolute,Ufe(e.size),o)}catch(A){return a(A)}let u=this.transform&&this.transform(e)||e;u!==e&&(u.on("error",A=>this[To](A,e)),e.pipe(u)),u.on("data",A=>{try{vn.writeSync(n,A,0,A.length)}catch(p){a(p)}}),u.on("end",A=>{let p=null;if(e.mtime&&!this.noMtime){let h=e.atime||new Date,E=e.mtime;try{vn.futimesSync(n,h,E)}catch(I){try{vn.utimesSync(e.absolute,h,E)}catch{p=I}}}if(this[N1](e)){let h=this[L1](e),E=this[M1](e);try{vn.fchownSync(n,h,E)}catch(I){try{vn.chownSync(e.absolute,h,E)}catch{p=p||I}}}a(p)})}[G3](e,r){let o=e.mode&4095||this.dmode,a=this[Bh](e.absolute,o);if(a){this[To](a,e),r();return}if(e.mtime&&!this.noMtime)try{vn.utimesSync(e.absolute,e.atime||new Date,e.mtime)}catch{}if(this[N1](e))try{vn.chownSync(e.absolute,this[L1](e),this[M1](e))}catch{}r(),e.resume()}[Bh](e,r){try{return Mfe.sync(pl(e),{uid:this.uid,gid:this.gid,processUid:this.processUid,processGid:this.processGid,umask:this.processUmask,preserve:this.preservePaths,unlink:this.unlink,cache:this.dirCache,cwd:this.cwd,mode:r})}catch(o){return o}}[Tx](e,r,o,a){try{vn[o+"Sync"](r,e.absolute),a(),e.resume()}catch(n){return this[To](n,e)}}};_1.Sync=W3;_fe.exports=_1});var Yfe=_((FUt,Gfe)=>{"use strict";var Jct=Ay(),Nx=K3(),qfe=ve("fs"),jfe=Sy(),Hfe=ve("path"),V3=Ey();Gfe.exports=(t,e,r)=>{typeof t=="function"?(r=t,e=null,t={}):Array.isArray(t)&&(e=t,t={}),typeof e=="function"&&(r=e,e=null),e?e=Array.from(e):e=[];let o=Jct(t);if(o.sync&&typeof r=="function")throw new TypeError("callback not supported for sync tar functions");if(!o.file&&typeof r=="function")throw new TypeError("callback only supported with file option");return e.length&&Xct(o,e),o.file&&o.sync?Zct(o):o.file?$ct(o,r):o.sync?eut(o):tut(o)};var Xct=(t,e)=>{let r=new Map(e.map(n=>[V3(n),!0])),o=t.filter,a=(n,u)=>{let A=u||Hfe.parse(n).root||".",p=n===A?!1:r.has(n)?r.get(n):a(Hfe.dirname(n),A);return r.set(n,p),p};t.filter=o?(n,u)=>o(n,u)&&a(V3(n)):n=>a(V3(n))},Zct=t=>{let e=new Nx.Sync(t),r=t.file,o=qfe.statSync(r),a=t.maxReadSize||16*1024*1024;new jfe.ReadStreamSync(r,{readSize:a,size:o.size}).pipe(e)},$ct=(t,e)=>{let r=new Nx(t),o=t.maxReadSize||16*1024*1024,a=t.file,n=new Promise((u,A)=>{r.on("error",A),r.on("close",u),qfe.stat(a,(p,h)=>{if(p)A(p);else{let E=new jfe.ReadStream(a,{readSize:o,size:h.size});E.on("error",A),E.pipe(r)}})});return e?n.then(e,e):n},eut=t=>new Nx.Sync(t),tut=t=>new Nx(t)});var Wfe=_(As=>{"use strict";As.c=As.create=bAe();As.r=As.replace=x3();As.t=As.list=Bx();As.u=As.update=LAe();As.x=As.extract=Yfe();As.Pack=lx();As.Unpack=K3();As.Parse=Ix();As.ReadEntry=YS();As.WriteEntry=i3();As.Header=yy();As.Pax=KS();As.types=_U()});var z3,Kfe,vh,H1,q1,Vfe=Et(()=>{z3=Ze(eg()),Kfe=ve("worker_threads"),vh=Symbol("kTaskInfo"),H1=class{constructor(e,r){this.fn=e;this.limit=(0,z3.default)(r.poolSize)}run(e){return this.limit(()=>this.fn(e))}},q1=class{constructor(e,r){this.source=e;this.workers=[];this.limit=(0,z3.default)(r.poolSize),this.cleanupInterval=setInterval(()=>{if(this.limit.pendingCount===0&&this.limit.activeCount===0){let o=this.workers.pop();o?o.terminate():clearInterval(this.cleanupInterval)}},5e3).unref()}createWorker(){this.cleanupInterval.refresh();let e=new Kfe.Worker(this.source,{eval:!0,execArgv:[...process.execArgv,"--unhandled-rejections=strict"]});return e.on("message",r=>{if(!e[vh])throw new Error("Assertion failed: Worker sent a result without having a task assigned");e[vh].resolve(r),e[vh]=null,e.unref(),this.workers.push(e)}),e.on("error",r=>{e[vh]?.reject(r),e[vh]=null}),e.on("exit",r=>{r!==0&&e[vh]?.reject(new Error(`Worker exited with code ${r}`)),e[vh]=null}),e}run(e){return this.limit(()=>{let r=this.workers.pop()??this.createWorker();return r.ref(),new Promise((o,a)=>{r[vh]={resolve:o,reject:a},r.postMessage(e)})})}}});var Jfe=_((LUt,zfe)=>{var J3;zfe.exports.getContent=()=>(typeof J3>"u"&&(J3=ve("zlib").brotliDecompressSync(Buffer.from("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","base64")).toString()),J3)});var $i={};Vt($i,{convertToZip:()=>sut,convertToZipWorker:()=>$3,extractArchiveTo:()=>tpe,getDefaultTaskPool:()=>$fe,getTaskPoolForConfiguration:()=>epe,makeArchiveFromDirectory:()=>iut});function rut(t,e){switch(t){case"async":return new H1($3,{poolSize:e});case"workers":return new q1((0,Z3.getContent)(),{poolSize:e});default:throw new Error(`Assertion failed: Unknown value ${t} for taskPoolMode`)}}function $fe(){return typeof X3>"u"&&(X3=rut("workers",Xi.availableParallelism())),X3}function epe(t){return typeof t>"u"?$fe():al(nut,t,()=>{let e=t.get("taskPoolMode"),r=t.get("taskPoolConcurrency");switch(e){case"async":return new H1($3,{poolSize:r});case"workers":return new q1((0,Z3.getContent)(),{poolSize:r});default:throw new Error(`Assertion failed: Unknown value ${e} for taskPoolMode`)}})}async function $3(t){let{tmpFile:e,tgz:r,compressionLevel:o,extractBufferOpts:a}=t,n=new Zi(e,{create:!0,level:o,stats:wa.makeDefaultStats()}),u=Buffer.from(r.buffer,r.byteOffset,r.byteLength);return await tpe(u,n,a),n.saveAndClose(),e}async function iut(t,{baseFs:e=new Tn,prefixPath:r=It.root,compressionLevel:o,inMemory:a=!1}={}){let n;if(a)n=new Zi(null,{level:o});else{let A=await oe.mktempPromise(),p=V.join(A,"archive.zip");n=new Zi(p,{create:!0,level:o})}let u=V.resolve(It.root,r);return await n.copyPromise(u,t,{baseFs:e,stableTime:!0,stableSort:!0}),n}async function sut(t,e={}){let r=await oe.mktempPromise(),o=V.join(r,"archive.zip"),a=e.compressionLevel??e.configuration?.get("compressionLevel")??"mixed",n={prefixPath:e.prefixPath,stripComponents:e.stripComponents};return await(e.taskPool??epe(e.configuration)).run({tmpFile:o,tgz:t,compressionLevel:a,extractBufferOpts:n}),new Zi(o,{level:e.compressionLevel})}async function*out(t){let e=new Zfe.default.Parse,r=new Xfe.PassThrough({objectMode:!0,autoDestroy:!0,emitClose:!0});e.on("entry",o=>{r.write(o)}),e.on("error",o=>{r.destroy(o)}),e.on("close",()=>{r.destroyed||r.end()}),e.end(t);for await(let o of r){let a=o;yield a,a.resume()}}async function tpe(t,e,{stripComponents:r=0,prefixPath:o=It.dot}={}){function a(n){if(n.path[0]==="/")return!0;let u=n.path.split(/\//g);return!!(u.some(A=>A==="..")||u.length<=r)}for await(let n of out(t)){if(a(n))continue;let u=V.normalize(ue.toPortablePath(n.path)).replace(/\/$/,"").split(/\//g);if(u.length<=r)continue;let A=u.slice(r).join("/"),p=V.join(o,A),h=420;switch((n.type==="Directory"||(n.mode??0)&73)&&(h|=73),n.type){case"Directory":e.mkdirpSync(V.dirname(p),{chmod:493,utimes:[Bi.SAFE_TIME,Bi.SAFE_TIME]}),e.mkdirSync(p,{mode:h}),e.utimesSync(p,Bi.SAFE_TIME,Bi.SAFE_TIME);break;case"OldFile":case"File":e.mkdirpSync(V.dirname(p),{chmod:493,utimes:[Bi.SAFE_TIME,Bi.SAFE_TIME]}),e.writeFileSync(p,await km(n),{mode:h}),e.utimesSync(p,Bi.SAFE_TIME,Bi.SAFE_TIME);break;case"SymbolicLink":e.mkdirpSync(V.dirname(p),{chmod:493,utimes:[Bi.SAFE_TIME,Bi.SAFE_TIME]}),e.symlinkSync(n.linkpath,p),e.lutimesSync(p,Bi.SAFE_TIME,Bi.SAFE_TIME);break}}return e}var Xfe,Zfe,Z3,X3,nut,rpe=Et(()=>{Ge();Pt();nA();Xfe=ve("stream"),Zfe=Ze(Wfe());Vfe();ql();Z3=Ze(Jfe());nut=new WeakMap});var ipe=_((e_,npe)=>{(function(t,e){typeof e_=="object"?npe.exports=e():typeof define=="function"&&define.amd?define(e):t.treeify=e()})(e_,function(){function t(a,n){var u=n?"\u2514":"\u251C";return a?u+="\u2500 ":u+="\u2500\u2500\u2510",u}function e(a,n){var u=[];for(var A in a)a.hasOwnProperty(A)&&(n&&typeof a[A]=="function"||u.push(A));return u}function r(a,n,u,A,p,h,E){var I="",v=0,x,C,R=A.slice(0);if(R.push([n,u])&&A.length>0&&(A.forEach(function(U,z){z>0&&(I+=(U[1]?" ":"\u2502")+" "),!C&&U[0]===n&&(C=!0)}),I+=t(a,u)+a,p&&(typeof n!="object"||n instanceof Date)&&(I+=": "+n),C&&(I+=" (circular ref.)"),E(I)),!C&&typeof n=="object"){var L=e(n,h);L.forEach(function(U){x=++v===L.length,r(U,n[U],x,R,p,h,E)})}}var o={};return o.asLines=function(a,n,u,A){var p=typeof u!="function"?u:!1;r(".",a,!1,[],n,p,A||u)},o.asTree=function(a,n,u){var A="";return r(".",a,!1,[],n,u,function(p){A+=p+` +`}),A},o})});var fs={};Vt(fs,{emitList:()=>aut,emitTree:()=>lpe,treeNodeToJson:()=>ape,treeNodeToTreeify:()=>ope});function ope(t,{configuration:e}){let r={},o=0,a=(n,u)=>{let A=Array.isArray(n)?n.entries():Object.entries(n);for(let[p,h]of A){if(!h)continue;let{label:E,value:I,children:v}=h,x=[];typeof E<"u"&&x.push(fg(e,E,2)),typeof I<"u"&&x.push(Ot(e,I[0],I[1])),x.length===0&&x.push(fg(e,`${p}`,2));let C=x.join(": ").trim(),R=`\0${o++}\0`,L=u[`${R}${C}`]={};typeof v<"u"&&a(v,L)}};if(typeof t.children>"u")throw new Error("The root node must only contain children");return a(t.children,r),r}function ape(t){let e=r=>{if(typeof r.children>"u"){if(typeof r.value>"u")throw new Error("Assertion failed: Expected a value to be set if the children are missing");return pg(r.value[0],r.value[1])}let o=Array.isArray(r.children)?r.children.entries():Object.entries(r.children??{}),a=Array.isArray(r.children)?[]:{};for(let[n,u]of o)u&&(a[lut(n)]=e(u));return typeof r.value>"u"?a:{value:pg(r.value[0],r.value[1]),children:a}};return e(t)}function aut(t,{configuration:e,stdout:r,json:o}){let a=t.map(n=>({value:n}));lpe({children:a},{configuration:e,stdout:r,json:o})}function lpe(t,{configuration:e,stdout:r,json:o,separators:a=0}){if(o){let u=Array.isArray(t.children)?t.children.values():Object.values(t.children??{});for(let A of u)A&&r.write(`${JSON.stringify(ape(A))} +`);return}let n=(0,spe.asTree)(ope(t,{configuration:e}),!1,!1);if(n=n.replace(/\0[0-9]+\0/g,""),a>=1&&(n=n.replace(/^([├└]─)/gm,`\u2502 +$1`).replace(/^│\n/,"")),a>=2)for(let u=0;u<2;++u)n=n.replace(/^([│ ].{2}[├│ ].{2}[^\n]+\n)(([│ ]).{2}[├└].{2}[^\n]*\n[│ ].{2}[│ ].{2}[├└]─)/gm,`$1$3 \u2502 +$2`).replace(/^│\n/,"");if(a>=3)throw new Error("Only the first two levels are accepted by treeUtils.emitTree");r.write(n)}function lut(t){return typeof t=="string"?t.replace(/^\0[0-9]+\0/,""):t}var spe,cpe=Et(()=>{spe=Ze(ipe());jl()});function j1(t){let e=t.match(cut);if(!e?.groups)throw new Error("Assertion failed: Expected the checksum to match the requested pattern");let r=e.groups.cacheVersion?parseInt(e.groups.cacheVersion):null;return{cacheKey:e.groups.cacheKey??null,cacheVersion:r,cacheSpec:e.groups.cacheSpec??null,hash:e.groups.hash}}var upe,t_,r_,Lx,Gr,cut,n_=Et(()=>{Ge();Pt();Pt();nA();upe=ve("crypto"),t_=Ze(ve("fs"));Wl();th();ql();So();r_=Qm(process.env.YARN_CACHE_CHECKPOINT_OVERRIDE??process.env.YARN_CACHE_VERSION_OVERRIDE??9),Lx=Qm(process.env.YARN_CACHE_VERSION_OVERRIDE??10),Gr=class t{constructor(e,{configuration:r,immutable:o=r.get("enableImmutableCache"),check:a=!1}){this.markedFiles=new Set;this.mutexes=new Map;this.cacheId=`-${(0,upe.randomBytes)(8).toString("hex")}.tmp`;this.configuration=r,this.cwd=e,this.immutable=o,this.check=a;let{cacheSpec:n,cacheKey:u}=t.getCacheKey(r);this.cacheSpec=n,this.cacheKey=u}static async find(e,{immutable:r,check:o}={}){let a=new t(e.get("cacheFolder"),{configuration:e,immutable:r,check:o});return await a.setup(),a}static getCacheKey(e){let r=e.get("compressionLevel"),o=r!=="mixed"?`c${r}`:"";return{cacheKey:[Lx,o].join(""),cacheSpec:o}}get mirrorCwd(){if(!this.configuration.get("enableMirror"))return null;let e=`${this.configuration.get("globalFolder")}/cache`;return e!==this.cwd?e:null}getVersionFilename(e){return`${Hm(e)}-${this.cacheKey}.zip`}getChecksumFilename(e,r){let a=j1(r).hash.slice(0,10);return`${Hm(e)}-${a}.zip`}isChecksumCompatible(e){if(e===null)return!1;let{cacheVersion:r,cacheSpec:o}=j1(e);if(r===null||r{let de=new Zi,Be=V.join(It.root,zM(e));return de.mkdirSync(Be,{recursive:!0}),de.writeJsonSync(V.join(Be,dr.manifest),{name:rn(e),mocked:!0}),de},E=async(de,{isColdHit:Be,controlPath:Ee=null})=>{if(Ee===null&&u.unstablePackages?.has(e.locatorHash))return{isValid:!0,hash:null};let g=r&&!Be?j1(r).cacheKey:this.cacheKey,me=!u.skipIntegrityCheck||!r?`${g}/${await Ib(de)}`:r;if(Ee!==null){let Ae=!u.skipIntegrityCheck||!r?`${this.cacheKey}/${await Ib(Ee)}`:r;if(me!==Ae)throw new Jt(18,"The remote archive doesn't match the local checksum - has the local cache been corrupted?")}let we=null;switch(r!==null&&me!==r&&(this.check?we="throw":j1(r).cacheKey!==j1(me).cacheKey?we="update":we=this.configuration.get("checksumBehavior")),we){case null:case"update":return{isValid:!0,hash:me};case"ignore":return{isValid:!0,hash:r};case"reset":return{isValid:!1,hash:r};default:case"throw":throw new Jt(18,"The remote archive doesn't match the expected checksum")}},I=async de=>{if(!n)throw new Error(`Cache check required but no loader configured for ${qr(this.configuration,e)}`);let Be=await n(),Ee=Be.getRealPath();Be.saveAndClose(),await oe.chmodPromise(Ee,420);let g=await E(de,{controlPath:Ee,isColdHit:!1});if(!g.isValid)throw new Error("Assertion failed: Expected a valid checksum");return g.hash},v=async()=>{if(A===null||!await oe.existsPromise(A)){let de=await n(),Be=de.getRealPath();return de.saveAndClose(),{source:"loader",path:Be}}return{source:"mirror",path:A}},x=async()=>{if(!n)throw new Error(`Cache entry required but missing for ${qr(this.configuration,e)}`);if(this.immutable)throw new Jt(56,`Cache entry required but missing for ${qr(this.configuration,e)}`);let{path:de,source:Be}=await v(),{hash:Ee}=await E(de,{isColdHit:!0}),g=this.getLocatorPath(e,Ee),me=[];Be!=="mirror"&&A!==null&&me.push(async()=>{let Ae=`${A}${this.cacheId}`;await oe.copyFilePromise(de,Ae,t_.default.constants.COPYFILE_FICLONE),await oe.chmodPromise(Ae,420),await oe.renamePromise(Ae,A)}),(!u.mirrorWriteOnly||A===null)&&me.push(async()=>{let Ae=`${g}${this.cacheId}`;await oe.copyFilePromise(de,Ae,t_.default.constants.COPYFILE_FICLONE),await oe.chmodPromise(Ae,420),await oe.renamePromise(Ae,g)});let we=u.mirrorWriteOnly?A??g:g;return await Promise.all(me.map(Ae=>Ae())),[!1,we,Ee]},C=async()=>{let Be=(async()=>{let Ee=u.unstablePackages?.has(e.locatorHash),g=Ee||!r||this.isChecksumCompatible(r)?this.getLocatorPath(e,r):null,me=g!==null?this.markedFiles.has(g)||await p.existsPromise(g):!1,we=!!u.mockedPackages?.has(e.locatorHash)&&(!this.check||!me),Ae=we||me,ne=Ae?o:a;if(ne&&ne(),Ae){let Z=null,xe=g;if(!we)if(this.check)Z=await I(xe);else{let Ne=await E(xe,{isColdHit:!1});if(Ne.isValid)Z=Ne.hash;else return x()}return[we,xe,Z]}else{if(this.immutable&&Ee)throw new Jt(56,`Cache entry required but missing for ${qr(this.configuration,e)}; consider defining ${pe.pretty(this.configuration,"supportedArchitectures",pe.Type.CODE)} to cache packages for multiple systems`);return x()}})();this.mutexes.set(e.locatorHash,Be);try{return await Be}finally{this.mutexes.delete(e.locatorHash)}};for(let de;de=this.mutexes.get(e.locatorHash);)await de;let[R,L,U]=await C();R||this.markedFiles.add(L);let z,te=R?()=>h():()=>new Zi(L,{baseFs:p,readOnly:!0}),ae=new Gd(()=>uL(()=>z=te(),de=>`Failed to open the cache entry for ${qr(this.configuration,e)}: ${de}`),V),le=new Hu(L,{baseFs:ae,pathUtils:V}),ce=()=>{z?.discardAndClose()},Ce=u.unstablePackages?.has(e.locatorHash)?null:U;return[le,ce,Ce]}},cut=/^(?:(?(?[0-9]+)(?.*))\/)?(?.*)$/});var Mx,Ape=Et(()=>{Mx=(r=>(r[r.SCRIPT=0]="SCRIPT",r[r.SHELLCODE=1]="SHELLCODE",r))(Mx||{})});var uut,Ty,i_=Et(()=>{Pt();Nl();Sf();So();uut=[[/^(git(?:\+(?:https|ssh))?:\/\/.*(?:\.git)?)#(.*)$/,(t,e,r,o)=>`${r}#commit=${o}`],[/^https:\/\/((?:[^/]+?)@)?codeload\.github\.com\/([^/]+\/[^/]+)\/tar\.gz\/([0-9a-f]+)$/,(t,e,r="",o,a)=>`https://${r}github.com/${o}.git#commit=${a}`],[/^https:\/\/((?:[^/]+?)@)?github\.com\/([^/]+\/[^/]+?)(?:\.git)?#([0-9a-f]+)$/,(t,e,r="",o,a)=>`https://${r}github.com/${o}.git#commit=${a}`],[/^https?:\/\/[^/]+\/(?:[^/]+\/)*(?:@.+(?:\/|(?:%2f)))?([^/]+)\/(?:-|download)\/\1-[^/]+\.tgz(?:#|$)/,t=>`npm:${t}`],[/^https:\/\/npm\.pkg\.github\.com\/download\/(?:@[^/]+)\/(?:[^/]+)\/(?:[^/]+)\/(?:[0-9a-f]+)(?:#|$)/,t=>`npm:${t}`],[/^https:\/\/npm\.fontawesome\.com\/(?:@[^/]+)\/([^/]+)\/-\/([^/]+)\/\1-\2.tgz(?:#|$)/,t=>`npm:${t}`],[/^https?:\/\/[^/]+\/.*\/(@[^/]+)\/([^/]+)\/-\/\1\/\2-(?:[.\d\w-]+)\.tgz(?:#|$)/,(t,e)=>bb({protocol:"npm:",source:null,selector:t,params:{__archiveUrl:e}})],[/^[^/]+\.tgz#[0-9a-f]+$/,t=>`npm:${t}`]],Ty=class{constructor(e){this.resolver=e;this.resolutions=null}async setup(e,{report:r}){let o=V.join(e.cwd,dr.lockfile);if(!oe.existsSync(o))return;let a=await oe.readFilePromise(o,"utf8"),n=Ki(a);if(Object.hasOwn(n,"__metadata"))return;let u=this.resolutions=new Map;for(let A of Object.keys(n)){let p=jI(A);if(!p){r.reportWarning(14,`Failed to parse the string "${A}" into a proper descriptor`);continue}let h=Qa(p.range)?In(p,`npm:${p.range}`):p,{version:E,resolved:I}=n[A];if(!I)continue;let v;for(let[C,R]of uut){let L=I.match(C);if(L){v=R(E,...L);break}}if(!v){r.reportWarning(14,`${jn(e.configuration,h)}: Only some patterns can be imported from legacy lockfiles (not "${I}")`);continue}let x=h;try{let C=dg(h.range),R=jI(C.selector,!0);R&&(x=R)}catch{}u.set(h.descriptorHash,Rs(x,v))}}supportsDescriptor(e,r){return this.resolutions?this.resolutions.has(e.descriptorHash):!1}supportsLocator(e,r){return!1}shouldPersistResolution(e,r){throw new Error("Assertion failed: This resolver doesn't support resolving locators to packages")}bindDescriptor(e,r,o){return e}getResolutionDependencies(e,r){return{}}async getCandidates(e,r,o){if(!this.resolutions)throw new Error("Assertion failed: The resolution store should have been setup");let a=this.resolutions.get(e.descriptorHash);if(!a)throw new Error("Assertion failed: The resolution should have been registered");let n=YM(a),u=o.project.configuration.normalizeDependency(n);return await this.resolver.getCandidates(u,r,o)}async getSatisfying(e,r,o,a){let[n]=await this.getCandidates(e,r,a);return{locators:o.filter(u=>u.locatorHash===n.locatorHash),sorted:!1}}async resolve(e,r){throw new Error("Assertion failed: This resolver doesn't support resolving locators to packages")}}});var AA,fpe=Et(()=>{Wl();I1();jl();AA=class extends Zs{constructor({configuration:r,stdout:o,suggestInstall:a=!0}){super();this.errorCount=0;TI(this,{configuration:r}),this.configuration=r,this.stdout=o,this.suggestInstall=a}static async start(r,o){let a=new this(r);try{await o(a)}catch(n){a.reportExceptionOnce(n)}finally{await a.finalize()}return a}hasErrors(){return this.errorCount>0}exitCode(){return this.hasErrors()?1:0}reportCacheHit(r){}reportCacheMiss(r){}startSectionSync(r,o){return o()}async startSectionPromise(r,o){return await o()}startTimerSync(r,o,a){return(typeof o=="function"?o:a)()}async startTimerPromise(r,o,a){return await(typeof o=="function"?o:a)()}reportSeparator(){}reportInfo(r,o){}reportWarning(r,o){}reportError(r,o){this.errorCount+=1,this.stdout.write(`${Ot(this.configuration,"\u27A4","redBright")} ${this.formatNameWithHyperlink(r)}: ${o} +`)}reportProgress(r){return{...Promise.resolve().then(async()=>{for await(let{}of r);}),stop:()=>{}}}reportJson(r){}reportFold(r,o){}async finalize(){this.errorCount>0&&(this.stdout.write(` +`),this.stdout.write(`${Ot(this.configuration,"\u27A4","redBright")} Errors happened when preparing the environment required to run this command. +`),this.suggestInstall&&this.stdout.write(`${Ot(this.configuration,"\u27A4","redBright")} This might be caused by packages being missing from the lockfile, in which case running "yarn install" might help. +`))}formatNameWithHyperlink(r){return AU(r,{configuration:this.configuration,json:!1})}}});var Ny,s_=Et(()=>{So();Ny=class{constructor(e){this.resolver=e}supportsDescriptor(e,r){return!!(r.project.storedResolutions.get(e.descriptorHash)||r.project.originalPackages.has(vb(e).locatorHash))}supportsLocator(e,r){return!!(r.project.originalPackages.has(e.locatorHash)&&!r.project.lockfileNeedsRefresh)}shouldPersistResolution(e,r){throw new Error("The shouldPersistResolution method shouldn't be called on the lockfile resolver, which would always answer yes")}bindDescriptor(e,r,o){return e}getResolutionDependencies(e,r){return this.resolver.getResolutionDependencies(e,r)}async getCandidates(e,r,o){let a=o.project.storedResolutions.get(e.descriptorHash);if(a){let u=o.project.originalPackages.get(a);if(u)return[u]}let n=o.project.originalPackages.get(vb(e).locatorHash);if(n)return[n];throw new Error("Resolution expected from the lockfile data")}async getSatisfying(e,r,o,a){let[n]=await this.getCandidates(e,r,a);return{locators:o.filter(u=>u.locatorHash===n.locatorHash),sorted:!1}}async resolve(e,r){let o=r.project.originalPackages.get(e.locatorHash);if(!o)throw new Error("The lockfile resolver isn't meant to resolve packages - they should already have been stored into a cache");return o}}});function Gf(){}function Aut(t,e,r,o,a){for(var n=0,u=e.length,A=0,p=0;nx.length?R:x}),h.value=t.join(E)}else h.value=t.join(r.slice(A,A+h.count));A+=h.count,h.added||(p+=h.count)}}var v=e[u-1];return u>1&&typeof v.value=="string"&&(v.added||v.removed)&&t.equals("",v.value)&&(e[u-2].value+=v.value,e.pop()),e}function fut(t){return{newPos:t.newPos,components:t.components.slice(0)}}function put(t,e){if(typeof t=="function")e.callback=t;else if(t)for(var r in t)t.hasOwnProperty(r)&&(e[r]=t[r]);return e}function gpe(t,e,r){return r=put(r,{ignoreWhitespace:!0}),u_.diff(t,e,r)}function hut(t,e,r){return A_.diff(t,e,r)}function Ox(t){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?Ox=function(e){return typeof e}:Ox=function(e){return e&&typeof Symbol=="function"&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},Ox(t)}function o_(t){return mut(t)||yut(t)||Eut(t)||Cut()}function mut(t){if(Array.isArray(t))return a_(t)}function yut(t){if(typeof Symbol<"u"&&Symbol.iterator in Object(t))return Array.from(t)}function Eut(t,e){if(t){if(typeof t=="string")return a_(t,e);var r=Object.prototype.toString.call(t).slice(8,-1);if(r==="Object"&&t.constructor&&(r=t.constructor.name),r==="Map"||r==="Set")return Array.from(t);if(r==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return a_(t,e)}}function a_(t,e){(e==null||e>t.length)&&(e=t.length);for(var r=0,o=new Array(e);r"u"&&(u.context=4);var A=hut(r,o,u);if(!A)return;A.push({value:"",lines:[]});function p(U){return U.map(function(z){return" "+z})}for(var h=[],E=0,I=0,v=[],x=1,C=1,R=function(z){var te=A[z],ae=te.lines||te.value.replace(/\n$/,"").split(` +`);if(te.lines=ae,te.added||te.removed){var le;if(!E){var ce=A[z-1];E=x,I=C,ce&&(v=u.context>0?p(ce.lines.slice(-u.context)):[],E-=v.length,I-=v.length)}(le=v).push.apply(le,o_(ae.map(function(Ae){return(te.added?"+":"-")+Ae}))),te.added?C+=ae.length:x+=ae.length}else{if(E)if(ae.length<=u.context*2&&z=A.length-2&&ae.length<=u.context){var g=/\n$/.test(r),me=/\n$/.test(o),we=ae.length==0&&v.length>Ee.oldLines;!g&&we&&r.length>0&&v.splice(Ee.oldLines,0,"\\ No newline at end of file"),(!g&&!we||!me)&&v.push("\\ No newline at end of file")}h.push(Ee),E=0,I=0,v=[]}x+=ae.length,C+=ae.length}},L=0;L{Gf.prototype={diff:function(e,r){var o=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{},a=o.callback;typeof o=="function"&&(a=o,o={}),this.options=o;var n=this;function u(R){return a?(setTimeout(function(){a(void 0,R)},0),!0):R}e=this.castInput(e),r=this.castInput(r),e=this.removeEmpty(this.tokenize(e)),r=this.removeEmpty(this.tokenize(r));var A=r.length,p=e.length,h=1,E=A+p;o.maxEditLength&&(E=Math.min(E,o.maxEditLength));var I=[{newPos:-1,components:[]}],v=this.extractCommon(I[0],r,e,0);if(I[0].newPos+1>=A&&v+1>=p)return u([{value:this.join(r),count:r.length}]);function x(){for(var R=-1*h;R<=h;R+=2){var L=void 0,U=I[R-1],z=I[R+1],te=(z?z.newPos:0)-R;U&&(I[R-1]=void 0);var ae=U&&U.newPos+1=A&&te+1>=p)return u(Aut(n,L.components,r,e,n.useLongestToken));I[R]=L}h++}if(a)(function R(){setTimeout(function(){if(h>E)return a();x()||R()},0)})();else for(;h<=E;){var C=x();if(C)return C}},pushComponent:function(e,r,o){var a=e[e.length-1];a&&a.added===r&&a.removed===o?e[e.length-1]={count:a.count+1,added:r,removed:o}:e.push({count:1,added:r,removed:o})},extractCommon:function(e,r,o,a){for(var n=r.length,u=o.length,A=e.newPos,p=A-a,h=0;A+1"u"?r:u}:o;return typeof t=="string"?t:JSON.stringify(l_(t,null,null,a),a," ")};G1.equals=function(t,e){return Gf.prototype.equals.call(G1,t.replace(/,([\r\n])/g,"$1"),e.replace(/,([\r\n])/g,"$1"))};c_=new Gf;c_.tokenize=function(t){return t.slice()};c_.join=c_.removeEmpty=function(t){return t}});var ype=_((A3t,mpe)=>{var Iut=Hl(),But=Ym(),vut=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,Dut=/^\w*$/;function Put(t,e){if(Iut(t))return!1;var r=typeof t;return r=="number"||r=="symbol"||r=="boolean"||t==null||But(t)?!0:Dut.test(t)||!vut.test(t)||e!=null&&t in Object(e)}mpe.exports=Put});var wpe=_((f3t,Cpe)=>{var Epe=PP(),but="Expected a function";function p_(t,e){if(typeof t!="function"||e!=null&&typeof e!="function")throw new TypeError(but);var r=function(){var o=arguments,a=e?e.apply(this,o):o[0],n=r.cache;if(n.has(a))return n.get(a);var u=t.apply(this,o);return r.cache=n.set(a,u)||n,u};return r.cache=new(p_.Cache||Epe),r}p_.Cache=Epe;Cpe.exports=p_});var Bpe=_((p3t,Ipe)=>{var Sut=wpe(),xut=500;function kut(t){var e=Sut(t,function(o){return r.size===xut&&r.clear(),o}),r=e.cache;return e}Ipe.exports=kut});var h_=_((h3t,vpe)=>{var Qut=Bpe(),Fut=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,Rut=/\\(\\)?/g,Tut=Qut(function(t){var e=[];return t.charCodeAt(0)===46&&e.push(""),t.replace(Fut,function(r,o,a,n){e.push(a?n.replace(Rut,"$1"):o||r)}),e});vpe.exports=Tut});var Mg=_((g3t,Dpe)=>{var Nut=Hl(),Lut=ype(),Mut=h_(),Out=C1();function Uut(t,e){return Nut(t)?t:Lut(t,e)?[t]:Mut(Out(t))}Dpe.exports=Uut});var Ly=_((d3t,Ppe)=>{var _ut=Ym(),Hut=1/0;function qut(t){if(typeof t=="string"||_ut(t))return t;var e=t+"";return e=="0"&&1/t==-Hut?"-0":e}Ppe.exports=qut});var Ux=_((m3t,bpe)=>{var jut=Mg(),Gut=Ly();function Yut(t,e){e=jut(e,t);for(var r=0,o=e.length;t!=null&&r{var Wut=qP(),Kut=Mg(),Vut=II(),Spe=sl(),zut=Ly();function Jut(t,e,r,o){if(!Spe(t))return t;e=Kut(e,t);for(var a=-1,n=e.length,u=n-1,A=t;A!=null&&++a{var Xut=Ux(),Zut=g_(),$ut=Mg();function eAt(t,e,r){for(var o=-1,a=e.length,n={};++o{function tAt(t,e){return t!=null&&e in Object(t)}Fpe.exports=tAt});var d_=_((w3t,Tpe)=>{var rAt=Mg(),nAt=EI(),iAt=Hl(),sAt=II(),oAt=QP(),aAt=Ly();function lAt(t,e,r){e=rAt(e,t);for(var o=-1,a=e.length,n=!1;++o{var cAt=Rpe(),uAt=d_();function AAt(t,e){return t!=null&&uAt(t,e,cAt)}Npe.exports=AAt});var Ope=_((B3t,Mpe)=>{var fAt=Qpe(),pAt=Lpe();function hAt(t,e){return fAt(t,e,function(r,o){return pAt(t,o)})}Mpe.exports=hAt});var qpe=_((v3t,Hpe)=>{var Upe=lg(),gAt=EI(),dAt=Hl(),_pe=Upe?Upe.isConcatSpreadable:void 0;function mAt(t){return dAt(t)||gAt(t)||!!(_pe&&t&&t[_pe])}Hpe.exports=mAt});var Ype=_((D3t,Gpe)=>{var yAt=xP(),EAt=qpe();function jpe(t,e,r,o,a){var n=-1,u=t.length;for(r||(r=EAt),a||(a=[]);++n0&&r(A)?e>1?jpe(A,e-1,r,o,a):yAt(a,A):o||(a[a.length]=A)}return a}Gpe.exports=jpe});var Kpe=_((P3t,Wpe)=>{var CAt=Ype();function wAt(t){var e=t==null?0:t.length;return e?CAt(t,1):[]}Wpe.exports=wAt});var m_=_((b3t,Vpe)=>{var IAt=Kpe(),BAt=rL(),vAt=nL();function DAt(t){return vAt(BAt(t,void 0,IAt),t+"")}Vpe.exports=DAt});var y_=_((S3t,zpe)=>{var PAt=Ope(),bAt=m_(),SAt=bAt(function(t,e){return t==null?{}:PAt(t,e)});zpe.exports=SAt});var _x,Jpe=Et(()=>{Wl();_x=class{constructor(e){this.resolver=e}supportsDescriptor(e,r){return this.resolver.supportsDescriptor(e,r)}supportsLocator(e,r){return this.resolver.supportsLocator(e,r)}shouldPersistResolution(e,r){return this.resolver.shouldPersistResolution(e,r)}bindDescriptor(e,r,o){return this.resolver.bindDescriptor(e,r,o)}getResolutionDependencies(e,r){return this.resolver.getResolutionDependencies(e,r)}async getCandidates(e,r,o){throw new Jt(20,`This package doesn't seem to be present in your lockfile; run "yarn install" to update the lockfile`)}async getSatisfying(e,r,o,a){throw new Jt(20,`This package doesn't seem to be present in your lockfile; run "yarn install" to update the lockfile`)}async resolve(e,r){throw new Jt(20,`This package doesn't seem to be present in your lockfile; run "yarn install" to update the lockfile`)}}});var ki,E_=Et(()=>{Wl();ki=class extends Zs{reportCacheHit(e){}reportCacheMiss(e){}startSectionSync(e,r){return r()}async startSectionPromise(e,r){return await r()}startTimerSync(e,r,o){return(typeof r=="function"?r:o)()}async startTimerPromise(e,r,o){return await(typeof r=="function"?r:o)()}reportSeparator(){}reportInfo(e,r){}reportWarning(e,r){}reportError(e,r){}reportProgress(e){return{...Promise.resolve().then(async()=>{for await(let{}of e);}),stop:()=>{}}}reportJson(e){}reportFold(e,r){}async finalize(){}}});var Xpe,My,C_=Et(()=>{Pt();Xpe=Ze(Cb());Gm();mg();jl();th();Sf();So();My=class{constructor(e,{project:r}){this.workspacesCwds=new Set;this.project=r,this.cwd=e}async setup(){this.manifest=await Ut.tryFind(this.cwd)??new Ut,this.relativeCwd=V.relative(this.project.cwd,this.cwd)||It.dot;let e=this.manifest.name?this.manifest.name:eA(null,`${this.computeCandidateName()}-${zi(this.relativeCwd).substring(0,6)}`);this.anchoredDescriptor=In(e,`${ei.protocol}${this.relativeCwd}`),this.anchoredLocator=Rs(e,`${ei.protocol}${this.relativeCwd}`);let r=this.manifest.workspaceDefinitions.map(({pattern:a})=>a);if(r.length===0)return;let o=await(0,Xpe.default)(r,{cwd:ue.fromPortablePath(this.cwd),onlyDirectories:!0,ignore:["**/node_modules","**/.git","**/.yarn"]});o.sort(),await o.reduce(async(a,n)=>{let u=V.resolve(this.cwd,ue.toPortablePath(n)),A=await oe.existsPromise(V.join(u,"package.json"));await a,A&&this.workspacesCwds.add(u)},Promise.resolve())}get anchoredPackage(){let e=this.project.storedPackages.get(this.anchoredLocator.locatorHash);if(!e)throw new Error(`Assertion failed: Expected workspace ${YI(this.project.configuration,this)} (${Ot(this.project.configuration,V.join(this.cwd,dr.manifest),yt.PATH)}) to have been resolved. Run "yarn install" to update the lockfile`);return e}accepts(e){let r=e.indexOf(":"),o=r!==-1?e.slice(0,r+1):null,a=r!==-1?e.slice(r+1):e;if(o===ei.protocol&&V.normalize(a)===this.relativeCwd||o===ei.protocol&&(a==="*"||a==="^"||a==="~"))return!0;let n=Qa(a);return n?o===ei.protocol?n.test(this.manifest.version??"0.0.0"):this.project.configuration.get("enableTransparentWorkspaces")&&this.manifest.version!==null?n.test(this.manifest.version):!1:!1}computeCandidateName(){return this.cwd===this.project.cwd?"root-workspace":`${V.basename(this.cwd)}`||"unnamed-workspace"}getRecursiveWorkspaceDependencies({dependencies:e=Ut.hardDependencies}={}){let r=new Set,o=a=>{for(let n of e)for(let u of a.manifest[n].values()){let A=this.project.tryWorkspaceByDescriptor(u);A===null||r.has(A)||(r.add(A),o(A))}};return o(this),r}getRecursiveWorkspaceDependents({dependencies:e=Ut.hardDependencies}={}){let r=new Set,o=a=>{for(let n of this.project.workspaces)e.some(A=>[...n.manifest[A].values()].some(p=>{let h=this.project.tryWorkspaceByDescriptor(p);return h!==null&&qI(h.anchoredLocator,a.anchoredLocator)}))&&!r.has(n)&&(r.add(n),o(n))};return o(this),r}getRecursiveWorkspaceChildren(){let e=new Set([this]);for(let r of e)for(let o of r.workspacesCwds){let a=this.project.workspacesByCwd.get(o);a&&e.add(a)}return e.delete(this),Array.from(e)}async persistManifest(){let e={};this.manifest.exportTo(e);let r=V.join(this.cwd,Ut.fileName),o=`${JSON.stringify(e,null,this.manifest.indent)} +`;await oe.changeFilePromise(r,o,{automaticNewlines:!0}),this.manifest.raw=e}}});function TAt({project:t,allDescriptors:e,allResolutions:r,allPackages:o,accessibleLocators:a=new Set,optionalBuilds:n=new Set,peerRequirements:u=new Map,peerWarnings:A=[],peerRequirementNodes:p=new Map,volatileDescriptors:h=new Set}){let E=new Map,I=[],v=new Map,x=new Map,C=new Map,R=new Map,L=new Map(t.workspaces.map(le=>{let ce=le.anchoredLocator.locatorHash,Ce=o.get(ce);if(typeof Ce>"u")throw new Error("Assertion failed: The workspace should have an associated package");return[ce,OI(Ce)]})),U=()=>{let le=oe.mktempSync(),ce=V.join(le,"stacktrace.log"),Ce=String(I.length+1).length,de=I.map((Be,Ee)=>`${`${Ee+1}.`.padStart(Ce," ")} ${ka(Be)} +`).join("");throw oe.writeFileSync(ce,de),oe.detachTemp(le),new Jt(45,`Encountered a stack overflow when resolving peer dependencies; cf ${ue.fromPortablePath(ce)}`)},z=le=>{let ce=r.get(le.descriptorHash);if(typeof ce>"u")throw new Error("Assertion failed: The resolution should have been registered");let Ce=o.get(ce);if(!Ce)throw new Error("Assertion failed: The package could not be found");return Ce},te=(le,ce,Ce,{top:de,optional:Be})=>{I.length>1e3&&U(),I.push(ce);let Ee=ae(le,ce,Ce,{top:de,optional:Be});return I.pop(),Ee},ae=(le,ce,Ce,{top:de,optional:Be})=>{if(Be||n.delete(ce.locatorHash),a.has(ce.locatorHash))return;a.add(ce.locatorHash);let Ee=o.get(ce.locatorHash);if(!Ee)throw new Error(`Assertion failed: The package (${qr(t.configuration,ce)}) should have been registered`);let g=[],me=new Map,we=[],Ae=[],ne=[],Z=[];for(let Ne of Array.from(Ee.dependencies.values())){if(Ee.peerDependencies.has(Ne.identHash)&&Ee.locatorHash!==de)continue;if(Pf(Ne))throw new Error("Assertion failed: Virtual packages shouldn't be encountered when virtualizing a branch");h.delete(Ne.descriptorHash);let ht=Be;if(!ht){let be=Ee.dependenciesMeta.get(rn(Ne));if(typeof be<"u"){let et=be.get(null);typeof et<"u"&&et.optional&&(ht=!0)}}let H=r.get(Ne.descriptorHash);if(!H)throw new Error(`Assertion failed: The resolution (${jn(t.configuration,Ne)}) should have been registered`);let rt=L.get(H)||o.get(H);if(!rt)throw new Error(`Assertion failed: The package (${H}, resolved from ${jn(t.configuration,Ne)}) should have been registered`);if(rt.peerDependencies.size===0){te(Ne,rt,new Map,{top:de,optional:ht});continue}let Te,Fe,ke=new Set,Ye=new Map;we.push(()=>{Te=KM(Ne,ce.locatorHash),Fe=VM(rt,ce.locatorHash),Ee.dependencies.delete(Ne.identHash),Ee.dependencies.set(Te.identHash,Te),r.set(Te.descriptorHash,Fe.locatorHash),e.set(Te.descriptorHash,Te),o.set(Fe.locatorHash,Fe),g.push([rt,Te,Fe])}),Ae.push(()=>{R.set(Fe.locatorHash,Ye);for(let be of Fe.peerDependencies.values()){let Ue=al(me,be.identHash,()=>{let S=Ce.get(be.identHash)??null,w=Ee.dependencies.get(be.identHash);return!w&&HI(ce,be)&&(le.identHash===ce.identHash?w=le:(w=In(ce,le.range),e.set(w.descriptorHash,w),r.set(w.descriptorHash,ce.locatorHash),h.delete(w.descriptorHash),S=null)),w||(w=In(be,"missing:")),{subject:ce,ident:be,provided:w,root:!S,requests:new Map,hash:`p${zi(ce.locatorHash,be.identHash).slice(0,5)}`}}).provided;if(Ue.range==="missing:"&&Fe.dependencies.has(be.identHash)){Fe.peerDependencies.delete(be.identHash);continue}Ye.set(be.identHash,{requester:Fe,descriptor:be,meta:Fe.peerDependenciesMeta.get(rn(be)),children:new Map}),Fe.dependencies.set(be.identHash,Ue),Pf(Ue)&&Sm(C,Ue.descriptorHash).add(Fe.locatorHash),v.set(Ue.identHash,Ue),Ue.range==="missing:"&&ke.add(Ue.identHash)}Fe.dependencies=new Map(Fs(Fe.dependencies,([be,et])=>rn(et)))}),ne.push(()=>{if(!o.has(Fe.locatorHash))return;let be=E.get(rt.locatorHash);typeof be=="number"&&be>=2&&U();let et=E.get(rt.locatorHash),Ue=typeof et<"u"?et+1:1;E.set(rt.locatorHash,Ue),te(Te,Fe,Ye,{top:de,optional:ht}),E.set(rt.locatorHash,Ue-1)}),Z.push(()=>{let be=Ee.dependencies.get(Ne.identHash);if(typeof be>"u")throw new Error("Assertion failed: Expected the peer dependency to have been turned into a dependency");let et=r.get(be.descriptorHash);if(typeof et>"u")throw new Error("Assertion failed: Expected the descriptor to be registered");let Ue=R.get(et);if(typeof Ue>"u")throw new Error("Assertion failed: Expected the peer requests to be registered");for(let S of me.values()){let w=Ue.get(S.ident.identHash);w&&(S.requests.set(be.descriptorHash,w),p.set(S.hash,S),S.root||Ce.get(S.ident.identHash)?.children.set(be.descriptorHash,w))}if(o.has(Fe.locatorHash))for(let S of ke)Fe.dependencies.delete(S)})}for(let Ne of[...we,...Ae])Ne();let xe;do{xe=!0;for(let[Ne,ht,H]of g){let rt=kI(x,Ne.locatorHash),Te=zi(...[...H.dependencies.values()].map(be=>{let et=be.range!=="missing:"?r.get(be.descriptorHash):"missing:";if(typeof et>"u")throw new Error(`Assertion failed: Expected the resolution for ${jn(t.configuration,be)} to have been registered`);return et===de?`${et} (top)`:et}),ht.identHash),Fe=rt.get(Te);if(typeof Fe>"u"){rt.set(Te,ht);continue}if(Fe===ht)continue;o.delete(H.locatorHash),e.delete(ht.descriptorHash),r.delete(ht.descriptorHash),a.delete(H.locatorHash);let ke=C.get(ht.descriptorHash)||[],Ye=[Ee.locatorHash,...ke];C.delete(ht.descriptorHash);for(let be of Ye){let et=o.get(be);typeof et>"u"||(et.dependencies.get(ht.identHash).descriptorHash!==Fe.descriptorHash&&(xe=!1),et.dependencies.set(ht.identHash,Fe))}for(let be of me.values())be.provided.descriptorHash===ht.descriptorHash&&(be.provided=Fe)}}while(!xe);for(let Ne of[...ne,...Z])Ne()};for(let le of t.workspaces){let ce=le.anchoredLocator;h.delete(le.anchoredDescriptor.descriptorHash),te(le.anchoredDescriptor,ce,new Map,{top:ce.locatorHash,optional:!1})}for(let le of p.values()){if(!le.root)continue;let ce=o.get(le.subject.locatorHash);if(typeof ce>"u")continue;for(let de of le.requests.values()){let Be=`p${zi(le.subject.locatorHash,rn(le.ident),de.requester.locatorHash).slice(0,5)}`;u.set(Be,{subject:le.subject.locatorHash,requested:le.ident,rootRequester:de.requester.locatorHash,allRequesters:Array.from(WI(de),Ee=>Ee.requester.locatorHash)})}let Ce=[...WI(le)];if(le.provided.range!=="missing:"){let de=z(le.provided),Be=de.version??"0.0.0",Ee=me=>{if(me.startsWith(ei.protocol)){if(!t.tryWorkspaceByLocator(de))return null;me=me.slice(ei.protocol.length),(me==="^"||me==="~")&&(me="*")}return me},g=!0;for(let me of Ce){let we=Ee(me.descriptor.range);if(we===null){g=!1;continue}if(!tA(Be,we)){g=!1;let Ae=`p${zi(le.subject.locatorHash,rn(le.ident),me.requester.locatorHash).slice(0,5)}`;A.push({type:1,subject:ce,requested:le.ident,requester:me.requester,version:Be,hash:Ae,requirementCount:Ce.length})}}if(!g){let me=Ce.map(we=>Ee(we.descriptor.range));A.push({type:3,node:le,range:me.includes(null)?null:XM(me),hash:le.hash})}}else{let de=!0;for(let Be of Ce)if(!Be.meta?.optional){de=!1;let Ee=`p${zi(le.subject.locatorHash,rn(le.ident),Be.requester.locatorHash).slice(0,5)}`;A.push({type:0,subject:ce,requested:le.ident,requester:Be.requester,hash:Ee})}de||A.push({type:2,node:le,hash:le.hash})}}}function*NAt(t){let e=new Map;if("children"in t)e.set(t,t);else for(let r of t.requests.values())e.set(r,r);for(let[r,o]of e){yield{request:r,root:o};for(let a of r.children.values())e.has(a)||e.set(a,o)}}function LAt(t,e){let r=[],o=[],a=!1;for(let n of t.peerWarnings)if(!(n.type===1||n.type===0)){if(!t.tryWorkspaceByLocator(n.node.subject)){a=!0;continue}if(n.type===3){let u=t.storedResolutions.get(n.node.provided.descriptorHash);if(typeof u>"u")throw new Error("Assertion failed: Expected the descriptor to be registered");let A=t.storedPackages.get(u);if(typeof A>"u")throw new Error("Assertion failed: Expected the package to be registered");let p=Vp(NAt(n.node),({request:I,root:v})=>tA(A.version??"0.0.0",I.descriptor.range)?Vp.skip:I===v?Oi(t.configuration,I.requester):`${Oi(t.configuration,I.requester)} (via ${Oi(t.configuration,v.requester)})`),h=[...WI(n.node)].length>1?"and other dependencies request":"requests",E=n.range?qm(t.configuration,n.range):Ot(t.configuration,"but they have non-overlapping ranges!","redBright");r.push(`${Oi(t.configuration,n.node.ident)} is listed by your project with version ${GI(t.configuration,A.version??"0.0.0")} (${Ot(t.configuration,n.hash,yt.CODE)}), which doesn't satisfy what ${p} ${h} (${E}).`)}if(n.type===2){let u=n.node.requests.size>1?" and other dependencies":"";o.push(`${qr(t.configuration,n.node.subject)} doesn't provide ${Oi(t.configuration,n.node.ident)} (${Ot(t.configuration,n.hash,yt.CODE)}), requested by ${Oi(t.configuration,n.node.requests.values().next().value.requester)}${u}.`)}}e.startSectionSync({reportFooter:()=>{e.reportWarning(86,`Some peer dependencies are incorrectly met by your project; run ${Ot(t.configuration,"yarn explain peer-requirements ",yt.CODE)} for details, where ${Ot(t.configuration,"",yt.CODE)} is the six-letter p-prefixed code.`)},skipIfEmpty:!0},()=>{for(let n of Fs(r,u=>Rm.default(u)))e.reportWarning(60,n);for(let n of Fs(o,u=>Rm.default(u)))e.reportWarning(2,n)}),a&&e.reportWarning(86,`Some peer dependencies are incorrectly met by dependencies; run ${Ot(t.configuration,"yarn explain peer-requirements",yt.CODE)} for details.`)}var Hx,qx,jx,ehe,B_,I_,v_,Gx,xAt,kAt,Zpe,QAt,FAt,RAt,hl,w_,Yx,$pe,kt,the=Et(()=>{Pt();Pt();Nl();qt();Hx=ve("crypto");f_();qx=Ze(y_()),jx=Ze(eg()),ehe=Ze(Jn()),B_=ve("util"),I_=Ze(ve("v8")),v_=Ze(ve("zlib"));n_();u1();i_();s_();Gm();rO();Wl();Jpe();I1();E_();mg();C_();Tb();jl();th();ql();fS();dU();Sf();So();Gx=Qm(process.env.YARN_LOCKFILE_VERSION_OVERRIDE??8),xAt=3,kAt=/ *, */g,Zpe=/\/$/,QAt=32,FAt=(0,B_.promisify)(v_.default.gzip),RAt=(0,B_.promisify)(v_.default.gunzip),hl=(r=>(r.UpdateLockfile="update-lockfile",r.SkipBuild="skip-build",r))(hl||{}),w_={restoreLinkersCustomData:["linkersCustomData"],restoreResolutions:["accessibleLocators","conditionalLocators","disabledLocators","optionalBuilds","storedDescriptors","storedResolutions","storedPackages","lockFileChecksum"],restoreBuildState:["skippedBuilds","storedBuildState"]},Yx=(a=>(a[a.NotProvided=0]="NotProvided",a[a.NotCompatible=1]="NotCompatible",a[a.NodeNotProvided=2]="NodeNotProvided",a[a.NodeNotCompatible=3]="NodeNotCompatible",a))(Yx||{}),$pe=t=>zi(`${xAt}`,t),kt=class t{constructor(e,{configuration:r}){this.resolutionAliases=new Map;this.workspaces=[];this.workspacesByCwd=new Map;this.workspacesByIdent=new Map;this.storedResolutions=new Map;this.storedDescriptors=new Map;this.storedPackages=new Map;this.storedChecksums=new Map;this.storedBuildState=new Map;this.accessibleLocators=new Set;this.conditionalLocators=new Set;this.disabledLocators=new Set;this.originalPackages=new Map;this.optionalBuilds=new Set;this.skippedBuilds=new Set;this.lockfileLastVersion=null;this.lockfileNeedsRefresh=!1;this.peerRequirements=new Map;this.peerWarnings=[];this.peerRequirementNodes=new Map;this.linkersCustomData=new Map;this.lockFileChecksum=null;this.installStateChecksum=null;this.configuration=r,this.cwd=e}static async find(e,r){if(!e.projectCwd)throw new st(`No project found in ${r}`);let o=e.projectCwd,a=r,n=null;for(;n!==e.projectCwd;){if(n=a,oe.existsSync(V.join(n,dr.manifest))){o=n;break}a=V.dirname(n)}let u=new t(e.projectCwd,{configuration:e});Ke.telemetry?.reportProject(u.cwd),await u.setupResolutions(),await u.setupWorkspaces(),Ke.telemetry?.reportWorkspaceCount(u.workspaces.length),Ke.telemetry?.reportDependencyCount(u.workspaces.reduce((C,R)=>C+R.manifest.dependencies.size+R.manifest.devDependencies.size,0));let A=u.tryWorkspaceByCwd(o);if(A)return{project:u,workspace:A,locator:A.anchoredLocator};let p=await u.findLocatorForLocation(`${o}/`,{strict:!0});if(p)return{project:u,locator:p,workspace:null};let h=Ot(e,u.cwd,yt.PATH),E=Ot(e,V.relative(u.cwd,o),yt.PATH),I=`- If ${h} isn't intended to be a project, remove any yarn.lock and/or package.json file there.`,v=`- If ${h} is intended to be a project, it might be that you forgot to list ${E} in its workspace configuration.`,x=`- Finally, if ${h} is fine and you intend ${E} to be treated as a completely separate project (not even a workspace), create an empty yarn.lock file in it.`;throw new st(`The nearest package directory (${Ot(e,o,yt.PATH)}) doesn't seem to be part of the project declared in ${Ot(e,u.cwd,yt.PATH)}. + +${[I,v,x].join(` +`)}`)}async setupResolutions(){this.storedResolutions=new Map,this.storedDescriptors=new Map,this.storedPackages=new Map,this.lockFileChecksum=null;let e=V.join(this.cwd,dr.lockfile),r=this.configuration.get("defaultLanguageName");if(oe.existsSync(e)){let o=await oe.readFilePromise(e,"utf8");this.lockFileChecksum=$pe(o);let a=Ki(o);if(a.__metadata){let n=a.__metadata.version,u=a.__metadata.cacheKey;this.lockfileLastVersion=n,this.lockfileNeedsRefresh=n"u")throw new Error(`Assertion failed: Expected the lockfile entry to have a resolution field (${A})`);let h=bf(p.resolution,!0),E=new Ut;E.load(p,{yamlCompatibilityMode:!0});let I=E.version,v=E.languageName||r,x=p.linkType.toUpperCase(),C=p.conditions??null,R=E.dependencies,L=E.peerDependencies,U=E.dependenciesMeta,z=E.peerDependenciesMeta,te=E.bin;if(p.checksum!=null){let le=typeof u<"u"&&!p.checksum.includes("/")?`${u}/${p.checksum}`:p.checksum;this.storedChecksums.set(h.locatorHash,le)}let ae={...h,version:I,languageName:v,linkType:x,conditions:C,dependencies:R,peerDependencies:L,dependenciesMeta:U,peerDependenciesMeta:z,bin:te};this.originalPackages.set(ae.locatorHash,ae);for(let le of A.split(kAt)){let ce=rh(le);n<=6&&(ce=this.configuration.normalizeDependency(ce),ce=In(ce,ce.range.replace(/^patch:[^@]+@(?!npm(:|%3A))/,"$1npm%3A"))),this.storedDescriptors.set(ce.descriptorHash,ce),this.storedResolutions.set(ce.descriptorHash,h.locatorHash)}}}else o.includes("yarn lockfile v1")&&(this.lockfileLastVersion=-1)}}async setupWorkspaces(){this.workspaces=[],this.workspacesByCwd=new Map,this.workspacesByIdent=new Map;let e=new Set,r=(0,jx.default)(4),o=async(a,n)=>{if(e.has(n))return a;e.add(n);let u=new My(n,{project:this});await r(()=>u.setup());let A=a.then(()=>{this.addWorkspace(u)});return Array.from(u.workspacesCwds).reduce(o,A)};await o(Promise.resolve(),this.cwd)}addWorkspace(e){let r=this.workspacesByIdent.get(e.anchoredLocator.identHash);if(typeof r<"u")throw new Error(`Duplicate workspace name ${Oi(this.configuration,e.anchoredLocator)}: ${ue.fromPortablePath(e.cwd)} conflicts with ${ue.fromPortablePath(r.cwd)}`);this.workspaces.push(e),this.workspacesByCwd.set(e.cwd,e),this.workspacesByIdent.set(e.anchoredLocator.identHash,e)}get topLevelWorkspace(){return this.getWorkspaceByCwd(this.cwd)}tryWorkspaceByCwd(e){V.isAbsolute(e)||(e=V.resolve(this.cwd,e)),e=V.normalize(e).replace(/\/+$/,"");let r=this.workspacesByCwd.get(e);return r||null}getWorkspaceByCwd(e){let r=this.tryWorkspaceByCwd(e);if(!r)throw new Error(`Workspace not found (${e})`);return r}tryWorkspaceByFilePath(e){let r=null;for(let o of this.workspaces)V.relative(o.cwd,e).startsWith("../")||r&&r.cwd.length>=o.cwd.length||(r=o);return r||null}getWorkspaceByFilePath(e){let r=this.tryWorkspaceByFilePath(e);if(!r)throw new Error(`Workspace not found (${e})`);return r}tryWorkspaceByIdent(e){let r=this.workspacesByIdent.get(e.identHash);return typeof r>"u"?null:r}getWorkspaceByIdent(e){let r=this.tryWorkspaceByIdent(e);if(!r)throw new Error(`Workspace not found (${Oi(this.configuration,e)})`);return r}tryWorkspaceByDescriptor(e){if(e.range.startsWith(ei.protocol)){let o=e.range.slice(ei.protocol.length);if(o!=="^"&&o!=="~"&&o!=="*"&&!Qa(o))return this.tryWorkspaceByCwd(o)}let r=this.tryWorkspaceByIdent(e);return r===null||(Pf(e)&&(e=UI(e)),!r.accepts(e.range))?null:r}getWorkspaceByDescriptor(e){let r=this.tryWorkspaceByDescriptor(e);if(r===null)throw new Error(`Workspace not found (${jn(this.configuration,e)})`);return r}tryWorkspaceByLocator(e){let r=this.tryWorkspaceByIdent(e);return r===null||(Gc(e)&&(e=_I(e)),r.anchoredLocator.locatorHash!==e.locatorHash)?null:r}getWorkspaceByLocator(e){let r=this.tryWorkspaceByLocator(e);if(!r)throw new Error(`Workspace not found (${qr(this.configuration,e)})`);return r}deleteDescriptor(e){this.storedResolutions.delete(e),this.storedDescriptors.delete(e)}deleteLocator(e){this.originalPackages.delete(e),this.storedPackages.delete(e),this.accessibleLocators.delete(e)}forgetResolution(e){if("descriptorHash"in e){let r=this.storedResolutions.get(e.descriptorHash);this.deleteDescriptor(e.descriptorHash);let o=new Set(this.storedResolutions.values());typeof r<"u"&&!o.has(r)&&this.deleteLocator(r)}if("locatorHash"in e){this.deleteLocator(e.locatorHash);for(let[r,o]of this.storedResolutions)o===e.locatorHash&&this.deleteDescriptor(r)}}forgetTransientResolutions(){let e=this.configuration.makeResolver(),r=new Map;for(let[o,a]of this.storedResolutions.entries()){let n=r.get(a);n||r.set(a,n=new Set),n.add(o)}for(let o of this.originalPackages.values()){let a;try{a=e.shouldPersistResolution(o,{project:this,resolver:e})}catch{a=!1}if(!a){this.deleteLocator(o.locatorHash);let n=r.get(o.locatorHash);if(n){r.delete(o.locatorHash);for(let u of n)this.deleteDescriptor(u)}}}}forgetVirtualResolutions(){for(let e of this.storedPackages.values())for(let[r,o]of e.dependencies)Pf(o)&&e.dependencies.set(r,UI(o))}getDependencyMeta(e,r){let o={},n=this.topLevelWorkspace.manifest.dependenciesMeta.get(rn(e));if(!n)return o;let u=n.get(null);if(u&&Object.assign(o,u),r===null||!ehe.default.valid(r))return o;for(let[A,p]of n)A!==null&&A===r&&Object.assign(o,p);return o}async findLocatorForLocation(e,{strict:r=!1}={}){let o=new ki,a=this.configuration.getLinkers(),n={project:this,report:o};for(let u of a){let A=await u.findPackageLocator(e,n);if(A){if(r&&(await u.findPackageLocation(A,n)).replace(Zpe,"")!==e.replace(Zpe,""))continue;return A}}return null}async loadUserConfig(){let e=V.join(this.cwd,".pnp.cjs");await oe.existsPromise(e)&&vf(e).setup();let r=V.join(this.cwd,"yarn.config.cjs");return await oe.existsPromise(r)?vf(r):null}async preparePackage(e,{resolver:r,resolveOptions:o}){let a=await this.configuration.getPackageExtensions(),n=this.configuration.normalizePackage(e,{packageExtensions:a});for(let[u,A]of n.dependencies){let p=await this.configuration.reduceHook(E=>E.reduceDependency,A,this,n,A,{resolver:r,resolveOptions:o});if(!HI(A,p))throw new Error("Assertion failed: The descriptor ident cannot be changed through aliases");let h=r.bindDescriptor(p,n,o);n.dependencies.set(u,h)}return n}async resolveEverything(e){if(!this.workspacesByCwd||!this.workspacesByIdent)throw new Error("Workspaces must have been setup before calling this function");this.forgetVirtualResolutions();let r=new Map(this.originalPackages),o=[];e.lockfileOnly||this.forgetTransientResolutions();let a=e.resolver||this.configuration.makeResolver(),n=new Ty(a);await n.setup(this,{report:e.report});let u=e.lockfileOnly?[new _x(a)]:[n,a],A=new yg([new Ny(a),...u]),p=new yg([...u]),h=this.configuration.makeFetcher(),E=e.lockfileOnly?{project:this,report:e.report,resolver:A}:{project:this,report:e.report,resolver:A,fetchOptions:{project:this,cache:e.cache,checksums:this.storedChecksums,report:e.report,fetcher:h,cacheOptions:{mirrorWriteOnly:!0}}},I=new Map,v=new Map,x=new Map,C=new Map,R=new Map,L=new Map,U=this.topLevelWorkspace.anchoredLocator,z=new Set,te=[],ae=k4(),le=this.configuration.getSupportedArchitectures();await e.report.startProgressPromise(Zs.progressViaTitle(),async ne=>{let Z=async rt=>{let Te=await xm(async()=>await A.resolve(rt,E),be=>`${qr(this.configuration,rt)}: ${be}`);if(!qI(rt,Te))throw new Error(`Assertion failed: The locator cannot be changed by the resolver (went from ${qr(this.configuration,rt)} to ${qr(this.configuration,Te)})`);C.set(Te.locatorHash,Te),!r.delete(Te.locatorHash)&&!this.tryWorkspaceByLocator(Te)&&o.push(Te);let ke=await this.preparePackage(Te,{resolver:A,resolveOptions:E}),Ye=_c([...ke.dependencies.values()].map(be=>H(be)));return te.push(Ye),Ye.catch(()=>{}),v.set(ke.locatorHash,ke),ke},xe=async rt=>{let Te=R.get(rt.locatorHash);if(typeof Te<"u")return Te;let Fe=Promise.resolve().then(()=>Z(rt));return R.set(rt.locatorHash,Fe),Fe},Ne=async(rt,Te)=>{let Fe=await H(Te);return I.set(rt.descriptorHash,rt),x.set(rt.descriptorHash,Fe.locatorHash),Fe},ht=async rt=>{ne.setTitle(jn(this.configuration,rt));let Te=this.resolutionAliases.get(rt.descriptorHash);if(typeof Te<"u")return Ne(rt,this.storedDescriptors.get(Te));let Fe=A.getResolutionDependencies(rt,E),ke=Object.fromEntries(await _c(Object.entries(Fe).map(async([et,Ue])=>{let S=A.bindDescriptor(Ue,U,E),w=await H(S);return z.add(w.locatorHash),[et,w]}))),be=(await xm(async()=>await A.getCandidates(rt,ke,E),et=>`${jn(this.configuration,rt)}: ${et}`))[0];if(typeof be>"u")throw new Jt(82,`${jn(this.configuration,rt)}: No candidates found`);if(e.checkResolutions){let{locators:et}=await p.getSatisfying(rt,ke,[be],{...E,resolver:p});if(!et.find(Ue=>Ue.locatorHash===be.locatorHash))throw new Jt(78,`Invalid resolution ${NI(this.configuration,rt,be)}`)}return I.set(rt.descriptorHash,rt),x.set(rt.descriptorHash,be.locatorHash),xe(be)},H=rt=>{let Te=L.get(rt.descriptorHash);if(typeof Te<"u")return Te;I.set(rt.descriptorHash,rt);let Fe=Promise.resolve().then(()=>ht(rt));return L.set(rt.descriptorHash,Fe),Fe};for(let rt of this.workspaces){let Te=rt.anchoredDescriptor;te.push(H(Te))}for(;te.length>0;){let rt=[...te];te.length=0,await _c(rt)}});let ce=ol(r.values(),ne=>this.tryWorkspaceByLocator(ne)?ol.skip:ne);if(o.length>0||ce.length>0){let ne=new Set(this.workspaces.flatMap(rt=>{let Te=v.get(rt.anchoredLocator.locatorHash);if(!Te)throw new Error("Assertion failed: The workspace should have been resolved");return Array.from(Te.dependencies.values(),Fe=>{let ke=x.get(Fe.descriptorHash);if(!ke)throw new Error("Assertion failed: The resolution should have been registered");return ke})})),Z=rt=>ne.has(rt.locatorHash)?"0":"1",xe=rt=>ka(rt),Ne=Fs(o,[Z,xe]),ht=Fs(ce,[Z,xe]),H=e.report.getRecommendedLength();Ne.length>0&&e.report.reportInfo(85,`${Ot(this.configuration,"+",yt.ADDED)} ${zP(this.configuration,Ne,H)}`),ht.length>0&&e.report.reportInfo(85,`${Ot(this.configuration,"-",yt.REMOVED)} ${zP(this.configuration,ht,H)}`)}let Ce=new Set(this.resolutionAliases.values()),de=new Set(v.keys()),Be=new Set,Ee=new Map,g=[],me=new Map;TAt({project:this,accessibleLocators:Be,volatileDescriptors:Ce,optionalBuilds:de,peerRequirements:Ee,peerWarnings:g,peerRequirementNodes:me,allDescriptors:I,allResolutions:x,allPackages:v});for(let ne of z)de.delete(ne);for(let ne of Ce)I.delete(ne),x.delete(ne);let we=new Set,Ae=new Set;for(let ne of v.values())ne.conditions!=null&&de.has(ne.locatorHash)&&(xb(ne,le)||(xb(ne,ae)&&e.report.reportWarningOnce(77,`${qr(this.configuration,ne)}: Your current architecture (${process.platform}-${process.arch}) is supported by this package, but is missing from the ${Ot(this.configuration,"supportedArchitectures",yt.SETTING)} setting`),Ae.add(ne.locatorHash)),we.add(ne.locatorHash));this.storedResolutions=x,this.storedDescriptors=I,this.storedPackages=v,this.accessibleLocators=Be,this.conditionalLocators=we,this.disabledLocators=Ae,this.originalPackages=C,this.optionalBuilds=de,this.peerRequirements=Ee,this.peerWarnings=g,this.peerRequirementNodes=me}async fetchEverything({cache:e,report:r,fetcher:o,mode:a,persistProject:n=!0}){let u={mockedPackages:this.disabledLocators,unstablePackages:this.conditionalLocators},A=o||this.configuration.makeFetcher(),p={checksums:this.storedChecksums,project:this,cache:e,fetcher:A,report:r,cacheOptions:u},h=Array.from(new Set(Fs(this.storedResolutions.values(),[C=>{let R=this.storedPackages.get(C);if(!R)throw new Error("Assertion failed: The locator should have been registered");return ka(R)}])));a==="update-lockfile"&&(h=h.filter(C=>!this.storedChecksums.has(C)));let E=!1,I=Zs.progressViaCounter(h.length);await r.reportProgress(I);let v=(0,jx.default)(QAt);if(await _c(h.map(C=>v(async()=>{let R=this.storedPackages.get(C);if(!R)throw new Error("Assertion failed: The locator should have been registered");if(Gc(R))return;let L;try{L=await A.fetch(R,p)}catch(U){U.message=`${qr(this.configuration,R)}: ${U.message}`,r.reportExceptionOnce(U),E=U;return}L.checksum!=null?this.storedChecksums.set(R.locatorHash,L.checksum):this.storedChecksums.delete(R.locatorHash),L.releaseFs&&L.releaseFs()}).finally(()=>{I.tick()}))),E)throw E;let x=n&&a!=="update-lockfile"?await this.cacheCleanup({cache:e,report:r}):null;if(r.cacheMisses.size>0||x){let R=(await Promise.all([...r.cacheMisses].map(async ce=>{let Ce=this.storedPackages.get(ce),de=this.storedChecksums.get(ce)??null,Be=e.getLocatorPath(Ce,de);return(await oe.statPromise(Be)).size}))).reduce((ce,Ce)=>ce+Ce,0)-(x?.size??0),L=r.cacheMisses.size,U=x?.count??0,z=`${jP(L,{zero:"No new packages",one:"A package was",more:`${Ot(this.configuration,L,yt.NUMBER)} packages were`})} added to the project`,te=`${jP(U,{zero:"none were",one:"one was",more:`${Ot(this.configuration,U,yt.NUMBER)} were`})} removed`,ae=R!==0?` (${Ot(this.configuration,R,yt.SIZE_DIFF)})`:"",le=U>0?L>0?`${z}, and ${te}${ae}.`:`${z}, but ${te}${ae}.`:`${z}${ae}.`;r.reportInfo(13,le)}}async linkEverything({cache:e,report:r,fetcher:o,mode:a}){let n={mockedPackages:this.disabledLocators,unstablePackages:this.conditionalLocators,skipIntegrityCheck:!0},u=o||this.configuration.makeFetcher(),A={checksums:this.storedChecksums,project:this,cache:e,fetcher:u,report:r,cacheOptions:n},p=this.configuration.getLinkers(),h={project:this,report:r},E=new Map(p.map(we=>{let Ae=we.makeInstaller(h),ne=we.getCustomDataKey(),Z=this.linkersCustomData.get(ne);return typeof Z<"u"&&Ae.attachCustomData(Z),[we,Ae]})),I=new Map,v=new Map,x=new Map,C=new Map(await _c([...this.accessibleLocators].map(async we=>{let Ae=this.storedPackages.get(we);if(!Ae)throw new Error("Assertion failed: The locator should have been registered");return[we,await u.fetch(Ae,A)]}))),R=[],L=new Set,U=[];for(let we of this.accessibleLocators){let Ae=this.storedPackages.get(we);if(typeof Ae>"u")throw new Error("Assertion failed: The locator should have been registered");let ne=C.get(Ae.locatorHash);if(typeof ne>"u")throw new Error("Assertion failed: The fetch result should have been registered");let Z=[],xe=ht=>{Z.push(ht)},Ne=this.tryWorkspaceByLocator(Ae);if(Ne!==null){let ht=[],{scripts:H}=Ne.manifest;for(let Te of["preinstall","install","postinstall"])H.has(Te)&&ht.push({type:0,script:Te});try{for(let[Te,Fe]of E)if(Te.supportsPackage(Ae,h)&&(await Fe.installPackage(Ae,ne,{holdFetchResult:xe})).buildRequest!==null)throw new Error("Assertion failed: Linkers can't return build directives for workspaces; this responsibility befalls to the Yarn core")}finally{Z.length===0?ne.releaseFs?.():R.push(_c(Z).catch(()=>{}).then(()=>{ne.releaseFs?.()}))}let rt=V.join(ne.packageFs.getRealPath(),ne.prefixPath);v.set(Ae.locatorHash,rt),!Gc(Ae)&&ht.length>0&&x.set(Ae.locatorHash,{buildDirectives:ht,buildLocations:[rt]})}else{let ht=p.find(Te=>Te.supportsPackage(Ae,h));if(!ht)throw new Jt(12,`${qr(this.configuration,Ae)} isn't supported by any available linker`);let H=E.get(ht);if(!H)throw new Error("Assertion failed: The installer should have been registered");let rt;try{rt=await H.installPackage(Ae,ne,{holdFetchResult:xe})}finally{Z.length===0?ne.releaseFs?.():R.push(_c(Z).then(()=>{}).then(()=>{ne.releaseFs?.()}))}I.set(Ae.locatorHash,ht),v.set(Ae.locatorHash,rt.packageLocation),rt.buildRequest&&rt.packageLocation&&(rt.buildRequest.skipped?(L.add(Ae.locatorHash),this.skippedBuilds.has(Ae.locatorHash)||U.push([Ae,rt.buildRequest.explain])):x.set(Ae.locatorHash,{buildDirectives:rt.buildRequest.directives,buildLocations:[rt.packageLocation]}))}}let z=new Map;for(let we of this.accessibleLocators){let Ae=this.storedPackages.get(we);if(!Ae)throw new Error("Assertion failed: The locator should have been registered");let ne=this.tryWorkspaceByLocator(Ae)!==null,Z=async(xe,Ne)=>{let ht=v.get(Ae.locatorHash);if(typeof ht>"u")throw new Error(`Assertion failed: The package (${qr(this.configuration,Ae)}) should have been registered`);let H=[];for(let rt of Ae.dependencies.values()){let Te=this.storedResolutions.get(rt.descriptorHash);if(typeof Te>"u")throw new Error(`Assertion failed: The resolution (${jn(this.configuration,rt)}, from ${qr(this.configuration,Ae)})should have been registered`);let Fe=this.storedPackages.get(Te);if(typeof Fe>"u")throw new Error(`Assertion failed: The package (${Te}, resolved from ${jn(this.configuration,rt)}) should have been registered`);let ke=this.tryWorkspaceByLocator(Fe)===null?I.get(Te):null;if(typeof ke>"u")throw new Error(`Assertion failed: The package (${Te}, resolved from ${jn(this.configuration,rt)}) should have been registered`);ke===xe||ke===null?v.get(Fe.locatorHash)!==null&&H.push([rt,Fe]):!ne&&ht!==null&&xI(z,Te).push(ht)}ht!==null&&await Ne.attachInternalDependencies(Ae,H)};if(ne)for(let[xe,Ne]of E)xe.supportsPackage(Ae,h)&&await Z(xe,Ne);else{let xe=I.get(Ae.locatorHash);if(!xe)throw new Error("Assertion failed: The linker should have been found");let Ne=E.get(xe);if(!Ne)throw new Error("Assertion failed: The installer should have been registered");await Z(xe,Ne)}}for(let[we,Ae]of z){let ne=this.storedPackages.get(we);if(!ne)throw new Error("Assertion failed: The package should have been registered");let Z=I.get(ne.locatorHash);if(!Z)throw new Error("Assertion failed: The linker should have been found");let xe=E.get(Z);if(!xe)throw new Error("Assertion failed: The installer should have been registered");await xe.attachExternalDependents(ne,Ae)}let te=new Map;for(let[we,Ae]of E){let ne=await Ae.finalizeInstall();for(let Z of ne?.records??[])Z.buildRequest.skipped?(L.add(Z.locator.locatorHash),this.skippedBuilds.has(Z.locator.locatorHash)||U.push([Z.locator,Z.buildRequest.explain])):x.set(Z.locator.locatorHash,{buildDirectives:Z.buildRequest.directives,buildLocations:Z.buildLocations});typeof ne?.customData<"u"&&te.set(we.getCustomDataKey(),ne.customData)}if(this.linkersCustomData=te,await _c(R),a==="skip-build")return;for(let[,we]of Fs(U,([Ae])=>ka(Ae)))we(r);let ae=new Set(x.keys()),le=(0,Hx.createHash)("sha512");le.update(process.versions.node),await this.configuration.triggerHook(we=>we.globalHashGeneration,this,we=>{le.update("\0"),le.update(we)});let ce=le.digest("hex"),Ce=new Map,de=we=>{let Ae=Ce.get(we.locatorHash);if(typeof Ae<"u")return Ae;let ne=this.storedPackages.get(we.locatorHash);if(typeof ne>"u")throw new Error("Assertion failed: The package should have been registered");let Z=(0,Hx.createHash)("sha512");Z.update(we.locatorHash),Ce.set(we.locatorHash,"");for(let xe of ne.dependencies.values()){let Ne=this.storedResolutions.get(xe.descriptorHash);if(typeof Ne>"u")throw new Error(`Assertion failed: The resolution (${jn(this.configuration,xe)}) should have been registered`);let ht=this.storedPackages.get(Ne);if(typeof ht>"u")throw new Error("Assertion failed: The package should have been registered");Z.update(de(ht))}return Ae=Z.digest("hex"),Ce.set(we.locatorHash,Ae),Ae},Be=(we,Ae)=>{let ne=(0,Hx.createHash)("sha512");ne.update(ce),ne.update(de(we));for(let Z of Ae)ne.update(Z);return ne.digest("hex")},Ee=new Map,g=!1,me=we=>{let Ae=new Set([we.locatorHash]);for(let ne of Ae){let Z=this.storedPackages.get(ne);if(!Z)throw new Error("Assertion failed: The package should have been registered");for(let xe of Z.dependencies.values()){let Ne=this.storedResolutions.get(xe.descriptorHash);if(!Ne)throw new Error(`Assertion failed: The resolution (${jn(this.configuration,xe)}) should have been registered`);if(Ne!==we.locatorHash&&ae.has(Ne))return!1;let ht=this.storedPackages.get(Ne);if(!ht)throw new Error("Assertion failed: The package should have been registered");let H=this.tryWorkspaceByLocator(ht);if(H){if(H.anchoredLocator.locatorHash!==we.locatorHash&&ae.has(H.anchoredLocator.locatorHash))return!1;Ae.add(H.anchoredLocator.locatorHash)}Ae.add(Ne)}}return!0};for(;ae.size>0;){let we=ae.size,Ae=[];for(let ne of ae){let Z=this.storedPackages.get(ne);if(!Z)throw new Error("Assertion failed: The package should have been registered");if(!me(Z))continue;let xe=x.get(Z.locatorHash);if(!xe)throw new Error("Assertion failed: The build directive should have been registered");let Ne=Be(Z,xe.buildLocations);if(this.storedBuildState.get(Z.locatorHash)===Ne){Ee.set(Z.locatorHash,Ne),ae.delete(ne);continue}g||(await this.persistInstallStateFile(),g=!0),this.storedBuildState.has(Z.locatorHash)?r.reportInfo(8,`${qr(this.configuration,Z)} must be rebuilt because its dependency tree changed`):r.reportInfo(7,`${qr(this.configuration,Z)} must be built because it never has been before or the last one failed`);let ht=xe.buildLocations.map(async H=>{if(!V.isAbsolute(H))throw new Error(`Assertion failed: Expected the build location to be absolute (not ${H})`);for(let rt of xe.buildDirectives){let Te=`# This file contains the result of Yarn building a package (${ka(Z)}) +`;switch(rt.type){case 0:Te+=`# Script name: ${rt.script} +`;break;case 1:Te+=`# Script code: ${rt.script} +`;break}let Fe=null;if(!await oe.mktempPromise(async Ye=>{let be=V.join(Ye,"build.log"),{stdout:et,stderr:Ue}=this.configuration.getSubprocessStreams(be,{header:Te,prefix:qr(this.configuration,Z),report:r}),S;try{switch(rt.type){case 0:S=await NS(Z,rt.script,[],{cwd:H,project:this,stdin:Fe,stdout:et,stderr:Ue});break;case 1:S=await fU(Z,rt.script,[],{cwd:H,project:this,stdin:Fe,stdout:et,stderr:Ue});break}}catch(y){Ue.write(y.stack),S=1}if(et.end(),Ue.end(),S===0)return!0;oe.detachTemp(Ye);let w=`${qr(this.configuration,Z)} couldn't be built successfully (exit code ${Ot(this.configuration,S,yt.NUMBER)}, logs can be found here: ${Ot(this.configuration,be,yt.PATH)})`,b=this.optionalBuilds.has(Z.locatorHash);return b?r.reportInfo(9,w):r.reportError(9,w),Zce&&r.reportFold(ue.fromPortablePath(be),oe.readFileSync(be,"utf8")),b}))return!1}return!0});Ae.push(...ht,Promise.allSettled(ht).then(H=>{ae.delete(ne),H.every(rt=>rt.status==="fulfilled"&&rt.value===!0)&&Ee.set(Z.locatorHash,Ne)}))}if(await _c(Ae),we===ae.size){let ne=Array.from(ae).map(Z=>{let xe=this.storedPackages.get(Z);if(!xe)throw new Error("Assertion failed: The package should have been registered");return qr(this.configuration,xe)}).join(", ");r.reportError(3,`Some packages have circular dependencies that make their build order unsatisfiable - as a result they won't be built (affected packages are: ${ne})`);break}}this.storedBuildState=Ee,this.skippedBuilds=L}async installWithNewReport(e,r){return(await Rt.start({configuration:this.configuration,json:e.json,stdout:e.stdout,forceSectionAlignment:!0,includeLogs:!e.json&&!e.quiet,includeVersion:!0},async a=>{await this.install({...r,report:a})})).exitCode()}async install(e){let r=this.configuration.get("nodeLinker");Ke.telemetry?.reportInstall(r);let o=!1;if(await e.report.startTimerPromise("Project validation",{skipIfEmpty:!0},async()=>{this.configuration.get("enableOfflineMode")&&e.report.reportWarning(90,"Offline work is enabled; Yarn won't fetch packages from the remote registry if it can avoid it"),await this.configuration.triggerHook(E=>E.validateProject,this,{reportWarning:(E,I)=>{e.report.reportWarning(E,I)},reportError:(E,I)=>{e.report.reportError(E,I),o=!0}})}),o)return;let a=await this.configuration.getPackageExtensions();for(let E of a.values())for(let[,I]of E)for(let v of I)v.status="inactive";let n=V.join(this.cwd,dr.lockfile),u=null;if(e.immutable)try{u=await oe.readFilePromise(n,"utf8")}catch(E){throw E.code==="ENOENT"?new Jt(28,"The lockfile would have been created by this install, which is explicitly forbidden."):E}await e.report.startTimerPromise("Resolution step",async()=>{await this.resolveEverything(e)}),await e.report.startTimerPromise("Post-resolution validation",{skipIfEmpty:!0},async()=>{LAt(this,e.report);for(let[,E]of a)for(let[,I]of E)for(let v of I)if(v.userProvided){let x=Ot(this.configuration,v,yt.PACKAGE_EXTENSION);switch(v.status){case"inactive":e.report.reportWarning(68,`${x}: No matching package in the dependency tree; you may not need this rule anymore.`);break;case"redundant":e.report.reportWarning(69,`${x}: This rule seems redundant when applied on the original package; the extension may have been applied upstream.`);break}}if(u!==null){let E=L0(u,this.generateLockfile());if(E!==u){let I=dpe(n,n,u,E,void 0,void 0,{maxEditLength:100});if(I){e.report.reportSeparator();for(let v of I.hunks){e.report.reportInfo(null,`@@ -${v.oldStart},${v.oldLines} +${v.newStart},${v.newLines} @@`);for(let x of v.lines)x.startsWith("+")?e.report.reportError(28,Ot(this.configuration,x,yt.ADDED)):x.startsWith("-")?e.report.reportError(28,Ot(this.configuration,x,yt.REMOVED)):e.report.reportInfo(null,Ot(this.configuration,x,"grey"))}e.report.reportSeparator()}throw new Jt(28,"The lockfile would have been modified by this install, which is explicitly forbidden.")}}});for(let E of a.values())for(let[,I]of E)for(let v of I)v.userProvided&&v.status==="active"&&Ke.telemetry?.reportPackageExtension(pg(v,yt.PACKAGE_EXTENSION));await e.report.startTimerPromise("Fetch step",async()=>{await this.fetchEverything(e)});let A=e.immutable?[...new Set(this.configuration.get("immutablePatterns"))].sort():[],p=await Promise.all(A.map(async E=>Bb(E,{cwd:this.cwd})));(typeof e.persistProject>"u"||e.persistProject)&&await this.persist(),await e.report.startTimerPromise("Link step",async()=>{if(e.mode==="update-lockfile"){e.report.reportWarning(73,`Skipped due to ${Ot(this.configuration,"mode=update-lockfile",yt.CODE)}`);return}await this.linkEverything(e);let E=await Promise.all(A.map(async I=>Bb(I,{cwd:this.cwd})));for(let I=0;I{await this.configuration.triggerHook(E=>E.validateProjectAfterInstall,this,{reportWarning:(E,I)=>{e.report.reportWarning(E,I)},reportError:(E,I)=>{e.report.reportError(E,I),h=!0}})}),!h&&await this.configuration.triggerHook(E=>E.afterAllInstalled,this,e)}generateLockfile(){let e=new Map;for(let[n,u]of this.storedResolutions.entries()){let A=e.get(u);A||e.set(u,A=new Set),A.add(n)}let r={},{cacheKey:o}=Gr.getCacheKey(this.configuration);r.__metadata={version:Gx,cacheKey:o};for(let[n,u]of e.entries()){let A=this.originalPackages.get(n);if(!A)continue;let p=[];for(let I of u){let v=this.storedDescriptors.get(I);if(!v)throw new Error("Assertion failed: The descriptor should have been registered");p.push(v)}let h=p.map(I=>xa(I)).sort().join(", "),E=new Ut;E.version=A.linkType==="HARD"?A.version:"0.0.0-use.local",E.languageName=A.languageName,E.dependencies=new Map(A.dependencies),E.peerDependencies=new Map(A.peerDependencies),E.dependenciesMeta=new Map(A.dependenciesMeta),E.peerDependenciesMeta=new Map(A.peerDependenciesMeta),E.bin=new Map(A.bin),r[h]={...E.exportTo({},{compatibilityMode:!1}),linkType:A.linkType.toLowerCase(),resolution:ka(A),checksum:this.storedChecksums.get(A.locatorHash),conditions:A.conditions||void 0}}return`${[`# This file is generated by running "yarn install" inside your project. +`,`# Manual changes might be lost - proceed with caution! +`].join("")} +`+Da(r)}async persistLockfile(){let e=V.join(this.cwd,dr.lockfile),r="";try{r=await oe.readFilePromise(e,"utf8")}catch{}let o=this.generateLockfile(),a=L0(r,o);a!==r&&(await oe.writeFilePromise(e,a),this.lockFileChecksum=$pe(a),this.lockfileNeedsRefresh=!1)}async persistInstallStateFile(){let e=[];for(let u of Object.values(w_))e.push(...u);let r=(0,qx.default)(this,e),o=I_.default.serialize(r),a=zi(o);if(this.installStateChecksum===a)return;let n=this.configuration.get("installStatePath");await oe.mkdirPromise(V.dirname(n),{recursive:!0}),await oe.writeFilePromise(n,await FAt(o)),this.installStateChecksum=a}async restoreInstallState({restoreLinkersCustomData:e=!0,restoreResolutions:r=!0,restoreBuildState:o=!0}={}){let a=this.configuration.get("installStatePath"),n;try{let u=await RAt(await oe.readFilePromise(a));n=I_.default.deserialize(u),this.installStateChecksum=zi(u)}catch{r&&await this.applyLightResolution();return}e&&typeof n.linkersCustomData<"u"&&(this.linkersCustomData=n.linkersCustomData),o&&Object.assign(this,(0,qx.default)(n,w_.restoreBuildState)),r&&(n.lockFileChecksum===this.lockFileChecksum?Object.assign(this,(0,qx.default)(n,w_.restoreResolutions)):await this.applyLightResolution())}async applyLightResolution(){await this.resolveEverything({lockfileOnly:!0,report:new ki}),await this.persistInstallStateFile()}async persist(){let e=(0,jx.default)(4);await Promise.all([this.persistLockfile(),...this.workspaces.map(r=>e(()=>r.persistManifest()))])}async cacheCleanup({cache:e,report:r}){if(this.configuration.get("enableGlobalCache"))return null;let o=new Set([".gitignore"]);if(!fO(e.cwd,this.cwd)||!await oe.existsPromise(e.cwd))return null;let a=[];for(let u of await oe.readdirPromise(e.cwd)){if(o.has(u))continue;let A=V.resolve(e.cwd,u);e.markedFiles.has(A)||(e.immutable?r.reportError(56,`${Ot(this.configuration,V.basename(A),"magenta")} appears to be unused and would be marked for deletion, but the cache is immutable`):a.push(oe.lstatPromise(A).then(async p=>(await oe.removePromise(A),p.size))))}if(a.length===0)return null;let n=await Promise.all(a);return{count:a.length,size:n.reduce((u,A)=>u+A,0)}}}});function MAt(t){let o=Math.floor(t.timeNow/864e5),a=t.updateInterval*864e5,n=t.state.lastUpdate??t.timeNow+a+Math.floor(a*t.randomInitialInterval),u=n+a,A=t.state.lastTips??o*864e5,p=A+864e5+8*36e5-t.timeZone,h=u<=t.timeNow,E=p<=t.timeNow,I=null;return(h||E||!t.state.lastUpdate||!t.state.lastTips)&&(I={},I.lastUpdate=h?t.timeNow:n,I.lastTips=A,I.blocks=h?{}:t.state.blocks,I.displayedTips=t.state.displayedTips),{nextState:I,triggerUpdate:h,triggerTips:E,nextTips:E?o*864e5:A}}var Oy,rhe=Et(()=>{Pt();w1();th();uS();ql();Sf();Oy=class{constructor(e,r){this.values=new Map;this.hits=new Map;this.enumerators=new Map;this.nextTips=0;this.displayedTips=[];this.shouldCommitTips=!1;this.configuration=e;let o=this.getRegistryPath();this.isNew=!oe.existsSync(o),this.shouldShowTips=!1,this.sendReport(r),this.startBuffer()}commitTips(){this.shouldShowTips&&(this.shouldCommitTips=!0)}selectTip(e){let r=new Set(this.displayedTips),o=A=>A&&nn?tA(nn,A):!1,a=e.map((A,p)=>p).filter(A=>e[A]&&o(e[A]?.selector));if(a.length===0)return null;let n=a.filter(A=>!r.has(A));if(n.length===0){let A=Math.floor(a.length*.2);this.displayedTips=A>0?this.displayedTips.slice(-A):[],n=a.filter(p=>!r.has(p))}let u=n[Math.floor(Math.random()*n.length)];return this.displayedTips.push(u),this.commitTips(),e[u]}reportVersion(e){this.reportValue("version",e.replace(/-git\..*/,"-git"))}reportCommandName(e){this.reportValue("commandName",e||"")}reportPluginName(e){this.reportValue("pluginName",e)}reportProject(e){this.reportEnumerator("projectCount",e)}reportInstall(e){this.reportHit("installCount",e)}reportPackageExtension(e){this.reportValue("packageExtension",e)}reportWorkspaceCount(e){this.reportValue("workspaceCount",String(e))}reportDependencyCount(e){this.reportValue("dependencyCount",String(e))}reportValue(e,r){Sm(this.values,e).add(r)}reportEnumerator(e,r){Sm(this.enumerators,e).add(zi(r))}reportHit(e,r="*"){let o=kI(this.hits,e),a=al(o,r,()=>0);o.set(r,a+1)}getRegistryPath(){let e=this.configuration.get("globalFolder");return V.join(e,"telemetry.json")}sendReport(e){let r=this.getRegistryPath(),o;try{o=oe.readJsonSync(r)}catch{o={}}let{nextState:a,triggerUpdate:n,triggerTips:u,nextTips:A}=MAt({state:o,timeNow:Date.now(),timeZone:new Date().getTimezoneOffset()*60*1e3,randomInitialInterval:Math.random(),updateInterval:this.configuration.get("telemetryInterval")});if(this.nextTips=A,this.displayedTips=o.displayedTips??[],a!==null)try{oe.mkdirSync(V.dirname(r),{recursive:!0}),oe.writeJsonSync(r,a)}catch{return!1}if(u&&this.configuration.get("enableTips")&&(this.shouldShowTips=!0),n){let p=o.blocks??{};if(Object.keys(p).length===0){let h=`https://browser-http-intake.logs.datadoghq.eu/v1/input/${e}?ddsource=yarn`,E=I=>x4(h,I,{configuration:this.configuration}).catch(()=>{});for(let[I,v]of Object.entries(o.blocks??{})){if(Object.keys(v).length===0)continue;let x=v;x.userId=I,x.reportType="primary";for(let L of Object.keys(x.enumerators??{}))x.enumerators[L]=x.enumerators[L].length;E(x);let C=new Map,R=20;for(let[L,U]of Object.entries(x.values))U.length>0&&C.set(L,U.slice(0,R));for(;C.size>0;){let L={};L.userId=I,L.reportType="secondary",L.metrics={};for(let[U,z]of C)L.metrics[U]=z.shift(),z.length===0&&C.delete(U);E(L)}}}}return!0}applyChanges(){let e=this.getRegistryPath(),r;try{r=oe.readJsonSync(e)}catch{r={}}let o=this.configuration.get("telemetryUserId")??"*",a=r.blocks=r.blocks??{},n=a[o]=a[o]??{};for(let u of this.hits.keys()){let A=n.hits=n.hits??{},p=A[u]=A[u]??{};for(let[h,E]of this.hits.get(u))p[h]=(p[h]??0)+E}for(let u of["values","enumerators"])for(let A of this[u].keys()){let p=n[u]=n[u]??{};p[A]=[...new Set([...p[A]??[],...this[u].get(A)??[]])]}this.shouldCommitTips&&(r.lastTips=this.nextTips,r.displayedTips=this.displayedTips),oe.mkdirSync(V.dirname(e),{recursive:!0}),oe.writeJsonSync(e,r)}startBuffer(){process.on("exit",()=>{try{this.applyChanges()}catch{}})}}});var Y1={};Vt(Y1,{BuildDirectiveType:()=>Mx,CACHE_CHECKPOINT:()=>r_,CACHE_VERSION:()=>Lx,Cache:()=>Gr,Configuration:()=>Ke,DEFAULT_RC_FILENAME:()=>L4,FormatType:()=>Tle,InstallMode:()=>hl,LEGACY_PLUGINS:()=>l1,LOCKFILE_VERSION:()=>Gx,LegacyMigrationResolver:()=>Ty,LightReport:()=>AA,LinkType:()=>Fm,LockfileResolver:()=>Ny,Manifest:()=>Ut,MessageName:()=>wr,MultiFetcher:()=>Wm,PackageExtensionStatus:()=>pL,PackageExtensionType:()=>fL,PeerWarningType:()=>Yx,Project:()=>kt,Report:()=>Zs,ReportError:()=>Jt,SettingsType:()=>c1,StreamReport:()=>Rt,TAG_REGEXP:()=>ly,TelemetryManager:()=>Oy,ThrowReport:()=>ki,VirtualFetcher:()=>Km,WindowsLinkType:()=>mS,Workspace:()=>My,WorkspaceFetcher:()=>Vm,WorkspaceResolver:()=>ei,YarnVersion:()=>nn,execUtils:()=>Ur,folderUtils:()=>Rb,formatUtils:()=>pe,hashUtils:()=>wn,httpUtils:()=>sn,miscUtils:()=>He,nodeUtils:()=>Xi,parseMessageName:()=>ZD,reportOptionDeprecations:()=>uy,scriptUtils:()=>An,semverUtils:()=>Lr,stringifyMessageName:()=>Ku,structUtils:()=>G,tgzUtils:()=>$i,treeUtils:()=>fs});var Ge=Et(()=>{pS();Tb();jl();th();uS();ql();fS();dU();Sf();So();rpe();cpe();n_();u1();u1();Ape();i_();fpe();s_();Gm();$D();tO();the();Wl();I1();rhe();E_();nO();iO();mg();C_();w1();Cne()});var lhe=_(($_t,K1)=>{"use strict";var UAt=process.env.TERM_PROGRAM==="Hyper",_At=process.platform==="win32",she=process.platform==="linux",D_={ballotDisabled:"\u2612",ballotOff:"\u2610",ballotOn:"\u2611",bullet:"\u2022",bulletWhite:"\u25E6",fullBlock:"\u2588",heart:"\u2764",identicalTo:"\u2261",line:"\u2500",mark:"\u203B",middot:"\xB7",minus:"\uFF0D",multiplication:"\xD7",obelus:"\xF7",pencilDownRight:"\u270E",pencilRight:"\u270F",pencilUpRight:"\u2710",percent:"%",pilcrow2:"\u2761",pilcrow:"\xB6",plusMinus:"\xB1",section:"\xA7",starsOff:"\u2606",starsOn:"\u2605",upDownArrow:"\u2195"},ohe=Object.assign({},D_,{check:"\u221A",cross:"\xD7",ellipsisLarge:"...",ellipsis:"...",info:"i",question:"?",questionSmall:"?",pointer:">",pointerSmall:"\xBB",radioOff:"( )",radioOn:"(*)",warning:"\u203C"}),ahe=Object.assign({},D_,{ballotCross:"\u2718",check:"\u2714",cross:"\u2716",ellipsisLarge:"\u22EF",ellipsis:"\u2026",info:"\u2139",question:"?",questionFull:"\uFF1F",questionSmall:"\uFE56",pointer:she?"\u25B8":"\u276F",pointerSmall:she?"\u2023":"\u203A",radioOff:"\u25EF",radioOn:"\u25C9",warning:"\u26A0"});K1.exports=_At&&!UAt?ohe:ahe;Reflect.defineProperty(K1.exports,"common",{enumerable:!1,value:D_});Reflect.defineProperty(K1.exports,"windows",{enumerable:!1,value:ohe});Reflect.defineProperty(K1.exports,"other",{enumerable:!1,value:ahe})});var zc=_((e8t,P_)=>{"use strict";var HAt=t=>t!==null&&typeof t=="object"&&!Array.isArray(t),qAt=/[\u001b\u009b][[\]#;?()]*(?:(?:(?:[^\W_]*;?[^\W_]*)\u0007)|(?:(?:[0-9]{1,4}(;[0-9]{0,4})*)?[~0-9=<>cf-nqrtyA-PRZ]))/g,che=()=>{let t={enabled:!0,visible:!0,styles:{},keys:{}};"FORCE_COLOR"in process.env&&(t.enabled=process.env.FORCE_COLOR!=="0");let e=n=>{let u=n.open=`\x1B[${n.codes[0]}m`,A=n.close=`\x1B[${n.codes[1]}m`,p=n.regex=new RegExp(`\\u001b\\[${n.codes[1]}m`,"g");return n.wrap=(h,E)=>{h.includes(A)&&(h=h.replace(p,A+u));let I=u+h+A;return E?I.replace(/\r*\n/g,`${A}$&${u}`):I},n},r=(n,u,A)=>typeof n=="function"?n(u):n.wrap(u,A),o=(n,u)=>{if(n===""||n==null)return"";if(t.enabled===!1)return n;if(t.visible===!1)return"";let A=""+n,p=A.includes(` +`),h=u.length;for(h>0&&u.includes("unstyle")&&(u=[...new Set(["unstyle",...u])].reverse());h-- >0;)A=r(t.styles[u[h]],A,p);return A},a=(n,u,A)=>{t.styles[n]=e({name:n,codes:u}),(t.keys[A]||(t.keys[A]=[])).push(n),Reflect.defineProperty(t,n,{configurable:!0,enumerable:!0,set(h){t.alias(n,h)},get(){let h=E=>o(E,h.stack);return Reflect.setPrototypeOf(h,t),h.stack=this.stack?this.stack.concat(n):[n],h}})};return a("reset",[0,0],"modifier"),a("bold",[1,22],"modifier"),a("dim",[2,22],"modifier"),a("italic",[3,23],"modifier"),a("underline",[4,24],"modifier"),a("inverse",[7,27],"modifier"),a("hidden",[8,28],"modifier"),a("strikethrough",[9,29],"modifier"),a("black",[30,39],"color"),a("red",[31,39],"color"),a("green",[32,39],"color"),a("yellow",[33,39],"color"),a("blue",[34,39],"color"),a("magenta",[35,39],"color"),a("cyan",[36,39],"color"),a("white",[37,39],"color"),a("gray",[90,39],"color"),a("grey",[90,39],"color"),a("bgBlack",[40,49],"bg"),a("bgRed",[41,49],"bg"),a("bgGreen",[42,49],"bg"),a("bgYellow",[43,49],"bg"),a("bgBlue",[44,49],"bg"),a("bgMagenta",[45,49],"bg"),a("bgCyan",[46,49],"bg"),a("bgWhite",[47,49],"bg"),a("blackBright",[90,39],"bright"),a("redBright",[91,39],"bright"),a("greenBright",[92,39],"bright"),a("yellowBright",[93,39],"bright"),a("blueBright",[94,39],"bright"),a("magentaBright",[95,39],"bright"),a("cyanBright",[96,39],"bright"),a("whiteBright",[97,39],"bright"),a("bgBlackBright",[100,49],"bgBright"),a("bgRedBright",[101,49],"bgBright"),a("bgGreenBright",[102,49],"bgBright"),a("bgYellowBright",[103,49],"bgBright"),a("bgBlueBright",[104,49],"bgBright"),a("bgMagentaBright",[105,49],"bgBright"),a("bgCyanBright",[106,49],"bgBright"),a("bgWhiteBright",[107,49],"bgBright"),t.ansiRegex=qAt,t.hasColor=t.hasAnsi=n=>(t.ansiRegex.lastIndex=0,typeof n=="string"&&n!==""&&t.ansiRegex.test(n)),t.alias=(n,u)=>{let A=typeof u=="string"?t[u]:u;if(typeof A!="function")throw new TypeError("Expected alias to be the name of an existing color (string) or a function");A.stack||(Reflect.defineProperty(A,"name",{value:n}),t.styles[n]=A,A.stack=[n]),Reflect.defineProperty(t,n,{configurable:!0,enumerable:!0,set(p){t.alias(n,p)},get(){let p=h=>o(h,p.stack);return Reflect.setPrototypeOf(p,t),p.stack=this.stack?this.stack.concat(A.stack):A.stack,p}})},t.theme=n=>{if(!HAt(n))throw new TypeError("Expected theme to be an object");for(let u of Object.keys(n))t.alias(u,n[u]);return t},t.alias("unstyle",n=>typeof n=="string"&&n!==""?(t.ansiRegex.lastIndex=0,n.replace(t.ansiRegex,"")):""),t.alias("noop",n=>n),t.none=t.clear=t.noop,t.stripColor=t.unstyle,t.symbols=lhe(),t.define=a,t};P_.exports=che();P_.exports.create=che});var No=_(on=>{"use strict";var jAt=Object.prototype.toString,rc=zc(),uhe=!1,b_=[],Ahe={yellow:"blue",cyan:"red",green:"magenta",black:"white",blue:"yellow",red:"cyan",magenta:"green",white:"black"};on.longest=(t,e)=>t.reduce((r,o)=>Math.max(r,e?o[e].length:o.length),0);on.hasColor=t=>!!t&&rc.hasColor(t);var Kx=on.isObject=t=>t!==null&&typeof t=="object"&&!Array.isArray(t);on.nativeType=t=>jAt.call(t).slice(8,-1).toLowerCase().replace(/\s/g,"");on.isAsyncFn=t=>on.nativeType(t)==="asyncfunction";on.isPrimitive=t=>t!=null&&typeof t!="object"&&typeof t!="function";on.resolve=(t,e,...r)=>typeof e=="function"?e.call(t,...r):e;on.scrollDown=(t=[])=>[...t.slice(1),t[0]];on.scrollUp=(t=[])=>[t.pop(),...t];on.reorder=(t=[])=>{let e=t.slice();return e.sort((r,o)=>r.index>o.index?1:r.index{let o=t.length,a=r===o?0:r<0?o-1:r,n=t[e];t[e]=t[a],t[a]=n};on.width=(t,e=80)=>{let r=t&&t.columns?t.columns:e;return t&&typeof t.getWindowSize=="function"&&(r=t.getWindowSize()[0]),process.platform==="win32"?r-1:r};on.height=(t,e=20)=>{let r=t&&t.rows?t.rows:e;return t&&typeof t.getWindowSize=="function"&&(r=t.getWindowSize()[1]),r};on.wordWrap=(t,e={})=>{if(!t)return t;typeof e=="number"&&(e={width:e});let{indent:r="",newline:o=` +`+r,width:a=80}=e,n=(o+r).match(/[^\S\n]/g)||[];a-=n.length;let u=`.{1,${a}}([\\s\\u200B]+|$)|[^\\s\\u200B]+?([\\s\\u200B]+|$)`,A=t.trim(),p=new RegExp(u,"g"),h=A.match(p)||[];return h=h.map(E=>E.replace(/\n$/,"")),e.padEnd&&(h=h.map(E=>E.padEnd(a," "))),e.padStart&&(h=h.map(E=>E.padStart(a," "))),r+h.join(o)};on.unmute=t=>{let e=t.stack.find(o=>rc.keys.color.includes(o));return e?rc[e]:t.stack.find(o=>o.slice(2)==="bg")?rc[e.slice(2)]:o=>o};on.pascal=t=>t?t[0].toUpperCase()+t.slice(1):"";on.inverse=t=>{if(!t||!t.stack)return t;let e=t.stack.find(o=>rc.keys.color.includes(o));if(e){let o=rc["bg"+on.pascal(e)];return o?o.black:t}let r=t.stack.find(o=>o.slice(0,2)==="bg");return r?rc[r.slice(2).toLowerCase()]||t:rc.none};on.complement=t=>{if(!t||!t.stack)return t;let e=t.stack.find(o=>rc.keys.color.includes(o)),r=t.stack.find(o=>o.slice(0,2)==="bg");if(e&&!r)return rc[Ahe[e]||e];if(r){let o=r.slice(2).toLowerCase(),a=Ahe[o];return a&&rc["bg"+on.pascal(a)]||t}return rc.none};on.meridiem=t=>{let e=t.getHours(),r=t.getMinutes(),o=e>=12?"pm":"am";e=e%12;let a=e===0?12:e,n=r<10?"0"+r:r;return a+":"+n+" "+o};on.set=(t={},e="",r)=>e.split(".").reduce((o,a,n,u)=>{let A=u.length-1>n?o[a]||{}:r;return!on.isObject(A)&&n{let o=t[e]==null?e.split(".").reduce((a,n)=>a&&a[n],t):t[e];return o??r};on.mixin=(t,e)=>{if(!Kx(t))return e;if(!Kx(e))return t;for(let r of Object.keys(e)){let o=Object.getOwnPropertyDescriptor(e,r);if(o.hasOwnProperty("value"))if(t.hasOwnProperty(r)&&Kx(o.value)){let a=Object.getOwnPropertyDescriptor(t,r);Kx(a.value)?t[r]=on.merge({},t[r],e[r]):Reflect.defineProperty(t,r,o)}else Reflect.defineProperty(t,r,o);else Reflect.defineProperty(t,r,o)}return t};on.merge=(...t)=>{let e={};for(let r of t)on.mixin(e,r);return e};on.mixinEmitter=(t,e)=>{let r=e.constructor.prototype;for(let o of Object.keys(r)){let a=r[o];typeof a=="function"?on.define(t,o,a.bind(e)):on.define(t,o,a)}};on.onExit=t=>{let e=(r,o)=>{uhe||(uhe=!0,b_.forEach(a=>a()),r===!0&&process.exit(128+o))};b_.length===0&&(process.once("SIGTERM",e.bind(null,!0,15)),process.once("SIGINT",e.bind(null,!0,2)),process.once("exit",e)),b_.push(t)};on.define=(t,e,r)=>{Reflect.defineProperty(t,e,{value:r})};on.defineExport=(t,e,r)=>{let o;Reflect.defineProperty(t,e,{enumerable:!0,configurable:!0,set(a){o=a},get(){return o?o():r()}})}});var fhe=_(qy=>{"use strict";qy.ctrl={a:"first",b:"backward",c:"cancel",d:"deleteForward",e:"last",f:"forward",g:"reset",i:"tab",k:"cutForward",l:"reset",n:"newItem",m:"cancel",j:"submit",p:"search",r:"remove",s:"save",u:"undo",w:"cutLeft",x:"toggleCursor",v:"paste"};qy.shift={up:"shiftUp",down:"shiftDown",left:"shiftLeft",right:"shiftRight",tab:"prev"};qy.fn={up:"pageUp",down:"pageDown",left:"pageLeft",right:"pageRight",delete:"deleteForward"};qy.option={b:"backward",f:"forward",d:"cutRight",left:"cutLeft",up:"altUp",down:"altDown"};qy.keys={pageup:"pageUp",pagedown:"pageDown",home:"home",end:"end",cancel:"cancel",delete:"deleteForward",backspace:"delete",down:"down",enter:"submit",escape:"cancel",left:"left",space:"space",number:"number",return:"submit",right:"right",tab:"next",up:"up"}});var ghe=_((n8t,hhe)=>{"use strict";var phe=ve("readline"),GAt=fhe(),YAt=/^(?:\x1b)([a-zA-Z0-9])$/,WAt=/^(?:\x1b+)(O|N|\[|\[\[)(?:(\d+)(?:;(\d+))?([~^$])|(?:1;)?(\d+)?([a-zA-Z]))/,KAt={OP:"f1",OQ:"f2",OR:"f3",OS:"f4","[11~":"f1","[12~":"f2","[13~":"f3","[14~":"f4","[[A":"f1","[[B":"f2","[[C":"f3","[[D":"f4","[[E":"f5","[15~":"f5","[17~":"f6","[18~":"f7","[19~":"f8","[20~":"f9","[21~":"f10","[23~":"f11","[24~":"f12","[A":"up","[B":"down","[C":"right","[D":"left","[E":"clear","[F":"end","[H":"home",OA:"up",OB:"down",OC:"right",OD:"left",OE:"clear",OF:"end",OH:"home","[1~":"home","[2~":"insert","[3~":"delete","[4~":"end","[5~":"pageup","[6~":"pagedown","[[5~":"pageup","[[6~":"pagedown","[7~":"home","[8~":"end","[a":"up","[b":"down","[c":"right","[d":"left","[e":"clear","[2$":"insert","[3$":"delete","[5$":"pageup","[6$":"pagedown","[7$":"home","[8$":"end",Oa:"up",Ob:"down",Oc:"right",Od:"left",Oe:"clear","[2^":"insert","[3^":"delete","[5^":"pageup","[6^":"pagedown","[7^":"home","[8^":"end","[Z":"tab"};function VAt(t){return["[a","[b","[c","[d","[e","[2$","[3$","[5$","[6$","[7$","[8$","[Z"].includes(t)}function zAt(t){return["Oa","Ob","Oc","Od","Oe","[2^","[3^","[5^","[6^","[7^","[8^"].includes(t)}var Vx=(t="",e={})=>{let r,o={name:e.name,ctrl:!1,meta:!1,shift:!1,option:!1,sequence:t,raw:t,...e};if(Buffer.isBuffer(t)?t[0]>127&&t[1]===void 0?(t[0]-=128,t="\x1B"+String(t)):t=String(t):t!==void 0&&typeof t!="string"?t=String(t):t||(t=o.sequence||""),o.sequence=o.sequence||t||o.name,t==="\r")o.raw=void 0,o.name="return";else if(t===` +`)o.name="enter";else if(t===" ")o.name="tab";else if(t==="\b"||t==="\x7F"||t==="\x1B\x7F"||t==="\x1B\b")o.name="backspace",o.meta=t.charAt(0)==="\x1B";else if(t==="\x1B"||t==="\x1B\x1B")o.name="escape",o.meta=t.length===2;else if(t===" "||t==="\x1B ")o.name="space",o.meta=t.length===2;else if(t<="")o.name=String.fromCharCode(t.charCodeAt(0)+97-1),o.ctrl=!0;else if(t.length===1&&t>="0"&&t<="9")o.name="number";else if(t.length===1&&t>="a"&&t<="z")o.name=t;else if(t.length===1&&t>="A"&&t<="Z")o.name=t.toLowerCase(),o.shift=!0;else if(r=YAt.exec(t))o.meta=!0,o.shift=/^[A-Z]$/.test(r[1]);else if(r=WAt.exec(t)){let a=[...t];a[0]==="\x1B"&&a[1]==="\x1B"&&(o.option=!0);let n=[r[1],r[2],r[4],r[6]].filter(Boolean).join(""),u=(r[3]||r[5]||1)-1;o.ctrl=!!(u&4),o.meta=!!(u&10),o.shift=!!(u&1),o.code=n,o.name=KAt[n],o.shift=VAt(n)||o.shift,o.ctrl=zAt(n)||o.ctrl}return o};Vx.listen=(t={},e)=>{let{stdin:r}=t;if(!r||r!==process.stdin&&!r.isTTY)throw new Error("Invalid stream passed");let o=phe.createInterface({terminal:!0,input:r});phe.emitKeypressEvents(r,o);let a=(A,p)=>e(A,Vx(A,p),o),n=r.isRaw;return r.isTTY&&r.setRawMode(!0),r.on("keypress",a),o.resume(),()=>{r.isTTY&&r.setRawMode(n),r.removeListener("keypress",a),o.pause(),o.close()}};Vx.action=(t,e,r)=>{let o={...GAt,...r};return e.ctrl?(e.action=o.ctrl[e.name],e):e.option&&o.option?(e.action=o.option[e.name],e):e.shift?(e.action=o.shift[e.name],e):(e.action=o.keys[e.name],e)};hhe.exports=Vx});var mhe=_((i8t,dhe)=>{"use strict";dhe.exports=t=>{t.timers=t.timers||{};let e=t.options.timers;if(e)for(let r of Object.keys(e)){let o=e[r];typeof o=="number"&&(o={interval:o}),JAt(t,r,o)}};function JAt(t,e,r={}){let o=t.timers[e]={name:e,start:Date.now(),ms:0,tick:0},a=r.interval||120;o.frames=r.frames||[],o.loading=!0;let n=setInterval(()=>{o.ms=Date.now()-o.start,o.tick++,t.render()},a);return o.stop=()=>{o.loading=!1,clearInterval(n)},Reflect.defineProperty(o,"interval",{value:n}),t.once("close",()=>o.stop()),o.stop}});var Ehe=_((s8t,yhe)=>{"use strict";var{define:XAt,width:ZAt}=No(),S_=class{constructor(e){let r=e.options;XAt(this,"_prompt",e),this.type=e.type,this.name=e.name,this.message="",this.header="",this.footer="",this.error="",this.hint="",this.input="",this.cursor=0,this.index=0,this.lines=0,this.tick=0,this.prompt="",this.buffer="",this.width=ZAt(r.stdout||process.stdout),Object.assign(this,r),this.name=this.name||this.message,this.message=this.message||this.name,this.symbols=e.symbols,this.styles=e.styles,this.required=new Set,this.cancelled=!1,this.submitted=!1}clone(){let e={...this};return e.status=this.status,e.buffer=Buffer.from(e.buffer),delete e.clone,e}set color(e){this._color=e}get color(){let e=this.prompt.styles;if(this.cancelled)return e.cancelled;if(this.submitted)return e.submitted;let r=this._color||e[this.status];return typeof r=="function"?r:e.pending}set loading(e){this._loading=e}get loading(){return typeof this._loading=="boolean"?this._loading:this.loadingChoices?"choices":!1}get status(){return this.cancelled?"cancelled":this.submitted?"submitted":"pending"}};yhe.exports=S_});var whe=_((o8t,Che)=>{"use strict";var x_=No(),eo=zc(),k_={default:eo.noop,noop:eo.noop,set inverse(t){this._inverse=t},get inverse(){return this._inverse||x_.inverse(this.primary)},set complement(t){this._complement=t},get complement(){return this._complement||x_.complement(this.primary)},primary:eo.cyan,success:eo.green,danger:eo.magenta,strong:eo.bold,warning:eo.yellow,muted:eo.dim,disabled:eo.gray,dark:eo.dim.gray,underline:eo.underline,set info(t){this._info=t},get info(){return this._info||this.primary},set em(t){this._em=t},get em(){return this._em||this.primary.underline},set heading(t){this._heading=t},get heading(){return this._heading||this.muted.underline},set pending(t){this._pending=t},get pending(){return this._pending||this.primary},set submitted(t){this._submitted=t},get submitted(){return this._submitted||this.success},set cancelled(t){this._cancelled=t},get cancelled(){return this._cancelled||this.danger},set typing(t){this._typing=t},get typing(){return this._typing||this.dim},set placeholder(t){this._placeholder=t},get placeholder(){return this._placeholder||this.primary.dim},set highlight(t){this._highlight=t},get highlight(){return this._highlight||this.inverse}};k_.merge=(t={})=>{t.styles&&typeof t.styles.enabled=="boolean"&&(eo.enabled=t.styles.enabled),t.styles&&typeof t.styles.visible=="boolean"&&(eo.visible=t.styles.visible);let e=x_.merge({},k_,t.styles);delete e.merge;for(let r of Object.keys(eo))e.hasOwnProperty(r)||Reflect.defineProperty(e,r,{get:()=>eo[r]});for(let r of Object.keys(eo.styles))e.hasOwnProperty(r)||Reflect.defineProperty(e,r,{get:()=>eo[r]});return e};Che.exports=k_});var Bhe=_((a8t,Ihe)=>{"use strict";var Q_=process.platform==="win32",Yf=zc(),$At=No(),F_={...Yf.symbols,upDownDoubleArrow:"\u21D5",upDownDoubleArrow2:"\u2B0D",upDownArrow:"\u2195",asterisk:"*",asterism:"\u2042",bulletWhite:"\u25E6",electricArrow:"\u2301",ellipsisLarge:"\u22EF",ellipsisSmall:"\u2026",fullBlock:"\u2588",identicalTo:"\u2261",indicator:Yf.symbols.check,leftAngle:"\u2039",mark:"\u203B",minus:"\u2212",multiplication:"\xD7",obelus:"\xF7",percent:"%",pilcrow:"\xB6",pilcrow2:"\u2761",pencilUpRight:"\u2710",pencilDownRight:"\u270E",pencilRight:"\u270F",plus:"+",plusMinus:"\xB1",pointRight:"\u261E",rightAngle:"\u203A",section:"\xA7",hexagon:{off:"\u2B21",on:"\u2B22",disabled:"\u2B22"},ballot:{on:"\u2611",off:"\u2610",disabled:"\u2612"},stars:{on:"\u2605",off:"\u2606",disabled:"\u2606"},folder:{on:"\u25BC",off:"\u25B6",disabled:"\u25B6"},prefix:{pending:Yf.symbols.question,submitted:Yf.symbols.check,cancelled:Yf.symbols.cross},separator:{pending:Yf.symbols.pointerSmall,submitted:Yf.symbols.middot,cancelled:Yf.symbols.middot},radio:{off:Q_?"( )":"\u25EF",on:Q_?"(*)":"\u25C9",disabled:Q_?"(|)":"\u24BE"},numbers:["\u24EA","\u2460","\u2461","\u2462","\u2463","\u2464","\u2465","\u2466","\u2467","\u2468","\u2469","\u246A","\u246B","\u246C","\u246D","\u246E","\u246F","\u2470","\u2471","\u2472","\u2473","\u3251","\u3252","\u3253","\u3254","\u3255","\u3256","\u3257","\u3258","\u3259","\u325A","\u325B","\u325C","\u325D","\u325E","\u325F","\u32B1","\u32B2","\u32B3","\u32B4","\u32B5","\u32B6","\u32B7","\u32B8","\u32B9","\u32BA","\u32BB","\u32BC","\u32BD","\u32BE","\u32BF"]};F_.merge=t=>{let e=$At.merge({},Yf.symbols,F_,t.symbols);return delete e.merge,e};Ihe.exports=F_});var Dhe=_((l8t,vhe)=>{"use strict";var eft=whe(),tft=Bhe(),rft=No();vhe.exports=t=>{t.options=rft.merge({},t.options.theme,t.options),t.symbols=tft.merge(t.options),t.styles=eft.merge(t.options)}});var khe=_((She,xhe)=>{"use strict";var Phe=process.env.TERM_PROGRAM==="Apple_Terminal",nft=zc(),R_=No(),Jc=xhe.exports=She,vi="\x1B[",bhe="\x07",T_=!1,Dh=Jc.code={bell:bhe,beep:bhe,beginning:`${vi}G`,down:`${vi}J`,esc:vi,getPosition:`${vi}6n`,hide:`${vi}?25l`,line:`${vi}2K`,lineEnd:`${vi}K`,lineStart:`${vi}1K`,restorePosition:vi+(Phe?"8":"u"),savePosition:vi+(Phe?"7":"s"),screen:`${vi}2J`,show:`${vi}?25h`,up:`${vi}1J`},Og=Jc.cursor={get hidden(){return T_},hide(){return T_=!0,Dh.hide},show(){return T_=!1,Dh.show},forward:(t=1)=>`${vi}${t}C`,backward:(t=1)=>`${vi}${t}D`,nextLine:(t=1)=>`${vi}E`.repeat(t),prevLine:(t=1)=>`${vi}F`.repeat(t),up:(t=1)=>t?`${vi}${t}A`:"",down:(t=1)=>t?`${vi}${t}B`:"",right:(t=1)=>t?`${vi}${t}C`:"",left:(t=1)=>t?`${vi}${t}D`:"",to(t,e){return e?`${vi}${e+1};${t+1}H`:`${vi}${t+1}G`},move(t=0,e=0){let r="";return r+=t<0?Og.left(-t):t>0?Og.right(t):"",r+=e<0?Og.up(-e):e>0?Og.down(e):"",r},restore(t={}){let{after:e,cursor:r,initial:o,input:a,prompt:n,size:u,value:A}=t;if(o=R_.isPrimitive(o)?String(o):"",a=R_.isPrimitive(a)?String(a):"",A=R_.isPrimitive(A)?String(A):"",u){let p=Jc.cursor.up(u)+Jc.cursor.to(n.length),h=a.length-r;return h>0&&(p+=Jc.cursor.left(h)),p}if(A||e){let p=!a&&o?-o.length:-a.length+r;return e&&(p-=e.length),a===""&&o&&!n.includes(o)&&(p+=o.length),Jc.cursor.move(p)}}},N_=Jc.erase={screen:Dh.screen,up:Dh.up,down:Dh.down,line:Dh.line,lineEnd:Dh.lineEnd,lineStart:Dh.lineStart,lines(t){let e="";for(let r=0;r{if(!e)return N_.line+Og.to(0);let r=n=>[...nft.unstyle(n)].length,o=t.split(/\r?\n/),a=0;for(let n of o)a+=1+Math.floor(Math.max(r(n)-1,0)/e);return(N_.line+Og.prevLine()).repeat(a-1)+N_.line+Og.to(0)}});var jy=_((c8t,Fhe)=>{"use strict";var ift=ve("events"),Qhe=zc(),L_=ghe(),sft=mhe(),oft=Ehe(),aft=Dhe(),Na=No(),Ug=khe(),M_=class t extends ift{constructor(e={}){super(),this.name=e.name,this.type=e.type,this.options=e,aft(this),sft(this),this.state=new oft(this),this.initial=[e.initial,e.default].find(r=>r!=null),this.stdout=e.stdout||process.stdout,this.stdin=e.stdin||process.stdin,this.scale=e.scale||1,this.term=this.options.term||process.env.TERM_PROGRAM,this.margin=cft(this.options.margin),this.setMaxListeners(0),lft(this)}async keypress(e,r={}){this.keypressed=!0;let o=L_.action(e,L_(e,r),this.options.actions);this.state.keypress=o,this.emit("keypress",e,o),this.emit("state",this.state.clone());let a=this.options[o.action]||this[o.action]||this.dispatch;if(typeof a=="function")return await a.call(this,e,o);this.alert()}alert(){delete this.state.alert,this.options.show===!1?this.emit("alert"):this.stdout.write(Ug.code.beep)}cursorHide(){this.stdout.write(Ug.cursor.hide()),Na.onExit(()=>this.cursorShow())}cursorShow(){this.stdout.write(Ug.cursor.show())}write(e){e&&(this.stdout&&this.state.show!==!1&&this.stdout.write(e),this.state.buffer+=e)}clear(e=0){let r=this.state.buffer;this.state.buffer="",!(!r&&!e||this.options.show===!1)&&this.stdout.write(Ug.cursor.down(e)+Ug.clear(r,this.width))}restore(){if(this.state.closed||this.options.show===!1)return;let{prompt:e,after:r,rest:o}=this.sections(),{cursor:a,initial:n="",input:u="",value:A=""}=this,p=this.state.size=o.length,h={after:r,cursor:a,initial:n,input:u,prompt:e,size:p,value:A},E=Ug.cursor.restore(h);E&&this.stdout.write(E)}sections(){let{buffer:e,input:r,prompt:o}=this.state;o=Qhe.unstyle(o);let a=Qhe.unstyle(e),n=a.indexOf(o),u=a.slice(0,n),p=a.slice(n).split(` +`),h=p[0],E=p[p.length-1],v=(o+(r?" "+r:"")).length,x=ve.call(this,this.value),this.result=()=>o.call(this,this.value),typeof r.initial=="function"&&(this.initial=await r.initial.call(this,this)),typeof r.onRun=="function"&&await r.onRun.call(this,this),typeof r.onSubmit=="function"){let a=r.onSubmit.bind(this),n=this.submit.bind(this);delete this.options.onSubmit,this.submit=async()=>(await a(this.name,this.value,this),n())}await this.start(),await this.render()}render(){throw new Error("expected prompt to have a custom render method")}run(){return new Promise(async(e,r)=>{if(this.once("submit",e),this.once("cancel",r),await this.skip())return this.render=()=>{},this.submit();await this.initialize(),this.emit("run")})}async element(e,r,o){let{options:a,state:n,symbols:u,timers:A}=this,p=A&&A[e];n.timer=p;let h=a[e]||n[e]||u[e],E=r&&r[e]!=null?r[e]:await h;if(E==="")return E;let I=await this.resolve(E,n,r,o);return!I&&r&&r[e]?this.resolve(h,n,r,o):I}async prefix(){let e=await this.element("prefix")||this.symbols,r=this.timers&&this.timers.prefix,o=this.state;return o.timer=r,Na.isObject(e)&&(e=e[o.status]||e.pending),Na.hasColor(e)?e:(this.styles[o.status]||this.styles.pending)(e)}async message(){let e=await this.element("message");return Na.hasColor(e)?e:this.styles.strong(e)}async separator(){let e=await this.element("separator")||this.symbols,r=this.timers&&this.timers.separator,o=this.state;o.timer=r;let a=e[o.status]||e.pending||o.separator,n=await this.resolve(a,o);return Na.isObject(n)&&(n=n[o.status]||n.pending),Na.hasColor(n)?n:this.styles.muted(n)}async pointer(e,r){let o=await this.element("pointer",e,r);if(typeof o=="string"&&Na.hasColor(o))return o;if(o){let a=this.styles,n=this.index===r,u=n?a.primary:h=>h,A=await this.resolve(o[n?"on":"off"]||o,this.state),p=Na.hasColor(A)?A:u(A);return n?p:" ".repeat(A.length)}}async indicator(e,r){let o=await this.element("indicator",e,r);if(typeof o=="string"&&Na.hasColor(o))return o;if(o){let a=this.styles,n=e.enabled===!0,u=n?a.success:a.dark,A=o[n?"on":"off"]||o;return Na.hasColor(A)?A:u(A)}return""}body(){return null}footer(){if(this.state.status==="pending")return this.element("footer")}header(){if(this.state.status==="pending")return this.element("header")}async hint(){if(this.state.status==="pending"&&!this.isValue(this.state.input)){let e=await this.element("hint");return Na.hasColor(e)?e:this.styles.muted(e)}}error(e){return this.state.submitted?"":e||this.state.error}format(e){return e}result(e){return e}validate(e){return this.options.required===!0?this.isValue(e):!0}isValue(e){return e!=null&&e!==""}resolve(e,...r){return Na.resolve(this,e,...r)}get base(){return t.prototype}get style(){return this.styles[this.state.status]}get height(){return this.options.rows||Na.height(this.stdout,25)}get width(){return this.options.columns||Na.width(this.stdout,80)}get size(){return{width:this.width,height:this.height}}set cursor(e){this.state.cursor=e}get cursor(){return this.state.cursor}set input(e){this.state.input=e}get input(){return this.state.input}set value(e){this.state.value=e}get value(){let{input:e,value:r}=this.state,o=[r,e].find(this.isValue.bind(this));return this.isValue(o)?o:this.initial}static get prompt(){return e=>new this(e).run()}};function lft(t){let e=a=>t[a]===void 0||typeof t[a]=="function",r=["actions","choices","initial","margin","roles","styles","symbols","theme","timers","value"],o=["body","footer","error","header","hint","indicator","message","prefix","separator","skip"];for(let a of Object.keys(t.options)){if(r.includes(a)||/^on[A-Z]/.test(a))continue;let n=t.options[a];typeof n=="function"&&e(a)?o.includes(a)||(t[a]=n.bind(t)):typeof t[a]!="function"&&(t[a]=n)}}function cft(t){typeof t=="number"&&(t=[t,t,t,t]);let e=[].concat(t||[]),r=a=>a%2===0?` +`:" ",o=[];for(let a=0;a<4;a++){let n=r(a);e[a]?o.push(n.repeat(e[a])):o.push("")}return o}Fhe.exports=M_});var Nhe=_((u8t,The)=>{"use strict";var uft=No(),Rhe={default(t,e){return e},checkbox(t,e){throw new Error("checkbox role is not implemented yet")},editable(t,e){throw new Error("editable role is not implemented yet")},expandable(t,e){throw new Error("expandable role is not implemented yet")},heading(t,e){return e.disabled="",e.indicator=[e.indicator," "].find(r=>r!=null),e.message=e.message||"",e},input(t,e){throw new Error("input role is not implemented yet")},option(t,e){return Rhe.default(t,e)},radio(t,e){throw new Error("radio role is not implemented yet")},separator(t,e){return e.disabled="",e.indicator=[e.indicator," "].find(r=>r!=null),e.message=e.message||t.symbols.line.repeat(5),e},spacer(t,e){return e}};The.exports=(t,e={})=>{let r=uft.merge({},Rhe,e.roles);return r[t]||r.default}});var V1=_((A8t,Ohe)=>{"use strict";var Aft=zc(),fft=jy(),pft=Nhe(),zx=No(),{reorder:O_,scrollUp:hft,scrollDown:gft,isObject:Lhe,swap:dft}=zx,U_=class extends fft{constructor(e){super(e),this.cursorHide(),this.maxSelected=e.maxSelected||1/0,this.multiple=e.multiple||!1,this.initial=e.initial||0,this.delay=e.delay||0,this.longest=0,this.num=""}async initialize(){typeof this.options.initial=="function"&&(this.initial=await this.options.initial.call(this)),await this.reset(!0),await super.initialize()}async reset(){let{choices:e,initial:r,autofocus:o,suggest:a}=this.options;if(this.state._choices=[],this.state.choices=[],this.choices=await Promise.all(await this.toChoices(e)),this.choices.forEach(n=>n.enabled=!1),typeof a!="function"&&this.selectable.length===0)throw new Error("At least one choice must be selectable");Lhe(r)&&(r=Object.keys(r)),Array.isArray(r)?(o!=null&&(this.index=this.findIndex(o)),r.forEach(n=>this.enable(this.find(n))),await this.render()):(o!=null&&(r=o),typeof r=="string"&&(r=this.findIndex(r)),typeof r=="number"&&r>-1&&(this.index=Math.max(0,Math.min(r,this.choices.length)),this.enable(this.find(this.index)))),this.isDisabled(this.focused)&&await this.down()}async toChoices(e,r){this.state.loadingChoices=!0;let o=[],a=0,n=async(u,A)=>{typeof u=="function"&&(u=await u.call(this)),u instanceof Promise&&(u=await u);for(let p=0;p(this.state.loadingChoices=!1,u))}async toChoice(e,r,o){if(typeof e=="function"&&(e=await e.call(this,this)),e instanceof Promise&&(e=await e),typeof e=="string"&&(e={name:e}),e.normalized)return e;e.normalized=!0;let a=e.value;if(e=pft(e.role,this.options)(this,e),typeof e.disabled=="string"&&!e.hint&&(e.hint=e.disabled,e.disabled=!0),e.disabled===!0&&e.hint==null&&(e.hint="(disabled)"),e.index!=null)return e;e.name=e.name||e.key||e.title||e.value||e.message,e.message=e.message||e.name||"",e.value=[e.value,e.name].find(this.isValue.bind(this)),e.input="",e.index=r,e.cursor=0,zx.define(e,"parent",o),e.level=o?o.level+1:1,e.indent==null&&(e.indent=o?o.indent+" ":e.indent||""),e.path=o?o.path+"."+e.name:e.name,e.enabled=!!(this.multiple&&!this.isDisabled(e)&&(e.enabled||this.isSelected(e))),this.isDisabled(e)||(this.longest=Math.max(this.longest,Aft.unstyle(e.message).length));let u={...e};return e.reset=(A=u.input,p=u.value)=>{for(let h of Object.keys(u))e[h]=u[h];e.input=A,e.value=p},a==null&&typeof e.initial=="function"&&(e.input=await e.initial.call(this,this.state,e,r)),e}async onChoice(e,r){this.emit("choice",e,r,this),typeof e.onChoice=="function"&&await e.onChoice.call(this,this.state,e,r)}async addChoice(e,r,o){let a=await this.toChoice(e,r,o);return this.choices.push(a),this.index=this.choices.length-1,this.limit=this.choices.length,a}async newItem(e,r,o){let a={name:"New choice name?",editable:!0,newChoice:!0,...e},n=await this.addChoice(a,r,o);return n.updateChoice=()=>{delete n.newChoice,n.name=n.message=n.input,n.input="",n.cursor=0},this.render()}indent(e){return e.indent==null?e.level>1?" ".repeat(e.level-1):"":e.indent}dispatch(e,r){if(this.multiple&&this[r.name])return this[r.name]();this.alert()}focus(e,r){return typeof r!="boolean"&&(r=e.enabled),r&&!e.enabled&&this.selected.length>=this.maxSelected?this.alert():(this.index=e.index,e.enabled=r&&!this.isDisabled(e),e)}space(){return this.multiple?(this.toggle(this.focused),this.render()):this.alert()}a(){if(this.maxSelectedr.enabled);return this.choices.forEach(r=>r.enabled=!e),this.render()}i(){return this.choices.length-this.selected.length>this.maxSelected?this.alert():(this.choices.forEach(e=>e.enabled=!e.enabled),this.render())}g(e=this.focused){return this.choices.some(r=>!!r.parent)?(this.toggle(e.parent&&!e.choices?e.parent:e),this.render()):this.a()}toggle(e,r){if(!e.enabled&&this.selected.length>=this.maxSelected)return this.alert();typeof r!="boolean"&&(r=!e.enabled),e.enabled=r,e.choices&&e.choices.forEach(a=>this.toggle(a,r));let o=e.parent;for(;o;){let a=o.choices.filter(n=>this.isDisabled(n));o.enabled=a.every(n=>n.enabled===!0),o=o.parent}return Mhe(this,this.choices),this.emit("toggle",e,this),e}enable(e){return this.selected.length>=this.maxSelected?this.alert():(e.enabled=!this.isDisabled(e),e.choices&&e.choices.forEach(this.enable.bind(this)),e)}disable(e){return e.enabled=!1,e.choices&&e.choices.forEach(this.disable.bind(this)),e}number(e){this.num+=e;let r=o=>{let a=Number(o);if(a>this.choices.length-1)return this.alert();let n=this.focused,u=this.choices.find(A=>a===A.index);if(!u.enabled&&this.selected.length>=this.maxSelected)return this.alert();if(this.visible.indexOf(u)===-1){let A=O_(this.choices),p=A.indexOf(u);if(n.index>p){let h=A.slice(p,p+this.limit),E=A.filter(I=>!h.includes(I));this.choices=h.concat(E)}else{let h=p-this.limit+1;this.choices=A.slice(h).concat(A.slice(0,h))}}return this.index=this.choices.indexOf(u),this.toggle(this.focused),this.render()};return clearTimeout(this.numberTimeout),new Promise(o=>{let a=this.choices.length,n=this.num,u=(A=!1,p)=>{clearTimeout(this.numberTimeout),A&&(p=r(n)),this.num="",o(p)};if(n==="0"||n.length===1&&+(n+"0")>a)return u(!0);if(Number(n)>a)return u(!1,this.alert());this.numberTimeout=setTimeout(()=>u(!0),this.delay)})}home(){return this.choices=O_(this.choices),this.index=0,this.render()}end(){let e=this.choices.length-this.limit,r=O_(this.choices);return this.choices=r.slice(e).concat(r.slice(0,e)),this.index=this.limit-1,this.render()}first(){return this.index=0,this.render()}last(){return this.index=this.visible.length-1,this.render()}prev(){return this.visible.length<=1?this.alert():this.up()}next(){return this.visible.length<=1?this.alert():this.down()}right(){return this.cursor>=this.input.length?this.alert():(this.cursor++,this.render())}left(){return this.cursor<=0?this.alert():(this.cursor--,this.render())}up(){let e=this.choices.length,r=this.visible.length,o=this.index;return this.options.scroll===!1&&o===0?this.alert():e>r&&o===0?this.scrollUp():(this.index=(o-1%e+e)%e,this.isDisabled()?this.up():this.render())}down(){let e=this.choices.length,r=this.visible.length,o=this.index;return this.options.scroll===!1&&o===r-1?this.alert():e>r&&o===r-1?this.scrollDown():(this.index=(o+1)%e,this.isDisabled()?this.down():this.render())}scrollUp(e=0){return this.choices=hft(this.choices),this.index=e,this.isDisabled()?this.up():this.render()}scrollDown(e=this.visible.length-1){return this.choices=gft(this.choices),this.index=e,this.isDisabled()?this.down():this.render()}async shiftUp(){if(this.options.sort===!0){this.sorting=!0,this.swap(this.index-1),await this.up(),this.sorting=!1;return}return this.scrollUp(this.index)}async shiftDown(){if(this.options.sort===!0){this.sorting=!0,this.swap(this.index+1),await this.down(),this.sorting=!1;return}return this.scrollDown(this.index)}pageUp(){return this.visible.length<=1?this.alert():(this.limit=Math.max(this.limit-1,0),this.index=Math.min(this.limit-1,this.index),this._limit=this.limit,this.isDisabled()?this.up():this.render())}pageDown(){return this.visible.length>=this.choices.length?this.alert():(this.index=Math.max(0,this.index),this.limit=Math.min(this.limit+1,this.choices.length),this._limit=this.limit,this.isDisabled()?this.down():this.render())}swap(e){dft(this.choices,this.index,e)}isDisabled(e=this.focused){return e&&["disabled","collapsed","hidden","completing","readonly"].some(o=>e[o]===!0)?!0:e&&e.role==="heading"}isEnabled(e=this.focused){if(Array.isArray(e))return e.every(r=>this.isEnabled(r));if(e.choices){let r=e.choices.filter(o=>!this.isDisabled(o));return e.enabled&&r.every(o=>this.isEnabled(o))}return e.enabled&&!this.isDisabled(e)}isChoice(e,r){return e.name===r||e.index===Number(r)}isSelected(e){return Array.isArray(this.initial)?this.initial.some(r=>this.isChoice(e,r)):this.isChoice(e,this.initial)}map(e=[],r="value"){return[].concat(e||[]).reduce((o,a)=>(o[a]=this.find(a,r),o),{})}filter(e,r){let a=typeof e=="function"?e:(A,p)=>[A.name,p].includes(e),u=(this.options.multiple?this.state._choices:this.choices).filter(a);return r?u.map(A=>A[r]):u}find(e,r){if(Lhe(e))return r?e[r]:e;let a=typeof e=="function"?e:(u,A)=>[u.name,A].includes(e),n=this.choices.find(a);if(n)return r?n[r]:n}findIndex(e){return this.choices.indexOf(this.find(e))}async submit(){let e=this.focused;if(!e)return this.alert();if(e.newChoice)return e.input?(e.updateChoice(),this.render()):this.alert();if(this.choices.some(u=>u.newChoice))return this.alert();let{reorder:r,sort:o}=this.options,a=this.multiple===!0,n=this.selected;return n===void 0?this.alert():(Array.isArray(n)&&r!==!1&&o!==!0&&(n=zx.reorder(n)),this.value=a?n.map(u=>u.name):n.name,super.submit())}set choices(e=[]){this.state._choices=this.state._choices||[],this.state.choices=e;for(let r of e)this.state._choices.some(o=>o.name===r.name)||this.state._choices.push(r);if(!this._initial&&this.options.initial){this._initial=!0;let r=this.initial;if(typeof r=="string"||typeof r=="number"){let o=this.find(r);o&&(this.initial=o.index,this.focus(o,!0))}}}get choices(){return Mhe(this,this.state.choices||[])}set visible(e){this.state.visible=e}get visible(){return(this.state.visible||this.choices).slice(0,this.limit)}set limit(e){this.state.limit=e}get limit(){let{state:e,options:r,choices:o}=this,a=e.limit||this._limit||r.limit||o.length;return Math.min(a,this.height)}set value(e){super.value=e}get value(){return typeof super.value!="string"&&super.value===this.initial?this.input:super.value}set index(e){this.state.index=e}get index(){return Math.max(0,this.state?this.state.index:0)}get enabled(){return this.filter(this.isEnabled.bind(this))}get focused(){let e=this.choices[this.index];return e&&this.state.submitted&&this.multiple!==!0&&(e.enabled=!0),e}get selectable(){return this.choices.filter(e=>!this.isDisabled(e))}get selected(){return this.multiple?this.enabled:this.focused}};function Mhe(t,e){if(e instanceof Promise)return e;if(typeof e=="function"){if(zx.isAsyncFn(e))return e;e=e.call(t,t)}for(let r of e){if(Array.isArray(r.choices)){let o=r.choices.filter(a=>!t.isDisabled(a));r.enabled=o.every(a=>a.enabled===!0)}t.isDisabled(r)===!0&&delete r.enabled}return e}Ohe.exports=U_});var Ph=_((f8t,Uhe)=>{"use strict";var mft=V1(),__=No(),H_=class extends mft{constructor(e){super(e),this.emptyError=this.options.emptyError||"No items were selected"}async dispatch(e,r){if(this.multiple)return this[r.name]?await this[r.name](e,r):await super.dispatch(e,r);this.alert()}separator(){if(this.options.separator)return super.separator();let e=this.styles.muted(this.symbols.ellipsis);return this.state.submitted?super.separator():e}pointer(e,r){return!this.multiple||this.options.pointer?super.pointer(e,r):""}indicator(e,r){return this.multiple?super.indicator(e,r):""}choiceMessage(e,r){let o=this.resolve(e.message,this.state,e,r);return e.role==="heading"&&!__.hasColor(o)&&(o=this.styles.strong(o)),this.resolve(o,this.state,e,r)}choiceSeparator(){return":"}async renderChoice(e,r){await this.onChoice(e,r);let o=this.index===r,a=await this.pointer(e,r),n=await this.indicator(e,r)+(e.pad||""),u=await this.resolve(e.hint,this.state,e,r);u&&!__.hasColor(u)&&(u=this.styles.muted(u));let A=this.indent(e),p=await this.choiceMessage(e,r),h=()=>[this.margin[3],A+a+n,p,this.margin[1],u].filter(Boolean).join(" ");return e.role==="heading"?h():e.disabled?(__.hasColor(p)||(p=this.styles.disabled(p)),h()):(o&&(p=this.styles.em(p)),h())}async renderChoices(){if(this.state.loading==="choices")return this.styles.warning("Loading choices");if(this.state.submitted)return"";let e=this.visible.map(async(n,u)=>await this.renderChoice(n,u)),r=await Promise.all(e);r.length||r.push(this.styles.danger("No matching choices"));let o=this.margin[0]+r.join(` +`),a;return this.options.choicesHeader&&(a=await this.resolve(this.options.choicesHeader,this.state)),[a,o].filter(Boolean).join(` +`)}format(){return!this.state.submitted||this.state.cancelled?"":Array.isArray(this.selected)?this.selected.map(e=>this.styles.primary(e.name)).join(", "):this.styles.primary(this.selected.name)}async render(){let{submitted:e,size:r}=this.state,o="",a=await this.header(),n=await this.prefix(),u=await this.separator(),A=await this.message();this.options.promptLine!==!1&&(o=[n,A,u,""].join(" "),this.state.prompt=o);let p=await this.format(),h=await this.error()||await this.hint(),E=await this.renderChoices(),I=await this.footer();p&&(o+=p),h&&!o.includes(h)&&(o+=" "+h),e&&!p&&!E.trim()&&this.multiple&&this.emptyError!=null&&(o+=this.styles.danger(this.emptyError)),this.clear(r),this.write([a,o,E,I].filter(Boolean).join(` +`)),this.write(this.margin[2]),this.restore()}};Uhe.exports=H_});var Hhe=_((p8t,_he)=>{"use strict";var yft=Ph(),Eft=(t,e)=>{let r=t.toLowerCase();return o=>{let n=o.toLowerCase().indexOf(r),u=e(o.slice(n,n+r.length));return n>=0?o.slice(0,n)+u+o.slice(n+r.length):o}},q_=class extends yft{constructor(e){super(e),this.cursorShow()}moveCursor(e){this.state.cursor+=e}dispatch(e){return this.append(e)}space(e){return this.options.multiple?super.space(e):this.append(e)}append(e){let{cursor:r,input:o}=this.state;return this.input=o.slice(0,r)+e+o.slice(r),this.moveCursor(1),this.complete()}delete(){let{cursor:e,input:r}=this.state;return r?(this.input=r.slice(0,e-1)+r.slice(e),this.moveCursor(-1),this.complete()):this.alert()}deleteForward(){let{cursor:e,input:r}=this.state;return r[e]===void 0?this.alert():(this.input=`${r}`.slice(0,e)+`${r}`.slice(e+1),this.complete())}number(e){return this.append(e)}async complete(){this.completing=!0,this.choices=await this.suggest(this.input,this.state._choices),this.state.limit=void 0,this.index=Math.min(Math.max(this.visible.length-1,0),this.index),await this.render(),this.completing=!1}suggest(e=this.input,r=this.state._choices){if(typeof this.options.suggest=="function")return this.options.suggest.call(this,e,r);let o=e.toLowerCase();return r.filter(a=>a.message.toLowerCase().includes(o))}pointer(){return""}format(){if(!this.focused)return this.input;if(this.options.multiple&&this.state.submitted)return this.selected.map(e=>this.styles.primary(e.message)).join(", ");if(this.state.submitted){let e=this.value=this.input=this.focused.value;return this.styles.primary(e)}return this.input}async render(){if(this.state.status!=="pending")return super.render();let e=this.options.highlight?this.options.highlight.bind(this):this.styles.placeholder,r=Eft(this.input,e),o=this.choices;this.choices=o.map(a=>({...a,message:r(a.message)})),await super.render(),this.choices=o}submit(){return this.options.multiple&&(this.value=this.selected.map(e=>e.name)),super.submit()}};_he.exports=q_});var G_=_((h8t,qhe)=>{"use strict";var j_=No();qhe.exports=(t,e={})=>{t.cursorHide();let{input:r="",initial:o="",pos:a,showCursor:n=!0,color:u}=e,A=u||t.styles.placeholder,p=j_.inverse(t.styles.primary),h=R=>p(t.styles.black(R)),E=r,I=" ",v=h(I);if(t.blink&&t.blink.off===!0&&(h=R=>R,v=""),n&&a===0&&o===""&&r==="")return h(I);if(n&&a===0&&(r===o||r===""))return h(o[0])+A(o.slice(1));o=j_.isPrimitive(o)?`${o}`:"",r=j_.isPrimitive(r)?`${r}`:"";let x=o&&o.startsWith(r)&&o!==r,C=x?h(o[r.length]):v;if(a!==r.length&&n===!0&&(E=r.slice(0,a)+h(r[a])+r.slice(a+1),C=""),n===!1&&(C=""),x){let R=t.styles.unstyle(E+C);return E+C+A(o.slice(R.length))}return E+C}});var Jx=_((g8t,jhe)=>{"use strict";var Cft=zc(),wft=Ph(),Ift=G_(),Y_=class extends wft{constructor(e){super({...e,multiple:!0}),this.type="form",this.initial=this.options.initial,this.align=[this.options.align,"right"].find(r=>r!=null),this.emptyError="",this.values={}}async reset(e){return await super.reset(),e===!0&&(this._index=this.index),this.index=this._index,this.values={},this.choices.forEach(r=>r.reset&&r.reset()),this.render()}dispatch(e){return!!e&&this.append(e)}append(e){let r=this.focused;if(!r)return this.alert();let{cursor:o,input:a}=r;return r.value=r.input=a.slice(0,o)+e+a.slice(o),r.cursor++,this.render()}delete(){let e=this.focused;if(!e||e.cursor<=0)return this.alert();let{cursor:r,input:o}=e;return e.value=e.input=o.slice(0,r-1)+o.slice(r),e.cursor--,this.render()}deleteForward(){let e=this.focused;if(!e)return this.alert();let{cursor:r,input:o}=e;if(o[r]===void 0)return this.alert();let a=`${o}`.slice(0,r)+`${o}`.slice(r+1);return e.value=e.input=a,this.render()}right(){let e=this.focused;return e?e.cursor>=e.input.length?this.alert():(e.cursor++,this.render()):this.alert()}left(){let e=this.focused;return e?e.cursor<=0?this.alert():(e.cursor--,this.render()):this.alert()}space(e,r){return this.dispatch(e,r)}number(e,r){return this.dispatch(e,r)}next(){let e=this.focused;if(!e)return this.alert();let{initial:r,input:o}=e;return r&&r.startsWith(o)&&o!==r?(e.value=e.input=r,e.cursor=e.value.length,this.render()):super.next()}prev(){let e=this.focused;return e?e.cursor===0?super.prev():(e.value=e.input="",e.cursor=0,this.render()):this.alert()}separator(){return""}format(e){return this.state.submitted?"":super.format(e)}pointer(){return""}indicator(e){return e.input?"\u29BF":"\u2299"}async choiceSeparator(e,r){let o=await this.resolve(e.separator,this.state,e,r)||":";return o?" "+this.styles.disabled(o):""}async renderChoice(e,r){await this.onChoice(e,r);let{state:o,styles:a}=this,{cursor:n,initial:u="",name:A,hint:p,input:h=""}=e,{muted:E,submitted:I,primary:v,danger:x}=a,C=p,R=this.index===r,L=e.validate||(()=>!0),U=await this.choiceSeparator(e,r),z=e.message;this.align==="right"&&(z=z.padStart(this.longest+1," ")),this.align==="left"&&(z=z.padEnd(this.longest+1," "));let te=this.values[A]=h||u,ae=h?"success":"dark";await L.call(e,te,this.state)!==!0&&(ae="danger");let le=a[ae],ce=le(await this.indicator(e,r))+(e.pad||""),Ce=this.indent(e),de=()=>[Ce,ce,z+U,h,C].filter(Boolean).join(" ");if(o.submitted)return z=Cft.unstyle(z),h=I(h),C="",de();if(e.format)h=await e.format.call(this,h,e,r);else{let Be=this.styles.muted;h=Ift(this,{input:h,initial:u,pos:n,showCursor:R,color:Be})}return this.isValue(h)||(h=this.styles.muted(this.symbols.ellipsis)),e.result&&(this.values[A]=await e.result.call(this,te,e,r)),R&&(z=v(z)),e.error?h+=(h?" ":"")+x(e.error.trim()):e.hint&&(h+=(h?" ":"")+E(e.hint.trim())),de()}async submit(){return this.value=this.values,super.base.submit.call(this)}};jhe.exports=Y_});var W_=_((d8t,Yhe)=>{"use strict";var Bft=Jx(),vft=()=>{throw new Error("expected prompt to have a custom authenticate method")},Ghe=(t=vft)=>{class e extends Bft{constructor(o){super(o)}async submit(){this.value=await t.call(this,this.values,this.state),super.base.submit.call(this)}static create(o){return Ghe(o)}}return e};Yhe.exports=Ghe()});var Vhe=_((m8t,Khe)=>{"use strict";var Dft=W_();function Pft(t,e){return t.username===this.options.username&&t.password===this.options.password}var Whe=(t=Pft)=>{let e=[{name:"username",message:"username"},{name:"password",message:"password",format(o){return this.options.showPassword?o:(this.state.submitted?this.styles.primary:this.styles.muted)(this.symbols.asterisk.repeat(o.length))}}];class r extends Dft.create(t){constructor(a){super({...a,choices:e})}static create(a){return Whe(a)}}return r};Khe.exports=Whe()});var Xx=_((y8t,zhe)=>{"use strict";var bft=jy(),{isPrimitive:Sft,hasColor:xft}=No(),K_=class extends bft{constructor(e){super(e),this.cursorHide()}async initialize(){let e=await this.resolve(this.initial,this.state);this.input=await this.cast(e),await super.initialize()}dispatch(e){return this.isValue(e)?(this.input=e,this.submit()):this.alert()}format(e){let{styles:r,state:o}=this;return o.submitted?r.success(e):r.primary(e)}cast(e){return this.isTrue(e)}isTrue(e){return/^[ty1]/i.test(e)}isFalse(e){return/^[fn0]/i.test(e)}isValue(e){return Sft(e)&&(this.isTrue(e)||this.isFalse(e))}async hint(){if(this.state.status==="pending"){let e=await this.element("hint");return xft(e)?e:this.styles.muted(e)}}async render(){let{input:e,size:r}=this.state,o=await this.prefix(),a=await this.separator(),n=await this.message(),u=this.styles.muted(this.default),A=[o,n,u,a].filter(Boolean).join(" ");this.state.prompt=A;let p=await this.header(),h=this.value=this.cast(e),E=await this.format(h),I=await this.error()||await this.hint(),v=await this.footer();I&&!A.includes(I)&&(E+=" "+I),A+=" "+E,this.clear(r),this.write([p,A,v].filter(Boolean).join(` +`)),this.restore()}set value(e){super.value=e}get value(){return this.cast(super.value)}};zhe.exports=K_});var Xhe=_((E8t,Jhe)=>{"use strict";var kft=Xx(),V_=class extends kft{constructor(e){super(e),this.default=this.options.default||(this.initial?"(Y/n)":"(y/N)")}};Jhe.exports=V_});var $he=_((C8t,Zhe)=>{"use strict";var Qft=Ph(),Fft=Jx(),Gy=Fft.prototype,z_=class extends Qft{constructor(e){super({...e,multiple:!0}),this.align=[this.options.align,"left"].find(r=>r!=null),this.emptyError="",this.values={}}dispatch(e,r){let o=this.focused,a=o.parent||{};return!o.editable&&!a.editable&&(e==="a"||e==="i")?super[e]():Gy.dispatch.call(this,e,r)}append(e,r){return Gy.append.call(this,e,r)}delete(e,r){return Gy.delete.call(this,e,r)}space(e){return this.focused.editable?this.append(e):super.space()}number(e){return this.focused.editable?this.append(e):super.number(e)}next(){return this.focused.editable?Gy.next.call(this):super.next()}prev(){return this.focused.editable?Gy.prev.call(this):super.prev()}async indicator(e,r){let o=e.indicator||"",a=e.editable?o:super.indicator(e,r);return await this.resolve(a,this.state,e,r)||""}indent(e){return e.role==="heading"?"":e.editable?" ":" "}async renderChoice(e,r){return e.indent="",e.editable?Gy.renderChoice.call(this,e,r):super.renderChoice(e,r)}error(){return""}footer(){return this.state.error}async validate(){let e=!0;for(let r of this.choices){if(typeof r.validate!="function"||r.role==="heading")continue;let o=r.parent?this.value[r.parent.name]:this.value;if(r.editable?o=r.value===r.name?r.initial||"":r.value:this.isDisabled(r)||(o=r.enabled===!0),e=await r.validate(o,this.state),e!==!0)break}return e!==!0&&(this.state.error=typeof e=="string"?e:"Invalid Input"),e}submit(){if(this.focused.newChoice===!0)return super.submit();if(this.choices.some(e=>e.newChoice))return this.alert();this.value={};for(let e of this.choices){let r=e.parent?this.value[e.parent.name]:this.value;if(e.role==="heading"){this.value[e.name]={};continue}e.editable?r[e.name]=e.value===e.name?e.initial||"":e.value:this.isDisabled(e)||(r[e.name]=e.enabled===!0)}return this.base.submit.call(this)}};Zhe.exports=z_});var _g=_((w8t,e0e)=>{"use strict";var Rft=jy(),Tft=G_(),{isPrimitive:Nft}=No(),J_=class extends Rft{constructor(e){super(e),this.initial=Nft(this.initial)?String(this.initial):"",this.initial&&this.cursorHide(),this.state.prevCursor=0,this.state.clipboard=[]}async keypress(e,r={}){let o=this.state.prevKeypress;return this.state.prevKeypress=r,this.options.multiline===!0&&r.name==="return"&&(!o||o.name!=="return")?this.append(` +`,r):super.keypress(e,r)}moveCursor(e){this.cursor+=e}reset(){return this.input=this.value="",this.cursor=0,this.render()}dispatch(e,r){if(!e||r.ctrl||r.code)return this.alert();this.append(e)}append(e){let{cursor:r,input:o}=this.state;this.input=`${o}`.slice(0,r)+e+`${o}`.slice(r),this.moveCursor(String(e).length),this.render()}insert(e){this.append(e)}delete(){let{cursor:e,input:r}=this.state;if(e<=0)return this.alert();this.input=`${r}`.slice(0,e-1)+`${r}`.slice(e),this.moveCursor(-1),this.render()}deleteForward(){let{cursor:e,input:r}=this.state;if(r[e]===void 0)return this.alert();this.input=`${r}`.slice(0,e)+`${r}`.slice(e+1),this.render()}cutForward(){let e=this.cursor;if(this.input.length<=e)return this.alert();this.state.clipboard.push(this.input.slice(e)),this.input=this.input.slice(0,e),this.render()}cutLeft(){let e=this.cursor;if(e===0)return this.alert();let r=this.input.slice(0,e),o=this.input.slice(e),a=r.split(" ");this.state.clipboard.push(a.pop()),this.input=a.join(" "),this.cursor=this.input.length,this.input+=o,this.render()}paste(){if(!this.state.clipboard.length)return this.alert();this.insert(this.state.clipboard.pop()),this.render()}toggleCursor(){this.state.prevCursor?(this.cursor=this.state.prevCursor,this.state.prevCursor=0):(this.state.prevCursor=this.cursor,this.cursor=0),this.render()}first(){this.cursor=0,this.render()}last(){this.cursor=this.input.length-1,this.render()}next(){let e=this.initial!=null?String(this.initial):"";if(!e||!e.startsWith(this.input))return this.alert();this.input=this.initial,this.cursor=this.initial.length,this.render()}prev(){if(!this.input)return this.alert();this.reset()}backward(){return this.left()}forward(){return this.right()}right(){return this.cursor>=this.input.length?this.alert():(this.moveCursor(1),this.render())}left(){return this.cursor<=0?this.alert():(this.moveCursor(-1),this.render())}isValue(e){return!!e}async format(e=this.value){let r=await this.resolve(this.initial,this.state);return this.state.submitted?this.styles.submitted(e||r):Tft(this,{input:e,initial:r,pos:this.cursor})}async render(){let e=this.state.size,r=await this.prefix(),o=await this.separator(),a=await this.message(),n=[r,a,o].filter(Boolean).join(" ");this.state.prompt=n;let u=await this.header(),A=await this.format(),p=await this.error()||await this.hint(),h=await this.footer();p&&!A.includes(p)&&(A+=" "+p),n+=" "+A,this.clear(e),this.write([u,n,h].filter(Boolean).join(` +`)),this.restore()}};e0e.exports=J_});var r0e=_((I8t,t0e)=>{"use strict";var Lft=t=>t.filter((e,r)=>t.lastIndexOf(e)===r),Zx=t=>Lft(t).filter(Boolean);t0e.exports=(t,e={},r="")=>{let{past:o=[],present:a=""}=e,n,u;switch(t){case"prev":case"undo":return n=o.slice(0,o.length-1),u=o[o.length-1]||"",{past:Zx([r,...n]),present:u};case"next":case"redo":return n=o.slice(1),u=o[0]||"",{past:Zx([...n,r]),present:u};case"save":return{past:Zx([...o,r]),present:""};case"remove":return u=Zx(o.filter(A=>A!==r)),a="",u.length&&(a=u.pop()),{past:u,present:a};default:throw new Error(`Invalid action: "${t}"`)}}});var Z_=_((B8t,i0e)=>{"use strict";var Mft=_g(),n0e=r0e(),X_=class extends Mft{constructor(e){super(e);let r=this.options.history;if(r&&r.store){let o=r.values||this.initial;this.autosave=!!r.autosave,this.store=r.store,this.data=this.store.get("values")||{past:[],present:o},this.initial=this.data.present||this.data.past[this.data.past.length-1]}}completion(e){return this.store?(this.data=n0e(e,this.data,this.input),this.data.present?(this.input=this.data.present,this.cursor=this.input.length,this.render()):this.alert()):this.alert()}altUp(){return this.completion("prev")}altDown(){return this.completion("next")}prev(){return this.save(),super.prev()}save(){this.store&&(this.data=n0e("save",this.data,this.input),this.store.set("values",this.data))}submit(){return this.store&&this.autosave===!0&&this.save(),super.submit()}};i0e.exports=X_});var o0e=_((v8t,s0e)=>{"use strict";var Oft=_g(),$_=class extends Oft{format(){return""}};s0e.exports=$_});var l0e=_((D8t,a0e)=>{"use strict";var Uft=_g(),e8=class extends Uft{constructor(e={}){super(e),this.sep=this.options.separator||/, */,this.initial=e.initial||""}split(e=this.value){return e?String(e).split(this.sep):[]}format(){let e=this.state.submitted?this.styles.primary:r=>r;return this.list.map(e).join(", ")}async submit(e){let r=this.state.error||await this.validate(this.list,this.state);return r!==!0?(this.state.error=r,super.submit()):(this.value=this.list,super.submit())}get list(){return this.split()}};a0e.exports=e8});var u0e=_((P8t,c0e)=>{"use strict";var _ft=Ph(),t8=class extends _ft{constructor(e){super({...e,multiple:!0})}};c0e.exports=t8});var n8=_((b8t,A0e)=>{"use strict";var Hft=_g(),r8=class extends Hft{constructor(e={}){super({style:"number",...e}),this.min=this.isValue(e.min)?this.toNumber(e.min):-1/0,this.max=this.isValue(e.max)?this.toNumber(e.max):1/0,this.delay=e.delay!=null?e.delay:1e3,this.float=e.float!==!1,this.round=e.round===!0||e.float===!1,this.major=e.major||10,this.minor=e.minor||1,this.initial=e.initial!=null?e.initial:"",this.input=String(this.initial),this.cursor=this.input.length,this.cursorShow()}append(e){return!/[-+.]/.test(e)||e==="."&&this.input.includes(".")?this.alert("invalid number"):super.append(e)}number(e){return super.append(e)}next(){return this.input&&this.input!==this.initial?this.alert():this.isValue(this.initial)?(this.input=this.initial,this.cursor=String(this.initial).length,this.render()):this.alert()}up(e){let r=e||this.minor,o=this.toNumber(this.input);return o>this.max+r?this.alert():(this.input=`${o+r}`,this.render())}down(e){let r=e||this.minor,o=this.toNumber(this.input);return othis.isValue(r));return this.value=this.toNumber(e||0),super.submit()}};A0e.exports=r8});var p0e=_((S8t,f0e)=>{f0e.exports=n8()});var g0e=_((x8t,h0e)=>{"use strict";var qft=_g(),i8=class extends qft{constructor(e){super(e),this.cursorShow()}format(e=this.input){return this.keypressed?(this.state.submitted?this.styles.primary:this.styles.muted)(this.symbols.asterisk.repeat(e.length)):""}};h0e.exports=i8});var y0e=_((k8t,m0e)=>{"use strict";var jft=zc(),Gft=V1(),d0e=No(),s8=class extends Gft{constructor(e={}){super(e),this.widths=[].concat(e.messageWidth||50),this.align=[].concat(e.align||"left"),this.linebreak=e.linebreak||!1,this.edgeLength=e.edgeLength||3,this.newline=e.newline||` + `;let r=e.startNumber||1;typeof this.scale=="number"&&(this.scaleKey=!1,this.scale=Array(this.scale).fill(0).map((o,a)=>({name:a+r})))}async reset(){return this.tableized=!1,await super.reset(),this.render()}tableize(){if(this.tableized===!0)return;this.tableized=!0;let e=0;for(let r of this.choices){e=Math.max(e,r.message.length),r.scaleIndex=r.initial||2,r.scale=[];for(let o=0;o=this.scale.length-1?this.alert():(e.scaleIndex++,this.render())}left(){let e=this.focused;return e.scaleIndex<=0?this.alert():(e.scaleIndex--,this.render())}indent(){return""}format(){return this.state.submitted?this.choices.map(r=>this.styles.info(r.index)).join(", "):""}pointer(){return""}renderScaleKey(){return this.scaleKey===!1||this.state.submitted?"":["",...this.scale.map(o=>` ${o.name} - ${o.message}`)].map(o=>this.styles.muted(o)).join(` +`)}renderScaleHeading(e){let r=this.scale.map(p=>p.name);typeof this.options.renderScaleHeading=="function"&&(r=this.options.renderScaleHeading.call(this,e));let o=this.scaleLength-r.join("").length,a=Math.round(o/(r.length-1)),u=r.map(p=>this.styles.strong(p)).join(" ".repeat(a)),A=" ".repeat(this.widths[0]);return this.margin[3]+A+this.margin[1]+u}scaleIndicator(e,r,o){if(typeof this.options.scaleIndicator=="function")return this.options.scaleIndicator.call(this,e,r,o);let a=e.scaleIndex===r.index;return r.disabled?this.styles.hint(this.symbols.radio.disabled):a?this.styles.success(this.symbols.radio.on):this.symbols.radio.off}renderScale(e,r){let o=e.scale.map(n=>this.scaleIndicator(e,n,r)),a=this.term==="Hyper"?"":" ";return o.join(a+this.symbols.line.repeat(this.edgeLength))}async renderChoice(e,r){await this.onChoice(e,r);let o=this.index===r,a=await this.pointer(e,r),n=await e.hint;n&&!d0e.hasColor(n)&&(n=this.styles.muted(n));let u=C=>this.margin[3]+C.replace(/\s+$/,"").padEnd(this.widths[0]," "),A=this.newline,p=this.indent(e),h=await this.resolve(e.message,this.state,e,r),E=await this.renderScale(e,r),I=this.margin[1]+this.margin[3];this.scaleLength=jft.unstyle(E).length,this.widths[0]=Math.min(this.widths[0],this.width-this.scaleLength-I.length);let x=d0e.wordWrap(h,{width:this.widths[0],newline:A}).split(` +`).map(C=>u(C)+this.margin[1]);return o&&(E=this.styles.info(E),x=x.map(C=>this.styles.info(C))),x[0]+=E,this.linebreak&&x.push(""),[p+a,x.join(` +`)].filter(Boolean)}async renderChoices(){if(this.state.submitted)return"";this.tableize();let e=this.visible.map(async(a,n)=>await this.renderChoice(a,n)),r=await Promise.all(e),o=await this.renderScaleHeading();return this.margin[0]+[o,...r.map(a=>a.join(" "))].join(` +`)}async render(){let{submitted:e,size:r}=this.state,o=await this.prefix(),a=await this.separator(),n=await this.message(),u="";this.options.promptLine!==!1&&(u=[o,n,a,""].join(" "),this.state.prompt=u);let A=await this.header(),p=await this.format(),h=await this.renderScaleKey(),E=await this.error()||await this.hint(),I=await this.renderChoices(),v=await this.footer(),x=this.emptyError;p&&(u+=p),E&&!u.includes(E)&&(u+=" "+E),e&&!p&&!I.trim()&&this.multiple&&x!=null&&(u+=this.styles.danger(x)),this.clear(r),this.write([A,u,h,I,v].filter(Boolean).join(` +`)),this.state.submitted||this.write(this.margin[2]),this.restore()}submit(){this.value={};for(let e of this.choices)this.value[e.name]=e.scaleIndex;return this.base.submit.call(this)}};m0e.exports=s8});var w0e=_((Q8t,C0e)=>{"use strict";var E0e=zc(),Yft=(t="")=>typeof t=="string"?t.replace(/^['"]|['"]$/g,""):"",a8=class{constructor(e){this.name=e.key,this.field=e.field||{},this.value=Yft(e.initial||this.field.initial||""),this.message=e.message||this.name,this.cursor=0,this.input="",this.lines=[]}},Wft=async(t={},e={},r=o=>o)=>{let o=new Set,a=t.fields||[],n=t.template,u=[],A=[],p=[],h=1;typeof n=="function"&&(n=await n());let E=-1,I=()=>n[++E],v=()=>n[E+1],x=C=>{C.line=h,u.push(C)};for(x({type:"bos",value:""});Eae.name===U.key);U.field=a.find(ae=>ae.name===U.key),te||(te=new a8(U),A.push(te)),te.lines.push(U.line-1);continue}let R=u[u.length-1];R.type==="text"&&R.line===h?R.value+=C:x({type:"text",value:C})}return x({type:"eos",value:""}),{input:n,tabstops:u,unique:o,keys:p,items:A}};C0e.exports=async t=>{let e=t.options,r=new Set(e.required===!0?[]:e.required||[]),o={...e.values,...e.initial},{tabstops:a,items:n,keys:u}=await Wft(e,o),A=o8("result",t,e),p=o8("format",t,e),h=o8("validate",t,e,!0),E=t.isValue.bind(t);return async(I={},v=!1)=>{let x=0;I.required=r,I.items=n,I.keys=u,I.output="";let C=async(z,te,ae,le)=>{let ce=await h(z,te,ae,le);return ce===!1?"Invalid field "+ae.name:ce};for(let z of a){let te=z.value,ae=z.key;if(z.type!=="template"){te&&(I.output+=te);continue}if(z.type==="template"){let le=n.find(Ee=>Ee.name===ae);e.required===!0&&I.required.add(le.name);let ce=[le.input,I.values[le.value],le.value,te].find(E),de=(le.field||{}).message||z.inner;if(v){let Ee=await C(I.values[ae],I,le,x);if(Ee&&typeof Ee=="string"||Ee===!1){I.invalid.set(ae,Ee);continue}I.invalid.delete(ae);let g=await A(I.values[ae],I,le,x);I.output+=E0e.unstyle(g);continue}le.placeholder=!1;let Be=te;te=await p(te,I,le,x),ce!==te?(I.values[ae]=ce,te=t.styles.typing(ce),I.missing.delete(de)):(I.values[ae]=void 0,ce=`<${de}>`,te=t.styles.primary(ce),le.placeholder=!0,I.required.has(ae)&&I.missing.add(de)),I.missing.has(de)&&I.validating&&(te=t.styles.warning(ce)),I.invalid.has(ae)&&I.validating&&(te=t.styles.danger(ce)),x===I.index&&(Be!==te?te=t.styles.underline(te):te=t.styles.heading(E0e.unstyle(te))),x++}te&&(I.output+=te)}let R=I.output.split(` +`).map(z=>" "+z),L=n.length,U=0;for(let z of n)I.invalid.has(z.name)&&z.lines.forEach(te=>{R[te][0]===" "&&(R[te]=I.styles.danger(I.symbols.bullet)+R[te].slice(1))}),t.isValue(I.values[z.name])&&U++;return I.completed=(U/L*100).toFixed(0),I.output=R.join(` +`),I.output}};function o8(t,e,r,o){return(a,n,u,A)=>typeof u.field[t]=="function"?u.field[t].call(e,a,n,u,A):[o,a].find(p=>e.isValue(p))}});var B0e=_((F8t,I0e)=>{"use strict";var Kft=zc(),Vft=w0e(),zft=jy(),l8=class extends zft{constructor(e){super(e),this.cursorHide(),this.reset(!0)}async initialize(){this.interpolate=await Vft(this),await super.initialize()}async reset(e){this.state.keys=[],this.state.invalid=new Map,this.state.missing=new Set,this.state.completed=0,this.state.values={},e!==!0&&(await this.initialize(),await this.render())}moveCursor(e){let r=this.getItem();this.cursor+=e,r.cursor+=e}dispatch(e,r){if(!r.code&&!r.ctrl&&e!=null&&this.getItem()){this.append(e,r);return}this.alert()}append(e,r){let o=this.getItem(),a=o.input.slice(0,this.cursor),n=o.input.slice(this.cursor);this.input=o.input=`${a}${e}${n}`,this.moveCursor(1),this.render()}delete(){let e=this.getItem();if(this.cursor<=0||!e.input)return this.alert();let r=e.input.slice(this.cursor),o=e.input.slice(0,this.cursor-1);this.input=e.input=`${o}${r}`,this.moveCursor(-1),this.render()}increment(e){return e>=this.state.keys.length-1?0:e+1}decrement(e){return e<=0?this.state.keys.length-1:e-1}first(){this.state.index=0,this.render()}last(){this.state.index=this.state.keys.length-1,this.render()}right(){if(this.cursor>=this.input.length)return this.alert();this.moveCursor(1),this.render()}left(){if(this.cursor<=0)return this.alert();this.moveCursor(-1),this.render()}prev(){this.state.index=this.decrement(this.state.index),this.getItem(),this.render()}next(){this.state.index=this.increment(this.state.index),this.getItem(),this.render()}up(){this.prev()}down(){this.next()}format(e){let r=this.state.completed<100?this.styles.warning:this.styles.success;return this.state.submitted===!0&&this.state.completed!==100&&(r=this.styles.danger),r(`${this.state.completed}% completed`)}async render(){let{index:e,keys:r=[],submitted:o,size:a}=this.state,n=[this.options.newline,` +`].find(z=>z!=null),u=await this.prefix(),A=await this.separator(),p=await this.message(),h=[u,p,A].filter(Boolean).join(" ");this.state.prompt=h;let E=await this.header(),I=await this.error()||"",v=await this.hint()||"",x=o?"":await this.interpolate(this.state),C=this.state.key=r[e]||"",R=await this.format(C),L=await this.footer();R&&(h+=" "+R),v&&!R&&this.state.completed===0&&(h+=" "+v),this.clear(a);let U=[E,h,x,L,I.trim()];this.write(U.filter(Boolean).join(n)),this.restore()}getItem(e){let{items:r,keys:o,index:a}=this.state,n=r.find(u=>u.name===o[a]);return n&&n.input!=null&&(this.input=n.input,this.cursor=n.cursor),n}async submit(){typeof this.interpolate!="function"&&await this.initialize(),await this.interpolate(this.state,!0);let{invalid:e,missing:r,output:o,values:a}=this.state;if(e.size){let A="";for(let[p,h]of e)A+=`Invalid ${p}: ${h} +`;return this.state.error=A,super.submit()}if(r.size)return this.state.error="Required: "+[...r.keys()].join(", "),super.submit();let u=Kft.unstyle(o).split(` +`).map(A=>A.slice(1)).join(` +`);return this.value={values:a,result:u},super.submit()}};I0e.exports=l8});var D0e=_((R8t,v0e)=>{"use strict";var Jft="(Use + to sort)",Xft=Ph(),c8=class extends Xft{constructor(e){super({...e,reorder:!1,sort:!0,multiple:!0}),this.state.hint=[this.options.hint,Jft].find(this.isValue.bind(this))}indicator(){return""}async renderChoice(e,r){let o=await super.renderChoice(e,r),a=this.symbols.identicalTo+" ",n=this.index===r&&this.sorting?this.styles.muted(a):" ";return this.options.drag===!1&&(n=""),this.options.numbered===!0?n+`${r+1} - `+o:n+o}get selected(){return this.choices}submit(){return this.value=this.choices.map(e=>e.value),super.submit()}};v0e.exports=c8});var b0e=_((T8t,P0e)=>{"use strict";var Zft=V1(),u8=class extends Zft{constructor(e={}){if(super(e),this.emptyError=e.emptyError||"No items were selected",this.term=process.env.TERM_PROGRAM,!this.options.header){let r=["","4 - Strongly Agree","3 - Agree","2 - Neutral","1 - Disagree","0 - Strongly Disagree",""];r=r.map(o=>this.styles.muted(o)),this.state.header=r.join(` + `)}}async toChoices(...e){if(this.createdScales)return!1;this.createdScales=!0;let r=await super.toChoices(...e);for(let o of r)o.scale=$ft(5,this.options),o.scaleIdx=2;return r}dispatch(){this.alert()}space(){let e=this.focused,r=e.scale[e.scaleIdx],o=r.selected;return e.scale.forEach(a=>a.selected=!1),r.selected=!o,this.render()}indicator(){return""}pointer(){return""}separator(){return this.styles.muted(this.symbols.ellipsis)}right(){let e=this.focused;return e.scaleIdx>=e.scale.length-1?this.alert():(e.scaleIdx++,this.render())}left(){let e=this.focused;return e.scaleIdx<=0?this.alert():(e.scaleIdx--,this.render())}indent(){return" "}async renderChoice(e,r){await this.onChoice(e,r);let o=this.index===r,a=this.term==="Hyper",n=a?9:8,u=a?"":" ",A=this.symbols.line.repeat(n),p=" ".repeat(n+(a?0:1)),h=te=>(te?this.styles.success("\u25C9"):"\u25EF")+u,E=r+1+".",I=o?this.styles.heading:this.styles.noop,v=await this.resolve(e.message,this.state,e,r),x=this.indent(e),C=x+e.scale.map((te,ae)=>h(ae===e.scaleIdx)).join(A),R=te=>te===e.scaleIdx?I(te):te,L=x+e.scale.map((te,ae)=>R(ae)).join(p),U=()=>[E,v].filter(Boolean).join(" "),z=()=>[U(),C,L," "].filter(Boolean).join(` +`);return o&&(C=this.styles.cyan(C),L=this.styles.cyan(L)),z()}async renderChoices(){if(this.state.submitted)return"";let e=this.visible.map(async(o,a)=>await this.renderChoice(o,a)),r=await Promise.all(e);return r.length||r.push(this.styles.danger("No matching choices")),r.join(` +`)}format(){return this.state.submitted?this.choices.map(r=>this.styles.info(r.scaleIdx)).join(", "):""}async render(){let{submitted:e,size:r}=this.state,o=await this.prefix(),a=await this.separator(),n=await this.message(),u=[o,n,a].filter(Boolean).join(" ");this.state.prompt=u;let A=await this.header(),p=await this.format(),h=await this.error()||await this.hint(),E=await this.renderChoices(),I=await this.footer();(p||!h)&&(u+=" "+p),h&&!u.includes(h)&&(u+=" "+h),e&&!p&&!E&&this.multiple&&this.type!=="form"&&(u+=this.styles.danger(this.emptyError)),this.clear(r),this.write([u,A,E,I].filter(Boolean).join(` +`)),this.restore()}submit(){this.value={};for(let e of this.choices)this.value[e.name]=e.scaleIdx;return this.base.submit.call(this)}};function $ft(t,e={}){if(Array.isArray(e.scale))return e.scale.map(o=>({...o}));let r=[];for(let o=1;o{S0e.exports=Z_()});var Q0e=_((L8t,k0e)=>{"use strict";var ept=Xx(),A8=class extends ept{async initialize(){await super.initialize(),this.value=this.initial=!!this.options.initial,this.disabled=this.options.disabled||"no",this.enabled=this.options.enabled||"yes",await this.render()}reset(){this.value=this.initial,this.render()}delete(){this.alert()}toggle(){this.value=!this.value,this.render()}enable(){if(this.value===!0)return this.alert();this.value=!0,this.render()}disable(){if(this.value===!1)return this.alert();this.value=!1,this.render()}up(){this.toggle()}down(){this.toggle()}right(){this.toggle()}left(){this.toggle()}next(){this.toggle()}prev(){this.toggle()}dispatch(e="",r){switch(e.toLowerCase()){case" ":return this.toggle();case"1":case"y":case"t":return this.enable();case"0":case"n":case"f":return this.disable();default:return this.alert()}}format(){let e=o=>this.styles.primary.underline(o);return[this.value?this.disabled:e(this.disabled),this.value?e(this.enabled):this.enabled].join(this.styles.muted(" / "))}async render(){let{size:e}=this.state,r=await this.header(),o=await this.prefix(),a=await this.separator(),n=await this.message(),u=await this.format(),A=await this.error()||await this.hint(),p=await this.footer(),h=[o,n,a,u].join(" ");this.state.prompt=h,A&&!h.includes(A)&&(h+=" "+A),this.clear(e),this.write([r,h,p].filter(Boolean).join(` +`)),this.write(this.margin[2]),this.restore()}};k0e.exports=A8});var R0e=_((M8t,F0e)=>{"use strict";var tpt=Ph(),f8=class extends tpt{constructor(e){if(super(e),typeof this.options.correctChoice!="number"||this.options.correctChoice<0)throw new Error("Please specify the index of the correct answer from the list of choices")}async toChoices(e,r){let o=await super.toChoices(e,r);if(o.length<2)throw new Error("Please give at least two choices to the user");if(this.options.correctChoice>o.length)throw new Error("Please specify the index of the correct answer from the list of choices");return o}check(e){return e.index===this.options.correctChoice}async result(e){return{selectedAnswer:e,correctAnswer:this.options.choices[this.options.correctChoice].value,correct:await this.check(this.state)}}};F0e.exports=f8});var N0e=_(p8=>{"use strict";var T0e=No(),ps=(t,e)=>{T0e.defineExport(p8,t,e),T0e.defineExport(p8,t.toLowerCase(),e)};ps("AutoComplete",()=>Hhe());ps("BasicAuth",()=>Vhe());ps("Confirm",()=>Xhe());ps("Editable",()=>$he());ps("Form",()=>Jx());ps("Input",()=>Z_());ps("Invisible",()=>o0e());ps("List",()=>l0e());ps("MultiSelect",()=>u0e());ps("Numeral",()=>p0e());ps("Password",()=>g0e());ps("Scale",()=>y0e());ps("Select",()=>Ph());ps("Snippet",()=>B0e());ps("Sort",()=>D0e());ps("Survey",()=>b0e());ps("Text",()=>x0e());ps("Toggle",()=>Q0e());ps("Quiz",()=>R0e())});var M0e=_((U8t,L0e)=>{L0e.exports={ArrayPrompt:V1(),AuthPrompt:W_(),BooleanPrompt:Xx(),NumberPrompt:n8(),StringPrompt:_g()}});var J1=_((_8t,U0e)=>{"use strict";var O0e=ve("assert"),g8=ve("events"),bh=No(),Xc=class extends g8{constructor(e,r){super(),this.options=bh.merge({},e),this.answers={...r}}register(e,r){if(bh.isObject(e)){for(let a of Object.keys(e))this.register(a,e[a]);return this}O0e.equal(typeof r,"function","expected a function");let o=e.toLowerCase();return r.prototype instanceof this.Prompt?this.prompts[o]=r:this.prompts[o]=r(this.Prompt,this),this}async prompt(e=[]){for(let r of[].concat(e))try{typeof r=="function"&&(r=await r.call(this)),await this.ask(bh.merge({},this.options,r))}catch(o){return Promise.reject(o)}return this.answers}async ask(e){typeof e=="function"&&(e=await e.call(this));let r=bh.merge({},this.options,e),{type:o,name:a}=e,{set:n,get:u}=bh;if(typeof o=="function"&&(o=await o.call(this,e,this.answers)),!o)return this.answers[a];O0e(this.prompts[o],`Prompt "${o}" is not registered`);let A=new this.prompts[o](r),p=u(this.answers,a);A.state.answers=this.answers,A.enquirer=this,a&&A.on("submit",E=>{this.emit("answer",a,E,A),n(this.answers,a,E)});let h=A.emit.bind(A);return A.emit=(...E)=>(this.emit.call(this,...E),h(...E)),this.emit("prompt",A,this),r.autofill&&p!=null?(A.value=A.input=p,r.autofill==="show"&&await A.submit()):p=A.value=await A.run(),p}use(e){return e.call(this,this),this}set Prompt(e){this._Prompt=e}get Prompt(){return this._Prompt||this.constructor.Prompt}get prompts(){return this.constructor.prompts}static set Prompt(e){this._Prompt=e}static get Prompt(){return this._Prompt||jy()}static get prompts(){return N0e()}static get types(){return M0e()}static get prompt(){let e=(r,...o)=>{let a=new this(...o),n=a.emit.bind(a);return a.emit=(...u)=>(e.emit(...u),n(...u)),a.prompt(r)};return bh.mixinEmitter(e,new g8),e}};bh.mixinEmitter(Xc,new g8);var h8=Xc.prompts;for(let t of Object.keys(h8)){let e=t.toLowerCase(),r=o=>new h8[t](o).run();Xc.prompt[e]=r,Xc[e]=r,Xc[t]||Reflect.defineProperty(Xc,t,{get:()=>h8[t]})}var z1=t=>{bh.defineExport(Xc,t,()=>Xc.types[t])};z1("ArrayPrompt");z1("AuthPrompt");z1("BooleanPrompt");z1("NumberPrompt");z1("StringPrompt");U0e.exports=Xc});var e2=_((IHt,W0e)=>{var apt=Ux();function lpt(t,e,r){var o=t==null?void 0:apt(t,e);return o===void 0?r:o}W0e.exports=lpt});var z0e=_((SHt,V0e)=>{function cpt(t,e){for(var r=-1,o=t==null?0:t.length;++r{var upt=Ag(),Apt=LP();function fpt(t,e){return t&&upt(e,Apt(e),t)}J0e.exports=fpt});var $0e=_((kHt,Z0e)=>{var ppt=Ag(),hpt=bm();function gpt(t,e){return t&&ppt(e,hpt(e),t)}Z0e.exports=gpt});var tge=_((QHt,ege)=>{var dpt=Ag(),mpt=kP();function ypt(t,e){return dpt(t,mpt(t),e)}ege.exports=ypt});var w8=_((FHt,rge)=>{var Ept=xP(),Cpt=HP(),wpt=kP(),Ipt=MN(),Bpt=Object.getOwnPropertySymbols,vpt=Bpt?function(t){for(var e=[];t;)Ept(e,wpt(t)),t=Cpt(t);return e}:Ipt;rge.exports=vpt});var ige=_((RHt,nge)=>{var Dpt=Ag(),Ppt=w8();function bpt(t,e){return Dpt(t,Ppt(t),e)}nge.exports=bpt});var I8=_((THt,sge)=>{var Spt=LN(),xpt=w8(),kpt=bm();function Qpt(t){return Spt(t,kpt,xpt)}sge.exports=Qpt});var age=_((NHt,oge)=>{var Fpt=Object.prototype,Rpt=Fpt.hasOwnProperty;function Tpt(t){var e=t.length,r=new t.constructor(e);return e&&typeof t[0]=="string"&&Rpt.call(t,"index")&&(r.index=t.index,r.input=t.input),r}oge.exports=Tpt});var cge=_((LHt,lge)=>{var Npt=UP();function Lpt(t,e){var r=e?Npt(t.buffer):t.buffer;return new t.constructor(r,t.byteOffset,t.byteLength)}lge.exports=Lpt});var Age=_((MHt,uge)=>{var Mpt=/\w*$/;function Opt(t){var e=new t.constructor(t.source,Mpt.exec(t));return e.lastIndex=t.lastIndex,e}uge.exports=Opt});var dge=_((OHt,gge)=>{var fge=lg(),pge=fge?fge.prototype:void 0,hge=pge?pge.valueOf:void 0;function Upt(t){return hge?Object(hge.call(t)):{}}gge.exports=Upt});var yge=_((UHt,mge)=>{var _pt=UP(),Hpt=cge(),qpt=Age(),jpt=dge(),Gpt=XN(),Ypt="[object Boolean]",Wpt="[object Date]",Kpt="[object Map]",Vpt="[object Number]",zpt="[object RegExp]",Jpt="[object Set]",Xpt="[object String]",Zpt="[object Symbol]",$pt="[object ArrayBuffer]",eht="[object DataView]",tht="[object Float32Array]",rht="[object Float64Array]",nht="[object Int8Array]",iht="[object Int16Array]",sht="[object Int32Array]",oht="[object Uint8Array]",aht="[object Uint8ClampedArray]",lht="[object Uint16Array]",cht="[object Uint32Array]";function uht(t,e,r){var o=t.constructor;switch(e){case $pt:return _pt(t);case Ypt:case Wpt:return new o(+t);case eht:return Hpt(t,r);case tht:case rht:case nht:case iht:case sht:case oht:case aht:case lht:case cht:return Gpt(t,r);case Kpt:return new o;case Vpt:case Xpt:return new o(t);case zpt:return qpt(t);case Jpt:return new o;case Zpt:return jpt(t)}}mge.exports=uht});var Cge=_((_Ht,Ege)=>{var Aht=PI(),fht=Ju(),pht="[object Map]";function hht(t){return fht(t)&&Aht(t)==pht}Ege.exports=hht});var vge=_((HHt,Bge)=>{var ght=Cge(),dht=FP(),wge=RP(),Ige=wge&&wge.isMap,mht=Ige?dht(Ige):ght;Bge.exports=mht});var Pge=_((qHt,Dge)=>{var yht=PI(),Eht=Ju(),Cht="[object Set]";function wht(t){return Eht(t)&&yht(t)==Cht}Dge.exports=wht});var kge=_((jHt,xge)=>{var Iht=Pge(),Bht=FP(),bge=RP(),Sge=bge&&bge.isSet,vht=Sge?Bht(Sge):Iht;xge.exports=vht});var B8=_((GHt,Tge)=>{var Dht=bP(),Pht=z0e(),bht=qP(),Sht=X0e(),xht=$0e(),kht=JN(),Qht=_P(),Fht=tge(),Rht=ige(),Tht=HN(),Nht=I8(),Lht=PI(),Mht=age(),Oht=yge(),Uht=ZN(),_ht=Hl(),Hht=wI(),qht=vge(),jht=sl(),Ght=kge(),Yht=LP(),Wht=bm(),Kht=1,Vht=2,zht=4,Qge="[object Arguments]",Jht="[object Array]",Xht="[object Boolean]",Zht="[object Date]",$ht="[object Error]",Fge="[object Function]",e0t="[object GeneratorFunction]",t0t="[object Map]",r0t="[object Number]",Rge="[object Object]",n0t="[object RegExp]",i0t="[object Set]",s0t="[object String]",o0t="[object Symbol]",a0t="[object WeakMap]",l0t="[object ArrayBuffer]",c0t="[object DataView]",u0t="[object Float32Array]",A0t="[object Float64Array]",f0t="[object Int8Array]",p0t="[object Int16Array]",h0t="[object Int32Array]",g0t="[object Uint8Array]",d0t="[object Uint8ClampedArray]",m0t="[object Uint16Array]",y0t="[object Uint32Array]",ri={};ri[Qge]=ri[Jht]=ri[l0t]=ri[c0t]=ri[Xht]=ri[Zht]=ri[u0t]=ri[A0t]=ri[f0t]=ri[p0t]=ri[h0t]=ri[t0t]=ri[r0t]=ri[Rge]=ri[n0t]=ri[i0t]=ri[s0t]=ri[o0t]=ri[g0t]=ri[d0t]=ri[m0t]=ri[y0t]=!0;ri[$ht]=ri[Fge]=ri[a0t]=!1;function ek(t,e,r,o,a,n){var u,A=e&Kht,p=e&Vht,h=e&zht;if(r&&(u=a?r(t,o,a,n):r(t)),u!==void 0)return u;if(!jht(t))return t;var E=_ht(t);if(E){if(u=Mht(t),!A)return Qht(t,u)}else{var I=Lht(t),v=I==Fge||I==e0t;if(Hht(t))return kht(t,A);if(I==Rge||I==Qge||v&&!a){if(u=p||v?{}:Uht(t),!A)return p?Rht(t,xht(u,t)):Fht(t,Sht(u,t))}else{if(!ri[I])return a?t:{};u=Oht(t,I,A)}}n||(n=new Dht);var x=n.get(t);if(x)return x;n.set(t,u),Ght(t)?t.forEach(function(L){u.add(ek(L,e,r,L,t,n))}):qht(t)&&t.forEach(function(L,U){u.set(U,ek(L,e,r,U,t,n))});var C=h?p?Nht:Tht:p?Wht:Yht,R=E?void 0:C(t);return Pht(R||t,function(L,U){R&&(U=L,L=t[U]),bht(u,U,ek(L,e,r,U,t,n))}),u}Tge.exports=ek});var v8=_((YHt,Nge)=>{var E0t=B8(),C0t=1,w0t=4;function I0t(t){return E0t(t,C0t|w0t)}Nge.exports=I0t});var D8=_((WHt,Lge)=>{var B0t=g_();function v0t(t,e,r){return t==null?t:B0t(t,e,r)}Lge.exports=v0t});var Hge=_((ZHt,_ge)=>{var D0t=Object.prototype,P0t=D0t.hasOwnProperty;function b0t(t,e){return t!=null&&P0t.call(t,e)}_ge.exports=b0t});var jge=_(($Ht,qge)=>{var S0t=Hge(),x0t=d_();function k0t(t,e){return t!=null&&x0t(t,e,S0t)}qge.exports=k0t});var Yge=_((e6t,Gge)=>{function Q0t(t){var e=t==null?0:t.length;return e?t[e-1]:void 0}Gge.exports=Q0t});var Kge=_((t6t,Wge)=>{var F0t=Ux(),R0t=oU();function T0t(t,e){return e.length<2?t:F0t(t,R0t(e,0,-1))}Wge.exports=T0t});var b8=_((r6t,Vge)=>{var N0t=Mg(),L0t=Yge(),M0t=Kge(),O0t=Ly();function U0t(t,e){return e=N0t(e,t),t=M0t(t,e),t==null||delete t[O0t(L0t(e))]}Vge.exports=U0t});var S8=_((n6t,zge)=>{var _0t=b8();function H0t(t,e){return t==null?!0:_0t(t,e)}zge.exports=H0t});var ede=_((F6t,G0t)=>{G0t.exports={name:"@yarnpkg/cli",version:"4.4.1",license:"BSD-2-Clause",main:"./sources/index.ts",exports:{".":"./sources/index.ts","./polyfills":"./sources/polyfills.ts","./package.json":"./package.json"},dependencies:{"@yarnpkg/core":"workspace:^","@yarnpkg/fslib":"workspace:^","@yarnpkg/libzip":"workspace:^","@yarnpkg/parsers":"workspace:^","@yarnpkg/plugin-compat":"workspace:^","@yarnpkg/plugin-constraints":"workspace:^","@yarnpkg/plugin-dlx":"workspace:^","@yarnpkg/plugin-essentials":"workspace:^","@yarnpkg/plugin-exec":"workspace:^","@yarnpkg/plugin-file":"workspace:^","@yarnpkg/plugin-git":"workspace:^","@yarnpkg/plugin-github":"workspace:^","@yarnpkg/plugin-http":"workspace:^","@yarnpkg/plugin-init":"workspace:^","@yarnpkg/plugin-interactive-tools":"workspace:^","@yarnpkg/plugin-link":"workspace:^","@yarnpkg/plugin-nm":"workspace:^","@yarnpkg/plugin-npm":"workspace:^","@yarnpkg/plugin-npm-cli":"workspace:^","@yarnpkg/plugin-pack":"workspace:^","@yarnpkg/plugin-patch":"workspace:^","@yarnpkg/plugin-pnp":"workspace:^","@yarnpkg/plugin-pnpm":"workspace:^","@yarnpkg/plugin-stage":"workspace:^","@yarnpkg/plugin-typescript":"workspace:^","@yarnpkg/plugin-version":"workspace:^","@yarnpkg/plugin-workspace-tools":"workspace:^","@yarnpkg/shell":"workspace:^","ci-info":"^4.0.0",clipanion:"^4.0.0-rc.2",semver:"^7.1.2",tslib:"^2.4.0",typanion:"^3.14.0"},devDependencies:{"@types/semver":"^7.1.0","@yarnpkg/builder":"workspace:^","@yarnpkg/monorepo":"workspace:^","@yarnpkg/pnpify":"workspace:^"},peerDependencies:{"@yarnpkg/core":"workspace:^"},scripts:{postpack:"rm -rf lib",prepack:'run build:compile "$(pwd)"',"build:cli+hook":"run build:pnp:hook && builder build bundle","build:cli":"builder build bundle","run:cli":"builder run","update-local":"run build:cli --no-git-hash && rsync -a --delete bundles/ bin/"},publishConfig:{main:"./lib/index.js",bin:null,exports:{".":"./lib/index.js","./package.json":"./package.json"}},files:["/lib/**/*","!/lib/pluginConfiguration.*","!/lib/cli.*"],"@yarnpkg/builder":{bundles:{standard:["@yarnpkg/plugin-essentials","@yarnpkg/plugin-compat","@yarnpkg/plugin-constraints","@yarnpkg/plugin-dlx","@yarnpkg/plugin-exec","@yarnpkg/plugin-file","@yarnpkg/plugin-git","@yarnpkg/plugin-github","@yarnpkg/plugin-http","@yarnpkg/plugin-init","@yarnpkg/plugin-interactive-tools","@yarnpkg/plugin-link","@yarnpkg/plugin-nm","@yarnpkg/plugin-npm","@yarnpkg/plugin-npm-cli","@yarnpkg/plugin-pack","@yarnpkg/plugin-patch","@yarnpkg/plugin-pnp","@yarnpkg/plugin-pnpm","@yarnpkg/plugin-stage","@yarnpkg/plugin-typescript","@yarnpkg/plugin-version","@yarnpkg/plugin-workspace-tools"]}},repository:{type:"git",url:"ssh://git@github.com/yarnpkg/berry.git",directory:"packages/yarnpkg-cli"},engines:{node:">=18.12.0"}}});var M8=_((cGt,fde)=>{"use strict";fde.exports=function(e,r){r===!0&&(r=0);var o="";if(typeof e=="string")try{o=new URL(e).protocol}catch{}else e&&e.constructor===URL&&(o=e.protocol);var a=o.split(/\:|\+/).filter(Boolean);return typeof r=="number"?a[r]:a}});var hde=_((uGt,pde)=>{"use strict";var ugt=M8();function Agt(t){var e={protocols:[],protocol:null,port:null,resource:"",host:"",user:"",password:"",pathname:"",hash:"",search:"",href:t,query:{},parse_failed:!1};try{var r=new URL(t);e.protocols=ugt(r),e.protocol=e.protocols[0],e.port=r.port,e.resource=r.hostname,e.host=r.host,e.user=r.username||"",e.password=r.password||"",e.pathname=r.pathname,e.hash=r.hash.slice(1),e.search=r.search.slice(1),e.href=r.href,e.query=Object.fromEntries(r.searchParams)}catch{e.protocols=["file"],e.protocol=e.protocols[0],e.port="",e.resource="",e.user="",e.pathname="",e.hash="",e.search="",e.href=t,e.query={},e.parse_failed=!0}return e}pde.exports=Agt});var mde=_((AGt,dde)=>{"use strict";var fgt=hde();function pgt(t){return t&&typeof t=="object"&&"default"in t?t:{default:t}}var hgt=pgt(fgt),ggt="text/plain",dgt="us-ascii",gde=(t,e)=>e.some(r=>r instanceof RegExp?r.test(t):r===t),mgt=(t,{stripHash:e})=>{let r=/^data:(?[^,]*?),(?[^#]*?)(?:#(?.*))?$/.exec(t);if(!r)throw new Error(`Invalid URL: ${t}`);let{type:o,data:a,hash:n}=r.groups,u=o.split(";");n=e?"":n;let A=!1;u[u.length-1]==="base64"&&(u.pop(),A=!0);let p=(u.shift()||"").toLowerCase(),E=[...u.map(I=>{let[v,x=""]=I.split("=").map(C=>C.trim());return v==="charset"&&(x=x.toLowerCase(),x===dgt)?"":`${v}${x?`=${x}`:""}`}).filter(Boolean)];return A&&E.push("base64"),(E.length>0||p&&p!==ggt)&&E.unshift(p),`data:${E.join(";")},${A?a.trim():a}${n?`#${n}`:""}`};function ygt(t,e){if(e={defaultProtocol:"http:",normalizeProtocol:!0,forceHttp:!1,forceHttps:!1,stripAuthentication:!0,stripHash:!1,stripTextFragment:!0,stripWWW:!0,removeQueryParameters:[/^utm_\w+/i],removeTrailingSlash:!0,removeSingleSlash:!0,removeDirectoryIndex:!1,sortQueryParameters:!0,...e},t=t.trim(),/^data:/i.test(t))return mgt(t,e);if(/^view-source:/i.test(t))throw new Error("`view-source:` is not supported as it is a non-standard protocol");let r=t.startsWith("//");!r&&/^\.*\//.test(t)||(t=t.replace(/^(?!(?:\w+:)?\/\/)|^\/\//,e.defaultProtocol));let a=new URL(t);if(e.forceHttp&&e.forceHttps)throw new Error("The `forceHttp` and `forceHttps` options cannot be used together");if(e.forceHttp&&a.protocol==="https:"&&(a.protocol="http:"),e.forceHttps&&a.protocol==="http:"&&(a.protocol="https:"),e.stripAuthentication&&(a.username="",a.password=""),e.stripHash?a.hash="":e.stripTextFragment&&(a.hash=a.hash.replace(/#?:~:text.*?$/i,"")),a.pathname){let u=/\b[a-z][a-z\d+\-.]{1,50}:\/\//g,A=0,p="";for(;;){let E=u.exec(a.pathname);if(!E)break;let I=E[0],v=E.index,x=a.pathname.slice(A,v);p+=x.replace(/\/{2,}/g,"/"),p+=I,A=v+I.length}let h=a.pathname.slice(A,a.pathname.length);p+=h.replace(/\/{2,}/g,"/"),a.pathname=p}if(a.pathname)try{a.pathname=decodeURI(a.pathname)}catch{}if(e.removeDirectoryIndex===!0&&(e.removeDirectoryIndex=[/^index\.[a-z]+$/]),Array.isArray(e.removeDirectoryIndex)&&e.removeDirectoryIndex.length>0){let u=a.pathname.split("/"),A=u[u.length-1];gde(A,e.removeDirectoryIndex)&&(u=u.slice(0,-1),a.pathname=u.slice(1).join("/")+"/")}if(a.hostname&&(a.hostname=a.hostname.replace(/\.$/,""),e.stripWWW&&/^www\.(?!www\.)[a-z\-\d]{1,63}\.[a-z.\-\d]{2,63}$/.test(a.hostname)&&(a.hostname=a.hostname.replace(/^www\./,""))),Array.isArray(e.removeQueryParameters))for(let u of[...a.searchParams.keys()])gde(u,e.removeQueryParameters)&&a.searchParams.delete(u);if(e.removeQueryParameters===!0&&(a.search=""),e.sortQueryParameters){a.searchParams.sort();try{a.search=decodeURIComponent(a.search)}catch{}}e.removeTrailingSlash&&(a.pathname=a.pathname.replace(/\/$/,""));let n=t;return t=a.toString(),!e.removeSingleSlash&&a.pathname==="/"&&!n.endsWith("/")&&a.hash===""&&(t=t.replace(/\/$/,"")),(e.removeTrailingSlash||a.pathname==="/")&&a.hash===""&&e.removeSingleSlash&&(t=t.replace(/\/$/,"")),r&&!e.normalizeProtocol&&(t=t.replace(/^http:\/\//,"//")),e.stripProtocol&&(t=t.replace(/^(?:https?:)?\/\//,"")),t}var O8=(t,e=!1)=>{let r=/^(?:([a-z_][a-z0-9_-]{0,31})@|https?:\/\/)([\w\.\-@]+)[\/:]([\~,\.\w,\-,\_,\/]+?(?:\.git|\/)?)$/,o=n=>{let u=new Error(n);throw u.subject_url=t,u};(typeof t!="string"||!t.trim())&&o("Invalid url."),t.length>O8.MAX_INPUT_LENGTH&&o("Input exceeds maximum length. If needed, change the value of parseUrl.MAX_INPUT_LENGTH."),e&&(typeof e!="object"&&(e={stripHash:!1}),t=ygt(t,e));let a=hgt.default(t);if(a.parse_failed){let n=a.href.match(r);n?(a.protocols=["ssh"],a.protocol="ssh",a.resource=n[2],a.host=n[2],a.user=n[1],a.pathname=`/${n[3]}`,a.parse_failed=!1):o("URL parsing failed.")}return a};O8.MAX_INPUT_LENGTH=2048;dde.exports=O8});var Cde=_((fGt,Ede)=>{"use strict";var Egt=M8();function yde(t){if(Array.isArray(t))return t.indexOf("ssh")!==-1||t.indexOf("rsync")!==-1;if(typeof t!="string")return!1;var e=Egt(t);if(t=t.substring(t.indexOf("://")+3),yde(e))return!0;var r=new RegExp(".([a-zA-Z\\d]+):(\\d+)/");return!t.match(r)&&t.indexOf("@"){"use strict";var Cgt=mde(),wde=Cde();function wgt(t){var e=Cgt(t);return e.token="",e.password==="x-oauth-basic"?e.token=e.user:e.user==="x-token-auth"&&(e.token=e.password),wde(e.protocols)||e.protocols.length===0&&wde(t)?e.protocol="ssh":e.protocols.length?e.protocol=e.protocols[0]:(e.protocol="file",e.protocols=["file"]),e.href=e.href.replace(/\/$/,""),e}Ide.exports=wgt});var Dde=_((hGt,vde)=>{"use strict";var Igt=Bde();function U8(t){if(typeof t!="string")throw new Error("The url must be a string.");var e=/^([a-z\d-]{1,39})\/([-\.\w]{1,100})$/i;e.test(t)&&(t="https://github.com/"+t);var r=Igt(t),o=r.resource.split("."),a=null;switch(r.toString=function(L){return U8.stringify(this,L)},r.source=o.length>2?o.slice(1-o.length).join("."):r.source=r.resource,r.git_suffix=/\.git$/.test(r.pathname),r.name=decodeURIComponent((r.pathname||r.href).replace(/(^\/)|(\/$)/g,"").replace(/\.git$/,"")),r.owner=decodeURIComponent(r.user),r.source){case"git.cloudforge.com":r.owner=r.user,r.organization=o[0],r.source="cloudforge.com";break;case"visualstudio.com":if(r.resource==="vs-ssh.visualstudio.com"){a=r.name.split("/"),a.length===4&&(r.organization=a[1],r.owner=a[2],r.name=a[3],r.full_name=a[2]+"/"+a[3]);break}else{a=r.name.split("/"),a.length===2?(r.owner=a[1],r.name=a[1],r.full_name="_git/"+r.name):a.length===3?(r.name=a[2],a[0]==="DefaultCollection"?(r.owner=a[2],r.organization=a[0],r.full_name=r.organization+"/_git/"+r.name):(r.owner=a[0],r.full_name=r.owner+"/_git/"+r.name)):a.length===4&&(r.organization=a[0],r.owner=a[1],r.name=a[3],r.full_name=r.organization+"/"+r.owner+"/_git/"+r.name);break}case"dev.azure.com":case"azure.com":if(r.resource==="ssh.dev.azure.com"){a=r.name.split("/"),a.length===4&&(r.organization=a[1],r.owner=a[2],r.name=a[3]);break}else{a=r.name.split("/"),a.length===5?(r.organization=a[0],r.owner=a[1],r.name=a[4],r.full_name="_git/"+r.name):a.length===3?(r.name=a[2],a[0]==="DefaultCollection"?(r.owner=a[2],r.organization=a[0],r.full_name=r.organization+"/_git/"+r.name):(r.owner=a[0],r.full_name=r.owner+"/_git/"+r.name)):a.length===4&&(r.organization=a[0],r.owner=a[1],r.name=a[3],r.full_name=r.organization+"/"+r.owner+"/_git/"+r.name),r.query&&r.query.path&&(r.filepath=r.query.path.replace(/^\/+/g,"")),r.query&&r.query.version&&(r.ref=r.query.version.replace(/^GB/,""));break}default:a=r.name.split("/");var n=a.length-1;if(a.length>=2){var u=a.indexOf("-",2),A=a.indexOf("blob",2),p=a.indexOf("tree",2),h=a.indexOf("commit",2),E=a.indexOf("src",2),I=a.indexOf("raw",2),v=a.indexOf("edit",2);n=u>0?u-1:A>0?A-1:p>0?p-1:h>0?h-1:E>0?E-1:I>0?I-1:v>0?v-1:n,r.owner=a.slice(0,n).join("/"),r.name=a[n],h&&(r.commit=a[n+2])}r.ref="",r.filepathtype="",r.filepath="";var x=a.length>n&&a[n+1]==="-"?n+1:n;a.length>x+2&&["raw","src","blob","tree","edit"].indexOf(a[x+1])>=0&&(r.filepathtype=a[x+1],r.ref=a[x+2],a.length>x+3&&(r.filepath=a.slice(x+3).join("/"))),r.organization=r.owner;break}r.full_name||(r.full_name=r.owner,r.name&&(r.full_name&&(r.full_name+="/"),r.full_name+=r.name)),r.owner.startsWith("scm/")&&(r.source="bitbucket-server",r.owner=r.owner.replace("scm/",""),r.organization=r.owner,r.full_name=r.owner+"/"+r.name);var C=/(projects|users)\/(.*?)\/repos\/(.*?)((\/.*$)|$)/,R=C.exec(r.pathname);return R!=null&&(r.source="bitbucket-server",R[1]==="users"?r.owner="~"+R[2]:r.owner=R[2],r.organization=r.owner,r.name=R[3],a=R[4].split("/"),a.length>1&&(["raw","browse"].indexOf(a[1])>=0?(r.filepathtype=a[1],a.length>2&&(r.filepath=a.slice(2).join("/"))):a[1]==="commits"&&a.length>2&&(r.commit=a[2])),r.full_name=r.owner+"/"+r.name,r.query.at?r.ref=r.query.at:r.ref=""),r}U8.stringify=function(t,e){e=e||(t.protocols&&t.protocols.length?t.protocols.join("+"):t.protocol);var r=t.port?":"+t.port:"",o=t.user||"git",a=t.git_suffix?".git":"";switch(e){case"ssh":return r?"ssh://"+o+"@"+t.resource+r+"/"+t.full_name+a:o+"@"+t.resource+":"+t.full_name+a;case"git+ssh":case"ssh+git":case"ftp":case"ftps":return e+"://"+o+"@"+t.resource+r+"/"+t.full_name+a;case"http":case"https":var n=t.token?Bgt(t):t.user&&(t.protocols.includes("http")||t.protocols.includes("https"))?t.user+"@":"";return e+"://"+n+t.resource+r+"/"+vgt(t)+a;default:return t.href}};function Bgt(t){switch(t.source){case"bitbucket.org":return"x-token-auth:"+t.token+"@";default:return t.token+"@"}}function vgt(t){switch(t.source){case"bitbucket-server":return"scm/"+t.full_name;default:return""+t.full_name}}vde.exports=U8});var Hde=_((K9t,_de)=>{var Ngt=xS(),Lgt=_P(),Mgt=Hl(),Ogt=Ym(),Ugt=h_(),_gt=Ly(),Hgt=C1();function qgt(t){return Mgt(t)?Ngt(t,_gt):Ogt(t)?[t]:Lgt(Ugt(Hgt(t)))}_de.exports=qgt});function Wgt(t,e){return e===1&&Ygt.has(t[0])}function a2(t){let e=Array.isArray(t)?t:(0,Gde.default)(t);return e.map((o,a)=>jgt.test(o)?`[${o}]`:Ggt.test(o)&&!Wgt(e,a)?`.${o}`:`[${JSON.stringify(o)}]`).join("").replace(/^\./,"")}function Kgt(t,e){let r=[];if(e.methodName!==null&&r.push(pe.pretty(t,e.methodName,pe.Type.CODE)),e.file!==null){let o=[];o.push(pe.pretty(t,e.file,pe.Type.PATH)),e.line!==null&&(o.push(pe.pretty(t,e.line,pe.Type.NUMBER)),e.column!==null&&o.push(pe.pretty(t,e.column,pe.Type.NUMBER))),r.push(`(${o.join(pe.pretty(t,":","grey"))})`)}return r.join(" ")}function ik(t,{manifestUpdates:e,reportedErrors:r},{fix:o}={}){let a=new Map,n=new Map,u=[...r.keys()].map(A=>[A,new Map]);for(let[A,p]of[...u,...e]){let h=r.get(A)?.map(x=>({text:x,fixable:!1}))??[],E=!1,I=t.getWorkspaceByCwd(A),v=I.manifest.exportTo({});for(let[x,C]of p){if(C.size>1){let R=[...C].map(([L,U])=>{let z=pe.pretty(t.configuration,L,pe.Type.INSPECT),te=U.size>0?Kgt(t.configuration,U.values().next().value):null;return te!==null?` +${z} at ${te}`:` +${z}`}).join("");h.push({text:`Conflict detected in constraint targeting ${pe.pretty(t.configuration,x,pe.Type.CODE)}; conflicting values are:${R}`,fixable:!1})}else{let[[R]]=C,L=(0,qde.default)(v,x);if(JSON.stringify(L)===JSON.stringify(R))continue;if(!o){let U=typeof L>"u"?`Missing field ${pe.pretty(t.configuration,x,pe.Type.CODE)}; expected ${pe.pretty(t.configuration,R,pe.Type.INSPECT)}`:typeof R>"u"?`Extraneous field ${pe.pretty(t.configuration,x,pe.Type.CODE)} currently set to ${pe.pretty(t.configuration,L,pe.Type.INSPECT)}`:`Invalid field ${pe.pretty(t.configuration,x,pe.Type.CODE)}; expected ${pe.pretty(t.configuration,R,pe.Type.INSPECT)}, found ${pe.pretty(t.configuration,L,pe.Type.INSPECT)}`;h.push({text:U,fixable:!0});continue}typeof R>"u"?(0,Yde.default)(v,x):(0,jde.default)(v,x,R),E=!0}E&&a.set(I,v)}h.length>0&&n.set(I,h)}return{changedWorkspaces:a,remainingErrors:n}}function Wde(t,{configuration:e}){let r={children:[]};for(let[o,a]of t){let n=[];for(let A of a){let p=A.text.split(/\n/);A.fixable&&(p[0]=`${pe.pretty(e,"\u2699","gray")} ${p[0]}`),n.push({value:pe.tuple(pe.Type.NO_HINT,p[0]),children:p.slice(1).map(h=>({value:pe.tuple(pe.Type.NO_HINT,h)}))})}let u={value:pe.tuple(pe.Type.LOCATOR,o.anchoredLocator),children:He.sortMap(n,A=>A.value[1])};r.children.push(u)}return r.children=He.sortMap(r.children,o=>o.value[1]),r}var qde,jde,Gde,Yde,QE,jgt,Ggt,Ygt,l2=Et(()=>{Ge();qde=Ze(e2()),jde=Ze(D8()),Gde=Ze(Hde()),Yde=Ze(S8()),QE=class{constructor(e){this.indexedFields=e;this.items=[];this.indexes={};this.clear()}clear(){this.items=[];for(let e of this.indexedFields)this.indexes[e]=new Map}insert(e){this.items.push(e);for(let r of this.indexedFields){let o=Object.hasOwn(e,r)?e[r]:void 0;if(typeof o>"u")continue;He.getArrayWithDefault(this.indexes[r],o).push(e)}return e}find(e){if(typeof e>"u")return this.items;let r=Object.entries(e);if(r.length===0)return this.items;let o=[],a;for(let[u,A]of r){let p=u,h=Object.hasOwn(this.indexes,p)?this.indexes[p]:void 0;if(typeof h>"u"){o.push([p,A]);continue}let E=new Set(h.get(A)??[]);if(E.size===0)return[];if(typeof a>"u")a=E;else for(let I of a)E.has(I)||a.delete(I);if(a.size===0)break}let n=[...a??[]];return o.length>0&&(n=n.filter(u=>{for(let[A,p]of o)if(!(typeof p<"u"?Object.hasOwn(u,A)&&u[A]===p:Object.hasOwn(u,A)===!1))return!1;return!0})),n}},jgt=/^[0-9]+$/,Ggt=/^[a-zA-Z0-9_]+$/,Ygt=new Set(["scripts",...Ut.allDependencies])});var Kde=_((s7t,$8)=>{var Vgt;(function(t){var e=function(){return{"append/2":[new t.type.Rule(new t.type.Term("append",[new t.type.Var("X"),new t.type.Var("L")]),new t.type.Term("foldl",[new t.type.Term("append",[]),new t.type.Var("X"),new t.type.Term("[]",[]),new t.type.Var("L")]))],"append/3":[new t.type.Rule(new t.type.Term("append",[new t.type.Term("[]",[]),new t.type.Var("X"),new t.type.Var("X")]),null),new t.type.Rule(new t.type.Term("append",[new t.type.Term(".",[new t.type.Var("H"),new t.type.Var("T")]),new t.type.Var("X"),new t.type.Term(".",[new t.type.Var("H"),new t.type.Var("S")])]),new t.type.Term("append",[new t.type.Var("T"),new t.type.Var("X"),new t.type.Var("S")]))],"member/2":[new t.type.Rule(new t.type.Term("member",[new t.type.Var("X"),new t.type.Term(".",[new t.type.Var("X"),new t.type.Var("_")])]),null),new t.type.Rule(new t.type.Term("member",[new t.type.Var("X"),new t.type.Term(".",[new t.type.Var("_"),new t.type.Var("Xs")])]),new t.type.Term("member",[new t.type.Var("X"),new t.type.Var("Xs")]))],"permutation/2":[new t.type.Rule(new t.type.Term("permutation",[new t.type.Term("[]",[]),new t.type.Term("[]",[])]),null),new t.type.Rule(new t.type.Term("permutation",[new t.type.Term(".",[new t.type.Var("H"),new t.type.Var("T")]),new t.type.Var("S")]),new t.type.Term(",",[new t.type.Term("permutation",[new t.type.Var("T"),new t.type.Var("P")]),new t.type.Term(",",[new t.type.Term("append",[new t.type.Var("X"),new t.type.Var("Y"),new t.type.Var("P")]),new t.type.Term("append",[new t.type.Var("X"),new t.type.Term(".",[new t.type.Var("H"),new t.type.Var("Y")]),new t.type.Var("S")])])]))],"maplist/2":[new t.type.Rule(new t.type.Term("maplist",[new t.type.Var("_"),new t.type.Term("[]",[])]),null),new t.type.Rule(new t.type.Term("maplist",[new t.type.Var("P"),new t.type.Term(".",[new t.type.Var("X"),new t.type.Var("Xs")])]),new t.type.Term(",",[new t.type.Term("call",[new t.type.Var("P"),new t.type.Var("X")]),new t.type.Term("maplist",[new t.type.Var("P"),new t.type.Var("Xs")])]))],"maplist/3":[new t.type.Rule(new t.type.Term("maplist",[new t.type.Var("_"),new t.type.Term("[]",[]),new t.type.Term("[]",[])]),null),new t.type.Rule(new t.type.Term("maplist",[new t.type.Var("P"),new t.type.Term(".",[new t.type.Var("A"),new t.type.Var("As")]),new t.type.Term(".",[new t.type.Var("B"),new t.type.Var("Bs")])]),new t.type.Term(",",[new t.type.Term("call",[new t.type.Var("P"),new t.type.Var("A"),new t.type.Var("B")]),new t.type.Term("maplist",[new t.type.Var("P"),new t.type.Var("As"),new t.type.Var("Bs")])]))],"maplist/4":[new t.type.Rule(new t.type.Term("maplist",[new t.type.Var("_"),new t.type.Term("[]",[]),new t.type.Term("[]",[]),new t.type.Term("[]",[])]),null),new t.type.Rule(new t.type.Term("maplist",[new t.type.Var("P"),new t.type.Term(".",[new t.type.Var("A"),new t.type.Var("As")]),new t.type.Term(".",[new t.type.Var("B"),new t.type.Var("Bs")]),new t.type.Term(".",[new t.type.Var("C"),new t.type.Var("Cs")])]),new t.type.Term(",",[new t.type.Term("call",[new t.type.Var("P"),new t.type.Var("A"),new t.type.Var("B"),new t.type.Var("C")]),new t.type.Term("maplist",[new t.type.Var("P"),new t.type.Var("As"),new t.type.Var("Bs"),new t.type.Var("Cs")])]))],"maplist/5":[new t.type.Rule(new t.type.Term("maplist",[new t.type.Var("_"),new t.type.Term("[]",[]),new t.type.Term("[]",[]),new t.type.Term("[]",[]),new t.type.Term("[]",[])]),null),new t.type.Rule(new t.type.Term("maplist",[new t.type.Var("P"),new t.type.Term(".",[new t.type.Var("A"),new t.type.Var("As")]),new t.type.Term(".",[new t.type.Var("B"),new t.type.Var("Bs")]),new t.type.Term(".",[new t.type.Var("C"),new t.type.Var("Cs")]),new t.type.Term(".",[new t.type.Var("D"),new t.type.Var("Ds")])]),new t.type.Term(",",[new t.type.Term("call",[new t.type.Var("P"),new t.type.Var("A"),new t.type.Var("B"),new t.type.Var("C"),new t.type.Var("D")]),new t.type.Term("maplist",[new t.type.Var("P"),new t.type.Var("As"),new t.type.Var("Bs"),new t.type.Var("Cs"),new t.type.Var("Ds")])]))],"maplist/6":[new t.type.Rule(new t.type.Term("maplist",[new t.type.Var("_"),new t.type.Term("[]",[]),new t.type.Term("[]",[]),new t.type.Term("[]",[]),new t.type.Term("[]",[]),new t.type.Term("[]",[])]),null),new t.type.Rule(new t.type.Term("maplist",[new t.type.Var("P"),new t.type.Term(".",[new t.type.Var("A"),new t.type.Var("As")]),new t.type.Term(".",[new t.type.Var("B"),new t.type.Var("Bs")]),new t.type.Term(".",[new t.type.Var("C"),new t.type.Var("Cs")]),new t.type.Term(".",[new t.type.Var("D"),new t.type.Var("Ds")]),new t.type.Term(".",[new t.type.Var("E"),new t.type.Var("Es")])]),new t.type.Term(",",[new t.type.Term("call",[new t.type.Var("P"),new t.type.Var("A"),new t.type.Var("B"),new t.type.Var("C"),new t.type.Var("D"),new t.type.Var("E")]),new t.type.Term("maplist",[new t.type.Var("P"),new t.type.Var("As"),new t.type.Var("Bs"),new t.type.Var("Cs"),new t.type.Var("Ds"),new t.type.Var("Es")])]))],"maplist/7":[new t.type.Rule(new t.type.Term("maplist",[new t.type.Var("_"),new t.type.Term("[]",[]),new t.type.Term("[]",[]),new t.type.Term("[]",[]),new t.type.Term("[]",[]),new t.type.Term("[]",[]),new t.type.Term("[]",[])]),null),new t.type.Rule(new t.type.Term("maplist",[new t.type.Var("P"),new t.type.Term(".",[new t.type.Var("A"),new t.type.Var("As")]),new t.type.Term(".",[new t.type.Var("B"),new t.type.Var("Bs")]),new t.type.Term(".",[new t.type.Var("C"),new t.type.Var("Cs")]),new t.type.Term(".",[new t.type.Var("D"),new t.type.Var("Ds")]),new t.type.Term(".",[new t.type.Var("E"),new t.type.Var("Es")]),new t.type.Term(".",[new t.type.Var("F"),new t.type.Var("Fs")])]),new t.type.Term(",",[new t.type.Term("call",[new t.type.Var("P"),new t.type.Var("A"),new t.type.Var("B"),new t.type.Var("C"),new t.type.Var("D"),new t.type.Var("E"),new t.type.Var("F")]),new t.type.Term("maplist",[new t.type.Var("P"),new t.type.Var("As"),new t.type.Var("Bs"),new t.type.Var("Cs"),new t.type.Var("Ds"),new t.type.Var("Es"),new t.type.Var("Fs")])]))],"maplist/8":[new t.type.Rule(new t.type.Term("maplist",[new t.type.Var("_"),new t.type.Term("[]",[]),new t.type.Term("[]",[]),new t.type.Term("[]",[]),new t.type.Term("[]",[]),new t.type.Term("[]",[]),new t.type.Term("[]",[]),new t.type.Term("[]",[])]),null),new t.type.Rule(new t.type.Term("maplist",[new t.type.Var("P"),new t.type.Term(".",[new t.type.Var("A"),new t.type.Var("As")]),new t.type.Term(".",[new t.type.Var("B"),new t.type.Var("Bs")]),new t.type.Term(".",[new t.type.Var("C"),new t.type.Var("Cs")]),new t.type.Term(".",[new t.type.Var("D"),new t.type.Var("Ds")]),new t.type.Term(".",[new t.type.Var("E"),new t.type.Var("Es")]),new t.type.Term(".",[new t.type.Var("F"),new t.type.Var("Fs")]),new t.type.Term(".",[new t.type.Var("G"),new t.type.Var("Gs")])]),new t.type.Term(",",[new t.type.Term("call",[new t.type.Var("P"),new t.type.Var("A"),new t.type.Var("B"),new t.type.Var("C"),new t.type.Var("D"),new t.type.Var("E"),new t.type.Var("F"),new t.type.Var("G")]),new t.type.Term("maplist",[new t.type.Var("P"),new t.type.Var("As"),new t.type.Var("Bs"),new t.type.Var("Cs"),new t.type.Var("Ds"),new t.type.Var("Es"),new t.type.Var("Fs"),new t.type.Var("Gs")])]))],"include/3":[new t.type.Rule(new t.type.Term("include",[new t.type.Var("_"),new t.type.Term("[]",[]),new t.type.Term("[]",[])]),null),new t.type.Rule(new t.type.Term("include",[new t.type.Var("P"),new t.type.Term(".",[new t.type.Var("H"),new t.type.Var("T")]),new t.type.Var("L")]),new t.type.Term(",",[new t.type.Term("=..",[new t.type.Var("P"),new t.type.Var("A")]),new t.type.Term(",",[new t.type.Term("append",[new t.type.Var("A"),new t.type.Term(".",[new t.type.Var("H"),new t.type.Term("[]",[])]),new t.type.Var("B")]),new t.type.Term(",",[new t.type.Term("=..",[new t.type.Var("F"),new t.type.Var("B")]),new t.type.Term(",",[new t.type.Term(";",[new t.type.Term(",",[new t.type.Term("call",[new t.type.Var("F")]),new t.type.Term(",",[new t.type.Term("=",[new t.type.Var("L"),new t.type.Term(".",[new t.type.Var("H"),new t.type.Var("S")])]),new t.type.Term("!",[])])]),new t.type.Term("=",[new t.type.Var("L"),new t.type.Var("S")])]),new t.type.Term("include",[new t.type.Var("P"),new t.type.Var("T"),new t.type.Var("S")])])])])]))],"exclude/3":[new t.type.Rule(new t.type.Term("exclude",[new t.type.Var("_"),new t.type.Term("[]",[]),new t.type.Term("[]",[])]),null),new t.type.Rule(new t.type.Term("exclude",[new t.type.Var("P"),new t.type.Term(".",[new t.type.Var("H"),new t.type.Var("T")]),new t.type.Var("S")]),new t.type.Term(",",[new t.type.Term("exclude",[new t.type.Var("P"),new t.type.Var("T"),new t.type.Var("E")]),new t.type.Term(",",[new t.type.Term("=..",[new t.type.Var("P"),new t.type.Var("L")]),new t.type.Term(",",[new t.type.Term("append",[new t.type.Var("L"),new t.type.Term(".",[new t.type.Var("H"),new t.type.Term("[]",[])]),new t.type.Var("Q")]),new t.type.Term(",",[new t.type.Term("=..",[new t.type.Var("R"),new t.type.Var("Q")]),new t.type.Term(";",[new t.type.Term(",",[new t.type.Term("call",[new t.type.Var("R")]),new t.type.Term(",",[new t.type.Term("!",[]),new t.type.Term("=",[new t.type.Var("S"),new t.type.Var("E")])])]),new t.type.Term("=",[new t.type.Var("S"),new t.type.Term(".",[new t.type.Var("H"),new t.type.Var("E")])])])])])])]))],"foldl/4":[new t.type.Rule(new t.type.Term("foldl",[new t.type.Var("_"),new t.type.Term("[]",[]),new t.type.Var("I"),new t.type.Var("I")]),null),new t.type.Rule(new t.type.Term("foldl",[new t.type.Var("P"),new t.type.Term(".",[new t.type.Var("H"),new t.type.Var("T")]),new t.type.Var("I"),new t.type.Var("R")]),new t.type.Term(",",[new t.type.Term("=..",[new t.type.Var("P"),new t.type.Var("L")]),new t.type.Term(",",[new t.type.Term("append",[new t.type.Var("L"),new t.type.Term(".",[new t.type.Var("I"),new t.type.Term(".",[new t.type.Var("H"),new t.type.Term(".",[new t.type.Var("X"),new t.type.Term("[]",[])])])]),new t.type.Var("L2")]),new t.type.Term(",",[new t.type.Term("=..",[new t.type.Var("P2"),new t.type.Var("L2")]),new t.type.Term(",",[new t.type.Term("call",[new t.type.Var("P2")]),new t.type.Term("foldl",[new t.type.Var("P"),new t.type.Var("T"),new t.type.Var("X"),new t.type.Var("R")])])])])]))],"select/3":[new t.type.Rule(new t.type.Term("select",[new t.type.Var("E"),new t.type.Term(".",[new t.type.Var("E"),new t.type.Var("Xs")]),new t.type.Var("Xs")]),null),new t.type.Rule(new t.type.Term("select",[new t.type.Var("E"),new t.type.Term(".",[new t.type.Var("X"),new t.type.Var("Xs")]),new t.type.Term(".",[new t.type.Var("X"),new t.type.Var("Ys")])]),new t.type.Term("select",[new t.type.Var("E"),new t.type.Var("Xs"),new t.type.Var("Ys")]))],"sum_list/2":[new t.type.Rule(new t.type.Term("sum_list",[new t.type.Term("[]",[]),new t.type.Num(0,!1)]),null),new t.type.Rule(new t.type.Term("sum_list",[new t.type.Term(".",[new t.type.Var("X"),new t.type.Var("Xs")]),new t.type.Var("S")]),new t.type.Term(",",[new t.type.Term("sum_list",[new t.type.Var("Xs"),new t.type.Var("Y")]),new t.type.Term("is",[new t.type.Var("S"),new t.type.Term("+",[new t.type.Var("X"),new t.type.Var("Y")])])]))],"max_list/2":[new t.type.Rule(new t.type.Term("max_list",[new t.type.Term(".",[new t.type.Var("X"),new t.type.Term("[]",[])]),new t.type.Var("X")]),null),new t.type.Rule(new t.type.Term("max_list",[new t.type.Term(".",[new t.type.Var("X"),new t.type.Var("Xs")]),new t.type.Var("S")]),new t.type.Term(",",[new t.type.Term("max_list",[new t.type.Var("Xs"),new t.type.Var("Y")]),new t.type.Term(";",[new t.type.Term(",",[new t.type.Term(">=",[new t.type.Var("X"),new t.type.Var("Y")]),new t.type.Term(",",[new t.type.Term("=",[new t.type.Var("S"),new t.type.Var("X")]),new t.type.Term("!",[])])]),new t.type.Term("=",[new t.type.Var("S"),new t.type.Var("Y")])])]))],"min_list/2":[new t.type.Rule(new t.type.Term("min_list",[new t.type.Term(".",[new t.type.Var("X"),new t.type.Term("[]",[])]),new t.type.Var("X")]),null),new t.type.Rule(new t.type.Term("min_list",[new t.type.Term(".",[new t.type.Var("X"),new t.type.Var("Xs")]),new t.type.Var("S")]),new t.type.Term(",",[new t.type.Term("min_list",[new t.type.Var("Xs"),new t.type.Var("Y")]),new t.type.Term(";",[new t.type.Term(",",[new t.type.Term("=<",[new t.type.Var("X"),new t.type.Var("Y")]),new t.type.Term(",",[new t.type.Term("=",[new t.type.Var("S"),new t.type.Var("X")]),new t.type.Term("!",[])])]),new t.type.Term("=",[new t.type.Var("S"),new t.type.Var("Y")])])]))],"prod_list/2":[new t.type.Rule(new t.type.Term("prod_list",[new t.type.Term("[]",[]),new t.type.Num(1,!1)]),null),new t.type.Rule(new t.type.Term("prod_list",[new t.type.Term(".",[new t.type.Var("X"),new t.type.Var("Xs")]),new t.type.Var("S")]),new t.type.Term(",",[new t.type.Term("prod_list",[new t.type.Var("Xs"),new t.type.Var("Y")]),new t.type.Term("is",[new t.type.Var("S"),new t.type.Term("*",[new t.type.Var("X"),new t.type.Var("Y")])])]))],"last/2":[new t.type.Rule(new t.type.Term("last",[new t.type.Term(".",[new t.type.Var("X"),new t.type.Term("[]",[])]),new t.type.Var("X")]),null),new t.type.Rule(new t.type.Term("last",[new t.type.Term(".",[new t.type.Var("_"),new t.type.Var("Xs")]),new t.type.Var("X")]),new t.type.Term("last",[new t.type.Var("Xs"),new t.type.Var("X")]))],"prefix/2":[new t.type.Rule(new t.type.Term("prefix",[new t.type.Var("Part"),new t.type.Var("Whole")]),new t.type.Term("append",[new t.type.Var("Part"),new t.type.Var("_"),new t.type.Var("Whole")]))],"nth0/3":[new t.type.Rule(new t.type.Term("nth0",[new t.type.Var("X"),new t.type.Var("Y"),new t.type.Var("Z")]),new t.type.Term(";",[new t.type.Term("->",[new t.type.Term("var",[new t.type.Var("X")]),new t.type.Term("nth",[new t.type.Num(0,!1),new t.type.Var("X"),new t.type.Var("Y"),new t.type.Var("Z"),new t.type.Var("_")])]),new t.type.Term(",",[new t.type.Term(">=",[new t.type.Var("X"),new t.type.Num(0,!1)]),new t.type.Term(",",[new t.type.Term("nth",[new t.type.Num(0,!1),new t.type.Var("X"),new t.type.Var("Y"),new t.type.Var("Z"),new t.type.Var("_")]),new t.type.Term("!",[])])])]))],"nth1/3":[new t.type.Rule(new t.type.Term("nth1",[new t.type.Var("X"),new t.type.Var("Y"),new t.type.Var("Z")]),new t.type.Term(";",[new t.type.Term("->",[new t.type.Term("var",[new t.type.Var("X")]),new t.type.Term("nth",[new t.type.Num(1,!1),new t.type.Var("X"),new t.type.Var("Y"),new t.type.Var("Z"),new t.type.Var("_")])]),new t.type.Term(",",[new t.type.Term(">",[new t.type.Var("X"),new t.type.Num(0,!1)]),new t.type.Term(",",[new t.type.Term("nth",[new t.type.Num(1,!1),new t.type.Var("X"),new t.type.Var("Y"),new t.type.Var("Z"),new t.type.Var("_")]),new t.type.Term("!",[])])])]))],"nth0/4":[new t.type.Rule(new t.type.Term("nth0",[new t.type.Var("X"),new t.type.Var("Y"),new t.type.Var("Z"),new t.type.Var("W")]),new t.type.Term(";",[new t.type.Term("->",[new t.type.Term("var",[new t.type.Var("X")]),new t.type.Term("nth",[new t.type.Num(0,!1),new t.type.Var("X"),new t.type.Var("Y"),new t.type.Var("Z"),new t.type.Var("W")])]),new t.type.Term(",",[new t.type.Term(">=",[new t.type.Var("X"),new t.type.Num(0,!1)]),new t.type.Term(",",[new t.type.Term("nth",[new t.type.Num(0,!1),new t.type.Var("X"),new t.type.Var("Y"),new t.type.Var("Z"),new t.type.Var("W")]),new t.type.Term("!",[])])])]))],"nth1/4":[new t.type.Rule(new t.type.Term("nth1",[new t.type.Var("X"),new t.type.Var("Y"),new t.type.Var("Z"),new t.type.Var("W")]),new t.type.Term(";",[new t.type.Term("->",[new t.type.Term("var",[new t.type.Var("X")]),new t.type.Term("nth",[new t.type.Num(1,!1),new t.type.Var("X"),new t.type.Var("Y"),new t.type.Var("Z"),new t.type.Var("W")])]),new t.type.Term(",",[new t.type.Term(">",[new t.type.Var("X"),new t.type.Num(0,!1)]),new t.type.Term(",",[new t.type.Term("nth",[new t.type.Num(1,!1),new t.type.Var("X"),new t.type.Var("Y"),new t.type.Var("Z"),new t.type.Var("W")]),new t.type.Term("!",[])])])]))],"nth/5":[new t.type.Rule(new t.type.Term("nth",[new t.type.Var("N"),new t.type.Var("N"),new t.type.Term(".",[new t.type.Var("X"),new t.type.Var("Xs")]),new t.type.Var("X"),new t.type.Var("Xs")]),null),new t.type.Rule(new t.type.Term("nth",[new t.type.Var("N"),new t.type.Var("O"),new t.type.Term(".",[new t.type.Var("X"),new t.type.Var("Xs")]),new t.type.Var("Y"),new t.type.Term(".",[new t.type.Var("X"),new t.type.Var("Ys")])]),new t.type.Term(",",[new t.type.Term("is",[new t.type.Var("M"),new t.type.Term("+",[new t.type.Var("N"),new t.type.Num(1,!1)])]),new t.type.Term("nth",[new t.type.Var("M"),new t.type.Var("O"),new t.type.Var("Xs"),new t.type.Var("Y"),new t.type.Var("Ys")])]))],"length/2":function(o,a,n){var u=n.args[0],A=n.args[1];if(!t.type.is_variable(A)&&!t.type.is_integer(A))o.throw_error(t.error.type("integer",A,n.indicator));else if(t.type.is_integer(A)&&A.value<0)o.throw_error(t.error.domain("not_less_than_zero",A,n.indicator));else{var p=new t.type.Term("length",[u,new t.type.Num(0,!1),A]);t.type.is_integer(A)&&(p=new t.type.Term(",",[p,new t.type.Term("!",[])])),o.prepend([new t.type.State(a.goal.replace(p),a.substitution,a)])}},"length/3":[new t.type.Rule(new t.type.Term("length",[new t.type.Term("[]",[]),new t.type.Var("N"),new t.type.Var("N")]),null),new t.type.Rule(new t.type.Term("length",[new t.type.Term(".",[new t.type.Var("_"),new t.type.Var("X")]),new t.type.Var("A"),new t.type.Var("N")]),new t.type.Term(",",[new t.type.Term("succ",[new t.type.Var("A"),new t.type.Var("B")]),new t.type.Term("length",[new t.type.Var("X"),new t.type.Var("B"),new t.type.Var("N")])]))],"replicate/3":function(o,a,n){var u=n.args[0],A=n.args[1],p=n.args[2];if(t.type.is_variable(A))o.throw_error(t.error.instantiation(n.indicator));else if(!t.type.is_integer(A))o.throw_error(t.error.type("integer",A,n.indicator));else if(A.value<0)o.throw_error(t.error.domain("not_less_than_zero",A,n.indicator));else if(!t.type.is_variable(p)&&!t.type.is_list(p))o.throw_error(t.error.type("list",p,n.indicator));else{for(var h=new t.type.Term("[]"),E=0;E0;I--)E[I].equals(E[I-1])&&E.splice(I,1);for(var v=new t.type.Term("[]"),I=E.length-1;I>=0;I--)v=new t.type.Term(".",[E[I],v]);o.prepend([new t.type.State(a.goal.replace(new t.type.Term("=",[v,A])),a.substitution,a)])}}},"msort/2":function(o,a,n){var u=n.args[0],A=n.args[1];if(t.type.is_variable(u))o.throw_error(t.error.instantiation(n.indicator));else if(!t.type.is_variable(A)&&!t.type.is_fully_list(A))o.throw_error(t.error.type("list",A,n.indicator));else{for(var p=[],h=u;h.indicator==="./2";)p.push(h.args[0]),h=h.args[1];if(t.type.is_variable(h))o.throw_error(t.error.instantiation(n.indicator));else if(!t.type.is_empty_list(h))o.throw_error(t.error.type("list",u,n.indicator));else{for(var E=p.sort(t.compare),I=new t.type.Term("[]"),v=E.length-1;v>=0;v--)I=new t.type.Term(".",[E[v],I]);o.prepend([new t.type.State(a.goal.replace(new t.type.Term("=",[I,A])),a.substitution,a)])}}},"keysort/2":function(o,a,n){var u=n.args[0],A=n.args[1];if(t.type.is_variable(u))o.throw_error(t.error.instantiation(n.indicator));else if(!t.type.is_variable(A)&&!t.type.is_fully_list(A))o.throw_error(t.error.type("list",A,n.indicator));else{for(var p=[],h,E=u;E.indicator==="./2";){if(h=E.args[0],t.type.is_variable(h)){o.throw_error(t.error.instantiation(n.indicator));return}else if(!t.type.is_term(h)||h.indicator!=="-/2"){o.throw_error(t.error.type("pair",h,n.indicator));return}h.args[0].pair=h.args[1],p.push(h.args[0]),E=E.args[1]}if(t.type.is_variable(E))o.throw_error(t.error.instantiation(n.indicator));else if(!t.type.is_empty_list(E))o.throw_error(t.error.type("list",u,n.indicator));else{for(var I=p.sort(t.compare),v=new t.type.Term("[]"),x=I.length-1;x>=0;x--)v=new t.type.Term(".",[new t.type.Term("-",[I[x],I[x].pair]),v]),delete I[x].pair;o.prepend([new t.type.State(a.goal.replace(new t.type.Term("=",[v,A])),a.substitution,a)])}}},"take/3":function(o,a,n){var u=n.args[0],A=n.args[1],p=n.args[2];if(t.type.is_variable(A)||t.type.is_variable(u))o.throw_error(t.error.instantiation(n.indicator));else if(!t.type.is_list(A))o.throw_error(t.error.type("list",A,n.indicator));else if(!t.type.is_integer(u))o.throw_error(t.error.type("integer",u,n.indicator));else if(!t.type.is_variable(p)&&!t.type.is_list(p))o.throw_error(t.error.type("list",p,n.indicator));else{for(var h=u.value,E=[],I=A;h>0&&I.indicator==="./2";)E.push(I.args[0]),I=I.args[1],h--;if(h===0){for(var v=new t.type.Term("[]"),h=E.length-1;h>=0;h--)v=new t.type.Term(".",[E[h],v]);o.prepend([new t.type.State(a.goal.replace(new t.type.Term("=",[v,p])),a.substitution,a)])}}},"drop/3":function(o,a,n){var u=n.args[0],A=n.args[1],p=n.args[2];if(t.type.is_variable(A)||t.type.is_variable(u))o.throw_error(t.error.instantiation(n.indicator));else if(!t.type.is_list(A))o.throw_error(t.error.type("list",A,n.indicator));else if(!t.type.is_integer(u))o.throw_error(t.error.type("integer",u,n.indicator));else if(!t.type.is_variable(p)&&!t.type.is_list(p))o.throw_error(t.error.type("list",p,n.indicator));else{for(var h=u.value,E=[],I=A;h>0&&I.indicator==="./2";)E.push(I.args[0]),I=I.args[1],h--;h===0&&o.prepend([new t.type.State(a.goal.replace(new t.type.Term("=",[I,p])),a.substitution,a)])}},"reverse/2":function(o,a,n){var u=n.args[0],A=n.args[1],p=t.type.is_instantiated_list(u),h=t.type.is_instantiated_list(A);if(t.type.is_variable(u)&&t.type.is_variable(A))o.throw_error(t.error.instantiation(n.indicator));else if(!t.type.is_variable(u)&&!t.type.is_fully_list(u))o.throw_error(t.error.type("list",u,n.indicator));else if(!t.type.is_variable(A)&&!t.type.is_fully_list(A))o.throw_error(t.error.type("list",A,n.indicator));else if(!p&&!h)o.throw_error(t.error.instantiation(n.indicator));else{for(var E=p?u:A,I=new t.type.Term("[]",[]);E.indicator==="./2";)I=new t.type.Term(".",[E.args[0],I]),E=E.args[1];o.prepend([new t.type.State(a.goal.replace(new t.type.Term("=",[I,p?A:u])),a.substitution,a)])}},"list_to_set/2":function(o,a,n){var u=n.args[0],A=n.args[1];if(t.type.is_variable(u))o.throw_error(t.error.instantiation(n.indicator));else{for(var p=u,h=[];p.indicator==="./2";)h.push(p.args[0]),p=p.args[1];if(t.type.is_variable(p))o.throw_error(t.error.instantiation(n.indicator));else if(!t.type.is_term(p)||p.indicator!=="[]/0")o.throw_error(t.error.type("list",u,n.indicator));else{for(var E=[],I=new t.type.Term("[]",[]),v,x=0;x=0;x--)I=new t.type.Term(".",[E[x],I]);o.prepend([new t.type.State(a.goal.replace(new t.type.Term("=",[A,I])),a.substitution,a)])}}}}},r=["append/2","append/3","member/2","permutation/2","maplist/2","maplist/3","maplist/4","maplist/5","maplist/6","maplist/7","maplist/8","include/3","exclude/3","foldl/4","sum_list/2","max_list/2","min_list/2","prod_list/2","last/2","prefix/2","nth0/3","nth1/3","nth0/4","nth1/4","length/2","replicate/3","select/3","sort/2","msort/2","keysort/2","take/3","drop/3","reverse/2","list_to_set/2"];typeof $8<"u"?$8.exports=function(o){t=o,new t.type.Module("lists",e(),r)}:new t.type.Module("lists",e(),r)})(Vgt)});var lme=_(Wr=>{"use strict";var jg=process.platform==="win32",eH="aes-256-cbc",zgt="sha256",Jde="The current environment doesn't support interactive reading from TTY.",Yn=ve("fs"),Vde=process.binding("tty_wrap").TTY,rH=ve("child_process"),kh=ve("path"),nH={prompt:"> ",hideEchoBack:!1,mask:"*",limit:[],limitMessage:"Input another, please.$<( [)limit(])>",defaultInput:"",trueValue:[],falseValue:[],caseSensitive:!1,keepWhitespace:!1,encoding:"utf8",bufferSize:1024,print:void 0,history:!0,cd:!1,phContent:void 0,preCheck:void 0},Wf="none",$c,RE,zde=!1,xh,ok,tH,Jgt=0,lH="",qg=[],ak,Xde=!1,iH=!1,c2=!1;function Zde(t){function e(r){return r.replace(/[^\w\u0080-\uFFFF]/g,function(o){return"#"+o.charCodeAt(0)+";"})}return ok.concat(function(r){var o=[];return Object.keys(r).forEach(function(a){r[a]==="boolean"?t[a]&&o.push("--"+a):r[a]==="string"&&t[a]&&o.push("--"+a,e(t[a]))}),o}({display:"string",displayOnly:"boolean",keyIn:"boolean",hideEchoBack:"boolean",mask:"string",limit:"string",caseSensitive:"boolean"}))}function Xgt(t,e){function r(U){var z,te="",ae;for(tH=tH||ve("os").tmpdir();;){z=kh.join(tH,U+te);try{ae=Yn.openSync(z,"wx")}catch(le){if(le.code==="EEXIST"){te++;continue}else throw le}Yn.closeSync(ae);break}return z}var o,a,n,u={},A,p,h=r("readline-sync.stdout"),E=r("readline-sync.stderr"),I=r("readline-sync.exit"),v=r("readline-sync.done"),x=ve("crypto"),C,R,L;C=x.createHash(zgt),C.update(""+process.pid+Jgt+++Math.random()),L=C.digest("hex"),R=x.createDecipher(eH,L),o=Zde(t),jg?(a=process.env.ComSpec||"cmd.exe",process.env.Q='"',n=["/V:ON","/S","/C","(%Q%"+a+"%Q% /V:ON /S /C %Q%%Q%"+xh+"%Q%"+o.map(function(U){return" %Q%"+U+"%Q%"}).join("")+" & (echo !ERRORLEVEL!)>%Q%"+I+"%Q%%Q%) 2>%Q%"+E+"%Q% |%Q%"+process.execPath+"%Q% %Q%"+__dirname+"\\encrypt.js%Q% %Q%"+eH+"%Q% %Q%"+L+"%Q% >%Q%"+h+"%Q% & (echo 1)>%Q%"+v+"%Q%"]):(a="/bin/sh",n=["-c",'("'+xh+'"'+o.map(function(U){return" '"+U.replace(/'/g,"'\\''")+"'"}).join("")+'; echo $?>"'+I+'") 2>"'+E+'" |"'+process.execPath+'" "'+__dirname+'/encrypt.js" "'+eH+'" "'+L+'" >"'+h+'"; echo 1 >"'+v+'"']),c2&&c2("_execFileSync",o);try{rH.spawn(a,n,e)}catch(U){u.error=new Error(U.message),u.error.method="_execFileSync - spawn",u.error.program=a,u.error.args=n}for(;Yn.readFileSync(v,{encoding:t.encoding}).trim()!=="1";);return(A=Yn.readFileSync(I,{encoding:t.encoding}).trim())==="0"?u.input=R.update(Yn.readFileSync(h,{encoding:"binary"}),"hex",t.encoding)+R.final(t.encoding):(p=Yn.readFileSync(E,{encoding:t.encoding}).trim(),u.error=new Error(Jde+(p?` +`+p:"")),u.error.method="_execFileSync",u.error.program=a,u.error.args=n,u.error.extMessage=p,u.error.exitCode=+A),Yn.unlinkSync(h),Yn.unlinkSync(E),Yn.unlinkSync(I),Yn.unlinkSync(v),u}function Zgt(t){var e,r={},o,a={env:process.env,encoding:t.encoding};if(xh||(jg?process.env.PSModulePath?(xh="powershell.exe",ok=["-ExecutionPolicy","Bypass","-File",__dirname+"\\read.ps1"]):(xh="cscript.exe",ok=["//nologo",__dirname+"\\read.cs.js"]):(xh="/bin/sh",ok=[__dirname+"/read.sh"])),jg&&!process.env.PSModulePath&&(a.stdio=[process.stdin]),rH.execFileSync){e=Zde(t),c2&&c2("execFileSync",e);try{r.input=rH.execFileSync(xh,e,a)}catch(n){o=n.stderr?(n.stderr+"").trim():"",r.error=new Error(Jde+(o?` +`+o:"")),r.error.method="execFileSync",r.error.program=xh,r.error.args=e,r.error.extMessage=o,r.error.exitCode=n.status,r.error.code=n.code,r.error.signal=n.signal}}else r=Xgt(t,a);return r.error||(r.input=r.input.replace(/^\s*'|'\s*$/g,""),t.display=""),r}function sH(t){var e="",r=t.display,o=!t.display&&t.keyIn&&t.hideEchoBack&&!t.mask;function a(){var n=Zgt(t);if(n.error)throw n.error;return n.input}return iH&&iH(t),function(){var n,u,A;function p(){return n||(n=process.binding("fs"),u=process.binding("constants")),n}if(typeof Wf=="string")if(Wf=null,jg){if(A=function(h){var E=h.replace(/^\D+/,"").split("."),I=0;return(E[0]=+E[0])&&(I+=E[0]*1e4),(E[1]=+E[1])&&(I+=E[1]*100),(E[2]=+E[2])&&(I+=E[2]),I}(process.version),!(A>=20302&&A<40204||A>=5e4&&A<50100||A>=50600&&A<60200)&&process.stdin.isTTY)process.stdin.pause(),Wf=process.stdin.fd,RE=process.stdin._handle;else try{Wf=p().open("CONIN$",u.O_RDWR,parseInt("0666",8)),RE=new Vde(Wf,!0)}catch{}if(process.stdout.isTTY)$c=process.stdout.fd;else{try{$c=Yn.openSync("\\\\.\\CON","w")}catch{}if(typeof $c!="number")try{$c=p().open("CONOUT$",u.O_RDWR,parseInt("0666",8))}catch{}}}else{if(process.stdin.isTTY){process.stdin.pause();try{Wf=Yn.openSync("/dev/tty","r"),RE=process.stdin._handle}catch{}}else try{Wf=Yn.openSync("/dev/tty","r"),RE=new Vde(Wf,!1)}catch{}if(process.stdout.isTTY)$c=process.stdout.fd;else try{$c=Yn.openSync("/dev/tty","w")}catch{}}}(),function(){var n,u,A=!t.hideEchoBack&&!t.keyIn,p,h,E,I,v;ak="";function x(C){return C===zde?!0:RE.setRawMode(C)!==0?!1:(zde=C,!0)}if(Xde||!RE||typeof $c!="number"&&(t.display||!A)){e=a();return}if(t.display&&(Yn.writeSync($c,t.display),t.display=""),!t.displayOnly){if(!x(!A)){e=a();return}for(h=t.keyIn?1:t.bufferSize,p=Buffer.allocUnsafe&&Buffer.alloc?Buffer.alloc(h):new Buffer(h),t.keyIn&&t.limit&&(u=new RegExp("[^"+t.limit+"]","g"+(t.caseSensitive?"":"i")));;){E=0;try{E=Yn.readSync(Wf,p,0,h)}catch(C){if(C.code!=="EOF"){x(!1),e+=a();return}}if(E>0?(I=p.toString(t.encoding,0,E),ak+=I):(I=` +`,ak+="\0"),I&&typeof(v=(I.match(/^(.*?)[\r\n]/)||[])[1])=="string"&&(I=v,n=!0),I&&(I=I.replace(/[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/g,"")),I&&u&&(I=I.replace(u,"")),I&&(A||(t.hideEchoBack?t.mask&&Yn.writeSync($c,new Array(I.length+1).join(t.mask)):Yn.writeSync($c,I)),e+=I),!t.keyIn&&n||t.keyIn&&e.length>=h)break}!A&&!o&&Yn.writeSync($c,` +`),x(!1)}}(),t.print&&!o&&t.print(r+(t.displayOnly?"":(t.hideEchoBack?new Array(e.length+1).join(t.mask):e)+` +`),t.encoding),t.displayOnly?"":lH=t.keepWhitespace||t.keyIn?e:e.trim()}function $gt(t,e){var r=[];function o(a){a!=null&&(Array.isArray(a)?a.forEach(o):(!e||e(a))&&r.push(a))}return o(t),r}function cH(t){return t.replace(/[\x00-\x7f]/g,function(e){return"\\x"+("00"+e.charCodeAt().toString(16)).substr(-2)})}function Ns(){var t=Array.prototype.slice.call(arguments),e,r;return t.length&&typeof t[0]=="boolean"&&(r=t.shift(),r&&(e=Object.keys(nH),t.unshift(nH))),t.reduce(function(o,a){return a==null||(a.hasOwnProperty("noEchoBack")&&!a.hasOwnProperty("hideEchoBack")&&(a.hideEchoBack=a.noEchoBack,delete a.noEchoBack),a.hasOwnProperty("noTrim")&&!a.hasOwnProperty("keepWhitespace")&&(a.keepWhitespace=a.noTrim,delete a.noTrim),r||(e=Object.keys(a)),e.forEach(function(n){var u;if(a.hasOwnProperty(n))switch(u=a[n],n){case"mask":case"limitMessage":case"defaultInput":case"encoding":u=u!=null?u+"":"",u&&n!=="limitMessage"&&(u=u.replace(/[\r\n]/g,"")),o[n]=u;break;case"bufferSize":!isNaN(u=parseInt(u,10))&&typeof u=="number"&&(o[n]=u);break;case"displayOnly":case"keyIn":case"hideEchoBack":case"caseSensitive":case"keepWhitespace":case"history":case"cd":o[n]=!!u;break;case"limit":case"trueValue":case"falseValue":o[n]=$gt(u,function(A){var p=typeof A;return p==="string"||p==="number"||p==="function"||A instanceof RegExp}).map(function(A){return typeof A=="string"?A.replace(/[\r\n]/g,""):A});break;case"print":case"phContent":case"preCheck":o[n]=typeof u=="function"?u:void 0;break;case"prompt":case"display":o[n]=u??"";break}})),o},{})}function oH(t,e,r){return e.some(function(o){var a=typeof o;return a==="string"?r?t===o:t.toLowerCase()===o.toLowerCase():a==="number"?parseFloat(t)===o:a==="function"?o(t):o instanceof RegExp?o.test(t):!1})}function uH(t,e){var r=kh.normalize(jg?(process.env.HOMEDRIVE||"")+(process.env.HOMEPATH||""):process.env.HOME||"").replace(/[\/\\]+$/,"");return t=kh.normalize(t),e?t.replace(/^~(?=\/|\\|$)/,r):t.replace(new RegExp("^"+cH(r)+"(?=\\/|\\\\|$)",jg?"i":""),"~")}function TE(t,e){var r="(?:\\(([\\s\\S]*?)\\))?(\\w+|.-.)(?:\\(([\\s\\S]*?)\\))?",o=new RegExp("(\\$)?(\\$<"+r+">)","g"),a=new RegExp("(\\$)?(\\$\\{"+r+"\\})","g");function n(u,A,p,h,E,I){var v;return A||typeof(v=e(E))!="string"?p:v?(h||"")+v+(I||""):""}return t.replace(o,n).replace(a,n)}function $de(t,e,r){var o,a=[],n=-1,u=0,A="",p;function h(E,I){return I.length>3?(E.push(I[0]+"..."+I[I.length-1]),p=!0):I.length&&(E=E.concat(I)),E}return o=t.reduce(function(E,I){return E.concat((I+"").split(""))},[]).reduce(function(E,I){var v,x;return e||(I=I.toLowerCase()),v=/^\d$/.test(I)?1:/^[A-Z]$/.test(I)?2:/^[a-z]$/.test(I)?3:0,r&&v===0?A+=I:(x=I.charCodeAt(0),v&&v===n&&x===u+1?a.push(I):(E=h(E,a),a=[I],n=v),u=x),E},[]),o=h(o,a),A&&(o.push(A),p=!0),{values:o,suppressed:p}}function eme(t,e){return t.join(t.length>2?", ":e?" / ":"/")}function tme(t,e){var r,o,a={},n;if(e.phContent&&(r=e.phContent(t,e)),typeof r!="string")switch(t){case"hideEchoBack":case"mask":case"defaultInput":case"caseSensitive":case"keepWhitespace":case"encoding":case"bufferSize":case"history":case"cd":r=e.hasOwnProperty(t)?typeof e[t]=="boolean"?e[t]?"on":"off":e[t]+"":"";break;case"limit":case"trueValue":case"falseValue":o=e[e.hasOwnProperty(t+"Src")?t+"Src":t],e.keyIn?(a=$de(o,e.caseSensitive),o=a.values):o=o.filter(function(u){var A=typeof u;return A==="string"||A==="number"}),r=eme(o,a.suppressed);break;case"limitCount":case"limitCountNotZero":r=e[e.hasOwnProperty("limitSrc")?"limitSrc":"limit"].length,r=r||t!=="limitCountNotZero"?r+"":"";break;case"lastInput":r=lH;break;case"cwd":case"CWD":case"cwdHome":r=process.cwd(),t==="CWD"?r=kh.basename(r):t==="cwdHome"&&(r=uH(r));break;case"date":case"time":case"localeDate":case"localeTime":r=new Date()["to"+t.replace(/^./,function(u){return u.toUpperCase()})+"String"]();break;default:typeof(n=(t.match(/^history_m(\d+)$/)||[])[1])=="string"&&(r=qg[qg.length-n]||"")}return r}function rme(t){var e=/^(.)-(.)$/.exec(t),r="",o,a,n,u;if(!e)return null;for(o=e[1].charCodeAt(0),a=e[2].charCodeAt(0),u=o +And the length must be: $`,trueValue:null,falseValue:null,caseSensitive:!0},e,{history:!1,cd:!1,phContent:function(x){return x==="charlist"?r.text:x==="length"?o+"..."+a:null}}),u,A,p,h,E,I,v;for(e=e||{},u=TE(e.charlist?e.charlist+"":"$",rme),(isNaN(o=parseInt(e.min,10))||typeof o!="number")&&(o=12),(isNaN(a=parseInt(e.max,10))||typeof a!="number")&&(a=24),h=new RegExp("^["+cH(u)+"]{"+o+","+a+"}$"),r=$de([u],n.caseSensitive,!0),r.text=eme(r.values,r.suppressed),A=e.confirmMessage!=null?e.confirmMessage:"Reinput a same one to confirm it: ",p=e.unmatchMessage!=null?e.unmatchMessage:"It differs from first one. Hit only the Enter key if you want to retry from first one.",t==null&&(t="Input new password: "),E=n.limitMessage;!v;)n.limit=h,n.limitMessage=E,I=Wr.question(t,n),n.limit=[I,""],n.limitMessage=p,v=Wr.question(A,n);return I};function sme(t,e,r){var o;function a(n){return o=r(n),!isNaN(o)&&typeof o=="number"}return Wr.question(t,Ns({limitMessage:"Input valid number, please."},e,{limit:a,cd:!1})),o}Wr.questionInt=function(t,e){return sme(t,e,function(r){return parseInt(r,10)})};Wr.questionFloat=function(t,e){return sme(t,e,parseFloat)};Wr.questionPath=function(t,e){var r,o="",a=Ns({hideEchoBack:!1,limitMessage:`$Input valid path, please.$<( Min:)min>$<( Max:)max>`,history:!0,cd:!0},e,{keepWhitespace:!1,limit:function(n){var u,A,p;n=uH(n,!0),o="";function h(E){E.split(/\/|\\/).reduce(function(I,v){var x=kh.resolve(I+=v+kh.sep);if(!Yn.existsSync(x))Yn.mkdirSync(x);else if(!Yn.statSync(x).isDirectory())throw new Error("Non directory already exists: "+x);return I},"")}try{if(u=Yn.existsSync(n),r=u?Yn.realpathSync(n):kh.resolve(n),!e.hasOwnProperty("exists")&&!u||typeof e.exists=="boolean"&&e.exists!==u)return o=(u?"Already exists":"No such file or directory")+": "+r,!1;if(!u&&e.create&&(e.isDirectory?h(r):(h(kh.dirname(r)),Yn.closeSync(Yn.openSync(r,"w"))),r=Yn.realpathSync(r)),u&&(e.min||e.max||e.isFile||e.isDirectory)){if(A=Yn.statSync(r),e.isFile&&!A.isFile())return o="Not file: "+r,!1;if(e.isDirectory&&!A.isDirectory())return o="Not directory: "+r,!1;if(e.min&&A.size<+e.min||e.max&&A.size>+e.max)return o="Size "+A.size+" is out of range: "+r,!1}if(typeof e.validate=="function"&&(p=e.validate(r))!==!0)return typeof p=="string"&&(o=p),!1}catch(E){return o=E+"",!1}return!0},phContent:function(n){return n==="error"?o:n!=="min"&&n!=="max"?null:e.hasOwnProperty(n)?e[n]+"":""}});return e=e||{},t==null&&(t='Input path (you can "cd" and "pwd"): '),Wr.question(t,a),r};function ome(t,e){var r={},o={};return typeof t=="object"?(Object.keys(t).forEach(function(a){typeof t[a]=="function"&&(o[e.caseSensitive?a:a.toLowerCase()]=t[a])}),r.preCheck=function(a){var n;return r.args=aH(a),n=r.args[0]||"",e.caseSensitive||(n=n.toLowerCase()),r.hRes=n!=="_"&&o.hasOwnProperty(n)?o[n].apply(a,r.args.slice(1)):o.hasOwnProperty("_")?o._.apply(a,r.args):null,{res:a,forceNext:!1}},o.hasOwnProperty("_")||(r.limit=function(){var a=r.args[0]||"";return e.caseSensitive||(a=a.toLowerCase()),o.hasOwnProperty(a)})):r.preCheck=function(a){return r.args=aH(a),r.hRes=typeof t=="function"?t.apply(a,r.args):!0,{res:a,forceNext:!1}},r}Wr.promptCL=function(t,e){var r=Ns({hideEchoBack:!1,limitMessage:"Requested command is not available.",caseSensitive:!1,history:!0},e),o=ome(t,r);return r.limit=o.limit,r.preCheck=o.preCheck,Wr.prompt(r),o.args};Wr.promptLoop=function(t,e){for(var r=Ns({hideEchoBack:!1,trueValue:null,falseValue:null,caseSensitive:!1,history:!0},e);!t(Wr.prompt(r)););};Wr.promptCLLoop=function(t,e){var r=Ns({hideEchoBack:!1,limitMessage:"Requested command is not available.",caseSensitive:!1,history:!0},e),o=ome(t,r);for(r.limit=o.limit,r.preCheck=o.preCheck;Wr.prompt(r),!o.hRes;);};Wr.promptSimShell=function(t){return Wr.prompt(Ns({hideEchoBack:!1,history:!0},t,{prompt:function(){return jg?"$>":(process.env.USER||"")+(process.env.HOSTNAME?"@"+process.env.HOSTNAME.replace(/\..*$/,""):"")+":$$ "}()}))};function ame(t,e,r){var o;return t==null&&(t="Are you sure? "),(!e||e.guide!==!1)&&(t+="")&&(t=t.replace(/\s*:?\s*$/,"")+" [y/n]: "),o=Wr.keyIn(t,Ns(e,{hideEchoBack:!1,limit:r,trueValue:"y",falseValue:"n",caseSensitive:!1})),typeof o=="boolean"?o:""}Wr.keyInYN=function(t,e){return ame(t,e)};Wr.keyInYNStrict=function(t,e){return ame(t,e,"yn")};Wr.keyInPause=function(t,e){t==null&&(t="Continue..."),(!e||e.guide!==!1)&&(t+="")&&(t=t.replace(/\s+$/,"")+" (Hit any key)"),Wr.keyIn(t,Ns({limit:null},e,{hideEchoBack:!0,mask:""}))};Wr.keyInSelect=function(t,e,r){var o=Ns({hideEchoBack:!1},r,{trueValue:null,falseValue:null,caseSensitive:!1,phContent:function(p){return p==="itemsCount"?t.length+"":p==="firstItem"?(t[0]+"").trim():p==="lastItem"?(t[t.length-1]+"").trim():null}}),a="",n={},u=49,A=` +`;if(!Array.isArray(t)||!t.length||t.length>35)throw"`items` must be Array (max length: 35).";return t.forEach(function(p,h){var E=String.fromCharCode(u);a+=E,n[E]=h,A+="["+E+"] "+(p+"").trim()+` +`,u=u===57?97:u+1}),(!r||r.cancel!==!1)&&(a+="0",n[0]=-1,A+="[0] "+(r&&r.cancel!=null&&typeof r.cancel!="boolean"?(r.cancel+"").trim():"CANCEL")+` +`),o.limit=a,A+=` +`,e==null&&(e="Choose one from list: "),(e+="")&&((!r||r.guide!==!1)&&(e=e.replace(/\s*:?\s*$/,"")+" [$]: "),A+=e),n[Wr.keyIn(A,o).toLowerCase()]};Wr.getRawInput=function(){return ak};function u2(t,e){var r;return e.length&&(r={},r[t]=e[0]),Wr.setDefaultOptions(r)[t]}Wr.setPrint=function(){return u2("print",arguments)};Wr.setPrompt=function(){return u2("prompt",arguments)};Wr.setEncoding=function(){return u2("encoding",arguments)};Wr.setMask=function(){return u2("mask",arguments)};Wr.setBufferSize=function(){return u2("bufferSize",arguments)}});var AH=_((a7t,gl)=>{(function(){var t={major:0,minor:2,patch:66,status:"beta"};tau_file_system={files:{},open:function(w,b,y){var F=tau_file_system.files[w];if(!F){if(y==="read")return null;F={path:w,text:"",type:b,get:function(J,X){return X===this.text.length||X>this.text.length?"end_of_file":this.text.substring(X,X+J)},put:function(J,X){return X==="end_of_file"?(this.text+=J,!0):X==="past_end_of_file"?null:(this.text=this.text.substring(0,X)+J+this.text.substring(X+J.length),!0)},get_byte:function(J){if(J==="end_of_stream")return-1;var X=Math.floor(J/2);if(this.text.length<=X)return-1;var $=n(this.text[Math.floor(J/2)],0);return J%2===0?$&255:$/256>>>0},put_byte:function(J,X){var $=X==="end_of_stream"?this.text.length:Math.floor(X/2);if(this.text.length<$)return null;var ie=this.text.length===$?-1:n(this.text[Math.floor(X/2)],0);return X%2===0?(ie=ie/256>>>0,ie=(ie&255)<<8|J&255):(ie=ie&255,ie=(J&255)<<8|ie&255),this.text.length===$?this.text+=u(ie):this.text=this.text.substring(0,$)+u(ie)+this.text.substring($+1),!0},flush:function(){return!0},close:function(){var J=tau_file_system.files[this.path];return J?!0:null}},tau_file_system.files[w]=F}return y==="write"&&(F.text=""),F}},tau_user_input={buffer:"",get:function(w,b){for(var y;tau_user_input.buffer.length\?\@\^\~\\]+|'(?:[^']*?(?:\\(?:x?\d+)?\\)*(?:'')*(?:\\')*)*')/,number:/^(?:0o[0-7]+|0x[0-9a-fA-F]+|0b[01]+|0'(?:''|\\[abfnrtv\\'"`]|\\x?\d+\\|[^\\])|\d+(?:\.\d+(?:[eE][+-]?\d+)?)?)/,string:/^(?:"([^"]|""|\\")*"|`([^`]|``|\\`)*`)/,l_brace:/^(?:\[)/,r_brace:/^(?:\])/,l_bracket:/^(?:\{)/,r_bracket:/^(?:\})/,bar:/^(?:\|)/,l_paren:/^(?:\()/,r_paren:/^(?:\))/};function L(w,b){return w.get_flag("char_conversion").id==="on"?b.replace(/./g,function(y){return w.get_char_conversion(y)}):b}function U(w){this.thread=w,this.text="",this.tokens=[]}U.prototype.set_last_tokens=function(w){return this.tokens=w},U.prototype.new_text=function(w){this.text=w,this.tokens=[]},U.prototype.get_tokens=function(w){var b,y=0,F=0,J=0,X=[],$=!1;if(w){var ie=this.tokens[w-1];y=ie.len,b=L(this.thread,this.text.substr(ie.len)),F=ie.line,J=ie.start}else b=this.text;if(/^\s*$/.test(b))return null;for(;b!=="";){var Se=[],Re=!1;if(/^\n/.exec(b)!==null){F++,J=0,y++,b=b.replace(/\n/,""),$=!0;continue}for(var at in R)if(R.hasOwnProperty(at)){var dt=R[at].exec(b);dt&&Se.push({value:dt[0],name:at,matches:dt})}if(!Se.length)return this.set_last_tokens([{value:b,matches:[],name:"lexical",line:F,start:J}]);var ie=r(Se,function(kr,mr){return kr.value.length>=mr.value.length?kr:mr});switch(ie.start=J,ie.line=F,b=b.replace(ie.value,""),J+=ie.value.length,y+=ie.value.length,ie.name){case"atom":ie.raw=ie.value,ie.value.charAt(0)==="'"&&(ie.value=v(ie.value.substr(1,ie.value.length-2),"'"),ie.value===null&&(ie.name="lexical",ie.value="unknown escape sequence"));break;case"number":ie.float=ie.value.substring(0,2)!=="0x"&&ie.value.match(/[.eE]/)!==null&&ie.value!=="0'.",ie.value=C(ie.value),ie.blank=Re;break;case"string":var jt=ie.value.charAt(0);ie.value=v(ie.value.substr(1,ie.value.length-2),jt),ie.value===null&&(ie.name="lexical",ie.value="unknown escape sequence");break;case"whitespace":var tr=X[X.length-1];tr&&(tr.space=!0),Re=!0;continue;case"r_bracket":X.length>0&&X[X.length-1].name==="l_bracket"&&(ie=X.pop(),ie.name="atom",ie.value="{}",ie.raw="{}",ie.space=!1);break;case"r_brace":X.length>0&&X[X.length-1].name==="l_brace"&&(ie=X.pop(),ie.name="atom",ie.value="[]",ie.raw="[]",ie.space=!1);break}ie.len=y,X.push(ie),Re=!1}var bt=this.set_last_tokens(X);return bt.length===0?null:bt};function z(w,b,y,F,J){if(!b[y])return{type:A,value:S.error.syntax(b[y-1],"expression expected",!0)};var X;if(F==="0"){var $=b[y];switch($.name){case"number":return{type:p,len:y+1,value:new S.type.Num($.value,$.float)};case"variable":return{type:p,len:y+1,value:new S.type.Var($.value)};case"string":var ie;switch(w.get_flag("double_quotes").id){case"atom":ie=new H($.value,[]);break;case"codes":ie=new H("[]",[]);for(var Se=$.value.length-1;Se>=0;Se--)ie=new H(".",[new S.type.Num(n($.value,Se),!1),ie]);break;case"chars":ie=new H("[]",[]);for(var Se=$.value.length-1;Se>=0;Se--)ie=new H(".",[new S.type.Term($.value.charAt(Se),[]),ie]);break}return{type:p,len:y+1,value:ie};case"l_paren":var bt=z(w,b,y+1,w.__get_max_priority(),!0);return bt.type!==p?bt:b[bt.len]&&b[bt.len].name==="r_paren"?(bt.len++,bt):{type:A,derived:!0,value:S.error.syntax(b[bt.len]?b[bt.len]:b[bt.len-1],") or operator expected",!b[bt.len])};case"l_bracket":var bt=z(w,b,y+1,w.__get_max_priority(),!0);return bt.type!==p?bt:b[bt.len]&&b[bt.len].name==="r_bracket"?(bt.len++,bt.value=new H("{}",[bt.value]),bt):{type:A,derived:!0,value:S.error.syntax(b[bt.len]?b[bt.len]:b[bt.len-1],"} or operator expected",!b[bt.len])}}var Re=te(w,b,y,J);return Re.type===p||Re.derived||(Re=ae(w,b,y),Re.type===p||Re.derived)?Re:{type:A,derived:!1,value:S.error.syntax(b[y],"unexpected token")}}var at=w.__get_max_priority(),dt=w.__get_next_priority(F),jt=y;if(b[y].name==="atom"&&b[y+1]&&(b[y].space||b[y+1].name!=="l_paren")){var $=b[y++],tr=w.__lookup_operator_classes(F,$.value);if(tr&&tr.indexOf("fy")>-1){var bt=z(w,b,y,F,J);if(bt.type!==A)return $.value==="-"&&!$.space&&S.type.is_number(bt.value)?{value:new S.type.Num(-bt.value.value,bt.value.is_float),len:bt.len,type:p}:{value:new S.type.Term($.value,[bt.value]),len:bt.len,type:p};X=bt}else if(tr&&tr.indexOf("fx")>-1){var bt=z(w,b,y,dt,J);if(bt.type!==A)return{value:new S.type.Term($.value,[bt.value]),len:bt.len,type:p};X=bt}}y=jt;var bt=z(w,b,y,dt,J);if(bt.type===p){y=bt.len;var $=b[y];if(b[y]&&(b[y].name==="atom"&&w.__lookup_operator_classes(F,$.value)||b[y].name==="bar"&&w.__lookup_operator_classes(F,"|"))){var ln=dt,kr=F,tr=w.__lookup_operator_classes(F,$.value);if(tr.indexOf("xf")>-1)return{value:new S.type.Term($.value,[bt.value]),len:++bt.len,type:p};if(tr.indexOf("xfx")>-1){var mr=z(w,b,y+1,ln,J);return mr.type===p?{value:new S.type.Term($.value,[bt.value,mr.value]),len:mr.len,type:p}:(mr.derived=!0,mr)}else if(tr.indexOf("xfy")>-1){var mr=z(w,b,y+1,kr,J);return mr.type===p?{value:new S.type.Term($.value,[bt.value,mr.value]),len:mr.len,type:p}:(mr.derived=!0,mr)}else if(bt.type!==A)for(;;){y=bt.len;var $=b[y];if($&&$.name==="atom"&&w.__lookup_operator_classes(F,$.value)){var tr=w.__lookup_operator_classes(F,$.value);if(tr.indexOf("yf")>-1)bt={value:new S.type.Term($.value,[bt.value]),len:++y,type:p};else if(tr.indexOf("yfx")>-1){var mr=z(w,b,++y,ln,J);if(mr.type===A)return mr.derived=!0,mr;y=mr.len,bt={value:new S.type.Term($.value,[bt.value,mr.value]),len:y,type:p}}else break}else break}}else X={type:A,value:S.error.syntax(b[bt.len-1],"operator expected")};return bt}return bt}function te(w,b,y,F){if(!b[y]||b[y].name==="atom"&&b[y].raw==="."&&!F&&(b[y].space||!b[y+1]||b[y+1].name!=="l_paren"))return{type:A,derived:!1,value:S.error.syntax(b[y-1],"unfounded token")};var J=b[y],X=[];if(b[y].name==="atom"&&b[y].raw!==","){if(y++,b[y-1].space)return{type:p,len:y,value:new S.type.Term(J.value,X)};if(b[y]&&b[y].name==="l_paren"){if(b[y+1]&&b[y+1].name==="r_paren")return{type:A,derived:!0,value:S.error.syntax(b[y+1],"argument expected")};var $=z(w,b,++y,"999",!0);if($.type===A)return $.derived?$:{type:A,derived:!0,value:S.error.syntax(b[y]?b[y]:b[y-1],"argument expected",!b[y])};for(X.push($.value),y=$.len;b[y]&&b[y].name==="atom"&&b[y].value===",";){if($=z(w,b,y+1,"999",!0),$.type===A)return $.derived?$:{type:A,derived:!0,value:S.error.syntax(b[y+1]?b[y+1]:b[y],"argument expected",!b[y+1])};X.push($.value),y=$.len}if(b[y]&&b[y].name==="r_paren")y++;else return{type:A,derived:!0,value:S.error.syntax(b[y]?b[y]:b[y-1],", or ) expected",!b[y])}}return{type:p,len:y,value:new S.type.Term(J.value,X)}}return{type:A,derived:!1,value:S.error.syntax(b[y],"term expected")}}function ae(w,b,y){if(!b[y])return{type:A,derived:!1,value:S.error.syntax(b[y-1],"[ expected")};if(b[y]&&b[y].name==="l_brace"){var F=z(w,b,++y,"999",!0),J=[F.value],X=void 0;if(F.type===A)return b[y]&&b[y].name==="r_brace"?{type:p,len:y+1,value:new S.type.Term("[]",[])}:{type:A,derived:!0,value:S.error.syntax(b[y],"] expected")};for(y=F.len;b[y]&&b[y].name==="atom"&&b[y].value===",";){if(F=z(w,b,y+1,"999",!0),F.type===A)return F.derived?F:{type:A,derived:!0,value:S.error.syntax(b[y+1]?b[y+1]:b[y],"argument expected",!b[y+1])};J.push(F.value),y=F.len}var $=!1;if(b[y]&&b[y].name==="bar"){if($=!0,F=z(w,b,y+1,"999",!0),F.type===A)return F.derived?F:{type:A,derived:!0,value:S.error.syntax(b[y+1]?b[y+1]:b[y],"argument expected",!b[y+1])};X=F.value,y=F.len}return b[y]&&b[y].name==="r_brace"?{type:p,len:y+1,value:g(J,X)}:{type:A,derived:!0,value:S.error.syntax(b[y]?b[y]:b[y-1],$?"] expected":", or | or ] expected",!b[y])}}return{type:A,derived:!1,value:S.error.syntax(b[y],"list expected")}}function le(w,b,y){var F=b[y].line,J=z(w,b,y,w.__get_max_priority(),!1),X=null,$;if(J.type!==A)if(y=J.len,b[y]&&b[y].name==="atom"&&b[y].raw===".")if(y++,S.type.is_term(J.value)){if(J.value.indicator===":-/2"?(X=new S.type.Rule(J.value.args[0],Ee(J.value.args[1])),$={value:X,len:y,type:p}):J.value.indicator==="-->/2"?(X=de(new S.type.Rule(J.value.args[0],J.value.args[1]),w),X.body=Ee(X.body),$={value:X,len:y,type:S.type.is_rule(X)?p:A}):(X=new S.type.Rule(J.value,null),$={value:X,len:y,type:p}),X){var ie=X.singleton_variables();ie.length>0&&w.throw_warning(S.warning.singleton(ie,X.head.indicator,F))}return $}else return{type:A,value:S.error.syntax(b[y],"callable expected")};else return{type:A,value:S.error.syntax(b[y]?b[y]:b[y-1],". or operator expected")};return J}function ce(w,b,y){y=y||{},y.from=y.from?y.from:"$tau-js",y.reconsult=y.reconsult!==void 0?y.reconsult:!0;var F=new U(w),J={},X;F.new_text(b);var $=0,ie=F.get_tokens($);do{if(ie===null||!ie[$])break;var Se=le(w,ie,$);if(Se.type===A)return new H("throw",[Se.value]);if(Se.value.body===null&&Se.value.head.indicator==="?-/1"){var Re=new et(w.session);Re.add_goal(Se.value.head.args[0]),Re.answer(function(dt){S.type.is_error(dt)?w.throw_warning(dt.args[0]):(dt===!1||dt===null)&&w.throw_warning(S.warning.failed_goal(Se.value.head.args[0],Se.len))}),$=Se.len;var at=!0}else if(Se.value.body===null&&Se.value.head.indicator===":-/1"){var at=w.run_directive(Se.value.head.args[0]);$=Se.len,Se.value.head.args[0].indicator==="char_conversion/2"&&(ie=F.get_tokens($),$=0)}else{X=Se.value.head.indicator,y.reconsult!==!1&&J[X]!==!0&&!w.is_multifile_predicate(X)&&(w.session.rules[X]=a(w.session.rules[X]||[],function(jt){return jt.dynamic}),J[X]=!0);var at=w.add_rule(Se.value,y);$=Se.len}if(!at)return at}while(!0);return!0}function Ce(w,b){var y=new U(w);y.new_text(b);var F=0;do{var J=y.get_tokens(F);if(J===null)break;var X=z(w,J,0,w.__get_max_priority(),!1);if(X.type!==A){var $=X.len,ie=$;if(J[$]&&J[$].name==="atom"&&J[$].raw===".")w.add_goal(Ee(X.value));else{var Se=J[$];return new H("throw",[S.error.syntax(Se||J[$-1],". or operator expected",!Se)])}F=X.len+1}else return new H("throw",[X.value])}while(!0);return!0}function de(w,b){w=w.rename(b);var y=b.next_free_variable(),F=Be(w.body,y,b);return F.error?F.value:(w.body=F.value,w.head.args=w.head.args.concat([y,F.variable]),w.head=new H(w.head.id,w.head.args),w)}function Be(w,b,y){var F;if(S.type.is_term(w)&&w.indicator==="!/0")return{value:w,variable:b,error:!1};if(S.type.is_term(w)&&w.indicator===",/2"){var J=Be(w.args[0],b,y);if(J.error)return J;var X=Be(w.args[1],J.variable,y);return X.error?X:{value:new H(",",[J.value,X.value]),variable:X.variable,error:!1}}else{if(S.type.is_term(w)&&w.indicator==="{}/1")return{value:w.args[0],variable:b,error:!1};if(S.type.is_empty_list(w))return{value:new H("true",[]),variable:b,error:!1};if(S.type.is_list(w)){F=y.next_free_variable();for(var $=w,ie;$.indicator==="./2";)ie=$,$=$.args[1];return S.type.is_variable($)?{value:S.error.instantiation("DCG"),variable:b,error:!0}:S.type.is_empty_list($)?(ie.args[1]=F,{value:new H("=",[b,w]),variable:F,error:!1}):{value:S.error.type("list",w,"DCG"),variable:b,error:!0}}else return S.type.is_callable(w)?(F=y.next_free_variable(),w.args=w.args.concat([b,F]),w=new H(w.id,w.args),{value:w,variable:F,error:!1}):{value:S.error.type("callable",w,"DCG"),variable:b,error:!0}}}function Ee(w){return S.type.is_variable(w)?new H("call",[w]):S.type.is_term(w)&&[",/2",";/2","->/2"].indexOf(w.indicator)!==-1?new H(w.id,[Ee(w.args[0]),Ee(w.args[1])]):w}function g(w,b){for(var y=b||new S.type.Term("[]",[]),F=w.length-1;F>=0;F--)y=new S.type.Term(".",[w[F],y]);return y}function me(w,b){for(var y=w.length-1;y>=0;y--)w[y]===b&&w.splice(y,1)}function we(w){for(var b={},y=[],F=0;F=0;b--)if(w.charAt(b)==="/")return new H("/",[new H(w.substring(0,b)),new Ne(parseInt(w.substring(b+1)),!1)])}function xe(w){this.id=w}function Ne(w,b){this.is_float=b!==void 0?b:parseInt(w)!==w,this.value=this.is_float?w:parseInt(w)}var ht=0;function H(w,b,y){this.ref=y||++ht,this.id=w,this.args=b||[],this.indicator=w+"/"+this.args.length}var rt=0;function Te(w,b,y,F,J,X){this.id=rt++,this.stream=w,this.mode=b,this.alias=y,this.type=F!==void 0?F:"text",this.reposition=J!==void 0?J:!0,this.eof_action=X!==void 0?X:"eof_code",this.position=this.mode==="append"?"end_of_stream":0,this.output=this.mode==="write"||this.mode==="append",this.input=this.mode==="read"}function Fe(w){w=w||{},this.links=w}function ke(w,b,y){b=b||new Fe,y=y||null,this.goal=w,this.substitution=b,this.parent=y}function Ye(w,b,y){this.head=w,this.body=b,this.dynamic=y||!1}function be(w){w=w===void 0||w<=0?1e3:w,this.rules={},this.src_predicates={},this.rename=0,this.modules=[],this.thread=new et(this),this.total_threads=1,this.renamed_variables={},this.public_predicates={},this.multifile_predicates={},this.limit=w,this.streams={user_input:new Te(typeof gl<"u"&&gl.exports?nodejs_user_input:tau_user_input,"read","user_input","text",!1,"reset"),user_output:new Te(typeof gl<"u"&&gl.exports?nodejs_user_output:tau_user_output,"write","user_output","text",!1,"eof_code")},this.file_system=typeof gl<"u"&&gl.exports?nodejs_file_system:tau_file_system,this.standard_input=this.streams.user_input,this.standard_output=this.streams.user_output,this.current_input=this.streams.user_input,this.current_output=this.streams.user_output,this.format_success=function(b){return b.substitution},this.format_error=function(b){return b.goal},this.flag={bounded:S.flag.bounded.value,max_integer:S.flag.max_integer.value,min_integer:S.flag.min_integer.value,integer_rounding_function:S.flag.integer_rounding_function.value,char_conversion:S.flag.char_conversion.value,debug:S.flag.debug.value,max_arity:S.flag.max_arity.value,unknown:S.flag.unknown.value,double_quotes:S.flag.double_quotes.value,occurs_check:S.flag.occurs_check.value,dialect:S.flag.dialect.value,version_data:S.flag.version_data.value,nodejs:S.flag.nodejs.value},this.__loaded_modules=[],this.__char_conversion={},this.__operators={1200:{":-":["fx","xfx"],"-->":["xfx"],"?-":["fx"]},1100:{";":["xfy"]},1050:{"->":["xfy"]},1e3:{",":["xfy"]},900:{"\\+":["fy"]},700:{"=":["xfx"],"\\=":["xfx"],"==":["xfx"],"\\==":["xfx"],"@<":["xfx"],"@=<":["xfx"],"@>":["xfx"],"@>=":["xfx"],"=..":["xfx"],is:["xfx"],"=:=":["xfx"],"=\\=":["xfx"],"<":["xfx"],"=<":["xfx"],">":["xfx"],">=":["xfx"]},600:{":":["xfy"]},500:{"+":["yfx"],"-":["yfx"],"/\\":["yfx"],"\\/":["yfx"]},400:{"*":["yfx"],"/":["yfx"],"//":["yfx"],rem:["yfx"],mod:["yfx"],"<<":["yfx"],">>":["yfx"]},200:{"**":["xfx"],"^":["xfy"],"-":["fy"],"+":["fy"],"\\":["fy"]}}}function et(w){this.epoch=Date.now(),this.session=w,this.session.total_threads++,this.total_steps=0,this.cpu_time=0,this.cpu_time_last=0,this.points=[],this.debugger=!1,this.debugger_states=[],this.level="top_level/0",this.__calls=[],this.current_limit=this.session.limit,this.warnings=[]}function Ue(w,b,y){this.id=w,this.rules=b,this.exports=y,S.module[w]=this}Ue.prototype.exports_predicate=function(w){return this.exports.indexOf(w)!==-1},xe.prototype.unify=function(w,b){if(b&&e(w.variables(),this.id)!==-1&&!S.type.is_variable(w))return null;var y={};return y[this.id]=w,new Fe(y)},Ne.prototype.unify=function(w,b){return S.type.is_number(w)&&this.value===w.value&&this.is_float===w.is_float?new Fe:null},H.prototype.unify=function(w,b){if(S.type.is_term(w)&&this.indicator===w.indicator){for(var y=new Fe,F=0;F=0){var F=this.args[0].value,J=Math.floor(F/26),X=F%26;return"ABCDEFGHIJKLMNOPQRSTUVWXYZ"[X]+(J!==0?J:"")}switch(this.indicator){case"[]/0":case"{}/0":case"!/0":return this.id;case"{}/1":return"{"+this.args[0].toString(w)+"}";case"./2":for(var $="["+this.args[0].toString(w),ie=this.args[1];ie.indicator==="./2";)$+=", "+ie.args[0].toString(w),ie=ie.args[1];return ie.indicator!=="[]/0"&&($+="|"+ie.toString(w)),$+="]",$;case",/2":return"("+this.args[0].toString(w)+", "+this.args[1].toString(w)+")";default:var Se=this.id,Re=w.session?w.session.lookup_operator(this.id,this.args.length):null;if(w.session===void 0||w.ignore_ops||Re===null)return w.quoted&&!/^(!|,|;|[a-z][0-9a-zA-Z_]*)$/.test(Se)&&Se!=="{}"&&Se!=="[]"&&(Se="'"+x(Se)+"'"),Se+(this.args.length?"("+o(this.args,function(tr){return tr.toString(w)}).join(", ")+")":"");var at=Re.priority>b.priority||Re.priority===b.priority&&(Re.class==="xfy"&&this.indicator!==b.indicator||Re.class==="yfx"&&this.indicator!==b.indicator||this.indicator===b.indicator&&Re.class==="yfx"&&y==="right"||this.indicator===b.indicator&&Re.class==="xfy"&&y==="left");Re.indicator=this.indicator;var dt=at?"(":"",jt=at?")":"";return this.args.length===0?"("+this.id+")":["fy","fx"].indexOf(Re.class)!==-1?dt+Se+" "+this.args[0].toString(w,Re)+jt:["yf","xf"].indexOf(Re.class)!==-1?dt+this.args[0].toString(w,Re)+" "+Se+jt:dt+this.args[0].toString(w,Re,"left")+" "+this.id+" "+this.args[1].toString(w,Re,"right")+jt}},Te.prototype.toString=function(w){return"("+this.id+")"},Fe.prototype.toString=function(w){var b="{";for(var y in this.links)this.links.hasOwnProperty(y)&&(b!=="{"&&(b+=", "),b+=y+"/"+this.links[y].toString(w));return b+="}",b},ke.prototype.toString=function(w){return this.goal===null?"<"+this.substitution.toString(w)+">":"<"+this.goal.toString(w)+", "+this.substitution.toString(w)+">"},Ye.prototype.toString=function(w){return this.body?this.head.toString(w)+" :- "+this.body.toString(w)+".":this.head.toString(w)+"."},be.prototype.toString=function(w){for(var b="",y=0;y=0;J--)F=new H(".",[b[J],F]);return F}return new H(this.id,o(this.args,function(X){return X.apply(w)}),this.ref)},Te.prototype.apply=function(w){return this},Ye.prototype.apply=function(w){return new Ye(this.head.apply(w),this.body!==null?this.body.apply(w):null)},Fe.prototype.apply=function(w){var b,y={};for(b in this.links)this.links.hasOwnProperty(b)&&(y[b]=this.links[b].apply(w));return new Fe(y)},H.prototype.select=function(){for(var w=this;w.indicator===",/2";)w=w.args[0];return w},H.prototype.replace=function(w){return this.indicator===",/2"?this.args[0].indicator===",/2"?new H(",",[this.args[0].replace(w),this.args[1]]):w===null?this.args[1]:new H(",",[w,this.args[1]]):w},H.prototype.search=function(w){if(S.type.is_term(w)&&w.ref!==void 0&&this.ref===w.ref)return!0;for(var b=0;bb&&F0&&(b=this.head_point().substitution.domain());e(b,S.format_variable(this.session.rename))!==-1;)this.session.rename++;if(w.id==="_")return new xe(S.format_variable(this.session.rename));this.session.renamed_variables[w.id]=S.format_variable(this.session.rename)}return new xe(this.session.renamed_variables[w.id])},be.prototype.next_free_variable=function(){return this.thread.next_free_variable()},et.prototype.next_free_variable=function(){this.session.rename++;var w=[];for(this.points.length>0&&(w=this.head_point().substitution.domain());e(w,S.format_variable(this.session.rename))!==-1;)this.session.rename++;return new xe(S.format_variable(this.session.rename))},be.prototype.is_public_predicate=function(w){return!this.public_predicates.hasOwnProperty(w)||this.public_predicates[w]===!0},et.prototype.is_public_predicate=function(w){return this.session.is_public_predicate(w)},be.prototype.is_multifile_predicate=function(w){return this.multifile_predicates.hasOwnProperty(w)&&this.multifile_predicates[w]===!0},et.prototype.is_multifile_predicate=function(w){return this.session.is_multifile_predicate(w)},be.prototype.prepend=function(w){return this.thread.prepend(w)},et.prototype.prepend=function(w){for(var b=w.length-1;b>=0;b--)this.points.push(w[b])},be.prototype.success=function(w,b){return this.thread.success(w,b)},et.prototype.success=function(w,y){var y=typeof y>"u"?w:y;this.prepend([new ke(w.goal.replace(null),w.substitution,y)])},be.prototype.throw_error=function(w){return this.thread.throw_error(w)},et.prototype.throw_error=function(w){this.prepend([new ke(new H("throw",[w]),new Fe,null,null)])},be.prototype.step_rule=function(w,b){return this.thread.step_rule(w,b)},et.prototype.step_rule=function(w,b){var y=b.indicator;if(w==="user"&&(w=null),w===null&&this.session.rules.hasOwnProperty(y))return this.session.rules[y];for(var F=w===null?this.session.modules:e(this.session.modules,w)===-1?[]:[w],J=0;J1)&&this.again()},be.prototype.answers=function(w,b,y){return this.thread.answers(w,b,y)},et.prototype.answers=function(w,b,y){var F=b||1e3,J=this;if(b<=0){y&&y();return}this.answer(function(X){w(X),X!==!1?setTimeout(function(){J.answers(w,b-1,y)},1):y&&y()})},be.prototype.again=function(w){return this.thread.again(w)},et.prototype.again=function(w){for(var b,y=Date.now();this.__calls.length>0;){for(this.warnings=[],w!==!1&&(this.current_limit=this.session.limit);this.current_limit>0&&this.points.length>0&&this.head_point().goal!==null&&!S.type.is_error(this.head_point().goal);)if(this.current_limit--,this.step()===!0)return;var F=Date.now();this.cpu_time_last=F-y,this.cpu_time+=this.cpu_time_last;var J=this.__calls.shift();this.current_limit<=0?J(null):this.points.length===0?J(!1):S.type.is_error(this.head_point().goal)?(b=this.session.format_error(this.points.pop()),this.points=[],J(b)):(this.debugger&&this.debugger_states.push(this.head_point()),b=this.session.format_success(this.points.pop()),J(b))}},be.prototype.unfold=function(w){if(w.body===null)return!1;var b=w.head,y=w.body,F=y.select(),J=new et(this),X=[];J.add_goal(F),J.step();for(var $=J.points.length-1;$>=0;$--){var ie=J.points[$],Se=b.apply(ie.substitution),Re=y.replace(ie.goal);Re!==null&&(Re=Re.apply(ie.substitution)),X.push(new Ye(Se,Re))}var at=this.rules[b.indicator],dt=e(at,w);return X.length>0&&dt!==-1?(at.splice.apply(at,[dt,1].concat(X)),!0):!1},et.prototype.unfold=function(w){return this.session.unfold(w)},xe.prototype.interpret=function(w){return S.error.instantiation(w.level)},Ne.prototype.interpret=function(w){return this},H.prototype.interpret=function(w){return S.type.is_unitary_list(this)?this.args[0].interpret(w):S.operate(w,this)},xe.prototype.compare=function(w){return this.idw.id?1:0},Ne.prototype.compare=function(w){if(this.value===w.value&&this.is_float===w.is_float)return 0;if(this.valuew.value)return 1},H.prototype.compare=function(w){if(this.args.lengthw.args.length||this.args.length===w.args.length&&this.id>w.id)return 1;for(var b=0;bF)return 1;if(w.constructor===Ne){if(w.is_float&&b.is_float)return 0;if(w.is_float)return-1;if(b.is_float)return 1}return 0},is_substitution:function(w){return w instanceof Fe},is_state:function(w){return w instanceof ke},is_rule:function(w){return w instanceof Ye},is_variable:function(w){return w instanceof xe},is_stream:function(w){return w instanceof Te},is_anonymous_var:function(w){return w instanceof xe&&w.id==="_"},is_callable:function(w){return w instanceof H},is_number:function(w){return w instanceof Ne},is_integer:function(w){return w instanceof Ne&&!w.is_float},is_float:function(w){return w instanceof Ne&&w.is_float},is_term:function(w){return w instanceof H},is_atom:function(w){return w instanceof H&&w.args.length===0},is_ground:function(w){if(w instanceof xe)return!1;if(w instanceof H){for(var b=0;b0},is_list:function(w){return w instanceof H&&(w.indicator==="[]/0"||w.indicator==="./2")},is_empty_list:function(w){return w instanceof H&&w.indicator==="[]/0"},is_non_empty_list:function(w){return w instanceof H&&w.indicator==="./2"},is_fully_list:function(w){for(;w instanceof H&&w.indicator==="./2";)w=w.args[1];return w instanceof xe||w instanceof H&&w.indicator==="[]/0"},is_instantiated_list:function(w){for(;w instanceof H&&w.indicator==="./2";)w=w.args[1];return w instanceof H&&w.indicator==="[]/0"},is_unitary_list:function(w){return w instanceof H&&w.indicator==="./2"&&w.args[1]instanceof H&&w.args[1].indicator==="[]/0"},is_character:function(w){return w instanceof H&&(w.id.length===1||w.id.length>0&&w.id.length<=2&&n(w.id,0)>=65536)},is_character_code:function(w){return w instanceof Ne&&!w.is_float&&w.value>=0&&w.value<=1114111},is_byte:function(w){return w instanceof Ne&&!w.is_float&&w.value>=0&&w.value<=255},is_operator:function(w){return w instanceof H&&S.arithmetic.evaluation[w.indicator]},is_directive:function(w){return w instanceof H&&S.directive[w.indicator]!==void 0},is_builtin:function(w){return w instanceof H&&S.predicate[w.indicator]!==void 0},is_error:function(w){return w instanceof H&&w.indicator==="throw/1"},is_predicate_indicator:function(w){return w instanceof H&&w.indicator==="//2"&&w.args[0]instanceof H&&w.args[0].args.length===0&&w.args[1]instanceof Ne&&w.args[1].is_float===!1},is_flag:function(w){return w instanceof H&&w.args.length===0&&S.flag[w.id]!==void 0},is_value_flag:function(w,b){if(!S.type.is_flag(w))return!1;for(var y in S.flag[w.id].allowed)if(S.flag[w.id].allowed.hasOwnProperty(y)&&S.flag[w.id].allowed[y].equals(b))return!0;return!1},is_io_mode:function(w){return S.type.is_atom(w)&&["read","write","append"].indexOf(w.id)!==-1},is_stream_option:function(w){return S.type.is_term(w)&&(w.indicator==="alias/1"&&S.type.is_atom(w.args[0])||w.indicator==="reposition/1"&&S.type.is_atom(w.args[0])&&(w.args[0].id==="true"||w.args[0].id==="false")||w.indicator==="type/1"&&S.type.is_atom(w.args[0])&&(w.args[0].id==="text"||w.args[0].id==="binary")||w.indicator==="eof_action/1"&&S.type.is_atom(w.args[0])&&(w.args[0].id==="error"||w.args[0].id==="eof_code"||w.args[0].id==="reset"))},is_stream_position:function(w){return S.type.is_integer(w)&&w.value>=0||S.type.is_atom(w)&&(w.id==="end_of_stream"||w.id==="past_end_of_stream")},is_stream_property:function(w){return S.type.is_term(w)&&(w.indicator==="input/0"||w.indicator==="output/0"||w.indicator==="alias/1"&&(S.type.is_variable(w.args[0])||S.type.is_atom(w.args[0]))||w.indicator==="file_name/1"&&(S.type.is_variable(w.args[0])||S.type.is_atom(w.args[0]))||w.indicator==="position/1"&&(S.type.is_variable(w.args[0])||S.type.is_stream_position(w.args[0]))||w.indicator==="reposition/1"&&(S.type.is_variable(w.args[0])||S.type.is_atom(w.args[0])&&(w.args[0].id==="true"||w.args[0].id==="false"))||w.indicator==="type/1"&&(S.type.is_variable(w.args[0])||S.type.is_atom(w.args[0])&&(w.args[0].id==="text"||w.args[0].id==="binary"))||w.indicator==="mode/1"&&(S.type.is_variable(w.args[0])||S.type.is_atom(w.args[0])&&(w.args[0].id==="read"||w.args[0].id==="write"||w.args[0].id==="append"))||w.indicator==="eof_action/1"&&(S.type.is_variable(w.args[0])||S.type.is_atom(w.args[0])&&(w.args[0].id==="error"||w.args[0].id==="eof_code"||w.args[0].id==="reset"))||w.indicator==="end_of_stream/1"&&(S.type.is_variable(w.args[0])||S.type.is_atom(w.args[0])&&(w.args[0].id==="at"||w.args[0].id==="past"||w.args[0].id==="not")))},is_streamable:function(w){return w.__proto__.stream!==void 0},is_read_option:function(w){return S.type.is_term(w)&&["variables/1","variable_names/1","singletons/1"].indexOf(w.indicator)!==-1},is_write_option:function(w){return S.type.is_term(w)&&(w.indicator==="quoted/1"&&S.type.is_atom(w.args[0])&&(w.args[0].id==="true"||w.args[0].id==="false")||w.indicator==="ignore_ops/1"&&S.type.is_atom(w.args[0])&&(w.args[0].id==="true"||w.args[0].id==="false")||w.indicator==="numbervars/1"&&S.type.is_atom(w.args[0])&&(w.args[0].id==="true"||w.args[0].id==="false"))},is_close_option:function(w){return S.type.is_term(w)&&w.indicator==="force/1"&&S.type.is_atom(w.args[0])&&(w.args[0].id==="true"||w.args[0].id==="false")},is_modifiable_flag:function(w){return S.type.is_flag(w)&&S.flag[w.id].changeable},is_module:function(w){return w instanceof H&&w.indicator==="library/1"&&w.args[0]instanceof H&&w.args[0].args.length===0&&S.module[w.args[0].id]!==void 0}},arithmetic:{evaluation:{"e/0":{type_args:null,type_result:!0,fn:function(w){return Math.E}},"pi/0":{type_args:null,type_result:!0,fn:function(w){return Math.PI}},"tau/0":{type_args:null,type_result:!0,fn:function(w){return 2*Math.PI}},"epsilon/0":{type_args:null,type_result:!0,fn:function(w){return Number.EPSILON}},"+/1":{type_args:null,type_result:null,fn:function(w,b){return w}},"-/1":{type_args:null,type_result:null,fn:function(w,b){return-w}},"\\/1":{type_args:!1,type_result:!1,fn:function(w,b){return~w}},"abs/1":{type_args:null,type_result:null,fn:function(w,b){return Math.abs(w)}},"sign/1":{type_args:null,type_result:null,fn:function(w,b){return Math.sign(w)}},"float_integer_part/1":{type_args:!0,type_result:!1,fn:function(w,b){return parseInt(w)}},"float_fractional_part/1":{type_args:!0,type_result:!0,fn:function(w,b){return w-parseInt(w)}},"float/1":{type_args:null,type_result:!0,fn:function(w,b){return parseFloat(w)}},"floor/1":{type_args:!0,type_result:!1,fn:function(w,b){return Math.floor(w)}},"truncate/1":{type_args:!0,type_result:!1,fn:function(w,b){return parseInt(w)}},"round/1":{type_args:!0,type_result:!1,fn:function(w,b){return Math.round(w)}},"ceiling/1":{type_args:!0,type_result:!1,fn:function(w,b){return Math.ceil(w)}},"sin/1":{type_args:null,type_result:!0,fn:function(w,b){return Math.sin(w)}},"cos/1":{type_args:null,type_result:!0,fn:function(w,b){return Math.cos(w)}},"tan/1":{type_args:null,type_result:!0,fn:function(w,b){return Math.tan(w)}},"asin/1":{type_args:null,type_result:!0,fn:function(w,b){return Math.asin(w)}},"acos/1":{type_args:null,type_result:!0,fn:function(w,b){return Math.acos(w)}},"atan/1":{type_args:null,type_result:!0,fn:function(w,b){return Math.atan(w)}},"atan2/2":{type_args:null,type_result:!0,fn:function(w,b,y){return Math.atan2(w,b)}},"exp/1":{type_args:null,type_result:!0,fn:function(w,b){return Math.exp(w)}},"sqrt/1":{type_args:null,type_result:!0,fn:function(w,b){return Math.sqrt(w)}},"log/1":{type_args:null,type_result:!0,fn:function(w,b){return w>0?Math.log(w):S.error.evaluation("undefined",b.__call_indicator)}},"+/2":{type_args:null,type_result:null,fn:function(w,b,y){return w+b}},"-/2":{type_args:null,type_result:null,fn:function(w,b,y){return w-b}},"*/2":{type_args:null,type_result:null,fn:function(w,b,y){return w*b}},"//2":{type_args:null,type_result:!0,fn:function(w,b,y){return b?w/b:S.error.evaluation("zero_division",y.__call_indicator)}},"///2":{type_args:!1,type_result:!1,fn:function(w,b,y){return b?parseInt(w/b):S.error.evaluation("zero_division",y.__call_indicator)}},"**/2":{type_args:null,type_result:!0,fn:function(w,b,y){return Math.pow(w,b)}},"^/2":{type_args:null,type_result:null,fn:function(w,b,y){return Math.pow(w,b)}},"<>/2":{type_args:!1,type_result:!1,fn:function(w,b,y){return w>>b}},"/\\/2":{type_args:!1,type_result:!1,fn:function(w,b,y){return w&b}},"\\//2":{type_args:!1,type_result:!1,fn:function(w,b,y){return w|b}},"xor/2":{type_args:!1,type_result:!1,fn:function(w,b,y){return w^b}},"rem/2":{type_args:!1,type_result:!1,fn:function(w,b,y){return b?w%b:S.error.evaluation("zero_division",y.__call_indicator)}},"mod/2":{type_args:!1,type_result:!1,fn:function(w,b,y){return b?w-parseInt(w/b)*b:S.error.evaluation("zero_division",y.__call_indicator)}},"max/2":{type_args:null,type_result:null,fn:function(w,b,y){return Math.max(w,b)}},"min/2":{type_args:null,type_result:null,fn:function(w,b,y){return Math.min(w,b)}}}},directive:{"dynamic/1":function(w,b){var y=b.args[0];if(S.type.is_variable(y))w.throw_error(S.error.instantiation(b.indicator));else if(!S.type.is_compound(y)||y.indicator!=="//2")w.throw_error(S.error.type("predicate_indicator",y,b.indicator));else if(S.type.is_variable(y.args[0])||S.type.is_variable(y.args[1]))w.throw_error(S.error.instantiation(b.indicator));else if(!S.type.is_atom(y.args[0]))w.throw_error(S.error.type("atom",y.args[0],b.indicator));else if(!S.type.is_integer(y.args[1]))w.throw_error(S.error.type("integer",y.args[1],b.indicator));else{var F=b.args[0].args[0].id+"/"+b.args[0].args[1].value;w.session.public_predicates[F]=!0,w.session.rules[F]||(w.session.rules[F]=[])}},"multifile/1":function(w,b){var y=b.args[0];S.type.is_variable(y)?w.throw_error(S.error.instantiation(b.indicator)):!S.type.is_compound(y)||y.indicator!=="//2"?w.throw_error(S.error.type("predicate_indicator",y,b.indicator)):S.type.is_variable(y.args[0])||S.type.is_variable(y.args[1])?w.throw_error(S.error.instantiation(b.indicator)):S.type.is_atom(y.args[0])?S.type.is_integer(y.args[1])?w.session.multifile_predicates[b.args[0].args[0].id+"/"+b.args[0].args[1].value]=!0:w.throw_error(S.error.type("integer",y.args[1],b.indicator)):w.throw_error(S.error.type("atom",y.args[0],b.indicator))},"set_prolog_flag/2":function(w,b){var y=b.args[0],F=b.args[1];S.type.is_variable(y)||S.type.is_variable(F)?w.throw_error(S.error.instantiation(b.indicator)):S.type.is_atom(y)?S.type.is_flag(y)?S.type.is_value_flag(y,F)?S.type.is_modifiable_flag(y)?w.session.flag[y.id]=F:w.throw_error(S.error.permission("modify","flag",y)):w.throw_error(S.error.domain("flag_value",new H("+",[y,F]),b.indicator)):w.throw_error(S.error.domain("prolog_flag",y,b.indicator)):w.throw_error(S.error.type("atom",y,b.indicator))},"use_module/1":function(w,b){var y=b.args[0];if(S.type.is_variable(y))w.throw_error(S.error.instantiation(b.indicator));else if(!S.type.is_term(y))w.throw_error(S.error.type("term",y,b.indicator));else if(S.type.is_module(y)){var F=y.args[0].id;e(w.session.modules,F)===-1&&w.session.modules.push(F)}},"char_conversion/2":function(w,b){var y=b.args[0],F=b.args[1];S.type.is_variable(y)||S.type.is_variable(F)?w.throw_error(S.error.instantiation(b.indicator)):S.type.is_character(y)?S.type.is_character(F)?y.id===F.id?delete w.session.__char_conversion[y.id]:w.session.__char_conversion[y.id]=F.id:w.throw_error(S.error.type("character",F,b.indicator)):w.throw_error(S.error.type("character",y,b.indicator))},"op/3":function(w,b){var y=b.args[0],F=b.args[1],J=b.args[2];if(S.type.is_variable(y)||S.type.is_variable(F)||S.type.is_variable(J))w.throw_error(S.error.instantiation(b.indicator));else if(!S.type.is_integer(y))w.throw_error(S.error.type("integer",y,b.indicator));else if(!S.type.is_atom(F))w.throw_error(S.error.type("atom",F,b.indicator));else if(!S.type.is_atom(J))w.throw_error(S.error.type("atom",J,b.indicator));else if(y.value<0||y.value>1200)w.throw_error(S.error.domain("operator_priority",y,b.indicator));else if(J.id===",")w.throw_error(S.error.permission("modify","operator",J,b.indicator));else if(J.id==="|"&&(y.value<1001||F.id.length!==3))w.throw_error(S.error.permission("modify","operator",J,b.indicator));else if(["fy","fx","yf","xf","xfx","yfx","xfy"].indexOf(F.id)===-1)w.throw_error(S.error.domain("operator_specifier",F,b.indicator));else{var X={prefix:null,infix:null,postfix:null};for(var $ in w.session.__operators)if(w.session.__operators.hasOwnProperty($)){var ie=w.session.__operators[$][J.id];ie&&(e(ie,"fx")!==-1&&(X.prefix={priority:$,type:"fx"}),e(ie,"fy")!==-1&&(X.prefix={priority:$,type:"fy"}),e(ie,"xf")!==-1&&(X.postfix={priority:$,type:"xf"}),e(ie,"yf")!==-1&&(X.postfix={priority:$,type:"yf"}),e(ie,"xfx")!==-1&&(X.infix={priority:$,type:"xfx"}),e(ie,"xfy")!==-1&&(X.infix={priority:$,type:"xfy"}),e(ie,"yfx")!==-1&&(X.infix={priority:$,type:"yfx"}))}var Se;switch(F.id){case"fy":case"fx":Se="prefix";break;case"yf":case"xf":Se="postfix";break;default:Se="infix";break}if(((X.prefix&&Se==="prefix"||X.postfix&&Se==="postfix"||X.infix&&Se==="infix")&&X[Se].type!==F.id||X.infix&&Se==="postfix"||X.postfix&&Se==="infix")&&y.value!==0)w.throw_error(S.error.permission("create","operator",J,b.indicator));else return X[Se]&&(me(w.session.__operators[X[Se].priority][J.id],F.id),w.session.__operators[X[Se].priority][J.id].length===0&&delete w.session.__operators[X[Se].priority][J.id]),y.value>0&&(w.session.__operators[y.value]||(w.session.__operators[y.value.toString()]={}),w.session.__operators[y.value][J.id]||(w.session.__operators[y.value][J.id]=[]),w.session.__operators[y.value][J.id].push(F.id)),!0}}},predicate:{"op/3":function(w,b,y){S.directive["op/3"](w,y)&&w.success(b)},"current_op/3":function(w,b,y){var F=y.args[0],J=y.args[1],X=y.args[2],$=[];for(var ie in w.session.__operators)for(var Se in w.session.__operators[ie])for(var Re=0;Re/2"){var F=w.points,J=w.session.format_success,X=w.session.format_error;w.session.format_success=function(Re){return Re.substitution},w.session.format_error=function(Re){return Re.goal},w.points=[new ke(y.args[0].args[0],b.substitution,b)];var $=function(Re){w.points=F,w.session.format_success=J,w.session.format_error=X,Re===!1?w.prepend([new ke(b.goal.replace(y.args[1]),b.substitution,b)]):S.type.is_error(Re)?w.throw_error(Re.args[0]):Re===null?(w.prepend([b]),w.__calls.shift()(null)):w.prepend([new ke(b.goal.replace(y.args[0].args[1]).apply(Re),b.substitution.apply(Re),b)])};w.__calls.unshift($)}else{var ie=new ke(b.goal.replace(y.args[0]),b.substitution,b),Se=new ke(b.goal.replace(y.args[1]),b.substitution,b);w.prepend([ie,Se])}},"!/0":function(w,b,y){var F,J,X=[];for(F=b,J=null;F.parent!==null&&F.parent.goal.search(y);)if(J=F,F=F.parent,F.goal!==null){var $=F.goal.select();if($&&$.id==="call"&&$.search(y)){F=J;break}}for(var ie=w.points.length-1;ie>=0;ie--){for(var Se=w.points[ie],Re=Se.parent;Re!==null&&Re!==F.parent;)Re=Re.parent;Re===null&&Re!==F.parent&&X.push(Se)}w.points=X.reverse(),w.success(b)},"\\+/1":function(w,b,y){var F=y.args[0];S.type.is_variable(F)?w.throw_error(S.error.instantiation(w.level)):S.type.is_callable(F)?w.prepend([new ke(b.goal.replace(new H(",",[new H(",",[new H("call",[F]),new H("!",[])]),new H("fail",[])])),b.substitution,b),new ke(b.goal.replace(null),b.substitution,b)]):w.throw_error(S.error.type("callable",F,w.level))},"->/2":function(w,b,y){var F=b.goal.replace(new H(",",[y.args[0],new H(",",[new H("!"),y.args[1]])]));w.prepend([new ke(F,b.substitution,b)])},"fail/0":function(w,b,y){},"false/0":function(w,b,y){},"true/0":function(w,b,y){w.success(b)},"call/1":ne(1),"call/2":ne(2),"call/3":ne(3),"call/4":ne(4),"call/5":ne(5),"call/6":ne(6),"call/7":ne(7),"call/8":ne(8),"once/1":function(w,b,y){var F=y.args[0];w.prepend([new ke(b.goal.replace(new H(",",[new H("call",[F]),new H("!",[])])),b.substitution,b)])},"forall/2":function(w,b,y){var F=y.args[0],J=y.args[1];w.prepend([new ke(b.goal.replace(new H("\\+",[new H(",",[new H("call",[F]),new H("\\+",[new H("call",[J])])])])),b.substitution,b)])},"repeat/0":function(w,b,y){w.prepend([new ke(b.goal.replace(null),b.substitution,b),b])},"throw/1":function(w,b,y){S.type.is_variable(y.args[0])?w.throw_error(S.error.instantiation(w.level)):w.throw_error(y.args[0])},"catch/3":function(w,b,y){var F=w.points;w.points=[],w.prepend([new ke(y.args[0],b.substitution,b)]);var J=w.session.format_success,X=w.session.format_error;w.session.format_success=function(ie){return ie.substitution},w.session.format_error=function(ie){return ie.goal};var $=function(ie){var Se=w.points;if(w.points=F,w.session.format_success=J,w.session.format_error=X,S.type.is_error(ie)){for(var Re=[],at=w.points.length-1;at>=0;at--){for(var tr=w.points[at],dt=tr.parent;dt!==null&&dt!==b.parent;)dt=dt.parent;dt===null&&dt!==b.parent&&Re.push(tr)}w.points=Re;var jt=w.get_flag("occurs_check").indicator==="true/0",tr=new ke,bt=S.unify(ie.args[0],y.args[1],jt);bt!==null?(tr.substitution=b.substitution.apply(bt),tr.goal=b.goal.replace(y.args[2]).apply(bt),tr.parent=b,w.prepend([tr])):w.throw_error(ie.args[0])}else if(ie!==!1){for(var ln=ie===null?[]:[new ke(b.goal.apply(ie).replace(null),b.substitution.apply(ie),b)],kr=[],at=Se.length-1;at>=0;at--){kr.push(Se[at]);var mr=Se[at].goal!==null?Se[at].goal.select():null;if(S.type.is_term(mr)&&mr.indicator==="!/0")break}var Sr=o(kr,function(Kr){return Kr.goal===null&&(Kr.goal=new H("true",[])),Kr=new ke(b.goal.replace(new H("catch",[Kr.goal,y.args[1],y.args[2]])),b.substitution.apply(Kr.substitution),Kr.parent),Kr.exclude=y.args[0].variables(),Kr}).reverse();w.prepend(Sr),w.prepend(ln),ie===null&&(this.current_limit=0,w.__calls.shift()(null))}};w.__calls.unshift($)},"=/2":function(w,b,y){var F=w.get_flag("occurs_check").indicator==="true/0",J=new ke,X=S.unify(y.args[0],y.args[1],F);X!==null&&(J.goal=b.goal.apply(X).replace(null),J.substitution=b.substitution.apply(X),J.parent=b,w.prepend([J]))},"unify_with_occurs_check/2":function(w,b,y){var F=new ke,J=S.unify(y.args[0],y.args[1],!0);J!==null&&(F.goal=b.goal.apply(J).replace(null),F.substitution=b.substitution.apply(J),F.parent=b,w.prepend([F]))},"\\=/2":function(w,b,y){var F=w.get_flag("occurs_check").indicator==="true/0",J=S.unify(y.args[0],y.args[1],F);J===null&&w.success(b)},"subsumes_term/2":function(w,b,y){var F=w.get_flag("occurs_check").indicator==="true/0",J=S.unify(y.args[1],y.args[0],F);J!==null&&y.args[1].apply(J).equals(y.args[1])&&w.success(b)},"findall/3":function(w,b,y){var F=y.args[0],J=y.args[1],X=y.args[2];if(S.type.is_variable(J))w.throw_error(S.error.instantiation(y.indicator));else if(!S.type.is_callable(J))w.throw_error(S.error.type("callable",J,y.indicator));else if(!S.type.is_variable(X)&&!S.type.is_list(X))w.throw_error(S.error.type("list",X,y.indicator));else{var $=w.next_free_variable(),ie=new H(",",[J,new H("=",[$,F])]),Se=w.points,Re=w.session.limit,at=w.session.format_success;w.session.format_success=function(tr){return tr.substitution},w.add_goal(ie,!0,b);var dt=[],jt=function(tr){if(tr!==!1&&tr!==null&&!S.type.is_error(tr))w.__calls.unshift(jt),dt.push(tr.links[$.id]),w.session.limit=w.current_limit;else if(w.points=Se,w.session.limit=Re,w.session.format_success=at,S.type.is_error(tr))w.throw_error(tr.args[0]);else if(w.current_limit>0){for(var bt=new H("[]"),ln=dt.length-1;ln>=0;ln--)bt=new H(".",[dt[ln],bt]);w.prepend([new ke(b.goal.replace(new H("=",[X,bt])),b.substitution,b)])}};w.__calls.unshift(jt)}},"bagof/3":function(w,b,y){var F,J=y.args[0],X=y.args[1],$=y.args[2];if(S.type.is_variable(X))w.throw_error(S.error.instantiation(y.indicator));else if(!S.type.is_callable(X))w.throw_error(S.error.type("callable",X,y.indicator));else if(!S.type.is_variable($)&&!S.type.is_list($))w.throw_error(S.error.type("list",$,y.indicator));else{var ie=w.next_free_variable(),Se;X.indicator==="^/2"?(Se=X.args[0].variables(),X=X.args[1]):Se=[],Se=Se.concat(J.variables());for(var Re=X.variables().filter(function(Sr){return e(Se,Sr)===-1}),at=new H("[]"),dt=Re.length-1;dt>=0;dt--)at=new H(".",[new xe(Re[dt]),at]);var jt=new H(",",[X,new H("=",[ie,new H(",",[at,J])])]),tr=w.points,bt=w.session.limit,ln=w.session.format_success;w.session.format_success=function(Sr){return Sr.substitution},w.add_goal(jt,!0,b);var kr=[],mr=function(Sr){if(Sr!==!1&&Sr!==null&&!S.type.is_error(Sr)){w.__calls.unshift(mr);var Kr=!1,Kn=Sr.links[ie.id].args[0],Ms=Sr.links[ie.id].args[1];for(var Ri in kr)if(kr.hasOwnProperty(Ri)){var gs=kr[Ri];if(gs.variables.equals(Kn)){gs.answers.push(Ms),Kr=!0;break}}Kr||kr.push({variables:Kn,answers:[Ms]}),w.session.limit=w.current_limit}else if(w.points=tr,w.session.limit=bt,w.session.format_success=ln,S.type.is_error(Sr))w.throw_error(Sr.args[0]);else if(w.current_limit>0){for(var io=[],Pi=0;Pi=0;so--)Os=new H(".",[Sr[so],Os]);io.push(new ke(b.goal.replace(new H(",",[new H("=",[at,kr[Pi].variables]),new H("=",[$,Os])])),b.substitution,b))}w.prepend(io)}};w.__calls.unshift(mr)}},"setof/3":function(w,b,y){var F,J=y.args[0],X=y.args[1],$=y.args[2];if(S.type.is_variable(X))w.throw_error(S.error.instantiation(y.indicator));else if(!S.type.is_callable(X))w.throw_error(S.error.type("callable",X,y.indicator));else if(!S.type.is_variable($)&&!S.type.is_list($))w.throw_error(S.error.type("list",$,y.indicator));else{var ie=w.next_free_variable(),Se;X.indicator==="^/2"?(Se=X.args[0].variables(),X=X.args[1]):Se=[],Se=Se.concat(J.variables());for(var Re=X.variables().filter(function(Sr){return e(Se,Sr)===-1}),at=new H("[]"),dt=Re.length-1;dt>=0;dt--)at=new H(".",[new xe(Re[dt]),at]);var jt=new H(",",[X,new H("=",[ie,new H(",",[at,J])])]),tr=w.points,bt=w.session.limit,ln=w.session.format_success;w.session.format_success=function(Sr){return Sr.substitution},w.add_goal(jt,!0,b);var kr=[],mr=function(Sr){if(Sr!==!1&&Sr!==null&&!S.type.is_error(Sr)){w.__calls.unshift(mr);var Kr=!1,Kn=Sr.links[ie.id].args[0],Ms=Sr.links[ie.id].args[1];for(var Ri in kr)if(kr.hasOwnProperty(Ri)){var gs=kr[Ri];if(gs.variables.equals(Kn)){gs.answers.push(Ms),Kr=!0;break}}Kr||kr.push({variables:Kn,answers:[Ms]}),w.session.limit=w.current_limit}else if(w.points=tr,w.session.limit=bt,w.session.format_success=ln,S.type.is_error(Sr))w.throw_error(Sr.args[0]);else if(w.current_limit>0){for(var io=[],Pi=0;Pi=0;so--)Os=new H(".",[Sr[so],Os]);io.push(new ke(b.goal.replace(new H(",",[new H("=",[at,kr[Pi].variables]),new H("=",[$,Os])])),b.substitution,b))}w.prepend(io)}};w.__calls.unshift(mr)}},"functor/3":function(w,b,y){var F,J=y.args[0],X=y.args[1],$=y.args[2];if(S.type.is_variable(J)&&(S.type.is_variable(X)||S.type.is_variable($)))w.throw_error(S.error.instantiation("functor/3"));else if(!S.type.is_variable($)&&!S.type.is_integer($))w.throw_error(S.error.type("integer",y.args[2],"functor/3"));else if(!S.type.is_variable(X)&&!S.type.is_atomic(X))w.throw_error(S.error.type("atomic",y.args[1],"functor/3"));else if(S.type.is_integer(X)&&S.type.is_integer($)&&$.value!==0)w.throw_error(S.error.type("atom",y.args[1],"functor/3"));else if(S.type.is_variable(J)){if(y.args[2].value>=0){for(var ie=[],Se=0;Se<$.value;Se++)ie.push(w.next_free_variable());var Re=S.type.is_integer(X)?X:new H(X.id,ie);w.prepend([new ke(b.goal.replace(new H("=",[J,Re])),b.substitution,b)])}}else{var at=S.type.is_integer(J)?J:new H(J.id,[]),dt=S.type.is_integer(J)?new Ne(0,!1):new Ne(J.args.length,!1),jt=new H(",",[new H("=",[at,X]),new H("=",[dt,$])]);w.prepend([new ke(b.goal.replace(jt),b.substitution,b)])}},"arg/3":function(w,b,y){if(S.type.is_variable(y.args[0])||S.type.is_variable(y.args[1]))w.throw_error(S.error.instantiation(y.indicator));else if(y.args[0].value<0)w.throw_error(S.error.domain("not_less_than_zero",y.args[0],y.indicator));else if(!S.type.is_compound(y.args[1]))w.throw_error(S.error.type("compound",y.args[1],y.indicator));else{var F=y.args[0].value;if(F>0&&F<=y.args[1].args.length){var J=new H("=",[y.args[1].args[F-1],y.args[2]]);w.prepend([new ke(b.goal.replace(J),b.substitution,b)])}}},"=../2":function(w,b,y){var F;if(S.type.is_variable(y.args[0])&&(S.type.is_variable(y.args[1])||S.type.is_non_empty_list(y.args[1])&&S.type.is_variable(y.args[1].args[0])))w.throw_error(S.error.instantiation(y.indicator));else if(!S.type.is_fully_list(y.args[1]))w.throw_error(S.error.type("list",y.args[1],y.indicator));else if(S.type.is_variable(y.args[0])){if(!S.type.is_variable(y.args[1])){var X=[];for(F=y.args[1].args[1];F.indicator==="./2";)X.push(F.args[0]),F=F.args[1];S.type.is_variable(y.args[0])&&S.type.is_variable(F)?w.throw_error(S.error.instantiation(y.indicator)):X.length===0&&S.type.is_compound(y.args[1].args[0])?w.throw_error(S.error.type("atomic",y.args[1].args[0],y.indicator)):X.length>0&&(S.type.is_compound(y.args[1].args[0])||S.type.is_number(y.args[1].args[0]))?w.throw_error(S.error.type("atom",y.args[1].args[0],y.indicator)):X.length===0?w.prepend([new ke(b.goal.replace(new H("=",[y.args[1].args[0],y.args[0]],b)),b.substitution,b)]):w.prepend([new ke(b.goal.replace(new H("=",[new H(y.args[1].args[0].id,X),y.args[0]])),b.substitution,b)])}}else{if(S.type.is_atomic(y.args[0]))F=new H(".",[y.args[0],new H("[]")]);else{F=new H("[]");for(var J=y.args[0].args.length-1;J>=0;J--)F=new H(".",[y.args[0].args[J],F]);F=new H(".",[new H(y.args[0].id),F])}w.prepend([new ke(b.goal.replace(new H("=",[F,y.args[1]])),b.substitution,b)])}},"copy_term/2":function(w,b,y){var F=y.args[0].rename(w);w.prepend([new ke(b.goal.replace(new H("=",[F,y.args[1]])),b.substitution,b.parent)])},"term_variables/2":function(w,b,y){var F=y.args[0],J=y.args[1];if(!S.type.is_fully_list(J))w.throw_error(S.error.type("list",J,y.indicator));else{var X=g(o(we(F.variables()),function($){return new xe($)}));w.prepend([new ke(b.goal.replace(new H("=",[J,X])),b.substitution,b)])}},"clause/2":function(w,b,y){if(S.type.is_variable(y.args[0]))w.throw_error(S.error.instantiation(y.indicator));else if(!S.type.is_callable(y.args[0]))w.throw_error(S.error.type("callable",y.args[0],y.indicator));else if(!S.type.is_variable(y.args[1])&&!S.type.is_callable(y.args[1]))w.throw_error(S.error.type("callable",y.args[1],y.indicator));else if(w.session.rules[y.args[0].indicator]!==void 0)if(w.is_public_predicate(y.args[0].indicator)){var F=[];for(var J in w.session.rules[y.args[0].indicator])if(w.session.rules[y.args[0].indicator].hasOwnProperty(J)){var X=w.session.rules[y.args[0].indicator][J];w.session.renamed_variables={},X=X.rename(w),X.body===null&&(X.body=new H("true"));var $=new H(",",[new H("=",[X.head,y.args[0]]),new H("=",[X.body,y.args[1]])]);F.push(new ke(b.goal.replace($),b.substitution,b))}w.prepend(F)}else w.throw_error(S.error.permission("access","private_procedure",y.args[0].indicator,y.indicator))},"current_predicate/1":function(w,b,y){var F=y.args[0];if(!S.type.is_variable(F)&&(!S.type.is_compound(F)||F.indicator!=="//2"))w.throw_error(S.error.type("predicate_indicator",F,y.indicator));else if(!S.type.is_variable(F)&&!S.type.is_variable(F.args[0])&&!S.type.is_atom(F.args[0]))w.throw_error(S.error.type("atom",F.args[0],y.indicator));else if(!S.type.is_variable(F)&&!S.type.is_variable(F.args[1])&&!S.type.is_integer(F.args[1]))w.throw_error(S.error.type("integer",F.args[1],y.indicator));else{var J=[];for(var X in w.session.rules)if(w.session.rules.hasOwnProperty(X)){var $=X.lastIndexOf("/"),ie=X.substr(0,$),Se=parseInt(X.substr($+1,X.length-($+1))),Re=new H("/",[new H(ie),new Ne(Se,!1)]),at=new H("=",[Re,F]);J.push(new ke(b.goal.replace(at),b.substitution,b))}w.prepend(J)}},"asserta/1":function(w,b,y){if(S.type.is_variable(y.args[0]))w.throw_error(S.error.instantiation(y.indicator));else if(!S.type.is_callable(y.args[0]))w.throw_error(S.error.type("callable",y.args[0],y.indicator));else{var F,J;y.args[0].indicator===":-/2"?(F=y.args[0].args[0],J=Ee(y.args[0].args[1])):(F=y.args[0],J=null),S.type.is_callable(F)?J!==null&&!S.type.is_callable(J)?w.throw_error(S.error.type("callable",J,y.indicator)):w.is_public_predicate(F.indicator)?(w.session.rules[F.indicator]===void 0&&(w.session.rules[F.indicator]=[]),w.session.public_predicates[F.indicator]=!0,w.session.rules[F.indicator]=[new Ye(F,J,!0)].concat(w.session.rules[F.indicator]),w.success(b)):w.throw_error(S.error.permission("modify","static_procedure",F.indicator,y.indicator)):w.throw_error(S.error.type("callable",F,y.indicator))}},"assertz/1":function(w,b,y){if(S.type.is_variable(y.args[0]))w.throw_error(S.error.instantiation(y.indicator));else if(!S.type.is_callable(y.args[0]))w.throw_error(S.error.type("callable",y.args[0],y.indicator));else{var F,J;y.args[0].indicator===":-/2"?(F=y.args[0].args[0],J=Ee(y.args[0].args[1])):(F=y.args[0],J=null),S.type.is_callable(F)?J!==null&&!S.type.is_callable(J)?w.throw_error(S.error.type("callable",J,y.indicator)):w.is_public_predicate(F.indicator)?(w.session.rules[F.indicator]===void 0&&(w.session.rules[F.indicator]=[]),w.session.public_predicates[F.indicator]=!0,w.session.rules[F.indicator].push(new Ye(F,J,!0)),w.success(b)):w.throw_error(S.error.permission("modify","static_procedure",F.indicator,y.indicator)):w.throw_error(S.error.type("callable",F,y.indicator))}},"retract/1":function(w,b,y){if(S.type.is_variable(y.args[0]))w.throw_error(S.error.instantiation(y.indicator));else if(!S.type.is_callable(y.args[0]))w.throw_error(S.error.type("callable",y.args[0],y.indicator));else{var F,J;if(y.args[0].indicator===":-/2"?(F=y.args[0].args[0],J=y.args[0].args[1]):(F=y.args[0],J=new H("true")),typeof b.retract>"u")if(w.is_public_predicate(F.indicator)){if(w.session.rules[F.indicator]!==void 0){for(var X=[],$=0;$w.get_flag("max_arity").value)w.throw_error(S.error.representation("max_arity",y.indicator));else{var F=y.args[0].args[0].id+"/"+y.args[0].args[1].value;w.is_public_predicate(F)?(delete w.session.rules[F],w.success(b)):w.throw_error(S.error.permission("modify","static_procedure",F,y.indicator))}},"atom_length/2":function(w,b,y){if(S.type.is_variable(y.args[0]))w.throw_error(S.error.instantiation(y.indicator));else if(!S.type.is_atom(y.args[0]))w.throw_error(S.error.type("atom",y.args[0],y.indicator));else if(!S.type.is_variable(y.args[1])&&!S.type.is_integer(y.args[1]))w.throw_error(S.error.type("integer",y.args[1],y.indicator));else if(S.type.is_integer(y.args[1])&&y.args[1].value<0)w.throw_error(S.error.domain("not_less_than_zero",y.args[1],y.indicator));else{var F=new Ne(y.args[0].id.length,!1);w.prepend([new ke(b.goal.replace(new H("=",[F,y.args[1]])),b.substitution,b)])}},"atom_concat/3":function(w,b,y){var F,J,X=y.args[0],$=y.args[1],ie=y.args[2];if(S.type.is_variable(ie)&&(S.type.is_variable(X)||S.type.is_variable($)))w.throw_error(S.error.instantiation(y.indicator));else if(!S.type.is_variable(X)&&!S.type.is_atom(X))w.throw_error(S.error.type("atom",X,y.indicator));else if(!S.type.is_variable($)&&!S.type.is_atom($))w.throw_error(S.error.type("atom",$,y.indicator));else if(!S.type.is_variable(ie)&&!S.type.is_atom(ie))w.throw_error(S.error.type("atom",ie,y.indicator));else{var Se=S.type.is_variable(X),Re=S.type.is_variable($);if(!Se&&!Re)J=new H("=",[ie,new H(X.id+$.id)]),w.prepend([new ke(b.goal.replace(J),b.substitution,b)]);else if(Se&&!Re)F=ie.id.substr(0,ie.id.length-$.id.length),F+$.id===ie.id&&(J=new H("=",[X,new H(F)]),w.prepend([new ke(b.goal.replace(J),b.substitution,b)]));else if(Re&&!Se)F=ie.id.substr(X.id.length),X.id+F===ie.id&&(J=new H("=",[$,new H(F)]),w.prepend([new ke(b.goal.replace(J),b.substitution,b)]));else{for(var at=[],dt=0;dt<=ie.id.length;dt++){var jt=new H(ie.id.substr(0,dt)),tr=new H(ie.id.substr(dt));J=new H(",",[new H("=",[jt,X]),new H("=",[tr,$])]),at.push(new ke(b.goal.replace(J),b.substitution,b))}w.prepend(at)}}},"sub_atom/5":function(w,b,y){var F,J=y.args[0],X=y.args[1],$=y.args[2],ie=y.args[3],Se=y.args[4];if(S.type.is_variable(J))w.throw_error(S.error.instantiation(y.indicator));else if(!S.type.is_variable(X)&&!S.type.is_integer(X))w.throw_error(S.error.type("integer",X,y.indicator));else if(!S.type.is_variable($)&&!S.type.is_integer($))w.throw_error(S.error.type("integer",$,y.indicator));else if(!S.type.is_variable(ie)&&!S.type.is_integer(ie))w.throw_error(S.error.type("integer",ie,y.indicator));else if(S.type.is_integer(X)&&X.value<0)w.throw_error(S.error.domain("not_less_than_zero",X,y.indicator));else if(S.type.is_integer($)&&$.value<0)w.throw_error(S.error.domain("not_less_than_zero",$,y.indicator));else if(S.type.is_integer(ie)&&ie.value<0)w.throw_error(S.error.domain("not_less_than_zero",ie,y.indicator));else{var Re=[],at=[],dt=[];if(S.type.is_variable(X))for(F=0;F<=J.id.length;F++)Re.push(F);else Re.push(X.value);if(S.type.is_variable($))for(F=0;F<=J.id.length;F++)at.push(F);else at.push($.value);if(S.type.is_variable(ie))for(F=0;F<=J.id.length;F++)dt.push(F);else dt.push(ie.value);var jt=[];for(var tr in Re)if(Re.hasOwnProperty(tr)){F=Re[tr];for(var bt in at)if(at.hasOwnProperty(bt)){var ln=at[bt],kr=J.id.length-F-ln;if(e(dt,kr)!==-1&&F+ln+kr===J.id.length){var mr=J.id.substr(F,ln);if(J.id===J.id.substr(0,F)+mr+J.id.substr(F+ln,kr)){var Sr=new H("=",[new H(mr),Se]),Kr=new H("=",[X,new Ne(F)]),Kn=new H("=",[$,new Ne(ln)]),Ms=new H("=",[ie,new Ne(kr)]),Ri=new H(",",[new H(",",[new H(",",[Kr,Kn]),Ms]),Sr]);jt.push(new ke(b.goal.replace(Ri),b.substitution,b))}}}}w.prepend(jt)}},"atom_chars/2":function(w,b,y){var F=y.args[0],J=y.args[1];if(S.type.is_variable(F)&&S.type.is_variable(J))w.throw_error(S.error.instantiation(y.indicator));else if(!S.type.is_variable(F)&&!S.type.is_atom(F))w.throw_error(S.error.type("atom",F,y.indicator));else if(S.type.is_variable(F)){for(var ie=J,Se=S.type.is_variable(F),Re="";ie.indicator==="./2";){if(S.type.is_character(ie.args[0]))Re+=ie.args[0].id;else if(S.type.is_variable(ie.args[0])&&Se){w.throw_error(S.error.instantiation(y.indicator));return}else if(!S.type.is_variable(ie.args[0])){w.throw_error(S.error.type("character",ie.args[0],y.indicator));return}ie=ie.args[1]}S.type.is_variable(ie)&&Se?w.throw_error(S.error.instantiation(y.indicator)):!S.type.is_empty_list(ie)&&!S.type.is_variable(ie)?w.throw_error(S.error.type("list",J,y.indicator)):w.prepend([new ke(b.goal.replace(new H("=",[new H(Re),F])),b.substitution,b)])}else{for(var X=new H("[]"),$=F.id.length-1;$>=0;$--)X=new H(".",[new H(F.id.charAt($)),X]);w.prepend([new ke(b.goal.replace(new H("=",[J,X])),b.substitution,b)])}},"atom_codes/2":function(w,b,y){var F=y.args[0],J=y.args[1];if(S.type.is_variable(F)&&S.type.is_variable(J))w.throw_error(S.error.instantiation(y.indicator));else if(!S.type.is_variable(F)&&!S.type.is_atom(F))w.throw_error(S.error.type("atom",F,y.indicator));else if(S.type.is_variable(F)){for(var ie=J,Se=S.type.is_variable(F),Re="";ie.indicator==="./2";){if(S.type.is_character_code(ie.args[0]))Re+=u(ie.args[0].value);else if(S.type.is_variable(ie.args[0])&&Se){w.throw_error(S.error.instantiation(y.indicator));return}else if(!S.type.is_variable(ie.args[0])){w.throw_error(S.error.representation("character_code",y.indicator));return}ie=ie.args[1]}S.type.is_variable(ie)&&Se?w.throw_error(S.error.instantiation(y.indicator)):!S.type.is_empty_list(ie)&&!S.type.is_variable(ie)?w.throw_error(S.error.type("list",J,y.indicator)):w.prepend([new ke(b.goal.replace(new H("=",[new H(Re),F])),b.substitution,b)])}else{for(var X=new H("[]"),$=F.id.length-1;$>=0;$--)X=new H(".",[new Ne(n(F.id,$),!1),X]);w.prepend([new ke(b.goal.replace(new H("=",[J,X])),b.substitution,b)])}},"char_code/2":function(w,b,y){var F=y.args[0],J=y.args[1];if(S.type.is_variable(F)&&S.type.is_variable(J))w.throw_error(S.error.instantiation(y.indicator));else if(!S.type.is_variable(F)&&!S.type.is_character(F))w.throw_error(S.error.type("character",F,y.indicator));else if(!S.type.is_variable(J)&&!S.type.is_integer(J))w.throw_error(S.error.type("integer",J,y.indicator));else if(!S.type.is_variable(J)&&!S.type.is_character_code(J))w.throw_error(S.error.representation("character_code",y.indicator));else if(S.type.is_variable(J)){var X=new Ne(n(F.id,0),!1);w.prepend([new ke(b.goal.replace(new H("=",[X,J])),b.substitution,b)])}else{var $=new H(u(J.value));w.prepend([new ke(b.goal.replace(new H("=",[$,F])),b.substitution,b)])}},"number_chars/2":function(w,b,y){var F,J=y.args[0],X=y.args[1];if(S.type.is_variable(J)&&S.type.is_variable(X))w.throw_error(S.error.instantiation(y.indicator));else if(!S.type.is_variable(J)&&!S.type.is_number(J))w.throw_error(S.error.type("number",J,y.indicator));else if(!S.type.is_variable(X)&&!S.type.is_list(X))w.throw_error(S.error.type("list",X,y.indicator));else{var $=S.type.is_variable(J);if(!S.type.is_variable(X)){var ie=X,Se=!0;for(F="";ie.indicator==="./2";){if(S.type.is_character(ie.args[0]))F+=ie.args[0].id;else if(S.type.is_variable(ie.args[0]))Se=!1;else if(!S.type.is_variable(ie.args[0])){w.throw_error(S.error.type("character",ie.args[0],y.indicator));return}ie=ie.args[1]}if(Se=Se&&S.type.is_empty_list(ie),!S.type.is_empty_list(ie)&&!S.type.is_variable(ie)){w.throw_error(S.error.type("list",X,y.indicator));return}if(!Se&&$){w.throw_error(S.error.instantiation(y.indicator));return}else if(Se)if(S.type.is_variable(ie)&&$){w.throw_error(S.error.instantiation(y.indicator));return}else{var Re=w.parse(F),at=Re.value;!S.type.is_number(at)||Re.tokens[Re.tokens.length-1].space?w.throw_error(S.error.syntax_by_predicate("parseable_number",y.indicator)):w.prepend([new ke(b.goal.replace(new H("=",[J,at])),b.substitution,b)]);return}}if(!$){F=J.toString();for(var dt=new H("[]"),jt=F.length-1;jt>=0;jt--)dt=new H(".",[new H(F.charAt(jt)),dt]);w.prepend([new ke(b.goal.replace(new H("=",[X,dt])),b.substitution,b)])}}},"number_codes/2":function(w,b,y){var F,J=y.args[0],X=y.args[1];if(S.type.is_variable(J)&&S.type.is_variable(X))w.throw_error(S.error.instantiation(y.indicator));else if(!S.type.is_variable(J)&&!S.type.is_number(J))w.throw_error(S.error.type("number",J,y.indicator));else if(!S.type.is_variable(X)&&!S.type.is_list(X))w.throw_error(S.error.type("list",X,y.indicator));else{var $=S.type.is_variable(J);if(!S.type.is_variable(X)){var ie=X,Se=!0;for(F="";ie.indicator==="./2";){if(S.type.is_character_code(ie.args[0]))F+=u(ie.args[0].value);else if(S.type.is_variable(ie.args[0]))Se=!1;else if(!S.type.is_variable(ie.args[0])){w.throw_error(S.error.type("character_code",ie.args[0],y.indicator));return}ie=ie.args[1]}if(Se=Se&&S.type.is_empty_list(ie),!S.type.is_empty_list(ie)&&!S.type.is_variable(ie)){w.throw_error(S.error.type("list",X,y.indicator));return}if(!Se&&$){w.throw_error(S.error.instantiation(y.indicator));return}else if(Se)if(S.type.is_variable(ie)&&$){w.throw_error(S.error.instantiation(y.indicator));return}else{var Re=w.parse(F),at=Re.value;!S.type.is_number(at)||Re.tokens[Re.tokens.length-1].space?w.throw_error(S.error.syntax_by_predicate("parseable_number",y.indicator)):w.prepend([new ke(b.goal.replace(new H("=",[J,at])),b.substitution,b)]);return}}if(!$){F=J.toString();for(var dt=new H("[]"),jt=F.length-1;jt>=0;jt--)dt=new H(".",[new Ne(n(F,jt),!1),dt]);w.prepend([new ke(b.goal.replace(new H("=",[X,dt])),b.substitution,b)])}}},"upcase_atom/2":function(w,b,y){var F=y.args[0],J=y.args[1];S.type.is_variable(F)?w.throw_error(S.error.instantiation(y.indicator)):S.type.is_atom(F)?!S.type.is_variable(J)&&!S.type.is_atom(J)?w.throw_error(S.error.type("atom",J,y.indicator)):w.prepend([new ke(b.goal.replace(new H("=",[J,new H(F.id.toUpperCase(),[])])),b.substitution,b)]):w.throw_error(S.error.type("atom",F,y.indicator))},"downcase_atom/2":function(w,b,y){var F=y.args[0],J=y.args[1];S.type.is_variable(F)?w.throw_error(S.error.instantiation(y.indicator)):S.type.is_atom(F)?!S.type.is_variable(J)&&!S.type.is_atom(J)?w.throw_error(S.error.type("atom",J,y.indicator)):w.prepend([new ke(b.goal.replace(new H("=",[J,new H(F.id.toLowerCase(),[])])),b.substitution,b)]):w.throw_error(S.error.type("atom",F,y.indicator))},"atomic_list_concat/2":function(w,b,y){var F=y.args[0],J=y.args[1];w.prepend([new ke(b.goal.replace(new H("atomic_list_concat",[F,new H("",[]),J])),b.substitution,b)])},"atomic_list_concat/3":function(w,b,y){var F=y.args[0],J=y.args[1],X=y.args[2];if(S.type.is_variable(J)||S.type.is_variable(F)&&S.type.is_variable(X))w.throw_error(S.error.instantiation(y.indicator));else if(!S.type.is_variable(F)&&!S.type.is_list(F))w.throw_error(S.error.type("list",F,y.indicator));else if(!S.type.is_variable(X)&&!S.type.is_atom(X))w.throw_error(S.error.type("atom",X,y.indicator));else if(S.type.is_variable(X)){for(var ie="",Se=F;S.type.is_term(Se)&&Se.indicator==="./2";){if(!S.type.is_atom(Se.args[0])&&!S.type.is_number(Se.args[0])){w.throw_error(S.error.type("atomic",Se.args[0],y.indicator));return}ie!==""&&(ie+=J.id),S.type.is_atom(Se.args[0])?ie+=Se.args[0].id:ie+=""+Se.args[0].value,Se=Se.args[1]}ie=new H(ie,[]),S.type.is_variable(Se)?w.throw_error(S.error.instantiation(y.indicator)):!S.type.is_term(Se)||Se.indicator!=="[]/0"?w.throw_error(S.error.type("list",F,y.indicator)):w.prepend([new ke(b.goal.replace(new H("=",[ie,X])),b.substitution,b)])}else{var $=g(o(X.id.split(J.id),function(Re){return new H(Re,[])}));w.prepend([new ke(b.goal.replace(new H("=",[$,F])),b.substitution,b)])}},"@=/2":function(w,b,y){S.compare(y.args[0],y.args[1])>0&&w.success(b)},"@>=/2":function(w,b,y){S.compare(y.args[0],y.args[1])>=0&&w.success(b)},"compare/3":function(w,b,y){var F=y.args[0],J=y.args[1],X=y.args[2];if(!S.type.is_variable(F)&&!S.type.is_atom(F))w.throw_error(S.error.type("atom",F,y.indicator));else if(S.type.is_atom(F)&&["<",">","="].indexOf(F.id)===-1)w.throw_error(S.type.domain("order",F,y.indicator));else{var $=S.compare(J,X);$=$===0?"=":$===-1?"<":">",w.prepend([new ke(b.goal.replace(new H("=",[F,new H($,[])])),b.substitution,b)])}},"is/2":function(w,b,y){var F=y.args[1].interpret(w);S.type.is_number(F)?w.prepend([new ke(b.goal.replace(new H("=",[y.args[0],F],w.level)),b.substitution,b)]):w.throw_error(F)},"between/3":function(w,b,y){var F=y.args[0],J=y.args[1],X=y.args[2];if(S.type.is_variable(F)||S.type.is_variable(J))w.throw_error(S.error.instantiation(y.indicator));else if(!S.type.is_integer(F))w.throw_error(S.error.type("integer",F,y.indicator));else if(!S.type.is_integer(J))w.throw_error(S.error.type("integer",J,y.indicator));else if(!S.type.is_variable(X)&&!S.type.is_integer(X))w.throw_error(S.error.type("integer",X,y.indicator));else if(S.type.is_variable(X)){var $=[new ke(b.goal.replace(new H("=",[X,F])),b.substitution,b)];F.value=X.value&&w.success(b)},"succ/2":function(w,b,y){var F=y.args[0],J=y.args[1];S.type.is_variable(F)&&S.type.is_variable(J)?w.throw_error(S.error.instantiation(y.indicator)):!S.type.is_variable(F)&&!S.type.is_integer(F)?w.throw_error(S.error.type("integer",F,y.indicator)):!S.type.is_variable(J)&&!S.type.is_integer(J)?w.throw_error(S.error.type("integer",J,y.indicator)):!S.type.is_variable(F)&&F.value<0?w.throw_error(S.error.domain("not_less_than_zero",F,y.indicator)):!S.type.is_variable(J)&&J.value<0?w.throw_error(S.error.domain("not_less_than_zero",J,y.indicator)):(S.type.is_variable(J)||J.value>0)&&(S.type.is_variable(F)?w.prepend([new ke(b.goal.replace(new H("=",[F,new Ne(J.value-1,!1)])),b.substitution,b)]):w.prepend([new ke(b.goal.replace(new H("=",[J,new Ne(F.value+1,!1)])),b.substitution,b)]))},"=:=/2":function(w,b,y){var F=S.arithmetic_compare(w,y.args[0],y.args[1]);S.type.is_term(F)?w.throw_error(F):F===0&&w.success(b)},"=\\=/2":function(w,b,y){var F=S.arithmetic_compare(w,y.args[0],y.args[1]);S.type.is_term(F)?w.throw_error(F):F!==0&&w.success(b)},"/2":function(w,b,y){var F=S.arithmetic_compare(w,y.args[0],y.args[1]);S.type.is_term(F)?w.throw_error(F):F>0&&w.success(b)},">=/2":function(w,b,y){var F=S.arithmetic_compare(w,y.args[0],y.args[1]);S.type.is_term(F)?w.throw_error(F):F>=0&&w.success(b)},"var/1":function(w,b,y){S.type.is_variable(y.args[0])&&w.success(b)},"atom/1":function(w,b,y){S.type.is_atom(y.args[0])&&w.success(b)},"atomic/1":function(w,b,y){S.type.is_atomic(y.args[0])&&w.success(b)},"compound/1":function(w,b,y){S.type.is_compound(y.args[0])&&w.success(b)},"integer/1":function(w,b,y){S.type.is_integer(y.args[0])&&w.success(b)},"float/1":function(w,b,y){S.type.is_float(y.args[0])&&w.success(b)},"number/1":function(w,b,y){S.type.is_number(y.args[0])&&w.success(b)},"nonvar/1":function(w,b,y){S.type.is_variable(y.args[0])||w.success(b)},"ground/1":function(w,b,y){y.variables().length===0&&w.success(b)},"acyclic_term/1":function(w,b,y){for(var F=b.substitution.apply(b.substitution),J=y.args[0].variables(),X=0;X0?bt[bt.length-1]:null,bt!==null&&(jt=z(w,bt,0,w.__get_max_priority(),!1))}if(jt.type===p&&jt.len===bt.length-1&&ln.value==="."){jt=jt.value.rename(w);var kr=new H("=",[J,jt]);if(ie.variables){var mr=g(o(we(jt.variables()),function(Sr){return new xe(Sr)}));kr=new H(",",[kr,new H("=",[ie.variables,mr])])}if(ie.variable_names){var mr=g(o(we(jt.variables()),function(Kr){var Kn;for(Kn in w.session.renamed_variables)if(w.session.renamed_variables.hasOwnProperty(Kn)&&w.session.renamed_variables[Kn]===Kr)break;return new H("=",[new H(Kn,[]),new xe(Kr)])}));kr=new H(",",[kr,new H("=",[ie.variable_names,mr])])}if(ie.singletons){var mr=g(o(new Ye(jt,null).singleton_variables(),function(Kr){var Kn;for(Kn in w.session.renamed_variables)if(w.session.renamed_variables.hasOwnProperty(Kn)&&w.session.renamed_variables[Kn]===Kr)break;return new H("=",[new H(Kn,[]),new xe(Kr)])}));kr=new H(",",[kr,new H("=",[ie.singletons,mr])])}w.prepend([new ke(b.goal.replace(kr),b.substitution,b)])}else jt.type===p?w.throw_error(S.error.syntax(bt[jt.len],"unexpected token",!1)):w.throw_error(jt.value)}}},"write/1":function(w,b,y){var F=y.args[0];w.prepend([new ke(b.goal.replace(new H(",",[new H("current_output",[new xe("S")]),new H("write",[new xe("S"),F])])),b.substitution,b)])},"write/2":function(w,b,y){var F=y.args[0],J=y.args[1];w.prepend([new ke(b.goal.replace(new H("write_term",[F,J,new H(".",[new H("quoted",[new H("false",[])]),new H(".",[new H("ignore_ops",[new H("false")]),new H(".",[new H("numbervars",[new H("true")]),new H("[]",[])])])])])),b.substitution,b)])},"writeq/1":function(w,b,y){var F=y.args[0];w.prepend([new ke(b.goal.replace(new H(",",[new H("current_output",[new xe("S")]),new H("writeq",[new xe("S"),F])])),b.substitution,b)])},"writeq/2":function(w,b,y){var F=y.args[0],J=y.args[1];w.prepend([new ke(b.goal.replace(new H("write_term",[F,J,new H(".",[new H("quoted",[new H("true",[])]),new H(".",[new H("ignore_ops",[new H("false")]),new H(".",[new H("numbervars",[new H("true")]),new H("[]",[])])])])])),b.substitution,b)])},"write_canonical/1":function(w,b,y){var F=y.args[0];w.prepend([new ke(b.goal.replace(new H(",",[new H("current_output",[new xe("S")]),new H("write_canonical",[new xe("S"),F])])),b.substitution,b)])},"write_canonical/2":function(w,b,y){var F=y.args[0],J=y.args[1];w.prepend([new ke(b.goal.replace(new H("write_term",[F,J,new H(".",[new H("quoted",[new H("true",[])]),new H(".",[new H("ignore_ops",[new H("true")]),new H(".",[new H("numbervars",[new H("false")]),new H("[]",[])])])])])),b.substitution,b)])},"write_term/2":function(w,b,y){var F=y.args[0],J=y.args[1];w.prepend([new ke(b.goal.replace(new H(",",[new H("current_output",[new xe("S")]),new H("write_term",[new xe("S"),F,J])])),b.substitution,b)])},"write_term/3":function(w,b,y){var F=y.args[0],J=y.args[1],X=y.args[2],$=S.type.is_stream(F)?F:w.get_stream_by_alias(F.id);if(S.type.is_variable(F)||S.type.is_variable(X))w.throw_error(S.error.instantiation(y.indicator));else if(!S.type.is_list(X))w.throw_error(S.error.type("list",X,y.indicator));else if(!S.type.is_stream(F)&&!S.type.is_atom(F))w.throw_error(S.error.domain("stream_or_alias",F,y.indicator));else if(!S.type.is_stream($)||$.stream===null)w.throw_error(S.error.existence("stream",F,y.indicator));else if($.input)w.throw_error(S.error.permission("output","stream",F,y.indicator));else if($.type==="binary")w.throw_error(S.error.permission("output","binary_stream",F,y.indicator));else if($.position==="past_end_of_stream"&&$.eof_action==="error")w.throw_error(S.error.permission("output","past_end_of_stream",F,y.indicator));else{for(var ie={},Se=X,Re;S.type.is_term(Se)&&Se.indicator==="./2";){if(Re=Se.args[0],S.type.is_variable(Re)){w.throw_error(S.error.instantiation(y.indicator));return}else if(!S.type.is_write_option(Re)){w.throw_error(S.error.domain("write_option",Re,y.indicator));return}ie[Re.id]=Re.args[0].id==="true",Se=Se.args[1]}if(Se.indicator!=="[]/0"){S.type.is_variable(Se)?w.throw_error(S.error.instantiation(y.indicator)):w.throw_error(S.error.type("list",X,y.indicator));return}else{ie.session=w.session;var at=J.toString(ie);$.stream.put(at,$.position),typeof $.position=="number"&&($.position+=at.length),w.success(b)}}},"halt/0":function(w,b,y){w.points=[]},"halt/1":function(w,b,y){var F=y.args[0];S.type.is_variable(F)?w.throw_error(S.error.instantiation(y.indicator)):S.type.is_integer(F)?w.points=[]:w.throw_error(S.error.type("integer",F,y.indicator))},"current_prolog_flag/2":function(w,b,y){var F=y.args[0],J=y.args[1];if(!S.type.is_variable(F)&&!S.type.is_atom(F))w.throw_error(S.error.type("atom",F,y.indicator));else if(!S.type.is_variable(F)&&!S.type.is_flag(F))w.throw_error(S.error.domain("prolog_flag",F,y.indicator));else{var X=[];for(var $ in S.flag)if(S.flag.hasOwnProperty($)){var ie=new H(",",[new H("=",[new H($),F]),new H("=",[w.get_flag($),J])]);X.push(new ke(b.goal.replace(ie),b.substitution,b))}w.prepend(X)}},"set_prolog_flag/2":function(w,b,y){var F=y.args[0],J=y.args[1];S.type.is_variable(F)||S.type.is_variable(J)?w.throw_error(S.error.instantiation(y.indicator)):S.type.is_atom(F)?S.type.is_flag(F)?S.type.is_value_flag(F,J)?S.type.is_modifiable_flag(F)?(w.session.flag[F.id]=J,w.success(b)):w.throw_error(S.error.permission("modify","flag",F)):w.throw_error(S.error.domain("flag_value",new H("+",[F,J]),y.indicator)):w.throw_error(S.error.domain("prolog_flag",F,y.indicator)):w.throw_error(S.error.type("atom",F,y.indicator))}},flag:{bounded:{allowed:[new H("true"),new H("false")],value:new H("true"),changeable:!1},max_integer:{allowed:[new Ne(Number.MAX_SAFE_INTEGER)],value:new Ne(Number.MAX_SAFE_INTEGER),changeable:!1},min_integer:{allowed:[new Ne(Number.MIN_SAFE_INTEGER)],value:new Ne(Number.MIN_SAFE_INTEGER),changeable:!1},integer_rounding_function:{allowed:[new H("down"),new H("toward_zero")],value:new H("toward_zero"),changeable:!1},char_conversion:{allowed:[new H("on"),new H("off")],value:new H("on"),changeable:!0},debug:{allowed:[new H("on"),new H("off")],value:new H("off"),changeable:!0},max_arity:{allowed:[new H("unbounded")],value:new H("unbounded"),changeable:!1},unknown:{allowed:[new H("error"),new H("fail"),new H("warning")],value:new H("error"),changeable:!0},double_quotes:{allowed:[new H("chars"),new H("codes"),new H("atom")],value:new H("codes"),changeable:!0},occurs_check:{allowed:[new H("false"),new H("true")],value:new H("false"),changeable:!0},dialect:{allowed:[new H("tau")],value:new H("tau"),changeable:!1},version_data:{allowed:[new H("tau",[new Ne(t.major,!1),new Ne(t.minor,!1),new Ne(t.patch,!1),new H(t.status)])],value:new H("tau",[new Ne(t.major,!1),new Ne(t.minor,!1),new Ne(t.patch,!1),new H(t.status)]),changeable:!1},nodejs:{allowed:[new H("yes"),new H("no")],value:new H(typeof gl<"u"&&gl.exports?"yes":"no"),changeable:!1}},unify:function(w,b,y){y=y===void 0?!1:y;for(var F=[{left:w,right:b}],J={};F.length!==0;){var X=F.pop();if(w=X.left,b=X.right,S.type.is_term(w)&&S.type.is_term(b)){if(w.indicator!==b.indicator)return null;for(var $=0;$J.value?1:0:J}else return F},operate:function(w,b){if(S.type.is_operator(b)){for(var y=S.type.is_operator(b),F=[],J,X=!1,$=0;$w.get_flag("max_integer").value||J0?w.start+w.matches[0].length:w.start,J=y?new H("token_not_found"):new H("found",[new H(w.value.toString())]),X=new H(".",[new H("line",[new Ne(w.line+1)]),new H(".",[new H("column",[new Ne(F+1)]),new H(".",[J,new H("[]",[])])])]);return new H("error",[new H("syntax_error",[new H(b)]),X])},syntax_by_predicate:function(w,b){return new H("error",[new H("syntax_error",[new H(w)]),Z(b)])}},warning:{singleton:function(w,b,y){for(var F=new H("[]"),J=w.length-1;J>=0;J--)F=new H(".",[new xe(w[J]),F]);return new H("warning",[new H("singleton_variables",[F,Z(b)]),new H(".",[new H("line",[new Ne(y,!1)]),new H("[]")])])},failed_goal:function(w,b){return new H("warning",[new H("failed_goal",[w]),new H(".",[new H("line",[new Ne(b,!1)]),new H("[]")])])}},format_variable:function(w){return"_"+w},format_answer:function(w,b,F){b instanceof be&&(b=b.thread);var F=F||{};if(F.session=b?b.session:void 0,S.type.is_error(w))return"uncaught exception: "+w.args[0].toString();if(w===!1)return"false.";if(w===null)return"limit exceeded ;";var J=0,X="";if(S.type.is_substitution(w)){var $=w.domain(!0);w=w.filter(function(Re,at){return!S.type.is_variable(at)||$.indexOf(at.id)!==-1&&Re!==at.id})}for(var ie in w.links)w.links.hasOwnProperty(ie)&&(J++,X!==""&&(X+=", "),X+=ie.toString(F)+" = "+w.links[ie].toString(F));var Se=typeof b>"u"||b.points.length>0?" ;":".";return J===0?"true"+Se:X+Se},flatten_error:function(w){if(!S.type.is_error(w))return null;w=w.args[0];var b={};return b.type=w.args[0].id,b.thrown=b.type==="syntax_error"?null:w.args[1].id,b.expected=null,b.found=null,b.representation=null,b.existence=null,b.existence_type=null,b.line=null,b.column=null,b.permission_operation=null,b.permission_type=null,b.evaluation_type=null,b.type==="type_error"||b.type==="domain_error"?(b.expected=w.args[0].args[0].id,b.found=w.args[0].args[1].toString()):b.type==="syntax_error"?w.args[1].indicator==="./2"?(b.expected=w.args[0].args[0].id,b.found=w.args[1].args[1].args[1].args[0],b.found=b.found.id==="token_not_found"?b.found.id:b.found.args[0].id,b.line=w.args[1].args[0].args[0].value,b.column=w.args[1].args[1].args[0].args[0].value):b.thrown=w.args[1].id:b.type==="permission_error"?(b.found=w.args[0].args[2].toString(),b.permission_operation=w.args[0].args[0].id,b.permission_type=w.args[0].args[1].id):b.type==="evaluation_error"?b.evaluation_type=w.args[0].args[0].id:b.type==="representation_error"?b.representation=w.args[0].args[0].id:b.type==="existence_error"&&(b.existence=w.args[0].args[1].toString(),b.existence_type=w.args[0].args[0].id),b},create:function(w){return new S.type.Session(w)}};typeof gl<"u"?gl.exports=S:window.pl=S})()});function cme(t,e,r){t.prepend(r.map(o=>new La.default.type.State(e.goal.replace(o),e.substitution,e)))}function fH(t){let e=Ame.get(t.session);if(e==null)throw new Error("Assertion failed: A project should have been registered for the active session");return e}function fme(t,e){Ame.set(t,e),t.consult(`:- use_module(library(${rdt.id})).`)}var pH,La,ume,Qh,edt,tdt,Ame,rdt,pme=Et(()=>{Ge();pH=Ze(e2()),La=Ze(AH()),ume=Ze(ve("vm")),{is_atom:Qh,is_variable:edt,is_instantiated_list:tdt}=La.default.type;Ame=new WeakMap;rdt=new La.default.type.Module("constraints",{"project_workspaces_by_descriptor/3":(t,e,r)=>{let[o,a,n]=r.args;if(!Qh(o)||!Qh(a)){t.throw_error(La.default.error.instantiation(r.indicator));return}let u=G.parseIdent(o.id),A=G.makeDescriptor(u,a.id),h=fH(t).tryWorkspaceByDescriptor(A);edt(n)&&h!==null&&cme(t,e,[new La.default.type.Term("=",[n,new La.default.type.Term(String(h.relativeCwd))])]),Qh(n)&&h!==null&&h.relativeCwd===n.id&&t.success(e)},"workspace_field/3":(t,e,r)=>{let[o,a,n]=r.args;if(!Qh(o)||!Qh(a)){t.throw_error(La.default.error.instantiation(r.indicator));return}let A=fH(t).tryWorkspaceByCwd(o.id);if(A==null)return;let p=(0,pH.default)(A.manifest.raw,a.id);typeof p>"u"||cme(t,e,[new La.default.type.Term("=",[n,new La.default.type.Term(typeof p=="object"?JSON.stringify(p):p)])])},"workspace_field_test/3":(t,e,r)=>{let[o,a,n]=r.args;t.prepend([new La.default.type.State(e.goal.replace(new La.default.type.Term("workspace_field_test",[o,a,n,new La.default.type.Term("[]",[])])),e.substitution,e)])},"workspace_field_test/4":(t,e,r)=>{let[o,a,n,u]=r.args;if(!Qh(o)||!Qh(a)||!Qh(n)||!tdt(u)){t.throw_error(La.default.error.instantiation(r.indicator));return}let p=fH(t).tryWorkspaceByCwd(o.id);if(p==null)return;let h=(0,pH.default)(p.manifest.raw,a.id);if(typeof h>"u")return;let E={$$:h};for(let[v,x]of u.toJavaScript().entries())E[`$${v}`]=x;ume.default.runInNewContext(n.id,E)&&t.success(e)}},["project_workspaces_by_descriptor/3","workspace_field/3","workspace_field_test/3","workspace_field_test/4"])});var A2={};Vt(A2,{Constraints:()=>gH,DependencyType:()=>mme});function to(t){if(t instanceof NE.default.type.Num)return t.value;if(t instanceof NE.default.type.Term)switch(t.indicator){case"throw/1":return to(t.args[0]);case"error/1":return to(t.args[0]);case"error/2":if(t.args[0]instanceof NE.default.type.Term&&t.args[0].indicator==="syntax_error/1")return Object.assign(to(t.args[0]),...to(t.args[1]));{let e=to(t.args[0]);return e.message+=` (in ${to(t.args[1])})`,e}case"syntax_error/1":return new Jt(43,`Syntax error: ${to(t.args[0])}`);case"existence_error/2":return new Jt(44,`Existence error: ${to(t.args[0])} ${to(t.args[1])} not found`);case"instantiation_error/0":return new Jt(75,"Instantiation error: an argument is variable when an instantiated argument was expected");case"line/1":return{line:to(t.args[0])};case"column/1":return{column:to(t.args[0])};case"found/1":return{found:to(t.args[0])};case"./2":return[to(t.args[0])].concat(to(t.args[1]));case"//2":return`${to(t.args[0])}/${to(t.args[1])}`;default:return t.id}throw`couldn't pretty print because of unsupported node ${t}`}function gme(t){let e;try{e=to(t)}catch(r){throw typeof r=="string"?new Jt(42,`Unknown error: ${t} (note: ${r})`):r}return typeof e.line<"u"&&typeof e.column<"u"&&(e.message+=` at line ${e.line}, column ${e.column}`),e}function Gg(t){return t.id==="null"?null:`${t.toJavaScript()}`}function ndt(t){if(t.id==="null")return null;{let e=t.toJavaScript();if(typeof e!="string")return JSON.stringify(e);try{return JSON.stringify(JSON.parse(e))}catch{return JSON.stringify(e)}}}function Fh(t){return typeof t=="string"?`'${t}'`:"[]"}var dme,NE,mme,hme,hH,gH,f2=Et(()=>{Ge();Ge();Pt();dme=Ze(Kde()),NE=Ze(AH());l2();pme();(0,dme.default)(NE.default);mme=(o=>(o.Dependencies="dependencies",o.DevDependencies="devDependencies",o.PeerDependencies="peerDependencies",o))(mme||{}),hme=["dependencies","devDependencies","peerDependencies"];hH=class{constructor(e,r){let o=1e3*e.workspaces.length;this.session=NE.default.create(o),fme(this.session,e),this.session.consult(":- use_module(library(lists))."),this.session.consult(r)}fetchNextAnswer(){return new Promise(e=>{this.session.answer(r=>{e(r)})})}async*makeQuery(e){let r=this.session.query(e);if(r!==!0)throw gme(r);for(;;){let o=await this.fetchNextAnswer();if(o===null)throw new Jt(79,"Resolution limit exceeded");if(!o)break;if(o.id==="throw")throw gme(o);yield o}}};gH=class t{constructor(e){this.source="";this.project=e;let r=e.configuration.get("constraintsPath");oe.existsSync(r)&&(this.source=oe.readFileSync(r,"utf8"))}static async find(e){return new t(e)}getProjectDatabase(){let e="";for(let r of hme)e+=`dependency_type(${r}). +`;for(let r of this.project.workspacesByCwd.values()){let o=r.relativeCwd;e+=`workspace(${Fh(o)}). +`,e+=`workspace_ident(${Fh(o)}, ${Fh(G.stringifyIdent(r.anchoredLocator))}). +`,e+=`workspace_version(${Fh(o)}, ${Fh(r.manifest.version)}). +`;for(let a of hme)for(let n of r.manifest[a].values())e+=`workspace_has_dependency(${Fh(o)}, ${Fh(G.stringifyIdent(n))}, ${Fh(n.range)}, ${a}). +`}return e+=`workspace(_) :- false. +`,e+=`workspace_ident(_, _) :- false. +`,e+=`workspace_version(_, _) :- false. +`,e+=`workspace_has_dependency(_, _, _, _) :- false. +`,e}getDeclarations(){let e="";return e+=`gen_enforced_dependency(_, _, _, _) :- false. +`,e+=`gen_enforced_field(_, _, _) :- false. +`,e}get fullSource(){return`${this.getProjectDatabase()} +${this.source} +${this.getDeclarations()}`}createSession(){return new hH(this.project,this.fullSource)}async processClassic(){let e=this.createSession();return{enforcedDependencies:await this.genEnforcedDependencies(e),enforcedFields:await this.genEnforcedFields(e)}}async process(){let{enforcedDependencies:e,enforcedFields:r}=await this.processClassic(),o=new Map;for(let{workspace:a,dependencyIdent:n,dependencyRange:u,dependencyType:A}of e){let p=a2([A,G.stringifyIdent(n)]),h=He.getMapWithDefault(o,a.cwd);He.getMapWithDefault(h,p).set(u??void 0,new Set)}for(let{workspace:a,fieldPath:n,fieldValue:u}of r){let A=a2(n),p=He.getMapWithDefault(o,a.cwd);He.getMapWithDefault(p,A).set(JSON.parse(u)??void 0,new Set)}return{manifestUpdates:o,reportedErrors:new Map}}async genEnforcedDependencies(e){let r=[];for await(let o of e.makeQuery("workspace(WorkspaceCwd), dependency_type(DependencyType), gen_enforced_dependency(WorkspaceCwd, DependencyIdent, DependencyRange, DependencyType).")){let a=V.resolve(this.project.cwd,Gg(o.links.WorkspaceCwd)),n=Gg(o.links.DependencyIdent),u=Gg(o.links.DependencyRange),A=Gg(o.links.DependencyType);if(a===null||n===null)throw new Error("Invalid rule");let p=this.project.getWorkspaceByCwd(a),h=G.parseIdent(n);r.push({workspace:p,dependencyIdent:h,dependencyRange:u,dependencyType:A})}return He.sortMap(r,[({dependencyRange:o})=>o!==null?"0":"1",({workspace:o})=>G.stringifyIdent(o.anchoredLocator),({dependencyIdent:o})=>G.stringifyIdent(o)])}async genEnforcedFields(e){let r=[];for await(let o of e.makeQuery("workspace(WorkspaceCwd), gen_enforced_field(WorkspaceCwd, FieldPath, FieldValue).")){let a=V.resolve(this.project.cwd,Gg(o.links.WorkspaceCwd)),n=Gg(o.links.FieldPath),u=ndt(o.links.FieldValue);if(a===null||n===null)throw new Error("Invalid rule");let A=this.project.getWorkspaceByCwd(a);r.push({workspace:A,fieldPath:n,fieldValue:u})}return He.sortMap(r,[({workspace:o})=>G.stringifyIdent(o.anchoredLocator),({fieldPath:o})=>o])}async*query(e){let r=this.createSession();for await(let o of r.makeQuery(e)){let a={};for(let[n,u]of Object.entries(o.links))n!=="_"&&(a[n]=Gg(u));yield a}}}});var Pme=_(Ak=>{"use strict";Object.defineProperty(Ak,"__esModule",{value:!0});function b2(t){let e=[...t.caches],r=e.shift();return r===void 0?Dme():{get(o,a,n={miss:()=>Promise.resolve()}){return r.get(o,a,n).catch(()=>b2({caches:e}).get(o,a,n))},set(o,a){return r.set(o,a).catch(()=>b2({caches:e}).set(o,a))},delete(o){return r.delete(o).catch(()=>b2({caches:e}).delete(o))},clear(){return r.clear().catch(()=>b2({caches:e}).clear())}}}function Dme(){return{get(t,e,r={miss:()=>Promise.resolve()}){return e().then(a=>Promise.all([a,r.miss(a)])).then(([a])=>a)},set(t,e){return Promise.resolve(e)},delete(t){return Promise.resolve()},clear(){return Promise.resolve()}}}Ak.createFallbackableCache=b2;Ak.createNullCache=Dme});var Sme=_((MWt,bme)=>{bme.exports=Pme()});var xme=_(xH=>{"use strict";Object.defineProperty(xH,"__esModule",{value:!0});function Idt(t={serializable:!0}){let e={};return{get(r,o,a={miss:()=>Promise.resolve()}){let n=JSON.stringify(r);if(n in e)return Promise.resolve(t.serializable?JSON.parse(e[n]):e[n]);let u=o(),A=a&&a.miss||(()=>Promise.resolve());return u.then(p=>A(p)).then(()=>u)},set(r,o){return e[JSON.stringify(r)]=t.serializable?JSON.stringify(o):o,Promise.resolve(o)},delete(r){return delete e[JSON.stringify(r)],Promise.resolve()},clear(){return e={},Promise.resolve()}}}xH.createInMemoryCache=Idt});var Qme=_((UWt,kme)=>{kme.exports=xme()});var Rme=_(eu=>{"use strict";Object.defineProperty(eu,"__esModule",{value:!0});function Bdt(t,e,r){let o={"x-algolia-api-key":r,"x-algolia-application-id":e};return{headers(){return t===kH.WithinHeaders?o:{}},queryParameters(){return t===kH.WithinQueryParameters?o:{}}}}function vdt(t){let e=0,r=()=>(e++,new Promise(o=>{setTimeout(()=>{o(t(r))},Math.min(100*e,1e3))}));return t(r)}function Fme(t,e=(r,o)=>Promise.resolve()){return Object.assign(t,{wait(r){return Fme(t.then(o=>Promise.all([e(o,r),o])).then(o=>o[1]))}})}function Ddt(t){let e=t.length-1;for(e;e>0;e--){let r=Math.floor(Math.random()*(e+1)),o=t[e];t[e]=t[r],t[r]=o}return t}function Pdt(t,e){return e&&Object.keys(e).forEach(r=>{t[r]=e[r](t)}),t}function bdt(t,...e){let r=0;return t.replace(/%s/g,()=>encodeURIComponent(e[r++]))}var Sdt="4.22.1",xdt=t=>()=>t.transporter.requester.destroy(),kH={WithinQueryParameters:0,WithinHeaders:1};eu.AuthMode=kH;eu.addMethods=Pdt;eu.createAuth=Bdt;eu.createRetryablePromise=vdt;eu.createWaitablePromise=Fme;eu.destroy=xdt;eu.encode=bdt;eu.shuffle=Ddt;eu.version=Sdt});var S2=_((HWt,Tme)=>{Tme.exports=Rme()});var Nme=_(QH=>{"use strict";Object.defineProperty(QH,"__esModule",{value:!0});var kdt={Delete:"DELETE",Get:"GET",Post:"POST",Put:"PUT"};QH.MethodEnum=kdt});var x2=_((jWt,Lme)=>{Lme.exports=Nme()});var Xme=_(Qi=>{"use strict";Object.defineProperty(Qi,"__esModule",{value:!0});var Ome=x2();function FH(t,e){let r=t||{},o=r.data||{};return Object.keys(r).forEach(a=>{["timeout","headers","queryParameters","data","cacheable"].indexOf(a)===-1&&(o[a]=r[a])}),{data:Object.entries(o).length>0?o:void 0,timeout:r.timeout||e,headers:r.headers||{},queryParameters:r.queryParameters||{},cacheable:r.cacheable}}var k2={Read:1,Write:2,Any:3},YE={Up:1,Down:2,Timeouted:3},Ume=2*60*1e3;function TH(t,e=YE.Up){return{...t,status:e,lastUpdate:Date.now()}}function _me(t){return t.status===YE.Up||Date.now()-t.lastUpdate>Ume}function Hme(t){return t.status===YE.Timeouted&&Date.now()-t.lastUpdate<=Ume}function NH(t){return typeof t=="string"?{protocol:"https",url:t,accept:k2.Any}:{protocol:t.protocol||"https",url:t.url,accept:t.accept||k2.Any}}function Qdt(t,e){return Promise.all(e.map(r=>t.get(r,()=>Promise.resolve(TH(r))))).then(r=>{let o=r.filter(A=>_me(A)),a=r.filter(A=>Hme(A)),n=[...o,...a],u=n.length>0?n.map(A=>NH(A)):e;return{getTimeout(A,p){return(a.length===0&&A===0?1:a.length+3+A)*p},statelessHosts:u}})}var Fdt=({isTimedOut:t,status:e})=>!t&&~~e===0,Rdt=t=>{let e=t.status;return t.isTimedOut||Fdt(t)||~~(e/100)!==2&&~~(e/100)!==4},Tdt=({status:t})=>~~(t/100)===2,Ndt=(t,e)=>Rdt(t)?e.onRetry(t):Tdt(t)?e.onSuccess(t):e.onFail(t);function Mme(t,e,r,o){let a=[],n=Wme(r,o),u=Kme(t,o),A=r.method,p=r.method!==Ome.MethodEnum.Get?{}:{...r.data,...o.data},h={"x-algolia-agent":t.userAgent.value,...t.queryParameters,...p,...o.queryParameters},E=0,I=(v,x)=>{let C=v.pop();if(C===void 0)throw Jme(RH(a));let R={data:n,headers:u,method:A,url:Gme(C,r.path,h),connectTimeout:x(E,t.timeouts.connect),responseTimeout:x(E,o.timeout)},L=z=>{let te={request:R,response:z,host:C,triesLeft:v.length};return a.push(te),te},U={onSuccess:z=>qme(z),onRetry(z){let te=L(z);return z.isTimedOut&&E++,Promise.all([t.logger.info("Retryable failure",LH(te)),t.hostsCache.set(C,TH(C,z.isTimedOut?YE.Timeouted:YE.Down))]).then(()=>I(v,x))},onFail(z){throw L(z),jme(z,RH(a))}};return t.requester.send(R).then(z=>Ndt(z,U))};return Qdt(t.hostsCache,e).then(v=>I([...v.statelessHosts].reverse(),v.getTimeout))}function Ldt(t){let{hostsCache:e,logger:r,requester:o,requestsCache:a,responsesCache:n,timeouts:u,userAgent:A,hosts:p,queryParameters:h,headers:E}=t,I={hostsCache:e,logger:r,requester:o,requestsCache:a,responsesCache:n,timeouts:u,userAgent:A,headers:E,queryParameters:h,hosts:p.map(v=>NH(v)),read(v,x){let C=FH(x,I.timeouts.read),R=()=>Mme(I,I.hosts.filter(z=>(z.accept&k2.Read)!==0),v,C);if((C.cacheable!==void 0?C.cacheable:v.cacheable)!==!0)return R();let U={request:v,mappedRequestOptions:C,transporter:{queryParameters:I.queryParameters,headers:I.headers}};return I.responsesCache.get(U,()=>I.requestsCache.get(U,()=>I.requestsCache.set(U,R()).then(z=>Promise.all([I.requestsCache.delete(U),z]),z=>Promise.all([I.requestsCache.delete(U),Promise.reject(z)])).then(([z,te])=>te)),{miss:z=>I.responsesCache.set(U,z)})},write(v,x){return Mme(I,I.hosts.filter(C=>(C.accept&k2.Write)!==0),v,FH(x,I.timeouts.write))}};return I}function Mdt(t){let e={value:`Algolia for JavaScript (${t})`,add(r){let o=`; ${r.segment}${r.version!==void 0?` (${r.version})`:""}`;return e.value.indexOf(o)===-1&&(e.value=`${e.value}${o}`),e}};return e}function qme(t){try{return JSON.parse(t.content)}catch(e){throw zme(e.message,t)}}function jme({content:t,status:e},r){let o=t;try{o=JSON.parse(t).message}catch{}return Vme(o,e,r)}function Odt(t,...e){let r=0;return t.replace(/%s/g,()=>encodeURIComponent(e[r++]))}function Gme(t,e,r){let o=Yme(r),a=`${t.protocol}://${t.url}/${e.charAt(0)==="/"?e.substr(1):e}`;return o.length&&(a+=`?${o}`),a}function Yme(t){let e=r=>Object.prototype.toString.call(r)==="[object Object]"||Object.prototype.toString.call(r)==="[object Array]";return Object.keys(t).map(r=>Odt("%s=%s",r,e(t[r])?JSON.stringify(t[r]):t[r])).join("&")}function Wme(t,e){if(t.method===Ome.MethodEnum.Get||t.data===void 0&&e.data===void 0)return;let r=Array.isArray(t.data)?t.data:{...t.data,...e.data};return JSON.stringify(r)}function Kme(t,e){let r={...t.headers,...e.headers},o={};return Object.keys(r).forEach(a=>{let n=r[a];o[a.toLowerCase()]=n}),o}function RH(t){return t.map(e=>LH(e))}function LH(t){let e=t.request.headers["x-algolia-api-key"]?{"x-algolia-api-key":"*****"}:{};return{...t,request:{...t.request,headers:{...t.request.headers,...e}}}}function Vme(t,e,r){return{name:"ApiError",message:t,status:e,transporterStackTrace:r}}function zme(t,e){return{name:"DeserializationError",message:t,response:e}}function Jme(t){return{name:"RetryError",message:"Unreachable hosts - your application id may be incorrect. If the error persists, contact support@algolia.com.",transporterStackTrace:t}}Qi.CallEnum=k2;Qi.HostStatusEnum=YE;Qi.createApiError=Vme;Qi.createDeserializationError=zme;Qi.createMappedRequestOptions=FH;Qi.createRetryError=Jme;Qi.createStatefulHost=TH;Qi.createStatelessHost=NH;Qi.createTransporter=Ldt;Qi.createUserAgent=Mdt;Qi.deserializeFailure=jme;Qi.deserializeSuccess=qme;Qi.isStatefulHostTimeouted=Hme;Qi.isStatefulHostUp=_me;Qi.serializeData=Wme;Qi.serializeHeaders=Kme;Qi.serializeQueryParameters=Yme;Qi.serializeUrl=Gme;Qi.stackFrameWithoutCredentials=LH;Qi.stackTraceWithoutCredentials=RH});var Q2=_((YWt,Zme)=>{Zme.exports=Xme()});var $me=_(Rh=>{"use strict";Object.defineProperty(Rh,"__esModule",{value:!0});var WE=S2(),Udt=Q2(),F2=x2(),_dt=t=>{let e=t.region||"us",r=WE.createAuth(WE.AuthMode.WithinHeaders,t.appId,t.apiKey),o=Udt.createTransporter({hosts:[{url:`analytics.${e}.algolia.com`}],...t,headers:{...r.headers(),"content-type":"application/json",...t.headers},queryParameters:{...r.queryParameters(),...t.queryParameters}}),a=t.appId;return WE.addMethods({appId:a,transporter:o},t.methods)},Hdt=t=>(e,r)=>t.transporter.write({method:F2.MethodEnum.Post,path:"2/abtests",data:e},r),qdt=t=>(e,r)=>t.transporter.write({method:F2.MethodEnum.Delete,path:WE.encode("2/abtests/%s",e)},r),jdt=t=>(e,r)=>t.transporter.read({method:F2.MethodEnum.Get,path:WE.encode("2/abtests/%s",e)},r),Gdt=t=>e=>t.transporter.read({method:F2.MethodEnum.Get,path:"2/abtests"},e),Ydt=t=>(e,r)=>t.transporter.write({method:F2.MethodEnum.Post,path:WE.encode("2/abtests/%s/stop",e)},r);Rh.addABTest=Hdt;Rh.createAnalyticsClient=_dt;Rh.deleteABTest=qdt;Rh.getABTest=jdt;Rh.getABTests=Gdt;Rh.stopABTest=Ydt});var tye=_((KWt,eye)=>{eye.exports=$me()});var nye=_(R2=>{"use strict";Object.defineProperty(R2,"__esModule",{value:!0});var MH=S2(),Wdt=Q2(),rye=x2(),Kdt=t=>{let e=t.region||"us",r=MH.createAuth(MH.AuthMode.WithinHeaders,t.appId,t.apiKey),o=Wdt.createTransporter({hosts:[{url:`personalization.${e}.algolia.com`}],...t,headers:{...r.headers(),"content-type":"application/json",...t.headers},queryParameters:{...r.queryParameters(),...t.queryParameters}});return MH.addMethods({appId:t.appId,transporter:o},t.methods)},Vdt=t=>e=>t.transporter.read({method:rye.MethodEnum.Get,path:"1/strategies/personalization"},e),zdt=t=>(e,r)=>t.transporter.write({method:rye.MethodEnum.Post,path:"1/strategies/personalization",data:e},r);R2.createPersonalizationClient=Kdt;R2.getPersonalizationStrategy=Vdt;R2.setPersonalizationStrategy=zdt});var sye=_((zWt,iye)=>{iye.exports=nye()});var Eye=_(Ft=>{"use strict";Object.defineProperty(Ft,"__esModule",{value:!0});var Gt=S2(),Ma=Q2(),Ir=x2(),Jdt=ve("crypto");function fk(t){let e=r=>t.request(r).then(o=>{if(t.batch!==void 0&&t.batch(o.hits),!t.shouldStop(o))return o.cursor?e({cursor:o.cursor}):e({page:(r.page||0)+1})});return e({})}var Xdt=t=>{let e=t.appId,r=Gt.createAuth(t.authMode!==void 0?t.authMode:Gt.AuthMode.WithinHeaders,e,t.apiKey),o=Ma.createTransporter({hosts:[{url:`${e}-dsn.algolia.net`,accept:Ma.CallEnum.Read},{url:`${e}.algolia.net`,accept:Ma.CallEnum.Write}].concat(Gt.shuffle([{url:`${e}-1.algolianet.com`},{url:`${e}-2.algolianet.com`},{url:`${e}-3.algolianet.com`}])),...t,headers:{...r.headers(),"content-type":"application/x-www-form-urlencoded",...t.headers},queryParameters:{...r.queryParameters(),...t.queryParameters}}),a={transporter:o,appId:e,addAlgoliaAgent(n,u){o.userAgent.add({segment:n,version:u})},clearCache(){return Promise.all([o.requestsCache.clear(),o.responsesCache.clear()]).then(()=>{})}};return Gt.addMethods(a,t.methods)};function oye(){return{name:"MissingObjectIDError",message:"All objects must have an unique objectID (like a primary key) to be valid. Algolia is also able to generate objectIDs automatically but *it's not recommended*. To do it, use the `{'autoGenerateObjectIDIfNotExist': true}` option."}}function aye(){return{name:"ObjectNotFoundError",message:"Object not found."}}function lye(){return{name:"ValidUntilNotFoundError",message:"ValidUntil not found in given secured api key."}}var Zdt=t=>(e,r)=>{let{queryParameters:o,...a}=r||{},n={acl:e,...o!==void 0?{queryParameters:o}:{}},u=(A,p)=>Gt.createRetryablePromise(h=>T2(t)(A.key,p).catch(E=>{if(E.status!==404)throw E;return h()}));return Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Post,path:"1/keys",data:n},a),u)},$dt=t=>(e,r,o)=>{let a=Ma.createMappedRequestOptions(o);return a.queryParameters["X-Algolia-User-ID"]=e,t.transporter.write({method:Ir.MethodEnum.Post,path:"1/clusters/mapping",data:{cluster:r}},a)},emt=t=>(e,r,o)=>t.transporter.write({method:Ir.MethodEnum.Post,path:"1/clusters/mapping/batch",data:{users:e,cluster:r}},o),tmt=t=>(e,r)=>Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Post,path:Gt.encode("/1/dictionaries/%s/batch",e),data:{clearExistingDictionaryEntries:!0,requests:{action:"addEntry",body:[]}}},r),(o,a)=>KE(t)(o.taskID,a)),pk=t=>(e,r,o)=>{let a=(n,u)=>N2(t)(e,{methods:{waitTask:es}}).waitTask(n.taskID,u);return Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Post,path:Gt.encode("1/indexes/%s/operation",e),data:{operation:"copy",destination:r}},o),a)},rmt=t=>(e,r,o)=>pk(t)(e,r,{...o,scope:[gk.Rules]}),nmt=t=>(e,r,o)=>pk(t)(e,r,{...o,scope:[gk.Settings]}),imt=t=>(e,r,o)=>pk(t)(e,r,{...o,scope:[gk.Synonyms]}),smt=t=>(e,r)=>e.method===Ir.MethodEnum.Get?t.transporter.read(e,r):t.transporter.write(e,r),omt=t=>(e,r)=>{let o=(a,n)=>Gt.createRetryablePromise(u=>T2(t)(e,n).then(u).catch(A=>{if(A.status!==404)throw A}));return Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Delete,path:Gt.encode("1/keys/%s",e)},r),o)},amt=t=>(e,r,o)=>{let a=r.map(n=>({action:"deleteEntry",body:{objectID:n}}));return Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Post,path:Gt.encode("/1/dictionaries/%s/batch",e),data:{clearExistingDictionaryEntries:!1,requests:a}},o),(n,u)=>KE(t)(n.taskID,u))},lmt=()=>(t,e)=>{let r=Ma.serializeQueryParameters(e),o=Jdt.createHmac("sha256",t).update(r).digest("hex");return Buffer.from(o+r).toString("base64")},T2=t=>(e,r)=>t.transporter.read({method:Ir.MethodEnum.Get,path:Gt.encode("1/keys/%s",e)},r),cye=t=>(e,r)=>t.transporter.read({method:Ir.MethodEnum.Get,path:Gt.encode("1/task/%s",e.toString())},r),cmt=t=>e=>t.transporter.read({method:Ir.MethodEnum.Get,path:"/1/dictionaries/*/settings"},e),umt=t=>e=>t.transporter.read({method:Ir.MethodEnum.Get,path:"1/logs"},e),Amt=()=>t=>{let e=Buffer.from(t,"base64").toString("ascii"),r=/validUntil=(\d+)/,o=e.match(r);if(o===null)throw lye();return parseInt(o[1],10)-Math.round(new Date().getTime()/1e3)},fmt=t=>e=>t.transporter.read({method:Ir.MethodEnum.Get,path:"1/clusters/mapping/top"},e),pmt=t=>(e,r)=>t.transporter.read({method:Ir.MethodEnum.Get,path:Gt.encode("1/clusters/mapping/%s",e)},r),hmt=t=>e=>{let{retrieveMappings:r,...o}=e||{};return r===!0&&(o.getClusters=!0),t.transporter.read({method:Ir.MethodEnum.Get,path:"1/clusters/mapping/pending"},o)},N2=t=>(e,r={})=>{let o={transporter:t.transporter,appId:t.appId,indexName:e};return Gt.addMethods(o,r.methods)},gmt=t=>e=>t.transporter.read({method:Ir.MethodEnum.Get,path:"1/keys"},e),dmt=t=>e=>t.transporter.read({method:Ir.MethodEnum.Get,path:"1/clusters"},e),mmt=t=>e=>t.transporter.read({method:Ir.MethodEnum.Get,path:"1/indexes"},e),ymt=t=>e=>t.transporter.read({method:Ir.MethodEnum.Get,path:"1/clusters/mapping"},e),Emt=t=>(e,r,o)=>{let a=(n,u)=>N2(t)(e,{methods:{waitTask:es}}).waitTask(n.taskID,u);return Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Post,path:Gt.encode("1/indexes/%s/operation",e),data:{operation:"move",destination:r}},o),a)},Cmt=t=>(e,r)=>{let o=(a,n)=>Promise.all(Object.keys(a.taskID).map(u=>N2(t)(u,{methods:{waitTask:es}}).waitTask(a.taskID[u],n)));return Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Post,path:"1/indexes/*/batch",data:{requests:e}},r),o)},wmt=t=>(e,r)=>t.transporter.read({method:Ir.MethodEnum.Post,path:"1/indexes/*/objects",data:{requests:e}},r),Imt=t=>(e,r)=>{let o=e.map(a=>({...a,params:Ma.serializeQueryParameters(a.params||{})}));return t.transporter.read({method:Ir.MethodEnum.Post,path:"1/indexes/*/queries",data:{requests:o},cacheable:!0},r)},Bmt=t=>(e,r)=>Promise.all(e.map(o=>{let{facetName:a,facetQuery:n,...u}=o.params;return N2(t)(o.indexName,{methods:{searchForFacetValues:dye}}).searchForFacetValues(a,n,{...r,...u})})),vmt=t=>(e,r)=>{let o=Ma.createMappedRequestOptions(r);return o.queryParameters["X-Algolia-User-ID"]=e,t.transporter.write({method:Ir.MethodEnum.Delete,path:"1/clusters/mapping"},o)},Dmt=t=>(e,r,o)=>{let a=r.map(n=>({action:"addEntry",body:n}));return Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Post,path:Gt.encode("/1/dictionaries/%s/batch",e),data:{clearExistingDictionaryEntries:!0,requests:a}},o),(n,u)=>KE(t)(n.taskID,u))},Pmt=t=>(e,r)=>{let o=(a,n)=>Gt.createRetryablePromise(u=>T2(t)(e,n).catch(A=>{if(A.status!==404)throw A;return u()}));return Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Post,path:Gt.encode("1/keys/%s/restore",e)},r),o)},bmt=t=>(e,r,o)=>{let a=r.map(n=>({action:"addEntry",body:n}));return Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Post,path:Gt.encode("/1/dictionaries/%s/batch",e),data:{clearExistingDictionaryEntries:!1,requests:a}},o),(n,u)=>KE(t)(n.taskID,u))},Smt=t=>(e,r,o)=>t.transporter.read({method:Ir.MethodEnum.Post,path:Gt.encode("/1/dictionaries/%s/search",e),data:{query:r},cacheable:!0},o),xmt=t=>(e,r)=>t.transporter.read({method:Ir.MethodEnum.Post,path:"1/clusters/mapping/search",data:{query:e}},r),kmt=t=>(e,r)=>Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Put,path:"/1/dictionaries/*/settings",data:e},r),(o,a)=>KE(t)(o.taskID,a)),Qmt=t=>(e,r)=>{let o=Object.assign({},r),{queryParameters:a,...n}=r||{},u=a?{queryParameters:a}:{},A=["acl","indexes","referers","restrictSources","queryParameters","description","maxQueriesPerIPPerHour","maxHitsPerQuery"],p=E=>Object.keys(o).filter(I=>A.indexOf(I)!==-1).every(I=>{if(Array.isArray(E[I])&&Array.isArray(o[I])){let v=E[I];return v.length===o[I].length&&v.every((x,C)=>x===o[I][C])}else return E[I]===o[I]}),h=(E,I)=>Gt.createRetryablePromise(v=>T2(t)(e,I).then(x=>p(x)?Promise.resolve():v()));return Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Put,path:Gt.encode("1/keys/%s",e),data:u},n),h)},KE=t=>(e,r)=>Gt.createRetryablePromise(o=>cye(t)(e,r).then(a=>a.status!=="published"?o():void 0)),uye=t=>(e,r)=>{let o=(a,n)=>es(t)(a.taskID,n);return Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Post,path:Gt.encode("1/indexes/%s/batch",t.indexName),data:{requests:e}},r),o)},Fmt=t=>e=>fk({shouldStop:r=>r.cursor===void 0,...e,request:r=>t.transporter.read({method:Ir.MethodEnum.Post,path:Gt.encode("1/indexes/%s/browse",t.indexName),data:r},e)}),Rmt=t=>e=>{let r={hitsPerPage:1e3,...e};return fk({shouldStop:o=>o.hits.length({...a,hits:a.hits.map(n=>(delete n._highlightResult,n))}))}})},Tmt=t=>e=>{let r={hitsPerPage:1e3,...e};return fk({shouldStop:o=>o.hits.length({...a,hits:a.hits.map(n=>(delete n._highlightResult,n))}))}})},hk=t=>(e,r,o)=>{let{batchSize:a,...n}=o||{},u={taskIDs:[],objectIDs:[]},A=(p=0)=>{let h=[],E;for(E=p;E({action:r,body:I})),n).then(I=>(u.objectIDs=u.objectIDs.concat(I.objectIDs),u.taskIDs.push(I.taskID),E++,A(E)))};return Gt.createWaitablePromise(A(),(p,h)=>Promise.all(p.taskIDs.map(E=>es(t)(E,h))))},Nmt=t=>e=>Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Post,path:Gt.encode("1/indexes/%s/clear",t.indexName)},e),(r,o)=>es(t)(r.taskID,o)),Lmt=t=>e=>{let{forwardToReplicas:r,...o}=e||{},a=Ma.createMappedRequestOptions(o);return r&&(a.queryParameters.forwardToReplicas=1),Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Post,path:Gt.encode("1/indexes/%s/rules/clear",t.indexName)},a),(n,u)=>es(t)(n.taskID,u))},Mmt=t=>e=>{let{forwardToReplicas:r,...o}=e||{},a=Ma.createMappedRequestOptions(o);return r&&(a.queryParameters.forwardToReplicas=1),Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Post,path:Gt.encode("1/indexes/%s/synonyms/clear",t.indexName)},a),(n,u)=>es(t)(n.taskID,u))},Omt=t=>(e,r)=>Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Post,path:Gt.encode("1/indexes/%s/deleteByQuery",t.indexName),data:e},r),(o,a)=>es(t)(o.taskID,a)),Umt=t=>e=>Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Delete,path:Gt.encode("1/indexes/%s",t.indexName)},e),(r,o)=>es(t)(r.taskID,o)),_mt=t=>(e,r)=>Gt.createWaitablePromise(Aye(t)([e],r).then(o=>({taskID:o.taskIDs[0]})),(o,a)=>es(t)(o.taskID,a)),Aye=t=>(e,r)=>{let o=e.map(a=>({objectID:a}));return hk(t)(o,Wg.DeleteObject,r)},Hmt=t=>(e,r)=>{let{forwardToReplicas:o,...a}=r||{},n=Ma.createMappedRequestOptions(a);return o&&(n.queryParameters.forwardToReplicas=1),Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Delete,path:Gt.encode("1/indexes/%s/rules/%s",t.indexName,e)},n),(u,A)=>es(t)(u.taskID,A))},qmt=t=>(e,r)=>{let{forwardToReplicas:o,...a}=r||{},n=Ma.createMappedRequestOptions(a);return o&&(n.queryParameters.forwardToReplicas=1),Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Delete,path:Gt.encode("1/indexes/%s/synonyms/%s",t.indexName,e)},n),(u,A)=>es(t)(u.taskID,A))},jmt=t=>e=>fye(t)(e).then(()=>!0).catch(r=>{if(r.status!==404)throw r;return!1}),Gmt=t=>(e,r,o)=>t.transporter.read({method:Ir.MethodEnum.Post,path:Gt.encode("1/answers/%s/prediction",t.indexName),data:{query:e,queryLanguages:r},cacheable:!0},o),Ymt=t=>(e,r)=>{let{query:o,paginate:a,...n}=r||{},u=0,A=()=>gye(t)(o||"",{...n,page:u}).then(p=>{for(let[h,E]of Object.entries(p.hits))if(e(E))return{object:E,position:parseInt(h,10),page:u};if(u++,a===!1||u>=p.nbPages)throw aye();return A()});return A()},Wmt=t=>(e,r)=>t.transporter.read({method:Ir.MethodEnum.Get,path:Gt.encode("1/indexes/%s/%s",t.indexName,e)},r),Kmt=()=>(t,e)=>{for(let[r,o]of Object.entries(t.hits))if(o.objectID===e)return parseInt(r,10);return-1},Vmt=t=>(e,r)=>{let{attributesToRetrieve:o,...a}=r||{},n=e.map(u=>({indexName:t.indexName,objectID:u,...o?{attributesToRetrieve:o}:{}}));return t.transporter.read({method:Ir.MethodEnum.Post,path:"1/indexes/*/objects",data:{requests:n}},a)},zmt=t=>(e,r)=>t.transporter.read({method:Ir.MethodEnum.Get,path:Gt.encode("1/indexes/%s/rules/%s",t.indexName,e)},r),fye=t=>e=>t.transporter.read({method:Ir.MethodEnum.Get,path:Gt.encode("1/indexes/%s/settings",t.indexName),data:{getVersion:2}},e),Jmt=t=>(e,r)=>t.transporter.read({method:Ir.MethodEnum.Get,path:Gt.encode("1/indexes/%s/synonyms/%s",t.indexName,e)},r),pye=t=>(e,r)=>t.transporter.read({method:Ir.MethodEnum.Get,path:Gt.encode("1/indexes/%s/task/%s",t.indexName,e.toString())},r),Xmt=t=>(e,r)=>Gt.createWaitablePromise(hye(t)([e],r).then(o=>({objectID:o.objectIDs[0],taskID:o.taskIDs[0]})),(o,a)=>es(t)(o.taskID,a)),hye=t=>(e,r)=>{let{createIfNotExists:o,...a}=r||{},n=o?Wg.PartialUpdateObject:Wg.PartialUpdateObjectNoCreate;return hk(t)(e,n,a)},Zmt=t=>(e,r)=>{let{safe:o,autoGenerateObjectIDIfNotExist:a,batchSize:n,...u}=r||{},A=(C,R,L,U)=>Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Post,path:Gt.encode("1/indexes/%s/operation",C),data:{operation:L,destination:R}},U),(z,te)=>es(t)(z.taskID,te)),p=Math.random().toString(36).substring(7),h=`${t.indexName}_tmp_${p}`,E=OH({appId:t.appId,transporter:t.transporter,indexName:h}),I=[],v=A(t.indexName,h,"copy",{...u,scope:["settings","synonyms","rules"]});I.push(v);let x=(o?v.wait(u):v).then(()=>{let C=E(e,{...u,autoGenerateObjectIDIfNotExist:a,batchSize:n});return I.push(C),o?C.wait(u):C}).then(()=>{let C=A(h,t.indexName,"move",u);return I.push(C),o?C.wait(u):C}).then(()=>Promise.all(I)).then(([C,R,L])=>({objectIDs:R.objectIDs,taskIDs:[C.taskID,...R.taskIDs,L.taskID]}));return Gt.createWaitablePromise(x,(C,R)=>Promise.all(I.map(L=>L.wait(R))))},$mt=t=>(e,r)=>UH(t)(e,{...r,clearExistingRules:!0}),eyt=t=>(e,r)=>_H(t)(e,{...r,clearExistingSynonyms:!0}),tyt=t=>(e,r)=>Gt.createWaitablePromise(OH(t)([e],r).then(o=>({objectID:o.objectIDs[0],taskID:o.taskIDs[0]})),(o,a)=>es(t)(o.taskID,a)),OH=t=>(e,r)=>{let{autoGenerateObjectIDIfNotExist:o,...a}=r||{},n=o?Wg.AddObject:Wg.UpdateObject;if(n===Wg.UpdateObject){for(let u of e)if(u.objectID===void 0)return Gt.createWaitablePromise(Promise.reject(oye()))}return hk(t)(e,n,a)},ryt=t=>(e,r)=>UH(t)([e],r),UH=t=>(e,r)=>{let{forwardToReplicas:o,clearExistingRules:a,...n}=r||{},u=Ma.createMappedRequestOptions(n);return o&&(u.queryParameters.forwardToReplicas=1),a&&(u.queryParameters.clearExistingRules=1),Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Post,path:Gt.encode("1/indexes/%s/rules/batch",t.indexName),data:e},u),(A,p)=>es(t)(A.taskID,p))},nyt=t=>(e,r)=>_H(t)([e],r),_H=t=>(e,r)=>{let{forwardToReplicas:o,clearExistingSynonyms:a,replaceExistingSynonyms:n,...u}=r||{},A=Ma.createMappedRequestOptions(u);return o&&(A.queryParameters.forwardToReplicas=1),(n||a)&&(A.queryParameters.replaceExistingSynonyms=1),Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Post,path:Gt.encode("1/indexes/%s/synonyms/batch",t.indexName),data:e},A),(p,h)=>es(t)(p.taskID,h))},gye=t=>(e,r)=>t.transporter.read({method:Ir.MethodEnum.Post,path:Gt.encode("1/indexes/%s/query",t.indexName),data:{query:e},cacheable:!0},r),dye=t=>(e,r,o)=>t.transporter.read({method:Ir.MethodEnum.Post,path:Gt.encode("1/indexes/%s/facets/%s/query",t.indexName,e),data:{facetQuery:r},cacheable:!0},o),mye=t=>(e,r)=>t.transporter.read({method:Ir.MethodEnum.Post,path:Gt.encode("1/indexes/%s/rules/search",t.indexName),data:{query:e}},r),yye=t=>(e,r)=>t.transporter.read({method:Ir.MethodEnum.Post,path:Gt.encode("1/indexes/%s/synonyms/search",t.indexName),data:{query:e}},r),iyt=t=>(e,r)=>{let{forwardToReplicas:o,...a}=r||{},n=Ma.createMappedRequestOptions(a);return o&&(n.queryParameters.forwardToReplicas=1),Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Put,path:Gt.encode("1/indexes/%s/settings",t.indexName),data:e},n),(u,A)=>es(t)(u.taskID,A))},es=t=>(e,r)=>Gt.createRetryablePromise(o=>pye(t)(e,r).then(a=>a.status!=="published"?o():void 0)),syt={AddObject:"addObject",Analytics:"analytics",Browser:"browse",DeleteIndex:"deleteIndex",DeleteObject:"deleteObject",EditSettings:"editSettings",Inference:"inference",ListIndexes:"listIndexes",Logs:"logs",Personalization:"personalization",Recommendation:"recommendation",Search:"search",SeeUnretrievableAttributes:"seeUnretrievableAttributes",Settings:"settings",Usage:"usage"},Wg={AddObject:"addObject",UpdateObject:"updateObject",PartialUpdateObject:"partialUpdateObject",PartialUpdateObjectNoCreate:"partialUpdateObjectNoCreate",DeleteObject:"deleteObject",DeleteIndex:"delete",ClearIndex:"clear"},gk={Settings:"settings",Synonyms:"synonyms",Rules:"rules"},oyt={None:"none",StopIfEnoughMatches:"stopIfEnoughMatches"},ayt={Synonym:"synonym",OneWaySynonym:"oneWaySynonym",AltCorrection1:"altCorrection1",AltCorrection2:"altCorrection2",Placeholder:"placeholder"};Ft.ApiKeyACLEnum=syt;Ft.BatchActionEnum=Wg;Ft.ScopeEnum=gk;Ft.StrategyEnum=oyt;Ft.SynonymEnum=ayt;Ft.addApiKey=Zdt;Ft.assignUserID=$dt;Ft.assignUserIDs=emt;Ft.batch=uye;Ft.browseObjects=Fmt;Ft.browseRules=Rmt;Ft.browseSynonyms=Tmt;Ft.chunkedBatch=hk;Ft.clearDictionaryEntries=tmt;Ft.clearObjects=Nmt;Ft.clearRules=Lmt;Ft.clearSynonyms=Mmt;Ft.copyIndex=pk;Ft.copyRules=rmt;Ft.copySettings=nmt;Ft.copySynonyms=imt;Ft.createBrowsablePromise=fk;Ft.createMissingObjectIDError=oye;Ft.createObjectNotFoundError=aye;Ft.createSearchClient=Xdt;Ft.createValidUntilNotFoundError=lye;Ft.customRequest=smt;Ft.deleteApiKey=omt;Ft.deleteBy=Omt;Ft.deleteDictionaryEntries=amt;Ft.deleteIndex=Umt;Ft.deleteObject=_mt;Ft.deleteObjects=Aye;Ft.deleteRule=Hmt;Ft.deleteSynonym=qmt;Ft.exists=jmt;Ft.findAnswers=Gmt;Ft.findObject=Ymt;Ft.generateSecuredApiKey=lmt;Ft.getApiKey=T2;Ft.getAppTask=cye;Ft.getDictionarySettings=cmt;Ft.getLogs=umt;Ft.getObject=Wmt;Ft.getObjectPosition=Kmt;Ft.getObjects=Vmt;Ft.getRule=zmt;Ft.getSecuredApiKeyRemainingValidity=Amt;Ft.getSettings=fye;Ft.getSynonym=Jmt;Ft.getTask=pye;Ft.getTopUserIDs=fmt;Ft.getUserID=pmt;Ft.hasPendingMappings=hmt;Ft.initIndex=N2;Ft.listApiKeys=gmt;Ft.listClusters=dmt;Ft.listIndices=mmt;Ft.listUserIDs=ymt;Ft.moveIndex=Emt;Ft.multipleBatch=Cmt;Ft.multipleGetObjects=wmt;Ft.multipleQueries=Imt;Ft.multipleSearchForFacetValues=Bmt;Ft.partialUpdateObject=Xmt;Ft.partialUpdateObjects=hye;Ft.removeUserID=vmt;Ft.replaceAllObjects=Zmt;Ft.replaceAllRules=$mt;Ft.replaceAllSynonyms=eyt;Ft.replaceDictionaryEntries=Dmt;Ft.restoreApiKey=Pmt;Ft.saveDictionaryEntries=bmt;Ft.saveObject=tyt;Ft.saveObjects=OH;Ft.saveRule=ryt;Ft.saveRules=UH;Ft.saveSynonym=nyt;Ft.saveSynonyms=_H;Ft.search=gye;Ft.searchDictionaryEntries=Smt;Ft.searchForFacetValues=dye;Ft.searchRules=mye;Ft.searchSynonyms=yye;Ft.searchUserIDs=xmt;Ft.setDictionarySettings=kmt;Ft.setSettings=iyt;Ft.updateApiKey=Qmt;Ft.waitAppTask=KE;Ft.waitTask=es});var wye=_((XWt,Cye)=>{Cye.exports=Eye()});var Iye=_(dk=>{"use strict";Object.defineProperty(dk,"__esModule",{value:!0});function lyt(){return{debug(t,e){return Promise.resolve()},info(t,e){return Promise.resolve()},error(t,e){return Promise.resolve()}}}var cyt={Debug:1,Info:2,Error:3};dk.LogLevelEnum=cyt;dk.createNullLogger=lyt});var vye=_(($Wt,Bye)=>{Bye.exports=Iye()});var Sye=_(HH=>{"use strict";Object.defineProperty(HH,"__esModule",{value:!0});var Dye=ve("http"),Pye=ve("https"),uyt=ve("url"),bye={keepAlive:!0},Ayt=new Dye.Agent(bye),fyt=new Pye.Agent(bye);function pyt({agent:t,httpAgent:e,httpsAgent:r,requesterOptions:o={}}={}){let a=e||t||Ayt,n=r||t||fyt;return{send(u){return new Promise(A=>{let p=uyt.parse(u.url),h=p.query===null?p.pathname:`${p.pathname}?${p.query}`,E={...o,agent:p.protocol==="https:"?n:a,hostname:p.hostname,path:h,method:u.method,headers:{...o&&o.headers?o.headers:{},...u.headers},...p.port!==void 0?{port:p.port||""}:{}},I=(p.protocol==="https:"?Pye:Dye).request(E,R=>{let L=[];R.on("data",U=>{L=L.concat(U)}),R.on("end",()=>{clearTimeout(x),clearTimeout(C),A({status:R.statusCode||0,content:Buffer.concat(L).toString(),isTimedOut:!1})})}),v=(R,L)=>setTimeout(()=>{I.abort(),A({status:0,content:L,isTimedOut:!0})},R*1e3),x=v(u.connectTimeout,"Connection timeout"),C;I.on("error",R=>{clearTimeout(x),clearTimeout(C),A({status:0,content:R.message,isTimedOut:!1})}),I.once("response",()=>{clearTimeout(x),C=v(u.responseTimeout,"Socket timeout")}),u.data!==void 0&&I.write(u.data),I.end()})},destroy(){return a.destroy(),n.destroy(),Promise.resolve()}}}HH.createNodeHttpRequester=pyt});var kye=_((tKt,xye)=>{xye.exports=Sye()});var Tye=_((rKt,Rye)=>{"use strict";var Qye=Sme(),hyt=Qme(),VE=tye(),jH=S2(),qH=sye(),_t=wye(),gyt=vye(),dyt=kye(),myt=Q2();function Fye(t,e,r){let o={appId:t,apiKey:e,timeouts:{connect:2,read:5,write:30},requester:dyt.createNodeHttpRequester(),logger:gyt.createNullLogger(),responsesCache:Qye.createNullCache(),requestsCache:Qye.createNullCache(),hostsCache:hyt.createInMemoryCache(),userAgent:myt.createUserAgent(jH.version).add({segment:"Node.js",version:process.versions.node})},a={...o,...r},n=()=>u=>qH.createPersonalizationClient({...o,...u,methods:{getPersonalizationStrategy:qH.getPersonalizationStrategy,setPersonalizationStrategy:qH.setPersonalizationStrategy}});return _t.createSearchClient({...a,methods:{search:_t.multipleQueries,searchForFacetValues:_t.multipleSearchForFacetValues,multipleBatch:_t.multipleBatch,multipleGetObjects:_t.multipleGetObjects,multipleQueries:_t.multipleQueries,copyIndex:_t.copyIndex,copySettings:_t.copySettings,copyRules:_t.copyRules,copySynonyms:_t.copySynonyms,moveIndex:_t.moveIndex,listIndices:_t.listIndices,getLogs:_t.getLogs,listClusters:_t.listClusters,multipleSearchForFacetValues:_t.multipleSearchForFacetValues,getApiKey:_t.getApiKey,addApiKey:_t.addApiKey,listApiKeys:_t.listApiKeys,updateApiKey:_t.updateApiKey,deleteApiKey:_t.deleteApiKey,restoreApiKey:_t.restoreApiKey,assignUserID:_t.assignUserID,assignUserIDs:_t.assignUserIDs,getUserID:_t.getUserID,searchUserIDs:_t.searchUserIDs,listUserIDs:_t.listUserIDs,getTopUserIDs:_t.getTopUserIDs,removeUserID:_t.removeUserID,hasPendingMappings:_t.hasPendingMappings,generateSecuredApiKey:_t.generateSecuredApiKey,getSecuredApiKeyRemainingValidity:_t.getSecuredApiKeyRemainingValidity,destroy:jH.destroy,clearDictionaryEntries:_t.clearDictionaryEntries,deleteDictionaryEntries:_t.deleteDictionaryEntries,getDictionarySettings:_t.getDictionarySettings,getAppTask:_t.getAppTask,replaceDictionaryEntries:_t.replaceDictionaryEntries,saveDictionaryEntries:_t.saveDictionaryEntries,searchDictionaryEntries:_t.searchDictionaryEntries,setDictionarySettings:_t.setDictionarySettings,waitAppTask:_t.waitAppTask,customRequest:_t.customRequest,initIndex:u=>A=>_t.initIndex(u)(A,{methods:{batch:_t.batch,delete:_t.deleteIndex,findAnswers:_t.findAnswers,getObject:_t.getObject,getObjects:_t.getObjects,saveObject:_t.saveObject,saveObjects:_t.saveObjects,search:_t.search,searchForFacetValues:_t.searchForFacetValues,waitTask:_t.waitTask,setSettings:_t.setSettings,getSettings:_t.getSettings,partialUpdateObject:_t.partialUpdateObject,partialUpdateObjects:_t.partialUpdateObjects,deleteObject:_t.deleteObject,deleteObjects:_t.deleteObjects,deleteBy:_t.deleteBy,clearObjects:_t.clearObjects,browseObjects:_t.browseObjects,getObjectPosition:_t.getObjectPosition,findObject:_t.findObject,exists:_t.exists,saveSynonym:_t.saveSynonym,saveSynonyms:_t.saveSynonyms,getSynonym:_t.getSynonym,searchSynonyms:_t.searchSynonyms,browseSynonyms:_t.browseSynonyms,deleteSynonym:_t.deleteSynonym,clearSynonyms:_t.clearSynonyms,replaceAllObjects:_t.replaceAllObjects,replaceAllSynonyms:_t.replaceAllSynonyms,searchRules:_t.searchRules,getRule:_t.getRule,deleteRule:_t.deleteRule,saveRule:_t.saveRule,saveRules:_t.saveRules,replaceAllRules:_t.replaceAllRules,browseRules:_t.browseRules,clearRules:_t.clearRules}}),initAnalytics:()=>u=>VE.createAnalyticsClient({...o,...u,methods:{addABTest:VE.addABTest,getABTest:VE.getABTest,getABTests:VE.getABTests,stopABTest:VE.stopABTest,deleteABTest:VE.deleteABTest}}),initPersonalization:n,initRecommendation:()=>u=>(a.logger.info("The `initRecommendation` method is deprecated. Use `initPersonalization` instead."),n()(u))}})}Fye.version=jH.version;Rye.exports=Fye});var YH=_((nKt,GH)=>{var Nye=Tye();GH.exports=Nye;GH.exports.default=Nye});var VH=_((sKt,Oye)=>{"use strict";var Mye=Object.getOwnPropertySymbols,Eyt=Object.prototype.hasOwnProperty,Cyt=Object.prototype.propertyIsEnumerable;function wyt(t){if(t==null)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(t)}function Iyt(){try{if(!Object.assign)return!1;var t=new String("abc");if(t[5]="de",Object.getOwnPropertyNames(t)[0]==="5")return!1;for(var e={},r=0;r<10;r++)e["_"+String.fromCharCode(r)]=r;var o=Object.getOwnPropertyNames(e).map(function(n){return e[n]});if(o.join("")!=="0123456789")return!1;var a={};return"abcdefghijklmnopqrst".split("").forEach(function(n){a[n]=n}),Object.keys(Object.assign({},a)).join("")==="abcdefghijklmnopqrst"}catch{return!1}}Oye.exports=Iyt()?Object.assign:function(t,e){for(var r,o=wyt(t),a,n=1;n{"use strict";var $H=VH(),tu=typeof Symbol=="function"&&Symbol.for,L2=tu?Symbol.for("react.element"):60103,Byt=tu?Symbol.for("react.portal"):60106,vyt=tu?Symbol.for("react.fragment"):60107,Dyt=tu?Symbol.for("react.strict_mode"):60108,Pyt=tu?Symbol.for("react.profiler"):60114,byt=tu?Symbol.for("react.provider"):60109,Syt=tu?Symbol.for("react.context"):60110,xyt=tu?Symbol.for("react.forward_ref"):60112,kyt=tu?Symbol.for("react.suspense"):60113,Qyt=tu?Symbol.for("react.memo"):60115,Fyt=tu?Symbol.for("react.lazy"):60116,Uye=typeof Symbol=="function"&&Symbol.iterator;function M2(t){for(var e="https://reactjs.org/docs/error-decoder.html?invariant="+t,r=1;rmk.length&&mk.push(t)}function JH(t,e,r,o){var a=typeof t;(a==="undefined"||a==="boolean")&&(t=null);var n=!1;if(t===null)n=!0;else switch(a){case"string":case"number":n=!0;break;case"object":switch(t.$$typeof){case L2:case Byt:n=!0}}if(n)return r(o,t,e===""?"."+zH(t,0):e),1;if(n=0,e=e===""?".":e+":",Array.isArray(t))for(var u=0;u{"use strict";Xye.exports=Jye()});var s6=_((lKt,i6)=>{"use strict";var fn=i6.exports;i6.exports.default=fn;var Ln="\x1B[",O2="\x1B]",JE="\x07",yk=";",Zye=process.env.TERM_PROGRAM==="Apple_Terminal";fn.cursorTo=(t,e)=>{if(typeof t!="number")throw new TypeError("The `x` argument is required");return typeof e!="number"?Ln+(t+1)+"G":Ln+(e+1)+";"+(t+1)+"H"};fn.cursorMove=(t,e)=>{if(typeof t!="number")throw new TypeError("The `x` argument is required");let r="";return t<0?r+=Ln+-t+"D":t>0&&(r+=Ln+t+"C"),e<0?r+=Ln+-e+"A":e>0&&(r+=Ln+e+"B"),r};fn.cursorUp=(t=1)=>Ln+t+"A";fn.cursorDown=(t=1)=>Ln+t+"B";fn.cursorForward=(t=1)=>Ln+t+"C";fn.cursorBackward=(t=1)=>Ln+t+"D";fn.cursorLeft=Ln+"G";fn.cursorSavePosition=Zye?"\x1B7":Ln+"s";fn.cursorRestorePosition=Zye?"\x1B8":Ln+"u";fn.cursorGetPosition=Ln+"6n";fn.cursorNextLine=Ln+"E";fn.cursorPrevLine=Ln+"F";fn.cursorHide=Ln+"?25l";fn.cursorShow=Ln+"?25h";fn.eraseLines=t=>{let e="";for(let r=0;r[O2,"8",yk,yk,e,JE,t,O2,"8",yk,yk,JE].join("");fn.image=(t,e={})=>{let r=`${O2}1337;File=inline=1`;return e.width&&(r+=`;width=${e.width}`),e.height&&(r+=`;height=${e.height}`),e.preserveAspectRatio===!1&&(r+=";preserveAspectRatio=0"),r+":"+t.toString("base64")+JE};fn.iTerm={setCwd:(t=process.cwd())=>`${O2}50;CurrentDir=${t}${JE}`,annotation:(t,e={})=>{let r=`${O2}1337;`,o=typeof e.x<"u",a=typeof e.y<"u";if((o||a)&&!(o&&a&&typeof e.length<"u"))throw new Error("`x`, `y` and `length` must be defined when `x` or `y` is defined");return t=t.replace(/\|/g,""),r+=e.isHidden?"AddHiddenAnnotation=":"AddAnnotation=",e.length>0?r+=(o?[t,e.length,e.x,e.y]:[e.length,t]).join("|"):r+=t,r+JE}}});var eEe=_((cKt,o6)=>{"use strict";var $ye=(t,e)=>{for(let r of Reflect.ownKeys(e))Object.defineProperty(t,r,Object.getOwnPropertyDescriptor(e,r));return t};o6.exports=$ye;o6.exports.default=$ye});var rEe=_((uKt,Ck)=>{"use strict";var Oyt=eEe(),Ek=new WeakMap,tEe=(t,e={})=>{if(typeof t!="function")throw new TypeError("Expected a function");let r,o=0,a=t.displayName||t.name||"",n=function(...u){if(Ek.set(n,++o),o===1)r=t.apply(this,u),t=null;else if(e.throw===!0)throw new Error(`Function \`${a}\` can only be called once`);return r};return Oyt(n,t),Ek.set(n,o),n};Ck.exports=tEe;Ck.exports.default=tEe;Ck.exports.callCount=t=>{if(!Ek.has(t))throw new Error(`The given function \`${t.name}\` is not wrapped by the \`onetime\` package`);return Ek.get(t)}});var nEe=_((AKt,wk)=>{wk.exports=["SIGABRT","SIGALRM","SIGHUP","SIGINT","SIGTERM"];process.platform!=="win32"&&wk.exports.push("SIGVTALRM","SIGXCPU","SIGXFSZ","SIGUSR2","SIGTRAP","SIGSYS","SIGQUIT","SIGIOT");process.platform==="linux"&&wk.exports.push("SIGIO","SIGPOLL","SIGPWR","SIGSTKFLT","SIGUNUSED")});var c6=_((fKt,$E)=>{var yi=global.process,Kg=function(t){return t&&typeof t=="object"&&typeof t.removeListener=="function"&&typeof t.emit=="function"&&typeof t.reallyExit=="function"&&typeof t.listeners=="function"&&typeof t.kill=="function"&&typeof t.pid=="number"&&typeof t.on=="function"};Kg(yi)?(iEe=ve("assert"),XE=nEe(),sEe=/^win/i.test(yi.platform),U2=ve("events"),typeof U2!="function"&&(U2=U2.EventEmitter),yi.__signal_exit_emitter__?Ls=yi.__signal_exit_emitter__:(Ls=yi.__signal_exit_emitter__=new U2,Ls.count=0,Ls.emitted={}),Ls.infinite||(Ls.setMaxListeners(1/0),Ls.infinite=!0),$E.exports=function(t,e){if(!Kg(global.process))return function(){};iEe.equal(typeof t,"function","a callback must be provided for exit handler"),ZE===!1&&a6();var r="exit";e&&e.alwaysLast&&(r="afterexit");var o=function(){Ls.removeListener(r,t),Ls.listeners("exit").length===0&&Ls.listeners("afterexit").length===0&&Ik()};return Ls.on(r,t),o},Ik=function(){!ZE||!Kg(global.process)||(ZE=!1,XE.forEach(function(e){try{yi.removeListener(e,Bk[e])}catch{}}),yi.emit=vk,yi.reallyExit=l6,Ls.count-=1)},$E.exports.unload=Ik,Vg=function(e,r,o){Ls.emitted[e]||(Ls.emitted[e]=!0,Ls.emit(e,r,o))},Bk={},XE.forEach(function(t){Bk[t]=function(){if(Kg(global.process)){var r=yi.listeners(t);r.length===Ls.count&&(Ik(),Vg("exit",null,t),Vg("afterexit",null,t),sEe&&t==="SIGHUP"&&(t="SIGINT"),yi.kill(yi.pid,t))}}}),$E.exports.signals=function(){return XE},ZE=!1,a6=function(){ZE||!Kg(global.process)||(ZE=!0,Ls.count+=1,XE=XE.filter(function(e){try{return yi.on(e,Bk[e]),!0}catch{return!1}}),yi.emit=aEe,yi.reallyExit=oEe)},$E.exports.load=a6,l6=yi.reallyExit,oEe=function(e){Kg(global.process)&&(yi.exitCode=e||0,Vg("exit",yi.exitCode,null),Vg("afterexit",yi.exitCode,null),l6.call(yi,yi.exitCode))},vk=yi.emit,aEe=function(e,r){if(e==="exit"&&Kg(global.process)){r!==void 0&&(yi.exitCode=r);var o=vk.apply(this,arguments);return Vg("exit",yi.exitCode,null),Vg("afterexit",yi.exitCode,null),o}else return vk.apply(this,arguments)}):$E.exports=function(){return function(){}};var iEe,XE,sEe,U2,Ls,Ik,Vg,Bk,ZE,a6,l6,oEe,vk,aEe});var cEe=_((pKt,lEe)=>{"use strict";var Uyt=rEe(),_yt=c6();lEe.exports=Uyt(()=>{_yt(()=>{process.stderr.write("\x1B[?25h")},{alwaysLast:!0})})});var u6=_(eC=>{"use strict";var Hyt=cEe(),Dk=!1;eC.show=(t=process.stderr)=>{t.isTTY&&(Dk=!1,t.write("\x1B[?25h"))};eC.hide=(t=process.stderr)=>{t.isTTY&&(Hyt(),Dk=!0,t.write("\x1B[?25l"))};eC.toggle=(t,e)=>{t!==void 0&&(Dk=t),Dk?eC.show(e):eC.hide(e)}});var pEe=_(_2=>{"use strict";var fEe=_2&&_2.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(_2,"__esModule",{value:!0});var uEe=fEe(s6()),AEe=fEe(u6()),qyt=(t,{showCursor:e=!1}={})=>{let r=0,o="",a=!1,n=u=>{!e&&!a&&(AEe.default.hide(),a=!0);let A=u+` +`;A!==o&&(o=A,t.write(uEe.default.eraseLines(r)+A),r=A.split(` +`).length)};return n.clear=()=>{t.write(uEe.default.eraseLines(r)),o="",r=0},n.done=()=>{o="",r=0,e||(AEe.default.show(),a=!1)},n};_2.default={create:qyt}});var hEe=_((dKt,jyt)=>{jyt.exports=[{name:"AppVeyor",constant:"APPVEYOR",env:"APPVEYOR",pr:"APPVEYOR_PULL_REQUEST_NUMBER"},{name:"Azure Pipelines",constant:"AZURE_PIPELINES",env:"SYSTEM_TEAMFOUNDATIONCOLLECTIONURI",pr:"SYSTEM_PULLREQUEST_PULLREQUESTID"},{name:"Bamboo",constant:"BAMBOO",env:"bamboo_planKey"},{name:"Bitbucket Pipelines",constant:"BITBUCKET",env:"BITBUCKET_COMMIT",pr:"BITBUCKET_PR_ID"},{name:"Bitrise",constant:"BITRISE",env:"BITRISE_IO",pr:"BITRISE_PULL_REQUEST"},{name:"Buddy",constant:"BUDDY",env:"BUDDY_WORKSPACE_ID",pr:"BUDDY_EXECUTION_PULL_REQUEST_ID"},{name:"Buildkite",constant:"BUILDKITE",env:"BUILDKITE",pr:{env:"BUILDKITE_PULL_REQUEST",ne:"false"}},{name:"CircleCI",constant:"CIRCLE",env:"CIRCLECI",pr:"CIRCLE_PULL_REQUEST"},{name:"Cirrus CI",constant:"CIRRUS",env:"CIRRUS_CI",pr:"CIRRUS_PR"},{name:"AWS CodeBuild",constant:"CODEBUILD",env:"CODEBUILD_BUILD_ARN"},{name:"Codeship",constant:"CODESHIP",env:{CI_NAME:"codeship"}},{name:"Drone",constant:"DRONE",env:"DRONE",pr:{DRONE_BUILD_EVENT:"pull_request"}},{name:"dsari",constant:"DSARI",env:"DSARI"},{name:"GitLab CI",constant:"GITLAB",env:"GITLAB_CI"},{name:"GoCD",constant:"GOCD",env:"GO_PIPELINE_LABEL"},{name:"Hudson",constant:"HUDSON",env:"HUDSON_URL"},{name:"Jenkins",constant:"JENKINS",env:["JENKINS_URL","BUILD_ID"],pr:{any:["ghprbPullId","CHANGE_ID"]}},{name:"Magnum CI",constant:"MAGNUM",env:"MAGNUM"},{name:"Netlify CI",constant:"NETLIFY",env:"NETLIFY_BUILD_BASE",pr:{env:"PULL_REQUEST",ne:"false"}},{name:"Sail CI",constant:"SAIL",env:"SAILCI",pr:"SAIL_PULL_REQUEST_NUMBER"},{name:"Semaphore",constant:"SEMAPHORE",env:"SEMAPHORE",pr:"PULL_REQUEST_NUMBER"},{name:"Shippable",constant:"SHIPPABLE",env:"SHIPPABLE",pr:{IS_PULL_REQUEST:"true"}},{name:"Solano CI",constant:"SOLANO",env:"TDDIUM",pr:"TDDIUM_PR_ID"},{name:"Strider CD",constant:"STRIDER",env:"STRIDER"},{name:"TaskCluster",constant:"TASKCLUSTER",env:["TASK_ID","RUN_ID"]},{name:"TeamCity",constant:"TEAMCITY",env:"TEAMCITY_VERSION"},{name:"Travis CI",constant:"TRAVIS",env:"TRAVIS",pr:{env:"TRAVIS_PULL_REQUEST",ne:"false"}}]});var mEe=_(dl=>{"use strict";var dEe=hEe(),pA=process.env;Object.defineProperty(dl,"_vendors",{value:dEe.map(function(t){return t.constant})});dl.name=null;dl.isPR=null;dEe.forEach(function(t){var e=Array.isArray(t.env)?t.env:[t.env],r=e.every(function(o){return gEe(o)});if(dl[t.constant]=r,r)switch(dl.name=t.name,typeof t.pr){case"string":dl.isPR=!!pA[t.pr];break;case"object":"env"in t.pr?dl.isPR=t.pr.env in pA&&pA[t.pr.env]!==t.pr.ne:"any"in t.pr?dl.isPR=t.pr.any.some(function(o){return!!pA[o]}):dl.isPR=gEe(t.pr);break;default:dl.isPR=null}});dl.isCI=!!(pA.CI||pA.CONTINUOUS_INTEGRATION||pA.BUILD_NUMBER||pA.RUN_ID||dl.name);function gEe(t){return typeof t=="string"?!!pA[t]:Object.keys(t).every(function(e){return pA[e]===t[e]})}});var EEe=_((yKt,yEe)=>{"use strict";yEe.exports=mEe().isCI});var wEe=_((EKt,CEe)=>{"use strict";var Gyt=t=>{let e=new Set;do for(let r of Reflect.ownKeys(t))e.add([t,r]);while((t=Reflect.getPrototypeOf(t))&&t!==Object.prototype);return e};CEe.exports=(t,{include:e,exclude:r}={})=>{let o=a=>{let n=u=>typeof u=="string"?a===u:u.test(a);return e?e.some(n):r?!r.some(n):!0};for(let[a,n]of Gyt(t.constructor.prototype)){if(n==="constructor"||!o(n))continue;let u=Reflect.getOwnPropertyDescriptor(a,n);u&&typeof u.value=="function"&&(t[n]=t[n].bind(t))}return t}});var SEe=_(kn=>{"use strict";Object.defineProperty(kn,"__esModule",{value:!0});var rC,j2,kk,Qk,m6;typeof window>"u"||typeof MessageChannel!="function"?(tC=null,A6=null,f6=function(){if(tC!==null)try{var t=kn.unstable_now();tC(!0,t),tC=null}catch(e){throw setTimeout(f6,0),e}},IEe=Date.now(),kn.unstable_now=function(){return Date.now()-IEe},rC=function(t){tC!==null?setTimeout(rC,0,t):(tC=t,setTimeout(f6,0))},j2=function(t,e){A6=setTimeout(t,e)},kk=function(){clearTimeout(A6)},Qk=function(){return!1},m6=kn.unstable_forceFrameRate=function(){}):(Pk=window.performance,p6=window.Date,BEe=window.setTimeout,vEe=window.clearTimeout,typeof console<"u"&&(DEe=window.cancelAnimationFrame,typeof window.requestAnimationFrame!="function"&&console.error("This browser doesn't support requestAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills"),typeof DEe!="function"&&console.error("This browser doesn't support cancelAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills")),typeof Pk=="object"&&typeof Pk.now=="function"?kn.unstable_now=function(){return Pk.now()}:(PEe=p6.now(),kn.unstable_now=function(){return p6.now()-PEe}),H2=!1,q2=null,bk=-1,h6=5,g6=0,Qk=function(){return kn.unstable_now()>=g6},m6=function(){},kn.unstable_forceFrameRate=function(t){0>t||125xk(u,r))p!==void 0&&0>xk(p,u)?(t[o]=p,t[A]=r,o=A):(t[o]=u,t[n]=r,o=n);else if(p!==void 0&&0>xk(p,r))t[o]=p,t[A]=r,o=A;else break e}}return e}return null}function xk(t,e){var r=t.sortIndex-e.sortIndex;return r!==0?r:t.id-e.id}var ru=[],Th=[],Yyt=1,sa=null,Lo=3,Rk=!1,zg=!1,G2=!1;function Tk(t){for(var e=nc(Th);e!==null;){if(e.callback===null)Fk(Th);else if(e.startTime<=t)Fk(Th),e.sortIndex=e.expirationTime,y6(ru,e);else break;e=nc(Th)}}function E6(t){if(G2=!1,Tk(t),!zg)if(nc(ru)!==null)zg=!0,rC(C6);else{var e=nc(Th);e!==null&&j2(E6,e.startTime-t)}}function C6(t,e){zg=!1,G2&&(G2=!1,kk()),Rk=!0;var r=Lo;try{for(Tk(e),sa=nc(ru);sa!==null&&(!(sa.expirationTime>e)||t&&!Qk());){var o=sa.callback;if(o!==null){sa.callback=null,Lo=sa.priorityLevel;var a=o(sa.expirationTime<=e);e=kn.unstable_now(),typeof a=="function"?sa.callback=a:sa===nc(ru)&&Fk(ru),Tk(e)}else Fk(ru);sa=nc(ru)}if(sa!==null)var n=!0;else{var u=nc(Th);u!==null&&j2(E6,u.startTime-e),n=!1}return n}finally{sa=null,Lo=r,Rk=!1}}function bEe(t){switch(t){case 1:return-1;case 2:return 250;case 5:return 1073741823;case 4:return 1e4;default:return 5e3}}var Wyt=m6;kn.unstable_ImmediatePriority=1;kn.unstable_UserBlockingPriority=2;kn.unstable_NormalPriority=3;kn.unstable_IdlePriority=5;kn.unstable_LowPriority=4;kn.unstable_runWithPriority=function(t,e){switch(t){case 1:case 2:case 3:case 4:case 5:break;default:t=3}var r=Lo;Lo=t;try{return e()}finally{Lo=r}};kn.unstable_next=function(t){switch(Lo){case 1:case 2:case 3:var e=3;break;default:e=Lo}var r=Lo;Lo=e;try{return t()}finally{Lo=r}};kn.unstable_scheduleCallback=function(t,e,r){var o=kn.unstable_now();if(typeof r=="object"&&r!==null){var a=r.delay;a=typeof a=="number"&&0o?(t.sortIndex=a,y6(Th,t),nc(ru)===null&&t===nc(Th)&&(G2?kk():G2=!0,j2(E6,a-o))):(t.sortIndex=r,y6(ru,t),zg||Rk||(zg=!0,rC(C6))),t};kn.unstable_cancelCallback=function(t){t.callback=null};kn.unstable_wrapCallback=function(t){var e=Lo;return function(){var r=Lo;Lo=e;try{return t.apply(this,arguments)}finally{Lo=r}}};kn.unstable_getCurrentPriorityLevel=function(){return Lo};kn.unstable_shouldYield=function(){var t=kn.unstable_now();Tk(t);var e=nc(ru);return e!==sa&&sa!==null&&e!==null&&e.callback!==null&&e.startTime<=t&&e.expirationTime{"use strict";xEe.exports=SEe()});var kEe=_((IKt,Y2)=>{Y2.exports=function t(e){"use strict";var r=VH(),o=an(),a=w6();function n(P){for(var D="https://reactjs.org/docs/error-decoder.html?invariant="+P,T=1;Tao||(P.current=yl[ao],yl[ao]=null,ao--)}function Mn(P,D){ao++,yl[ao]=P.current,P.current=D}var Ti={},On={current:Ti},_i={current:!1},ir=Ti;function Me(P,D){var T=P.type.contextTypes;if(!T)return Ti;var q=P.stateNode;if(q&&q.__reactInternalMemoizedUnmaskedChildContext===D)return q.__reactInternalMemoizedMaskedChildContext;var W={},fe;for(fe in T)W[fe]=D[fe];return q&&(P=P.stateNode,P.__reactInternalMemoizedUnmaskedChildContext=D,P.__reactInternalMemoizedMaskedChildContext=W),W}function ii(P){return P=P.childContextTypes,P!=null}function Ha(P){Vn(_i,P),Vn(On,P)}function hr(P){Vn(_i,P),Vn(On,P)}function Ac(P,D,T){if(On.current!==Ti)throw Error(n(168));Mn(On,D,P),Mn(_i,T,P)}function fu(P,D,T){var q=P.stateNode;if(P=D.childContextTypes,typeof q.getChildContext!="function")return T;q=q.getChildContext();for(var W in q)if(!(W in P))throw Error(n(108,de(D)||"Unknown",W));return r({},T,{},q)}function fc(P){var D=P.stateNode;return D=D&&D.__reactInternalMemoizedMergedChildContext||Ti,ir=On.current,Mn(On,D,P),Mn(_i,_i.current,P),!0}function El(P,D,T){var q=P.stateNode;if(!q)throw Error(n(169));T?(D=fu(P,D,ir),q.__reactInternalMemoizedMergedChildContext=D,Vn(_i,P),Vn(On,P),Mn(On,D,P)):Vn(_i,P),Mn(_i,T,P)}var vA=a.unstable_runWithPriority,pu=a.unstable_scheduleCallback,Ie=a.unstable_cancelCallback,Tt=a.unstable_shouldYield,pc=a.unstable_requestPaint,Hi=a.unstable_now,hu=a.unstable_getCurrentPriorityLevel,Yt=a.unstable_ImmediatePriority,Cl=a.unstable_UserBlockingPriority,DA=a.unstable_NormalPriority,ap=a.unstable_LowPriority,hc=a.unstable_IdlePriority,PA={},Qn=pc!==void 0?pc:function(){},hi=null,gc=null,bA=!1,aa=Hi(),Ni=1e4>aa?Hi:function(){return Hi()-aa};function _o(){switch(hu()){case Yt:return 99;case Cl:return 98;case DA:return 97;case ap:return 96;case hc:return 95;default:throw Error(n(332))}}function Xe(P){switch(P){case 99:return Yt;case 98:return Cl;case 97:return DA;case 96:return ap;case 95:return hc;default:throw Error(n(332))}}function lo(P,D){return P=Xe(P),vA(P,D)}function dc(P,D,T){return P=Xe(P),pu(P,D,T)}function gu(P){return hi===null?(hi=[P],gc=pu(Yt,du)):hi.push(P),PA}function qi(){if(gc!==null){var P=gc;gc=null,Ie(P)}du()}function du(){if(!bA&&hi!==null){bA=!0;var P=0;try{var D=hi;lo(99,function(){for(;P=D&&(jo=!0),P.firstContext=null)}function Es(P,D){if(ca!==P&&D!==!1&&D!==0)if((typeof D!="number"||D===1073741823)&&(ca=P,D=1073741823),D={context:P,observedBits:D,next:null},Hs===null){if(co===null)throw Error(n(308));Hs=D,co.dependencies={expirationTime:0,firstContext:D,responders:null}}else Hs=Hs.next=D;return S?P._currentValue:P._currentValue2}var qs=!1;function Un(P){return{baseState:P,firstUpdate:null,lastUpdate:null,firstCapturedUpdate:null,lastCapturedUpdate:null,firstEffect:null,lastEffect:null,firstCapturedEffect:null,lastCapturedEffect:null}}function Pn(P){return{baseState:P.baseState,firstUpdate:P.firstUpdate,lastUpdate:P.lastUpdate,firstCapturedUpdate:null,lastCapturedUpdate:null,firstEffect:null,lastEffect:null,firstCapturedEffect:null,lastCapturedEffect:null}}function Cs(P,D){return{expirationTime:P,suspenseConfig:D,tag:0,payload:null,callback:null,next:null,nextEffect:null}}function We(P,D){P.lastUpdate===null?P.firstUpdate=P.lastUpdate=D:(P.lastUpdate.next=D,P.lastUpdate=D)}function tt(P,D){var T=P.alternate;if(T===null){var q=P.updateQueue,W=null;q===null&&(q=P.updateQueue=Un(P.memoizedState))}else q=P.updateQueue,W=T.updateQueue,q===null?W===null?(q=P.updateQueue=Un(P.memoizedState),W=T.updateQueue=Un(T.memoizedState)):q=P.updateQueue=Pn(W):W===null&&(W=T.updateQueue=Pn(q));W===null||q===W?We(q,D):q.lastUpdate===null||W.lastUpdate===null?(We(q,D),We(W,D)):(We(q,D),W.lastUpdate=D)}function Bt(P,D){var T=P.updateQueue;T=T===null?P.updateQueue=Un(P.memoizedState):or(P,T),T.lastCapturedUpdate===null?T.firstCapturedUpdate=T.lastCapturedUpdate=D:(T.lastCapturedUpdate.next=D,T.lastCapturedUpdate=D)}function or(P,D){var T=P.alternate;return T!==null&&D===T.updateQueue&&(D=P.updateQueue=Pn(D)),D}function ee(P,D,T,q,W,fe){switch(T.tag){case 1:return P=T.payload,typeof P=="function"?P.call(fe,q,W):P;case 3:P.effectTag=P.effectTag&-4097|64;case 0:if(P=T.payload,W=typeof P=="function"?P.call(fe,q,W):P,W==null)break;return r({},q,W);case 2:qs=!0}return q}function ye(P,D,T,q,W){qs=!1,D=or(P,D);for(var fe=D.baseState,De=null,vt=0,wt=D.firstUpdate,St=fe;wt!==null;){var _r=wt.expirationTime;_rSn?(ai=Qr,Qr=null):ai=Qr.sibling;var tn=di(nt,Qr,At[Sn],Wt);if(tn===null){Qr===null&&(Qr=ai);break}P&&Qr&&tn.alternate===null&&D(nt,Qr),Ve=fe(tn,Ve,Sn),bn===null?vr=tn:bn.sibling=tn,bn=tn,Qr=ai}if(Sn===At.length)return T(nt,Qr),vr;if(Qr===null){for(;SnSn?(ai=Qr,Qr=null):ai=Qr.sibling;var ho=di(nt,Qr,tn.value,Wt);if(ho===null){Qr===null&&(Qr=ai);break}P&&Qr&&ho.alternate===null&&D(nt,Qr),Ve=fe(ho,Ve,Sn),bn===null?vr=ho:bn.sibling=ho,bn=ho,Qr=ai}if(tn.done)return T(nt,Qr),vr;if(Qr===null){for(;!tn.done;Sn++,tn=At.next())tn=os(nt,tn.value,Wt),tn!==null&&(Ve=fe(tn,Ve,Sn),bn===null?vr=tn:bn.sibling=tn,bn=tn);return vr}for(Qr=q(nt,Qr);!tn.done;Sn++,tn=At.next())tn=po(Qr,nt,Sn,tn.value,Wt),tn!==null&&(P&&tn.alternate!==null&&Qr.delete(tn.key===null?Sn:tn.key),Ve=fe(tn,Ve,Sn),bn===null?vr=tn:bn.sibling=tn,bn=tn);return P&&Qr.forEach(function(pF){return D(nt,pF)}),vr}return function(nt,Ve,At,Wt){var vr=typeof At=="object"&&At!==null&&At.type===E&&At.key===null;vr&&(At=At.props.children);var bn=typeof At=="object"&&At!==null;if(bn)switch(At.$$typeof){case p:e:{for(bn=At.key,vr=Ve;vr!==null;){if(vr.key===bn)if(vr.tag===7?At.type===E:vr.elementType===At.type){T(nt,vr.sibling),Ve=W(vr,At.type===E?At.props.children:At.props,Wt),Ve.ref=kA(nt,vr,At),Ve.return=nt,nt=Ve;break e}else{T(nt,vr);break}else D(nt,vr);vr=vr.sibling}At.type===E?(Ve=ku(At.props.children,nt.mode,Wt,At.key),Ve.return=nt,nt=Ve):(Wt=xd(At.type,At.key,At.props,null,nt.mode,Wt),Wt.ref=kA(nt,Ve,At),Wt.return=nt,nt=Wt)}return De(nt);case h:e:{for(vr=At.key;Ve!==null;){if(Ve.key===vr)if(Ve.tag===4&&Ve.stateNode.containerInfo===At.containerInfo&&Ve.stateNode.implementation===At.implementation){T(nt,Ve.sibling),Ve=W(Ve,At.children||[],Wt),Ve.return=nt,nt=Ve;break e}else{T(nt,Ve);break}else D(nt,Ve);Ve=Ve.sibling}Ve=dw(At,nt.mode,Wt),Ve.return=nt,nt=Ve}return De(nt)}if(typeof At=="string"||typeof At=="number")return At=""+At,Ve!==null&&Ve.tag===6?(T(nt,Ve.sibling),Ve=W(Ve,At,Wt),Ve.return=nt,nt=Ve):(T(nt,Ve),Ve=gw(At,nt.mode,Wt),Ve.return=nt,nt=Ve),De(nt);if(xA(At))return KA(nt,Ve,At,Wt);if(ce(At))return Yo(nt,Ve,At,Wt);if(bn&&lp(nt,At),typeof At>"u"&&!vr)switch(nt.tag){case 1:case 0:throw nt=nt.type,Error(n(152,nt.displayName||nt.name||"Component"))}return T(nt,Ve)}}var mu=e0(!0),t0=e0(!1),yu={},uo={current:yu},QA={current:yu},yc={current:yu};function Aa(P){if(P===yu)throw Error(n(174));return P}function r0(P,D){Mn(yc,D,P),Mn(QA,P,P),Mn(uo,yu,P),D=ne(D),Vn(uo,P),Mn(uo,D,P)}function Ec(P){Vn(uo,P),Vn(QA,P),Vn(yc,P)}function hd(P){var D=Aa(yc.current),T=Aa(uo.current);D=Z(T,P.type,D),T!==D&&(Mn(QA,P,P),Mn(uo,D,P))}function n0(P){QA.current===P&&(Vn(uo,P),Vn(QA,P))}var $n={current:0};function cp(P){for(var D=P;D!==null;){if(D.tag===13){var T=D.memoizedState;if(T!==null&&(T=T.dehydrated,T===null||Os(T)||so(T)))return D}else if(D.tag===19&&D.memoizedProps.revealOrder!==void 0){if(D.effectTag&64)return D}else if(D.child!==null){D.child.return=D,D=D.child;continue}if(D===P)break;for(;D.sibling===null;){if(D.return===null||D.return===P)return null;D=D.return}D.sibling.return=D.return,D=D.sibling}return null}function i0(P,D){return{responder:P,props:D}}var FA=u.ReactCurrentDispatcher,js=u.ReactCurrentBatchConfig,Eu=0,ja=null,Gi=null,fa=null,Cu=null,ws=null,Cc=null,wc=0,Y=null,Dt=0,wl=!1,Si=null,Ic=0;function ct(){throw Error(n(321))}function wu(P,D){if(D===null)return!1;for(var T=0;Twc&&(wc=_r,Sd(wc))):(uw(_r,wt.suspenseConfig),fe=wt.eagerReducer===P?wt.eagerState:P(fe,wt.action)),De=wt,wt=wt.next}while(wt!==null&&wt!==q);St||(vt=De,W=fe),ds(fe,D.memoizedState)||(jo=!0),D.memoizedState=fe,D.baseUpdate=vt,D.baseState=W,T.lastRenderedState=fe}return[D.memoizedState,T.dispatch]}function o0(P){var D=RA();return typeof P=="function"&&(P=P()),D.memoizedState=D.baseState=P,P=D.queue={last:null,dispatch:null,lastRenderedReducer:Br,lastRenderedState:P},P=P.dispatch=A0.bind(null,ja,P),[D.memoizedState,P]}function a0(P){return Is(Br,P)}function l0(P,D,T,q){return P={tag:P,create:D,destroy:T,deps:q,next:null},Y===null?(Y={lastEffect:null},Y.lastEffect=P.next=P):(D=Y.lastEffect,D===null?Y.lastEffect=P.next=P:(T=D.next,D.next=P,P.next=T,Y.lastEffect=P)),P}function Ap(P,D,T,q){var W=RA();Dt|=P,W.memoizedState=l0(D,T,void 0,q===void 0?null:q)}function Bc(P,D,T,q){var W=up();q=q===void 0?null:q;var fe=void 0;if(Gi!==null){var De=Gi.memoizedState;if(fe=De.destroy,q!==null&&wu(q,De.deps)){l0(0,T,fe,q);return}}Dt|=P,W.memoizedState=l0(D,T,fe,q)}function Ct(P,D){return Ap(516,192,P,D)}function gd(P,D){return Bc(516,192,P,D)}function c0(P,D){if(typeof D=="function")return P=P(),D(P),function(){D(null)};if(D!=null)return P=P(),D.current=P,function(){D.current=null}}function u0(){}function Iu(P,D){return RA().memoizedState=[P,D===void 0?null:D],P}function dd(P,D){var T=up();D=D===void 0?null:D;var q=T.memoizedState;return q!==null&&D!==null&&wu(D,q[1])?q[0]:(T.memoizedState=[P,D],P)}function A0(P,D,T){if(!(25>Ic))throw Error(n(301));var q=P.alternate;if(P===ja||q!==null&&q===ja)if(wl=!0,P={expirationTime:Eu,suspenseConfig:null,action:T,eagerReducer:null,eagerState:null,next:null},Si===null&&(Si=new Map),T=Si.get(D),T===void 0)Si.set(D,P);else{for(D=T;D.next!==null;)D=D.next;D.next=P}else{var W=ma(),fe=pt.suspense;W=HA(W,P,fe),fe={expirationTime:W,suspenseConfig:fe,action:T,eagerReducer:null,eagerState:null,next:null};var De=D.last;if(De===null)fe.next=fe;else{var vt=De.next;vt!==null&&(fe.next=vt),De.next=fe}if(D.last=fe,P.expirationTime===0&&(q===null||q.expirationTime===0)&&(q=D.lastRenderedReducer,q!==null))try{var wt=D.lastRenderedState,St=q(wt,T);if(fe.eagerReducer=q,fe.eagerState=St,ds(St,wt))return}catch{}finally{}Sc(P,W)}}var Bu={readContext:Es,useCallback:ct,useContext:ct,useEffect:ct,useImperativeHandle:ct,useLayoutEffect:ct,useMemo:ct,useReducer:ct,useRef:ct,useState:ct,useDebugValue:ct,useResponder:ct,useDeferredValue:ct,useTransition:ct},rw={readContext:Es,useCallback:Iu,useContext:Es,useEffect:Ct,useImperativeHandle:function(P,D,T){return T=T!=null?T.concat([P]):null,Ap(4,36,c0.bind(null,D,P),T)},useLayoutEffect:function(P,D){return Ap(4,36,P,D)},useMemo:function(P,D){var T=RA();return D=D===void 0?null:D,P=P(),T.memoizedState=[P,D],P},useReducer:function(P,D,T){var q=RA();return D=T!==void 0?T(D):D,q.memoizedState=q.baseState=D,P=q.queue={last:null,dispatch:null,lastRenderedReducer:P,lastRenderedState:D},P=P.dispatch=A0.bind(null,ja,P),[q.memoizedState,P]},useRef:function(P){var D=RA();return P={current:P},D.memoizedState=P},useState:o0,useDebugValue:u0,useResponder:i0,useDeferredValue:function(P,D){var T=o0(P),q=T[0],W=T[1];return Ct(function(){a.unstable_next(function(){var fe=js.suspense;js.suspense=D===void 0?null:D;try{W(P)}finally{js.suspense=fe}})},[P,D]),q},useTransition:function(P){var D=o0(!1),T=D[0],q=D[1];return[Iu(function(W){q(!0),a.unstable_next(function(){var fe=js.suspense;js.suspense=P===void 0?null:P;try{q(!1),W()}finally{js.suspense=fe}})},[P,T]),T]}},md={readContext:Es,useCallback:dd,useContext:Es,useEffect:gd,useImperativeHandle:function(P,D,T){return T=T!=null?T.concat([P]):null,Bc(4,36,c0.bind(null,D,P),T)},useLayoutEffect:function(P,D){return Bc(4,36,P,D)},useMemo:function(P,D){var T=up();D=D===void 0?null:D;var q=T.memoizedState;return q!==null&&D!==null&&wu(D,q[1])?q[0]:(P=P(),T.memoizedState=[P,D],P)},useReducer:Is,useRef:function(){return up().memoizedState},useState:a0,useDebugValue:u0,useResponder:i0,useDeferredValue:function(P,D){var T=a0(P),q=T[0],W=T[1];return gd(function(){a.unstable_next(function(){var fe=js.suspense;js.suspense=D===void 0?null:D;try{W(P)}finally{js.suspense=fe}})},[P,D]),q},useTransition:function(P){var D=a0(!1),T=D[0],q=D[1];return[dd(function(W){q(!0),a.unstable_next(function(){var fe=js.suspense;js.suspense=P===void 0?null:P;try{q(!1),W()}finally{js.suspense=fe}})},[P,T]),T]}},pa=null,vc=null,Il=!1;function vu(P,D){var T=Dl(5,null,null,0);T.elementType="DELETED",T.type="DELETED",T.stateNode=D,T.return=P,T.effectTag=8,P.lastEffect!==null?(P.lastEffect.nextEffect=T,P.lastEffect=T):P.firstEffect=P.lastEffect=T}function f0(P,D){switch(P.tag){case 5:return D=io(D,P.type,P.pendingProps),D!==null?(P.stateNode=D,!0):!1;case 6:return D=Pi(D,P.pendingProps),D!==null?(P.stateNode=D,!0):!1;case 13:return!1;default:return!1}}function TA(P){if(Il){var D=vc;if(D){var T=D;if(!f0(P,D)){if(D=uc(T),!D||!f0(P,D)){P.effectTag=P.effectTag&-1025|2,Il=!1,pa=P;return}vu(pa,T)}pa=P,vc=Au(D)}else P.effectTag=P.effectTag&-1025|2,Il=!1,pa=P}}function fp(P){for(P=P.return;P!==null&&P.tag!==5&&P.tag!==3&&P.tag!==13;)P=P.return;pa=P}function Ga(P){if(!y||P!==pa)return!1;if(!Il)return fp(P),Il=!0,!1;var D=P.type;if(P.tag!==5||D!=="head"&&D!=="body"&&!Fe(D,P.memoizedProps))for(D=vc;D;)vu(P,D),D=uc(D);if(fp(P),P.tag===13){if(!y)throw Error(n(316));if(P=P.memoizedState,P=P!==null?P.dehydrated:null,!P)throw Error(n(317));vc=Us(P)}else vc=pa?uc(P.stateNode):null;return!0}function p0(){y&&(vc=pa=null,Il=!1)}var pp=u.ReactCurrentOwner,jo=!1;function Bs(P,D,T,q){D.child=P===null?t0(D,null,T,q):mu(D,P.child,T,q)}function wi(P,D,T,q,W){T=T.render;var fe=D.ref;return ys(D,W),q=s0(P,D,T,q,fe,W),P!==null&&!jo?(D.updateQueue=P.updateQueue,D.effectTag&=-517,P.expirationTime<=W&&(P.expirationTime=0),si(P,D,W)):(D.effectTag|=1,Bs(P,D,q,W),D.child)}function yd(P,D,T,q,W,fe){if(P===null){var De=T.type;return typeof De=="function"&&!hw(De)&&De.defaultProps===void 0&&T.compare===null&&T.defaultProps===void 0?(D.tag=15,D.type=De,Ed(P,D,De,q,W,fe)):(P=xd(T.type,null,q,null,D.mode,fe),P.ref=D.ref,P.return=D,D.child=P)}return De=P.child,WD)&&_A.set(P,D)))}}function w0(P,D){P.expirationTimeP?D:P)}function fo(P){if(P.lastExpiredTime!==0)P.callbackExpirationTime=1073741823,P.callbackPriority=99,P.callbackNode=gu(cw.bind(null,P));else{var D=bd(P),T=P.callbackNode;if(D===0)T!==null&&(P.callbackNode=null,P.callbackExpirationTime=0,P.callbackPriority=90);else{var q=ma();if(D===1073741823?q=99:D===1||D===2?q=95:(q=10*(1073741821-D)-10*(1073741821-q),q=0>=q?99:250>=q?98:5250>=q?97:95),T!==null){var W=P.callbackPriority;if(P.callbackExpirationTime===D&&W>=q)return;T!==PA&&Ie(T)}P.callbackExpirationTime=D,P.callbackPriority=q,D=D===1073741823?gu(cw.bind(null,P)):dc(q,xv.bind(null,P),{timeout:10*(1073741821-D)-Ni()}),P.callbackNode=D}}}function xv(P,D){if(Pd=0,D)return D=ma(),kd(P,D),fo(P),null;var T=bd(P);if(T!==0){if(D=P.callbackNode,(yr&(is|Gs))!==En)throw Error(n(327));if(Cp(),P===gi&&T===ss||Su(P,T),Mr!==null){var q=yr;yr|=is;var W=jA(P);do try{rF();break}catch(vt){qA(P,vt)}while(!0);if(ua(),yr=q,mp.current=W,Yi===Id)throw D=Bd,Su(P,T),WA(P,T),fo(P),D;if(Mr===null)switch(W=P.finishedWork=P.current.alternate,P.finishedExpirationTime=T,q=Yi,gi=null,q){case Du:case Id:throw Error(n(345));case Ii:kd(P,2=T){P.lastPingedTime=T,Su(P,T);break}}if(fe=bd(P),fe!==0&&fe!==T)break;if(q!==0&&q!==T){P.lastPingedTime=q;break}P.timeoutHandle=be(xu.bind(null,P),W);break}xu(P);break;case vl:if(WA(P,T),q=P.lastSuspendedTime,T===q&&(P.nextKnownPendingLevel=Aw(W)),OA&&(W=P.lastPingedTime,W===0||W>=T)){P.lastPingedTime=T,Su(P,T);break}if(W=bd(P),W!==0&&W!==T)break;if(q!==0&&q!==T){P.lastPingedTime=q;break}if(MA!==1073741823?q=10*(1073741821-MA)-Ni():Ka===1073741823?q=0:(q=10*(1073741821-Ka)-5e3,W=Ni(),T=10*(1073741821-T)-W,q=W-q,0>q&&(q=0),q=(120>q?120:480>q?480:1080>q?1080:1920>q?1920:3e3>q?3e3:4320>q?4320:1960*iw(q/1960))-q,T=q?q=0:(W=De.busyDelayMs|0,fe=Ni()-(10*(1073741821-fe)-(De.timeoutMs|0||5e3)),q=fe<=W?0:W+q-fe),10 component higher in the tree to provide a loading indicator or placeholder to display.`+ml(W))}Yi!==bc&&(Yi=Ii),fe=g0(fe,W),wt=q;do{switch(wt.tag){case 3:De=fe,wt.effectTag|=4096,wt.expirationTime=D;var Ve=bv(wt,De,D);Bt(wt,Ve);break e;case 1:De=fe;var At=wt.type,Wt=wt.stateNode;if(!(wt.effectTag&64)&&(typeof At.getDerivedStateFromError=="function"||Wt!==null&&typeof Wt.componentDidCatch=="function"&&(bu===null||!bu.has(Wt)))){wt.effectTag|=4096,wt.expirationTime=D;var vr=Sv(wt,De,D);Bt(wt,vr);break e}}wt=wt.return}while(wt!==null)}Mr=Rv(Mr)}catch(bn){D=bn;continue}break}while(!0)}function jA(){var P=mp.current;return mp.current=Bu,P===null?Bu:P}function uw(P,D){Pyp&&(yp=P)}function tF(){for(;Mr!==null;)Mr=Fv(Mr)}function rF(){for(;Mr!==null&&!Tt();)Mr=Fv(Mr)}function Fv(P){var D=Nv(P.alternate,P,ss);return P.memoizedProps=P.pendingProps,D===null&&(D=Rv(P)),sw.current=null,D}function Rv(P){Mr=P;do{var D=Mr.alternate;if(P=Mr.return,Mr.effectTag&2048){if(D=nw(Mr,ss),D!==null)return D.effectTag&=2047,D;P!==null&&(P.firstEffect=P.lastEffect=null,P.effectTag|=2048)}else{e:{var T=D;D=Mr;var q=ss,W=D.pendingProps;switch(D.tag){case 2:break;case 16:break;case 15:case 0:break;case 1:ii(D.type)&&Ha(D);break;case 3:Ec(D),hr(D),W=D.stateNode,W.pendingContext&&(W.context=W.pendingContext,W.pendingContext=null),(T===null||T.child===null)&&Ga(D)&&ga(D),Bl(D);break;case 5:n0(D);var fe=Aa(yc.current);if(q=D.type,T!==null&&D.stateNode!=null)ns(T,D,q,W,fe),T.ref!==D.ref&&(D.effectTag|=128);else if(W){if(T=Aa(uo.current),Ga(D)){if(W=D,!y)throw Error(n(175));T=sp(W.stateNode,W.type,W.memoizedProps,fe,T,W),W.updateQueue=T,T=T!==null,T&&ga(D)}else{var De=ht(q,W,fe,T,D);Dc(De,D,!1,!1),D.stateNode=De,rt(De,q,W,fe,T)&&ga(D)}D.ref!==null&&(D.effectTag|=128)}else if(D.stateNode===null)throw Error(n(166));break;case 6:if(T&&D.stateNode!=null)Yr(T,D,T.memoizedProps,W);else{if(typeof W!="string"&&D.stateNode===null)throw Error(n(166));if(T=Aa(yc.current),fe=Aa(uo.current),Ga(D)){if(T=D,!y)throw Error(n(176));(T=op(T.stateNode,T.memoizedProps,T))&&ga(D)}else D.stateNode=Ye(W,T,fe,D)}break;case 11:break;case 13:if(Vn($n,D),W=D.memoizedState,D.effectTag&64){D.expirationTime=q;break e}W=W!==null,fe=!1,T===null?D.memoizedProps.fallback!==void 0&&Ga(D):(q=T.memoizedState,fe=q!==null,W||q===null||(q=T.child.sibling,q!==null&&(De=D.firstEffect,De!==null?(D.firstEffect=q,q.nextEffect=De):(D.firstEffect=D.lastEffect=q,q.nextEffect=null),q.effectTag=8))),W&&!fe&&D.mode&2&&(T===null&&D.memoizedProps.unstable_avoidThisFallback!==!0||$n.current&1?Yi===Du&&(Yi=da):((Yi===Du||Yi===da)&&(Yi=vl),yp!==0&&gi!==null&&(WA(gi,ss),Mv(gi,yp)))),b&&W&&(D.effectTag|=4),w&&(W||fe)&&(D.effectTag|=4);break;case 7:break;case 8:break;case 12:break;case 4:Ec(D),Bl(D);break;case 10:Ci(D);break;case 9:break;case 14:break;case 17:ii(D.type)&&Ha(D);break;case 19:if(Vn($n,D),W=D.memoizedState,W===null)break;if(fe=(D.effectTag&64)!==0,De=W.rendering,De===null){if(fe)Pc(W,!1);else if(Yi!==Du||T!==null&&T.effectTag&64)for(T=D.child;T!==null;){if(De=cp(T),De!==null){for(D.effectTag|=64,Pc(W,!1),T=De.updateQueue,T!==null&&(D.updateQueue=T,D.effectTag|=4),W.lastEffect===null&&(D.firstEffect=null),D.lastEffect=W.lastEffect,T=q,W=D.child;W!==null;)fe=W,q=T,fe.effectTag&=2,fe.nextEffect=null,fe.firstEffect=null,fe.lastEffect=null,De=fe.alternate,De===null?(fe.childExpirationTime=0,fe.expirationTime=q,fe.child=null,fe.memoizedProps=null,fe.memoizedState=null,fe.updateQueue=null,fe.dependencies=null):(fe.childExpirationTime=De.childExpirationTime,fe.expirationTime=De.expirationTime,fe.child=De.child,fe.memoizedProps=De.memoizedProps,fe.memoizedState=De.memoizedState,fe.updateQueue=De.updateQueue,q=De.dependencies,fe.dependencies=q===null?null:{expirationTime:q.expirationTime,firstContext:q.firstContext,responders:q.responders}),W=W.sibling;Mn($n,$n.current&1|2,D),D=D.child;break e}T=T.sibling}}else{if(!fe)if(T=cp(De),T!==null){if(D.effectTag|=64,fe=!0,T=T.updateQueue,T!==null&&(D.updateQueue=T,D.effectTag|=4),Pc(W,!0),W.tail===null&&W.tailMode==="hidden"&&!De.alternate){D=D.lastEffect=W.lastEffect,D!==null&&(D.nextEffect=null);break}}else Ni()>W.tailExpiration&&1W&&(W=q),De>W&&(W=De),fe=fe.sibling;T.childExpirationTime=W}if(D!==null)return D;P!==null&&!(P.effectTag&2048)&&(P.firstEffect===null&&(P.firstEffect=Mr.firstEffect),Mr.lastEffect!==null&&(P.lastEffect!==null&&(P.lastEffect.nextEffect=Mr.firstEffect),P.lastEffect=Mr.lastEffect),1P?D:P}function xu(P){var D=_o();return lo(99,nF.bind(null,P,D)),null}function nF(P,D){do Cp();while(E0!==null);if((yr&(is|Gs))!==En)throw Error(n(327));var T=P.finishedWork,q=P.finishedExpirationTime;if(T===null)return null;if(P.finishedWork=null,P.finishedExpirationTime=0,T===P.current)throw Error(n(177));P.callbackNode=null,P.callbackExpirationTime=0,P.callbackPriority=90,P.nextKnownPendingLevel=0;var W=Aw(T);if(P.firstPendingTime=W,q<=P.lastSuspendedTime?P.firstSuspendedTime=P.lastSuspendedTime=P.nextKnownPendingLevel=0:q<=P.firstSuspendedTime&&(P.firstSuspendedTime=q-1),q<=P.lastPingedTime&&(P.lastPingedTime=0),q<=P.lastExpiredTime&&(P.lastExpiredTime=0),P===gi&&(Mr=gi=null,ss=0),1=T?cn(P,D,T):(Mn($n,$n.current&1,D),D=si(P,D,T),D!==null?D.sibling:null);Mn($n,$n.current&1,D);break;case 19:if(q=D.childExpirationTime>=T,P.effectTag&64){if(q)return Ya(P,D,T);D.effectTag|=64}if(W=D.memoizedState,W!==null&&(W.rendering=null,W.tail=null),Mn($n,$n.current,D),!q)return null}return si(P,D,T)}jo=!1}}else jo=!1;switch(D.expirationTime=0,D.tag){case 2:if(q=D.type,P!==null&&(P.alternate=null,D.alternate=null,D.effectTag|=2),P=D.pendingProps,W=Me(D,On.current),ys(D,T),W=s0(null,D,q,P,W,T),D.effectTag|=1,typeof W=="object"&&W!==null&&typeof W.render=="function"&&W.$$typeof===void 0){if(D.tag=1,tw(),ii(q)){var fe=!0;fc(D)}else fe=!1;D.memoizedState=W.state!==null&&W.state!==void 0?W.state:null;var De=q.getDerivedStateFromProps;typeof De=="function"&&rr(D,q,De,P),W.updater=$r,D.stateNode=W,W._reactInternalFiber=D,qo(D,q,P,T),D=gp(null,D,q,!0,fe,T)}else D.tag=0,Bs(null,D,W,T),D=D.child;return D;case 16:if(W=D.elementType,P!==null&&(P.alternate=null,D.alternate=null,D.effectTag|=2),P=D.pendingProps,Ce(W),W._status!==1)throw W._result;switch(W=W._result,D.type=W,fe=D.tag=uF(W),P=Ei(W,P),fe){case 0:D=NA(null,D,W,P,T);break;case 1:D=hp(null,D,W,P,T);break;case 11:D=wi(null,D,W,P,T);break;case 14:D=yd(null,D,W,Ei(W.type,P),q,T);break;default:throw Error(n(306,W,""))}return D;case 0:return q=D.type,W=D.pendingProps,W=D.elementType===q?W:Ei(q,W),NA(P,D,q,W,T);case 1:return q=D.type,W=D.pendingProps,W=D.elementType===q?W:Ei(q,W),hp(P,D,q,W,T);case 3:if(h0(D),q=D.updateQueue,q===null)throw Error(n(282));if(W=D.memoizedState,W=W!==null?W.element:null,ye(D,q,D.pendingProps,null,T),q=D.memoizedState.element,q===W)p0(),D=si(P,D,T);else{if((W=D.stateNode.hydrate)&&(y?(vc=Au(D.stateNode.containerInfo),pa=D,W=Il=!0):W=!1),W)for(T=t0(D,null,q,T),D.child=T;T;)T.effectTag=T.effectTag&-3|1024,T=T.sibling;else Bs(P,D,q,T),p0();D=D.child}return D;case 5:return hd(D),P===null&&TA(D),q=D.type,W=D.pendingProps,fe=P!==null?P.memoizedProps:null,De=W.children,Fe(q,W)?De=null:fe!==null&&Fe(q,fe)&&(D.effectTag|=16),Go(P,D),D.mode&4&&T!==1&&ke(q,W)?(D.expirationTime=D.childExpirationTime=1,D=null):(Bs(P,D,De,T),D=D.child),D;case 6:return P===null&&TA(D),null;case 13:return cn(P,D,T);case 4:return r0(D,D.stateNode.containerInfo),q=D.pendingProps,P===null?D.child=mu(D,null,q,T):Bs(P,D,q,T),D.child;case 11:return q=D.type,W=D.pendingProps,W=D.elementType===q?W:Ei(q,W),wi(P,D,q,W,T);case 7:return Bs(P,D,D.pendingProps,T),D.child;case 8:return Bs(P,D,D.pendingProps.children,T),D.child;case 12:return Bs(P,D,D.pendingProps.children,T),D.child;case 10:e:{if(q=D.type._context,W=D.pendingProps,De=D.memoizedProps,fe=W.value,Ho(D,fe),De!==null){var vt=De.value;if(fe=ds(vt,fe)?0:(typeof q._calculateChangedBits=="function"?q._calculateChangedBits(vt,fe):1073741823)|0,fe===0){if(De.children===W.children&&!_i.current){D=si(P,D,T);break e}}else for(vt=D.child,vt!==null&&(vt.return=D);vt!==null;){var wt=vt.dependencies;if(wt!==null){De=vt.child;for(var St=wt.firstContext;St!==null;){if(St.context===q&&St.observedBits&fe){vt.tag===1&&(St=Cs(T,null),St.tag=2,tt(vt,St)),vt.expirationTime"u")return!1;var D=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(D.isDisabled||!D.supportsFiber)return!0;try{var T=D.inject(P);fw=function(q){try{D.onCommitFiberRoot(T,q,void 0,(q.current.effectTag&64)===64)}catch{}},pw=function(q){try{D.onCommitFiberUnmount(T,q)}catch{}}}catch{}return!0}function cF(P,D,T,q){this.tag=P,this.key=T,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=D,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=q,this.effectTag=0,this.lastEffect=this.firstEffect=this.nextEffect=null,this.childExpirationTime=this.expirationTime=0,this.alternate=null}function Dl(P,D,T,q){return new cF(P,D,T,q)}function hw(P){return P=P.prototype,!(!P||!P.isReactComponent)}function uF(P){if(typeof P=="function")return hw(P)?1:0;if(P!=null){if(P=P.$$typeof,P===L)return 11;if(P===te)return 14}return 2}function YA(P,D){var T=P.alternate;return T===null?(T=Dl(P.tag,D,P.key,P.mode),T.elementType=P.elementType,T.type=P.type,T.stateNode=P.stateNode,T.alternate=P,P.alternate=T):(T.pendingProps=D,T.effectTag=0,T.nextEffect=null,T.firstEffect=null,T.lastEffect=null),T.childExpirationTime=P.childExpirationTime,T.expirationTime=P.expirationTime,T.child=P.child,T.memoizedProps=P.memoizedProps,T.memoizedState=P.memoizedState,T.updateQueue=P.updateQueue,D=P.dependencies,T.dependencies=D===null?null:{expirationTime:D.expirationTime,firstContext:D.firstContext,responders:D.responders},T.sibling=P.sibling,T.index=P.index,T.ref=P.ref,T}function xd(P,D,T,q,W,fe){var De=2;if(q=P,typeof P=="function")hw(P)&&(De=1);else if(typeof P=="string")De=5;else e:switch(P){case E:return ku(T.children,W,fe,D);case R:De=8,W|=7;break;case I:De=8,W|=1;break;case v:return P=Dl(12,T,D,W|8),P.elementType=v,P.type=v,P.expirationTime=fe,P;case U:return P=Dl(13,T,D,W),P.type=U,P.elementType=U,P.expirationTime=fe,P;case z:return P=Dl(19,T,D,W),P.elementType=z,P.expirationTime=fe,P;default:if(typeof P=="object"&&P!==null)switch(P.$$typeof){case x:De=10;break e;case C:De=9;break e;case L:De=11;break e;case te:De=14;break e;case ae:De=16,q=null;break e}throw Error(n(130,P==null?P:typeof P,""))}return D=Dl(De,T,D,W),D.elementType=P,D.type=q,D.expirationTime=fe,D}function ku(P,D,T,q){return P=Dl(7,P,q,D),P.expirationTime=T,P}function gw(P,D,T){return P=Dl(6,P,null,D),P.expirationTime=T,P}function dw(P,D,T){return D=Dl(4,P.children!==null?P.children:[],P.key,D),D.expirationTime=T,D.stateNode={containerInfo:P.containerInfo,pendingChildren:null,implementation:P.implementation},D}function AF(P,D,T){this.tag=D,this.current=null,this.containerInfo=P,this.pingCache=this.pendingChildren=null,this.finishedExpirationTime=0,this.finishedWork=null,this.timeoutHandle=Ue,this.pendingContext=this.context=null,this.hydrate=T,this.callbackNode=null,this.callbackPriority=90,this.lastExpiredTime=this.lastPingedTime=this.nextKnownPendingLevel=this.lastSuspendedTime=this.firstSuspendedTime=this.firstPendingTime=0}function Lv(P,D){var T=P.firstSuspendedTime;return P=P.lastSuspendedTime,T!==0&&T>=D&&P<=D}function WA(P,D){var T=P.firstSuspendedTime,q=P.lastSuspendedTime;TD||T===0)&&(P.lastSuspendedTime=D),D<=P.lastPingedTime&&(P.lastPingedTime=0),D<=P.lastExpiredTime&&(P.lastExpiredTime=0)}function Mv(P,D){D>P.firstPendingTime&&(P.firstPendingTime=D);var T=P.firstSuspendedTime;T!==0&&(D>=T?P.firstSuspendedTime=P.lastSuspendedTime=P.nextKnownPendingLevel=0:D>=P.lastSuspendedTime&&(P.lastSuspendedTime=D+1),D>P.nextKnownPendingLevel&&(P.nextKnownPendingLevel=D))}function kd(P,D){var T=P.lastExpiredTime;(T===0||T>D)&&(P.lastExpiredTime=D)}function Ov(P){var D=P._reactInternalFiber;if(D===void 0)throw typeof P.render=="function"?Error(n(188)):Error(n(268,Object.keys(P)));return P=me(D),P===null?null:P.stateNode}function Uv(P,D){P=P.memoizedState,P!==null&&P.dehydrated!==null&&P.retryTime{"use strict";QEe.exports=kEe()});var TEe=_((vKt,REe)=>{"use strict";var Kyt={ALIGN_COUNT:8,ALIGN_AUTO:0,ALIGN_FLEX_START:1,ALIGN_CENTER:2,ALIGN_FLEX_END:3,ALIGN_STRETCH:4,ALIGN_BASELINE:5,ALIGN_SPACE_BETWEEN:6,ALIGN_SPACE_AROUND:7,DIMENSION_COUNT:2,DIMENSION_WIDTH:0,DIMENSION_HEIGHT:1,DIRECTION_COUNT:3,DIRECTION_INHERIT:0,DIRECTION_LTR:1,DIRECTION_RTL:2,DISPLAY_COUNT:2,DISPLAY_FLEX:0,DISPLAY_NONE:1,EDGE_COUNT:9,EDGE_LEFT:0,EDGE_TOP:1,EDGE_RIGHT:2,EDGE_BOTTOM:3,EDGE_START:4,EDGE_END:5,EDGE_HORIZONTAL:6,EDGE_VERTICAL:7,EDGE_ALL:8,EXPERIMENTAL_FEATURE_COUNT:1,EXPERIMENTAL_FEATURE_WEB_FLEX_BASIS:0,FLEX_DIRECTION_COUNT:4,FLEX_DIRECTION_COLUMN:0,FLEX_DIRECTION_COLUMN_REVERSE:1,FLEX_DIRECTION_ROW:2,FLEX_DIRECTION_ROW_REVERSE:3,JUSTIFY_COUNT:6,JUSTIFY_FLEX_START:0,JUSTIFY_CENTER:1,JUSTIFY_FLEX_END:2,JUSTIFY_SPACE_BETWEEN:3,JUSTIFY_SPACE_AROUND:4,JUSTIFY_SPACE_EVENLY:5,LOG_LEVEL_COUNT:6,LOG_LEVEL_ERROR:0,LOG_LEVEL_WARN:1,LOG_LEVEL_INFO:2,LOG_LEVEL_DEBUG:3,LOG_LEVEL_VERBOSE:4,LOG_LEVEL_FATAL:5,MEASURE_MODE_COUNT:3,MEASURE_MODE_UNDEFINED:0,MEASURE_MODE_EXACTLY:1,MEASURE_MODE_AT_MOST:2,NODE_TYPE_COUNT:2,NODE_TYPE_DEFAULT:0,NODE_TYPE_TEXT:1,OVERFLOW_COUNT:3,OVERFLOW_VISIBLE:0,OVERFLOW_HIDDEN:1,OVERFLOW_SCROLL:2,POSITION_TYPE_COUNT:2,POSITION_TYPE_RELATIVE:0,POSITION_TYPE_ABSOLUTE:1,PRINT_OPTIONS_COUNT:3,PRINT_OPTIONS_LAYOUT:1,PRINT_OPTIONS_STYLE:2,PRINT_OPTIONS_CHILDREN:4,UNIT_COUNT:4,UNIT_UNDEFINED:0,UNIT_POINT:1,UNIT_PERCENT:2,UNIT_AUTO:3,WRAP_COUNT:3,WRAP_NO_WRAP:0,WRAP_WRAP:1,WRAP_WRAP_REVERSE:2};REe.exports=Kyt});var OEe=_((DKt,MEe)=>{"use strict";var Vyt=Object.assign||function(t){for(var e=1;e"}}]),t}(),NEe=function(){Nk(t,null,[{key:"fromJS",value:function(r){var o=r.width,a=r.height;return new t(o,a)}}]);function t(e,r){B6(this,t),this.width=e,this.height=r}return Nk(t,[{key:"fromJS",value:function(r){r(this.width,this.height)}},{key:"toString",value:function(){return""}}]),t}(),LEe=function(){function t(e,r){B6(this,t),this.unit=e,this.value=r}return Nk(t,[{key:"fromJS",value:function(r){r(this.unit,this.value)}},{key:"toString",value:function(){switch(this.unit){case nu.UNIT_POINT:return String(this.value);case nu.UNIT_PERCENT:return this.value+"%";case nu.UNIT_AUTO:return"auto";default:return this.value+"?"}}},{key:"valueOf",value:function(){return this.value}}]),t}();MEe.exports=function(t,e){function r(u,A,p){var h=u[A];u[A]=function(){for(var E=arguments.length,I=Array(E),v=0;v1?I-1:0),x=1;x1&&arguments[1]!==void 0?arguments[1]:NaN,p=arguments.length>2&&arguments[2]!==void 0?arguments[2]:NaN,h=arguments.length>3&&arguments[3]!==void 0?arguments[3]:nu.DIRECTION_LTR;return u.call(this,A,p,h)}),Vyt({Config:e.Config,Node:e.Node,Layout:t("Layout",zyt),Size:t("Size",NEe),Value:t("Value",LEe),getInstanceCount:function(){return e.getInstanceCount.apply(e,arguments)}},nu)}});var UEe=_((exports,module)=>{(function(t,e){typeof define=="function"&&define.amd?define([],function(){return e}):typeof module=="object"&&module.exports?module.exports=e:(t.nbind=t.nbind||{}).init=e})(exports,function(Module,cb){typeof Module=="function"&&(cb=Module,Module={}),Module.onRuntimeInitialized=function(t,e){return function(){t&&t.apply(this,arguments);try{Module.ccall("nbind_init")}catch(r){e(r);return}e(null,{bind:Module._nbind_value,reflect:Module.NBind.reflect,queryType:Module.NBind.queryType,toggleLightGC:Module.toggleLightGC,lib:Module})}}(Module.onRuntimeInitialized,cb);var Module;Module||(Module=(typeof Module<"u"?Module:null)||{});var moduleOverrides={};for(var key in Module)Module.hasOwnProperty(key)&&(moduleOverrides[key]=Module[key]);var ENVIRONMENT_IS_WEB=!1,ENVIRONMENT_IS_WORKER=!1,ENVIRONMENT_IS_NODE=!1,ENVIRONMENT_IS_SHELL=!1;if(Module.ENVIRONMENT)if(Module.ENVIRONMENT==="WEB")ENVIRONMENT_IS_WEB=!0;else if(Module.ENVIRONMENT==="WORKER")ENVIRONMENT_IS_WORKER=!0;else if(Module.ENVIRONMENT==="NODE")ENVIRONMENT_IS_NODE=!0;else if(Module.ENVIRONMENT==="SHELL")ENVIRONMENT_IS_SHELL=!0;else throw new Error("The provided Module['ENVIRONMENT'] value is not valid. It must be one of: WEB|WORKER|NODE|SHELL.");else ENVIRONMENT_IS_WEB=typeof window=="object",ENVIRONMENT_IS_WORKER=typeof importScripts=="function",ENVIRONMENT_IS_NODE=typeof process=="object"&&typeof ve=="function"&&!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_WORKER,ENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER;if(ENVIRONMENT_IS_NODE){Module.print||(Module.print=console.log),Module.printErr||(Module.printErr=console.warn);var nodeFS,nodePath;Module.read=function(e,r){nodeFS||(nodeFS={}("")),nodePath||(nodePath={}("")),e=nodePath.normalize(e);var o=nodeFS.readFileSync(e);return r?o:o.toString()},Module.readBinary=function(e){var r=Module.read(e,!0);return r.buffer||(r=new Uint8Array(r)),assert(r.buffer),r},Module.load=function(e){globalEval(read(e))},Module.thisProgram||(process.argv.length>1?Module.thisProgram=process.argv[1].replace(/\\/g,"/"):Module.thisProgram="unknown-program"),Module.arguments=process.argv.slice(2),typeof module<"u"&&(module.exports=Module),Module.inspect=function(){return"[Emscripten Module object]"}}else if(ENVIRONMENT_IS_SHELL)Module.print||(Module.print=print),typeof printErr<"u"&&(Module.printErr=printErr),typeof read<"u"?Module.read=read:Module.read=function(){throw"no read() available"},Module.readBinary=function(e){if(typeof readbuffer=="function")return new Uint8Array(readbuffer(e));var r=read(e,"binary");return assert(typeof r=="object"),r},typeof scriptArgs<"u"?Module.arguments=scriptArgs:typeof arguments<"u"&&(Module.arguments=arguments),typeof quit=="function"&&(Module.quit=function(t,e){quit(t)});else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(Module.read=function(e){var r=new XMLHttpRequest;return r.open("GET",e,!1),r.send(null),r.responseText},ENVIRONMENT_IS_WORKER&&(Module.readBinary=function(e){var r=new XMLHttpRequest;return r.open("GET",e,!1),r.responseType="arraybuffer",r.send(null),new Uint8Array(r.response)}),Module.readAsync=function(e,r,o){var a=new XMLHttpRequest;a.open("GET",e,!0),a.responseType="arraybuffer",a.onload=function(){a.status==200||a.status==0&&a.response?r(a.response):o()},a.onerror=o,a.send(null)},typeof arguments<"u"&&(Module.arguments=arguments),typeof console<"u")Module.print||(Module.print=function(e){console.log(e)}),Module.printErr||(Module.printErr=function(e){console.warn(e)});else{var TRY_USE_DUMP=!1;Module.print||(Module.print=TRY_USE_DUMP&&typeof dump<"u"?function(t){dump(t)}:function(t){})}ENVIRONMENT_IS_WORKER&&(Module.load=importScripts),typeof Module.setWindowTitle>"u"&&(Module.setWindowTitle=function(t){document.title=t})}else throw"Unknown runtime environment. Where are we?";function globalEval(t){eval.call(null,t)}!Module.load&&Module.read&&(Module.load=function(e){globalEval(Module.read(e))}),Module.print||(Module.print=function(){}),Module.printErr||(Module.printErr=Module.print),Module.arguments||(Module.arguments=[]),Module.thisProgram||(Module.thisProgram="./this.program"),Module.quit||(Module.quit=function(t,e){throw e}),Module.print=Module.print,Module.printErr=Module.printErr,Module.preRun=[],Module.postRun=[];for(var key in moduleOverrides)moduleOverrides.hasOwnProperty(key)&&(Module[key]=moduleOverrides[key]);moduleOverrides=void 0;var Runtime={setTempRet0:function(t){return tempRet0=t,t},getTempRet0:function(){return tempRet0},stackSave:function(){return STACKTOP},stackRestore:function(t){STACKTOP=t},getNativeTypeSize:function(t){switch(t){case"i1":case"i8":return 1;case"i16":return 2;case"i32":return 4;case"i64":return 8;case"float":return 4;case"double":return 8;default:{if(t[t.length-1]==="*")return Runtime.QUANTUM_SIZE;if(t[0]==="i"){var e=parseInt(t.substr(1));return assert(e%8===0),e/8}else return 0}}},getNativeFieldSize:function(t){return Math.max(Runtime.getNativeTypeSize(t),Runtime.QUANTUM_SIZE)},STACK_ALIGN:16,prepVararg:function(t,e){return e==="double"||e==="i64"?t&7&&(assert((t&7)===4),t+=4):assert((t&3)===0),t},getAlignSize:function(t,e,r){return!r&&(t=="i64"||t=="double")?8:t?Math.min(e||(t?Runtime.getNativeFieldSize(t):0),Runtime.QUANTUM_SIZE):Math.min(e,8)},dynCall:function(t,e,r){return r&&r.length?Module["dynCall_"+t].apply(null,[e].concat(r)):Module["dynCall_"+t].call(null,e)},functionPointers:[],addFunction:function(t){for(var e=0;e>2],r=(e+t+15|0)&-16;if(HEAP32[DYNAMICTOP_PTR>>2]=r,r>=TOTAL_MEMORY){var o=enlargeMemory();if(!o)return HEAP32[DYNAMICTOP_PTR>>2]=e,0}return e},alignMemory:function(t,e){var r=t=Math.ceil(t/(e||16))*(e||16);return r},makeBigInt:function(t,e,r){var o=r?+(t>>>0)+ +(e>>>0)*4294967296:+(t>>>0)+ +(e|0)*4294967296;return o},GLOBAL_BASE:8,QUANTUM_SIZE:4,__dummy__:0};Module.Runtime=Runtime;var ABORT=0,EXITSTATUS=0;function assert(t,e){t||abort("Assertion failed: "+e)}function getCFunc(ident){var func=Module["_"+ident];if(!func)try{func=eval("_"+ident)}catch(t){}return assert(func,"Cannot call unknown function "+ident+" (perhaps LLVM optimizations or closure removed it?)"),func}var cwrap,ccall;(function(){var JSfuncs={stackSave:function(){Runtime.stackSave()},stackRestore:function(){Runtime.stackRestore()},arrayToC:function(t){var e=Runtime.stackAlloc(t.length);return writeArrayToMemory(t,e),e},stringToC:function(t){var e=0;if(t!=null&&t!==0){var r=(t.length<<2)+1;e=Runtime.stackAlloc(r),stringToUTF8(t,e,r)}return e}},toC={string:JSfuncs.stringToC,array:JSfuncs.arrayToC};ccall=function(e,r,o,a,n){var u=getCFunc(e),A=[],p=0;if(a)for(var h=0;h>0]=e;break;case"i8":HEAP8[t>>0]=e;break;case"i16":HEAP16[t>>1]=e;break;case"i32":HEAP32[t>>2]=e;break;case"i64":tempI64=[e>>>0,(tempDouble=e,+Math_abs(tempDouble)>=1?tempDouble>0?(Math_min(+Math_floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math_ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[t>>2]=tempI64[0],HEAP32[t+4>>2]=tempI64[1];break;case"float":HEAPF32[t>>2]=e;break;case"double":HEAPF64[t>>3]=e;break;default:abort("invalid type for setValue: "+r)}}Module.setValue=setValue;function getValue(t,e,r){switch(e=e||"i8",e.charAt(e.length-1)==="*"&&(e="i32"),e){case"i1":return HEAP8[t>>0];case"i8":return HEAP8[t>>0];case"i16":return HEAP16[t>>1];case"i32":return HEAP32[t>>2];case"i64":return HEAP32[t>>2];case"float":return HEAPF32[t>>2];case"double":return HEAPF64[t>>3];default:abort("invalid type for setValue: "+e)}return null}Module.getValue=getValue;var ALLOC_NORMAL=0,ALLOC_STACK=1,ALLOC_STATIC=2,ALLOC_DYNAMIC=3,ALLOC_NONE=4;Module.ALLOC_NORMAL=ALLOC_NORMAL,Module.ALLOC_STACK=ALLOC_STACK,Module.ALLOC_STATIC=ALLOC_STATIC,Module.ALLOC_DYNAMIC=ALLOC_DYNAMIC,Module.ALLOC_NONE=ALLOC_NONE;function allocate(t,e,r,o){var a,n;typeof t=="number"?(a=!0,n=t):(a=!1,n=t.length);var u=typeof e=="string"?e:null,A;if(r==ALLOC_NONE?A=o:A=[typeof _malloc=="function"?_malloc:Runtime.staticAlloc,Runtime.stackAlloc,Runtime.staticAlloc,Runtime.dynamicAlloc][r===void 0?ALLOC_STATIC:r](Math.max(n,u?1:e.length)),a){var o=A,p;for(assert((A&3)==0),p=A+(n&-4);o>2]=0;for(p=A+n;o>0]=0;return A}if(u==="i8")return t.subarray||t.slice?HEAPU8.set(t,A):HEAPU8.set(new Uint8Array(t),A),A;for(var h=0,E,I,v;h>0],r|=o,!(o==0&&!e||(a++,e&&a==e)););e||(e=a);var n="";if(r<128){for(var u=1024,A;e>0;)A=String.fromCharCode.apply(String,HEAPU8.subarray(t,t+Math.min(e,u))),n=n?n+A:A,t+=u,e-=u;return n}return Module.UTF8ToString(t)}Module.Pointer_stringify=Pointer_stringify;function AsciiToString(t){for(var e="";;){var r=HEAP8[t++>>0];if(!r)return e;e+=String.fromCharCode(r)}}Module.AsciiToString=AsciiToString;function stringToAscii(t,e){return writeAsciiToMemory(t,e,!1)}Module.stringToAscii=stringToAscii;var UTF8Decoder=typeof TextDecoder<"u"?new TextDecoder("utf8"):void 0;function UTF8ArrayToString(t,e){for(var r=e;t[r];)++r;if(r-e>16&&t.subarray&&UTF8Decoder)return UTF8Decoder.decode(t.subarray(e,r));for(var o,a,n,u,A,p,h="";;){if(o=t[e++],!o)return h;if(!(o&128)){h+=String.fromCharCode(o);continue}if(a=t[e++]&63,(o&224)==192){h+=String.fromCharCode((o&31)<<6|a);continue}if(n=t[e++]&63,(o&240)==224?o=(o&15)<<12|a<<6|n:(u=t[e++]&63,(o&248)==240?o=(o&7)<<18|a<<12|n<<6|u:(A=t[e++]&63,(o&252)==248?o=(o&3)<<24|a<<18|n<<12|u<<6|A:(p=t[e++]&63,o=(o&1)<<30|a<<24|n<<18|u<<12|A<<6|p))),o<65536)h+=String.fromCharCode(o);else{var E=o-65536;h+=String.fromCharCode(55296|E>>10,56320|E&1023)}}}Module.UTF8ArrayToString=UTF8ArrayToString;function UTF8ToString(t){return UTF8ArrayToString(HEAPU8,t)}Module.UTF8ToString=UTF8ToString;function stringToUTF8Array(t,e,r,o){if(!(o>0))return 0;for(var a=r,n=r+o-1,u=0;u=55296&&A<=57343&&(A=65536+((A&1023)<<10)|t.charCodeAt(++u)&1023),A<=127){if(r>=n)break;e[r++]=A}else if(A<=2047){if(r+1>=n)break;e[r++]=192|A>>6,e[r++]=128|A&63}else if(A<=65535){if(r+2>=n)break;e[r++]=224|A>>12,e[r++]=128|A>>6&63,e[r++]=128|A&63}else if(A<=2097151){if(r+3>=n)break;e[r++]=240|A>>18,e[r++]=128|A>>12&63,e[r++]=128|A>>6&63,e[r++]=128|A&63}else if(A<=67108863){if(r+4>=n)break;e[r++]=248|A>>24,e[r++]=128|A>>18&63,e[r++]=128|A>>12&63,e[r++]=128|A>>6&63,e[r++]=128|A&63}else{if(r+5>=n)break;e[r++]=252|A>>30,e[r++]=128|A>>24&63,e[r++]=128|A>>18&63,e[r++]=128|A>>12&63,e[r++]=128|A>>6&63,e[r++]=128|A&63}}return e[r]=0,r-a}Module.stringToUTF8Array=stringToUTF8Array;function stringToUTF8(t,e,r){return stringToUTF8Array(t,HEAPU8,e,r)}Module.stringToUTF8=stringToUTF8;function lengthBytesUTF8(t){for(var e=0,r=0;r=55296&&o<=57343&&(o=65536+((o&1023)<<10)|t.charCodeAt(++r)&1023),o<=127?++e:o<=2047?e+=2:o<=65535?e+=3:o<=2097151?e+=4:o<=67108863?e+=5:e+=6}return e}Module.lengthBytesUTF8=lengthBytesUTF8;var UTF16Decoder=typeof TextDecoder<"u"?new TextDecoder("utf-16le"):void 0;function demangle(t){var e=Module.___cxa_demangle||Module.__cxa_demangle;if(e){try{var r=t.substr(1),o=lengthBytesUTF8(r)+1,a=_malloc(o);stringToUTF8(r,a,o);var n=_malloc(4),u=e(a,0,0,n);if(getValue(n,"i32")===0&&u)return Pointer_stringify(u)}catch{}finally{a&&_free(a),n&&_free(n),u&&_free(u)}return t}return Runtime.warnOnce("warning: build with -s DEMANGLE_SUPPORT=1 to link in libcxxabi demangling"),t}function demangleAll(t){var e=/__Z[\w\d_]+/g;return t.replace(e,function(r){var o=demangle(r);return r===o?r:r+" ["+o+"]"})}function jsStackTrace(){var t=new Error;if(!t.stack){try{throw new Error(0)}catch(e){t=e}if(!t.stack)return"(no stack trace available)"}return t.stack.toString()}function stackTrace(){var t=jsStackTrace();return Module.extraStackTrace&&(t+=` +`+Module.extraStackTrace()),demangleAll(t)}Module.stackTrace=stackTrace;var HEAP,buffer,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateGlobalBufferViews(){Module.HEAP8=HEAP8=new Int8Array(buffer),Module.HEAP16=HEAP16=new Int16Array(buffer),Module.HEAP32=HEAP32=new Int32Array(buffer),Module.HEAPU8=HEAPU8=new Uint8Array(buffer),Module.HEAPU16=HEAPU16=new Uint16Array(buffer),Module.HEAPU32=HEAPU32=new Uint32Array(buffer),Module.HEAPF32=HEAPF32=new Float32Array(buffer),Module.HEAPF64=HEAPF64=new Float64Array(buffer)}var STATIC_BASE,STATICTOP,staticSealed,STACK_BASE,STACKTOP,STACK_MAX,DYNAMIC_BASE,DYNAMICTOP_PTR;STATIC_BASE=STATICTOP=STACK_BASE=STACKTOP=STACK_MAX=DYNAMIC_BASE=DYNAMICTOP_PTR=0,staticSealed=!1;function abortOnCannotGrowMemory(){abort("Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value "+TOTAL_MEMORY+", (2) compile with -s ALLOW_MEMORY_GROWTH=1 which allows increasing the size at runtime but prevents some optimizations, (3) set Module.TOTAL_MEMORY to a higher value before the program runs, or (4) if you want malloc to return NULL (0) instead of this abort, compile with -s ABORTING_MALLOC=0 ")}function enlargeMemory(){abortOnCannotGrowMemory()}var TOTAL_STACK=Module.TOTAL_STACK||5242880,TOTAL_MEMORY=Module.TOTAL_MEMORY||134217728;TOTAL_MEMORY0;){var e=t.shift();if(typeof e=="function"){e();continue}var r=e.func;typeof r=="number"?e.arg===void 0?Module.dynCall_v(r):Module.dynCall_vi(r,e.arg):r(e.arg===void 0?null:e.arg)}}var __ATPRERUN__=[],__ATINIT__=[],__ATMAIN__=[],__ATEXIT__=[],__ATPOSTRUN__=[],runtimeInitialized=!1,runtimeExited=!1;function preRun(){if(Module.preRun)for(typeof Module.preRun=="function"&&(Module.preRun=[Module.preRun]);Module.preRun.length;)addOnPreRun(Module.preRun.shift());callRuntimeCallbacks(__ATPRERUN__)}function ensureInitRuntime(){runtimeInitialized||(runtimeInitialized=!0,callRuntimeCallbacks(__ATINIT__))}function preMain(){callRuntimeCallbacks(__ATMAIN__)}function exitRuntime(){callRuntimeCallbacks(__ATEXIT__),runtimeExited=!0}function postRun(){if(Module.postRun)for(typeof Module.postRun=="function"&&(Module.postRun=[Module.postRun]);Module.postRun.length;)addOnPostRun(Module.postRun.shift());callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(t){__ATPRERUN__.unshift(t)}Module.addOnPreRun=addOnPreRun;function addOnInit(t){__ATINIT__.unshift(t)}Module.addOnInit=addOnInit;function addOnPreMain(t){__ATMAIN__.unshift(t)}Module.addOnPreMain=addOnPreMain;function addOnExit(t){__ATEXIT__.unshift(t)}Module.addOnExit=addOnExit;function addOnPostRun(t){__ATPOSTRUN__.unshift(t)}Module.addOnPostRun=addOnPostRun;function intArrayFromString(t,e,r){var o=r>0?r:lengthBytesUTF8(t)+1,a=new Array(o),n=stringToUTF8Array(t,a,0,a.length);return e&&(a.length=n),a}Module.intArrayFromString=intArrayFromString;function intArrayToString(t){for(var e=[],r=0;r255&&(o&=255),e.push(String.fromCharCode(o))}return e.join("")}Module.intArrayToString=intArrayToString;function writeStringToMemory(t,e,r){Runtime.warnOnce("writeStringToMemory is deprecated and should not be called! Use stringToUTF8() instead!");var o,a;r&&(a=e+lengthBytesUTF8(t),o=HEAP8[a]),stringToUTF8(t,e,1/0),r&&(HEAP8[a]=o)}Module.writeStringToMemory=writeStringToMemory;function writeArrayToMemory(t,e){HEAP8.set(t,e)}Module.writeArrayToMemory=writeArrayToMemory;function writeAsciiToMemory(t,e,r){for(var o=0;o>0]=t.charCodeAt(o);r||(HEAP8[e>>0]=0)}if(Module.writeAsciiToMemory=writeAsciiToMemory,(!Math.imul||Math.imul(4294967295,5)!==-5)&&(Math.imul=function t(e,r){var o=e>>>16,a=e&65535,n=r>>>16,u=r&65535;return a*u+(o*u+a*n<<16)|0}),Math.imul=Math.imul,!Math.fround){var froundBuffer=new Float32Array(1);Math.fround=function(t){return froundBuffer[0]=t,froundBuffer[0]}}Math.fround=Math.fround,Math.clz32||(Math.clz32=function(t){t=t>>>0;for(var e=0;e<32;e++)if(t&1<<31-e)return e;return 32}),Math.clz32=Math.clz32,Math.trunc||(Math.trunc=function(t){return t<0?Math.ceil(t):Math.floor(t)}),Math.trunc=Math.trunc;var Math_abs=Math.abs,Math_cos=Math.cos,Math_sin=Math.sin,Math_tan=Math.tan,Math_acos=Math.acos,Math_asin=Math.asin,Math_atan=Math.atan,Math_atan2=Math.atan2,Math_exp=Math.exp,Math_log=Math.log,Math_sqrt=Math.sqrt,Math_ceil=Math.ceil,Math_floor=Math.floor,Math_pow=Math.pow,Math_imul=Math.imul,Math_fround=Math.fround,Math_round=Math.round,Math_min=Math.min,Math_clz32=Math.clz32,Math_trunc=Math.trunc,runDependencies=0,runDependencyWatcher=null,dependenciesFulfilled=null;function getUniqueRunDependency(t){return t}function addRunDependency(t){runDependencies++,Module.monitorRunDependencies&&Module.monitorRunDependencies(runDependencies)}Module.addRunDependency=addRunDependency;function removeRunDependency(t){if(runDependencies--,Module.monitorRunDependencies&&Module.monitorRunDependencies(runDependencies),runDependencies==0&&(runDependencyWatcher!==null&&(clearInterval(runDependencyWatcher),runDependencyWatcher=null),dependenciesFulfilled)){var e=dependenciesFulfilled;dependenciesFulfilled=null,e()}}Module.removeRunDependency=removeRunDependency,Module.preloadedImages={},Module.preloadedAudios={};var ASM_CONSTS=[function(t,e,r,o,a,n,u,A){return _nbind.callbackSignatureList[t].apply(this,arguments)}];function _emscripten_asm_const_iiiiiiii(t,e,r,o,a,n,u,A){return ASM_CONSTS[t](e,r,o,a,n,u,A)}function _emscripten_asm_const_iiiii(t,e,r,o,a){return ASM_CONSTS[t](e,r,o,a)}function _emscripten_asm_const_iiidddddd(t,e,r,o,a,n,u,A,p){return ASM_CONSTS[t](e,r,o,a,n,u,A,p)}function _emscripten_asm_const_iiididi(t,e,r,o,a,n,u){return ASM_CONSTS[t](e,r,o,a,n,u)}function _emscripten_asm_const_iiii(t,e,r,o){return ASM_CONSTS[t](e,r,o)}function _emscripten_asm_const_iiiid(t,e,r,o,a){return ASM_CONSTS[t](e,r,o,a)}function _emscripten_asm_const_iiiiii(t,e,r,o,a,n){return ASM_CONSTS[t](e,r,o,a,n)}STATIC_BASE=Runtime.GLOBAL_BASE,STATICTOP=STATIC_BASE+12800,__ATINIT__.push({func:function(){__GLOBAL__sub_I_Yoga_cpp()}},{func:function(){__GLOBAL__sub_I_nbind_cc()}},{func:function(){__GLOBAL__sub_I_common_cc()}},{func:function(){__GLOBAL__sub_I_Binding_cc()}}),allocate([0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,127,0,0,192,127,0,0,192,127,0,0,192,127,3,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,3,0,0,0,0,0,192,127,3,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,127,0,0,192,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,127,0,0,0,0,0,0,0,0,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,127,0,0,192,127,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,0,0,128,191,0,0,128,191,0,0,192,127,0,0,0,0,0,0,0,0,0,0,128,63,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,3,0,0,0,1,0,0,0,2,0,0,0,0,0,0,0,190,12,0,0,200,12,0,0,208,12,0,0,216,12,0,0,230,12,0,0,242,12,0,0,1,0,0,0,3,0,0,0,0,0,0,0,2,0,0,0,0,0,192,127,3,0,0,0,180,45,0,0,181,45,0,0,182,45,0,0,181,45,0,0,182,45,0,0,0,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,3,0,0,0,1,0,0,0,4,0,0,0,183,45,0,0,181,45,0,0,181,45,0,0,181,45,0,0,181,45,0,0,181,45,0,0,181,45,0,0,184,45,0,0,185,45,0,0,181,45,0,0,181,45,0,0,182,45,0,0,186,45,0,0,185,45,0,0,148,4,0,0,3,0,0,0,187,45,0,0,164,4,0,0,188,45,0,0,2,0,0,0,189,45,0,0,164,4,0,0,188,45,0,0,185,45,0,0,164,4,0,0,185,45,0,0,164,4,0,0,188,45,0,0,181,45,0,0,182,45,0,0,181,45,0,0,0,0,0,0,0,0,0,0,1,0,0,0,5,0,0,0,6,0,0,0,1,0,0,0,7,0,0,0,183,45,0,0,182,45,0,0,181,45,0,0,190,45,0,0,190,45,0,0,182,45,0,0,182,45,0,0,185,45,0,0,181,45,0,0,185,45,0,0,182,45,0,0,181,45,0,0,185,45,0,0,182,45,0,0,185,45,0,0,48,5,0,0,3,0,0,0,56,5,0,0,1,0,0,0,189,45,0,0,185,45,0,0,164,4,0,0,76,5,0,0,2,0,0,0,191,45,0,0,186,45,0,0,182,45,0,0,185,45,0,0,192,45,0,0,185,45,0,0,182,45,0,0,186,45,0,0,185,45,0,0,76,5,0,0,76,5,0,0,136,5,0,0,182,45,0,0,181,45,0,0,2,0,0,0,190,45,0,0,136,5,0,0,56,19,0,0,156,5,0,0,2,0,0,0,184,45,0,0,0,0,0,0,0,0,0,0,1,0,0,0,8,0,0,0,9,0,0,0,1,0,0,0,10,0,0,0,204,5,0,0,181,45,0,0,181,45,0,0,2,0,0,0,180,45,0,0,204,5,0,0,2,0,0,0,195,45,0,0,236,5,0,0,97,19,0,0,198,45,0,0,211,45,0,0,212,45,0,0,213,45,0,0,214,45,0,0,215,45,0,0,188,45,0,0,182,45,0,0,216,45,0,0,217,45,0,0,218,45,0,0,219,45,0,0,192,45,0,0,181,45,0,0,0,0,0,0,185,45,0,0,110,19,0,0,186,45,0,0,115,19,0,0,221,45,0,0,120,19,0,0,148,4,0,0,132,19,0,0,96,6,0,0,145,19,0,0,222,45,0,0,164,19,0,0,223,45,0,0,173,19,0,0,0,0,0,0,3,0,0,0,104,6,0,0,1,0,0,0,187,45,0,0,0,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,12,0,0,0,1,0,0,0,13,0,0,0,185,45,0,0,224,45,0,0,164,6,0,0,188,45,0,0,172,6,0,0,180,6,0,0,2,0,0,0,188,6,0,0,7,0,0,0,224,45,0,0,7,0,0,0,164,6,0,0,1,0,0,0,213,45,0,0,185,45,0,0,224,45,0,0,172,6,0,0,185,45,0,0,224,45,0,0,164,6,0,0,185,45,0,0,224,45,0,0,211,45,0,0,211,45,0,0,222,45,0,0,211,45,0,0,224,45,0,0,222,45,0,0,211,45,0,0,224,45,0,0,172,6,0,0,222,45,0,0,211,45,0,0,224,45,0,0,188,45,0,0,222,45,0,0,211,45,0,0,40,7,0,0,188,45,0,0,2,0,0,0,224,45,0,0,185,45,0,0,188,45,0,0,188,45,0,0,188,45,0,0,188,45,0,0,222,45,0,0,224,45,0,0,148,4,0,0,185,45,0,0,148,4,0,0,148,4,0,0,148,4,0,0,148,4,0,0,148,4,0,0,185,45,0,0,164,6,0,0,148,4,0,0,0,0,0,0,0,0,0,0,1,0,0,0,14,0,0,0,15,0,0,0,1,0,0,0,16,0,0,0,148,7,0,0,2,0,0,0,225,45,0,0,183,45,0,0,188,45,0,0,168,7,0,0,5,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,234,45,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,148,45,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,28,9,0,0,5,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,2,0,0,0,242,45,0,0,0,4,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67,111,117,108,100,32,110,111,116,32,97,108,108,111,99,97,116,101,32,109,101,109,111,114,121,32,102,111,114,32,110,111,100,101,0,67,97,110,110,111,116,32,114,101,115,101,116,32,97,32,110,111,100,101,32,119,104,105,99,104,32,115,116,105,108,108,32,104,97,115,32,99,104,105,108,100,114,101,110,32,97,116,116,97,99,104,101,100,0,67,97,110,110,111,116,32,114,101,115,101,116,32,97,32,110,111,100,101,32,115,116,105,108,108,32,97,116,116,97,99,104,101,100,32,116,111,32,97,32,112,97,114,101,110,116,0,67,111,117,108,100,32,110,111,116,32,97,108,108,111,99,97,116,101,32,109,101,109,111,114,121,32,102,111,114,32,99,111,110,102,105,103,0,67,97,110,110,111,116,32,115,101,116,32,109,101,97,115,117,114,101,32,102,117,110,99,116,105,111,110,58,32,78,111,100,101,115,32,119,105,116,104,32,109,101,97,115,117,114,101,32,102,117,110,99,116,105,111,110,115,32,99,97,110,110,111,116,32,104,97,118,101,32,99,104,105,108,100,114,101,110,46,0,67,104,105,108,100,32,97,108,114,101,97,100,121,32,104,97,115,32,97,32,112,97,114,101,110,116,44,32,105,116,32,109,117,115,116,32,98,101,32,114,101,109,111,118,101,100,32,102,105,114,115,116,46,0,67,97,110,110,111,116,32,97,100,100,32,99,104,105,108,100,58,32,78,111,100,101,115,32,119,105,116,104,32,109,101,97,115,117,114,101,32,102,117,110,99,116,105,111,110,115,32,99,97,110,110,111,116,32,104,97,118,101,32,99,104,105,108,100,114,101,110,46,0,79,110,108,121,32,108,101,97,102,32,110,111,100,101,115,32,119,105,116,104,32,99,117,115,116,111,109,32,109,101,97,115,117,114,101,32,102,117,110,99,116,105,111,110,115,115,104,111,117,108,100,32,109,97,110,117,97,108,108,121,32,109,97,114,107,32,116,104,101,109,115,101,108,118,101,115,32,97,115,32,100,105,114,116,121,0,67,97,110,110,111,116,32,103,101,116,32,108,97,121,111,117,116,32,112,114,111,112,101,114,116,105,101,115,32,111,102,32,109,117,108,116,105,45,101,100,103,101,32,115,104,111,114,116,104,97,110,100,115,0,37,115,37,100,46,123,91,115,107,105,112,112,101,100,93,32,0,119,109,58,32,37,115,44,32,104,109,58,32,37,115,44,32,97,119,58,32,37,102,32,97,104,58,32,37,102,32,61,62,32,100,58,32,40,37,102,44,32,37,102,41,32,37,115,10,0,37,115,37,100,46,123,37,115,0,42,0,119,109,58,32,37,115,44,32,104,109,58,32,37,115,44,32,97,119,58,32,37,102,32,97,104,58,32,37,102,32,37,115,10,0,37,115,37,100,46,125,37,115,0,119,109,58,32,37,115,44,32,104,109,58,32,37,115,44,32,100,58,32,40,37,102,44,32,37,102,41,32,37,115,10,0,79,117,116,32,111,102,32,99,97,99,104,101,32,101,110,116,114,105,101,115,33,10,0,83,99,97,108,101,32,102,97,99,116,111,114,32,115,104,111,117,108,100,32,110,111,116,32,98,101,32,108,101,115,115,32,116,104,97,110,32,122,101,114,111,0,105,110,105,116,105,97,108,0,37,115,10,0,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,0,85,78,68,69,70,73,78,69,68,0,69,88,65,67,84,76,89,0,65,84,95,77,79,83,84,0,76,65,89,95,85,78,68,69,70,73,78,69,68,0,76,65,89,95,69,88,65,67,84,76,89,0,76,65,89,95,65,84,95,77,79,83,84,0,97,118,97,105,108,97,98,108,101,87,105,100,116,104,32,105,115,32,105,110,100,101,102,105,110,105,116,101,32,115,111,32,119,105,100,116,104,77,101,97,115,117,114,101,77,111,100,101,32,109,117,115,116,32,98,101,32,89,71,77,101,97,115,117,114,101,77,111,100,101,85,110,100,101,102,105,110,101,100,0,97,118,97,105,108,97,98,108,101,72,101,105,103,104,116,32,105,115,32,105,110,100,101,102,105,110,105,116,101,32,115,111,32,104,101,105,103,104,116,77,101,97,115,117,114,101,77,111,100,101,32,109,117,115,116,32,98,101,32,89,71,77,101,97,115,117,114,101,77,111,100,101,85,110,100,101,102,105,110,101,100,0,102,108,101,120,0,115,116,114,101,116,99,104,0,109,117,108,116,105,108,105,110,101,45,115,116,114,101,116,99,104,0,69,120,112,101,99,116,101,100,32,110,111,100,101,32,116,111,32,104,97,118,101,32,99,117,115,116,111,109,32,109,101,97,115,117,114,101,32,102,117,110,99,116,105,111,110,0,109,101,97,115,117,114,101,0,69,120,112,101,99,116,32,99,117,115,116,111,109,32,98,97,115,101,108,105,110,101,32,102,117,110,99,116,105,111,110,32,116,111,32,110,111,116,32,114,101,116,117,114,110,32,78,97,78,0,97,98,115,45,109,101,97,115,117,114,101,0,97,98,115,45,108,97,121,111,117,116,0,78,111,100,101,0,99,114,101,97,116,101,68,101,102,97,117,108,116,0,99,114,101,97,116,101,87,105,116,104,67,111,110,102,105,103,0,100,101,115,116,114,111,121,0,114,101,115,101,116,0,99,111,112,121,83,116,121,108,101,0,115,101,116,80,111,115,105,116,105,111,110,84,121,112,101,0,115,101,116,80,111,115,105,116,105,111,110,0,115,101,116,80,111,115,105,116,105,111,110,80,101,114,99,101,110,116,0,115,101,116,65,108,105,103,110,67,111,110,116,101,110,116,0,115,101,116,65,108,105,103,110,73,116,101,109,115,0,115,101,116,65,108,105,103,110,83,101,108,102,0,115,101,116,70,108,101,120,68,105,114,101,99,116,105,111,110,0,115,101,116,70,108,101,120,87,114,97,112,0,115,101,116,74,117,115,116,105,102,121,67,111,110,116,101,110,116,0,115,101,116,77,97,114,103,105,110,0,115,101,116,77,97,114,103,105,110,80,101,114,99,101,110,116,0,115,101,116,77,97,114,103,105,110,65,117,116,111,0,115,101,116,79,118,101,114,102,108,111,119,0,115,101,116,68,105,115,112,108,97,121,0,115,101,116,70,108,101,120,0,115,101,116,70,108,101,120,66,97,115,105,115,0,115,101,116,70,108,101,120,66,97,115,105,115,80,101,114,99,101,110,116,0,115,101,116,70,108,101,120,71,114,111,119,0,115,101,116,70,108,101,120,83,104,114,105,110,107,0,115,101,116,87,105,100,116,104,0,115,101,116,87,105,100,116,104,80,101,114,99,101,110,116,0,115,101,116,87,105,100,116,104,65,117,116,111,0,115,101,116,72,101,105,103,104,116,0,115,101,116,72,101,105,103,104,116,80,101,114,99,101,110,116,0,115,101,116,72,101,105,103,104,116,65,117,116,111,0,115,101,116,77,105,110,87,105,100,116,104,0,115,101,116,77,105,110,87,105,100,116,104,80,101,114,99,101,110,116,0,115,101,116,77,105,110,72,101,105,103,104,116,0,115,101,116,77,105,110,72,101,105,103,104,116,80,101,114,99,101,110,116,0,115,101,116,77,97,120,87,105,100,116,104,0,115,101,116,77,97,120,87,105,100,116,104,80,101,114,99,101,110,116,0,115,101,116,77,97,120,72,101,105,103,104,116,0,115,101,116,77,97,120,72,101,105,103,104,116,80,101,114,99,101,110,116,0,115,101,116,65,115,112,101,99,116,82,97,116,105,111,0,115,101,116,66,111,114,100,101,114,0,115,101,116,80,97,100,100,105,110,103,0,115,101,116,80,97,100,100,105,110,103,80,101,114,99,101,110,116,0,103,101,116,80,111,115,105,116,105,111,110,84,121,112,101,0,103,101,116,80,111,115,105,116,105,111,110,0,103,101,116,65,108,105,103,110,67,111,110,116,101,110,116,0,103,101,116,65,108,105,103,110,73,116,101,109,115,0,103,101,116,65,108,105,103,110,83,101,108,102,0,103,101,116,70,108,101,120,68,105,114,101,99,116,105,111,110,0,103,101,116,70,108,101,120,87,114,97,112,0,103,101,116,74,117,115,116,105,102,121,67,111,110,116,101,110,116,0,103,101,116,77,97,114,103,105,110,0,103,101,116,70,108,101,120,66,97,115,105,115,0,103,101,116,70,108,101,120,71,114,111,119,0,103,101,116,70,108,101,120,83,104,114,105,110,107,0,103,101,116,87,105,100,116,104,0,103,101,116,72,101,105,103,104,116,0,103,101,116,77,105,110,87,105,100,116,104,0,103,101,116,77,105,110,72,101,105,103,104,116,0,103,101,116,77,97,120,87,105,100,116,104,0,103,101,116,77,97,120,72,101,105,103,104,116,0,103,101,116,65,115,112,101,99,116,82,97,116,105,111,0,103,101,116,66,111,114,100,101,114,0,103,101,116,79,118,101,114,102,108,111,119,0,103,101,116,68,105,115,112,108,97,121,0,103,101,116,80,97,100,100,105,110,103,0,105,110,115,101,114,116,67,104,105,108,100,0,114,101,109,111,118,101,67,104,105,108,100,0,103,101,116,67,104,105,108,100,67,111,117,110,116,0,103,101,116,80,97,114,101,110,116,0,103,101,116,67,104,105,108,100,0,115,101,116,77,101,97,115,117,114,101,70,117,110,99,0,117,110,115,101,116,77,101,97,115,117,114,101,70,117,110,99,0,109,97,114,107,68,105,114,116,121,0,105,115,68,105,114,116,121,0,99,97,108,99,117,108,97,116,101,76,97,121,111,117,116,0,103,101,116,67,111,109,112,117,116,101,100,76,101,102,116,0,103,101,116,67,111,109,112,117,116,101,100,82,105,103,104,116,0,103,101,116,67,111,109,112,117,116,101,100,84,111,112,0,103,101,116,67,111,109,112,117,116,101,100,66,111,116,116,111,109,0,103,101,116,67,111,109,112,117,116,101,100,87,105,100,116,104,0,103,101,116,67,111,109,112,117,116,101,100,72,101,105,103,104,116,0,103,101,116,67,111,109,112,117,116,101,100,76,97,121,111,117,116,0,103,101,116,67,111,109,112,117,116,101,100,77,97,114,103,105,110,0,103,101,116,67,111,109,112,117,116,101,100,66,111,114,100,101,114,0,103,101,116,67,111,109,112,117,116,101,100,80,97,100,100,105,110,103,0,67,111,110,102,105,103,0,99,114,101,97,116,101,0,115,101,116,69,120,112,101,114,105,109,101,110,116,97,108,70,101,97,116,117,114,101,69,110,97,98,108,101,100,0,115,101,116,80,111,105,110,116,83,99,97,108,101,70,97,99,116,111,114,0,105,115,69,120,112,101,114,105,109,101,110,116,97,108,70,101,97,116,117,114,101,69,110,97,98,108,101,100,0,86,97,108,117,101,0,76,97,121,111,117,116,0,83,105,122,101,0,103,101,116,73,110,115,116,97,110,99,101,67,111,117,110,116,0,73,110,116,54,52,0,1,1,1,2,2,4,4,4,4,8,8,4,8,118,111,105,100,0,98,111,111,108,0,115,116,100,58,58,115,116,114,105,110,103,0,99,98,70,117,110,99,116,105,111,110,32,38,0,99,111,110,115,116,32,99,98,70,117,110,99,116,105,111,110,32,38,0,69,120,116,101,114,110,97,108,0,66,117,102,102,101,114,0,78,66,105,110,100,73,68,0,78,66,105,110,100,0,98,105,110,100,95,118,97,108,117,101,0,114,101,102,108,101,99,116,0,113,117,101,114,121,84,121,112,101,0,108,97,108,108,111,99,0,108,114,101,115,101,116,0,123,114,101,116,117,114,110,40,95,110,98,105,110,100,46,99,97,108,108,98,97,99,107,83,105,103,110,97,116,117,114,101,76,105,115,116,91,36,48,93,46,97,112,112,108,121,40,116,104,105,115,44,97,114,103,117,109,101,110,116,115,41,41,59,125,0,95,110,98,105,110,100,95,110,101,119,0,17,0,10,0,17,17,17,0,0,0,0,5,0,0,0,0,0,0,9,0,0,0,0,11,0,0,0,0,0,0,0,0,17,0,15,10,17,17,17,3,10,7,0,1,19,9,11,11,0,0,9,6,11,0,0,11,0,6,17,0,0,0,17,17,17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,17,0,10,10,17,17,17,0,10,0,0,2,0,9,11,0,0,0,9,0,11,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,12,0,0,0,0,9,12,0,0,0,0,0,12,0,0,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,13,0,0,0,4,13,0,0,0,0,9,14,0,0,0,0,0,14,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,15,0,0,0,0,15,0,0,0,0,9,16,0,0,0,0,0,16,0,0,16,0,0,18,0,0,0,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,0,0,0,18,18,18,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,10,0,0,0,0,9,11,0,0,0,0,0,11,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,12,0,0,0,0,9,12,0,0,0,0,0,12,0,0,12,0,0,45,43,32,32,32,48,88,48,120,0,40,110,117,108,108,41,0,45,48,88,43,48,88,32,48,88,45,48,120,43,48,120,32,48,120,0,105,110,102,0,73,78,70,0,110,97,110,0,78,65,78,0,48,49,50,51,52,53,54,55,56,57,65,66,67,68,69,70,46,0,84,33,34,25,13,1,2,3,17,75,28,12,16,4,11,29,18,30,39,104,110,111,112,113,98,32,5,6,15,19,20,21,26,8,22,7,40,36,23,24,9,10,14,27,31,37,35,131,130,125,38,42,43,60,61,62,63,67,71,74,77,88,89,90,91,92,93,94,95,96,97,99,100,101,102,103,105,106,107,108,114,115,116,121,122,123,124,0,73,108,108,101,103,97,108,32,98,121,116,101,32,115,101,113,117,101,110,99,101,0,68,111,109,97,105,110,32,101,114,114,111,114,0,82,101,115,117,108,116,32,110,111,116,32,114,101,112,114,101,115,101,110,116,97,98,108,101,0,78,111,116,32,97,32,116,116,121,0,80,101,114,109,105,115,115,105,111,110,32,100,101,110,105,101,100,0,79,112,101,114,97,116,105,111,110,32,110,111,116,32,112,101,114,109,105,116,116,101,100,0,78,111,32,115,117,99,104,32,102,105,108,101,32,111,114,32,100,105,114,101,99,116,111,114,121,0,78,111,32,115,117,99,104,32,112,114,111,99,101,115,115,0,70,105,108,101,32,101,120,105,115,116,115,0,86,97,108,117,101,32,116,111,111,32,108,97,114,103,101,32,102,111,114,32,100,97,116,97,32,116,121,112,101,0,78,111,32,115,112,97,99,101,32,108,101,102,116,32,111,110,32,100,101,118,105,99,101,0,79,117,116,32,111,102,32,109,101,109,111,114,121,0,82,101,115,111,117,114,99,101,32,98,117,115,121,0,73,110,116,101,114,114,117,112,116,101,100,32,115,121,115,116,101,109,32,99,97,108,108,0,82,101,115,111,117,114,99,101,32,116,101,109,112,111,114,97,114,105,108,121,32,117,110,97,118,97,105,108,97,98,108,101,0,73,110,118,97,108,105,100,32,115,101,101,107,0,67,114,111,115,115,45,100,101,118,105,99,101,32,108,105,110,107,0,82,101,97,100,45,111,110,108,121,32,102,105,108,101,32,115,121,115,116,101,109,0,68,105,114,101,99,116,111,114,121,32,110,111,116,32,101,109,112,116,121,0,67,111,110,110,101,99,116,105,111,110,32,114,101,115,101,116,32,98,121,32,112,101,101,114,0,79,112,101,114,97,116,105,111,110,32,116,105,109,101,100,32,111,117,116,0,67,111,110,110,101,99,116,105,111,110,32,114,101,102,117,115,101,100,0,72,111,115,116,32,105,115,32,100,111,119,110,0,72,111,115,116,32,105,115,32,117,110,114,101,97,99,104,97,98,108,101,0,65,100,100,114,101,115,115,32,105,110,32,117,115,101,0,66,114,111,107,101,110,32,112,105,112,101,0,73,47,79,32,101,114,114,111,114,0,78,111,32,115,117,99,104,32,100,101,118,105,99,101,32,111,114,32,97,100,100,114,101,115,115,0,66,108,111,99,107,32,100,101,118,105,99,101,32,114,101,113,117,105,114,101,100,0,78,111,32,115,117,99,104,32,100,101,118,105,99,101,0,78,111,116,32,97,32,100,105,114,101,99,116,111,114,121,0,73,115,32,97,32,100,105,114,101,99,116,111,114,121,0,84,101,120,116,32,102,105,108,101,32,98,117,115,121,0,69,120,101,99,32,102,111,114,109,97,116,32,101,114,114,111,114,0,73,110,118,97,108,105,100,32,97,114,103,117,109,101,110,116,0,65,114,103,117,109,101,110,116,32,108,105,115,116,32,116,111,111,32,108,111,110,103,0,83,121,109,98,111,108,105,99,32,108,105,110,107,32,108,111,111,112,0,70,105,108,101,110,97,109,101,32,116,111,111,32,108,111,110,103,0,84,111,111,32,109,97,110,121,32,111,112,101,110,32,102,105,108,101,115,32,105,110,32,115,121,115,116,101,109,0,78,111,32,102,105,108,101,32,100,101,115,99,114,105,112,116,111,114,115,32,97,118,97,105,108,97,98,108,101,0,66,97,100,32,102,105,108,101,32,100,101,115,99,114,105,112,116,111,114,0,78,111,32,99,104,105,108,100,32,112,114,111,99,101,115,115,0,66,97,100,32,97,100,100,114,101,115,115,0,70,105,108,101,32,116,111,111,32,108,97,114,103,101,0,84,111,111,32,109,97,110,121,32,108,105,110,107,115,0,78,111,32,108,111,99,107,115,32,97,118,97,105,108,97,98,108,101,0,82,101,115,111,117,114,99,101,32,100,101,97,100,108,111,99,107,32,119,111,117,108,100,32,111,99,99,117,114,0,83,116,97,116,101,32,110,111,116,32,114,101,99,111,118,101,114,97,98,108,101,0,80,114,101,118,105,111,117,115,32,111,119,110,101,114,32,100,105,101,100,0,79,112,101,114,97,116,105,111,110,32,99,97,110,99,101,108,101,100,0,70,117,110,99,116,105,111,110,32,110,111,116,32,105,109,112,108,101,109,101,110,116,101,100,0,78,111,32,109,101,115,115,97,103,101,32,111,102,32,100,101,115,105,114,101,100,32,116,121,112,101,0,73,100,101,110,116,105,102,105,101,114,32,114,101,109,111,118,101,100,0,68,101,118,105,99,101,32,110,111,116,32,97,32,115,116,114,101,97,109,0,78,111,32,100,97,116,97,32,97,118,97,105,108,97,98,108,101,0,68,101,118,105,99,101,32,116,105,109,101,111,117,116,0,79,117,116,32,111,102,32,115,116,114,101,97,109,115,32,114,101,115,111,117,114,99,101,115,0,76,105,110,107,32,104,97,115,32,98,101,101,110,32,115,101,118,101,114,101,100,0,80,114,111,116,111,99,111,108,32,101,114,114,111,114,0,66,97,100,32,109,101,115,115,97,103,101,0,70,105,108,101,32,100,101,115,99,114,105,112,116,111,114,32,105,110,32,98,97,100,32,115,116,97,116,101,0,78,111,116,32,97,32,115,111,99,107,101,116,0,68,101,115,116,105,110,97,116,105,111,110,32,97,100,100,114,101,115,115,32,114,101,113,117,105,114,101,100,0,77,101,115,115,97,103,101,32,116,111,111,32,108,97,114,103,101,0,80,114,111,116,111,99,111,108,32,119,114,111,110,103,32,116,121,112,101,32,102,111,114,32,115,111,99,107,101,116,0,80,114,111,116,111,99,111,108,32,110,111,116,32,97,118,97,105,108,97,98,108,101,0,80,114,111,116,111,99,111,108,32,110,111,116,32,115,117,112,112,111,114,116,101,100,0,83,111,99,107,101,116,32,116,121,112,101,32,110,111,116,32,115,117,112,112,111,114,116,101,100,0,78,111,116,32,115,117,112,112,111,114,116,101,100,0,80,114,111,116,111,99,111,108,32,102,97,109,105,108,121,32,110,111,116,32,115,117,112,112,111,114,116,101,100,0,65,100,100,114,101,115,115,32,102,97,109,105,108,121,32,110,111,116,32,115,117,112,112,111,114,116,101,100,32,98,121,32,112,114,111,116,111,99,111,108,0,65,100,100,114,101,115,115,32,110,111,116,32,97,118,97,105,108,97,98,108,101,0,78,101,116,119,111,114,107,32,105,115,32,100,111,119,110,0,78,101,116,119,111,114,107,32,117,110,114,101,97,99,104,97,98,108,101,0,67,111,110,110,101,99,116,105,111,110,32,114,101,115,101,116,32,98,121,32,110,101,116,119,111,114,107,0,67,111,110,110,101,99,116,105,111,110,32,97,98,111,114,116,101,100,0,78,111,32,98,117,102,102,101,114,32,115,112,97,99,101,32,97,118,97,105,108,97,98,108,101,0,83,111,99,107,101,116,32,105,115,32,99,111,110,110,101,99,116,101,100,0,83,111,99,107,101,116,32,110,111,116,32,99,111,110,110,101,99,116,101,100,0,67,97,110,110,111,116,32,115,101,110,100,32,97,102,116,101,114,32,115,111,99,107,101,116,32,115,104,117,116,100,111,119,110,0,79,112,101,114,97,116,105,111,110,32,97,108,114,101,97,100,121,32,105,110,32,112,114,111,103,114,101,115,115,0,79,112,101,114,97,116,105,111,110,32,105,110,32,112,114,111,103,114,101,115,115,0,83,116,97,108,101,32,102,105,108,101,32,104,97,110,100,108,101,0,82,101,109,111,116,101,32,73,47,79,32,101,114,114,111,114,0,81,117,111,116,97,32,101,120,99,101,101,100,101,100,0,78,111,32,109,101,100,105,117,109,32,102,111,117,110,100,0,87,114,111,110,103,32,109,101,100,105,117,109,32,116,121,112,101,0,78,111,32,101,114,114,111,114,32,105,110,102,111,114,109,97,116,105,111,110,0,0],"i8",ALLOC_NONE,Runtime.GLOBAL_BASE);var tempDoublePtr=STATICTOP;STATICTOP+=16;function _atexit(t,e){__ATEXIT__.unshift({func:t,arg:e})}function ___cxa_atexit(){return _atexit.apply(null,arguments)}function _abort(){Module.abort()}function __ZN8facebook4yoga14YGNodeToStringEPNSt3__212basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEP6YGNode14YGPrintOptionsj(){Module.printErr("missing function: _ZN8facebook4yoga14YGNodeToStringEPNSt3__212basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEP6YGNode14YGPrintOptionsj"),abort(-1)}function __decorate(t,e,r,o){var a=arguments.length,n=a<3?e:o===null?o=Object.getOwnPropertyDescriptor(e,r):o,u;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")n=Reflect.decorate(t,e,r,o);else for(var A=t.length-1;A>=0;A--)(u=t[A])&&(n=(a<3?u(n):a>3?u(e,r,n):u(e,r))||n);return a>3&&n&&Object.defineProperty(e,r,n),n}function _defineHidden(t){return function(e,r){Object.defineProperty(e,r,{configurable:!1,enumerable:!1,value:t,writable:!0})}}var _nbind={};function __nbind_free_external(t){_nbind.externalList[t].dereference(t)}function __nbind_reference_external(t){_nbind.externalList[t].reference()}function _llvm_stackrestore(t){var e=_llvm_stacksave,r=e.LLVM_SAVEDSTACKS[t];e.LLVM_SAVEDSTACKS.splice(t,1),Runtime.stackRestore(r)}function __nbind_register_pool(t,e,r,o){_nbind.Pool.pageSize=t,_nbind.Pool.usedPtr=e/4,_nbind.Pool.rootPtr=r,_nbind.Pool.pagePtr=o/4,HEAP32[e/4]=16909060,HEAP8[e]==1&&(_nbind.bigEndian=!0),HEAP32[e/4]=0,_nbind.makeTypeKindTbl=(n={},n[1024]=_nbind.PrimitiveType,n[64]=_nbind.Int64Type,n[2048]=_nbind.BindClass,n[3072]=_nbind.BindClassPtr,n[4096]=_nbind.SharedClassPtr,n[5120]=_nbind.ArrayType,n[6144]=_nbind.ArrayType,n[7168]=_nbind.CStringType,n[9216]=_nbind.CallbackType,n[10240]=_nbind.BindType,n),_nbind.makeTypeNameTbl={Buffer:_nbind.BufferType,External:_nbind.ExternalType,Int64:_nbind.Int64Type,_nbind_new:_nbind.CreateValueType,bool:_nbind.BooleanType,"cbFunction &":_nbind.CallbackType,"const cbFunction &":_nbind.CallbackType,"const std::string &":_nbind.StringType,"std::string":_nbind.StringType},Module.toggleLightGC=_nbind.toggleLightGC,_nbind.callUpcast=Module.dynCall_ii;var a=_nbind.makeType(_nbind.constructType,{flags:2048,id:0,name:""});a.proto=Module,_nbind.BindClass.list.push(a);var n}function _emscripten_set_main_loop_timing(t,e){if(Browser.mainLoop.timingMode=t,Browser.mainLoop.timingValue=e,!Browser.mainLoop.func)return 1;if(t==0)Browser.mainLoop.scheduler=function(){var u=Math.max(0,Browser.mainLoop.tickStartTime+e-_emscripten_get_now())|0;setTimeout(Browser.mainLoop.runner,u)},Browser.mainLoop.method="timeout";else if(t==1)Browser.mainLoop.scheduler=function(){Browser.requestAnimationFrame(Browser.mainLoop.runner)},Browser.mainLoop.method="rAF";else if(t==2){if(!window.setImmediate){let n=function(u){u.source===window&&u.data===o&&(u.stopPropagation(),r.shift()())};var a=n,r=[],o="setimmediate";window.addEventListener("message",n,!0),window.setImmediate=function(A){r.push(A),ENVIRONMENT_IS_WORKER?(Module.setImmediates===void 0&&(Module.setImmediates=[]),Module.setImmediates.push(A),window.postMessage({target:o})):window.postMessage(o,"*")}}Browser.mainLoop.scheduler=function(){window.setImmediate(Browser.mainLoop.runner)},Browser.mainLoop.method="immediate"}return 0}function _emscripten_get_now(){abort()}function _emscripten_set_main_loop(t,e,r,o,a){Module.noExitRuntime=!0,assert(!Browser.mainLoop.func,"emscripten_set_main_loop: there can only be one main loop function at once: call emscripten_cancel_main_loop to cancel the previous one before setting a new one with different parameters."),Browser.mainLoop.func=t,Browser.mainLoop.arg=o;var n;typeof o<"u"?n=function(){Module.dynCall_vi(t,o)}:n=function(){Module.dynCall_v(t)};var u=Browser.mainLoop.currentlyRunningMainloop;if(Browser.mainLoop.runner=function(){if(!ABORT){if(Browser.mainLoop.queue.length>0){var p=Date.now(),h=Browser.mainLoop.queue.shift();if(h.func(h.arg),Browser.mainLoop.remainingBlockers){var E=Browser.mainLoop.remainingBlockers,I=E%1==0?E-1:Math.floor(E);h.counted?Browser.mainLoop.remainingBlockers=I:(I=I+.5,Browser.mainLoop.remainingBlockers=(8*E+I)/9)}if(console.log('main loop blocker "'+h.name+'" took '+(Date.now()-p)+" ms"),Browser.mainLoop.updateStatus(),u1&&Browser.mainLoop.currentFrameNumber%Browser.mainLoop.timingValue!=0){Browser.mainLoop.scheduler();return}else Browser.mainLoop.timingMode==0&&(Browser.mainLoop.tickStartTime=_emscripten_get_now());Browser.mainLoop.method==="timeout"&&Module.ctx&&(Module.printErr("Looks like you are rendering without using requestAnimationFrame for the main loop. You should use 0 for the frame rate in emscripten_set_main_loop in order to use requestAnimationFrame, as that can greatly improve your frame rates!"),Browser.mainLoop.method=""),Browser.mainLoop.runIter(n),!(u0?_emscripten_set_main_loop_timing(0,1e3/e):_emscripten_set_main_loop_timing(1,1),Browser.mainLoop.scheduler()),r)throw"SimulateInfiniteLoop"}var Browser={mainLoop:{scheduler:null,method:"",currentlyRunningMainloop:0,func:null,arg:0,timingMode:0,timingValue:0,currentFrameNumber:0,queue:[],pause:function(){Browser.mainLoop.scheduler=null,Browser.mainLoop.currentlyRunningMainloop++},resume:function(){Browser.mainLoop.currentlyRunningMainloop++;var t=Browser.mainLoop.timingMode,e=Browser.mainLoop.timingValue,r=Browser.mainLoop.func;Browser.mainLoop.func=null,_emscripten_set_main_loop(r,0,!1,Browser.mainLoop.arg,!0),_emscripten_set_main_loop_timing(t,e),Browser.mainLoop.scheduler()},updateStatus:function(){if(Module.setStatus){var t=Module.statusMessage||"Please wait...",e=Browser.mainLoop.remainingBlockers,r=Browser.mainLoop.expectedBlockers;e?e"u"&&(console.log("warning: Browser does not support creating object URLs. Built-in browser image decoding will not be available."),Module.noImageDecoding=!0);var t={};t.canHandle=function(n){return!Module.noImageDecoding&&/\.(jpg|jpeg|png|bmp)$/i.test(n)},t.handle=function(n,u,A,p){var h=null;if(Browser.hasBlobConstructor)try{h=new Blob([n],{type:Browser.getMimetype(u)}),h.size!==n.length&&(h=new Blob([new Uint8Array(n).buffer],{type:Browser.getMimetype(u)}))}catch(x){Runtime.warnOnce("Blob constructor present but fails: "+x+"; falling back to blob builder")}if(!h){var E=new Browser.BlobBuilder;E.append(new Uint8Array(n).buffer),h=E.getBlob()}var I=Browser.URLObject.createObjectURL(h),v=new Image;v.onload=function(){assert(v.complete,"Image "+u+" could not be decoded");var C=document.createElement("canvas");C.width=v.width,C.height=v.height;var R=C.getContext("2d");R.drawImage(v,0,0),Module.preloadedImages[u]=C,Browser.URLObject.revokeObjectURL(I),A&&A(n)},v.onerror=function(C){console.log("Image "+I+" could not be decoded"),p&&p()},v.src=I},Module.preloadPlugins.push(t);var e={};e.canHandle=function(n){return!Module.noAudioDecoding&&n.substr(-4)in{".ogg":1,".wav":1,".mp3":1}},e.handle=function(n,u,A,p){var h=!1;function E(R){h||(h=!0,Module.preloadedAudios[u]=R,A&&A(n))}function I(){h||(h=!0,Module.preloadedAudios[u]=new Audio,p&&p())}if(Browser.hasBlobConstructor){try{var v=new Blob([n],{type:Browser.getMimetype(u)})}catch{return I()}var x=Browser.URLObject.createObjectURL(v),C=new Audio;C.addEventListener("canplaythrough",function(){E(C)},!1),C.onerror=function(L){if(h)return;console.log("warning: browser could not fully decode audio "+u+", trying slower base64 approach");function U(z){for(var te="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",ae="=",le="",ce=0,Ce=0,de=0;de=6;){var Be=ce>>Ce-6&63;Ce-=6,le+=te[Be]}return Ce==2?(le+=te[(ce&3)<<4],le+=ae+ae):Ce==4&&(le+=te[(ce&15)<<2],le+=ae),le}C.src="data:audio/x-"+u.substr(-3)+";base64,"+U(n),E(C)},C.src=x,Browser.safeSetTimeout(function(){E(C)},1e4)}else return I()},Module.preloadPlugins.push(e);function r(){Browser.pointerLock=document.pointerLockElement===Module.canvas||document.mozPointerLockElement===Module.canvas||document.webkitPointerLockElement===Module.canvas||document.msPointerLockElement===Module.canvas}var o=Module.canvas;o&&(o.requestPointerLock=o.requestPointerLock||o.mozRequestPointerLock||o.webkitRequestPointerLock||o.msRequestPointerLock||function(){},o.exitPointerLock=document.exitPointerLock||document.mozExitPointerLock||document.webkitExitPointerLock||document.msExitPointerLock||function(){},o.exitPointerLock=o.exitPointerLock.bind(document),document.addEventListener("pointerlockchange",r,!1),document.addEventListener("mozpointerlockchange",r,!1),document.addEventListener("webkitpointerlockchange",r,!1),document.addEventListener("mspointerlockchange",r,!1),Module.elementPointerLock&&o.addEventListener("click",function(a){!Browser.pointerLock&&Module.canvas.requestPointerLock&&(Module.canvas.requestPointerLock(),a.preventDefault())},!1))},createContext:function(t,e,r,o){if(e&&Module.ctx&&t==Module.canvas)return Module.ctx;var a,n;if(e){var u={antialias:!1,alpha:!1};if(o)for(var A in o)u[A]=o[A];n=GL.createContext(t,u),n&&(a=GL.getContext(n).GLctx)}else a=t.getContext("2d");return a?(r&&(e||assert(typeof GLctx>"u","cannot set in module if GLctx is used, but we are a non-GL context that would replace it"),Module.ctx=a,e&&GL.makeContextCurrent(n),Module.useWebGL=e,Browser.moduleContextCreatedCallbacks.forEach(function(p){p()}),Browser.init()),a):null},destroyContext:function(t,e,r){},fullscreenHandlersInstalled:!1,lockPointer:void 0,resizeCanvas:void 0,requestFullscreen:function(t,e,r){Browser.lockPointer=t,Browser.resizeCanvas=e,Browser.vrDevice=r,typeof Browser.lockPointer>"u"&&(Browser.lockPointer=!0),typeof Browser.resizeCanvas>"u"&&(Browser.resizeCanvas=!1),typeof Browser.vrDevice>"u"&&(Browser.vrDevice=null);var o=Module.canvas;function a(){Browser.isFullscreen=!1;var u=o.parentNode;(document.fullscreenElement||document.mozFullScreenElement||document.msFullscreenElement||document.webkitFullscreenElement||document.webkitCurrentFullScreenElement)===u?(o.exitFullscreen=document.exitFullscreen||document.cancelFullScreen||document.mozCancelFullScreen||document.msExitFullscreen||document.webkitCancelFullScreen||function(){},o.exitFullscreen=o.exitFullscreen.bind(document),Browser.lockPointer&&o.requestPointerLock(),Browser.isFullscreen=!0,Browser.resizeCanvas&&Browser.setFullscreenCanvasSize()):(u.parentNode.insertBefore(o,u),u.parentNode.removeChild(u),Browser.resizeCanvas&&Browser.setWindowedCanvasSize()),Module.onFullScreen&&Module.onFullScreen(Browser.isFullscreen),Module.onFullscreen&&Module.onFullscreen(Browser.isFullscreen),Browser.updateCanvasDimensions(o)}Browser.fullscreenHandlersInstalled||(Browser.fullscreenHandlersInstalled=!0,document.addEventListener("fullscreenchange",a,!1),document.addEventListener("mozfullscreenchange",a,!1),document.addEventListener("webkitfullscreenchange",a,!1),document.addEventListener("MSFullscreenChange",a,!1));var n=document.createElement("div");o.parentNode.insertBefore(n,o),n.appendChild(o),n.requestFullscreen=n.requestFullscreen||n.mozRequestFullScreen||n.msRequestFullscreen||(n.webkitRequestFullscreen?function(){n.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT)}:null)||(n.webkitRequestFullScreen?function(){n.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT)}:null),r?n.requestFullscreen({vrDisplay:r}):n.requestFullscreen()},requestFullScreen:function(t,e,r){return Module.printErr("Browser.requestFullScreen() is deprecated. Please call Browser.requestFullscreen instead."),Browser.requestFullScreen=function(o,a,n){return Browser.requestFullscreen(o,a,n)},Browser.requestFullscreen(t,e,r)},nextRAF:0,fakeRequestAnimationFrame:function(t){var e=Date.now();if(Browser.nextRAF===0)Browser.nextRAF=e+1e3/60;else for(;e+2>=Browser.nextRAF;)Browser.nextRAF+=1e3/60;var r=Math.max(Browser.nextRAF-e,0);setTimeout(t,r)},requestAnimationFrame:function t(e){typeof window>"u"?Browser.fakeRequestAnimationFrame(e):(window.requestAnimationFrame||(window.requestAnimationFrame=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame||window.oRequestAnimationFrame||Browser.fakeRequestAnimationFrame),window.requestAnimationFrame(e))},safeCallback:function(t){return function(){if(!ABORT)return t.apply(null,arguments)}},allowAsyncCallbacks:!0,queuedAsyncCallbacks:[],pauseAsyncCallbacks:function(){Browser.allowAsyncCallbacks=!1},resumeAsyncCallbacks:function(){if(Browser.allowAsyncCallbacks=!0,Browser.queuedAsyncCallbacks.length>0){var t=Browser.queuedAsyncCallbacks;Browser.queuedAsyncCallbacks=[],t.forEach(function(e){e()})}},safeRequestAnimationFrame:function(t){return Browser.requestAnimationFrame(function(){ABORT||(Browser.allowAsyncCallbacks?t():Browser.queuedAsyncCallbacks.push(t))})},safeSetTimeout:function(t,e){return Module.noExitRuntime=!0,setTimeout(function(){ABORT||(Browser.allowAsyncCallbacks?t():Browser.queuedAsyncCallbacks.push(t))},e)},safeSetInterval:function(t,e){return Module.noExitRuntime=!0,setInterval(function(){ABORT||Browser.allowAsyncCallbacks&&t()},e)},getMimetype:function(t){return{jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",bmp:"image/bmp",ogg:"audio/ogg",wav:"audio/wav",mp3:"audio/mpeg"}[t.substr(t.lastIndexOf(".")+1)]},getUserMedia:function(t){window.getUserMedia||(window.getUserMedia=navigator.getUserMedia||navigator.mozGetUserMedia),window.getUserMedia(t)},getMovementX:function(t){return t.movementX||t.mozMovementX||t.webkitMovementX||0},getMovementY:function(t){return t.movementY||t.mozMovementY||t.webkitMovementY||0},getMouseWheelDelta:function(t){var e=0;switch(t.type){case"DOMMouseScroll":e=t.detail;break;case"mousewheel":e=t.wheelDelta;break;case"wheel":e=t.deltaY;break;default:throw"unrecognized mouse wheel event: "+t.type}return e},mouseX:0,mouseY:0,mouseMovementX:0,mouseMovementY:0,touches:{},lastTouches:{},calculateMouseEvent:function(t){if(Browser.pointerLock)t.type!="mousemove"&&"mozMovementX"in t?Browser.mouseMovementX=Browser.mouseMovementY=0:(Browser.mouseMovementX=Browser.getMovementX(t),Browser.mouseMovementY=Browser.getMovementY(t)),typeof SDL<"u"?(Browser.mouseX=SDL.mouseX+Browser.mouseMovementX,Browser.mouseY=SDL.mouseY+Browser.mouseMovementY):(Browser.mouseX+=Browser.mouseMovementX,Browser.mouseY+=Browser.mouseMovementY);else{var e=Module.canvas.getBoundingClientRect(),r=Module.canvas.width,o=Module.canvas.height,a=typeof window.scrollX<"u"?window.scrollX:window.pageXOffset,n=typeof window.scrollY<"u"?window.scrollY:window.pageYOffset;if(t.type==="touchstart"||t.type==="touchend"||t.type==="touchmove"){var u=t.touch;if(u===void 0)return;var A=u.pageX-(a+e.left),p=u.pageY-(n+e.top);A=A*(r/e.width),p=p*(o/e.height);var h={x:A,y:p};if(t.type==="touchstart")Browser.lastTouches[u.identifier]=h,Browser.touches[u.identifier]=h;else if(t.type==="touchend"||t.type==="touchmove"){var E=Browser.touches[u.identifier];E||(E=h),Browser.lastTouches[u.identifier]=E,Browser.touches[u.identifier]=h}return}var I=t.pageX-(a+e.left),v=t.pageY-(n+e.top);I=I*(r/e.width),v=v*(o/e.height),Browser.mouseMovementX=I-Browser.mouseX,Browser.mouseMovementY=v-Browser.mouseY,Browser.mouseX=I,Browser.mouseY=v}},asyncLoad:function(t,e,r,o){var a=o?"":"al "+t;Module.readAsync(t,function(n){assert(n,'Loading data file "'+t+'" failed (no arrayBuffer).'),e(new Uint8Array(n)),a&&removeRunDependency(a)},function(n){if(r)r();else throw'Loading data file "'+t+'" failed.'}),a&&addRunDependency(a)},resizeListeners:[],updateResizeListeners:function(){var t=Module.canvas;Browser.resizeListeners.forEach(function(e){e(t.width,t.height)})},setCanvasSize:function(t,e,r){var o=Module.canvas;Browser.updateCanvasDimensions(o,t,e),r||Browser.updateResizeListeners()},windowedWidth:0,windowedHeight:0,setFullscreenCanvasSize:function(){if(typeof SDL<"u"){var t=HEAPU32[SDL.screen+Runtime.QUANTUM_SIZE*0>>2];t=t|8388608,HEAP32[SDL.screen+Runtime.QUANTUM_SIZE*0>>2]=t}Browser.updateResizeListeners()},setWindowedCanvasSize:function(){if(typeof SDL<"u"){var t=HEAPU32[SDL.screen+Runtime.QUANTUM_SIZE*0>>2];t=t&-8388609,HEAP32[SDL.screen+Runtime.QUANTUM_SIZE*0>>2]=t}Browser.updateResizeListeners()},updateCanvasDimensions:function(t,e,r){e&&r?(t.widthNative=e,t.heightNative=r):(e=t.widthNative,r=t.heightNative);var o=e,a=r;if(Module.forcedAspectRatio&&Module.forcedAspectRatio>0&&(o/a>2];return e},getStr:function(){var t=Pointer_stringify(SYSCALLS.get());return t},get64:function(){var t=SYSCALLS.get(),e=SYSCALLS.get();return t>=0?assert(e===0):assert(e===-1),t},getZero:function(){assert(SYSCALLS.get()===0)}};function ___syscall6(t,e){SYSCALLS.varargs=e;try{var r=SYSCALLS.getStreamFromFD();return FS.close(r),0}catch(o){return(typeof FS>"u"||!(o instanceof FS.ErrnoError))&&abort(o),-o.errno}}function ___syscall54(t,e){SYSCALLS.varargs=e;try{return 0}catch(r){return(typeof FS>"u"||!(r instanceof FS.ErrnoError))&&abort(r),-r.errno}}function _typeModule(t){var e=[[0,1,"X"],[1,1,"const X"],[128,1,"X *"],[256,1,"X &"],[384,1,"X &&"],[512,1,"std::shared_ptr"],[640,1,"std::unique_ptr"],[5120,1,"std::vector"],[6144,2,"std::array"],[9216,-1,"std::function"]];function r(p,h,E,I,v,x){if(h==1){var C=I&896;(C==128||C==256||C==384)&&(p="X const")}var R;return x?R=E.replace("X",p).replace("Y",v):R=p.replace("X",E).replace("Y",v),R.replace(/([*&]) (?=[*&])/g,"$1")}function o(p,h,E,I,v){throw new Error(p+" type "+E.replace("X",h+"?")+(I?" with flag "+I:"")+" in "+v)}function a(p,h,E,I,v,x,C,R){x===void 0&&(x="X"),R===void 0&&(R=1);var L=E(p);if(L)return L;var U=I(p),z=U.placeholderFlag,te=e[z];C&&te&&(x=r(C[2],C[0],x,te[0],"?",!0));var ae;z==0&&(ae="Unbound"),z>=10&&(ae="Corrupt"),R>20&&(ae="Deeply nested"),ae&&o(ae,p,x,z,v||"?");var le=U.paramList[0],ce=a(le,h,E,I,v,x,te,R+1),Ce,de={flags:te[0],id:p,name:"",paramList:[ce]},Be=[],Ee="?";switch(U.placeholderFlag){case 1:Ce=ce.spec;break;case 2:if((ce.flags&15360)==1024&&ce.spec.ptrSize==1){de.flags=7168;break}case 3:case 6:case 5:Ce=ce.spec,ce.flags&15360;break;case 8:Ee=""+U.paramList[1],de.paramList.push(U.paramList[1]);break;case 9:for(var g=0,me=U.paramList[1];g>2]=t),t}function _llvm_stacksave(){var t=_llvm_stacksave;return t.LLVM_SAVEDSTACKS||(t.LLVM_SAVEDSTACKS=[]),t.LLVM_SAVEDSTACKS.push(Runtime.stackSave()),t.LLVM_SAVEDSTACKS.length-1}function ___syscall140(t,e){SYSCALLS.varargs=e;try{var r=SYSCALLS.getStreamFromFD(),o=SYSCALLS.get(),a=SYSCALLS.get(),n=SYSCALLS.get(),u=SYSCALLS.get(),A=a;return FS.llseek(r,A,u),HEAP32[n>>2]=r.position,r.getdents&&A===0&&u===0&&(r.getdents=null),0}catch(p){return(typeof FS>"u"||!(p instanceof FS.ErrnoError))&&abort(p),-p.errno}}function ___syscall146(t,e){SYSCALLS.varargs=e;try{var r=SYSCALLS.get(),o=SYSCALLS.get(),a=SYSCALLS.get(),n=0;___syscall146.buffer||(___syscall146.buffers=[null,[],[]],___syscall146.printChar=function(E,I){var v=___syscall146.buffers[E];assert(v),I===0||I===10?((E===1?Module.print:Module.printErr)(UTF8ArrayToString(v,0)),v.length=0):v.push(I)});for(var u=0;u>2],p=HEAP32[o+(u*8+4)>>2],h=0;h"u"||!(E instanceof FS.ErrnoError))&&abort(E),-E.errno}}function __nbind_finish(){for(var t=0,e=_nbind.BindClass.list;tt.pageSize/2||e>t.pageSize-r){var o=_nbind.typeNameTbl.NBind.proto;return o.lalloc(e)}else return HEAPU32[t.usedPtr]=r+e,t.rootPtr+r},t.lreset=function(e,r){var o=HEAPU32[t.pagePtr];if(o){var a=_nbind.typeNameTbl.NBind.proto;a.lreset(e,r)}else HEAPU32[t.usedPtr]=e},t}();_nbind.Pool=Pool;function constructType(t,e){var r=t==10240?_nbind.makeTypeNameTbl[e.name]||_nbind.BindType:_nbind.makeTypeKindTbl[t],o=new r(e);return typeIdTbl[e.id]=o,_nbind.typeNameTbl[e.name]=o,o}_nbind.constructType=constructType;function getType(t){return typeIdTbl[t]}_nbind.getType=getType;function queryType(t){var e=HEAPU8[t],r=_nbind.structureList[e][1];t/=4,r<0&&(++t,r=HEAPU32[t]+1);var o=Array.prototype.slice.call(HEAPU32.subarray(t+1,t+1+r));return e==9&&(o=[o[0],o.slice(1)]),{paramList:o,placeholderFlag:e}}_nbind.queryType=queryType;function getTypes(t,e){return t.map(function(r){return typeof r=="number"?_nbind.getComplexType(r,constructType,getType,queryType,e):_nbind.typeNameTbl[r]})}_nbind.getTypes=getTypes;function readTypeIdList(t,e){return Array.prototype.slice.call(HEAPU32,t/4,t/4+e)}_nbind.readTypeIdList=readTypeIdList;function readAsciiString(t){for(var e=t;HEAPU8[e++];);return String.fromCharCode.apply("",HEAPU8.subarray(t,e-1))}_nbind.readAsciiString=readAsciiString;function readPolicyList(t){var e={};if(t)for(;;){var r=HEAPU32[t/4];if(!r)break;e[readAsciiString(r)]=!0,t+=4}return e}_nbind.readPolicyList=readPolicyList;function getDynCall(t,e){var r={float32_t:"d",float64_t:"d",int64_t:"d",uint64_t:"d",void:"v"},o=t.map(function(n){return r[n.name]||"i"}).join(""),a=Module["dynCall_"+o];if(!a)throw new Error("dynCall_"+o+" not found for "+e+"("+t.map(function(n){return n.name}).join(", ")+")");return a}_nbind.getDynCall=getDynCall;function addMethod(t,e,r,o){var a=t[e];t.hasOwnProperty(e)&&a?((a.arity||a.arity===0)&&(a=_nbind.makeOverloader(a,a.arity),t[e]=a),a.addMethod(r,o)):(r.arity=o,t[e]=r)}_nbind.addMethod=addMethod;function throwError(t){throw new Error(t)}_nbind.throwError=throwError,_nbind.bigEndian=!1,_a=_typeModule(_typeModule),_nbind.Type=_a.Type,_nbind.makeType=_a.makeType,_nbind.getComplexType=_a.getComplexType,_nbind.structureList=_a.structureList;var BindType=function(t){__extends(e,t);function e(){var r=t!==null&&t.apply(this,arguments)||this;return r.heap=HEAPU32,r.ptrSize=4,r}return e.prototype.needsWireRead=function(r){return!!this.wireRead||!!this.makeWireRead},e.prototype.needsWireWrite=function(r){return!!this.wireWrite||!!this.makeWireWrite},e}(_nbind.Type);_nbind.BindType=BindType;var PrimitiveType=function(t){__extends(e,t);function e(r){var o=t.call(this,r)||this,a=r.flags&32?{32:HEAPF32,64:HEAPF64}:r.flags&8?{8:HEAPU8,16:HEAPU16,32:HEAPU32}:{8:HEAP8,16:HEAP16,32:HEAP32};return o.heap=a[r.ptrSize*8],o.ptrSize=r.ptrSize,o}return e.prototype.needsWireWrite=function(r){return!!r&&!!r.Strict},e.prototype.makeWireWrite=function(r,o){return o&&o.Strict&&function(a){if(typeof a=="number")return a;throw new Error("Type mismatch")}},e}(BindType);_nbind.PrimitiveType=PrimitiveType;function pushCString(t,e){if(t==null){if(e&&e.Nullable)return 0;throw new Error("Type mismatch")}if(e&&e.Strict){if(typeof t!="string")throw new Error("Type mismatch")}else t=t.toString();var r=Module.lengthBytesUTF8(t)+1,o=_nbind.Pool.lalloc(r);return Module.stringToUTF8Array(t,HEAPU8,o,r),o}_nbind.pushCString=pushCString;function popCString(t){return t===0?null:Module.Pointer_stringify(t)}_nbind.popCString=popCString;var CStringType=function(t){__extends(e,t);function e(){var r=t!==null&&t.apply(this,arguments)||this;return r.wireRead=popCString,r.wireWrite=pushCString,r.readResources=[_nbind.resources.pool],r.writeResources=[_nbind.resources.pool],r}return e.prototype.makeWireWrite=function(r,o){return function(a){return pushCString(a,o)}},e}(BindType);_nbind.CStringType=CStringType;var BooleanType=function(t){__extends(e,t);function e(){var r=t!==null&&t.apply(this,arguments)||this;return r.wireRead=function(o){return!!o},r}return e.prototype.needsWireWrite=function(r){return!!r&&!!r.Strict},e.prototype.makeWireRead=function(r){return"!!("+r+")"},e.prototype.makeWireWrite=function(r,o){return o&&o.Strict&&function(a){if(typeof a=="boolean")return a;throw new Error("Type mismatch")}||r},e}(BindType);_nbind.BooleanType=BooleanType;var Wrapper=function(){function t(){}return t.prototype.persist=function(){this.__nbindState|=1},t}();_nbind.Wrapper=Wrapper;function makeBound(t,e){var r=function(o){__extends(a,o);function a(n,u,A,p){var h=o.call(this)||this;if(!(h instanceof a))return new(Function.prototype.bind.apply(a,Array.prototype.concat.apply([null],arguments)));var E=u,I=A,v=p;if(n!==_nbind.ptrMarker){var x=h.__nbindConstructor.apply(h,arguments);E=4608,v=HEAPU32[x/4],I=HEAPU32[x/4+1]}var C={configurable:!0,enumerable:!1,value:null,writable:!1},R={__nbindFlags:E,__nbindPtr:I};v&&(R.__nbindShared=v,_nbind.mark(h));for(var L=0,U=Object.keys(R);L>=1;var r=_nbind.valueList[t];return _nbind.valueList[t]=firstFreeValue,firstFreeValue=t,r}else{if(e)return _nbind.popShared(t,e);throw new Error("Invalid value slot "+t)}}_nbind.popValue=popValue;var valueBase=18446744073709552e3;function push64(t){return typeof t=="number"?t:pushValue(t)*4096+valueBase}function pop64(t){return t=3?u=Buffer.from(n):u=new Buffer(n),u.copy(o)}else getBuffer(o).set(n)}}_nbind.commitBuffer=commitBuffer;var dirtyList=[],gcTimer=0;function sweep(){for(var t=0,e=dirtyList;t>2]=DYNAMIC_BASE,staticSealed=!0;function invoke_viiiii(t,e,r,o,a,n){try{Module.dynCall_viiiii(t,e,r,o,a,n)}catch(u){if(typeof u!="number"&&u!=="longjmp")throw u;Module.setThrew(1,0)}}function invoke_vif(t,e,r){try{Module.dynCall_vif(t,e,r)}catch(o){if(typeof o!="number"&&o!=="longjmp")throw o;Module.setThrew(1,0)}}function invoke_vid(t,e,r){try{Module.dynCall_vid(t,e,r)}catch(o){if(typeof o!="number"&&o!=="longjmp")throw o;Module.setThrew(1,0)}}function invoke_fiff(t,e,r,o){try{return Module.dynCall_fiff(t,e,r,o)}catch(a){if(typeof a!="number"&&a!=="longjmp")throw a;Module.setThrew(1,0)}}function invoke_vi(t,e){try{Module.dynCall_vi(t,e)}catch(r){if(typeof r!="number"&&r!=="longjmp")throw r;Module.setThrew(1,0)}}function invoke_vii(t,e,r){try{Module.dynCall_vii(t,e,r)}catch(o){if(typeof o!="number"&&o!=="longjmp")throw o;Module.setThrew(1,0)}}function invoke_ii(t,e){try{return Module.dynCall_ii(t,e)}catch(r){if(typeof r!="number"&&r!=="longjmp")throw r;Module.setThrew(1,0)}}function invoke_viddi(t,e,r,o,a){try{Module.dynCall_viddi(t,e,r,o,a)}catch(n){if(typeof n!="number"&&n!=="longjmp")throw n;Module.setThrew(1,0)}}function invoke_vidd(t,e,r,o){try{Module.dynCall_vidd(t,e,r,o)}catch(a){if(typeof a!="number"&&a!=="longjmp")throw a;Module.setThrew(1,0)}}function invoke_iiii(t,e,r,o){try{return Module.dynCall_iiii(t,e,r,o)}catch(a){if(typeof a!="number"&&a!=="longjmp")throw a;Module.setThrew(1,0)}}function invoke_diii(t,e,r,o){try{return Module.dynCall_diii(t,e,r,o)}catch(a){if(typeof a!="number"&&a!=="longjmp")throw a;Module.setThrew(1,0)}}function invoke_di(t,e){try{return Module.dynCall_di(t,e)}catch(r){if(typeof r!="number"&&r!=="longjmp")throw r;Module.setThrew(1,0)}}function invoke_iid(t,e,r){try{return Module.dynCall_iid(t,e,r)}catch(o){if(typeof o!="number"&&o!=="longjmp")throw o;Module.setThrew(1,0)}}function invoke_iii(t,e,r){try{return Module.dynCall_iii(t,e,r)}catch(o){if(typeof o!="number"&&o!=="longjmp")throw o;Module.setThrew(1,0)}}function invoke_viiddi(t,e,r,o,a,n){try{Module.dynCall_viiddi(t,e,r,o,a,n)}catch(u){if(typeof u!="number"&&u!=="longjmp")throw u;Module.setThrew(1,0)}}function invoke_viiiiii(t,e,r,o,a,n,u){try{Module.dynCall_viiiiii(t,e,r,o,a,n,u)}catch(A){if(typeof A!="number"&&A!=="longjmp")throw A;Module.setThrew(1,0)}}function invoke_dii(t,e,r){try{return Module.dynCall_dii(t,e,r)}catch(o){if(typeof o!="number"&&o!=="longjmp")throw o;Module.setThrew(1,0)}}function invoke_i(t){try{return Module.dynCall_i(t)}catch(e){if(typeof e!="number"&&e!=="longjmp")throw e;Module.setThrew(1,0)}}function invoke_iiiiii(t,e,r,o,a,n){try{return Module.dynCall_iiiiii(t,e,r,o,a,n)}catch(u){if(typeof u!="number"&&u!=="longjmp")throw u;Module.setThrew(1,0)}}function invoke_viiid(t,e,r,o,a){try{Module.dynCall_viiid(t,e,r,o,a)}catch(n){if(typeof n!="number"&&n!=="longjmp")throw n;Module.setThrew(1,0)}}function invoke_viififi(t,e,r,o,a,n,u){try{Module.dynCall_viififi(t,e,r,o,a,n,u)}catch(A){if(typeof A!="number"&&A!=="longjmp")throw A;Module.setThrew(1,0)}}function invoke_viii(t,e,r,o){try{Module.dynCall_viii(t,e,r,o)}catch(a){if(typeof a!="number"&&a!=="longjmp")throw a;Module.setThrew(1,0)}}function invoke_v(t){try{Module.dynCall_v(t)}catch(e){if(typeof e!="number"&&e!=="longjmp")throw e;Module.setThrew(1,0)}}function invoke_viid(t,e,r,o){try{Module.dynCall_viid(t,e,r,o)}catch(a){if(typeof a!="number"&&a!=="longjmp")throw a;Module.setThrew(1,0)}}function invoke_idd(t,e,r){try{return Module.dynCall_idd(t,e,r)}catch(o){if(typeof o!="number"&&o!=="longjmp")throw o;Module.setThrew(1,0)}}function invoke_viiii(t,e,r,o,a){try{Module.dynCall_viiii(t,e,r,o,a)}catch(n){if(typeof n!="number"&&n!=="longjmp")throw n;Module.setThrew(1,0)}}Module.asmGlobalArg={Math,Int8Array,Int16Array,Int32Array,Uint8Array,Uint16Array,Uint32Array,Float32Array,Float64Array,NaN:NaN,Infinity:1/0},Module.asmLibraryArg={abort,assert,enlargeMemory,getTotalMemory,abortOnCannotGrowMemory,invoke_viiiii,invoke_vif,invoke_vid,invoke_fiff,invoke_vi,invoke_vii,invoke_ii,invoke_viddi,invoke_vidd,invoke_iiii,invoke_diii,invoke_di,invoke_iid,invoke_iii,invoke_viiddi,invoke_viiiiii,invoke_dii,invoke_i,invoke_iiiiii,invoke_viiid,invoke_viififi,invoke_viii,invoke_v,invoke_viid,invoke_idd,invoke_viiii,_emscripten_asm_const_iiiii,_emscripten_asm_const_iiidddddd,_emscripten_asm_const_iiiid,__nbind_reference_external,_emscripten_asm_const_iiiiiiii,_removeAccessorPrefix,_typeModule,__nbind_register_pool,__decorate,_llvm_stackrestore,___cxa_atexit,__extends,__nbind_get_value_object,__ZN8facebook4yoga14YGNodeToStringEPNSt3__212basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEP6YGNode14YGPrintOptionsj,_emscripten_set_main_loop_timing,__nbind_register_primitive,__nbind_register_type,_emscripten_memcpy_big,__nbind_register_function,___setErrNo,__nbind_register_class,__nbind_finish,_abort,_nbind_value,_llvm_stacksave,___syscall54,_defineHidden,_emscripten_set_main_loop,_emscripten_get_now,__nbind_register_callback_signature,_emscripten_asm_const_iiiiii,__nbind_free_external,_emscripten_asm_const_iiii,_emscripten_asm_const_iiididi,___syscall6,_atexit,___syscall140,___syscall146,DYNAMICTOP_PTR,tempDoublePtr,ABORT,STACKTOP,STACK_MAX,cttz_i8,___dso_handle};var asm=function(t,e,r){var o=new t.Int8Array(r),a=new t.Int16Array(r),n=new t.Int32Array(r),u=new t.Uint8Array(r),A=new t.Uint16Array(r),p=new t.Uint32Array(r),h=new t.Float32Array(r),E=new t.Float64Array(r),I=e.DYNAMICTOP_PTR|0,v=e.tempDoublePtr|0,x=e.ABORT|0,C=e.STACKTOP|0,R=e.STACK_MAX|0,L=e.cttz_i8|0,U=e.___dso_handle|0,z=0,te=0,ae=0,le=0,ce=t.NaN,Ce=t.Infinity,de=0,Be=0,Ee=0,g=0,me=0,we=0,Ae=t.Math.floor,ne=t.Math.abs,Z=t.Math.sqrt,xe=t.Math.pow,Ne=t.Math.cos,ht=t.Math.sin,H=t.Math.tan,rt=t.Math.acos,Te=t.Math.asin,Fe=t.Math.atan,ke=t.Math.atan2,Ye=t.Math.exp,be=t.Math.log,et=t.Math.ceil,Ue=t.Math.imul,S=t.Math.min,w=t.Math.max,b=t.Math.clz32,y=t.Math.fround,F=e.abort,J=e.assert,X=e.enlargeMemory,$=e.getTotalMemory,ie=e.abortOnCannotGrowMemory,Se=e.invoke_viiiii,Re=e.invoke_vif,at=e.invoke_vid,dt=e.invoke_fiff,jt=e.invoke_vi,tr=e.invoke_vii,bt=e.invoke_ii,ln=e.invoke_viddi,kr=e.invoke_vidd,mr=e.invoke_iiii,Sr=e.invoke_diii,Kr=e.invoke_di,Kn=e.invoke_iid,Ms=e.invoke_iii,Ri=e.invoke_viiddi,gs=e.invoke_viiiiii,io=e.invoke_dii,Pi=e.invoke_i,Os=e.invoke_iiiiii,so=e.invoke_viiid,uc=e.invoke_viififi,Au=e.invoke_viii,sp=e.invoke_v,op=e.invoke_viid,Us=e.invoke_idd,Dn=e.invoke_viiii,oo=e._emscripten_asm_const_iiiii,_s=e._emscripten_asm_const_iiidddddd,ml=e._emscripten_asm_const_iiiid,yl=e.__nbind_reference_external,ao=e._emscripten_asm_const_iiiiiiii,Vn=e._removeAccessorPrefix,Mn=e._typeModule,Ti=e.__nbind_register_pool,On=e.__decorate,_i=e._llvm_stackrestore,ir=e.___cxa_atexit,Me=e.__extends,ii=e.__nbind_get_value_object,Ha=e.__ZN8facebook4yoga14YGNodeToStringEPNSt3__212basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEP6YGNode14YGPrintOptionsj,hr=e._emscripten_set_main_loop_timing,Ac=e.__nbind_register_primitive,fu=e.__nbind_register_type,fc=e._emscripten_memcpy_big,El=e.__nbind_register_function,vA=e.___setErrNo,pu=e.__nbind_register_class,Ie=e.__nbind_finish,Tt=e._abort,pc=e._nbind_value,Hi=e._llvm_stacksave,hu=e.___syscall54,Yt=e._defineHidden,Cl=e._emscripten_set_main_loop,DA=e._emscripten_get_now,ap=e.__nbind_register_callback_signature,hc=e._emscripten_asm_const_iiiiii,PA=e.__nbind_free_external,Qn=e._emscripten_asm_const_iiii,hi=e._emscripten_asm_const_iiididi,gc=e.___syscall6,bA=e._atexit,aa=e.___syscall140,Ni=e.___syscall146,_o=y(0);let Xe=y(0);function lo(s){s=s|0;var l=0;return l=C,C=C+s|0,C=C+15&-16,l|0}function dc(){return C|0}function gu(s){s=s|0,C=s}function qi(s,l){s=s|0,l=l|0,C=s,R=l}function du(s,l){s=s|0,l=l|0,z||(z=s,te=l)}function SA(s){s=s|0,we=s}function qa(){return we|0}function mc(){var s=0,l=0;Dr(8104,8,400)|0,Dr(8504,408,540)|0,s=9044,l=s+44|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));o[9088]=0,o[9089]=1,n[2273]=0,n[2274]=948,n[2275]=948,ir(17,8104,U|0)|0}function ds(s){s=s|0,ft(s+948|0)}function Ht(s){return s=y(s),((bu(s)|0)&2147483647)>>>0>2139095040|0}function Fn(s,l,c){s=s|0,l=l|0,c=c|0;e:do if(n[s+(l<<3)+4>>2]|0)s=s+(l<<3)|0;else{if((l|2|0)==3&&n[s+60>>2]|0){s=s+56|0;break}switch(l|0){case 0:case 2:case 4:case 5:{if(n[s+52>>2]|0){s=s+48|0;break e}break}default:}if(n[s+68>>2]|0){s=s+64|0;break}else{s=(l|1|0)==5?948:c;break}}while(!1);return s|0}function Ei(s){s=s|0;var l=0;return l=Jv(1e3)|0,la(s,(l|0)!=0,2456),n[2276]=(n[2276]|0)+1,Dr(l|0,8104,1e3)|0,o[s+2>>0]|0&&(n[l+4>>2]=2,n[l+12>>2]=4),n[l+976>>2]=s,l|0}function la(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0;d=C,C=C+16|0,f=d,l||(n[f>>2]=c,g0(s,5,3197,f)),C=d}function co(){return Ei(956)|0}function Hs(s){s=s|0;var l=0;return l=Kt(1e3)|0,ca(l,s),la(n[s+976>>2]|0,1,2456),n[2276]=(n[2276]|0)+1,n[l+944>>2]=0,l|0}function ca(s,l){s=s|0,l=l|0;var c=0;Dr(s|0,l|0,948)|0,Cd(s+948|0,l+948|0),c=s+960|0,s=l+960|0,l=c+40|0;do n[c>>2]=n[s>>2],c=c+4|0,s=s+4|0;while((c|0)<(l|0))}function ua(s){s=s|0;var l=0,c=0,f=0,d=0;if(l=s+944|0,c=n[l>>2]|0,c|0&&(Ho(c+948|0,s)|0,n[l>>2]=0),c=Ci(s)|0,c|0){l=0;do n[(ms(s,l)|0)+944>>2]=0,l=l+1|0;while((l|0)!=(c|0))}c=s+948|0,f=n[c>>2]|0,d=s+952|0,l=n[d>>2]|0,(l|0)!=(f|0)&&(n[d>>2]=l+(~((l+-4-f|0)>>>2)<<2)),ys(c),Xv(s),n[2276]=(n[2276]|0)+-1}function Ho(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0;f=n[s>>2]|0,k=s+4|0,c=n[k>>2]|0,m=c;e:do if((f|0)==(c|0))d=f,B=4;else for(s=f;;){if((n[s>>2]|0)==(l|0)){d=s,B=4;break e}if(s=s+4|0,(s|0)==(c|0)){s=0;break}}while(!1);return(B|0)==4&&((d|0)!=(c|0)?(f=d+4|0,s=m-f|0,l=s>>2,l&&(ww(d|0,f|0,s|0)|0,c=n[k>>2]|0),s=d+(l<<2)|0,(c|0)==(s|0)||(n[k>>2]=c+(~((c+-4-s|0)>>>2)<<2)),s=1):s=0),s|0}function Ci(s){return s=s|0,(n[s+952>>2]|0)-(n[s+948>>2]|0)>>2|0}function ms(s,l){s=s|0,l=l|0;var c=0;return c=n[s+948>>2]|0,(n[s+952>>2]|0)-c>>2>>>0>l>>>0?s=n[c+(l<<2)>>2]|0:s=0,s|0}function ys(s){s=s|0;var l=0,c=0,f=0,d=0;f=C,C=C+32|0,l=f,d=n[s>>2]|0,c=(n[s+4>>2]|0)-d|0,((n[s+8>>2]|0)-d|0)>>>0>c>>>0&&(d=c>>2,Ep(l,d,d,s+8|0),E0(s,l),UA(l)),C=f}function Es(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0;O=Ci(s)|0;do if(O|0){if((n[(ms(s,0)|0)+944>>2]|0)==(s|0)){if(!(Ho(s+948|0,l)|0))break;Dr(l+400|0,8504,540)|0,n[l+944>>2]=0,Le(s);break}B=n[(n[s+976>>2]|0)+12>>2]|0,k=s+948|0,Q=(B|0)==0,c=0,m=0;do f=n[(n[k>>2]|0)+(m<<2)>>2]|0,(f|0)==(l|0)?Le(s):(d=Hs(f)|0,n[(n[k>>2]|0)+(c<<2)>>2]=d,n[d+944>>2]=s,Q||BR[B&15](f,d,s,c),c=c+1|0),m=m+1|0;while((m|0)!=(O|0));if(c>>>0>>0){Q=s+948|0,k=s+952|0,B=c,c=n[k>>2]|0;do m=(n[Q>>2]|0)+(B<<2)|0,f=m+4|0,d=c-f|0,l=d>>2,l&&(ww(m|0,f|0,d|0)|0,c=n[k>>2]|0),d=c,f=m+(l<<2)|0,(d|0)!=(f|0)&&(c=d+(~((d+-4-f|0)>>>2)<<2)|0,n[k>>2]=c),B=B+1|0;while((B|0)!=(O|0))}}while(!1)}function qs(s){s=s|0;var l=0,c=0,f=0,d=0;Un(s,(Ci(s)|0)==0,2491),Un(s,(n[s+944>>2]|0)==0,2545),l=s+948|0,c=n[l>>2]|0,f=s+952|0,d=n[f>>2]|0,(d|0)!=(c|0)&&(n[f>>2]=d+(~((d+-4-c|0)>>>2)<<2)),ys(l),l=s+976|0,c=n[l>>2]|0,Dr(s|0,8104,1e3)|0,o[c+2>>0]|0&&(n[s+4>>2]=2,n[s+12>>2]=4),n[l>>2]=c}function Un(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0;d=C,C=C+16|0,f=d,l||(n[f>>2]=c,Ao(s,5,3197,f)),C=d}function Pn(){return n[2276]|0}function Cs(){var s=0;return s=Jv(20)|0,We((s|0)!=0,2592),n[2277]=(n[2277]|0)+1,n[s>>2]=n[239],n[s+4>>2]=n[240],n[s+8>>2]=n[241],n[s+12>>2]=n[242],n[s+16>>2]=n[243],s|0}function We(s,l){s=s|0,l=l|0;var c=0,f=0;f=C,C=C+16|0,c=f,s||(n[c>>2]=l,Ao(0,5,3197,c)),C=f}function tt(s){s=s|0,Xv(s),n[2277]=(n[2277]|0)+-1}function Bt(s,l){s=s|0,l=l|0;var c=0;l?(Un(s,(Ci(s)|0)==0,2629),c=1):(c=0,l=0),n[s+964>>2]=l,n[s+988>>2]=c}function or(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;f=C,C=C+16|0,m=f+8|0,d=f+4|0,B=f,n[d>>2]=l,Un(s,(n[l+944>>2]|0)==0,2709),Un(s,(n[s+964>>2]|0)==0,2763),ee(s),l=s+948|0,n[B>>2]=(n[l>>2]|0)+(c<<2),n[m>>2]=n[B>>2],ye(l,m,d)|0,n[(n[d>>2]|0)+944>>2]=s,Le(s),C=f}function ee(s){s=s|0;var l=0,c=0,f=0,d=0,m=0,B=0,k=0;if(c=Ci(s)|0,c|0&&(n[(ms(s,0)|0)+944>>2]|0)!=(s|0)){f=n[(n[s+976>>2]|0)+12>>2]|0,d=s+948|0,m=(f|0)==0,l=0;do B=n[(n[d>>2]|0)+(l<<2)>>2]|0,k=Hs(B)|0,n[(n[d>>2]|0)+(l<<2)>>2]=k,n[k+944>>2]=s,m||BR[f&15](B,k,s,l),l=l+1|0;while((l|0)!=(c|0))}}function ye(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0,se=0,je=0,Oe=0,Qe=0,$e=0,Je=0;$e=C,C=C+64|0,j=$e+52|0,k=$e+48|0,se=$e+28|0,je=$e+24|0,Oe=$e+20|0,Qe=$e,f=n[s>>2]|0,m=f,l=f+((n[l>>2]|0)-m>>2<<2)|0,f=s+4|0,d=n[f>>2]|0,B=s+8|0;do if(d>>>0<(n[B>>2]|0)>>>0){if((l|0)==(d|0)){n[l>>2]=n[c>>2],n[f>>2]=(n[f>>2]|0)+4;break}_A(s,l,d,l+4|0),l>>>0<=c>>>0&&(c=(n[f>>2]|0)>>>0>c>>>0?c+4|0:c),n[l>>2]=n[c>>2]}else{f=(d-m>>2)+1|0,d=N(s)|0,d>>>0>>0&&Jr(s),M=n[s>>2]|0,O=(n[B>>2]|0)-M|0,m=O>>1,Ep(Qe,O>>2>>>0>>1>>>0?m>>>0>>0?f:m:d,l-M>>2,s+8|0),M=Qe+8|0,f=n[M>>2]|0,m=Qe+12|0,O=n[m>>2]|0,B=O,Q=f;do if((f|0)==(O|0)){if(O=Qe+4|0,f=n[O>>2]|0,Je=n[Qe>>2]|0,d=Je,f>>>0<=Je>>>0){f=B-d>>1,f=f|0?f:1,Ep(se,f,f>>>2,n[Qe+16>>2]|0),n[je>>2]=n[O>>2],n[Oe>>2]=n[M>>2],n[k>>2]=n[je>>2],n[j>>2]=n[Oe>>2],lw(se,k,j),f=n[Qe>>2]|0,n[Qe>>2]=n[se>>2],n[se>>2]=f,f=se+4|0,Je=n[O>>2]|0,n[O>>2]=n[f>>2],n[f>>2]=Je,f=se+8|0,Je=n[M>>2]|0,n[M>>2]=n[f>>2],n[f>>2]=Je,f=se+12|0,Je=n[m>>2]|0,n[m>>2]=n[f>>2],n[f>>2]=Je,UA(se),f=n[M>>2]|0;break}m=f,B=((m-d>>2)+1|0)/-2|0,k=f+(B<<2)|0,d=Q-m|0,m=d>>2,m&&(ww(k|0,f|0,d|0)|0,f=n[O>>2]|0),Je=k+(m<<2)|0,n[M>>2]=Je,n[O>>2]=f+(B<<2),f=Je}while(!1);n[f>>2]=n[c>>2],n[M>>2]=(n[M>>2]|0)+4,l=C0(s,Qe,l)|0,UA(Qe)}while(!1);return C=$e,l|0}function Le(s){s=s|0;var l=0;do{if(l=s+984|0,o[l>>0]|0)break;o[l>>0]=1,h[s+504>>2]=y(ce),s=n[s+944>>2]|0}while(s|0)}function ft(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~((l+-4-f|0)>>>2)<<2)),gt(c))}function pt(s){return s=s|0,n[s+944>>2]|0}function Nt(s){s=s|0,Un(s,(n[s+964>>2]|0)!=0,2832),Le(s)}function rr(s){return s=s|0,(o[s+984>>0]|0)!=0|0}function $r(s,l){s=s|0,l=l|0,TUe(s,l,400)|0&&(Dr(s|0,l|0,400)|0,Le(s))}function ji(s){s=s|0;var l=Xe;return l=y(h[s+44>>2]),s=Ht(l)|0,y(s?y(0):l)}function rs(s){s=s|0;var l=Xe;return l=y(h[s+48>>2]),Ht(l)|0&&(l=o[(n[s+976>>2]|0)+2>>0]|0?y(1):y(0)),y(l)}function bi(s,l){s=s|0,l=l|0,n[s+980>>2]=l}function qo(s){return s=s|0,n[s+980>>2]|0}function xA(s,l){s=s|0,l=l|0;var c=0;c=s+4|0,(n[c>>2]|0)!=(l|0)&&(n[c>>2]=l,Le(s))}function kA(s){return s=s|0,n[s+4>>2]|0}function lp(s,l){s=s|0,l=l|0;var c=0;c=s+8|0,(n[c>>2]|0)!=(l|0)&&(n[c>>2]=l,Le(s))}function e0(s){return s=s|0,n[s+8>>2]|0}function mu(s,l){s=s|0,l=l|0;var c=0;c=s+12|0,(n[c>>2]|0)!=(l|0)&&(n[c>>2]=l,Le(s))}function t0(s){return s=s|0,n[s+12>>2]|0}function yu(s,l){s=s|0,l=l|0;var c=0;c=s+16|0,(n[c>>2]|0)!=(l|0)&&(n[c>>2]=l,Le(s))}function uo(s){return s=s|0,n[s+16>>2]|0}function QA(s,l){s=s|0,l=l|0;var c=0;c=s+20|0,(n[c>>2]|0)!=(l|0)&&(n[c>>2]=l,Le(s))}function yc(s){return s=s|0,n[s+20>>2]|0}function Aa(s,l){s=s|0,l=l|0;var c=0;c=s+24|0,(n[c>>2]|0)!=(l|0)&&(n[c>>2]=l,Le(s))}function r0(s){return s=s|0,n[s+24>>2]|0}function Ec(s,l){s=s|0,l=l|0;var c=0;c=s+28|0,(n[c>>2]|0)!=(l|0)&&(n[c>>2]=l,Le(s))}function hd(s){return s=s|0,n[s+28>>2]|0}function n0(s,l){s=s|0,l=l|0;var c=0;c=s+32|0,(n[c>>2]|0)!=(l|0)&&(n[c>>2]=l,Le(s))}function $n(s){return s=s|0,n[s+32>>2]|0}function cp(s,l){s=s|0,l=l|0;var c=0;c=s+36|0,(n[c>>2]|0)!=(l|0)&&(n[c>>2]=l,Le(s))}function i0(s){return s=s|0,n[s+36>>2]|0}function FA(s,l){s=s|0,l=y(l);var c=0;c=s+40|0,y(h[c>>2])!=l&&(h[c>>2]=l,Le(s))}function js(s,l){s=s|0,l=y(l);var c=0;c=s+44|0,y(h[c>>2])!=l&&(h[c>>2]=l,Le(s))}function Eu(s,l){s=s|0,l=y(l);var c=0;c=s+48|0,y(h[c>>2])!=l&&(h[c>>2]=l,Le(s))}function ja(s,l){s=s|0,l=y(l);var c=0,f=0,d=0,m=0;m=Ht(l)|0,c=(m^1)&1,f=s+52|0,d=s+56|0,m|y(h[f>>2])==l&&(n[d>>2]|0)==(c|0)||(h[f>>2]=l,n[d>>2]=c,Le(s))}function Gi(s,l){s=s|0,l=y(l);var c=0,f=0;f=s+52|0,c=s+56|0,y(h[f>>2])==l&&(n[c>>2]|0)==2||(h[f>>2]=l,f=Ht(l)|0,n[c>>2]=f?3:2,Le(s))}function fa(s,l){s=s|0,l=l|0;var c=0,f=0;f=l+52|0,c=n[f+4>>2]|0,l=s,n[l>>2]=n[f>>2],n[l+4>>2]=c}function Cu(s,l,c){s=s|0,l=l|0,c=y(c);var f=0,d=0,m=0;m=Ht(c)|0,f=(m^1)&1,d=s+132+(l<<3)|0,l=s+132+(l<<3)+4|0,m|y(h[d>>2])==c&&(n[l>>2]|0)==(f|0)||(h[d>>2]=c,n[l>>2]=f,Le(s))}function ws(s,l,c){s=s|0,l=l|0,c=y(c);var f=0,d=0,m=0;m=Ht(c)|0,f=m?0:2,d=s+132+(l<<3)|0,l=s+132+(l<<3)+4|0,m|y(h[d>>2])==c&&(n[l>>2]|0)==(f|0)||(h[d>>2]=c,n[l>>2]=f,Le(s))}function Cc(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=l+132+(c<<3)|0,l=n[f+4>>2]|0,c=s,n[c>>2]=n[f>>2],n[c+4>>2]=l}function wc(s,l,c){s=s|0,l=l|0,c=y(c);var f=0,d=0,m=0;m=Ht(c)|0,f=(m^1)&1,d=s+60+(l<<3)|0,l=s+60+(l<<3)+4|0,m|y(h[d>>2])==c&&(n[l>>2]|0)==(f|0)||(h[d>>2]=c,n[l>>2]=f,Le(s))}function Y(s,l,c){s=s|0,l=l|0,c=y(c);var f=0,d=0,m=0;m=Ht(c)|0,f=m?0:2,d=s+60+(l<<3)|0,l=s+60+(l<<3)+4|0,m|y(h[d>>2])==c&&(n[l>>2]|0)==(f|0)||(h[d>>2]=c,n[l>>2]=f,Le(s))}function Dt(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=l+60+(c<<3)|0,l=n[f+4>>2]|0,c=s,n[c>>2]=n[f>>2],n[c+4>>2]=l}function wl(s,l){s=s|0,l=l|0;var c=0;c=s+60+(l<<3)+4|0,(n[c>>2]|0)!=3&&(h[s+60+(l<<3)>>2]=y(ce),n[c>>2]=3,Le(s))}function Si(s,l,c){s=s|0,l=l|0,c=y(c);var f=0,d=0,m=0;m=Ht(c)|0,f=(m^1)&1,d=s+204+(l<<3)|0,l=s+204+(l<<3)+4|0,m|y(h[d>>2])==c&&(n[l>>2]|0)==(f|0)||(h[d>>2]=c,n[l>>2]=f,Le(s))}function Ic(s,l,c){s=s|0,l=l|0,c=y(c);var f=0,d=0,m=0;m=Ht(c)|0,f=m?0:2,d=s+204+(l<<3)|0,l=s+204+(l<<3)+4|0,m|y(h[d>>2])==c&&(n[l>>2]|0)==(f|0)||(h[d>>2]=c,n[l>>2]=f,Le(s))}function ct(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=l+204+(c<<3)|0,l=n[f+4>>2]|0,c=s,n[c>>2]=n[f>>2],n[c+4>>2]=l}function wu(s,l,c){s=s|0,l=l|0,c=y(c);var f=0,d=0,m=0;m=Ht(c)|0,f=(m^1)&1,d=s+276+(l<<3)|0,l=s+276+(l<<3)+4|0,m|y(h[d>>2])==c&&(n[l>>2]|0)==(f|0)||(h[d>>2]=c,n[l>>2]=f,Le(s))}function s0(s,l){return s=s|0,l=l|0,y(h[s+276+(l<<3)>>2])}function tw(s,l){s=s|0,l=y(l);var c=0,f=0,d=0,m=0;m=Ht(l)|0,c=(m^1)&1,f=s+348|0,d=s+352|0,m|y(h[f>>2])==l&&(n[d>>2]|0)==(c|0)||(h[f>>2]=l,n[d>>2]=c,Le(s))}function RA(s,l){s=s|0,l=y(l);var c=0,f=0;f=s+348|0,c=s+352|0,y(h[f>>2])==l&&(n[c>>2]|0)==2||(h[f>>2]=l,f=Ht(l)|0,n[c>>2]=f?3:2,Le(s))}function up(s){s=s|0;var l=0;l=s+352|0,(n[l>>2]|0)!=3&&(h[s+348>>2]=y(ce),n[l>>2]=3,Le(s))}function Br(s,l){s=s|0,l=l|0;var c=0,f=0;f=l+348|0,c=n[f+4>>2]|0,l=s,n[l>>2]=n[f>>2],n[l+4>>2]=c}function Is(s,l){s=s|0,l=y(l);var c=0,f=0,d=0,m=0;m=Ht(l)|0,c=(m^1)&1,f=s+356|0,d=s+360|0,m|y(h[f>>2])==l&&(n[d>>2]|0)==(c|0)||(h[f>>2]=l,n[d>>2]=c,Le(s))}function o0(s,l){s=s|0,l=y(l);var c=0,f=0;f=s+356|0,c=s+360|0,y(h[f>>2])==l&&(n[c>>2]|0)==2||(h[f>>2]=l,f=Ht(l)|0,n[c>>2]=f?3:2,Le(s))}function a0(s){s=s|0;var l=0;l=s+360|0,(n[l>>2]|0)!=3&&(h[s+356>>2]=y(ce),n[l>>2]=3,Le(s))}function l0(s,l){s=s|0,l=l|0;var c=0,f=0;f=l+356|0,c=n[f+4>>2]|0,l=s,n[l>>2]=n[f>>2],n[l+4>>2]=c}function Ap(s,l){s=s|0,l=y(l);var c=0,f=0,d=0,m=0;m=Ht(l)|0,c=(m^1)&1,f=s+364|0,d=s+368|0,m|y(h[f>>2])==l&&(n[d>>2]|0)==(c|0)||(h[f>>2]=l,n[d>>2]=c,Le(s))}function Bc(s,l){s=s|0,l=y(l);var c=0,f=0,d=0,m=0;m=Ht(l)|0,c=m?0:2,f=s+364|0,d=s+368|0,m|y(h[f>>2])==l&&(n[d>>2]|0)==(c|0)||(h[f>>2]=l,n[d>>2]=c,Le(s))}function Ct(s,l){s=s|0,l=l|0;var c=0,f=0;f=l+364|0,c=n[f+4>>2]|0,l=s,n[l>>2]=n[f>>2],n[l+4>>2]=c}function gd(s,l){s=s|0,l=y(l);var c=0,f=0,d=0,m=0;m=Ht(l)|0,c=(m^1)&1,f=s+372|0,d=s+376|0,m|y(h[f>>2])==l&&(n[d>>2]|0)==(c|0)||(h[f>>2]=l,n[d>>2]=c,Le(s))}function c0(s,l){s=s|0,l=y(l);var c=0,f=0,d=0,m=0;m=Ht(l)|0,c=m?0:2,f=s+372|0,d=s+376|0,m|y(h[f>>2])==l&&(n[d>>2]|0)==(c|0)||(h[f>>2]=l,n[d>>2]=c,Le(s))}function u0(s,l){s=s|0,l=l|0;var c=0,f=0;f=l+372|0,c=n[f+4>>2]|0,l=s,n[l>>2]=n[f>>2],n[l+4>>2]=c}function Iu(s,l){s=s|0,l=y(l);var c=0,f=0,d=0,m=0;m=Ht(l)|0,c=(m^1)&1,f=s+380|0,d=s+384|0,m|y(h[f>>2])==l&&(n[d>>2]|0)==(c|0)||(h[f>>2]=l,n[d>>2]=c,Le(s))}function dd(s,l){s=s|0,l=y(l);var c=0,f=0,d=0,m=0;m=Ht(l)|0,c=m?0:2,f=s+380|0,d=s+384|0,m|y(h[f>>2])==l&&(n[d>>2]|0)==(c|0)||(h[f>>2]=l,n[d>>2]=c,Le(s))}function A0(s,l){s=s|0,l=l|0;var c=0,f=0;f=l+380|0,c=n[f+4>>2]|0,l=s,n[l>>2]=n[f>>2],n[l+4>>2]=c}function Bu(s,l){s=s|0,l=y(l);var c=0,f=0,d=0,m=0;m=Ht(l)|0,c=(m^1)&1,f=s+388|0,d=s+392|0,m|y(h[f>>2])==l&&(n[d>>2]|0)==(c|0)||(h[f>>2]=l,n[d>>2]=c,Le(s))}function rw(s,l){s=s|0,l=y(l);var c=0,f=0,d=0,m=0;m=Ht(l)|0,c=m?0:2,f=s+388|0,d=s+392|0,m|y(h[f>>2])==l&&(n[d>>2]|0)==(c|0)||(h[f>>2]=l,n[d>>2]=c,Le(s))}function md(s,l){s=s|0,l=l|0;var c=0,f=0;f=l+388|0,c=n[f+4>>2]|0,l=s,n[l>>2]=n[f>>2],n[l+4>>2]=c}function pa(s,l){s=s|0,l=y(l);var c=0;c=s+396|0,y(h[c>>2])!=l&&(h[c>>2]=l,Le(s))}function vc(s){return s=s|0,y(h[s+396>>2])}function Il(s){return s=s|0,y(h[s+400>>2])}function vu(s){return s=s|0,y(h[s+404>>2])}function f0(s){return s=s|0,y(h[s+408>>2])}function TA(s){return s=s|0,y(h[s+412>>2])}function fp(s){return s=s|0,y(h[s+416>>2])}function Ga(s){return s=s|0,y(h[s+420>>2])}function p0(s,l){switch(s=s|0,l=l|0,Un(s,(l|0)<6,2918),l|0){case 0:{l=(n[s+496>>2]|0)==2?5:4;break}case 2:{l=(n[s+496>>2]|0)==2?4:5;break}default:}return y(h[s+424+(l<<2)>>2])}function pp(s,l){switch(s=s|0,l=l|0,Un(s,(l|0)<6,2918),l|0){case 0:{l=(n[s+496>>2]|0)==2?5:4;break}case 2:{l=(n[s+496>>2]|0)==2?4:5;break}default:}return y(h[s+448+(l<<2)>>2])}function jo(s,l){switch(s=s|0,l=l|0,Un(s,(l|0)<6,2918),l|0){case 0:{l=(n[s+496>>2]|0)==2?5:4;break}case 2:{l=(n[s+496>>2]|0)==2?4:5;break}default:}return y(h[s+472+(l<<2)>>2])}function Bs(s,l){s=s|0,l=l|0;var c=0,f=Xe;return c=n[s+4>>2]|0,(c|0)==(n[l+4>>2]|0)?c?(f=y(h[s>>2]),s=y(ne(y(f-y(h[l>>2]))))>2]=0,n[f+4>>2]=0,n[f+8>>2]=0,Ha(f|0,s|0,l|0,0),Ao(s,3,(o[f+11>>0]|0)<0?n[f>>2]|0:f,c),n3e(f),C=c}function Go(s,l,c,f){s=y(s),l=y(l),c=c|0,f=f|0;var d=Xe;s=y(s*l),d=y(mR(s,y(1)));do if(wi(d,y(0))|0)s=y(s-d);else{if(s=y(s-d),wi(d,y(1))|0){s=y(s+y(1));break}if(c){s=y(s+y(1));break}f||(d>y(.5)?d=y(1):(f=wi(d,y(.5))|0,d=y(f?1:0)),s=y(s+d))}while(!1);return y(s/l)}function NA(s,l,c,f,d,m,B,k,Q,O,M,j,se){s=s|0,l=y(l),c=c|0,f=y(f),d=d|0,m=y(m),B=B|0,k=y(k),Q=y(Q),O=y(O),M=y(M),j=y(j),se=se|0;var je=0,Oe=Xe,Qe=Xe,$e=Xe,Je=Xe,lt=Xe,_e=Xe;return Q>2]),Oe!=y(0))?($e=y(Go(l,Oe,0,0)),Je=y(Go(f,Oe,0,0)),Qe=y(Go(m,Oe,0,0)),Oe=y(Go(k,Oe,0,0))):(Qe=m,$e=l,Oe=k,Je=f),(d|0)==(s|0)?je=wi(Qe,$e)|0:je=0,(B|0)==(c|0)?se=wi(Oe,Je)|0:se=0,!je&&(lt=y(l-M),!(hp(s,lt,Q)|0))&&!(gp(s,lt,d,Q)|0)?je=h0(s,lt,d,m,Q)|0:je=1,!se&&(_e=y(f-j),!(hp(c,_e,O)|0))&&!(gp(c,_e,B,O)|0)?se=h0(c,_e,B,k,O)|0:se=1,se=je&se),se|0}function hp(s,l,c){return s=s|0,l=y(l),c=y(c),(s|0)==1?s=wi(l,c)|0:s=0,s|0}function gp(s,l,c,f){return s=s|0,l=y(l),c=c|0,f=y(f),(s|0)==2&(c|0)==0?l>=f?s=1:s=wi(l,f)|0:s=0,s|0}function h0(s,l,c,f,d){return s=s|0,l=y(l),c=c|0,f=y(f),d=y(d),(s|0)==2&(c|0)==2&f>l?d<=l?s=1:s=wi(l,d)|0:s=0,s|0}function ha(s,l,c,f,d,m,B,k,Q,O,M){s=s|0,l=y(l),c=y(c),f=f|0,d=d|0,m=m|0,B=y(B),k=y(k),Q=Q|0,O=O|0,M=M|0;var j=0,se=0,je=0,Oe=0,Qe=Xe,$e=Xe,Je=0,lt=0,_e=0,qe=0,Lt=0,Or=0,cr=0,Xt=0,Pr=0,Tr=0,ar=0,xn=Xe,go=Xe,mo=Xe,yo=0,Ca=0;ar=C,C=C+160|0,Xt=ar+152|0,cr=ar+120|0,Or=ar+104|0,_e=ar+72|0,Oe=ar+56|0,Lt=ar+8|0,lt=ar,qe=(n[2279]|0)+1|0,n[2279]=qe,Pr=s+984|0,o[Pr>>0]|0&&(n[s+512>>2]|0)!=(n[2278]|0)?Je=4:(n[s+516>>2]|0)==(f|0)?Tr=0:Je=4,(Je|0)==4&&(n[s+520>>2]=0,n[s+924>>2]=-1,n[s+928>>2]=-1,h[s+932>>2]=y(-1),h[s+936>>2]=y(-1),Tr=1);e:do if(n[s+964>>2]|0)if(Qe=y(cn(s,2,B)),$e=y(cn(s,0,B)),j=s+916|0,mo=y(h[j>>2]),go=y(h[s+920>>2]),xn=y(h[s+932>>2]),NA(d,l,m,c,n[s+924>>2]|0,mo,n[s+928>>2]|0,go,xn,y(h[s+936>>2]),Qe,$e,M)|0)Je=22;else if(je=n[s+520>>2]|0,!je)Je=21;else for(se=0;;){if(j=s+524+(se*24|0)|0,xn=y(h[j>>2]),go=y(h[s+524+(se*24|0)+4>>2]),mo=y(h[s+524+(se*24|0)+16>>2]),NA(d,l,m,c,n[s+524+(se*24|0)+8>>2]|0,xn,n[s+524+(se*24|0)+12>>2]|0,go,mo,y(h[s+524+(se*24|0)+20>>2]),Qe,$e,M)|0){Je=22;break e}if(se=se+1|0,se>>>0>=je>>>0){Je=21;break}}else{if(Q){if(j=s+916|0,!(wi(y(h[j>>2]),l)|0)){Je=21;break}if(!(wi(y(h[s+920>>2]),c)|0)){Je=21;break}if((n[s+924>>2]|0)!=(d|0)){Je=21;break}j=(n[s+928>>2]|0)==(m|0)?j:0,Je=22;break}if(je=n[s+520>>2]|0,!je)Je=21;else for(se=0;;){if(j=s+524+(se*24|0)|0,wi(y(h[j>>2]),l)|0&&wi(y(h[s+524+(se*24|0)+4>>2]),c)|0&&(n[s+524+(se*24|0)+8>>2]|0)==(d|0)&&(n[s+524+(se*24|0)+12>>2]|0)==(m|0)){Je=22;break e}if(se=se+1|0,se>>>0>=je>>>0){Je=21;break}}}while(!1);do if((Je|0)==21)o[11697]|0?(j=0,Je=28):(j=0,Je=31);else if((Je|0)==22){if(se=(o[11697]|0)!=0,!((j|0)!=0&(Tr^1)))if(se){Je=28;break}else{Je=31;break}Oe=j+16|0,n[s+908>>2]=n[Oe>>2],je=j+20|0,n[s+912>>2]=n[je>>2],(o[11698]|0)==0|se^1||(n[lt>>2]=LA(qe)|0,n[lt+4>>2]=qe,Ao(s,4,2972,lt),se=n[s+972>>2]|0,se|0&&ef[se&127](s),d=Ya(d,Q)|0,m=Ya(m,Q)|0,Ca=+y(h[Oe>>2]),yo=+y(h[je>>2]),n[Lt>>2]=d,n[Lt+4>>2]=m,E[Lt+8>>3]=+l,E[Lt+16>>3]=+c,E[Lt+24>>3]=Ca,E[Lt+32>>3]=yo,n[Lt+40>>2]=O,Ao(s,4,2989,Lt))}while(!1);return(Je|0)==28&&(se=LA(qe)|0,n[Oe>>2]=se,n[Oe+4>>2]=qe,n[Oe+8>>2]=Tr?3047:11699,Ao(s,4,3038,Oe),se=n[s+972>>2]|0,se|0&&ef[se&127](s),Lt=Ya(d,Q)|0,Je=Ya(m,Q)|0,n[_e>>2]=Lt,n[_e+4>>2]=Je,E[_e+8>>3]=+l,E[_e+16>>3]=+c,n[_e+24>>2]=O,Ao(s,4,3049,_e),Je=31),(Je|0)==31&&(si(s,l,c,f,d,m,B,k,Q,M),o[11697]|0&&(se=n[2279]|0,Lt=LA(se)|0,n[Or>>2]=Lt,n[Or+4>>2]=se,n[Or+8>>2]=Tr?3047:11699,Ao(s,4,3083,Or),se=n[s+972>>2]|0,se|0&&ef[se&127](s),Lt=Ya(d,Q)|0,Or=Ya(m,Q)|0,yo=+y(h[s+908>>2]),Ca=+y(h[s+912>>2]),n[cr>>2]=Lt,n[cr+4>>2]=Or,E[cr+8>>3]=yo,E[cr+16>>3]=Ca,n[cr+24>>2]=O,Ao(s,4,3092,cr)),n[s+516>>2]=f,j||(se=s+520|0,j=n[se>>2]|0,(j|0)==16&&(o[11697]|0&&Ao(s,4,3124,Xt),n[se>>2]=0,j=0),Q?j=s+916|0:(n[se>>2]=j+1,j=s+524+(j*24|0)|0),h[j>>2]=l,h[j+4>>2]=c,n[j+8>>2]=d,n[j+12>>2]=m,n[j+16>>2]=n[s+908>>2],n[j+20>>2]=n[s+912>>2],j=0)),Q&&(n[s+416>>2]=n[s+908>>2],n[s+420>>2]=n[s+912>>2],o[s+985>>0]=1,o[Pr>>0]=0),n[2279]=(n[2279]|0)+-1,n[s+512>>2]=n[2278],C=ar,Tr|(j|0)==0|0}function cn(s,l,c){s=s|0,l=l|0,c=y(c);var f=Xe;return f=y(K(s,l,c)),y(f+y(re(s,l,c)))}function Ao(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0;m=C,C=C+16|0,d=m,n[d>>2]=f,s?f=n[s+976>>2]|0:f=0,d0(f,s,l,c,d),C=m}function LA(s){return s=s|0,(s>>>0>60?3201:3201+(60-s)|0)|0}function Ya(s,l){s=s|0,l=l|0;var c=0,f=0,d=0;return d=C,C=C+32|0,c=d+12|0,f=d,n[c>>2]=n[254],n[c+4>>2]=n[255],n[c+8>>2]=n[256],n[f>>2]=n[257],n[f+4>>2]=n[258],n[f+8>>2]=n[259],(s|0)>2?s=11699:s=n[(l?f:c)+(s<<2)>>2]|0,C=d,s|0}function si(s,l,c,f,d,m,B,k,Q,O){s=s|0,l=y(l),c=y(c),f=f|0,d=d|0,m=m|0,B=y(B),k=y(k),Q=Q|0,O=O|0;var M=0,j=0,se=0,je=0,Oe=Xe,Qe=Xe,$e=Xe,Je=Xe,lt=Xe,_e=Xe,qe=Xe,Lt=0,Or=0,cr=0,Xt=Xe,Pr=Xe,Tr=0,ar=Xe,xn=0,go=0,mo=0,yo=0,Ca=0,xp=0,kp=0,Sl=0,Qp=0,Tu=0,Nu=0,Fp=0,Rp=0,Tp=0,Xr=0,xl=0,Np=0,kc=0,Lp=Xe,Mp=Xe,Lu=Xe,Mu=Xe,Qc=Xe,Ys=0,Za=0,Wo=0,kl=0,rf=0,nf=Xe,Ou=Xe,sf=Xe,of=Xe,Ws=Xe,Ps=Xe,Ql=0,Rn=Xe,af=Xe,Eo=Xe,Fc=Xe,Co=Xe,Rc=Xe,lf=0,cf=0,Tc=Xe,Ks=Xe,Fl=0,uf=0,Af=0,ff=0,xr=Xe,zn=0,bs=0,wo=0,Vs=0,Fr=0,ur=0,Rl=0,zt=Xe,pf=0,li=0;Rl=C,C=C+16|0,Ys=Rl+12|0,Za=Rl+8|0,Wo=Rl+4|0,kl=Rl,Un(s,(d|0)==0|(Ht(l)|0)^1,3326),Un(s,(m|0)==0|(Ht(c)|0)^1,3406),bs=mt(s,f)|0,n[s+496>>2]=bs,Fr=fr(2,bs)|0,ur=fr(0,bs)|0,h[s+440>>2]=y(K(s,Fr,B)),h[s+444>>2]=y(re(s,Fr,B)),h[s+428>>2]=y(K(s,ur,B)),h[s+436>>2]=y(re(s,ur,B)),h[s+464>>2]=y(Cr(s,Fr)),h[s+468>>2]=y(yn(s,Fr)),h[s+452>>2]=y(Cr(s,ur)),h[s+460>>2]=y(yn(s,ur)),h[s+488>>2]=y(oi(s,Fr,B)),h[s+492>>2]=y(Li(s,Fr,B)),h[s+476>>2]=y(oi(s,ur,B)),h[s+484>>2]=y(Li(s,ur,B));do if(n[s+964>>2]|0)y0(s,l,c,d,m,B,k);else{if(wo=s+948|0,Vs=(n[s+952>>2]|0)-(n[wo>>2]|0)>>2,!Vs){bv(s,l,c,d,m,B,k);break}if(!Q&&Sv(s,l,c,d,m,B,k)|0)break;ee(s),xl=s+508|0,o[xl>>0]=0,Fr=fr(n[s+4>>2]|0,bs)|0,ur=iw(Fr,bs)|0,zn=he(Fr)|0,Np=n[s+8>>2]|0,uf=s+28|0,kc=(n[uf>>2]|0)!=0,Co=zn?B:k,Tc=zn?k:B,Lp=y(mp(s,Fr,B)),Mp=y(sw(s,Fr,B)),Oe=y(mp(s,ur,B)),Rc=y(En(s,Fr,B)),Ks=y(En(s,ur,B)),cr=zn?d:m,Fl=zn?m:d,xr=zn?Rc:Ks,lt=zn?Ks:Rc,Fc=y(cn(s,2,B)),Je=y(cn(s,0,B)),Qe=y(y(Yr(s+364|0,B))-xr),$e=y(y(Yr(s+380|0,B))-xr),_e=y(y(Yr(s+372|0,k))-lt),qe=y(y(Yr(s+388|0,k))-lt),Lu=zn?Qe:_e,Mu=zn?$e:qe,Fc=y(l-Fc),l=y(Fc-xr),Ht(l)|0?xr=l:xr=y(_n(y(k0(l,$e)),Qe)),af=y(c-Je),l=y(af-lt),Ht(l)|0?Eo=l:Eo=y(_n(y(k0(l,qe)),_e)),Qe=zn?xr:Eo,Rn=zn?Eo:xr;e:do if((cr|0)==1)for(f=0,j=0;;){if(M=ms(s,j)|0,!f)y(is(M))>y(0)&&y(Gs(M))>y(0)?f=M:f=0;else if(wd(M)|0){je=0;break e}if(j=j+1|0,j>>>0>=Vs>>>0){je=f;break}}else je=0;while(!1);Lt=je+500|0,Or=je+504|0,f=0,M=0,l=y(0),se=0;do{if(j=n[(n[wo>>2]|0)+(se<<2)>>2]|0,(n[j+36>>2]|0)==1)Du(j),o[j+985>>0]=1,o[j+984>>0]=0;else{Bl(j),Q&&dp(j,mt(j,bs)|0,Qe,Rn,xr);do if((n[j+24>>2]|0)!=1)if((j|0)==(je|0)){n[Lt>>2]=n[2278],h[Or>>2]=y(0);break}else{Id(s,j,xr,d,Eo,xr,Eo,m,bs,O);break}else M|0&&(n[M+960>>2]=j),n[j+960>>2]=0,M=j,f=f|0?f:j;while(!1);Ps=y(h[j+504>>2]),l=y(l+y(Ps+y(cn(j,Fr,xr))))}se=se+1|0}while((se|0)!=(Vs|0));for(mo=l>Qe,Ql=kc&((cr|0)==2&mo)?1:cr,xn=(Fl|0)==1,Ca=xn&(Q^1),xp=(Ql|0)==1,kp=(Ql|0)==2,Sl=976+(Fr<<2)|0,Qp=(Fl|2|0)==2,Tp=xn&(kc^1),Tu=1040+(ur<<2)|0,Nu=1040+(Fr<<2)|0,Fp=976+(ur<<2)|0,Rp=(Fl|0)!=1,mo=kc&((cr|0)!=0&mo),go=s+976|0,xn=xn^1,l=Qe,Tr=0,yo=0,Ps=y(0),Qc=y(0);;){e:do if(Tr>>>0>>0)for(Or=n[wo>>2]|0,se=0,qe=y(0),_e=y(0),$e=y(0),Qe=y(0),j=0,M=0,je=Tr;;){if(Lt=n[Or+(je<<2)>>2]|0,(n[Lt+36>>2]|0)!=1&&(n[Lt+940>>2]=yo,(n[Lt+24>>2]|0)!=1)){if(Je=y(cn(Lt,Fr,xr)),Xr=n[Sl>>2]|0,c=y(Yr(Lt+380+(Xr<<3)|0,Co)),lt=y(h[Lt+504>>2]),c=y(k0(c,lt)),c=y(_n(y(Yr(Lt+364+(Xr<<3)|0,Co)),c)),kc&(se|0)!=0&y(Je+y(_e+c))>l){m=se,Je=qe,cr=je;break e}Je=y(Je+c),c=y(_e+Je),Je=y(qe+Je),wd(Lt)|0&&($e=y($e+y(is(Lt))),Qe=y(Qe-y(lt*y(Gs(Lt))))),M|0&&(n[M+960>>2]=Lt),n[Lt+960>>2]=0,se=se+1|0,M=Lt,j=j|0?j:Lt}else Je=qe,c=_e;if(je=je+1|0,je>>>0>>0)qe=Je,_e=c;else{m=se,cr=je;break}}else m=0,Je=y(0),$e=y(0),Qe=y(0),j=0,cr=Tr;while(!1);Xr=$e>y(0)&$ey(0)&QeMu&((Ht(Mu)|0)^1))l=Mu,Xr=51;else if(o[(n[go>>2]|0)+3>>0]|0)Xr=51;else{if(Xt!=y(0)&&y(is(s))!=y(0)){Xr=53;break}l=Je,Xr=53}while(!1);if((Xr|0)==51&&(Xr=0,Ht(l)|0?Xr=53:(Pr=y(l-Je),ar=l)),(Xr|0)==53&&(Xr=0,Je>2]|0,je=Pry(0),_e=y(Pr/Xt),$e=y(0),Je=y(0),l=y(0),M=j;do c=y(Yr(M+380+(se<<3)|0,Co)),Qe=y(Yr(M+364+(se<<3)|0,Co)),Qe=y(k0(c,y(_n(Qe,y(h[M+504>>2]))))),je?(c=y(Qe*y(Gs(M))),c!=y(-0)&&(zt=y(Qe-y(lt*c)),nf=y(Ii(M,Fr,zt,ar,xr)),zt!=nf)&&($e=y($e-y(nf-Qe)),l=y(l+c))):Lt&&(Ou=y(is(M)),Ou!=y(0))&&(zt=y(Qe+y(_e*Ou)),sf=y(Ii(M,Fr,zt,ar,xr)),zt!=sf)&&($e=y($e-y(sf-Qe)),Je=y(Je-Ou)),M=n[M+960>>2]|0;while(M|0);if(l=y(qe+l),Qe=y(Pr+$e),rf)l=y(0);else{lt=y(Xt+Je),je=n[Sl>>2]|0,Lt=Qey(0),lt=y(Qe/lt),l=y(0);do{zt=y(Yr(j+380+(je<<3)|0,Co)),$e=y(Yr(j+364+(je<<3)|0,Co)),$e=y(k0(zt,y(_n($e,y(h[j+504>>2]))))),Lt?(zt=y($e*y(Gs(j))),Qe=y(-zt),zt!=y(-0)?(zt=y(_e*Qe),Qe=y(Ii(j,Fr,y($e+(Or?Qe:zt)),ar,xr))):Qe=$e):se&&(of=y(is(j)),of!=y(0))?Qe=y(Ii(j,Fr,y($e+y(lt*of)),ar,xr)):Qe=$e,l=y(l-y(Qe-$e)),Je=y(cn(j,Fr,xr)),c=y(cn(j,ur,xr)),Qe=y(Qe+Je),h[Za>>2]=Qe,n[kl>>2]=1,$e=y(h[j+396>>2]);e:do if(Ht($e)|0){M=Ht(Rn)|0;do if(!M){if(mo|(ns(j,ur,Rn)|0|xn)||(da(s,j)|0)!=4||(n[(vl(j,ur)|0)+4>>2]|0)==3||(n[(bc(j,ur)|0)+4>>2]|0)==3)break;h[Ys>>2]=Rn,n[Wo>>2]=1;break e}while(!1);if(ns(j,ur,Rn)|0){M=n[j+992+(n[Fp>>2]<<2)>>2]|0,zt=y(c+y(Yr(M,Rn))),h[Ys>>2]=zt,M=Rp&(n[M+4>>2]|0)==2,n[Wo>>2]=((Ht(zt)|0|M)^1)&1;break}else{h[Ys>>2]=Rn,n[Wo>>2]=M?0:2;break}}else zt=y(Qe-Je),Xt=y(zt/$e),zt=y($e*zt),n[Wo>>2]=1,h[Ys>>2]=y(c+(zn?Xt:zt));while(!1);yr(j,Fr,ar,xr,kl,Za),yr(j,ur,Rn,xr,Wo,Ys);do if(!(ns(j,ur,Rn)|0)&&(da(s,j)|0)==4){if((n[(vl(j,ur)|0)+4>>2]|0)==3){M=0;break}M=(n[(bc(j,ur)|0)+4>>2]|0)!=3}else M=0;while(!1);zt=y(h[Za>>2]),Xt=y(h[Ys>>2]),pf=n[kl>>2]|0,li=n[Wo>>2]|0,ha(j,zn?zt:Xt,zn?Xt:zt,bs,zn?pf:li,zn?li:pf,xr,Eo,Q&(M^1),3488,O)|0,o[xl>>0]=o[xl>>0]|o[j+508>>0],j=n[j+960>>2]|0}while(j|0)}}else l=y(0);if(l=y(Pr+l),li=l>0]=li|u[xl>>0],kp&l>y(0)?(M=n[Sl>>2]|0,n[s+364+(M<<3)+4>>2]|0&&(Ws=y(Yr(s+364+(M<<3)|0,Co)),Ws>=y(0))?Qe=y(_n(y(0),y(Ws-y(ar-l)))):Qe=y(0)):Qe=l,Lt=Tr>>>0>>0,Lt){je=n[wo>>2]|0,se=Tr,M=0;do j=n[je+(se<<2)>>2]|0,n[j+24>>2]|0||(M=((n[(vl(j,Fr)|0)+4>>2]|0)==3&1)+M|0,M=M+((n[(bc(j,Fr)|0)+4>>2]|0)==3&1)|0),se=se+1|0;while((se|0)!=(cr|0));M?(Je=y(0),c=y(0)):Xr=101}else Xr=101;e:do if((Xr|0)==101)switch(Xr=0,Np|0){case 1:{M=0,Je=y(Qe*y(.5)),c=y(0);break e}case 2:{M=0,Je=Qe,c=y(0);break e}case 3:{if(m>>>0<=1){M=0,Je=y(0),c=y(0);break e}c=y((m+-1|0)>>>0),M=0,Je=y(0),c=y(y(_n(Qe,y(0)))/c);break e}case 5:{c=y(Qe/y((m+1|0)>>>0)),M=0,Je=c;break e}case 4:{c=y(Qe/y(m>>>0)),M=0,Je=y(c*y(.5));break e}default:{M=0,Je=y(0),c=y(0);break e}}while(!1);if(l=y(Lp+Je),Lt){$e=y(Qe/y(M|0)),se=n[wo>>2]|0,j=Tr,Qe=y(0);do{M=n[se+(j<<2)>>2]|0;e:do if((n[M+36>>2]|0)!=1){switch(n[M+24>>2]|0){case 1:{if(gi(M,Fr)|0){if(!Q)break e;zt=y(Mr(M,Fr,ar)),zt=y(zt+y(Cr(s,Fr))),zt=y(zt+y(K(M,Fr,xr))),h[M+400+(n[Nu>>2]<<2)>>2]=zt;break e}break}case 0:if(li=(n[(vl(M,Fr)|0)+4>>2]|0)==3,zt=y($e+l),l=li?zt:l,Q&&(li=M+400+(n[Nu>>2]<<2)|0,h[li>>2]=y(l+y(h[li>>2]))),li=(n[(bc(M,Fr)|0)+4>>2]|0)==3,zt=y($e+l),l=li?zt:l,Ca){zt=y(c+y(cn(M,Fr,xr))),Qe=Rn,l=y(l+y(zt+y(h[M+504>>2])));break e}else{l=y(l+y(c+y(ss(M,Fr,xr)))),Qe=y(_n(Qe,y(ss(M,ur,xr))));break e}default:}Q&&(zt=y(Je+y(Cr(s,Fr))),li=M+400+(n[Nu>>2]<<2)|0,h[li>>2]=y(zt+y(h[li>>2])))}while(!1);j=j+1|0}while((j|0)!=(cr|0))}else Qe=y(0);if(c=y(Mp+l),Qp?Je=y(y(Ii(s,ur,y(Ks+Qe),Tc,B))-Ks):Je=Rn,$e=y(y(Ii(s,ur,y(Ks+(Tp?Rn:Qe)),Tc,B))-Ks),Lt&Q){j=Tr;do{se=n[(n[wo>>2]|0)+(j<<2)>>2]|0;do if((n[se+36>>2]|0)!=1){if((n[se+24>>2]|0)==1){if(gi(se,ur)|0){if(zt=y(Mr(se,ur,Rn)),zt=y(zt+y(Cr(s,ur))),zt=y(zt+y(K(se,ur,xr))),M=n[Tu>>2]|0,h[se+400+(M<<2)>>2]=zt,!(Ht(zt)|0))break}else M=n[Tu>>2]|0;zt=y(Cr(s,ur)),h[se+400+(M<<2)>>2]=y(zt+y(K(se,ur,xr)));break}M=da(s,se)|0;do if((M|0)==4){if((n[(vl(se,ur)|0)+4>>2]|0)==3){Xr=139;break}if((n[(bc(se,ur)|0)+4>>2]|0)==3){Xr=139;break}if(ns(se,ur,Rn)|0){l=Oe;break}pf=n[se+908+(n[Sl>>2]<<2)>>2]|0,n[Ys>>2]=pf,l=y(h[se+396>>2]),li=Ht(l)|0,Qe=(n[v>>2]=pf,y(h[v>>2])),li?l=$e:(Pr=y(cn(se,ur,xr)),zt=y(Qe/l),l=y(l*Qe),l=y(Pr+(zn?zt:l))),h[Za>>2]=l,h[Ys>>2]=y(y(cn(se,Fr,xr))+Qe),n[Wo>>2]=1,n[kl>>2]=1,yr(se,Fr,ar,xr,Wo,Ys),yr(se,ur,Rn,xr,kl,Za),l=y(h[Ys>>2]),Pr=y(h[Za>>2]),zt=zn?l:Pr,l=zn?Pr:l,li=((Ht(zt)|0)^1)&1,ha(se,zt,l,bs,li,((Ht(l)|0)^1)&1,xr,Eo,1,3493,O)|0,l=Oe}else Xr=139;while(!1);e:do if((Xr|0)==139){Xr=0,l=y(Je-y(ss(se,ur,xr)));do if((n[(vl(se,ur)|0)+4>>2]|0)==3){if((n[(bc(se,ur)|0)+4>>2]|0)!=3)break;l=y(Oe+y(_n(y(0),y(l*y(.5)))));break e}while(!1);if((n[(bc(se,ur)|0)+4>>2]|0)==3){l=Oe;break}if((n[(vl(se,ur)|0)+4>>2]|0)==3){l=y(Oe+y(_n(y(0),l)));break}switch(M|0){case 1:{l=Oe;break e}case 2:{l=y(Oe+y(l*y(.5)));break e}default:{l=y(Oe+l);break e}}}while(!1);zt=y(Ps+l),li=se+400+(n[Tu>>2]<<2)|0,h[li>>2]=y(zt+y(h[li>>2]))}while(!1);j=j+1|0}while((j|0)!=(cr|0))}if(Ps=y(Ps+$e),Qc=y(_n(Qc,c)),m=yo+1|0,cr>>>0>=Vs>>>0)break;l=ar,Tr=cr,yo=m}do if(Q){if(M=m>>>0>1,!M&&!(Yi(s)|0))break;if(!(Ht(Rn)|0)){l=y(Rn-Ps);e:do switch(n[s+12>>2]|0){case 3:{Oe=y(Oe+l),_e=y(0);break}case 2:{Oe=y(Oe+y(l*y(.5))),_e=y(0);break}case 4:{Rn>Ps?_e=y(l/y(m>>>0)):_e=y(0);break}case 7:if(Rn>Ps){Oe=y(Oe+y(l/y(m<<1>>>0))),_e=y(l/y(m>>>0)),_e=M?_e:y(0);break e}else{Oe=y(Oe+y(l*y(.5))),_e=y(0);break e}case 6:{_e=y(l/y(yo>>>0)),_e=Rn>Ps&M?_e:y(0);break}default:_e=y(0)}while(!1);if(m|0)for(Lt=1040+(ur<<2)|0,Or=976+(ur<<2)|0,je=0,j=0;;){e:do if(j>>>0>>0)for(Qe=y(0),$e=y(0),l=y(0),se=j;;){M=n[(n[wo>>2]|0)+(se<<2)>>2]|0;do if((n[M+36>>2]|0)!=1&&!(n[M+24>>2]|0)){if((n[M+940>>2]|0)!=(je|0))break e;if(Bd(M,ur)|0&&(zt=y(h[M+908+(n[Or>>2]<<2)>>2]),l=y(_n(l,y(zt+y(cn(M,ur,xr)))))),(da(s,M)|0)!=5)break;Ws=y(Ka(M)),Ws=y(Ws+y(K(M,0,xr))),zt=y(h[M+912>>2]),zt=y(y(zt+y(cn(M,0,xr)))-Ws),Ws=y(_n($e,Ws)),zt=y(_n(Qe,zt)),Qe=zt,$e=Ws,l=y(_n(l,y(Ws+zt)))}while(!1);if(M=se+1|0,M>>>0>>0)se=M;else{se=M;break}}else $e=y(0),l=y(0),se=j;while(!1);if(lt=y(_e+l),c=Oe,Oe=y(Oe+lt),j>>>0>>0){Je=y(c+$e),M=j;do{j=n[(n[wo>>2]|0)+(M<<2)>>2]|0;e:do if((n[j+36>>2]|0)!=1&&!(n[j+24>>2]|0))switch(da(s,j)|0){case 1:{zt=y(c+y(K(j,ur,xr))),h[j+400+(n[Lt>>2]<<2)>>2]=zt;break e}case 3:{zt=y(y(Oe-y(re(j,ur,xr)))-y(h[j+908+(n[Or>>2]<<2)>>2])),h[j+400+(n[Lt>>2]<<2)>>2]=zt;break e}case 2:{zt=y(c+y(y(lt-y(h[j+908+(n[Or>>2]<<2)>>2]))*y(.5))),h[j+400+(n[Lt>>2]<<2)>>2]=zt;break e}case 4:{if(zt=y(c+y(K(j,ur,xr))),h[j+400+(n[Lt>>2]<<2)>>2]=zt,ns(j,ur,Rn)|0||(zn?(Qe=y(h[j+908>>2]),l=y(Qe+y(cn(j,Fr,xr))),$e=lt):($e=y(h[j+912>>2]),$e=y($e+y(cn(j,ur,xr))),l=lt,Qe=y(h[j+908>>2])),wi(l,Qe)|0&&wi($e,y(h[j+912>>2]))|0))break e;ha(j,l,$e,bs,1,1,xr,Eo,1,3501,O)|0;break e}case 5:{h[j+404>>2]=y(y(Je-y(Ka(j)))+y(Mr(j,0,Rn)));break e}default:break e}while(!1);M=M+1|0}while((M|0)!=(se|0))}if(je=je+1|0,(je|0)==(m|0))break;j=se}}}while(!1);if(h[s+908>>2]=y(Ii(s,2,Fc,B,B)),h[s+912>>2]=y(Ii(s,0,af,k,B)),Ql|0&&(lf=n[s+32>>2]|0,cf=(Ql|0)==2,!(cf&(lf|0)!=2))?cf&(lf|0)==2&&(l=y(Rc+ar),l=y(_n(y(k0(l,y(MA(s,Fr,Qc,Co)))),Rc)),Xr=198):(l=y(Ii(s,Fr,Qc,Co,B)),Xr=198),(Xr|0)==198&&(h[s+908+(n[976+(Fr<<2)>>2]<<2)>>2]=l),Fl|0&&(Af=n[s+32>>2]|0,ff=(Fl|0)==2,!(ff&(Af|0)!=2))?ff&(Af|0)==2&&(l=y(Ks+Rn),l=y(_n(y(k0(l,y(MA(s,ur,y(Ks+Ps),Tc)))),Ks)),Xr=204):(l=y(Ii(s,ur,y(Ks+Ps),Tc,B)),Xr=204),(Xr|0)==204&&(h[s+908+(n[976+(ur<<2)>>2]<<2)>>2]=l),Q){if((n[uf>>2]|0)==2){j=976+(ur<<2)|0,se=1040+(ur<<2)|0,M=0;do je=ms(s,M)|0,n[je+24>>2]|0||(pf=n[j>>2]|0,zt=y(h[s+908+(pf<<2)>>2]),li=je+400+(n[se>>2]<<2)|0,zt=y(zt-y(h[li>>2])),h[li>>2]=y(zt-y(h[je+908+(pf<<2)>>2]))),M=M+1|0;while((M|0)!=(Vs|0))}if(f|0){M=zn?Ql:d;do vd(s,f,xr,M,Eo,bs,O),f=n[f+960>>2]|0;while(f|0)}if(M=(Fr|2|0)==3,j=(ur|2|0)==3,M|j){f=0;do se=n[(n[wo>>2]|0)+(f<<2)>>2]|0,(n[se+36>>2]|0)!=1&&(M&&yp(s,se,Fr),j&&yp(s,se,ur)),f=f+1|0;while((f|0)!=(Vs|0))}}}while(!1);C=Rl}function ga(s,l){s=s|0,l=y(l);var c=0;la(s,l>=y(0),3147),c=l==y(0),h[s+4>>2]=c?y(0):l}function Dc(s,l,c,f){s=s|0,l=y(l),c=y(c),f=f|0;var d=Xe,m=Xe,B=0,k=0,Q=0;n[2278]=(n[2278]|0)+1,Bl(s),ns(s,2,l)|0?(d=y(Yr(n[s+992>>2]|0,l)),Q=1,d=y(d+y(cn(s,2,l)))):(d=y(Yr(s+380|0,l)),d>=y(0)?Q=2:(Q=((Ht(l)|0)^1)&1,d=l)),ns(s,0,c)|0?(m=y(Yr(n[s+996>>2]|0,c)),k=1,m=y(m+y(cn(s,0,l)))):(m=y(Yr(s+388|0,c)),m>=y(0)?k=2:(k=((Ht(c)|0)^1)&1,m=c)),B=s+976|0,ha(s,d,m,f,Q,k,l,c,1,3189,n[B>>2]|0)|0&&(dp(s,n[s+496>>2]|0,l,c,l),Pc(s,y(h[(n[B>>2]|0)+4>>2]),y(0),y(0)),o[11696]|0)&&yd(s,7)}function Bl(s){s=s|0;var l=0,c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0;k=C,C=C+32|0,B=k+24|0,m=k+16|0,f=k+8|0,d=k,c=0;do l=s+380+(c<<3)|0,n[s+380+(c<<3)+4>>2]|0&&(Q=l,O=n[Q+4>>2]|0,M=f,n[M>>2]=n[Q>>2],n[M+4>>2]=O,M=s+364+(c<<3)|0,O=n[M+4>>2]|0,Q=d,n[Q>>2]=n[M>>2],n[Q+4>>2]=O,n[m>>2]=n[f>>2],n[m+4>>2]=n[f+4>>2],n[B>>2]=n[d>>2],n[B+4>>2]=n[d+4>>2],Bs(m,B)|0)||(l=s+348+(c<<3)|0),n[s+992+(c<<2)>>2]=l,c=c+1|0;while((c|0)!=2);C=k}function ns(s,l,c){s=s|0,l=l|0,c=y(c);var f=0;switch(s=n[s+992+(n[976+(l<<2)>>2]<<2)>>2]|0,n[s+4>>2]|0){case 0:case 3:{s=0;break}case 1:{y(h[s>>2])>2])>2]|0){case 2:{l=y(y(y(h[s>>2])*l)/y(100));break}case 1:{l=y(h[s>>2]);break}default:l=y(ce)}return y(l)}function dp(s,l,c,f,d){s=s|0,l=l|0,c=y(c),f=y(f),d=y(d);var m=0,B=Xe;l=n[s+944>>2]|0?l:1,m=fr(n[s+4>>2]|0,l)|0,l=iw(m,l)|0,c=y(Dd(s,m,c)),f=y(Dd(s,l,f)),B=y(c+y(K(s,m,d))),h[s+400+(n[1040+(m<<2)>>2]<<2)>>2]=B,c=y(c+y(re(s,m,d))),h[s+400+(n[1e3+(m<<2)>>2]<<2)>>2]=c,c=y(f+y(K(s,l,d))),h[s+400+(n[1040+(l<<2)>>2]<<2)>>2]=c,d=y(f+y(re(s,l,d))),h[s+400+(n[1e3+(l<<2)>>2]<<2)>>2]=d}function Pc(s,l,c,f){s=s|0,l=y(l),c=y(c),f=y(f);var d=0,m=0,B=Xe,k=Xe,Q=0,O=0,M=Xe,j=0,se=Xe,je=Xe,Oe=Xe,Qe=Xe;if(l!=y(0)&&(d=s+400|0,Qe=y(h[d>>2]),m=s+404|0,Oe=y(h[m>>2]),j=s+416|0,je=y(h[j>>2]),O=s+420|0,B=y(h[O>>2]),se=y(Qe+c),M=y(Oe+f),f=y(se+je),k=y(M+B),Q=(n[s+988>>2]|0)==1,h[d>>2]=y(Go(Qe,l,0,Q)),h[m>>2]=y(Go(Oe,l,0,Q)),c=y(mR(y(je*l),y(1))),wi(c,y(0))|0?m=0:m=(wi(c,y(1))|0)^1,c=y(mR(y(B*l),y(1))),wi(c,y(0))|0?d=0:d=(wi(c,y(1))|0)^1,Qe=y(Go(f,l,Q&m,Q&(m^1))),h[j>>2]=y(Qe-y(Go(se,l,0,Q))),Qe=y(Go(k,l,Q&d,Q&(d^1))),h[O>>2]=y(Qe-y(Go(M,l,0,Q))),m=(n[s+952>>2]|0)-(n[s+948>>2]|0)>>2,m|0)){d=0;do Pc(ms(s,d)|0,l,se,M),d=d+1|0;while((d|0)!=(m|0))}}function nw(s,l,c,f,d){switch(s=s|0,l=l|0,c=c|0,f=f|0,d=d|0,c|0){case 5:case 0:{s=e7(n[489]|0,f,d)|0;break}default:s=$Ue(f,d)|0}return s|0}function g0(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0;d=C,C=C+16|0,m=d,n[m>>2]=f,d0(s,0,l,c,m),C=d}function d0(s,l,c,f,d){if(s=s|0,l=l|0,c=c|0,f=f|0,d=d|0,s=s|0?s:956,w7[n[s+8>>2]&1](s,l,c,f,d)|0,(c|0)==5)Tt();else return}function Wa(s,l,c){s=s|0,l=l|0,c=c|0,o[s+l>>0]=c&1}function Cd(s,l){s=s|0,l=l|0;var c=0,f=0;n[s>>2]=0,n[s+4>>2]=0,n[s+8>>2]=0,c=l+4|0,f=(n[c>>2]|0)-(n[l>>2]|0)>>2,f|0&&(m0(s,f),Qt(s,n[l>>2]|0,n[c>>2]|0,f))}function m0(s,l){s=s|0,l=l|0;var c=0;if((N(s)|0)>>>0>>0&&Jr(s),l>>>0>1073741823)Tt();else{c=Kt(l<<2)|0,n[s+4>>2]=c,n[s>>2]=c,n[s+8>>2]=c+(l<<2);return}}function Qt(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0,f=s+4|0,s=c-l|0,(s|0)>0&&(Dr(n[f>>2]|0,l|0,s|0)|0,n[f>>2]=(n[f>>2]|0)+(s>>>2<<2))}function N(s){return s=s|0,1073741823}function K(s,l,c){return s=s|0,l=l|0,c=y(c),he(l)|0&&n[s+96>>2]|0?s=s+92|0:s=Fn(s+60|0,n[1040+(l<<2)>>2]|0,992)|0,y(ze(s,c))}function re(s,l,c){return s=s|0,l=l|0,c=y(c),he(l)|0&&n[s+104>>2]|0?s=s+100|0:s=Fn(s+60|0,n[1e3+(l<<2)>>2]|0,992)|0,y(ze(s,c))}function he(s){return s=s|0,(s|1|0)==3|0}function ze(s,l){return s=s|0,l=y(l),(n[s+4>>2]|0)==3?l=y(0):l=y(Yr(s,l)),y(l)}function mt(s,l){return s=s|0,l=l|0,s=n[s>>2]|0,(s|0?s:(l|0)>1?l:1)|0}function fr(s,l){s=s|0,l=l|0;var c=0;e:do if((l|0)==2){switch(s|0){case 2:{s=3;break e}case 3:break;default:{c=4;break e}}s=2}else c=4;while(!1);return s|0}function Cr(s,l){s=s|0,l=l|0;var c=Xe;return he(l)|0&&n[s+312>>2]|0&&(c=y(h[s+308>>2]),c>=y(0))||(c=y(_n(y(h[(Fn(s+276|0,n[1040+(l<<2)>>2]|0,992)|0)>>2]),y(0)))),y(c)}function yn(s,l){s=s|0,l=l|0;var c=Xe;return he(l)|0&&n[s+320>>2]|0&&(c=y(h[s+316>>2]),c>=y(0))||(c=y(_n(y(h[(Fn(s+276|0,n[1e3+(l<<2)>>2]|0,992)|0)>>2]),y(0)))),y(c)}function oi(s,l,c){s=s|0,l=l|0,c=y(c);var f=Xe;return he(l)|0&&n[s+240>>2]|0&&(f=y(Yr(s+236|0,c)),f>=y(0))||(f=y(_n(y(Yr(Fn(s+204|0,n[1040+(l<<2)>>2]|0,992)|0,c)),y(0)))),y(f)}function Li(s,l,c){s=s|0,l=l|0,c=y(c);var f=Xe;return he(l)|0&&n[s+248>>2]|0&&(f=y(Yr(s+244|0,c)),f>=y(0))||(f=y(_n(y(Yr(Fn(s+204|0,n[1e3+(l<<2)>>2]|0,992)|0,c)),y(0)))),y(f)}function y0(s,l,c,f,d,m,B){s=s|0,l=y(l),c=y(c),f=f|0,d=d|0,m=y(m),B=y(B);var k=Xe,Q=Xe,O=Xe,M=Xe,j=Xe,se=Xe,je=0,Oe=0,Qe=0;Qe=C,C=C+16|0,je=Qe,Oe=s+964|0,Un(s,(n[Oe>>2]|0)!=0,3519),k=y(En(s,2,l)),Q=y(En(s,0,l)),O=y(cn(s,2,l)),M=y(cn(s,0,l)),Ht(l)|0?j=l:j=y(_n(y(0),y(y(l-O)-k))),Ht(c)|0?se=c:se=y(_n(y(0),y(y(c-M)-Q))),(f|0)==1&(d|0)==1?(h[s+908>>2]=y(Ii(s,2,y(l-O),m,m)),l=y(Ii(s,0,y(c-M),B,m))):(I7[n[Oe>>2]&1](je,s,j,f,se,d),j=y(k+y(h[je>>2])),se=y(l-O),h[s+908>>2]=y(Ii(s,2,(f|2|0)==2?j:se,m,m)),se=y(Q+y(h[je+4>>2])),l=y(c-M),l=y(Ii(s,0,(d|2|0)==2?se:l,B,m))),h[s+912>>2]=l,C=Qe}function bv(s,l,c,f,d,m,B){s=s|0,l=y(l),c=y(c),f=f|0,d=d|0,m=y(m),B=y(B);var k=Xe,Q=Xe,O=Xe,M=Xe;O=y(En(s,2,m)),k=y(En(s,0,m)),M=y(cn(s,2,m)),Q=y(cn(s,0,m)),l=y(l-M),h[s+908>>2]=y(Ii(s,2,(f|2|0)==2?O:l,m,m)),c=y(c-Q),h[s+912>>2]=y(Ii(s,0,(d|2|0)==2?k:c,B,m))}function Sv(s,l,c,f,d,m,B){s=s|0,l=y(l),c=y(c),f=f|0,d=d|0,m=y(m),B=y(B);var k=0,Q=Xe,O=Xe;return k=(f|0)==2,!(l<=y(0)&k)&&!(c<=y(0)&(d|0)==2)&&!((f|0)==1&(d|0)==1)?s=0:(Q=y(cn(s,0,m)),O=y(cn(s,2,m)),k=l>2]=y(Ii(s,2,k?y(0):l,m,m)),l=y(c-Q),k=c>2]=y(Ii(s,0,k?y(0):l,B,m)),s=1),s|0}function iw(s,l){return s=s|0,l=l|0,OA(s)|0?s=fr(2,l)|0:s=0,s|0}function mp(s,l,c){return s=s|0,l=l|0,c=y(c),c=y(oi(s,l,c)),y(c+y(Cr(s,l)))}function sw(s,l,c){return s=s|0,l=l|0,c=y(c),c=y(Li(s,l,c)),y(c+y(yn(s,l)))}function En(s,l,c){s=s|0,l=l|0,c=y(c);var f=Xe;return f=y(mp(s,l,c)),y(f+y(sw(s,l,c)))}function wd(s){return s=s|0,n[s+24>>2]|0?s=0:y(is(s))!=y(0)?s=1:s=y(Gs(s))!=y(0),s|0}function is(s){s=s|0;var l=Xe;if(n[s+944>>2]|0){if(l=y(h[s+44>>2]),Ht(l)|0)return l=y(h[s+40>>2]),s=l>y(0)&((Ht(l)|0)^1),y(s?l:y(0))}else l=y(0);return y(l)}function Gs(s){s=s|0;var l=Xe,c=0,f=Xe;do if(n[s+944>>2]|0){if(l=y(h[s+48>>2]),Ht(l)|0){if(c=o[(n[s+976>>2]|0)+2>>0]|0,!(c<<24>>24)&&(f=y(h[s+40>>2]),f>24?y(1):y(0)}}else l=y(0);while(!1);return y(l)}function Du(s){s=s|0;var l=0,c=0;if(Od(s+400|0,0,540)|0,o[s+985>>0]=1,ee(s),c=Ci(s)|0,c|0){l=s+948|0,s=0;do Du(n[(n[l>>2]|0)+(s<<2)>>2]|0),s=s+1|0;while((s|0)!=(c|0))}}function Id(s,l,c,f,d,m,B,k,Q,O){s=s|0,l=l|0,c=y(c),f=f|0,d=y(d),m=y(m),B=y(B),k=k|0,Q=Q|0,O=O|0;var M=0,j=Xe,se=0,je=0,Oe=Xe,Qe=Xe,$e=0,Je=Xe,lt=0,_e=Xe,qe=0,Lt=0,Or=0,cr=0,Xt=0,Pr=0,Tr=0,ar=0,xn=0,go=0;xn=C,C=C+16|0,Or=xn+12|0,cr=xn+8|0,Xt=xn+4|0,Pr=xn,ar=fr(n[s+4>>2]|0,Q)|0,qe=he(ar)|0,j=y(Yr(ow(l)|0,qe?m:B)),Lt=ns(l,2,m)|0,Tr=ns(l,0,B)|0;do if(!(Ht(j)|0)&&!(Ht(qe?c:d)|0)){if(M=l+504|0,!(Ht(y(h[M>>2]))|0)&&(!(aw(n[l+976>>2]|0,0)|0)||(n[l+500>>2]|0)==(n[2278]|0)))break;h[M>>2]=y(_n(j,y(En(l,ar,m))))}else se=7;while(!1);do if((se|0)==7){if(lt=qe^1,!(lt|Lt^1)){B=y(Yr(n[l+992>>2]|0,m)),h[l+504>>2]=y(_n(B,y(En(l,2,m))));break}if(!(qe|Tr^1)){B=y(Yr(n[l+996>>2]|0,B)),h[l+504>>2]=y(_n(B,y(En(l,0,m))));break}h[Or>>2]=y(ce),h[cr>>2]=y(ce),n[Xt>>2]=0,n[Pr>>2]=0,Je=y(cn(l,2,m)),_e=y(cn(l,0,m)),Lt?(Oe=y(Je+y(Yr(n[l+992>>2]|0,m))),h[Or>>2]=Oe,n[Xt>>2]=1,je=1):(je=0,Oe=y(ce)),Tr?(j=y(_e+y(Yr(n[l+996>>2]|0,B))),h[cr>>2]=j,n[Pr>>2]=1,M=1):(M=0,j=y(ce)),se=n[s+32>>2]|0,qe&(se|0)==2?se=2:Ht(Oe)|0&&!(Ht(c)|0)&&(h[Or>>2]=c,n[Xt>>2]=2,je=2,Oe=c),!((se|0)==2<)&&Ht(j)|0&&!(Ht(d)|0)&&(h[cr>>2]=d,n[Pr>>2]=2,M=2,j=d),Qe=y(h[l+396>>2]),$e=Ht(Qe)|0;do if($e)se=je;else{if((je|0)==1<){h[cr>>2]=y(y(Oe-Je)/Qe),n[Pr>>2]=1,M=1,se=1;break}qe&(M|0)==1?(h[Or>>2]=y(Qe*y(j-_e)),n[Xt>>2]=1,M=1,se=1):se=je}while(!1);go=Ht(c)|0,je=(da(s,l)|0)!=4,!(qe|Lt|((f|0)!=1|go)|(je|(se|0)==1))&&(h[Or>>2]=c,n[Xt>>2]=1,!$e)&&(h[cr>>2]=y(y(c-Je)/Qe),n[Pr>>2]=1,M=1),!(Tr|lt|((k|0)!=1|(Ht(d)|0))|(je|(M|0)==1))&&(h[cr>>2]=d,n[Pr>>2]=1,!$e)&&(h[Or>>2]=y(Qe*y(d-_e)),n[Xt>>2]=1),yr(l,2,m,m,Xt,Or),yr(l,0,B,m,Pr,cr),c=y(h[Or>>2]),d=y(h[cr>>2]),ha(l,c,d,Q,n[Xt>>2]|0,n[Pr>>2]|0,m,B,0,3565,O)|0,B=y(h[l+908+(n[976+(ar<<2)>>2]<<2)>>2]),h[l+504>>2]=y(_n(B,y(En(l,ar,m))))}while(!1);n[l+500>>2]=n[2278],C=xn}function Ii(s,l,c,f,d){return s=s|0,l=l|0,c=y(c),f=y(f),d=y(d),f=y(MA(s,l,c,f)),y(_n(f,y(En(s,l,d))))}function da(s,l){return s=s|0,l=l|0,l=l+20|0,l=n[(n[l>>2]|0?l:s+16|0)>>2]|0,(l|0)==5&&OA(n[s+4>>2]|0)|0&&(l=1),l|0}function vl(s,l){return s=s|0,l=l|0,he(l)|0&&n[s+96>>2]|0?l=4:l=n[1040+(l<<2)>>2]|0,s+60+(l<<3)|0}function bc(s,l){return s=s|0,l=l|0,he(l)|0&&n[s+104>>2]|0?l=5:l=n[1e3+(l<<2)>>2]|0,s+60+(l<<3)|0}function yr(s,l,c,f,d,m){switch(s=s|0,l=l|0,c=y(c),f=y(f),d=d|0,m=m|0,c=y(Yr(s+380+(n[976+(l<<2)>>2]<<3)|0,c)),c=y(c+y(cn(s,l,f))),n[d>>2]|0){case 2:case 1:{d=Ht(c)|0,f=y(h[m>>2]),h[m>>2]=d|f>2]=2,h[m>>2]=c);break}default:}}function gi(s,l){return s=s|0,l=l|0,s=s+132|0,he(l)|0&&n[(Fn(s,4,948)|0)+4>>2]|0?s=1:s=(n[(Fn(s,n[1040+(l<<2)>>2]|0,948)|0)+4>>2]|0)!=0,s|0}function Mr(s,l,c){s=s|0,l=l|0,c=y(c);var f=0,d=0;return s=s+132|0,he(l)|0&&(f=Fn(s,4,948)|0,(n[f+4>>2]|0)!=0)?d=4:(f=Fn(s,n[1040+(l<<2)>>2]|0,948)|0,n[f+4>>2]|0?d=4:c=y(0)),(d|0)==4&&(c=y(Yr(f,c))),y(c)}function ss(s,l,c){s=s|0,l=l|0,c=y(c);var f=Xe;return f=y(h[s+908+(n[976+(l<<2)>>2]<<2)>>2]),f=y(f+y(K(s,l,c))),y(f+y(re(s,l,c)))}function Yi(s){s=s|0;var l=0,c=0,f=0;e:do if(OA(n[s+4>>2]|0)|0)l=0;else if((n[s+16>>2]|0)!=5)if(c=Ci(s)|0,!c)l=0;else for(l=0;;){if(f=ms(s,l)|0,!(n[f+24>>2]|0)&&(n[f+20>>2]|0)==5){l=1;break e}if(l=l+1|0,l>>>0>=c>>>0){l=0;break}}else l=1;while(!1);return l|0}function Bd(s,l){s=s|0,l=l|0;var c=Xe;return c=y(h[s+908+(n[976+(l<<2)>>2]<<2)>>2]),c>=y(0)&((Ht(c)|0)^1)|0}function Ka(s){s=s|0;var l=Xe,c=0,f=0,d=0,m=0,B=0,k=0,Q=Xe;if(c=n[s+968>>2]|0,c)Q=y(h[s+908>>2]),l=y(h[s+912>>2]),l=y(m7[c&0](s,Q,l)),Un(s,(Ht(l)|0)^1,3573);else{m=Ci(s)|0;do if(m|0){for(c=0,d=0;;){if(f=ms(s,d)|0,n[f+940>>2]|0){B=8;break}if((n[f+24>>2]|0)!=1)if(k=(da(s,f)|0)==5,k){c=f;break}else c=c|0?c:f;if(d=d+1|0,d>>>0>=m>>>0){B=8;break}}if((B|0)==8&&!c)break;return l=y(Ka(c)),y(l+y(h[c+404>>2]))}while(!1);l=y(h[s+912>>2])}return y(l)}function MA(s,l,c,f){s=s|0,l=l|0,c=y(c),f=y(f);var d=Xe,m=0;return OA(l)|0?(l=1,m=3):he(l)|0?(l=0,m=3):(f=y(ce),d=y(ce)),(m|0)==3&&(d=y(Yr(s+364+(l<<3)|0,f)),f=y(Yr(s+380+(l<<3)|0,f))),m=f=y(0)&((Ht(f)|0)^1)),c=m?f:c,m=d>=y(0)&((Ht(d)|0)^1)&c>2]|0,m)|0,Oe=iw($e,m)|0,Qe=he($e)|0,j=y(cn(l,2,c)),se=y(cn(l,0,c)),ns(l,2,c)|0?k=y(j+y(Yr(n[l+992>>2]|0,c))):gi(l,2)|0&&lr(l,2)|0?(k=y(h[s+908>>2]),Q=y(Cr(s,2)),Q=y(k-y(Q+y(yn(s,2)))),k=y(Mr(l,2,c)),k=y(Ii(l,2,y(Q-y(k+y(Pu(l,2,c)))),c,c))):k=y(ce),ns(l,0,d)|0?Q=y(se+y(Yr(n[l+996>>2]|0,d))):gi(l,0)|0&&lr(l,0)|0?(Q=y(h[s+912>>2]),lt=y(Cr(s,0)),lt=y(Q-y(lt+y(yn(s,0)))),Q=y(Mr(l,0,d)),Q=y(Ii(l,0,y(lt-y(Q+y(Pu(l,0,d)))),d,c))):Q=y(ce),O=Ht(k)|0,M=Ht(Q)|0;do if(O^M&&(je=y(h[l+396>>2]),!(Ht(je)|0)))if(O){k=y(j+y(y(Q-se)*je));break}else{lt=y(se+y(y(k-j)/je)),Q=M?lt:Q;break}while(!1);M=Ht(k)|0,O=Ht(Q)|0,M|O&&(_e=(M^1)&1,f=c>y(0)&((f|0)!=0&M),k=Qe?k:f?c:k,ha(l,k,Q,m,Qe?_e:f?2:_e,M&(O^1)&1,k,Q,0,3623,B)|0,k=y(h[l+908>>2]),k=y(k+y(cn(l,2,c))),Q=y(h[l+912>>2]),Q=y(Q+y(cn(l,0,c)))),ha(l,k,Q,m,1,1,k,Q,1,3635,B)|0,lr(l,$e)|0&&!(gi(l,$e)|0)?(_e=n[976+($e<<2)>>2]|0,lt=y(h[s+908+(_e<<2)>>2]),lt=y(lt-y(h[l+908+(_e<<2)>>2])),lt=y(lt-y(yn(s,$e))),lt=y(lt-y(re(l,$e,c))),lt=y(lt-y(Pu(l,$e,Qe?c:d))),h[l+400+(n[1040+($e<<2)>>2]<<2)>>2]=lt):Je=21;do if((Je|0)==21){if(!(gi(l,$e)|0)&&(n[s+8>>2]|0)==1){_e=n[976+($e<<2)>>2]|0,lt=y(h[s+908+(_e<<2)>>2]),lt=y(y(lt-y(h[l+908+(_e<<2)>>2]))*y(.5)),h[l+400+(n[1040+($e<<2)>>2]<<2)>>2]=lt;break}!(gi(l,$e)|0)&&(n[s+8>>2]|0)==2&&(_e=n[976+($e<<2)>>2]|0,lt=y(h[s+908+(_e<<2)>>2]),lt=y(lt-y(h[l+908+(_e<<2)>>2])),h[l+400+(n[1040+($e<<2)>>2]<<2)>>2]=lt)}while(!1);lr(l,Oe)|0&&!(gi(l,Oe)|0)?(_e=n[976+(Oe<<2)>>2]|0,lt=y(h[s+908+(_e<<2)>>2]),lt=y(lt-y(h[l+908+(_e<<2)>>2])),lt=y(lt-y(yn(s,Oe))),lt=y(lt-y(re(l,Oe,c))),lt=y(lt-y(Pu(l,Oe,Qe?d:c))),h[l+400+(n[1040+(Oe<<2)>>2]<<2)>>2]=lt):Je=30;do if((Je|0)==30&&!(gi(l,Oe)|0)){if((da(s,l)|0)==2){_e=n[976+(Oe<<2)>>2]|0,lt=y(h[s+908+(_e<<2)>>2]),lt=y(y(lt-y(h[l+908+(_e<<2)>>2]))*y(.5)),h[l+400+(n[1040+(Oe<<2)>>2]<<2)>>2]=lt;break}_e=(da(s,l)|0)==3,_e^(n[s+28>>2]|0)==2&&(_e=n[976+(Oe<<2)>>2]|0,lt=y(h[s+908+(_e<<2)>>2]),lt=y(lt-y(h[l+908+(_e<<2)>>2])),h[l+400+(n[1040+(Oe<<2)>>2]<<2)>>2]=lt)}while(!1)}function yp(s,l,c){s=s|0,l=l|0,c=c|0;var f=Xe,d=0;d=n[976+(c<<2)>>2]|0,f=y(h[l+908+(d<<2)>>2]),f=y(y(h[s+908+(d<<2)>>2])-f),f=y(f-y(h[l+400+(n[1040+(c<<2)>>2]<<2)>>2])),h[l+400+(n[1e3+(c<<2)>>2]<<2)>>2]=f}function OA(s){return s=s|0,(s|1|0)==1|0}function ow(s){s=s|0;var l=Xe;switch(n[s+56>>2]|0){case 0:case 3:{l=y(h[s+40>>2]),l>y(0)&((Ht(l)|0)^1)?s=o[(n[s+976>>2]|0)+2>>0]|0?1056:992:s=1056;break}default:s=s+52|0}return s|0}function aw(s,l){return s=s|0,l=l|0,(o[s+l>>0]|0)!=0|0}function lr(s,l){return s=s|0,l=l|0,s=s+132|0,he(l)|0&&n[(Fn(s,5,948)|0)+4>>2]|0?s=1:s=(n[(Fn(s,n[1e3+(l<<2)>>2]|0,948)|0)+4>>2]|0)!=0,s|0}function Pu(s,l,c){s=s|0,l=l|0,c=y(c);var f=0,d=0;return s=s+132|0,he(l)|0&&(f=Fn(s,5,948)|0,(n[f+4>>2]|0)!=0)?d=4:(f=Fn(s,n[1e3+(l<<2)>>2]|0,948)|0,n[f+4>>2]|0?d=4:c=y(0)),(d|0)==4&&(c=y(Yr(f,c))),y(c)}function Dd(s,l,c){return s=s|0,l=l|0,c=y(c),gi(s,l)|0?c=y(Mr(s,l,c)):c=y(-y(Pu(s,l,c))),y(c)}function bu(s){return s=y(s),h[v>>2]=s,n[v>>2]|0|0}function Ep(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>1073741823)Tt();else{d=Kt(l<<2)|0;break}else d=0;while(!1);n[s>>2]=d,f=d+(c<<2)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l<<2)}function E0(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(0-(d>>2)<<2)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function UA(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~((f+-4-l|0)>>>2)<<2)),s=n[s>>2]|0,s|0&>(s)}function _A(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0;if(B=s+4|0,k=n[B>>2]|0,d=k-f|0,m=d>>2,s=l+(m<<2)|0,s>>>0>>0){f=k;do n[f>>2]=n[s>>2],s=s+4|0,f=(n[B>>2]|0)+4|0,n[B>>2]=f;while(s>>>0>>0)}m|0&&ww(k+(0-m<<2)|0,l|0,d|0)|0}function C0(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0;return k=l+4|0,Q=n[k>>2]|0,d=n[s>>2]|0,B=c,m=B-d|0,f=Q+(0-(m>>2)<<2)|0,n[k>>2]=f,(m|0)>0&&Dr(f|0,d|0,m|0)|0,d=s+4|0,m=l+8|0,f=(n[d>>2]|0)-B|0,(f|0)>0&&(Dr(n[m>>2]|0,c|0,f|0)|0,n[m>>2]=(n[m>>2]|0)+(f>>>2<<2)),B=n[s>>2]|0,n[s>>2]=n[k>>2],n[k>>2]=B,B=n[d>>2]|0,n[d>>2]=n[m>>2],n[m>>2]=B,B=s+8|0,c=l+12|0,s=n[B>>2]|0,n[B>>2]=n[c>>2],n[c>>2]=s,n[l>>2]=n[k>>2],Q|0}function lw(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;if(B=n[l>>2]|0,m=n[c>>2]|0,(B|0)!=(m|0)){d=s+8|0,c=((m+-4-B|0)>>>2)+1|0,s=B,f=n[d>>2]|0;do n[f>>2]=n[s>>2],f=(n[d>>2]|0)+4|0,n[d>>2]=f,s=s+4|0;while((s|0)!=(m|0));n[l>>2]=B+(c<<2)}}function Pd(){mc()}function ma(){var s=0;return s=Kt(4)|0,HA(s),s|0}function HA(s){s=s|0,n[s>>2]=Cs()|0}function Sc(s){s=s|0,s|0&&(w0(s),gt(s))}function w0(s){s=s|0,tt(n[s>>2]|0)}function bd(s,l,c){s=s|0,l=l|0,c=c|0,Wa(n[s>>2]|0,l,c)}function fo(s,l){s=s|0,l=y(l),ga(n[s>>2]|0,l)}function xv(s,l){return s=s|0,l=l|0,aw(n[s>>2]|0,l)|0}function cw(){var s=0;return s=Kt(8)|0,kv(s,0),s|0}function kv(s,l){s=s|0,l=l|0,l?l=Ei(n[l>>2]|0)|0:l=co()|0,n[s>>2]=l,n[s+4>>2]=0,bi(l,s)}function eF(s){s=s|0;var l=0;return l=Kt(8)|0,kv(l,s),l|0}function Qv(s){s=s|0,s|0&&(Su(s),gt(s))}function Su(s){s=s|0;var l=0;ua(n[s>>2]|0),l=s+4|0,s=n[l>>2]|0,n[l>>2]=0,s|0&&(qA(s),gt(s))}function qA(s){s=s|0,jA(s)}function jA(s){s=s|0,s=n[s>>2]|0,s|0&&PA(s|0)}function uw(s){return s=s|0,qo(s)|0}function Sd(s){s=s|0;var l=0,c=0;c=s+4|0,l=n[c>>2]|0,n[c>>2]=0,l|0&&(qA(l),gt(l)),qs(n[s>>2]|0)}function tF(s,l){s=s|0,l=l|0,$r(n[s>>2]|0,n[l>>2]|0)}function rF(s,l){s=s|0,l=l|0,Aa(n[s>>2]|0,l)}function Fv(s,l,c){s=s|0,l=l|0,c=+c,Cu(n[s>>2]|0,l,y(c))}function Rv(s,l,c){s=s|0,l=l|0,c=+c,ws(n[s>>2]|0,l,y(c))}function Aw(s,l){s=s|0,l=l|0,mu(n[s>>2]|0,l)}function xu(s,l){s=s|0,l=l|0,yu(n[s>>2]|0,l)}function nF(s,l){s=s|0,l=l|0,QA(n[s>>2]|0,l)}function iF(s,l){s=s|0,l=l|0,xA(n[s>>2]|0,l)}function Cp(s,l){s=s|0,l=l|0,Ec(n[s>>2]|0,l)}function sF(s,l){s=s|0,l=l|0,lp(n[s>>2]|0,l)}function Tv(s,l,c){s=s|0,l=l|0,c=+c,wc(n[s>>2]|0,l,y(c))}function GA(s,l,c){s=s|0,l=l|0,c=+c,Y(n[s>>2]|0,l,y(c))}function oF(s,l){s=s|0,l=l|0,wl(n[s>>2]|0,l)}function aF(s,l){s=s|0,l=l|0,n0(n[s>>2]|0,l)}function Nv(s,l){s=s|0,l=l|0,cp(n[s>>2]|0,l)}function fw(s,l){s=s|0,l=+l,FA(n[s>>2]|0,y(l))}function pw(s,l){s=s|0,l=+l,ja(n[s>>2]|0,y(l))}function lF(s,l){s=s|0,l=+l,Gi(n[s>>2]|0,y(l))}function cF(s,l){s=s|0,l=+l,js(n[s>>2]|0,y(l))}function Dl(s,l){s=s|0,l=+l,Eu(n[s>>2]|0,y(l))}function hw(s,l){s=s|0,l=+l,tw(n[s>>2]|0,y(l))}function uF(s,l){s=s|0,l=+l,RA(n[s>>2]|0,y(l))}function YA(s){s=s|0,up(n[s>>2]|0)}function xd(s,l){s=s|0,l=+l,Is(n[s>>2]|0,y(l))}function ku(s,l){s=s|0,l=+l,o0(n[s>>2]|0,y(l))}function gw(s){s=s|0,a0(n[s>>2]|0)}function dw(s,l){s=s|0,l=+l,Ap(n[s>>2]|0,y(l))}function AF(s,l){s=s|0,l=+l,Bc(n[s>>2]|0,y(l))}function Lv(s,l){s=s|0,l=+l,gd(n[s>>2]|0,y(l))}function WA(s,l){s=s|0,l=+l,c0(n[s>>2]|0,y(l))}function Mv(s,l){s=s|0,l=+l,Iu(n[s>>2]|0,y(l))}function kd(s,l){s=s|0,l=+l,dd(n[s>>2]|0,y(l))}function Ov(s,l){s=s|0,l=+l,Bu(n[s>>2]|0,y(l))}function Uv(s,l){s=s|0,l=+l,rw(n[s>>2]|0,y(l))}function Qd(s,l){s=s|0,l=+l,pa(n[s>>2]|0,y(l))}function _v(s,l,c){s=s|0,l=l|0,c=+c,wu(n[s>>2]|0,l,y(c))}function fF(s,l,c){s=s|0,l=l|0,c=+c,Si(n[s>>2]|0,l,y(c))}function P(s,l,c){s=s|0,l=l|0,c=+c,Ic(n[s>>2]|0,l,y(c))}function D(s){return s=s|0,r0(n[s>>2]|0)|0}function T(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0;f=C,C=C+16|0,d=f,Cc(d,n[l>>2]|0,c),q(s,d),C=f}function q(s,l){s=s|0,l=l|0,W(s,n[l+4>>2]|0,+y(h[l>>2]))}function W(s,l,c){s=s|0,l=l|0,c=+c,n[s>>2]=l,E[s+8>>3]=c}function fe(s){return s=s|0,t0(n[s>>2]|0)|0}function De(s){return s=s|0,uo(n[s>>2]|0)|0}function vt(s){return s=s|0,yc(n[s>>2]|0)|0}function wt(s){return s=s|0,kA(n[s>>2]|0)|0}function St(s){return s=s|0,hd(n[s>>2]|0)|0}function _r(s){return s=s|0,e0(n[s>>2]|0)|0}function os(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0;f=C,C=C+16|0,d=f,Dt(d,n[l>>2]|0,c),q(s,d),C=f}function di(s){return s=s|0,$n(n[s>>2]|0)|0}function po(s){return s=s|0,i0(n[s>>2]|0)|0}function KA(s,l){s=s|0,l=l|0;var c=0,f=0;c=C,C=C+16|0,f=c,fa(f,n[l>>2]|0),q(s,f),C=c}function Yo(s){return s=s|0,+ +y(ji(n[s>>2]|0))}function nt(s){return s=s|0,+ +y(rs(n[s>>2]|0))}function Ve(s,l){s=s|0,l=l|0;var c=0,f=0;c=C,C=C+16|0,f=c,Br(f,n[l>>2]|0),q(s,f),C=c}function At(s,l){s=s|0,l=l|0;var c=0,f=0;c=C,C=C+16|0,f=c,l0(f,n[l>>2]|0),q(s,f),C=c}function Wt(s,l){s=s|0,l=l|0;var c=0,f=0;c=C,C=C+16|0,f=c,Ct(f,n[l>>2]|0),q(s,f),C=c}function vr(s,l){s=s|0,l=l|0;var c=0,f=0;c=C,C=C+16|0,f=c,u0(f,n[l>>2]|0),q(s,f),C=c}function bn(s,l){s=s|0,l=l|0;var c=0,f=0;c=C,C=C+16|0,f=c,A0(f,n[l>>2]|0),q(s,f),C=c}function Qr(s,l){s=s|0,l=l|0;var c=0,f=0;c=C,C=C+16|0,f=c,md(f,n[l>>2]|0),q(s,f),C=c}function Sn(s){return s=s|0,+ +y(vc(n[s>>2]|0))}function ai(s,l){return s=s|0,l=l|0,+ +y(s0(n[s>>2]|0,l))}function tn(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0;f=C,C=C+16|0,d=f,ct(d,n[l>>2]|0,c),q(s,d),C=f}function ho(s,l,c){s=s|0,l=l|0,c=c|0,or(n[s>>2]|0,n[l>>2]|0,c)}function pF(s,l){s=s|0,l=l|0,Es(n[s>>2]|0,n[l>>2]|0)}function nve(s){return s=s|0,Ci(n[s>>2]|0)|0}function ive(s){return s=s|0,s=pt(n[s>>2]|0)|0,s?s=uw(s)|0:s=0,s|0}function sve(s,l){return s=s|0,l=l|0,s=ms(n[s>>2]|0,l)|0,s?s=uw(s)|0:s=0,s|0}function ove(s,l){s=s|0,l=l|0;var c=0,f=0;f=Kt(4)|0,W5(f,l),c=s+4|0,l=n[c>>2]|0,n[c>>2]=f,l|0&&(qA(l),gt(l)),Bt(n[s>>2]|0,1)}function W5(s,l){s=s|0,l=l|0,yve(s,l)}function ave(s,l,c,f,d,m){s=s|0,l=l|0,c=y(c),f=f|0,d=y(d),m=m|0;var B=0,k=0;B=C,C=C+16|0,k=B,lve(k,qo(l)|0,+c,f,+d,m),h[s>>2]=y(+E[k>>3]),h[s+4>>2]=y(+E[k+8>>3]),C=B}function lve(s,l,c,f,d,m){s=s|0,l=l|0,c=+c,f=f|0,d=+d,m=m|0;var B=0,k=0,Q=0,O=0,M=0;B=C,C=C+32|0,M=B+8|0,O=B+20|0,Q=B,k=B+16|0,E[M>>3]=c,n[O>>2]=f,E[Q>>3]=d,n[k>>2]=m,cve(s,n[l+4>>2]|0,M,O,Q,k),C=B}function cve(s,l,c,f,d,m){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0,m=m|0;var B=0,k=0;B=C,C=C+16|0,k=B,za(k),l=ya(l)|0,uve(s,l,+E[c>>3],n[f>>2]|0,+E[d>>3],n[m>>2]|0),Ja(k),C=B}function ya(s){return s=s|0,n[s>>2]|0}function uve(s,l,c,f,d,m){s=s|0,l=l|0,c=+c,f=f|0,d=+d,m=m|0;var B=0;B=Pl(Ave()|0)|0,c=+VA(c),f=hF(f)|0,d=+VA(d),fve(s,hi(0,B|0,l|0,+c,f|0,+d,hF(m)|0)|0)}function Ave(){var s=0;return o[7608]|0||(dve(9120),s=7608,n[s>>2]=1,n[s+4>>2]=0),9120}function Pl(s){return s=s|0,n[s+8>>2]|0}function VA(s){return s=+s,+ +gF(s)}function hF(s){return s=s|0,V5(s)|0}function fve(s,l){s=s|0,l=l|0;var c=0,f=0,d=0;d=C,C=C+32|0,c=d,f=l,f&1?(pve(c,0),ii(f|0,c|0)|0,hve(s,c),gve(c)):(n[s>>2]=n[l>>2],n[s+4>>2]=n[l+4>>2],n[s+8>>2]=n[l+8>>2],n[s+12>>2]=n[l+12>>2]),C=d}function pve(s,l){s=s|0,l=l|0,K5(s,l),n[s+8>>2]=0,o[s+24>>0]=0}function hve(s,l){s=s|0,l=l|0,l=l+8|0,n[s>>2]=n[l>>2],n[s+4>>2]=n[l+4>>2],n[s+8>>2]=n[l+8>>2],n[s+12>>2]=n[l+12>>2]}function gve(s){s=s|0,o[s+24>>0]=0}function K5(s,l){s=s|0,l=l|0,n[s>>2]=l}function V5(s){return s=s|0,s|0}function gF(s){return s=+s,+s}function dve(s){s=s|0,bl(s,mve()|0,4)}function mve(){return 1064}function bl(s,l,c){s=s|0,l=l|0,c=c|0,n[s>>2]=l,n[s+4>>2]=c,n[s+8>>2]=ap(l|0,c+1|0)|0}function yve(s,l){s=s|0,l=l|0,l=n[l>>2]|0,n[s>>2]=l,yl(l|0)}function Eve(s){s=s|0;var l=0,c=0;c=s+4|0,l=n[c>>2]|0,n[c>>2]=0,l|0&&(qA(l),gt(l)),Bt(n[s>>2]|0,0)}function Cve(s){s=s|0,Nt(n[s>>2]|0)}function wve(s){return s=s|0,rr(n[s>>2]|0)|0}function Ive(s,l,c,f){s=s|0,l=+l,c=+c,f=f|0,Dc(n[s>>2]|0,y(l),y(c),f)}function Bve(s){return s=s|0,+ +y(Il(n[s>>2]|0))}function vve(s){return s=s|0,+ +y(f0(n[s>>2]|0))}function Dve(s){return s=s|0,+ +y(vu(n[s>>2]|0))}function Pve(s){return s=s|0,+ +y(TA(n[s>>2]|0))}function bve(s){return s=s|0,+ +y(fp(n[s>>2]|0))}function Sve(s){return s=s|0,+ +y(Ga(n[s>>2]|0))}function xve(s,l){s=s|0,l=l|0,E[s>>3]=+y(Il(n[l>>2]|0)),E[s+8>>3]=+y(f0(n[l>>2]|0)),E[s+16>>3]=+y(vu(n[l>>2]|0)),E[s+24>>3]=+y(TA(n[l>>2]|0)),E[s+32>>3]=+y(fp(n[l>>2]|0)),E[s+40>>3]=+y(Ga(n[l>>2]|0))}function kve(s,l){return s=s|0,l=l|0,+ +y(p0(n[s>>2]|0,l))}function Qve(s,l){return s=s|0,l=l|0,+ +y(pp(n[s>>2]|0,l))}function Fve(s,l){return s=s|0,l=l|0,+ +y(jo(n[s>>2]|0,l))}function Rve(){return Pn()|0}function Tve(){Nve(),Lve(),Mve(),Ove(),Uve(),_ve()}function Nve(){UNe(11713,4938,1)}function Lve(){iNe(10448)}function Mve(){UTe(10408)}function Ove(){lTe(10324)}function Uve(){dFe(10096)}function _ve(){Hve(9132)}function Hve(s){s=s|0;var l=0,c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0,se=0,je=0,Oe=0,Qe=0,$e=0,Je=0,lt=0,_e=0,qe=0,Lt=0,Or=0,cr=0,Xt=0,Pr=0,Tr=0,ar=0,xn=0,go=0,mo=0,yo=0,Ca=0,xp=0,kp=0,Sl=0,Qp=0,Tu=0,Nu=0,Fp=0,Rp=0,Tp=0,Xr=0,xl=0,Np=0,kc=0,Lp=0,Mp=0,Lu=0,Mu=0,Qc=0,Ys=0,Za=0,Wo=0,kl=0,rf=0,nf=0,Ou=0,sf=0,of=0,Ws=0,Ps=0,Ql=0,Rn=0,af=0,Eo=0,Fc=0,Co=0,Rc=0,lf=0,cf=0,Tc=0,Ks=0,Fl=0,uf=0,Af=0,ff=0,xr=0,zn=0,bs=0,wo=0,Vs=0,Fr=0,ur=0,Rl=0;l=C,C=C+672|0,c=l+656|0,Rl=l+648|0,ur=l+640|0,Fr=l+632|0,Vs=l+624|0,wo=l+616|0,bs=l+608|0,zn=l+600|0,xr=l+592|0,ff=l+584|0,Af=l+576|0,uf=l+568|0,Fl=l+560|0,Ks=l+552|0,Tc=l+544|0,cf=l+536|0,lf=l+528|0,Rc=l+520|0,Co=l+512|0,Fc=l+504|0,Eo=l+496|0,af=l+488|0,Rn=l+480|0,Ql=l+472|0,Ps=l+464|0,Ws=l+456|0,of=l+448|0,sf=l+440|0,Ou=l+432|0,nf=l+424|0,rf=l+416|0,kl=l+408|0,Wo=l+400|0,Za=l+392|0,Ys=l+384|0,Qc=l+376|0,Mu=l+368|0,Lu=l+360|0,Mp=l+352|0,Lp=l+344|0,kc=l+336|0,Np=l+328|0,xl=l+320|0,Xr=l+312|0,Tp=l+304|0,Rp=l+296|0,Fp=l+288|0,Nu=l+280|0,Tu=l+272|0,Qp=l+264|0,Sl=l+256|0,kp=l+248|0,xp=l+240|0,Ca=l+232|0,yo=l+224|0,mo=l+216|0,go=l+208|0,xn=l+200|0,ar=l+192|0,Tr=l+184|0,Pr=l+176|0,Xt=l+168|0,cr=l+160|0,Or=l+152|0,Lt=l+144|0,qe=l+136|0,_e=l+128|0,lt=l+120|0,Je=l+112|0,$e=l+104|0,Qe=l+96|0,Oe=l+88|0,je=l+80|0,se=l+72|0,j=l+64|0,M=l+56|0,O=l+48|0,Q=l+40|0,k=l+32|0,B=l+24|0,m=l+16|0,d=l+8|0,f=l,qve(s,3646),jve(s,3651,2)|0,Gve(s,3665,2)|0,Yve(s,3682,18)|0,n[Rl>>2]=19,n[Rl+4>>2]=0,n[c>>2]=n[Rl>>2],n[c+4>>2]=n[Rl+4>>2],mw(s,3690,c)|0,n[ur>>2]=1,n[ur+4>>2]=0,n[c>>2]=n[ur>>2],n[c+4>>2]=n[ur+4>>2],Wve(s,3696,c)|0,n[Fr>>2]=2,n[Fr+4>>2]=0,n[c>>2]=n[Fr>>2],n[c+4>>2]=n[Fr+4>>2],Qu(s,3706,c)|0,n[Vs>>2]=1,n[Vs+4>>2]=0,n[c>>2]=n[Vs>>2],n[c+4>>2]=n[Vs+4>>2],I0(s,3722,c)|0,n[wo>>2]=2,n[wo+4>>2]=0,n[c>>2]=n[wo>>2],n[c+4>>2]=n[wo+4>>2],I0(s,3734,c)|0,n[bs>>2]=3,n[bs+4>>2]=0,n[c>>2]=n[bs>>2],n[c+4>>2]=n[bs+4>>2],Qu(s,3753,c)|0,n[zn>>2]=4,n[zn+4>>2]=0,n[c>>2]=n[zn>>2],n[c+4>>2]=n[zn+4>>2],Qu(s,3769,c)|0,n[xr>>2]=5,n[xr+4>>2]=0,n[c>>2]=n[xr>>2],n[c+4>>2]=n[xr+4>>2],Qu(s,3783,c)|0,n[ff>>2]=6,n[ff+4>>2]=0,n[c>>2]=n[ff>>2],n[c+4>>2]=n[ff+4>>2],Qu(s,3796,c)|0,n[Af>>2]=7,n[Af+4>>2]=0,n[c>>2]=n[Af>>2],n[c+4>>2]=n[Af+4>>2],Qu(s,3813,c)|0,n[uf>>2]=8,n[uf+4>>2]=0,n[c>>2]=n[uf>>2],n[c+4>>2]=n[uf+4>>2],Qu(s,3825,c)|0,n[Fl>>2]=3,n[Fl+4>>2]=0,n[c>>2]=n[Fl>>2],n[c+4>>2]=n[Fl+4>>2],I0(s,3843,c)|0,n[Ks>>2]=4,n[Ks+4>>2]=0,n[c>>2]=n[Ks>>2],n[c+4>>2]=n[Ks+4>>2],I0(s,3853,c)|0,n[Tc>>2]=9,n[Tc+4>>2]=0,n[c>>2]=n[Tc>>2],n[c+4>>2]=n[Tc+4>>2],Qu(s,3870,c)|0,n[cf>>2]=10,n[cf+4>>2]=0,n[c>>2]=n[cf>>2],n[c+4>>2]=n[cf+4>>2],Qu(s,3884,c)|0,n[lf>>2]=11,n[lf+4>>2]=0,n[c>>2]=n[lf>>2],n[c+4>>2]=n[lf+4>>2],Qu(s,3896,c)|0,n[Rc>>2]=1,n[Rc+4>>2]=0,n[c>>2]=n[Rc>>2],n[c+4>>2]=n[Rc+4>>2],vs(s,3907,c)|0,n[Co>>2]=2,n[Co+4>>2]=0,n[c>>2]=n[Co>>2],n[c+4>>2]=n[Co+4>>2],vs(s,3915,c)|0,n[Fc>>2]=3,n[Fc+4>>2]=0,n[c>>2]=n[Fc>>2],n[c+4>>2]=n[Fc+4>>2],vs(s,3928,c)|0,n[Eo>>2]=4,n[Eo+4>>2]=0,n[c>>2]=n[Eo>>2],n[c+4>>2]=n[Eo+4>>2],vs(s,3948,c)|0,n[af>>2]=5,n[af+4>>2]=0,n[c>>2]=n[af>>2],n[c+4>>2]=n[af+4>>2],vs(s,3960,c)|0,n[Rn>>2]=6,n[Rn+4>>2]=0,n[c>>2]=n[Rn>>2],n[c+4>>2]=n[Rn+4>>2],vs(s,3974,c)|0,n[Ql>>2]=7,n[Ql+4>>2]=0,n[c>>2]=n[Ql>>2],n[c+4>>2]=n[Ql+4>>2],vs(s,3983,c)|0,n[Ps>>2]=20,n[Ps+4>>2]=0,n[c>>2]=n[Ps>>2],n[c+4>>2]=n[Ps+4>>2],mw(s,3999,c)|0,n[Ws>>2]=8,n[Ws+4>>2]=0,n[c>>2]=n[Ws>>2],n[c+4>>2]=n[Ws+4>>2],vs(s,4012,c)|0,n[of>>2]=9,n[of+4>>2]=0,n[c>>2]=n[of>>2],n[c+4>>2]=n[of+4>>2],vs(s,4022,c)|0,n[sf>>2]=21,n[sf+4>>2]=0,n[c>>2]=n[sf>>2],n[c+4>>2]=n[sf+4>>2],mw(s,4039,c)|0,n[Ou>>2]=10,n[Ou+4>>2]=0,n[c>>2]=n[Ou>>2],n[c+4>>2]=n[Ou+4>>2],vs(s,4053,c)|0,n[nf>>2]=11,n[nf+4>>2]=0,n[c>>2]=n[nf>>2],n[c+4>>2]=n[nf+4>>2],vs(s,4065,c)|0,n[rf>>2]=12,n[rf+4>>2]=0,n[c>>2]=n[rf>>2],n[c+4>>2]=n[rf+4>>2],vs(s,4084,c)|0,n[kl>>2]=13,n[kl+4>>2]=0,n[c>>2]=n[kl>>2],n[c+4>>2]=n[kl+4>>2],vs(s,4097,c)|0,n[Wo>>2]=14,n[Wo+4>>2]=0,n[c>>2]=n[Wo>>2],n[c+4>>2]=n[Wo+4>>2],vs(s,4117,c)|0,n[Za>>2]=15,n[Za+4>>2]=0,n[c>>2]=n[Za>>2],n[c+4>>2]=n[Za+4>>2],vs(s,4129,c)|0,n[Ys>>2]=16,n[Ys+4>>2]=0,n[c>>2]=n[Ys>>2],n[c+4>>2]=n[Ys+4>>2],vs(s,4148,c)|0,n[Qc>>2]=17,n[Qc+4>>2]=0,n[c>>2]=n[Qc>>2],n[c+4>>2]=n[Qc+4>>2],vs(s,4161,c)|0,n[Mu>>2]=18,n[Mu+4>>2]=0,n[c>>2]=n[Mu>>2],n[c+4>>2]=n[Mu+4>>2],vs(s,4181,c)|0,n[Lu>>2]=5,n[Lu+4>>2]=0,n[c>>2]=n[Lu>>2],n[c+4>>2]=n[Lu+4>>2],I0(s,4196,c)|0,n[Mp>>2]=6,n[Mp+4>>2]=0,n[c>>2]=n[Mp>>2],n[c+4>>2]=n[Mp+4>>2],I0(s,4206,c)|0,n[Lp>>2]=7,n[Lp+4>>2]=0,n[c>>2]=n[Lp>>2],n[c+4>>2]=n[Lp+4>>2],I0(s,4217,c)|0,n[kc>>2]=3,n[kc+4>>2]=0,n[c>>2]=n[kc>>2],n[c+4>>2]=n[kc+4>>2],zA(s,4235,c)|0,n[Np>>2]=1,n[Np+4>>2]=0,n[c>>2]=n[Np>>2],n[c+4>>2]=n[Np+4>>2],dF(s,4251,c)|0,n[xl>>2]=4,n[xl+4>>2]=0,n[c>>2]=n[xl>>2],n[c+4>>2]=n[xl+4>>2],zA(s,4263,c)|0,n[Xr>>2]=5,n[Xr+4>>2]=0,n[c>>2]=n[Xr>>2],n[c+4>>2]=n[Xr+4>>2],zA(s,4279,c)|0,n[Tp>>2]=6,n[Tp+4>>2]=0,n[c>>2]=n[Tp>>2],n[c+4>>2]=n[Tp+4>>2],zA(s,4293,c)|0,n[Rp>>2]=7,n[Rp+4>>2]=0,n[c>>2]=n[Rp>>2],n[c+4>>2]=n[Rp+4>>2],zA(s,4306,c)|0,n[Fp>>2]=8,n[Fp+4>>2]=0,n[c>>2]=n[Fp>>2],n[c+4>>2]=n[Fp+4>>2],zA(s,4323,c)|0,n[Nu>>2]=9,n[Nu+4>>2]=0,n[c>>2]=n[Nu>>2],n[c+4>>2]=n[Nu+4>>2],zA(s,4335,c)|0,n[Tu>>2]=2,n[Tu+4>>2]=0,n[c>>2]=n[Tu>>2],n[c+4>>2]=n[Tu+4>>2],dF(s,4353,c)|0,n[Qp>>2]=12,n[Qp+4>>2]=0,n[c>>2]=n[Qp>>2],n[c+4>>2]=n[Qp+4>>2],B0(s,4363,c)|0,n[Sl>>2]=1,n[Sl+4>>2]=0,n[c>>2]=n[Sl>>2],n[c+4>>2]=n[Sl+4>>2],JA(s,4376,c)|0,n[kp>>2]=2,n[kp+4>>2]=0,n[c>>2]=n[kp>>2],n[c+4>>2]=n[kp+4>>2],JA(s,4388,c)|0,n[xp>>2]=13,n[xp+4>>2]=0,n[c>>2]=n[xp>>2],n[c+4>>2]=n[xp+4>>2],B0(s,4402,c)|0,n[Ca>>2]=14,n[Ca+4>>2]=0,n[c>>2]=n[Ca>>2],n[c+4>>2]=n[Ca+4>>2],B0(s,4411,c)|0,n[yo>>2]=15,n[yo+4>>2]=0,n[c>>2]=n[yo>>2],n[c+4>>2]=n[yo+4>>2],B0(s,4421,c)|0,n[mo>>2]=16,n[mo+4>>2]=0,n[c>>2]=n[mo>>2],n[c+4>>2]=n[mo+4>>2],B0(s,4433,c)|0,n[go>>2]=17,n[go+4>>2]=0,n[c>>2]=n[go>>2],n[c+4>>2]=n[go+4>>2],B0(s,4446,c)|0,n[xn>>2]=18,n[xn+4>>2]=0,n[c>>2]=n[xn>>2],n[c+4>>2]=n[xn+4>>2],B0(s,4458,c)|0,n[ar>>2]=3,n[ar+4>>2]=0,n[c>>2]=n[ar>>2],n[c+4>>2]=n[ar+4>>2],JA(s,4471,c)|0,n[Tr>>2]=1,n[Tr+4>>2]=0,n[c>>2]=n[Tr>>2],n[c+4>>2]=n[Tr+4>>2],Hv(s,4486,c)|0,n[Pr>>2]=10,n[Pr+4>>2]=0,n[c>>2]=n[Pr>>2],n[c+4>>2]=n[Pr+4>>2],zA(s,4496,c)|0,n[Xt>>2]=11,n[Xt+4>>2]=0,n[c>>2]=n[Xt>>2],n[c+4>>2]=n[Xt+4>>2],zA(s,4508,c)|0,n[cr>>2]=3,n[cr+4>>2]=0,n[c>>2]=n[cr>>2],n[c+4>>2]=n[cr+4>>2],dF(s,4519,c)|0,n[Or>>2]=4,n[Or+4>>2]=0,n[c>>2]=n[Or>>2],n[c+4>>2]=n[Or+4>>2],Kve(s,4530,c)|0,n[Lt>>2]=19,n[Lt+4>>2]=0,n[c>>2]=n[Lt>>2],n[c+4>>2]=n[Lt+4>>2],Vve(s,4542,c)|0,n[qe>>2]=12,n[qe+4>>2]=0,n[c>>2]=n[qe>>2],n[c+4>>2]=n[qe+4>>2],zve(s,4554,c)|0,n[_e>>2]=13,n[_e+4>>2]=0,n[c>>2]=n[_e>>2],n[c+4>>2]=n[_e+4>>2],Jve(s,4568,c)|0,n[lt>>2]=2,n[lt+4>>2]=0,n[c>>2]=n[lt>>2],n[c+4>>2]=n[lt+4>>2],Xve(s,4578,c)|0,n[Je>>2]=20,n[Je+4>>2]=0,n[c>>2]=n[Je>>2],n[c+4>>2]=n[Je+4>>2],Zve(s,4587,c)|0,n[$e>>2]=22,n[$e+4>>2]=0,n[c>>2]=n[$e>>2],n[c+4>>2]=n[$e+4>>2],mw(s,4602,c)|0,n[Qe>>2]=23,n[Qe+4>>2]=0,n[c>>2]=n[Qe>>2],n[c+4>>2]=n[Qe+4>>2],mw(s,4619,c)|0,n[Oe>>2]=14,n[Oe+4>>2]=0,n[c>>2]=n[Oe>>2],n[c+4>>2]=n[Oe+4>>2],$ve(s,4629,c)|0,n[je>>2]=1,n[je+4>>2]=0,n[c>>2]=n[je>>2],n[c+4>>2]=n[je+4>>2],eDe(s,4637,c)|0,n[se>>2]=4,n[se+4>>2]=0,n[c>>2]=n[se>>2],n[c+4>>2]=n[se+4>>2],JA(s,4653,c)|0,n[j>>2]=5,n[j+4>>2]=0,n[c>>2]=n[j>>2],n[c+4>>2]=n[j+4>>2],JA(s,4669,c)|0,n[M>>2]=6,n[M+4>>2]=0,n[c>>2]=n[M>>2],n[c+4>>2]=n[M+4>>2],JA(s,4686,c)|0,n[O>>2]=7,n[O+4>>2]=0,n[c>>2]=n[O>>2],n[c+4>>2]=n[O+4>>2],JA(s,4701,c)|0,n[Q>>2]=8,n[Q+4>>2]=0,n[c>>2]=n[Q>>2],n[c+4>>2]=n[Q+4>>2],JA(s,4719,c)|0,n[k>>2]=9,n[k+4>>2]=0,n[c>>2]=n[k>>2],n[c+4>>2]=n[k+4>>2],JA(s,4736,c)|0,n[B>>2]=21,n[B+4>>2]=0,n[c>>2]=n[B>>2],n[c+4>>2]=n[B+4>>2],tDe(s,4754,c)|0,n[m>>2]=2,n[m+4>>2]=0,n[c>>2]=n[m>>2],n[c+4>>2]=n[m+4>>2],Hv(s,4772,c)|0,n[d>>2]=3,n[d+4>>2]=0,n[c>>2]=n[d>>2],n[c+4>>2]=n[d+4>>2],Hv(s,4790,c)|0,n[f>>2]=4,n[f+4>>2]=0,n[c>>2]=n[f>>2],n[c+4>>2]=n[f+4>>2],Hv(s,4808,c)|0,C=l}function qve(s,l){s=s|0,l=l|0;var c=0;c=aFe()|0,n[s>>2]=c,lFe(c,l),Pp(n[s>>2]|0)}function jve(s,l,c){return s=s|0,l=l|0,c=c|0,KQe(s,pn(l)|0,c,0),s|0}function Gve(s,l,c){return s=s|0,l=l|0,c=c|0,QQe(s,pn(l)|0,c,0),s|0}function Yve(s,l,c){return s=s|0,l=l|0,c=c|0,mQe(s,pn(l)|0,c,0),s|0}function mw(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=n[c+4>>2]|0,n[m>>2]=n[c>>2],n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],tQe(s,l,d),C=f,s|0}function Wve(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=n[c+4>>2]|0,n[m>>2]=n[c>>2],n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],Lke(s,l,d),C=f,s|0}function Qu(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=n[c+4>>2]|0,n[m>>2]=n[c>>2],n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],Cke(s,l,d),C=f,s|0}function I0(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=n[c+4>>2]|0,n[m>>2]=n[c>>2],n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],ike(s,l,d),C=f,s|0}function vs(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=n[c+4>>2]|0,n[m>>2]=n[c>>2],n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],qxe(s,l,d),C=f,s|0}function zA(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=n[c+4>>2]|0,n[m>>2]=n[c>>2],n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],Pxe(s,l,d),C=f,s|0}function dF(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=n[c+4>>2]|0,n[m>>2]=n[c>>2],n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],uxe(s,l,d),C=f,s|0}function B0(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=n[c+4>>2]|0,n[m>>2]=n[c>>2],n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],LSe(s,l,d),C=f,s|0}function JA(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=n[c+4>>2]|0,n[m>>2]=n[c>>2],n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],CSe(s,l,d),C=f,s|0}function Hv(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=n[c+4>>2]|0,n[m>>2]=n[c>>2],n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],iSe(s,l,d),C=f,s|0}function Kve(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=n[c+4>>2]|0,n[m>>2]=n[c>>2],n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],qbe(s,l,d),C=f,s|0}function Vve(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=n[c+4>>2]|0,n[m>>2]=n[c>>2],n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],Pbe(s,l,d),C=f,s|0}function zve(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=n[c+4>>2]|0,n[m>>2]=n[c>>2],n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],Abe(s,l,d),C=f,s|0}function Jve(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=n[c+4>>2]|0,n[m>>2]=n[c>>2],n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],JPe(s,l,d),C=f,s|0}function Xve(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=n[c+4>>2]|0,n[m>>2]=n[c>>2],n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],RPe(s,l,d),C=f,s|0}function Zve(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=n[c+4>>2]|0,n[m>>2]=n[c>>2],n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],dPe(s,l,d),C=f,s|0}function $ve(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=n[c+4>>2]|0,n[m>>2]=n[c>>2],n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],ePe(s,l,d),C=f,s|0}function eDe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=n[c+4>>2]|0,n[m>>2]=n[c>>2],n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],LDe(s,l,d),C=f,s|0}function tDe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=n[c+4>>2]|0,n[m>>2]=n[c>>2],n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],rDe(s,l,d),C=f,s|0}function rDe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+16|0,d=f+8|0,m=f,k=n[c>>2]|0,B=n[c+4>>2]|0,c=pn(l)|0,n[m>>2]=k,n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],nDe(s,c,d,1),C=f}function pn(s){return s=s|0,s|0}function nDe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0,Q=0,O=0,M=0;d=C,C=C+32|0,m=d+16|0,M=d+8|0,k=d,O=n[c>>2]|0,Q=n[c+4>>2]|0,B=n[s>>2]|0,s=mF()|0,n[M>>2]=O,n[M+4>>2]=Q,n[m>>2]=n[M>>2],n[m+4>>2]=n[M+4>>2],c=iDe(m)|0,n[k>>2]=O,n[k+4>>2]=Q,n[m>>2]=n[k>>2],n[m+4>>2]=n[k+4>>2],hn(B,l,s,c,sDe(m,f)|0,f),C=d}function mF(){var s=0,l=0;if(o[7616]|0||(X5(9136),ir(24,9136,U|0)|0,l=7616,n[l>>2]=1,n[l+4>>2]=0),!(Rr(9136)|0)){s=9136,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));X5(9136)}return 9136}function iDe(s){return s=s|0,0}function sDe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0;return M=C,C=C+32|0,d=M+24|0,B=M+16|0,k=M,Q=M+8|0,m=n[s>>2]|0,f=n[s+4>>2]|0,n[k>>2]=m,n[k+4>>2]=f,j=mF()|0,O=j+24|0,s=gr(l,4)|0,n[Q>>2]=s,l=j+28|0,c=n[l>>2]|0,c>>>0<(n[j+32>>2]|0)>>>0?(n[B>>2]=m,n[B+4>>2]=f,n[d>>2]=n[B>>2],n[d+4>>2]=n[B+4>>2],J5(c,d,s),s=(n[l>>2]|0)+12|0,n[l>>2]=s):(lDe(O,k,Q),s=n[l>>2]|0),C=M,((s-(n[O>>2]|0)|0)/12|0)+-1|0}function hn(s,l,c,f,d,m){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0,m=m|0;var B=0,k=0,Q=0,O=0,M=0,j=0,se=0,je=0;B=C,C=C+32|0,se=B+24|0,j=B+20|0,Q=B+16|0,M=B+12|0,O=B+8|0,k=B+4|0,je=B,n[j>>2]=l,n[Q>>2]=c,n[M>>2]=f,n[O>>2]=d,n[k>>2]=m,m=s+28|0,n[je>>2]=n[m>>2],n[se>>2]=n[je>>2],oDe(s+24|0,se,j,M,O,Q,k)|0,n[m>>2]=n[n[m>>2]>>2],C=B}function oDe(s,l,c,f,d,m,B){return s=s|0,l=l|0,c=c|0,f=f|0,d=d|0,m=m|0,B=B|0,s=aDe(l)|0,l=Kt(24)|0,z5(l+4|0,n[c>>2]|0,n[f>>2]|0,n[d>>2]|0,n[m>>2]|0,n[B>>2]|0),n[l>>2]=n[s>>2],n[s>>2]=l,l|0}function aDe(s){return s=s|0,n[s>>2]|0}function z5(s,l,c,f,d,m){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0,m=m|0,n[s>>2]=l,n[s+4>>2]=c,n[s+8>>2]=f,n[s+12>>2]=d,n[s+16>>2]=m}function gr(s,l){return s=s|0,l=l|0,l|s|0}function J5(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=n[l+4>>2]|0,n[s>>2]=n[l>>2],n[s+4>>2]=f,n[s+8>>2]=c}function lDe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0,se=0;if(O=C,C=C+48|0,f=O+32|0,B=O+24|0,k=O,Q=s+4|0,d=(((n[Q>>2]|0)-(n[s>>2]|0)|0)/12|0)+1|0,m=cDe(s)|0,m>>>0>>0)Jr(s);else{M=n[s>>2]|0,se=((n[s+8>>2]|0)-M|0)/12|0,j=se<<1,uDe(k,se>>>0>>1>>>0?j>>>0>>0?d:j:m,((n[Q>>2]|0)-M|0)/12|0,s+8|0),Q=k+8|0,m=n[Q>>2]|0,d=n[l+4>>2]|0,c=n[c>>2]|0,n[B>>2]=n[l>>2],n[B+4>>2]=d,n[f>>2]=n[B>>2],n[f+4>>2]=n[B+4>>2],J5(m,f,c),n[Q>>2]=(n[Q>>2]|0)+12,ADe(s,k),fDe(k),C=O;return}}function cDe(s){return s=s|0,357913941}function uDe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>357913941)Tt();else{d=Kt(l*12|0)|0;break}else d=0;while(!1);n[s>>2]=d,f=d+(c*12|0)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l*12|0)}function ADe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(((d|0)/-12|0)*12|0)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function fDe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~(((f+-12-l|0)>>>0)/12|0)*12|0)),s=n[s>>2]|0,s|0&>(s)}function X5(s){s=s|0,gDe(s)}function pDe(s){s=s|0,hDe(s+24|0)}function Rr(s){return s=s|0,n[s>>2]|0}function hDe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~(((l+-12-f|0)>>>0)/12|0)*12|0)),gt(c))}function gDe(s){s=s|0;var l=0;l=Vr()|0,zr(s,2,3,l,dDe()|0,0),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function Vr(){return 9228}function dDe(){return 1140}function mDe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0;return c=C,C=C+16|0,f=c+8|0,d=c,m=yDe(s)|0,s=n[m+4>>2]|0,n[d>>2]=n[m>>2],n[d+4>>2]=s,n[f>>2]=n[d>>2],n[f+4>>2]=n[d+4>>2],l=EDe(l,f)|0,C=c,l|0}function zr(s,l,c,f,d,m){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0,m=m|0,n[s>>2]=l,n[s+4>>2]=c,n[s+8>>2]=f,n[s+12>>2]=d,n[s+16>>2]=m}function yDe(s){return s=s|0,(n[(mF()|0)+24>>2]|0)+(s*12|0)|0}function EDe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0;return d=C,C=C+48|0,f=d,c=n[l>>2]|0,l=n[l+4>>2]|0,s=s+(l>>1)|0,l&1&&(c=n[(n[s>>2]|0)+c>>2]|0),tf[c&31](f,s),f=CDe(f)|0,C=d,f|0}function CDe(s){s=s|0;var l=0,c=0,f=0,d=0;return d=C,C=C+32|0,l=d+12|0,c=d,f=yF(Z5()|0)|0,f?(EF(l,f),CF(c,l),wDe(s,c),s=wF(l)|0):s=IDe(s)|0,C=d,s|0}function Z5(){var s=0;return o[7632]|0||(FDe(9184),ir(25,9184,U|0)|0,s=7632,n[s>>2]=1,n[s+4>>2]=0),9184}function yF(s){return s=s|0,n[s+36>>2]|0}function EF(s,l){s=s|0,l=l|0,n[s>>2]=l,n[s+4>>2]=s,n[s+8>>2]=0}function CF(s,l){s=s|0,l=l|0,n[s>>2]=n[l>>2],n[s+4>>2]=n[l+4>>2],n[s+8>>2]=0}function wDe(s,l){s=s|0,l=l|0,PDe(l,s,s+8|0,s+16|0,s+24|0,s+32|0,s+40|0)|0}function wF(s){return s=s|0,n[(n[s+4>>2]|0)+8>>2]|0}function IDe(s){s=s|0;var l=0,c=0,f=0,d=0,m=0,B=0,k=0,Q=0;Q=C,C=C+16|0,c=Q+4|0,f=Q,d=Va(8)|0,m=d,B=Kt(48)|0,k=B,l=k+48|0;do n[k>>2]=n[s>>2],k=k+4|0,s=s+4|0;while((k|0)<(l|0));return l=m+4|0,n[l>>2]=B,k=Kt(8)|0,B=n[l>>2]|0,n[f>>2]=0,n[c>>2]=n[f>>2],$5(k,B,c),n[d>>2]=k,C=Q,m|0}function $5(s,l,c){s=s|0,l=l|0,c=c|0,n[s>>2]=l,c=Kt(16)|0,n[c+4>>2]=0,n[c+8>>2]=0,n[c>>2]=1092,n[c+12>>2]=l,n[s+4>>2]=c}function BDe(s){s=s|0,Md(s),gt(s)}function vDe(s){s=s|0,s=n[s+12>>2]|0,s|0&>(s)}function DDe(s){s=s|0,gt(s)}function PDe(s,l,c,f,d,m,B){return s=s|0,l=l|0,c=c|0,f=f|0,d=d|0,m=m|0,B=B|0,m=bDe(n[s>>2]|0,l,c,f,d,m,B)|0,B=s+4|0,n[(n[B>>2]|0)+8>>2]=m,n[(n[B>>2]|0)+8>>2]|0}function bDe(s,l,c,f,d,m,B){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0,m=m|0,B=B|0;var k=0,Q=0;return k=C,C=C+16|0,Q=k,za(Q),s=ya(s)|0,B=SDe(s,+E[l>>3],+E[c>>3],+E[f>>3],+E[d>>3],+E[m>>3],+E[B>>3])|0,Ja(Q),C=k,B|0}function SDe(s,l,c,f,d,m,B){s=s|0,l=+l,c=+c,f=+f,d=+d,m=+m,B=+B;var k=0;return k=Pl(xDe()|0)|0,l=+VA(l),c=+VA(c),f=+VA(f),d=+VA(d),m=+VA(m),_s(0,k|0,s|0,+l,+c,+f,+d,+m,+ +VA(B))|0}function xDe(){var s=0;return o[7624]|0||(kDe(9172),s=7624,n[s>>2]=1,n[s+4>>2]=0),9172}function kDe(s){s=s|0,bl(s,QDe()|0,6)}function QDe(){return 1112}function FDe(s){s=s|0,wp(s)}function RDe(s){s=s|0,eG(s+24|0),tG(s+16|0)}function eG(s){s=s|0,NDe(s)}function tG(s){s=s|0,TDe(s)}function TDe(s){s=s|0;var l=0,c=0;if(l=n[s>>2]|0,l|0)do c=l,l=n[l>>2]|0,gt(c);while(l|0);n[s>>2]=0}function NDe(s){s=s|0;var l=0,c=0;if(l=n[s>>2]|0,l|0)do c=l,l=n[l>>2]|0,gt(c);while(l|0);n[s>>2]=0}function wp(s){s=s|0;var l=0;n[s+16>>2]=0,n[s+20>>2]=0,l=s+24|0,n[l>>2]=0,n[s+28>>2]=l,n[s+36>>2]=0,o[s+40>>0]=0,o[s+41>>0]=0}function LDe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+16|0,d=f+8|0,m=f,k=n[c>>2]|0,B=n[c+4>>2]|0,c=pn(l)|0,n[m>>2]=k,n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],MDe(s,c,d,0),C=f}function MDe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0,Q=0,O=0,M=0;d=C,C=C+32|0,m=d+16|0,M=d+8|0,k=d,O=n[c>>2]|0,Q=n[c+4>>2]|0,B=n[s>>2]|0,s=IF()|0,n[M>>2]=O,n[M+4>>2]=Q,n[m>>2]=n[M>>2],n[m+4>>2]=n[M+4>>2],c=ODe(m)|0,n[k>>2]=O,n[k+4>>2]=Q,n[m>>2]=n[k>>2],n[m+4>>2]=n[k+4>>2],hn(B,l,s,c,UDe(m,f)|0,f),C=d}function IF(){var s=0,l=0;if(o[7640]|0||(nG(9232),ir(26,9232,U|0)|0,l=7640,n[l>>2]=1,n[l+4>>2]=0),!(Rr(9232)|0)){s=9232,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));nG(9232)}return 9232}function ODe(s){return s=s|0,0}function UDe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0;return M=C,C=C+32|0,d=M+24|0,B=M+16|0,k=M,Q=M+8|0,m=n[s>>2]|0,f=n[s+4>>2]|0,n[k>>2]=m,n[k+4>>2]=f,j=IF()|0,O=j+24|0,s=gr(l,4)|0,n[Q>>2]=s,l=j+28|0,c=n[l>>2]|0,c>>>0<(n[j+32>>2]|0)>>>0?(n[B>>2]=m,n[B+4>>2]=f,n[d>>2]=n[B>>2],n[d+4>>2]=n[B+4>>2],rG(c,d,s),s=(n[l>>2]|0)+12|0,n[l>>2]=s):(_De(O,k,Q),s=n[l>>2]|0),C=M,((s-(n[O>>2]|0)|0)/12|0)+-1|0}function rG(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=n[l+4>>2]|0,n[s>>2]=n[l>>2],n[s+4>>2]=f,n[s+8>>2]=c}function _De(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0,se=0;if(O=C,C=C+48|0,f=O+32|0,B=O+24|0,k=O,Q=s+4|0,d=(((n[Q>>2]|0)-(n[s>>2]|0)|0)/12|0)+1|0,m=HDe(s)|0,m>>>0>>0)Jr(s);else{M=n[s>>2]|0,se=((n[s+8>>2]|0)-M|0)/12|0,j=se<<1,qDe(k,se>>>0>>1>>>0?j>>>0>>0?d:j:m,((n[Q>>2]|0)-M|0)/12|0,s+8|0),Q=k+8|0,m=n[Q>>2]|0,d=n[l+4>>2]|0,c=n[c>>2]|0,n[B>>2]=n[l>>2],n[B+4>>2]=d,n[f>>2]=n[B>>2],n[f+4>>2]=n[B+4>>2],rG(m,f,c),n[Q>>2]=(n[Q>>2]|0)+12,jDe(s,k),GDe(k),C=O;return}}function HDe(s){return s=s|0,357913941}function qDe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>357913941)Tt();else{d=Kt(l*12|0)|0;break}else d=0;while(!1);n[s>>2]=d,f=d+(c*12|0)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l*12|0)}function jDe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(((d|0)/-12|0)*12|0)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function GDe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~(((f+-12-l|0)>>>0)/12|0)*12|0)),s=n[s>>2]|0,s|0&>(s)}function nG(s){s=s|0,KDe(s)}function YDe(s){s=s|0,WDe(s+24|0)}function WDe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~(((l+-12-f|0)>>>0)/12|0)*12|0)),gt(c))}function KDe(s){s=s|0;var l=0;l=Vr()|0,zr(s,2,1,l,VDe()|0,3),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function VDe(){return 1144}function zDe(s,l,c,f,d){s=s|0,l=l|0,c=+c,f=+f,d=d|0;var m=0,B=0,k=0,Q=0;m=C,C=C+16|0,B=m+8|0,k=m,Q=JDe(s)|0,s=n[Q+4>>2]|0,n[k>>2]=n[Q>>2],n[k+4>>2]=s,n[B>>2]=n[k>>2],n[B+4>>2]=n[k+4>>2],XDe(l,B,c,f,d),C=m}function JDe(s){return s=s|0,(n[(IF()|0)+24>>2]|0)+(s*12|0)|0}function XDe(s,l,c,f,d){s=s|0,l=l|0,c=+c,f=+f,d=d|0;var m=0,B=0,k=0,Q=0,O=0;O=C,C=C+16|0,B=O+2|0,k=O+1|0,Q=O,m=n[l>>2]|0,l=n[l+4>>2]|0,s=s+(l>>1)|0,l&1&&(m=n[(n[s>>2]|0)+m>>2]|0),Fu(B,c),c=+Ru(B,c),Fu(k,f),f=+Ru(k,f),XA(Q,d),Q=ZA(Q,d)|0,y7[m&1](s,c,f,Q),C=O}function Fu(s,l){s=s|0,l=+l}function Ru(s,l){return s=s|0,l=+l,+ +$De(l)}function XA(s,l){s=s|0,l=l|0}function ZA(s,l){return s=s|0,l=l|0,ZDe(l)|0}function ZDe(s){return s=s|0,s|0}function $De(s){return s=+s,+s}function ePe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+16|0,d=f+8|0,m=f,k=n[c>>2]|0,B=n[c+4>>2]|0,c=pn(l)|0,n[m>>2]=k,n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],tPe(s,c,d,1),C=f}function tPe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0,Q=0,O=0,M=0;d=C,C=C+32|0,m=d+16|0,M=d+8|0,k=d,O=n[c>>2]|0,Q=n[c+4>>2]|0,B=n[s>>2]|0,s=BF()|0,n[M>>2]=O,n[M+4>>2]=Q,n[m>>2]=n[M>>2],n[m+4>>2]=n[M+4>>2],c=rPe(m)|0,n[k>>2]=O,n[k+4>>2]=Q,n[m>>2]=n[k>>2],n[m+4>>2]=n[k+4>>2],hn(B,l,s,c,nPe(m,f)|0,f),C=d}function BF(){var s=0,l=0;if(o[7648]|0||(sG(9268),ir(27,9268,U|0)|0,l=7648,n[l>>2]=1,n[l+4>>2]=0),!(Rr(9268)|0)){s=9268,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));sG(9268)}return 9268}function rPe(s){return s=s|0,0}function nPe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0;return M=C,C=C+32|0,d=M+24|0,B=M+16|0,k=M,Q=M+8|0,m=n[s>>2]|0,f=n[s+4>>2]|0,n[k>>2]=m,n[k+4>>2]=f,j=BF()|0,O=j+24|0,s=gr(l,4)|0,n[Q>>2]=s,l=j+28|0,c=n[l>>2]|0,c>>>0<(n[j+32>>2]|0)>>>0?(n[B>>2]=m,n[B+4>>2]=f,n[d>>2]=n[B>>2],n[d+4>>2]=n[B+4>>2],iG(c,d,s),s=(n[l>>2]|0)+12|0,n[l>>2]=s):(iPe(O,k,Q),s=n[l>>2]|0),C=M,((s-(n[O>>2]|0)|0)/12|0)+-1|0}function iG(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=n[l+4>>2]|0,n[s>>2]=n[l>>2],n[s+4>>2]=f,n[s+8>>2]=c}function iPe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0,se=0;if(O=C,C=C+48|0,f=O+32|0,B=O+24|0,k=O,Q=s+4|0,d=(((n[Q>>2]|0)-(n[s>>2]|0)|0)/12|0)+1|0,m=sPe(s)|0,m>>>0>>0)Jr(s);else{M=n[s>>2]|0,se=((n[s+8>>2]|0)-M|0)/12|0,j=se<<1,oPe(k,se>>>0>>1>>>0?j>>>0>>0?d:j:m,((n[Q>>2]|0)-M|0)/12|0,s+8|0),Q=k+8|0,m=n[Q>>2]|0,d=n[l+4>>2]|0,c=n[c>>2]|0,n[B>>2]=n[l>>2],n[B+4>>2]=d,n[f>>2]=n[B>>2],n[f+4>>2]=n[B+4>>2],iG(m,f,c),n[Q>>2]=(n[Q>>2]|0)+12,aPe(s,k),lPe(k),C=O;return}}function sPe(s){return s=s|0,357913941}function oPe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>357913941)Tt();else{d=Kt(l*12|0)|0;break}else d=0;while(!1);n[s>>2]=d,f=d+(c*12|0)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l*12|0)}function aPe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(((d|0)/-12|0)*12|0)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function lPe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~(((f+-12-l|0)>>>0)/12|0)*12|0)),s=n[s>>2]|0,s|0&>(s)}function sG(s){s=s|0,APe(s)}function cPe(s){s=s|0,uPe(s+24|0)}function uPe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~(((l+-12-f|0)>>>0)/12|0)*12|0)),gt(c))}function APe(s){s=s|0;var l=0;l=Vr()|0,zr(s,2,4,l,fPe()|0,0),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function fPe(){return 1160}function pPe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0;return c=C,C=C+16|0,f=c+8|0,d=c,m=hPe(s)|0,s=n[m+4>>2]|0,n[d>>2]=n[m>>2],n[d+4>>2]=s,n[f>>2]=n[d>>2],n[f+4>>2]=n[d+4>>2],l=gPe(l,f)|0,C=c,l|0}function hPe(s){return s=s|0,(n[(BF()|0)+24>>2]|0)+(s*12|0)|0}function gPe(s,l){s=s|0,l=l|0;var c=0;return c=n[l>>2]|0,l=n[l+4>>2]|0,s=s+(l>>1)|0,l&1&&(c=n[(n[s>>2]|0)+c>>2]|0),oG(F0[c&31](s)|0)|0}function oG(s){return s=s|0,s&1|0}function dPe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+16|0,d=f+8|0,m=f,k=n[c>>2]|0,B=n[c+4>>2]|0,c=pn(l)|0,n[m>>2]=k,n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],mPe(s,c,d,0),C=f}function mPe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0,Q=0,O=0,M=0;d=C,C=C+32|0,m=d+16|0,M=d+8|0,k=d,O=n[c>>2]|0,Q=n[c+4>>2]|0,B=n[s>>2]|0,s=vF()|0,n[M>>2]=O,n[M+4>>2]=Q,n[m>>2]=n[M>>2],n[m+4>>2]=n[M+4>>2],c=yPe(m)|0,n[k>>2]=O,n[k+4>>2]=Q,n[m>>2]=n[k>>2],n[m+4>>2]=n[k+4>>2],hn(B,l,s,c,EPe(m,f)|0,f),C=d}function vF(){var s=0,l=0;if(o[7656]|0||(lG(9304),ir(28,9304,U|0)|0,l=7656,n[l>>2]=1,n[l+4>>2]=0),!(Rr(9304)|0)){s=9304,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));lG(9304)}return 9304}function yPe(s){return s=s|0,0}function EPe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0;return M=C,C=C+32|0,d=M+24|0,B=M+16|0,k=M,Q=M+8|0,m=n[s>>2]|0,f=n[s+4>>2]|0,n[k>>2]=m,n[k+4>>2]=f,j=vF()|0,O=j+24|0,s=gr(l,4)|0,n[Q>>2]=s,l=j+28|0,c=n[l>>2]|0,c>>>0<(n[j+32>>2]|0)>>>0?(n[B>>2]=m,n[B+4>>2]=f,n[d>>2]=n[B>>2],n[d+4>>2]=n[B+4>>2],aG(c,d,s),s=(n[l>>2]|0)+12|0,n[l>>2]=s):(CPe(O,k,Q),s=n[l>>2]|0),C=M,((s-(n[O>>2]|0)|0)/12|0)+-1|0}function aG(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=n[l+4>>2]|0,n[s>>2]=n[l>>2],n[s+4>>2]=f,n[s+8>>2]=c}function CPe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0,se=0;if(O=C,C=C+48|0,f=O+32|0,B=O+24|0,k=O,Q=s+4|0,d=(((n[Q>>2]|0)-(n[s>>2]|0)|0)/12|0)+1|0,m=wPe(s)|0,m>>>0>>0)Jr(s);else{M=n[s>>2]|0,se=((n[s+8>>2]|0)-M|0)/12|0,j=se<<1,IPe(k,se>>>0>>1>>>0?j>>>0>>0?d:j:m,((n[Q>>2]|0)-M|0)/12|0,s+8|0),Q=k+8|0,m=n[Q>>2]|0,d=n[l+4>>2]|0,c=n[c>>2]|0,n[B>>2]=n[l>>2],n[B+4>>2]=d,n[f>>2]=n[B>>2],n[f+4>>2]=n[B+4>>2],aG(m,f,c),n[Q>>2]=(n[Q>>2]|0)+12,BPe(s,k),vPe(k),C=O;return}}function wPe(s){return s=s|0,357913941}function IPe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>357913941)Tt();else{d=Kt(l*12|0)|0;break}else d=0;while(!1);n[s>>2]=d,f=d+(c*12|0)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l*12|0)}function BPe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(((d|0)/-12|0)*12|0)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function vPe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~(((f+-12-l|0)>>>0)/12|0)*12|0)),s=n[s>>2]|0,s|0&>(s)}function lG(s){s=s|0,bPe(s)}function DPe(s){s=s|0,PPe(s+24|0)}function PPe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~(((l+-12-f|0)>>>0)/12|0)*12|0)),gt(c))}function bPe(s){s=s|0;var l=0;l=Vr()|0,zr(s,2,5,l,SPe()|0,1),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function SPe(){return 1164}function xPe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;f=C,C=C+16|0,d=f+8|0,m=f,B=kPe(s)|0,s=n[B+4>>2]|0,n[m>>2]=n[B>>2],n[m+4>>2]=s,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],QPe(l,d,c),C=f}function kPe(s){return s=s|0,(n[(vF()|0)+24>>2]|0)+(s*12|0)|0}function QPe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0;m=C,C=C+16|0,d=m,f=n[l>>2]|0,l=n[l+4>>2]|0,s=s+(l>>1)|0,l&1&&(f=n[(n[s>>2]|0)+f>>2]|0),Ip(d,c),c=Bp(d,c)|0,tf[f&31](s,c),vp(d),C=m}function Ip(s,l){s=s|0,l=l|0,FPe(s,l)}function Bp(s,l){return s=s|0,l=l|0,s|0}function vp(s){s=s|0,qA(s)}function FPe(s,l){s=s|0,l=l|0,DF(s,l)}function DF(s,l){s=s|0,l=l|0,n[s>>2]=l}function RPe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+16|0,d=f+8|0,m=f,k=n[c>>2]|0,B=n[c+4>>2]|0,c=pn(l)|0,n[m>>2]=k,n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],TPe(s,c,d,0),C=f}function TPe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0,Q=0,O=0,M=0;d=C,C=C+32|0,m=d+16|0,M=d+8|0,k=d,O=n[c>>2]|0,Q=n[c+4>>2]|0,B=n[s>>2]|0,s=PF()|0,n[M>>2]=O,n[M+4>>2]=Q,n[m>>2]=n[M>>2],n[m+4>>2]=n[M+4>>2],c=NPe(m)|0,n[k>>2]=O,n[k+4>>2]=Q,n[m>>2]=n[k>>2],n[m+4>>2]=n[k+4>>2],hn(B,l,s,c,LPe(m,f)|0,f),C=d}function PF(){var s=0,l=0;if(o[7664]|0||(uG(9340),ir(29,9340,U|0)|0,l=7664,n[l>>2]=1,n[l+4>>2]=0),!(Rr(9340)|0)){s=9340,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));uG(9340)}return 9340}function NPe(s){return s=s|0,0}function LPe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0;return M=C,C=C+32|0,d=M+24|0,B=M+16|0,k=M,Q=M+8|0,m=n[s>>2]|0,f=n[s+4>>2]|0,n[k>>2]=m,n[k+4>>2]=f,j=PF()|0,O=j+24|0,s=gr(l,4)|0,n[Q>>2]=s,l=j+28|0,c=n[l>>2]|0,c>>>0<(n[j+32>>2]|0)>>>0?(n[B>>2]=m,n[B+4>>2]=f,n[d>>2]=n[B>>2],n[d+4>>2]=n[B+4>>2],cG(c,d,s),s=(n[l>>2]|0)+12|0,n[l>>2]=s):(MPe(O,k,Q),s=n[l>>2]|0),C=M,((s-(n[O>>2]|0)|0)/12|0)+-1|0}function cG(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=n[l+4>>2]|0,n[s>>2]=n[l>>2],n[s+4>>2]=f,n[s+8>>2]=c}function MPe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0,se=0;if(O=C,C=C+48|0,f=O+32|0,B=O+24|0,k=O,Q=s+4|0,d=(((n[Q>>2]|0)-(n[s>>2]|0)|0)/12|0)+1|0,m=OPe(s)|0,m>>>0>>0)Jr(s);else{M=n[s>>2]|0,se=((n[s+8>>2]|0)-M|0)/12|0,j=se<<1,UPe(k,se>>>0>>1>>>0?j>>>0>>0?d:j:m,((n[Q>>2]|0)-M|0)/12|0,s+8|0),Q=k+8|0,m=n[Q>>2]|0,d=n[l+4>>2]|0,c=n[c>>2]|0,n[B>>2]=n[l>>2],n[B+4>>2]=d,n[f>>2]=n[B>>2],n[f+4>>2]=n[B+4>>2],cG(m,f,c),n[Q>>2]=(n[Q>>2]|0)+12,_Pe(s,k),HPe(k),C=O;return}}function OPe(s){return s=s|0,357913941}function UPe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>357913941)Tt();else{d=Kt(l*12|0)|0;break}else d=0;while(!1);n[s>>2]=d,f=d+(c*12|0)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l*12|0)}function _Pe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(((d|0)/-12|0)*12|0)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function HPe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~(((f+-12-l|0)>>>0)/12|0)*12|0)),s=n[s>>2]|0,s|0&>(s)}function uG(s){s=s|0,GPe(s)}function qPe(s){s=s|0,jPe(s+24|0)}function jPe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~(((l+-12-f|0)>>>0)/12|0)*12|0)),gt(c))}function GPe(s){s=s|0;var l=0;l=Vr()|0,zr(s,2,4,l,YPe()|0,1),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function YPe(){return 1180}function WPe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=KPe(s)|0,s=n[B+4>>2]|0,n[m>>2]=n[B>>2],n[m+4>>2]=s,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],c=VPe(l,d,c)|0,C=f,c|0}function KPe(s){return s=s|0,(n[(PF()|0)+24>>2]|0)+(s*12|0)|0}function VPe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0;return m=C,C=C+16|0,d=m,f=n[l>>2]|0,l=n[l+4>>2]|0,s=s+(l>>1)|0,l&1&&(f=n[(n[s>>2]|0)+f>>2]|0),v0(d,c),d=D0(d,c)|0,d=qv(IR[f&15](s,d)|0)|0,C=m,d|0}function v0(s,l){s=s|0,l=l|0}function D0(s,l){return s=s|0,l=l|0,zPe(l)|0}function qv(s){return s=s|0,s|0}function zPe(s){return s=s|0,s|0}function JPe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+16|0,d=f+8|0,m=f,k=n[c>>2]|0,B=n[c+4>>2]|0,c=pn(l)|0,n[m>>2]=k,n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],XPe(s,c,d,0),C=f}function XPe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0,Q=0,O=0,M=0;d=C,C=C+32|0,m=d+16|0,M=d+8|0,k=d,O=n[c>>2]|0,Q=n[c+4>>2]|0,B=n[s>>2]|0,s=bF()|0,n[M>>2]=O,n[M+4>>2]=Q,n[m>>2]=n[M>>2],n[m+4>>2]=n[M+4>>2],c=ZPe(m)|0,n[k>>2]=O,n[k+4>>2]=Q,n[m>>2]=n[k>>2],n[m+4>>2]=n[k+4>>2],hn(B,l,s,c,$Pe(m,f)|0,f),C=d}function bF(){var s=0,l=0;if(o[7672]|0||(fG(9376),ir(30,9376,U|0)|0,l=7672,n[l>>2]=1,n[l+4>>2]=0),!(Rr(9376)|0)){s=9376,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));fG(9376)}return 9376}function ZPe(s){return s=s|0,0}function $Pe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0;return M=C,C=C+32|0,d=M+24|0,B=M+16|0,k=M,Q=M+8|0,m=n[s>>2]|0,f=n[s+4>>2]|0,n[k>>2]=m,n[k+4>>2]=f,j=bF()|0,O=j+24|0,s=gr(l,4)|0,n[Q>>2]=s,l=j+28|0,c=n[l>>2]|0,c>>>0<(n[j+32>>2]|0)>>>0?(n[B>>2]=m,n[B+4>>2]=f,n[d>>2]=n[B>>2],n[d+4>>2]=n[B+4>>2],AG(c,d,s),s=(n[l>>2]|0)+12|0,n[l>>2]=s):(ebe(O,k,Q),s=n[l>>2]|0),C=M,((s-(n[O>>2]|0)|0)/12|0)+-1|0}function AG(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=n[l+4>>2]|0,n[s>>2]=n[l>>2],n[s+4>>2]=f,n[s+8>>2]=c}function ebe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0,se=0;if(O=C,C=C+48|0,f=O+32|0,B=O+24|0,k=O,Q=s+4|0,d=(((n[Q>>2]|0)-(n[s>>2]|0)|0)/12|0)+1|0,m=tbe(s)|0,m>>>0>>0)Jr(s);else{M=n[s>>2]|0,se=((n[s+8>>2]|0)-M|0)/12|0,j=se<<1,rbe(k,se>>>0>>1>>>0?j>>>0>>0?d:j:m,((n[Q>>2]|0)-M|0)/12|0,s+8|0),Q=k+8|0,m=n[Q>>2]|0,d=n[l+4>>2]|0,c=n[c>>2]|0,n[B>>2]=n[l>>2],n[B+4>>2]=d,n[f>>2]=n[B>>2],n[f+4>>2]=n[B+4>>2],AG(m,f,c),n[Q>>2]=(n[Q>>2]|0)+12,nbe(s,k),ibe(k),C=O;return}}function tbe(s){return s=s|0,357913941}function rbe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>357913941)Tt();else{d=Kt(l*12|0)|0;break}else d=0;while(!1);n[s>>2]=d,f=d+(c*12|0)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l*12|0)}function nbe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(((d|0)/-12|0)*12|0)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function ibe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~(((f+-12-l|0)>>>0)/12|0)*12|0)),s=n[s>>2]|0,s|0&>(s)}function fG(s){s=s|0,abe(s)}function sbe(s){s=s|0,obe(s+24|0)}function obe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~(((l+-12-f|0)>>>0)/12|0)*12|0)),gt(c))}function abe(s){s=s|0;var l=0;l=Vr()|0,zr(s,2,5,l,pG()|0,0),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function pG(){return 1196}function lbe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0;return c=C,C=C+16|0,f=c+8|0,d=c,m=cbe(s)|0,s=n[m+4>>2]|0,n[d>>2]=n[m>>2],n[d+4>>2]=s,n[f>>2]=n[d>>2],n[f+4>>2]=n[d+4>>2],l=ube(l,f)|0,C=c,l|0}function cbe(s){return s=s|0,(n[(bF()|0)+24>>2]|0)+(s*12|0)|0}function ube(s,l){s=s|0,l=l|0;var c=0;return c=n[l>>2]|0,l=n[l+4>>2]|0,s=s+(l>>1)|0,l&1&&(c=n[(n[s>>2]|0)+c>>2]|0),qv(F0[c&31](s)|0)|0}function Abe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+16|0,d=f+8|0,m=f,k=n[c>>2]|0,B=n[c+4>>2]|0,c=pn(l)|0,n[m>>2]=k,n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],fbe(s,c,d,1),C=f}function fbe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0,Q=0,O=0,M=0;d=C,C=C+32|0,m=d+16|0,M=d+8|0,k=d,O=n[c>>2]|0,Q=n[c+4>>2]|0,B=n[s>>2]|0,s=SF()|0,n[M>>2]=O,n[M+4>>2]=Q,n[m>>2]=n[M>>2],n[m+4>>2]=n[M+4>>2],c=pbe(m)|0,n[k>>2]=O,n[k+4>>2]=Q,n[m>>2]=n[k>>2],n[m+4>>2]=n[k+4>>2],hn(B,l,s,c,hbe(m,f)|0,f),C=d}function SF(){var s=0,l=0;if(o[7680]|0||(gG(9412),ir(31,9412,U|0)|0,l=7680,n[l>>2]=1,n[l+4>>2]=0),!(Rr(9412)|0)){s=9412,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));gG(9412)}return 9412}function pbe(s){return s=s|0,0}function hbe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0;return M=C,C=C+32|0,d=M+24|0,B=M+16|0,k=M,Q=M+8|0,m=n[s>>2]|0,f=n[s+4>>2]|0,n[k>>2]=m,n[k+4>>2]=f,j=SF()|0,O=j+24|0,s=gr(l,4)|0,n[Q>>2]=s,l=j+28|0,c=n[l>>2]|0,c>>>0<(n[j+32>>2]|0)>>>0?(n[B>>2]=m,n[B+4>>2]=f,n[d>>2]=n[B>>2],n[d+4>>2]=n[B+4>>2],hG(c,d,s),s=(n[l>>2]|0)+12|0,n[l>>2]=s):(gbe(O,k,Q),s=n[l>>2]|0),C=M,((s-(n[O>>2]|0)|0)/12|0)+-1|0}function hG(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=n[l+4>>2]|0,n[s>>2]=n[l>>2],n[s+4>>2]=f,n[s+8>>2]=c}function gbe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0,se=0;if(O=C,C=C+48|0,f=O+32|0,B=O+24|0,k=O,Q=s+4|0,d=(((n[Q>>2]|0)-(n[s>>2]|0)|0)/12|0)+1|0,m=dbe(s)|0,m>>>0>>0)Jr(s);else{M=n[s>>2]|0,se=((n[s+8>>2]|0)-M|0)/12|0,j=se<<1,mbe(k,se>>>0>>1>>>0?j>>>0>>0?d:j:m,((n[Q>>2]|0)-M|0)/12|0,s+8|0),Q=k+8|0,m=n[Q>>2]|0,d=n[l+4>>2]|0,c=n[c>>2]|0,n[B>>2]=n[l>>2],n[B+4>>2]=d,n[f>>2]=n[B>>2],n[f+4>>2]=n[B+4>>2],hG(m,f,c),n[Q>>2]=(n[Q>>2]|0)+12,ybe(s,k),Ebe(k),C=O;return}}function dbe(s){return s=s|0,357913941}function mbe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>357913941)Tt();else{d=Kt(l*12|0)|0;break}else d=0;while(!1);n[s>>2]=d,f=d+(c*12|0)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l*12|0)}function ybe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(((d|0)/-12|0)*12|0)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function Ebe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~(((f+-12-l|0)>>>0)/12|0)*12|0)),s=n[s>>2]|0,s|0&>(s)}function gG(s){s=s|0,Ibe(s)}function Cbe(s){s=s|0,wbe(s+24|0)}function wbe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~(((l+-12-f|0)>>>0)/12|0)*12|0)),gt(c))}function Ibe(s){s=s|0;var l=0;l=Vr()|0,zr(s,2,6,l,dG()|0,0),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function dG(){return 1200}function Bbe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0;return c=C,C=C+16|0,f=c+8|0,d=c,m=vbe(s)|0,s=n[m+4>>2]|0,n[d>>2]=n[m>>2],n[d+4>>2]=s,n[f>>2]=n[d>>2],n[f+4>>2]=n[d+4>>2],l=Dbe(l,f)|0,C=c,l|0}function vbe(s){return s=s|0,(n[(SF()|0)+24>>2]|0)+(s*12|0)|0}function Dbe(s,l){s=s|0,l=l|0;var c=0;return c=n[l>>2]|0,l=n[l+4>>2]|0,s=s+(l>>1)|0,l&1&&(c=n[(n[s>>2]|0)+c>>2]|0),jv(F0[c&31](s)|0)|0}function jv(s){return s=s|0,s|0}function Pbe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+16|0,d=f+8|0,m=f,k=n[c>>2]|0,B=n[c+4>>2]|0,c=pn(l)|0,n[m>>2]=k,n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],bbe(s,c,d,0),C=f}function bbe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0,Q=0,O=0,M=0;d=C,C=C+32|0,m=d+16|0,M=d+8|0,k=d,O=n[c>>2]|0,Q=n[c+4>>2]|0,B=n[s>>2]|0,s=xF()|0,n[M>>2]=O,n[M+4>>2]=Q,n[m>>2]=n[M>>2],n[m+4>>2]=n[M+4>>2],c=Sbe(m)|0,n[k>>2]=O,n[k+4>>2]=Q,n[m>>2]=n[k>>2],n[m+4>>2]=n[k+4>>2],hn(B,l,s,c,xbe(m,f)|0,f),C=d}function xF(){var s=0,l=0;if(o[7688]|0||(yG(9448),ir(32,9448,U|0)|0,l=7688,n[l>>2]=1,n[l+4>>2]=0),!(Rr(9448)|0)){s=9448,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));yG(9448)}return 9448}function Sbe(s){return s=s|0,0}function xbe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0;return M=C,C=C+32|0,d=M+24|0,B=M+16|0,k=M,Q=M+8|0,m=n[s>>2]|0,f=n[s+4>>2]|0,n[k>>2]=m,n[k+4>>2]=f,j=xF()|0,O=j+24|0,s=gr(l,4)|0,n[Q>>2]=s,l=j+28|0,c=n[l>>2]|0,c>>>0<(n[j+32>>2]|0)>>>0?(n[B>>2]=m,n[B+4>>2]=f,n[d>>2]=n[B>>2],n[d+4>>2]=n[B+4>>2],mG(c,d,s),s=(n[l>>2]|0)+12|0,n[l>>2]=s):(kbe(O,k,Q),s=n[l>>2]|0),C=M,((s-(n[O>>2]|0)|0)/12|0)+-1|0}function mG(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=n[l+4>>2]|0,n[s>>2]=n[l>>2],n[s+4>>2]=f,n[s+8>>2]=c}function kbe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0,se=0;if(O=C,C=C+48|0,f=O+32|0,B=O+24|0,k=O,Q=s+4|0,d=(((n[Q>>2]|0)-(n[s>>2]|0)|0)/12|0)+1|0,m=Qbe(s)|0,m>>>0>>0)Jr(s);else{M=n[s>>2]|0,se=((n[s+8>>2]|0)-M|0)/12|0,j=se<<1,Fbe(k,se>>>0>>1>>>0?j>>>0>>0?d:j:m,((n[Q>>2]|0)-M|0)/12|0,s+8|0),Q=k+8|0,m=n[Q>>2]|0,d=n[l+4>>2]|0,c=n[c>>2]|0,n[B>>2]=n[l>>2],n[B+4>>2]=d,n[f>>2]=n[B>>2],n[f+4>>2]=n[B+4>>2],mG(m,f,c),n[Q>>2]=(n[Q>>2]|0)+12,Rbe(s,k),Tbe(k),C=O;return}}function Qbe(s){return s=s|0,357913941}function Fbe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>357913941)Tt();else{d=Kt(l*12|0)|0;break}else d=0;while(!1);n[s>>2]=d,f=d+(c*12|0)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l*12|0)}function Rbe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(((d|0)/-12|0)*12|0)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function Tbe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~(((f+-12-l|0)>>>0)/12|0)*12|0)),s=n[s>>2]|0,s|0&>(s)}function yG(s){s=s|0,Mbe(s)}function Nbe(s){s=s|0,Lbe(s+24|0)}function Lbe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~(((l+-12-f|0)>>>0)/12|0)*12|0)),gt(c))}function Mbe(s){s=s|0;var l=0;l=Vr()|0,zr(s,2,6,l,EG()|0,1),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function EG(){return 1204}function Obe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;f=C,C=C+16|0,d=f+8|0,m=f,B=Ube(s)|0,s=n[B+4>>2]|0,n[m>>2]=n[B>>2],n[m+4>>2]=s,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],_be(l,d,c),C=f}function Ube(s){return s=s|0,(n[(xF()|0)+24>>2]|0)+(s*12|0)|0}function _be(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0;m=C,C=C+16|0,d=m,f=n[l>>2]|0,l=n[l+4>>2]|0,s=s+(l>>1)|0,l&1&&(f=n[(n[s>>2]|0)+f>>2]|0),kF(d,c),d=QF(d,c)|0,tf[f&31](s,d),C=m}function kF(s,l){s=s|0,l=l|0}function QF(s,l){return s=s|0,l=l|0,Hbe(l)|0}function Hbe(s){return s=s|0,s|0}function qbe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+16|0,d=f+8|0,m=f,k=n[c>>2]|0,B=n[c+4>>2]|0,c=pn(l)|0,n[m>>2]=k,n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],jbe(s,c,d,0),C=f}function jbe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0,Q=0,O=0,M=0;d=C,C=C+32|0,m=d+16|0,M=d+8|0,k=d,O=n[c>>2]|0,Q=n[c+4>>2]|0,B=n[s>>2]|0,s=FF()|0,n[M>>2]=O,n[M+4>>2]=Q,n[m>>2]=n[M>>2],n[m+4>>2]=n[M+4>>2],c=Gbe(m)|0,n[k>>2]=O,n[k+4>>2]=Q,n[m>>2]=n[k>>2],n[m+4>>2]=n[k+4>>2],hn(B,l,s,c,Ybe(m,f)|0,f),C=d}function FF(){var s=0,l=0;if(o[7696]|0||(wG(9484),ir(33,9484,U|0)|0,l=7696,n[l>>2]=1,n[l+4>>2]=0),!(Rr(9484)|0)){s=9484,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));wG(9484)}return 9484}function Gbe(s){return s=s|0,0}function Ybe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0;return M=C,C=C+32|0,d=M+24|0,B=M+16|0,k=M,Q=M+8|0,m=n[s>>2]|0,f=n[s+4>>2]|0,n[k>>2]=m,n[k+4>>2]=f,j=FF()|0,O=j+24|0,s=gr(l,4)|0,n[Q>>2]=s,l=j+28|0,c=n[l>>2]|0,c>>>0<(n[j+32>>2]|0)>>>0?(n[B>>2]=m,n[B+4>>2]=f,n[d>>2]=n[B>>2],n[d+4>>2]=n[B+4>>2],CG(c,d,s),s=(n[l>>2]|0)+12|0,n[l>>2]=s):(Wbe(O,k,Q),s=n[l>>2]|0),C=M,((s-(n[O>>2]|0)|0)/12|0)+-1|0}function CG(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=n[l+4>>2]|0,n[s>>2]=n[l>>2],n[s+4>>2]=f,n[s+8>>2]=c}function Wbe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0,se=0;if(O=C,C=C+48|0,f=O+32|0,B=O+24|0,k=O,Q=s+4|0,d=(((n[Q>>2]|0)-(n[s>>2]|0)|0)/12|0)+1|0,m=Kbe(s)|0,m>>>0>>0)Jr(s);else{M=n[s>>2]|0,se=((n[s+8>>2]|0)-M|0)/12|0,j=se<<1,Vbe(k,se>>>0>>1>>>0?j>>>0>>0?d:j:m,((n[Q>>2]|0)-M|0)/12|0,s+8|0),Q=k+8|0,m=n[Q>>2]|0,d=n[l+4>>2]|0,c=n[c>>2]|0,n[B>>2]=n[l>>2],n[B+4>>2]=d,n[f>>2]=n[B>>2],n[f+4>>2]=n[B+4>>2],CG(m,f,c),n[Q>>2]=(n[Q>>2]|0)+12,zbe(s,k),Jbe(k),C=O;return}}function Kbe(s){return s=s|0,357913941}function Vbe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>357913941)Tt();else{d=Kt(l*12|0)|0;break}else d=0;while(!1);n[s>>2]=d,f=d+(c*12|0)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l*12|0)}function zbe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(((d|0)/-12|0)*12|0)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function Jbe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~(((f+-12-l|0)>>>0)/12|0)*12|0)),s=n[s>>2]|0,s|0&>(s)}function wG(s){s=s|0,$be(s)}function Xbe(s){s=s|0,Zbe(s+24|0)}function Zbe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~(((l+-12-f|0)>>>0)/12|0)*12|0)),gt(c))}function $be(s){s=s|0;var l=0;l=Vr()|0,zr(s,2,1,l,eSe()|0,2),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function eSe(){return 1212}function tSe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0;d=C,C=C+16|0,m=d+8|0,B=d,k=rSe(s)|0,s=n[k+4>>2]|0,n[B>>2]=n[k>>2],n[B+4>>2]=s,n[m>>2]=n[B>>2],n[m+4>>2]=n[B+4>>2],nSe(l,m,c,f),C=d}function rSe(s){return s=s|0,(n[(FF()|0)+24>>2]|0)+(s*12|0)|0}function nSe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0;k=C,C=C+16|0,m=k+1|0,B=k,d=n[l>>2]|0,l=n[l+4>>2]|0,s=s+(l>>1)|0,l&1&&(d=n[(n[s>>2]|0)+d>>2]|0),kF(m,c),m=QF(m,c)|0,v0(B,f),B=D0(B,f)|0,vw[d&15](s,m,B),C=k}function iSe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+16|0,d=f+8|0,m=f,k=n[c>>2]|0,B=n[c+4>>2]|0,c=pn(l)|0,n[m>>2]=k,n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],sSe(s,c,d,1),C=f}function sSe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0,Q=0,O=0,M=0;d=C,C=C+32|0,m=d+16|0,M=d+8|0,k=d,O=n[c>>2]|0,Q=n[c+4>>2]|0,B=n[s>>2]|0,s=RF()|0,n[M>>2]=O,n[M+4>>2]=Q,n[m>>2]=n[M>>2],n[m+4>>2]=n[M+4>>2],c=oSe(m)|0,n[k>>2]=O,n[k+4>>2]=Q,n[m>>2]=n[k>>2],n[m+4>>2]=n[k+4>>2],hn(B,l,s,c,aSe(m,f)|0,f),C=d}function RF(){var s=0,l=0;if(o[7704]|0||(BG(9520),ir(34,9520,U|0)|0,l=7704,n[l>>2]=1,n[l+4>>2]=0),!(Rr(9520)|0)){s=9520,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));BG(9520)}return 9520}function oSe(s){return s=s|0,0}function aSe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0;return M=C,C=C+32|0,d=M+24|0,B=M+16|0,k=M,Q=M+8|0,m=n[s>>2]|0,f=n[s+4>>2]|0,n[k>>2]=m,n[k+4>>2]=f,j=RF()|0,O=j+24|0,s=gr(l,4)|0,n[Q>>2]=s,l=j+28|0,c=n[l>>2]|0,c>>>0<(n[j+32>>2]|0)>>>0?(n[B>>2]=m,n[B+4>>2]=f,n[d>>2]=n[B>>2],n[d+4>>2]=n[B+4>>2],IG(c,d,s),s=(n[l>>2]|0)+12|0,n[l>>2]=s):(lSe(O,k,Q),s=n[l>>2]|0),C=M,((s-(n[O>>2]|0)|0)/12|0)+-1|0}function IG(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=n[l+4>>2]|0,n[s>>2]=n[l>>2],n[s+4>>2]=f,n[s+8>>2]=c}function lSe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0,se=0;if(O=C,C=C+48|0,f=O+32|0,B=O+24|0,k=O,Q=s+4|0,d=(((n[Q>>2]|0)-(n[s>>2]|0)|0)/12|0)+1|0,m=cSe(s)|0,m>>>0>>0)Jr(s);else{M=n[s>>2]|0,se=((n[s+8>>2]|0)-M|0)/12|0,j=se<<1,uSe(k,se>>>0>>1>>>0?j>>>0>>0?d:j:m,((n[Q>>2]|0)-M|0)/12|0,s+8|0),Q=k+8|0,m=n[Q>>2]|0,d=n[l+4>>2]|0,c=n[c>>2]|0,n[B>>2]=n[l>>2],n[B+4>>2]=d,n[f>>2]=n[B>>2],n[f+4>>2]=n[B+4>>2],IG(m,f,c),n[Q>>2]=(n[Q>>2]|0)+12,ASe(s,k),fSe(k),C=O;return}}function cSe(s){return s=s|0,357913941}function uSe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>357913941)Tt();else{d=Kt(l*12|0)|0;break}else d=0;while(!1);n[s>>2]=d,f=d+(c*12|0)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l*12|0)}function ASe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(((d|0)/-12|0)*12|0)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function fSe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~(((f+-12-l|0)>>>0)/12|0)*12|0)),s=n[s>>2]|0,s|0&>(s)}function BG(s){s=s|0,gSe(s)}function pSe(s){s=s|0,hSe(s+24|0)}function hSe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~(((l+-12-f|0)>>>0)/12|0)*12|0)),gt(c))}function gSe(s){s=s|0;var l=0;l=Vr()|0,zr(s,2,1,l,dSe()|0,1),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function dSe(){return 1224}function mSe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;return d=C,C=C+16|0,m=d+8|0,B=d,k=ySe(s)|0,s=n[k+4>>2]|0,n[B>>2]=n[k>>2],n[B+4>>2]=s,n[m>>2]=n[B>>2],n[m+4>>2]=n[B+4>>2],f=+ESe(l,m,c),C=d,+f}function ySe(s){return s=s|0,(n[(RF()|0)+24>>2]|0)+(s*12|0)|0}function ESe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return m=C,C=C+16|0,d=m,f=n[l>>2]|0,l=n[l+4>>2]|0,s=s+(l>>1)|0,l&1&&(f=n[(n[s>>2]|0)+f>>2]|0),XA(d,c),d=ZA(d,c)|0,B=+gF(+C7[f&7](s,d)),C=m,+B}function CSe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+16|0,d=f+8|0,m=f,k=n[c>>2]|0,B=n[c+4>>2]|0,c=pn(l)|0,n[m>>2]=k,n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],wSe(s,c,d,1),C=f}function wSe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0,Q=0,O=0,M=0;d=C,C=C+32|0,m=d+16|0,M=d+8|0,k=d,O=n[c>>2]|0,Q=n[c+4>>2]|0,B=n[s>>2]|0,s=TF()|0,n[M>>2]=O,n[M+4>>2]=Q,n[m>>2]=n[M>>2],n[m+4>>2]=n[M+4>>2],c=ISe(m)|0,n[k>>2]=O,n[k+4>>2]=Q,n[m>>2]=n[k>>2],n[m+4>>2]=n[k+4>>2],hn(B,l,s,c,BSe(m,f)|0,f),C=d}function TF(){var s=0,l=0;if(o[7712]|0||(DG(9556),ir(35,9556,U|0)|0,l=7712,n[l>>2]=1,n[l+4>>2]=0),!(Rr(9556)|0)){s=9556,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));DG(9556)}return 9556}function ISe(s){return s=s|0,0}function BSe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0;return M=C,C=C+32|0,d=M+24|0,B=M+16|0,k=M,Q=M+8|0,m=n[s>>2]|0,f=n[s+4>>2]|0,n[k>>2]=m,n[k+4>>2]=f,j=TF()|0,O=j+24|0,s=gr(l,4)|0,n[Q>>2]=s,l=j+28|0,c=n[l>>2]|0,c>>>0<(n[j+32>>2]|0)>>>0?(n[B>>2]=m,n[B+4>>2]=f,n[d>>2]=n[B>>2],n[d+4>>2]=n[B+4>>2],vG(c,d,s),s=(n[l>>2]|0)+12|0,n[l>>2]=s):(vSe(O,k,Q),s=n[l>>2]|0),C=M,((s-(n[O>>2]|0)|0)/12|0)+-1|0}function vG(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=n[l+4>>2]|0,n[s>>2]=n[l>>2],n[s+4>>2]=f,n[s+8>>2]=c}function vSe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0,se=0;if(O=C,C=C+48|0,f=O+32|0,B=O+24|0,k=O,Q=s+4|0,d=(((n[Q>>2]|0)-(n[s>>2]|0)|0)/12|0)+1|0,m=DSe(s)|0,m>>>0>>0)Jr(s);else{M=n[s>>2]|0,se=((n[s+8>>2]|0)-M|0)/12|0,j=se<<1,PSe(k,se>>>0>>1>>>0?j>>>0>>0?d:j:m,((n[Q>>2]|0)-M|0)/12|0,s+8|0),Q=k+8|0,m=n[Q>>2]|0,d=n[l+4>>2]|0,c=n[c>>2]|0,n[B>>2]=n[l>>2],n[B+4>>2]=d,n[f>>2]=n[B>>2],n[f+4>>2]=n[B+4>>2],vG(m,f,c),n[Q>>2]=(n[Q>>2]|0)+12,bSe(s,k),SSe(k),C=O;return}}function DSe(s){return s=s|0,357913941}function PSe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>357913941)Tt();else{d=Kt(l*12|0)|0;break}else d=0;while(!1);n[s>>2]=d,f=d+(c*12|0)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l*12|0)}function bSe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(((d|0)/-12|0)*12|0)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function SSe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~(((f+-12-l|0)>>>0)/12|0)*12|0)),s=n[s>>2]|0,s|0&>(s)}function DG(s){s=s|0,QSe(s)}function xSe(s){s=s|0,kSe(s+24|0)}function kSe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~(((l+-12-f|0)>>>0)/12|0)*12|0)),gt(c))}function QSe(s){s=s|0;var l=0;l=Vr()|0,zr(s,2,5,l,FSe()|0,0),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function FSe(){return 1232}function RSe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=TSe(s)|0,s=n[B+4>>2]|0,n[m>>2]=n[B>>2],n[m+4>>2]=s,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],c=+NSe(l,d),C=f,+c}function TSe(s){return s=s|0,(n[(TF()|0)+24>>2]|0)+(s*12|0)|0}function NSe(s,l){s=s|0,l=l|0;var c=0;return c=n[l>>2]|0,l=n[l+4>>2]|0,s=s+(l>>1)|0,l&1&&(c=n[(n[s>>2]|0)+c>>2]|0),+ +gF(+E7[c&15](s))}function LSe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+16|0,d=f+8|0,m=f,k=n[c>>2]|0,B=n[c+4>>2]|0,c=pn(l)|0,n[m>>2]=k,n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],MSe(s,c,d,1),C=f}function MSe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0,Q=0,O=0,M=0;d=C,C=C+32|0,m=d+16|0,M=d+8|0,k=d,O=n[c>>2]|0,Q=n[c+4>>2]|0,B=n[s>>2]|0,s=NF()|0,n[M>>2]=O,n[M+4>>2]=Q,n[m>>2]=n[M>>2],n[m+4>>2]=n[M+4>>2],c=OSe(m)|0,n[k>>2]=O,n[k+4>>2]=Q,n[m>>2]=n[k>>2],n[m+4>>2]=n[k+4>>2],hn(B,l,s,c,USe(m,f)|0,f),C=d}function NF(){var s=0,l=0;if(o[7720]|0||(bG(9592),ir(36,9592,U|0)|0,l=7720,n[l>>2]=1,n[l+4>>2]=0),!(Rr(9592)|0)){s=9592,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));bG(9592)}return 9592}function OSe(s){return s=s|0,0}function USe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0;return M=C,C=C+32|0,d=M+24|0,B=M+16|0,k=M,Q=M+8|0,m=n[s>>2]|0,f=n[s+4>>2]|0,n[k>>2]=m,n[k+4>>2]=f,j=NF()|0,O=j+24|0,s=gr(l,4)|0,n[Q>>2]=s,l=j+28|0,c=n[l>>2]|0,c>>>0<(n[j+32>>2]|0)>>>0?(n[B>>2]=m,n[B+4>>2]=f,n[d>>2]=n[B>>2],n[d+4>>2]=n[B+4>>2],PG(c,d,s),s=(n[l>>2]|0)+12|0,n[l>>2]=s):(_Se(O,k,Q),s=n[l>>2]|0),C=M,((s-(n[O>>2]|0)|0)/12|0)+-1|0}function PG(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=n[l+4>>2]|0,n[s>>2]=n[l>>2],n[s+4>>2]=f,n[s+8>>2]=c}function _Se(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0,se=0;if(O=C,C=C+48|0,f=O+32|0,B=O+24|0,k=O,Q=s+4|0,d=(((n[Q>>2]|0)-(n[s>>2]|0)|0)/12|0)+1|0,m=HSe(s)|0,m>>>0>>0)Jr(s);else{M=n[s>>2]|0,se=((n[s+8>>2]|0)-M|0)/12|0,j=se<<1,qSe(k,se>>>0>>1>>>0?j>>>0>>0?d:j:m,((n[Q>>2]|0)-M|0)/12|0,s+8|0),Q=k+8|0,m=n[Q>>2]|0,d=n[l+4>>2]|0,c=n[c>>2]|0,n[B>>2]=n[l>>2],n[B+4>>2]=d,n[f>>2]=n[B>>2],n[f+4>>2]=n[B+4>>2],PG(m,f,c),n[Q>>2]=(n[Q>>2]|0)+12,jSe(s,k),GSe(k),C=O;return}}function HSe(s){return s=s|0,357913941}function qSe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>357913941)Tt();else{d=Kt(l*12|0)|0;break}else d=0;while(!1);n[s>>2]=d,f=d+(c*12|0)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l*12|0)}function jSe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(((d|0)/-12|0)*12|0)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function GSe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~(((f+-12-l|0)>>>0)/12|0)*12|0)),s=n[s>>2]|0,s|0&>(s)}function bG(s){s=s|0,KSe(s)}function YSe(s){s=s|0,WSe(s+24|0)}function WSe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~(((l+-12-f|0)>>>0)/12|0)*12|0)),gt(c))}function KSe(s){s=s|0;var l=0;l=Vr()|0,zr(s,2,7,l,VSe()|0,0),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function VSe(){return 1276}function zSe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0;return c=C,C=C+16|0,f=c+8|0,d=c,m=JSe(s)|0,s=n[m+4>>2]|0,n[d>>2]=n[m>>2],n[d+4>>2]=s,n[f>>2]=n[d>>2],n[f+4>>2]=n[d+4>>2],l=XSe(l,f)|0,C=c,l|0}function JSe(s){return s=s|0,(n[(NF()|0)+24>>2]|0)+(s*12|0)|0}function XSe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0;return d=C,C=C+16|0,f=d,c=n[l>>2]|0,l=n[l+4>>2]|0,s=s+(l>>1)|0,l&1&&(c=n[(n[s>>2]|0)+c>>2]|0),tf[c&31](f,s),f=SG(f)|0,C=d,f|0}function SG(s){s=s|0;var l=0,c=0,f=0,d=0;return d=C,C=C+32|0,l=d+12|0,c=d,f=yF(xG()|0)|0,f?(EF(l,f),CF(c,l),ZSe(s,c),s=wF(l)|0):s=$Se(s)|0,C=d,s|0}function xG(){var s=0;return o[7736]|0||(cxe(9640),ir(25,9640,U|0)|0,s=7736,n[s>>2]=1,n[s+4>>2]=0),9640}function ZSe(s,l){s=s|0,l=l|0,nxe(l,s,s+8|0)|0}function $Se(s){s=s|0;var l=0,c=0,f=0,d=0,m=0,B=0,k=0;return c=C,C=C+16|0,d=c+4|0,B=c,f=Va(8)|0,l=f,k=Kt(16)|0,n[k>>2]=n[s>>2],n[k+4>>2]=n[s+4>>2],n[k+8>>2]=n[s+8>>2],n[k+12>>2]=n[s+12>>2],m=l+4|0,n[m>>2]=k,s=Kt(8)|0,m=n[m>>2]|0,n[B>>2]=0,n[d>>2]=n[B>>2],LF(s,m,d),n[f>>2]=s,C=c,l|0}function LF(s,l,c){s=s|0,l=l|0,c=c|0,n[s>>2]=l,c=Kt(16)|0,n[c+4>>2]=0,n[c+8>>2]=0,n[c>>2]=1244,n[c+12>>2]=l,n[s+4>>2]=c}function exe(s){s=s|0,Md(s),gt(s)}function txe(s){s=s|0,s=n[s+12>>2]|0,s|0&>(s)}function rxe(s){s=s|0,gt(s)}function nxe(s,l,c){return s=s|0,l=l|0,c=c|0,l=ixe(n[s>>2]|0,l,c)|0,c=s+4|0,n[(n[c>>2]|0)+8>>2]=l,n[(n[c>>2]|0)+8>>2]|0}function ixe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0;return f=C,C=C+16|0,d=f,za(d),s=ya(s)|0,c=sxe(s,n[l>>2]|0,+E[c>>3])|0,Ja(d),C=f,c|0}function sxe(s,l,c){s=s|0,l=l|0,c=+c;var f=0;return f=Pl(oxe()|0)|0,l=hF(l)|0,ml(0,f|0,s|0,l|0,+ +VA(c))|0}function oxe(){var s=0;return o[7728]|0||(axe(9628),s=7728,n[s>>2]=1,n[s+4>>2]=0),9628}function axe(s){s=s|0,bl(s,lxe()|0,2)}function lxe(){return 1264}function cxe(s){s=s|0,wp(s)}function uxe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+16|0,d=f+8|0,m=f,k=n[c>>2]|0,B=n[c+4>>2]|0,c=pn(l)|0,n[m>>2]=k,n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],Axe(s,c,d,1),C=f}function Axe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0,Q=0,O=0,M=0;d=C,C=C+32|0,m=d+16|0,M=d+8|0,k=d,O=n[c>>2]|0,Q=n[c+4>>2]|0,B=n[s>>2]|0,s=MF()|0,n[M>>2]=O,n[M+4>>2]=Q,n[m>>2]=n[M>>2],n[m+4>>2]=n[M+4>>2],c=fxe(m)|0,n[k>>2]=O,n[k+4>>2]=Q,n[m>>2]=n[k>>2],n[m+4>>2]=n[k+4>>2],hn(B,l,s,c,pxe(m,f)|0,f),C=d}function MF(){var s=0,l=0;if(o[7744]|0||(QG(9684),ir(37,9684,U|0)|0,l=7744,n[l>>2]=1,n[l+4>>2]=0),!(Rr(9684)|0)){s=9684,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));QG(9684)}return 9684}function fxe(s){return s=s|0,0}function pxe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0;return M=C,C=C+32|0,d=M+24|0,B=M+16|0,k=M,Q=M+8|0,m=n[s>>2]|0,f=n[s+4>>2]|0,n[k>>2]=m,n[k+4>>2]=f,j=MF()|0,O=j+24|0,s=gr(l,4)|0,n[Q>>2]=s,l=j+28|0,c=n[l>>2]|0,c>>>0<(n[j+32>>2]|0)>>>0?(n[B>>2]=m,n[B+4>>2]=f,n[d>>2]=n[B>>2],n[d+4>>2]=n[B+4>>2],kG(c,d,s),s=(n[l>>2]|0)+12|0,n[l>>2]=s):(hxe(O,k,Q),s=n[l>>2]|0),C=M,((s-(n[O>>2]|0)|0)/12|0)+-1|0}function kG(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=n[l+4>>2]|0,n[s>>2]=n[l>>2],n[s+4>>2]=f,n[s+8>>2]=c}function hxe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0,se=0;if(O=C,C=C+48|0,f=O+32|0,B=O+24|0,k=O,Q=s+4|0,d=(((n[Q>>2]|0)-(n[s>>2]|0)|0)/12|0)+1|0,m=gxe(s)|0,m>>>0>>0)Jr(s);else{M=n[s>>2]|0,se=((n[s+8>>2]|0)-M|0)/12|0,j=se<<1,dxe(k,se>>>0>>1>>>0?j>>>0>>0?d:j:m,((n[Q>>2]|0)-M|0)/12|0,s+8|0),Q=k+8|0,m=n[Q>>2]|0,d=n[l+4>>2]|0,c=n[c>>2]|0,n[B>>2]=n[l>>2],n[B+4>>2]=d,n[f>>2]=n[B>>2],n[f+4>>2]=n[B+4>>2],kG(m,f,c),n[Q>>2]=(n[Q>>2]|0)+12,mxe(s,k),yxe(k),C=O;return}}function gxe(s){return s=s|0,357913941}function dxe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>357913941)Tt();else{d=Kt(l*12|0)|0;break}else d=0;while(!1);n[s>>2]=d,f=d+(c*12|0)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l*12|0)}function mxe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(((d|0)/-12|0)*12|0)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function yxe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~(((f+-12-l|0)>>>0)/12|0)*12|0)),s=n[s>>2]|0,s|0&>(s)}function QG(s){s=s|0,wxe(s)}function Exe(s){s=s|0,Cxe(s+24|0)}function Cxe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~(((l+-12-f|0)>>>0)/12|0)*12|0)),gt(c))}function wxe(s){s=s|0;var l=0;l=Vr()|0,zr(s,2,5,l,Ixe()|0,1),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function Ixe(){return 1280}function Bxe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=vxe(s)|0,s=n[B+4>>2]|0,n[m>>2]=n[B>>2],n[m+4>>2]=s,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],c=Dxe(l,d,c)|0,C=f,c|0}function vxe(s){return s=s|0,(n[(MF()|0)+24>>2]|0)+(s*12|0)|0}function Dxe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return B=C,C=C+32|0,d=B,m=B+16|0,f=n[l>>2]|0,l=n[l+4>>2]|0,s=s+(l>>1)|0,l&1&&(f=n[(n[s>>2]|0)+f>>2]|0),XA(m,c),m=ZA(m,c)|0,vw[f&15](d,s,m),m=SG(d)|0,C=B,m|0}function Pxe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+16|0,d=f+8|0,m=f,k=n[c>>2]|0,B=n[c+4>>2]|0,c=pn(l)|0,n[m>>2]=k,n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],bxe(s,c,d,1),C=f}function bxe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0,Q=0,O=0,M=0;d=C,C=C+32|0,m=d+16|0,M=d+8|0,k=d,O=n[c>>2]|0,Q=n[c+4>>2]|0,B=n[s>>2]|0,s=OF()|0,n[M>>2]=O,n[M+4>>2]=Q,n[m>>2]=n[M>>2],n[m+4>>2]=n[M+4>>2],c=Sxe(m)|0,n[k>>2]=O,n[k+4>>2]=Q,n[m>>2]=n[k>>2],n[m+4>>2]=n[k+4>>2],hn(B,l,s,c,xxe(m,f)|0,f),C=d}function OF(){var s=0,l=0;if(o[7752]|0||(RG(9720),ir(38,9720,U|0)|0,l=7752,n[l>>2]=1,n[l+4>>2]=0),!(Rr(9720)|0)){s=9720,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));RG(9720)}return 9720}function Sxe(s){return s=s|0,0}function xxe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0;return M=C,C=C+32|0,d=M+24|0,B=M+16|0,k=M,Q=M+8|0,m=n[s>>2]|0,f=n[s+4>>2]|0,n[k>>2]=m,n[k+4>>2]=f,j=OF()|0,O=j+24|0,s=gr(l,4)|0,n[Q>>2]=s,l=j+28|0,c=n[l>>2]|0,c>>>0<(n[j+32>>2]|0)>>>0?(n[B>>2]=m,n[B+4>>2]=f,n[d>>2]=n[B>>2],n[d+4>>2]=n[B+4>>2],FG(c,d,s),s=(n[l>>2]|0)+12|0,n[l>>2]=s):(kxe(O,k,Q),s=n[l>>2]|0),C=M,((s-(n[O>>2]|0)|0)/12|0)+-1|0}function FG(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=n[l+4>>2]|0,n[s>>2]=n[l>>2],n[s+4>>2]=f,n[s+8>>2]=c}function kxe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0,se=0;if(O=C,C=C+48|0,f=O+32|0,B=O+24|0,k=O,Q=s+4|0,d=(((n[Q>>2]|0)-(n[s>>2]|0)|0)/12|0)+1|0,m=Qxe(s)|0,m>>>0>>0)Jr(s);else{M=n[s>>2]|0,se=((n[s+8>>2]|0)-M|0)/12|0,j=se<<1,Fxe(k,se>>>0>>1>>>0?j>>>0>>0?d:j:m,((n[Q>>2]|0)-M|0)/12|0,s+8|0),Q=k+8|0,m=n[Q>>2]|0,d=n[l+4>>2]|0,c=n[c>>2]|0,n[B>>2]=n[l>>2],n[B+4>>2]=d,n[f>>2]=n[B>>2],n[f+4>>2]=n[B+4>>2],FG(m,f,c),n[Q>>2]=(n[Q>>2]|0)+12,Rxe(s,k),Txe(k),C=O;return}}function Qxe(s){return s=s|0,357913941}function Fxe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>357913941)Tt();else{d=Kt(l*12|0)|0;break}else d=0;while(!1);n[s>>2]=d,f=d+(c*12|0)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l*12|0)}function Rxe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(((d|0)/-12|0)*12|0)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function Txe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~(((f+-12-l|0)>>>0)/12|0)*12|0)),s=n[s>>2]|0,s|0&>(s)}function RG(s){s=s|0,Mxe(s)}function Nxe(s){s=s|0,Lxe(s+24|0)}function Lxe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~(((l+-12-f|0)>>>0)/12|0)*12|0)),gt(c))}function Mxe(s){s=s|0;var l=0;l=Vr()|0,zr(s,2,8,l,Oxe()|0,0),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function Oxe(){return 1288}function Uxe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0;return c=C,C=C+16|0,f=c+8|0,d=c,m=_xe(s)|0,s=n[m+4>>2]|0,n[d>>2]=n[m>>2],n[d+4>>2]=s,n[f>>2]=n[d>>2],n[f+4>>2]=n[d+4>>2],l=Hxe(l,f)|0,C=c,l|0}function _xe(s){return s=s|0,(n[(OF()|0)+24>>2]|0)+(s*12|0)|0}function Hxe(s,l){s=s|0,l=l|0;var c=0;return c=n[l>>2]|0,l=n[l+4>>2]|0,s=s+(l>>1)|0,l&1&&(c=n[(n[s>>2]|0)+c>>2]|0),V5(F0[c&31](s)|0)|0}function qxe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+16|0,d=f+8|0,m=f,k=n[c>>2]|0,B=n[c+4>>2]|0,c=pn(l)|0,n[m>>2]=k,n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],jxe(s,c,d,0),C=f}function jxe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0,Q=0,O=0,M=0;d=C,C=C+32|0,m=d+16|0,M=d+8|0,k=d,O=n[c>>2]|0,Q=n[c+4>>2]|0,B=n[s>>2]|0,s=UF()|0,n[M>>2]=O,n[M+4>>2]=Q,n[m>>2]=n[M>>2],n[m+4>>2]=n[M+4>>2],c=Gxe(m)|0,n[k>>2]=O,n[k+4>>2]=Q,n[m>>2]=n[k>>2],n[m+4>>2]=n[k+4>>2],hn(B,l,s,c,Yxe(m,f)|0,f),C=d}function UF(){var s=0,l=0;if(o[7760]|0||(NG(9756),ir(39,9756,U|0)|0,l=7760,n[l>>2]=1,n[l+4>>2]=0),!(Rr(9756)|0)){s=9756,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));NG(9756)}return 9756}function Gxe(s){return s=s|0,0}function Yxe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0;return M=C,C=C+32|0,d=M+24|0,B=M+16|0,k=M,Q=M+8|0,m=n[s>>2]|0,f=n[s+4>>2]|0,n[k>>2]=m,n[k+4>>2]=f,j=UF()|0,O=j+24|0,s=gr(l,4)|0,n[Q>>2]=s,l=j+28|0,c=n[l>>2]|0,c>>>0<(n[j+32>>2]|0)>>>0?(n[B>>2]=m,n[B+4>>2]=f,n[d>>2]=n[B>>2],n[d+4>>2]=n[B+4>>2],TG(c,d,s),s=(n[l>>2]|0)+12|0,n[l>>2]=s):(Wxe(O,k,Q),s=n[l>>2]|0),C=M,((s-(n[O>>2]|0)|0)/12|0)+-1|0}function TG(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=n[l+4>>2]|0,n[s>>2]=n[l>>2],n[s+4>>2]=f,n[s+8>>2]=c}function Wxe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0,se=0;if(O=C,C=C+48|0,f=O+32|0,B=O+24|0,k=O,Q=s+4|0,d=(((n[Q>>2]|0)-(n[s>>2]|0)|0)/12|0)+1|0,m=Kxe(s)|0,m>>>0>>0)Jr(s);else{M=n[s>>2]|0,se=((n[s+8>>2]|0)-M|0)/12|0,j=se<<1,Vxe(k,se>>>0>>1>>>0?j>>>0>>0?d:j:m,((n[Q>>2]|0)-M|0)/12|0,s+8|0),Q=k+8|0,m=n[Q>>2]|0,d=n[l+4>>2]|0,c=n[c>>2]|0,n[B>>2]=n[l>>2],n[B+4>>2]=d,n[f>>2]=n[B>>2],n[f+4>>2]=n[B+4>>2],TG(m,f,c),n[Q>>2]=(n[Q>>2]|0)+12,zxe(s,k),Jxe(k),C=O;return}}function Kxe(s){return s=s|0,357913941}function Vxe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>357913941)Tt();else{d=Kt(l*12|0)|0;break}else d=0;while(!1);n[s>>2]=d,f=d+(c*12|0)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l*12|0)}function zxe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(((d|0)/-12|0)*12|0)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function Jxe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~(((f+-12-l|0)>>>0)/12|0)*12|0)),s=n[s>>2]|0,s|0&>(s)}function NG(s){s=s|0,$xe(s)}function Xxe(s){s=s|0,Zxe(s+24|0)}function Zxe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~(((l+-12-f|0)>>>0)/12|0)*12|0)),gt(c))}function $xe(s){s=s|0;var l=0;l=Vr()|0,zr(s,2,8,l,eke()|0,1),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function eke(){return 1292}function tke(s,l,c){s=s|0,l=l|0,c=+c;var f=0,d=0,m=0,B=0;f=C,C=C+16|0,d=f+8|0,m=f,B=rke(s)|0,s=n[B+4>>2]|0,n[m>>2]=n[B>>2],n[m+4>>2]=s,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],nke(l,d,c),C=f}function rke(s){return s=s|0,(n[(UF()|0)+24>>2]|0)+(s*12|0)|0}function nke(s,l,c){s=s|0,l=l|0,c=+c;var f=0,d=0,m=0;m=C,C=C+16|0,d=m,f=n[l>>2]|0,l=n[l+4>>2]|0,s=s+(l>>1)|0,l&1&&(f=n[(n[s>>2]|0)+f>>2]|0),Fu(d,c),c=+Ru(d,c),d7[f&31](s,c),C=m}function ike(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+16|0,d=f+8|0,m=f,k=n[c>>2]|0,B=n[c+4>>2]|0,c=pn(l)|0,n[m>>2]=k,n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],ske(s,c,d,0),C=f}function ske(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0,Q=0,O=0,M=0;d=C,C=C+32|0,m=d+16|0,M=d+8|0,k=d,O=n[c>>2]|0,Q=n[c+4>>2]|0,B=n[s>>2]|0,s=_F()|0,n[M>>2]=O,n[M+4>>2]=Q,n[m>>2]=n[M>>2],n[m+4>>2]=n[M+4>>2],c=oke(m)|0,n[k>>2]=O,n[k+4>>2]=Q,n[m>>2]=n[k>>2],n[m+4>>2]=n[k+4>>2],hn(B,l,s,c,ake(m,f)|0,f),C=d}function _F(){var s=0,l=0;if(o[7768]|0||(MG(9792),ir(40,9792,U|0)|0,l=7768,n[l>>2]=1,n[l+4>>2]=0),!(Rr(9792)|0)){s=9792,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));MG(9792)}return 9792}function oke(s){return s=s|0,0}function ake(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0;return M=C,C=C+32|0,d=M+24|0,B=M+16|0,k=M,Q=M+8|0,m=n[s>>2]|0,f=n[s+4>>2]|0,n[k>>2]=m,n[k+4>>2]=f,j=_F()|0,O=j+24|0,s=gr(l,4)|0,n[Q>>2]=s,l=j+28|0,c=n[l>>2]|0,c>>>0<(n[j+32>>2]|0)>>>0?(n[B>>2]=m,n[B+4>>2]=f,n[d>>2]=n[B>>2],n[d+4>>2]=n[B+4>>2],LG(c,d,s),s=(n[l>>2]|0)+12|0,n[l>>2]=s):(lke(O,k,Q),s=n[l>>2]|0),C=M,((s-(n[O>>2]|0)|0)/12|0)+-1|0}function LG(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=n[l+4>>2]|0,n[s>>2]=n[l>>2],n[s+4>>2]=f,n[s+8>>2]=c}function lke(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0,se=0;if(O=C,C=C+48|0,f=O+32|0,B=O+24|0,k=O,Q=s+4|0,d=(((n[Q>>2]|0)-(n[s>>2]|0)|0)/12|0)+1|0,m=cke(s)|0,m>>>0>>0)Jr(s);else{M=n[s>>2]|0,se=((n[s+8>>2]|0)-M|0)/12|0,j=se<<1,uke(k,se>>>0>>1>>>0?j>>>0>>0?d:j:m,((n[Q>>2]|0)-M|0)/12|0,s+8|0),Q=k+8|0,m=n[Q>>2]|0,d=n[l+4>>2]|0,c=n[c>>2]|0,n[B>>2]=n[l>>2],n[B+4>>2]=d,n[f>>2]=n[B>>2],n[f+4>>2]=n[B+4>>2],LG(m,f,c),n[Q>>2]=(n[Q>>2]|0)+12,Ake(s,k),fke(k),C=O;return}}function cke(s){return s=s|0,357913941}function uke(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>357913941)Tt();else{d=Kt(l*12|0)|0;break}else d=0;while(!1);n[s>>2]=d,f=d+(c*12|0)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l*12|0)}function Ake(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(((d|0)/-12|0)*12|0)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function fke(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~(((f+-12-l|0)>>>0)/12|0)*12|0)),s=n[s>>2]|0,s|0&>(s)}function MG(s){s=s|0,gke(s)}function pke(s){s=s|0,hke(s+24|0)}function hke(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~(((l+-12-f|0)>>>0)/12|0)*12|0)),gt(c))}function gke(s){s=s|0;var l=0;l=Vr()|0,zr(s,2,1,l,dke()|0,2),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function dke(){return 1300}function mke(s,l,c,f){s=s|0,l=l|0,c=c|0,f=+f;var d=0,m=0,B=0,k=0;d=C,C=C+16|0,m=d+8|0,B=d,k=yke(s)|0,s=n[k+4>>2]|0,n[B>>2]=n[k>>2],n[B+4>>2]=s,n[m>>2]=n[B>>2],n[m+4>>2]=n[B+4>>2],Eke(l,m,c,f),C=d}function yke(s){return s=s|0,(n[(_F()|0)+24>>2]|0)+(s*12|0)|0}function Eke(s,l,c,f){s=s|0,l=l|0,c=c|0,f=+f;var d=0,m=0,B=0,k=0;k=C,C=C+16|0,m=k+1|0,B=k,d=n[l>>2]|0,l=n[l+4>>2]|0,s=s+(l>>1)|0,l&1&&(d=n[(n[s>>2]|0)+d>>2]|0),XA(m,c),m=ZA(m,c)|0,Fu(B,f),f=+Ru(B,f),v7[d&15](s,m,f),C=k}function Cke(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+16|0,d=f+8|0,m=f,k=n[c>>2]|0,B=n[c+4>>2]|0,c=pn(l)|0,n[m>>2]=k,n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],wke(s,c,d,0),C=f}function wke(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0,Q=0,O=0,M=0;d=C,C=C+32|0,m=d+16|0,M=d+8|0,k=d,O=n[c>>2]|0,Q=n[c+4>>2]|0,B=n[s>>2]|0,s=HF()|0,n[M>>2]=O,n[M+4>>2]=Q,n[m>>2]=n[M>>2],n[m+4>>2]=n[M+4>>2],c=Ike(m)|0,n[k>>2]=O,n[k+4>>2]=Q,n[m>>2]=n[k>>2],n[m+4>>2]=n[k+4>>2],hn(B,l,s,c,Bke(m,f)|0,f),C=d}function HF(){var s=0,l=0;if(o[7776]|0||(UG(9828),ir(41,9828,U|0)|0,l=7776,n[l>>2]=1,n[l+4>>2]=0),!(Rr(9828)|0)){s=9828,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));UG(9828)}return 9828}function Ike(s){return s=s|0,0}function Bke(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0;return M=C,C=C+32|0,d=M+24|0,B=M+16|0,k=M,Q=M+8|0,m=n[s>>2]|0,f=n[s+4>>2]|0,n[k>>2]=m,n[k+4>>2]=f,j=HF()|0,O=j+24|0,s=gr(l,4)|0,n[Q>>2]=s,l=j+28|0,c=n[l>>2]|0,c>>>0<(n[j+32>>2]|0)>>>0?(n[B>>2]=m,n[B+4>>2]=f,n[d>>2]=n[B>>2],n[d+4>>2]=n[B+4>>2],OG(c,d,s),s=(n[l>>2]|0)+12|0,n[l>>2]=s):(vke(O,k,Q),s=n[l>>2]|0),C=M,((s-(n[O>>2]|0)|0)/12|0)+-1|0}function OG(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=n[l+4>>2]|0,n[s>>2]=n[l>>2],n[s+4>>2]=f,n[s+8>>2]=c}function vke(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0,se=0;if(O=C,C=C+48|0,f=O+32|0,B=O+24|0,k=O,Q=s+4|0,d=(((n[Q>>2]|0)-(n[s>>2]|0)|0)/12|0)+1|0,m=Dke(s)|0,m>>>0>>0)Jr(s);else{M=n[s>>2]|0,se=((n[s+8>>2]|0)-M|0)/12|0,j=se<<1,Pke(k,se>>>0>>1>>>0?j>>>0>>0?d:j:m,((n[Q>>2]|0)-M|0)/12|0,s+8|0),Q=k+8|0,m=n[Q>>2]|0,d=n[l+4>>2]|0,c=n[c>>2]|0,n[B>>2]=n[l>>2],n[B+4>>2]=d,n[f>>2]=n[B>>2],n[f+4>>2]=n[B+4>>2],OG(m,f,c),n[Q>>2]=(n[Q>>2]|0)+12,bke(s,k),Ske(k),C=O;return}}function Dke(s){return s=s|0,357913941}function Pke(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>357913941)Tt();else{d=Kt(l*12|0)|0;break}else d=0;while(!1);n[s>>2]=d,f=d+(c*12|0)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l*12|0)}function bke(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(((d|0)/-12|0)*12|0)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function Ske(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~(((f+-12-l|0)>>>0)/12|0)*12|0)),s=n[s>>2]|0,s|0&>(s)}function UG(s){s=s|0,Qke(s)}function xke(s){s=s|0,kke(s+24|0)}function kke(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~(((l+-12-f|0)>>>0)/12|0)*12|0)),gt(c))}function Qke(s){s=s|0;var l=0;l=Vr()|0,zr(s,2,7,l,Fke()|0,1),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function Fke(){return 1312}function Rke(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;f=C,C=C+16|0,d=f+8|0,m=f,B=Tke(s)|0,s=n[B+4>>2]|0,n[m>>2]=n[B>>2],n[m+4>>2]=s,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],Nke(l,d,c),C=f}function Tke(s){return s=s|0,(n[(HF()|0)+24>>2]|0)+(s*12|0)|0}function Nke(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0;m=C,C=C+16|0,d=m,f=n[l>>2]|0,l=n[l+4>>2]|0,s=s+(l>>1)|0,l&1&&(f=n[(n[s>>2]|0)+f>>2]|0),XA(d,c),d=ZA(d,c)|0,tf[f&31](s,d),C=m}function Lke(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+16|0,d=f+8|0,m=f,k=n[c>>2]|0,B=n[c+4>>2]|0,c=pn(l)|0,n[m>>2]=k,n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],Mke(s,c,d,0),C=f}function Mke(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0,Q=0,O=0,M=0;d=C,C=C+32|0,m=d+16|0,M=d+8|0,k=d,O=n[c>>2]|0,Q=n[c+4>>2]|0,B=n[s>>2]|0,s=qF()|0,n[M>>2]=O,n[M+4>>2]=Q,n[m>>2]=n[M>>2],n[m+4>>2]=n[M+4>>2],c=Oke(m)|0,n[k>>2]=O,n[k+4>>2]=Q,n[m>>2]=n[k>>2],n[m+4>>2]=n[k+4>>2],hn(B,l,s,c,Uke(m,f)|0,f),C=d}function qF(){var s=0,l=0;if(o[7784]|0||(HG(9864),ir(42,9864,U|0)|0,l=7784,n[l>>2]=1,n[l+4>>2]=0),!(Rr(9864)|0)){s=9864,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));HG(9864)}return 9864}function Oke(s){return s=s|0,0}function Uke(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0;return M=C,C=C+32|0,d=M+24|0,B=M+16|0,k=M,Q=M+8|0,m=n[s>>2]|0,f=n[s+4>>2]|0,n[k>>2]=m,n[k+4>>2]=f,j=qF()|0,O=j+24|0,s=gr(l,4)|0,n[Q>>2]=s,l=j+28|0,c=n[l>>2]|0,c>>>0<(n[j+32>>2]|0)>>>0?(n[B>>2]=m,n[B+4>>2]=f,n[d>>2]=n[B>>2],n[d+4>>2]=n[B+4>>2],_G(c,d,s),s=(n[l>>2]|0)+12|0,n[l>>2]=s):(_ke(O,k,Q),s=n[l>>2]|0),C=M,((s-(n[O>>2]|0)|0)/12|0)+-1|0}function _G(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=n[l+4>>2]|0,n[s>>2]=n[l>>2],n[s+4>>2]=f,n[s+8>>2]=c}function _ke(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0,se=0;if(O=C,C=C+48|0,f=O+32|0,B=O+24|0,k=O,Q=s+4|0,d=(((n[Q>>2]|0)-(n[s>>2]|0)|0)/12|0)+1|0,m=Hke(s)|0,m>>>0>>0)Jr(s);else{M=n[s>>2]|0,se=((n[s+8>>2]|0)-M|0)/12|0,j=se<<1,qke(k,se>>>0>>1>>>0?j>>>0>>0?d:j:m,((n[Q>>2]|0)-M|0)/12|0,s+8|0),Q=k+8|0,m=n[Q>>2]|0,d=n[l+4>>2]|0,c=n[c>>2]|0,n[B>>2]=n[l>>2],n[B+4>>2]=d,n[f>>2]=n[B>>2],n[f+4>>2]=n[B+4>>2],_G(m,f,c),n[Q>>2]=(n[Q>>2]|0)+12,jke(s,k),Gke(k),C=O;return}}function Hke(s){return s=s|0,357913941}function qke(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>357913941)Tt();else{d=Kt(l*12|0)|0;break}else d=0;while(!1);n[s>>2]=d,f=d+(c*12|0)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l*12|0)}function jke(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(((d|0)/-12|0)*12|0)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function Gke(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~(((f+-12-l|0)>>>0)/12|0)*12|0)),s=n[s>>2]|0,s|0&>(s)}function HG(s){s=s|0,Kke(s)}function Yke(s){s=s|0,Wke(s+24|0)}function Wke(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~(((l+-12-f|0)>>>0)/12|0)*12|0)),gt(c))}function Kke(s){s=s|0;var l=0;l=Vr()|0,zr(s,2,8,l,Vke()|0,1),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function Vke(){return 1320}function zke(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;f=C,C=C+16|0,d=f+8|0,m=f,B=Jke(s)|0,s=n[B+4>>2]|0,n[m>>2]=n[B>>2],n[m+4>>2]=s,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],Xke(l,d,c),C=f}function Jke(s){return s=s|0,(n[(qF()|0)+24>>2]|0)+(s*12|0)|0}function Xke(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0;m=C,C=C+16|0,d=m,f=n[l>>2]|0,l=n[l+4>>2]|0,s=s+(l>>1)|0,l&1&&(f=n[(n[s>>2]|0)+f>>2]|0),Zke(d,c),d=$ke(d,c)|0,tf[f&31](s,d),C=m}function Zke(s,l){s=s|0,l=l|0}function $ke(s,l){return s=s|0,l=l|0,eQe(l)|0}function eQe(s){return s=s|0,s|0}function tQe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+16|0,d=f+8|0,m=f,k=n[c>>2]|0,B=n[c+4>>2]|0,c=pn(l)|0,n[m>>2]=k,n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],rQe(s,c,d,0),C=f}function rQe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0,Q=0,O=0,M=0;d=C,C=C+32|0,m=d+16|0,M=d+8|0,k=d,O=n[c>>2]|0,Q=n[c+4>>2]|0,B=n[s>>2]|0,s=jF()|0,n[M>>2]=O,n[M+4>>2]=Q,n[m>>2]=n[M>>2],n[m+4>>2]=n[M+4>>2],c=nQe(m)|0,n[k>>2]=O,n[k+4>>2]=Q,n[m>>2]=n[k>>2],n[m+4>>2]=n[k+4>>2],hn(B,l,s,c,iQe(m,f)|0,f),C=d}function jF(){var s=0,l=0;if(o[7792]|0||(jG(9900),ir(43,9900,U|0)|0,l=7792,n[l>>2]=1,n[l+4>>2]=0),!(Rr(9900)|0)){s=9900,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));jG(9900)}return 9900}function nQe(s){return s=s|0,0}function iQe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0;return M=C,C=C+32|0,d=M+24|0,B=M+16|0,k=M,Q=M+8|0,m=n[s>>2]|0,f=n[s+4>>2]|0,n[k>>2]=m,n[k+4>>2]=f,j=jF()|0,O=j+24|0,s=gr(l,4)|0,n[Q>>2]=s,l=j+28|0,c=n[l>>2]|0,c>>>0<(n[j+32>>2]|0)>>>0?(n[B>>2]=m,n[B+4>>2]=f,n[d>>2]=n[B>>2],n[d+4>>2]=n[B+4>>2],qG(c,d,s),s=(n[l>>2]|0)+12|0,n[l>>2]=s):(sQe(O,k,Q),s=n[l>>2]|0),C=M,((s-(n[O>>2]|0)|0)/12|0)+-1|0}function qG(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=n[l+4>>2]|0,n[s>>2]=n[l>>2],n[s+4>>2]=f,n[s+8>>2]=c}function sQe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0,se=0;if(O=C,C=C+48|0,f=O+32|0,B=O+24|0,k=O,Q=s+4|0,d=(((n[Q>>2]|0)-(n[s>>2]|0)|0)/12|0)+1|0,m=oQe(s)|0,m>>>0>>0)Jr(s);else{M=n[s>>2]|0,se=((n[s+8>>2]|0)-M|0)/12|0,j=se<<1,aQe(k,se>>>0>>1>>>0?j>>>0>>0?d:j:m,((n[Q>>2]|0)-M|0)/12|0,s+8|0),Q=k+8|0,m=n[Q>>2]|0,d=n[l+4>>2]|0,c=n[c>>2]|0,n[B>>2]=n[l>>2],n[B+4>>2]=d,n[f>>2]=n[B>>2],n[f+4>>2]=n[B+4>>2],qG(m,f,c),n[Q>>2]=(n[Q>>2]|0)+12,lQe(s,k),cQe(k),C=O;return}}function oQe(s){return s=s|0,357913941}function aQe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>357913941)Tt();else{d=Kt(l*12|0)|0;break}else d=0;while(!1);n[s>>2]=d,f=d+(c*12|0)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l*12|0)}function lQe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(((d|0)/-12|0)*12|0)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function cQe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~(((f+-12-l|0)>>>0)/12|0)*12|0)),s=n[s>>2]|0,s|0&>(s)}function jG(s){s=s|0,fQe(s)}function uQe(s){s=s|0,AQe(s+24|0)}function AQe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~(((l+-12-f|0)>>>0)/12|0)*12|0)),gt(c))}function fQe(s){s=s|0;var l=0;l=Vr()|0,zr(s,2,22,l,pQe()|0,0),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function pQe(){return 1344}function hQe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0;c=C,C=C+16|0,f=c+8|0,d=c,m=gQe(s)|0,s=n[m+4>>2]|0,n[d>>2]=n[m>>2],n[d+4>>2]=s,n[f>>2]=n[d>>2],n[f+4>>2]=n[d+4>>2],dQe(l,f),C=c}function gQe(s){return s=s|0,(n[(jF()|0)+24>>2]|0)+(s*12|0)|0}function dQe(s,l){s=s|0,l=l|0;var c=0;c=n[l>>2]|0,l=n[l+4>>2]|0,s=s+(l>>1)|0,l&1&&(c=n[(n[s>>2]|0)+c>>2]|0),ef[c&127](s)}function mQe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0;m=n[s>>2]|0,d=GF()|0,s=yQe(c)|0,hn(m,l,d,s,EQe(c,f)|0,f)}function GF(){var s=0,l=0;if(o[7800]|0||(YG(9936),ir(44,9936,U|0)|0,l=7800,n[l>>2]=1,n[l+4>>2]=0),!(Rr(9936)|0)){s=9936,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));YG(9936)}return 9936}function yQe(s){return s=s|0,s|0}function EQe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0;return k=C,C=C+16|0,d=k,m=k+4|0,n[d>>2]=s,Q=GF()|0,B=Q+24|0,l=gr(l,4)|0,n[m>>2]=l,c=Q+28|0,f=n[c>>2]|0,f>>>0<(n[Q+32>>2]|0)>>>0?(GG(f,s,l),l=(n[c>>2]|0)+8|0,n[c>>2]=l):(CQe(B,d,m),l=n[c>>2]|0),C=k,(l-(n[B>>2]|0)>>3)+-1|0}function GG(s,l,c){s=s|0,l=l|0,c=c|0,n[s>>2]=l,n[s+4>>2]=c}function CQe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0;if(k=C,C=C+32|0,d=k,m=s+4|0,B=((n[m>>2]|0)-(n[s>>2]|0)>>3)+1|0,f=wQe(s)|0,f>>>0>>0)Jr(s);else{Q=n[s>>2]|0,M=(n[s+8>>2]|0)-Q|0,O=M>>2,IQe(d,M>>3>>>0>>1>>>0?O>>>0>>0?B:O:f,(n[m>>2]|0)-Q>>3,s+8|0),B=d+8|0,GG(n[B>>2]|0,n[l>>2]|0,n[c>>2]|0),n[B>>2]=(n[B>>2]|0)+8,BQe(s,d),vQe(d),C=k;return}}function wQe(s){return s=s|0,536870911}function IQe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>536870911)Tt();else{d=Kt(l<<3)|0;break}else d=0;while(!1);n[s>>2]=d,f=d+(c<<3)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l<<3)}function BQe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(0-(d>>3)<<3)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function vQe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~((f+-8-l|0)>>>3)<<3)),s=n[s>>2]|0,s|0&>(s)}function YG(s){s=s|0,bQe(s)}function DQe(s){s=s|0,PQe(s+24|0)}function PQe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~((l+-8-f|0)>>>3)<<3)),gt(c))}function bQe(s){s=s|0;var l=0;l=Vr()|0,zr(s,1,23,l,EG()|0,1),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function SQe(s,l){s=s|0,l=l|0,kQe(n[(xQe(s)|0)>>2]|0,l)}function xQe(s){return s=s|0,(n[(GF()|0)+24>>2]|0)+(s<<3)|0}function kQe(s,l){s=s|0,l=l|0;var c=0,f=0;c=C,C=C+16|0,f=c,kF(f,l),l=QF(f,l)|0,ef[s&127](l),C=c}function QQe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0;m=n[s>>2]|0,d=YF()|0,s=FQe(c)|0,hn(m,l,d,s,RQe(c,f)|0,f)}function YF(){var s=0,l=0;if(o[7808]|0||(KG(9972),ir(45,9972,U|0)|0,l=7808,n[l>>2]=1,n[l+4>>2]=0),!(Rr(9972)|0)){s=9972,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));KG(9972)}return 9972}function FQe(s){return s=s|0,s|0}function RQe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0;return k=C,C=C+16|0,d=k,m=k+4|0,n[d>>2]=s,Q=YF()|0,B=Q+24|0,l=gr(l,4)|0,n[m>>2]=l,c=Q+28|0,f=n[c>>2]|0,f>>>0<(n[Q+32>>2]|0)>>>0?(WG(f,s,l),l=(n[c>>2]|0)+8|0,n[c>>2]=l):(TQe(B,d,m),l=n[c>>2]|0),C=k,(l-(n[B>>2]|0)>>3)+-1|0}function WG(s,l,c){s=s|0,l=l|0,c=c|0,n[s>>2]=l,n[s+4>>2]=c}function TQe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0;if(k=C,C=C+32|0,d=k,m=s+4|0,B=((n[m>>2]|0)-(n[s>>2]|0)>>3)+1|0,f=NQe(s)|0,f>>>0>>0)Jr(s);else{Q=n[s>>2]|0,M=(n[s+8>>2]|0)-Q|0,O=M>>2,LQe(d,M>>3>>>0>>1>>>0?O>>>0>>0?B:O:f,(n[m>>2]|0)-Q>>3,s+8|0),B=d+8|0,WG(n[B>>2]|0,n[l>>2]|0,n[c>>2]|0),n[B>>2]=(n[B>>2]|0)+8,MQe(s,d),OQe(d),C=k;return}}function NQe(s){return s=s|0,536870911}function LQe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>536870911)Tt();else{d=Kt(l<<3)|0;break}else d=0;while(!1);n[s>>2]=d,f=d+(c<<3)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l<<3)}function MQe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(0-(d>>3)<<3)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function OQe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~((f+-8-l|0)>>>3)<<3)),s=n[s>>2]|0,s|0&>(s)}function KG(s){s=s|0,HQe(s)}function UQe(s){s=s|0,_Qe(s+24|0)}function _Qe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~((l+-8-f|0)>>>3)<<3)),gt(c))}function HQe(s){s=s|0;var l=0;l=Vr()|0,zr(s,1,9,l,qQe()|0,1),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function qQe(){return 1348}function jQe(s,l){return s=s|0,l=l|0,YQe(n[(GQe(s)|0)>>2]|0,l)|0}function GQe(s){return s=s|0,(n[(YF()|0)+24>>2]|0)+(s<<3)|0}function YQe(s,l){s=s|0,l=l|0;var c=0,f=0;return c=C,C=C+16|0,f=c,VG(f,l),l=zG(f,l)|0,l=qv(F0[s&31](l)|0)|0,C=c,l|0}function VG(s,l){s=s|0,l=l|0}function zG(s,l){return s=s|0,l=l|0,WQe(l)|0}function WQe(s){return s=s|0,s|0}function KQe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0;m=n[s>>2]|0,d=WF()|0,s=VQe(c)|0,hn(m,l,d,s,zQe(c,f)|0,f)}function WF(){var s=0,l=0;if(o[7816]|0||(XG(10008),ir(46,10008,U|0)|0,l=7816,n[l>>2]=1,n[l+4>>2]=0),!(Rr(10008)|0)){s=10008,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));XG(10008)}return 10008}function VQe(s){return s=s|0,s|0}function zQe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0;return k=C,C=C+16|0,d=k,m=k+4|0,n[d>>2]=s,Q=WF()|0,B=Q+24|0,l=gr(l,4)|0,n[m>>2]=l,c=Q+28|0,f=n[c>>2]|0,f>>>0<(n[Q+32>>2]|0)>>>0?(JG(f,s,l),l=(n[c>>2]|0)+8|0,n[c>>2]=l):(JQe(B,d,m),l=n[c>>2]|0),C=k,(l-(n[B>>2]|0)>>3)+-1|0}function JG(s,l,c){s=s|0,l=l|0,c=c|0,n[s>>2]=l,n[s+4>>2]=c}function JQe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0;if(k=C,C=C+32|0,d=k,m=s+4|0,B=((n[m>>2]|0)-(n[s>>2]|0)>>3)+1|0,f=XQe(s)|0,f>>>0>>0)Jr(s);else{Q=n[s>>2]|0,M=(n[s+8>>2]|0)-Q|0,O=M>>2,ZQe(d,M>>3>>>0>>1>>>0?O>>>0>>0?B:O:f,(n[m>>2]|0)-Q>>3,s+8|0),B=d+8|0,JG(n[B>>2]|0,n[l>>2]|0,n[c>>2]|0),n[B>>2]=(n[B>>2]|0)+8,$Qe(s,d),eFe(d),C=k;return}}function XQe(s){return s=s|0,536870911}function ZQe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>536870911)Tt();else{d=Kt(l<<3)|0;break}else d=0;while(!1);n[s>>2]=d,f=d+(c<<3)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l<<3)}function $Qe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(0-(d>>3)<<3)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function eFe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~((f+-8-l|0)>>>3)<<3)),s=n[s>>2]|0,s|0&>(s)}function XG(s){s=s|0,nFe(s)}function tFe(s){s=s|0,rFe(s+24|0)}function rFe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~((l+-8-f|0)>>>3)<<3)),gt(c))}function nFe(s){s=s|0;var l=0;l=Vr()|0,zr(s,1,15,l,pG()|0,0),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function iFe(s){return s=s|0,oFe(n[(sFe(s)|0)>>2]|0)|0}function sFe(s){return s=s|0,(n[(WF()|0)+24>>2]|0)+(s<<3)|0}function oFe(s){return s=s|0,qv(nD[s&7]()|0)|0}function aFe(){var s=0;return o[7832]|0||(gFe(10052),ir(25,10052,U|0)|0,s=7832,n[s>>2]=1,n[s+4>>2]=0),10052}function lFe(s,l){s=s|0,l=l|0,n[s>>2]=cFe()|0,n[s+4>>2]=uFe()|0,n[s+12>>2]=l,n[s+8>>2]=AFe()|0,n[s+32>>2]=2}function cFe(){return 11709}function uFe(){return 1188}function AFe(){return Gv()|0}function fFe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0,(Dp(f,896)|0)==512?c|0&&(pFe(c),gt(c)):l|0&&(Su(l),gt(l))}function Dp(s,l){return s=s|0,l=l|0,l&s|0}function pFe(s){s=s|0,s=n[s+4>>2]|0,s|0&&bp(s)}function Gv(){var s=0;return o[7824]|0||(n[2511]=hFe()|0,n[2512]=0,s=7824,n[s>>2]=1,n[s+4>>2]=0),10044}function hFe(){return 0}function gFe(s){s=s|0,wp(s)}function dFe(s){s=s|0;var l=0,c=0,f=0,d=0,m=0;l=C,C=C+32|0,c=l+24|0,m=l+16|0,d=l+8|0,f=l,mFe(s,4827),yFe(s,4834,3)|0,EFe(s,3682,47)|0,n[m>>2]=9,n[m+4>>2]=0,n[c>>2]=n[m>>2],n[c+4>>2]=n[m+4>>2],CFe(s,4841,c)|0,n[d>>2]=1,n[d+4>>2]=0,n[c>>2]=n[d>>2],n[c+4>>2]=n[d+4>>2],wFe(s,4871,c)|0,n[f>>2]=10,n[f+4>>2]=0,n[c>>2]=n[f>>2],n[c+4>>2]=n[f+4>>2],IFe(s,4891,c)|0,C=l}function mFe(s,l){s=s|0,l=l|0;var c=0;c=eTe()|0,n[s>>2]=c,tTe(c,l),Pp(n[s>>2]|0)}function yFe(s,l,c){return s=s|0,l=l|0,c=c|0,ORe(s,pn(l)|0,c,0),s|0}function EFe(s,l,c){return s=s|0,l=l|0,c=c|0,BRe(s,pn(l)|0,c,0),s|0}function CFe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=n[c+4>>2]|0,n[m>>2]=n[c>>2],n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],iRe(s,l,d),C=f,s|0}function wFe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=n[c+4>>2]|0,n[m>>2]=n[c>>2],n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],UFe(s,l,d),C=f,s|0}function IFe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=n[c+4>>2]|0,n[m>>2]=n[c>>2],n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],BFe(s,l,d),C=f,s|0}function BFe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+16|0,d=f+8|0,m=f,k=n[c>>2]|0,B=n[c+4>>2]|0,c=pn(l)|0,n[m>>2]=k,n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],vFe(s,c,d,1),C=f}function vFe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0,Q=0,O=0,M=0;d=C,C=C+32|0,m=d+16|0,M=d+8|0,k=d,O=n[c>>2]|0,Q=n[c+4>>2]|0,B=n[s>>2]|0,s=KF()|0,n[M>>2]=O,n[M+4>>2]=Q,n[m>>2]=n[M>>2],n[m+4>>2]=n[M+4>>2],c=DFe(m)|0,n[k>>2]=O,n[k+4>>2]=Q,n[m>>2]=n[k>>2],n[m+4>>2]=n[k+4>>2],hn(B,l,s,c,PFe(m,f)|0,f),C=d}function KF(){var s=0,l=0;if(o[7840]|0||($G(10100),ir(48,10100,U|0)|0,l=7840,n[l>>2]=1,n[l+4>>2]=0),!(Rr(10100)|0)){s=10100,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));$G(10100)}return 10100}function DFe(s){return s=s|0,0}function PFe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0;return M=C,C=C+32|0,d=M+24|0,B=M+16|0,k=M,Q=M+8|0,m=n[s>>2]|0,f=n[s+4>>2]|0,n[k>>2]=m,n[k+4>>2]=f,j=KF()|0,O=j+24|0,s=gr(l,4)|0,n[Q>>2]=s,l=j+28|0,c=n[l>>2]|0,c>>>0<(n[j+32>>2]|0)>>>0?(n[B>>2]=m,n[B+4>>2]=f,n[d>>2]=n[B>>2],n[d+4>>2]=n[B+4>>2],ZG(c,d,s),s=(n[l>>2]|0)+12|0,n[l>>2]=s):(bFe(O,k,Q),s=n[l>>2]|0),C=M,((s-(n[O>>2]|0)|0)/12|0)+-1|0}function ZG(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=n[l+4>>2]|0,n[s>>2]=n[l>>2],n[s+4>>2]=f,n[s+8>>2]=c}function bFe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0,se=0;if(O=C,C=C+48|0,f=O+32|0,B=O+24|0,k=O,Q=s+4|0,d=(((n[Q>>2]|0)-(n[s>>2]|0)|0)/12|0)+1|0,m=SFe(s)|0,m>>>0>>0)Jr(s);else{M=n[s>>2]|0,se=((n[s+8>>2]|0)-M|0)/12|0,j=se<<1,xFe(k,se>>>0>>1>>>0?j>>>0>>0?d:j:m,((n[Q>>2]|0)-M|0)/12|0,s+8|0),Q=k+8|0,m=n[Q>>2]|0,d=n[l+4>>2]|0,c=n[c>>2]|0,n[B>>2]=n[l>>2],n[B+4>>2]=d,n[f>>2]=n[B>>2],n[f+4>>2]=n[B+4>>2],ZG(m,f,c),n[Q>>2]=(n[Q>>2]|0)+12,kFe(s,k),QFe(k),C=O;return}}function SFe(s){return s=s|0,357913941}function xFe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>357913941)Tt();else{d=Kt(l*12|0)|0;break}else d=0;while(!1);n[s>>2]=d,f=d+(c*12|0)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l*12|0)}function kFe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(((d|0)/-12|0)*12|0)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function QFe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~(((f+-12-l|0)>>>0)/12|0)*12|0)),s=n[s>>2]|0,s|0&>(s)}function $G(s){s=s|0,TFe(s)}function FFe(s){s=s|0,RFe(s+24|0)}function RFe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~(((l+-12-f|0)>>>0)/12|0)*12|0)),gt(c))}function TFe(s){s=s|0;var l=0;l=Vr()|0,zr(s,2,6,l,NFe()|0,1),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function NFe(){return 1364}function LFe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=MFe(s)|0,s=n[B+4>>2]|0,n[m>>2]=n[B>>2],n[m+4>>2]=s,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],c=OFe(l,d,c)|0,C=f,c|0}function MFe(s){return s=s|0,(n[(KF()|0)+24>>2]|0)+(s*12|0)|0}function OFe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0;return m=C,C=C+16|0,d=m,f=n[l>>2]|0,l=n[l+4>>2]|0,s=s+(l>>1)|0,l&1&&(f=n[(n[s>>2]|0)+f>>2]|0),XA(d,c),d=ZA(d,c)|0,d=oG(IR[f&15](s,d)|0)|0,C=m,d|0}function UFe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+16|0,d=f+8|0,m=f,k=n[c>>2]|0,B=n[c+4>>2]|0,c=pn(l)|0,n[m>>2]=k,n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],_Fe(s,c,d,0),C=f}function _Fe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0,Q=0,O=0,M=0;d=C,C=C+32|0,m=d+16|0,M=d+8|0,k=d,O=n[c>>2]|0,Q=n[c+4>>2]|0,B=n[s>>2]|0,s=VF()|0,n[M>>2]=O,n[M+4>>2]=Q,n[m>>2]=n[M>>2],n[m+4>>2]=n[M+4>>2],c=HFe(m)|0,n[k>>2]=O,n[k+4>>2]=Q,n[m>>2]=n[k>>2],n[m+4>>2]=n[k+4>>2],hn(B,l,s,c,qFe(m,f)|0,f),C=d}function VF(){var s=0,l=0;if(o[7848]|0||(t9(10136),ir(49,10136,U|0)|0,l=7848,n[l>>2]=1,n[l+4>>2]=0),!(Rr(10136)|0)){s=10136,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));t9(10136)}return 10136}function HFe(s){return s=s|0,0}function qFe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0;return M=C,C=C+32|0,d=M+24|0,B=M+16|0,k=M,Q=M+8|0,m=n[s>>2]|0,f=n[s+4>>2]|0,n[k>>2]=m,n[k+4>>2]=f,j=VF()|0,O=j+24|0,s=gr(l,4)|0,n[Q>>2]=s,l=j+28|0,c=n[l>>2]|0,c>>>0<(n[j+32>>2]|0)>>>0?(n[B>>2]=m,n[B+4>>2]=f,n[d>>2]=n[B>>2],n[d+4>>2]=n[B+4>>2],e9(c,d,s),s=(n[l>>2]|0)+12|0,n[l>>2]=s):(jFe(O,k,Q),s=n[l>>2]|0),C=M,((s-(n[O>>2]|0)|0)/12|0)+-1|0}function e9(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=n[l+4>>2]|0,n[s>>2]=n[l>>2],n[s+4>>2]=f,n[s+8>>2]=c}function jFe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0,se=0;if(O=C,C=C+48|0,f=O+32|0,B=O+24|0,k=O,Q=s+4|0,d=(((n[Q>>2]|0)-(n[s>>2]|0)|0)/12|0)+1|0,m=GFe(s)|0,m>>>0>>0)Jr(s);else{M=n[s>>2]|0,se=((n[s+8>>2]|0)-M|0)/12|0,j=se<<1,YFe(k,se>>>0>>1>>>0?j>>>0>>0?d:j:m,((n[Q>>2]|0)-M|0)/12|0,s+8|0),Q=k+8|0,m=n[Q>>2]|0,d=n[l+4>>2]|0,c=n[c>>2]|0,n[B>>2]=n[l>>2],n[B+4>>2]=d,n[f>>2]=n[B>>2],n[f+4>>2]=n[B+4>>2],e9(m,f,c),n[Q>>2]=(n[Q>>2]|0)+12,WFe(s,k),KFe(k),C=O;return}}function GFe(s){return s=s|0,357913941}function YFe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>357913941)Tt();else{d=Kt(l*12|0)|0;break}else d=0;while(!1);n[s>>2]=d,f=d+(c*12|0)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l*12|0)}function WFe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(((d|0)/-12|0)*12|0)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function KFe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~(((f+-12-l|0)>>>0)/12|0)*12|0)),s=n[s>>2]|0,s|0&>(s)}function t9(s){s=s|0,JFe(s)}function VFe(s){s=s|0,zFe(s+24|0)}function zFe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~(((l+-12-f|0)>>>0)/12|0)*12|0)),gt(c))}function JFe(s){s=s|0;var l=0;l=Vr()|0,zr(s,2,9,l,XFe()|0,1),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function XFe(){return 1372}function ZFe(s,l,c){s=s|0,l=l|0,c=+c;var f=0,d=0,m=0,B=0;f=C,C=C+16|0,d=f+8|0,m=f,B=$Fe(s)|0,s=n[B+4>>2]|0,n[m>>2]=n[B>>2],n[m+4>>2]=s,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],eRe(l,d,c),C=f}function $Fe(s){return s=s|0,(n[(VF()|0)+24>>2]|0)+(s*12|0)|0}function eRe(s,l,c){s=s|0,l=l|0,c=+c;var f=0,d=0,m=0,B=Xe;m=C,C=C+16|0,d=m,f=n[l>>2]|0,l=n[l+4>>2]|0,s=s+(l>>1)|0,l&1&&(f=n[(n[s>>2]|0)+f>>2]|0),tRe(d,c),B=y(rRe(d,c)),g7[f&1](s,B),C=m}function tRe(s,l){s=s|0,l=+l}function rRe(s,l){return s=s|0,l=+l,y(nRe(l))}function nRe(s){return s=+s,y(s)}function iRe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+16|0,d=f+8|0,m=f,k=n[c>>2]|0,B=n[c+4>>2]|0,c=pn(l)|0,n[m>>2]=k,n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],sRe(s,c,d,0),C=f}function sRe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0,Q=0,O=0,M=0;d=C,C=C+32|0,m=d+16|0,M=d+8|0,k=d,O=n[c>>2]|0,Q=n[c+4>>2]|0,B=n[s>>2]|0,s=zF()|0,n[M>>2]=O,n[M+4>>2]=Q,n[m>>2]=n[M>>2],n[m+4>>2]=n[M+4>>2],c=oRe(m)|0,n[k>>2]=O,n[k+4>>2]=Q,n[m>>2]=n[k>>2],n[m+4>>2]=n[k+4>>2],hn(B,l,s,c,aRe(m,f)|0,f),C=d}function zF(){var s=0,l=0;if(o[7856]|0||(n9(10172),ir(50,10172,U|0)|0,l=7856,n[l>>2]=1,n[l+4>>2]=0),!(Rr(10172)|0)){s=10172,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));n9(10172)}return 10172}function oRe(s){return s=s|0,0}function aRe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0;return M=C,C=C+32|0,d=M+24|0,B=M+16|0,k=M,Q=M+8|0,m=n[s>>2]|0,f=n[s+4>>2]|0,n[k>>2]=m,n[k+4>>2]=f,j=zF()|0,O=j+24|0,s=gr(l,4)|0,n[Q>>2]=s,l=j+28|0,c=n[l>>2]|0,c>>>0<(n[j+32>>2]|0)>>>0?(n[B>>2]=m,n[B+4>>2]=f,n[d>>2]=n[B>>2],n[d+4>>2]=n[B+4>>2],r9(c,d,s),s=(n[l>>2]|0)+12|0,n[l>>2]=s):(lRe(O,k,Q),s=n[l>>2]|0),C=M,((s-(n[O>>2]|0)|0)/12|0)+-1|0}function r9(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=n[l+4>>2]|0,n[s>>2]=n[l>>2],n[s+4>>2]=f,n[s+8>>2]=c}function lRe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0,se=0;if(O=C,C=C+48|0,f=O+32|0,B=O+24|0,k=O,Q=s+4|0,d=(((n[Q>>2]|0)-(n[s>>2]|0)|0)/12|0)+1|0,m=cRe(s)|0,m>>>0>>0)Jr(s);else{M=n[s>>2]|0,se=((n[s+8>>2]|0)-M|0)/12|0,j=se<<1,uRe(k,se>>>0>>1>>>0?j>>>0>>0?d:j:m,((n[Q>>2]|0)-M|0)/12|0,s+8|0),Q=k+8|0,m=n[Q>>2]|0,d=n[l+4>>2]|0,c=n[c>>2]|0,n[B>>2]=n[l>>2],n[B+4>>2]=d,n[f>>2]=n[B>>2],n[f+4>>2]=n[B+4>>2],r9(m,f,c),n[Q>>2]=(n[Q>>2]|0)+12,ARe(s,k),fRe(k),C=O;return}}function cRe(s){return s=s|0,357913941}function uRe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>357913941)Tt();else{d=Kt(l*12|0)|0;break}else d=0;while(!1);n[s>>2]=d,f=d+(c*12|0)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l*12|0)}function ARe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(((d|0)/-12|0)*12|0)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function fRe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~(((f+-12-l|0)>>>0)/12|0)*12|0)),s=n[s>>2]|0,s|0&>(s)}function n9(s){s=s|0,gRe(s)}function pRe(s){s=s|0,hRe(s+24|0)}function hRe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~(((l+-12-f|0)>>>0)/12|0)*12|0)),gt(c))}function gRe(s){s=s|0;var l=0;l=Vr()|0,zr(s,2,3,l,dRe()|0,2),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function dRe(){return 1380}function mRe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0;d=C,C=C+16|0,m=d+8|0,B=d,k=yRe(s)|0,s=n[k+4>>2]|0,n[B>>2]=n[k>>2],n[B+4>>2]=s,n[m>>2]=n[B>>2],n[m+4>>2]=n[B+4>>2],ERe(l,m,c,f),C=d}function yRe(s){return s=s|0,(n[(zF()|0)+24>>2]|0)+(s*12|0)|0}function ERe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0;k=C,C=C+16|0,m=k+1|0,B=k,d=n[l>>2]|0,l=n[l+4>>2]|0,s=s+(l>>1)|0,l&1&&(d=n[(n[s>>2]|0)+d>>2]|0),XA(m,c),m=ZA(m,c)|0,CRe(B,f),B=wRe(B,f)|0,vw[d&15](s,m,B),C=k}function CRe(s,l){s=s|0,l=l|0}function wRe(s,l){return s=s|0,l=l|0,IRe(l)|0}function IRe(s){return s=s|0,(s|0)!=0|0}function BRe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0;m=n[s>>2]|0,d=JF()|0,s=vRe(c)|0,hn(m,l,d,s,DRe(c,f)|0,f)}function JF(){var s=0,l=0;if(o[7864]|0||(s9(10208),ir(51,10208,U|0)|0,l=7864,n[l>>2]=1,n[l+4>>2]=0),!(Rr(10208)|0)){s=10208,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));s9(10208)}return 10208}function vRe(s){return s=s|0,s|0}function DRe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0;return k=C,C=C+16|0,d=k,m=k+4|0,n[d>>2]=s,Q=JF()|0,B=Q+24|0,l=gr(l,4)|0,n[m>>2]=l,c=Q+28|0,f=n[c>>2]|0,f>>>0<(n[Q+32>>2]|0)>>>0?(i9(f,s,l),l=(n[c>>2]|0)+8|0,n[c>>2]=l):(PRe(B,d,m),l=n[c>>2]|0),C=k,(l-(n[B>>2]|0)>>3)+-1|0}function i9(s,l,c){s=s|0,l=l|0,c=c|0,n[s>>2]=l,n[s+4>>2]=c}function PRe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0;if(k=C,C=C+32|0,d=k,m=s+4|0,B=((n[m>>2]|0)-(n[s>>2]|0)>>3)+1|0,f=bRe(s)|0,f>>>0>>0)Jr(s);else{Q=n[s>>2]|0,M=(n[s+8>>2]|0)-Q|0,O=M>>2,SRe(d,M>>3>>>0>>1>>>0?O>>>0>>0?B:O:f,(n[m>>2]|0)-Q>>3,s+8|0),B=d+8|0,i9(n[B>>2]|0,n[l>>2]|0,n[c>>2]|0),n[B>>2]=(n[B>>2]|0)+8,xRe(s,d),kRe(d),C=k;return}}function bRe(s){return s=s|0,536870911}function SRe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>536870911)Tt();else{d=Kt(l<<3)|0;break}else d=0;while(!1);n[s>>2]=d,f=d+(c<<3)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l<<3)}function xRe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(0-(d>>3)<<3)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function kRe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~((f+-8-l|0)>>>3)<<3)),s=n[s>>2]|0,s|0&>(s)}function s9(s){s=s|0,RRe(s)}function QRe(s){s=s|0,FRe(s+24|0)}function FRe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~((l+-8-f|0)>>>3)<<3)),gt(c))}function RRe(s){s=s|0;var l=0;l=Vr()|0,zr(s,1,24,l,TRe()|0,1),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function TRe(){return 1392}function NRe(s,l){s=s|0,l=l|0,MRe(n[(LRe(s)|0)>>2]|0,l)}function LRe(s){return s=s|0,(n[(JF()|0)+24>>2]|0)+(s<<3)|0}function MRe(s,l){s=s|0,l=l|0;var c=0,f=0;c=C,C=C+16|0,f=c,VG(f,l),l=zG(f,l)|0,ef[s&127](l),C=c}function ORe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0;m=n[s>>2]|0,d=XF()|0,s=URe(c)|0,hn(m,l,d,s,_Re(c,f)|0,f)}function XF(){var s=0,l=0;if(o[7872]|0||(a9(10244),ir(52,10244,U|0)|0,l=7872,n[l>>2]=1,n[l+4>>2]=0),!(Rr(10244)|0)){s=10244,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));a9(10244)}return 10244}function URe(s){return s=s|0,s|0}function _Re(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0;return k=C,C=C+16|0,d=k,m=k+4|0,n[d>>2]=s,Q=XF()|0,B=Q+24|0,l=gr(l,4)|0,n[m>>2]=l,c=Q+28|0,f=n[c>>2]|0,f>>>0<(n[Q+32>>2]|0)>>>0?(o9(f,s,l),l=(n[c>>2]|0)+8|0,n[c>>2]=l):(HRe(B,d,m),l=n[c>>2]|0),C=k,(l-(n[B>>2]|0)>>3)+-1|0}function o9(s,l,c){s=s|0,l=l|0,c=c|0,n[s>>2]=l,n[s+4>>2]=c}function HRe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0;if(k=C,C=C+32|0,d=k,m=s+4|0,B=((n[m>>2]|0)-(n[s>>2]|0)>>3)+1|0,f=qRe(s)|0,f>>>0>>0)Jr(s);else{Q=n[s>>2]|0,M=(n[s+8>>2]|0)-Q|0,O=M>>2,jRe(d,M>>3>>>0>>1>>>0?O>>>0>>0?B:O:f,(n[m>>2]|0)-Q>>3,s+8|0),B=d+8|0,o9(n[B>>2]|0,n[l>>2]|0,n[c>>2]|0),n[B>>2]=(n[B>>2]|0)+8,GRe(s,d),YRe(d),C=k;return}}function qRe(s){return s=s|0,536870911}function jRe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>536870911)Tt();else{d=Kt(l<<3)|0;break}else d=0;while(!1);n[s>>2]=d,f=d+(c<<3)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l<<3)}function GRe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(0-(d>>3)<<3)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function YRe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~((f+-8-l|0)>>>3)<<3)),s=n[s>>2]|0,s|0&>(s)}function a9(s){s=s|0,VRe(s)}function WRe(s){s=s|0,KRe(s+24|0)}function KRe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~((l+-8-f|0)>>>3)<<3)),gt(c))}function VRe(s){s=s|0;var l=0;l=Vr()|0,zr(s,1,16,l,zRe()|0,0),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function zRe(){return 1400}function JRe(s){return s=s|0,ZRe(n[(XRe(s)|0)>>2]|0)|0}function XRe(s){return s=s|0,(n[(XF()|0)+24>>2]|0)+(s<<3)|0}function ZRe(s){return s=s|0,$Re(nD[s&7]()|0)|0}function $Re(s){return s=s|0,s|0}function eTe(){var s=0;return o[7880]|0||(aTe(10280),ir(25,10280,U|0)|0,s=7880,n[s>>2]=1,n[s+4>>2]=0),10280}function tTe(s,l){s=s|0,l=l|0,n[s>>2]=rTe()|0,n[s+4>>2]=nTe()|0,n[s+12>>2]=l,n[s+8>>2]=iTe()|0,n[s+32>>2]=4}function rTe(){return 11711}function nTe(){return 1356}function iTe(){return Gv()|0}function sTe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0,(Dp(f,896)|0)==512?c|0&&(oTe(c),gt(c)):l|0&&(w0(l),gt(l))}function oTe(s){s=s|0,s=n[s+4>>2]|0,s|0&&bp(s)}function aTe(s){s=s|0,wp(s)}function lTe(s){s=s|0,cTe(s,4920),uTe(s)|0,ATe(s)|0}function cTe(s,l){s=s|0,l=l|0;var c=0;c=xG()|0,n[s>>2]=c,FTe(c,l),Pp(n[s>>2]|0)}function uTe(s){s=s|0;var l=0;return l=n[s>>2]|0,P0(l,ITe()|0),s|0}function ATe(s){s=s|0;var l=0;return l=n[s>>2]|0,P0(l,fTe()|0),s|0}function fTe(){var s=0;return o[7888]|0||(l9(10328),ir(53,10328,U|0)|0,s=7888,n[s>>2]=1,n[s+4>>2]=0),Rr(10328)|0||l9(10328),10328}function P0(s,l){s=s|0,l=l|0,hn(s,0,l,0,0,0)}function l9(s){s=s|0,gTe(s),b0(s,10)}function pTe(s){s=s|0,hTe(s+24|0)}function hTe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~((l+-8-f|0)>>>3)<<3)),gt(c))}function gTe(s){s=s|0;var l=0;l=Vr()|0,zr(s,5,1,l,ETe()|0,2),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function dTe(s,l,c){s=s|0,l=l|0,c=+c,mTe(s,l,c)}function b0(s,l){s=s|0,l=l|0,n[s+20>>2]=l}function mTe(s,l,c){s=s|0,l=l|0,c=+c;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+16|0,m=f+8|0,k=f+13|0,d=f,B=f+12|0,XA(k,l),n[m>>2]=ZA(k,l)|0,Fu(B,c),E[d>>3]=+Ru(B,c),yTe(s,m,d),C=f}function yTe(s,l,c){s=s|0,l=l|0,c=c|0,W(s+8|0,n[l>>2]|0,+E[c>>3]),o[s+24>>0]=1}function ETe(){return 1404}function CTe(s,l){return s=s|0,l=+l,wTe(s,l)|0}function wTe(s,l){s=s|0,l=+l;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0;return f=C,C=C+16|0,m=f+4|0,B=f+8|0,k=f,d=Va(8)|0,c=d,Q=Kt(16)|0,XA(m,s),s=ZA(m,s)|0,Fu(B,l),W(Q,s,+Ru(B,l)),B=c+4|0,n[B>>2]=Q,s=Kt(8)|0,B=n[B>>2]|0,n[k>>2]=0,n[m>>2]=n[k>>2],LF(s,B,m),n[d>>2]=s,C=f,c|0}function ITe(){var s=0;return o[7896]|0||(c9(10364),ir(54,10364,U|0)|0,s=7896,n[s>>2]=1,n[s+4>>2]=0),Rr(10364)|0||c9(10364),10364}function c9(s){s=s|0,DTe(s),b0(s,55)}function BTe(s){s=s|0,vTe(s+24|0)}function vTe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~((l+-8-f|0)>>>3)<<3)),gt(c))}function DTe(s){s=s|0;var l=0;l=Vr()|0,zr(s,5,4,l,xTe()|0,0),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function PTe(s){s=s|0,bTe(s)}function bTe(s){s=s|0,STe(s)}function STe(s){s=s|0,u9(s+8|0),o[s+24>>0]=1}function u9(s){s=s|0,n[s>>2]=0,E[s+8>>3]=0}function xTe(){return 1424}function kTe(){return QTe()|0}function QTe(){var s=0,l=0,c=0,f=0,d=0,m=0,B=0;return l=C,C=C+16|0,d=l+4|0,B=l,c=Va(8)|0,s=c,f=Kt(16)|0,u9(f),m=s+4|0,n[m>>2]=f,f=Kt(8)|0,m=n[m>>2]|0,n[B>>2]=0,n[d>>2]=n[B>>2],LF(f,m,d),n[c>>2]=f,C=l,s|0}function FTe(s,l){s=s|0,l=l|0,n[s>>2]=RTe()|0,n[s+4>>2]=TTe()|0,n[s+12>>2]=l,n[s+8>>2]=NTe()|0,n[s+32>>2]=5}function RTe(){return 11710}function TTe(){return 1416}function NTe(){return Yv()|0}function LTe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0,(Dp(f,896)|0)==512?c|0&&(MTe(c),gt(c)):l|0&>(l)}function MTe(s){s=s|0,s=n[s+4>>2]|0,s|0&&bp(s)}function Yv(){var s=0;return o[7904]|0||(n[2600]=OTe()|0,n[2601]=0,s=7904,n[s>>2]=1,n[s+4>>2]=0),10400}function OTe(){return n[357]|0}function UTe(s){s=s|0,_Te(s,4926),HTe(s)|0}function _Te(s,l){s=s|0,l=l|0;var c=0;c=Z5()|0,n[s>>2]=c,ZTe(c,l),Pp(n[s>>2]|0)}function HTe(s){s=s|0;var l=0;return l=n[s>>2]|0,P0(l,qTe()|0),s|0}function qTe(){var s=0;return o[7912]|0||(A9(10412),ir(56,10412,U|0)|0,s=7912,n[s>>2]=1,n[s+4>>2]=0),Rr(10412)|0||A9(10412),10412}function A9(s){s=s|0,YTe(s),b0(s,57)}function jTe(s){s=s|0,GTe(s+24|0)}function GTe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~((l+-8-f|0)>>>3)<<3)),gt(c))}function YTe(s){s=s|0;var l=0;l=Vr()|0,zr(s,5,5,l,zTe()|0,0),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function WTe(s){s=s|0,KTe(s)}function KTe(s){s=s|0,VTe(s)}function VTe(s){s=s|0;var l=0,c=0;l=s+8|0,c=l+48|0;do n[l>>2]=0,l=l+4|0;while((l|0)<(c|0));o[s+56>>0]=1}function zTe(){return 1432}function JTe(){return XTe()|0}function XTe(){var s=0,l=0,c=0,f=0,d=0,m=0,B=0,k=0;B=C,C=C+16|0,s=B+4|0,l=B,c=Va(8)|0,f=c,d=Kt(48)|0,m=d,k=m+48|0;do n[m>>2]=0,m=m+4|0;while((m|0)<(k|0));return m=f+4|0,n[m>>2]=d,k=Kt(8)|0,m=n[m>>2]|0,n[l>>2]=0,n[s>>2]=n[l>>2],$5(k,m,s),n[c>>2]=k,C=B,f|0}function ZTe(s,l){s=s|0,l=l|0,n[s>>2]=$Te()|0,n[s+4>>2]=eNe()|0,n[s+12>>2]=l,n[s+8>>2]=tNe()|0,n[s+32>>2]=6}function $Te(){return 11704}function eNe(){return 1436}function tNe(){return Yv()|0}function rNe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0,(Dp(f,896)|0)==512?c|0&&(nNe(c),gt(c)):l|0&>(l)}function nNe(s){s=s|0,s=n[s+4>>2]|0,s|0&&bp(s)}function iNe(s){s=s|0,sNe(s,4933),oNe(s)|0,aNe(s)|0}function sNe(s,l){s=s|0,l=l|0;var c=0;c=QNe()|0,n[s>>2]=c,FNe(c,l),Pp(n[s>>2]|0)}function oNe(s){s=s|0;var l=0;return l=n[s>>2]|0,P0(l,wNe()|0),s|0}function aNe(s){s=s|0;var l=0;return l=n[s>>2]|0,P0(l,lNe()|0),s|0}function lNe(){var s=0;return o[7920]|0||(f9(10452),ir(58,10452,U|0)|0,s=7920,n[s>>2]=1,n[s+4>>2]=0),Rr(10452)|0||f9(10452),10452}function f9(s){s=s|0,ANe(s),b0(s,1)}function cNe(s){s=s|0,uNe(s+24|0)}function uNe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~((l+-8-f|0)>>>3)<<3)),gt(c))}function ANe(s){s=s|0;var l=0;l=Vr()|0,zr(s,5,1,l,gNe()|0,2),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function fNe(s,l,c){s=s|0,l=+l,c=+c,pNe(s,l,c)}function pNe(s,l,c){s=s|0,l=+l,c=+c;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+32|0,m=f+8|0,k=f+17|0,d=f,B=f+16|0,Fu(k,l),E[m>>3]=+Ru(k,l),Fu(B,c),E[d>>3]=+Ru(B,c),hNe(s,m,d),C=f}function hNe(s,l,c){s=s|0,l=l|0,c=c|0,p9(s+8|0,+E[l>>3],+E[c>>3]),o[s+24>>0]=1}function p9(s,l,c){s=s|0,l=+l,c=+c,E[s>>3]=l,E[s+8>>3]=c}function gNe(){return 1472}function dNe(s,l){return s=+s,l=+l,mNe(s,l)|0}function mNe(s,l){s=+s,l=+l;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0;return f=C,C=C+16|0,B=f+4|0,k=f+8|0,Q=f,d=Va(8)|0,c=d,m=Kt(16)|0,Fu(B,s),s=+Ru(B,s),Fu(k,l),p9(m,s,+Ru(k,l)),k=c+4|0,n[k>>2]=m,m=Kt(8)|0,k=n[k>>2]|0,n[Q>>2]=0,n[B>>2]=n[Q>>2],h9(m,k,B),n[d>>2]=m,C=f,c|0}function h9(s,l,c){s=s|0,l=l|0,c=c|0,n[s>>2]=l,c=Kt(16)|0,n[c+4>>2]=0,n[c+8>>2]=0,n[c>>2]=1452,n[c+12>>2]=l,n[s+4>>2]=c}function yNe(s){s=s|0,Md(s),gt(s)}function ENe(s){s=s|0,s=n[s+12>>2]|0,s|0&>(s)}function CNe(s){s=s|0,gt(s)}function wNe(){var s=0;return o[7928]|0||(g9(10488),ir(59,10488,U|0)|0,s=7928,n[s>>2]=1,n[s+4>>2]=0),Rr(10488)|0||g9(10488),10488}function g9(s){s=s|0,vNe(s),b0(s,60)}function INe(s){s=s|0,BNe(s+24|0)}function BNe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~((l+-8-f|0)>>>3)<<3)),gt(c))}function vNe(s){s=s|0;var l=0;l=Vr()|0,zr(s,5,6,l,SNe()|0,0),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function DNe(s){s=s|0,PNe(s)}function PNe(s){s=s|0,bNe(s)}function bNe(s){s=s|0,d9(s+8|0),o[s+24>>0]=1}function d9(s){s=s|0,n[s>>2]=0,n[s+4>>2]=0,n[s+8>>2]=0,n[s+12>>2]=0}function SNe(){return 1492}function xNe(){return kNe()|0}function kNe(){var s=0,l=0,c=0,f=0,d=0,m=0,B=0;return l=C,C=C+16|0,d=l+4|0,B=l,c=Va(8)|0,s=c,f=Kt(16)|0,d9(f),m=s+4|0,n[m>>2]=f,f=Kt(8)|0,m=n[m>>2]|0,n[B>>2]=0,n[d>>2]=n[B>>2],h9(f,m,d),n[c>>2]=f,C=l,s|0}function QNe(){var s=0;return o[7936]|0||(ONe(10524),ir(25,10524,U|0)|0,s=7936,n[s>>2]=1,n[s+4>>2]=0),10524}function FNe(s,l){s=s|0,l=l|0,n[s>>2]=RNe()|0,n[s+4>>2]=TNe()|0,n[s+12>>2]=l,n[s+8>>2]=NNe()|0,n[s+32>>2]=7}function RNe(){return 11700}function TNe(){return 1484}function NNe(){return Yv()|0}function LNe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0,(Dp(f,896)|0)==512?c|0&&(MNe(c),gt(c)):l|0&>(l)}function MNe(s){s=s|0,s=n[s+4>>2]|0,s|0&&bp(s)}function ONe(s){s=s|0,wp(s)}function UNe(s,l,c){s=s|0,l=l|0,c=c|0,s=pn(l)|0,l=_Ne(c)|0,c=HNe(c,0)|0,mLe(s,l,c,ZF()|0,0)}function _Ne(s){return s=s|0,s|0}function HNe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0;return k=C,C=C+16|0,d=k,m=k+4|0,n[d>>2]=s,Q=ZF()|0,B=Q+24|0,l=gr(l,4)|0,n[m>>2]=l,c=Q+28|0,f=n[c>>2]|0,f>>>0<(n[Q+32>>2]|0)>>>0?(y9(f,s,l),l=(n[c>>2]|0)+8|0,n[c>>2]=l):(VNe(B,d,m),l=n[c>>2]|0),C=k,(l-(n[B>>2]|0)>>3)+-1|0}function ZF(){var s=0,l=0;if(o[7944]|0||(m9(10568),ir(61,10568,U|0)|0,l=7944,n[l>>2]=1,n[l+4>>2]=0),!(Rr(10568)|0)){s=10568,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));m9(10568)}return 10568}function m9(s){s=s|0,GNe(s)}function qNe(s){s=s|0,jNe(s+24|0)}function jNe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~((l+-8-f|0)>>>3)<<3)),gt(c))}function GNe(s){s=s|0;var l=0;l=Vr()|0,zr(s,1,17,l,dG()|0,0),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function YNe(s){return s=s|0,KNe(n[(WNe(s)|0)>>2]|0)|0}function WNe(s){return s=s|0,(n[(ZF()|0)+24>>2]|0)+(s<<3)|0}function KNe(s){return s=s|0,jv(nD[s&7]()|0)|0}function y9(s,l,c){s=s|0,l=l|0,c=c|0,n[s>>2]=l,n[s+4>>2]=c}function VNe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0;if(k=C,C=C+32|0,d=k,m=s+4|0,B=((n[m>>2]|0)-(n[s>>2]|0)>>3)+1|0,f=zNe(s)|0,f>>>0>>0)Jr(s);else{Q=n[s>>2]|0,M=(n[s+8>>2]|0)-Q|0,O=M>>2,JNe(d,M>>3>>>0>>1>>>0?O>>>0>>0?B:O:f,(n[m>>2]|0)-Q>>3,s+8|0),B=d+8|0,y9(n[B>>2]|0,n[l>>2]|0,n[c>>2]|0),n[B>>2]=(n[B>>2]|0)+8,XNe(s,d),ZNe(d),C=k;return}}function zNe(s){return s=s|0,536870911}function JNe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>536870911)Tt();else{d=Kt(l<<3)|0;break}else d=0;while(!1);n[s>>2]=d,f=d+(c<<3)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l<<3)}function XNe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(0-(d>>3)<<3)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function ZNe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~((f+-8-l|0)>>>3)<<3)),s=n[s>>2]|0,s|0&>(s)}function $Ne(){eLe()}function eLe(){tLe(10604)}function tLe(s){s=s|0,rLe(s,4955)}function rLe(s,l){s=s|0,l=l|0;var c=0;c=nLe()|0,n[s>>2]=c,iLe(c,l),Pp(n[s>>2]|0)}function nLe(){var s=0;return o[7952]|0||(pLe(10612),ir(25,10612,U|0)|0,s=7952,n[s>>2]=1,n[s+4>>2]=0),10612}function iLe(s,l){s=s|0,l=l|0,n[s>>2]=lLe()|0,n[s+4>>2]=cLe()|0,n[s+12>>2]=l,n[s+8>>2]=uLe()|0,n[s+32>>2]=8}function Pp(s){s=s|0;var l=0,c=0;l=C,C=C+16|0,c=l,Fd()|0,n[c>>2]=s,sLe(10608,c),C=l}function Fd(){return o[11714]|0||(n[2652]=0,ir(62,10608,U|0)|0,o[11714]=1),10608}function sLe(s,l){s=s|0,l=l|0;var c=0;c=Kt(8)|0,n[c+4>>2]=n[l>>2],n[c>>2]=n[s>>2],n[s>>2]=c}function oLe(s){s=s|0,aLe(s)}function aLe(s){s=s|0;var l=0,c=0;if(l=n[s>>2]|0,l|0)do c=l,l=n[l>>2]|0,gt(c);while(l|0);n[s>>2]=0}function lLe(){return 11715}function cLe(){return 1496}function uLe(){return Gv()|0}function ALe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0,(Dp(f,896)|0)==512?c|0&&(fLe(c),gt(c)):l|0&>(l)}function fLe(s){s=s|0,s=n[s+4>>2]|0,s|0&&bp(s)}function pLe(s){s=s|0,wp(s)}function hLe(s,l){s=s|0,l=l|0;var c=0,f=0;Fd()|0,c=n[2652]|0;e:do if(c|0){for(;f=n[c+4>>2]|0,!(f|0&&!($9($F(f)|0,s)|0));)if(c=n[c>>2]|0,!c)break e;gLe(f,l)}while(!1)}function $F(s){return s=s|0,n[s+12>>2]|0}function gLe(s,l){s=s|0,l=l|0;var c=0;s=s+36|0,c=n[s>>2]|0,c|0&&(qA(c),gt(c)),c=Kt(4)|0,W5(c,l),n[s>>2]=c}function eR(){return o[11716]|0||(n[2664]=0,ir(63,10656,U|0)|0,o[11716]=1),10656}function E9(){var s=0;return o[11717]|0?s=n[2665]|0:(dLe(),n[2665]=1504,o[11717]=1,s=1504),s|0}function dLe(){o[11740]|0||(o[11718]=gr(gr(8,0)|0,0)|0,o[11719]=gr(gr(0,0)|0,0)|0,o[11720]=gr(gr(0,16)|0,0)|0,o[11721]=gr(gr(8,0)|0,0)|0,o[11722]=gr(gr(0,0)|0,0)|0,o[11723]=gr(gr(8,0)|0,0)|0,o[11724]=gr(gr(0,0)|0,0)|0,o[11725]=gr(gr(8,0)|0,0)|0,o[11726]=gr(gr(0,0)|0,0)|0,o[11727]=gr(gr(8,0)|0,0)|0,o[11728]=gr(gr(0,0)|0,0)|0,o[11729]=gr(gr(0,0)|0,32)|0,o[11730]=gr(gr(0,0)|0,32)|0,o[11740]=1)}function C9(){return 1572}function mLe(s,l,c,f,d){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0;var m=0,B=0,k=0,Q=0,O=0,M=0;m=C,C=C+32|0,M=m+16|0,O=m+12|0,Q=m+8|0,k=m+4|0,B=m,n[M>>2]=s,n[O>>2]=l,n[Q>>2]=c,n[k>>2]=f,n[B>>2]=d,eR()|0,yLe(10656,M,O,Q,k,B),C=m}function yLe(s,l,c,f,d,m){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0,m=m|0;var B=0;B=Kt(24)|0,z5(B+4|0,n[l>>2]|0,n[c>>2]|0,n[f>>2]|0,n[d>>2]|0,n[m>>2]|0),n[B>>2]=n[s>>2],n[s>>2]=B}function w9(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0,se=0,je=0,Oe=0,Qe=0,$e=0,Je=0,lt=0;if(lt=C,C=C+32|0,Oe=lt+20|0,Qe=lt+8|0,$e=lt+4|0,Je=lt,l=n[l>>2]|0,l|0){je=Oe+4|0,Q=Oe+8|0,O=Qe+4|0,M=Qe+8|0,j=Qe+8|0,se=Oe+8|0;do{if(B=l+4|0,k=tR(B)|0,k|0){if(d=yw(k)|0,n[Oe>>2]=0,n[je>>2]=0,n[Q>>2]=0,f=(Ew(k)|0)+1|0,ELe(Oe,f),f|0)for(;f=f+-1|0,xc(Qe,n[d>>2]|0),m=n[je>>2]|0,m>>>0<(n[se>>2]|0)>>>0?(n[m>>2]=n[Qe>>2],n[je>>2]=(n[je>>2]|0)+4):rR(Oe,Qe),f;)d=d+4|0;f=Cw(k)|0,n[Qe>>2]=0,n[O>>2]=0,n[M>>2]=0;e:do if(n[f>>2]|0)for(d=0,m=0;;){if((d|0)==(m|0)?CLe(Qe,f):(n[d>>2]=n[f>>2],n[O>>2]=(n[O>>2]|0)+4),f=f+4|0,!(n[f>>2]|0))break e;d=n[O>>2]|0,m=n[j>>2]|0}while(!1);n[$e>>2]=Wv(B)|0,n[Je>>2]=Rr(k)|0,wLe(c,s,$e,Je,Oe,Qe),nR(Qe),$A(Oe)}l=n[l>>2]|0}while(l|0)}C=lt}function tR(s){return s=s|0,n[s+12>>2]|0}function yw(s){return s=s|0,n[s+12>>2]|0}function Ew(s){return s=s|0,n[s+16>>2]|0}function ELe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0;d=C,C=C+32|0,c=d,f=n[s>>2]|0,(n[s+8>>2]|0)-f>>2>>>0>>0&&(x9(c,l,(n[s+4>>2]|0)-f>>2,s+8|0),k9(s,c),Q9(c)),C=d}function rR(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0;if(B=C,C=C+32|0,c=B,f=s+4|0,d=((n[f>>2]|0)-(n[s>>2]|0)>>2)+1|0,m=S9(s)|0,m>>>0>>0)Jr(s);else{k=n[s>>2]|0,O=(n[s+8>>2]|0)-k|0,Q=O>>1,x9(c,O>>2>>>0>>1>>>0?Q>>>0>>0?d:Q:m,(n[f>>2]|0)-k>>2,s+8|0),m=c+8|0,n[n[m>>2]>>2]=n[l>>2],n[m>>2]=(n[m>>2]|0)+4,k9(s,c),Q9(c),C=B;return}}function Cw(s){return s=s|0,n[s+8>>2]|0}function CLe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0;if(B=C,C=C+32|0,c=B,f=s+4|0,d=((n[f>>2]|0)-(n[s>>2]|0)>>2)+1|0,m=b9(s)|0,m>>>0>>0)Jr(s);else{k=n[s>>2]|0,O=(n[s+8>>2]|0)-k|0,Q=O>>1,_Le(c,O>>2>>>0>>1>>>0?Q>>>0>>0?d:Q:m,(n[f>>2]|0)-k>>2,s+8|0),m=c+8|0,n[n[m>>2]>>2]=n[l>>2],n[m>>2]=(n[m>>2]|0)+4,HLe(s,c),qLe(c),C=B;return}}function Wv(s){return s=s|0,n[s>>2]|0}function wLe(s,l,c,f,d,m){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0,m=m|0,ILe(s,l,c,f,d,m)}function nR(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~((l+-4-f|0)>>>2)<<2)),gt(c))}function $A(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~((l+-4-f|0)>>>2)<<2)),gt(c))}function ILe(s,l,c,f,d,m){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0,m=m|0;var B=0,k=0,Q=0,O=0,M=0,j=0;B=C,C=C+48|0,M=B+40|0,k=B+32|0,j=B+24|0,Q=B+12|0,O=B,za(k),s=ya(s)|0,n[j>>2]=n[l>>2],c=n[c>>2]|0,f=n[f>>2]|0,iR(Q,d),BLe(O,m),n[M>>2]=n[j>>2],vLe(s,M,c,f,Q,O),nR(O),$A(Q),Ja(k),C=B}function iR(s,l){s=s|0,l=l|0;var c=0,f=0;n[s>>2]=0,n[s+4>>2]=0,n[s+8>>2]=0,c=l+4|0,f=(n[c>>2]|0)-(n[l>>2]|0)>>2,f|0&&(OLe(s,f),ULe(s,n[l>>2]|0,n[c>>2]|0,f))}function BLe(s,l){s=s|0,l=l|0;var c=0,f=0;n[s>>2]=0,n[s+4>>2]=0,n[s+8>>2]=0,c=l+4|0,f=(n[c>>2]|0)-(n[l>>2]|0)>>2,f|0&&(LLe(s,f),MLe(s,n[l>>2]|0,n[c>>2]|0,f))}function vLe(s,l,c,f,d,m){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0,m=m|0;var B=0,k=0,Q=0,O=0,M=0,j=0;B=C,C=C+32|0,M=B+28|0,j=B+24|0,k=B+12|0,Q=B,O=Pl(DLe()|0)|0,n[j>>2]=n[l>>2],n[M>>2]=n[j>>2],l=S0(M)|0,c=I9(c)|0,f=sR(f)|0,n[k>>2]=n[d>>2],M=d+4|0,n[k+4>>2]=n[M>>2],j=d+8|0,n[k+8>>2]=n[j>>2],n[j>>2]=0,n[M>>2]=0,n[d>>2]=0,d=oR(k)|0,n[Q>>2]=n[m>>2],M=m+4|0,n[Q+4>>2]=n[M>>2],j=m+8|0,n[Q+8>>2]=n[j>>2],n[j>>2]=0,n[M>>2]=0,n[m>>2]=0,ao(0,O|0,s|0,l|0,c|0,f|0,d|0,PLe(Q)|0)|0,nR(Q),$A(k),C=B}function DLe(){var s=0;return o[7968]|0||(TLe(10708),s=7968,n[s>>2]=1,n[s+4>>2]=0),10708}function S0(s){return s=s|0,v9(s)|0}function I9(s){return s=s|0,B9(s)|0}function sR(s){return s=s|0,jv(s)|0}function oR(s){return s=s|0,SLe(s)|0}function PLe(s){return s=s|0,bLe(s)|0}function bLe(s){s=s|0;var l=0,c=0,f=0;if(f=(n[s+4>>2]|0)-(n[s>>2]|0)|0,c=f>>2,f=Va(f+4|0)|0,n[f>>2]=c,c|0){l=0;do n[f+4+(l<<2)>>2]=B9(n[(n[s>>2]|0)+(l<<2)>>2]|0)|0,l=l+1|0;while((l|0)!=(c|0))}return f|0}function B9(s){return s=s|0,s|0}function SLe(s){s=s|0;var l=0,c=0,f=0;if(f=(n[s+4>>2]|0)-(n[s>>2]|0)|0,c=f>>2,f=Va(f+4|0)|0,n[f>>2]=c,c|0){l=0;do n[f+4+(l<<2)>>2]=v9((n[s>>2]|0)+(l<<2)|0)|0,l=l+1|0;while((l|0)!=(c|0))}return f|0}function v9(s){s=s|0;var l=0,c=0,f=0,d=0;return d=C,C=C+32|0,l=d+12|0,c=d,f=yF(D9()|0)|0,f?(EF(l,f),CF(c,l),uUe(s,c),s=wF(l)|0):s=xLe(s)|0,C=d,s|0}function D9(){var s=0;return o[7960]|0||(RLe(10664),ir(25,10664,U|0)|0,s=7960,n[s>>2]=1,n[s+4>>2]=0),10664}function xLe(s){s=s|0;var l=0,c=0,f=0,d=0,m=0,B=0,k=0;return c=C,C=C+16|0,d=c+4|0,B=c,f=Va(8)|0,l=f,k=Kt(4)|0,n[k>>2]=n[s>>2],m=l+4|0,n[m>>2]=k,s=Kt(8)|0,m=n[m>>2]|0,n[B>>2]=0,n[d>>2]=n[B>>2],P9(s,m,d),n[f>>2]=s,C=c,l|0}function P9(s,l,c){s=s|0,l=l|0,c=c|0,n[s>>2]=l,c=Kt(16)|0,n[c+4>>2]=0,n[c+8>>2]=0,n[c>>2]=1656,n[c+12>>2]=l,n[s+4>>2]=c}function kLe(s){s=s|0,Md(s),gt(s)}function QLe(s){s=s|0,s=n[s+12>>2]|0,s|0&>(s)}function FLe(s){s=s|0,gt(s)}function RLe(s){s=s|0,wp(s)}function TLe(s){s=s|0,bl(s,NLe()|0,5)}function NLe(){return 1676}function LLe(s,l){s=s|0,l=l|0;var c=0;if((b9(s)|0)>>>0>>0&&Jr(s),l>>>0>1073741823)Tt();else{c=Kt(l<<2)|0,n[s+4>>2]=c,n[s>>2]=c,n[s+8>>2]=c+(l<<2);return}}function MLe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0,f=s+4|0,s=c-l|0,(s|0)>0&&(Dr(n[f>>2]|0,l|0,s|0)|0,n[f>>2]=(n[f>>2]|0)+(s>>>2<<2))}function b9(s){return s=s|0,1073741823}function OLe(s,l){s=s|0,l=l|0;var c=0;if((S9(s)|0)>>>0>>0&&Jr(s),l>>>0>1073741823)Tt();else{c=Kt(l<<2)|0,n[s+4>>2]=c,n[s>>2]=c,n[s+8>>2]=c+(l<<2);return}}function ULe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0,f=s+4|0,s=c-l|0,(s|0)>0&&(Dr(n[f>>2]|0,l|0,s|0)|0,n[f>>2]=(n[f>>2]|0)+(s>>>2<<2))}function S9(s){return s=s|0,1073741823}function _Le(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>1073741823)Tt();else{d=Kt(l<<2)|0;break}else d=0;while(!1);n[s>>2]=d,f=d+(c<<2)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l<<2)}function HLe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(0-(d>>2)<<2)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function qLe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~((f+-4-l|0)>>>2)<<2)),s=n[s>>2]|0,s|0&>(s)}function x9(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>1073741823)Tt();else{d=Kt(l<<2)|0;break}else d=0;while(!1);n[s>>2]=d,f=d+(c<<2)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l<<2)}function k9(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(0-(d>>2)<<2)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function Q9(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~((f+-4-l|0)>>>2)<<2)),s=n[s>>2]|0,s|0&>(s)}function jLe(s,l,c,f,d){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0;var m=0,B=0,k=0,Q=0,O=0,M=0,j=0,se=0,je=0,Oe=0,Qe=0;if(Qe=C,C=C+32|0,M=Qe+20|0,j=Qe+12|0,O=Qe+16|0,se=Qe+4|0,je=Qe,Oe=Qe+8|0,k=E9()|0,m=n[k>>2]|0,B=n[m>>2]|0,B|0)for(Q=n[k+8>>2]|0,k=n[k+4>>2]|0;xc(M,B),GLe(s,M,k,Q),m=m+4|0,B=n[m>>2]|0,B;)Q=Q+1|0,k=k+1|0;if(m=C9()|0,B=n[m>>2]|0,B|0)do xc(M,B),n[j>>2]=n[m+4>>2],YLe(l,M,j),m=m+8|0,B=n[m>>2]|0;while(B|0);if(m=n[(Fd()|0)>>2]|0,m|0)do l=n[m+4>>2]|0,xc(M,n[(Rd(l)|0)>>2]|0),n[j>>2]=$F(l)|0,WLe(c,M,j),m=n[m>>2]|0;while(m|0);if(xc(O,0),m=eR()|0,n[M>>2]=n[O>>2],w9(M,m,d),m=n[(Fd()|0)>>2]|0,m|0){s=M+4|0,l=M+8|0,c=M+8|0;do{if(Q=n[m+4>>2]|0,xc(j,n[(Rd(Q)|0)>>2]|0),KLe(se,F9(Q)|0),B=n[se>>2]|0,B|0){n[M>>2]=0,n[s>>2]=0,n[l>>2]=0;do xc(je,n[(Rd(n[B+4>>2]|0)|0)>>2]|0),k=n[s>>2]|0,k>>>0<(n[c>>2]|0)>>>0?(n[k>>2]=n[je>>2],n[s>>2]=(n[s>>2]|0)+4):rR(M,je),B=n[B>>2]|0;while(B|0);VLe(f,j,M),$A(M)}n[Oe>>2]=n[j>>2],O=R9(Q)|0,n[M>>2]=n[Oe>>2],w9(M,O,d),tG(se),m=n[m>>2]|0}while(m|0)}C=Qe}function GLe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0,oMe(s,l,c,f)}function YLe(s,l,c){s=s|0,l=l|0,c=c|0,sMe(s,l,c)}function Rd(s){return s=s|0,s|0}function WLe(s,l,c){s=s|0,l=l|0,c=c|0,tMe(s,l,c)}function F9(s){return s=s|0,s+16|0}function KLe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0;if(m=C,C=C+16|0,d=m+8|0,c=m,n[s>>2]=0,f=n[l>>2]|0,n[d>>2]=f,n[c>>2]=s,c=eMe(c)|0,f|0){if(f=Kt(12)|0,B=(T9(d)|0)+4|0,s=n[B+4>>2]|0,l=f+4|0,n[l>>2]=n[B>>2],n[l+4>>2]=s,l=n[n[d>>2]>>2]|0,n[d>>2]=l,!l)s=f;else for(l=f;s=Kt(12)|0,Q=(T9(d)|0)+4|0,k=n[Q+4>>2]|0,B=s+4|0,n[B>>2]=n[Q>>2],n[B+4>>2]=k,n[l>>2]=s,B=n[n[d>>2]>>2]|0,n[d>>2]=B,B;)l=s;n[s>>2]=n[c>>2],n[c>>2]=f}C=m}function VLe(s,l,c){s=s|0,l=l|0,c=c|0,zLe(s,l,c)}function R9(s){return s=s|0,s+24|0}function zLe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+32|0,B=f+24|0,d=f+16|0,k=f+12|0,m=f,za(d),s=ya(s)|0,n[k>>2]=n[l>>2],iR(m,c),n[B>>2]=n[k>>2],JLe(s,B,m),$A(m),Ja(d),C=f}function JLe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+32|0,B=f+16|0,k=f+12|0,d=f,m=Pl(XLe()|0)|0,n[k>>2]=n[l>>2],n[B>>2]=n[k>>2],l=S0(B)|0,n[d>>2]=n[c>>2],B=c+4|0,n[d+4>>2]=n[B>>2],k=c+8|0,n[d+8>>2]=n[k>>2],n[k>>2]=0,n[B>>2]=0,n[c>>2]=0,oo(0,m|0,s|0,l|0,oR(d)|0)|0,$A(d),C=f}function XLe(){var s=0;return o[7976]|0||(ZLe(10720),s=7976,n[s>>2]=1,n[s+4>>2]=0),10720}function ZLe(s){s=s|0,bl(s,$Le()|0,2)}function $Le(){return 1732}function eMe(s){return s=s|0,n[s>>2]|0}function T9(s){return s=s|0,n[s>>2]|0}function tMe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;f=C,C=C+32|0,m=f+16|0,d=f+8|0,B=f,za(d),s=ya(s)|0,n[B>>2]=n[l>>2],c=n[c>>2]|0,n[m>>2]=n[B>>2],N9(s,m,c),Ja(d),C=f}function N9(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;f=C,C=C+16|0,m=f+4|0,B=f,d=Pl(rMe()|0)|0,n[B>>2]=n[l>>2],n[m>>2]=n[B>>2],l=S0(m)|0,oo(0,d|0,s|0,l|0,I9(c)|0)|0,C=f}function rMe(){var s=0;return o[7984]|0||(nMe(10732),s=7984,n[s>>2]=1,n[s+4>>2]=0),10732}function nMe(s){s=s|0,bl(s,iMe()|0,2)}function iMe(){return 1744}function sMe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;f=C,C=C+32|0,m=f+16|0,d=f+8|0,B=f,za(d),s=ya(s)|0,n[B>>2]=n[l>>2],c=n[c>>2]|0,n[m>>2]=n[B>>2],N9(s,m,c),Ja(d),C=f}function oMe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0;d=C,C=C+32|0,B=d+16|0,m=d+8|0,k=d,za(m),s=ya(s)|0,n[k>>2]=n[l>>2],c=o[c>>0]|0,f=o[f>>0]|0,n[B>>2]=n[k>>2],aMe(s,B,c,f),Ja(m),C=d}function aMe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0;d=C,C=C+16|0,B=d+4|0,k=d,m=Pl(lMe()|0)|0,n[k>>2]=n[l>>2],n[B>>2]=n[k>>2],l=S0(B)|0,c=Td(c)|0,hc(0,m|0,s|0,l|0,c|0,Td(f)|0)|0,C=d}function lMe(){var s=0;return o[7992]|0||(uMe(10744),s=7992,n[s>>2]=1,n[s+4>>2]=0),10744}function Td(s){return s=s|0,cMe(s)|0}function cMe(s){return s=s|0,s&255|0}function uMe(s){s=s|0,bl(s,AMe()|0,3)}function AMe(){return 1756}function fMe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0,se=0;switch(se=C,C=C+32|0,k=se+8|0,Q=se+4|0,O=se+20|0,M=se,DF(s,0),f=cUe(l)|0,n[k>>2]=0,j=k+4|0,n[j>>2]=0,n[k+8>>2]=0,f<<24>>24){case 0:{o[O>>0]=0,pMe(Q,c,O),Kv(s,Q)|0,jA(Q);break}case 8:{j=fR(l)|0,o[O>>0]=8,xc(M,n[j+4>>2]|0),hMe(Q,c,O,M,j+8|0),Kv(s,Q)|0,jA(Q);break}case 9:{if(m=fR(l)|0,l=n[m+4>>2]|0,l|0)for(B=k+8|0,d=m+12|0;l=l+-1|0,xc(Q,n[d>>2]|0),f=n[j>>2]|0,f>>>0<(n[B>>2]|0)>>>0?(n[f>>2]=n[Q>>2],n[j>>2]=(n[j>>2]|0)+4):rR(k,Q),l;)d=d+4|0;o[O>>0]=9,xc(M,n[m+8>>2]|0),gMe(Q,c,O,M,k),Kv(s,Q)|0,jA(Q);break}default:j=fR(l)|0,o[O>>0]=f,xc(M,n[j+4>>2]|0),dMe(Q,c,O,M),Kv(s,Q)|0,jA(Q)}$A(k),C=se}function pMe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0;f=C,C=C+16|0,d=f,za(d),l=ya(l)|0,xMe(s,l,o[c>>0]|0),Ja(d),C=f}function Kv(s,l){s=s|0,l=l|0;var c=0;return c=n[s>>2]|0,c|0&&PA(c|0),n[s>>2]=n[l>>2],n[l>>2]=0,s|0}function hMe(s,l,c,f,d){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0;var m=0,B=0,k=0,Q=0;m=C,C=C+32|0,k=m+16|0,B=m+8|0,Q=m,za(B),l=ya(l)|0,c=o[c>>0]|0,n[Q>>2]=n[f>>2],d=n[d>>2]|0,n[k>>2]=n[Q>>2],DMe(s,l,c,k,d),Ja(B),C=m}function gMe(s,l,c,f,d){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0;var m=0,B=0,k=0,Q=0,O=0;m=C,C=C+32|0,Q=m+24|0,B=m+16|0,O=m+12|0,k=m,za(B),l=ya(l)|0,c=o[c>>0]|0,n[O>>2]=n[f>>2],iR(k,d),n[Q>>2]=n[O>>2],wMe(s,l,c,Q,k),$A(k),Ja(B),C=m}function dMe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0;d=C,C=C+32|0,B=d+16|0,m=d+8|0,k=d,za(m),l=ya(l)|0,c=o[c>>0]|0,n[k>>2]=n[f>>2],n[B>>2]=n[k>>2],mMe(s,l,c,B),Ja(m),C=d}function mMe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0;d=C,C=C+16|0,m=d+4|0,k=d,B=Pl(yMe()|0)|0,c=Td(c)|0,n[k>>2]=n[f>>2],n[m>>2]=n[k>>2],Vv(s,oo(0,B|0,l|0,c|0,S0(m)|0)|0),C=d}function yMe(){var s=0;return o[8e3]|0||(EMe(10756),s=8e3,n[s>>2]=1,n[s+4>>2]=0),10756}function Vv(s,l){s=s|0,l=l|0,DF(s,l)}function EMe(s){s=s|0,bl(s,CMe()|0,2)}function CMe(){return 1772}function wMe(s,l,c,f,d){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0;var m=0,B=0,k=0,Q=0,O=0;m=C,C=C+32|0,Q=m+16|0,O=m+12|0,B=m,k=Pl(IMe()|0)|0,c=Td(c)|0,n[O>>2]=n[f>>2],n[Q>>2]=n[O>>2],f=S0(Q)|0,n[B>>2]=n[d>>2],Q=d+4|0,n[B+4>>2]=n[Q>>2],O=d+8|0,n[B+8>>2]=n[O>>2],n[O>>2]=0,n[Q>>2]=0,n[d>>2]=0,Vv(s,hc(0,k|0,l|0,c|0,f|0,oR(B)|0)|0),$A(B),C=m}function IMe(){var s=0;return o[8008]|0||(BMe(10768),s=8008,n[s>>2]=1,n[s+4>>2]=0),10768}function BMe(s){s=s|0,bl(s,vMe()|0,3)}function vMe(){return 1784}function DMe(s,l,c,f,d){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0;var m=0,B=0,k=0,Q=0;m=C,C=C+16|0,k=m+4|0,Q=m,B=Pl(PMe()|0)|0,c=Td(c)|0,n[Q>>2]=n[f>>2],n[k>>2]=n[Q>>2],f=S0(k)|0,Vv(s,hc(0,B|0,l|0,c|0,f|0,sR(d)|0)|0),C=m}function PMe(){var s=0;return o[8016]|0||(bMe(10780),s=8016,n[s>>2]=1,n[s+4>>2]=0),10780}function bMe(s){s=s|0,bl(s,SMe()|0,3)}function SMe(){return 1800}function xMe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=Pl(kMe()|0)|0,Vv(s,Qn(0,f|0,l|0,Td(c)|0)|0)}function kMe(){var s=0;return o[8024]|0||(QMe(10792),s=8024,n[s>>2]=1,n[s+4>>2]=0),10792}function QMe(s){s=s|0,bl(s,FMe()|0,1)}function FMe(){return 1816}function RMe(){TMe(),NMe(),LMe()}function TMe(){n[2702]=c7(65536)|0}function NMe(){rOe(10856)}function LMe(){MMe(10816)}function MMe(s){s=s|0,OMe(s,5044),UMe(s)|0}function OMe(s,l){s=s|0,l=l|0;var c=0;c=D9()|0,n[s>>2]=c,JMe(c,l),Pp(n[s>>2]|0)}function UMe(s){s=s|0;var l=0;return l=n[s>>2]|0,P0(l,_Me()|0),s|0}function _Me(){var s=0;return o[8032]|0||(L9(10820),ir(64,10820,U|0)|0,s=8032,n[s>>2]=1,n[s+4>>2]=0),Rr(10820)|0||L9(10820),10820}function L9(s){s=s|0,jMe(s),b0(s,25)}function HMe(s){s=s|0,qMe(s+24|0)}function qMe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~((l+-8-f|0)>>>3)<<3)),gt(c))}function jMe(s){s=s|0;var l=0;l=Vr()|0,zr(s,5,18,l,KMe()|0,1),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function GMe(s,l){s=s|0,l=l|0,YMe(s,l)}function YMe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0;c=C,C=C+16|0,f=c,d=c+4|0,v0(d,l),n[f>>2]=D0(d,l)|0,WMe(s,f),C=c}function WMe(s,l){s=s|0,l=l|0,M9(s+4|0,n[l>>2]|0),o[s+8>>0]=1}function M9(s,l){s=s|0,l=l|0,n[s>>2]=l}function KMe(){return 1824}function VMe(s){return s=s|0,zMe(s)|0}function zMe(s){s=s|0;var l=0,c=0,f=0,d=0,m=0,B=0,k=0;return c=C,C=C+16|0,d=c+4|0,B=c,f=Va(8)|0,l=f,k=Kt(4)|0,v0(d,s),M9(k,D0(d,s)|0),m=l+4|0,n[m>>2]=k,s=Kt(8)|0,m=n[m>>2]|0,n[B>>2]=0,n[d>>2]=n[B>>2],P9(s,m,d),n[f>>2]=s,C=c,l|0}function Va(s){s=s|0;var l=0,c=0;return s=s+7&-8,s>>>0<=32768&&(l=n[2701]|0,s>>>0<=(65536-l|0)>>>0)?(c=(n[2702]|0)+l|0,n[2701]=l+s,s=c):(s=c7(s+8|0)|0,n[s>>2]=n[2703],n[2703]=s,s=s+8|0),s|0}function JMe(s,l){s=s|0,l=l|0,n[s>>2]=XMe()|0,n[s+4>>2]=ZMe()|0,n[s+12>>2]=l,n[s+8>>2]=$Me()|0,n[s+32>>2]=9}function XMe(){return 11744}function ZMe(){return 1832}function $Me(){return Yv()|0}function eOe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0,(Dp(f,896)|0)==512?c|0&&(tOe(c),gt(c)):l|0&>(l)}function tOe(s){s=s|0,s=n[s+4>>2]|0,s|0&&bp(s)}function rOe(s){s=s|0,nOe(s,5052),iOe(s)|0,sOe(s,5058,26)|0,oOe(s,5069,1)|0,aOe(s,5077,10)|0,lOe(s,5087,19)|0,cOe(s,5094,27)|0}function nOe(s,l){s=s|0,l=l|0;var c=0;c=tUe()|0,n[s>>2]=c,rUe(c,l),Pp(n[s>>2]|0)}function iOe(s){s=s|0;var l=0;return l=n[s>>2]|0,P0(l,H4e()|0),s|0}function sOe(s,l,c){return s=s|0,l=l|0,c=c|0,B4e(s,pn(l)|0,c,0),s|0}function oOe(s,l,c){return s=s|0,l=l|0,c=c|0,l4e(s,pn(l)|0,c,0),s|0}function aOe(s,l,c){return s=s|0,l=l|0,c=c|0,_Oe(s,pn(l)|0,c,0),s|0}function lOe(s,l,c){return s=s|0,l=l|0,c=c|0,DOe(s,pn(l)|0,c,0),s|0}function O9(s,l){s=s|0,l=l|0;var c=0,f=0;e:for(;;){for(c=n[2703]|0;;){if((c|0)==(l|0))break e;if(f=n[c>>2]|0,n[2703]=f,!c)c=f;else break}gt(c)}n[2701]=s}function cOe(s,l,c){return s=s|0,l=l|0,c=c|0,uOe(s,pn(l)|0,c,0),s|0}function uOe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0;m=n[s>>2]|0,d=aR()|0,s=AOe(c)|0,hn(m,l,d,s,fOe(c,f)|0,f)}function aR(){var s=0,l=0;if(o[8040]|0||(_9(10860),ir(65,10860,U|0)|0,l=8040,n[l>>2]=1,n[l+4>>2]=0),!(Rr(10860)|0)){s=10860,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));_9(10860)}return 10860}function AOe(s){return s=s|0,s|0}function fOe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0;return k=C,C=C+16|0,d=k,m=k+4|0,n[d>>2]=s,Q=aR()|0,B=Q+24|0,l=gr(l,4)|0,n[m>>2]=l,c=Q+28|0,f=n[c>>2]|0,f>>>0<(n[Q+32>>2]|0)>>>0?(U9(f,s,l),l=(n[c>>2]|0)+8|0,n[c>>2]=l):(pOe(B,d,m),l=n[c>>2]|0),C=k,(l-(n[B>>2]|0)>>3)+-1|0}function U9(s,l,c){s=s|0,l=l|0,c=c|0,n[s>>2]=l,n[s+4>>2]=c}function pOe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0;if(k=C,C=C+32|0,d=k,m=s+4|0,B=((n[m>>2]|0)-(n[s>>2]|0)>>3)+1|0,f=hOe(s)|0,f>>>0>>0)Jr(s);else{Q=n[s>>2]|0,M=(n[s+8>>2]|0)-Q|0,O=M>>2,gOe(d,M>>3>>>0>>1>>>0?O>>>0>>0?B:O:f,(n[m>>2]|0)-Q>>3,s+8|0),B=d+8|0,U9(n[B>>2]|0,n[l>>2]|0,n[c>>2]|0),n[B>>2]=(n[B>>2]|0)+8,dOe(s,d),mOe(d),C=k;return}}function hOe(s){return s=s|0,536870911}function gOe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>536870911)Tt();else{d=Kt(l<<3)|0;break}else d=0;while(!1);n[s>>2]=d,f=d+(c<<3)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l<<3)}function dOe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(0-(d>>3)<<3)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function mOe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~((f+-8-l|0)>>>3)<<3)),s=n[s>>2]|0,s|0&>(s)}function _9(s){s=s|0,COe(s)}function yOe(s){s=s|0,EOe(s+24|0)}function EOe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~((l+-8-f|0)>>>3)<<3)),gt(c))}function COe(s){s=s|0;var l=0;l=Vr()|0,zr(s,1,11,l,wOe()|0,2),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function wOe(){return 1840}function IOe(s,l,c){s=s|0,l=l|0,c=c|0,vOe(n[(BOe(s)|0)>>2]|0,l,c)}function BOe(s){return s=s|0,(n[(aR()|0)+24>>2]|0)+(s<<3)|0}function vOe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0;f=C,C=C+16|0,m=f+1|0,d=f,v0(m,l),l=D0(m,l)|0,v0(d,c),c=D0(d,c)|0,tf[s&31](l,c),C=f}function DOe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0;m=n[s>>2]|0,d=lR()|0,s=POe(c)|0,hn(m,l,d,s,bOe(c,f)|0,f)}function lR(){var s=0,l=0;if(o[8048]|0||(q9(10896),ir(66,10896,U|0)|0,l=8048,n[l>>2]=1,n[l+4>>2]=0),!(Rr(10896)|0)){s=10896,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));q9(10896)}return 10896}function POe(s){return s=s|0,s|0}function bOe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0;return k=C,C=C+16|0,d=k,m=k+4|0,n[d>>2]=s,Q=lR()|0,B=Q+24|0,l=gr(l,4)|0,n[m>>2]=l,c=Q+28|0,f=n[c>>2]|0,f>>>0<(n[Q+32>>2]|0)>>>0?(H9(f,s,l),l=(n[c>>2]|0)+8|0,n[c>>2]=l):(SOe(B,d,m),l=n[c>>2]|0),C=k,(l-(n[B>>2]|0)>>3)+-1|0}function H9(s,l,c){s=s|0,l=l|0,c=c|0,n[s>>2]=l,n[s+4>>2]=c}function SOe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0;if(k=C,C=C+32|0,d=k,m=s+4|0,B=((n[m>>2]|0)-(n[s>>2]|0)>>3)+1|0,f=xOe(s)|0,f>>>0>>0)Jr(s);else{Q=n[s>>2]|0,M=(n[s+8>>2]|0)-Q|0,O=M>>2,kOe(d,M>>3>>>0>>1>>>0?O>>>0>>0?B:O:f,(n[m>>2]|0)-Q>>3,s+8|0),B=d+8|0,H9(n[B>>2]|0,n[l>>2]|0,n[c>>2]|0),n[B>>2]=(n[B>>2]|0)+8,QOe(s,d),FOe(d),C=k;return}}function xOe(s){return s=s|0,536870911}function kOe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>536870911)Tt();else{d=Kt(l<<3)|0;break}else d=0;while(!1);n[s>>2]=d,f=d+(c<<3)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l<<3)}function QOe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(0-(d>>3)<<3)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function FOe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~((f+-8-l|0)>>>3)<<3)),s=n[s>>2]|0,s|0&>(s)}function q9(s){s=s|0,NOe(s)}function ROe(s){s=s|0,TOe(s+24|0)}function TOe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~((l+-8-f|0)>>>3)<<3)),gt(c))}function NOe(s){s=s|0;var l=0;l=Vr()|0,zr(s,1,11,l,LOe()|0,1),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function LOe(){return 1852}function MOe(s,l){return s=s|0,l=l|0,UOe(n[(OOe(s)|0)>>2]|0,l)|0}function OOe(s){return s=s|0,(n[(lR()|0)+24>>2]|0)+(s<<3)|0}function UOe(s,l){s=s|0,l=l|0;var c=0,f=0;return c=C,C=C+16|0,f=c,v0(f,l),l=D0(f,l)|0,l=jv(F0[s&31](l)|0)|0,C=c,l|0}function _Oe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0;m=n[s>>2]|0,d=cR()|0,s=HOe(c)|0,hn(m,l,d,s,qOe(c,f)|0,f)}function cR(){var s=0,l=0;if(o[8056]|0||(G9(10932),ir(67,10932,U|0)|0,l=8056,n[l>>2]=1,n[l+4>>2]=0),!(Rr(10932)|0)){s=10932,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));G9(10932)}return 10932}function HOe(s){return s=s|0,s|0}function qOe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0;return k=C,C=C+16|0,d=k,m=k+4|0,n[d>>2]=s,Q=cR()|0,B=Q+24|0,l=gr(l,4)|0,n[m>>2]=l,c=Q+28|0,f=n[c>>2]|0,f>>>0<(n[Q+32>>2]|0)>>>0?(j9(f,s,l),l=(n[c>>2]|0)+8|0,n[c>>2]=l):(jOe(B,d,m),l=n[c>>2]|0),C=k,(l-(n[B>>2]|0)>>3)+-1|0}function j9(s,l,c){s=s|0,l=l|0,c=c|0,n[s>>2]=l,n[s+4>>2]=c}function jOe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0;if(k=C,C=C+32|0,d=k,m=s+4|0,B=((n[m>>2]|0)-(n[s>>2]|0)>>3)+1|0,f=GOe(s)|0,f>>>0>>0)Jr(s);else{Q=n[s>>2]|0,M=(n[s+8>>2]|0)-Q|0,O=M>>2,YOe(d,M>>3>>>0>>1>>>0?O>>>0>>0?B:O:f,(n[m>>2]|0)-Q>>3,s+8|0),B=d+8|0,j9(n[B>>2]|0,n[l>>2]|0,n[c>>2]|0),n[B>>2]=(n[B>>2]|0)+8,WOe(s,d),KOe(d),C=k;return}}function GOe(s){return s=s|0,536870911}function YOe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>536870911)Tt();else{d=Kt(l<<3)|0;break}else d=0;while(!1);n[s>>2]=d,f=d+(c<<3)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l<<3)}function WOe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(0-(d>>3)<<3)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function KOe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~((f+-8-l|0)>>>3)<<3)),s=n[s>>2]|0,s|0&>(s)}function G9(s){s=s|0,JOe(s)}function VOe(s){s=s|0,zOe(s+24|0)}function zOe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~((l+-8-f|0)>>>3)<<3)),gt(c))}function JOe(s){s=s|0;var l=0;l=Vr()|0,zr(s,1,7,l,XOe()|0,2),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function XOe(){return 1860}function ZOe(s,l,c){return s=s|0,l=l|0,c=c|0,e4e(n[($Oe(s)|0)>>2]|0,l,c)|0}function $Oe(s){return s=s|0,(n[(cR()|0)+24>>2]|0)+(s<<3)|0}function e4e(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0;return f=C,C=C+32|0,B=f+12|0,m=f+8|0,k=f,Q=f+16|0,d=f+4|0,t4e(Q,l),r4e(k,Q,l),Ip(d,c),c=Bp(d,c)|0,n[B>>2]=n[k>>2],vw[s&15](m,B,c),c=n4e(m)|0,jA(m),vp(d),C=f,c|0}function t4e(s,l){s=s|0,l=l|0}function r4e(s,l,c){s=s|0,l=l|0,c=c|0,i4e(s,c)}function n4e(s){return s=s|0,ya(s)|0}function i4e(s,l){s=s|0,l=l|0;var c=0,f=0,d=0;d=C,C=C+16|0,c=d,f=l,f&1?(s4e(c,0),ii(f|0,c|0)|0,o4e(s,c),a4e(c)):n[s>>2]=n[l>>2],C=d}function s4e(s,l){s=s|0,l=l|0,K5(s,l),n[s+4>>2]=0,o[s+8>>0]=0}function o4e(s,l){s=s|0,l=l|0,n[s>>2]=n[l+4>>2]}function a4e(s){s=s|0,o[s+8>>0]=0}function l4e(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0;m=n[s>>2]|0,d=uR()|0,s=c4e(c)|0,hn(m,l,d,s,u4e(c,f)|0,f)}function uR(){var s=0,l=0;if(o[8064]|0||(W9(10968),ir(68,10968,U|0)|0,l=8064,n[l>>2]=1,n[l+4>>2]=0),!(Rr(10968)|0)){s=10968,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));W9(10968)}return 10968}function c4e(s){return s=s|0,s|0}function u4e(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0;return k=C,C=C+16|0,d=k,m=k+4|0,n[d>>2]=s,Q=uR()|0,B=Q+24|0,l=gr(l,4)|0,n[m>>2]=l,c=Q+28|0,f=n[c>>2]|0,f>>>0<(n[Q+32>>2]|0)>>>0?(Y9(f,s,l),l=(n[c>>2]|0)+8|0,n[c>>2]=l):(A4e(B,d,m),l=n[c>>2]|0),C=k,(l-(n[B>>2]|0)>>3)+-1|0}function Y9(s,l,c){s=s|0,l=l|0,c=c|0,n[s>>2]=l,n[s+4>>2]=c}function A4e(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0;if(k=C,C=C+32|0,d=k,m=s+4|0,B=((n[m>>2]|0)-(n[s>>2]|0)>>3)+1|0,f=f4e(s)|0,f>>>0>>0)Jr(s);else{Q=n[s>>2]|0,M=(n[s+8>>2]|0)-Q|0,O=M>>2,p4e(d,M>>3>>>0>>1>>>0?O>>>0>>0?B:O:f,(n[m>>2]|0)-Q>>3,s+8|0),B=d+8|0,Y9(n[B>>2]|0,n[l>>2]|0,n[c>>2]|0),n[B>>2]=(n[B>>2]|0)+8,h4e(s,d),g4e(d),C=k;return}}function f4e(s){return s=s|0,536870911}function p4e(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>536870911)Tt();else{d=Kt(l<<3)|0;break}else d=0;while(!1);n[s>>2]=d,f=d+(c<<3)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l<<3)}function h4e(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(0-(d>>3)<<3)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function g4e(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~((f+-8-l|0)>>>3)<<3)),s=n[s>>2]|0,s|0&>(s)}function W9(s){s=s|0,y4e(s)}function d4e(s){s=s|0,m4e(s+24|0)}function m4e(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~((l+-8-f|0)>>>3)<<3)),gt(c))}function y4e(s){s=s|0;var l=0;l=Vr()|0,zr(s,1,1,l,E4e()|0,5),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function E4e(){return 1872}function C4e(s,l,c,f,d,m){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0,m=m|0,I4e(n[(w4e(s)|0)>>2]|0,l,c,f,d,m)}function w4e(s){return s=s|0,(n[(uR()|0)+24>>2]|0)+(s<<3)|0}function I4e(s,l,c,f,d,m){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0,m=m|0;var B=0,k=0,Q=0,O=0,M=0,j=0;B=C,C=C+32|0,k=B+16|0,Q=B+12|0,O=B+8|0,M=B+4|0,j=B,Ip(k,l),l=Bp(k,l)|0,Ip(Q,c),c=Bp(Q,c)|0,Ip(O,f),f=Bp(O,f)|0,Ip(M,d),d=Bp(M,d)|0,Ip(j,m),m=Bp(j,m)|0,h7[s&1](l,c,f,d,m),vp(j),vp(M),vp(O),vp(Q),vp(k),C=B}function B4e(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0;m=n[s>>2]|0,d=AR()|0,s=v4e(c)|0,hn(m,l,d,s,D4e(c,f)|0,f)}function AR(){var s=0,l=0;if(o[8072]|0||(V9(11004),ir(69,11004,U|0)|0,l=8072,n[l>>2]=1,n[l+4>>2]=0),!(Rr(11004)|0)){s=11004,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));V9(11004)}return 11004}function v4e(s){return s=s|0,s|0}function D4e(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0;return k=C,C=C+16|0,d=k,m=k+4|0,n[d>>2]=s,Q=AR()|0,B=Q+24|0,l=gr(l,4)|0,n[m>>2]=l,c=Q+28|0,f=n[c>>2]|0,f>>>0<(n[Q+32>>2]|0)>>>0?(K9(f,s,l),l=(n[c>>2]|0)+8|0,n[c>>2]=l):(P4e(B,d,m),l=n[c>>2]|0),C=k,(l-(n[B>>2]|0)>>3)+-1|0}function K9(s,l,c){s=s|0,l=l|0,c=c|0,n[s>>2]=l,n[s+4>>2]=c}function P4e(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0;if(k=C,C=C+32|0,d=k,m=s+4|0,B=((n[m>>2]|0)-(n[s>>2]|0)>>3)+1|0,f=b4e(s)|0,f>>>0>>0)Jr(s);else{Q=n[s>>2]|0,M=(n[s+8>>2]|0)-Q|0,O=M>>2,S4e(d,M>>3>>>0>>1>>>0?O>>>0>>0?B:O:f,(n[m>>2]|0)-Q>>3,s+8|0),B=d+8|0,K9(n[B>>2]|0,n[l>>2]|0,n[c>>2]|0),n[B>>2]=(n[B>>2]|0)+8,x4e(s,d),k4e(d),C=k;return}}function b4e(s){return s=s|0,536870911}function S4e(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>536870911)Tt();else{d=Kt(l<<3)|0;break}else d=0;while(!1);n[s>>2]=d,f=d+(c<<3)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l<<3)}function x4e(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(0-(d>>3)<<3)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function k4e(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~((f+-8-l|0)>>>3)<<3)),s=n[s>>2]|0,s|0&>(s)}function V9(s){s=s|0,R4e(s)}function Q4e(s){s=s|0,F4e(s+24|0)}function F4e(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~((l+-8-f|0)>>>3)<<3)),gt(c))}function R4e(s){s=s|0;var l=0;l=Vr()|0,zr(s,1,12,l,T4e()|0,2),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function T4e(){return 1896}function N4e(s,l,c){s=s|0,l=l|0,c=c|0,M4e(n[(L4e(s)|0)>>2]|0,l,c)}function L4e(s){return s=s|0,(n[(AR()|0)+24>>2]|0)+(s<<3)|0}function M4e(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0;f=C,C=C+16|0,m=f+4|0,d=f,O4e(m,l),l=U4e(m,l)|0,Ip(d,c),c=Bp(d,c)|0,tf[s&31](l,c),vp(d),C=f}function O4e(s,l){s=s|0,l=l|0}function U4e(s,l){return s=s|0,l=l|0,_4e(l)|0}function _4e(s){return s=s|0,s|0}function H4e(){var s=0;return o[8080]|0||(z9(11040),ir(70,11040,U|0)|0,s=8080,n[s>>2]=1,n[s+4>>2]=0),Rr(11040)|0||z9(11040),11040}function z9(s){s=s|0,G4e(s),b0(s,71)}function q4e(s){s=s|0,j4e(s+24|0)}function j4e(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~((l+-8-f|0)>>>3)<<3)),gt(c))}function G4e(s){s=s|0;var l=0;l=Vr()|0,zr(s,5,7,l,V4e()|0,0),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function Y4e(s){s=s|0,W4e(s)}function W4e(s){s=s|0,K4e(s)}function K4e(s){s=s|0,o[s+8>>0]=1}function V4e(){return 1936}function z4e(){return J4e()|0}function J4e(){var s=0,l=0,c=0,f=0,d=0,m=0,B=0;return l=C,C=C+16|0,d=l+4|0,B=l,c=Va(8)|0,s=c,m=s+4|0,n[m>>2]=Kt(1)|0,f=Kt(8)|0,m=n[m>>2]|0,n[B>>2]=0,n[d>>2]=n[B>>2],X4e(f,m,d),n[c>>2]=f,C=l,s|0}function X4e(s,l,c){s=s|0,l=l|0,c=c|0,n[s>>2]=l,c=Kt(16)|0,n[c+4>>2]=0,n[c+8>>2]=0,n[c>>2]=1916,n[c+12>>2]=l,n[s+4>>2]=c}function Z4e(s){s=s|0,Md(s),gt(s)}function $4e(s){s=s|0,s=n[s+12>>2]|0,s|0&>(s)}function eUe(s){s=s|0,gt(s)}function tUe(){var s=0;return o[8088]|0||(lUe(11076),ir(25,11076,U|0)|0,s=8088,n[s>>2]=1,n[s+4>>2]=0),11076}function rUe(s,l){s=s|0,l=l|0,n[s>>2]=nUe()|0,n[s+4>>2]=iUe()|0,n[s+12>>2]=l,n[s+8>>2]=sUe()|0,n[s+32>>2]=10}function nUe(){return 11745}function iUe(){return 1940}function sUe(){return Gv()|0}function oUe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0,(Dp(f,896)|0)==512?c|0&&(aUe(c),gt(c)):l|0&>(l)}function aUe(s){s=s|0,s=n[s+4>>2]|0,s|0&&bp(s)}function lUe(s){s=s|0,wp(s)}function xc(s,l){s=s|0,l=l|0,n[s>>2]=l}function fR(s){return s=s|0,n[s>>2]|0}function cUe(s){return s=s|0,o[n[s>>2]>>0]|0}function uUe(s,l){s=s|0,l=l|0;var c=0,f=0;c=C,C=C+16|0,f=c,n[f>>2]=n[s>>2],AUe(l,f)|0,C=c}function AUe(s,l){s=s|0,l=l|0;var c=0;return c=fUe(n[s>>2]|0,l)|0,l=s+4|0,n[(n[l>>2]|0)+8>>2]=c,n[(n[l>>2]|0)+8>>2]|0}function fUe(s,l){s=s|0,l=l|0;var c=0,f=0;return c=C,C=C+16|0,f=c,za(f),s=ya(s)|0,l=pUe(s,n[l>>2]|0)|0,Ja(f),C=c,l|0}function za(s){s=s|0,n[s>>2]=n[2701],n[s+4>>2]=n[2703]}function pUe(s,l){s=s|0,l=l|0;var c=0;return c=Pl(hUe()|0)|0,Qn(0,c|0,s|0,sR(l)|0)|0}function Ja(s){s=s|0,O9(n[s>>2]|0,n[s+4>>2]|0)}function hUe(){var s=0;return o[8096]|0||(gUe(11120),s=8096,n[s>>2]=1,n[s+4>>2]=0),11120}function gUe(s){s=s|0,bl(s,dUe()|0,1)}function dUe(){return 1948}function mUe(){yUe()}function yUe(){var s=0,l=0,c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0,se=0,je=0,Oe=0,Qe=0;if(Oe=C,C=C+16|0,M=Oe+4|0,j=Oe,Ti(65536,10804,n[2702]|0,10812),c=E9()|0,l=n[c>>2]|0,s=n[l>>2]|0,s|0)for(f=n[c+8>>2]|0,c=n[c+4>>2]|0;Ac(s|0,u[c>>0]|0|0,o[f>>0]|0),l=l+4|0,s=n[l>>2]|0,s;)f=f+1|0,c=c+1|0;if(s=C9()|0,l=n[s>>2]|0,l|0)do fu(l|0,n[s+4>>2]|0),s=s+8|0,l=n[s>>2]|0;while(l|0);fu(EUe()|0,5167),O=Fd()|0,s=n[O>>2]|0;e:do if(s|0){do CUe(n[s+4>>2]|0),s=n[s>>2]|0;while(s|0);if(s=n[O>>2]|0,s|0){Q=O;do{for(;d=s,s=n[s>>2]|0,d=n[d+4>>2]|0,!!(wUe(d)|0);)if(n[j>>2]=Q,n[M>>2]=n[j>>2],IUe(O,M)|0,!s)break e;if(BUe(d),Q=n[Q>>2]|0,l=J9(d)|0,m=Hi()|0,B=C,C=C+((1*(l<<2)|0)+15&-16)|0,k=C,C=C+((1*(l<<2)|0)+15&-16)|0,l=n[(F9(d)|0)>>2]|0,l|0)for(c=B,f=k;n[c>>2]=n[(Rd(n[l+4>>2]|0)|0)>>2],n[f>>2]=n[l+8>>2],l=n[l>>2]|0,l;)c=c+4|0,f=f+4|0;Qe=Rd(d)|0,l=vUe(d)|0,c=J9(d)|0,f=DUe(d)|0,pu(Qe|0,l|0,B|0,k|0,c|0,f|0,$F(d)|0),_i(m|0)}while(s|0)}}while(!1);if(s=n[(eR()|0)>>2]|0,s|0)do Qe=s+4|0,O=tR(Qe)|0,d=Cw(O)|0,m=yw(O)|0,B=(Ew(O)|0)+1|0,k=zv(O)|0,Q=X9(Qe)|0,O=Rr(O)|0,M=Wv(Qe)|0,j=pR(Qe)|0,El(0,d|0,m|0,B|0,k|0,Q|0,O|0,M|0,j|0,hR(Qe)|0),s=n[s>>2]|0;while(s|0);s=n[(Fd()|0)>>2]|0;e:do if(s|0){t:for(;;){if(l=n[s+4>>2]|0,l|0&&(se=n[(Rd(l)|0)>>2]|0,je=n[(R9(l)|0)>>2]|0,je|0)){c=je;do{l=c+4|0,f=tR(l)|0;r:do if(f|0)switch(Rr(f)|0){case 0:break t;case 4:case 3:case 2:{k=Cw(f)|0,Q=yw(f)|0,O=(Ew(f)|0)+1|0,M=zv(f)|0,j=Rr(f)|0,Qe=Wv(l)|0,El(se|0,k|0,Q|0,O|0,M|0,0,j|0,Qe|0,pR(l)|0,hR(l)|0);break r}case 1:{B=Cw(f)|0,k=yw(f)|0,Q=(Ew(f)|0)+1|0,O=zv(f)|0,M=X9(l)|0,j=Rr(f)|0,Qe=Wv(l)|0,El(se|0,B|0,k|0,Q|0,O|0,M|0,j|0,Qe|0,pR(l)|0,hR(l)|0);break r}case 5:{O=Cw(f)|0,M=yw(f)|0,j=(Ew(f)|0)+1|0,Qe=zv(f)|0,El(se|0,O|0,M|0,j|0,Qe|0,PUe(f)|0,Rr(f)|0,0,0,0);break r}default:break r}while(!1);c=n[c>>2]|0}while(c|0)}if(s=n[s>>2]|0,!s)break e}Tt()}while(!1);Ie(),C=Oe}function EUe(){return 11703}function CUe(s){s=s|0,o[s+40>>0]=0}function wUe(s){return s=s|0,(o[s+40>>0]|0)!=0|0}function IUe(s,l){return s=s|0,l=l|0,l=bUe(l)|0,s=n[l>>2]|0,n[l>>2]=n[s>>2],gt(s),n[l>>2]|0}function BUe(s){s=s|0,o[s+40>>0]=1}function J9(s){return s=s|0,n[s+20>>2]|0}function vUe(s){return s=s|0,n[s+8>>2]|0}function DUe(s){return s=s|0,n[s+32>>2]|0}function zv(s){return s=s|0,n[s+4>>2]|0}function X9(s){return s=s|0,n[s+4>>2]|0}function pR(s){return s=s|0,n[s+8>>2]|0}function hR(s){return s=s|0,n[s+16>>2]|0}function PUe(s){return s=s|0,n[s+20>>2]|0}function bUe(s){return s=s|0,n[s>>2]|0}function Jv(s){s=s|0;var l=0,c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0,se=0,je=0,Oe=0,Qe=0,$e=0,Je=0,lt=0,_e=0,qe=0,Lt=0;Lt=C,C=C+16|0,se=Lt;do if(s>>>0<245){if(O=s>>>0<11?16:s+11&-8,s=O>>>3,j=n[2783]|0,c=j>>>s,c&3|0)return l=(c&1^1)+s|0,s=11172+(l<<1<<2)|0,c=s+8|0,f=n[c>>2]|0,d=f+8|0,m=n[d>>2]|0,(s|0)==(m|0)?n[2783]=j&~(1<>2]=s,n[c>>2]=m),qe=l<<3,n[f+4>>2]=qe|3,qe=f+qe+4|0,n[qe>>2]=n[qe>>2]|1,qe=d,C=Lt,qe|0;if(M=n[2785]|0,O>>>0>M>>>0){if(c|0)return l=2<>>12&16,l=l>>>B,c=l>>>5&8,l=l>>>c,d=l>>>2&4,l=l>>>d,s=l>>>1&2,l=l>>>s,f=l>>>1&1,f=(c|B|d|s|f)+(l>>>f)|0,l=11172+(f<<1<<2)|0,s=l+8|0,d=n[s>>2]|0,B=d+8|0,c=n[B>>2]|0,(l|0)==(c|0)?(s=j&~(1<>2]=l,n[s>>2]=c,s=j),m=(f<<3)-O|0,n[d+4>>2]=O|3,f=d+O|0,n[f+4>>2]=m|1,n[f+m>>2]=m,M|0&&(d=n[2788]|0,l=M>>>3,c=11172+(l<<1<<2)|0,l=1<>2]|0):(n[2783]=s|l,l=c,s=c+8|0),n[s>>2]=d,n[l+12>>2]=d,n[d+8>>2]=l,n[d+12>>2]=c),n[2785]=m,n[2788]=f,qe=B,C=Lt,qe|0;if(k=n[2784]|0,k){if(c=(k&0-k)+-1|0,B=c>>>12&16,c=c>>>B,m=c>>>5&8,c=c>>>m,Q=c>>>2&4,c=c>>>Q,f=c>>>1&2,c=c>>>f,s=c>>>1&1,s=n[11436+((m|B|Q|f|s)+(c>>>s)<<2)>>2]|0,c=(n[s+4>>2]&-8)-O|0,f=n[s+16+(((n[s+16>>2]|0)==0&1)<<2)>>2]|0,!f)Q=s,m=c;else{do B=(n[f+4>>2]&-8)-O|0,Q=B>>>0>>0,c=Q?B:c,s=Q?f:s,f=n[f+16+(((n[f+16>>2]|0)==0&1)<<2)>>2]|0;while(f|0);Q=s,m=c}if(B=Q+O|0,Q>>>0>>0){d=n[Q+24>>2]|0,l=n[Q+12>>2]|0;do if((l|0)==(Q|0)){if(s=Q+20|0,l=n[s>>2]|0,!l&&(s=Q+16|0,l=n[s>>2]|0,!l)){c=0;break}for(;;){if(c=l+20|0,f=n[c>>2]|0,f|0){l=f,s=c;continue}if(c=l+16|0,f=n[c>>2]|0,f)l=f,s=c;else break}n[s>>2]=0,c=l}else c=n[Q+8>>2]|0,n[c+12>>2]=l,n[l+8>>2]=c,c=l;while(!1);do if(d|0){if(l=n[Q+28>>2]|0,s=11436+(l<<2)|0,(Q|0)==(n[s>>2]|0)){if(n[s>>2]=c,!c){n[2784]=k&~(1<>2]|0)!=(Q|0)&1)<<2)>>2]=c,!c)break;n[c+24>>2]=d,l=n[Q+16>>2]|0,l|0&&(n[c+16>>2]=l,n[l+24>>2]=c),l=n[Q+20>>2]|0,l|0&&(n[c+20>>2]=l,n[l+24>>2]=c)}while(!1);return m>>>0<16?(qe=m+O|0,n[Q+4>>2]=qe|3,qe=Q+qe+4|0,n[qe>>2]=n[qe>>2]|1):(n[Q+4>>2]=O|3,n[B+4>>2]=m|1,n[B+m>>2]=m,M|0&&(f=n[2788]|0,l=M>>>3,c=11172+(l<<1<<2)|0,l=1<>2]|0):(n[2783]=j|l,l=c,s=c+8|0),n[s>>2]=f,n[l+12>>2]=f,n[f+8>>2]=l,n[f+12>>2]=c),n[2785]=m,n[2788]=B),qe=Q+8|0,C=Lt,qe|0}else j=O}else j=O}else j=O}else if(s>>>0<=4294967231)if(s=s+11|0,O=s&-8,Q=n[2784]|0,Q){f=0-O|0,s=s>>>8,s?O>>>0>16777215?k=31:(j=(s+1048320|0)>>>16&8,_e=s<>>16&4,_e=_e<>>16&2,k=14-(M|j|k)+(_e<>>15)|0,k=O>>>(k+7|0)&1|k<<1):k=0,c=n[11436+(k<<2)>>2]|0;e:do if(!c)c=0,s=0,_e=57;else for(s=0,B=O<<((k|0)==31?0:25-(k>>>1)|0),m=0;;){if(d=(n[c+4>>2]&-8)-O|0,d>>>0>>0)if(d)s=c,f=d;else{s=c,f=0,d=c,_e=61;break e}if(d=n[c+20>>2]|0,c=n[c+16+(B>>>31<<2)>>2]|0,m=(d|0)==0|(d|0)==(c|0)?m:d,d=(c|0)==0,d){c=m,_e=57;break}else B=B<<((d^1)&1)}while(!1);if((_e|0)==57){if((c|0)==0&(s|0)==0){if(s=2<>>12&16,j=j>>>B,m=j>>>5&8,j=j>>>m,k=j>>>2&4,j=j>>>k,M=j>>>1&2,j=j>>>M,c=j>>>1&1,s=0,c=n[11436+((m|B|k|M|c)+(j>>>c)<<2)>>2]|0}c?(d=c,_e=61):(k=s,B=f)}if((_e|0)==61)for(;;)if(_e=0,c=(n[d+4>>2]&-8)-O|0,j=c>>>0>>0,c=j?c:f,s=j?d:s,d=n[d+16+(((n[d+16>>2]|0)==0&1)<<2)>>2]|0,d)f=c,_e=61;else{k=s,B=c;break}if(k|0&&B>>>0<((n[2785]|0)-O|0)>>>0){if(m=k+O|0,k>>>0>=m>>>0)return qe=0,C=Lt,qe|0;d=n[k+24>>2]|0,l=n[k+12>>2]|0;do if((l|0)==(k|0)){if(s=k+20|0,l=n[s>>2]|0,!l&&(s=k+16|0,l=n[s>>2]|0,!l)){l=0;break}for(;;){if(c=l+20|0,f=n[c>>2]|0,f|0){l=f,s=c;continue}if(c=l+16|0,f=n[c>>2]|0,f)l=f,s=c;else break}n[s>>2]=0}else qe=n[k+8>>2]|0,n[qe+12>>2]=l,n[l+8>>2]=qe;while(!1);do if(d){if(s=n[k+28>>2]|0,c=11436+(s<<2)|0,(k|0)==(n[c>>2]|0)){if(n[c>>2]=l,!l){f=Q&~(1<>2]|0)!=(k|0)&1)<<2)>>2]=l,!l){f=Q;break}n[l+24>>2]=d,s=n[k+16>>2]|0,s|0&&(n[l+16>>2]=s,n[s+24>>2]=l),s=n[k+20>>2]|0,s&&(n[l+20>>2]=s,n[s+24>>2]=l),f=Q}else f=Q;while(!1);do if(B>>>0>=16){if(n[k+4>>2]=O|3,n[m+4>>2]=B|1,n[m+B>>2]=B,l=B>>>3,B>>>0<256){c=11172+(l<<1<<2)|0,s=n[2783]|0,l=1<>2]|0):(n[2783]=s|l,l=c,s=c+8|0),n[s>>2]=m,n[l+12>>2]=m,n[m+8>>2]=l,n[m+12>>2]=c;break}if(l=B>>>8,l?B>>>0>16777215?l=31:(_e=(l+1048320|0)>>>16&8,qe=l<<_e,lt=(qe+520192|0)>>>16&4,qe=qe<>>16&2,l=14-(lt|_e|l)+(qe<>>15)|0,l=B>>>(l+7|0)&1|l<<1):l=0,c=11436+(l<<2)|0,n[m+28>>2]=l,s=m+16|0,n[s+4>>2]=0,n[s>>2]=0,s=1<>2]=m,n[m+24>>2]=c,n[m+12>>2]=m,n[m+8>>2]=m;break}for(s=B<<((l|0)==31?0:25-(l>>>1)|0),c=n[c>>2]|0;;){if((n[c+4>>2]&-8|0)==(B|0)){_e=97;break}if(f=c+16+(s>>>31<<2)|0,l=n[f>>2]|0,l)s=s<<1,c=l;else{_e=96;break}}if((_e|0)==96){n[f>>2]=m,n[m+24>>2]=c,n[m+12>>2]=m,n[m+8>>2]=m;break}else if((_e|0)==97){_e=c+8|0,qe=n[_e>>2]|0,n[qe+12>>2]=m,n[_e>>2]=m,n[m+8>>2]=qe,n[m+12>>2]=c,n[m+24>>2]=0;break}}else qe=B+O|0,n[k+4>>2]=qe|3,qe=k+qe+4|0,n[qe>>2]=n[qe>>2]|1;while(!1);return qe=k+8|0,C=Lt,qe|0}else j=O}else j=O;else j=-1;while(!1);if(c=n[2785]|0,c>>>0>=j>>>0)return l=c-j|0,s=n[2788]|0,l>>>0>15?(qe=s+j|0,n[2788]=qe,n[2785]=l,n[qe+4>>2]=l|1,n[qe+l>>2]=l,n[s+4>>2]=j|3):(n[2785]=0,n[2788]=0,n[s+4>>2]=c|3,qe=s+c+4|0,n[qe>>2]=n[qe>>2]|1),qe=s+8|0,C=Lt,qe|0;if(B=n[2786]|0,B>>>0>j>>>0)return lt=B-j|0,n[2786]=lt,qe=n[2789]|0,_e=qe+j|0,n[2789]=_e,n[_e+4>>2]=lt|1,n[qe+4>>2]=j|3,qe=qe+8|0,C=Lt,qe|0;if(n[2901]|0?s=n[2903]|0:(n[2903]=4096,n[2902]=4096,n[2904]=-1,n[2905]=-1,n[2906]=0,n[2894]=0,s=se&-16^1431655768,n[se>>2]=s,n[2901]=s,s=4096),k=j+48|0,Q=j+47|0,m=s+Q|0,d=0-s|0,O=m&d,O>>>0<=j>>>0||(s=n[2893]|0,s|0&&(M=n[2891]|0,se=M+O|0,se>>>0<=M>>>0|se>>>0>s>>>0)))return qe=0,C=Lt,qe|0;e:do if(n[2894]&4)l=0,_e=133;else{c=n[2789]|0;t:do if(c){for(f=11580;s=n[f>>2]|0,!(s>>>0<=c>>>0&&(Qe=f+4|0,(s+(n[Qe>>2]|0)|0)>>>0>c>>>0));)if(s=n[f+8>>2]|0,s)f=s;else{_e=118;break t}if(l=m-B&d,l>>>0<2147483647)if(s=Sp(l|0)|0,(s|0)==((n[f>>2]|0)+(n[Qe>>2]|0)|0)){if((s|0)!=-1){B=l,m=s,_e=135;break e}}else f=s,_e=126;else l=0}else _e=118;while(!1);do if((_e|0)==118)if(c=Sp(0)|0,(c|0)!=-1&&(l=c,je=n[2902]|0,Oe=je+-1|0,l=(Oe&l|0?(Oe+l&0-je)-l|0:0)+O|0,je=n[2891]|0,Oe=l+je|0,l>>>0>j>>>0&l>>>0<2147483647)){if(Qe=n[2893]|0,Qe|0&&Oe>>>0<=je>>>0|Oe>>>0>Qe>>>0){l=0;break}if(s=Sp(l|0)|0,(s|0)==(c|0)){B=l,m=c,_e=135;break e}else f=s,_e=126}else l=0;while(!1);do if((_e|0)==126){if(c=0-l|0,!(k>>>0>l>>>0&(l>>>0<2147483647&(f|0)!=-1)))if((f|0)==-1){l=0;break}else{B=l,m=f,_e=135;break e}if(s=n[2903]|0,s=Q-l+s&0-s,s>>>0>=2147483647){B=l,m=f,_e=135;break e}if((Sp(s|0)|0)==-1){Sp(c|0)|0,l=0;break}else{B=s+l|0,m=f,_e=135;break e}}while(!1);n[2894]=n[2894]|4,_e=133}while(!1);if((_e|0)==133&&O>>>0<2147483647&&(lt=Sp(O|0)|0,Qe=Sp(0)|0,$e=Qe-lt|0,Je=$e>>>0>(j+40|0)>>>0,!((lt|0)==-1|Je^1|lt>>>0>>0&((lt|0)!=-1&(Qe|0)!=-1)^1))&&(B=Je?$e:l,m=lt,_e=135),(_e|0)==135){l=(n[2891]|0)+B|0,n[2891]=l,l>>>0>(n[2892]|0)>>>0&&(n[2892]=l),Q=n[2789]|0;do if(Q){for(l=11580;;){if(s=n[l>>2]|0,c=l+4|0,f=n[c>>2]|0,(m|0)==(s+f|0)){_e=145;break}if(d=n[l+8>>2]|0,d)l=d;else break}if((_e|0)==145&&!(n[l+12>>2]&8|0)&&Q>>>0>>0&Q>>>0>=s>>>0){n[c>>2]=f+B,qe=Q+8|0,qe=qe&7|0?0-qe&7:0,_e=Q+qe|0,qe=(n[2786]|0)+(B-qe)|0,n[2789]=_e,n[2786]=qe,n[_e+4>>2]=qe|1,n[_e+qe+4>>2]=40,n[2790]=n[2905];break}for(m>>>0<(n[2787]|0)>>>0&&(n[2787]=m),c=m+B|0,l=11580;;){if((n[l>>2]|0)==(c|0)){_e=153;break}if(s=n[l+8>>2]|0,s)l=s;else break}if((_e|0)==153&&!(n[l+12>>2]&8|0)){n[l>>2]=m,M=l+4|0,n[M>>2]=(n[M>>2]|0)+B,M=m+8|0,M=m+(M&7|0?0-M&7:0)|0,l=c+8|0,l=c+(l&7|0?0-l&7:0)|0,O=M+j|0,k=l-M-j|0,n[M+4>>2]=j|3;do if((l|0)!=(Q|0)){if((l|0)==(n[2788]|0)){qe=(n[2785]|0)+k|0,n[2785]=qe,n[2788]=O,n[O+4>>2]=qe|1,n[O+qe>>2]=qe;break}if(s=n[l+4>>2]|0,(s&3|0)==1){B=s&-8,f=s>>>3;e:do if(s>>>0<256)if(s=n[l+8>>2]|0,c=n[l+12>>2]|0,(c|0)==(s|0)){n[2783]=n[2783]&~(1<>2]=c,n[c+8>>2]=s;break}else{m=n[l+24>>2]|0,s=n[l+12>>2]|0;do if((s|0)==(l|0)){if(f=l+16|0,c=f+4|0,s=n[c>>2]|0,!s)if(s=n[f>>2]|0,s)c=f;else{s=0;break}for(;;){if(f=s+20|0,d=n[f>>2]|0,d|0){s=d,c=f;continue}if(f=s+16|0,d=n[f>>2]|0,d)s=d,c=f;else break}n[c>>2]=0}else qe=n[l+8>>2]|0,n[qe+12>>2]=s,n[s+8>>2]=qe;while(!1);if(!m)break;c=n[l+28>>2]|0,f=11436+(c<<2)|0;do if((l|0)!=(n[f>>2]|0)){if(n[m+16+(((n[m+16>>2]|0)!=(l|0)&1)<<2)>>2]=s,!s)break e}else{if(n[f>>2]=s,s|0)break;n[2784]=n[2784]&~(1<>2]=m,c=l+16|0,f=n[c>>2]|0,f|0&&(n[s+16>>2]=f,n[f+24>>2]=s),c=n[c+4>>2]|0,!c)break;n[s+20>>2]=c,n[c+24>>2]=s}while(!1);l=l+B|0,d=B+k|0}else d=k;if(l=l+4|0,n[l>>2]=n[l>>2]&-2,n[O+4>>2]=d|1,n[O+d>>2]=d,l=d>>>3,d>>>0<256){c=11172+(l<<1<<2)|0,s=n[2783]|0,l=1<>2]|0):(n[2783]=s|l,l=c,s=c+8|0),n[s>>2]=O,n[l+12>>2]=O,n[O+8>>2]=l,n[O+12>>2]=c;break}l=d>>>8;do if(!l)l=0;else{if(d>>>0>16777215){l=31;break}_e=(l+1048320|0)>>>16&8,qe=l<<_e,lt=(qe+520192|0)>>>16&4,qe=qe<>>16&2,l=14-(lt|_e|l)+(qe<>>15)|0,l=d>>>(l+7|0)&1|l<<1}while(!1);if(f=11436+(l<<2)|0,n[O+28>>2]=l,s=O+16|0,n[s+4>>2]=0,n[s>>2]=0,s=n[2784]|0,c=1<>2]=O,n[O+24>>2]=f,n[O+12>>2]=O,n[O+8>>2]=O;break}for(s=d<<((l|0)==31?0:25-(l>>>1)|0),c=n[f>>2]|0;;){if((n[c+4>>2]&-8|0)==(d|0)){_e=194;break}if(f=c+16+(s>>>31<<2)|0,l=n[f>>2]|0,l)s=s<<1,c=l;else{_e=193;break}}if((_e|0)==193){n[f>>2]=O,n[O+24>>2]=c,n[O+12>>2]=O,n[O+8>>2]=O;break}else if((_e|0)==194){_e=c+8|0,qe=n[_e>>2]|0,n[qe+12>>2]=O,n[_e>>2]=O,n[O+8>>2]=qe,n[O+12>>2]=c,n[O+24>>2]=0;break}}else qe=(n[2786]|0)+k|0,n[2786]=qe,n[2789]=O,n[O+4>>2]=qe|1;while(!1);return qe=M+8|0,C=Lt,qe|0}for(l=11580;s=n[l>>2]|0,!(s>>>0<=Q>>>0&&(qe=s+(n[l+4>>2]|0)|0,qe>>>0>Q>>>0));)l=n[l+8>>2]|0;d=qe+-47|0,s=d+8|0,s=d+(s&7|0?0-s&7:0)|0,d=Q+16|0,s=s>>>0>>0?Q:s,l=s+8|0,c=m+8|0,c=c&7|0?0-c&7:0,_e=m+c|0,c=B+-40-c|0,n[2789]=_e,n[2786]=c,n[_e+4>>2]=c|1,n[_e+c+4>>2]=40,n[2790]=n[2905],c=s+4|0,n[c>>2]=27,n[l>>2]=n[2895],n[l+4>>2]=n[2896],n[l+8>>2]=n[2897],n[l+12>>2]=n[2898],n[2895]=m,n[2896]=B,n[2898]=0,n[2897]=l,l=s+24|0;do _e=l,l=l+4|0,n[l>>2]=7;while((_e+8|0)>>>0>>0);if((s|0)!=(Q|0)){if(m=s-Q|0,n[c>>2]=n[c>>2]&-2,n[Q+4>>2]=m|1,n[s>>2]=m,l=m>>>3,m>>>0<256){c=11172+(l<<1<<2)|0,s=n[2783]|0,l=1<>2]|0):(n[2783]=s|l,l=c,s=c+8|0),n[s>>2]=Q,n[l+12>>2]=Q,n[Q+8>>2]=l,n[Q+12>>2]=c;break}if(l=m>>>8,l?m>>>0>16777215?c=31:(_e=(l+1048320|0)>>>16&8,qe=l<<_e,lt=(qe+520192|0)>>>16&4,qe=qe<>>16&2,c=14-(lt|_e|c)+(qe<>>15)|0,c=m>>>(c+7|0)&1|c<<1):c=0,f=11436+(c<<2)|0,n[Q+28>>2]=c,n[Q+20>>2]=0,n[d>>2]=0,l=n[2784]|0,s=1<>2]=Q,n[Q+24>>2]=f,n[Q+12>>2]=Q,n[Q+8>>2]=Q;break}for(s=m<<((c|0)==31?0:25-(c>>>1)|0),c=n[f>>2]|0;;){if((n[c+4>>2]&-8|0)==(m|0)){_e=216;break}if(f=c+16+(s>>>31<<2)|0,l=n[f>>2]|0,l)s=s<<1,c=l;else{_e=215;break}}if((_e|0)==215){n[f>>2]=Q,n[Q+24>>2]=c,n[Q+12>>2]=Q,n[Q+8>>2]=Q;break}else if((_e|0)==216){_e=c+8|0,qe=n[_e>>2]|0,n[qe+12>>2]=Q,n[_e>>2]=Q,n[Q+8>>2]=qe,n[Q+12>>2]=c,n[Q+24>>2]=0;break}}}else{qe=n[2787]|0,(qe|0)==0|m>>>0>>0&&(n[2787]=m),n[2895]=m,n[2896]=B,n[2898]=0,n[2792]=n[2901],n[2791]=-1,l=0;do qe=11172+(l<<1<<2)|0,n[qe+12>>2]=qe,n[qe+8>>2]=qe,l=l+1|0;while((l|0)!=32);qe=m+8|0,qe=qe&7|0?0-qe&7:0,_e=m+qe|0,qe=B+-40-qe|0,n[2789]=_e,n[2786]=qe,n[_e+4>>2]=qe|1,n[_e+qe+4>>2]=40,n[2790]=n[2905]}while(!1);if(l=n[2786]|0,l>>>0>j>>>0)return lt=l-j|0,n[2786]=lt,qe=n[2789]|0,_e=qe+j|0,n[2789]=_e,n[_e+4>>2]=lt|1,n[qe+4>>2]=j|3,qe=qe+8|0,C=Lt,qe|0}return n[(Nd()|0)>>2]=12,qe=0,C=Lt,qe|0}function Xv(s){s=s|0;var l=0,c=0,f=0,d=0,m=0,B=0,k=0,Q=0;if(s){c=s+-8|0,d=n[2787]|0,s=n[s+-4>>2]|0,l=s&-8,Q=c+l|0;do if(s&1)k=c,B=c;else{if(f=n[c>>2]|0,!(s&3)||(B=c+(0-f)|0,m=f+l|0,B>>>0>>0))return;if((B|0)==(n[2788]|0)){if(s=Q+4|0,l=n[s>>2]|0,(l&3|0)!=3){k=B,l=m;break}n[2785]=m,n[s>>2]=l&-2,n[B+4>>2]=m|1,n[B+m>>2]=m;return}if(c=f>>>3,f>>>0<256)if(s=n[B+8>>2]|0,l=n[B+12>>2]|0,(l|0)==(s|0)){n[2783]=n[2783]&~(1<>2]=l,n[l+8>>2]=s,k=B,l=m;break}d=n[B+24>>2]|0,s=n[B+12>>2]|0;do if((s|0)==(B|0)){if(c=B+16|0,l=c+4|0,s=n[l>>2]|0,!s)if(s=n[c>>2]|0,s)l=c;else{s=0;break}for(;;){if(c=s+20|0,f=n[c>>2]|0,f|0){s=f,l=c;continue}if(c=s+16|0,f=n[c>>2]|0,f)s=f,l=c;else break}n[l>>2]=0}else k=n[B+8>>2]|0,n[k+12>>2]=s,n[s+8>>2]=k;while(!1);if(d){if(l=n[B+28>>2]|0,c=11436+(l<<2)|0,(B|0)==(n[c>>2]|0)){if(n[c>>2]=s,!s){n[2784]=n[2784]&~(1<>2]|0)!=(B|0)&1)<<2)>>2]=s,!s){k=B,l=m;break}n[s+24>>2]=d,l=B+16|0,c=n[l>>2]|0,c|0&&(n[s+16>>2]=c,n[c+24>>2]=s),l=n[l+4>>2]|0,l?(n[s+20>>2]=l,n[l+24>>2]=s,k=B,l=m):(k=B,l=m)}else k=B,l=m}while(!1);if(!(B>>>0>=Q>>>0)&&(s=Q+4|0,f=n[s>>2]|0,!!(f&1))){if(f&2)n[s>>2]=f&-2,n[k+4>>2]=l|1,n[B+l>>2]=l,d=l;else{if(s=n[2788]|0,(Q|0)==(n[2789]|0)){if(Q=(n[2786]|0)+l|0,n[2786]=Q,n[2789]=k,n[k+4>>2]=Q|1,(k|0)!=(s|0))return;n[2788]=0,n[2785]=0;return}if((Q|0)==(s|0)){Q=(n[2785]|0)+l|0,n[2785]=Q,n[2788]=B,n[k+4>>2]=Q|1,n[B+Q>>2]=Q;return}d=(f&-8)+l|0,c=f>>>3;do if(f>>>0<256)if(l=n[Q+8>>2]|0,s=n[Q+12>>2]|0,(s|0)==(l|0)){n[2783]=n[2783]&~(1<>2]=s,n[s+8>>2]=l;break}else{m=n[Q+24>>2]|0,s=n[Q+12>>2]|0;do if((s|0)==(Q|0)){if(c=Q+16|0,l=c+4|0,s=n[l>>2]|0,!s)if(s=n[c>>2]|0,s)l=c;else{c=0;break}for(;;){if(c=s+20|0,f=n[c>>2]|0,f|0){s=f,l=c;continue}if(c=s+16|0,f=n[c>>2]|0,f)s=f,l=c;else break}n[l>>2]=0,c=s}else c=n[Q+8>>2]|0,n[c+12>>2]=s,n[s+8>>2]=c,c=s;while(!1);if(m|0){if(s=n[Q+28>>2]|0,l=11436+(s<<2)|0,(Q|0)==(n[l>>2]|0)){if(n[l>>2]=c,!c){n[2784]=n[2784]&~(1<>2]|0)!=(Q|0)&1)<<2)>>2]=c,!c)break;n[c+24>>2]=m,s=Q+16|0,l=n[s>>2]|0,l|0&&(n[c+16>>2]=l,n[l+24>>2]=c),s=n[s+4>>2]|0,s|0&&(n[c+20>>2]=s,n[s+24>>2]=c)}}while(!1);if(n[k+4>>2]=d|1,n[B+d>>2]=d,(k|0)==(n[2788]|0)){n[2785]=d;return}}if(s=d>>>3,d>>>0<256){c=11172+(s<<1<<2)|0,l=n[2783]|0,s=1<>2]|0):(n[2783]=l|s,s=c,l=c+8|0),n[l>>2]=k,n[s+12>>2]=k,n[k+8>>2]=s,n[k+12>>2]=c;return}s=d>>>8,s?d>>>0>16777215?s=31:(B=(s+1048320|0)>>>16&8,Q=s<>>16&4,Q=Q<>>16&2,s=14-(m|B|s)+(Q<>>15)|0,s=d>>>(s+7|0)&1|s<<1):s=0,f=11436+(s<<2)|0,n[k+28>>2]=s,n[k+20>>2]=0,n[k+16>>2]=0,l=n[2784]|0,c=1<>>1)|0),c=n[f>>2]|0;;){if((n[c+4>>2]&-8|0)==(d|0)){s=73;break}if(f=c+16+(l>>>31<<2)|0,s=n[f>>2]|0,s)l=l<<1,c=s;else{s=72;break}}if((s|0)==72){n[f>>2]=k,n[k+24>>2]=c,n[k+12>>2]=k,n[k+8>>2]=k;break}else if((s|0)==73){B=c+8|0,Q=n[B>>2]|0,n[Q+12>>2]=k,n[B>>2]=k,n[k+8>>2]=Q,n[k+12>>2]=c,n[k+24>>2]=0;break}}else n[2784]=l|c,n[f>>2]=k,n[k+24>>2]=f,n[k+12>>2]=k,n[k+8>>2]=k;while(!1);if(Q=(n[2791]|0)+-1|0,n[2791]=Q,!Q)s=11588;else return;for(;s=n[s>>2]|0,s;)s=s+8|0;n[2791]=-1}}}function SUe(){return 11628}function xUe(s){s=s|0;var l=0,c=0;return l=C,C=C+16|0,c=l,n[c>>2]=FUe(n[s+60>>2]|0)|0,s=Zv(gc(6,c|0)|0)|0,C=l,s|0}function Z9(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0,se=0,je=0;j=C,C=C+48|0,O=j+16|0,m=j,d=j+32|0,k=s+28|0,f=n[k>>2]|0,n[d>>2]=f,Q=s+20|0,f=(n[Q>>2]|0)-f|0,n[d+4>>2]=f,n[d+8>>2]=l,n[d+12>>2]=c,f=f+c|0,B=s+60|0,n[m>>2]=n[B>>2],n[m+4>>2]=d,n[m+8>>2]=2,m=Zv(Ni(146,m|0)|0)|0;e:do if((f|0)!=(m|0)){for(l=2;!((m|0)<0);)if(f=f-m|0,je=n[d+4>>2]|0,se=m>>>0>je>>>0,d=se?d+8|0:d,l=(se<<31>>31)+l|0,je=m-(se?je:0)|0,n[d>>2]=(n[d>>2]|0)+je,se=d+4|0,n[se>>2]=(n[se>>2]|0)-je,n[O>>2]=n[B>>2],n[O+4>>2]=d,n[O+8>>2]=l,m=Zv(Ni(146,O|0)|0)|0,(f|0)==(m|0)){M=3;break e}n[s+16>>2]=0,n[k>>2]=0,n[Q>>2]=0,n[s>>2]=n[s>>2]|32,(l|0)==2?c=0:c=c-(n[d+4>>2]|0)|0}else M=3;while(!1);return(M|0)==3&&(je=n[s+44>>2]|0,n[s+16>>2]=je+(n[s+48>>2]|0),n[k>>2]=je,n[Q>>2]=je),C=j,c|0}function kUe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0;return d=C,C=C+32|0,m=d,f=d+20|0,n[m>>2]=n[s+60>>2],n[m+4>>2]=0,n[m+8>>2]=l,n[m+12>>2]=f,n[m+16>>2]=c,(Zv(aa(140,m|0)|0)|0)<0?(n[f>>2]=-1,s=-1):s=n[f>>2]|0,C=d,s|0}function Zv(s){return s=s|0,s>>>0>4294963200&&(n[(Nd()|0)>>2]=0-s,s=-1),s|0}function Nd(){return(QUe()|0)+64|0}function QUe(){return gR()|0}function gR(){return 2084}function FUe(s){return s=s|0,s|0}function RUe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0;return d=C,C=C+32|0,f=d,n[s+36>>2]=1,!(n[s>>2]&64|0)&&(n[f>>2]=n[s+60>>2],n[f+4>>2]=21523,n[f+8>>2]=d+16,hu(54,f|0)|0)&&(o[s+75>>0]=-1),f=Z9(s,l,c)|0,C=d,f|0}function $9(s,l){s=s|0,l=l|0;var c=0,f=0;if(c=o[s>>0]|0,f=o[l>>0]|0,!(c<<24>>24)||c<<24>>24!=f<<24>>24)s=f;else{do s=s+1|0,l=l+1|0,c=o[s>>0]|0,f=o[l>>0]|0;while(!(!(c<<24>>24)||c<<24>>24!=f<<24>>24));s=f}return(c&255)-(s&255)|0}function TUe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0;e:do if(!c)s=0;else{for(;f=o[s>>0]|0,d=o[l>>0]|0,f<<24>>24==d<<24>>24;)if(c=c+-1|0,c)s=s+1|0,l=l+1|0;else{s=0;break e}s=(f&255)-(d&255)|0}while(!1);return s|0}function e7(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0,se=0,je=0,Oe=0,Qe=0;Qe=C,C=C+224|0,M=Qe+120|0,j=Qe+80|0,je=Qe,Oe=Qe+136|0,f=j,d=f+40|0;do n[f>>2]=0,f=f+4|0;while((f|0)<(d|0));return n[M>>2]=n[c>>2],(dR(0,l,M,je,j)|0)<0?c=-1:((n[s+76>>2]|0)>-1?se=NUe(s)|0:se=0,c=n[s>>2]|0,O=c&32,(o[s+74>>0]|0)<1&&(n[s>>2]=c&-33),f=s+48|0,n[f>>2]|0?c=dR(s,l,M,je,j)|0:(d=s+44|0,m=n[d>>2]|0,n[d>>2]=Oe,B=s+28|0,n[B>>2]=Oe,k=s+20|0,n[k>>2]=Oe,n[f>>2]=80,Q=s+16|0,n[Q>>2]=Oe+80,c=dR(s,l,M,je,j)|0,m&&(rD[n[s+36>>2]&7](s,0,0)|0,c=n[k>>2]|0?c:-1,n[d>>2]=m,n[f>>2]=0,n[Q>>2]=0,n[B>>2]=0,n[k>>2]=0)),f=n[s>>2]|0,n[s>>2]=f|O,se|0&&LUe(s),c=f&32|0?-1:c),C=Qe,c|0}function dR(s,l,c,f,d){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0;var m=0,B=0,k=0,Q=0,O=0,M=0,j=0,se=0,je=0,Oe=0,Qe=0,$e=0,Je=0,lt=0,_e=0,qe=0,Lt=0,Or=0,cr=0,Xt=0,Pr=0,Tr=0,ar=0;ar=C,C=C+64|0,cr=ar+16|0,Xt=ar,Lt=ar+24|0,Pr=ar+8|0,Tr=ar+20|0,n[cr>>2]=l,lt=(s|0)!=0,_e=Lt+40|0,qe=_e,Lt=Lt+39|0,Or=Pr+4|0,B=0,m=0,M=0;e:for(;;){do if((m|0)>-1)if((B|0)>(2147483647-m|0)){n[(Nd()|0)>>2]=75,m=-1;break}else{m=B+m|0;break}while(!1);if(B=o[l>>0]|0,B<<24>>24)k=l;else{Je=87;break}t:for(;;){switch(B<<24>>24){case 37:{B=k,Je=9;break t}case 0:{B=k;break t}default:}$e=k+1|0,n[cr>>2]=$e,B=o[$e>>0]|0,k=$e}t:do if((Je|0)==9)for(;;){if(Je=0,(o[k+1>>0]|0)!=37)break t;if(B=B+1|0,k=k+2|0,n[cr>>2]=k,(o[k>>0]|0)==37)Je=9;else break}while(!1);if(B=B-l|0,lt&&as(s,l,B),B|0){l=k;continue}Q=k+1|0,B=(o[Q>>0]|0)+-48|0,B>>>0<10?($e=(o[k+2>>0]|0)==36,Qe=$e?B:-1,M=$e?1:M,Q=$e?k+3|0:Q):Qe=-1,n[cr>>2]=Q,B=o[Q>>0]|0,k=(B<<24>>24)+-32|0;t:do if(k>>>0<32)for(O=0,j=B;;){if(B=1<>2]=Q,B=o[Q>>0]|0,k=(B<<24>>24)+-32|0,k>>>0>=32)break;j=B}else O=0;while(!1);if(B<<24>>24==42){if(k=Q+1|0,B=(o[k>>0]|0)+-48|0,B>>>0<10&&(o[Q+2>>0]|0)==36)n[d+(B<<2)>>2]=10,B=n[f+((o[k>>0]|0)+-48<<3)>>2]|0,M=1,Q=Q+3|0;else{if(M|0){m=-1;break}lt?(M=(n[c>>2]|0)+3&-4,B=n[M>>2]|0,n[c>>2]=M+4,M=0,Q=k):(B=0,M=0,Q=k)}n[cr>>2]=Q,$e=(B|0)<0,B=$e?0-B|0:B,O=$e?O|8192:O}else{if(B=t7(cr)|0,(B|0)<0){m=-1;break}Q=n[cr>>2]|0}do if((o[Q>>0]|0)==46){if((o[Q+1>>0]|0)!=42){n[cr>>2]=Q+1,k=t7(cr)|0,Q=n[cr>>2]|0;break}if(j=Q+2|0,k=(o[j>>0]|0)+-48|0,k>>>0<10&&(o[Q+3>>0]|0)==36){n[d+(k<<2)>>2]=10,k=n[f+((o[j>>0]|0)+-48<<3)>>2]|0,Q=Q+4|0,n[cr>>2]=Q;break}if(M|0){m=-1;break e}lt?($e=(n[c>>2]|0)+3&-4,k=n[$e>>2]|0,n[c>>2]=$e+4):k=0,n[cr>>2]=j,Q=j}else k=-1;while(!1);for(Oe=0;;){if(((o[Q>>0]|0)+-65|0)>>>0>57){m=-1;break e}if($e=Q+1|0,n[cr>>2]=$e,j=o[(o[Q>>0]|0)+-65+(5178+(Oe*58|0))>>0]|0,se=j&255,(se+-1|0)>>>0<8)Oe=se,Q=$e;else break}if(!(j<<24>>24)){m=-1;break}je=(Qe|0)>-1;do if(j<<24>>24==19)if(je){m=-1;break e}else Je=49;else{if(je){n[d+(Qe<<2)>>2]=se,je=f+(Qe<<3)|0,Qe=n[je+4>>2]|0,Je=Xt,n[Je>>2]=n[je>>2],n[Je+4>>2]=Qe,Je=49;break}if(!lt){m=0;break e}r7(Xt,se,c)}while(!1);if((Je|0)==49&&(Je=0,!lt)){B=0,l=$e;continue}Q=o[Q>>0]|0,Q=(Oe|0)!=0&(Q&15|0)==3?Q&-33:Q,je=O&-65537,Qe=O&8192|0?je:O;t:do switch(Q|0){case 110:switch((Oe&255)<<24>>24){case 0:{n[n[Xt>>2]>>2]=m,B=0,l=$e;continue e}case 1:{n[n[Xt>>2]>>2]=m,B=0,l=$e;continue e}case 2:{B=n[Xt>>2]|0,n[B>>2]=m,n[B+4>>2]=((m|0)<0)<<31>>31,B=0,l=$e;continue e}case 3:{a[n[Xt>>2]>>1]=m,B=0,l=$e;continue e}case 4:{o[n[Xt>>2]>>0]=m,B=0,l=$e;continue e}case 6:{n[n[Xt>>2]>>2]=m,B=0,l=$e;continue e}case 7:{B=n[Xt>>2]|0,n[B>>2]=m,n[B+4>>2]=((m|0)<0)<<31>>31,B=0,l=$e;continue e}default:{B=0,l=$e;continue e}}case 112:{Q=120,k=k>>>0>8?k:8,l=Qe|8,Je=61;break}case 88:case 120:{l=Qe,Je=61;break}case 111:{Q=Xt,l=n[Q>>2]|0,Q=n[Q+4>>2]|0,se=OUe(l,Q,_e)|0,je=qe-se|0,O=0,j=5642,k=(Qe&8|0)==0|(k|0)>(je|0)?k:je+1|0,je=Qe,Je=67;break}case 105:case 100:if(Q=Xt,l=n[Q>>2]|0,Q=n[Q+4>>2]|0,(Q|0)<0){l=$v(0,0,l|0,Q|0)|0,Q=we,O=Xt,n[O>>2]=l,n[O+4>>2]=Q,O=1,j=5642,Je=66;break t}else{O=(Qe&2049|0)!=0&1,j=Qe&2048|0?5643:Qe&1|0?5644:5642,Je=66;break t}case 117:{Q=Xt,O=0,j=5642,l=n[Q>>2]|0,Q=n[Q+4>>2]|0,Je=66;break}case 99:{o[Lt>>0]=n[Xt>>2],l=Lt,O=0,j=5642,se=_e,Q=1,k=je;break}case 109:{Q=UUe(n[(Nd()|0)>>2]|0)|0,Je=71;break}case 115:{Q=n[Xt>>2]|0,Q=Q|0?Q:5652,Je=71;break}case 67:{n[Pr>>2]=n[Xt>>2],n[Or>>2]=0,n[Xt>>2]=Pr,se=-1,Q=Pr,Je=75;break}case 83:{l=n[Xt>>2]|0,k?(se=k,Q=l,Je=75):(Ds(s,32,B,0,Qe),l=0,Je=84);break}case 65:case 71:case 70:case 69:case 97:case 103:case 102:case 101:{B=HUe(s,+E[Xt>>3],B,k,Qe,Q)|0,l=$e;continue e}default:O=0,j=5642,se=_e,Q=k,k=Qe}while(!1);t:do if((Je|0)==61)Qe=Xt,Oe=n[Qe>>2]|0,Qe=n[Qe+4>>2]|0,se=MUe(Oe,Qe,_e,Q&32)|0,j=(l&8|0)==0|(Oe|0)==0&(Qe|0)==0,O=j?0:2,j=j?5642:5642+(Q>>4)|0,je=l,l=Oe,Q=Qe,Je=67;else if((Je|0)==66)se=Ld(l,Q,_e)|0,je=Qe,Je=67;else if((Je|0)==71)Je=0,Qe=_Ue(Q,0,k)|0,Oe=(Qe|0)==0,l=Q,O=0,j=5642,se=Oe?Q+k|0:Qe,Q=Oe?k:Qe-Q|0,k=je;else if((Je|0)==75){for(Je=0,j=Q,l=0,k=0;O=n[j>>2]|0,!(!O||(k=n7(Tr,O)|0,(k|0)<0|k>>>0>(se-l|0)>>>0));)if(l=k+l|0,se>>>0>l>>>0)j=j+4|0;else break;if((k|0)<0){m=-1;break e}if(Ds(s,32,B,l,Qe),!l)l=0,Je=84;else for(O=0;;){if(k=n[Q>>2]|0,!k){Je=84;break t}if(k=n7(Tr,k)|0,O=k+O|0,(O|0)>(l|0)){Je=84;break t}if(as(s,Tr,k),O>>>0>=l>>>0){Je=84;break}else Q=Q+4|0}}while(!1);if((Je|0)==67)Je=0,Q=(l|0)!=0|(Q|0)!=0,Qe=(k|0)!=0|Q,Q=((Q^1)&1)+(qe-se)|0,l=Qe?se:_e,se=_e,Q=Qe?(k|0)>(Q|0)?k:Q:k,k=(k|0)>-1?je&-65537:je;else if((Je|0)==84){Je=0,Ds(s,32,B,l,Qe^8192),B=(B|0)>(l|0)?B:l,l=$e;continue}Oe=se-l|0,je=(Q|0)<(Oe|0)?Oe:Q,Qe=je+O|0,B=(B|0)<(Qe|0)?Qe:B,Ds(s,32,B,Qe,k),as(s,j,O),Ds(s,48,B,Qe,k^65536),Ds(s,48,je,Oe,0),as(s,l,Oe),Ds(s,32,B,Qe,k^8192),l=$e}e:do if((Je|0)==87&&!s)if(!M)m=0;else{for(m=1;l=n[d+(m<<2)>>2]|0,!!l;)if(r7(f+(m<<3)|0,l,c),m=m+1|0,(m|0)>=10){m=1;break e}for(;;){if(n[d+(m<<2)>>2]|0){m=-1;break e}if(m=m+1|0,(m|0)>=10){m=1;break}}}while(!1);return C=ar,m|0}function NUe(s){return s=s|0,0}function LUe(s){s=s|0}function as(s,l,c){s=s|0,l=l|0,c=c|0,n[s>>2]&32||JUe(l,c,s)|0}function t7(s){s=s|0;var l=0,c=0,f=0;if(c=n[s>>2]|0,f=(o[c>>0]|0)+-48|0,f>>>0<10){l=0;do l=f+(l*10|0)|0,c=c+1|0,n[s>>2]=c,f=(o[c>>0]|0)+-48|0;while(f>>>0<10)}else l=0;return l|0}function r7(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0;e:do if(l>>>0<=20)do switch(l|0){case 9:{f=(n[c>>2]|0)+3&-4,l=n[f>>2]|0,n[c>>2]=f+4,n[s>>2]=l;break e}case 10:{f=(n[c>>2]|0)+3&-4,l=n[f>>2]|0,n[c>>2]=f+4,f=s,n[f>>2]=l,n[f+4>>2]=((l|0)<0)<<31>>31;break e}case 11:{f=(n[c>>2]|0)+3&-4,l=n[f>>2]|0,n[c>>2]=f+4,f=s,n[f>>2]=l,n[f+4>>2]=0;break e}case 12:{f=(n[c>>2]|0)+7&-8,l=f,d=n[l>>2]|0,l=n[l+4>>2]|0,n[c>>2]=f+8,f=s,n[f>>2]=d,n[f+4>>2]=l;break e}case 13:{d=(n[c>>2]|0)+3&-4,f=n[d>>2]|0,n[c>>2]=d+4,f=(f&65535)<<16>>16,d=s,n[d>>2]=f,n[d+4>>2]=((f|0)<0)<<31>>31;break e}case 14:{d=(n[c>>2]|0)+3&-4,f=n[d>>2]|0,n[c>>2]=d+4,d=s,n[d>>2]=f&65535,n[d+4>>2]=0;break e}case 15:{d=(n[c>>2]|0)+3&-4,f=n[d>>2]|0,n[c>>2]=d+4,f=(f&255)<<24>>24,d=s,n[d>>2]=f,n[d+4>>2]=((f|0)<0)<<31>>31;break e}case 16:{d=(n[c>>2]|0)+3&-4,f=n[d>>2]|0,n[c>>2]=d+4,d=s,n[d>>2]=f&255,n[d+4>>2]=0;break e}case 17:{d=(n[c>>2]|0)+7&-8,m=+E[d>>3],n[c>>2]=d+8,E[s>>3]=m;break e}case 18:{d=(n[c>>2]|0)+7&-8,m=+E[d>>3],n[c>>2]=d+8,E[s>>3]=m;break e}default:break e}while(!1);while(!1)}function MUe(s,l,c,f){if(s=s|0,l=l|0,c=c|0,f=f|0,!((s|0)==0&(l|0)==0))do c=c+-1|0,o[c>>0]=u[5694+(s&15)>>0]|0|f,s=eD(s|0,l|0,4)|0,l=we;while(!((s|0)==0&(l|0)==0));return c|0}function OUe(s,l,c){if(s=s|0,l=l|0,c=c|0,!((s|0)==0&(l|0)==0))do c=c+-1|0,o[c>>0]=s&7|48,s=eD(s|0,l|0,3)|0,l=we;while(!((s|0)==0&(l|0)==0));return c|0}function Ld(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;if(l>>>0>0|(l|0)==0&s>>>0>4294967295){for(;f=CR(s|0,l|0,10,0)|0,c=c+-1|0,o[c>>0]=f&255|48,f=s,s=ER(s|0,l|0,10,0)|0,l>>>0>9|(l|0)==9&f>>>0>4294967295;)l=we;l=s}else l=s;if(l)for(;c=c+-1|0,o[c>>0]=(l>>>0)%10|0|48,!(l>>>0<10);)l=(l>>>0)/10|0;return c|0}function UUe(s){return s=s|0,WUe(s,n[(YUe()|0)+188>>2]|0)|0}function _Ue(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;m=l&255,f=(c|0)!=0;e:do if(f&(s&3|0)!=0)for(d=l&255;;){if((o[s>>0]|0)==d<<24>>24){B=6;break e}if(s=s+1|0,c=c+-1|0,f=(c|0)!=0,!(f&(s&3|0)!=0)){B=5;break}}else B=5;while(!1);(B|0)==5&&(f?B=6:c=0);e:do if((B|0)==6&&(d=l&255,(o[s>>0]|0)!=d<<24>>24)){f=Ue(m,16843009)|0;t:do if(c>>>0>3){for(;m=n[s>>2]^f,!((m&-2139062144^-2139062144)&m+-16843009|0);)if(s=s+4|0,c=c+-4|0,c>>>0<=3){B=11;break t}}else B=11;while(!1);if((B|0)==11&&!c){c=0;break}for(;;){if((o[s>>0]|0)==d<<24>>24)break e;if(s=s+1|0,c=c+-1|0,!c){c=0;break}}}while(!1);return(c|0?s:0)|0}function Ds(s,l,c,f,d){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0;var m=0,B=0;if(B=C,C=C+256|0,m=B,(c|0)>(f|0)&(d&73728|0)==0){if(d=c-f|0,Od(m|0,l|0,(d>>>0<256?d:256)|0)|0,d>>>0>255){l=c-f|0;do as(s,m,256),d=d+-256|0;while(d>>>0>255);d=l&255}as(s,m,d)}C=B}function n7(s,l){return s=s|0,l=l|0,s?s=jUe(s,l,0)|0:s=0,s|0}function HUe(s,l,c,f,d,m){s=s|0,l=+l,c=c|0,f=f|0,d=d|0,m=m|0;var B=0,k=0,Q=0,O=0,M=0,j=0,se=0,je=0,Oe=0,Qe=0,$e=0,Je=0,lt=0,_e=0,qe=0,Lt=0,Or=0,cr=0,Xt=0,Pr=0,Tr=0,ar=0,xn=0;xn=C,C=C+560|0,Q=xn+8|0,$e=xn,ar=xn+524|0,Tr=ar,O=xn+512|0,n[$e>>2]=0,Pr=O+12|0,i7(l)|0,(we|0)<0?(l=-l,cr=1,Or=5659):(cr=(d&2049|0)!=0&1,Or=d&2048|0?5662:d&1|0?5665:5660),i7(l)|0,Xt=we&2146435072;do if(Xt>>>0<2146435072|(Xt|0)==2146435072&!1){if(je=+qUe(l,$e)*2,B=je!=0,B&&(n[$e>>2]=(n[$e>>2]|0)+-1),lt=m|32,(lt|0)==97){Oe=m&32,se=Oe|0?Or+9|0:Or,j=cr|2,B=12-f|0;do if(f>>>0>11|(B|0)==0)l=je;else{l=8;do B=B+-1|0,l=l*16;while(B|0);if((o[se>>0]|0)==45){l=-(l+(-je-l));break}else{l=je+l-l;break}}while(!1);k=n[$e>>2]|0,B=(k|0)<0?0-k|0:k,B=Ld(B,((B|0)<0)<<31>>31,Pr)|0,(B|0)==(Pr|0)&&(B=O+11|0,o[B>>0]=48),o[B+-1>>0]=(k>>31&2)+43,M=B+-2|0,o[M>>0]=m+15,O=(f|0)<1,Q=(d&8|0)==0,B=ar;do Xt=~~l,k=B+1|0,o[B>>0]=u[5694+Xt>>0]|Oe,l=(l-+(Xt|0))*16,(k-Tr|0)==1&&!(Q&(O&l==0))?(o[k>>0]=46,B=B+2|0):B=k;while(l!=0);Xt=B-Tr|0,Tr=Pr-M|0,Pr=(f|0)!=0&(Xt+-2|0)<(f|0)?f+2|0:Xt,B=Tr+j+Pr|0,Ds(s,32,c,B,d),as(s,se,j),Ds(s,48,c,B,d^65536),as(s,ar,Xt),Ds(s,48,Pr-Xt|0,0,0),as(s,M,Tr),Ds(s,32,c,B,d^8192);break}k=(f|0)<0?6:f,B?(B=(n[$e>>2]|0)+-28|0,n[$e>>2]=B,l=je*268435456):(l=je,B=n[$e>>2]|0),Xt=(B|0)<0?Q:Q+288|0,Q=Xt;do qe=~~l>>>0,n[Q>>2]=qe,Q=Q+4|0,l=(l-+(qe>>>0))*1e9;while(l!=0);if((B|0)>0)for(O=Xt,j=Q;;){if(M=(B|0)<29?B:29,B=j+-4|0,B>>>0>=O>>>0){Q=0;do _e=u7(n[B>>2]|0,0,M|0)|0,_e=yR(_e|0,we|0,Q|0,0)|0,qe=we,Je=CR(_e|0,qe|0,1e9,0)|0,n[B>>2]=Je,Q=ER(_e|0,qe|0,1e9,0)|0,B=B+-4|0;while(B>>>0>=O>>>0);Q&&(O=O+-4|0,n[O>>2]=Q)}for(Q=j;!(Q>>>0<=O>>>0);)if(B=Q+-4|0,!(n[B>>2]|0))Q=B;else break;if(B=(n[$e>>2]|0)-M|0,n[$e>>2]=B,(B|0)>0)j=Q;else break}else O=Xt;if((B|0)<0){f=((k+25|0)/9|0)+1|0,Qe=(lt|0)==102;do{if(Oe=0-B|0,Oe=(Oe|0)<9?Oe:9,O>>>0>>0){M=(1<>>Oe,se=0,B=O;do qe=n[B>>2]|0,n[B>>2]=(qe>>>Oe)+se,se=Ue(qe&M,j)|0,B=B+4|0;while(B>>>0>>0);B=n[O>>2]|0?O:O+4|0,se?(n[Q>>2]=se,O=B,B=Q+4|0):(O=B,B=Q)}else O=n[O>>2]|0?O:O+4|0,B=Q;Q=Qe?Xt:O,Q=(B-Q>>2|0)>(f|0)?Q+(f<<2)|0:B,B=(n[$e>>2]|0)+Oe|0,n[$e>>2]=B}while((B|0)<0);B=O,f=Q}else B=O,f=Q;if(qe=Xt,B>>>0>>0){if(Q=(qe-B>>2)*9|0,M=n[B>>2]|0,M>>>0>=10){O=10;do O=O*10|0,Q=Q+1|0;while(M>>>0>=O>>>0)}}else Q=0;if(Qe=(lt|0)==103,Je=(k|0)!=0,O=k-((lt|0)!=102?Q:0)+((Je&Qe)<<31>>31)|0,(O|0)<(((f-qe>>2)*9|0)+-9|0)){if(O=O+9216|0,Oe=Xt+4+(((O|0)/9|0)+-1024<<2)|0,O=((O|0)%9|0)+1|0,(O|0)<9){M=10;do M=M*10|0,O=O+1|0;while((O|0)!=9)}else M=10;if(j=n[Oe>>2]|0,se=(j>>>0)%(M>>>0)|0,O=(Oe+4|0)==(f|0),O&(se|0)==0)O=Oe;else if(je=((j>>>0)/(M>>>0)|0)&1|0?9007199254740994:9007199254740992,_e=(M|0)/2|0,l=se>>>0<_e>>>0?.5:O&(se|0)==(_e|0)?1:1.5,cr&&(_e=(o[Or>>0]|0)==45,l=_e?-l:l,je=_e?-je:je),O=j-se|0,n[Oe>>2]=O,je+l!=je){if(_e=O+M|0,n[Oe>>2]=_e,_e>>>0>999999999)for(Q=Oe;O=Q+-4|0,n[Q>>2]=0,O>>>0>>0&&(B=B+-4|0,n[B>>2]=0),_e=(n[O>>2]|0)+1|0,n[O>>2]=_e,_e>>>0>999999999;)Q=O;else O=Oe;if(Q=(qe-B>>2)*9|0,j=n[B>>2]|0,j>>>0>=10){M=10;do M=M*10|0,Q=Q+1|0;while(j>>>0>=M>>>0)}}else O=Oe;O=O+4|0,O=f>>>0>O>>>0?O:f,_e=B}else O=f,_e=B;for(lt=O;;){if(lt>>>0<=_e>>>0){$e=0;break}if(B=lt+-4|0,!(n[B>>2]|0))lt=B;else{$e=1;break}}f=0-Q|0;do if(Qe)if(B=((Je^1)&1)+k|0,(B|0)>(Q|0)&(Q|0)>-5?(M=m+-1|0,k=B+-1-Q|0):(M=m+-2|0,k=B+-1|0),B=d&8,B)Oe=B;else{if($e&&(Lt=n[lt+-4>>2]|0,(Lt|0)!=0))if((Lt>>>0)%10|0)O=0;else{O=0,B=10;do B=B*10|0,O=O+1|0;while(!((Lt>>>0)%(B>>>0)|0|0))}else O=9;if(B=((lt-qe>>2)*9|0)+-9|0,(M|32|0)==102){Oe=B-O|0,Oe=(Oe|0)>0?Oe:0,k=(k|0)<(Oe|0)?k:Oe,Oe=0;break}else{Oe=B+Q-O|0,Oe=(Oe|0)>0?Oe:0,k=(k|0)<(Oe|0)?k:Oe,Oe=0;break}}else M=m,Oe=d&8;while(!1);if(Qe=k|Oe,j=(Qe|0)!=0&1,se=(M|32|0)==102,se)Je=0,B=(Q|0)>0?Q:0;else{if(B=(Q|0)<0?f:Q,B=Ld(B,((B|0)<0)<<31>>31,Pr)|0,O=Pr,(O-B|0)<2)do B=B+-1|0,o[B>>0]=48;while((O-B|0)<2);o[B+-1>>0]=(Q>>31&2)+43,B=B+-2|0,o[B>>0]=M,Je=B,B=O-B|0}if(B=cr+1+k+j+B|0,Ds(s,32,c,B,d),as(s,Or,cr),Ds(s,48,c,B,d^65536),se){M=_e>>>0>Xt>>>0?Xt:_e,Oe=ar+9|0,j=Oe,se=ar+8|0,O=M;do{if(Q=Ld(n[O>>2]|0,0,Oe)|0,(O|0)==(M|0))(Q|0)==(Oe|0)&&(o[se>>0]=48,Q=se);else if(Q>>>0>ar>>>0){Od(ar|0,48,Q-Tr|0)|0;do Q=Q+-1|0;while(Q>>>0>ar>>>0)}as(s,Q,j-Q|0),O=O+4|0}while(O>>>0<=Xt>>>0);if(Qe|0&&as(s,5710,1),O>>>0>>0&(k|0)>0)for(;;){if(Q=Ld(n[O>>2]|0,0,Oe)|0,Q>>>0>ar>>>0){Od(ar|0,48,Q-Tr|0)|0;do Q=Q+-1|0;while(Q>>>0>ar>>>0)}if(as(s,Q,(k|0)<9?k:9),O=O+4|0,Q=k+-9|0,O>>>0>>0&(k|0)>9)k=Q;else{k=Q;break}}Ds(s,48,k+9|0,9,0)}else{if(Qe=$e?lt:_e+4|0,(k|0)>-1){$e=ar+9|0,Oe=(Oe|0)==0,f=$e,j=0-Tr|0,se=ar+8|0,M=_e;do{Q=Ld(n[M>>2]|0,0,$e)|0,(Q|0)==($e|0)&&(o[se>>0]=48,Q=se);do if((M|0)==(_e|0)){if(O=Q+1|0,as(s,Q,1),Oe&(k|0)<1){Q=O;break}as(s,5710,1),Q=O}else{if(Q>>>0<=ar>>>0)break;Od(ar|0,48,Q+j|0)|0;do Q=Q+-1|0;while(Q>>>0>ar>>>0)}while(!1);Tr=f-Q|0,as(s,Q,(k|0)>(Tr|0)?Tr:k),k=k-Tr|0,M=M+4|0}while(M>>>0>>0&(k|0)>-1)}Ds(s,48,k+18|0,18,0),as(s,Je,Pr-Je|0)}Ds(s,32,c,B,d^8192)}else ar=(m&32|0)!=0,B=cr+3|0,Ds(s,32,c,B,d&-65537),as(s,Or,cr),as(s,l!=l|!1?ar?5686:5690:ar?5678:5682,3),Ds(s,32,c,B,d^8192);while(!1);return C=xn,((B|0)<(c|0)?c:B)|0}function i7(s){s=+s;var l=0;return E[v>>3]=s,l=n[v>>2]|0,we=n[v+4>>2]|0,l|0}function qUe(s,l){return s=+s,l=l|0,+ +s7(s,l)}function s7(s,l){s=+s,l=l|0;var c=0,f=0,d=0;switch(E[v>>3]=s,c=n[v>>2]|0,f=n[v+4>>2]|0,d=eD(c|0,f|0,52)|0,d&2047){case 0:{s!=0?(s=+s7(s*18446744073709552e3,l),c=(n[l>>2]|0)+-64|0):c=0,n[l>>2]=c;break}case 2047:break;default:n[l>>2]=(d&2047)+-1022,n[v>>2]=c,n[v+4>>2]=f&-2146435073|1071644672,s=+E[v>>3]}return+s}function jUe(s,l,c){s=s|0,l=l|0,c=c|0;do if(s){if(l>>>0<128){o[s>>0]=l,s=1;break}if(!(n[n[(GUe()|0)+188>>2]>>2]|0))if((l&-128|0)==57216){o[s>>0]=l,s=1;break}else{n[(Nd()|0)>>2]=84,s=-1;break}if(l>>>0<2048){o[s>>0]=l>>>6|192,o[s+1>>0]=l&63|128,s=2;break}if(l>>>0<55296|(l&-8192|0)==57344){o[s>>0]=l>>>12|224,o[s+1>>0]=l>>>6&63|128,o[s+2>>0]=l&63|128,s=3;break}if((l+-65536|0)>>>0<1048576){o[s>>0]=l>>>18|240,o[s+1>>0]=l>>>12&63|128,o[s+2>>0]=l>>>6&63|128,o[s+3>>0]=l&63|128,s=4;break}else{n[(Nd()|0)>>2]=84,s=-1;break}}else s=1;while(!1);return s|0}function GUe(){return gR()|0}function YUe(){return gR()|0}function WUe(s,l){s=s|0,l=l|0;var c=0,f=0;for(f=0;;){if((u[5712+f>>0]|0)==(s|0)){s=2;break}if(c=f+1|0,(c|0)==87){c=5800,f=87,s=5;break}else f=c}if((s|0)==2&&(f?(c=5800,s=5):c=5800),(s|0)==5)for(;;){do s=c,c=c+1|0;while(o[s>>0]|0);if(f=f+-1|0,f)s=5;else break}return KUe(c,n[l+20>>2]|0)|0}function KUe(s,l){return s=s|0,l=l|0,VUe(s,l)|0}function VUe(s,l){return s=s|0,l=l|0,l?l=zUe(n[l>>2]|0,n[l+4>>2]|0,s)|0:l=0,(l|0?l:s)|0}function zUe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,j=0,se=0;se=(n[s>>2]|0)+1794895138|0,m=x0(n[s+8>>2]|0,se)|0,f=x0(n[s+12>>2]|0,se)|0,d=x0(n[s+16>>2]|0,se)|0;e:do if(m>>>0>>2>>>0&&(j=l-(m<<2)|0,f>>>0>>0&d>>>0>>0)&&!((d|f)&3|0)){for(j=f>>>2,M=d>>>2,O=0;;){if(k=m>>>1,Q=O+k|0,B=Q<<1,d=B+j|0,f=x0(n[s+(d<<2)>>2]|0,se)|0,d=x0(n[s+(d+1<<2)>>2]|0,se)|0,!(d>>>0>>0&f>>>0<(l-d|0)>>>0)){f=0;break e}if(o[s+(d+f)>>0]|0){f=0;break e}if(f=$9(c,s+d|0)|0,!f)break;if(f=(f|0)<0,(m|0)==1){f=0;break e}else O=f?O:Q,m=f?k:m-k|0}f=B+M|0,d=x0(n[s+(f<<2)>>2]|0,se)|0,f=x0(n[s+(f+1<<2)>>2]|0,se)|0,f>>>0>>0&d>>>0<(l-f|0)>>>0?f=o[s+(f+d)>>0]|0?0:s+f|0:f=0}else f=0;while(!1);return f|0}function x0(s,l){s=s|0,l=l|0;var c=0;return c=p7(s|0)|0,(l|0?c:s)|0}function JUe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=c+16|0,d=n[f>>2]|0,d?m=5:XUe(c)|0?f=0:(d=n[f>>2]|0,m=5);e:do if((m|0)==5){if(k=c+20|0,B=n[k>>2]|0,f=B,(d-B|0)>>>0>>0){f=rD[n[c+36>>2]&7](c,s,l)|0;break}t:do if((o[c+75>>0]|0)>-1){for(B=l;;){if(!B){m=0,d=s;break t}if(d=B+-1|0,(o[s+d>>0]|0)==10)break;B=d}if(f=rD[n[c+36>>2]&7](c,s,B)|0,f>>>0>>0)break e;m=B,d=s+B|0,l=l-B|0,f=n[k>>2]|0}else m=0,d=s;while(!1);Dr(f|0,d|0,l|0)|0,n[k>>2]=(n[k>>2]|0)+l,f=m+l|0}while(!1);return f|0}function XUe(s){s=s|0;var l=0,c=0;return l=s+74|0,c=o[l>>0]|0,o[l>>0]=c+255|c,l=n[s>>2]|0,l&8?(n[s>>2]=l|32,s=-1):(n[s+8>>2]=0,n[s+4>>2]=0,c=n[s+44>>2]|0,n[s+28>>2]=c,n[s+20>>2]=c,n[s+16>>2]=c+(n[s+48>>2]|0),s=0),s|0}function _n(s,l){s=y(s),l=y(l);var c=0,f=0;c=o7(s)|0;do if((c&2147483647)>>>0<=2139095040){if(f=o7(l)|0,(f&2147483647)>>>0<=2139095040)if((f^c|0)<0){s=(c|0)<0?l:s;break}else{s=s>2]=s,n[v>>2]|0|0}function k0(s,l){s=y(s),l=y(l);var c=0,f=0;c=a7(s)|0;do if((c&2147483647)>>>0<=2139095040){if(f=a7(l)|0,(f&2147483647)>>>0<=2139095040)if((f^c|0)<0){s=(c|0)<0?s:l;break}else{s=s>2]=s,n[v>>2]|0|0}function mR(s,l){s=y(s),l=y(l);var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0;m=(h[v>>2]=s,n[v>>2]|0),k=(h[v>>2]=l,n[v>>2]|0),c=m>>>23&255,B=k>>>23&255,Q=m&-2147483648,d=k<<1;e:do if(d|0&&!((c|0)==255|((ZUe(l)|0)&2147483647)>>>0>2139095040)){if(f=m<<1,f>>>0<=d>>>0)return l=y(s*y(0)),y((f|0)==(d|0)?l:s);if(c)f=m&8388607|8388608;else{if(c=m<<9,(c|0)>-1){f=c,c=0;do c=c+-1|0,f=f<<1;while((f|0)>-1)}else c=0;f=m<<1-c}if(B)k=k&8388607|8388608;else{if(m=k<<9,(m|0)>-1){d=0;do d=d+-1|0,m=m<<1;while((m|0)>-1)}else d=0;B=d,k=k<<1-d}d=f-k|0,m=(d|0)>-1;t:do if((c|0)>(B|0)){for(;;){if(m)if(d)f=d;else break;if(f=f<<1,c=c+-1|0,d=f-k|0,m=(d|0)>-1,(c|0)<=(B|0))break t}l=y(s*y(0));break e}while(!1);if(m)if(d)f=d;else{l=y(s*y(0));break}if(f>>>0<8388608)do f=f<<1,c=c+-1|0;while(f>>>0<8388608);(c|0)>0?c=f+-8388608|c<<23:c=f>>>(1-c|0),l=(n[v>>2]=c|Q,y(h[v>>2]))}else O=3;while(!1);return(O|0)==3&&(l=y(s*l),l=y(l/l)),y(l)}function ZUe(s){return s=y(s),h[v>>2]=s,n[v>>2]|0|0}function $Ue(s,l){return s=s|0,l=l|0,e7(n[582]|0,s,l)|0}function Jr(s){s=s|0,Tt()}function Md(s){s=s|0}function e3e(s,l){return s=s|0,l=l|0,0}function t3e(s){return s=s|0,(l7(s+4|0)|0)==-1?(ef[n[(n[s>>2]|0)+8>>2]&127](s),s=1):s=0,s|0}function l7(s){s=s|0;var l=0;return l=n[s>>2]|0,n[s>>2]=l+-1,l+-1|0}function bp(s){s=s|0,t3e(s)|0&&r3e(s)}function r3e(s){s=s|0;var l=0;l=s+8|0,n[l>>2]|0&&(l7(l)|0)!=-1||ef[n[(n[s>>2]|0)+16>>2]&127](s)}function Kt(s){s=s|0;var l=0;for(l=s|0?s:1;s=Jv(l)|0,!(s|0);){if(s=i3e()|0,!s){s=0;break}B7[s&0]()}return s|0}function c7(s){return s=s|0,Kt(s)|0}function gt(s){s=s|0,Xv(s)}function n3e(s){s=s|0,(o[s+11>>0]|0)<0&>(n[s>>2]|0)}function i3e(){var s=0;return s=n[2923]|0,n[2923]=s+0,s|0}function s3e(){}function $v(s,l,c,f){return s=s|0,l=l|0,c=c|0,f=f|0,f=l-f-(c>>>0>s>>>0|0)>>>0,we=f,s-c>>>0|0|0}function yR(s,l,c,f){return s=s|0,l=l|0,c=c|0,f=f|0,c=s+c>>>0,we=l+f+(c>>>0>>0|0)>>>0,c|0|0}function Od(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;if(m=s+c|0,l=l&255,(c|0)>=67){for(;s&3;)o[s>>0]=l,s=s+1|0;for(f=m&-4|0,d=f-64|0,B=l|l<<8|l<<16|l<<24;(s|0)<=(d|0);)n[s>>2]=B,n[s+4>>2]=B,n[s+8>>2]=B,n[s+12>>2]=B,n[s+16>>2]=B,n[s+20>>2]=B,n[s+24>>2]=B,n[s+28>>2]=B,n[s+32>>2]=B,n[s+36>>2]=B,n[s+40>>2]=B,n[s+44>>2]=B,n[s+48>>2]=B,n[s+52>>2]=B,n[s+56>>2]=B,n[s+60>>2]=B,s=s+64|0;for(;(s|0)<(f|0);)n[s>>2]=B,s=s+4|0}for(;(s|0)<(m|0);)o[s>>0]=l,s=s+1|0;return m-c|0}function u7(s,l,c){return s=s|0,l=l|0,c=c|0,(c|0)<32?(we=l<>>32-c,s<>>c,s>>>c|(l&(1<>>c-32|0)}function Dr(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0;if((c|0)>=8192)return fc(s|0,l|0,c|0)|0;if(m=s|0,d=s+c|0,(s&3)==(l&3)){for(;s&3;){if(!c)return m|0;o[s>>0]=o[l>>0]|0,s=s+1|0,l=l+1|0,c=c-1|0}for(c=d&-4|0,f=c-64|0;(s|0)<=(f|0);)n[s>>2]=n[l>>2],n[s+4>>2]=n[l+4>>2],n[s+8>>2]=n[l+8>>2],n[s+12>>2]=n[l+12>>2],n[s+16>>2]=n[l+16>>2],n[s+20>>2]=n[l+20>>2],n[s+24>>2]=n[l+24>>2],n[s+28>>2]=n[l+28>>2],n[s+32>>2]=n[l+32>>2],n[s+36>>2]=n[l+36>>2],n[s+40>>2]=n[l+40>>2],n[s+44>>2]=n[l+44>>2],n[s+48>>2]=n[l+48>>2],n[s+52>>2]=n[l+52>>2],n[s+56>>2]=n[l+56>>2],n[s+60>>2]=n[l+60>>2],s=s+64|0,l=l+64|0;for(;(s|0)<(c|0);)n[s>>2]=n[l>>2],s=s+4|0,l=l+4|0}else for(c=d-4|0;(s|0)<(c|0);)o[s>>0]=o[l>>0]|0,o[s+1>>0]=o[l+1>>0]|0,o[s+2>>0]=o[l+2>>0]|0,o[s+3>>0]=o[l+3>>0]|0,s=s+4|0,l=l+4|0;for(;(s|0)<(d|0);)o[s>>0]=o[l>>0]|0,s=s+1|0,l=l+1|0;return m|0}function A7(s){s=s|0;var l=0;return l=o[L+(s&255)>>0]|0,(l|0)<8?l|0:(l=o[L+(s>>8&255)>>0]|0,(l|0)<8?l+8|0:(l=o[L+(s>>16&255)>>0]|0,(l|0)<8?l+16|0:(o[L+(s>>>24)>>0]|0)+24|0))}function f7(s,l,c,f,d){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0;var m=0,B=0,k=0,Q=0,O=0,M=0,j=0,se=0,je=0,Oe=0;if(M=s,Q=l,O=Q,B=c,se=f,k=se,!O)return m=(d|0)!=0,k?m?(n[d>>2]=s|0,n[d+4>>2]=l&0,se=0,d=0,we=se,d|0):(se=0,d=0,we=se,d|0):(m&&(n[d>>2]=(M>>>0)%(B>>>0),n[d+4>>2]=0),se=0,d=(M>>>0)/(B>>>0)>>>0,we=se,d|0);m=(k|0)==0;do if(B){if(!m){if(m=(b(k|0)|0)-(b(O|0)|0)|0,m>>>0<=31){j=m+1|0,k=31-m|0,l=m-31>>31,B=j,s=M>>>(j>>>0)&l|O<>>(j>>>0)&l,m=0,k=M<>2]=s|0,n[d+4>>2]=Q|l&0,se=0,d=0,we=se,d|0):(se=0,d=0,we=se,d|0)}if(m=B-1|0,m&B|0){k=(b(B|0)|0)+33-(b(O|0)|0)|0,Oe=64-k|0,j=32-k|0,Q=j>>31,je=k-32|0,l=je>>31,B=k,s=j-1>>31&O>>>(je>>>0)|(O<>>(k>>>0))&l,l=l&O>>>(k>>>0),m=M<>>(je>>>0))&Q|M<>31;break}return d|0&&(n[d>>2]=m&M,n[d+4>>2]=0),(B|0)==1?(je=Q|l&0,Oe=s|0|0,we=je,Oe|0):(Oe=A7(B|0)|0,je=O>>>(Oe>>>0)|0,Oe=O<<32-Oe|M>>>(Oe>>>0)|0,we=je,Oe|0)}else{if(m)return d|0&&(n[d>>2]=(O>>>0)%(B>>>0),n[d+4>>2]=0),je=0,Oe=(O>>>0)/(B>>>0)>>>0,we=je,Oe|0;if(!M)return d|0&&(n[d>>2]=0,n[d+4>>2]=(O>>>0)%(k>>>0)),je=0,Oe=(O>>>0)/(k>>>0)>>>0,we=je,Oe|0;if(m=k-1|0,!(m&k))return d|0&&(n[d>>2]=s|0,n[d+4>>2]=m&O|l&0),je=0,Oe=O>>>((A7(k|0)|0)>>>0),we=je,Oe|0;if(m=(b(k|0)|0)-(b(O|0)|0)|0,m>>>0<=30){l=m+1|0,k=31-m|0,B=l,s=O<>>(l>>>0),l=O>>>(l>>>0),m=0,k=M<>2]=s|0,n[d+4>>2]=Q|l&0,je=0,Oe=0,we=je,Oe|0):(je=0,Oe=0,we=je,Oe|0)}while(!1);if(!B)O=k,Q=0,k=0;else{j=c|0|0,M=se|f&0,O=yR(j|0,M|0,-1,-1)|0,c=we,Q=k,k=0;do f=Q,Q=m>>>31|Q<<1,m=k|m<<1,f=s<<1|f>>>31|0,se=s>>>31|l<<1|0,$v(O|0,c|0,f|0,se|0)|0,Oe=we,je=Oe>>31|((Oe|0)<0?-1:0)<<1,k=je&1,s=$v(f|0,se|0,je&j|0,(((Oe|0)<0?-1:0)>>31|((Oe|0)<0?-1:0)<<1)&M|0)|0,l=we,B=B-1|0;while(B|0);O=Q,Q=0}return B=0,d|0&&(n[d>>2]=s,n[d+4>>2]=l),je=(m|0)>>>31|(O|B)<<1|(B<<1|m>>>31)&0|Q,Oe=(m<<1|0)&-2|k,we=je,Oe|0}function ER(s,l,c,f){return s=s|0,l=l|0,c=c|0,f=f|0,f7(s,l,c,f,0)|0}function Sp(s){s=s|0;var l=0,c=0;return c=s+15&-16|0,l=n[I>>2]|0,s=l+c|0,(c|0)>0&(s|0)<(l|0)|(s|0)<0?(ie()|0,vA(12),-1):(n[I>>2]=s,(s|0)>($()|0)&&!(X()|0)?(n[I>>2]=l,vA(12),-1):l|0)}function ww(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;if((l|0)<(s|0)&(s|0)<(l+c|0)){for(f=s,l=l+c|0,s=s+c|0;(c|0)>0;)s=s-1|0,l=l-1|0,c=c-1|0,o[s>>0]=o[l>>0]|0;s=f}else Dr(s,l,c)|0;return s|0}function CR(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0;return m=C,C=C+16|0,d=m|0,f7(s,l,c,f,d)|0,C=m,we=n[d+4>>2]|0,n[d>>2]|0|0}function p7(s){return s=s|0,(s&255)<<24|(s>>8&255)<<16|(s>>16&255)<<8|s>>>24|0}function o3e(s,l,c,f,d,m){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0,m=m|0,h7[s&1](l|0,c|0,f|0,d|0,m|0)}function a3e(s,l,c){s=s|0,l=l|0,c=y(c),g7[s&1](l|0,y(c))}function l3e(s,l,c){s=s|0,l=l|0,c=+c,d7[s&31](l|0,+c)}function c3e(s,l,c,f){return s=s|0,l=l|0,c=y(c),f=y(f),y(m7[s&0](l|0,y(c),y(f)))}function u3e(s,l){s=s|0,l=l|0,ef[s&127](l|0)}function A3e(s,l,c){s=s|0,l=l|0,c=c|0,tf[s&31](l|0,c|0)}function f3e(s,l){return s=s|0,l=l|0,F0[s&31](l|0)|0}function p3e(s,l,c,f,d){s=s|0,l=l|0,c=+c,f=+f,d=d|0,y7[s&1](l|0,+c,+f,d|0)}function h3e(s,l,c,f){s=s|0,l=l|0,c=+c,f=+f,V3e[s&1](l|0,+c,+f)}function g3e(s,l,c,f){return s=s|0,l=l|0,c=c|0,f=f|0,rD[s&7](l|0,c|0,f|0)|0}function d3e(s,l,c,f){return s=s|0,l=l|0,c=c|0,f=f|0,+z3e[s&1](l|0,c|0,f|0)}function m3e(s,l){return s=s|0,l=l|0,+E7[s&15](l|0)}function y3e(s,l,c){return s=s|0,l=l|0,c=+c,J3e[s&1](l|0,+c)|0}function E3e(s,l,c){return s=s|0,l=l|0,c=c|0,IR[s&15](l|0,c|0)|0}function C3e(s,l,c,f,d,m){s=s|0,l=l|0,c=c|0,f=+f,d=+d,m=m|0,X3e[s&1](l|0,c|0,+f,+d,m|0)}function w3e(s,l,c,f,d,m,B){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0,m=m|0,B=B|0,Z3e[s&1](l|0,c|0,f|0,d|0,m|0,B|0)}function I3e(s,l,c){return s=s|0,l=l|0,c=c|0,+C7[s&7](l|0,c|0)}function B3e(s){return s=s|0,nD[s&7]()|0}function v3e(s,l,c,f,d,m){return s=s|0,l=l|0,c=c|0,f=f|0,d=d|0,m=m|0,w7[s&1](l|0,c|0,f|0,d|0,m|0)|0}function D3e(s,l,c,f,d){s=s|0,l=l|0,c=c|0,f=f|0,d=+d,$3e[s&1](l|0,c|0,f|0,+d)}function P3e(s,l,c,f,d,m,B){s=s|0,l=l|0,c=c|0,f=y(f),d=d|0,m=y(m),B=B|0,I7[s&1](l|0,c|0,y(f),d|0,y(m),B|0)}function b3e(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0,vw[s&15](l|0,c|0,f|0)}function S3e(s){s=s|0,B7[s&0]()}function x3e(s,l,c,f){s=s|0,l=l|0,c=c|0,f=+f,v7[s&15](l|0,c|0,+f)}function k3e(s,l,c){return s=s|0,l=+l,c=+c,e_e[s&1](+l,+c)|0}function Q3e(s,l,c,f,d){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0,BR[s&15](l|0,c|0,f|0,d|0)}function F3e(s,l,c,f,d){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0,F(0)}function R3e(s,l){s=s|0,l=y(l),F(1)}function Ea(s,l){s=s|0,l=+l,F(2)}function T3e(s,l,c){return s=s|0,l=y(l),c=y(c),F(3),Xe}function Er(s){s=s|0,F(4)}function Iw(s,l){s=s|0,l=l|0,F(5)}function Xa(s){return s=s|0,F(6),0}function N3e(s,l,c,f){s=s|0,l=+l,c=+c,f=f|0,F(7)}function L3e(s,l,c){s=s|0,l=+l,c=+c,F(8)}function M3e(s,l,c){return s=s|0,l=l|0,c=c|0,F(9),0}function O3e(s,l,c){return s=s|0,l=l|0,c=c|0,F(10),0}function Q0(s){return s=s|0,F(11),0}function U3e(s,l){return s=s|0,l=+l,F(12),0}function Bw(s,l){return s=s|0,l=l|0,F(13),0}function _3e(s,l,c,f,d){s=s|0,l=l|0,c=+c,f=+f,d=d|0,F(14)}function H3e(s,l,c,f,d,m){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0,m=m|0,F(15)}function wR(s,l){return s=s|0,l=l|0,F(16),0}function q3e(){return F(17),0}function j3e(s,l,c,f,d){return s=s|0,l=l|0,c=c|0,f=f|0,d=d|0,F(18),0}function G3e(s,l,c,f){s=s|0,l=l|0,c=c|0,f=+f,F(19)}function Y3e(s,l,c,f,d,m){s=s|0,l=l|0,c=y(c),f=f|0,d=y(d),m=m|0,F(20)}function tD(s,l,c){s=s|0,l=l|0,c=c|0,F(21)}function W3e(){F(22)}function Ud(s,l,c){s=s|0,l=l|0,c=+c,F(23)}function K3e(s,l){return s=+s,l=+l,F(24),0}function _d(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0,F(25)}var h7=[F3e,jLe],g7=[R3e,fo],d7=[Ea,fw,pw,lF,cF,Dl,hw,uF,xd,ku,dw,AF,Lv,WA,Mv,kd,Ov,Uv,Qd,Ea,Ea,Ea,Ea,Ea,Ea,Ea,Ea,Ea,Ea,Ea,Ea,Ea],m7=[T3e],ef=[Er,Md,BDe,vDe,DDe,exe,txe,rxe,yNe,ENe,CNe,kLe,QLe,FLe,Z4e,$4e,eUe,ds,Qv,Sd,YA,gw,Eve,Cve,pDe,RDe,YDe,cPe,DPe,qPe,sbe,Cbe,Nbe,Xbe,pSe,xSe,YSe,Exe,Nxe,Xxe,pke,xke,Yke,uQe,DQe,UQe,tFe,Sc,FFe,VFe,pRe,QRe,WRe,pTe,BTe,PTe,jTe,WTe,cNe,INe,DNe,qNe,oLe,eG,HMe,yOe,ROe,VOe,d4e,Q4e,q4e,Y4e,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er],tf=[Iw,tF,rF,Aw,xu,nF,iF,Cp,sF,oF,aF,Nv,KA,Ve,At,Wt,vr,bn,Qr,pF,ove,xve,hQe,SQe,NRe,GMe,hLe,O9,Iw,Iw,Iw,Iw],F0=[Xa,xUe,eF,D,fe,De,vt,wt,St,_r,di,po,nve,ive,wve,iFe,JRe,YNe,VMe,Va,Xa,Xa,Xa,Xa,Xa,Xa,Xa,Xa,Xa,Xa,Xa,Xa],y7=[N3e,Ive],V3e=[L3e,fNe],rD=[M3e,Z9,kUe,RUe,WPe,Bxe,LFe,ZOe],z3e=[O3e,mSe],E7=[Q0,Yo,nt,Sn,Bve,vve,Dve,Pve,bve,Sve,Q0,Q0,Q0,Q0,Q0,Q0],J3e=[U3e,CTe],IR=[Bw,e3e,sve,mDe,pPe,lbe,Bbe,zSe,Uxe,jQe,xv,MOe,Bw,Bw,Bw,Bw],X3e=[_3e,zDe],Z3e=[H3e,C4e],C7=[wR,ai,kve,Qve,Fve,RSe,wR,wR],nD=[q3e,Rve,cw,ma,kTe,JTe,xNe,z4e],w7=[j3e,nw],$3e=[G3e,mke],I7=[Y3e,ave],vw=[tD,T,os,tn,ho,xPe,Obe,Rke,zke,bd,fMe,IOe,N4e,tD,tD,tD],B7=[W3e],v7=[Ud,Fv,Rv,Tv,GA,_v,fF,P,tke,ZFe,dTe,Ud,Ud,Ud,Ud,Ud],e_e=[K3e,dNe],BR=[_d,tSe,fFe,mRe,sTe,LTe,rNe,LNe,ALe,eOe,oUe,_d,_d,_d,_d,_d];return{_llvm_bswap_i32:p7,dynCall_idd:k3e,dynCall_i:B3e,_i64Subtract:$v,___udivdi3:ER,dynCall_vif:a3e,setThrew:du,dynCall_viii:b3e,_bitshift64Lshr:eD,_bitshift64Shl:u7,dynCall_vi:u3e,dynCall_viiddi:C3e,dynCall_diii:d3e,dynCall_iii:E3e,_memset:Od,_sbrk:Sp,_memcpy:Dr,__GLOBAL__sub_I_Yoga_cpp:Pd,dynCall_vii:A3e,___uremdi3:CR,dynCall_vid:l3e,stackAlloc:lo,_nbind_init:mUe,getTempRet0:qa,dynCall_di:m3e,dynCall_iid:y3e,setTempRet0:SA,_i64Add:yR,dynCall_fiff:c3e,dynCall_iiii:g3e,_emscripten_get_global_libc:SUe,dynCall_viid:x3e,dynCall_viiid:D3e,dynCall_viififi:P3e,dynCall_ii:f3e,__GLOBAL__sub_I_Binding_cc:RMe,dynCall_viiii:Q3e,dynCall_iiiiii:v3e,stackSave:dc,dynCall_viiiii:o3e,__GLOBAL__sub_I_nbind_cc:Tve,dynCall_vidd:h3e,_free:Xv,runPostSets:s3e,dynCall_viiiiii:w3e,establishStackSpace:qi,_memmove:ww,stackRestore:gu,_malloc:Jv,__GLOBAL__sub_I_common_cc:$Ne,dynCall_viddi:p3e,dynCall_dii:I3e,dynCall_v:S3e}}(Module.asmGlobalArg,Module.asmLibraryArg,buffer),_llvm_bswap_i32=Module._llvm_bswap_i32=asm._llvm_bswap_i32,getTempRet0=Module.getTempRet0=asm.getTempRet0,___udivdi3=Module.___udivdi3=asm.___udivdi3,setThrew=Module.setThrew=asm.setThrew,_bitshift64Lshr=Module._bitshift64Lshr=asm._bitshift64Lshr,_bitshift64Shl=Module._bitshift64Shl=asm._bitshift64Shl,_memset=Module._memset=asm._memset,_sbrk=Module._sbrk=asm._sbrk,_memcpy=Module._memcpy=asm._memcpy,stackAlloc=Module.stackAlloc=asm.stackAlloc,___uremdi3=Module.___uremdi3=asm.___uremdi3,_nbind_init=Module._nbind_init=asm._nbind_init,_i64Subtract=Module._i64Subtract=asm._i64Subtract,setTempRet0=Module.setTempRet0=asm.setTempRet0,_i64Add=Module._i64Add=asm._i64Add,_emscripten_get_global_libc=Module._emscripten_get_global_libc=asm._emscripten_get_global_libc,__GLOBAL__sub_I_Yoga_cpp=Module.__GLOBAL__sub_I_Yoga_cpp=asm.__GLOBAL__sub_I_Yoga_cpp,__GLOBAL__sub_I_Binding_cc=Module.__GLOBAL__sub_I_Binding_cc=asm.__GLOBAL__sub_I_Binding_cc,stackSave=Module.stackSave=asm.stackSave,__GLOBAL__sub_I_nbind_cc=Module.__GLOBAL__sub_I_nbind_cc=asm.__GLOBAL__sub_I_nbind_cc,_free=Module._free=asm._free,runPostSets=Module.runPostSets=asm.runPostSets,establishStackSpace=Module.establishStackSpace=asm.establishStackSpace,_memmove=Module._memmove=asm._memmove,stackRestore=Module.stackRestore=asm.stackRestore,_malloc=Module._malloc=asm._malloc,__GLOBAL__sub_I_common_cc=Module.__GLOBAL__sub_I_common_cc=asm.__GLOBAL__sub_I_common_cc,dynCall_viiiii=Module.dynCall_viiiii=asm.dynCall_viiiii,dynCall_vif=Module.dynCall_vif=asm.dynCall_vif,dynCall_vid=Module.dynCall_vid=asm.dynCall_vid,dynCall_fiff=Module.dynCall_fiff=asm.dynCall_fiff,dynCall_vi=Module.dynCall_vi=asm.dynCall_vi,dynCall_vii=Module.dynCall_vii=asm.dynCall_vii,dynCall_ii=Module.dynCall_ii=asm.dynCall_ii,dynCall_viddi=Module.dynCall_viddi=asm.dynCall_viddi,dynCall_vidd=Module.dynCall_vidd=asm.dynCall_vidd,dynCall_iiii=Module.dynCall_iiii=asm.dynCall_iiii,dynCall_diii=Module.dynCall_diii=asm.dynCall_diii,dynCall_di=Module.dynCall_di=asm.dynCall_di,dynCall_iid=Module.dynCall_iid=asm.dynCall_iid,dynCall_iii=Module.dynCall_iii=asm.dynCall_iii,dynCall_viiddi=Module.dynCall_viiddi=asm.dynCall_viiddi,dynCall_viiiiii=Module.dynCall_viiiiii=asm.dynCall_viiiiii,dynCall_dii=Module.dynCall_dii=asm.dynCall_dii,dynCall_i=Module.dynCall_i=asm.dynCall_i,dynCall_iiiiii=Module.dynCall_iiiiii=asm.dynCall_iiiiii,dynCall_viiid=Module.dynCall_viiid=asm.dynCall_viiid,dynCall_viififi=Module.dynCall_viififi=asm.dynCall_viififi,dynCall_viii=Module.dynCall_viii=asm.dynCall_viii,dynCall_v=Module.dynCall_v=asm.dynCall_v,dynCall_viid=Module.dynCall_viid=asm.dynCall_viid,dynCall_idd=Module.dynCall_idd=asm.dynCall_idd,dynCall_viiii=Module.dynCall_viiii=asm.dynCall_viiii;Runtime.stackAlloc=Module.stackAlloc,Runtime.stackSave=Module.stackSave,Runtime.stackRestore=Module.stackRestore,Runtime.establishStackSpace=Module.establishStackSpace,Runtime.setTempRet0=Module.setTempRet0,Runtime.getTempRet0=Module.getTempRet0,Module.asm=asm;function ExitStatus(t){this.name="ExitStatus",this.message="Program terminated with exit("+t+")",this.status=t}ExitStatus.prototype=new Error,ExitStatus.prototype.constructor=ExitStatus;var initialStackTop,preloadStartTime=null,calledMain=!1;dependenciesFulfilled=function t(){Module.calledRun||run(),Module.calledRun||(dependenciesFulfilled=t)},Module.callMain=Module.callMain=function t(e){e=e||[],ensureInitRuntime();var r=e.length+1;function o(){for(var p=0;p<3;p++)a.push(0)}var a=[allocate(intArrayFromString(Module.thisProgram),"i8",ALLOC_NORMAL)];o();for(var n=0;n0||(preRun(),runDependencies>0)||Module.calledRun)return;function e(){Module.calledRun||(Module.calledRun=!0,!ABORT&&(ensureInitRuntime(),preMain(),Module.onRuntimeInitialized&&Module.onRuntimeInitialized(),Module._main&&shouldRunNow&&Module.callMain(t),postRun()))}Module.setStatus?(Module.setStatus("Running..."),setTimeout(function(){setTimeout(function(){Module.setStatus("")},1),e()},1)):e()}Module.run=Module.run=run;function exit(t,e){e&&Module.noExitRuntime||(Module.noExitRuntime||(ABORT=!0,EXITSTATUS=t,STACKTOP=initialStackTop,exitRuntime(),Module.onExit&&Module.onExit(t)),ENVIRONMENT_IS_NODE&&process.exit(t),Module.quit(t,new ExitStatus(t)))}Module.exit=Module.exit=exit;var abortDecorators=[];function abort(t){Module.onAbort&&Module.onAbort(t),t!==void 0?(Module.print(t),Module.printErr(t),t=JSON.stringify(t)):t="",ABORT=!0,EXITSTATUS=1;var e=` +If this abort() is unexpected, build with -s ASSERTIONS=1 which can give more information.`,r="abort("+t+") at "+stackTrace()+e;throw abortDecorators&&abortDecorators.forEach(function(o){r=o(r,t)}),r}if(Module.abort=Module.abort=abort,Module.preInit)for(typeof Module.preInit=="function"&&(Module.preInit=[Module.preInit]);Module.preInit.length>0;)Module.preInit.pop()();var shouldRunNow=!0;Module.noInitialRun&&(shouldRunNow=!1),run()})});var Jg=_((bKt,_Ee)=>{"use strict";var Jyt=OEe(),Xyt=UEe(),v6=!1,D6=null;Xyt({},function(t,e){if(!v6){if(v6=!0,t)throw t;D6=e}});if(!v6)throw new Error("Failed to load the yoga module - it needed to be loaded synchronously, but didn't");_Ee.exports=Jyt(D6.bind,D6.lib)});var b6=_((SKt,P6)=>{"use strict";var HEe=t=>Number.isNaN(t)?!1:t>=4352&&(t<=4447||t===9001||t===9002||11904<=t&&t<=12871&&t!==12351||12880<=t&&t<=19903||19968<=t&&t<=42182||43360<=t&&t<=43388||44032<=t&&t<=55203||63744<=t&&t<=64255||65040<=t&&t<=65049||65072<=t&&t<=65131||65281<=t&&t<=65376||65504<=t&&t<=65510||110592<=t&&t<=110593||127488<=t&&t<=127569||131072<=t&&t<=262141);P6.exports=HEe;P6.exports.default=HEe});var jEe=_((xKt,qEe)=>{"use strict";qEe.exports=function(){return/\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F|\uD83D\uDC68(?:\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68\uD83C\uDFFB|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|[\u2695\u2696\u2708]\uFE0F|\uD83D[\uDC66\uDC67]|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708])\uFE0F|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C[\uDFFB-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)\uD83C\uDFFB|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])|\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)(?:\uD83C[\uDFFB\uDFFC])|\uD83D\uDC69(?:\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)(?:\uD83C[\uDFFB-\uDFFD])|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|(?:(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)\uFE0F|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD6-\uDDDD])(?:(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\u200D[\u2640\u2642])|\uD83C\uDFF4\u200D\u2620)\uFE0F|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF4\uD83C\uDDF2|\uD83C\uDDF6\uD83C\uDDE6|[#\*0-9]\uFE0F\u20E3|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83D\uDC69(?:\uD83C[\uDFFB-\uDFFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270A-\u270D]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC70\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDCAA\uDD74\uDD7A\uDD90\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD36\uDDB5\uDDB6\uDDBB\uDDD2-\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDED5\uDEEB\uDEEC\uDEF4-\uDEFA\uDFE0-\uDFEB]|\uD83E[\uDD0D-\uDD3A\uDD3C-\uDD45\uDD47-\uDD71\uDD73-\uDD76\uDD7A-\uDDA2\uDDA5-\uDDAA\uDDAE-\uDDCA\uDDCD-\uDDFF\uDE70-\uDE73\uDE78-\uDE7A\uDE80-\uDE82\uDE90-\uDE95])|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFA\uDFE0-\uDFEB]|\uD83E[\uDD0D-\uDD3A\uDD3C-\uDD45\uDD47-\uDD71\uDD73-\uDD76\uDD7A-\uDDA2\uDDA5-\uDDAA\uDDAE-\uDDCA\uDDCD-\uDDFF\uDE70-\uDE73\uDE78-\uDE7A\uDE80-\uDE82\uDE90-\uDE95])\uFE0F|(?:[\u261D\u26F9\u270A-\u270D]|\uD83C[\uDF85\uDFC2-\uDFC4\uDFC7\uDFCA-\uDFCC]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66-\uDC78\uDC7C\uDC81-\uDC83\uDC85-\uDC87\uDC8F\uDC91\uDCAA\uDD74\uDD75\uDD7A\uDD90\uDD95\uDD96\uDE45-\uDE47\uDE4B-\uDE4F\uDEA3\uDEB4-\uDEB6\uDEC0\uDECC]|\uD83E[\uDD0F\uDD18-\uDD1F\uDD26\uDD30-\uDD39\uDD3C-\uDD3E\uDDB5\uDDB6\uDDB8\uDDB9\uDDBB\uDDCD-\uDDCF\uDDD1-\uDDDD])/g}});var Lk=_((kKt,S6)=>{"use strict";var Zyt=BP(),$yt=b6(),eEt=jEe(),GEe=t=>{if(typeof t!="string"||t.length===0||(t=Zyt(t),t.length===0))return 0;t=t.replace(eEt()," ");let e=0;for(let r=0;r=127&&o<=159||o>=768&&o<=879||(o>65535&&r++,e+=$yt(o)?2:1)}return e};S6.exports=GEe;S6.exports.default=GEe});var k6=_((QKt,x6)=>{"use strict";var tEt=Lk(),YEe=t=>{let e=0;for(let r of t.split(` +`))e=Math.max(e,tEt(r));return e};x6.exports=YEe;x6.exports.default=YEe});var WEe=_(W2=>{"use strict";var rEt=W2&&W2.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(W2,"__esModule",{value:!0});var nEt=rEt(k6()),Q6={};W2.default=t=>{if(t.length===0)return{width:0,height:0};if(Q6[t])return Q6[t];let e=nEt.default(t),r=t.split(` +`).length;return Q6[t]={width:e,height:r},{width:e,height:r}}});var KEe=_(K2=>{"use strict";var iEt=K2&&K2.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(K2,"__esModule",{value:!0});var dn=iEt(Jg()),sEt=(t,e)=>{"position"in e&&t.setPositionType(e.position==="absolute"?dn.default.POSITION_TYPE_ABSOLUTE:dn.default.POSITION_TYPE_RELATIVE)},oEt=(t,e)=>{"marginLeft"in e&&t.setMargin(dn.default.EDGE_START,e.marginLeft||0),"marginRight"in e&&t.setMargin(dn.default.EDGE_END,e.marginRight||0),"marginTop"in e&&t.setMargin(dn.default.EDGE_TOP,e.marginTop||0),"marginBottom"in e&&t.setMargin(dn.default.EDGE_BOTTOM,e.marginBottom||0)},aEt=(t,e)=>{"paddingLeft"in e&&t.setPadding(dn.default.EDGE_LEFT,e.paddingLeft||0),"paddingRight"in e&&t.setPadding(dn.default.EDGE_RIGHT,e.paddingRight||0),"paddingTop"in e&&t.setPadding(dn.default.EDGE_TOP,e.paddingTop||0),"paddingBottom"in e&&t.setPadding(dn.default.EDGE_BOTTOM,e.paddingBottom||0)},lEt=(t,e)=>{var r;"flexGrow"in e&&t.setFlexGrow((r=e.flexGrow)!==null&&r!==void 0?r:0),"flexShrink"in e&&t.setFlexShrink(typeof e.flexShrink=="number"?e.flexShrink:1),"flexDirection"in e&&(e.flexDirection==="row"&&t.setFlexDirection(dn.default.FLEX_DIRECTION_ROW),e.flexDirection==="row-reverse"&&t.setFlexDirection(dn.default.FLEX_DIRECTION_ROW_REVERSE),e.flexDirection==="column"&&t.setFlexDirection(dn.default.FLEX_DIRECTION_COLUMN),e.flexDirection==="column-reverse"&&t.setFlexDirection(dn.default.FLEX_DIRECTION_COLUMN_REVERSE)),"flexBasis"in e&&(typeof e.flexBasis=="number"?t.setFlexBasis(e.flexBasis):typeof e.flexBasis=="string"?t.setFlexBasisPercent(Number.parseInt(e.flexBasis,10)):t.setFlexBasis(NaN)),"alignItems"in e&&((e.alignItems==="stretch"||!e.alignItems)&&t.setAlignItems(dn.default.ALIGN_STRETCH),e.alignItems==="flex-start"&&t.setAlignItems(dn.default.ALIGN_FLEX_START),e.alignItems==="center"&&t.setAlignItems(dn.default.ALIGN_CENTER),e.alignItems==="flex-end"&&t.setAlignItems(dn.default.ALIGN_FLEX_END)),"alignSelf"in e&&((e.alignSelf==="auto"||!e.alignSelf)&&t.setAlignSelf(dn.default.ALIGN_AUTO),e.alignSelf==="flex-start"&&t.setAlignSelf(dn.default.ALIGN_FLEX_START),e.alignSelf==="center"&&t.setAlignSelf(dn.default.ALIGN_CENTER),e.alignSelf==="flex-end"&&t.setAlignSelf(dn.default.ALIGN_FLEX_END)),"justifyContent"in e&&((e.justifyContent==="flex-start"||!e.justifyContent)&&t.setJustifyContent(dn.default.JUSTIFY_FLEX_START),e.justifyContent==="center"&&t.setJustifyContent(dn.default.JUSTIFY_CENTER),e.justifyContent==="flex-end"&&t.setJustifyContent(dn.default.JUSTIFY_FLEX_END),e.justifyContent==="space-between"&&t.setJustifyContent(dn.default.JUSTIFY_SPACE_BETWEEN),e.justifyContent==="space-around"&&t.setJustifyContent(dn.default.JUSTIFY_SPACE_AROUND))},cEt=(t,e)=>{var r,o;"width"in e&&(typeof e.width=="number"?t.setWidth(e.width):typeof e.width=="string"?t.setWidthPercent(Number.parseInt(e.width,10)):t.setWidthAuto()),"height"in e&&(typeof e.height=="number"?t.setHeight(e.height):typeof e.height=="string"?t.setHeightPercent(Number.parseInt(e.height,10)):t.setHeightAuto()),"minWidth"in e&&(typeof e.minWidth=="string"?t.setMinWidthPercent(Number.parseInt(e.minWidth,10)):t.setMinWidth((r=e.minWidth)!==null&&r!==void 0?r:0)),"minHeight"in e&&(typeof e.minHeight=="string"?t.setMinHeightPercent(Number.parseInt(e.minHeight,10)):t.setMinHeight((o=e.minHeight)!==null&&o!==void 0?o:0))},uEt=(t,e)=>{"display"in e&&t.setDisplay(e.display==="flex"?dn.default.DISPLAY_FLEX:dn.default.DISPLAY_NONE)},AEt=(t,e)=>{if("borderStyle"in e){let r=typeof e.borderStyle=="string"?1:0;t.setBorder(dn.default.EDGE_TOP,r),t.setBorder(dn.default.EDGE_BOTTOM,r),t.setBorder(dn.default.EDGE_LEFT,r),t.setBorder(dn.default.EDGE_RIGHT,r)}};K2.default=(t,e={})=>{sEt(t,e),oEt(t,e),aEt(t,e),lEt(t,e),cEt(t,e),uEt(t,e),AEt(t,e)}});var JEe=_((TKt,zEe)=>{"use strict";var V2=Lk(),fEt=BP(),pEt=aI(),R6=new Set(["\x1B","\x9B"]),hEt=39,VEe=t=>`${R6.values().next().value}[${t}m`,gEt=t=>t.split(" ").map(e=>V2(e)),F6=(t,e,r)=>{let o=[...e],a=!1,n=V2(fEt(t[t.length-1]));for(let[u,A]of o.entries()){let p=V2(A);if(n+p<=r?t[t.length-1]+=A:(t.push(A),n=0),R6.has(A))a=!0;else if(a&&A==="m"){a=!1;continue}a||(n+=p,n===r&&u0&&t.length>1&&(t[t.length-2]+=t.pop())},dEt=t=>{let e=t.split(" "),r=e.length;for(;r>0&&!(V2(e[r-1])>0);)r--;return r===e.length?t:e.slice(0,r).join(" ")+e.slice(r).join("")},mEt=(t,e,r={})=>{if(r.trim!==!1&&t.trim()==="")return"";let o="",a="",n,u=gEt(t),A=[""];for(let[p,h]of t.split(" ").entries()){r.trim!==!1&&(A[A.length-1]=A[A.length-1].trimLeft());let E=V2(A[A.length-1]);if(p!==0&&(E>=e&&(r.wordWrap===!1||r.trim===!1)&&(A.push(""),E=0),(E>0||r.trim===!1)&&(A[A.length-1]+=" ",E++)),r.hard&&u[p]>e){let I=e-E,v=1+Math.floor((u[p]-I-1)/e);Math.floor((u[p]-1)/e)e&&E>0&&u[p]>0){if(r.wordWrap===!1&&Ee&&r.wordWrap===!1){F6(A,h,e);continue}A[A.length-1]+=h}r.trim!==!1&&(A=A.map(dEt)),o=A.join(` +`);for(let[p,h]of[...o].entries()){if(a+=h,R6.has(h)){let I=parseFloat(/\d[^m]*/.exec(o.slice(p,p+4)));n=I===hEt?null:I}let E=pEt.codes.get(Number(n));n&&E&&(o[p+1]===` +`?a+=VEe(E):h===` +`&&(a+=VEe(n)))}return a};zEe.exports=(t,e,r)=>String(t).normalize().replace(/\r\n/g,` +`).split(` +`).map(o=>mEt(o,e,r)).join(` +`)});var $Ee=_((NKt,ZEe)=>{"use strict";var XEe="[\uD800-\uDBFF][\uDC00-\uDFFF]",yEt=t=>t&&t.exact?new RegExp(`^${XEe}$`):new RegExp(XEe,"g");ZEe.exports=yEt});var T6=_((LKt,nCe)=>{"use strict";var EEt=b6(),CEt=$Ee(),eCe=aI(),rCe=["\x1B","\x9B"],Mk=t=>`${rCe[0]}[${t}m`,tCe=(t,e,r)=>{let o=[];t=[...t];for(let a of t){let n=a;a.match(";")&&(a=a.split(";")[0][0]+"0");let u=eCe.codes.get(parseInt(a,10));if(u){let A=t.indexOf(u.toString());A>=0?t.splice(A,1):o.push(Mk(e?u:n))}else if(e){o.push(Mk(0));break}else o.push(Mk(n))}if(e&&(o=o.filter((a,n)=>o.indexOf(a)===n),r!==void 0)){let a=Mk(eCe.codes.get(parseInt(r,10)));o=o.reduce((n,u)=>u===a?[u,...n]:[...n,u],[])}return o.join("")};nCe.exports=(t,e,r)=>{let o=[...t.normalize()],a=[];r=typeof r=="number"?r:o.length;let n=!1,u,A=0,p="";for(let[h,E]of o.entries()){let I=!1;if(rCe.includes(E)){let v=/\d[^m]*/.exec(t.slice(h,h+18));u=v&&v.length>0?v[0]:void 0,Ae&&A<=r)p+=E;else if(A===e&&!n&&u!==void 0)p=tCe(a);else if(A>=r){p+=tCe(a,!0,u);break}}return p}});var sCe=_((MKt,iCe)=>{"use strict";var Nh=T6(),wEt=Lk();function Ok(t,e,r){if(t.charAt(e)===" ")return e;for(let o=1;o<=3;o++)if(r){if(t.charAt(e+o)===" ")return e+o}else if(t.charAt(e-o)===" ")return e-o;return e}iCe.exports=(t,e,r)=>{r={position:"end",preferTruncationOnSpace:!1,...r};let{position:o,space:a,preferTruncationOnSpace:n}=r,u="\u2026",A=1;if(typeof t!="string")throw new TypeError(`Expected \`input\` to be a string, got ${typeof t}`);if(typeof e!="number")throw new TypeError(`Expected \`columns\` to be a number, got ${typeof e}`);if(e<1)return"";if(e===1)return u;let p=wEt(t);if(p<=e)return t;if(o==="start"){if(n){let h=Ok(t,p-e+1,!0);return u+Nh(t,h,p).trim()}return a===!0&&(u+=" ",A=2),u+Nh(t,p-e+A,p)}if(o==="middle"){a===!0&&(u=" "+u+" ",A=3);let h=Math.floor(e/2);if(n){let E=Ok(t,h),I=Ok(t,p-(e-h)+1,!0);return Nh(t,0,E)+u+Nh(t,I,p).trim()}return Nh(t,0,h)+u+Nh(t,p-(e-h)+A,p)}if(o==="end"){if(n){let h=Ok(t,e-1);return Nh(t,0,h)+u}return a===!0&&(u=" "+u,A=2),Nh(t,0,e-A)+u}throw new Error(`Expected \`options.position\` to be either \`start\`, \`middle\` or \`end\`, got ${o}`)}});var L6=_(z2=>{"use strict";var oCe=z2&&z2.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(z2,"__esModule",{value:!0});var IEt=oCe(JEe()),BEt=oCe(sCe()),N6={};z2.default=(t,e,r)=>{let o=t+String(e)+String(r);if(N6[o])return N6[o];let a=t;if(r==="wrap"&&(a=IEt.default(t,e,{trim:!1,hard:!0})),r.startsWith("truncate")){let n="end";r==="truncate-middle"&&(n="middle"),r==="truncate-start"&&(n="start"),a=BEt.default(t,e,{position:n})}return N6[o]=a,a}});var O6=_(M6=>{"use strict";Object.defineProperty(M6,"__esModule",{value:!0});var aCe=t=>{let e="";if(t.childNodes.length>0)for(let r of t.childNodes){let o="";r.nodeName==="#text"?o=r.nodeValue:((r.nodeName==="ink-text"||r.nodeName==="ink-virtual-text")&&(o=aCe(r)),o.length>0&&typeof r.internal_transform=="function"&&(o=r.internal_transform(o))),e+=o}return e};M6.default=aCe});var U6=_(pi=>{"use strict";var J2=pi&&pi.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(pi,"__esModule",{value:!0});pi.setTextNodeValue=pi.createTextNode=pi.setStyle=pi.setAttribute=pi.removeChildNode=pi.insertBeforeNode=pi.appendChildNode=pi.createNode=pi.TEXT_NAME=void 0;var vEt=J2(Jg()),lCe=J2(WEe()),DEt=J2(KEe()),PEt=J2(L6()),bEt=J2(O6());pi.TEXT_NAME="#text";pi.createNode=t=>{var e;let r={nodeName:t,style:{},attributes:{},childNodes:[],parentNode:null,yogaNode:t==="ink-virtual-text"?void 0:vEt.default.Node.create()};return t==="ink-text"&&((e=r.yogaNode)===null||e===void 0||e.setMeasureFunc(SEt.bind(null,r))),r};pi.appendChildNode=(t,e)=>{var r;e.parentNode&&pi.removeChildNode(e.parentNode,e),e.parentNode=t,t.childNodes.push(e),e.yogaNode&&((r=t.yogaNode)===null||r===void 0||r.insertChild(e.yogaNode,t.yogaNode.getChildCount())),(t.nodeName==="ink-text"||t.nodeName==="ink-virtual-text")&&Uk(t)};pi.insertBeforeNode=(t,e,r)=>{var o,a;e.parentNode&&pi.removeChildNode(e.parentNode,e),e.parentNode=t;let n=t.childNodes.indexOf(r);if(n>=0){t.childNodes.splice(n,0,e),e.yogaNode&&((o=t.yogaNode)===null||o===void 0||o.insertChild(e.yogaNode,n));return}t.childNodes.push(e),e.yogaNode&&((a=t.yogaNode)===null||a===void 0||a.insertChild(e.yogaNode,t.yogaNode.getChildCount())),(t.nodeName==="ink-text"||t.nodeName==="ink-virtual-text")&&Uk(t)};pi.removeChildNode=(t,e)=>{var r,o;e.yogaNode&&((o=(r=e.parentNode)===null||r===void 0?void 0:r.yogaNode)===null||o===void 0||o.removeChild(e.yogaNode)),e.parentNode=null;let a=t.childNodes.indexOf(e);a>=0&&t.childNodes.splice(a,1),(t.nodeName==="ink-text"||t.nodeName==="ink-virtual-text")&&Uk(t)};pi.setAttribute=(t,e,r)=>{t.attributes[e]=r};pi.setStyle=(t,e)=>{t.style=e,t.yogaNode&&DEt.default(t.yogaNode,e)};pi.createTextNode=t=>{let e={nodeName:"#text",nodeValue:t,yogaNode:void 0,parentNode:null,style:{}};return pi.setTextNodeValue(e,t),e};var SEt=function(t,e){var r,o;let a=t.nodeName==="#text"?t.nodeValue:bEt.default(t),n=lCe.default(a);if(n.width<=e||n.width>=1&&e>0&&e<1)return n;let u=(o=(r=t.style)===null||r===void 0?void 0:r.textWrap)!==null&&o!==void 0?o:"wrap",A=PEt.default(a,e,u);return lCe.default(A)},cCe=t=>{var e;if(!(!t||!t.parentNode))return(e=t.yogaNode)!==null&&e!==void 0?e:cCe(t.parentNode)},Uk=t=>{let e=cCe(t);e?.markDirty()};pi.setTextNodeValue=(t,e)=>{typeof e!="string"&&(e=String(e)),t.nodeValue=e,Uk(t)}});var hCe=_(X2=>{"use strict";var pCe=X2&&X2.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(X2,"__esModule",{value:!0});var uCe=w6(),xEt=pCe(FEe()),ACe=pCe(Jg()),Mo=U6(),fCe=t=>{t?.unsetMeasureFunc(),t?.freeRecursive()};X2.default=xEt.default({schedulePassiveEffects:uCe.unstable_scheduleCallback,cancelPassiveEffects:uCe.unstable_cancelCallback,now:Date.now,getRootHostContext:()=>({isInsideText:!1}),prepareForCommit:()=>{},resetAfterCommit:t=>{if(t.isStaticDirty){t.isStaticDirty=!1,typeof t.onImmediateRender=="function"&&t.onImmediateRender();return}typeof t.onRender=="function"&&t.onRender()},getChildHostContext:(t,e)=>{let r=t.isInsideText,o=e==="ink-text"||e==="ink-virtual-text";return r===o?t:{isInsideText:o}},shouldSetTextContent:()=>!1,createInstance:(t,e,r,o)=>{if(o.isInsideText&&t==="ink-box")throw new Error(" can\u2019t be nested inside component");let a=t==="ink-text"&&o.isInsideText?"ink-virtual-text":t,n=Mo.createNode(a);for(let[u,A]of Object.entries(e))u!=="children"&&(u==="style"?Mo.setStyle(n,A):u==="internal_transform"?n.internal_transform=A:u==="internal_static"?n.internal_static=!0:Mo.setAttribute(n,u,A));return n},createTextInstance:(t,e,r)=>{if(!r.isInsideText)throw new Error(`Text string "${t}" must be rendered inside component`);return Mo.createTextNode(t)},resetTextContent:()=>{},hideTextInstance:t=>{Mo.setTextNodeValue(t,"")},unhideTextInstance:(t,e)=>{Mo.setTextNodeValue(t,e)},getPublicInstance:t=>t,hideInstance:t=>{var e;(e=t.yogaNode)===null||e===void 0||e.setDisplay(ACe.default.DISPLAY_NONE)},unhideInstance:t=>{var e;(e=t.yogaNode)===null||e===void 0||e.setDisplay(ACe.default.DISPLAY_FLEX)},appendInitialChild:Mo.appendChildNode,appendChild:Mo.appendChildNode,insertBefore:Mo.insertBeforeNode,finalizeInitialChildren:(t,e,r,o)=>(t.internal_static&&(o.isStaticDirty=!0,o.staticNode=t),!1),supportsMutation:!0,appendChildToContainer:Mo.appendChildNode,insertInContainerBefore:Mo.insertBeforeNode,removeChildFromContainer:(t,e)=>{Mo.removeChildNode(t,e),fCe(e.yogaNode)},prepareUpdate:(t,e,r,o,a)=>{t.internal_static&&(a.isStaticDirty=!0);let n={},u=Object.keys(o);for(let A of u)if(o[A]!==r[A]){if(A==="style"&&typeof o.style=="object"&&typeof r.style=="object"){let h=o.style,E=r.style,I=Object.keys(h);for(let v of I){if(v==="borderStyle"||v==="borderColor"){if(typeof n.style!="object"){let x={};n.style=x}n.style.borderStyle=h.borderStyle,n.style.borderColor=h.borderColor}if(h[v]!==E[v]){if(typeof n.style!="object"){let x={};n.style=x}n.style[v]=h[v]}}continue}n[A]=o[A]}return n},commitUpdate:(t,e)=>{for(let[r,o]of Object.entries(e))r!=="children"&&(r==="style"?Mo.setStyle(t,o):r==="internal_transform"?t.internal_transform=o:r==="internal_static"?t.internal_static=!0:Mo.setAttribute(t,r,o))},commitTextUpdate:(t,e,r)=>{Mo.setTextNodeValue(t,r)},removeChild:(t,e)=>{Mo.removeChildNode(t,e),fCe(e.yogaNode)}})});var dCe=_((qKt,gCe)=>{"use strict";gCe.exports=(t,e=1,r)=>{if(r={indent:" ",includeEmptyLines:!1,...r},typeof t!="string")throw new TypeError(`Expected \`input\` to be a \`string\`, got \`${typeof t}\``);if(typeof e!="number")throw new TypeError(`Expected \`count\` to be a \`number\`, got \`${typeof e}\``);if(typeof r.indent!="string")throw new TypeError(`Expected \`options.indent\` to be a \`string\`, got \`${typeof r.indent}\``);if(e===0)return t;let o=r.includeEmptyLines?/^/gm:/^(?!\s*$)/gm;return t.replace(o,r.indent.repeat(e))}});var mCe=_(Z2=>{"use strict";var kEt=Z2&&Z2.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(Z2,"__esModule",{value:!0});var _k=kEt(Jg());Z2.default=t=>t.getComputedWidth()-t.getComputedPadding(_k.default.EDGE_LEFT)-t.getComputedPadding(_k.default.EDGE_RIGHT)-t.getComputedBorder(_k.default.EDGE_LEFT)-t.getComputedBorder(_k.default.EDGE_RIGHT)});var yCe=_((GKt,QEt)=>{QEt.exports={single:{topLeft:"\u250C",topRight:"\u2510",bottomRight:"\u2518",bottomLeft:"\u2514",vertical:"\u2502",horizontal:"\u2500"},double:{topLeft:"\u2554",topRight:"\u2557",bottomRight:"\u255D",bottomLeft:"\u255A",vertical:"\u2551",horizontal:"\u2550"},round:{topLeft:"\u256D",topRight:"\u256E",bottomRight:"\u256F",bottomLeft:"\u2570",vertical:"\u2502",horizontal:"\u2500"},bold:{topLeft:"\u250F",topRight:"\u2513",bottomRight:"\u251B",bottomLeft:"\u2517",vertical:"\u2503",horizontal:"\u2501"},singleDouble:{topLeft:"\u2553",topRight:"\u2556",bottomRight:"\u255C",bottomLeft:"\u2559",vertical:"\u2551",horizontal:"\u2500"},doubleSingle:{topLeft:"\u2552",topRight:"\u2555",bottomRight:"\u255B",bottomLeft:"\u2558",vertical:"\u2502",horizontal:"\u2550"},classic:{topLeft:"+",topRight:"+",bottomRight:"+",bottomLeft:"+",vertical:"|",horizontal:"-"}}});var CCe=_((YKt,_6)=>{"use strict";var ECe=yCe();_6.exports=ECe;_6.exports.default=ECe});var ICe=_((WKt,wCe)=>{"use strict";var FEt=(t,e,r)=>{let o=t.indexOf(e);if(o===-1)return t;let a=e.length,n=0,u="";do u+=t.substr(n,o-n)+e+r,n=o+a,o=t.indexOf(e,n);while(o!==-1);return u+=t.substr(n),u},REt=(t,e,r,o)=>{let a=0,n="";do{let u=t[o-1]==="\r";n+=t.substr(a,(u?o-1:o)-a)+e+(u?`\r +`:` +`)+r,a=o+1,o=t.indexOf(` +`,a)}while(o!==-1);return n+=t.substr(a),n};wCe.exports={stringReplaceAll:FEt,stringEncaseCRLFWithFirstIndex:REt}});var bCe=_((KKt,PCe)=>{"use strict";var TEt=/(?:\\(u(?:[a-f\d]{4}|\{[a-f\d]{1,6}\})|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi,BCe=/(?:^|\.)(\w+)(?:\(([^)]*)\))?/g,NEt=/^(['"])((?:\\.|(?!\1)[^\\])*)\1$/,LEt=/\\(u(?:[a-f\d]{4}|{[a-f\d]{1,6}})|x[a-f\d]{2}|.)|([^\\])/gi,MEt=new Map([["n",` +`],["r","\r"],["t"," "],["b","\b"],["f","\f"],["v","\v"],["0","\0"],["\\","\\"],["e","\x1B"],["a","\x07"]]);function DCe(t){let e=t[0]==="u",r=t[1]==="{";return e&&!r&&t.length===5||t[0]==="x"&&t.length===3?String.fromCharCode(parseInt(t.slice(1),16)):e&&r?String.fromCodePoint(parseInt(t.slice(2,-1),16)):MEt.get(t)||t}function OEt(t,e){let r=[],o=e.trim().split(/\s*,\s*/g),a;for(let n of o){let u=Number(n);if(!Number.isNaN(u))r.push(u);else if(a=n.match(NEt))r.push(a[2].replace(LEt,(A,p,h)=>p?DCe(p):h));else throw new Error(`Invalid Chalk template style argument: ${n} (in style '${t}')`)}return r}function UEt(t){BCe.lastIndex=0;let e=[],r;for(;(r=BCe.exec(t))!==null;){let o=r[1];if(r[2]){let a=OEt(o,r[2]);e.push([o].concat(a))}else e.push([o])}return e}function vCe(t,e){let r={};for(let a of e)for(let n of a.styles)r[n[0]]=a.inverse?null:n.slice(1);let o=t;for(let[a,n]of Object.entries(r))if(Array.isArray(n)){if(!(a in o))throw new Error(`Unknown Chalk style: ${a}`);o=n.length>0?o[a](...n):o[a]}return o}PCe.exports=(t,e)=>{let r=[],o=[],a=[];if(e.replace(TEt,(n,u,A,p,h,E)=>{if(u)a.push(DCe(u));else if(p){let I=a.join("");a=[],o.push(r.length===0?I:vCe(t,r)(I)),r.push({inverse:A,styles:UEt(p)})}else if(h){if(r.length===0)throw new Error("Found extraneous } in Chalk template literal");o.push(vCe(t,r)(a.join(""))),a=[],r.pop()}else a.push(E)}),o.push(a.join("")),r.length>0){let n=`Chalk template literal is missing ${r.length} closing bracket${r.length===1?"":"s"} (\`}\`)`;throw new Error(n)}return o.join("")}});var Yk=_((VKt,RCe)=>{"use strict";var $2=aI(),{stdout:q6,stderr:j6}=aN(),{stringReplaceAll:_Et,stringEncaseCRLFWithFirstIndex:HEt}=ICe(),{isArray:Hk}=Array,xCe=["ansi","ansi","ansi256","ansi16m"],nC=Object.create(null),qEt=(t,e={})=>{if(e.level&&!(Number.isInteger(e.level)&&e.level>=0&&e.level<=3))throw new Error("The `level` option should be an integer from 0 to 3");let r=q6?q6.level:0;t.level=e.level===void 0?r:e.level},G6=class{constructor(e){return kCe(e)}},kCe=t=>{let e={};return qEt(e,t),e.template=(...r)=>FCe(e.template,...r),Object.setPrototypeOf(e,qk.prototype),Object.setPrototypeOf(e.template,e),e.template.constructor=()=>{throw new Error("`chalk.constructor()` is deprecated. Use `new chalk.Instance()` instead.")},e.template.Instance=G6,e.template};function qk(t){return kCe(t)}for(let[t,e]of Object.entries($2))nC[t]={get(){let r=jk(this,Y6(e.open,e.close,this._styler),this._isEmpty);return Object.defineProperty(this,t,{value:r}),r}};nC.visible={get(){let t=jk(this,this._styler,!0);return Object.defineProperty(this,"visible",{value:t}),t}};var QCe=["rgb","hex","keyword","hsl","hsv","hwb","ansi","ansi256"];for(let t of QCe)nC[t]={get(){let{level:e}=this;return function(...r){let o=Y6($2.color[xCe[e]][t](...r),$2.color.close,this._styler);return jk(this,o,this._isEmpty)}}};for(let t of QCe){let e="bg"+t[0].toUpperCase()+t.slice(1);nC[e]={get(){let{level:r}=this;return function(...o){let a=Y6($2.bgColor[xCe[r]][t](...o),$2.bgColor.close,this._styler);return jk(this,a,this._isEmpty)}}}}var jEt=Object.defineProperties(()=>{},{...nC,level:{enumerable:!0,get(){return this._generator.level},set(t){this._generator.level=t}}}),Y6=(t,e,r)=>{let o,a;return r===void 0?(o=t,a=e):(o=r.openAll+t,a=e+r.closeAll),{open:t,close:e,openAll:o,closeAll:a,parent:r}},jk=(t,e,r)=>{let o=(...a)=>Hk(a[0])&&Hk(a[0].raw)?SCe(o,FCe(o,...a)):SCe(o,a.length===1?""+a[0]:a.join(" "));return Object.setPrototypeOf(o,jEt),o._generator=t,o._styler=e,o._isEmpty=r,o},SCe=(t,e)=>{if(t.level<=0||!e)return t._isEmpty?"":e;let r=t._styler;if(r===void 0)return e;let{openAll:o,closeAll:a}=r;if(e.indexOf("\x1B")!==-1)for(;r!==void 0;)e=_Et(e,r.close,r.open),r=r.parent;let n=e.indexOf(` +`);return n!==-1&&(e=HEt(e,a,o,n)),o+e+a},H6,FCe=(t,...e)=>{let[r]=e;if(!Hk(r)||!Hk(r.raw))return e.join(" ");let o=e.slice(1),a=[r.raw[0]];for(let n=1;n{"use strict";var GEt=tB&&tB.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(tB,"__esModule",{value:!0});var eB=GEt(Yk()),YEt=/^(rgb|hsl|hsv|hwb)\(\s?(\d+),\s?(\d+),\s?(\d+)\s?\)$/,WEt=/^(ansi|ansi256)\(\s?(\d+)\s?\)$/,Wk=(t,e)=>e==="foreground"?t:"bg"+t[0].toUpperCase()+t.slice(1);tB.default=(t,e,r)=>{if(!e)return t;if(e in eB.default){let a=Wk(e,r);return eB.default[a](t)}if(e.startsWith("#")){let a=Wk("hex",r);return eB.default[a](e)(t)}if(e.startsWith("ansi")){let a=WEt.exec(e);if(!a)return t;let n=Wk(a[1],r),u=Number(a[2]);return eB.default[n](u)(t)}if(e.startsWith("rgb")||e.startsWith("hsl")||e.startsWith("hsv")||e.startsWith("hwb")){let a=YEt.exec(e);if(!a)return t;let n=Wk(a[1],r),u=Number(a[2]),A=Number(a[3]),p=Number(a[4]);return eB.default[n](u,A,p)(t)}return t}});var NCe=_(rB=>{"use strict";var TCe=rB&&rB.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(rB,"__esModule",{value:!0});var KEt=TCe(CCe()),K6=TCe(W6());rB.default=(t,e,r,o)=>{if(typeof r.style.borderStyle=="string"){let a=r.yogaNode.getComputedWidth(),n=r.yogaNode.getComputedHeight(),u=r.style.borderColor,A=KEt.default[r.style.borderStyle],p=K6.default(A.topLeft+A.horizontal.repeat(a-2)+A.topRight,u,"foreground"),h=(K6.default(A.vertical,u,"foreground")+` +`).repeat(n-2),E=K6.default(A.bottomLeft+A.horizontal.repeat(a-2)+A.bottomRight,u,"foreground");o.write(t,e,p,{transformers:[]}),o.write(t,e+1,h,{transformers:[]}),o.write(t+a-1,e+1,h,{transformers:[]}),o.write(t,e+n-1,E,{transformers:[]})}}});var MCe=_(nB=>{"use strict";var Xg=nB&&nB.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(nB,"__esModule",{value:!0});var VEt=Xg(Jg()),zEt=Xg(k6()),JEt=Xg(dCe()),XEt=Xg(L6()),ZEt=Xg(mCe()),$Et=Xg(O6()),eCt=Xg(NCe()),tCt=(t,e)=>{var r;let o=(r=t.childNodes[0])===null||r===void 0?void 0:r.yogaNode;if(o){let a=o.getComputedLeft(),n=o.getComputedTop();e=` +`.repeat(n)+JEt.default(e,a)}return e},LCe=(t,e,r)=>{var o;let{offsetX:a=0,offsetY:n=0,transformers:u=[],skipStaticElements:A}=r;if(A&&t.internal_static)return;let{yogaNode:p}=t;if(p){if(p.getDisplay()===VEt.default.DISPLAY_NONE)return;let h=a+p.getComputedLeft(),E=n+p.getComputedTop(),I=u;if(typeof t.internal_transform=="function"&&(I=[t.internal_transform,...u]),t.nodeName==="ink-text"){let v=$Et.default(t);if(v.length>0){let x=zEt.default(v),C=ZEt.default(p);if(x>C){let R=(o=t.style.textWrap)!==null&&o!==void 0?o:"wrap";v=XEt.default(v,C,R)}v=tCt(t,v),e.write(h,E,v,{transformers:I})}return}if(t.nodeName==="ink-box"&&eCt.default(h,E,t,e),t.nodeName==="ink-root"||t.nodeName==="ink-box")for(let v of t.childNodes)LCe(v,e,{offsetX:h,offsetY:E,transformers:I,skipStaticElements:A})}};nB.default=LCe});var UCe=_((ZKt,OCe)=>{"use strict";OCe.exports=t=>{t=Object.assign({onlyFirst:!1},t);let e=["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)","(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))"].join("|");return new RegExp(e,t.onlyFirst?void 0:"g")}});var HCe=_(($Kt,V6)=>{"use strict";var rCt=UCe(),_Ce=t=>typeof t=="string"?t.replace(rCt(),""):t;V6.exports=_Ce;V6.exports.default=_Ce});var GCe=_((eVt,jCe)=>{"use strict";var qCe="[\uD800-\uDBFF][\uDC00-\uDFFF]";jCe.exports=t=>t&&t.exact?new RegExp(`^${qCe}$`):new RegExp(qCe,"g")});var WCe=_((tVt,z6)=>{"use strict";var nCt=HCe(),iCt=GCe(),YCe=t=>nCt(t).replace(iCt()," ").length;z6.exports=YCe;z6.exports.default=YCe});var zCe=_(iB=>{"use strict";var VCe=iB&&iB.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(iB,"__esModule",{value:!0});var KCe=VCe(T6()),sCt=VCe(WCe()),J6=class{constructor(e){this.writes=[];let{width:r,height:o}=e;this.width=r,this.height=o}write(e,r,o,a){let{transformers:n}=a;o&&this.writes.push({x:e,y:r,text:o,transformers:n})}get(){let e=[];for(let o=0;oo.trimRight()).join(` +`),height:e.length}}};iB.default=J6});var ZCe=_(sB=>{"use strict";var X6=sB&&sB.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(sB,"__esModule",{value:!0});var oCt=X6(Jg()),JCe=X6(MCe()),XCe=X6(zCe());sB.default=(t,e)=>{var r;if(t.yogaNode.setWidth(e),t.yogaNode){t.yogaNode.calculateLayout(void 0,void 0,oCt.default.DIRECTION_LTR);let o=new XCe.default({width:t.yogaNode.getComputedWidth(),height:t.yogaNode.getComputedHeight()});JCe.default(t,o,{skipStaticElements:!0});let a;!((r=t.staticNode)===null||r===void 0)&&r.yogaNode&&(a=new XCe.default({width:t.staticNode.yogaNode.getComputedWidth(),height:t.staticNode.yogaNode.getComputedHeight()}),JCe.default(t.staticNode,a,{skipStaticElements:!1}));let{output:n,height:u}=o.get();return{output:n,outputHeight:u,staticOutput:a?`${a.get().output} +`:""}}return{output:"",outputHeight:0,staticOutput:""}}});var rwe=_((iVt,twe)=>{"use strict";var $Ce=ve("stream"),ewe=["assert","count","countReset","debug","dir","dirxml","error","group","groupCollapsed","groupEnd","info","log","table","time","timeEnd","timeLog","trace","warn"],Z6={},aCt=t=>{let e=new $Ce.PassThrough,r=new $Ce.PassThrough;e.write=a=>t("stdout",a),r.write=a=>t("stderr",a);let o=new console.Console(e,r);for(let a of ewe)Z6[a]=console[a],console[a]=o[a];return()=>{for(let a of ewe)console[a]=Z6[a];Z6={}}};twe.exports=aCt});var eq=_($6=>{"use strict";Object.defineProperty($6,"__esModule",{value:!0});$6.default=new WeakMap});var rq=_(tq=>{"use strict";Object.defineProperty(tq,"__esModule",{value:!0});var lCt=an(),nwe=lCt.createContext({exit:()=>{}});nwe.displayName="InternalAppContext";tq.default=nwe});var iq=_(nq=>{"use strict";Object.defineProperty(nq,"__esModule",{value:!0});var cCt=an(),iwe=cCt.createContext({stdin:void 0,setRawMode:()=>{},isRawModeSupported:!1,internal_exitOnCtrlC:!0});iwe.displayName="InternalStdinContext";nq.default=iwe});var oq=_(sq=>{"use strict";Object.defineProperty(sq,"__esModule",{value:!0});var uCt=an(),swe=uCt.createContext({stdout:void 0,write:()=>{}});swe.displayName="InternalStdoutContext";sq.default=swe});var lq=_(aq=>{"use strict";Object.defineProperty(aq,"__esModule",{value:!0});var ACt=an(),owe=ACt.createContext({stderr:void 0,write:()=>{}});owe.displayName="InternalStderrContext";aq.default=owe});var Kk=_(cq=>{"use strict";Object.defineProperty(cq,"__esModule",{value:!0});var fCt=an(),awe=fCt.createContext({activeId:void 0,add:()=>{},remove:()=>{},activate:()=>{},deactivate:()=>{},enableFocus:()=>{},disableFocus:()=>{},focusNext:()=>{},focusPrevious:()=>{}});awe.displayName="InternalFocusContext";cq.default=awe});var cwe=_((AVt,lwe)=>{"use strict";var pCt=/[|\\{}()[\]^$+*?.-]/g;lwe.exports=t=>{if(typeof t!="string")throw new TypeError("Expected a string");return t.replace(pCt,"\\$&")}});var pwe=_((fVt,fwe)=>{"use strict";var hCt=cwe(),gCt=typeof process=="object"&&process&&typeof process.cwd=="function"?process.cwd():".",Awe=[].concat(ve("module").builtinModules,"bootstrap_node","node").map(t=>new RegExp(`(?:\\((?:node:)?${t}(?:\\.js)?:\\d+:\\d+\\)$|^\\s*at (?:node:)?${t}(?:\\.js)?:\\d+:\\d+$)`));Awe.push(/\((?:node:)?internal\/[^:]+:\d+:\d+\)$/,/\s*at (?:node:)?internal\/[^:]+:\d+:\d+$/,/\/\.node-spawn-wrap-\w+-\w+\/node:\d+:\d+\)?$/);var uq=class t{constructor(e){e={ignoredPackages:[],...e},"internals"in e||(e.internals=t.nodeInternals()),"cwd"in e||(e.cwd=gCt),this._cwd=e.cwd.replace(/\\/g,"/"),this._internals=[].concat(e.internals,dCt(e.ignoredPackages)),this._wrapCallSite=e.wrapCallSite||!1}static nodeInternals(){return[...Awe]}clean(e,r=0){r=" ".repeat(r),Array.isArray(e)||(e=e.split(` +`)),!/^\s*at /.test(e[0])&&/^\s*at /.test(e[1])&&(e=e.slice(1));let o=!1,a=null,n=[];return e.forEach(u=>{if(u=u.replace(/\\/g,"/"),this._internals.some(p=>p.test(u)))return;let A=/^\s*at /.test(u);o?u=u.trimEnd().replace(/^(\s+)at /,"$1"):(u=u.trim(),A&&(u=u.slice(3))),u=u.replace(`${this._cwd}/`,""),u&&(A?(a&&(n.push(a),a=null),n.push(u)):(o=!0,a=u))}),n.map(u=>`${r}${u} +`).join("")}captureString(e,r=this.captureString){typeof e=="function"&&(r=e,e=1/0);let{stackTraceLimit:o}=Error;e&&(Error.stackTraceLimit=e);let a={};Error.captureStackTrace(a,r);let{stack:n}=a;return Error.stackTraceLimit=o,this.clean(n)}capture(e,r=this.capture){typeof e=="function"&&(r=e,e=1/0);let{prepareStackTrace:o,stackTraceLimit:a}=Error;Error.prepareStackTrace=(A,p)=>this._wrapCallSite?p.map(this._wrapCallSite):p,e&&(Error.stackTraceLimit=e);let n={};Error.captureStackTrace(n,r);let{stack:u}=n;return Object.assign(Error,{prepareStackTrace:o,stackTraceLimit:a}),u}at(e=this.at){let[r]=this.capture(1,e);if(!r)return{};let o={line:r.getLineNumber(),column:r.getColumnNumber()};uwe(o,r.getFileName(),this._cwd),r.isConstructor()&&(o.constructor=!0),r.isEval()&&(o.evalOrigin=r.getEvalOrigin()),r.isNative()&&(o.native=!0);let a;try{a=r.getTypeName()}catch{}a&&a!=="Object"&&a!=="[object Object]"&&(o.type=a);let n=r.getFunctionName();n&&(o.function=n);let u=r.getMethodName();return u&&n!==u&&(o.method=u),o}parseLine(e){let r=e&&e.match(mCt);if(!r)return null;let o=r[1]==="new",a=r[2],n=r[3],u=r[4],A=Number(r[5]),p=Number(r[6]),h=r[7],E=r[8],I=r[9],v=r[10]==="native",x=r[11]===")",C,R={};if(E&&(R.line=Number(E)),I&&(R.column=Number(I)),x&&h){let L=0;for(let U=h.length-1;U>0;U--)if(h.charAt(U)===")")L++;else if(h.charAt(U)==="("&&h.charAt(U-1)===" "&&(L--,L===-1&&h.charAt(U-1)===" ")){let z=h.slice(0,U-1);h=h.slice(U+1),a+=` (${z}`;break}}if(a){let L=a.match(yCt);L&&(a=L[1],C=L[2])}return uwe(R,h,this._cwd),o&&(R.constructor=!0),n&&(R.evalOrigin=n,R.evalLine=A,R.evalColumn=p,R.evalFile=u&&u.replace(/\\/g,"/")),v&&(R.native=!0),a&&(R.function=a),C&&a!==C&&(R.method=C),R}};function uwe(t,e,r){e&&(e=e.replace(/\\/g,"/"),e.startsWith(`${r}/`)&&(e=e.slice(r.length+1)),t.file=e)}function dCt(t){if(t.length===0)return[];let e=t.map(r=>hCt(r));return new RegExp(`[/\\\\]node_modules[/\\\\](?:${e.join("|")})[/\\\\][^:]+:\\d+:\\d+`)}var mCt=new RegExp("^(?:\\s*at )?(?:(new) )?(?:(.*?) \\()?(?:eval at ([^ ]+) \\((.+?):(\\d+):(\\d+)\\), )?(?:(.+?):(\\d+):(\\d+)|(native))(\\)?)$"),yCt=/^(.*?) \[as (.*?)\]$/;fwe.exports=uq});var gwe=_((pVt,hwe)=>{"use strict";hwe.exports=(t,e)=>t.replace(/^\t+/gm,r=>" ".repeat(r.length*(e||2)))});var mwe=_((hVt,dwe)=>{"use strict";var ECt=gwe(),CCt=(t,e)=>{let r=[],o=t-e,a=t+e;for(let n=o;n<=a;n++)r.push(n);return r};dwe.exports=(t,e,r)=>{if(typeof t!="string")throw new TypeError("Source code is missing.");if(!e||e<1)throw new TypeError("Line number must start from `1`.");if(t=ECt(t).split(/\r?\n/),!(e>t.length))return r={around:3,...r},CCt(e,r.around).filter(o=>t[o-1]!==void 0).map(o=>({line:o,value:t[o-1]}))}});var Vk=_(iu=>{"use strict";var wCt=iu&&iu.__createBinding||(Object.create?function(t,e,r,o){o===void 0&&(o=r),Object.defineProperty(t,o,{enumerable:!0,get:function(){return e[r]}})}:function(t,e,r,o){o===void 0&&(o=r),t[o]=e[r]}),ICt=iu&&iu.__setModuleDefault||(Object.create?function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}:function(t,e){t.default=e}),BCt=iu&&iu.__importStar||function(t){if(t&&t.__esModule)return t;var e={};if(t!=null)for(var r in t)r!=="default"&&Object.hasOwnProperty.call(t,r)&&wCt(e,t,r);return ICt(e,t),e},vCt=iu&&iu.__rest||function(t,e){var r={};for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&e.indexOf(o)<0&&(r[o]=t[o]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var a=0,o=Object.getOwnPropertySymbols(t);a{var{children:r}=t,o=vCt(t,["children"]);let a=Object.assign(Object.assign({},o),{marginLeft:o.marginLeft||o.marginX||o.margin||0,marginRight:o.marginRight||o.marginX||o.margin||0,marginTop:o.marginTop||o.marginY||o.margin||0,marginBottom:o.marginBottom||o.marginY||o.margin||0,paddingLeft:o.paddingLeft||o.paddingX||o.padding||0,paddingRight:o.paddingRight||o.paddingX||o.padding||0,paddingTop:o.paddingTop||o.paddingY||o.padding||0,paddingBottom:o.paddingBottom||o.paddingY||o.padding||0});return ywe.default.createElement("ink-box",{ref:e,style:a},r)});Aq.displayName="Box";Aq.defaultProps={flexDirection:"row",flexGrow:0,flexShrink:1};iu.default=Aq});var hq=_(oB=>{"use strict";var fq=oB&&oB.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(oB,"__esModule",{value:!0});var DCt=fq(an()),iC=fq(Yk()),Ewe=fq(W6()),pq=({color:t,backgroundColor:e,dimColor:r,bold:o,italic:a,underline:n,strikethrough:u,inverse:A,wrap:p,children:h})=>{if(h==null)return null;let E=I=>(r&&(I=iC.default.dim(I)),t&&(I=Ewe.default(I,t,"foreground")),e&&(I=Ewe.default(I,e,"background")),o&&(I=iC.default.bold(I)),a&&(I=iC.default.italic(I)),n&&(I=iC.default.underline(I)),u&&(I=iC.default.strikethrough(I)),A&&(I=iC.default.inverse(I)),I);return DCt.default.createElement("ink-text",{style:{flexGrow:0,flexShrink:1,flexDirection:"row",textWrap:p},internal_transform:E},h)};pq.displayName="Text";pq.defaultProps={dimColor:!1,bold:!1,italic:!1,underline:!1,strikethrough:!1,wrap:"wrap"};oB.default=pq});var Bwe=_(su=>{"use strict";var PCt=su&&su.__createBinding||(Object.create?function(t,e,r,o){o===void 0&&(o=r),Object.defineProperty(t,o,{enumerable:!0,get:function(){return e[r]}})}:function(t,e,r,o){o===void 0&&(o=r),t[o]=e[r]}),bCt=su&&su.__setModuleDefault||(Object.create?function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}:function(t,e){t.default=e}),SCt=su&&su.__importStar||function(t){if(t&&t.__esModule)return t;var e={};if(t!=null)for(var r in t)r!=="default"&&Object.hasOwnProperty.call(t,r)&&PCt(e,t,r);return bCt(e,t),e},aB=su&&su.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(su,"__esModule",{value:!0});var Cwe=SCt(ve("fs")),hs=aB(an()),wwe=aB(pwe()),xCt=aB(mwe()),Vf=aB(Vk()),hA=aB(hq()),Iwe=new wwe.default({cwd:process.cwd(),internals:wwe.default.nodeInternals()}),kCt=({error:t})=>{let e=t.stack?t.stack.split(` +`).slice(1):void 0,r=e?Iwe.parseLine(e[0]):void 0,o,a=0;if(r?.file&&r?.line&&Cwe.existsSync(r.file)){let n=Cwe.readFileSync(r.file,"utf8");if(o=xCt.default(n,r.line),o)for(let{line:u}of o)a=Math.max(a,String(u).length)}return hs.default.createElement(Vf.default,{flexDirection:"column",padding:1},hs.default.createElement(Vf.default,null,hs.default.createElement(hA.default,{backgroundColor:"red",color:"white"}," ","ERROR"," "),hs.default.createElement(hA.default,null," ",t.message)),r&&hs.default.createElement(Vf.default,{marginTop:1},hs.default.createElement(hA.default,{dimColor:!0},r.file,":",r.line,":",r.column)),r&&o&&hs.default.createElement(Vf.default,{marginTop:1,flexDirection:"column"},o.map(({line:n,value:u})=>hs.default.createElement(Vf.default,{key:n},hs.default.createElement(Vf.default,{width:a+1},hs.default.createElement(hA.default,{dimColor:n!==r.line,backgroundColor:n===r.line?"red":void 0,color:n===r.line?"white":void 0},String(n).padStart(a," "),":")),hs.default.createElement(hA.default,{key:n,backgroundColor:n===r.line?"red":void 0,color:n===r.line?"white":void 0}," "+u)))),t.stack&&hs.default.createElement(Vf.default,{marginTop:1,flexDirection:"column"},t.stack.split(` +`).slice(1).map(n=>{let u=Iwe.parseLine(n);return u?hs.default.createElement(Vf.default,{key:n},hs.default.createElement(hA.default,{dimColor:!0},"- "),hs.default.createElement(hA.default,{dimColor:!0,bold:!0},u.function),hs.default.createElement(hA.default,{dimColor:!0,color:"gray"}," ","(",u.file,":",u.line,":",u.column,")")):hs.default.createElement(Vf.default,{key:n},hs.default.createElement(hA.default,{dimColor:!0},"- "),hs.default.createElement(hA.default,{dimColor:!0,bold:!0},n))})))};su.default=kCt});var Dwe=_(ou=>{"use strict";var QCt=ou&&ou.__createBinding||(Object.create?function(t,e,r,o){o===void 0&&(o=r),Object.defineProperty(t,o,{enumerable:!0,get:function(){return e[r]}})}:function(t,e,r,o){o===void 0&&(o=r),t[o]=e[r]}),FCt=ou&&ou.__setModuleDefault||(Object.create?function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}:function(t,e){t.default=e}),RCt=ou&&ou.__importStar||function(t){if(t&&t.__esModule)return t;var e={};if(t!=null)for(var r in t)r!=="default"&&Object.hasOwnProperty.call(t,r)&&QCt(e,t,r);return FCt(e,t),e},$g=ou&&ou.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(ou,"__esModule",{value:!0});var Zg=RCt(an()),vwe=$g(u6()),TCt=$g(rq()),NCt=$g(iq()),LCt=$g(oq()),MCt=$g(lq()),OCt=$g(Kk()),UCt=$g(Bwe()),_Ct=" ",HCt="\x1B[Z",qCt="\x1B",zk=class extends Zg.PureComponent{constructor(){super(...arguments),this.state={isFocusEnabled:!0,activeFocusId:void 0,focusables:[],error:void 0},this.rawModeEnabledCount=0,this.handleSetRawMode=e=>{let{stdin:r}=this.props;if(!this.isRawModeSupported())throw r===process.stdin?new Error(`Raw mode is not supported on the current process.stdin, which Ink uses as input stream by default. +Read about how to prevent this error on https://github.com/vadimdemedes/ink/#israwmodesupported`):new Error(`Raw mode is not supported on the stdin provided to Ink. +Read about how to prevent this error on https://github.com/vadimdemedes/ink/#israwmodesupported`);if(r.setEncoding("utf8"),e){this.rawModeEnabledCount===0&&(r.addListener("data",this.handleInput),r.resume(),r.setRawMode(!0)),this.rawModeEnabledCount++;return}--this.rawModeEnabledCount===0&&(r.setRawMode(!1),r.removeListener("data",this.handleInput),r.pause())},this.handleInput=e=>{e===""&&this.props.exitOnCtrlC&&this.handleExit(),e===qCt&&this.state.activeFocusId&&this.setState({activeFocusId:void 0}),this.state.isFocusEnabled&&this.state.focusables.length>0&&(e===_Ct&&this.focusNext(),e===HCt&&this.focusPrevious())},this.handleExit=e=>{this.isRawModeSupported()&&this.handleSetRawMode(!1),this.props.onExit(e)},this.enableFocus=()=>{this.setState({isFocusEnabled:!0})},this.disableFocus=()=>{this.setState({isFocusEnabled:!1})},this.focusNext=()=>{this.setState(e=>{let r=e.focusables[0].id;return{activeFocusId:this.findNextFocusable(e)||r}})},this.focusPrevious=()=>{this.setState(e=>{let r=e.focusables[e.focusables.length-1].id;return{activeFocusId:this.findPreviousFocusable(e)||r}})},this.addFocusable=(e,{autoFocus:r})=>{this.setState(o=>{let a=o.activeFocusId;return!a&&r&&(a=e),{activeFocusId:a,focusables:[...o.focusables,{id:e,isActive:!0}]}})},this.removeFocusable=e=>{this.setState(r=>({activeFocusId:r.activeFocusId===e?void 0:r.activeFocusId,focusables:r.focusables.filter(o=>o.id!==e)}))},this.activateFocusable=e=>{this.setState(r=>({focusables:r.focusables.map(o=>o.id!==e?o:{id:e,isActive:!0})}))},this.deactivateFocusable=e=>{this.setState(r=>({activeFocusId:r.activeFocusId===e?void 0:r.activeFocusId,focusables:r.focusables.map(o=>o.id!==e?o:{id:e,isActive:!1})}))},this.findNextFocusable=e=>{let r=e.focusables.findIndex(o=>o.id===e.activeFocusId);for(let o=r+1;o{let r=e.focusables.findIndex(o=>o.id===e.activeFocusId);for(let o=r-1;o>=0;o--)if(e.focusables[o].isActive)return e.focusables[o].id}}static getDerivedStateFromError(e){return{error:e}}isRawModeSupported(){return this.props.stdin.isTTY}render(){return Zg.default.createElement(TCt.default.Provider,{value:{exit:this.handleExit}},Zg.default.createElement(NCt.default.Provider,{value:{stdin:this.props.stdin,setRawMode:this.handleSetRawMode,isRawModeSupported:this.isRawModeSupported(),internal_exitOnCtrlC:this.props.exitOnCtrlC}},Zg.default.createElement(LCt.default.Provider,{value:{stdout:this.props.stdout,write:this.props.writeToStdout}},Zg.default.createElement(MCt.default.Provider,{value:{stderr:this.props.stderr,write:this.props.writeToStderr}},Zg.default.createElement(OCt.default.Provider,{value:{activeId:this.state.activeFocusId,add:this.addFocusable,remove:this.removeFocusable,activate:this.activateFocusable,deactivate:this.deactivateFocusable,enableFocus:this.enableFocus,disableFocus:this.disableFocus,focusNext:this.focusNext,focusPrevious:this.focusPrevious}},this.state.error?Zg.default.createElement(UCt.default,{error:this.state.error}):this.props.children)))))}componentDidMount(){vwe.default.hide(this.props.stdout)}componentWillUnmount(){vwe.default.show(this.props.stdout),this.isRawModeSupported()&&this.handleSetRawMode(!1)}componentDidCatch(e){this.handleExit(e)}};ou.default=zk;zk.displayName="InternalApp"});var Swe=_(au=>{"use strict";var jCt=au&&au.__createBinding||(Object.create?function(t,e,r,o){o===void 0&&(o=r),Object.defineProperty(t,o,{enumerable:!0,get:function(){return e[r]}})}:function(t,e,r,o){o===void 0&&(o=r),t[o]=e[r]}),GCt=au&&au.__setModuleDefault||(Object.create?function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}:function(t,e){t.default=e}),YCt=au&&au.__importStar||function(t){if(t&&t.__esModule)return t;var e={};if(t!=null)for(var r in t)r!=="default"&&Object.hasOwnProperty.call(t,r)&&jCt(e,t,r);return GCt(e,t),e},lu=au&&au.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(au,"__esModule",{value:!0});var WCt=lu(an()),Pwe=eO(),KCt=lu(pEe()),VCt=lu(s6()),zCt=lu(EEe()),JCt=lu(wEe()),gq=lu(hCe()),XCt=lu(ZCe()),ZCt=lu(c6()),$Ct=lu(rwe()),ewt=YCt(U6()),twt=lu(eq()),rwt=lu(Dwe()),sC=process.env.CI==="false"?!1:zCt.default,bwe=()=>{},dq=class{constructor(e){this.resolveExitPromise=()=>{},this.rejectExitPromise=()=>{},this.unsubscribeExit=()=>{},this.onRender=()=>{if(this.isUnmounted)return;let{output:r,outputHeight:o,staticOutput:a}=XCt.default(this.rootNode,this.options.stdout.columns||80),n=a&&a!==` +`;if(this.options.debug){n&&(this.fullStaticOutput+=a),this.options.stdout.write(this.fullStaticOutput+r);return}if(sC){n&&this.options.stdout.write(a),this.lastOutput=r;return}if(n&&(this.fullStaticOutput+=a),o>=this.options.stdout.rows){this.options.stdout.write(VCt.default.clearTerminal+this.fullStaticOutput+r),this.lastOutput=r;return}n&&(this.log.clear(),this.options.stdout.write(a),this.log(r)),!n&&r!==this.lastOutput&&this.throttledLog(r),this.lastOutput=r},JCt.default(this),this.options=e,this.rootNode=ewt.createNode("ink-root"),this.rootNode.onRender=e.debug?this.onRender:Pwe(this.onRender,32,{leading:!0,trailing:!0}),this.rootNode.onImmediateRender=this.onRender,this.log=KCt.default.create(e.stdout),this.throttledLog=e.debug?this.log:Pwe(this.log,void 0,{leading:!0,trailing:!0}),this.isUnmounted=!1,this.lastOutput="",this.fullStaticOutput="",this.container=gq.default.createContainer(this.rootNode,!1,!1),this.unsubscribeExit=ZCt.default(this.unmount,{alwaysLast:!1}),e.patchConsole&&this.patchConsole(),sC||(e.stdout.on("resize",this.onRender),this.unsubscribeResize=()=>{e.stdout.off("resize",this.onRender)})}render(e){let r=WCt.default.createElement(rwt.default,{stdin:this.options.stdin,stdout:this.options.stdout,stderr:this.options.stderr,writeToStdout:this.writeToStdout,writeToStderr:this.writeToStderr,exitOnCtrlC:this.options.exitOnCtrlC,onExit:this.unmount},e);gq.default.updateContainer(r,this.container,null,bwe)}writeToStdout(e){if(!this.isUnmounted){if(this.options.debug){this.options.stdout.write(e+this.fullStaticOutput+this.lastOutput);return}if(sC){this.options.stdout.write(e);return}this.log.clear(),this.options.stdout.write(e),this.log(this.lastOutput)}}writeToStderr(e){if(!this.isUnmounted){if(this.options.debug){this.options.stderr.write(e),this.options.stdout.write(this.fullStaticOutput+this.lastOutput);return}if(sC){this.options.stderr.write(e);return}this.log.clear(),this.options.stderr.write(e),this.log(this.lastOutput)}}unmount(e){this.isUnmounted||(this.onRender(),this.unsubscribeExit(),typeof this.restoreConsole=="function"&&this.restoreConsole(),typeof this.unsubscribeResize=="function"&&this.unsubscribeResize(),sC?this.options.stdout.write(this.lastOutput+` +`):this.options.debug||this.log.done(),this.isUnmounted=!0,gq.default.updateContainer(null,this.container,null,bwe),twt.default.delete(this.options.stdout),e instanceof Error?this.rejectExitPromise(e):this.resolveExitPromise())}waitUntilExit(){return this.exitPromise||(this.exitPromise=new Promise((e,r)=>{this.resolveExitPromise=e,this.rejectExitPromise=r})),this.exitPromise}clear(){!sC&&!this.options.debug&&this.log.clear()}patchConsole(){this.options.debug||(this.restoreConsole=$Ct.default((e,r)=>{e==="stdout"&&this.writeToStdout(r),e==="stderr"&&(r.startsWith("The above error occurred")||this.writeToStderr(r))}))}};au.default=dq});var kwe=_(lB=>{"use strict";var xwe=lB&&lB.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(lB,"__esModule",{value:!0});var nwt=xwe(Swe()),Jk=xwe(eq()),iwt=ve("stream"),swt=(t,e)=>{let r=Object.assign({stdout:process.stdout,stdin:process.stdin,stderr:process.stderr,debug:!1,exitOnCtrlC:!0,patchConsole:!0},owt(e)),o=awt(r.stdout,()=>new nwt.default(r));return o.render(t),{rerender:o.render,unmount:()=>o.unmount(),waitUntilExit:o.waitUntilExit,cleanup:()=>Jk.default.delete(r.stdout),clear:o.clear}};lB.default=swt;var owt=(t={})=>t instanceof iwt.Stream?{stdout:t,stdin:process.stdin}:t,awt=(t,e)=>{let r;return Jk.default.has(t)?r=Jk.default.get(t):(r=e(),Jk.default.set(t,r)),r}});var Fwe=_(zf=>{"use strict";var lwt=zf&&zf.__createBinding||(Object.create?function(t,e,r,o){o===void 0&&(o=r),Object.defineProperty(t,o,{enumerable:!0,get:function(){return e[r]}})}:function(t,e,r,o){o===void 0&&(o=r),t[o]=e[r]}),cwt=zf&&zf.__setModuleDefault||(Object.create?function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}:function(t,e){t.default=e}),uwt=zf&&zf.__importStar||function(t){if(t&&t.__esModule)return t;var e={};if(t!=null)for(var r in t)r!=="default"&&Object.hasOwnProperty.call(t,r)&&lwt(e,t,r);return cwt(e,t),e};Object.defineProperty(zf,"__esModule",{value:!0});var cB=uwt(an()),Qwe=t=>{let{items:e,children:r,style:o}=t,[a,n]=cB.useState(0),u=cB.useMemo(()=>e.slice(a),[e,a]);cB.useLayoutEffect(()=>{n(e.length)},[e.length]);let A=u.map((h,E)=>r(h,a+E)),p=cB.useMemo(()=>Object.assign({position:"absolute",flexDirection:"column"},o),[o]);return cB.default.createElement("ink-box",{internal_static:!0,style:p},A)};Qwe.displayName="Static";zf.default=Qwe});var Twe=_(uB=>{"use strict";var Awt=uB&&uB.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(uB,"__esModule",{value:!0});var fwt=Awt(an()),Rwe=({children:t,transform:e})=>t==null?null:fwt.default.createElement("ink-text",{style:{flexGrow:0,flexShrink:1,flexDirection:"row"},internal_transform:e},t);Rwe.displayName="Transform";uB.default=Rwe});var Lwe=_(AB=>{"use strict";var pwt=AB&&AB.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(AB,"__esModule",{value:!0});var hwt=pwt(an()),Nwe=({count:t=1})=>hwt.default.createElement("ink-text",null,` +`.repeat(t));Nwe.displayName="Newline";AB.default=Nwe});var Uwe=_(fB=>{"use strict";var Mwe=fB&&fB.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(fB,"__esModule",{value:!0});var gwt=Mwe(an()),dwt=Mwe(Vk()),Owe=()=>gwt.default.createElement(dwt.default,{flexGrow:1});Owe.displayName="Spacer";fB.default=Owe});var Xk=_(pB=>{"use strict";var mwt=pB&&pB.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(pB,"__esModule",{value:!0});var ywt=an(),Ewt=mwt(iq()),Cwt=()=>ywt.useContext(Ewt.default);pB.default=Cwt});var Hwe=_(hB=>{"use strict";var wwt=hB&&hB.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(hB,"__esModule",{value:!0});var _we=an(),Iwt=wwt(Xk()),Bwt=(t,e={})=>{let{stdin:r,setRawMode:o,internal_exitOnCtrlC:a}=Iwt.default();_we.useEffect(()=>{if(e.isActive!==!1)return o(!0),()=>{o(!1)}},[e.isActive,o]),_we.useEffect(()=>{if(e.isActive===!1)return;let n=u=>{let A=String(u),p={upArrow:A==="\x1B[A",downArrow:A==="\x1B[B",leftArrow:A==="\x1B[D",rightArrow:A==="\x1B[C",pageDown:A==="\x1B[6~",pageUp:A==="\x1B[5~",return:A==="\r",escape:A==="\x1B",ctrl:!1,shift:!1,tab:A===" "||A==="\x1B[Z",backspace:A==="\b",delete:A==="\x7F"||A==="\x1B[3~",meta:!1};A<=""&&!p.return&&(A=String.fromCharCode(A.charCodeAt(0)+97-1),p.ctrl=!0),A.startsWith("\x1B")&&(A=A.slice(1),p.meta=!0);let h=A>="A"&&A<="Z",E=A>="\u0410"&&A<="\u042F";A.length===1&&(h||E)&&(p.shift=!0),p.tab&&A==="[Z"&&(p.shift=!0),(p.tab||p.backspace||p.delete)&&(A=""),(!(A==="c"&&p.ctrl)||!a)&&t(A,p)};return r?.on("data",n),()=>{r?.off("data",n)}},[e.isActive,r,a,t])};hB.default=Bwt});var qwe=_(gB=>{"use strict";var vwt=gB&&gB.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(gB,"__esModule",{value:!0});var Dwt=an(),Pwt=vwt(rq()),bwt=()=>Dwt.useContext(Pwt.default);gB.default=bwt});var jwe=_(dB=>{"use strict";var Swt=dB&&dB.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(dB,"__esModule",{value:!0});var xwt=an(),kwt=Swt(oq()),Qwt=()=>xwt.useContext(kwt.default);dB.default=Qwt});var Gwe=_(mB=>{"use strict";var Fwt=mB&&mB.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(mB,"__esModule",{value:!0});var Rwt=an(),Twt=Fwt(lq()),Nwt=()=>Rwt.useContext(Twt.default);mB.default=Nwt});var Wwe=_(EB=>{"use strict";var Ywe=EB&&EB.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(EB,"__esModule",{value:!0});var yB=an(),Lwt=Ywe(Kk()),Mwt=Ywe(Xk()),Owt=({isActive:t=!0,autoFocus:e=!1}={})=>{let{isRawModeSupported:r,setRawMode:o}=Mwt.default(),{activeId:a,add:n,remove:u,activate:A,deactivate:p}=yB.useContext(Lwt.default),h=yB.useMemo(()=>Math.random().toString().slice(2,7),[]);return yB.useEffect(()=>(n(h,{autoFocus:e}),()=>{u(h)}),[h,e]),yB.useEffect(()=>{t?A(h):p(h)},[t,h]),yB.useEffect(()=>{if(!(!r||!t))return o(!0),()=>{o(!1)}},[t]),{isFocused:!!h&&a===h}};EB.default=Owt});var Kwe=_(CB=>{"use strict";var Uwt=CB&&CB.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(CB,"__esModule",{value:!0});var _wt=an(),Hwt=Uwt(Kk()),qwt=()=>{let t=_wt.useContext(Hwt.default);return{enableFocus:t.enableFocus,disableFocus:t.disableFocus,focusNext:t.focusNext,focusPrevious:t.focusPrevious}};CB.default=qwt});var Vwe=_(mq=>{"use strict";Object.defineProperty(mq,"__esModule",{value:!0});mq.default=t=>{var e,r,o,a;return{width:(r=(e=t.yogaNode)===null||e===void 0?void 0:e.getComputedWidth())!==null&&r!==void 0?r:0,height:(a=(o=t.yogaNode)===null||o===void 0?void 0:o.getComputedHeight())!==null&&a!==void 0?a:0}}});var ic=_(ro=>{"use strict";Object.defineProperty(ro,"__esModule",{value:!0});var jwt=kwe();Object.defineProperty(ro,"render",{enumerable:!0,get:function(){return jwt.default}});var Gwt=Vk();Object.defineProperty(ro,"Box",{enumerable:!0,get:function(){return Gwt.default}});var Ywt=hq();Object.defineProperty(ro,"Text",{enumerable:!0,get:function(){return Ywt.default}});var Wwt=Fwe();Object.defineProperty(ro,"Static",{enumerable:!0,get:function(){return Wwt.default}});var Kwt=Twe();Object.defineProperty(ro,"Transform",{enumerable:!0,get:function(){return Kwt.default}});var Vwt=Lwe();Object.defineProperty(ro,"Newline",{enumerable:!0,get:function(){return Vwt.default}});var zwt=Uwe();Object.defineProperty(ro,"Spacer",{enumerable:!0,get:function(){return zwt.default}});var Jwt=Hwe();Object.defineProperty(ro,"useInput",{enumerable:!0,get:function(){return Jwt.default}});var Xwt=qwe();Object.defineProperty(ro,"useApp",{enumerable:!0,get:function(){return Xwt.default}});var Zwt=Xk();Object.defineProperty(ro,"useStdin",{enumerable:!0,get:function(){return Zwt.default}});var $wt=jwe();Object.defineProperty(ro,"useStdout",{enumerable:!0,get:function(){return $wt.default}});var eIt=Gwe();Object.defineProperty(ro,"useStderr",{enumerable:!0,get:function(){return eIt.default}});var tIt=Wwe();Object.defineProperty(ro,"useFocus",{enumerable:!0,get:function(){return tIt.default}});var rIt=Kwe();Object.defineProperty(ro,"useFocusManager",{enumerable:!0,get:function(){return rIt.default}});var nIt=Vwe();Object.defineProperty(ro,"measureElement",{enumerable:!0,get:function(){return nIt.default}})});var Eq={};Vt(Eq,{Gem:()=>yq});var zwe,ed,yq,Zk=Et(()=>{zwe=Ze(ic()),ed=Ze(an()),yq=(0,ed.memo)(({active:t})=>{let e=(0,ed.useMemo)(()=>t?"\u25C9":"\u25EF",[t]),r=(0,ed.useMemo)(()=>t?"green":"yellow",[t]);return ed.default.createElement(zwe.Text,{color:r},e)})});var Xwe={};Vt(Xwe,{useKeypress:()=>td});function td({active:t},e,r){let{stdin:o}=(0,Jwe.useStdin)(),a=(0,$k.useCallback)((n,u)=>e(n,u),r);(0,$k.useEffect)(()=>{if(!(!t||!o))return o.on("keypress",a),()=>{o.off("keypress",a)}},[t,a,o])}var Jwe,$k,wB=Et(()=>{Jwe=Ze(ic()),$k=Ze(an())});var $we={};Vt($we,{FocusRequest:()=>Zwe,useFocusRequest:()=>Cq});var Zwe,Cq,wq=Et(()=>{wB();Zwe=(r=>(r.BEFORE="before",r.AFTER="after",r))(Zwe||{}),Cq=function({active:t},e,r){td({active:t},(o,a)=>{a.name==="tab"&&(a.shift?e("before"):e("after"))},r)}});var eIe={};Vt(eIe,{useListInput:()=>IB});var IB,eQ=Et(()=>{wB();IB=function(t,e,{active:r,minus:o,plus:a,set:n,loop:u=!0}){td({active:r},(A,p)=>{let h=e.indexOf(t);switch(p.name){case o:{let E=h-1;if(u){n(e[(e.length+E)%e.length]);return}if(E<0)return;n(e[E])}break;case a:{let E=h+1;if(u){n(e[E%e.length]);return}if(E>=e.length)return;n(e[E])}break}},[e,t,a,n,u])}});var tQ={};Vt(tQ,{ScrollableItems:()=>iIt});var Lh,Oa,iIt,rQ=Et(()=>{Lh=Ze(ic()),Oa=Ze(an());wq();eQ();iIt=({active:t=!0,children:e=[],radius:r=10,size:o=1,loop:a=!0,onFocusRequest:n,willReachEnd:u})=>{let A=L=>{if(L.key===null)throw new Error("Expected all children to have a key");return L.key},p=Oa.default.Children.map(e,L=>A(L)),h=p[0],[E,I]=(0,Oa.useState)(h),v=p.indexOf(E);(0,Oa.useEffect)(()=>{p.includes(E)||I(h)},[e]),(0,Oa.useEffect)(()=>{u&&v>=p.length-2&&u()},[v]),Cq({active:t&&!!n},L=>{n?.(L)},[n]),IB(E,p,{active:t,minus:"up",plus:"down",set:I,loop:a});let x=v-r,C=v+r;C>p.length&&(x-=C-p.length,C=p.length),x<0&&(C+=-x,x=0),C>=p.length&&(C=p.length-1);let R=[];for(let L=x;L<=C;++L){let U=p[L],z=t&&U===E;R.push(Oa.default.createElement(Lh.Box,{key:U,height:o},Oa.default.createElement(Lh.Box,{marginLeft:1,marginRight:1},Oa.default.createElement(Lh.Text,null,z?Oa.default.createElement(Lh.Text,{color:"cyan",bold:!0},">"):" ")),Oa.default.createElement(Lh.Box,null,Oa.default.cloneElement(e[L],{active:z}))))}return Oa.default.createElement(Lh.Box,{flexDirection:"column",width:"100%"},R)}});var tIe,Jf,rIe,Iq,nIe,Bq=Et(()=>{tIe=Ze(ic()),Jf=Ze(an()),rIe=ve("readline"),Iq=Jf.default.createContext(null),nIe=({children:t})=>{let{stdin:e,setRawMode:r}=(0,tIe.useStdin)();(0,Jf.useEffect)(()=>{r&&r(!0),e&&(0,rIe.emitKeypressEvents)(e)},[e,r]);let[o,a]=(0,Jf.useState)(new Map),n=(0,Jf.useMemo)(()=>({getAll:()=>o,get:u=>o.get(u),set:(u,A)=>a(new Map([...o,[u,A]]))}),[o,a]);return Jf.default.createElement(Iq.Provider,{value:n,children:t})}});var vq={};Vt(vq,{useMinistore:()=>sIt});function sIt(t,e){let r=(0,nQ.useContext)(Iq);if(r===null)throw new Error("Expected this hook to run with a ministore context attached");if(typeof t>"u")return r.getAll();let o=(0,nQ.useCallback)(n=>{r.set(t,n)},[t,r.set]),a=r.get(t);return typeof a>"u"&&(a=e),[a,o]}var nQ,Dq=Et(()=>{nQ=Ze(an());Bq()});var sQ={};Vt(sQ,{renderForm:()=>oIt});async function oIt(t,e,{stdin:r,stdout:o,stderr:a}){let n,u=p=>{let{exit:h}=(0,iQ.useApp)();td({active:!0},(E,I)=>{I.name==="return"&&(n=p,h())},[h,p])},{waitUntilExit:A}=(0,iQ.render)(Pq.default.createElement(nIe,null,Pq.default.createElement(t,{...e,useSubmit:u})),{stdin:r,stdout:o,stderr:a});return await A(),n}var iQ,Pq,oQ=Et(()=>{iQ=Ze(ic()),Pq=Ze(an());Bq();wB()});var aIe=_(BB=>{"use strict";Object.defineProperty(BB,"__esModule",{value:!0});BB.UncontrolledTextInput=void 0;var sIe=an(),bq=an(),iIe=ic(),rd=Yk(),oIe=({value:t,placeholder:e="",focus:r=!0,mask:o,highlightPastedText:a=!1,showCursor:n=!0,onChange:u,onSubmit:A})=>{let[{cursorOffset:p,cursorWidth:h},E]=bq.useState({cursorOffset:(t||"").length,cursorWidth:0});bq.useEffect(()=>{E(R=>{if(!r||!n)return R;let L=t||"";return R.cursorOffset>L.length-1?{cursorOffset:L.length,cursorWidth:0}:R})},[t,r,n]);let I=a?h:0,v=o?o.repeat(t.length):t,x=v,C=e?rd.grey(e):void 0;if(n&&r){C=e.length>0?rd.inverse(e[0])+rd.grey(e.slice(1)):rd.inverse(" "),x=v.length>0?"":rd.inverse(" ");let R=0;for(let L of v)R>=p-I&&R<=p?x+=rd.inverse(L):x+=L,R++;v.length>0&&p===v.length&&(x+=rd.inverse(" "))}return iIe.useInput((R,L)=>{if(L.upArrow||L.downArrow||L.ctrl&&R==="c"||L.tab||L.shift&&L.tab)return;if(L.return){A&&A(t);return}let U=p,z=t,te=0;L.leftArrow?n&&U--:L.rightArrow?n&&U++:L.backspace||L.delete?p>0&&(z=t.slice(0,p-1)+t.slice(p,t.length),U--):(z=t.slice(0,p)+R+t.slice(p,t.length),U+=R.length,R.length>1&&(te=R.length)),p<0&&(U=0),p>t.length&&(U=t.length),E({cursorOffset:U,cursorWidth:te}),z!==t&&u(z)},{isActive:r}),sIe.createElement(iIe.Text,null,e?v.length>0?x:C:x)};BB.default=oIe;BB.UncontrolledTextInput=t=>{let[e,r]=bq.useState("");return sIe.createElement(oIe,Object.assign({},t,{value:e,onChange:r}))}});var uIe={};Vt(uIe,{Pad:()=>Sq});var lIe,cIe,Sq,xq=Et(()=>{lIe=Ze(ic()),cIe=Ze(an()),Sq=({length:t,active:e})=>{if(t===0)return null;let r=t>1?` ${"-".repeat(t-1)}`:" ";return cIe.default.createElement(lIe.Text,{dimColor:!e},r)}});var AIe={};Vt(AIe,{ItemOptions:()=>aIt});var DB,Mh,aIt,fIe=Et(()=>{DB=Ze(ic()),Mh=Ze(an());eQ();Zk();xq();aIt=function({active:t,skewer:e,options:r,value:o,onChange:a,sizes:n=[]}){let u=r.filter(({label:p})=>!!p).map(({value:p})=>p),A=r.findIndex(p=>p.value===o&&p.label!="");return IB(o,u,{active:t,minus:"left",plus:"right",set:a}),Mh.default.createElement(Mh.default.Fragment,null,r.map(({label:p},h)=>{let E=h===A,I=n[h]-1||0,v=p.replace(/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g,""),x=Math.max(0,I-v.length-2);return p?Mh.default.createElement(DB.Box,{key:p,width:I,marginLeft:1},Mh.default.createElement(DB.Text,{wrap:"truncate"},Mh.default.createElement(yq,{active:E})," ",p),e?Mh.default.createElement(Sq,{active:t,length:x}):null):Mh.default.createElement(DB.Box,{key:`spacer-${h}`,width:I,marginLeft:1})}))}});var bIe=_((rJt,PIe)=>{var Oq;PIe.exports=()=>(typeof Oq>"u"&&(Oq=ve("zlib").brotliDecompressSync(Buffer.from("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","base64")).toString()),Oq)});var VIe=_((bJt,KIe)=>{var Kq=Symbol("arg flag"),sc=class t extends Error{constructor(e,r){super(e),this.name="ArgError",this.code=r,Object.setPrototypeOf(this,t.prototype)}};function HB(t,{argv:e=process.argv.slice(2),permissive:r=!1,stopAtPositional:o=!1}={}){if(!t)throw new sc("argument specification object is required","ARG_CONFIG_NO_SPEC");let a={_:[]},n={},u={};for(let A of Object.keys(t)){if(!A)throw new sc("argument key cannot be an empty string","ARG_CONFIG_EMPTY_KEY");if(A[0]!=="-")throw new sc(`argument key must start with '-' but found: '${A}'`,"ARG_CONFIG_NONOPT_KEY");if(A.length===1)throw new sc(`argument key must have a name; singular '-' keys are not allowed: ${A}`,"ARG_CONFIG_NONAME_KEY");if(typeof t[A]=="string"){n[A]=t[A];continue}let p=t[A],h=!1;if(Array.isArray(p)&&p.length===1&&typeof p[0]=="function"){let[E]=p;p=(I,v,x=[])=>(x.push(E(I,v,x[x.length-1])),x),h=E===Boolean||E[Kq]===!0}else if(typeof p=="function")h=p===Boolean||p[Kq]===!0;else throw new sc(`type missing or not a function or valid array type: ${A}`,"ARG_CONFIG_VAD_TYPE");if(A[1]!=="-"&&A.length>2)throw new sc(`short argument keys (with a single hyphen) must have only one character: ${A}`,"ARG_CONFIG_SHORTOPT_TOOLONG");u[A]=[p,h]}for(let A=0,p=e.length;A0){a._=a._.concat(e.slice(A));break}if(h==="--"){a._=a._.concat(e.slice(A+1));break}if(h.length>1&&h[0]==="-"){let E=h[1]==="-"||h.length===2?[h]:h.slice(1).split("").map(I=>`-${I}`);for(let I=0;I1&&e[A+1][0]==="-"&&!(e[A+1].match(/^-?\d*(\.(?=\d))?\d*$/)&&(L===Number||typeof BigInt<"u"&&L===BigInt))){let z=x===R?"":` (alias for ${R})`;throw new sc(`option requires argument: ${x}${z}`,"ARG_MISSING_REQUIRED_LONGARG")}a[R]=L(e[A+1],R,a[R]),++A}else a[R]=L(C,R,a[R])}}else a._.push(h)}return a}HB.flag=t=>(t[Kq]=!0,t);HB.COUNT=HB.flag((t,e,r)=>(r||0)+1);HB.ArgError=sc;KIe.exports=HB});var r1e=_((nXt,t1e)=>{var Xq;t1e.exports=()=>(typeof Xq>"u"&&(Xq=ve("zlib").brotliDecompressSync(Buffer.from("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","base64")).toString()),Xq)});var a1e=_((nj,ij)=>{(function(t){nj&&typeof nj=="object"&&typeof ij<"u"?ij.exports=t():typeof define=="function"&&define.amd?define([],t):typeof window<"u"?window.isWindows=t():typeof global<"u"?global.isWindows=t():typeof self<"u"?self.isWindows=t():this.isWindows=t()})(function(){"use strict";return function(){return process&&(process.platform==="win32"||/^(msys|cygwin)$/.test(process.env.OSTYPE))}})});var A1e=_((tZt,u1e)=>{"use strict";sj.ifExists=i1t;var uC=ve("util"),oc=ve("path"),l1e=a1e(),t1t=/^#!\s*(?:\/usr\/bin\/env)?\s*([^ \t]+)(.*)$/,r1t={createPwshFile:!0,createCmdFile:l1e(),fs:ve("fs")},n1t=new Map([[".js","node"],[".cjs","node"],[".mjs","node"],[".cmd","cmd"],[".bat","cmd"],[".ps1","pwsh"],[".sh","sh"]]);function c1e(t){let e={...r1t,...t},r=e.fs;return e.fs_={chmod:r.chmod?uC.promisify(r.chmod):async()=>{},mkdir:uC.promisify(r.mkdir),readFile:uC.promisify(r.readFile),stat:uC.promisify(r.stat),unlink:uC.promisify(r.unlink),writeFile:uC.promisify(r.writeFile)},e}async function sj(t,e,r){let o=c1e(r);await o.fs_.stat(t),await o1t(t,e,o)}function i1t(t,e,r){return sj(t,e,r).catch(()=>{})}function s1t(t,e){return e.fs_.unlink(t).catch(()=>{})}async function o1t(t,e,r){let o=await A1t(t,r);return await a1t(e,r),l1t(t,e,o,r)}function a1t(t,e){return e.fs_.mkdir(oc.dirname(t),{recursive:!0})}function l1t(t,e,r,o){let a=c1e(o),n=[{generator:h1t,extension:""}];return a.createCmdFile&&n.push({generator:p1t,extension:".cmd"}),a.createPwshFile&&n.push({generator:g1t,extension:".ps1"}),Promise.all(n.map(u=>f1t(t,e+u.extension,r,u.generator,a)))}function c1t(t,e){return s1t(t,e)}function u1t(t,e){return d1t(t,e)}async function A1t(t,e){let a=(await e.fs_.readFile(t,"utf8")).trim().split(/\r*\n/)[0].match(t1t);if(!a){let n=oc.extname(t).toLowerCase();return{program:n1t.get(n)||null,additionalArgs:""}}return{program:a[1],additionalArgs:a[2]}}async function f1t(t,e,r,o,a){let n=a.preserveSymlinks?"--preserve-symlinks":"",u=[r.additionalArgs,n].filter(A=>A).join(" ");return a=Object.assign({},a,{prog:r.program,args:u}),await c1t(e,a),await a.fs_.writeFile(e,o(t,e,a),"utf8"),u1t(e,a)}function p1t(t,e,r){let a=oc.relative(oc.dirname(e),t).split("/").join("\\"),n=oc.isAbsolute(a)?`"${a}"`:`"%~dp0\\${a}"`,u,A=r.prog,p=r.args||"",h=oj(r.nodePath).win32;A?(u=`"%~dp0\\${A}.exe"`,a=n):(A=n,p="",a="");let E=r.progArgs?`${r.progArgs.join(" ")} `:"",I=h?`@SET NODE_PATH=${h}\r +`:"";return u?I+=`@IF EXIST ${u} (\r + ${u} ${p} ${a} ${E}%*\r +) ELSE (\r + @SETLOCAL\r + @SET PATHEXT=%PATHEXT:;.JS;=;%\r + ${A} ${p} ${a} ${E}%*\r +)\r +`:I+=`@${A} ${p} ${a} ${E}%*\r +`,I}function h1t(t,e,r){let o=oc.relative(oc.dirname(e),t),a=r.prog&&r.prog.split("\\").join("/"),n;o=o.split("\\").join("/");let u=oc.isAbsolute(o)?`"${o}"`:`"$basedir/${o}"`,A=r.args||"",p=oj(r.nodePath).posix;a?(n=`"$basedir/${r.prog}"`,o=u):(a=u,A="",o="");let h=r.progArgs?`${r.progArgs.join(" ")} `:"",E=`#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\\\,/,g')") + +case \`uname\` in + *CYGWIN*) basedir=\`cygpath -w "$basedir"\`;; +esac + +`,I=r.nodePath?`export NODE_PATH="${p}" +`:"";return n?E+=`${I}if [ -x ${n} ]; then + exec ${n} ${A} ${o} ${h}"$@" +else + exec ${a} ${A} ${o} ${h}"$@" +fi +`:E+=`${I}${a} ${A} ${o} ${h}"$@" +exit $? +`,E}function g1t(t,e,r){let o=oc.relative(oc.dirname(e),t),a=r.prog&&r.prog.split("\\").join("/"),n=a&&`"${a}$exe"`,u;o=o.split("\\").join("/");let A=oc.isAbsolute(o)?`"${o}"`:`"$basedir/${o}"`,p=r.args||"",h=oj(r.nodePath),E=h.win32,I=h.posix;n?(u=`"$basedir/${r.prog}$exe"`,o=A):(n=A,p="",o="");let v=r.progArgs?`${r.progArgs.join(" ")} `:"",x=`#!/usr/bin/env pwsh +$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent + +$exe="" +${r.nodePath?`$env_node_path=$env:NODE_PATH +$env:NODE_PATH="${E}" +`:""}if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { + # Fix case when both the Windows and Linux builds of Node + # are installed in the same directory + $exe=".exe" +}`;return r.nodePath&&(x+=` else { + $env:NODE_PATH="${I}" +}`),u?x+=` +$ret=0 +if (Test-Path ${u}) { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & ${u} ${p} ${o} ${v}$args + } else { + & ${u} ${p} ${o} ${v}$args + } + $ret=$LASTEXITCODE +} else { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & ${n} ${p} ${o} ${v}$args + } else { + & ${n} ${p} ${o} ${v}$args + } + $ret=$LASTEXITCODE +} +${r.nodePath?`$env:NODE_PATH=$env_node_path +`:""}exit $ret +`:x+=` +# Support pipeline input +if ($MyInvocation.ExpectingInput) { + $input | & ${n} ${p} ${o} ${v}$args +} else { + & ${n} ${p} ${o} ${v}$args +} +${r.nodePath?`$env:NODE_PATH=$env_node_path +`:""}exit $LASTEXITCODE +`,x}function d1t(t,e){return e.fs_.chmod(t,493)}function oj(t){if(!t)return{win32:"",posix:""};let e=typeof t=="string"?t.split(oc.delimiter):Array.from(t),r={};for(let o=0;o`/mnt/${A.toLowerCase()}`):e[o];r.win32=r.win32?`${r.win32};${a}`:a,r.posix=r.posix?`${r.posix}:${n}`:n,r[o]={win32:a,posix:n}}return r}u1e.exports=sj});var Cj=_((I$t,Q1e)=>{Q1e.exports=ve("stream")});var N1e=_((B$t,T1e)=>{"use strict";function F1e(t,e){var r=Object.keys(t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(t);e&&(o=o.filter(function(a){return Object.getOwnPropertyDescriptor(t,a).enumerable})),r.push.apply(r,o)}return r}function j1t(t){for(var e=1;e0?this.tail.next=o:this.head=o,this.tail=o,++this.length}},{key:"unshift",value:function(r){var o={data:r,next:this.head};this.length===0&&(this.tail=o),this.head=o,++this.length}},{key:"shift",value:function(){if(this.length!==0){var r=this.head.data;return this.length===1?this.head=this.tail=null:this.head=this.head.next,--this.length,r}}},{key:"clear",value:function(){this.head=this.tail=null,this.length=0}},{key:"join",value:function(r){if(this.length===0)return"";for(var o=this.head,a=""+o.data;o=o.next;)a+=r+o.data;return a}},{key:"concat",value:function(r){if(this.length===0)return yQ.alloc(0);for(var o=yQ.allocUnsafe(r>>>0),a=this.head,n=0;a;)J1t(a.data,o,n),n+=a.data.length,a=a.next;return o}},{key:"consume",value:function(r,o){var a;return ru.length?u.length:r;if(A===u.length?n+=u:n+=u.slice(0,r),r-=A,r===0){A===u.length?(++a,o.next?this.head=o.next:this.head=this.tail=null):(this.head=o,o.data=u.slice(A));break}++a}return this.length-=a,n}},{key:"_getBuffer",value:function(r){var o=yQ.allocUnsafe(r),a=this.head,n=1;for(a.data.copy(o),r-=a.data.length;a=a.next;){var u=a.data,A=r>u.length?u.length:r;if(u.copy(o,o.length-r,0,A),r-=A,r===0){A===u.length?(++n,a.next?this.head=a.next:this.head=this.tail=null):(this.head=a,a.data=u.slice(A));break}++n}return this.length-=n,o}},{key:z1t,value:function(r,o){return wj(this,j1t({},o,{depth:0,customInspect:!1}))}}]),t}()});var Bj=_((v$t,M1e)=>{"use strict";function X1t(t,e){var r=this,o=this._readableState&&this._readableState.destroyed,a=this._writableState&&this._writableState.destroyed;return o||a?(e?e(t):t&&(this._writableState?this._writableState.errorEmitted||(this._writableState.errorEmitted=!0,process.nextTick(Ij,this,t)):process.nextTick(Ij,this,t)),this):(this._readableState&&(this._readableState.destroyed=!0),this._writableState&&(this._writableState.destroyed=!0),this._destroy(t||null,function(n){!e&&n?r._writableState?r._writableState.errorEmitted?process.nextTick(EQ,r):(r._writableState.errorEmitted=!0,process.nextTick(L1e,r,n)):process.nextTick(L1e,r,n):e?(process.nextTick(EQ,r),e(n)):process.nextTick(EQ,r)}),this)}function L1e(t,e){Ij(t,e),EQ(t)}function EQ(t){t._writableState&&!t._writableState.emitClose||t._readableState&&!t._readableState.emitClose||t.emit("close")}function Z1t(){this._readableState&&(this._readableState.destroyed=!1,this._readableState.reading=!1,this._readableState.ended=!1,this._readableState.endEmitted=!1),this._writableState&&(this._writableState.destroyed=!1,this._writableState.ended=!1,this._writableState.ending=!1,this._writableState.finalCalled=!1,this._writableState.prefinished=!1,this._writableState.finished=!1,this._writableState.errorEmitted=!1)}function Ij(t,e){t.emit("error",e)}function $1t(t,e){var r=t._readableState,o=t._writableState;r&&r.autoDestroy||o&&o.autoDestroy?t.destroy(e):t.emit("error",e)}M1e.exports={destroy:X1t,undestroy:Z1t,errorOrDestroy:$1t}});var Gh=_((D$t,_1e)=>{"use strict";var U1e={};function lc(t,e,r){r||(r=Error);function o(n,u,A){return typeof e=="string"?e:e(n,u,A)}class a extends r{constructor(u,A,p){super(o(u,A,p))}}a.prototype.name=r.name,a.prototype.code=t,U1e[t]=a}function O1e(t,e){if(Array.isArray(t)){let r=t.length;return t=t.map(o=>String(o)),r>2?`one of ${e} ${t.slice(0,r-1).join(", ")}, or `+t[r-1]:r===2?`one of ${e} ${t[0]} or ${t[1]}`:`of ${e} ${t[0]}`}else return`of ${e} ${String(t)}`}function e2t(t,e,r){return t.substr(!r||r<0?0:+r,e.length)===e}function t2t(t,e,r){return(r===void 0||r>t.length)&&(r=t.length),t.substring(r-e.length,r)===e}function r2t(t,e,r){return typeof r!="number"&&(r=0),r+e.length>t.length?!1:t.indexOf(e,r)!==-1}lc("ERR_INVALID_OPT_VALUE",function(t,e){return'The value "'+e+'" is invalid for option "'+t+'"'},TypeError);lc("ERR_INVALID_ARG_TYPE",function(t,e,r){let o;typeof e=="string"&&e2t(e,"not ")?(o="must not be",e=e.replace(/^not /,"")):o="must be";let a;if(t2t(t," argument"))a=`The ${t} ${o} ${O1e(e,"type")}`;else{let n=r2t(t,".")?"property":"argument";a=`The "${t}" ${n} ${o} ${O1e(e,"type")}`}return a+=`. Received type ${typeof r}`,a},TypeError);lc("ERR_STREAM_PUSH_AFTER_EOF","stream.push() after EOF");lc("ERR_METHOD_NOT_IMPLEMENTED",function(t){return"The "+t+" method is not implemented"});lc("ERR_STREAM_PREMATURE_CLOSE","Premature close");lc("ERR_STREAM_DESTROYED",function(t){return"Cannot call "+t+" after a stream was destroyed"});lc("ERR_MULTIPLE_CALLBACK","Callback called multiple times");lc("ERR_STREAM_CANNOT_PIPE","Cannot pipe, not readable");lc("ERR_STREAM_WRITE_AFTER_END","write after end");lc("ERR_STREAM_NULL_VALUES","May not write null values to stream",TypeError);lc("ERR_UNKNOWN_ENCODING",function(t){return"Unknown encoding: "+t},TypeError);lc("ERR_STREAM_UNSHIFT_AFTER_END_EVENT","stream.unshift() after end event");_1e.exports.codes=U1e});var vj=_((P$t,H1e)=>{"use strict";var n2t=Gh().codes.ERR_INVALID_OPT_VALUE;function i2t(t,e,r){return t.highWaterMark!=null?t.highWaterMark:e?t[r]:null}function s2t(t,e,r,o){var a=i2t(e,o,r);if(a!=null){if(!(isFinite(a)&&Math.floor(a)===a)||a<0){var n=o?r:"highWaterMark";throw new n2t(n,a)}return Math.floor(a)}return t.objectMode?16:16*1024}H1e.exports={getHighWaterMark:s2t}});var q1e=_((b$t,Dj)=>{typeof Object.create=="function"?Dj.exports=function(e,r){r&&(e.super_=r,e.prototype=Object.create(r.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}))}:Dj.exports=function(e,r){if(r){e.super_=r;var o=function(){};o.prototype=r.prototype,e.prototype=new o,e.prototype.constructor=e}}});var Yh=_((S$t,bj)=>{try{if(Pj=ve("util"),typeof Pj.inherits!="function")throw"";bj.exports=Pj.inherits}catch{bj.exports=q1e()}var Pj});var G1e=_((x$t,j1e)=>{j1e.exports=ve("util").deprecate});var kj=_((k$t,J1e)=>{"use strict";J1e.exports=Fi;function W1e(t){var e=this;this.next=null,this.entry=null,this.finish=function(){F2t(e,t)}}var gC;Fi.WritableState=$B;var o2t={deprecate:G1e()},K1e=Cj(),wQ=ve("buffer").Buffer,a2t=global.Uint8Array||function(){};function l2t(t){return wQ.from(t)}function c2t(t){return wQ.isBuffer(t)||t instanceof a2t}var xj=Bj(),u2t=vj(),A2t=u2t.getHighWaterMark,Wh=Gh().codes,f2t=Wh.ERR_INVALID_ARG_TYPE,p2t=Wh.ERR_METHOD_NOT_IMPLEMENTED,h2t=Wh.ERR_MULTIPLE_CALLBACK,g2t=Wh.ERR_STREAM_CANNOT_PIPE,d2t=Wh.ERR_STREAM_DESTROYED,m2t=Wh.ERR_STREAM_NULL_VALUES,y2t=Wh.ERR_STREAM_WRITE_AFTER_END,E2t=Wh.ERR_UNKNOWN_ENCODING,dC=xj.errorOrDestroy;Yh()(Fi,K1e);function C2t(){}function $B(t,e,r){gC=gC||ld(),t=t||{},typeof r!="boolean"&&(r=e instanceof gC),this.objectMode=!!t.objectMode,r&&(this.objectMode=this.objectMode||!!t.writableObjectMode),this.highWaterMark=A2t(this,t,"writableHighWaterMark",r),this.finalCalled=!1,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1,this.destroyed=!1;var o=t.decodeStrings===!1;this.decodeStrings=!o,this.defaultEncoding=t.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(a){b2t(e,a)},this.writecb=null,this.writelen=0,this.bufferedRequest=null,this.lastBufferedRequest=null,this.pendingcb=0,this.prefinished=!1,this.errorEmitted=!1,this.emitClose=t.emitClose!==!1,this.autoDestroy=!!t.autoDestroy,this.bufferedRequestCount=0,this.corkedRequestsFree=new W1e(this)}$B.prototype.getBuffer=function(){for(var e=this.bufferedRequest,r=[];e;)r.push(e),e=e.next;return r};(function(){try{Object.defineProperty($B.prototype,"buffer",{get:o2t.deprecate(function(){return this.getBuffer()},"_writableState.buffer is deprecated. Use _writableState.getBuffer instead.","DEP0003")})}catch{}})();var CQ;typeof Symbol=="function"&&Symbol.hasInstance&&typeof Function.prototype[Symbol.hasInstance]=="function"?(CQ=Function.prototype[Symbol.hasInstance],Object.defineProperty(Fi,Symbol.hasInstance,{value:function(e){return CQ.call(this,e)?!0:this!==Fi?!1:e&&e._writableState instanceof $B}})):CQ=function(e){return e instanceof this};function Fi(t){gC=gC||ld();var e=this instanceof gC;if(!e&&!CQ.call(Fi,this))return new Fi(t);this._writableState=new $B(t,this,e),this.writable=!0,t&&(typeof t.write=="function"&&(this._write=t.write),typeof t.writev=="function"&&(this._writev=t.writev),typeof t.destroy=="function"&&(this._destroy=t.destroy),typeof t.final=="function"&&(this._final=t.final)),K1e.call(this)}Fi.prototype.pipe=function(){dC(this,new g2t)};function w2t(t,e){var r=new y2t;dC(t,r),process.nextTick(e,r)}function I2t(t,e,r,o){var a;return r===null?a=new m2t:typeof r!="string"&&!e.objectMode&&(a=new f2t("chunk",["string","Buffer"],r)),a?(dC(t,a),process.nextTick(o,a),!1):!0}Fi.prototype.write=function(t,e,r){var o=this._writableState,a=!1,n=!o.objectMode&&c2t(t);return n&&!wQ.isBuffer(t)&&(t=l2t(t)),typeof e=="function"&&(r=e,e=null),n?e="buffer":e||(e=o.defaultEncoding),typeof r!="function"&&(r=C2t),o.ending?w2t(this,r):(n||I2t(this,o,t,r))&&(o.pendingcb++,a=v2t(this,o,n,t,e,r)),a};Fi.prototype.cork=function(){this._writableState.corked++};Fi.prototype.uncork=function(){var t=this._writableState;t.corked&&(t.corked--,!t.writing&&!t.corked&&!t.bufferProcessing&&t.bufferedRequest&&V1e(this,t))};Fi.prototype.setDefaultEncoding=function(e){if(typeof e=="string"&&(e=e.toLowerCase()),!(["hex","utf8","utf-8","ascii","binary","base64","ucs2","ucs-2","utf16le","utf-16le","raw"].indexOf((e+"").toLowerCase())>-1))throw new E2t(e);return this._writableState.defaultEncoding=e,this};Object.defineProperty(Fi.prototype,"writableBuffer",{enumerable:!1,get:function(){return this._writableState&&this._writableState.getBuffer()}});function B2t(t,e,r){return!t.objectMode&&t.decodeStrings!==!1&&typeof e=="string"&&(e=wQ.from(e,r)),e}Object.defineProperty(Fi.prototype,"writableHighWaterMark",{enumerable:!1,get:function(){return this._writableState.highWaterMark}});function v2t(t,e,r,o,a,n){if(!r){var u=B2t(e,o,a);o!==u&&(r=!0,a="buffer",o=u)}var A=e.objectMode?1:o.length;e.length+=A;var p=e.length{"use strict";var R2t=Object.keys||function(t){var e=[];for(var r in t)e.push(r);return e};Z1e.exports=yA;var X1e=Rj(),Fj=kj();Yh()(yA,X1e);for(Qj=R2t(Fj.prototype),IQ=0;IQ{var vQ=ve("buffer"),rp=vQ.Buffer;function $1e(t,e){for(var r in t)e[r]=t[r]}rp.from&&rp.alloc&&rp.allocUnsafe&&rp.allocUnsafeSlow?e2e.exports=vQ:($1e(vQ,Tj),Tj.Buffer=mC);function mC(t,e,r){return rp(t,e,r)}$1e(rp,mC);mC.from=function(t,e,r){if(typeof t=="number")throw new TypeError("Argument must not be a number");return rp(t,e,r)};mC.alloc=function(t,e,r){if(typeof t!="number")throw new TypeError("Argument must be a number");var o=rp(t);return e!==void 0?typeof r=="string"?o.fill(e,r):o.fill(e):o.fill(0),o};mC.allocUnsafe=function(t){if(typeof t!="number")throw new TypeError("Argument must be a number");return rp(t)};mC.allocUnsafeSlow=function(t){if(typeof t!="number")throw new TypeError("Argument must be a number");return vQ.SlowBuffer(t)}});var Mj=_(n2e=>{"use strict";var Lj=t2e().Buffer,r2e=Lj.isEncoding||function(t){switch(t=""+t,t&&t.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}};function L2t(t){if(!t)return"utf8";for(var e;;)switch(t){case"utf8":case"utf-8":return"utf8";case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return"utf16le";case"latin1":case"binary":return"latin1";case"base64":case"ascii":case"hex":return t;default:if(e)return;t=(""+t).toLowerCase(),e=!0}}function M2t(t){var e=L2t(t);if(typeof e!="string"&&(Lj.isEncoding===r2e||!r2e(t)))throw new Error("Unknown encoding: "+t);return e||t}n2e.StringDecoder=ev;function ev(t){this.encoding=M2t(t);var e;switch(this.encoding){case"utf16le":this.text=j2t,this.end=G2t,e=4;break;case"utf8":this.fillLast=_2t,e=4;break;case"base64":this.text=Y2t,this.end=W2t,e=3;break;default:this.write=K2t,this.end=V2t;return}this.lastNeed=0,this.lastTotal=0,this.lastChar=Lj.allocUnsafe(e)}ev.prototype.write=function(t){if(t.length===0)return"";var e,r;if(this.lastNeed){if(e=this.fillLast(t),e===void 0)return"";r=this.lastNeed,this.lastNeed=0}else r=0;return r>5===6?2:t>>4===14?3:t>>3===30?4:t>>6===2?-1:-2}function O2t(t,e,r){var o=e.length-1;if(o=0?(a>0&&(t.lastNeed=a-1),a):--o=0?(a>0&&(t.lastNeed=a-2),a):--o=0?(a>0&&(a===2?a=0:t.lastNeed=a-3),a):0))}function U2t(t,e,r){if((e[0]&192)!==128)return t.lastNeed=0,"\uFFFD";if(t.lastNeed>1&&e.length>1){if((e[1]&192)!==128)return t.lastNeed=1,"\uFFFD";if(t.lastNeed>2&&e.length>2&&(e[2]&192)!==128)return t.lastNeed=2,"\uFFFD"}}function _2t(t){var e=this.lastTotal-this.lastNeed,r=U2t(this,t,e);if(r!==void 0)return r;if(this.lastNeed<=t.length)return t.copy(this.lastChar,e,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal);t.copy(this.lastChar,e,0,t.length),this.lastNeed-=t.length}function H2t(t,e){var r=O2t(this,t,e);if(!this.lastNeed)return t.toString("utf8",e);this.lastTotal=r;var o=t.length-(r-this.lastNeed);return t.copy(this.lastChar,0,o),t.toString("utf8",e,o)}function q2t(t){var e=t&&t.length?this.write(t):"";return this.lastNeed?e+"\uFFFD":e}function j2t(t,e){if((t.length-e)%2===0){var r=t.toString("utf16le",e);if(r){var o=r.charCodeAt(r.length-1);if(o>=55296&&o<=56319)return this.lastNeed=2,this.lastTotal=4,this.lastChar[0]=t[t.length-2],this.lastChar[1]=t[t.length-1],r.slice(0,-1)}return r}return this.lastNeed=1,this.lastTotal=2,this.lastChar[0]=t[t.length-1],t.toString("utf16le",e,t.length-1)}function G2t(t){var e=t&&t.length?this.write(t):"";if(this.lastNeed){var r=this.lastTotal-this.lastNeed;return e+this.lastChar.toString("utf16le",0,r)}return e}function Y2t(t,e){var r=(t.length-e)%3;return r===0?t.toString("base64",e):(this.lastNeed=3-r,this.lastTotal=3,r===1?this.lastChar[0]=t[t.length-1]:(this.lastChar[0]=t[t.length-2],this.lastChar[1]=t[t.length-1]),t.toString("base64",e,t.length-r))}function W2t(t){var e=t&&t.length?this.write(t):"";return this.lastNeed?e+this.lastChar.toString("base64",0,3-this.lastNeed):e}function K2t(t){return t.toString(this.encoding)}function V2t(t){return t&&t.length?this.write(t):""}});var DQ=_((R$t,o2e)=>{"use strict";var i2e=Gh().codes.ERR_STREAM_PREMATURE_CLOSE;function z2t(t){var e=!1;return function(){if(!e){e=!0;for(var r=arguments.length,o=new Array(r),a=0;a{"use strict";var PQ;function Kh(t,e,r){return e in t?Object.defineProperty(t,e,{value:r,enumerable:!0,configurable:!0,writable:!0}):t[e]=r,t}var Z2t=DQ(),Vh=Symbol("lastResolve"),cd=Symbol("lastReject"),tv=Symbol("error"),bQ=Symbol("ended"),ud=Symbol("lastPromise"),Oj=Symbol("handlePromise"),Ad=Symbol("stream");function zh(t,e){return{value:t,done:e}}function $2t(t){var e=t[Vh];if(e!==null){var r=t[Ad].read();r!==null&&(t[ud]=null,t[Vh]=null,t[cd]=null,e(zh(r,!1)))}}function eBt(t){process.nextTick($2t,t)}function tBt(t,e){return function(r,o){t.then(function(){if(e[bQ]){r(zh(void 0,!0));return}e[Oj](r,o)},o)}}var rBt=Object.getPrototypeOf(function(){}),nBt=Object.setPrototypeOf((PQ={get stream(){return this[Ad]},next:function(){var e=this,r=this[tv];if(r!==null)return Promise.reject(r);if(this[bQ])return Promise.resolve(zh(void 0,!0));if(this[Ad].destroyed)return new Promise(function(u,A){process.nextTick(function(){e[tv]?A(e[tv]):u(zh(void 0,!0))})});var o=this[ud],a;if(o)a=new Promise(tBt(o,this));else{var n=this[Ad].read();if(n!==null)return Promise.resolve(zh(n,!1));a=new Promise(this[Oj])}return this[ud]=a,a}},Kh(PQ,Symbol.asyncIterator,function(){return this}),Kh(PQ,"return",function(){var e=this;return new Promise(function(r,o){e[Ad].destroy(null,function(a){if(a){o(a);return}r(zh(void 0,!0))})})}),PQ),rBt),iBt=function(e){var r,o=Object.create(nBt,(r={},Kh(r,Ad,{value:e,writable:!0}),Kh(r,Vh,{value:null,writable:!0}),Kh(r,cd,{value:null,writable:!0}),Kh(r,tv,{value:null,writable:!0}),Kh(r,bQ,{value:e._readableState.endEmitted,writable:!0}),Kh(r,Oj,{value:function(n,u){var A=o[Ad].read();A?(o[ud]=null,o[Vh]=null,o[cd]=null,n(zh(A,!1))):(o[Vh]=n,o[cd]=u)},writable:!0}),r));return o[ud]=null,Z2t(e,function(a){if(a&&a.code!=="ERR_STREAM_PREMATURE_CLOSE"){var n=o[cd];n!==null&&(o[ud]=null,o[Vh]=null,o[cd]=null,n(a)),o[tv]=a;return}var u=o[Vh];u!==null&&(o[ud]=null,o[Vh]=null,o[cd]=null,u(zh(void 0,!0))),o[bQ]=!0}),e.on("readable",eBt.bind(null,o)),o};a2e.exports=iBt});var f2e=_((N$t,A2e)=>{"use strict";function c2e(t,e,r,o,a,n,u){try{var A=t[n](u),p=A.value}catch(h){r(h);return}A.done?e(p):Promise.resolve(p).then(o,a)}function sBt(t){return function(){var e=this,r=arguments;return new Promise(function(o,a){var n=t.apply(e,r);function u(p){c2e(n,o,a,u,A,"next",p)}function A(p){c2e(n,o,a,u,A,"throw",p)}u(void 0)})}}function u2e(t,e){var r=Object.keys(t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(t);e&&(o=o.filter(function(a){return Object.getOwnPropertyDescriptor(t,a).enumerable})),r.push.apply(r,o)}return r}function oBt(t){for(var e=1;e{"use strict";I2e.exports=mn;var yC;mn.ReadableState=d2e;var L$t=ve("events").EventEmitter,g2e=function(e,r){return e.listeners(r).length},nv=Cj(),SQ=ve("buffer").Buffer,uBt=global.Uint8Array||function(){};function ABt(t){return SQ.from(t)}function fBt(t){return SQ.isBuffer(t)||t instanceof uBt}var Uj=ve("util"),en;Uj&&Uj.debuglog?en=Uj.debuglog("stream"):en=function(){};var pBt=N1e(),Wj=Bj(),hBt=vj(),gBt=hBt.getHighWaterMark,xQ=Gh().codes,dBt=xQ.ERR_INVALID_ARG_TYPE,mBt=xQ.ERR_STREAM_PUSH_AFTER_EOF,yBt=xQ.ERR_METHOD_NOT_IMPLEMENTED,EBt=xQ.ERR_STREAM_UNSHIFT_AFTER_END_EVENT,EC,_j,Hj;Yh()(mn,nv);var rv=Wj.errorOrDestroy,qj=["error","close","destroy","pause","resume"];function CBt(t,e,r){if(typeof t.prependListener=="function")return t.prependListener(e,r);!t._events||!t._events[e]?t.on(e,r):Array.isArray(t._events[e])?t._events[e].unshift(r):t._events[e]=[r,t._events[e]]}function d2e(t,e,r){yC=yC||ld(),t=t||{},typeof r!="boolean"&&(r=e instanceof yC),this.objectMode=!!t.objectMode,r&&(this.objectMode=this.objectMode||!!t.readableObjectMode),this.highWaterMark=gBt(this,t,"readableHighWaterMark",r),this.buffer=new pBt,this.length=0,this.pipes=null,this.pipesCount=0,this.flowing=null,this.ended=!1,this.endEmitted=!1,this.reading=!1,this.sync=!0,this.needReadable=!1,this.emittedReadable=!1,this.readableListening=!1,this.resumeScheduled=!1,this.paused=!0,this.emitClose=t.emitClose!==!1,this.autoDestroy=!!t.autoDestroy,this.destroyed=!1,this.defaultEncoding=t.defaultEncoding||"utf8",this.awaitDrain=0,this.readingMore=!1,this.decoder=null,this.encoding=null,t.encoding&&(EC||(EC=Mj().StringDecoder),this.decoder=new EC(t.encoding),this.encoding=t.encoding)}function mn(t){if(yC=yC||ld(),!(this instanceof mn))return new mn(t);var e=this instanceof yC;this._readableState=new d2e(t,this,e),this.readable=!0,t&&(typeof t.read=="function"&&(this._read=t.read),typeof t.destroy=="function"&&(this._destroy=t.destroy)),nv.call(this)}Object.defineProperty(mn.prototype,"destroyed",{enumerable:!1,get:function(){return this._readableState===void 0?!1:this._readableState.destroyed},set:function(e){this._readableState&&(this._readableState.destroyed=e)}});mn.prototype.destroy=Wj.destroy;mn.prototype._undestroy=Wj.undestroy;mn.prototype._destroy=function(t,e){e(t)};mn.prototype.push=function(t,e){var r=this._readableState,o;return r.objectMode?o=!0:typeof t=="string"&&(e=e||r.defaultEncoding,e!==r.encoding&&(t=SQ.from(t,e),e=""),o=!0),m2e(this,t,e,!1,o)};mn.prototype.unshift=function(t){return m2e(this,t,null,!0,!1)};function m2e(t,e,r,o,a){en("readableAddChunk",e);var n=t._readableState;if(e===null)n.reading=!1,BBt(t,n);else{var u;if(a||(u=wBt(n,e)),u)rv(t,u);else if(n.objectMode||e&&e.length>0)if(typeof e!="string"&&!n.objectMode&&Object.getPrototypeOf(e)!==SQ.prototype&&(e=ABt(e)),o)n.endEmitted?rv(t,new EBt):jj(t,n,e,!0);else if(n.ended)rv(t,new mBt);else{if(n.destroyed)return!1;n.reading=!1,n.decoder&&!r?(e=n.decoder.write(e),n.objectMode||e.length!==0?jj(t,n,e,!1):Yj(t,n)):jj(t,n,e,!1)}else o||(n.reading=!1,Yj(t,n))}return!n.ended&&(n.length=p2e?t=p2e:(t--,t|=t>>>1,t|=t>>>2,t|=t>>>4,t|=t>>>8,t|=t>>>16,t++),t}function h2e(t,e){return t<=0||e.length===0&&e.ended?0:e.objectMode?1:t!==t?e.flowing&&e.length?e.buffer.head.data.length:e.length:(t>e.highWaterMark&&(e.highWaterMark=IBt(t)),t<=e.length?t:e.ended?e.length:(e.needReadable=!0,0))}mn.prototype.read=function(t){en("read",t),t=parseInt(t,10);var e=this._readableState,r=t;if(t!==0&&(e.emittedReadable=!1),t===0&&e.needReadable&&((e.highWaterMark!==0?e.length>=e.highWaterMark:e.length>0)||e.ended))return en("read: emitReadable",e.length,e.ended),e.length===0&&e.ended?Gj(this):kQ(this),null;if(t=h2e(t,e),t===0&&e.ended)return e.length===0&&Gj(this),null;var o=e.needReadable;en("need readable",o),(e.length===0||e.length-t0?a=C2e(t,e):a=null,a===null?(e.needReadable=e.length<=e.highWaterMark,t=0):(e.length-=t,e.awaitDrain=0),e.length===0&&(e.ended||(e.needReadable=!0),r!==t&&e.ended&&Gj(this)),a!==null&&this.emit("data",a),a};function BBt(t,e){if(en("onEofChunk"),!e.ended){if(e.decoder){var r=e.decoder.end();r&&r.length&&(e.buffer.push(r),e.length+=e.objectMode?1:r.length)}e.ended=!0,e.sync?kQ(t):(e.needReadable=!1,e.emittedReadable||(e.emittedReadable=!0,y2e(t)))}}function kQ(t){var e=t._readableState;en("emitReadable",e.needReadable,e.emittedReadable),e.needReadable=!1,e.emittedReadable||(en("emitReadable",e.flowing),e.emittedReadable=!0,process.nextTick(y2e,t))}function y2e(t){var e=t._readableState;en("emitReadable_",e.destroyed,e.length,e.ended),!e.destroyed&&(e.length||e.ended)&&(t.emit("readable"),e.emittedReadable=!1),e.needReadable=!e.flowing&&!e.ended&&e.length<=e.highWaterMark,Kj(t)}function Yj(t,e){e.readingMore||(e.readingMore=!0,process.nextTick(vBt,t,e))}function vBt(t,e){for(;!e.reading&&!e.ended&&(e.length1&&w2e(o.pipes,t)!==-1)&&!h&&(en("false write response, pause",o.awaitDrain),o.awaitDrain++),r.pause())}function v(L){en("onerror",L),R(),t.removeListener("error",v),g2e(t,"error")===0&&rv(t,L)}CBt(t,"error",v);function x(){t.removeListener("finish",C),R()}t.once("close",x);function C(){en("onfinish"),t.removeListener("close",x),R()}t.once("finish",C);function R(){en("unpipe"),r.unpipe(t)}return t.emit("pipe",r),o.flowing||(en("pipe resume"),r.resume()),t};function DBt(t){return function(){var r=t._readableState;en("pipeOnDrain",r.awaitDrain),r.awaitDrain&&r.awaitDrain--,r.awaitDrain===0&&g2e(t,"data")&&(r.flowing=!0,Kj(t))}}mn.prototype.unpipe=function(t){var e=this._readableState,r={hasUnpiped:!1};if(e.pipesCount===0)return this;if(e.pipesCount===1)return t&&t!==e.pipes?this:(t||(t=e.pipes),e.pipes=null,e.pipesCount=0,e.flowing=!1,t&&t.emit("unpipe",this,r),this);if(!t){var o=e.pipes,a=e.pipesCount;e.pipes=null,e.pipesCount=0,e.flowing=!1;for(var n=0;n0,o.flowing!==!1&&this.resume()):t==="readable"&&!o.endEmitted&&!o.readableListening&&(o.readableListening=o.needReadable=!0,o.flowing=!1,o.emittedReadable=!1,en("on readable",o.length,o.reading),o.length?kQ(this):o.reading||process.nextTick(PBt,this)),r};mn.prototype.addListener=mn.prototype.on;mn.prototype.removeListener=function(t,e){var r=nv.prototype.removeListener.call(this,t,e);return t==="readable"&&process.nextTick(E2e,this),r};mn.prototype.removeAllListeners=function(t){var e=nv.prototype.removeAllListeners.apply(this,arguments);return(t==="readable"||t===void 0)&&process.nextTick(E2e,this),e};function E2e(t){var e=t._readableState;e.readableListening=t.listenerCount("readable")>0,e.resumeScheduled&&!e.paused?e.flowing=!0:t.listenerCount("data")>0&&t.resume()}function PBt(t){en("readable nexttick read 0"),t.read(0)}mn.prototype.resume=function(){var t=this._readableState;return t.flowing||(en("resume"),t.flowing=!t.readableListening,bBt(this,t)),t.paused=!1,this};function bBt(t,e){e.resumeScheduled||(e.resumeScheduled=!0,process.nextTick(SBt,t,e))}function SBt(t,e){en("resume",e.reading),e.reading||t.read(0),e.resumeScheduled=!1,t.emit("resume"),Kj(t),e.flowing&&!e.reading&&t.read(0)}mn.prototype.pause=function(){return en("call pause flowing=%j",this._readableState.flowing),this._readableState.flowing!==!1&&(en("pause"),this._readableState.flowing=!1,this.emit("pause")),this._readableState.paused=!0,this};function Kj(t){var e=t._readableState;for(en("flow",e.flowing);e.flowing&&t.read()!==null;);}mn.prototype.wrap=function(t){var e=this,r=this._readableState,o=!1;t.on("end",function(){if(en("wrapped end"),r.decoder&&!r.ended){var u=r.decoder.end();u&&u.length&&e.push(u)}e.push(null)}),t.on("data",function(u){if(en("wrapped data"),r.decoder&&(u=r.decoder.write(u)),!(r.objectMode&&u==null)&&!(!r.objectMode&&(!u||!u.length))){var A=e.push(u);A||(o=!0,t.pause())}});for(var a in t)this[a]===void 0&&typeof t[a]=="function"&&(this[a]=function(A){return function(){return t[A].apply(t,arguments)}}(a));for(var n=0;n=e.length?(e.decoder?r=e.buffer.join(""):e.buffer.length===1?r=e.buffer.first():r=e.buffer.concat(e.length),e.buffer.clear()):r=e.buffer.consume(t,e.decoder),r}function Gj(t){var e=t._readableState;en("endReadable",e.endEmitted),e.endEmitted||(e.ended=!0,process.nextTick(xBt,e,t))}function xBt(t,e){if(en("endReadableNT",t.endEmitted,t.length),!t.endEmitted&&t.length===0&&(t.endEmitted=!0,e.readable=!1,e.emit("end"),t.autoDestroy)){var r=e._writableState;(!r||r.autoDestroy&&r.finished)&&e.destroy()}}typeof Symbol=="function"&&(mn.from=function(t,e){return Hj===void 0&&(Hj=f2e()),Hj(mn,t,e)});function w2e(t,e){for(var r=0,o=t.length;r{"use strict";v2e.exports=np;var QQ=Gh().codes,kBt=QQ.ERR_METHOD_NOT_IMPLEMENTED,QBt=QQ.ERR_MULTIPLE_CALLBACK,FBt=QQ.ERR_TRANSFORM_ALREADY_TRANSFORMING,RBt=QQ.ERR_TRANSFORM_WITH_LENGTH_0,FQ=ld();Yh()(np,FQ);function TBt(t,e){var r=this._transformState;r.transforming=!1;var o=r.writecb;if(o===null)return this.emit("error",new QBt);r.writechunk=null,r.writecb=null,e!=null&&this.push(e),o(t);var a=this._readableState;a.reading=!1,(a.needReadable||a.length{"use strict";P2e.exports=iv;var D2e=Vj();Yh()(iv,D2e);function iv(t){if(!(this instanceof iv))return new iv(t);D2e.call(this,t)}iv.prototype._transform=function(t,e,r){r(null,t)}});var F2e=_((_$t,Q2e)=>{"use strict";var zj;function LBt(t){var e=!1;return function(){e||(e=!0,t.apply(void 0,arguments))}}var k2e=Gh().codes,MBt=k2e.ERR_MISSING_ARGS,OBt=k2e.ERR_STREAM_DESTROYED;function S2e(t){if(t)throw t}function UBt(t){return t.setHeader&&typeof t.abort=="function"}function _Bt(t,e,r,o){o=LBt(o);var a=!1;t.on("close",function(){a=!0}),zj===void 0&&(zj=DQ()),zj(t,{readable:e,writable:r},function(u){if(u)return o(u);a=!0,o()});var n=!1;return function(u){if(!a&&!n){if(n=!0,UBt(t))return t.abort();if(typeof t.destroy=="function")return t.destroy();o(u||new OBt("pipe"))}}}function x2e(t){t()}function HBt(t,e){return t.pipe(e)}function qBt(t){return!t.length||typeof t[t.length-1]!="function"?S2e:t.pop()}function jBt(){for(var t=arguments.length,e=new Array(t),r=0;r0;return _Bt(u,p,h,function(E){a||(a=E),E&&n.forEach(x2e),!p&&(n.forEach(x2e),o(a))})});return e.reduce(HBt)}Q2e.exports=jBt});var CC=_((cc,ov)=>{var sv=ve("stream");process.env.READABLE_STREAM==="disable"&&sv?(ov.exports=sv.Readable,Object.assign(ov.exports,sv),ov.exports.Stream=sv):(cc=ov.exports=Rj(),cc.Stream=sv||cc,cc.Readable=cc,cc.Writable=kj(),cc.Duplex=ld(),cc.Transform=Vj(),cc.PassThrough=b2e(),cc.finished=DQ(),cc.pipeline=F2e())});var N2e=_((H$t,T2e)=>{"use strict";var{Buffer:uu}=ve("buffer"),R2e=Symbol.for("BufferList");function ni(t){if(!(this instanceof ni))return new ni(t);ni._init.call(this,t)}ni._init=function(e){Object.defineProperty(this,R2e,{value:!0}),this._bufs=[],this.length=0,e&&this.append(e)};ni.prototype._new=function(e){return new ni(e)};ni.prototype._offset=function(e){if(e===0)return[0,0];let r=0;for(let o=0;othis.length||e<0)return;let r=this._offset(e);return this._bufs[r[0]][r[1]]};ni.prototype.slice=function(e,r){return typeof e=="number"&&e<0&&(e+=this.length),typeof r=="number"&&r<0&&(r+=this.length),this.copy(null,0,e,r)};ni.prototype.copy=function(e,r,o,a){if((typeof o!="number"||o<0)&&(o=0),(typeof a!="number"||a>this.length)&&(a=this.length),o>=this.length||a<=0)return e||uu.alloc(0);let n=!!e,u=this._offset(o),A=a-o,p=A,h=n&&r||0,E=u[1];if(o===0&&a===this.length){if(!n)return this._bufs.length===1?this._bufs[0]:uu.concat(this._bufs,this.length);for(let I=0;Iv)this._bufs[I].copy(e,h,E),h+=v;else{this._bufs[I].copy(e,h,E,E+p),h+=v;break}p-=v,E&&(E=0)}return e.length>h?e.slice(0,h):e};ni.prototype.shallowSlice=function(e,r){if(e=e||0,r=typeof r!="number"?this.length:r,e<0&&(e+=this.length),r<0&&(r+=this.length),e===r)return this._new();let o=this._offset(e),a=this._offset(r),n=this._bufs.slice(o[0],a[0]+1);return a[1]===0?n.pop():n[n.length-1]=n[n.length-1].slice(0,a[1]),o[1]!==0&&(n[0]=n[0].slice(o[1])),this._new(n)};ni.prototype.toString=function(e,r,o){return this.slice(r,o).toString(e)};ni.prototype.consume=function(e){if(e=Math.trunc(e),Number.isNaN(e)||e<=0)return this;for(;this._bufs.length;)if(e>=this._bufs[0].length)e-=this._bufs[0].length,this.length-=this._bufs[0].length,this._bufs.shift();else{this._bufs[0]=this._bufs[0].slice(e),this.length-=e;break}return this};ni.prototype.duplicate=function(){let e=this._new();for(let r=0;rthis.length?this.length:e;let o=this._offset(e),a=o[0],n=o[1];for(;a=t.length){let p=u.indexOf(t,n);if(p!==-1)return this._reverseOffset([a,p]);n=u.length-t.length+1}else{let p=this._reverseOffset([a,n]);if(this._match(p,t))return p;n++}n=0}return-1};ni.prototype._match=function(t,e){if(this.length-t{"use strict";var Jj=CC().Duplex,GBt=Yh(),av=N2e();function Uo(t){if(!(this instanceof Uo))return new Uo(t);if(typeof t=="function"){this._callback=t;let e=function(o){this._callback&&(this._callback(o),this._callback=null)}.bind(this);this.on("pipe",function(o){o.on("error",e)}),this.on("unpipe",function(o){o.removeListener("error",e)}),t=null}av._init.call(this,t),Jj.call(this)}GBt(Uo,Jj);Object.assign(Uo.prototype,av.prototype);Uo.prototype._new=function(e){return new Uo(e)};Uo.prototype._write=function(e,r,o){this._appendBuffer(e),typeof o=="function"&&o()};Uo.prototype._read=function(e){if(!this.length)return this.push(null);e=Math.min(e,this.length),this.push(this.slice(0,e)),this.consume(e)};Uo.prototype.end=function(e){Jj.prototype.end.call(this,e),this._callback&&(this._callback(null,this.slice()),this._callback=null)};Uo.prototype._destroy=function(e,r){this._bufs.length=0,this.length=0,r(e)};Uo.prototype._isBufferList=function(e){return e instanceof Uo||e instanceof av||Uo.isBufferList(e)};Uo.isBufferList=av.isBufferList;RQ.exports=Uo;RQ.exports.BufferListStream=Uo;RQ.exports.BufferList=av});var $j=_(IC=>{var YBt=Buffer.alloc,WBt="0000000000000000000",KBt="7777777777777777777",M2e=48,O2e=Buffer.from("ustar\0","binary"),VBt=Buffer.from("00","binary"),zBt=Buffer.from("ustar ","binary"),JBt=Buffer.from(" \0","binary"),XBt=parseInt("7777",8),lv=257,Zj=263,ZBt=function(t,e,r){return typeof t!="number"?r:(t=~~t,t>=e?e:t>=0||(t+=e,t>=0)?t:0)},$Bt=function(t){switch(t){case 0:return"file";case 1:return"link";case 2:return"symlink";case 3:return"character-device";case 4:return"block-device";case 5:return"directory";case 6:return"fifo";case 7:return"contiguous-file";case 72:return"pax-header";case 55:return"pax-global-header";case 27:return"gnu-long-link-path";case 28:case 30:return"gnu-long-path"}return null},evt=function(t){switch(t){case"file":return 0;case"link":return 1;case"symlink":return 2;case"character-device":return 3;case"block-device":return 4;case"directory":return 5;case"fifo":return 6;case"contiguous-file":return 7;case"pax-header":return 72}return 0},U2e=function(t,e,r,o){for(;re?KBt.slice(0,e)+" ":WBt.slice(0,e-t.length)+t+" "};function tvt(t){var e;if(t[0]===128)e=!0;else if(t[0]===255)e=!1;else return null;for(var r=[],o=t.length-1;o>0;o--){var a=t[o];e?r.push(a):r.push(255-a)}var n=0,u=r.length;for(o=0;o=Math.pow(10,r)&&r++,e+r+t};IC.decodeLongPath=function(t,e){return wC(t,0,t.length,e)};IC.encodePax=function(t){var e="";t.name&&(e+=Xj(" path="+t.name+` +`)),t.linkname&&(e+=Xj(" linkpath="+t.linkname+` +`));var r=t.pax;if(r)for(var o in r)e+=Xj(" "+o+"="+r[o]+` +`);return Buffer.from(e)};IC.decodePax=function(t){for(var e={};t.length;){for(var r=0;r100;){var a=r.indexOf("/");if(a===-1)return null;o+=o?"/"+r.slice(0,a):r.slice(0,a),r=r.slice(a+1)}return Buffer.byteLength(r)>100||Buffer.byteLength(o)>155||t.linkname&&Buffer.byteLength(t.linkname)>100?null:(e.write(r),e.write(Jh(t.mode&XBt,6),100),e.write(Jh(t.uid,6),108),e.write(Jh(t.gid,6),116),e.write(Jh(t.size,11),124),e.write(Jh(t.mtime.getTime()/1e3|0,11),136),e[156]=M2e+evt(t.type),t.linkname&&e.write(t.linkname,157),O2e.copy(e,lv),VBt.copy(e,Zj),t.uname&&e.write(t.uname,265),t.gname&&e.write(t.gname,297),e.write(Jh(t.devmajor||0,6),329),e.write(Jh(t.devminor||0,6),337),o&&e.write(o,345),e.write(Jh(_2e(e),6),148),e)};IC.decode=function(t,e,r){var o=t[156]===0?0:t[156]-M2e,a=wC(t,0,100,e),n=Xh(t,100,8),u=Xh(t,108,8),A=Xh(t,116,8),p=Xh(t,124,12),h=Xh(t,136,12),E=$Bt(o),I=t[157]===0?null:wC(t,157,100,e),v=wC(t,265,32),x=wC(t,297,32),C=Xh(t,329,8),R=Xh(t,337,8),L=_2e(t);if(L===8*32)return null;if(L!==Xh(t,148,8))throw new Error("Invalid tar header. Maybe the tar is corrupted or it needs to be gunzipped?");if(O2e.compare(t,lv,lv+6)===0)t[345]&&(a=wC(t,345,155,e)+"/"+a);else if(!(zBt.compare(t,lv,lv+6)===0&&JBt.compare(t,Zj,Zj+2)===0)){if(!r)throw new Error("Invalid tar header: unknown format.")}return o===0&&a&&a[a.length-1]==="/"&&(o=5),{name:a,mode:n,uid:u,gid:A,size:p,mtime:new Date(1e3*h),type:E,linkname:I,uname:v,gname:x,devmajor:C,devminor:R}}});var K2e=_((G$t,W2e)=>{var q2e=ve("util"),rvt=L2e(),cv=$j(),j2e=CC().Writable,G2e=CC().PassThrough,Y2e=function(){},H2e=function(t){return t&=511,t&&512-t},nvt=function(t,e){var r=new TQ(t,e);return r.end(),r},ivt=function(t,e){return e.path&&(t.name=e.path),e.linkpath&&(t.linkname=e.linkpath),e.size&&(t.size=parseInt(e.size,10)),t.pax=e,t},TQ=function(t,e){this._parent=t,this.offset=e,G2e.call(this,{autoDestroy:!1})};q2e.inherits(TQ,G2e);TQ.prototype.destroy=function(t){this._parent.destroy(t)};var ip=function(t){if(!(this instanceof ip))return new ip(t);j2e.call(this,t),t=t||{},this._offset=0,this._buffer=rvt(),this._missing=0,this._partial=!1,this._onparse=Y2e,this._header=null,this._stream=null,this._overflow=null,this._cb=null,this._locked=!1,this._destroyed=!1,this._pax=null,this._paxGlobal=null,this._gnuLongPath=null,this._gnuLongLinkPath=null;var e=this,r=e._buffer,o=function(){e._continue()},a=function(v){if(e._locked=!1,v)return e.destroy(v);e._stream||o()},n=function(){e._stream=null;var v=H2e(e._header.size);v?e._parse(v,u):e._parse(512,I),e._locked||o()},u=function(){e._buffer.consume(H2e(e._header.size)),e._parse(512,I),o()},A=function(){var v=e._header.size;e._paxGlobal=cv.decodePax(r.slice(0,v)),r.consume(v),n()},p=function(){var v=e._header.size;e._pax=cv.decodePax(r.slice(0,v)),e._paxGlobal&&(e._pax=Object.assign({},e._paxGlobal,e._pax)),r.consume(v),n()},h=function(){var v=e._header.size;this._gnuLongPath=cv.decodeLongPath(r.slice(0,v),t.filenameEncoding),r.consume(v),n()},E=function(){var v=e._header.size;this._gnuLongLinkPath=cv.decodeLongPath(r.slice(0,v),t.filenameEncoding),r.consume(v),n()},I=function(){var v=e._offset,x;try{x=e._header=cv.decode(r.slice(0,512),t.filenameEncoding,t.allowUnknownFormat)}catch(C){e.emit("error",C)}if(r.consume(512),!x){e._parse(512,I),o();return}if(x.type==="gnu-long-path"){e._parse(x.size,h),o();return}if(x.type==="gnu-long-link-path"){e._parse(x.size,E),o();return}if(x.type==="pax-global-header"){e._parse(x.size,A),o();return}if(x.type==="pax-header"){e._parse(x.size,p),o();return}if(e._gnuLongPath&&(x.name=e._gnuLongPath,e._gnuLongPath=null),e._gnuLongLinkPath&&(x.linkname=e._gnuLongLinkPath,e._gnuLongLinkPath=null),e._pax&&(e._header=x=ivt(x,e._pax),e._pax=null),e._locked=!0,!x.size||x.type==="directory"){e._parse(512,I),e.emit("entry",x,nvt(e,v),a);return}e._stream=new TQ(e,v),e.emit("entry",x,e._stream,a),e._parse(x.size,n),o()};this._onheader=I,this._parse(512,I)};q2e.inherits(ip,j2e);ip.prototype.destroy=function(t){this._destroyed||(this._destroyed=!0,t&&this.emit("error",t),this.emit("close"),this._stream&&this._stream.emit("close"))};ip.prototype._parse=function(t,e){this._destroyed||(this._offset+=t,this._missing=t,e===this._onheader&&(this._partial=!1),this._onparse=e)};ip.prototype._continue=function(){if(!this._destroyed){var t=this._cb;this._cb=Y2e,this._overflow?this._write(this._overflow,void 0,t):t()}};ip.prototype._write=function(t,e,r){if(!this._destroyed){var o=this._stream,a=this._buffer,n=this._missing;if(t.length&&(this._partial=!0),t.lengthn&&(u=t.slice(n),t=t.slice(0,n)),o?o.end(t):a.append(t),this._overflow=u,this._onparse()}};ip.prototype._final=function(t){if(this._partial)return this.destroy(new Error("Unexpected end of data"));t()};W2e.exports=ip});var z2e=_((Y$t,V2e)=>{V2e.exports=ve("fs").constants||ve("constants")});var eBe=_((W$t,$2e)=>{var BC=z2e(),J2e=SO(),LQ=Yh(),svt=Buffer.alloc,X2e=CC().Readable,vC=CC().Writable,ovt=ve("string_decoder").StringDecoder,NQ=$j(),avt=parseInt("755",8),lvt=parseInt("644",8),Z2e=svt(1024),t5=function(){},e5=function(t,e){e&=511,e&&t.push(Z2e.slice(0,512-e))};function cvt(t){switch(t&BC.S_IFMT){case BC.S_IFBLK:return"block-device";case BC.S_IFCHR:return"character-device";case BC.S_IFDIR:return"directory";case BC.S_IFIFO:return"fifo";case BC.S_IFLNK:return"symlink"}return"file"}var MQ=function(t){vC.call(this),this.written=0,this._to=t,this._destroyed=!1};LQ(MQ,vC);MQ.prototype._write=function(t,e,r){if(this.written+=t.length,this._to.push(t))return r();this._to._drain=r};MQ.prototype.destroy=function(){this._destroyed||(this._destroyed=!0,this.emit("close"))};var OQ=function(){vC.call(this),this.linkname="",this._decoder=new ovt("utf-8"),this._destroyed=!1};LQ(OQ,vC);OQ.prototype._write=function(t,e,r){this.linkname+=this._decoder.write(t),r()};OQ.prototype.destroy=function(){this._destroyed||(this._destroyed=!0,this.emit("close"))};var uv=function(){vC.call(this),this._destroyed=!1};LQ(uv,vC);uv.prototype._write=function(t,e,r){r(new Error("No body allowed for this entry"))};uv.prototype.destroy=function(){this._destroyed||(this._destroyed=!0,this.emit("close"))};var EA=function(t){if(!(this instanceof EA))return new EA(t);X2e.call(this,t),this._drain=t5,this._finalized=!1,this._finalizing=!1,this._destroyed=!1,this._stream=null};LQ(EA,X2e);EA.prototype.entry=function(t,e,r){if(this._stream)throw new Error("already piping an entry");if(!(this._finalized||this._destroyed)){typeof e=="function"&&(r=e,e=null),r||(r=t5);var o=this;if((!t.size||t.type==="symlink")&&(t.size=0),t.type||(t.type=cvt(t.mode)),t.mode||(t.mode=t.type==="directory"?avt:lvt),t.uid||(t.uid=0),t.gid||(t.gid=0),t.mtime||(t.mtime=new Date),typeof e=="string"&&(e=Buffer.from(e)),Buffer.isBuffer(e)){t.size=e.length,this._encode(t);var a=this.push(e);return e5(o,t.size),a?process.nextTick(r):this._drain=r,new uv}if(t.type==="symlink"&&!t.linkname){var n=new OQ;return J2e(n,function(A){if(A)return o.destroy(),r(A);t.linkname=n.linkname,o._encode(t),r()}),n}if(this._encode(t),t.type!=="file"&&t.type!=="contiguous-file")return process.nextTick(r),new uv;var u=new MQ(this);return this._stream=u,J2e(u,function(A){if(o._stream=null,A)return o.destroy(),r(A);if(u.written!==t.size)return o.destroy(),r(new Error("size mismatch"));e5(o,t.size),o._finalizing&&o.finalize(),r()}),u}};EA.prototype.finalize=function(){if(this._stream){this._finalizing=!0;return}this._finalized||(this._finalized=!0,this.push(Z2e),this.push(null))};EA.prototype.destroy=function(t){this._destroyed||(this._destroyed=!0,t&&this.emit("error",t),this.emit("close"),this._stream&&this._stream.destroy&&this._stream.destroy())};EA.prototype._encode=function(t){if(!t.pax){var e=NQ.encode(t);if(e){this.push(e);return}}this._encodePax(t)};EA.prototype._encodePax=function(t){var e=NQ.encodePax({name:t.name,linkname:t.linkname,pax:t.pax}),r={name:"PaxHeader",mode:t.mode,uid:t.uid,gid:t.gid,size:e.length,mtime:t.mtime,type:"pax-header",linkname:t.linkname&&"PaxHeader",uname:t.uname,gname:t.gname,devmajor:t.devmajor,devminor:t.devminor};this.push(NQ.encode(r)),this.push(e),e5(this,e.length),r.size=t.size,r.type=t.type,this.push(NQ.encode(r))};EA.prototype._read=function(t){var e=this._drain;this._drain=t5,e()};$2e.exports=EA});var tBe=_(r5=>{r5.extract=K2e();r5.pack=eBe()});var pBe=_((fer,fBe)=>{"use strict";var Av=class t{constructor(e,r,o){this.__specs=e||{},Object.keys(this.__specs).forEach(a=>{if(typeof this.__specs[a]=="string"){let n=this.__specs[a],u=this.__specs[n];if(u){let A=u.aliases||[];A.push(a,n),u.aliases=[...new Set(A)],this.__specs[a]=u}else throw new Error(`Alias refers to invalid key: ${n} -> ${a}`)}}),this.__opts=r||{},this.__providers=uBe(o.filter(a=>a!=null&&typeof a=="object")),this.__isFiggyPudding=!0}get(e){return l5(this,e,!0)}get[Symbol.toStringTag](){return"FiggyPudding"}forEach(e,r=this){for(let[o,a]of this.entries())e.call(r,a,o,this)}toJSON(){let e={};return this.forEach((r,o)=>{e[o]=r}),e}*entries(e){for(let o of Object.keys(this.__specs))yield[o,this.get(o)];let r=e||this.__opts.other;if(r){let o=new Set;for(let a of this.__providers){let n=a.entries?a.entries(r):vvt(a);for(let[u,A]of n)r(u)&&!o.has(u)&&(o.add(u),yield[u,A])}}}*[Symbol.iterator](){for(let[e,r]of this.entries())yield[e,r]}*keys(){for(let[e]of this.entries())yield e}*values(){for(let[,e]of this.entries())yield e}concat(...e){return new Proxy(new t(this.__specs,this.__opts,uBe(this.__providers).concat(e)),ABe)}};try{let t=ve("util");Av.prototype[t.inspect.custom]=function(e,r){return this[Symbol.toStringTag]+" "+t.inspect(this.toJSON(),r)}}catch{}function Ivt(t){throw Object.assign(new Error(`invalid config key requested: ${t}`),{code:"EBADKEY"})}function l5(t,e,r){let o=t.__specs[e];if(r&&!o&&(!t.__opts.other||!t.__opts.other(e)))Ivt(e);else{o||(o={});let a;for(let n of t.__providers){if(a=cBe(e,n),a===void 0&&o.aliases&&o.aliases.length){for(let u of o.aliases)if(u!==e&&(a=cBe(u,n),a!==void 0))break}if(a!==void 0)break}return a===void 0&&o.default!==void 0?typeof o.default=="function"?o.default(t):o.default:a}}function cBe(t,e){let r;return e.__isFiggyPudding?r=l5(e,t,!1):typeof e.get=="function"?r=e.get(t):r=e[t],r}var ABe={has(t,e){return e in t.__specs&&l5(t,e,!1)!==void 0},ownKeys(t){return Object.keys(t.__specs)},get(t,e){return typeof e=="symbol"||e.slice(0,2)==="__"||e in Av.prototype?t[e]:t.get(e)},set(t,e,r){if(typeof e=="symbol"||e.slice(0,2)==="__")return t[e]=r,!0;throw new Error("figgyPudding options cannot be modified. Use .concat() instead.")},deleteProperty(){throw new Error("figgyPudding options cannot be deleted. Use .concat() and shadow them instead.")}};fBe.exports=Bvt;function Bvt(t,e){function r(...o){return new Proxy(new Av(t,e,o),ABe)}return r}function uBe(t){let e=[];return t.forEach(r=>e.unshift(r)),e}function vvt(t){return Object.keys(t).map(e=>[e,t[e]])}});var dBe=_((per,IA)=>{"use strict";var pv=ve("crypto"),Dvt=pBe(),Pvt=ve("stream").Transform,hBe=["sha256","sha384","sha512"],bvt=/^[a-z0-9+/]+(?:=?=?)$/i,Svt=/^([^-]+)-([^?]+)([?\S*]*)$/,xvt=/^([^-]+)-([A-Za-z0-9+/=]{44,88})(\?[\x21-\x7E]*)*$/,kvt=/^[\x21-\x7E]+$/,oa=Dvt({algorithms:{default:["sha512"]},error:{default:!1},integrity:{},options:{default:[]},pickAlgorithm:{default:()=>Ovt},Promise:{default:()=>Promise},sep:{default:" "},single:{default:!1},size:{},strict:{default:!1}}),Zh=class{get isHash(){return!0}constructor(e,r){r=oa(r);let o=!!r.strict;this.source=e.trim();let a=this.source.match(o?xvt:Svt);if(!a||o&&!hBe.some(u=>u===a[1]))return;this.algorithm=a[1],this.digest=a[2];let n=a[3];this.options=n?n.slice(1).split("?"):[]}hexDigest(){return this.digest&&Buffer.from(this.digest,"base64").toString("hex")}toJSON(){return this.toString()}toString(e){if(e=oa(e),e.strict&&!(hBe.some(o=>o===this.algorithm)&&this.digest.match(bvt)&&(this.options||[]).every(o=>o.match(kvt))))return"";let r=this.options&&this.options.length?`?${this.options.join("?")}`:"";return`${this.algorithm}-${this.digest}${r}`}},fd=class{get isIntegrity(){return!0}toJSON(){return this.toString()}toString(e){e=oa(e);let r=e.sep||" ";return e.strict&&(r=r.replace(/\S+/g," ")),Object.keys(this).map(o=>this[o].map(a=>Zh.prototype.toString.call(a,e)).filter(a=>a.length).join(r)).filter(o=>o.length).join(r)}concat(e,r){r=oa(r);let o=typeof e=="string"?e:fv(e,r);return wA(`${this.toString(r)} ${o}`,r)}hexDigest(){return wA(this,{single:!0}).hexDigest()}match(e,r){r=oa(r);let o=wA(e,r),a=o.pickAlgorithm(r);return this[a]&&o[a]&&this[a].find(n=>o[a].find(u=>n.digest===u.digest))||!1}pickAlgorithm(e){e=oa(e);let r=e.pickAlgorithm,o=Object.keys(this);if(!o.length)throw new Error(`No algorithms available for ${JSON.stringify(this.toString())}`);return o.reduce((a,n)=>r(a,n)||a)}};IA.exports.parse=wA;function wA(t,e){if(e=oa(e),typeof t=="string")return c5(t,e);if(t.algorithm&&t.digest){let r=new fd;return r[t.algorithm]=[t],c5(fv(r,e),e)}else return c5(fv(t,e),e)}function c5(t,e){return e.single?new Zh(t,e):t.trim().split(/\s+/).reduce((r,o)=>{let a=new Zh(o,e);if(a.algorithm&&a.digest){let n=a.algorithm;r[n]||(r[n]=[]),r[n].push(a)}return r},new fd)}IA.exports.stringify=fv;function fv(t,e){return e=oa(e),t.algorithm&&t.digest?Zh.prototype.toString.call(t,e):typeof t=="string"?fv(wA(t,e),e):fd.prototype.toString.call(t,e)}IA.exports.fromHex=Qvt;function Qvt(t,e,r){r=oa(r);let o=r.options&&r.options.length?`?${r.options.join("?")}`:"";return wA(`${e}-${Buffer.from(t,"hex").toString("base64")}${o}`,r)}IA.exports.fromData=Fvt;function Fvt(t,e){e=oa(e);let r=e.algorithms,o=e.options&&e.options.length?`?${e.options.join("?")}`:"";return r.reduce((a,n)=>{let u=pv.createHash(n).update(t).digest("base64"),A=new Zh(`${n}-${u}${o}`,e);if(A.algorithm&&A.digest){let p=A.algorithm;a[p]||(a[p]=[]),a[p].push(A)}return a},new fd)}IA.exports.fromStream=Rvt;function Rvt(t,e){e=oa(e);let r=e.Promise||Promise,o=u5(e);return new r((a,n)=>{t.pipe(o),t.on("error",n),o.on("error",n);let u;o.on("integrity",A=>{u=A}),o.on("end",()=>a(u)),o.on("data",()=>{})})}IA.exports.checkData=Tvt;function Tvt(t,e,r){if(r=oa(r),e=wA(e,r),!Object.keys(e).length){if(r.error)throw Object.assign(new Error("No valid integrity hashes to check against"),{code:"EINTEGRITY"});return!1}let o=e.pickAlgorithm(r),a=pv.createHash(o).update(t).digest("base64"),n=wA({algorithm:o,digest:a}),u=n.match(e,r);if(u||!r.error)return u;if(typeof r.size=="number"&&t.length!==r.size){let A=new Error(`data size mismatch when checking ${e}. + Wanted: ${r.size} + Found: ${t.length}`);throw A.code="EBADSIZE",A.found=t.length,A.expected=r.size,A.sri=e,A}else{let A=new Error(`Integrity checksum failed when using ${o}: Wanted ${e}, but got ${n}. (${t.length} bytes)`);throw A.code="EINTEGRITY",A.found=n,A.expected=e,A.algorithm=o,A.sri=e,A}}IA.exports.checkStream=Nvt;function Nvt(t,e,r){r=oa(r);let o=r.Promise||Promise,a=u5(r.concat({integrity:e}));return new o((n,u)=>{t.pipe(a),t.on("error",u),a.on("error",u);let A;a.on("verified",p=>{A=p}),a.on("end",()=>n(A)),a.on("data",()=>{})})}IA.exports.integrityStream=u5;function u5(t){t=oa(t);let e=t.integrity&&wA(t.integrity,t),r=e&&Object.keys(e).length,o=r&&e.pickAlgorithm(t),a=r&&e[o],n=Array.from(new Set(t.algorithms.concat(o?[o]:[]))),u=n.map(pv.createHash),A=0,p=new Pvt({transform(h,E,I){A+=h.length,u.forEach(v=>v.update(h,E)),I(null,h,E)}}).on("end",()=>{let h=t.options&&t.options.length?`?${t.options.join("?")}`:"",E=wA(u.map((v,x)=>`${n[x]}-${v.digest("base64")}${h}`).join(" "),t),I=r&&E.match(e,t);if(typeof t.size=="number"&&A!==t.size){let v=new Error(`stream size mismatch when checking ${e}. + Wanted: ${t.size} + Found: ${A}`);v.code="EBADSIZE",v.found=A,v.expected=t.size,v.sri=e,p.emit("error",v)}else if(t.integrity&&!I){let v=new Error(`${e} integrity checksum failed when using ${o}: wanted ${a} but got ${E}. (${A} bytes)`);v.code="EINTEGRITY",v.found=E,v.expected=a,v.algorithm=o,v.sri=e,p.emit("error",v)}else p.emit("size",A),p.emit("integrity",E),I&&p.emit("verified",I)});return p}IA.exports.create=Lvt;function Lvt(t){t=oa(t);let e=t.algorithms,r=t.options.length?`?${t.options.join("?")}`:"",o=e.map(pv.createHash);return{update:function(a,n){return o.forEach(u=>u.update(a,n)),this},digest:function(a){return e.reduce((u,A)=>{let p=o.shift().digest("base64"),h=new Zh(`${A}-${p}${r}`,t);if(h.algorithm&&h.digest){let E=h.algorithm;u[E]||(u[E]=[]),u[E].push(h)}return u},new fd)}}}var Mvt=new Set(pv.getHashes()),gBe=["md5","whirlpool","sha1","sha224","sha256","sha384","sha512","sha3","sha3-256","sha3-384","sha3-512","sha3_256","sha3_384","sha3_512"].filter(t=>Mvt.has(t));function Ovt(t,e){return gBe.indexOf(t.toLowerCase())>=gBe.indexOf(e.toLowerCase())?t:e}});var YBe=_((dir,GBe)=>{var ODt=$N();function UDt(t){return ODt(t)?void 0:t}GBe.exports=UDt});var KBe=_((mir,WBe)=>{var _Dt=xS(),HDt=B8(),qDt=b8(),jDt=Mg(),GDt=Ag(),YDt=YBe(),WDt=m_(),KDt=I8(),VDt=1,zDt=2,JDt=4,XDt=WDt(function(t,e){var r={};if(t==null)return r;var o=!1;e=_Dt(e,function(n){return n=jDt(n,t),o||(o=n.length>1),n}),GDt(t,KDt(t),r),o&&(r=HDt(r,VDt|zDt|JDt,YDt));for(var a=e.length;a--;)qDt(r,e[a]);return r});WBe.exports=XDt});Pt();Ge();Pt();var ZBe=ve("child_process"),$Be=Ze(X0());qt();var Uy=new Map([]);var W1={};Vt(W1,{BaseCommand:()=>ut,WorkspaceRequiredError:()=>sr,getCli:()=>ihe,getDynamicLibs:()=>nhe,getPluginConfiguration:()=>Hy,openWorkspace:()=>_y,pluginCommands:()=>Uy,runExit:()=>Wx});qt();var ut=class extends it{constructor(){super(...arguments);this.cwd=ge.String("--cwd",{hidden:!0})}validateAndExecute(){if(typeof this.cwd<"u")throw new st("The --cwd option is ambiguous when used anywhere else than the very first parameter provided in the command line, before even the command path");return super.validateAndExecute()}};Ge();Pt();qt();var sr=class extends st{constructor(e,r){let o=V.relative(e,r),a=V.join(e,Ut.fileName);super(`This command can only be run from within a workspace of your project (${o} isn't a workspace of ${a}).`)}};Ge();Pt();nA();Nl();g1();qt();var OAt=Ze(Jn());el();var nhe=()=>new Map([["@yarnpkg/cli",W1],["@yarnpkg/core",Y1],["@yarnpkg/fslib",kw],["@yarnpkg/libzip",p1],["@yarnpkg/parsers",Ow],["@yarnpkg/shell",E1],["clipanion",Jw],["semver",OAt],["typanion",Vo]]);Ge();async function _y(t,e){let{project:r,workspace:o}=await kt.find(t,e);if(!o)throw new sr(r.cwd,e);return o}Ge();Pt();nA();Nl();g1();qt();var oPt=Ze(Jn());el();var K8={};Vt(K8,{AddCommand:()=>Yy,BinCommand:()=>Wy,CacheCleanCommand:()=>Ky,ClipanionCommand:()=>$y,ConfigCommand:()=>Xy,ConfigGetCommand:()=>Vy,ConfigSetCommand:()=>zy,ConfigUnsetCommand:()=>Jy,DedupeCommand:()=>Zy,EntryCommand:()=>tE,ExecCommand:()=>nE,ExplainCommand:()=>oE,ExplainPeerRequirementsCommand:()=>iE,HelpCommand:()=>eE,InfoCommand:()=>aE,LinkCommand:()=>cE,NodeCommand:()=>uE,PluginCheckCommand:()=>AE,PluginImportCommand:()=>hE,PluginImportSourcesCommand:()=>gE,PluginListCommand:()=>fE,PluginRemoveCommand:()=>dE,PluginRuntimeCommand:()=>mE,RebuildCommand:()=>yE,RemoveCommand:()=>EE,RunCommand:()=>wE,RunIndexCommand:()=>CE,SetResolutionCommand:()=>IE,SetVersionCommand:()=>sE,SetVersionSourcesCommand:()=>pE,UnlinkCommand:()=>BE,UpCommand:()=>vE,VersionCommand:()=>rE,WhyCommand:()=>DE,WorkspaceCommand:()=>kE,WorkspacesListCommand:()=>xE,YarnCommand:()=>lE,dedupeUtils:()=>rk,default:()=>Fgt,suggestUtils:()=>Zc});var Nde=Ze(X0());Ge();Ge();Ge();qt();var Y0e=Ze(J1());el();var Zc={};Vt(Zc,{Modifier:()=>m8,Strategy:()=>$x,Target:()=>X1,WorkspaceModifier:()=>_0e,applyModifier:()=>ipt,extractDescriptorFromPath:()=>y8,extractRangeModifier:()=>H0e,fetchDescriptorFrom:()=>E8,findProjectDescriptors:()=>G0e,getModifier:()=>Z1,getSuggestedDescriptors:()=>$1,makeWorkspaceDescriptor:()=>j0e,toWorkspaceModifier:()=>q0e});Ge();Ge();Pt();var d8=Ze(Jn()),rpt="workspace:",X1=(o=>(o.REGULAR="dependencies",o.DEVELOPMENT="devDependencies",o.PEER="peerDependencies",o))(X1||{}),m8=(o=>(o.CARET="^",o.TILDE="~",o.EXACT="",o))(m8||{}),_0e=(o=>(o.CARET="^",o.TILDE="~",o.EXACT="*",o))(_0e||{}),$x=(n=>(n.KEEP="keep",n.REUSE="reuse",n.PROJECT="project",n.LATEST="latest",n.CACHE="cache",n))($x||{});function Z1(t,e){return t.exact?"":t.caret?"^":t.tilde?"~":e.configuration.get("defaultSemverRangePrefix")}var npt=/^([\^~]?)[0-9]+(?:\.[0-9]+){0,2}(?:-\S+)?$/;function H0e(t,{project:e}){let r=t.match(npt);return r?r[1]:e.configuration.get("defaultSemverRangePrefix")}function ipt(t,e){let{protocol:r,source:o,params:a,selector:n}=G.parseRange(t.range);return d8.default.valid(n)&&(n=`${e}${t.range}`),G.makeDescriptor(t,G.makeRange({protocol:r,source:o,params:a,selector:n}))}function q0e(t){switch(t){case"^":return"^";case"~":return"~";case"":return"*";default:throw new Error(`Assertion failed: Unknown modifier: "${t}"`)}}function j0e(t,e){return G.makeDescriptor(t.anchoredDescriptor,`${rpt}${q0e(e)}`)}async function G0e(t,{project:e,target:r}){let o=new Map,a=n=>{let u=o.get(n.descriptorHash);return u||o.set(n.descriptorHash,u={descriptor:n,locators:[]}),u};for(let n of e.workspaces)if(r==="peerDependencies"){let u=n.manifest.peerDependencies.get(t.identHash);u!==void 0&&a(u).locators.push(n.anchoredLocator)}else{let u=n.manifest.dependencies.get(t.identHash),A=n.manifest.devDependencies.get(t.identHash);r==="devDependencies"?A!==void 0?a(A).locators.push(n.anchoredLocator):u!==void 0&&a(u).locators.push(n.anchoredLocator):u!==void 0?a(u).locators.push(n.anchoredLocator):A!==void 0&&a(A).locators.push(n.anchoredLocator)}return o}async function y8(t,{cwd:e,workspace:r}){return await spt(async o=>{V.isAbsolute(t)||(t=V.relative(r.cwd,V.resolve(e,t)),t.match(/^\.{0,2}\//)||(t=`./${t}`));let{project:a}=r,n=await E8(G.makeIdent(null,"archive"),t,{project:r.project,cache:o,workspace:r});if(!n)throw new Error("Assertion failed: The descriptor should have been found");let u=new ki,A=a.configuration.makeResolver(),p=a.configuration.makeFetcher(),h={checksums:a.storedChecksums,project:a,cache:o,fetcher:p,report:u,resolver:A},E=A.bindDescriptor(n,r.anchoredLocator,h),I=G.convertDescriptorToLocator(E),v=await p.fetch(I,h),x=await Ut.find(v.prefixPath,{baseFs:v.packageFs});if(!x.name)throw new Error("Target path doesn't have a name");return G.makeDescriptor(x.name,t)})}async function $1(t,{project:e,workspace:r,cache:o,target:a,fixed:n,modifier:u,strategies:A,maxResults:p=1/0}){if(!(p>=0))throw new Error(`Invalid maxResults (${p})`);let[h,E]=t.range!=="unknown"?n||Lr.validRange(t.range)||!t.range.match(/^[a-z0-9._-]+$/i)?[t.range,"latest"]:["unknown",t.range]:["unknown","latest"];if(h!=="unknown")return{suggestions:[{descriptor:t,name:`Use ${G.prettyDescriptor(e.configuration,t)}`,reason:"(unambiguous explicit request)"}],rejections:[]};let I=typeof r<"u"&&r!==null&&r.manifest[a].get(t.identHash)||null,v=[],x=[],C=async R=>{try{await R()}catch(L){x.push(L)}};for(let R of A){if(v.length>=p)break;switch(R){case"keep":await C(async()=>{I&&v.push({descriptor:I,name:`Keep ${G.prettyDescriptor(e.configuration,I)}`,reason:"(no changes)"})});break;case"reuse":await C(async()=>{for(let{descriptor:L,locators:U}of(await G0e(t,{project:e,target:a})).values()){if(U.length===1&&U[0].locatorHash===r.anchoredLocator.locatorHash&&A.includes("keep"))continue;let z=`(originally used by ${G.prettyLocator(e.configuration,U[0])}`;z+=U.length>1?` and ${U.length-1} other${U.length>2?"s":""})`:")",v.push({descriptor:L,name:`Reuse ${G.prettyDescriptor(e.configuration,L)}`,reason:z})}});break;case"cache":await C(async()=>{for(let L of e.storedDescriptors.values())L.identHash===t.identHash&&v.push({descriptor:L,name:`Reuse ${G.prettyDescriptor(e.configuration,L)}`,reason:"(already used somewhere in the lockfile)"})});break;case"project":await C(async()=>{if(r.manifest.name!==null&&t.identHash===r.manifest.name.identHash)return;let L=e.tryWorkspaceByIdent(t);if(L===null)return;let U=j0e(L,u);v.push({descriptor:U,name:`Attach ${G.prettyDescriptor(e.configuration,U)}`,reason:`(local workspace at ${pe.pretty(e.configuration,L.relativeCwd,pe.Type.PATH)})`})});break;case"latest":{let L=e.configuration.get("enableNetwork"),U=e.configuration.get("enableOfflineMode");await C(async()=>{if(a==="peerDependencies")v.push({descriptor:G.makeDescriptor(t,"*"),name:"Use *",reason:"(catch-all peer dependency pattern)"});else if(!L&&!U)v.push({descriptor:null,name:"Resolve from latest",reason:pe.pretty(e.configuration,"(unavailable because enableNetwork is toggled off)","grey")});else{let z=await E8(t,E,{project:e,cache:o,workspace:r,modifier:u});z&&v.push({descriptor:z,name:`Use ${G.prettyDescriptor(e.configuration,z)}`,reason:`(resolved from ${U?"the cache":"latest"})`})}})}break}}return{suggestions:v.slice(0,p),rejections:x.slice(0,p)}}async function E8(t,e,{project:r,cache:o,workspace:a,preserveModifier:n=!0,modifier:u}){let A=r.configuration.normalizeDependency(G.makeDescriptor(t,e)),p=new ki,h=r.configuration.makeFetcher(),E=r.configuration.makeResolver(),I={project:r,fetcher:h,cache:o,checksums:r.storedChecksums,report:p,cacheOptions:{skipIntegrityCheck:!0}},v={...I,resolver:E,fetchOptions:I},x=E.bindDescriptor(A,a.anchoredLocator,v),C=await E.getCandidates(x,{},v);if(C.length===0)return null;let R=C[0],{protocol:L,source:U,params:z,selector:te}=G.parseRange(G.convertToManifestRange(R.reference));if(L===r.configuration.get("defaultProtocol")&&(L=null),d8.default.valid(te)){let ae=te;if(typeof u<"u")te=u+te;else if(n!==!1){let Ce=typeof n=="string"?n:A.range;te=H0e(Ce,{project:r})+te}let le=G.makeDescriptor(R,G.makeRange({protocol:L,source:U,params:z,selector:te}));(await E.getCandidates(r.configuration.normalizeDependency(le),{},v)).length!==1&&(te=ae)}return G.makeDescriptor(R,G.makeRange({protocol:L,source:U,params:z,selector:te}))}async function spt(t){return await oe.mktempPromise(async e=>{let r=Ke.create(e);return r.useWithSource(e,{enableMirror:!1,compressionLevel:0},e,{overwrite:!0}),await t(new Gr(e,{configuration:r,check:!1,immutable:!1}))})}var Yy=class extends ut{constructor(){super(...arguments);this.json=ge.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.fixed=ge.Boolean("-F,--fixed",!1,{description:"Store dependency tags as-is instead of resolving them"});this.exact=ge.Boolean("-E,--exact",!1,{description:"Don't use any semver modifier on the resolved range"});this.tilde=ge.Boolean("-T,--tilde",!1,{description:"Use the `~` semver modifier on the resolved range"});this.caret=ge.Boolean("-C,--caret",!1,{description:"Use the `^` semver modifier on the resolved range"});this.dev=ge.Boolean("-D,--dev",!1,{description:"Add a package as a dev dependency"});this.peer=ge.Boolean("-P,--peer",!1,{description:"Add a package as a peer dependency"});this.optional=ge.Boolean("-O,--optional",!1,{description:"Add / upgrade a package to an optional regular / peer dependency"});this.preferDev=ge.Boolean("--prefer-dev",!1,{description:"Add / upgrade a package to a dev dependency"});this.interactive=ge.Boolean("-i,--interactive",{description:"Reuse the specified package from other workspaces in the project"});this.cached=ge.Boolean("--cached",!1,{description:"Reuse the highest version already used somewhere within the project"});this.mode=ge.String("--mode",{description:"Change what artifacts installs generate",validator:Js(hl)});this.silent=ge.Boolean("--silent",{hidden:!0});this.packages=ge.Rest()}static{this.paths=[["add"]]}static{this.usage=it.Usage({description:"add dependencies to the project",details:"\n This command adds a package to the package.json for the nearest workspace.\n\n - If it didn't exist before, the package will by default be added to the regular `dependencies` field, but this behavior can be overriden thanks to the `-D,--dev` flag (which will cause the dependency to be added to the `devDependencies` field instead) and the `-P,--peer` flag (which will do the same but for `peerDependencies`).\n\n - If the package was already listed in your dependencies, it will by default be upgraded whether it's part of your `dependencies` or `devDependencies` (it won't ever update `peerDependencies`, though).\n\n - If set, the `--prefer-dev` flag will operate as a more flexible `-D,--dev` in that it will add the package to your `devDependencies` if it isn't already listed in either `dependencies` or `devDependencies`, but it will also happily upgrade your `dependencies` if that's what you already use (whereas `-D,--dev` would throw an exception).\n\n - If set, the `-O,--optional` flag will add the package to the `optionalDependencies` field and, in combination with the `-P,--peer` flag, it will add the package as an optional peer dependency. If the package was already listed in your `dependencies`, it will be upgraded to `optionalDependencies`. If the package was already listed in your `peerDependencies`, in combination with the `-P,--peer` flag, it will be upgraded to an optional peer dependency: `\"peerDependenciesMeta\": { \"\": { \"optional\": true } }`\n\n - If the added package doesn't specify a range at all its `latest` tag will be resolved and the returned version will be used to generate a new semver range (using the `^` modifier by default unless otherwise configured via the `defaultSemverRangePrefix` configuration, or the `~` modifier if `-T,--tilde` is specified, or no modifier at all if `-E,--exact` is specified). Two exceptions to this rule: the first one is that if the package is a workspace then its local version will be used, and the second one is that if you use `-P,--peer` the default range will be `*` and won't be resolved at all.\n\n - If the added package specifies a range (such as `^1.0.0`, `latest`, or `rc`), Yarn will add this range as-is in the resulting package.json entry (in particular, tags such as `rc` will be encoded as-is rather than being converted into a semver range).\n\n If the `--cached` option is used, Yarn will preferably reuse the highest version already used somewhere within the project, even if through a transitive dependency.\n\n If the `-i,--interactive` option is used (or if the `preferInteractive` settings is toggled on) the command will first try to check whether other workspaces in the project use the specified package and, if so, will offer to reuse them.\n\n If the `--mode=` option is set, Yarn will change which artifacts are generated. The modes currently supported are:\n\n - `skip-build` will not run the build scripts at all. Note that this is different from setting `enableScripts` to false because the latter will disable build scripts, and thus affect the content of the artifacts generated on disk, whereas the former will just disable the build step - but not the scripts themselves, which just won't run.\n\n - `update-lockfile` will skip the link step altogether, and only fetch packages that are missing from the lockfile (or that have no associated checksums). This mode is typically used by tools like Renovate or Dependabot to keep a lockfile up-to-date without incurring the full install cost.\n\n For a compilation of all the supported protocols, please consult the dedicated page from our website: https://yarnpkg.com/protocols.\n ",examples:[["Add a regular package to the current workspace","$0 add lodash"],["Add a specific version for a package to the current workspace","$0 add lodash@1.2.3"],["Add a package from a GitHub repository (the master branch) to the current workspace using a URL","$0 add lodash@https://github.com/lodash/lodash"],["Add a package from a GitHub repository (the master branch) to the current workspace using the GitHub protocol","$0 add lodash@github:lodash/lodash"],["Add a package from a GitHub repository (the master branch) to the current workspace using the GitHub protocol (shorthand)","$0 add lodash@lodash/lodash"],["Add a package from a specific branch of a GitHub repository to the current workspace using the GitHub protocol (shorthand)","$0 add lodash-es@lodash/lodash#es"],["Add a local package (gzipped tarball format) to the current workspace","$0 add local-package-name@file:../path/to/local-package-name-v0.1.2.tgz"]]})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await kt.find(r,this.context.cwd),n=await Gr.find(r);if(!a)throw new sr(o.cwd,this.context.cwd);await o.restoreInstallState({restoreResolutions:!1});let u=this.fixed,A=r.isInteractive({interactive:this.interactive,stdout:this.context.stdout}),p=A||r.get("preferReuse"),h=Z1(this,o),E=[p?"reuse":void 0,"project",this.cached?"cache":void 0,"latest"].filter(U=>typeof U<"u"),I=A?1/0:1,v=await Promise.all(this.packages.map(async U=>{let z=U.match(/^\.{0,2}\//)?await y8(U,{cwd:this.context.cwd,workspace:a}):G.tryParseDescriptor(U),te=U.match(/^(https?:|git@github)/);if(te)throw new st(`It seems you are trying to add a package using a ${pe.pretty(r,`${te[0]}...`,pe.Type.RANGE)} url; we now require package names to be explicitly specified. +Try running the command again with the package name prefixed: ${pe.pretty(r,"yarn add",pe.Type.CODE)} ${pe.pretty(r,G.makeDescriptor(G.makeIdent(null,"my-package"),`${te[0]}...`),pe.Type.DESCRIPTOR)}`);if(!z)throw new st(`The ${pe.pretty(r,U,pe.Type.CODE)} string didn't match the required format (package-name@range). Did you perhaps forget to explicitly reference the package name?`);let ae=opt(a,z,{dev:this.dev,peer:this.peer,preferDev:this.preferDev,optional:this.optional});return await Promise.all(ae.map(async ce=>{let Ce=await $1(z,{project:o,workspace:a,cache:n,fixed:u,target:ce,modifier:h,strategies:E,maxResults:I});return{request:z,suggestedDescriptors:Ce,target:ce}}))})).then(U=>U.flat()),x=await AA.start({configuration:r,stdout:this.context.stdout,suggestInstall:!1},async U=>{for(let{request:z,suggestedDescriptors:{suggestions:te,rejections:ae}}of v)if(te.filter(ce=>ce.descriptor!==null).length===0){let[ce]=ae;if(typeof ce>"u")throw new Error("Assertion failed: Expected an error to have been set");o.configuration.get("enableNetwork")?U.reportError(27,`${G.prettyDescriptor(r,z)} can't be resolved to a satisfying range`):U.reportError(27,`${G.prettyDescriptor(r,z)} can't be resolved to a satisfying range (note: network resolution has been disabled)`),U.reportSeparator(),U.reportExceptionOnce(ce)}});if(x.hasErrors())return x.exitCode();let C=!1,R=[],L=[];for(let{suggestedDescriptors:{suggestions:U},target:z}of v){let te,ae=U.filter(de=>de.descriptor!==null),le=ae[0].descriptor,ce=ae.every(de=>G.areDescriptorsEqual(de.descriptor,le));ae.length===1||ce?te=le:(C=!0,{answer:te}=await(0,Y0e.prompt)({type:"select",name:"answer",message:"Which range do you want to use?",choices:U.map(({descriptor:de,name:Be,reason:Ee})=>de?{name:Be,hint:Ee,descriptor:de}:{name:Be,hint:Ee,disabled:!0}),onCancel:()=>process.exit(130),result(de){return this.find(de,"descriptor")},stdin:this.context.stdin,stdout:this.context.stdout}));let Ce=a.manifest[z].get(te.identHash);(typeof Ce>"u"||Ce.descriptorHash!==te.descriptorHash)&&(a.manifest[z].set(te.identHash,te),this.optional&&(z==="dependencies"?a.manifest.ensureDependencyMeta({...te,range:"unknown"}).optional=!0:z==="peerDependencies"&&(a.manifest.ensurePeerDependencyMeta({...te,range:"unknown"}).optional=!0)),typeof Ce>"u"?R.push([a,z,te,E]):L.push([a,z,Ce,te]))}return await r.triggerMultipleHooks(U=>U.afterWorkspaceDependencyAddition,R),await r.triggerMultipleHooks(U=>U.afterWorkspaceDependencyReplacement,L),C&&this.context.stdout.write(` +`),await o.installWithNewReport({json:this.json,stdout:this.context.stdout,quiet:this.context.quiet},{cache:n,mode:this.mode})}};function opt(t,e,{dev:r,peer:o,preferDev:a,optional:n}){let u=t.manifest.dependencies.has(e.identHash),A=t.manifest.devDependencies.has(e.identHash),p=t.manifest.peerDependencies.has(e.identHash);if((r||o)&&u)throw new st(`Package "${G.prettyIdent(t.project.configuration,e)}" is already listed as a regular dependency - remove the -D,-P flags or remove it from your dependencies first`);if(!r&&!o&&p)throw new st(`Package "${G.prettyIdent(t.project.configuration,e)}" is already listed as a peer dependency - use either of -D or -P, or remove it from your peer dependencies first`);if(n&&A)throw new st(`Package "${G.prettyIdent(t.project.configuration,e)}" is already listed as a dev dependency - remove the -O flag or remove it from your dev dependencies first`);if(n&&!o&&p)throw new st(`Package "${G.prettyIdent(t.project.configuration,e)}" is already listed as a peer dependency - remove the -O flag or add the -P flag or remove it from your peer dependencies first`);if((r||a)&&n)throw new st(`Package "${G.prettyIdent(t.project.configuration,e)}" cannot simultaneously be a dev dependency and an optional dependency`);let h=[];return o&&h.push("peerDependencies"),(r||a)&&h.push("devDependencies"),n&&h.push("dependencies"),h.length>0?h:A?["devDependencies"]:p?["peerDependencies"]:["dependencies"]}Ge();Ge();qt();var Wy=class extends ut{constructor(){super(...arguments);this.verbose=ge.Boolean("-v,--verbose",!1,{description:"Print both the binary name and the locator of the package that provides the binary"});this.json=ge.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.name=ge.String({required:!1})}static{this.paths=[["bin"]]}static{this.usage=it.Usage({description:"get the path to a binary script",details:` + When used without arguments, this command will print the list of all the binaries available in the current workspace. Adding the \`-v,--verbose\` flag will cause the output to contain both the binary name and the locator of the package that provides the binary. + + When an argument is specified, this command will just print the path to the binary on the standard output and exit. Note that the reported path may be stored within a zip archive. + `,examples:[["List all the available binaries","$0 bin"],["Print the path to a specific binary","$0 bin eslint"]]})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins),{project:o,locator:a}=await kt.find(r,this.context.cwd);if(await o.restoreInstallState(),this.name){let A=(await An.getPackageAccessibleBinaries(a,{project:o})).get(this.name);if(!A)throw new st(`Couldn't find a binary named "${this.name}" for package "${G.prettyLocator(r,a)}"`);let[,p]=A;return this.context.stdout.write(`${p} +`),0}return(await Rt.start({configuration:r,json:this.json,stdout:this.context.stdout},async u=>{let A=await An.getPackageAccessibleBinaries(a,{project:o}),h=Array.from(A.keys()).reduce((E,I)=>Math.max(E,I.length),0);for(let[E,[I,v]]of A)u.reportJson({name:E,source:G.stringifyIdent(I),path:v});if(this.verbose)for(let[E,[I]]of A)u.reportInfo(null,`${E.padEnd(h," ")} ${G.prettyLocator(r,I)}`);else for(let E of A.keys())u.reportInfo(null,E)})).exitCode()}};Ge();Pt();qt();var Ky=class extends ut{constructor(){super(...arguments);this.mirror=ge.Boolean("--mirror",!1,{description:"Remove the global cache files instead of the local cache files"});this.all=ge.Boolean("--all",!1,{description:"Remove both the global cache files and the local cache files of the current project"})}static{this.paths=[["cache","clean"],["cache","clear"]]}static{this.usage=it.Usage({description:"remove the shared cache files",details:` + This command will remove all the files from the cache. + `,examples:[["Remove all the local archives","$0 cache clean"],["Remove all the archives stored in the ~/.yarn directory","$0 cache clean --mirror"]]})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins),o=await Gr.find(r);return(await Rt.start({configuration:r,stdout:this.context.stdout},async()=>{let n=(this.all||this.mirror)&&o.mirrorCwd!==null,u=!this.mirror;n&&(await oe.removePromise(o.mirrorCwd),await r.triggerHook(A=>A.cleanGlobalArtifacts,r)),u&&await oe.removePromise(o.cwd)})).exitCode()}};Ge();qt();var K0e=Ze(e2()),C8=ve("util"),Vy=class extends ut{constructor(){super(...arguments);this.why=ge.Boolean("--why",!1,{description:"Print the explanation for why a setting has its value"});this.json=ge.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.unsafe=ge.Boolean("--no-redacted",!1,{description:"Don't redact secrets (such as tokens) from the output"});this.name=ge.String()}static{this.paths=[["config","get"]]}static{this.usage=it.Usage({description:"read a configuration settings",details:` + This command will print a configuration setting. + + Secrets (such as tokens) will be redacted from the output by default. If this behavior isn't desired, set the \`--no-redacted\` to get the untransformed value. + `,examples:[["Print a simple configuration setting","yarn config get yarnPath"],["Print a complex configuration setting","yarn config get packageExtensions"],["Print a nested field from the configuration",`yarn config get 'npmScopes["my-company"].npmRegistryServer'`],["Print a token from the configuration","yarn config get npmAuthToken --no-redacted"],["Print a configuration setting as JSON","yarn config get packageExtensions --json"]]})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins),o=this.name.replace(/[.[].*$/,""),a=this.name.replace(/^[^.[]*/,"");if(typeof r.settings.get(o)>"u")throw new st(`Couldn't find a configuration settings named "${o}"`);let u=r.getSpecial(o,{hideSecrets:!this.unsafe,getNativePaths:!0}),A=He.convertMapsToIndexableObjects(u),p=a?(0,K0e.default)(A,a):A,h=await Rt.start({configuration:r,includeFooter:!1,json:this.json,stdout:this.context.stdout},async E=>{E.reportJson(p)});if(!this.json){if(typeof p=="string")return this.context.stdout.write(`${p} +`),h.exitCode();C8.inspect.styles.name="cyan",this.context.stdout.write(`${(0,C8.inspect)(p,{depth:1/0,colors:r.get("enableColors"),compact:!1})} +`)}return h.exitCode()}};Ge();qt();var Mge=Ze(v8()),Oge=Ze(e2()),Uge=Ze(D8()),P8=ve("util"),zy=class extends ut{constructor(){super(...arguments);this.json=ge.Boolean("--json",!1,{description:"Set complex configuration settings to JSON values"});this.home=ge.Boolean("-H,--home",!1,{description:"Update the home configuration instead of the project configuration"});this.name=ge.String();this.value=ge.String()}static{this.paths=[["config","set"]]}static{this.usage=it.Usage({description:"change a configuration settings",details:` + This command will set a configuration setting. + + When used without the \`--json\` flag, it can only set a simple configuration setting (a string, a number, or a boolean). + + When used with the \`--json\` flag, it can set both simple and complex configuration settings, including Arrays and Objects. + `,examples:[["Set a simple configuration setting (a string, a number, or a boolean)","yarn config set initScope myScope"],["Set a simple configuration setting (a string, a number, or a boolean) using the `--json` flag",'yarn config set initScope --json \\"myScope\\"'],["Set a complex configuration setting (an Array) using the `--json` flag",`yarn config set unsafeHttpWhitelist --json '["*.example.com", "example.com"]'`],["Set a complex configuration setting (an Object) using the `--json` flag",`yarn config set packageExtensions --json '{ "@babel/parser@*": { "dependencies": { "@babel/types": "*" } } }'`],["Set a nested configuration setting",'yarn config set npmScopes.company.npmRegistryServer "https://npm.example.com"'],["Set a nested configuration setting using indexed access for non-simple keys",`yarn config set 'npmRegistries["//npm.example.com"].npmAuthToken' "ffffffff-ffff-ffff-ffff-ffffffffffff"`]]})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins),o=()=>{if(!r.projectCwd)throw new st("This command must be run from within a project folder");return r.projectCwd},a=this.name.replace(/[.[].*$/,""),n=this.name.replace(/^[^.[]*\.?/,"");if(typeof r.settings.get(a)>"u")throw new st(`Couldn't find a configuration settings named "${a}"`);if(a==="enableStrictSettings")throw new st("This setting only affects the file it's in, and thus cannot be set from the CLI");let A=this.json?JSON.parse(this.value):this.value;await(this.home?C=>Ke.updateHomeConfiguration(C):C=>Ke.updateConfiguration(o(),C))(C=>{if(n){let R=(0,Mge.default)(C);return(0,Uge.default)(R,this.name,A),R}else return{...C,[a]:A}});let E=(await Ke.find(this.context.cwd,this.context.plugins)).getSpecial(a,{hideSecrets:!0,getNativePaths:!0}),I=He.convertMapsToIndexableObjects(E),v=n?(0,Oge.default)(I,n):I;return(await Rt.start({configuration:r,includeFooter:!1,stdout:this.context.stdout},async C=>{P8.inspect.styles.name="cyan",C.reportInfo(0,`Successfully set ${this.name} to ${(0,P8.inspect)(v,{depth:1/0,colors:r.get("enableColors"),compact:!1})}`)})).exitCode()}};Ge();qt();var Jge=Ze(v8()),Xge=Ze(jge()),Zge=Ze(S8()),Jy=class extends ut{constructor(){super(...arguments);this.home=ge.Boolean("-H,--home",!1,{description:"Update the home configuration instead of the project configuration"});this.name=ge.String()}static{this.paths=[["config","unset"]]}static{this.usage=it.Usage({description:"unset a configuration setting",details:` + This command will unset a configuration setting. + `,examples:[["Unset a simple configuration setting","yarn config unset initScope"],["Unset a complex configuration setting","yarn config unset packageExtensions"],["Unset a nested configuration setting","yarn config unset npmScopes.company.npmRegistryServer"]]})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins),o=()=>{if(!r.projectCwd)throw new st("This command must be run from within a project folder");return r.projectCwd},a=this.name.replace(/[.[].*$/,""),n=this.name.replace(/^[^.[]*\.?/,"");if(typeof r.settings.get(a)>"u")throw new st(`Couldn't find a configuration settings named "${a}"`);let A=this.home?h=>Ke.updateHomeConfiguration(h):h=>Ke.updateConfiguration(o(),h);return(await Rt.start({configuration:r,includeFooter:!1,stdout:this.context.stdout},async h=>{let E=!1;await A(I=>{if(!(0,Xge.default)(I,this.name))return h.reportWarning(0,`Configuration doesn't contain setting ${this.name}; there is nothing to unset`),E=!0,I;let v=n?(0,Jge.default)(I):{...I};return(0,Zge.default)(v,this.name),v}),E||h.reportInfo(0,`Successfully unset ${this.name}`)})).exitCode()}};Ge();Pt();qt();var tk=ve("util"),Xy=class extends ut{constructor(){super(...arguments);this.noDefaults=ge.Boolean("--no-defaults",!1,{description:"Omit the default values from the display"});this.json=ge.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.verbose=ge.Boolean("-v,--verbose",{hidden:!0});this.why=ge.Boolean("--why",{hidden:!0});this.names=ge.Rest()}static{this.paths=[["config"]]}static{this.usage=it.Usage({description:"display the current configuration",details:` + This command prints the current active configuration settings. + `,examples:[["Print the active configuration settings","$0 config"]]})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins,{strict:!1}),o=await uy({configuration:r,stdout:this.context.stdout,forceError:this.json},[{option:this.verbose,message:"The --verbose option is deprecated, the settings' descriptions are now always displayed"},{option:this.why,message:"The --why option is deprecated, the settings' sources are now always displayed"}]);if(o!==null)return o;let a=this.names.length>0?[...new Set(this.names)].sort():[...r.settings.keys()].sort(),n,u=await Rt.start({configuration:r,json:this.json,stdout:this.context.stdout,includeFooter:!1},async A=>{if(r.invalid.size>0&&!this.json){for(let[p,h]of r.invalid)A.reportError(34,`Invalid configuration key "${p}" in ${h}`);A.reportSeparator()}if(this.json)for(let p of a){let h=r.settings.get(p);typeof h>"u"&&A.reportError(34,`No configuration key named "${p}"`);let E=r.getSpecial(p,{hideSecrets:!0,getNativePaths:!0}),I=r.sources.get(p)??"",v=I&&I[0]!=="<"?ue.fromPortablePath(I):I;A.reportJson({key:p,effective:E,source:v,...h})}else{let p={breakLength:1/0,colors:r.get("enableColors"),maxArrayLength:2},h={},E={children:h};for(let I of a){if(this.noDefaults&&!r.sources.has(I))continue;let v=r.settings.get(I),x=r.sources.get(I)??"",C=r.getSpecial(I,{hideSecrets:!0,getNativePaths:!0}),R={Description:{label:"Description",value:pe.tuple(pe.Type.MARKDOWN,{text:v.description,format:this.cli.format(),paragraphs:!1})},Source:{label:"Source",value:pe.tuple(x[0]==="<"?pe.Type.CODE:pe.Type.PATH,x)}};h[I]={value:pe.tuple(pe.Type.CODE,I),children:R};let L=(U,z)=>{for(let[te,ae]of z)if(ae instanceof Map){let le={};U[te]={children:le},L(le,ae)}else U[te]={label:te,value:pe.tuple(pe.Type.NO_HINT,(0,tk.inspect)(ae,p))}};C instanceof Map?L(R,C):R.Value={label:"Value",value:pe.tuple(pe.Type.NO_HINT,(0,tk.inspect)(C,p))}}a.length!==1&&(n=void 0),fs.emitTree(E,{configuration:r,json:this.json,stdout:this.context.stdout,separators:2})}});if(!this.json&&typeof n<"u"){let A=a[0],p=(0,tk.inspect)(r.getSpecial(A,{hideSecrets:!0,getNativePaths:!0}),{colors:r.get("enableColors")});this.context.stdout.write(` +`),this.context.stdout.write(`${p} +`)}return u.exitCode()}};Ge();qt();el();var rk={};Vt(rk,{Strategy:()=>t2,acceptedStrategies:()=>q0t,dedupe:()=>x8});Ge();Ge();var $ge=Ze($o()),t2=(e=>(e.HIGHEST="highest",e))(t2||{}),q0t=new Set(Object.values(t2)),j0t={highest:async(t,e,{resolver:r,fetcher:o,resolveOptions:a,fetchOptions:n})=>{let u=new Map;for(let[p,h]of t.storedResolutions){let E=t.storedDescriptors.get(p);if(typeof E>"u")throw new Error(`Assertion failed: The descriptor (${p}) should have been registered`);He.getSetWithDefault(u,E.identHash).add(h)}let A=new Map(He.mapAndFilter(t.storedDescriptors.values(),p=>G.isVirtualDescriptor(p)?He.mapAndFilter.skip:[p.descriptorHash,He.makeDeferred()]));for(let p of t.storedDescriptors.values()){let h=A.get(p.descriptorHash);if(typeof h>"u")throw new Error(`Assertion failed: The descriptor (${p.descriptorHash}) should have been registered`);let E=t.storedResolutions.get(p.descriptorHash);if(typeof E>"u")throw new Error(`Assertion failed: The resolution (${p.descriptorHash}) should have been registered`);let I=t.originalPackages.get(E);if(typeof I>"u")throw new Error(`Assertion failed: The package (${E}) should have been registered`);Promise.resolve().then(async()=>{let v=r.getResolutionDependencies(p,a),x=Object.fromEntries(await He.allSettledSafe(Object.entries(v).map(async([te,ae])=>{let le=A.get(ae.descriptorHash);if(typeof le>"u")throw new Error(`Assertion failed: The descriptor (${ae.descriptorHash}) should have been registered`);let ce=await le.promise;if(!ce)throw new Error("Assertion failed: Expected the dependency to have been through the dedupe process itself");return[te,ce.updatedPackage]})));if(e.length&&!$ge.default.isMatch(G.stringifyIdent(p),e)||!r.shouldPersistResolution(I,a))return I;let C=u.get(p.identHash);if(typeof C>"u")throw new Error(`Assertion failed: The resolutions (${p.identHash}) should have been registered`);if(C.size===1)return I;let R=[...C].map(te=>{let ae=t.originalPackages.get(te);if(typeof ae>"u")throw new Error(`Assertion failed: The package (${te}) should have been registered`);return ae}),L=await r.getSatisfying(p,x,R,a),U=L.locators?.[0];if(typeof U>"u"||!L.sorted)return I;let z=t.originalPackages.get(U.locatorHash);if(typeof z>"u")throw new Error(`Assertion failed: The package (${U.locatorHash}) should have been registered`);return z}).then(async v=>{let x=await t.preparePackage(v,{resolver:r,resolveOptions:a});h.resolve({descriptor:p,currentPackage:I,updatedPackage:v,resolvedPackage:x})}).catch(v=>{h.reject(v)})}return[...A.values()].map(p=>p.promise)}};async function x8(t,{strategy:e,patterns:r,cache:o,report:a}){let{configuration:n}=t,u=new ki,A=n.makeResolver(),p=n.makeFetcher(),h={cache:o,checksums:t.storedChecksums,fetcher:p,project:t,report:u,cacheOptions:{skipIntegrityCheck:!0}},E={project:t,resolver:A,report:u,fetchOptions:h};return await a.startTimerPromise("Deduplication step",async()=>{let I=j0t[e],v=await I(t,r,{resolver:A,resolveOptions:E,fetcher:p,fetchOptions:h}),x=Zs.progressViaCounter(v.length);await a.reportProgress(x);let C=0;await Promise.all(v.map(U=>U.then(z=>{if(z===null||z.currentPackage.locatorHash===z.updatedPackage.locatorHash)return;C++;let{descriptor:te,currentPackage:ae,updatedPackage:le}=z;a.reportInfo(0,`${G.prettyDescriptor(n,te)} can be deduped from ${G.prettyLocator(n,ae)} to ${G.prettyLocator(n,le)}`),a.reportJson({descriptor:G.stringifyDescriptor(te),currentResolution:G.stringifyLocator(ae),updatedResolution:G.stringifyLocator(le)}),t.storedResolutions.set(te.descriptorHash,le.locatorHash)}).finally(()=>x.tick())));let R;switch(C){case 0:R="No packages";break;case 1:R="One package";break;default:R=`${C} packages`}let L=pe.pretty(n,e,pe.Type.CODE);return a.reportInfo(0,`${R} can be deduped using the ${L} strategy`),C})}var Zy=class extends ut{constructor(){super(...arguments);this.strategy=ge.String("-s,--strategy","highest",{description:"The strategy to use when deduping dependencies",validator:Js(t2)});this.check=ge.Boolean("-c,--check",!1,{description:"Exit with exit code 1 when duplicates are found, without persisting the dependency tree"});this.json=ge.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.mode=ge.String("--mode",{description:"Change what artifacts installs generate",validator:Js(hl)});this.patterns=ge.Rest()}static{this.paths=[["dedupe"]]}static{this.usage=it.Usage({description:"deduplicate dependencies with overlapping ranges",details:"\n Duplicates are defined as descriptors with overlapping ranges being resolved and locked to different locators. They are a natural consequence of Yarn's deterministic installs, but they can sometimes pile up and unnecessarily increase the size of your project.\n\n This command dedupes dependencies in the current project using different strategies (only one is implemented at the moment):\n\n - `highest`: Reuses (where possible) the locators with the highest versions. This means that dependencies can only be upgraded, never downgraded. It's also guaranteed that it never takes more than a single pass to dedupe the entire dependency tree.\n\n **Note:** Even though it never produces a wrong dependency tree, this command should be used with caution, as it modifies the dependency tree, which can sometimes cause problems when packages don't strictly follow semver recommendations. Because of this, it is recommended to also review the changes manually.\n\n If set, the `-c,--check` flag will only report the found duplicates, without persisting the modified dependency tree. If changes are found, the command will exit with a non-zero exit code, making it suitable for CI purposes.\n\n If the `--mode=` option is set, Yarn will change which artifacts are generated. The modes currently supported are:\n\n - `skip-build` will not run the build scripts at all. Note that this is different from setting `enableScripts` to false because the latter will disable build scripts, and thus affect the content of the artifacts generated on disk, whereas the former will just disable the build step - but not the scripts themselves, which just won't run.\n\n - `update-lockfile` will skip the link step altogether, and only fetch packages that are missing from the lockfile (or that have no associated checksums). This mode is typically used by tools like Renovate or Dependabot to keep a lockfile up-to-date without incurring the full install cost.\n\n This command accepts glob patterns as arguments (if valid Idents and supported by [micromatch](https://github.com/micromatch/micromatch)). Make sure to escape the patterns, to prevent your own shell from trying to expand them.\n\n ### In-depth explanation:\n\n Yarn doesn't deduplicate dependencies by default, otherwise installs wouldn't be deterministic and the lockfile would be useless. What it actually does is that it tries to not duplicate dependencies in the first place.\n\n **Example:** If `foo@^2.3.4` (a dependency of a dependency) has already been resolved to `foo@2.3.4`, running `yarn add foo@*`will cause Yarn to reuse `foo@2.3.4`, even if the latest `foo` is actually `foo@2.10.14`, thus preventing unnecessary duplication.\n\n Duplication happens when Yarn can't unlock dependencies that have already been locked inside the lockfile.\n\n **Example:** If `foo@^2.3.4` (a dependency of a dependency) has already been resolved to `foo@2.3.4`, running `yarn add foo@2.10.14` will cause Yarn to install `foo@2.10.14` because the existing resolution doesn't satisfy the range `2.10.14`. This behavior can lead to (sometimes) unwanted duplication, since now the lockfile contains 2 separate resolutions for the 2 `foo` descriptors, even though they have overlapping ranges, which means that the lockfile can be simplified so that both descriptors resolve to `foo@2.10.14`.\n ",examples:[["Dedupe all packages","$0 dedupe"],["Dedupe all packages using a specific strategy","$0 dedupe --strategy highest"],["Dedupe a specific package","$0 dedupe lodash"],["Dedupe all packages with the `@babel/*` scope","$0 dedupe '@babel/*'"],["Check for duplicates (can be used as a CI step)","$0 dedupe --check"]]})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins),{project:o}=await kt.find(r,this.context.cwd),a=await Gr.find(r);await o.restoreInstallState({restoreResolutions:!1});let n=0,u=await Rt.start({configuration:r,includeFooter:!1,stdout:this.context.stdout,json:this.json},async A=>{n=await x8(o,{strategy:this.strategy,patterns:this.patterns,cache:a,report:A})});return u.hasErrors()?u.exitCode():this.check?n?1:0:await o.installWithNewReport({json:this.json,stdout:this.context.stdout},{cache:a,mode:this.mode})}};Ge();qt();var $y=class extends ut{static{this.paths=[["--clipanion=definitions"]]}async execute(){let{plugins:e}=await Ke.find(this.context.cwd,this.context.plugins),r=[];for(let u of e){let{commands:A}=u[1];if(A){let h=Jo.from(A).definitions();r.push([u[0],h])}}let o=this.cli.definitions(),a=(u,A)=>u.split(" ").slice(1).join()===A.split(" ").slice(1).join(),n=ede()["@yarnpkg/builder"].bundles.standard;for(let u of r){let A=u[1];for(let p of A)o.find(h=>a(h.path,p.path)).plugin={name:u[0],isDefault:n.includes(u[0])}}this.context.stdout.write(`${JSON.stringify(o,null,2)} +`)}};var eE=class extends ut{static{this.paths=[["help"],["--help"],["-h"]]}async execute(){this.context.stdout.write(this.cli.usage(null))}};Ge();Pt();qt();var tE=class extends ut{constructor(){super(...arguments);this.leadingArgument=ge.String();this.args=ge.Proxy()}async execute(){if(this.leadingArgument.match(/[\\/]/)&&!G.tryParseIdent(this.leadingArgument)){let r=V.resolve(this.context.cwd,ue.toPortablePath(this.leadingArgument));return await this.cli.run(this.args,{cwd:r})}else return await this.cli.run(["run",this.leadingArgument,...this.args])}};Ge();var rE=class extends ut{static{this.paths=[["-v"],["--version"]]}async execute(){this.context.stdout.write(`${nn||""} +`)}};Ge();Ge();qt();var nE=class extends ut{constructor(){super(...arguments);this.commandName=ge.String();this.args=ge.Proxy()}static{this.paths=[["exec"]]}static{this.usage=it.Usage({description:"execute a shell script",details:` + This command simply executes a shell script within the context of the root directory of the active workspace using the portable shell. + + It also makes sure to call it in a way that's compatible with the current project (for example, on PnP projects the environment will be setup in such a way that PnP will be correctly injected into the environment). + `,examples:[["Execute a single shell command","$0 exec echo Hello World"],["Execute a shell script",'$0 exec "tsc & babel src --out-dir lib"']]})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins),{project:o,locator:a}=await kt.find(r,this.context.cwd);return await o.restoreInstallState(),await An.executePackageShellcode(a,this.commandName,this.args,{cwd:this.context.cwd,stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr,project:o})}};Ge();qt();el();var iE=class extends ut{constructor(){super(...arguments);this.hash=ge.String({required:!1,validator:YD(om(),[qw(/^p[0-9a-f]{5}$/)])})}static{this.paths=[["explain","peer-requirements"]]}static{this.usage=it.Usage({description:"explain a set of peer requirements",details:` + A peer requirement represents all peer requests that a subject must satisfy when providing a requested package to requesters. + + When the hash argument is specified, this command prints a detailed explanation of the peer requirement corresponding to the hash and whether it is satisfied or not. + + When used without arguments, this command lists all peer requirements and the corresponding hash that can be used to get detailed information about a given requirement. + + **Note:** A hash is a six-letter p-prefixed code that can be obtained from peer dependency warnings or from the list of all peer requirements (\`yarn explain peer-requirements\`). + `,examples:[["Explain the corresponding peer requirement for a hash","$0 explain peer-requirements p1a4ed"],["List all peer requirements","$0 explain peer-requirements"]]})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins),{project:o}=await kt.find(r,this.context.cwd);return await o.restoreInstallState({restoreResolutions:!1}),await o.applyLightResolution(),typeof this.hash<"u"?await Y0t(this.hash,o,{stdout:this.context.stdout}):await W0t(o,{stdout:this.context.stdout})}};async function Y0t(t,e,r){let o=e.peerRequirementNodes.get(t);if(typeof o>"u")throw new Error(`No peerDependency requirements found for hash: "${t}"`);let a=new Set,n=p=>a.has(p.requester.locatorHash)?{value:pe.tuple(pe.Type.DEPENDENT,{locator:p.requester,descriptor:p.descriptor}),children:p.children.size>0?[{value:pe.tuple(pe.Type.NO_HINT,"...")}]:[]}:(a.add(p.requester.locatorHash),{value:pe.tuple(pe.Type.DEPENDENT,{locator:p.requester,descriptor:p.descriptor}),children:Object.fromEntries(Array.from(p.children.values(),h=>[G.stringifyLocator(h.requester),n(h)]))}),u=e.peerWarnings.find(p=>p.hash===t);return(await Rt.start({configuration:e.configuration,stdout:r.stdout,includeFooter:!1,includePrefix:!1},async p=>{let h=pe.mark(e.configuration),E=u?h.Cross:h.Check;if(p.reportInfo(0,`Package ${pe.pretty(e.configuration,o.subject,pe.Type.LOCATOR)} is requested to provide ${pe.pretty(e.configuration,o.ident,pe.Type.IDENT)} by its descendants`),p.reportSeparator(),p.reportInfo(0,pe.pretty(e.configuration,o.subject,pe.Type.LOCATOR)),fs.emitTree({children:Object.fromEntries(Array.from(o.requests.values(),I=>[G.stringifyLocator(I.requester),n(I)]))},{configuration:e.configuration,stdout:r.stdout,json:!1}),p.reportSeparator(),o.provided.range==="missing:"){let I=u?"":" , but all peer requests are optional";p.reportInfo(0,`${E} Package ${pe.pretty(e.configuration,o.subject,pe.Type.LOCATOR)} does not provide ${pe.pretty(e.configuration,o.ident,pe.Type.IDENT)}${I}.`)}else{let I=e.storedResolutions.get(o.provided.descriptorHash);if(!I)throw new Error("Assertion failed: Expected the descriptor to be registered");let v=e.storedPackages.get(I);if(!v)throw new Error("Assertion failed: Expected the package to be registered");p.reportInfo(0,`${E} Package ${pe.pretty(e.configuration,o.subject,pe.Type.LOCATOR)} provides ${pe.pretty(e.configuration,o.ident,pe.Type.IDENT)} with version ${G.prettyReference(e.configuration,v.version??"0.0.0")}, ${u?"which does not satisfy all requests.":"which satisfies all requests"}`),u?.type===3&&(u.range?p.reportInfo(0,` The combined requested range is ${pe.pretty(e.configuration,u.range,pe.Type.RANGE)}`):p.reportInfo(0," Unfortunately, the requested ranges have no overlap"))}})).exitCode()}async function W0t(t,e){return(await Rt.start({configuration:t.configuration,stdout:e.stdout,includeFooter:!1,includePrefix:!1},async o=>{let a=pe.mark(t.configuration),n=He.sortMap(t.peerRequirementNodes,[([,u])=>G.stringifyLocator(u.subject),([,u])=>G.stringifyIdent(u.ident)]);for(let[,u]of n.values()){if(!u.root)continue;let A=t.peerWarnings.find(E=>E.hash===u.hash),p=[...G.allPeerRequests(u)],h;if(p.length>2?h=` and ${p.length-1} other dependencies`:p.length===2?h=" and 1 other dependency":h="",u.provided.range!=="missing:"){let E=t.storedResolutions.get(u.provided.descriptorHash);if(!E)throw new Error("Assertion failed: Expected the resolution to have been registered");let I=t.storedPackages.get(E);if(!I)throw new Error("Assertion failed: Expected the provided package to have been registered");let v=`${pe.pretty(t.configuration,u.hash,pe.Type.CODE)} \u2192 ${A?a.Cross:a.Check} ${G.prettyLocator(t.configuration,u.subject)} provides ${G.prettyLocator(t.configuration,I)} to ${G.prettyLocator(t.configuration,p[0].requester)}${h}`;A?o.reportWarning(0,v):o.reportInfo(0,v)}else{let E=`${pe.pretty(t.configuration,u.hash,pe.Type.CODE)} \u2192 ${A?a.Cross:a.Check} ${G.prettyLocator(t.configuration,u.subject)} doesn't provide ${G.prettyIdent(t.configuration,u.ident)} to ${G.prettyLocator(t.configuration,p[0].requester)}${h}`;A?o.reportWarning(0,E):o.reportInfo(0,E)}}})).exitCode()}Ge();qt();el();Ge();Ge();Pt();qt();var tde=Ze(Jn()),sE=class extends ut{constructor(){super(...arguments);this.useYarnPath=ge.Boolean("--yarn-path",{description:"Set the yarnPath setting even if the version can be accessed by Corepack"});this.onlyIfNeeded=ge.Boolean("--only-if-needed",!1,{description:"Only lock the Yarn version if it isn't already locked"});this.version=ge.String()}static{this.paths=[["set","version"]]}static{this.usage=it.Usage({description:"lock the Yarn version used by the project",details:"\n This command will set a specific release of Yarn to be used by Corepack: https://nodejs.org/api/corepack.html.\n\n By default it only will set the `packageManager` field at the root of your project, but if the referenced release cannot be represented this way, if you already have `yarnPath` configured, or if you set the `--yarn-path` command line flag, then the release will also be downloaded from the Yarn GitHub repository, stored inside your project, and referenced via the `yarnPath` settings from your project `.yarnrc.yml` file.\n\n A very good use case for this command is to enforce the version of Yarn used by any single member of your team inside the same project - by doing this you ensure that you have control over Yarn upgrades and downgrades (including on your deployment servers), and get rid of most of the headaches related to someone using a slightly different version and getting different behavior.\n\n The version specifier can be:\n\n - a tag:\n - `latest` / `berry` / `stable` -> the most recent stable berry (`>=2.0.0`) release\n - `canary` -> the most recent canary (release candidate) berry (`>=2.0.0`) release\n - `classic` -> the most recent classic (`^0.x || ^1.x`) release\n\n - a semver range (e.g. `2.x`) -> the most recent version satisfying the range (limited to berry releases)\n\n - a semver version (e.g. `2.4.1`, `1.22.1`)\n\n - a local file referenced through either a relative or absolute path\n\n - `self` -> the version used to invoke the command\n ",examples:[["Download the latest release from the Yarn repository","$0 set version latest"],["Download the latest canary release from the Yarn repository","$0 set version canary"],["Download the latest classic release from the Yarn repository","$0 set version classic"],["Download the most recent Yarn 3 build","$0 set version 3.x"],["Download a specific Yarn 2 build","$0 set version 2.0.0-rc.30"],["Switch back to a specific Yarn 1 release","$0 set version 1.22.1"],["Use a release from the local filesystem","$0 set version ./yarn.cjs"],["Use a release from a URL","$0 set version https://repo.yarnpkg.com/3.1.0/packages/yarnpkg-cli/bin/yarn.js"],["Download the version used to invoke the command","$0 set version self"]]})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins);if(this.onlyIfNeeded&&r.get("yarnPath")){let A=r.sources.get("yarnPath");if(!A)throw new Error("Assertion failed: Expected 'yarnPath' to have a source");let p=r.projectCwd??r.startingCwd;if(V.contains(p,A))return 0}let o=()=>{if(typeof nn>"u")throw new st("The --install flag can only be used without explicit version specifier from the Yarn CLI");return`file://${process.argv[1]}`},a,n=(A,p)=>({version:p,url:A.replace(/\{\}/g,p)});if(this.version==="self")a={url:o(),version:nn??"self"};else if(this.version==="latest"||this.version==="berry"||this.version==="stable")a=n("https://repo.yarnpkg.com/{}/packages/yarnpkg-cli/bin/yarn.js",await r2(r,"stable"));else if(this.version==="canary")a=n("https://repo.yarnpkg.com/{}/packages/yarnpkg-cli/bin/yarn.js",await r2(r,"canary"));else if(this.version==="classic")a={url:"https://classic.yarnpkg.com/latest.js",version:"classic"};else if(this.version.match(/^https?:/))a={url:this.version,version:"remote"};else if(this.version.match(/^\.{0,2}[\\/]/)||ue.isAbsolute(this.version))a={url:`file://${V.resolve(ue.toPortablePath(this.version))}`,version:"file"};else if(Lr.satisfiesWithPrereleases(this.version,">=2.0.0"))a=n("https://repo.yarnpkg.com/{}/packages/yarnpkg-cli/bin/yarn.js",this.version);else if(Lr.satisfiesWithPrereleases(this.version,"^0.x || ^1.x"))a=n("https://github.com/yarnpkg/yarn/releases/download/v{}/yarn-{}.js",this.version);else if(Lr.validRange(this.version))a=n("https://repo.yarnpkg.com/{}/packages/yarnpkg-cli/bin/yarn.js",await K0t(r,this.version));else throw new st(`Invalid version descriptor "${this.version}"`);return(await Rt.start({configuration:r,stdout:this.context.stdout,includeLogs:!this.context.quiet},async A=>{let p=async()=>{let h="file://";return a.url.startsWith(h)?(A.reportInfo(0,`Retrieving ${pe.pretty(r,a.url,pe.Type.PATH)}`),await oe.readFilePromise(a.url.slice(h.length))):(A.reportInfo(0,`Downloading ${pe.pretty(r,a.url,pe.Type.URL)}`),await sn.get(a.url,{configuration:r}))};await k8(r,a.version,p,{report:A,useYarnPath:this.useYarnPath})})).exitCode()}};async function K0t(t,e){let o=(await sn.get("https://repo.yarnpkg.com/tags",{configuration:t,jsonResponse:!0})).tags.filter(a=>Lr.satisfiesWithPrereleases(a,e));if(o.length===0)throw new st(`No matching release found for range ${pe.pretty(t,e,pe.Type.RANGE)}.`);return o[0]}async function r2(t,e){let r=await sn.get("https://repo.yarnpkg.com/tags",{configuration:t,jsonResponse:!0});if(!r.latest[e])throw new st(`Tag ${pe.pretty(t,e,pe.Type.RANGE)} not found`);return r.latest[e]}async function k8(t,e,r,{report:o,useYarnPath:a}){let n,u=async()=>(typeof n>"u"&&(n=await r()),n);if(e===null){let te=await u();await oe.mktempPromise(async ae=>{let le=V.join(ae,"yarn.cjs");await oe.writeFilePromise(le,te);let{stdout:ce}=await Ur.execvp(process.execPath,[ue.fromPortablePath(le),"--version"],{cwd:ae,env:{...t.env,YARN_IGNORE_PATH:"1"}});if(e=ce.trim(),!tde.default.valid(e))throw new Error(`Invalid semver version. ${pe.pretty(t,"yarn --version",pe.Type.CODE)} returned: +${e}`)})}let A=t.projectCwd??t.startingCwd,p=V.resolve(A,".yarn/releases"),h=V.resolve(p,`yarn-${e}.cjs`),E=V.relative(t.startingCwd,h),I=He.isTaggedYarnVersion(e),v=t.get("yarnPath"),x=!I,C=x||!!v||!!a;if(a===!1){if(x)throw new Jt(0,"You explicitly opted out of yarnPath usage in your command line, but the version you specified cannot be represented by Corepack");C=!1}else!C&&!process.env.COREPACK_ROOT&&(o.reportWarning(0,`You don't seem to have ${pe.applyHyperlink(t,"Corepack","https://nodejs.org/api/corepack.html")} enabled; we'll have to rely on ${pe.applyHyperlink(t,"yarnPath","https://yarnpkg.com/configuration/yarnrc#yarnPath")} instead`),C=!0);if(C){let te=await u();o.reportInfo(0,`Saving the new release in ${pe.pretty(t,E,"magenta")}`),await oe.removePromise(V.dirname(h)),await oe.mkdirPromise(V.dirname(h),{recursive:!0}),await oe.writeFilePromise(h,te,{mode:493}),await Ke.updateConfiguration(A,{yarnPath:V.relative(A,h)})}else await oe.removePromise(V.dirname(h)),await Ke.updateConfiguration(A,{yarnPath:Ke.deleteProperty});let R=await Ut.tryFind(A)||new Ut;R.packageManager=`yarn@${I?e:await r2(t,"stable")}`;let L={};R.exportTo(L);let U=V.join(A,Ut.fileName),z=`${JSON.stringify(L,null,R.indent)} +`;return await oe.changeFilePromise(U,z,{automaticNewlines:!0}),{bundleVersion:e}}function rde(t){return wr[ZD(t)]}var V0t=/## (?YN[0-9]{4}) - `(?[A-Z_]+)`\n\n(?

(?:.(?!##))+)/gs;async function z0t(t){let r=`https://repo.yarnpkg.com/${He.isTaggedYarnVersion(nn)?nn:await r2(t,"canary")}/packages/docusaurus/docs/advanced/01-general-reference/error-codes.mdx`,o=await sn.get(r,{configuration:t});return new Map(Array.from(o.toString().matchAll(V0t),({groups:a})=>{if(!a)throw new Error("Assertion failed: Expected the match to have been successful");let n=rde(a.code);if(a.name!==n)throw new Error(`Assertion failed: Invalid error code data: Expected "${a.name}" to be named "${n}"`);return[a.code,a.details]}))}var oE=class extends ut{constructor(){super(...arguments);this.code=ge.String({required:!1,validator:jw(om(),[qw(/^YN[0-9]{4}$/)])});this.json=ge.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"})}static{this.paths=[["explain"]]}static{this.usage=it.Usage({description:"explain an error code",details:` + When the code argument is specified, this command prints its name and its details. + + When used without arguments, this command lists all error codes and their names. + `,examples:[["Explain an error code","$0 explain YN0006"],["List all error codes","$0 explain"]]})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins);if(typeof this.code<"u"){let o=rde(this.code),a=pe.pretty(r,o,pe.Type.CODE),n=this.cli.format().header(`${this.code} - ${a}`),A=(await z0t(r)).get(this.code),p=typeof A<"u"?pe.jsonOrPretty(this.json,r,pe.tuple(pe.Type.MARKDOWN,{text:A,format:this.cli.format(),paragraphs:!0})):`This error code does not have a description. + +You can help us by editing this page on GitHub \u{1F642}: +${pe.jsonOrPretty(this.json,r,pe.tuple(pe.Type.URL,"https://github.com/yarnpkg/berry/blob/master/packages/docusaurus/docs/advanced/01-general-reference/error-codes.mdx"))} +`;this.json?this.context.stdout.write(`${JSON.stringify({code:this.code,name:o,details:p})} +`):this.context.stdout.write(`${n} + +${p} +`)}else{let o={children:He.mapAndFilter(Object.entries(wr),([a,n])=>Number.isNaN(Number(a))?He.mapAndFilter.skip:{label:Ku(Number(a)),value:pe.tuple(pe.Type.CODE,n)})};fs.emitTree(o,{configuration:r,stdout:this.context.stdout,json:this.json})}}};Ge();Pt();qt();var nde=Ze($o()),aE=class extends ut{constructor(){super(...arguments);this.all=ge.Boolean("-A,--all",!1,{description:"Print versions of a package from the whole project"});this.recursive=ge.Boolean("-R,--recursive",!1,{description:"Print information for all packages, including transitive dependencies"});this.extra=ge.Array("-X,--extra",[],{description:"An array of requests of extra data provided by plugins"});this.cache=ge.Boolean("--cache",!1,{description:"Print information about the cache entry of a package (path, size, checksum)"});this.dependents=ge.Boolean("--dependents",!1,{description:"Print all dependents for each matching package"});this.manifest=ge.Boolean("--manifest",!1,{description:"Print data obtained by looking at the package archive (license, homepage, ...)"});this.nameOnly=ge.Boolean("--name-only",!1,{description:"Only print the name for the matching packages"});this.virtuals=ge.Boolean("--virtuals",!1,{description:"Print each instance of the virtual packages"});this.json=ge.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.patterns=ge.Rest()}static{this.paths=[["info"]]}static{this.usage=it.Usage({description:"see information related to packages",details:"\n This command prints various information related to the specified packages, accepting glob patterns.\n\n By default, if the locator reference is missing, Yarn will default to print the information about all the matching direct dependencies of the package for the active workspace. To instead print all versions of the package that are direct dependencies of any of your workspaces, use the `-A,--all` flag. Adding the `-R,--recursive` flag will also report transitive dependencies.\n\n Some fields will be hidden by default in order to keep the output readable, but can be selectively displayed by using additional options (`--dependents`, `--manifest`, `--virtuals`, ...) described in the option descriptions.\n\n Note that this command will only print the information directly related to the selected packages - if you wish to know why the package is there in the first place, use `yarn why` which will do just that (it also provides a `-R,--recursive` flag that may be of some help).\n ",examples:[["Show information about Lodash","$0 info lodash"]]})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await kt.find(r,this.context.cwd),n=await Gr.find(r);if(!a&&!this.all)throw new sr(o.cwd,this.context.cwd);await o.restoreInstallState();let u=new Set(this.extra);this.cache&&u.add("cache"),this.dependents&&u.add("dependents"),this.manifest&&u.add("manifest");let A=(ae,{recursive:le})=>{let ce=ae.anchoredLocator.locatorHash,Ce=new Map,de=[ce];for(;de.length>0;){let Be=de.shift();if(Ce.has(Be))continue;let Ee=o.storedPackages.get(Be);if(typeof Ee>"u")throw new Error("Assertion failed: Expected the package to be registered");if(Ce.set(Be,Ee),G.isVirtualLocator(Ee)&&de.push(G.devirtualizeLocator(Ee).locatorHash),!(!le&&Be!==ce))for(let g of Ee.dependencies.values()){let me=o.storedResolutions.get(g.descriptorHash);if(typeof me>"u")throw new Error("Assertion failed: Expected the resolution to be registered");de.push(me)}}return Ce.values()},p=({recursive:ae})=>{let le=new Map;for(let ce of o.workspaces)for(let Ce of A(ce,{recursive:ae}))le.set(Ce.locatorHash,Ce);return le.values()},h=({all:ae,recursive:le})=>ae&&le?o.storedPackages.values():ae?p({recursive:le}):A(a,{recursive:le}),E=({all:ae,recursive:le})=>{let ce=h({all:ae,recursive:le}),Ce=this.patterns.map(Ee=>{let g=G.parseLocator(Ee),me=nde.default.makeRe(G.stringifyIdent(g)),we=G.isVirtualLocator(g),Ae=we?G.devirtualizeLocator(g):g;return ne=>{let Z=G.stringifyIdent(ne);if(!me.test(Z))return!1;if(g.reference==="unknown")return!0;let xe=G.isVirtualLocator(ne),Ne=xe?G.devirtualizeLocator(ne):ne;return!(we&&xe&&g.reference!==ne.reference||Ae.reference!==Ne.reference)}}),de=He.sortMap([...ce],Ee=>G.stringifyLocator(Ee));return{selection:de.filter(Ee=>Ce.length===0||Ce.some(g=>g(Ee))),sortedLookup:de}},{selection:I,sortedLookup:v}=E({all:this.all,recursive:this.recursive});if(I.length===0)throw new st("No package matched your request");let x=new Map;if(this.dependents)for(let ae of v)for(let le of ae.dependencies.values()){let ce=o.storedResolutions.get(le.descriptorHash);if(typeof ce>"u")throw new Error("Assertion failed: Expected the resolution to be registered");He.getArrayWithDefault(x,ce).push(ae)}let C=new Map;for(let ae of v){if(!G.isVirtualLocator(ae))continue;let le=G.devirtualizeLocator(ae);He.getArrayWithDefault(C,le.locatorHash).push(ae)}let R={},L={children:R},U=r.makeFetcher(),z={project:o,fetcher:U,cache:n,checksums:o.storedChecksums,report:new ki,cacheOptions:{skipIntegrityCheck:!0}},te=[async(ae,le,ce)=>{if(!le.has("manifest"))return;let Ce=await U.fetch(ae,z),de;try{de=await Ut.find(Ce.prefixPath,{baseFs:Ce.packageFs})}finally{Ce.releaseFs?.()}ce("Manifest",{License:pe.tuple(pe.Type.NO_HINT,de.license),Homepage:pe.tuple(pe.Type.URL,de.raw.homepage??null)})},async(ae,le,ce)=>{if(!le.has("cache"))return;let Ce=o.storedChecksums.get(ae.locatorHash)??null,de=n.getLocatorPath(ae,Ce),Be;if(de!==null)try{Be=await oe.statPromise(de)}catch{}let Ee=typeof Be<"u"?[Be.size,pe.Type.SIZE]:void 0;ce("Cache",{Checksum:pe.tuple(pe.Type.NO_HINT,Ce),Path:pe.tuple(pe.Type.PATH,de),Size:Ee})}];for(let ae of I){let le=G.isVirtualLocator(ae);if(!this.virtuals&&le)continue;let ce={},Ce={value:[ae,pe.Type.LOCATOR],children:ce};if(R[G.stringifyLocator(ae)]=Ce,this.nameOnly){delete Ce.children;continue}let de=C.get(ae.locatorHash);typeof de<"u"&&(ce.Instances={label:"Instances",value:pe.tuple(pe.Type.NUMBER,de.length)}),ce.Version={label:"Version",value:pe.tuple(pe.Type.NO_HINT,ae.version)};let Be=(g,me)=>{let we={};if(ce[g]=we,Array.isArray(me))we.children=me.map(Ae=>({value:Ae}));else{let Ae={};we.children=Ae;for(let[ne,Z]of Object.entries(me))typeof Z>"u"||(Ae[ne]={label:ne,value:Z})}};if(!le){for(let g of te)await g(ae,u,Be);await r.triggerHook(g=>g.fetchPackageInfo,ae,u,Be)}ae.bin.size>0&&!le&&Be("Exported Binaries",[...ae.bin.keys()].map(g=>pe.tuple(pe.Type.PATH,g)));let Ee=x.get(ae.locatorHash);typeof Ee<"u"&&Ee.length>0&&Be("Dependents",Ee.map(g=>pe.tuple(pe.Type.LOCATOR,g))),ae.dependencies.size>0&&!le&&Be("Dependencies",[...ae.dependencies.values()].map(g=>{let me=o.storedResolutions.get(g.descriptorHash),we=typeof me<"u"?o.storedPackages.get(me)??null:null;return pe.tuple(pe.Type.RESOLUTION,{descriptor:g,locator:we})})),ae.peerDependencies.size>0&&le&&Be("Peer dependencies",[...ae.peerDependencies.values()].map(g=>{let me=ae.dependencies.get(g.identHash),we=typeof me<"u"?o.storedResolutions.get(me.descriptorHash)??null:null,Ae=we!==null?o.storedPackages.get(we)??null:null;return pe.tuple(pe.Type.RESOLUTION,{descriptor:g,locator:Ae})}))}fs.emitTree(L,{configuration:r,json:this.json,stdout:this.context.stdout,separators:this.nameOnly?0:2})}};Ge();Pt();Nl();var nk=Ze(X0());qt();var Q8=Ze(Jn());el();var J0t=[{selector:t=>t===-1,name:"nodeLinker",value:"node-modules"},{selector:t=>t!==-1&&t<8,name:"enableGlobalCache",value:!1},{selector:t=>t!==-1&&t<8,name:"compressionLevel",value:"mixed"}],lE=class extends ut{constructor(){super(...arguments);this.json=ge.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.immutable=ge.Boolean("--immutable",{description:"Abort with an error exit code if the lockfile was to be modified"});this.immutableCache=ge.Boolean("--immutable-cache",{description:"Abort with an error exit code if the cache folder was to be modified"});this.refreshLockfile=ge.Boolean("--refresh-lockfile",{description:"Refresh the package metadata stored in the lockfile"});this.checkCache=ge.Boolean("--check-cache",{description:"Always refetch the packages and ensure that their checksums are consistent"});this.checkResolutions=ge.Boolean("--check-resolutions",{description:"Validates that the package resolutions are coherent"});this.inlineBuilds=ge.Boolean("--inline-builds",{description:"Verbosely print the output of the build steps of dependencies"});this.mode=ge.String("--mode",{description:"Change what artifacts installs generate",validator:Js(hl)});this.cacheFolder=ge.String("--cache-folder",{hidden:!0});this.frozenLockfile=ge.Boolean("--frozen-lockfile",{hidden:!0});this.ignoreEngines=ge.Boolean("--ignore-engines",{hidden:!0});this.nonInteractive=ge.Boolean("--non-interactive",{hidden:!0});this.preferOffline=ge.Boolean("--prefer-offline",{hidden:!0});this.production=ge.Boolean("--production",{hidden:!0});this.registry=ge.String("--registry",{hidden:!0});this.silent=ge.Boolean("--silent",{hidden:!0});this.networkTimeout=ge.String("--network-timeout",{hidden:!0})}static{this.paths=[["install"],it.Default]}static{this.usage=it.Usage({description:"install the project dependencies",details:"\n This command sets up your project if needed. The installation is split into four different steps that each have their own characteristics:\n\n - **Resolution:** First the package manager will resolve your dependencies. The exact way a dependency version is privileged over another isn't standardized outside of the regular semver guarantees. If a package doesn't resolve to what you would expect, check that all dependencies are correctly declared (also check our website for more information: ).\n\n - **Fetch:** Then we download all the dependencies if needed, and make sure that they're all stored within our cache (check the value of `cacheFolder` in `yarn config` to see where the cache files are stored).\n\n - **Link:** Then we send the dependency tree information to internal plugins tasked with writing them on the disk in some form (for example by generating the `.pnp.cjs` file you might know).\n\n - **Build:** Once the dependency tree has been written on the disk, the package manager will now be free to run the build scripts for all packages that might need it, in a topological order compatible with the way they depend on one another. See https://yarnpkg.com/advanced/lifecycle-scripts for detail.\n\n Note that running this command is not part of the recommended workflow. Yarn supports zero-installs, which means that as long as you store your cache and your `.pnp.cjs` file inside your repository, everything will work without requiring any install right after cloning your repository or switching branches.\n\n If the `--immutable` option is set (defaults to true on CI), Yarn will abort with an error exit code if the lockfile was to be modified (other paths can be added using the `immutablePatterns` configuration setting). For backward compatibility we offer an alias under the name of `--frozen-lockfile`, but it will be removed in a later release.\n\n If the `--immutable-cache` option is set, Yarn will abort with an error exit code if the cache folder was to be modified (either because files would be added, or because they'd be removed).\n\n If the `--refresh-lockfile` option is set, Yarn will keep the same resolution for the packages currently in the lockfile but will refresh their metadata. If used together with `--immutable`, it can validate that the lockfile information are consistent. This flag is enabled by default when Yarn detects it runs within a pull request context.\n\n If the `--check-cache` option is set, Yarn will always refetch the packages and will ensure that their checksum matches what's 1/ described in the lockfile 2/ inside the existing cache files (if present). This is recommended as part of your CI workflow if you're both following the Zero-Installs model and accepting PRs from third-parties, as they'd otherwise have the ability to alter the checked-in packages before submitting them.\n\n If the `--inline-builds` option is set, Yarn will verbosely print the output of the build steps of your dependencies (instead of writing them into individual files). This is likely useful mostly for debug purposes only when using Docker-like environments.\n\n If the `--mode=` option is set, Yarn will change which artifacts are generated. The modes currently supported are:\n\n - `skip-build` will not run the build scripts at all. Note that this is different from setting `enableScripts` to false because the latter will disable build scripts, and thus affect the content of the artifacts generated on disk, whereas the former will just disable the build step - but not the scripts themselves, which just won't run.\n\n - `update-lockfile` will skip the link step altogether, and only fetch packages that are missing from the lockfile (or that have no associated checksums). This mode is typically used by tools like Renovate or Dependabot to keep a lockfile up-to-date without incurring the full install cost.\n ",examples:[["Install the project","$0 install"],["Validate a project when using Zero-Installs","$0 install --immutable --immutable-cache"],["Validate a project when using Zero-Installs (slightly safer if you accept external PRs)","$0 install --immutable --immutable-cache --check-cache"]]})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins);typeof this.inlineBuilds<"u"&&r.useWithSource("",{enableInlineBuilds:this.inlineBuilds},r.startingCwd,{overwrite:!0});let o=!!process.env.FUNCTION_TARGET||!!process.env.GOOGLE_RUNTIME,a=await uy({configuration:r,stdout:this.context.stdout},[{option:this.ignoreEngines,message:"The --ignore-engines option is deprecated; engine checking isn't a core feature anymore",error:!nk.default.VERCEL},{option:this.registry,message:"The --registry option is deprecated; prefer setting npmRegistryServer in your .yarnrc.yml file"},{option:this.preferOffline,message:"The --prefer-offline flag is deprecated; use the --cached flag with 'yarn add' instead",error:!nk.default.VERCEL},{option:this.production,message:"The --production option is deprecated on 'install'; use 'yarn workspaces focus' instead",error:!0},{option:this.nonInteractive,message:"The --non-interactive option is deprecated",error:!o},{option:this.frozenLockfile,message:"The --frozen-lockfile option is deprecated; use --immutable and/or --immutable-cache instead",callback:()=>this.immutable=this.frozenLockfile},{option:this.cacheFolder,message:"The cache-folder option has been deprecated; use rc settings instead",error:!nk.default.NETLIFY}]);if(a!==null)return a;let n=this.mode==="update-lockfile";if(n&&(this.immutable||this.immutableCache))throw new st(`${pe.pretty(r,"--immutable",pe.Type.CODE)} and ${pe.pretty(r,"--immutable-cache",pe.Type.CODE)} cannot be used with ${pe.pretty(r,"--mode=update-lockfile",pe.Type.CODE)}`);let u=(this.immutable??r.get("enableImmutableInstalls"))&&!n,A=this.immutableCache&&!n;if(r.projectCwd!==null){let R=await Rt.start({configuration:r,json:this.json,stdout:this.context.stdout,includeFooter:!1},async L=>{let U=!1;await $0t(r,u)&&(L.reportInfo(48,"Automatically removed core plugins that are now builtins \u{1F44D}"),U=!0),await Z0t(r,u)&&(L.reportInfo(48,"Automatically fixed merge conflicts \u{1F44D}"),U=!0),U&&L.reportSeparator()});if(R.hasErrors())return R.exitCode()}if(r.projectCwd!==null){let R=await Rt.start({configuration:r,json:this.json,stdout:this.context.stdout,includeFooter:!1},async L=>{if(Ke.telemetry?.isNew)Ke.telemetry.commitTips(),L.reportInfo(65,"Yarn will periodically gather anonymous telemetry: https://yarnpkg.com/advanced/telemetry"),L.reportInfo(65,`Run ${pe.pretty(r,"yarn config set --home enableTelemetry 0",pe.Type.CODE)} to disable`),L.reportSeparator();else if(Ke.telemetry?.shouldShowTips){let U=await sn.get("https://repo.yarnpkg.com/tags",{configuration:r,jsonResponse:!0}).catch(()=>null);if(U!==null){let z=null;if(nn!==null){let ae=Q8.default.prerelease(nn)?"canary":"stable",le=U.latest[ae];Q8.default.gt(le,nn)&&(z=[ae,le])}if(z)Ke.telemetry.commitTips(),L.reportInfo(88,`${pe.applyStyle(r,`A new ${z[0]} version of Yarn is available:`,pe.Style.BOLD)} ${G.prettyReference(r,z[1])}!`),L.reportInfo(88,`Upgrade now by running ${pe.pretty(r,`yarn set version ${z[1]}`,pe.Type.CODE)}`),L.reportSeparator();else{let te=Ke.telemetry.selectTip(U.tips);te&&(L.reportInfo(89,pe.pretty(r,te.message,pe.Type.MARKDOWN_INLINE)),te.url&&L.reportInfo(89,`Learn more at ${te.url}`),L.reportSeparator())}}}});if(R.hasErrors())return R.exitCode()}let{project:p,workspace:h}=await kt.find(r,this.context.cwd),E=p.lockfileLastVersion;if(E!==null){let R=await Rt.start({configuration:r,json:this.json,stdout:this.context.stdout,includeFooter:!1},async L=>{let U={};for(let z of J0t)z.selector(E)&&typeof r.sources.get(z.name)>"u"&&(r.use("",{[z.name]:z.value},p.cwd,{overwrite:!0}),U[z.name]=z.value);Object.keys(U).length>0&&(await Ke.updateConfiguration(p.cwd,U),L.reportInfo(87,"Migrated your project to the latest Yarn version \u{1F680}"),L.reportSeparator())});if(R.hasErrors())return R.exitCode()}let I=await Gr.find(r,{immutable:A,check:this.checkCache});if(!h)throw new sr(p.cwd,this.context.cwd);await p.restoreInstallState({restoreResolutions:!1});let v=r.get("enableHardenedMode");v&&typeof r.sources.get("enableHardenedMode")>"u"&&await Rt.start({configuration:r,json:this.json,stdout:this.context.stdout,includeFooter:!1},async R=>{R.reportWarning(0,"Yarn detected that the current workflow is executed from a public pull request. For safety the hardened mode has been enabled."),R.reportWarning(0,`It will prevent malicious lockfile manipulations, in exchange for a slower install time. You can opt-out if necessary; check our ${pe.applyHyperlink(r,"documentation","https://yarnpkg.com/features/security#hardened-mode")} for more details.`),R.reportSeparator()}),(this.refreshLockfile??v)&&(p.lockfileNeedsRefresh=!0);let x=this.checkResolutions??v;return(await Rt.start({configuration:r,json:this.json,stdout:this.context.stdout,forceSectionAlignment:!0,includeLogs:!0,includeVersion:!0},async R=>{await p.install({cache:I,report:R,immutable:u,checkResolutions:x,mode:this.mode})})).exitCode()}},X0t="<<<<<<<";async function Z0t(t,e){if(!t.projectCwd)return!1;let r=V.join(t.projectCwd,dr.lockfile);if(!await oe.existsPromise(r)||!(await oe.readFilePromise(r,"utf8")).includes(X0t))return!1;if(e)throw new Jt(47,"Cannot autofix a lockfile when running an immutable install");let a=await Ur.execvp("git",["rev-parse","MERGE_HEAD","HEAD"],{cwd:t.projectCwd});if(a.code!==0&&(a=await Ur.execvp("git",["rev-parse","REBASE_HEAD","HEAD"],{cwd:t.projectCwd})),a.code!==0&&(a=await Ur.execvp("git",["rev-parse","CHERRY_PICK_HEAD","HEAD"],{cwd:t.projectCwd})),a.code!==0)throw new Jt(83,"Git returned an error when trying to find the commits pertaining to the conflict");let n=await Promise.all(a.stdout.trim().split(/\n/).map(async A=>{let p=await Ur.execvp("git",["show",`${A}:./${dr.lockfile}`],{cwd:t.projectCwd});if(p.code!==0)throw new Jt(83,`Git returned an error when trying to access the lockfile content in ${A}`);try{return Ki(p.stdout)}catch{throw new Jt(46,"A variant of the conflicting lockfile failed to parse")}}));n=n.filter(A=>!!A.__metadata);for(let A of n){if(A.__metadata.version<7)for(let p of Object.keys(A)){if(p==="__metadata")continue;let h=G.parseDescriptor(p,!0),E=t.normalizeDependency(h),I=G.stringifyDescriptor(E);I!==p&&(A[I]=A[p],delete A[p])}for(let p of Object.keys(A)){if(p==="__metadata")continue;let h=A[p].checksum;typeof h=="string"&&h.includes("/")||(A[p].checksum=`${A.__metadata.cacheKey}/${h}`)}}let u=Object.assign({},...n);u.__metadata.version=`${Math.min(...n.map(A=>parseInt(A.__metadata.version??0)))}`,u.__metadata.cacheKey="merged";for(let[A,p]of Object.entries(u))typeof p=="string"&&delete u[A];return await oe.changeFilePromise(r,Da(u),{automaticNewlines:!0}),!0}async function $0t(t,e){if(!t.projectCwd)return!1;let r=[],o=V.join(t.projectCwd,".yarn/plugins/@yarnpkg");return await Ke.updateConfiguration(t.projectCwd,{plugins:n=>{if(!Array.isArray(n))return n;let u=n.filter(A=>{if(!A.path)return!0;let p=V.resolve(t.projectCwd,A.path),h=l1.has(A.spec)&&V.contains(o,p);return h&&r.push(p),!h});return u.length===0?Ke.deleteProperty:u.length===n.length?n:u}},{immutable:e})?(await Promise.all(r.map(async n=>{await oe.removePromise(n)})),!0):!1}Ge();Pt();qt();var cE=class extends ut{constructor(){super(...arguments);this.all=ge.Boolean("-A,--all",!1,{description:"Link all workspaces belonging to the target projects to the current one"});this.private=ge.Boolean("-p,--private",!1,{description:"Also link private workspaces belonging to the target projects to the current one"});this.relative=ge.Boolean("-r,--relative",!1,{description:"Link workspaces using relative paths instead of absolute paths"});this.destinations=ge.Rest()}static{this.paths=[["link"]]}static{this.usage=it.Usage({description:"connect the local project to another one",details:"\n This command will set a new `resolutions` field in the project-level manifest and point it to the workspace at the specified location (even if part of another project).\n ",examples:[["Register one or more remote workspaces for use in the current project","$0 link ~/ts-loader ~/jest"],["Register all workspaces from a remote project for use in the current project","$0 link ~/jest --all"]]})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await kt.find(r,this.context.cwd),n=await Gr.find(r);if(!a)throw new sr(o.cwd,this.context.cwd);await o.restoreInstallState({restoreResolutions:!1});let u=o.topLevelWorkspace,A=[];for(let p of this.destinations){let h=V.resolve(this.context.cwd,ue.toPortablePath(p)),E=await Ke.find(h,this.context.plugins,{useRc:!1,strict:!1}),{project:I,workspace:v}=await kt.find(E,h);if(o.cwd===I.cwd)throw new st(`Invalid destination '${p}'; Can't link the project to itself`);if(!v)throw new sr(I.cwd,h);if(this.all){let x=!1;for(let C of I.workspaces)C.manifest.name&&(!C.manifest.private||this.private)&&(A.push(C),x=!0);if(!x)throw new st(`No workspace found to be linked in the target project: ${p}`)}else{if(!v.manifest.name)throw new st(`The target workspace at '${p}' doesn't have a name and thus cannot be linked`);if(v.manifest.private&&!this.private)throw new st(`The target workspace at '${p}' is marked private - use the --private flag to link it anyway`);A.push(v)}}for(let p of A){let h=G.stringifyIdent(p.anchoredLocator),E=this.relative?V.relative(o.cwd,p.cwd):p.cwd;u.manifest.resolutions.push({pattern:{descriptor:{fullName:h}},reference:`portal:${E}`})}return await o.installWithNewReport({stdout:this.context.stdout},{cache:n})}};qt();var uE=class extends ut{constructor(){super(...arguments);this.args=ge.Proxy()}static{this.paths=[["node"]]}static{this.usage=it.Usage({description:"run node with the hook already setup",details:` + This command simply runs Node. It also makes sure to call it in a way that's compatible with the current project (for example, on PnP projects the environment will be setup in such a way that PnP will be correctly injected into the environment). + + The Node process will use the exact same version of Node as the one used to run Yarn itself, which might be a good way to ensure that your commands always use a consistent Node version. + `,examples:[["Run a Node script","$0 node ./my-script.js"]]})}async execute(){return this.cli.run(["exec","node",...this.args])}};Ge();qt();var AE=class extends ut{constructor(){super(...arguments);this.json=ge.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"})}static{this.paths=[["plugin","check"]]}static{this.usage=it.Usage({category:"Plugin-related commands",description:"find all third-party plugins that differ from their own spec",details:` + Check only the plugins from https. + + If this command detects any plugin differences in the CI environment, it will throw an error. + `,examples:[["find all third-party plugins that differ from their own spec","$0 plugin check"]]})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins),o=await Ke.findRcFiles(this.context.cwd);return(await Rt.start({configuration:r,json:this.json,stdout:this.context.stdout},async n=>{for(let u of o)if(u.data?.plugins)for(let A of u.data.plugins){if(!A.checksum||!A.spec.match(/^https?:/))continue;let p=await sn.get(A.spec,{configuration:r}),h=wn.makeHash(p);if(A.checksum===h)continue;let E=pe.pretty(r,A.path,pe.Type.PATH),I=pe.pretty(r,A.spec,pe.Type.URL),v=`${E} is different from the file provided by ${I}`;n.reportJson({...A,newChecksum:h}),n.reportError(0,v)}})).exitCode()}};Ge();Ge();Pt();qt();var lde=ve("os");Ge();Pt();qt();var ide=ve("os");Ge();Nl();qt();var egt="https://raw.githubusercontent.com/yarnpkg/berry/master/plugins.yml";async function Hg(t,e){let r=await sn.get(egt,{configuration:t}),o=Ki(r.toString());return Object.fromEntries(Object.entries(o).filter(([a,n])=>!e||Lr.satisfiesWithPrereleases(e,n.range??"<4.0.0-rc.1")))}var fE=class extends ut{constructor(){super(...arguments);this.json=ge.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"})}static{this.paths=[["plugin","list"]]}static{this.usage=it.Usage({category:"Plugin-related commands",description:"list the available official plugins",details:"\n This command prints the plugins available directly from the Yarn repository. Only those plugins can be referenced by name in `yarn plugin import`.\n ",examples:[["List the official plugins","$0 plugin list"]]})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins);return(await Rt.start({configuration:r,json:this.json,stdout:this.context.stdout},async a=>{let n=await Hg(r,nn);for(let[u,{experimental:A,...p}]of Object.entries(n)){let h=u;A&&(h+=" [experimental]"),a.reportJson({name:u,experimental:A,...p}),a.reportInfo(null,h)}})).exitCode()}};var tgt=/^[0-9]+$/,rgt=process.platform==="win32";function sde(t){return tgt.test(t)?`pull/${t}/head`:t}var ngt=({repository:t,branch:e},r)=>[["git","init",ue.fromPortablePath(r)],["git","remote","add","origin",t],["git","fetch","origin","--depth=1",sde(e)],["git","reset","--hard","FETCH_HEAD"]],igt=({branch:t})=>[["git","fetch","origin","--depth=1",sde(t),"--force"],["git","reset","--hard","FETCH_HEAD"],["git","clean","-dfx","-e","packages/yarnpkg-cli/bundles"]],sgt=({plugins:t,noMinify:e},r,o)=>[["yarn","build:cli",...new Array().concat(...t.map(a=>["--plugin",V.resolve(o,a)])),...e?["--no-minify"]:[],"|"],[rgt?"move":"mv","packages/yarnpkg-cli/bundles/yarn.js",ue.fromPortablePath(r),"|"]],pE=class extends ut{constructor(){super(...arguments);this.installPath=ge.String("--path",{description:"The path where the repository should be cloned to"});this.repository=ge.String("--repository","https://github.com/yarnpkg/berry.git",{description:"The repository that should be cloned"});this.branch=ge.String("--branch","master",{description:"The branch of the repository that should be cloned"});this.plugins=ge.Array("--plugin",[],{description:"An array of additional plugins that should be included in the bundle"});this.dryRun=ge.Boolean("-n,--dry-run",!1,{description:"If set, the bundle will be built but not added to the project"});this.noMinify=ge.Boolean("--no-minify",!1,{description:"Build a bundle for development (debugging) - non-minified and non-mangled"});this.force=ge.Boolean("-f,--force",!1,{description:"Always clone the repository instead of trying to fetch the latest commits"});this.skipPlugins=ge.Boolean("--skip-plugins",!1,{description:"Skip updating the contrib plugins"})}static{this.paths=[["set","version","from","sources"]]}static{this.usage=it.Usage({description:"build Yarn from master",details:` + This command will clone the Yarn repository into a temporary folder, then build it. The resulting bundle will then be copied into the local project. + + By default, it also updates all contrib plugins to the same commit the bundle is built from. This behavior can be disabled by using the \`--skip-plugins\` flag. + `,examples:[["Build Yarn from master","$0 set version from sources"]]})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins),{project:o}=await kt.find(r,this.context.cwd),a=typeof this.installPath<"u"?V.resolve(this.context.cwd,ue.toPortablePath(this.installPath)):V.resolve(ue.toPortablePath((0,ide.tmpdir)()),"yarnpkg-sources",wn.makeHash(this.repository).slice(0,6));return(await Rt.start({configuration:r,stdout:this.context.stdout},async u=>{await F8(this,{configuration:r,report:u,target:a}),u.reportSeparator(),u.reportInfo(0,"Building a fresh bundle"),u.reportSeparator();let A=await Ur.execvp("git",["rev-parse","--short","HEAD"],{cwd:a,strict:!0}),p=V.join(a,`packages/yarnpkg-cli/bundles/yarn-${A.stdout.trim()}.js`);oe.existsSync(p)||(await n2(sgt(this,p,a),{configuration:r,context:this.context,target:a}),u.reportSeparator());let h=await oe.readFilePromise(p);if(!this.dryRun){let{bundleVersion:E}=await k8(r,null,async()=>h,{report:u});this.skipPlugins||await ogt(this,E,{project:o,report:u,target:a})}})).exitCode()}};async function n2(t,{configuration:e,context:r,target:o}){for(let[a,...n]of t){let u=n[n.length-1]==="|";if(u&&n.pop(),u)await Ur.pipevp(a,n,{cwd:o,stdin:r.stdin,stdout:r.stdout,stderr:r.stderr,strict:!0});else{r.stdout.write(`${pe.pretty(e,` $ ${[a,...n].join(" ")}`,"grey")} +`);try{await Ur.execvp(a,n,{cwd:o,strict:!0})}catch(A){throw r.stdout.write(A.stdout||A.stack),A}}}}async function F8(t,{configuration:e,report:r,target:o}){let a=!1;if(!t.force&&oe.existsSync(V.join(o,".git"))){r.reportInfo(0,"Fetching the latest commits"),r.reportSeparator();try{await n2(igt(t),{configuration:e,context:t.context,target:o}),a=!0}catch{r.reportSeparator(),r.reportWarning(0,"Repository update failed; we'll try to regenerate it")}}a||(r.reportInfo(0,"Cloning the remote repository"),r.reportSeparator(),await oe.removePromise(o),await oe.mkdirPromise(o,{recursive:!0}),await n2(ngt(t,o),{configuration:e,context:t.context,target:o}))}async function ogt(t,e,{project:r,report:o,target:a}){let n=await Hg(r.configuration,e),u=new Set(Object.keys(n));for(let A of r.configuration.plugins.keys())u.has(A)&&await R8(A,t,{project:r,report:o,target:a})}Ge();Ge();Pt();qt();var ode=Ze(Jn()),ade=ve("vm");var hE=class extends ut{constructor(){super(...arguments);this.name=ge.String();this.checksum=ge.Boolean("--checksum",!0,{description:"Whether to care if this plugin is modified"})}static{this.paths=[["plugin","import"]]}static{this.usage=it.Usage({category:"Plugin-related commands",description:"download a plugin",details:` + This command downloads the specified plugin from its remote location and updates the configuration to reference it in further CLI invocations. + + Three types of plugin references are accepted: + + - If the plugin is stored within the Yarn repository, it can be referenced by name. + - Third-party plugins can be referenced directly through their public urls. + - Local plugins can be referenced by their path on the disk. + + If the \`--no-checksum\` option is set, Yarn will no longer care if the plugin is modified. + + Plugins cannot be downloaded from the npm registry, and aren't allowed to have dependencies (they need to be bundled into a single file, possibly thanks to the \`@yarnpkg/builder\` package). + `,examples:[['Download and activate the "@yarnpkg/plugin-exec" plugin',"$0 plugin import @yarnpkg/plugin-exec"],['Download and activate the "@yarnpkg/plugin-exec" plugin (shorthand)',"$0 plugin import exec"],["Download and activate a community plugin","$0 plugin import https://example.org/path/to/plugin.js"],["Activate a local plugin","$0 plugin import ./path/to/plugin.js"]]})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins);return(await Rt.start({configuration:r,stdout:this.context.stdout},async a=>{let{project:n}=await kt.find(r,this.context.cwd),u,A;if(this.name.match(/^\.{0,2}[\\/]/)||ue.isAbsolute(this.name)){let p=V.resolve(this.context.cwd,ue.toPortablePath(this.name));a.reportInfo(0,`Reading ${pe.pretty(r,p,pe.Type.PATH)}`),u=V.relative(n.cwd,p),A=await oe.readFilePromise(p)}else{let p;if(this.name.match(/^https?:/)){try{new URL(this.name)}catch{throw new Jt(52,`Plugin specifier "${this.name}" is neither a plugin name nor a valid url`)}u=this.name,p=this.name}else{let h=G.parseLocator(this.name.replace(/^((@yarnpkg\/)?plugin-)?/,"@yarnpkg/plugin-"));if(h.reference!=="unknown"&&!ode.default.valid(h.reference))throw new Jt(0,"Official plugins only accept strict version references. Use an explicit URL if you wish to download them from another location.");let E=G.stringifyIdent(h),I=await Hg(r,nn);if(!Object.hasOwn(I,E)){let v=`Couldn't find a plugin named ${G.prettyIdent(r,h)} on the remote registry. +`;throw r.plugins.has(E)?v+=`A plugin named ${G.prettyIdent(r,h)} is already installed; possibly attempting to import a built-in plugin.`:v+=`Note that only the plugins referenced on our website (${pe.pretty(r,"https://github.com/yarnpkg/berry/blob/master/plugins.yml",pe.Type.URL)}) can be referenced by their name; any other plugin will have to be referenced through its public url (for example ${pe.pretty(r,"https://github.com/yarnpkg/berry/raw/master/packages/plugin-typescript/bin/%40yarnpkg/plugin-typescript.js",pe.Type.URL)}).`,new Jt(51,v)}u=E,p=I[E].url,h.reference!=="unknown"?p=p.replace(/\/master\//,`/${E}/${h.reference}/`):nn!==null&&(p=p.replace(/\/master\//,`/@yarnpkg/cli/${nn}/`))}a.reportInfo(0,`Downloading ${pe.pretty(r,p,"green")}`),A=await sn.get(p,{configuration:r})}await T8(u,A,{checksum:this.checksum,project:n,report:a})})).exitCode()}};async function T8(t,e,{checksum:r=!0,project:o,report:a}){let{configuration:n}=o,u={},A={exports:u};(0,ade.runInNewContext)(e.toString(),{module:A,exports:u});let h=`.yarn/plugins/${A.exports.name}.cjs`,E=V.resolve(o.cwd,h);a.reportInfo(0,`Saving the new plugin in ${pe.pretty(n,h,"magenta")}`),await oe.mkdirPromise(V.dirname(E),{recursive:!0}),await oe.writeFilePromise(E,e);let I={path:h,spec:t};r&&(I.checksum=wn.makeHash(e)),await Ke.addPlugin(o.cwd,[I])}var agt=({pluginName:t,noMinify:e},r)=>[["yarn",`build:${t}`,...e?["--no-minify"]:[],"|"]],gE=class extends ut{constructor(){super(...arguments);this.installPath=ge.String("--path",{description:"The path where the repository should be cloned to"});this.repository=ge.String("--repository","https://github.com/yarnpkg/berry.git",{description:"The repository that should be cloned"});this.branch=ge.String("--branch","master",{description:"The branch of the repository that should be cloned"});this.noMinify=ge.Boolean("--no-minify",!1,{description:"Build a plugin for development (debugging) - non-minified and non-mangled"});this.force=ge.Boolean("-f,--force",!1,{description:"Always clone the repository instead of trying to fetch the latest commits"});this.name=ge.String()}static{this.paths=[["plugin","import","from","sources"]]}static{this.usage=it.Usage({category:"Plugin-related commands",description:"build a plugin from sources",details:` + This command clones the Yarn repository into a temporary folder, builds the specified contrib plugin and updates the configuration to reference it in further CLI invocations. + + The plugins can be referenced by their short name if sourced from the official Yarn repository. + `,examples:[['Build and activate the "@yarnpkg/plugin-exec" plugin',"$0 plugin import from sources @yarnpkg/plugin-exec"],['Build and activate the "@yarnpkg/plugin-exec" plugin (shorthand)',"$0 plugin import from sources exec"]]})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins),o=typeof this.installPath<"u"?V.resolve(this.context.cwd,ue.toPortablePath(this.installPath)):V.resolve(ue.toPortablePath((0,lde.tmpdir)()),"yarnpkg-sources",wn.makeHash(this.repository).slice(0,6));return(await Rt.start({configuration:r,stdout:this.context.stdout},async n=>{let{project:u}=await kt.find(r,this.context.cwd),A=G.parseIdent(this.name.replace(/^((@yarnpkg\/)?plugin-)?/,"@yarnpkg/plugin-")),p=G.stringifyIdent(A),h=await Hg(r,nn);if(!Object.hasOwn(h,p))throw new Jt(51,`Couldn't find a plugin named "${p}" on the remote registry. Note that only the plugins referenced on our website (https://github.com/yarnpkg/berry/blob/master/plugins.yml) can be built and imported from sources.`);let E=p;await F8(this,{configuration:r,report:n,target:o}),await R8(E,this,{project:u,report:n,target:o})})).exitCode()}};async function R8(t,{context:e,noMinify:r},{project:o,report:a,target:n}){let u=t.replace(/@yarnpkg\//,""),{configuration:A}=o;a.reportSeparator(),a.reportInfo(0,`Building a fresh ${u}`),a.reportSeparator(),await n2(agt({pluginName:u,noMinify:r},n),{configuration:A,context:e,target:n}),a.reportSeparator();let p=V.resolve(n,`packages/${u}/bundles/${t}.js`),h=await oe.readFilePromise(p);await T8(t,h,{project:o,report:a})}Ge();Pt();qt();var dE=class extends ut{constructor(){super(...arguments);this.name=ge.String()}static{this.paths=[["plugin","remove"]]}static{this.usage=it.Usage({category:"Plugin-related commands",description:"remove a plugin",details:` + This command deletes the specified plugin from the .yarn/plugins folder and removes it from the configuration. + + **Note:** The plugins have to be referenced by their name property, which can be obtained using the \`yarn plugin runtime\` command. Shorthands are not allowed. + `,examples:[["Remove a plugin imported from the Yarn repository","$0 plugin remove @yarnpkg/plugin-typescript"],["Remove a plugin imported from a local file","$0 plugin remove my-local-plugin"]]})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins),{project:o}=await kt.find(r,this.context.cwd);return(await Rt.start({configuration:r,stdout:this.context.stdout},async n=>{let u=this.name,A=G.parseIdent(u);if(!r.plugins.has(u))throw new st(`${G.prettyIdent(r,A)} isn't referenced by the current configuration`);let p=`.yarn/plugins/${u}.cjs`,h=V.resolve(o.cwd,p);oe.existsSync(h)&&(n.reportInfo(0,`Removing ${pe.pretty(r,p,pe.Type.PATH)}...`),await oe.removePromise(h)),n.reportInfo(0,"Updating the configuration..."),await Ke.updateConfiguration(o.cwd,{plugins:E=>{if(!Array.isArray(E))return E;let I=E.filter(v=>v.path!==p);return I.length===0?Ke.deleteProperty:I.length===E.length?E:I}})})).exitCode()}};Ge();qt();var mE=class extends ut{constructor(){super(...arguments);this.json=ge.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"})}static{this.paths=[["plugin","runtime"]]}static{this.usage=it.Usage({category:"Plugin-related commands",description:"list the active plugins",details:` + This command prints the currently active plugins. Will be displayed both builtin plugins and external plugins. + `,examples:[["List the currently active plugins","$0 plugin runtime"]]})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins);return(await Rt.start({configuration:r,json:this.json,stdout:this.context.stdout},async a=>{for(let n of r.plugins.keys()){let u=this.context.plugins.plugins.has(n),A=n;u&&(A+=" [builtin]"),a.reportJson({name:n,builtin:u}),a.reportInfo(null,`${A}`)}})).exitCode()}};Ge();Ge();qt();var yE=class extends ut{constructor(){super(...arguments);this.idents=ge.Rest()}static{this.paths=[["rebuild"]]}static{this.usage=it.Usage({description:"rebuild the project's native packages",details:` + This command will automatically cause Yarn to forget about previous compilations of the given packages and to run them again. + + Note that while Yarn forgets the compilation, the previous artifacts aren't erased from the filesystem and may affect the next builds (in good or bad). To avoid this, you may remove the .yarn/unplugged folder, or any other relevant location where packages might have been stored (Yarn may offer a way to do that automatically in the future). + + By default all packages will be rebuilt, but you can filter the list by specifying the names of the packages you want to clear from memory. + `,examples:[["Rebuild all packages","$0 rebuild"],["Rebuild fsevents only","$0 rebuild fsevents"]]})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await kt.find(r,this.context.cwd),n=await Gr.find(r);if(!a)throw new sr(o.cwd,this.context.cwd);let u=new Set;for(let A of this.idents)u.add(G.parseIdent(A).identHash);if(await o.restoreInstallState({restoreResolutions:!1}),await o.resolveEverything({cache:n,report:new ki}),u.size>0)for(let A of o.storedPackages.values())u.has(A.identHash)&&(o.storedBuildState.delete(A.locatorHash),o.skippedBuilds.delete(A.locatorHash));else o.storedBuildState.clear(),o.skippedBuilds.clear();return await o.installWithNewReport({stdout:this.context.stdout,quiet:this.context.quiet},{cache:n})}};Ge();Ge();Ge();qt();var N8=Ze($o());el();var EE=class extends ut{constructor(){super(...arguments);this.all=ge.Boolean("-A,--all",!1,{description:"Apply the operation to all workspaces from the current project"});this.mode=ge.String("--mode",{description:"Change what artifacts installs generate",validator:Js(hl)});this.patterns=ge.Rest()}static{this.paths=[["remove"]]}static{this.usage=it.Usage({description:"remove dependencies from the project",details:` + This command will remove the packages matching the specified patterns from the current workspace. + + If the \`--mode=\` option is set, Yarn will change which artifacts are generated. The modes currently supported are: + + - \`skip-build\` will not run the build scripts at all. Note that this is different from setting \`enableScripts\` to false because the latter will disable build scripts, and thus affect the content of the artifacts generated on disk, whereas the former will just disable the build step - but not the scripts themselves, which just won't run. + + - \`update-lockfile\` will skip the link step altogether, and only fetch packages that are missing from the lockfile (or that have no associated checksums). This mode is typically used by tools like Renovate or Dependabot to keep a lockfile up-to-date without incurring the full install cost. + + This command accepts glob patterns as arguments (if valid Idents and supported by [micromatch](https://github.com/micromatch/micromatch)). Make sure to escape the patterns, to prevent your own shell from trying to expand them. + `,examples:[["Remove a dependency from the current project","$0 remove lodash"],["Remove a dependency from all workspaces at once","$0 remove lodash --all"],["Remove all dependencies starting with `eslint-`","$0 remove 'eslint-*'"],["Remove all dependencies with the `@babel` scope","$0 remove '@babel/*'"],["Remove all dependencies matching `react-dom` or `react-helmet`","$0 remove 'react-{dom,helmet}'"]]})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await kt.find(r,this.context.cwd),n=await Gr.find(r);if(!a)throw new sr(o.cwd,this.context.cwd);await o.restoreInstallState({restoreResolutions:!1});let u=this.all?o.workspaces:[a],A=["dependencies","devDependencies","peerDependencies"],p=[],h=!1,E=[];for(let C of this.patterns){let R=!1,L=G.parseIdent(C);for(let U of u){let z=[...U.manifest.peerDependenciesMeta.keys()];for(let te of(0,N8.default)(z,C))U.manifest.peerDependenciesMeta.delete(te),h=!0,R=!0;for(let te of A){let ae=U.manifest.getForScope(te),le=[...ae.values()].map(ce=>G.stringifyIdent(ce));for(let ce of(0,N8.default)(le,G.stringifyIdent(L))){let{identHash:Ce}=G.parseIdent(ce),de=ae.get(Ce);if(typeof de>"u")throw new Error("Assertion failed: Expected the descriptor to be registered");U.manifest[te].delete(Ce),E.push([U,te,de]),h=!0,R=!0}}}R||p.push(C)}let I=p.length>1?"Patterns":"Pattern",v=p.length>1?"don't":"doesn't",x=this.all?"any":"this";if(p.length>0)throw new st(`${I} ${pe.prettyList(r,p,pe.Type.CODE)} ${v} match any packages referenced by ${x} workspace`);return h?(await r.triggerMultipleHooks(C=>C.afterWorkspaceDependencyRemoval,E),await o.installWithNewReport({stdout:this.context.stdout},{cache:n,mode:this.mode})):0}};Ge();Ge();qt();var cde=ve("util"),CE=class extends ut{constructor(){super(...arguments);this.json=ge.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"})}static{this.paths=[["run"]]}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await kt.find(r,this.context.cwd);if(!a)throw new sr(o.cwd,this.context.cwd);return(await Rt.start({configuration:r,stdout:this.context.stdout,json:this.json},async u=>{let A=a.manifest.scripts,p=He.sortMap(A.keys(),I=>I),h={breakLength:1/0,colors:r.get("enableColors"),maxArrayLength:2},E=p.reduce((I,v)=>Math.max(I,v.length),0);for(let[I,v]of A.entries())u.reportInfo(null,`${I.padEnd(E," ")} ${(0,cde.inspect)(v,h)}`),u.reportJson({name:I,script:v})})).exitCode()}};Ge();Ge();qt();var wE=class extends ut{constructor(){super(...arguments);this.inspect=ge.String("--inspect",!1,{tolerateBoolean:!0,description:"Forwarded to the underlying Node process when executing a binary"});this.inspectBrk=ge.String("--inspect-brk",!1,{tolerateBoolean:!0,description:"Forwarded to the underlying Node process when executing a binary"});this.topLevel=ge.Boolean("-T,--top-level",!1,{description:"Check the root workspace for scripts and/or binaries instead of the current one"});this.binariesOnly=ge.Boolean("-B,--binaries-only",!1,{description:"Ignore any user defined scripts and only check for binaries"});this.require=ge.String("--require",{description:"Forwarded to the underlying Node process when executing a binary"});this.silent=ge.Boolean("--silent",{hidden:!0});this.scriptName=ge.String();this.args=ge.Proxy()}static{this.paths=[["run"]]}static{this.usage=it.Usage({description:"run a script defined in the package.json",details:` + This command will run a tool. The exact tool that will be executed will depend on the current state of your workspace: + + - If the \`scripts\` field from your local package.json contains a matching script name, its definition will get executed. + + - Otherwise, if one of the local workspace's dependencies exposes a binary with a matching name, this binary will get executed. + + - Otherwise, if the specified name contains a colon character and if one of the workspaces in the project contains exactly one script with a matching name, then this script will get executed. + + Whatever happens, the cwd of the spawned process will be the workspace that declares the script (which makes it possible to call commands cross-workspaces using the third syntax). + `,examples:[["Run the tests from the local workspace","$0 run test"],['Same thing, but without the "run" keyword',"$0 test"],["Inspect Webpack while running","$0 run --inspect-brk webpack"]]})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins),{project:o,workspace:a,locator:n}=await kt.find(r,this.context.cwd);await o.restoreInstallState();let u=this.topLevel?o.topLevelWorkspace.anchoredLocator:n;if(!this.binariesOnly&&await An.hasPackageScript(u,this.scriptName,{project:o}))return await An.executePackageScript(u,this.scriptName,this.args,{project:o,stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr});let A=await An.getPackageAccessibleBinaries(u,{project:o});if(A.get(this.scriptName)){let h=[];return this.inspect&&(typeof this.inspect=="string"?h.push(`--inspect=${this.inspect}`):h.push("--inspect")),this.inspectBrk&&(typeof this.inspectBrk=="string"?h.push(`--inspect-brk=${this.inspectBrk}`):h.push("--inspect-brk")),this.require&&h.push(`--require=${this.require}`),await An.executePackageAccessibleBinary(u,this.scriptName,this.args,{cwd:this.context.cwd,project:o,stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr,nodeArgs:h,packageAccessibleBinaries:A})}if(!this.topLevel&&!this.binariesOnly&&a&&this.scriptName.includes(":")){let E=(await Promise.all(o.workspaces.map(async I=>I.manifest.scripts.has(this.scriptName)?I:null))).filter(I=>I!==null);if(E.length===1)return await An.executeWorkspaceScript(E[0],this.scriptName,this.args,{stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr})}if(this.topLevel)throw this.scriptName==="node-gyp"?new st(`Couldn't find a script name "${this.scriptName}" in the top-level (used by ${G.prettyLocator(r,n)}). This typically happens because some package depends on "node-gyp" to build itself, but didn't list it in their dependencies. To fix that, please run "yarn add node-gyp" into your top-level workspace. You also can open an issue on the repository of the specified package to suggest them to use an optional peer dependency.`):new st(`Couldn't find a script name "${this.scriptName}" in the top-level (used by ${G.prettyLocator(r,n)}).`);{if(this.scriptName==="global")throw new st("The 'yarn global' commands have been removed in 2.x - consider using 'yarn dlx' or a third-party plugin instead");let h=[this.scriptName].concat(this.args);for(let[E,I]of Uy)for(let v of I)if(h.length>=v.length&&JSON.stringify(h.slice(0,v.length))===JSON.stringify(v))throw new st(`Couldn't find a script named "${this.scriptName}", but a matching command can be found in the ${E} plugin. You can install it with "yarn plugin import ${E}".`);throw new st(`Couldn't find a script named "${this.scriptName}".`)}}};Ge();Ge();qt();var IE=class extends ut{constructor(){super(...arguments);this.descriptor=ge.String();this.resolution=ge.String()}static{this.paths=[["set","resolution"]]}static{this.usage=it.Usage({description:"enforce a package resolution",details:'\n This command updates the resolution table so that `descriptor` is resolved by `resolution`.\n\n Note that by default this command only affect the current resolution table - meaning that this "manual override" will disappear if you remove the lockfile, or if the package disappear from the table. If you wish to make the enforced resolution persist whatever happens, edit the `resolutions` field in your top-level manifest.\n\n Note that no attempt is made at validating that `resolution` is a valid resolution entry for `descriptor`.\n ',examples:[["Force all instances of lodash@npm:^1.2.3 to resolve to 1.5.0","$0 set resolution lodash@npm:^1.2.3 1.5.0"]]})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await kt.find(r,this.context.cwd),n=await Gr.find(r);if(await o.restoreInstallState({restoreResolutions:!1}),!a)throw new sr(o.cwd,this.context.cwd);let u=G.parseDescriptor(this.descriptor,!0),A=G.makeDescriptor(u,this.resolution);return o.storedDescriptors.set(u.descriptorHash,u),o.storedDescriptors.set(A.descriptorHash,A),o.resolutionAliases.set(u.descriptorHash,A.descriptorHash),await o.installWithNewReport({stdout:this.context.stdout},{cache:n})}};Ge();Pt();qt();var ude=Ze($o()),BE=class extends ut{constructor(){super(...arguments);this.all=ge.Boolean("-A,--all",!1,{description:"Unlink all workspaces belonging to the target project from the current one"});this.leadingArguments=ge.Rest()}static{this.paths=[["unlink"]]}static{this.usage=it.Usage({description:"disconnect the local project from another one",details:` + This command will remove any resolutions in the project-level manifest that would have been added via a yarn link with similar arguments. + `,examples:[["Unregister a remote workspace in the current project","$0 unlink ~/ts-loader"],["Unregister all workspaces from a remote project in the current project","$0 unlink ~/jest --all"],["Unregister all previously linked workspaces","$0 unlink --all"],["Unregister all workspaces matching a glob","$0 unlink '@babel/*' 'pkg-{a,b}'"]]})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await kt.find(r,this.context.cwd),n=await Gr.find(r);if(!a)throw new sr(o.cwd,this.context.cwd);let u=o.topLevelWorkspace,A=new Set;if(this.leadingArguments.length===0&&this.all)for(let{pattern:p,reference:h}of u.manifest.resolutions)h.startsWith("portal:")&&A.add(p.descriptor.fullName);if(this.leadingArguments.length>0)for(let p of this.leadingArguments){let h=V.resolve(this.context.cwd,ue.toPortablePath(p));if(He.isPathLike(p)){let E=await Ke.find(h,this.context.plugins,{useRc:!1,strict:!1}),{project:I,workspace:v}=await kt.find(E,h);if(!v)throw new sr(I.cwd,h);if(this.all){for(let x of I.workspaces)x.manifest.name&&A.add(G.stringifyIdent(x.anchoredLocator));if(A.size===0)throw new st("No workspace found to be unlinked in the target project")}else{if(!v.manifest.name)throw new st("The target workspace doesn't have a name and thus cannot be unlinked");A.add(G.stringifyIdent(v.anchoredLocator))}}else{let E=[...u.manifest.resolutions.map(({pattern:I})=>I.descriptor.fullName)];for(let I of(0,ude.default)(E,p))A.add(I)}}return u.manifest.resolutions=u.manifest.resolutions.filter(({pattern:p})=>!A.has(p.descriptor.fullName)),await o.installWithNewReport({stdout:this.context.stdout,quiet:this.context.quiet},{cache:n})}};Ge();Ge();Ge();qt();var Ade=Ze(J1()),L8=Ze($o());el();var vE=class extends ut{constructor(){super(...arguments);this.interactive=ge.Boolean("-i,--interactive",{description:"Offer various choices, depending on the detected upgrade paths"});this.fixed=ge.Boolean("-F,--fixed",!1,{description:"Store dependency tags as-is instead of resolving them"});this.exact=ge.Boolean("-E,--exact",!1,{description:"Don't use any semver modifier on the resolved range"});this.tilde=ge.Boolean("-T,--tilde",!1,{description:"Use the `~` semver modifier on the resolved range"});this.caret=ge.Boolean("-C,--caret",!1,{description:"Use the `^` semver modifier on the resolved range"});this.recursive=ge.Boolean("-R,--recursive",!1,{description:"Resolve again ALL resolutions for those packages"});this.mode=ge.String("--mode",{description:"Change what artifacts installs generate",validator:Js(hl)});this.patterns=ge.Rest()}static{this.paths=[["up"]]}static{this.usage=it.Usage({description:"upgrade dependencies across the project",details:"\n This command upgrades the packages matching the list of specified patterns to their latest available version across the whole project (regardless of whether they're part of `dependencies` or `devDependencies` - `peerDependencies` won't be affected). This is a project-wide command: all workspaces will be upgraded in the process.\n\n If `-R,--recursive` is set the command will change behavior and no other switch will be allowed. When operating under this mode `yarn up` will force all ranges matching the selected packages to be resolved again (often to the highest available versions) before being stored in the lockfile. It however won't touch your manifests anymore, so depending on your needs you might want to run both `yarn up` and `yarn up -R` to cover all bases.\n\n If `-i,--interactive` is set (or if the `preferInteractive` settings is toggled on) the command will offer various choices, depending on the detected upgrade paths. Some upgrades require this flag in order to resolve ambiguities.\n\n The, `-C,--caret`, `-E,--exact` and `-T,--tilde` options have the same meaning as in the `add` command (they change the modifier used when the range is missing or a tag, and are ignored when the range is explicitly set).\n\n If the `--mode=` option is set, Yarn will change which artifacts are generated. The modes currently supported are:\n\n - `skip-build` will not run the build scripts at all. Note that this is different from setting `enableScripts` to false because the latter will disable build scripts, and thus affect the content of the artifacts generated on disk, whereas the former will just disable the build step - but not the scripts themselves, which just won't run.\n\n - `update-lockfile` will skip the link step altogether, and only fetch packages that are missing from the lockfile (or that have no associated checksums). This mode is typically used by tools like Renovate or Dependabot to keep a lockfile up-to-date without incurring the full install cost.\n\n Generally you can see `yarn up` as a counterpart to what was `yarn upgrade --latest` in Yarn 1 (ie it ignores the ranges previously listed in your manifests), but unlike `yarn upgrade` which only upgraded dependencies in the current workspace, `yarn up` will upgrade all workspaces at the same time.\n\n This command accepts glob patterns as arguments (if valid Descriptors and supported by [micromatch](https://github.com/micromatch/micromatch)). Make sure to escape the patterns, to prevent your own shell from trying to expand them.\n\n **Note:** The ranges have to be static, only the package scopes and names can contain glob patterns.\n ",examples:[["Upgrade all instances of lodash to the latest release","$0 up lodash"],["Upgrade all instances of lodash to the latest release, but ask confirmation for each","$0 up lodash -i"],["Upgrade all instances of lodash to 1.2.3","$0 up lodash@1.2.3"],["Upgrade all instances of packages with the `@babel` scope to the latest release","$0 up '@babel/*'"],["Upgrade all instances of packages containing the word `jest` to the latest release","$0 up '*jest*'"],["Upgrade all instances of packages with the `@babel` scope to 7.0.0","$0 up '@babel/*@7.0.0'"]]})}static{this.schema=[Yw("recursive",Yu.Forbids,["interactive","exact","tilde","caret"],{ignore:[void 0,!1]})]}async execute(){return this.recursive?await this.executeUpRecursive():await this.executeUpClassic()}async executeUpRecursive(){let r=await Ke.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await kt.find(r,this.context.cwd),n=await Gr.find(r);if(!a)throw new sr(o.cwd,this.context.cwd);await o.restoreInstallState({restoreResolutions:!1});let u=[...o.storedDescriptors.values()],A=u.map(E=>G.stringifyIdent(E)),p=new Set;for(let E of this.patterns){if(G.parseDescriptor(E).range!=="unknown")throw new st("Ranges aren't allowed when using --recursive");for(let I of(0,L8.default)(A,E)){let v=G.parseIdent(I);p.add(v.identHash)}}let h=u.filter(E=>p.has(E.identHash));for(let E of h)o.storedDescriptors.delete(E.descriptorHash),o.storedResolutions.delete(E.descriptorHash);return await o.installWithNewReport({stdout:this.context.stdout},{cache:n,mode:this.mode})}async executeUpClassic(){let r=await Ke.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await kt.find(r,this.context.cwd),n=await Gr.find(r);if(!a)throw new sr(o.cwd,this.context.cwd);await o.restoreInstallState({restoreResolutions:!1});let u=this.fixed,A=r.isInteractive({interactive:this.interactive,stdout:this.context.stdout}),p=Z1(this,o),h=A?["keep","reuse","project","latest"]:["project","latest"],E=[],I=[];for(let L of this.patterns){let U=!1,z=G.parseDescriptor(L),te=G.stringifyIdent(z);for(let ae of o.workspaces)for(let le of["dependencies","devDependencies"]){let Ce=[...ae.manifest.getForScope(le).values()].map(Be=>G.stringifyIdent(Be)),de=te==="*"?Ce:(0,L8.default)(Ce,te);for(let Be of de){let Ee=G.parseIdent(Be),g=ae.manifest[le].get(Ee.identHash);if(typeof g>"u")throw new Error("Assertion failed: Expected the descriptor to be registered");let me=G.makeDescriptor(Ee,z.range);E.push(Promise.resolve().then(async()=>[ae,le,g,await $1(me,{project:o,workspace:ae,cache:n,target:le,fixed:u,modifier:p,strategies:h})])),U=!0}}U||I.push(L)}if(I.length>1)throw new st(`Patterns ${pe.prettyList(r,I,pe.Type.CODE)} don't match any packages referenced by any workspace`);if(I.length>0)throw new st(`Pattern ${pe.prettyList(r,I,pe.Type.CODE)} doesn't match any packages referenced by any workspace`);let v=await Promise.all(E),x=await AA.start({configuration:r,stdout:this.context.stdout,suggestInstall:!1},async L=>{for(let[,,U,{suggestions:z,rejections:te}]of v){let ae=z.filter(le=>le.descriptor!==null);if(ae.length===0){let[le]=te;if(typeof le>"u")throw new Error("Assertion failed: Expected an error to have been set");let ce=this.cli.error(le);o.configuration.get("enableNetwork")?L.reportError(27,`${G.prettyDescriptor(r,U)} can't be resolved to a satisfying range + +${ce}`):L.reportError(27,`${G.prettyDescriptor(r,U)} can't be resolved to a satisfying range (note: network resolution has been disabled) + +${ce}`)}else ae.length>1&&!A&&L.reportError(27,`${G.prettyDescriptor(r,U)} has multiple possible upgrade strategies; use -i to disambiguate manually`)}});if(x.hasErrors())return x.exitCode();let C=!1,R=[];for(let[L,U,,{suggestions:z}]of v){let te,ae=z.filter(de=>de.descriptor!==null),le=ae[0].descriptor,ce=ae.every(de=>G.areDescriptorsEqual(de.descriptor,le));ae.length===1||ce?te=le:(C=!0,{answer:te}=await(0,Ade.prompt)({type:"select",name:"answer",message:`Which range do you want to use in ${G.prettyWorkspace(r,L)} \u276F ${U}?`,choices:z.map(({descriptor:de,name:Be,reason:Ee})=>de?{name:Be,hint:Ee,descriptor:de}:{name:Be,hint:Ee,disabled:!0}),onCancel:()=>process.exit(130),result(de){return this.find(de,"descriptor")},stdin:this.context.stdin,stdout:this.context.stdout}));let Ce=L.manifest[U].get(te.identHash);if(typeof Ce>"u")throw new Error("Assertion failed: This descriptor should have a matching entry");if(Ce.descriptorHash!==te.descriptorHash)L.manifest[U].set(te.identHash,te),R.push([L,U,Ce,te]);else{let de=r.makeResolver(),Be={project:o,resolver:de},Ee=r.normalizeDependency(Ce),g=de.bindDescriptor(Ee,L.anchoredLocator,Be);o.forgetResolution(g)}}return await r.triggerMultipleHooks(L=>L.afterWorkspaceDependencyReplacement,R),C&&this.context.stdout.write(` +`),await o.installWithNewReport({stdout:this.context.stdout},{cache:n,mode:this.mode})}};Ge();Ge();Ge();qt();var DE=class extends ut{constructor(){super(...arguments);this.recursive=ge.Boolean("-R,--recursive",!1,{description:"List, for each workspace, what are all the paths that lead to the dependency"});this.json=ge.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.peers=ge.Boolean("--peers",!1,{description:"Also print the peer dependencies that match the specified name"});this.package=ge.String()}static{this.paths=[["why"]]}static{this.usage=it.Usage({description:"display the reason why a package is needed",details:` + This command prints the exact reasons why a package appears in the dependency tree. + + If \`-R,--recursive\` is set, the listing will go in depth and will list, for each workspaces, what are all the paths that lead to the dependency. Note that the display is somewhat optimized in that it will not print the package listing twice for a single package, so if you see a leaf named "Foo" when looking for "Bar", it means that "Foo" already got printed higher in the tree. + `,examples:[["Explain why lodash is used in your project","$0 why lodash"]]})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await kt.find(r,this.context.cwd);if(!a)throw new sr(o.cwd,this.context.cwd);await o.restoreInstallState();let n=G.parseIdent(this.package).identHash,u=this.recursive?cgt(o,n,{configuration:r,peers:this.peers}):lgt(o,n,{configuration:r,peers:this.peers});fs.emitTree(u,{configuration:r,stdout:this.context.stdout,json:this.json,separators:1})}};function lgt(t,e,{configuration:r,peers:o}){let a=He.sortMap(t.storedPackages.values(),A=>G.stringifyLocator(A)),n={},u={children:n};for(let A of a){let p={};for(let E of A.dependencies.values()){if(!o&&A.peerDependencies.has(E.identHash))continue;let I=t.storedResolutions.get(E.descriptorHash);if(!I)throw new Error("Assertion failed: The resolution should have been registered");let v=t.storedPackages.get(I);if(!v)throw new Error("Assertion failed: The package should have been registered");if(v.identHash!==e)continue;{let C=G.stringifyLocator(A);n[C]={value:[A,pe.Type.LOCATOR],children:p}}let x=G.stringifyLocator(v);p[x]={value:[{descriptor:E,locator:v},pe.Type.DEPENDENT]}}}return u}function cgt(t,e,{configuration:r,peers:o}){let a=He.sortMap(t.workspaces,v=>G.stringifyLocator(v.anchoredLocator)),n=new Set,u=new Set,A=v=>{if(n.has(v.locatorHash))return u.has(v.locatorHash);if(n.add(v.locatorHash),v.identHash===e)return u.add(v.locatorHash),!0;let x=!1;v.identHash===e&&(x=!0);for(let C of v.dependencies.values()){if(!o&&v.peerDependencies.has(C.identHash))continue;let R=t.storedResolutions.get(C.descriptorHash);if(!R)throw new Error("Assertion failed: The resolution should have been registered");let L=t.storedPackages.get(R);if(!L)throw new Error("Assertion failed: The package should have been registered");A(L)&&(x=!0)}return x&&u.add(v.locatorHash),x};for(let v of a)A(v.anchoredPackage);let p=new Set,h={},E={children:h},I=(v,x,C)=>{if(!u.has(v.locatorHash))return;let R=C!==null?pe.tuple(pe.Type.DEPENDENT,{locator:v,descriptor:C}):pe.tuple(pe.Type.LOCATOR,v),L={},U={value:R,children:L},z=G.stringifyLocator(v);if(x[z]=U,!(C!==null&&t.tryWorkspaceByLocator(v))&&!p.has(v.locatorHash)){p.add(v.locatorHash);for(let te of v.dependencies.values()){if(!o&&v.peerDependencies.has(te.identHash))continue;let ae=t.storedResolutions.get(te.descriptorHash);if(!ae)throw new Error("Assertion failed: The resolution should have been registered");let le=t.storedPackages.get(ae);if(!le)throw new Error("Assertion failed: The package should have been registered");I(le,L,te)}}};for(let v of a)I(v.anchoredPackage,h,null);return E}Ge();var W8={};Vt(W8,{GitFetcher:()=>s2,GitResolver:()=>o2,default:()=>kgt,gitUtils:()=>ia});Ge();Pt();var ia={};Vt(ia,{TreeishProtocols:()=>i2,clone:()=>Y8,fetchBase:()=>Rde,fetchChangedFiles:()=>Tde,fetchChangedWorkspaces:()=>Sgt,fetchRoot:()=>Fde,isGitUrl:()=>SE,lsRemote:()=>Qde,normalizeLocator:()=>bgt,normalizeRepoUrl:()=>PE,resolveUrl:()=>G8,splitRepoUrl:()=>Sh,validateRepoUrl:()=>j8});Ge();Pt();qt();var Sde=Ze(Dde()),xde=Ze(uU()),bE=Ze(ve("querystring")),H8=Ze(Jn());function _8(t,e,r){let o=t.indexOf(r);return t.lastIndexOf(e,o>-1?o:1/0)}function Pde(t){try{return new URL(t)}catch{return}}function Dgt(t){let e=_8(t,"@","#"),r=_8(t,":","#");return r>e&&(t=`${t.slice(0,r)}/${t.slice(r+1)}`),_8(t,":","#")===-1&&t.indexOf("//")===-1&&(t=`ssh://${t}`),t}function bde(t){return Pde(t)||Pde(Dgt(t))}function PE(t,{git:e=!1}={}){if(t=t.replace(/^git\+https:/,"https:"),t=t.replace(/^(?:github:|https:\/\/github\.com\/|git:\/\/github\.com\/)?(?!\.{1,2}\/)([a-zA-Z0-9._-]+)\/(?!\.{1,2}(?:#|$))([a-zA-Z0-9._-]+?)(?:\.git)?(#.*)?$/,"https://github.com/$1/$2.git$3"),t=t.replace(/^https:\/\/github\.com\/(?!\.{1,2}\/)([a-zA-Z0-9._-]+)\/(?!\.{1,2}(?:#|$))([a-zA-Z0-9._-]+?)\/tarball\/(.+)?$/,"https://github.com/$1/$2.git#$3"),e){let r=bde(t);r&&(t=r.href),t=t.replace(/^git\+([^:]+):/,"$1:")}return t}function kde(){return{...process.env,GIT_SSH_COMMAND:process.env.GIT_SSH_COMMAND||`${process.env.GIT_SSH||"ssh"} -o BatchMode=yes`}}var Pgt=[/^ssh:/,/^git(?:\+[^:]+)?:/,/^(?:git\+)?https?:[^#]+\/[^#]+(?:\.git)(?:#.*)?$/,/^git@[^#]+\/[^#]+\.git(?:#.*)?$/,/^(?:github:|https:\/\/github\.com\/)?(?!\.{1,2}\/)([a-zA-Z._0-9-]+)\/(?!\.{1,2}(?:#|$))([a-zA-Z._0-9-]+?)(?:\.git)?(?:#.*)?$/,/^https:\/\/github\.com\/(?!\.{1,2}\/)([a-zA-Z0-9._-]+)\/(?!\.{1,2}(?:#|$))([a-zA-Z0-9._-]+?)\/tarball\/(.+)?$/],i2=(a=>(a.Commit="commit",a.Head="head",a.Tag="tag",a.Semver="semver",a))(i2||{});function SE(t){return t?Pgt.some(e=>!!t.match(e)):!1}function Sh(t){t=PE(t);let e=t.indexOf("#");if(e===-1)return{repo:t,treeish:{protocol:"head",request:"HEAD"},extra:{}};let r=t.slice(0,e),o=t.slice(e+1);if(o.match(/^[a-z]+=/)){let a=bE.default.parse(o);for(let[p,h]of Object.entries(a))if(typeof h!="string")throw new Error(`Assertion failed: The ${p} parameter must be a literal string`);let n=Object.values(i2).find(p=>Object.hasOwn(a,p)),[u,A]=typeof n<"u"?[n,a[n]]:["head","HEAD"];for(let p of Object.values(i2))delete a[p];return{repo:r,treeish:{protocol:u,request:A},extra:a}}else{let a=o.indexOf(":"),[n,u]=a===-1?[null,o]:[o.slice(0,a),o.slice(a+1)];return{repo:r,treeish:{protocol:n,request:u},extra:{}}}}function bgt(t){return G.makeLocator(t,PE(t.reference))}function j8(t,{configuration:e}){let r=PE(t,{git:!0});if(!sn.getNetworkSettings(`https://${(0,Sde.default)(r).resource}`,{configuration:e}).enableNetwork)throw new Jt(80,`Request to '${r}' has been blocked because of your configuration settings`);return r}async function Qde(t,e){let r=j8(t,{configuration:e}),o=await q8("listing refs",["ls-remote",r],{cwd:e.startingCwd,env:kde()},{configuration:e,normalizedRepoUrl:r}),a=new Map,n=/^([a-f0-9]{40})\t([^\n]+)/gm,u;for(;(u=n.exec(o.stdout))!==null;)a.set(u[2],u[1]);return a}async function G8(t,e){let{repo:r,treeish:{protocol:o,request:a},extra:n}=Sh(t),u=await Qde(r,e),A=(h,E)=>{switch(h){case"commit":{if(!E.match(/^[a-f0-9]{40}$/))throw new Error("Invalid commit hash");return bE.default.stringify({...n,commit:E})}case"head":{let I=u.get(E==="HEAD"?E:`refs/heads/${E}`);if(typeof I>"u")throw new Error(`Unknown head ("${E}")`);return bE.default.stringify({...n,commit:I})}case"tag":{let I=u.get(`refs/tags/${E}`);if(typeof I>"u")throw new Error(`Unknown tag ("${E}")`);return bE.default.stringify({...n,commit:I})}case"semver":{let I=Lr.validRange(E);if(!I)throw new Error(`Invalid range ("${E}")`);let v=new Map([...u.entries()].filter(([C])=>C.startsWith("refs/tags/")).map(([C,R])=>[H8.default.parse(C.slice(10)),R]).filter(C=>C[0]!==null)),x=H8.default.maxSatisfying([...v.keys()],I);if(x===null)throw new Error(`No matching range ("${E}")`);return bE.default.stringify({...n,commit:v.get(x)})}case null:{let I;if((I=p("commit",E))!==null||(I=p("tag",E))!==null||(I=p("head",E))!==null)return I;throw E.match(/^[a-f0-9]+$/)?new Error(`Couldn't resolve "${E}" as either a commit, a tag, or a head - if a commit, use the 40-characters commit hash`):new Error(`Couldn't resolve "${E}" as either a commit, a tag, or a head`)}default:throw new Error(`Invalid Git resolution protocol ("${h}")`)}},p=(h,E)=>{try{return A(h,E)}catch{return null}};return PE(`${r}#${A(o,a)}`)}async function Y8(t,e){return await e.getLimit("cloneConcurrency")(async()=>{let{repo:r,treeish:{protocol:o,request:a}}=Sh(t);if(o!=="commit")throw new Error("Invalid treeish protocol when cloning");let n=j8(r,{configuration:e}),u=await oe.mktempPromise(),A={cwd:u,env:kde()};return await q8("cloning the repository",["clone","-c core.autocrlf=false",n,ue.fromPortablePath(u)],A,{configuration:e,normalizedRepoUrl:n}),await q8("switching branch",["checkout",`${a}`],A,{configuration:e,normalizedRepoUrl:n}),u})}async function Fde(t){let e,r=t;do{if(e=r,await oe.existsPromise(V.join(e,".git")))return e;r=V.dirname(e)}while(r!==e);return null}async function Rde(t,{baseRefs:e}){if(e.length===0)throw new st("Can't run this command with zero base refs specified.");let r=[];for(let A of e){let{code:p}=await Ur.execvp("git",["merge-base",A,"HEAD"],{cwd:t});p===0&&r.push(A)}if(r.length===0)throw new st(`No ancestor could be found between any of HEAD and ${e.join(", ")}`);let{stdout:o}=await Ur.execvp("git",["merge-base","HEAD",...r],{cwd:t,strict:!0}),a=o.trim(),{stdout:n}=await Ur.execvp("git",["show","--quiet","--pretty=format:%s",a],{cwd:t,strict:!0}),u=n.trim();return{hash:a,title:u}}async function Tde(t,{base:e,project:r}){let o=He.buildIgnorePattern(r.configuration.get("changesetIgnorePatterns")),{stdout:a}=await Ur.execvp("git",["diff","--name-only",`${e}`],{cwd:t,strict:!0}),n=a.split(/\r\n|\r|\n/).filter(h=>h.length>0).map(h=>V.resolve(t,ue.toPortablePath(h))),{stdout:u}=await Ur.execvp("git",["ls-files","--others","--exclude-standard"],{cwd:t,strict:!0}),A=u.split(/\r\n|\r|\n/).filter(h=>h.length>0).map(h=>V.resolve(t,ue.toPortablePath(h))),p=[...new Set([...n,...A].sort())];return o?p.filter(h=>!V.relative(r.cwd,h).match(o)):p}async function Sgt({ref:t,project:e}){if(e.configuration.projectCwd===null)throw new st("This command can only be run from within a Yarn project");let r=[V.resolve(e.cwd,dr.lockfile),V.resolve(e.cwd,e.configuration.get("cacheFolder")),V.resolve(e.cwd,e.configuration.get("installStatePath")),V.resolve(e.cwd,e.configuration.get("virtualFolder"))];await e.configuration.triggerHook(u=>u.populateYarnPaths,e,u=>{u!=null&&r.push(u)});let o=await Fde(e.configuration.projectCwd);if(o==null)throw new st("This command can only be run on Git repositories");let a=await Rde(o,{baseRefs:typeof t=="string"?[t]:e.configuration.get("changesetBaseRefs")}),n=await Tde(o,{base:a.hash,project:e});return new Set(He.mapAndFilter(n,u=>{let A=e.tryWorkspaceByFilePath(u);return A===null?He.mapAndFilter.skip:r.some(p=>u.startsWith(p))?He.mapAndFilter.skip:A}))}async function q8(t,e,r,{configuration:o,normalizedRepoUrl:a}){try{return await Ur.execvp("git",e,{...r,strict:!0})}catch(n){if(!(n instanceof Ur.ExecError))throw n;let u=n.reportExtra,A=n.stderr.toString();throw new Jt(1,`Failed ${t}`,p=>{p.reportError(1,` ${pe.prettyField(o,{label:"Repository URL",value:pe.tuple(pe.Type.URL,a)})}`);for(let h of A.matchAll(/^(.+?): (.*)$/gm)){let[,E,I]=h;E=E.toLowerCase();let v=E==="error"?"Error":`${(0,xde.default)(E)} Error`;p.reportError(1,` ${pe.prettyField(o,{label:v,value:pe.tuple(pe.Type.NO_HINT,I)})}`)}u?.(p)})}}var s2=class{supports(e,r){return SE(e.reference)}getLocalPath(e,r){return null}async fetch(e,r){let o=r.checksums.get(e.locatorHash)||null,a=new Map(r.checksums);a.set(e.locatorHash,o);let n={...r,checksums:a},u=await this.downloadHosted(e,n);if(u!==null)return u;let[A,p,h]=await r.cache.fetchPackageFromCache(e,o,{onHit:()=>r.report.reportCacheHit(e),onMiss:()=>r.report.reportCacheMiss(e,`${G.prettyLocator(r.project.configuration,e)} can't be found in the cache and will be fetched from the remote repository`),loader:()=>this.cloneFromRemote(e,n),...r.cacheOptions});return{packageFs:A,releaseFs:p,prefixPath:G.getIdentVendorPath(e),checksum:h}}async downloadHosted(e,r){return r.project.configuration.reduceHook(o=>o.fetchHostedRepository,null,e,r)}async cloneFromRemote(e,r){let o=Sh(e.reference),a=await Y8(e.reference,r.project.configuration),n=V.resolve(a,o.extra.cwd??It.dot),u=V.join(n,"package.tgz");await An.prepareExternalProject(n,u,{configuration:r.project.configuration,report:r.report,workspace:o.extra.workspace,locator:e});let A=await oe.readFilePromise(u);return await He.releaseAfterUseAsync(async()=>await $i.convertToZip(A,{configuration:r.project.configuration,prefixPath:G.getIdentVendorPath(e),stripComponents:1}))}};Ge();Ge();var o2=class{supportsDescriptor(e,r){return SE(e.range)}supportsLocator(e,r){return SE(e.reference)}shouldPersistResolution(e,r){return!0}bindDescriptor(e,r,o){return e}getResolutionDependencies(e,r){return{}}async getCandidates(e,r,o){let a=await G8(e.range,o.project.configuration);return[G.makeLocator(e,a)]}async getSatisfying(e,r,o,a){let n=Sh(e.range);return{locators:o.filter(A=>{if(A.identHash!==e.identHash)return!1;let p=Sh(A.reference);return!(n.repo!==p.repo||n.treeish.protocol==="commit"&&n.treeish.request!==p.treeish.request)}),sorted:!1}}async resolve(e,r){if(!r.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let o=await r.fetchOptions.fetcher.fetch(e,r.fetchOptions),a=await He.releaseAfterUseAsync(async()=>await Ut.find(o.prefixPath,{baseFs:o.packageFs}),o.releaseFs);return{...e,version:a.version||"0.0.0",languageName:a.languageName||r.project.configuration.get("defaultLanguageName"),linkType:"HARD",conditions:a.getConditions(),dependencies:r.project.configuration.normalizeDependencyMap(a.dependencies),peerDependencies:a.peerDependencies,dependenciesMeta:a.dependenciesMeta,peerDependenciesMeta:a.peerDependenciesMeta,bin:a.bin}}};var xgt={configuration:{changesetBaseRefs:{description:"The base git refs that the current HEAD is compared against when detecting changes. Supports git branches, tags, and commits.",type:"STRING",isArray:!0,isNullable:!1,default:["master","origin/master","upstream/master","main","origin/main","upstream/main"]},changesetIgnorePatterns:{description:"Array of glob patterns; files matching them will be ignored when fetching the changed files",type:"STRING",default:[],isArray:!0},cloneConcurrency:{description:"Maximal number of concurrent clones",type:"NUMBER",default:2}},fetchers:[s2],resolvers:[o2]};var kgt=xgt;qt();var xE=class extends ut{constructor(){super(...arguments);this.since=ge.String("--since",{description:"Only include workspaces that have been changed since the specified ref.",tolerateBoolean:!0});this.recursive=ge.Boolean("-R,--recursive",!1,{description:"Find packages via dependencies/devDependencies instead of using the workspaces field"});this.noPrivate=ge.Boolean("--no-private",{description:"Exclude workspaces that have the private field set to true"});this.verbose=ge.Boolean("-v,--verbose",!1,{description:"Also return the cross-dependencies between workspaces"});this.json=ge.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"})}static{this.paths=[["workspaces","list"]]}static{this.usage=it.Usage({category:"Workspace-related commands",description:"list all available workspaces",details:"\n This command will print the list of all workspaces in the project.\n\n - If `--since` is set, Yarn will only list workspaces that have been modified since the specified ref. By default Yarn will use the refs specified by the `changesetBaseRefs` configuration option.\n\n - If `-R,--recursive` is set, Yarn will find workspaces to run the command on by recursively evaluating `dependencies` and `devDependencies` fields, instead of looking at the `workspaces` fields.\n\n - If `--no-private` is set, Yarn will not list any workspaces that have the `private` field set to `true`.\n\n - If both the `-v,--verbose` and `--json` options are set, Yarn will also return the cross-dependencies between each workspaces (useful when you wish to automatically generate Buck / Bazel rules).\n "})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins),{project:o}=await kt.find(r,this.context.cwd);return(await Rt.start({configuration:r,json:this.json,stdout:this.context.stdout},async n=>{let u=this.since?await ia.fetchChangedWorkspaces({ref:this.since,project:o}):o.workspaces,A=new Set(u);if(this.recursive)for(let p of[...u].map(h=>h.getRecursiveWorkspaceDependents()))for(let h of p)A.add(h);for(let p of A){let{manifest:h}=p;if(h.private&&this.noPrivate)continue;let E;if(this.verbose){let I=new Set,v=new Set;for(let x of Ut.hardDependencies)for(let[C,R]of h.getForScope(x)){let L=o.tryWorkspaceByDescriptor(R);L===null?o.workspacesByIdent.has(C)&&v.add(R):I.add(L)}E={workspaceDependencies:Array.from(I).map(x=>x.relativeCwd),mismatchedWorkspaceDependencies:Array.from(v).map(x=>G.stringifyDescriptor(x))}}n.reportInfo(null,`${p.relativeCwd}`),n.reportJson({location:p.relativeCwd,name:h.name?G.stringifyIdent(h.name):null,...E})}})).exitCode()}};Ge();Ge();qt();var kE=class extends ut{constructor(){super(...arguments);this.workspaceName=ge.String();this.commandName=ge.String();this.args=ge.Proxy()}static{this.paths=[["workspace"]]}static{this.usage=it.Usage({category:"Workspace-related commands",description:"run a command within the specified workspace",details:` + This command will run a given sub-command on a single workspace. + `,examples:[["Add a package to a single workspace","yarn workspace components add -D react"],["Run build script on a single workspace","yarn workspace components run build"]]})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await kt.find(r,this.context.cwd);if(!a)throw new sr(o.cwd,this.context.cwd);let n=o.workspaces,u=new Map(n.map(p=>[G.stringifyIdent(p.anchoredLocator),p])),A=u.get(this.workspaceName);if(A===void 0){let p=Array.from(u.keys()).sort();throw new st(`Workspace '${this.workspaceName}' not found. Did you mean any of the following: + - ${p.join(` + - `)}?`)}return this.cli.run([this.commandName,...this.args],{cwd:A.cwd})}};var Qgt={configuration:{enableImmutableInstalls:{description:"If true (the default on CI), prevents the install command from modifying the lockfile",type:"BOOLEAN",default:Nde.isCI},defaultSemverRangePrefix:{description:"The default save prefix: '^', '~' or ''",type:"STRING",values:["^","~",""],default:"^"},preferReuse:{description:"If true, `yarn add` will attempt to reuse the most common dependency range in other workspaces.",type:"BOOLEAN",default:!1}},commands:[Ky,Vy,zy,Jy,IE,pE,sE,xE,$y,eE,tE,rE,Yy,Wy,Xy,Zy,nE,iE,oE,aE,lE,cE,BE,uE,AE,gE,hE,dE,fE,mE,yE,EE,CE,wE,vE,DE,kE]},Fgt=Qgt;var Z8={};Vt(Z8,{default:()=>Tgt});Ge();var xt={optional:!0},V8=[["@tailwindcss/aspect-ratio@<0.2.1",{peerDependencies:{tailwindcss:"^2.0.2"}}],["@tailwindcss/line-clamp@<0.2.1",{peerDependencies:{tailwindcss:"^2.0.2"}}],["@fullhuman/postcss-purgecss@3.1.3 || 3.1.3-alpha.0",{peerDependencies:{postcss:"^8.0.0"}}],["@samverschueren/stream-to-observable@<0.3.1",{peerDependenciesMeta:{rxjs:xt,zenObservable:xt}}],["any-observable@<0.5.1",{peerDependenciesMeta:{rxjs:xt,zenObservable:xt}}],["@pm2/agent@<1.0.4",{dependencies:{debug:"*"}}],["debug@<4.2.0",{peerDependenciesMeta:{"supports-color":xt}}],["got@<11",{dependencies:{"@types/responselike":"^1.0.0","@types/keyv":"^3.1.1"}}],["cacheable-lookup@<4.1.2",{dependencies:{"@types/keyv":"^3.1.1"}}],["http-link-dataloader@*",{peerDependencies:{graphql:"^0.13.1 || ^14.0.0"}}],["typescript-language-server@*",{dependencies:{"vscode-jsonrpc":"^5.0.1","vscode-languageserver-protocol":"^3.15.0"}}],["postcss-syntax@*",{peerDependenciesMeta:{"postcss-html":xt,"postcss-jsx":xt,"postcss-less":xt,"postcss-markdown":xt,"postcss-scss":xt}}],["jss-plugin-rule-value-function@<=10.1.1",{dependencies:{"tiny-warning":"^1.0.2"}}],["ink-select-input@<4.1.0",{peerDependencies:{react:"^16.8.2"}}],["license-webpack-plugin@<2.3.18",{peerDependenciesMeta:{webpack:xt}}],["snowpack@>=3.3.0",{dependencies:{"node-gyp":"^7.1.0"}}],["promise-inflight@*",{peerDependenciesMeta:{bluebird:xt}}],["reactcss@*",{peerDependencies:{react:"*"}}],["react-color@<=2.19.0",{peerDependencies:{react:"*"}}],["gatsby-plugin-i18n@*",{dependencies:{ramda:"^0.24.1"}}],["useragent@^2.0.0",{dependencies:{request:"^2.88.0",yamlparser:"0.0.x",semver:"5.5.x"}}],["@apollographql/apollo-tools@<=0.5.2",{peerDependencies:{graphql:"^14.2.1 || ^15.0.0"}}],["material-table@^2.0.0",{dependencies:{"@babel/runtime":"^7.11.2"}}],["@babel/parser@*",{dependencies:{"@babel/types":"^7.8.3"}}],["fork-ts-checker-webpack-plugin@<=6.3.4",{peerDependencies:{eslint:">= 6",typescript:">= 2.7",webpack:">= 4","vue-template-compiler":"*"},peerDependenciesMeta:{eslint:xt,"vue-template-compiler":xt}}],["rc-animate@<=3.1.1",{peerDependencies:{react:">=16.9.0","react-dom":">=16.9.0"}}],["react-bootstrap-table2-paginator@*",{dependencies:{classnames:"^2.2.6"}}],["react-draggable@<=4.4.3",{peerDependencies:{react:">= 16.3.0","react-dom":">= 16.3.0"}}],["apollo-upload-client@<14",{peerDependencies:{graphql:"14 - 15"}}],["react-instantsearch-core@<=6.7.0",{peerDependencies:{algoliasearch:">= 3.1 < 5"}}],["react-instantsearch-dom@<=6.7.0",{dependencies:{"react-fast-compare":"^3.0.0"}}],["ws@<7.2.1",{peerDependencies:{bufferutil:"^4.0.1","utf-8-validate":"^5.0.2"},peerDependenciesMeta:{bufferutil:xt,"utf-8-validate":xt}}],["react-portal@<4.2.2",{peerDependencies:{"react-dom":"^15.0.0-0 || ^16.0.0-0 || ^17.0.0-0"}}],["react-scripts@<=4.0.1",{peerDependencies:{react:"*"}}],["testcafe@<=1.10.1",{dependencies:{"@babel/plugin-transform-for-of":"^7.12.1","@babel/runtime":"^7.12.5"}}],["testcafe-legacy-api@<=4.2.0",{dependencies:{"testcafe-hammerhead":"^17.0.1","read-file-relative":"^1.2.0"}}],["@google-cloud/firestore@<=4.9.3",{dependencies:{protobufjs:"^6.8.6"}}],["gatsby-source-apiserver@*",{dependencies:{"babel-polyfill":"^6.26.0"}}],["@webpack-cli/package-utils@<=1.0.1-alpha.4",{dependencies:{"cross-spawn":"^7.0.3"}}],["gatsby-remark-prismjs@<3.3.28",{dependencies:{lodash:"^4"}}],["gatsby-plugin-favicon@*",{peerDependencies:{webpack:"*"}}],["gatsby-plugin-sharp@<=4.6.0-next.3",{dependencies:{debug:"^4.3.1"}}],["gatsby-react-router-scroll@<=5.6.0-next.0",{dependencies:{"prop-types":"^15.7.2"}}],["@rebass/forms@*",{dependencies:{"@styled-system/should-forward-prop":"^5.0.0"},peerDependencies:{react:"^16.8.6"}}],["rebass@*",{peerDependencies:{react:"^16.8.6"}}],["@ant-design/react-slick@<=0.28.3",{peerDependencies:{react:">=16.0.0"}}],["mqtt@<4.2.7",{dependencies:{duplexify:"^4.1.1"}}],["vue-cli-plugin-vuetify@<=2.0.3",{dependencies:{semver:"^6.3.0"},peerDependenciesMeta:{"sass-loader":xt,"vuetify-loader":xt}}],["vue-cli-plugin-vuetify@<=2.0.4",{dependencies:{"null-loader":"^3.0.0"}}],["vue-cli-plugin-vuetify@>=2.4.3",{peerDependencies:{vue:"*"}}],["@vuetify/cli-plugin-utils@<=0.0.4",{dependencies:{semver:"^6.3.0"},peerDependenciesMeta:{"sass-loader":xt}}],["@vue/cli-plugin-typescript@<=5.0.0-alpha.0",{dependencies:{"babel-loader":"^8.1.0"}}],["@vue/cli-plugin-typescript@<=5.0.0-beta.0",{dependencies:{"@babel/core":"^7.12.16"},peerDependencies:{"vue-template-compiler":"^2.0.0"},peerDependenciesMeta:{"vue-template-compiler":xt}}],["cordova-ios@<=6.3.0",{dependencies:{underscore:"^1.9.2"}}],["cordova-lib@<=10.0.1",{dependencies:{underscore:"^1.9.2"}}],["git-node-fs@*",{peerDependencies:{"js-git":"^0.7.8"},peerDependenciesMeta:{"js-git":xt}}],["consolidate@<0.16.0",{peerDependencies:{mustache:"^3.0.0"},peerDependenciesMeta:{mustache:xt}}],["consolidate@<=0.16.0",{peerDependencies:{velocityjs:"^2.0.1",tinyliquid:"^0.2.34","liquid-node":"^3.0.1",jade:"^1.11.0","then-jade":"*",dust:"^0.3.0","dustjs-helpers":"^1.7.4","dustjs-linkedin":"^2.7.5",swig:"^1.4.2","swig-templates":"^2.0.3","razor-tmpl":"^1.3.1",atpl:">=0.7.6",liquor:"^0.0.5",twig:"^1.15.2",ejs:"^3.1.5",eco:"^1.1.0-rc-3",jazz:"^0.0.18",jqtpl:"~1.1.0",hamljs:"^0.6.2",hamlet:"^0.3.3",whiskers:"^0.4.0","haml-coffee":"^1.14.1","hogan.js":"^3.0.2",templayed:">=0.2.3",handlebars:"^4.7.6",underscore:"^1.11.0",lodash:"^4.17.20",pug:"^3.0.0","then-pug":"*",qejs:"^3.0.5",walrus:"^0.10.1",mustache:"^4.0.1",just:"^0.1.8",ect:"^0.5.9",mote:"^0.2.0",toffee:"^0.3.6",dot:"^1.1.3","bracket-template":"^1.1.5",ractive:"^1.3.12",nunjucks:"^3.2.2",htmling:"^0.0.8","babel-core":"^6.26.3",plates:"~0.4.11","react-dom":"^16.13.1",react:"^16.13.1","arc-templates":"^0.5.3",vash:"^0.13.0",slm:"^2.0.0",marko:"^3.14.4",teacup:"^2.0.0","coffee-script":"^1.12.7",squirrelly:"^5.1.0",twing:"^5.0.2"},peerDependenciesMeta:{velocityjs:xt,tinyliquid:xt,"liquid-node":xt,jade:xt,"then-jade":xt,dust:xt,"dustjs-helpers":xt,"dustjs-linkedin":xt,swig:xt,"swig-templates":xt,"razor-tmpl":xt,atpl:xt,liquor:xt,twig:xt,ejs:xt,eco:xt,jazz:xt,jqtpl:xt,hamljs:xt,hamlet:xt,whiskers:xt,"haml-coffee":xt,"hogan.js":xt,templayed:xt,handlebars:xt,underscore:xt,lodash:xt,pug:xt,"then-pug":xt,qejs:xt,walrus:xt,mustache:xt,just:xt,ect:xt,mote:xt,toffee:xt,dot:xt,"bracket-template":xt,ractive:xt,nunjucks:xt,htmling:xt,"babel-core":xt,plates:xt,"react-dom":xt,react:xt,"arc-templates":xt,vash:xt,slm:xt,marko:xt,teacup:xt,"coffee-script":xt,squirrelly:xt,twing:xt}}],["vue-loader@<=16.3.3",{peerDependencies:{"@vue/compiler-sfc":"^3.0.8",webpack:"^4.1.0 || ^5.0.0-0"},peerDependenciesMeta:{"@vue/compiler-sfc":xt}}],["vue-loader@^16.7.0",{peerDependencies:{"@vue/compiler-sfc":"^3.0.8",vue:"^3.2.13"},peerDependenciesMeta:{"@vue/compiler-sfc":xt,vue:xt}}],["scss-parser@<=1.0.5",{dependencies:{lodash:"^4.17.21"}}],["query-ast@<1.0.5",{dependencies:{lodash:"^4.17.21"}}],["redux-thunk@<=2.3.0",{peerDependencies:{redux:"^4.0.0"}}],["skypack@<=0.3.2",{dependencies:{tar:"^6.1.0"}}],["@npmcli/metavuln-calculator@<2.0.0",{dependencies:{"json-parse-even-better-errors":"^2.3.1"}}],["bin-links@<2.3.0",{dependencies:{"mkdirp-infer-owner":"^1.0.2"}}],["rollup-plugin-polyfill-node@<=0.8.0",{peerDependencies:{rollup:"^1.20.0 || ^2.0.0"}}],["snowpack@<3.8.6",{dependencies:{"magic-string":"^0.25.7"}}],["elm-webpack-loader@*",{dependencies:{temp:"^0.9.4"}}],["winston-transport@<=4.4.0",{dependencies:{logform:"^2.2.0"}}],["jest-vue-preprocessor@*",{dependencies:{"@babel/core":"7.8.7","@babel/template":"7.8.6"},peerDependencies:{pug:"^2.0.4"},peerDependenciesMeta:{pug:xt}}],["redux-persist@*",{peerDependencies:{react:">=16"},peerDependenciesMeta:{react:xt}}],["sodium@>=3",{dependencies:{"node-gyp":"^3.8.0"}}],["babel-plugin-graphql-tag@<=3.1.0",{peerDependencies:{graphql:"^14.0.0 || ^15.0.0"}}],["@playwright/test@<=1.14.1",{dependencies:{"jest-matcher-utils":"^26.4.2"}}],...["babel-plugin-remove-graphql-queries@<3.14.0-next.1","babel-preset-gatsby-package@<1.14.0-next.1","create-gatsby@<1.14.0-next.1","gatsby-admin@<0.24.0-next.1","gatsby-cli@<3.14.0-next.1","gatsby-core-utils@<2.14.0-next.1","gatsby-design-tokens@<3.14.0-next.1","gatsby-legacy-polyfills@<1.14.0-next.1","gatsby-plugin-benchmark-reporting@<1.14.0-next.1","gatsby-plugin-graphql-config@<0.23.0-next.1","gatsby-plugin-image@<1.14.0-next.1","gatsby-plugin-mdx@<2.14.0-next.1","gatsby-plugin-netlify-cms@<5.14.0-next.1","gatsby-plugin-no-sourcemaps@<3.14.0-next.1","gatsby-plugin-page-creator@<3.14.0-next.1","gatsby-plugin-preact@<5.14.0-next.1","gatsby-plugin-preload-fonts@<2.14.0-next.1","gatsby-plugin-schema-snapshot@<2.14.0-next.1","gatsby-plugin-styletron@<6.14.0-next.1","gatsby-plugin-subfont@<3.14.0-next.1","gatsby-plugin-utils@<1.14.0-next.1","gatsby-recipes@<0.25.0-next.1","gatsby-source-shopify@<5.6.0-next.1","gatsby-source-wikipedia@<3.14.0-next.1","gatsby-transformer-screenshot@<3.14.0-next.1","gatsby-worker@<0.5.0-next.1"].map(t=>[t,{dependencies:{"@babel/runtime":"^7.14.8"}}]),["gatsby-core-utils@<2.14.0-next.1",{dependencies:{got:"8.3.2"}}],["gatsby-plugin-gatsby-cloud@<=3.1.0-next.0",{dependencies:{"gatsby-core-utils":"^2.13.0-next.0"}}],["gatsby-plugin-gatsby-cloud@<=3.2.0-next.1",{peerDependencies:{webpack:"*"}}],["babel-plugin-remove-graphql-queries@<=3.14.0-next.1",{dependencies:{"gatsby-core-utils":"^2.8.0-next.1"}}],["gatsby-plugin-netlify@3.13.0-next.1",{dependencies:{"gatsby-core-utils":"^2.13.0-next.0"}}],["clipanion-v3-codemod@<=0.2.0",{peerDependencies:{jscodeshift:"^0.11.0"}}],["react-live@*",{peerDependencies:{"react-dom":"*",react:"*"}}],["webpack@<4.44.1",{peerDependenciesMeta:{"webpack-cli":xt,"webpack-command":xt}}],["webpack@<5.0.0-beta.23",{peerDependenciesMeta:{"webpack-cli":xt}}],["webpack-dev-server@<3.10.2",{peerDependenciesMeta:{"webpack-cli":xt}}],["@docusaurus/responsive-loader@<1.5.0",{peerDependenciesMeta:{sharp:xt,jimp:xt}}],["eslint-module-utils@*",{peerDependenciesMeta:{"eslint-import-resolver-node":xt,"eslint-import-resolver-typescript":xt,"eslint-import-resolver-webpack":xt,"@typescript-eslint/parser":xt}}],["eslint-plugin-import@*",{peerDependenciesMeta:{"@typescript-eslint/parser":xt}}],["critters-webpack-plugin@<3.0.2",{peerDependenciesMeta:{"html-webpack-plugin":xt}}],["terser@<=5.10.0",{dependencies:{acorn:"^8.5.0"}}],["babel-preset-react-app@10.0.x <10.0.2",{dependencies:{"@babel/plugin-proposal-private-property-in-object":"^7.16.7"}}],["eslint-config-react-app@*",{peerDependenciesMeta:{typescript:xt}}],["@vue/eslint-config-typescript@<11.0.0",{peerDependenciesMeta:{typescript:xt}}],["unplugin-vue2-script-setup@<0.9.1",{peerDependencies:{"@vue/composition-api":"^1.4.3","@vue/runtime-dom":"^3.2.26"}}],["@cypress/snapshot@*",{dependencies:{debug:"^3.2.7"}}],["auto-relay@<=0.14.0",{peerDependencies:{"reflect-metadata":"^0.1.13"}}],["vue-template-babel-compiler@<1.2.0",{peerDependencies:{"vue-template-compiler":"^2.6.0"}}],["@parcel/transformer-image@<2.5.0",{peerDependencies:{"@parcel/core":"*"}}],["@parcel/transformer-js@<2.5.0",{peerDependencies:{"@parcel/core":"*"}}],["parcel@*",{peerDependenciesMeta:{"@parcel/core":xt}}],["react-scripts@*",{peerDependencies:{eslint:"*"}}],["focus-trap-react@^8.0.0",{dependencies:{tabbable:"^5.3.2"}}],["react-rnd@<10.3.7",{peerDependencies:{react:">=16.3.0","react-dom":">=16.3.0"}}],["connect-mongo@<5.0.0",{peerDependencies:{"express-session":"^1.17.1"}}],["vue-i18n@<9",{peerDependencies:{vue:"^2"}}],["vue-router@<4",{peerDependencies:{vue:"^2"}}],["unified@<10",{dependencies:{"@types/unist":"^2.0.0"}}],["react-github-btn@<=1.3.0",{peerDependencies:{react:">=16.3.0"}}],["react-dev-utils@*",{peerDependencies:{typescript:">=2.7",webpack:">=4"},peerDependenciesMeta:{typescript:xt}}],["@asyncapi/react-component@<=1.0.0-next.39",{peerDependencies:{react:">=16.8.0","react-dom":">=16.8.0"}}],["xo@*",{peerDependencies:{webpack:">=1.11.0"},peerDependenciesMeta:{webpack:xt}}],["babel-plugin-remove-graphql-queries@<=4.20.0-next.0",{dependencies:{"@babel/types":"^7.15.4"}}],["gatsby-plugin-page-creator@<=4.20.0-next.1",{dependencies:{"fs-extra":"^10.1.0"}}],["gatsby-plugin-utils@<=3.14.0-next.1",{dependencies:{fastq:"^1.13.0"},peerDependencies:{graphql:"^15.0.0"}}],["gatsby-plugin-mdx@<3.1.0-next.1",{dependencies:{mkdirp:"^1.0.4"}}],["gatsby-plugin-mdx@^2",{peerDependencies:{gatsby:"^3.0.0-next"}}],["fdir@<=5.2.0",{peerDependencies:{picomatch:"2.x"},peerDependenciesMeta:{picomatch:xt}}],["babel-plugin-transform-typescript-metadata@<=0.3.2",{peerDependencies:{"@babel/core":"^7","@babel/traverse":"^7"},peerDependenciesMeta:{"@babel/traverse":xt}}],["graphql-compose@>=9.0.10",{peerDependencies:{graphql:"^14.2.0 || ^15.0.0 || ^16.0.0"}}],["vite-plugin-vuetify@<=1.0.2",{peerDependencies:{vue:"^3.0.0"}}],["webpack-plugin-vuetify@<=2.0.1",{peerDependencies:{vue:"^3.2.6"}}],["eslint-import-resolver-vite@<2.0.1",{dependencies:{debug:"^4.3.4",resolve:"^1.22.8"}}]];var z8;function Lde(){return typeof z8>"u"&&(z8=ve("zlib").brotliDecompressSync(Buffer.from("G7weAByFTVk3Vs7UfHhq4yykgEM7pbW7TI43SG2S5tvGrwHBAzdz+s/npQ6tgEvobvxisrPIadkXeUAJotBn5bDZ5kAhcRqsIHe3F75Walet5hNalwgFDtxb0BiDUjiUQkjG0yW2hto9HPgiCkm316d6bC0kST72YN7D7rfkhCE9x4J0XwB0yavalxpUu2t9xszHrmtwalOxT7VslsxWcB1qpqZwERUra4psWhTV8BgwWeizurec82Caf1ABL11YMfbf8FJ9JBceZOkgmvrQPbC9DUldX/yMbmX06UQluCEjSwUoyO+EZPIjofr+/oAZUck2enraRD+oWLlnlYnj8xB+gwSo9lmmks4fXv574qSqcWA6z21uYkzMu3EWj+K23RxeQlLqiE35/rC8GcS4CGkKHKKq+zAIQwD9iRDNfiAqueLLpicFFrNsAI4zeTD/eO9MHcnRa5m8UT+M2+V+AkFST4BlKneiAQRSdST8KEAIyFlULt6wa9EBd0Ds28VmpaxquJdVt+nwdEs5xUskI13OVtFyY0UrQIRAlCuvvWivvlSKQfTO+2Q8OyUR1W5RvetaPz4jD27hdtwHFFA1Ptx6Ee/t2cY2rg2G46M1pNDRf2pWhvpy8pqMnuI3++4OF3+7OFIWXGjh+o7Nr2jNvbiYcQdQS1h903/jVFgOpA0yJ78z+x759bFA0rq+6aY5qPB4FzS3oYoLupDUhD9nDz6F6H7hpnlMf18KNKDu4IKjTWwrAnY6MFQw1W6ymOALHlFyCZmQhldg1MQHaMVVQTVgDC60TfaBqG++Y8PEoFhN/PBTZT175KNP/BlHDYGOOBmnBdzqJKplZ/ljiVG0ZBzfqeBRrrUkn6rA54462SgiliKoYVnbeptMdXNfAuaupIEi0bApF10TlgHfmEJAPUVidRVFyDupSem5po5vErPqWKhKbUIp0LozpYsIKK57dM/HKr+nguF+7924IIWMICkQ8JUigs9D+W+c4LnNoRtPPKNRUiCYmP+Jfo2lfKCKw8qpraEeWU3uiNRO6zcyKQoXPR5htmzzLznke7b4YbXW3I1lIRzmgG02Udb58U+7TpwyN7XymCgH+wuPDthZVQvRZuEP+SnLtMicz9m5zASWOBiAcLmkuFlTKuHspSIhCBD0yUPKcxu81A+4YD78rA2vtwsUEday9WNyrShyrl60rWmA+SmbYZkQOwFJWArxRYYc5jGhA5ikxYw1rx3ei4NmeX/lKiwpZ9Ln1tV2Ae7sArvxuVLbJjqJRjW1vFXAyHpvLG+8MJ6T2Ubx5M2KDa2SN6vuIGxJ9WQM9Mk3Q7aCNiZONXllhqq24DmoLbQfW2rYWsOgHWjtOmIQMyMKdiHZDjoyIq5+U700nZ6odJAoYXPQBvFNiQ78d5jaXliBqLTJEqUCwi+LiH2mx92EmNKDsJL74Z613+3lf20pxkV1+erOrjj8pW00vsPaahKUM+05ssd5uwM7K482KWEf3TCwlg/o3e5ngto7qSMz7YteIgCsF1UOcsLk7F7MxWbvrPMY473ew0G+noVL8EPbkmEMftMSeL6HFub/zy+2JQ==","base64")).toString()),z8}var J8;function Mde(){return typeof J8>"u"&&(J8=ve("zlib").brotliDecompressSync(Buffer.from("G8MSIIzURnVBnObTcvb3XE6v2S9Qgc2K801Oa5otNKEtK8BINZNcaQHy+9/vf/WXBimwutXC33P2DPc64pps5rz7NGGWaOKNSPL4Y2KRE8twut2lFOIN+OXPtRmPMRhMTILib2bEQx43az2I5d3YS8Roa5UZpF/ujHb3Djd3GDvYUfvFYSUQ39vb2cmifp/rgB4J/65JK3wRBTvMBoNBmn3mbXC63/gbBkW/2IRPri0O8bcsRBsmarF328pAln04nyJFkwUAvNu934supAqLtyerZZpJ8I8suJHhf/ocMV+scKwa8NOiDKIPXw6Ex/EEZD6TEGaW8N5zvNHYF10l6Lfooj7D5W2k3dgvQSbp2Wv8TGOayS978gxlOLVjTGXs66ozewbrjwElLtyrYNnWTfzzdEutgROUFPVMhnMoy8EjJLLlWwIEoySxliim9kYW30JUHiPVyjt0iAw/ZpPmCbUCltYPnq6ZNblIKhTNhqS/oqC9iya5sGKZTOVsTEg34n92uZTf2iPpcZih8rPW8CzA+adIGmyCPcKdLMsBLShd+zuEbTrqpwuh+DLmracZcjPC5Sdf5odDAhKpFuOsQS67RT+1VgWWygSv3YwxDnylc04/PYuaMeIzhBkLrvs7e/OUzRTF56MmfY6rI63QtEjEQzq637zQqJ39nNhu3NmoRRhW/086bHGBUtx0PE0j3aEGvkdh9WJC8y8j8mqqke9/dQ5la+Q3ba4RlhvTbnfQhPDDab3tUifkjKuOsp13mXEmO00Mu88F/M67R7LXfoFDFLNtgCSWjWX+3Jn1371pJTK9xPBiMJafvDjtFyAzu8rxeQ0TKMQXNPs5xxiBOd+BRJP8KP88XPtJIbZKh/cdW8KvBUkpqKpGoiIaA32c3/JnQr4efXt85mXvidOvn/eU3Pase1typLYBalJ14mCso9h79nuMOuCa/kZAOkJHmTjP5RM2WNoPasZUAnT1TAE/NH25hUxcQv6hQWR/m1PKk4ooXMcM4SR1iYU3fUohvqk4RY2hbmTVVIXv6TvqO+0doOjgeVFAcom+RlwJQmOVH7pr1Q9LoJT6n1DeQEB+NHygsATbIwTcOKZlJsY8G4+suX1uQLjUWwLjjs0mvSvZcLTpIGAekeR7GCgl8eo3ndAqEe2XCav4huliHjdbIPBsGJuPX7lrO9HX1UbXRH5opOe1x6JsOSgHZR+EaxuXVhpLLxm6jk1LJtZfHSc6BKPun3CpYYVMJGwEUyk8MTGG0XL5MfEwaXpnc9TKnBmlGn6nHiGREc3ysn47XIBDzA+YvFdjZzVIEDcKGpS6PbUJehFRjEne8D0lVU1XuRtlgszq6pTNlQ/3MzNOEgCWPyTct22V2mEi2krizn5VDo9B19/X2DB3hCGRMM7ONbtnAcIx/OWB1u5uPbW1gsH8irXxT/IzG0PoXWYjhbMsH3KTuoOl5o17PulcgvsfTSnKFM354GWI8luqZnrswWjiXy3G+Vbyo1KMopFmmvBwNELgaS8z8dNZchx/Cl/xjddxhMcyqtzFyONb2Zdu90NkI8pAeufe7YlXrp53v8Dj/l8vWeVspRKBGXScBBPI/HinSTGmLDOGGOCIyH0JFdOZx0gWsacNlQLJMIrBhqRxXxHF/5pseWwejlAAvZ3klZSDSYY8mkToaWejXhgNomeGtx1DTLEUFMRkgF5yFB22WYdJnaWN14r1YJj81hGi45+jrADS5nYRhCiSlCJJ1nL8pYX+HDSMhdTEWyRcgHVp/IsUIZYMfT+YYncUQPgcxNGCHfZ88vDdrcUuaGIl6zhAsiaq7R5dfqrqXH/JcBhfjT8D0azayIyEz75Nxp6YkcyDxlJq3EXnJUpqDohJJOysL1t1uNiHESlvsxPb5cpbW0+ICZqJmUZus1BMW0F5IVBODLIo2zHHjA0=","base64")).toString()),J8}var X8;function Ode(){return typeof X8>"u"&&(X8=ve("zlib").brotliDecompressSync(Buffer.from("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","base64")).toString()),X8}var Ude=new Map([[G.makeIdent(null,"fsevents").identHash,Lde],[G.makeIdent(null,"resolve").identHash,Mde],[G.makeIdent(null,"typescript").identHash,Ode]]),Rgt={hooks:{registerPackageExtensions:async(t,e)=>{for(let[r,o]of V8)e(G.parseDescriptor(r,!0),o)},getBuiltinPatch:async(t,e)=>{let r="compat/";if(!e.startsWith(r))return;let o=G.parseIdent(e.slice(r.length)),a=Ude.get(o.identHash)?.();return typeof a<"u"?a:null},reduceDependency:async(t,e,r,o)=>typeof Ude.get(t.identHash)>"u"?t:G.makeDescriptor(t,G.makeRange({protocol:"patch:",source:G.stringifyDescriptor(t),selector:`optional!builtin`,params:null}))}},Tgt=Rgt;var dH={};Vt(dH,{ConstraintsCheckCommand:()=>OE,ConstraintsQueryCommand:()=>LE,ConstraintsSourceCommand:()=>ME,default:()=>adt});Ge();Ge();l2();var FE=class{constructor(e){this.project=e}createEnvironment(){let e=new QE(["cwd","ident"]),r=new QE(["workspace","type","ident"]),o=new QE(["ident"]),a={manifestUpdates:new Map,reportedErrors:new Map},n=new Map,u=new Map;for(let A of this.project.storedPackages.values()){let p=Array.from(A.peerDependencies.values(),h=>[G.stringifyIdent(h),h.range]);n.set(A.locatorHash,{workspace:null,ident:G.stringifyIdent(A),version:A.version,dependencies:new Map,peerDependencies:new Map(p.filter(([h])=>A.peerDependenciesMeta.get(h)?.optional!==!0)),optionalPeerDependencies:new Map(p.filter(([h])=>A.peerDependenciesMeta.get(h)?.optional===!0))})}for(let A of this.project.storedPackages.values()){let p=n.get(A.locatorHash);p.dependencies=new Map(Array.from(A.dependencies.values(),h=>{let E=this.project.storedResolutions.get(h.descriptorHash);if(typeof E>"u")throw new Error("Assertion failed: The resolution should have been registered");let I=n.get(E);if(typeof I>"u")throw new Error("Assertion failed: The package should have been registered");return[G.stringifyIdent(h),I]})),p.dependencies.delete(p.ident)}for(let A of this.project.workspaces){let p=G.stringifyIdent(A.anchoredLocator),h=A.manifest.exportTo({}),E=n.get(A.anchoredLocator.locatorHash);if(typeof E>"u")throw new Error("Assertion failed: The package should have been registered");let I=(R,L,{caller:U=Xi.getCaller()}={})=>{let z=a2(R),te=He.getMapWithDefault(a.manifestUpdates,A.cwd),ae=He.getMapWithDefault(te,z),le=He.getSetWithDefault(ae,L);U!==null&&le.add(U)},v=R=>I(R,void 0,{caller:Xi.getCaller()}),x=R=>{He.getArrayWithDefault(a.reportedErrors,A.cwd).push(R)},C=e.insert({cwd:A.relativeCwd,ident:p,manifest:h,pkg:E,set:I,unset:v,error:x});u.set(A,C);for(let R of Ut.allDependencies)for(let L of A.manifest[R].values()){let U=G.stringifyIdent(L),z=()=>{I([R,U],void 0,{caller:Xi.getCaller()})},te=le=>{I([R,U],le,{caller:Xi.getCaller()})},ae=null;if(R!=="peerDependencies"&&(R!=="dependencies"||!A.manifest.devDependencies.has(L.identHash))){let le=A.anchoredPackage.dependencies.get(L.identHash);if(le){if(typeof le>"u")throw new Error("Assertion failed: The dependency should have been registered");let ce=this.project.storedResolutions.get(le.descriptorHash);if(typeof ce>"u")throw new Error("Assertion failed: The resolution should have been registered");let Ce=n.get(ce);if(typeof Ce>"u")throw new Error("Assertion failed: The package should have been registered");ae=Ce}}r.insert({workspace:C,ident:U,range:L.range,type:R,resolution:ae,update:te,delete:z,error:x})}}for(let A of this.project.storedPackages.values()){let p=this.project.tryWorkspaceByLocator(A);if(!p)continue;let h=u.get(p);if(typeof h>"u")throw new Error("Assertion failed: The workspace should have been registered");let E=n.get(A.locatorHash);if(typeof E>"u")throw new Error("Assertion failed: The package should have been registered");E.workspace=h}return{workspaces:e,dependencies:r,packages:o,result:a}}async process(){let e=this.createEnvironment(),r={Yarn:{workspace:a=>e.workspaces.find(a)[0]??null,workspaces:a=>e.workspaces.find(a),dependency:a=>e.dependencies.find(a)[0]??null,dependencies:a=>e.dependencies.find(a),package:a=>e.packages.find(a)[0]??null,packages:a=>e.packages.find(a)}},o=await this.project.loadUserConfig();return o?.constraints?(await o.constraints(r),e.result):null}};Ge();Ge();qt();var LE=class extends ut{constructor(){super(...arguments);this.json=ge.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.query=ge.String()}static{this.paths=[["constraints","query"]]}static{this.usage=it.Usage({category:"Constraints-related commands",description:"query the constraints fact database",details:` + This command will output all matches to the given prolog query. + `,examples:[["List all dependencies throughout the workspace","yarn constraints query 'workspace_has_dependency(_, DependencyName, _, _).'"]]})}async execute(){let{Constraints:r}=await Promise.resolve().then(()=>(f2(),A2)),o=await Ke.find(this.context.cwd,this.context.plugins),{project:a}=await kt.find(o,this.context.cwd),n=await r.find(a),u=this.query;return u.endsWith(".")||(u=`${u}.`),(await Rt.start({configuration:o,json:this.json,stdout:this.context.stdout},async p=>{for await(let h of n.query(u)){let E=Array.from(Object.entries(h)),I=E.length,v=E.reduce((x,[C])=>Math.max(x,C.length),0);for(let x=0;x(f2(),A2)),o=await Ke.find(this.context.cwd,this.context.plugins),{project:a}=await kt.find(o,this.context.cwd),n=await r.find(a);this.context.stdout.write(this.verbose?n.fullSource:n.source)}};Ge();Ge();qt();l2();var OE=class extends ut{constructor(){super(...arguments);this.fix=ge.Boolean("--fix",!1,{description:"Attempt to automatically fix unambiguous issues, following a multi-pass process"});this.json=ge.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"})}static{this.paths=[["constraints"]]}static{this.usage=it.Usage({category:"Constraints-related commands",description:"check that the project constraints are met",details:` + This command will run constraints on your project and emit errors for each one that is found but isn't met. If any error is emitted the process will exit with a non-zero exit code. + + If the \`--fix\` flag is used, Yarn will attempt to automatically fix the issues the best it can, following a multi-pass process (with a maximum of 10 iterations). Some ambiguous patterns cannot be autofixed, in which case you'll have to manually specify the right resolution. + + For more information as to how to write constraints, please consult our dedicated page on our website: https://yarnpkg.com/features/constraints. + `,examples:[["Check that all constraints are satisfied","yarn constraints"],["Autofix all unmet constraints","yarn constraints --fix"]]})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins),{project:o}=await kt.find(r,this.context.cwd);await o.restoreInstallState();let a=await o.loadUserConfig(),n;if(a?.constraints)n=new FE(o);else{let{Constraints:h}=await Promise.resolve().then(()=>(f2(),A2));n=await h.find(o)}let u,A=!1,p=!1;for(let h=this.fix?10:1;h>0;--h){let E=await n.process();if(!E)break;let{changedWorkspaces:I,remainingErrors:v}=ik(o,E,{fix:this.fix}),x=[];for(let[C,R]of I){let L=C.manifest.indent;C.manifest=new Ut,C.manifest.indent=L,C.manifest.load(R),x.push(C.persistManifest())}if(await Promise.all(x),!(I.size>0&&h>1)){u=Wde(v,{configuration:r}),A=!1,p=!0;for(let[,C]of v)for(let R of C)R.fixable?A=!0:p=!1}}if(u.children.length===0)return 0;if(A){let h=p?`Those errors can all be fixed by running ${pe.pretty(r,"yarn constraints --fix",pe.Type.CODE)}`:`Errors prefixed by '\u2699' can be fixed by running ${pe.pretty(r,"yarn constraints --fix",pe.Type.CODE)}`;await Rt.start({configuration:r,stdout:this.context.stdout,includeNames:!1,includeFooter:!1},async E=>{E.reportInfo(0,h),E.reportSeparator()})}return u.children=He.sortMap(u.children,h=>h.value[1]),fs.emitTree(u,{configuration:r,stdout:this.context.stdout,json:this.json,separators:1}),1}};l2();var odt={configuration:{enableConstraintsChecks:{description:"If true, constraints will run during installs",type:"BOOLEAN",default:!1},constraintsPath:{description:"The path of the constraints file.",type:"ABSOLUTE_PATH",default:"./constraints.pro"}},commands:[LE,ME,OE],hooks:{async validateProjectAfterInstall(t,{reportError:e}){if(!t.configuration.get("enableConstraintsChecks"))return;let r=await t.loadUserConfig(),o;if(r?.constraints)o=new FE(t);else{let{Constraints:u}=await Promise.resolve().then(()=>(f2(),A2));o=await u.find(t)}let a=await o.process();if(!a)return;let{remainingErrors:n}=ik(t,a);if(n.size!==0)if(t.configuration.isCI)for(let[u,A]of n)for(let p of A)e(84,`${pe.pretty(t.configuration,u.anchoredLocator,pe.Type.IDENT)}: ${p.text}`);else e(84,`Constraint check failed; run ${pe.pretty(t.configuration,"yarn constraints",pe.Type.CODE)} for more details`)}}},adt=odt;var mH={};Vt(mH,{CreateCommand:()=>UE,DlxCommand:()=>_E,default:()=>cdt});Ge();qt();var UE=class extends ut{constructor(){super(...arguments);this.pkg=ge.String("-p,--package",{description:"The package to run the provided command from"});this.quiet=ge.Boolean("-q,--quiet",!1,{description:"Only report critical errors instead of printing the full install logs"});this.command=ge.String();this.args=ge.Proxy()}static{this.paths=[["create"]]}async execute(){let r=[];this.pkg&&r.push("--package",this.pkg),this.quiet&&r.push("--quiet");let o=this.command.replace(/^(@[^@/]+)(@|$)/,"$1/create$2"),a=G.parseDescriptor(o),n=a.name.match(/^create(-|$)/)?a:a.scope?G.makeIdent(a.scope,`create-${a.name}`):G.makeIdent(null,`create-${a.name}`),u=G.stringifyIdent(n);return a.range!=="unknown"&&(u+=`@${a.range}`),this.cli.run(["dlx",...r,u,...this.args])}};Ge();Ge();Pt();qt();var _E=class extends ut{constructor(){super(...arguments);this.packages=ge.Array("-p,--package",{description:"The package(s) to install before running the command"});this.quiet=ge.Boolean("-q,--quiet",!1,{description:"Only report critical errors instead of printing the full install logs"});this.command=ge.String();this.args=ge.Proxy()}static{this.paths=[["dlx"]]}static{this.usage=it.Usage({description:"run a package in a temporary environment",details:"\n This command will install a package within a temporary environment, and run its binary script if it contains any. The binary will run within the current cwd.\n\n By default Yarn will download the package named `command`, but this can be changed through the use of the `-p,--package` flag which will instruct Yarn to still run the same command but from a different package.\n\n Using `yarn dlx` as a replacement of `yarn add` isn't recommended, as it makes your project non-deterministic (Yarn doesn't keep track of the packages installed through `dlx` - neither their name, nor their version).\n ",examples:[["Use create-react-app to create a new React app","yarn dlx create-react-app ./my-app"],["Install multiple packages for a single command",`yarn dlx -p typescript -p ts-node ts-node --transpile-only -e "console.log('hello!')"`]]})}async execute(){return Ke.telemetry=null,await oe.mktempPromise(async r=>{let o=V.join(r,`dlx-${process.pid}`);await oe.mkdirPromise(o),await oe.writeFilePromise(V.join(o,"package.json"),`{} +`),await oe.writeFilePromise(V.join(o,"yarn.lock"),"");let a=V.join(o,".yarnrc.yml"),n=await Ke.findProjectCwd(this.context.cwd),A={enableGlobalCache:!(await Ke.find(this.context.cwd,null,{strict:!1})).get("enableGlobalCache"),enableTelemetry:!1,logFilters:[{code:Ku(68),level:pe.LogLevel.Discard}]},p=n!==null?V.join(n,".yarnrc.yml"):null;p!==null&&oe.existsSync(p)?(await oe.copyFilePromise(p,a),await Ke.updateConfiguration(o,L=>{let U=He.toMerged(L,A);return Array.isArray(L.plugins)&&(U.plugins=L.plugins.map(z=>{let te=typeof z=="string"?z:z.path,ae=ue.isAbsolute(te)?te:ue.resolve(ue.fromPortablePath(n),te);return typeof z=="string"?ae:{path:ae,spec:z.spec}})),U})):await oe.writeJsonPromise(a,A);let h=this.packages??[this.command],E=G.parseDescriptor(this.command).name,I=await this.cli.run(["add","--fixed","--",...h],{cwd:o,quiet:this.quiet});if(I!==0)return I;this.quiet||this.context.stdout.write(` +`);let v=await Ke.find(o,this.context.plugins),{project:x,workspace:C}=await kt.find(v,o);if(C===null)throw new sr(x.cwd,o);await x.restoreInstallState();let R=await An.getWorkspaceAccessibleBinaries(C);return R.has(E)===!1&&R.size===1&&typeof this.packages>"u"&&(E=Array.from(R)[0][0]),await An.executeWorkspaceAccessibleBinary(C,E,this.args,{packageAccessibleBinaries:R,cwd:this.context.cwd,stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr})})}};var ldt={commands:[UE,_E]},cdt=ldt;var CH={};Vt(CH,{ExecFetcher:()=>h2,ExecResolver:()=>g2,default:()=>fdt,execUtils:()=>lk});Ge();Ge();Pt();var fA="exec:";var lk={};Vt(lk,{loadGeneratorFile:()=>p2,makeLocator:()=>EH,makeSpec:()=>yme,parseSpec:()=>yH});Ge();Pt();function yH(t){let{params:e,selector:r}=G.parseRange(t),o=ue.toPortablePath(r);return{parentLocator:e&&typeof e.locator=="string"?G.parseLocator(e.locator):null,path:o}}function yme({parentLocator:t,path:e,generatorHash:r,protocol:o}){let a=t!==null?{locator:G.stringifyLocator(t)}:{},n=typeof r<"u"?{hash:r}:{};return G.makeRange({protocol:o,source:e,selector:e,params:{...n,...a}})}function EH(t,{parentLocator:e,path:r,generatorHash:o,protocol:a}){return G.makeLocator(t,yme({parentLocator:e,path:r,generatorHash:o,protocol:a}))}async function p2(t,e,r){let{parentLocator:o,path:a}=G.parseFileStyleRange(t,{protocol:e}),n=V.isAbsolute(a)?{packageFs:new gn(It.root),prefixPath:It.dot,localPath:It.root}:await r.fetcher.fetch(o,r),u=n.localPath?{packageFs:new gn(It.root),prefixPath:V.relative(It.root,n.localPath)}:n;n!==u&&n.releaseFs&&n.releaseFs();let A=u.packageFs,p=V.join(u.prefixPath,a);return await A.readFilePromise(p,"utf8")}var h2=class{supports(e,r){return!!e.reference.startsWith(fA)}getLocalPath(e,r){let{parentLocator:o,path:a}=G.parseFileStyleRange(e.reference,{protocol:fA});if(V.isAbsolute(a))return a;let n=r.fetcher.getLocalPath(o,r);return n===null?null:V.resolve(n,a)}async fetch(e,r){let o=r.checksums.get(e.locatorHash)||null,[a,n,u]=await r.cache.fetchPackageFromCache(e,o,{onHit:()=>r.report.reportCacheHit(e),onMiss:()=>r.report.reportCacheMiss(e),loader:()=>this.fetchFromDisk(e,r),...r.cacheOptions});return{packageFs:a,releaseFs:n,prefixPath:G.getIdentVendorPath(e),localPath:this.getLocalPath(e,r),checksum:u}}async fetchFromDisk(e,r){let o=await p2(e.reference,fA,r);return oe.mktempPromise(async a=>{let n=V.join(a,"generator.js");return await oe.writeFilePromise(n,o),oe.mktempPromise(async u=>{if(await this.generatePackage(u,e,n,r),!oe.existsSync(V.join(u,"build")))throw new Error("The script should have generated a build directory");return await $i.makeArchiveFromDirectory(V.join(u,"build"),{prefixPath:G.getIdentVendorPath(e),compressionLevel:r.project.configuration.get("compressionLevel")})})})}async generatePackage(e,r,o,a){return await oe.mktempPromise(async n=>{let u=await An.makeScriptEnv({project:a.project,binFolder:n}),A=V.join(e,"runtime.js");return await oe.mktempPromise(async p=>{let h=V.join(p,"buildfile.log"),E=V.join(e,"generator"),I=V.join(e,"build");await oe.mkdirPromise(E),await oe.mkdirPromise(I);let v={tempDir:ue.fromPortablePath(E),buildDir:ue.fromPortablePath(I),locator:G.stringifyLocator(r)};await oe.writeFilePromise(A,` + // Expose 'Module' as a global variable + Object.defineProperty(global, 'Module', { + get: () => require('module'), + configurable: true, + enumerable: false, + }); + + // Expose non-hidden built-in modules as global variables + for (const name of Module.builtinModules.filter((name) => name !== 'module' && !name.startsWith('_'))) { + Object.defineProperty(global, name, { + get: () => require(name), + configurable: true, + enumerable: false, + }); + } + + // Expose the 'execEnv' global variable + Object.defineProperty(global, 'execEnv', { + value: { + ...${JSON.stringify(v)}, + }, + enumerable: true, + }); + `);let x=u.NODE_OPTIONS||"",C=/\s*--require\s+\S*\.pnp\.c?js\s*/g;x=x.replace(C," ").trim(),u.NODE_OPTIONS=x;let{stdout:R,stderr:L}=a.project.configuration.getSubprocessStreams(h,{header:`# This file contains the result of Yarn generating a package (${G.stringifyLocator(r)}) +`,prefix:G.prettyLocator(a.project.configuration,r),report:a.report}),{code:U}=await Ur.pipevp(process.execPath,["--require",ue.fromPortablePath(A),ue.fromPortablePath(o),G.stringifyIdent(r)],{cwd:e,env:u,stdin:null,stdout:R,stderr:L});if(U!==0)throw oe.detachTemp(p),new Error(`Package generation failed (exit code ${U}, logs can be found here: ${pe.pretty(a.project.configuration,h,pe.Type.PATH)})`)})})}};Ge();Ge();var udt=2,g2=class{supportsDescriptor(e,r){return!!e.range.startsWith(fA)}supportsLocator(e,r){return!!e.reference.startsWith(fA)}shouldPersistResolution(e,r){return!1}bindDescriptor(e,r,o){return G.bindDescriptor(e,{locator:G.stringifyLocator(r)})}getResolutionDependencies(e,r){return{}}async getCandidates(e,r,o){if(!o.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let{path:a,parentLocator:n}=yH(e.range);if(n===null)throw new Error("Assertion failed: The descriptor should have been bound");let u=await p2(G.makeRange({protocol:fA,source:a,selector:a,params:{locator:G.stringifyLocator(n)}}),fA,o.fetchOptions),A=wn.makeHash(`${udt}`,u).slice(0,6);return[EH(e,{parentLocator:n,path:a,generatorHash:A,protocol:fA})]}async getSatisfying(e,r,o,a){let[n]=await this.getCandidates(e,r,a);return{locators:o.filter(u=>u.locatorHash===n.locatorHash),sorted:!1}}async resolve(e,r){if(!r.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let o=await r.fetchOptions.fetcher.fetch(e,r.fetchOptions),a=await He.releaseAfterUseAsync(async()=>await Ut.find(o.prefixPath,{baseFs:o.packageFs}),o.releaseFs);return{...e,version:a.version||"0.0.0",languageName:a.languageName||r.project.configuration.get("defaultLanguageName"),linkType:"HARD",conditions:a.getConditions(),dependencies:r.project.configuration.normalizeDependencyMap(a.dependencies),peerDependencies:a.peerDependencies,dependenciesMeta:a.dependenciesMeta,peerDependenciesMeta:a.peerDependenciesMeta,bin:a.bin}}};var Adt={fetchers:[h2],resolvers:[g2]},fdt=Adt;var IH={};Vt(IH,{FileFetcher:()=>E2,FileResolver:()=>C2,TarballFileFetcher:()=>w2,TarballFileResolver:()=>I2,default:()=>gdt,fileUtils:()=>Yg});Ge();Pt();var HE=/^(?:[a-zA-Z]:[\\/]|\.{0,2}\/)/,d2=/^[^?]*\.(?:tar\.gz|tgz)(?:::.*)?$/,Ui="file:";var Yg={};Vt(Yg,{fetchArchiveFromLocator:()=>y2,makeArchiveFromLocator:()=>ck,makeBufferFromLocator:()=>wH,makeLocator:()=>qE,makeSpec:()=>Eme,parseSpec:()=>m2});Ge();Pt();function m2(t){let{params:e,selector:r}=G.parseRange(t),o=ue.toPortablePath(r);return{parentLocator:e&&typeof e.locator=="string"?G.parseLocator(e.locator):null,path:o}}function Eme({parentLocator:t,path:e,hash:r,protocol:o}){let a=t!==null?{locator:G.stringifyLocator(t)}:{},n=typeof r<"u"?{hash:r}:{};return G.makeRange({protocol:o,source:e,selector:e,params:{...n,...a}})}function qE(t,{parentLocator:e,path:r,hash:o,protocol:a}){return G.makeLocator(t,Eme({parentLocator:e,path:r,hash:o,protocol:a}))}async function y2(t,e){let{parentLocator:r,path:o}=G.parseFileStyleRange(t.reference,{protocol:Ui}),a=V.isAbsolute(o)?{packageFs:new gn(It.root),prefixPath:It.dot,localPath:It.root}:await e.fetcher.fetch(r,e),n=a.localPath?{packageFs:new gn(It.root),prefixPath:V.relative(It.root,a.localPath)}:a;a!==n&&a.releaseFs&&a.releaseFs();let u=n.packageFs,A=V.join(n.prefixPath,o);return await He.releaseAfterUseAsync(async()=>await u.readFilePromise(A),n.releaseFs)}async function ck(t,{protocol:e,fetchOptions:r,inMemory:o=!1}){let{parentLocator:a,path:n}=G.parseFileStyleRange(t.reference,{protocol:e}),u=V.isAbsolute(n)?{packageFs:new gn(It.root),prefixPath:It.dot,localPath:It.root}:await r.fetcher.fetch(a,r),A=u.localPath?{packageFs:new gn(It.root),prefixPath:V.relative(It.root,u.localPath)}:u;u!==A&&u.releaseFs&&u.releaseFs();let p=A.packageFs,h=V.join(A.prefixPath,n);return await He.releaseAfterUseAsync(async()=>await $i.makeArchiveFromDirectory(h,{baseFs:p,prefixPath:G.getIdentVendorPath(t),compressionLevel:r.project.configuration.get("compressionLevel"),inMemory:o}),A.releaseFs)}async function wH(t,{protocol:e,fetchOptions:r}){return(await ck(t,{protocol:e,fetchOptions:r,inMemory:!0})).getBufferAndClose()}var E2=class{supports(e,r){return!!e.reference.startsWith(Ui)}getLocalPath(e,r){let{parentLocator:o,path:a}=G.parseFileStyleRange(e.reference,{protocol:Ui});if(V.isAbsolute(a))return a;let n=r.fetcher.getLocalPath(o,r);return n===null?null:V.resolve(n,a)}async fetch(e,r){let o=r.checksums.get(e.locatorHash)||null,[a,n,u]=await r.cache.fetchPackageFromCache(e,o,{onHit:()=>r.report.reportCacheHit(e),onMiss:()=>r.report.reportCacheMiss(e,`${G.prettyLocator(r.project.configuration,e)} can't be found in the cache and will be fetched from the disk`),loader:()=>this.fetchFromDisk(e,r),...r.cacheOptions});return{packageFs:a,releaseFs:n,prefixPath:G.getIdentVendorPath(e),localPath:this.getLocalPath(e,r),checksum:u}}async fetchFromDisk(e,r){return ck(e,{protocol:Ui,fetchOptions:r})}};Ge();Ge();var pdt=2,C2=class{supportsDescriptor(e,r){return e.range.match(HE)?!0:!!e.range.startsWith(Ui)}supportsLocator(e,r){return!!e.reference.startsWith(Ui)}shouldPersistResolution(e,r){return!1}bindDescriptor(e,r,o){return HE.test(e.range)&&(e=G.makeDescriptor(e,`${Ui}${e.range}`)),G.bindDescriptor(e,{locator:G.stringifyLocator(r)})}getResolutionDependencies(e,r){return{}}async getCandidates(e,r,o){if(!o.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let{path:a,parentLocator:n}=m2(e.range);if(n===null)throw new Error("Assertion failed: The descriptor should have been bound");let u=await wH(G.makeLocator(e,G.makeRange({protocol:Ui,source:a,selector:a,params:{locator:G.stringifyLocator(n)}})),{protocol:Ui,fetchOptions:o.fetchOptions}),A=wn.makeHash(`${pdt}`,u).slice(0,6);return[qE(e,{parentLocator:n,path:a,hash:A,protocol:Ui})]}async getSatisfying(e,r,o,a){let[n]=await this.getCandidates(e,r,a);return{locators:o.filter(u=>u.locatorHash===n.locatorHash),sorted:!1}}async resolve(e,r){if(!r.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let o=await r.fetchOptions.fetcher.fetch(e,r.fetchOptions),a=await He.releaseAfterUseAsync(async()=>await Ut.find(o.prefixPath,{baseFs:o.packageFs}),o.releaseFs);return{...e,version:a.version||"0.0.0",languageName:a.languageName||r.project.configuration.get("defaultLanguageName"),linkType:"HARD",conditions:a.getConditions(),dependencies:r.project.configuration.normalizeDependencyMap(a.dependencies),peerDependencies:a.peerDependencies,dependenciesMeta:a.dependenciesMeta,peerDependenciesMeta:a.peerDependenciesMeta,bin:a.bin}}};Ge();var w2=class{supports(e,r){return d2.test(e.reference)?!!e.reference.startsWith(Ui):!1}getLocalPath(e,r){return null}async fetch(e,r){let o=r.checksums.get(e.locatorHash)||null,[a,n,u]=await r.cache.fetchPackageFromCache(e,o,{onHit:()=>r.report.reportCacheHit(e),onMiss:()=>r.report.reportCacheMiss(e,`${G.prettyLocator(r.project.configuration,e)} can't be found in the cache and will be fetched from the disk`),loader:()=>this.fetchFromDisk(e,r),...r.cacheOptions});return{packageFs:a,releaseFs:n,prefixPath:G.getIdentVendorPath(e),checksum:u}}async fetchFromDisk(e,r){let o=await y2(e,r);return await $i.convertToZip(o,{configuration:r.project.configuration,prefixPath:G.getIdentVendorPath(e),stripComponents:1})}};Ge();Ge();Ge();var I2=class{supportsDescriptor(e,r){return d2.test(e.range)?!!(e.range.startsWith(Ui)||HE.test(e.range)):!1}supportsLocator(e,r){return d2.test(e.reference)?!!e.reference.startsWith(Ui):!1}shouldPersistResolution(e,r){return!1}bindDescriptor(e,r,o){return HE.test(e.range)&&(e=G.makeDescriptor(e,`${Ui}${e.range}`)),G.bindDescriptor(e,{locator:G.stringifyLocator(r)})}getResolutionDependencies(e,r){return{}}async getCandidates(e,r,o){if(!o.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let{path:a,parentLocator:n}=m2(e.range);if(n===null)throw new Error("Assertion failed: The descriptor should have been bound");let u=qE(e,{parentLocator:n,path:a,hash:"",protocol:Ui}),A=await y2(u,o.fetchOptions),p=wn.makeHash(A).slice(0,6);return[qE(e,{parentLocator:n,path:a,hash:p,protocol:Ui})]}async getSatisfying(e,r,o,a){let[n]=await this.getCandidates(e,r,a);return{locators:o.filter(u=>u.locatorHash===n.locatorHash),sorted:!1}}async resolve(e,r){if(!r.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let o=await r.fetchOptions.fetcher.fetch(e,r.fetchOptions),a=await He.releaseAfterUseAsync(async()=>await Ut.find(o.prefixPath,{baseFs:o.packageFs}),o.releaseFs);return{...e,version:a.version||"0.0.0",languageName:a.languageName||r.project.configuration.get("defaultLanguageName"),linkType:"HARD",conditions:a.getConditions(),dependencies:r.project.configuration.normalizeDependencyMap(a.dependencies),peerDependencies:a.peerDependencies,dependenciesMeta:a.dependenciesMeta,peerDependenciesMeta:a.peerDependenciesMeta,bin:a.bin}}};var hdt={fetchers:[w2,E2],resolvers:[I2,C2]},gdt=hdt;var DH={};Vt(DH,{GithubFetcher:()=>B2,default:()=>mdt,githubUtils:()=>uk});Ge();Pt();var uk={};Vt(uk,{invalidGithubUrlMessage:()=>Ime,isGithubUrl:()=>BH,parseGithubUrl:()=>vH});var Cme=Ze(ve("querystring")),wme=[/^https?:\/\/(?:([^/]+?)@)?github.com\/([^/#]+)\/([^/#]+)\/tarball\/([^/#]+)(?:#(.*))?$/,/^https?:\/\/(?:([^/]+?)@)?github.com\/([^/#]+)\/([^/#]+?)(?:\.git)?(?:#(.*))?$/];function BH(t){return t?wme.some(e=>!!t.match(e)):!1}function vH(t){let e;for(let A of wme)if(e=t.match(A),e)break;if(!e)throw new Error(Ime(t));let[,r,o,a,n="master"]=e,{commit:u}=Cme.default.parse(n);return n=u||n.replace(/[^:]*:/,""),{auth:r,username:o,reponame:a,treeish:n}}function Ime(t){return`Input cannot be parsed as a valid GitHub URL ('${t}').`}var B2=class{supports(e,r){return!!BH(e.reference)}getLocalPath(e,r){return null}async fetch(e,r){let o=r.checksums.get(e.locatorHash)||null,[a,n,u]=await r.cache.fetchPackageFromCache(e,o,{onHit:()=>r.report.reportCacheHit(e),onMiss:()=>r.report.reportCacheMiss(e,`${G.prettyLocator(r.project.configuration,e)} can't be found in the cache and will be fetched from GitHub`),loader:()=>this.fetchFromNetwork(e,r),...r.cacheOptions});return{packageFs:a,releaseFs:n,prefixPath:G.getIdentVendorPath(e),checksum:u}}async fetchFromNetwork(e,r){let o=await sn.get(this.getLocatorUrl(e,r),{configuration:r.project.configuration});return await oe.mktempPromise(async a=>{let n=new gn(a);await $i.extractArchiveTo(o,n,{stripComponents:1});let u=ia.splitRepoUrl(e.reference),A=V.join(a,"package.tgz");await An.prepareExternalProject(a,A,{configuration:r.project.configuration,report:r.report,workspace:u.extra.workspace,locator:e});let p=await oe.readFilePromise(A);return await $i.convertToZip(p,{configuration:r.project.configuration,prefixPath:G.getIdentVendorPath(e),stripComponents:1})})}getLocatorUrl(e,r){let{auth:o,username:a,reponame:n,treeish:u}=vH(e.reference);return`https://${o?`${o}@`:""}github.com/${a}/${n}/archive/${u}.tar.gz`}};var ddt={hooks:{async fetchHostedRepository(t,e,r){if(t!==null)return t;let o=new B2;if(!o.supports(e,r))return null;try{return await o.fetch(e,r)}catch{return null}}}},mdt=ddt;var PH={};Vt(PH,{TarballHttpFetcher:()=>D2,TarballHttpResolver:()=>P2,default:()=>Edt});Ge();function v2(t){let e;try{e=new URL(t)}catch{return!1}return!(e.protocol!=="http:"&&e.protocol!=="https:"||!e.pathname.match(/(\.tar\.gz|\.tgz|\/[^.]+)$/))}var D2=class{supports(e,r){return v2(e.reference)}getLocalPath(e,r){return null}async fetch(e,r){let o=r.checksums.get(e.locatorHash)||null,[a,n,u]=await r.cache.fetchPackageFromCache(e,o,{onHit:()=>r.report.reportCacheHit(e),onMiss:()=>r.report.reportCacheMiss(e,`${G.prettyLocator(r.project.configuration,e)} can't be found in the cache and will be fetched from the remote server`),loader:()=>this.fetchFromNetwork(e,r),...r.cacheOptions});return{packageFs:a,releaseFs:n,prefixPath:G.getIdentVendorPath(e),checksum:u}}async fetchFromNetwork(e,r){let o=await sn.get(e.reference,{configuration:r.project.configuration});return await $i.convertToZip(o,{configuration:r.project.configuration,prefixPath:G.getIdentVendorPath(e),stripComponents:1})}};Ge();Ge();var P2=class{supportsDescriptor(e,r){return v2(e.range)}supportsLocator(e,r){return v2(e.reference)}shouldPersistResolution(e,r){return!0}bindDescriptor(e,r,o){return e}getResolutionDependencies(e,r){return{}}async getCandidates(e,r,o){return[G.convertDescriptorToLocator(e)]}async getSatisfying(e,r,o,a){let[n]=await this.getCandidates(e,r,a);return{locators:o.filter(u=>u.locatorHash===n.locatorHash),sorted:!1}}async resolve(e,r){if(!r.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let o=await r.fetchOptions.fetcher.fetch(e,r.fetchOptions),a=await He.releaseAfterUseAsync(async()=>await Ut.find(o.prefixPath,{baseFs:o.packageFs}),o.releaseFs);return{...e,version:a.version||"0.0.0",languageName:a.languageName||r.project.configuration.get("defaultLanguageName"),linkType:"HARD",conditions:a.getConditions(),dependencies:r.project.configuration.normalizeDependencyMap(a.dependencies),peerDependencies:a.peerDependencies,dependenciesMeta:a.dependenciesMeta,peerDependenciesMeta:a.peerDependenciesMeta,bin:a.bin}}};var ydt={fetchers:[D2],resolvers:[P2]},Edt=ydt;var bH={};Vt(bH,{InitCommand:()=>jE,default:()=>wdt});Ge();Ge();Pt();qt();var jE=class extends ut{constructor(){super(...arguments);this.private=ge.Boolean("-p,--private",!1,{description:"Initialize a private package"});this.workspace=ge.Boolean("-w,--workspace",!1,{description:"Initialize a workspace root with a `packages/` directory"});this.install=ge.String("-i,--install",!1,{tolerateBoolean:!0,description:"Initialize a package with a specific bundle that will be locked in the project"});this.name=ge.String("-n,--name",{description:"Initialize a package with the given name"});this.usev2=ge.Boolean("-2",!1,{hidden:!0});this.yes=ge.Boolean("-y,--yes",{hidden:!0})}static{this.paths=[["init"]]}static{this.usage=it.Usage({description:"create a new package",details:"\n This command will setup a new package in your local directory.\n\n If the `-p,--private` or `-w,--workspace` options are set, the package will be private by default.\n\n If the `-w,--workspace` option is set, the package will be configured to accept a set of workspaces in the `packages/` directory.\n\n If the `-i,--install` option is given a value, Yarn will first download it using `yarn set version` and only then forward the init call to the newly downloaded bundle. Without arguments, the downloaded bundle will be `latest`.\n\n The initial settings of the manifest can be changed by using the `initScope` and `initFields` configuration values. Additionally, Yarn will generate an EditorConfig file whose rules can be altered via `initEditorConfig`, and will initialize a Git repository in the current directory.\n ",examples:[["Create a new package in the local directory","yarn init"],["Create a new private package in the local directory","yarn init -p"],["Create a new package and store the Yarn release inside","yarn init -i=latest"],["Create a new private package and defines it as a workspace root","yarn init -w"]]})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins),o=typeof this.install=="string"?this.install:this.usev2||this.install===!0?"latest":null;return o!==null?await this.executeProxy(r,o):await this.executeRegular(r)}async executeProxy(r,o){if(r.projectCwd!==null&&r.projectCwd!==this.context.cwd)throw new st("Cannot use the --install flag from within a project subdirectory");oe.existsSync(this.context.cwd)||await oe.mkdirPromise(this.context.cwd,{recursive:!0});let a=V.join(this.context.cwd,dr.lockfile);oe.existsSync(a)||await oe.writeFilePromise(a,"");let n=await this.cli.run(["set","version",o],{quiet:!0});if(n!==0)return n;let u=[];return this.private&&u.push("-p"),this.workspace&&u.push("-w"),this.name&&u.push(`-n=${this.name}`),this.yes&&u.push("-y"),await oe.mktempPromise(async A=>{let{code:p}=await Ur.pipevp("yarn",["init",...u],{cwd:this.context.cwd,stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr,env:await An.makeScriptEnv({binFolder:A})});return p})}async executeRegular(r){let o=null;try{o=(await kt.find(r,this.context.cwd)).project}catch{o=null}oe.existsSync(this.context.cwd)||await oe.mkdirPromise(this.context.cwd,{recursive:!0});let a=await Ut.tryFind(this.context.cwd),n=a??new Ut,u=Object.fromEntries(r.get("initFields").entries());n.load(u),n.name=n.name??G.makeIdent(r.get("initScope"),this.name??V.basename(this.context.cwd)),n.packageManager=nn&&He.isTaggedYarnVersion(nn)?`yarn@${nn}`:null,(!a&&this.workspace||this.private)&&(n.private=!0),this.workspace&&n.workspaceDefinitions.length===0&&(await oe.mkdirPromise(V.join(this.context.cwd,"packages"),{recursive:!0}),n.workspaceDefinitions=[{pattern:"packages/*"}]);let A={};n.exportTo(A);let p=V.join(this.context.cwd,Ut.fileName);await oe.changeFilePromise(p,`${JSON.stringify(A,null,2)} +`,{automaticNewlines:!0});let h=[p],E=V.join(this.context.cwd,"README.md");if(oe.existsSync(E)||(await oe.writeFilePromise(E,`# ${G.stringifyIdent(n.name)} +`),h.push(E)),!o||o.cwd===this.context.cwd){let I=V.join(this.context.cwd,dr.lockfile);oe.existsSync(I)||(await oe.writeFilePromise(I,""),h.push(I));let x=[".yarn/*","!.yarn/patches","!.yarn/plugins","!.yarn/releases","!.yarn/sdks","!.yarn/versions","","# Swap the comments on the following lines if you wish to use zero-installs","# In that case, don't forget to run `yarn config set enableGlobalCache false`!","# Documentation here: https://yarnpkg.com/features/caching#zero-installs","","#!.yarn/cache",".pnp.*"].map(le=>`${le} +`).join(""),C=V.join(this.context.cwd,".gitignore");oe.existsSync(C)||(await oe.writeFilePromise(C,x),h.push(C));let L=["/.yarn/** linguist-vendored","/.yarn/releases/* binary","/.yarn/plugins/**/* binary","/.pnp.* binary linguist-generated"].map(le=>`${le} +`).join(""),U=V.join(this.context.cwd,".gitattributes");oe.existsSync(U)||(await oe.writeFilePromise(U,L),h.push(U));let z={"*":{endOfLine:"lf",insertFinalNewline:!0},"*.{js,json,yml}":{charset:"utf-8",indentStyle:"space",indentSize:2}};He.mergeIntoTarget(z,r.get("initEditorConfig"));let te=`root = true +`;for(let[le,ce]of Object.entries(z)){te+=` +[${le}] +`;for(let[Ce,de]of Object.entries(ce)){let Be=Ce.replace(/[A-Z]/g,Ee=>`_${Ee.toLowerCase()}`);te+=`${Be} = ${de} +`}}let ae=V.join(this.context.cwd,".editorconfig");oe.existsSync(ae)||(await oe.writeFilePromise(ae,te),h.push(ae)),await this.cli.run(["install"],{quiet:!0}),oe.existsSync(V.join(this.context.cwd,".git"))||(await Ur.execvp("git",["init"],{cwd:this.context.cwd}),await Ur.execvp("git",["add","--",...h],{cwd:this.context.cwd}),await Ur.execvp("git",["commit","--allow-empty","-m","First commit"],{cwd:this.context.cwd}))}}};var Cdt={configuration:{initScope:{description:"Scope used when creating packages via the init command",type:"STRING",default:null},initFields:{description:"Additional fields to set when creating packages via the init command",type:"MAP",valueDefinition:{description:"",type:"ANY"}},initEditorConfig:{description:"Extra rules to define in the generator editorconfig",type:"MAP",valueDefinition:{description:"",type:"ANY"}}},commands:[jE]},wdt=Cdt;var kq={};Vt(kq,{SearchCommand:()=>oC,UpgradeInteractiveCommand:()=>aC,default:()=>cIt});Ge();var vme=Ze(ve("os"));function GE({stdout:t}){if(vme.default.endianness()==="BE")throw new Error("Interactive commands cannot be used on big-endian systems because ink depends on yoga-layout-prebuilt which only supports little-endian architectures");if(!t.isTTY)throw new Error("Interactive commands can only be used inside a TTY environment")}qt();var Lye=Ze(YH()),WH={appId:"OFCNCOG2CU",apiKey:"6fe4476ee5a1832882e326b506d14126",indexName:"npm-search"},yyt=(0,Lye.default)(WH.appId,WH.apiKey).initIndex(WH.indexName),KH=async(t,e=0)=>await yyt.search(t,{analyticsTags:["yarn-plugin-interactive-tools"],attributesToRetrieve:["name","version","owner","repository","humanDownloadsLast30Days"],page:e,hitsPerPage:10});var vB=["regular","dev","peer"],oC=class extends ut{static{this.paths=[["search"]]}static{this.usage=it.Usage({category:"Interactive commands",description:"open the search interface",details:` + This command opens a fullscreen terminal interface where you can search for and install packages from the npm registry. + `,examples:[["Open the search window","yarn search"]]})}async execute(){GE(this.context);let{Gem:e}=await Promise.resolve().then(()=>(Zk(),Eq)),{ScrollableItems:r}=await Promise.resolve().then(()=>(rQ(),tQ)),{useKeypress:o}=await Promise.resolve().then(()=>(wB(),Xwe)),{useMinistore:a}=await Promise.resolve().then(()=>(Dq(),vq)),{renderForm:n}=await Promise.resolve().then(()=>(oQ(),sQ)),{default:u}=await Promise.resolve().then(()=>Ze(aIe())),{Box:A,Text:p}=await Promise.resolve().then(()=>Ze(ic())),{default:h,useEffect:E,useState:I}=await Promise.resolve().then(()=>Ze(an())),v=await Ke.find(this.context.cwd,this.context.plugins),x=()=>h.createElement(A,{flexDirection:"row"},h.createElement(A,{flexDirection:"column",width:48},h.createElement(A,null,h.createElement(p,null,"Press ",h.createElement(p,{bold:!0,color:"cyanBright"},""),"/",h.createElement(p,{bold:!0,color:"cyanBright"},"")," to move between packages.")),h.createElement(A,null,h.createElement(p,null,"Press ",h.createElement(p,{bold:!0,color:"cyanBright"},"")," to select a package.")),h.createElement(A,null,h.createElement(p,null,"Press ",h.createElement(p,{bold:!0,color:"cyanBright"},"")," again to change the target."))),h.createElement(A,{flexDirection:"column"},h.createElement(A,{marginLeft:1},h.createElement(p,null,"Press ",h.createElement(p,{bold:!0,color:"cyanBright"},"")," to install the selected packages.")),h.createElement(A,{marginLeft:1},h.createElement(p,null,"Press ",h.createElement(p,{bold:!0,color:"cyanBright"},"")," to abort.")))),C=()=>h.createElement(h.Fragment,null,h.createElement(A,{width:15},h.createElement(p,{bold:!0,underline:!0,color:"gray"},"Owner")),h.createElement(A,{width:11},h.createElement(p,{bold:!0,underline:!0,color:"gray"},"Version")),h.createElement(A,{width:10},h.createElement(p,{bold:!0,underline:!0,color:"gray"},"Downloads"))),R=()=>h.createElement(A,{width:17},h.createElement(p,{bold:!0,underline:!0,color:"gray"},"Target")),L=({hit:de,active:Be})=>{let[Ee,g]=a(de.name,null);o({active:Be},(Ae,ne)=>{if(ne.name!=="space")return;if(!Ee){g(vB[0]);return}let Z=vB.indexOf(Ee)+1;Z===vB.length?g(null):g(vB[Z])},[Ee,g]);let me=G.parseIdent(de.name),we=G.prettyIdent(v,me);return h.createElement(A,null,h.createElement(A,{width:45},h.createElement(p,{bold:!0,wrap:"wrap"},we)),h.createElement(A,{width:14,marginLeft:1},h.createElement(p,{bold:!0,wrap:"truncate"},de.owner.name)),h.createElement(A,{width:10,marginLeft:1},h.createElement(p,{italic:!0,wrap:"truncate"},de.version)),h.createElement(A,{width:16,marginLeft:1},h.createElement(p,null,de.humanDownloadsLast30Days)))},U=({name:de,active:Be})=>{let[Ee]=a(de,null),g=G.parseIdent(de);return h.createElement(A,null,h.createElement(A,{width:47},h.createElement(p,{bold:!0}," - ",G.prettyIdent(v,g))),vB.map(me=>h.createElement(A,{key:me,width:14,marginLeft:1},h.createElement(p,null," ",h.createElement(e,{active:Ee===me})," ",h.createElement(p,{bold:!0},me)))))},z=()=>h.createElement(A,{marginTop:1},h.createElement(p,null,"Powered by Algolia.")),ae=await n(({useSubmit:de})=>{let Be=a();de(Be);let Ee=Array.from(Be.keys()).filter(H=>Be.get(H)!==null),[g,me]=I(""),[we,Ae]=I(0),[ne,Z]=I([]),xe=H=>{H.match(/\t| /)||me(H)},Ne=async()=>{Ae(0);let H=await KH(g);H.query===g&&Z(H.hits)},ht=async()=>{let H=await KH(g,we+1);H.query===g&&H.page-1===we&&(Ae(H.page),Z([...ne,...H.hits]))};return E(()=>{g?Ne():Z([])},[g]),h.createElement(A,{flexDirection:"column"},h.createElement(x,null),h.createElement(A,{flexDirection:"row",marginTop:1},h.createElement(p,{bold:!0},"Search: "),h.createElement(A,{width:41},h.createElement(u,{value:g,onChange:xe,placeholder:"i.e. babel, webpack, react...",showCursor:!1})),h.createElement(C,null)),ne.length?h.createElement(r,{radius:2,loop:!1,children:ne.map(H=>h.createElement(L,{key:H.name,hit:H,active:!1})),willReachEnd:ht}):h.createElement(p,{color:"gray"},"Start typing..."),h.createElement(A,{flexDirection:"row",marginTop:1},h.createElement(A,{width:49},h.createElement(p,{bold:!0},"Selected:")),h.createElement(R,null)),Ee.length?Ee.map(H=>h.createElement(U,{key:H,name:H,active:!1})):h.createElement(p,{color:"gray"},"No selected packages..."),h.createElement(z,null))},{},{stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr});if(typeof ae>"u")return 1;let le=Array.from(ae.keys()).filter(de=>ae.get(de)==="regular"),ce=Array.from(ae.keys()).filter(de=>ae.get(de)==="dev"),Ce=Array.from(ae.keys()).filter(de=>ae.get(de)==="peer");return le.length&&await this.cli.run(["add",...le]),ce.length&&await this.cli.run(["add","--dev",...ce]),Ce&&await this.cli.run(["add","--peer",...Ce]),0}};Ge();qt();f_();var hIe=Ze(Jn()),pIe=/^((?:[\^~]|>=?)?)([0-9]+)(\.[0-9]+)(\.[0-9]+)((?:-\S+)?)$/,gIe=(t,e)=>t.length>0?[t.slice(0,e)].concat(gIe(t.slice(e),e)):[],aC=class extends ut{static{this.paths=[["upgrade-interactive"]]}static{this.usage=it.Usage({category:"Interactive commands",description:"open the upgrade interface",details:` + This command opens a fullscreen terminal interface where you can see any out of date packages used by your application, their status compared to the latest versions available on the remote registry, and select packages to upgrade. + `,examples:[["Open the upgrade window","yarn upgrade-interactive"]]})}async execute(){GE(this.context);let{ItemOptions:e}=await Promise.resolve().then(()=>(fIe(),AIe)),{Pad:r}=await Promise.resolve().then(()=>(xq(),uIe)),{ScrollableItems:o}=await Promise.resolve().then(()=>(rQ(),tQ)),{useMinistore:a}=await Promise.resolve().then(()=>(Dq(),vq)),{renderForm:n}=await Promise.resolve().then(()=>(oQ(),sQ)),{Box:u,Text:A}=await Promise.resolve().then(()=>Ze(ic())),{default:p,useEffect:h,useRef:E,useState:I}=await Promise.resolve().then(()=>Ze(an())),v=await Ke.find(this.context.cwd,this.context.plugins),{project:x,workspace:C}=await kt.find(v,this.context.cwd),R=await Gr.find(v);if(!C)throw new sr(x.cwd,this.context.cwd);await x.restoreInstallState({restoreResolutions:!1});let L=this.context.stdout.rows-7,U=(me,we)=>{let Ae=gpe(me,we),ne="";for(let Z of Ae)Z.added?ne+=pe.pretty(v,Z.value,"green"):Z.removed||(ne+=Z.value);return ne},z=(me,we)=>{if(me===we)return we;let Ae=G.parseRange(me),ne=G.parseRange(we),Z=Ae.selector.match(pIe),xe=ne.selector.match(pIe);if(!Z||!xe)return U(me,we);let Ne=["gray","red","yellow","green","magenta"],ht=null,H="";for(let rt=1;rt{let ne=await Zc.fetchDescriptorFrom(me,Ae,{project:x,cache:R,preserveModifier:we,workspace:C});return ne!==null?ne.range:me.range},ae=async me=>{let we=hIe.default.valid(me.range)?`^${me.range}`:me.range,[Ae,ne]=await Promise.all([te(me,me.range,we).catch(()=>null),te(me,me.range,"latest").catch(()=>null)]),Z=[{value:null,label:me.range}];return Ae&&Ae!==me.range?Z.push({value:Ae,label:z(me.range,Ae)}):Z.push({value:null,label:""}),ne&&ne!==Ae&&ne!==me.range?Z.push({value:ne,label:z(me.range,ne)}):Z.push({value:null,label:""}),Z},le=()=>p.createElement(u,{flexDirection:"row"},p.createElement(u,{flexDirection:"column",width:49},p.createElement(u,{marginLeft:1},p.createElement(A,null,"Press ",p.createElement(A,{bold:!0,color:"cyanBright"},""),"/",p.createElement(A,{bold:!0,color:"cyanBright"},"")," to select packages.")),p.createElement(u,{marginLeft:1},p.createElement(A,null,"Press ",p.createElement(A,{bold:!0,color:"cyanBright"},""),"/",p.createElement(A,{bold:!0,color:"cyanBright"},"")," to select versions."))),p.createElement(u,{flexDirection:"column"},p.createElement(u,{marginLeft:1},p.createElement(A,null,"Press ",p.createElement(A,{bold:!0,color:"cyanBright"},"")," to install.")),p.createElement(u,{marginLeft:1},p.createElement(A,null,"Press ",p.createElement(A,{bold:!0,color:"cyanBright"},"")," to abort.")))),ce=()=>p.createElement(u,{flexDirection:"row",paddingTop:1,paddingBottom:1},p.createElement(u,{width:50},p.createElement(A,{bold:!0},p.createElement(A,{color:"greenBright"},"?")," Pick the packages you want to upgrade.")),p.createElement(u,{width:17},p.createElement(A,{bold:!0,underline:!0,color:"gray"},"Current")),p.createElement(u,{width:17},p.createElement(A,{bold:!0,underline:!0,color:"gray"},"Range")),p.createElement(u,{width:17},p.createElement(A,{bold:!0,underline:!0,color:"gray"},"Latest"))),Ce=({active:me,descriptor:we,suggestions:Ae})=>{let[ne,Z]=a(we.descriptorHash,null),xe=G.stringifyIdent(we),Ne=Math.max(0,45-xe.length);return p.createElement(p.Fragment,null,p.createElement(u,null,p.createElement(u,{width:45},p.createElement(A,{bold:!0},G.prettyIdent(v,we)),p.createElement(r,{active:me,length:Ne})),p.createElement(e,{active:me,options:Ae,value:ne,skewer:!0,onChange:Z,sizes:[17,17,17]})))},de=({dependencies:me})=>{let[we,Ae]=I(me.map(()=>null)),ne=E(!0),Z=async xe=>{let Ne=await ae(xe);return Ne.filter(ht=>ht.label!=="").length<=1?null:{descriptor:xe,suggestions:Ne}};return h(()=>()=>{ne.current=!1},[]),h(()=>{let xe=Math.trunc(L*1.75),Ne=me.slice(0,xe),ht=me.slice(xe),H=gIe(ht,L),rt=Ne.map(Z).reduce(async(Te,Fe)=>{await Te;let ke=await Fe;ke!==null&&ne.current&&Ae(Ye=>{let be=Ye.findIndex(Ue=>Ue===null),et=[...Ye];return et[be]=ke,et})},Promise.resolve());H.reduce((Te,Fe)=>Promise.all(Fe.map(ke=>Promise.resolve().then(()=>Z(ke)))).then(async ke=>{ke=ke.filter(Ye=>Ye!==null),await Te,ne.current&&Ae(Ye=>{let be=Ye.findIndex(et=>et===null);return Ye.slice(0,be).concat(ke).concat(Ye.slice(be+ke.length))})}),rt).then(()=>{ne.current&&Ae(Te=>Te.filter(Fe=>Fe!==null))})},[]),we.length?p.createElement(o,{radius:L>>1,children:we.map((xe,Ne)=>xe!==null?p.createElement(Ce,{key:Ne,active:!1,descriptor:xe.descriptor,suggestions:xe.suggestions}):p.createElement(A,{key:Ne},"Loading..."))}):p.createElement(A,null,"No upgrades found")},Ee=await n(({useSubmit:me})=>{me(a());let we=new Map;for(let ne of x.workspaces)for(let Z of["dependencies","devDependencies"])for(let xe of ne.manifest[Z].values())x.tryWorkspaceByDescriptor(xe)===null&&(xe.range.startsWith("link:")||we.set(xe.descriptorHash,xe));let Ae=He.sortMap(we.values(),ne=>G.stringifyDescriptor(ne));return p.createElement(u,{flexDirection:"column"},p.createElement(le,null),p.createElement(ce,null),p.createElement(de,{dependencies:Ae}))},{},{stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr});if(typeof Ee>"u")return 1;let g=!1;for(let me of x.workspaces)for(let we of["dependencies","devDependencies"]){let Ae=me.manifest[we];for(let ne of Ae.values()){let Z=Ee.get(ne.descriptorHash);typeof Z<"u"&&Z!==null&&(Ae.set(ne.identHash,G.makeDescriptor(ne,Z)),g=!0)}}return g?await x.installWithNewReport({quiet:this.context.quiet,stdout:this.context.stdout},{cache:R}):0}};var lIt={commands:[oC,aC]},cIt=lIt;var Qq={};Vt(Qq,{LinkFetcher:()=>PB,LinkResolver:()=>bB,PortalFetcher:()=>SB,PortalResolver:()=>xB,default:()=>AIt});Ge();Pt();var Xf="portal:",Zf="link:";var PB=class{supports(e,r){return!!e.reference.startsWith(Zf)}getLocalPath(e,r){let{parentLocator:o,path:a}=G.parseFileStyleRange(e.reference,{protocol:Zf});if(V.isAbsolute(a))return a;let n=r.fetcher.getLocalPath(o,r);return n===null?null:V.resolve(n,a)}async fetch(e,r){let{parentLocator:o,path:a}=G.parseFileStyleRange(e.reference,{protocol:Zf}),n=V.isAbsolute(a)?{packageFs:new gn(It.root),prefixPath:It.dot,localPath:It.root}:await r.fetcher.fetch(o,r),u=n.localPath?{packageFs:new gn(It.root),prefixPath:V.relative(It.root,n.localPath),localPath:It.root}:n;n!==u&&n.releaseFs&&n.releaseFs();let A=u.packageFs,p=V.resolve(u.localPath??u.packageFs.getRealPath(),u.prefixPath,a);return n.localPath?{packageFs:new gn(p,{baseFs:A}),releaseFs:u.releaseFs,prefixPath:It.dot,discardFromLookup:!0,localPath:p}:{packageFs:new qu(p,{baseFs:A}),releaseFs:u.releaseFs,prefixPath:It.dot,discardFromLookup:!0}}};Ge();Pt();var bB=class{supportsDescriptor(e,r){return!!e.range.startsWith(Zf)}supportsLocator(e,r){return!!e.reference.startsWith(Zf)}shouldPersistResolution(e,r){return!1}bindDescriptor(e,r,o){return G.bindDescriptor(e,{locator:G.stringifyLocator(r)})}getResolutionDependencies(e,r){return{}}async getCandidates(e,r,o){let a=e.range.slice(Zf.length);return[G.makeLocator(e,`${Zf}${ue.toPortablePath(a)}`)]}async getSatisfying(e,r,o,a){let[n]=await this.getCandidates(e,r,a);return{locators:o.filter(u=>u.locatorHash===n.locatorHash),sorted:!1}}async resolve(e,r){return{...e,version:"0.0.0",languageName:r.project.configuration.get("defaultLanguageName"),linkType:"SOFT",conditions:null,dependencies:new Map,peerDependencies:new Map,dependenciesMeta:new Map,peerDependenciesMeta:new Map,bin:new Map}}};Ge();Pt();var SB=class{supports(e,r){return!!e.reference.startsWith(Xf)}getLocalPath(e,r){let{parentLocator:o,path:a}=G.parseFileStyleRange(e.reference,{protocol:Xf});if(V.isAbsolute(a))return a;let n=r.fetcher.getLocalPath(o,r);return n===null?null:V.resolve(n,a)}async fetch(e,r){let{parentLocator:o,path:a}=G.parseFileStyleRange(e.reference,{protocol:Xf}),n=V.isAbsolute(a)?{packageFs:new gn(It.root),prefixPath:It.dot,localPath:It.root}:await r.fetcher.fetch(o,r),u=n.localPath?{packageFs:new gn(It.root),prefixPath:V.relative(It.root,n.localPath),localPath:It.root}:n;n!==u&&n.releaseFs&&n.releaseFs();let A=u.packageFs,p=V.resolve(u.localPath??u.packageFs.getRealPath(),u.prefixPath,a);return n.localPath?{packageFs:new gn(p,{baseFs:A}),releaseFs:u.releaseFs,prefixPath:It.dot,localPath:p}:{packageFs:new qu(p,{baseFs:A}),releaseFs:u.releaseFs,prefixPath:It.dot}}};Ge();Ge();Pt();var xB=class{supportsDescriptor(e,r){return!!e.range.startsWith(Xf)}supportsLocator(e,r){return!!e.reference.startsWith(Xf)}shouldPersistResolution(e,r){return!1}bindDescriptor(e,r,o){return G.bindDescriptor(e,{locator:G.stringifyLocator(r)})}getResolutionDependencies(e,r){return{}}async getCandidates(e,r,o){let a=e.range.slice(Xf.length);return[G.makeLocator(e,`${Xf}${ue.toPortablePath(a)}`)]}async getSatisfying(e,r,o,a){let[n]=await this.getCandidates(e,r,a);return{locators:o.filter(u=>u.locatorHash===n.locatorHash),sorted:!1}}async resolve(e,r){if(!r.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let o=await r.fetchOptions.fetcher.fetch(e,r.fetchOptions),a=await He.releaseAfterUseAsync(async()=>await Ut.find(o.prefixPath,{baseFs:o.packageFs}),o.releaseFs);return{...e,version:a.version||"0.0.0",languageName:a.languageName||r.project.configuration.get("defaultLanguageName"),linkType:"SOFT",conditions:a.getConditions(),dependencies:r.project.configuration.normalizeDependencyMap(a.dependencies),peerDependencies:a.peerDependencies,dependenciesMeta:a.dependenciesMeta,peerDependenciesMeta:a.peerDependenciesMeta,bin:a.bin}}};var uIt={fetchers:[PB,SB],resolvers:[bB,xB]},AIt=uIt;var hj={};Vt(hj,{NodeModulesLinker:()=>GB,NodeModulesMode:()=>uj,PnpLooseLinker:()=>YB,default:()=>b1t});Pt();Ge();Pt();Pt();var Rq=(t,e)=>`${t}@${e}`,dIe=(t,e)=>{let r=e.indexOf("#"),o=r>=0?e.substring(r+1):e;return Rq(t,o)};var yIe=(t,e={})=>{let r=e.debugLevel||Number(process.env.NM_DEBUG_LEVEL||-1),o=e.check||r>=9,a=e.hoistingLimits||new Map,n={check:o,debugLevel:r,hoistingLimits:a,fastLookupPossible:!0},u;n.debugLevel>=0&&(u=Date.now());let A=yIt(t,n),p=!1,h=0;do p=Tq(A,[A],new Set([A.locator]),new Map,n).anotherRoundNeeded,n.fastLookupPossible=!1,h++;while(p);if(n.debugLevel>=0&&console.log(`hoist time: ${Date.now()-u}ms, rounds: ${h}`),n.debugLevel>=1){let E=kB(A);if(Tq(A,[A],new Set([A.locator]),new Map,n).isGraphChanged)throw new Error(`The hoisting result is not terminal, prev tree: +${E}, next tree: +${kB(A)}`);let v=EIe(A);if(v)throw new Error(`${v}, after hoisting finished: +${kB(A)}`)}return n.debugLevel>=2&&console.log(kB(A)),EIt(A)},fIt=t=>{let e=t[t.length-1],r=new Map,o=new Set,a=n=>{if(!o.has(n)){o.add(n);for(let u of n.hoistedDependencies.values())r.set(u.name,u);for(let u of n.dependencies.values())n.peerNames.has(u.name)||a(u)}};return a(e),r},pIt=t=>{let e=t[t.length-1],r=new Map,o=new Set,a=new Set,n=(u,A)=>{if(o.has(u))return;o.add(u);for(let h of u.hoistedDependencies.values())if(!A.has(h.name)){let E;for(let I of t)E=I.dependencies.get(h.name),E&&r.set(E.name,E)}let p=new Set;for(let h of u.dependencies.values())p.add(h.name);for(let h of u.dependencies.values())u.peerNames.has(h.name)||n(h,p)};return n(e,a),r},mIe=(t,e)=>{if(e.decoupled)return e;let{name:r,references:o,ident:a,locator:n,dependencies:u,originalDependencies:A,hoistedDependencies:p,peerNames:h,reasons:E,isHoistBorder:I,hoistPriority:v,dependencyKind:x,hoistedFrom:C,hoistedTo:R}=e,L={name:r,references:new Set(o),ident:a,locator:n,dependencies:new Map(u),originalDependencies:new Map(A),hoistedDependencies:new Map(p),peerNames:new Set(h),reasons:new Map(E),decoupled:!0,isHoistBorder:I,hoistPriority:v,dependencyKind:x,hoistedFrom:new Map(C),hoistedTo:new Map(R)},U=L.dependencies.get(r);return U&&U.ident==L.ident&&L.dependencies.set(r,L),t.dependencies.set(L.name,L),L},hIt=(t,e)=>{let r=new Map([[t.name,[t.ident]]]);for(let a of t.dependencies.values())t.peerNames.has(a.name)||r.set(a.name,[a.ident]);let o=Array.from(e.keys());o.sort((a,n)=>{let u=e.get(a),A=e.get(n);return A.hoistPriority!==u.hoistPriority?A.hoistPriority-u.hoistPriority:A.peerDependents.size!==u.peerDependents.size?A.peerDependents.size-u.peerDependents.size:A.dependents.size-u.dependents.size});for(let a of o){let n=a.substring(0,a.indexOf("@",1)),u=a.substring(n.length+1);if(!t.peerNames.has(n)){let A=r.get(n);A||(A=[],r.set(n,A)),A.indexOf(u)<0&&A.push(u)}}return r},Fq=t=>{let e=new Set,r=(o,a=new Set)=>{if(!a.has(o)){a.add(o);for(let n of o.peerNames)if(!t.peerNames.has(n)){let u=t.dependencies.get(n);u&&!e.has(u)&&r(u,a)}e.add(o)}};for(let o of t.dependencies.values())t.peerNames.has(o.name)||r(o);return e},Tq=(t,e,r,o,a,n=new Set)=>{let u=e[e.length-1];if(n.has(u))return{anotherRoundNeeded:!1,isGraphChanged:!1};n.add(u);let A=CIt(u),p=hIt(u,A),h=t==u?new Map:a.fastLookupPossible?fIt(e):pIt(e),E,I=!1,v=!1,x=new Map(Array.from(p.entries()).map(([R,L])=>[R,L[0]])),C=new Map;do{let R=mIt(t,e,r,h,x,p,o,C,a);R.isGraphChanged&&(v=!0),R.anotherRoundNeeded&&(I=!0),E=!1;for(let[L,U]of p)U.length>1&&!u.dependencies.has(L)&&(x.delete(L),U.shift(),x.set(L,U[0]),E=!0)}while(E);for(let R of u.dependencies.values())if(!u.peerNames.has(R.name)&&!r.has(R.locator)){r.add(R.locator);let L=Tq(t,[...e,R],r,C,a);L.isGraphChanged&&(v=!0),L.anotherRoundNeeded&&(I=!0),r.delete(R.locator)}return{anotherRoundNeeded:I,isGraphChanged:v}},gIt=t=>{for(let[e,r]of t.dependencies)if(!t.peerNames.has(e)&&r.ident!==t.ident)return!0;return!1},dIt=(t,e,r,o,a,n,u,A,{outputReason:p,fastLookupPossible:h})=>{let E,I=null,v=new Set;p&&(E=`${Array.from(e).map(L=>no(L)).join("\u2192")}`);let x=r[r.length-1],R=!(o.ident===x.ident);if(p&&!R&&(I="- self-reference"),R&&(R=o.dependencyKind!==1,p&&!R&&(I="- workspace")),R&&o.dependencyKind===2&&(R=!gIt(o),p&&!R&&(I="- external soft link with unhoisted dependencies")),R&&(R=x.dependencyKind!==1||x.hoistedFrom.has(o.name)||e.size===1,p&&!R&&(I=x.reasons.get(o.name))),R&&(R=!t.peerNames.has(o.name),p&&!R&&(I=`- cannot shadow peer: ${no(t.originalDependencies.get(o.name).locator)} at ${E}`)),R){let L=!1,U=a.get(o.name);if(L=!U||U.ident===o.ident,p&&!L&&(I=`- filled by: ${no(U.locator)} at ${E}`),L)for(let z=r.length-1;z>=1;z--){let ae=r[z].dependencies.get(o.name);if(ae&&ae.ident!==o.ident){L=!1;let le=A.get(x);le||(le=new Set,A.set(x,le)),le.add(o.name),p&&(I=`- filled by ${no(ae.locator)} at ${r.slice(0,z).map(ce=>no(ce.locator)).join("\u2192")}`);break}}R=L}if(R&&(R=n.get(o.name)===o.ident,p&&!R&&(I=`- filled by: ${no(u.get(o.name)[0])} at ${E}`)),R){let L=!0,U=new Set(o.peerNames);for(let z=r.length-1;z>=1;z--){let te=r[z];for(let ae of U){if(te.peerNames.has(ae)&&te.originalDependencies.has(ae))continue;let le=te.dependencies.get(ae);le&&t.dependencies.get(ae)!==le&&(z===r.length-1?v.add(le):(v=null,L=!1,p&&(I=`- peer dependency ${no(le.locator)} from parent ${no(te.locator)} was not hoisted to ${E}`))),U.delete(ae)}if(!L)break}R=L}if(R&&!h)for(let L of o.hoistedDependencies.values()){let U=a.get(L.name)||t.dependencies.get(L.name);if(!U||L.ident!==U.ident){R=!1,p&&(I=`- previously hoisted dependency mismatch, needed: ${no(L.locator)}, available: ${no(U?.locator)}`);break}}return v!==null&&v.size>0?{isHoistable:2,dependsOn:v,reason:I}:{isHoistable:R?0:1,reason:I}},aQ=t=>`${t.name}@${t.locator}`,mIt=(t,e,r,o,a,n,u,A,p)=>{let h=e[e.length-1],E=new Set,I=!1,v=!1,x=(U,z,te,ae,le)=>{if(E.has(ae))return;let ce=[...z,aQ(ae)],Ce=[...te,aQ(ae)],de=new Map,Be=new Map;for(let Ae of Fq(ae)){let ne=dIt(h,r,[h,...U,ae],Ae,o,a,n,A,{outputReason:p.debugLevel>=2,fastLookupPossible:p.fastLookupPossible});if(Be.set(Ae,ne),ne.isHoistable===2)for(let Z of ne.dependsOn){let xe=de.get(Z.name)||new Set;xe.add(Ae.name),de.set(Z.name,xe)}}let Ee=new Set,g=(Ae,ne,Z)=>{if(!Ee.has(Ae)){Ee.add(Ae),Be.set(Ae,{isHoistable:1,reason:Z});for(let xe of de.get(Ae.name)||[])g(ae.dependencies.get(xe),ne,p.debugLevel>=2?`- peer dependency ${no(Ae.locator)} from parent ${no(ae.locator)} was not hoisted`:"")}};for(let[Ae,ne]of Be)ne.isHoistable===1&&g(Ae,ne,ne.reason);let me=!1;for(let Ae of Be.keys())if(!Ee.has(Ae)){v=!0;let ne=u.get(ae);ne&&ne.has(Ae.name)&&(I=!0),me=!0,ae.dependencies.delete(Ae.name),ae.hoistedDependencies.set(Ae.name,Ae),ae.reasons.delete(Ae.name);let Z=h.dependencies.get(Ae.name);if(p.debugLevel>=2){let xe=Array.from(z).concat([ae.locator]).map(ht=>no(ht)).join("\u2192"),Ne=h.hoistedFrom.get(Ae.name);Ne||(Ne=[],h.hoistedFrom.set(Ae.name,Ne)),Ne.push(xe),ae.hoistedTo.set(Ae.name,Array.from(e).map(ht=>no(ht.locator)).join("\u2192"))}if(!Z)h.ident!==Ae.ident&&(h.dependencies.set(Ae.name,Ae),le.add(Ae));else for(let xe of Ae.references)Z.references.add(xe)}if(ae.dependencyKind===2&&me&&(I=!0),p.check){let Ae=EIe(t);if(Ae)throw new Error(`${Ae}, after hoisting dependencies of ${[h,...U,ae].map(ne=>no(ne.locator)).join("\u2192")}: +${kB(t)}`)}let we=Fq(ae);for(let Ae of we)if(Ee.has(Ae)){let ne=Be.get(Ae);if((a.get(Ae.name)===Ae.ident||!ae.reasons.has(Ae.name))&&ne.isHoistable!==0&&ae.reasons.set(Ae.name,ne.reason),!Ae.isHoistBorder&&Ce.indexOf(aQ(Ae))<0){E.add(ae);let xe=mIe(ae,Ae);x([...U,ae],ce,Ce,xe,R),E.delete(ae)}}},C,R=new Set(Fq(h)),L=Array.from(e).map(U=>aQ(U));do{C=R,R=new Set;for(let U of C){if(U.locator===h.locator||U.isHoistBorder)continue;let z=mIe(h,U);x([],Array.from(r),L,z,R)}}while(R.size>0);return{anotherRoundNeeded:I,isGraphChanged:v}},EIe=t=>{let e=[],r=new Set,o=new Set,a=(n,u,A)=>{if(r.has(n)||(r.add(n),o.has(n)))return;let p=new Map(u);for(let h of n.dependencies.values())n.peerNames.has(h.name)||p.set(h.name,h);for(let h of n.originalDependencies.values()){let E=p.get(h.name),I=()=>`${Array.from(o).concat([n]).map(v=>no(v.locator)).join("\u2192")}`;if(n.peerNames.has(h.name)){let v=u.get(h.name);(v!==E||!v||v.ident!==h.ident)&&e.push(`${I()} - broken peer promise: expected ${h.ident} but found ${v&&v.ident}`)}else{let v=A.hoistedFrom.get(n.name),x=n.hoistedTo.get(h.name),C=`${v?` hoisted from ${v.join(", ")}`:""}`,R=`${x?` hoisted to ${x}`:""}`,L=`${I()}${C}`;E?E.ident!==h.ident&&e.push(`${L} - broken require promise for ${h.name}${R}: expected ${h.ident}, but found: ${E.ident}`):e.push(`${L} - broken require promise: no required dependency ${h.name}${R} found`)}}o.add(n);for(let h of n.dependencies.values())n.peerNames.has(h.name)||a(h,p,n);o.delete(n)};return a(t,t.dependencies,t),e.join(` +`)},yIt=(t,e)=>{let{identName:r,name:o,reference:a,peerNames:n}=t,u={name:o,references:new Set([a]),locator:Rq(r,a),ident:dIe(r,a),dependencies:new Map,originalDependencies:new Map,hoistedDependencies:new Map,peerNames:new Set(n),reasons:new Map,decoupled:!0,isHoistBorder:!0,hoistPriority:0,dependencyKind:1,hoistedFrom:new Map,hoistedTo:new Map},A=new Map([[t,u]]),p=(h,E)=>{let I=A.get(h),v=!!I;if(!I){let{name:x,identName:C,reference:R,peerNames:L,hoistPriority:U,dependencyKind:z}=h,te=e.hoistingLimits.get(E.locator);I={name:x,references:new Set([R]),locator:Rq(C,R),ident:dIe(C,R),dependencies:new Map,originalDependencies:new Map,hoistedDependencies:new Map,peerNames:new Set(L),reasons:new Map,decoupled:!0,isHoistBorder:te?te.has(x):!1,hoistPriority:U||0,dependencyKind:z||0,hoistedFrom:new Map,hoistedTo:new Map},A.set(h,I)}if(E.dependencies.set(h.name,I),E.originalDependencies.set(h.name,I),v){let x=new Set,C=R=>{if(!x.has(R)){x.add(R),R.decoupled=!1;for(let L of R.dependencies.values())R.peerNames.has(L.name)||C(L)}};C(I)}else for(let x of h.dependencies)p(x,I)};for(let h of t.dependencies)p(h,u);return u},Nq=t=>t.substring(0,t.indexOf("@",1)),EIt=t=>{let e={name:t.name,identName:Nq(t.locator),references:new Set(t.references),dependencies:new Set},r=new Set([t]),o=(a,n,u)=>{let A=r.has(a),p;if(n===a)p=u;else{let{name:h,references:E,locator:I}=a;p={name:h,identName:Nq(I),references:E,dependencies:new Set}}if(u.dependencies.add(p),!A){r.add(a);for(let h of a.dependencies.values())a.peerNames.has(h.name)||o(h,a,p);r.delete(a)}};for(let a of t.dependencies.values())o(a,t,e);return e},CIt=t=>{let e=new Map,r=new Set([t]),o=u=>`${u.name}@${u.ident}`,a=u=>{let A=o(u),p=e.get(A);return p||(p={dependents:new Set,peerDependents:new Set,hoistPriority:0},e.set(A,p)),p},n=(u,A)=>{let p=!!r.has(A);if(a(A).dependents.add(u.ident),!p){r.add(A);for(let E of A.dependencies.values()){let I=a(E);I.hoistPriority=Math.max(I.hoistPriority,E.hoistPriority),A.peerNames.has(E.name)?I.peerDependents.add(A.ident):n(A,E)}}};for(let u of t.dependencies.values())t.peerNames.has(u.name)||n(t,u);return e},no=t=>{if(!t)return"none";let e=t.indexOf("@",1),r=t.substring(0,e);r.endsWith("$wsroot$")&&(r=`wh:${r.replace("$wsroot$","")}`);let o=t.substring(e+1);if(o==="workspace:.")return".";if(o){let a=(o.indexOf("#")>0?o.split("#")[1]:o).replace("npm:","");return o.startsWith("virtual")&&(r=`v:${r}`),a.startsWith("workspace")&&(r=`w:${r}`,a=""),`${r}${a?`@${a}`:""}`}else return`${r}`};var kB=t=>{let e=0,r=(a,n,u="")=>{if(e>5e4||n.has(a))return"";e++;let A=Array.from(a.dependencies.values()).sort((h,E)=>h.name===E.name?0:h.name>E.name?1:-1),p="";n.add(a);for(let h=0;h":"")+(v!==E.name?`a:${E.name}:`:"")+no(E.locator)+(I?` ${I}`:"")} +`,p+=r(E,n,`${u}${h5e4?` +Tree is too large, part of the tree has been dunped +`:"")};var QB=(o=>(o.WORKSPACES="workspaces",o.DEPENDENCIES="dependencies",o.NONE="none",o))(QB||{}),CIe="node_modules",Oh="$wsroot$";var FB=(t,e)=>{let{packageTree:r,hoistingLimits:o,errors:a,preserveSymlinksRequired:n}=IIt(t,e),u=null;if(a.length===0){let A=yIe(r,{hoistingLimits:o});u=vIt(t,A,e)}return{tree:u,errors:a,preserveSymlinksRequired:n}},gA=t=>`${t.name}@${t.reference}`,Mq=t=>{let e=new Map;for(let[r,o]of t.entries())if(!o.dirList){let a=e.get(o.locator);a||(a={target:o.target,linkType:o.linkType,locations:[],aliases:o.aliases},e.set(o.locator,a)),a.locations.push(r)}for(let r of e.values())r.locations=r.locations.sort((o,a)=>{let n=o.split(V.delimiter).length,u=a.split(V.delimiter).length;return a===o?0:n!==u?u-n:a>o?1:-1});return e},wIe=(t,e)=>{let r=G.isVirtualLocator(t)?G.devirtualizeLocator(t):t,o=G.isVirtualLocator(e)?G.devirtualizeLocator(e):e;return G.areLocatorsEqual(r,o)},Lq=(t,e,r,o)=>{if(t.linkType!=="SOFT")return!1;let a=ue.toPortablePath(r.resolveVirtual&&e.reference&&e.reference.startsWith("virtual:")?r.resolveVirtual(t.packageLocation):t.packageLocation);return V.contains(o,a)===null},wIt=t=>{let e=t.getPackageInformation(t.topLevel);if(e===null)throw new Error("Assertion failed: Expected the top-level package to have been registered");if(t.findPackageLocator(e.packageLocation)===null)throw new Error("Assertion failed: Expected the top-level package to have a physical locator");let o=ue.toPortablePath(e.packageLocation.slice(0,-1)),a=new Map,n={children:new Map},u=t.getDependencyTreeRoots(),A=new Map,p=new Set,h=(v,x)=>{let C=gA(v);if(p.has(C))return;p.add(C);let R=t.getPackageInformation(v);if(R){let L=x?gA(x):"";if(gA(v)!==L&&R.linkType==="SOFT"&&!v.reference.startsWith("link:")&&!Lq(R,v,t,o)){let U=IIe(R,v,t);(!A.get(U)||v.reference.startsWith("workspace:"))&&A.set(U,v)}for(let[U,z]of R.packageDependencies)z!==null&&(R.packagePeers.has(U)||h(t.getLocator(U,z),v))}};for(let v of u)h(v,null);let E=o.split(V.sep);for(let v of A.values()){let x=t.getPackageInformation(v),R=ue.toPortablePath(x.packageLocation.slice(0,-1)).split(V.sep).slice(E.length),L=n;for(let U of R){let z=L.children.get(U);z||(z={children:new Map},L.children.set(U,z)),L=z}L.workspaceLocator=v}let I=(v,x)=>{if(v.workspaceLocator){let C=gA(x),R=a.get(C);R||(R=new Set,a.set(C,R)),R.add(v.workspaceLocator)}for(let C of v.children.values())I(C,v.workspaceLocator||x)};for(let v of n.children.values())I(v,n.workspaceLocator);return a},IIt=(t,e)=>{let r=[],o=!1,a=new Map,n=wIt(t),u=t.getPackageInformation(t.topLevel);if(u===null)throw new Error("Assertion failed: Expected the top-level package to have been registered");let A=t.findPackageLocator(u.packageLocation);if(A===null)throw new Error("Assertion failed: Expected the top-level package to have a physical locator");let p=ue.toPortablePath(u.packageLocation.slice(0,-1)),h={name:A.name,identName:A.name,reference:A.reference,peerNames:u.packagePeers,dependencies:new Set,dependencyKind:1},E=new Map,I=(x,C)=>`${gA(C)}:${x}`,v=(x,C,R,L,U,z,te,ae)=>{let le=I(x,R),ce=E.get(le),Ce=!!ce;!Ce&&R.name===A.name&&R.reference===A.reference&&(ce=h,E.set(le,h));let de=Lq(C,R,t,p);if(!ce){let Ae=0;de?Ae=2:C.linkType==="SOFT"&&R.name.endsWith(Oh)&&(Ae=1),ce={name:x,identName:R.name,reference:R.reference,dependencies:new Set,peerNames:Ae===1?new Set:C.packagePeers,dependencyKind:Ae},E.set(le,ce)}let Be;if(de?Be=2:U.linkType==="SOFT"?Be=1:Be=0,ce.hoistPriority=Math.max(ce.hoistPriority||0,Be),ae&&!de){let Ae=gA({name:L.identName,reference:L.reference}),ne=a.get(Ae)||new Set;a.set(Ae,ne),ne.add(ce.name)}let Ee=new Map(C.packageDependencies);if(e.project){let Ae=e.project.workspacesByCwd.get(ue.toPortablePath(C.packageLocation.slice(0,-1)));if(Ae){let ne=new Set([...Array.from(Ae.manifest.peerDependencies.values(),Z=>G.stringifyIdent(Z)),...Array.from(Ae.manifest.peerDependenciesMeta.keys())]);for(let Z of ne)Ee.has(Z)||(Ee.set(Z,z.get(Z)||null),ce.peerNames.add(Z))}}let g=gA({name:R.name.replace(Oh,""),reference:R.reference}),me=n.get(g);if(me)for(let Ae of me)Ee.set(`${Ae.name}${Oh}`,Ae.reference);(C!==U||C.linkType!=="SOFT"||!de&&(!e.selfReferencesByCwd||e.selfReferencesByCwd.get(te)))&&L.dependencies.add(ce);let we=R!==A&&C.linkType==="SOFT"&&!R.name.endsWith(Oh)&&!de;if(!Ce&&!we){let Ae=new Map;for(let[ne,Z]of Ee)if(Z!==null){let xe=t.getLocator(ne,Z),Ne=t.getLocator(ne.replace(Oh,""),Z),ht=t.getPackageInformation(Ne);if(ht===null)throw new Error("Assertion failed: Expected the package to have been registered");let H=Lq(ht,xe,t,p);if(e.validateExternalSoftLinks&&e.project&&H){ht.packageDependencies.size>0&&(o=!0);for(let[Ye,be]of ht.packageDependencies)if(be!==null){let et=G.parseLocator(Array.isArray(be)?`${be[0]}@${be[1]}`:`${Ye}@${be}`);if(gA(et)!==gA(xe)){let Ue=Ee.get(Ye);if(Ue){let S=G.parseLocator(Array.isArray(Ue)?`${Ue[0]}@${Ue[1]}`:`${Ye}@${Ue}`);wIe(S,et)||r.push({messageName:71,text:`Cannot link ${G.prettyIdent(e.project.configuration,G.parseIdent(xe.name))} into ${G.prettyLocator(e.project.configuration,G.parseLocator(`${R.name}@${R.reference}`))} dependency ${G.prettyLocator(e.project.configuration,et)} conflicts with parent dependency ${G.prettyLocator(e.project.configuration,S)}`})}else{let S=Ae.get(Ye);if(S){let w=S.target,b=G.parseLocator(Array.isArray(w)?`${w[0]}@${w[1]}`:`${Ye}@${w}`);wIe(b,et)||r.push({messageName:71,text:`Cannot link ${G.prettyIdent(e.project.configuration,G.parseIdent(xe.name))} into ${G.prettyLocator(e.project.configuration,G.parseLocator(`${R.name}@${R.reference}`))} dependency ${G.prettyLocator(e.project.configuration,et)} conflicts with dependency ${G.prettyLocator(e.project.configuration,b)} from sibling portal ${G.prettyIdent(e.project.configuration,G.parseIdent(S.portal.name))}`})}else Ae.set(Ye,{target:et.reference,portal:xe})}}}}let rt=e.hoistingLimitsByCwd?.get(te),Te=H?te:V.relative(p,ue.toPortablePath(ht.packageLocation))||It.dot,Fe=e.hoistingLimitsByCwd?.get(Te);v(ne,ht,xe,ce,C,Ee,Te,rt==="dependencies"||Fe==="dependencies"||Fe==="workspaces")}}};return v(A.name,u,A,h,u,u.packageDependencies,It.dot,!1),{packageTree:h,hoistingLimits:a,errors:r,preserveSymlinksRequired:o}};function IIe(t,e,r){let o=r.resolveVirtual&&e.reference&&e.reference.startsWith("virtual:")?r.resolveVirtual(t.packageLocation):t.packageLocation;return ue.toPortablePath(o||t.packageLocation)}function BIt(t,e,r){let o=e.getLocator(t.name.replace(Oh,""),t.reference),a=e.getPackageInformation(o);if(a===null)throw new Error("Assertion failed: Expected the package to be registered");return r.pnpifyFs?{linkType:"SOFT",target:ue.toPortablePath(a.packageLocation)}:{linkType:a.linkType,target:IIe(a,t,e)}}var vIt=(t,e,r)=>{let o=new Map,a=(E,I,v)=>{let{linkType:x,target:C}=BIt(E,t,r);return{locator:gA(E),nodePath:I,target:C,linkType:x,aliases:v}},n=E=>{let[I,v]=E.split("/");return v?{scope:I,name:v}:{scope:null,name:I}},u=new Set,A=(E,I,v)=>{if(u.has(E))return;u.add(E);let x=Array.from(E.references).sort().join("#");for(let C of E.dependencies){let R=Array.from(C.references).sort().join("#");if(C.identName===E.identName.replace(Oh,"")&&R===x)continue;let L=Array.from(C.references).sort(),U={name:C.identName,reference:L[0]},{name:z,scope:te}=n(C.name),ae=te?[te,z]:[z],le=V.join(I,CIe),ce=V.join(le,...ae),Ce=`${v}/${U.name}`,de=a(U,v,L.slice(1)),Be=!1;if(de.linkType==="SOFT"&&r.project){let Ee=r.project.workspacesByCwd.get(de.target.slice(0,-1));Be=!!(Ee&&!Ee.manifest.name)}if(!C.name.endsWith(Oh)&&!Be){let Ee=o.get(ce);if(Ee){if(Ee.dirList)throw new Error(`Assertion failed: ${ce} cannot merge dir node with leaf node`);{let we=G.parseLocator(Ee.locator),Ae=G.parseLocator(de.locator);if(Ee.linkType!==de.linkType)throw new Error(`Assertion failed: ${ce} cannot merge nodes with different link types ${Ee.nodePath}/${G.stringifyLocator(we)} and ${v}/${G.stringifyLocator(Ae)}`);if(we.identHash!==Ae.identHash)throw new Error(`Assertion failed: ${ce} cannot merge nodes with different idents ${Ee.nodePath}/${G.stringifyLocator(we)} and ${v}/s${G.stringifyLocator(Ae)}`);de.aliases=[...de.aliases,...Ee.aliases,G.parseLocator(Ee.locator).reference]}}o.set(ce,de);let g=ce.split("/"),me=g.indexOf(CIe);for(let we=g.length-1;me>=0&&we>me;we--){let Ae=ue.toPortablePath(g.slice(0,we).join(V.sep)),ne=g[we],Z=o.get(Ae);if(!Z)o.set(Ae,{dirList:new Set([ne])});else if(Z.dirList){if(Z.dirList.has(ne))break;Z.dirList.add(ne)}}}A(C,de.linkType==="SOFT"?de.target:ce,Ce)}},p=a({name:e.name,reference:Array.from(e.references)[0]},"",[]),h=p.target;return o.set(h,p),A(e,h,""),o};Ge();Ge();Pt();Pt();nA();Nl();var rj={};Vt(rj,{PnpInstaller:()=>sd,PnpLinker:()=>Hh,UnplugCommand:()=>cC,default:()=>e1t,getPnpPath:()=>qh,jsInstallUtils:()=>mA,pnpUtils:()=>jB,quotePathIfNeeded:()=>o1e});Pt();var s1e=ve("url");Ge();Ge();Pt();Pt();var BIe={DEFAULT:{collapsed:!1,next:{"*":"DEFAULT"}},TOP_LEVEL:{collapsed:!1,next:{fallbackExclusionList:"FALLBACK_EXCLUSION_LIST",packageRegistryData:"PACKAGE_REGISTRY_DATA","*":"DEFAULT"}},FALLBACK_EXCLUSION_LIST:{collapsed:!1,next:{"*":"FALLBACK_EXCLUSION_ENTRIES"}},FALLBACK_EXCLUSION_ENTRIES:{collapsed:!0,next:{"*":"FALLBACK_EXCLUSION_DATA"}},FALLBACK_EXCLUSION_DATA:{collapsed:!0,next:{"*":"DEFAULT"}},PACKAGE_REGISTRY_DATA:{collapsed:!1,next:{"*":"PACKAGE_REGISTRY_ENTRIES"}},PACKAGE_REGISTRY_ENTRIES:{collapsed:!0,next:{"*":"PACKAGE_STORE_DATA"}},PACKAGE_STORE_DATA:{collapsed:!1,next:{"*":"PACKAGE_STORE_ENTRIES"}},PACKAGE_STORE_ENTRIES:{collapsed:!0,next:{"*":"PACKAGE_INFORMATION_DATA"}},PACKAGE_INFORMATION_DATA:{collapsed:!1,next:{packageDependencies:"PACKAGE_DEPENDENCIES","*":"DEFAULT"}},PACKAGE_DEPENDENCIES:{collapsed:!1,next:{"*":"PACKAGE_DEPENDENCY"}},PACKAGE_DEPENDENCY:{collapsed:!0,next:{"*":"DEFAULT"}}};function DIt(t,e,r){let o="";o+="[";for(let a=0,n=t.length;a"u"||(A!==0&&(a+=", "),a+=JSON.stringify(p),a+=": ",a+=lQ(p,h,e,r).replace(/^ +/g,""),A+=1)}return a+="}",a}function SIt(t,e,r){let o=Object.keys(t),a=`${r} `,n="";n+=r,n+=`{ +`;let u=0;for(let A=0,p=o.length;A"u"||(u!==0&&(n+=",",n+=` +`),n+=a,n+=JSON.stringify(h),n+=": ",n+=lQ(h,E,e,a).replace(/^ +/g,""),u+=1)}return u!==0&&(n+=` +`),n+=r,n+="}",n}function lQ(t,e,r,o){let{next:a}=BIe[r],n=a[t]||a["*"];return vIe(e,n,o)}function vIe(t,e,r){let{collapsed:o}=BIe[e];return Array.isArray(t)?o?DIt(t,e,r):PIt(t,e,r):typeof t=="object"&&t!==null?o?bIt(t,e,r):SIt(t,e,r):JSON.stringify(t)}function DIe(t){return vIe(t,"TOP_LEVEL","")}function RB(t,e){let r=Array.from(t);Array.isArray(e)||(e=[e]);let o=[];for(let n of e)o.push(r.map(u=>n(u)));let a=r.map((n,u)=>u);return a.sort((n,u)=>{for(let A of o){let p=A[n]A[u]?1:0;if(p!==0)return p}return 0}),a.map(n=>r[n])}function xIt(t){let e=new Map,r=RB(t.fallbackExclusionList||[],[({name:o,reference:a})=>o,({name:o,reference:a})=>a]);for(let{name:o,reference:a}of r){let n=e.get(o);typeof n>"u"&&e.set(o,n=new Set),n.add(a)}return Array.from(e).map(([o,a])=>[o,Array.from(a)])}function kIt(t){return RB(t.fallbackPool||[],([e])=>e)}function QIt(t){let e=[];for(let[r,o]of RB(t.packageRegistry,([a])=>a===null?"0":`1${a}`)){let a=[];e.push([r,a]);for(let[n,{packageLocation:u,packageDependencies:A,packagePeers:p,linkType:h,discardFromLookup:E}]of RB(o,([I])=>I===null?"0":`1${I}`)){let I=[];r!==null&&n!==null&&!A.has(r)&&I.push([r,n]);for(let[C,R]of RB(A.entries(),([L])=>L))I.push([C,R]);let v=p&&p.size>0?Array.from(p):void 0,x=E||void 0;a.push([n,{packageLocation:u,packageDependencies:I,packagePeers:v,linkType:h,discardFromLookup:x}])}}return e}function TB(t){return{__info:["This file is automatically generated. Do not touch it, or risk","your modifications being lost."],dependencyTreeRoots:t.dependencyTreeRoots,enableTopLevelFallback:t.enableTopLevelFallback||!1,ignorePatternData:t.ignorePattern||null,fallbackExclusionList:xIt(t),fallbackPool:kIt(t),packageRegistryData:QIt(t)}}var SIe=Ze(bIe());function xIe(t,e){return[t?`${t} +`:"",`/* eslint-disable */ +`,`// @ts-nocheck +`,`"use strict"; +`,` +`,e,` +`,(0,SIe.default)()].join("")}function FIt(t){return JSON.stringify(t,null,2)}function RIt(t){return`'${t.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(/\n/g,`\\ +`)}'`}function TIt(t){return[`const RAW_RUNTIME_STATE = +`,`${RIt(DIe(t))}; + +`,`function $$SETUP_STATE(hydrateRuntimeState, basePath) { +`,` return hydrateRuntimeState(JSON.parse(RAW_RUNTIME_STATE), {basePath: basePath || __dirname}); +`,`} +`].join("")}function NIt(){return[`function $$SETUP_STATE(hydrateRuntimeState, basePath) { +`,` const fs = require('fs'); +`,` const path = require('path'); +`,` const pnpDataFilepath = path.resolve(__dirname, ${JSON.stringify(dr.pnpData)}); +`,` return hydrateRuntimeState(JSON.parse(fs.readFileSync(pnpDataFilepath, 'utf8')), {basePath: basePath || __dirname}); +`,`} +`].join("")}function kIe(t){let e=TB(t),r=TIt(e);return xIe(t.shebang,r)}function QIe(t){let e=TB(t),r=NIt(),o=xIe(t.shebang,r);return{dataFile:FIt(e),loaderFile:o}}Pt();function Uq(t,{basePath:e}){let r=ue.toPortablePath(e),o=V.resolve(r),a=t.ignorePatternData!==null?new RegExp(t.ignorePatternData):null,n=new Map,u=new Map(t.packageRegistryData.map(([I,v])=>[I,new Map(v.map(([x,C])=>{if(I===null!=(x===null))throw new Error("Assertion failed: The name and reference should be null, or neither should");let R=C.discardFromLookup??!1,L={name:I,reference:x},U=n.get(C.packageLocation);U?(U.discardFromLookup=U.discardFromLookup&&R,R||(U.locator=L)):n.set(C.packageLocation,{locator:L,discardFromLookup:R});let z=null;return[x,{packageDependencies:new Map(C.packageDependencies),packagePeers:new Set(C.packagePeers),linkType:C.linkType,discardFromLookup:R,get packageLocation(){return z||(z=V.join(o,C.packageLocation))}}]}))])),A=new Map(t.fallbackExclusionList.map(([I,v])=>[I,new Set(v)])),p=new Map(t.fallbackPool),h=t.dependencyTreeRoots,E=t.enableTopLevelFallback;return{basePath:r,dependencyTreeRoots:h,enableTopLevelFallback:E,fallbackExclusionList:A,fallbackPool:p,ignorePattern:a,packageLocatorsByLocations:n,packageRegistry:u}}Pt();Pt();var ep=ve("module"),id=ve("url"),zq=ve("util");var Oo=ve("url");var NIe=Ze(ve("assert"));var _q=Array.isArray,NB=JSON.stringify,LB=Object.getOwnPropertyNames,nd=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),Hq=(t,e)=>RegExp.prototype.exec.call(t,e),qq=(t,...e)=>RegExp.prototype[Symbol.replace].apply(t,e),Uh=(t,...e)=>String.prototype.endsWith.apply(t,e),jq=(t,...e)=>String.prototype.includes.apply(t,e),Gq=(t,...e)=>String.prototype.lastIndexOf.apply(t,e),MB=(t,...e)=>String.prototype.indexOf.apply(t,e),FIe=(t,...e)=>String.prototype.replace.apply(t,e),_h=(t,...e)=>String.prototype.slice.apply(t,e),dA=(t,...e)=>String.prototype.startsWith.apply(t,e),RIe=Map,TIe=JSON.parse;function OB(t,e,r){return class extends r{constructor(...o){super(e(...o)),this.code=t,this.name=`${r.name} [${t}]`}}}var LIe=OB("ERR_PACKAGE_IMPORT_NOT_DEFINED",(t,e,r)=>`Package import specifier "${t}" is not defined${e?` in package ${e}package.json`:""} imported from ${r}`,TypeError),Yq=OB("ERR_INVALID_MODULE_SPECIFIER",(t,e,r=void 0)=>`Invalid module "${t}" ${e}${r?` imported from ${r}`:""}`,TypeError),MIe=OB("ERR_INVALID_PACKAGE_TARGET",(t,e,r,o=!1,a=void 0)=>{let n=typeof r=="string"&&!o&&r.length&&!dA(r,"./");return e==="."?((0,NIe.default)(o===!1),`Invalid "exports" main target ${NB(r)} defined in the package config ${t}package.json${a?` imported from ${a}`:""}${n?'; targets must start with "./"':""}`):`Invalid "${o?"imports":"exports"}" target ${NB(r)} defined for '${e}' in the package config ${t}package.json${a?` imported from ${a}`:""}${n?'; targets must start with "./"':""}`},Error),UB=OB("ERR_INVALID_PACKAGE_CONFIG",(t,e,r)=>`Invalid package config ${t}${e?` while importing ${e}`:""}${r?`. ${r}`:""}`,Error),OIe=OB("ERR_PACKAGE_PATH_NOT_EXPORTED",(t,e,r=void 0)=>e==="."?`No "exports" main defined in ${t}package.json${r?` imported from ${r}`:""}`:`Package subpath '${e}' is not defined by "exports" in ${t}package.json${r?` imported from ${r}`:""}`,Error);var uQ=ve("url");function UIe(t,e){let r=Object.create(null);for(let o=0;oe):t+e}_B(r,t,o,u,a)}Hq(HIe,_h(t,2))!==null&&_B(r,t,o,u,a);let p=new URL(t,o),h=p.pathname,E=new URL(".",o).pathname;if(dA(h,E)||_B(r,t,o,u,a),e==="")return p;if(Hq(HIe,e)!==null){let I=n?FIe(r,"*",()=>e):r+e;OIt(I,o,u,a)}return n?new URL(qq(qIe,p.href,()=>e)):new URL(e,p)}function _It(t){let e=+t;return`${e}`!==t?!1:e>=0&&e<4294967295}function lC(t,e,r,o,a,n,u,A){if(typeof e=="string")return UIt(e,r,o,t,a,n,u,A);if(_q(e)){if(e.length===0)return null;let p;for(let h=0;hn?-1:n>a||r===-1?1:o===-1||t.length>e.length?-1:e.length>t.length?1:0}function HIt(t,e,r){if(typeof t=="string"||_q(t))return!0;if(typeof t!="object"||t===null)return!1;let o=LB(t),a=!1,n=0;for(let u=0;u=h.length&&Uh(e,I)&&GIe(n,h)===1&&Gq(h,"*")===E&&(n=h,u=_h(e,E,e.length-I.length))}}if(n){let p=r[n],h=lC(t,p,u,n,o,!0,!1,a);return h==null&&Wq(e,t,o),h}Wq(e,t,o)}function WIe({name:t,base:e,conditions:r,readFileSyncFn:o}){if(t==="#"||dA(t,"#/")||Uh(t,"/")){let u="is not a valid internal imports specifier name";throw new Yq(t,u,(0,Oo.fileURLToPath)(e))}let a,n=_Ie(e,o);if(n.exists){a=(0,Oo.pathToFileURL)(n.pjsonPath);let u=n.imports;if(u)if(nd(u,t)&&!jq(t,"*")){let A=lC(a,u[t],"",t,e,!1,!0,r);if(A!=null)return A}else{let A="",p,h=LB(u);for(let E=0;E=I.length&&Uh(t,x)&&GIe(A,I)===1&&Gq(I,"*")===v&&(A=I,p=_h(t,v,t.length-x.length))}}if(A){let E=u[A],I=lC(a,E,p,A,e,!0,!0,r);if(I!=null)return I}}}MIt(t,a,e)}Pt();var jIt=new Set(["BUILTIN_NODE_RESOLUTION_FAILED","MISSING_DEPENDENCY","MISSING_PEER_DEPENDENCY","QUALIFIED_PATH_RESOLUTION_FAILED","UNDECLARED_DEPENDENCY"]);function ts(t,e,r={},o){o??=jIt.has(t)?"MODULE_NOT_FOUND":t;let a={configurable:!0,writable:!0,enumerable:!1};return Object.defineProperties(new Error(e),{code:{...a,value:o},pnpCode:{...a,value:t},data:{...a,value:r}})}function cu(t){return ue.normalize(ue.fromPortablePath(t))}var JIe=Ze(VIe());function XIe(t){return GIt(),Vq[t]}var Vq;function GIt(){Vq||(Vq={"--conditions":[],...zIe(YIt()),...zIe(process.execArgv)})}function zIe(t){return(0,JIe.default)({"--conditions":[String],"-C":"--conditions"},{argv:t,permissive:!0})}function YIt(){let t=[],e=WIt(process.env.NODE_OPTIONS||"",t);return t.length,e}function WIt(t,e){let r=[],o=!1,a=!0;for(let n=0;nparseInt(t,10)),ZIe=Ua>19||Ua===19&&$f>=2||Ua===18&&$f>=13,xJt=Ua===20&&$f<6||Ua===19&&$f>=3,kJt=Ua>19||Ua===19&&$f>=6,QJt=Ua>=21||Ua===20&&$f>=10||Ua===18&&$f>=19,FJt=Ua>=21||Ua===20&&$f>=10||Ua===18&&$f>=20,RJt=Ua>=22;function $Ie(t){if(process.env.WATCH_REPORT_DEPENDENCIES&&process.send)if(t=t.map(e=>ue.fromPortablePath(zs.resolveVirtual(ue.toPortablePath(e)))),ZIe)process.send({"watch:require":t});else for(let e of t)process.send({"watch:require":e})}function Jq(t,e){let r=Number(process.env.PNP_ALWAYS_WARN_ON_FALLBACK)>0,o=Number(process.env.PNP_DEBUG_LEVEL),a=/^(?![a-zA-Z]:[\\/]|\\\\|\.{0,2}(?:\/|$))((?:node:)?(?:@[^/]+\/)?[^/]+)\/*(.*|)$/,n=/^(\/|\.{1,2}(\/|$))/,u=/\/$/,A=/^\.{0,2}\//,p={name:null,reference:null},h=[],E=new Set;if(t.enableTopLevelFallback===!0&&h.push(p),e.compatibilityMode!==!1)for(let Te of["react-scripts","gatsby"]){let Fe=t.packageRegistry.get(Te);if(Fe)for(let ke of Fe.keys()){if(ke===null)throw new Error("Assertion failed: This reference shouldn't be null");h.push({name:Te,reference:ke})}}let{ignorePattern:I,packageRegistry:v,packageLocatorsByLocations:x}=t;function C(Te,Fe){return{fn:Te,args:Fe,error:null,result:null}}function R(Te){let Fe=process.stderr?.hasColors?.()??process.stdout.isTTY,ke=(et,Ue)=>`\x1B[${et}m${Ue}\x1B[0m`,Ye=Te.error;console.error(Ye?ke("31;1",`\u2716 ${Te.error?.message.replace(/\n.*/s,"")}`):ke("33;1","\u203C Resolution")),Te.args.length>0&&console.error();for(let et of Te.args)console.error(` ${ke("37;1","In \u2190")} ${(0,zq.inspect)(et,{colors:Fe,compact:!0})}`);Te.result&&(console.error(),console.error(` ${ke("37;1","Out \u2192")} ${(0,zq.inspect)(Te.result,{colors:Fe,compact:!0})}`));let be=new Error().stack.match(/(?<=^ +)at.*/gm)?.slice(2)??[];if(be.length>0){console.error();for(let et of be)console.error(` ${ke("38;5;244",et)}`)}console.error()}function L(Te,Fe){if(e.allowDebug===!1)return Fe;if(Number.isFinite(o)){if(o>=2)return(...ke)=>{let Ye=C(Te,ke);try{return Ye.result=Fe(...ke)}catch(be){throw Ye.error=be}finally{R(Ye)}};if(o>=1)return(...ke)=>{try{return Fe(...ke)}catch(Ye){let be=C(Te,ke);throw be.error=Ye,R(be),Ye}}}return Fe}function U(Te){let Fe=g(Te);if(!Fe)throw ts("INTERNAL","Couldn't find a matching entry in the dependency tree for the specified parent (this is probably an internal error)");return Fe}function z(Te){if(Te.name===null)return!0;for(let Fe of t.dependencyTreeRoots)if(Fe.name===Te.name&&Fe.reference===Te.reference)return!0;return!1}let te=new Set(["node","require",...XIe("--conditions")]);function ae(Te,Fe=te,ke){let Ye=Ae(V.join(Te,"internal.js"),{resolveIgnored:!0,includeDiscardFromLookup:!0});if(Ye===null)throw ts("INTERNAL",`The locator that owns the "${Te}" path can't be found inside the dependency tree (this is probably an internal error)`);let{packageLocation:be}=U(Ye),et=V.join(be,dr.manifest);if(!e.fakeFs.existsSync(et))return null;let Ue=JSON.parse(e.fakeFs.readFileSync(et,"utf8"));if(Ue.exports==null)return null;let S=V.contains(be,Te);if(S===null)throw ts("INTERNAL","unqualifiedPath doesn't contain the packageLocation (this is probably an internal error)");S!=="."&&!A.test(S)&&(S=`./${S}`);try{let w=YIe({packageJSONUrl:(0,id.pathToFileURL)(ue.fromPortablePath(et)),packageSubpath:S,exports:Ue.exports,base:ke?(0,id.pathToFileURL)(ue.fromPortablePath(ke)):null,conditions:Fe});return ue.toPortablePath((0,id.fileURLToPath)(w))}catch(w){throw ts("EXPORTS_RESOLUTION_FAILED",w.message,{unqualifiedPath:cu(Te),locator:Ye,pkgJson:Ue,subpath:cu(S),conditions:Fe},w.code)}}function le(Te,Fe,{extensions:ke}){let Ye;try{Fe.push(Te),Ye=e.fakeFs.statSync(Te)}catch{}if(Ye&&!Ye.isDirectory())return e.fakeFs.realpathSync(Te);if(Ye&&Ye.isDirectory()){let be;try{be=JSON.parse(e.fakeFs.readFileSync(V.join(Te,dr.manifest),"utf8"))}catch{}let et;if(be&&be.main&&(et=V.resolve(Te,be.main)),et&&et!==Te){let Ue=le(et,Fe,{extensions:ke});if(Ue!==null)return Ue}}for(let be=0,et=ke.length;be{let S=JSON.stringify(Ue.name);if(Ye.has(S))return;Ye.add(S);let w=me(Ue);for(let b of w)if(U(b).packagePeers.has(Te))be(b);else{let F=ke.get(b.name);typeof F>"u"&&ke.set(b.name,F=new Set),F.add(b.reference)}};be(Fe);let et=[];for(let Ue of[...ke.keys()].sort())for(let S of[...ke.get(Ue)].sort())et.push({name:Ue,reference:S});return et}function Ae(Te,{resolveIgnored:Fe=!1,includeDiscardFromLookup:ke=!1}={}){if(de(Te)&&!Fe)return null;let Ye=V.relative(t.basePath,Te);Ye.match(n)||(Ye=`./${Ye}`),Ye.endsWith("/")||(Ye=`${Ye}/`);do{let be=x.get(Ye);if(typeof be>"u"||be.discardFromLookup&&!ke){Ye=Ye.substring(0,Ye.lastIndexOf("/",Ye.length-2)+1);continue}return be.locator}while(Ye!=="");return null}function ne(Te){try{return e.fakeFs.readFileSync(ue.toPortablePath(Te),"utf8")}catch(Fe){if(Fe.code==="ENOENT")return;throw Fe}}function Z(Te,Fe,{considerBuiltins:ke=!0}={}){if(Te.startsWith("#"))throw new Error("resolveToUnqualified can not handle private import mappings");if(Te==="pnpapi")return ue.toPortablePath(e.pnpapiResolution);if(ke&&(0,ep.isBuiltin)(Te))return null;let Ye=cu(Te),be=Fe&&cu(Fe);if(Fe&&de(Fe)&&(!V.isAbsolute(Te)||Ae(Te)===null)){let S=Ce(Te,Fe);if(S===!1)throw ts("BUILTIN_NODE_RESOLUTION_FAILED",`The builtin node resolution algorithm was unable to resolve the requested module (it didn't go through the pnp resolver because the issuer was explicitely ignored by the regexp) + +Require request: "${Ye}" +Required by: ${be} +`,{request:Ye,issuer:be});return ue.toPortablePath(S)}let et,Ue=Te.match(a);if(Ue){if(!Fe)throw ts("API_ERROR","The resolveToUnqualified function must be called with a valid issuer when the path isn't a builtin nor absolute",{request:Ye,issuer:be});let[,S,w]=Ue,b=Ae(Fe);if(!b){let Re=Ce(Te,Fe);if(Re===!1)throw ts("BUILTIN_NODE_RESOLUTION_FAILED",`The builtin node resolution algorithm was unable to resolve the requested module (it didn't go through the pnp resolver because the issuer doesn't seem to be part of the Yarn-managed dependency tree). + +Require path: "${Ye}" +Required by: ${be} +`,{request:Ye,issuer:be});return ue.toPortablePath(Re)}let F=U(b).packageDependencies.get(S),J=null;if(F==null&&b.name!==null){let Re=t.fallbackExclusionList.get(b.name);if(!Re||!Re.has(b.reference)){for(let dt=0,jt=h.length;dtz(at))?X=ts("MISSING_PEER_DEPENDENCY",`${b.name} tried to access ${S} (a peer dependency) but it isn't provided by your application; this makes the require call ambiguous and unsound. + +Required package: ${S}${S!==Ye?` (via "${Ye}")`:""} +Required by: ${b.name}@${b.reference} (via ${be}) +${Re.map(at=>`Ancestor breaking the chain: ${at.name}@${at.reference} +`).join("")} +`,{request:Ye,issuer:be,issuerLocator:Object.assign({},b),dependencyName:S,brokenAncestors:Re}):X=ts("MISSING_PEER_DEPENDENCY",`${b.name} tried to access ${S} (a peer dependency) but it isn't provided by its ancestors; this makes the require call ambiguous and unsound. + +Required package: ${S}${S!==Ye?` (via "${Ye}")`:""} +Required by: ${b.name}@${b.reference} (via ${be}) + +${Re.map(at=>`Ancestor breaking the chain: ${at.name}@${at.reference} +`).join("")} +`,{request:Ye,issuer:be,issuerLocator:Object.assign({},b),dependencyName:S,brokenAncestors:Re})}else F===void 0&&(!ke&&(0,ep.isBuiltin)(Te)?z(b)?X=ts("UNDECLARED_DEPENDENCY",`Your application tried to access ${S}. While this module is usually interpreted as a Node builtin, your resolver is running inside a non-Node resolution context where such builtins are ignored. Since ${S} isn't otherwise declared in your dependencies, this makes the require call ambiguous and unsound. + +Required package: ${S}${S!==Ye?` (via "${Ye}")`:""} +Required by: ${be} +`,{request:Ye,issuer:be,dependencyName:S}):X=ts("UNDECLARED_DEPENDENCY",`${b.name} tried to access ${S}. While this module is usually interpreted as a Node builtin, your resolver is running inside a non-Node resolution context where such builtins are ignored. Since ${S} isn't otherwise declared in ${b.name}'s dependencies, this makes the require call ambiguous and unsound. + +Required package: ${S}${S!==Ye?` (via "${Ye}")`:""} +Required by: ${be} +`,{request:Ye,issuer:be,issuerLocator:Object.assign({},b),dependencyName:S}):z(b)?X=ts("UNDECLARED_DEPENDENCY",`Your application tried to access ${S}, but it isn't declared in your dependencies; this makes the require call ambiguous and unsound. + +Required package: ${S}${S!==Ye?` (via "${Ye}")`:""} +Required by: ${be} +`,{request:Ye,issuer:be,dependencyName:S}):X=ts("UNDECLARED_DEPENDENCY",`${b.name} tried to access ${S}, but it isn't declared in its dependencies; this makes the require call ambiguous and unsound. + +Required package: ${S}${S!==Ye?` (via "${Ye}")`:""} +Required by: ${b.name}@${b.reference} (via ${be}) +`,{request:Ye,issuer:be,issuerLocator:Object.assign({},b),dependencyName:S}));if(F==null){if(J===null||X===null)throw X||new Error("Assertion failed: Expected an error to have been set");F=J;let Re=X.message.replace(/\n.*/g,"");X.message=Re,!E.has(Re)&&o!==0&&(E.add(Re),process.emitWarning(X))}let $=Array.isArray(F)?{name:F[0],reference:F[1]}:{name:S,reference:F},ie=U($);if(!ie.packageLocation)throw ts("MISSING_DEPENDENCY",`A dependency seems valid but didn't get installed for some reason. This might be caused by a partial install, such as dev vs prod. + +Required package: ${$.name}@${$.reference}${$.name!==Ye?` (via "${Ye}")`:""} +Required by: ${b.name}@${b.reference} (via ${be}) +`,{request:Ye,issuer:be,dependencyLocator:Object.assign({},$)});let Se=ie.packageLocation;w?et=V.join(Se,w):et=Se}else if(V.isAbsolute(Te))et=V.normalize(Te);else{if(!Fe)throw ts("API_ERROR","The resolveToUnqualified function must be called with a valid issuer when the path isn't a builtin nor absolute",{request:Ye,issuer:be});let S=V.resolve(Fe);Fe.match(u)?et=V.normalize(V.join(S,Te)):et=V.normalize(V.join(V.dirname(S),Te))}return V.normalize(et)}function xe(Te,Fe,ke=te,Ye){if(n.test(Te))return Fe;let be=ae(Fe,ke,Ye);return be?V.normalize(be):Fe}function Ne(Te,{extensions:Fe=Object.keys(ep.Module._extensions)}={}){let ke=[],Ye=le(Te,ke,{extensions:Fe});if(Ye)return V.normalize(Ye);{$Ie(ke.map(Ue=>ue.fromPortablePath(Ue)));let be=cu(Te),et=Ae(Te);if(et){let{packageLocation:Ue}=U(et),S=!0;try{e.fakeFs.accessSync(Ue)}catch(w){if(w?.code==="ENOENT")S=!1;else{let b=(w?.message??w??"empty exception thrown").replace(/^[A-Z]/,y=>y.toLowerCase());throw ts("QUALIFIED_PATH_RESOLUTION_FAILED",`Required package exists but could not be accessed (${b}). + +Missing package: ${et.name}@${et.reference} +Expected package location: ${cu(Ue)} +`,{unqualifiedPath:be,extensions:Fe})}}if(!S){let w=Ue.includes("/unplugged/")?"Required unplugged package missing from disk. This may happen when switching branches without running installs (unplugged packages must be fully materialized on disk to work).":"Required package missing from disk. If you keep your packages inside your repository then restarting the Node process may be enough. Otherwise, try to run an install first.";throw ts("QUALIFIED_PATH_RESOLUTION_FAILED",`${w} + +Missing package: ${et.name}@${et.reference} +Expected package location: ${cu(Ue)} +`,{unqualifiedPath:be,extensions:Fe})}}throw ts("QUALIFIED_PATH_RESOLUTION_FAILED",`Qualified path resolution failed: we looked for the following paths, but none could be accessed. + +Source path: ${be} +${ke.map(Ue=>`Not found: ${cu(Ue)} +`).join("")}`,{unqualifiedPath:be,extensions:Fe})}}function ht(Te,Fe,ke){if(!Fe)throw new Error("Assertion failed: An issuer is required to resolve private import mappings");let Ye=WIe({name:Te,base:(0,id.pathToFileURL)(ue.fromPortablePath(Fe)),conditions:ke.conditions??te,readFileSyncFn:ne});if(Ye instanceof URL)return Ne(ue.toPortablePath((0,id.fileURLToPath)(Ye)),{extensions:ke.extensions});if(Ye.startsWith("#"))throw new Error("Mapping from one private import to another isn't allowed");return H(Ye,Fe,ke)}function H(Te,Fe,ke={}){try{if(Te.startsWith("#"))return ht(Te,Fe,ke);let{considerBuiltins:Ye,extensions:be,conditions:et}=ke,Ue=Z(Te,Fe,{considerBuiltins:Ye});if(Te==="pnpapi")return Ue;if(Ue===null)return null;let S=()=>Fe!==null?de(Fe):!1,w=(!Ye||!(0,ep.isBuiltin)(Te))&&!S()?xe(Te,Ue,et,Fe):Ue;return Ne(w,{extensions:be})}catch(Ye){throw Object.hasOwn(Ye,"pnpCode")&&Object.assign(Ye.data,{request:cu(Te),issuer:Fe&&cu(Fe)}),Ye}}function rt(Te){let Fe=V.normalize(Te),ke=zs.resolveVirtual(Fe);return ke!==Fe?ke:null}return{VERSIONS:Be,topLevel:Ee,getLocator:(Te,Fe)=>Array.isArray(Fe)?{name:Fe[0],reference:Fe[1]}:{name:Te,reference:Fe},getDependencyTreeRoots:()=>[...t.dependencyTreeRoots],getAllLocators(){let Te=[];for(let[Fe,ke]of v)for(let Ye of ke.keys())Fe!==null&&Ye!==null&&Te.push({name:Fe,reference:Ye});return Te},getPackageInformation:Te=>{let Fe=g(Te);if(Fe===null)return null;let ke=ue.fromPortablePath(Fe.packageLocation);return{...Fe,packageLocation:ke}},findPackageLocator:Te=>Ae(ue.toPortablePath(Te)),resolveToUnqualified:L("resolveToUnqualified",(Te,Fe,ke)=>{let Ye=Fe!==null?ue.toPortablePath(Fe):null,be=Z(ue.toPortablePath(Te),Ye,ke);return be===null?null:ue.fromPortablePath(be)}),resolveUnqualified:L("resolveUnqualified",(Te,Fe)=>ue.fromPortablePath(Ne(ue.toPortablePath(Te),Fe))),resolveRequest:L("resolveRequest",(Te,Fe,ke)=>{let Ye=Fe!==null?ue.toPortablePath(Fe):null,be=H(ue.toPortablePath(Te),Ye,ke);return be===null?null:ue.fromPortablePath(be)}),resolveVirtual:L("resolveVirtual",Te=>{let Fe=rt(ue.toPortablePath(Te));return Fe!==null?ue.fromPortablePath(Fe):null})}}Pt();var e1e=(t,e,r)=>{let o=TB(t),a=Uq(o,{basePath:e}),n=ue.join(e,dr.pnpCjs);return Jq(a,{fakeFs:r,pnpapiResolution:n})};var Zq=Ze(r1e());qt();var mA={};Vt(mA,{checkManifestCompatibility:()=>n1e,extractBuildRequest:()=>AQ,getExtractHint:()=>$q,hasBindingGyp:()=>ej});Ge();Pt();function n1e(t){return G.isPackageCompatible(t,Xi.getArchitectureSet())}function AQ(t,e,r,{configuration:o}){let a=[];for(let n of["preinstall","install","postinstall"])e.manifest.scripts.has(n)&&a.push({type:0,script:n});return!e.manifest.scripts.has("install")&&e.misc.hasBindingGyp&&a.push({type:1,script:"node-gyp rebuild"}),a.length===0?null:t.linkType!=="HARD"?{skipped:!0,explain:n=>n.reportWarningOnce(6,`${G.prettyLocator(o,t)} lists build scripts, but is referenced through a soft link. Soft links don't support build scripts, so they'll be ignored.`)}:r&&r.built===!1?{skipped:!0,explain:n=>n.reportInfoOnce(5,`${G.prettyLocator(o,t)} lists build scripts, but its build has been explicitly disabled through configuration.`)}:!o.get("enableScripts")&&!r.built?{skipped:!0,explain:n=>n.reportWarningOnce(4,`${G.prettyLocator(o,t)} lists build scripts, but all build scripts have been disabled.`)}:n1e(t)?{skipped:!1,directives:a}:{skipped:!0,explain:n=>n.reportWarningOnce(76,`${G.prettyLocator(o,t)} The ${Xi.getArchitectureName()} architecture is incompatible with this package, build skipped.`)}}var VIt=new Set([".exe",".bin",".h",".hh",".hpp",".c",".cc",".cpp",".java",".jar",".node"]);function $q(t){return t.packageFs.getExtractHint({relevantExtensions:VIt})}function ej(t){let e=V.join(t.prefixPath,"binding.gyp");return t.packageFs.existsSync(e)}var jB={};Vt(jB,{getUnpluggedPath:()=>qB});Ge();Pt();function qB(t,{configuration:e}){return V.resolve(e.get("pnpUnpluggedFolder"),G.slugifyLocator(t))}var zIt=new Set([G.makeIdent(null,"open").identHash,G.makeIdent(null,"opn").identHash]),Hh=class{constructor(){this.mode="strict";this.pnpCache=new Map}getCustomDataKey(){return JSON.stringify({name:"PnpLinker",version:2})}supportsPackage(e,r){return this.isEnabled(r)}async findPackageLocation(e,r){if(!this.isEnabled(r))throw new Error("Assertion failed: Expected the PnP linker to be enabled");let o=qh(r.project).cjs;if(!oe.existsSync(o))throw new st(`The project in ${pe.pretty(r.project.configuration,`${r.project.cwd}/package.json`,pe.Type.PATH)} doesn't seem to have been installed - running an install there might help`);let a=He.getFactoryWithDefault(this.pnpCache,o,()=>He.dynamicRequire(o,{cachingStrategy:He.CachingStrategy.FsTime})),n={name:G.stringifyIdent(e),reference:e.reference},u=a.getPackageInformation(n);if(!u)throw new st(`Couldn't find ${G.prettyLocator(r.project.configuration,e)} in the currently installed PnP map - running an install might help`);return ue.toPortablePath(u.packageLocation)}async findPackageLocator(e,r){if(!this.isEnabled(r))return null;let o=qh(r.project).cjs;if(!oe.existsSync(o))return null;let n=He.getFactoryWithDefault(this.pnpCache,o,()=>He.dynamicRequire(o,{cachingStrategy:He.CachingStrategy.FsTime})).findPackageLocator(ue.fromPortablePath(e));return n?G.makeLocator(G.parseIdent(n.name),n.reference):null}makeInstaller(e){return new sd(e)}isEnabled(e){return!(e.project.configuration.get("nodeLinker")!=="pnp"||e.project.configuration.get("pnpMode")!==this.mode)}},sd=class{constructor(e){this.opts=e;this.mode="strict";this.asyncActions=new He.AsyncActions(10);this.packageRegistry=new Map;this.virtualTemplates=new Map;this.isESMLoaderRequired=!1;this.customData={store:new Map};this.unpluggedPaths=new Set;this.opts=e}attachCustomData(e){this.customData=e}async installPackage(e,r,o){let a=G.stringifyIdent(e),n=e.reference,u=!!this.opts.project.tryWorkspaceByLocator(e),A=G.isVirtualLocator(e),p=e.peerDependencies.size>0&&!A,h=!p&&!u,E=!p&&e.linkType!=="SOFT",I,v;if(h||E){let te=A?G.devirtualizeLocator(e):e;I=this.customData.store.get(te.locatorHash),typeof I>"u"&&(I=await JIt(r),e.linkType==="HARD"&&this.customData.store.set(te.locatorHash,I)),I.manifest.type==="module"&&(this.isESMLoaderRequired=!0),v=this.opts.project.getDependencyMeta(te,e.version)}let x=h?AQ(e,I,v,{configuration:this.opts.project.configuration}):null,C=E?await this.unplugPackageIfNeeded(e,I,r,v,o):r.packageFs;if(V.isAbsolute(r.prefixPath))throw new Error(`Assertion failed: Expected the prefix path (${r.prefixPath}) to be relative to the parent`);let R=V.resolve(C.getRealPath(),r.prefixPath),L=tj(this.opts.project.cwd,R),U=new Map,z=new Set;if(A){for(let te of e.peerDependencies.values())U.set(G.stringifyIdent(te),null),z.add(G.stringifyIdent(te));if(!u){let te=G.devirtualizeLocator(e);this.virtualTemplates.set(te.locatorHash,{location:tj(this.opts.project.cwd,zs.resolveVirtual(R)),locator:te})}}return He.getMapWithDefault(this.packageRegistry,a).set(n,{packageLocation:L,packageDependencies:U,packagePeers:z,linkType:e.linkType,discardFromLookup:r.discardFromLookup||!1}),{packageLocation:R,buildRequest:x}}async attachInternalDependencies(e,r){let o=this.getPackageInformation(e);for(let[a,n]of r){let u=G.areIdentsEqual(a,n)?n.reference:[G.stringifyIdent(n),n.reference];o.packageDependencies.set(G.stringifyIdent(a),u)}}async attachExternalDependents(e,r){for(let o of r)this.getDiskInformation(o).packageDependencies.set(G.stringifyIdent(e),e.reference)}async finalizeInstall(){if(this.opts.project.configuration.get("pnpMode")!==this.mode)return;let e=qh(this.opts.project);if(this.isEsmEnabled()||await oe.removePromise(e.esmLoader),this.opts.project.configuration.get("nodeLinker")!=="pnp"){await oe.removePromise(e.cjs),await oe.removePromise(e.data),await oe.removePromise(e.esmLoader),await oe.removePromise(this.opts.project.configuration.get("pnpUnpluggedFolder"));return}for(let{locator:E,location:I}of this.virtualTemplates.values())He.getMapWithDefault(this.packageRegistry,G.stringifyIdent(E)).set(E.reference,{packageLocation:I,packageDependencies:new Map,packagePeers:new Set,linkType:"SOFT",discardFromLookup:!1});this.packageRegistry.set(null,new Map([[null,this.getPackageInformation(this.opts.project.topLevelWorkspace.anchoredLocator)]]));let r=this.opts.project.configuration.get("pnpFallbackMode"),o=this.opts.project.workspaces.map(({anchoredLocator:E})=>({name:G.stringifyIdent(E),reference:E.reference})),a=r!=="none",n=[],u=new Map,A=He.buildIgnorePattern([".yarn/sdks/**",...this.opts.project.configuration.get("pnpIgnorePatterns")]),p=this.packageRegistry,h=this.opts.project.configuration.get("pnpShebang");if(r==="dependencies-only")for(let E of this.opts.project.storedPackages.values())this.opts.project.tryWorkspaceByLocator(E)&&n.push({name:G.stringifyIdent(E),reference:E.reference});return await this.asyncActions.wait(),await this.finalizeInstallWithPnp({dependencyTreeRoots:o,enableTopLevelFallback:a,fallbackExclusionList:n,fallbackPool:u,ignorePattern:A,packageRegistry:p,shebang:h}),{customData:this.customData}}async transformPnpSettings(e){}isEsmEnabled(){if(this.opts.project.configuration.sources.has("pnpEnableEsmLoader"))return this.opts.project.configuration.get("pnpEnableEsmLoader");if(this.isESMLoaderRequired)return!0;for(let e of this.opts.project.workspaces)if(e.manifest.type==="module")return!0;return!1}async finalizeInstallWithPnp(e){let r=qh(this.opts.project),o=await this.locateNodeModules(e.ignorePattern);if(o.length>0){this.opts.report.reportWarning(31,"One or more node_modules have been detected and will be removed. This operation may take some time.");for(let n of o)await oe.removePromise(n)}if(await this.transformPnpSettings(e),this.opts.project.configuration.get("pnpEnableInlining")){let n=kIe(e);await oe.changeFilePromise(r.cjs,n,{automaticNewlines:!0,mode:493}),await oe.removePromise(r.data)}else{let{dataFile:n,loaderFile:u}=QIe(e);await oe.changeFilePromise(r.cjs,u,{automaticNewlines:!0,mode:493}),await oe.changeFilePromise(r.data,n,{automaticNewlines:!0,mode:420})}this.isEsmEnabled()&&(this.opts.report.reportWarning(0,"ESM support for PnP uses the experimental loader API and is therefore experimental"),await oe.changeFilePromise(r.esmLoader,(0,Zq.default)(),{automaticNewlines:!0,mode:420}));let a=this.opts.project.configuration.get("pnpUnpluggedFolder");if(this.unpluggedPaths.size===0)await oe.removePromise(a);else for(let n of await oe.readdirPromise(a)){let u=V.resolve(a,n);this.unpluggedPaths.has(u)||await oe.removePromise(u)}}async locateNodeModules(e){let r=[],o=e?new RegExp(e):null;for(let a of this.opts.project.workspaces){let n=V.join(a.cwd,"node_modules");if(o&&o.test(V.relative(this.opts.project.cwd,a.cwd))||!oe.existsSync(n))continue;let u=await oe.readdirPromise(n,{withFileTypes:!0}),A=u.filter(p=>!p.isDirectory()||p.name===".bin"||!p.name.startsWith("."));if(A.length===u.length)r.push(n);else for(let p of A)r.push(V.join(n,p.name))}return r}async unplugPackageIfNeeded(e,r,o,a,n){return this.shouldBeUnplugged(e,r,a)?this.unplugPackage(e,o,n):o.packageFs}shouldBeUnplugged(e,r,o){return typeof o.unplugged<"u"?o.unplugged:zIt.has(e.identHash)||e.conditions!=null?!0:r.manifest.preferUnplugged!==null?r.manifest.preferUnplugged:!!(AQ(e,r,o,{configuration:this.opts.project.configuration})?.skipped===!1||r.misc.extractHint)}async unplugPackage(e,r,o){let a=qB(e,{configuration:this.opts.project.configuration});return this.opts.project.disabledLocators.has(e.locatorHash)?new Hu(a,{baseFs:r.packageFs,pathUtils:V}):(this.unpluggedPaths.add(a),o.holdFetchResult(this.asyncActions.set(e.locatorHash,async()=>{let n=V.join(a,r.prefixPath,".ready");await oe.existsPromise(n)||(this.opts.project.storedBuildState.delete(e.locatorHash),await oe.mkdirPromise(a,{recursive:!0}),await oe.copyPromise(a,It.dot,{baseFs:r.packageFs,overwrite:!1}),await oe.writeFilePromise(n,""))})),new gn(a))}getPackageInformation(e){let r=G.stringifyIdent(e),o=e.reference,a=this.packageRegistry.get(r);if(!a)throw new Error(`Assertion failed: The package information store should have been available (for ${G.prettyIdent(this.opts.project.configuration,e)})`);let n=a.get(o);if(!n)throw new Error(`Assertion failed: The package information should have been available (for ${G.prettyLocator(this.opts.project.configuration,e)})`);return n}getDiskInformation(e){let r=He.getMapWithDefault(this.packageRegistry,"@@disk"),o=tj(this.opts.project.cwd,e);return He.getFactoryWithDefault(r,o,()=>({packageLocation:o,packageDependencies:new Map,packagePeers:new Set,linkType:"SOFT",discardFromLookup:!1}))}};function tj(t,e){let r=V.relative(t,e);return r.match(/^\.{0,2}\//)||(r=`./${r}`),r.replace(/\/?$/,"/")}async function JIt(t){let e=await Ut.tryFind(t.prefixPath,{baseFs:t.packageFs})??new Ut,r=new Set(["preinstall","install","postinstall"]);for(let o of e.scripts.keys())r.has(o)||e.scripts.delete(o);return{manifest:{scripts:e.scripts,preferUnplugged:e.preferUnplugged,type:e.type},misc:{extractHint:$q(t),hasBindingGyp:ej(t)}}}Ge();Ge();qt();var i1e=Ze($o());var cC=class extends ut{constructor(){super(...arguments);this.all=ge.Boolean("-A,--all",!1,{description:"Unplug direct dependencies from the entire project"});this.recursive=ge.Boolean("-R,--recursive",!1,{description:"Unplug both direct and transitive dependencies"});this.json=ge.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.patterns=ge.Rest()}static{this.paths=[["unplug"]]}static{this.usage=it.Usage({description:"force the unpacking of a list of packages",details:"\n This command will add the selectors matching the specified patterns to the list of packages that must be unplugged when installed.\n\n A package being unplugged means that instead of being referenced directly through its archive, it will be unpacked at install time in the directory configured via `pnpUnpluggedFolder`. Note that unpacking packages this way is generally not recommended because it'll make it harder to store your packages within the repository. However, it's a good approach to quickly and safely debug some packages, and can even sometimes be required depending on the context (for example when the package contains shellscripts).\n\n Running the command will set a persistent flag inside your top-level `package.json`, in the `dependenciesMeta` field. As such, to undo its effects, you'll need to revert the changes made to the manifest and run `yarn install` to apply the modification.\n\n By default, only direct dependencies from the current workspace are affected. If `-A,--all` is set, direct dependencies from the entire project are affected. Using the `-R,--recursive` flag will affect transitive dependencies as well as direct ones.\n\n This command accepts glob patterns inside the scope and name components (not the range). Make sure to escape the patterns to prevent your own shell from trying to expand them.\n ",examples:[["Unplug the lodash dependency from the active workspace","yarn unplug lodash"],["Unplug all instances of lodash referenced by any workspace","yarn unplug lodash -A"],["Unplug all instances of lodash referenced by the active workspace and its dependencies","yarn unplug lodash -R"],["Unplug all instances of lodash, anywhere","yarn unplug lodash -AR"],["Unplug one specific version of lodash","yarn unplug lodash@1.2.3"],["Unplug all packages with the `@babel` scope","yarn unplug '@babel/*'"],["Unplug all packages (only for testing, not recommended)","yarn unplug -R '*'"]]})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await kt.find(r,this.context.cwd),n=await Gr.find(r);if(!a)throw new sr(o.cwd,this.context.cwd);if(r.get("nodeLinker")!=="pnp")throw new st("This command can only be used if the `nodeLinker` option is set to `pnp`");await o.restoreInstallState();let u=new Set(this.patterns),A=this.patterns.map(x=>{let C=G.parseDescriptor(x),R=C.range!=="unknown"?C:G.makeDescriptor(C,"*");if(!Lr.validRange(R.range))throw new st(`The range of the descriptor patterns must be a valid semver range (${G.prettyDescriptor(r,R)})`);return L=>{let U=G.stringifyIdent(L);return!i1e.default.isMatch(U,G.stringifyIdent(R))||L.version&&!Lr.satisfiesWithPrereleases(L.version,R.range)?!1:(u.delete(x),!0)}}),p=()=>{let x=[];for(let C of o.storedPackages.values())!o.tryWorkspaceByLocator(C)&&!G.isVirtualLocator(C)&&A.some(R=>R(C))&&x.push(C);return x},h=x=>{let C=new Set,R=[],L=(U,z)=>{if(C.has(U.locatorHash))return;let te=!!o.tryWorkspaceByLocator(U);if(!(z>0&&!this.recursive&&te)&&(C.add(U.locatorHash),!o.tryWorkspaceByLocator(U)&&A.some(ae=>ae(U))&&R.push(U),!(z>0&&!this.recursive)))for(let ae of U.dependencies.values()){let le=o.storedResolutions.get(ae.descriptorHash);if(!le)throw new Error("Assertion failed: The resolution should have been registered");let ce=o.storedPackages.get(le);if(!ce)throw new Error("Assertion failed: The package should have been registered");L(ce,z+1)}};for(let U of x)L(U.anchoredPackage,0);return R},E,I;if(this.all&&this.recursive?(E=p(),I="the project"):this.all?(E=h(o.workspaces),I="any workspace"):(E=h([a]),I="this workspace"),u.size>1)throw new st(`Patterns ${pe.prettyList(r,u,pe.Type.CODE)} don't match any packages referenced by ${I}`);if(u.size>0)throw new st(`Pattern ${pe.prettyList(r,u,pe.Type.CODE)} doesn't match any packages referenced by ${I}`);E=He.sortMap(E,x=>G.stringifyLocator(x));let v=await Rt.start({configuration:r,stdout:this.context.stdout,json:this.json},async x=>{for(let C of E){let R=C.version??"unknown",L=o.topLevelWorkspace.manifest.ensureDependencyMeta(G.makeDescriptor(C,R));L.unplugged=!0,x.reportInfo(0,`Will unpack ${G.prettyLocator(r,C)} to ${pe.pretty(r,qB(C,{configuration:r}),pe.Type.PATH)}`),x.reportJson({locator:G.stringifyLocator(C),version:R})}await o.topLevelWorkspace.persistManifest(),this.json||x.reportSeparator()});return v.hasErrors()?v.exitCode():await o.installWithNewReport({json:this.json,stdout:this.context.stdout},{cache:n})}};var qh=t=>({cjs:V.join(t.cwd,dr.pnpCjs),data:V.join(t.cwd,dr.pnpData),esmLoader:V.join(t.cwd,dr.pnpEsmLoader)}),o1e=t=>/\s/.test(t)?JSON.stringify(t):t;async function XIt(t,e,r){let o=/\s*--require\s+\S*\.pnp\.c?js\s*/g,a=/\s*--experimental-loader\s+\S*\.pnp\.loader\.mjs\s*/,n=(e.NODE_OPTIONS??"").replace(o," ").replace(a," ").trim();if(t.configuration.get("nodeLinker")!=="pnp"){e.NODE_OPTIONS=n||void 0;return}let u=qh(t),A=`--require ${o1e(ue.fromPortablePath(u.cjs))}`;oe.existsSync(u.esmLoader)&&(A=`${A} --experimental-loader ${(0,s1e.pathToFileURL)(ue.fromPortablePath(u.esmLoader)).href}`),oe.existsSync(u.cjs)&&(e.NODE_OPTIONS=n?`${A} ${n}`:A)}async function ZIt(t,e){let r=qh(t);e(r.cjs),e(r.data),e(r.esmLoader),e(t.configuration.get("pnpUnpluggedFolder"))}var $It={hooks:{populateYarnPaths:ZIt,setupScriptEnvironment:XIt},configuration:{nodeLinker:{description:'The linker used for installing Node packages, one of: "pnp", "pnpm", or "node-modules"',type:"STRING",default:"pnp"},winLinkType:{description:"Whether Yarn should use Windows Junctions or symlinks when creating links on Windows.",type:"STRING",values:["junctions","symlinks"],default:"junctions"},pnpMode:{description:"If 'strict', generates standard PnP maps. If 'loose', merges them with the n_m resolution.",type:"STRING",default:"strict"},pnpShebang:{description:"String to prepend to the generated PnP script",type:"STRING",default:"#!/usr/bin/env node"},pnpIgnorePatterns:{description:"Array of glob patterns; files matching them will use the classic resolution",type:"STRING",default:[],isArray:!0},pnpEnableEsmLoader:{description:"If true, Yarn will generate an ESM loader (`.pnp.loader.mjs`). If this is not explicitly set Yarn tries to automatically detect whether ESM support is required.",type:"BOOLEAN",default:!1},pnpEnableInlining:{description:"If true, the PnP data will be inlined along with the generated loader",type:"BOOLEAN",default:!0},pnpFallbackMode:{description:"If true, the generated PnP loader will follow the top-level fallback rule",type:"STRING",default:"dependencies-only"},pnpUnpluggedFolder:{description:"Folder where the unplugged packages must be stored",type:"ABSOLUTE_PATH",default:"./.yarn/unplugged"}},linkers:[Hh],commands:[cC]},e1t=$It;var h1e=Ze(A1e());qt();var cj=Ze(ve("crypto")),g1e=Ze(ve("fs")),d1e=1,Di="node_modules",fQ=".bin",m1e=".yarn-state.yml",m1t=1e3,uj=(o=>(o.CLASSIC="classic",o.HARDLINKS_LOCAL="hardlinks-local",o.HARDLINKS_GLOBAL="hardlinks-global",o))(uj||{}),GB=class{constructor(){this.installStateCache=new Map}getCustomDataKey(){return JSON.stringify({name:"NodeModulesLinker",version:3})}supportsPackage(e,r){return this.isEnabled(r)}async findPackageLocation(e,r){if(!this.isEnabled(r))throw new Error("Assertion failed: Expected the node-modules linker to be enabled");let o=r.project.tryWorkspaceByLocator(e);if(o)return o.cwd;let a=await He.getFactoryWithDefault(this.installStateCache,r.project.cwd,async()=>await lj(r.project,{unrollAliases:!0}));if(a===null)throw new st("Couldn't find the node_modules state file - running an install might help (findPackageLocation)");let n=a.locatorMap.get(G.stringifyLocator(e));if(!n){let p=new st(`Couldn't find ${G.prettyLocator(r.project.configuration,e)} in the currently installed node_modules map - running an install might help`);throw p.code="LOCATOR_NOT_INSTALLED",p}let u=n.locations.sort((p,h)=>p.split(V.sep).length-h.split(V.sep).length),A=V.join(r.project.configuration.startingCwd,Di);return u.find(p=>V.contains(A,p))||n.locations[0]}async findPackageLocator(e,r){if(!this.isEnabled(r))return null;let o=await He.getFactoryWithDefault(this.installStateCache,r.project.cwd,async()=>await lj(r.project,{unrollAliases:!0}));if(o===null)return null;let{locationRoot:a,segments:n}=pQ(V.resolve(e),{skipPrefix:r.project.cwd}),u=o.locationTree.get(a);if(!u)return null;let A=u.locator;for(let p of n){if(u=u.children.get(p),!u)break;A=u.locator||A}return G.parseLocator(A)}makeInstaller(e){return new aj(e)}isEnabled(e){return e.project.configuration.get("nodeLinker")==="node-modules"}},aj=class{constructor(e){this.opts=e;this.localStore=new Map;this.realLocatorChecksums=new Map;this.customData={store:new Map}}attachCustomData(e){this.customData=e}async installPackage(e,r){let o=V.resolve(r.packageFs.getRealPath(),r.prefixPath),a=this.customData.store.get(e.locatorHash);if(typeof a>"u"&&(a=await y1t(e,r),e.linkType==="HARD"&&this.customData.store.set(e.locatorHash,a)),!G.isPackageCompatible(e,this.opts.project.configuration.getSupportedArchitectures()))return{packageLocation:null,buildRequest:null};let n=new Map,u=new Set;n.has(G.stringifyIdent(e))||n.set(G.stringifyIdent(e),e.reference);let A=e;if(G.isVirtualLocator(e)){A=G.devirtualizeLocator(e);for(let E of e.peerDependencies.values())n.set(G.stringifyIdent(E),null),u.add(G.stringifyIdent(E))}let p={packageLocation:`${ue.fromPortablePath(o)}/`,packageDependencies:n,packagePeers:u,linkType:e.linkType,discardFromLookup:r.discardFromLookup??!1};this.localStore.set(e.locatorHash,{pkg:e,customPackageData:a,dependencyMeta:this.opts.project.getDependencyMeta(e,e.version),pnpNode:p});let h=r.checksum?r.checksum.substring(r.checksum.indexOf("/")+1):null;return this.realLocatorChecksums.set(A.locatorHash,h),{packageLocation:o,buildRequest:null}}async attachInternalDependencies(e,r){let o=this.localStore.get(e.locatorHash);if(typeof o>"u")throw new Error("Assertion failed: Expected information object to have been registered");for(let[a,n]of r){let u=G.areIdentsEqual(a,n)?n.reference:[G.stringifyIdent(n),n.reference];o.pnpNode.packageDependencies.set(G.stringifyIdent(a),u)}}async attachExternalDependents(e,r){throw new Error("External dependencies haven't been implemented for the node-modules linker")}async finalizeInstall(){if(this.opts.project.configuration.get("nodeLinker")!=="node-modules")return;let e=new zs({baseFs:new rA({maxOpenFiles:80,readOnlyArchives:!0})}),r=await lj(this.opts.project),o=this.opts.project.configuration.get("nmMode");(r===null||o!==r.nmMode)&&(this.opts.project.storedBuildState.clear(),r={locatorMap:new Map,binSymlinks:new Map,locationTree:new Map,nmMode:o,mtimeMs:0});let a=new Map(this.opts.project.workspaces.map(v=>{let x=this.opts.project.configuration.get("nmHoistingLimits");try{x=He.validateEnum(QB,v.manifest.installConfig?.hoistingLimits??x)}catch{let R=G.prettyWorkspace(this.opts.project.configuration,v);this.opts.report.reportWarning(57,`${R}: Invalid 'installConfig.hoistingLimits' value. Expected one of ${Object.values(QB).join(", ")}, using default: "${x}"`)}return[v.relativeCwd,x]})),n=new Map(this.opts.project.workspaces.map(v=>{let x=this.opts.project.configuration.get("nmSelfReferences");return x=v.manifest.installConfig?.selfReferences??x,[v.relativeCwd,x]})),u={VERSIONS:{std:1},topLevel:{name:null,reference:null},getLocator:(v,x)=>Array.isArray(x)?{name:x[0],reference:x[1]}:{name:v,reference:x},getDependencyTreeRoots:()=>this.opts.project.workspaces.map(v=>{let x=v.anchoredLocator;return{name:G.stringifyIdent(x),reference:x.reference}}),getPackageInformation:v=>{let x=v.reference===null?this.opts.project.topLevelWorkspace.anchoredLocator:G.makeLocator(G.parseIdent(v.name),v.reference),C=this.localStore.get(x.locatorHash);if(typeof C>"u")throw new Error("Assertion failed: Expected the package reference to have been registered");return C.pnpNode},findPackageLocator:v=>{let x=this.opts.project.tryWorkspaceByCwd(ue.toPortablePath(v));if(x!==null){let C=x.anchoredLocator;return{name:G.stringifyIdent(C),reference:C.reference}}throw new Error("Assertion failed: Unimplemented")},resolveToUnqualified:()=>{throw new Error("Assertion failed: Unimplemented")},resolveUnqualified:()=>{throw new Error("Assertion failed: Unimplemented")},resolveRequest:()=>{throw new Error("Assertion failed: Unimplemented")},resolveVirtual:v=>ue.fromPortablePath(zs.resolveVirtual(ue.toPortablePath(v)))},{tree:A,errors:p,preserveSymlinksRequired:h}=FB(u,{pnpifyFs:!1,validateExternalSoftLinks:!0,hoistingLimitsByCwd:a,project:this.opts.project,selfReferencesByCwd:n});if(!A){for(let{messageName:v,text:x}of p)this.opts.report.reportError(v,x);return}let E=Mq(A);await v1t(r,E,{baseFs:e,project:this.opts.project,report:this.opts.report,realLocatorChecksums:this.realLocatorChecksums,loadManifest:async v=>{let x=G.parseLocator(v),C=this.localStore.get(x.locatorHash);if(typeof C>"u")throw new Error("Assertion failed: Expected the slot to exist");return C.customPackageData.manifest}});let I=[];for(let[v,x]of E.entries()){if(C1e(v))continue;let C=G.parseLocator(v),R=this.localStore.get(C.locatorHash);if(typeof R>"u")throw new Error("Assertion failed: Expected the slot to exist");if(this.opts.project.tryWorkspaceByLocator(R.pkg))continue;let L=mA.extractBuildRequest(R.pkg,R.customPackageData,R.dependencyMeta,{configuration:this.opts.project.configuration});L&&I.push({buildLocations:x.locations,locator:C,buildRequest:L})}return h&&this.opts.report.reportWarning(72,`The application uses portals and that's why ${pe.pretty(this.opts.project.configuration,"--preserve-symlinks",pe.Type.CODE)} Node option is required for launching it`),{customData:this.customData,records:I}}};async function y1t(t,e){let r=await Ut.tryFind(e.prefixPath,{baseFs:e.packageFs})??new Ut,o=new Set(["preinstall","install","postinstall"]);for(let a of r.scripts.keys())o.has(a)||r.scripts.delete(a);return{manifest:{bin:r.bin,scripts:r.scripts},misc:{hasBindingGyp:mA.hasBindingGyp(e)}}}async function E1t(t,e,r,o,{installChangedByUser:a}){let n="";n+=`# Warning: This file is automatically generated. Removing it is fine, but will +`,n+=`# cause your node_modules installation to become invalidated. +`,n+=` +`,n+=`__metadata: +`,n+=` version: ${d1e} +`,n+=` nmMode: ${o.value} +`;let u=Array.from(e.keys()).sort(),A=G.stringifyLocator(t.topLevelWorkspace.anchoredLocator);for(let E of u){let I=e.get(E);n+=` +`,n+=`${JSON.stringify(E)}: +`,n+=` locations: +`;for(let v of I.locations){let x=V.contains(t.cwd,v);if(x===null)throw new Error(`Assertion failed: Expected the path to be within the project (${v})`);n+=` - ${JSON.stringify(x)} +`}if(I.aliases.length>0){n+=` aliases: +`;for(let v of I.aliases)n+=` - ${JSON.stringify(v)} +`}if(E===A&&r.size>0){n+=` bin: +`;for(let[v,x]of r){let C=V.contains(t.cwd,v);if(C===null)throw new Error(`Assertion failed: Expected the path to be within the project (${v})`);n+=` ${JSON.stringify(C)}: +`;for(let[R,L]of x){let U=V.relative(V.join(v,Di),L);n+=` ${JSON.stringify(R)}: ${JSON.stringify(U)} +`}}}}let p=t.cwd,h=V.join(p,Di,m1e);a&&await oe.removePromise(h),await oe.changeFilePromise(h,n,{automaticNewlines:!0})}async function lj(t,{unrollAliases:e=!1}={}){let r=t.cwd,o=V.join(r,Di,m1e),a;try{a=await oe.statPromise(o)}catch{}if(!a)return null;let n=Ki(await oe.readFilePromise(o,"utf8"));if(n.__metadata.version>d1e)return null;let u=n.__metadata.nmMode||"classic",A=new Map,p=new Map;delete n.__metadata;for(let[h,E]of Object.entries(n)){let I=E.locations.map(x=>V.join(r,x)),v=E.bin;if(v)for(let[x,C]of Object.entries(v)){let R=V.join(r,ue.toPortablePath(x)),L=He.getMapWithDefault(p,R);for(let[U,z]of Object.entries(C))L.set(U,ue.toPortablePath([R,Di,z].join(V.sep)))}if(A.set(h,{target:It.dot,linkType:"HARD",locations:I,aliases:E.aliases||[]}),e&&E.aliases)for(let x of E.aliases){let{scope:C,name:R}=G.parseLocator(h),L=G.makeLocator(G.makeIdent(C,R),x),U=G.stringifyLocator(L);A.set(U,{target:It.dot,linkType:"HARD",locations:I,aliases:[]})}}return{locatorMap:A,binSymlinks:p,locationTree:y1e(A,{skipPrefix:t.cwd}),nmMode:u,mtimeMs:a.mtimeMs}}var AC=async(t,e)=>{if(t.split(V.sep).indexOf(Di)<0)throw new Error(`Assertion failed: trying to remove dir that doesn't contain node_modules: ${t}`);try{let r;if(!e.innerLoop&&(r=await oe.lstatPromise(t),!r.isDirectory()&&!r.isSymbolicLink()||r.isSymbolicLink()&&!e.isWorkspaceDir)){await oe.unlinkPromise(t);return}let o=await oe.readdirPromise(t,{withFileTypes:!0});for(let n of o){let u=V.join(t,n.name);n.isDirectory()?(n.name!==Di||e&&e.innerLoop)&&await AC(u,{innerLoop:!0,contentsOnly:!1}):await oe.unlinkPromise(u)}let a=!e.innerLoop&&e.isWorkspaceDir&&r?.isSymbolicLink();!e.contentsOnly&&!a&&await oe.rmdirPromise(t)}catch(r){if(r.code!=="ENOENT"&&r.code!=="ENOTEMPTY")throw r}},f1e=4,pQ=(t,{skipPrefix:e})=>{let r=V.contains(e,t);if(r===null)throw new Error(`Assertion failed: Writing attempt prevented to ${t} which is outside project root: ${e}`);let o=r.split(V.sep).filter(p=>p!==""),a=o.indexOf(Di),n=o.slice(0,a).join(V.sep),u=V.join(e,n),A=o.slice(a);return{locationRoot:u,segments:A}},y1e=(t,{skipPrefix:e})=>{let r=new Map;if(t===null)return r;let o=()=>({children:new Map,linkType:"HARD"});for(let[a,n]of t.entries()){if(n.linkType==="SOFT"&&V.contains(e,n.target)!==null){let A=He.getFactoryWithDefault(r,n.target,o);A.locator=a,A.linkType=n.linkType}for(let u of n.locations){let{locationRoot:A,segments:p}=pQ(u,{skipPrefix:e}),h=He.getFactoryWithDefault(r,A,o);for(let E=0;E{if(process.platform==="win32"&&r==="junctions"){let o;try{o=await oe.lstatPromise(t)}catch{}if(!o||o.isDirectory()){await oe.symlinkPromise(t,e,"junction");return}}await oe.symlinkPromise(V.relative(V.dirname(e),t),e)};async function E1e(t,e,r){let o=V.join(t,`${cj.default.randomBytes(16).toString("hex")}.tmp`);try{await oe.writeFilePromise(o,r);try{await oe.linkPromise(o,e)}catch{}}finally{await oe.unlinkPromise(o)}}async function C1t({srcPath:t,dstPath:e,entry:r,globalHardlinksStore:o,baseFs:a,nmMode:n}){if(r.kind==="file"){if(n.value==="hardlinks-global"&&o&&r.digest){let A=V.join(o,r.digest.substring(0,2),`${r.digest.substring(2)}.dat`),p;try{let h=await oe.statPromise(A);if(h&&(!r.mtimeMs||h.mtimeMs>r.mtimeMs||h.mtimeMs{await oe.mkdirPromise(t,{recursive:!0});let A=async(E=It.dot)=>{let I=V.join(e,E),v=await r.readdirPromise(I,{withFileTypes:!0}),x=new Map;for(let C of v){let R=V.join(E,C.name),L,U=V.join(I,C.name);if(C.isFile()){if(L={kind:"file",mode:(await r.lstatPromise(U)).mode},a.value==="hardlinks-global"){let z=await wn.checksumFile(U,{baseFs:r,algorithm:"sha1"});L.digest=z}}else if(C.isDirectory())L={kind:"directory"};else if(C.isSymbolicLink())L={kind:"symlink",symlinkTo:await r.readlinkPromise(U)};else throw new Error(`Unsupported file type (file: ${U}, mode: 0o${await r.statSync(U).mode.toString(8).padStart(6,"0")})`);if(x.set(R,L),C.isDirectory()&&R!==Di){let z=await A(R);for(let[te,ae]of z)x.set(te,ae)}}return x},p;if(a.value==="hardlinks-global"&&o&&u){let E=V.join(o,u.substring(0,2),`${u.substring(2)}.json`);try{p=new Map(Object.entries(JSON.parse(await oe.readFilePromise(E,"utf8"))))}catch{p=await A()}}else p=await A();let h=!1;for(let[E,I]of p){let v=V.join(e,E),x=V.join(t,E);if(I.kind==="directory")await oe.mkdirPromise(x,{recursive:!0});else if(I.kind==="file"){let C=I.mtimeMs;await C1t({srcPath:v,dstPath:x,entry:I,nmMode:a,baseFs:r,globalHardlinksStore:o}),I.mtimeMs!==C&&(h=!0)}else I.kind==="symlink"&&await Aj(V.resolve(V.dirname(x),I.symlinkTo),x,n)}if(a.value==="hardlinks-global"&&o&&h&&u){let E=V.join(o,u.substring(0,2),`${u.substring(2)}.json`);await oe.removePromise(E),await E1e(o,E,Buffer.from(JSON.stringify(Object.fromEntries(p))))}};function I1t(t,e,r,o){let a=new Map,n=new Map,u=new Map,A=!1,p=(h,E,I,v,x)=>{let C=!0,R=V.join(h,E),L=new Set;if(E===Di||E.startsWith("@")){let z;try{z=oe.statSync(R)}catch{}C=!!z,z?z.mtimeMs>r?(A=!0,L=new Set(oe.readdirSync(R))):L=new Set(I.children.get(E).children.keys()):A=!0;let te=e.get(h);if(te){let ae=V.join(h,Di,fQ),le;try{le=oe.statSync(ae)}catch{}if(!le)A=!0;else if(le.mtimeMs>r){A=!0;let ce=new Set(oe.readdirSync(ae)),Ce=new Map;n.set(h,Ce);for(let[de,Be]of te)ce.has(de)&&Ce.set(de,Be)}else n.set(h,te)}}else C=x.has(E);let U=I.children.get(E);if(C){let{linkType:z,locator:te}=U,ae={children:new Map,linkType:z,locator:te};if(v.children.set(E,ae),te){let le=He.getSetWithDefault(u,te);le.add(R),u.set(te,le)}for(let le of U.children.keys())p(R,le,U,ae,L)}else U.locator&&o.storedBuildState.delete(G.parseLocator(U.locator).locatorHash)};for(let[h,E]of t){let{linkType:I,locator:v}=E,x={children:new Map,linkType:I,locator:v};if(a.set(h,x),v){let C=He.getSetWithDefault(u,E.locator);C.add(h),u.set(E.locator,C)}E.children.has(Di)&&p(h,Di,E,x,new Set)}return{locationTree:a,binSymlinks:n,locatorLocations:u,installChangedByUser:A}}function C1e(t){let e=G.parseDescriptor(t);return G.isVirtualDescriptor(e)&&(e=G.devirtualizeDescriptor(e)),e.range.startsWith("link:")}async function B1t(t,e,r,{loadManifest:o}){let a=new Map;for(let[A,{locations:p}]of t){let h=C1e(A)?null:await o(A,p[0]),E=new Map;if(h)for(let[I,v]of h.bin){let x=V.join(p[0],v);v!==""&&oe.existsSync(x)&&E.set(I,v)}a.set(A,E)}let n=new Map,u=(A,p,h)=>{let E=new Map,I=V.contains(r,A);if(h.locator&&I!==null){let v=a.get(h.locator);for(let[x,C]of v){let R=V.join(A,ue.toPortablePath(C));E.set(x,R)}for(let[x,C]of h.children){let R=V.join(A,x),L=u(R,R,C);L.size>0&&n.set(A,new Map([...n.get(A)||new Map,...L]))}}else for(let[v,x]of h.children){let C=u(V.join(A,v),p,x);for(let[R,L]of C)E.set(R,L)}return E};for(let[A,p]of e){let h=u(A,A,p);h.size>0&&n.set(A,new Map([...n.get(A)||new Map,...h]))}return n}var p1e=(t,e)=>{if(!t||!e)return t===e;let r=G.parseLocator(t);G.isVirtualLocator(r)&&(r=G.devirtualizeLocator(r));let o=G.parseLocator(e);return G.isVirtualLocator(o)&&(o=G.devirtualizeLocator(o)),G.areLocatorsEqual(r,o)};function fj(t){return V.join(t.get("globalFolder"),"store")}async function v1t(t,e,{baseFs:r,project:o,report:a,loadManifest:n,realLocatorChecksums:u}){let A=V.join(o.cwd,Di),{locationTree:p,binSymlinks:h,locatorLocations:E,installChangedByUser:I}=I1t(t.locationTree,t.binSymlinks,t.mtimeMs,o),v=y1e(e,{skipPrefix:o.cwd}),x=[],C=async({srcDir:Be,dstDir:Ee,linkType:g,globalHardlinksStore:me,nmMode:we,windowsLinkType:Ae,packageChecksum:ne})=>{let Z=(async()=>{try{g==="SOFT"?(await oe.mkdirPromise(V.dirname(Ee),{recursive:!0}),await Aj(V.resolve(Be),Ee,Ae)):await w1t(Ee,Be,{baseFs:r,globalHardlinksStore:me,nmMode:we,windowsLinkType:Ae,packageChecksum:ne})}catch(xe){throw xe.message=`While persisting ${Be} -> ${Ee} ${xe.message}`,xe}finally{ae.tick()}})().then(()=>x.splice(x.indexOf(Z),1));x.push(Z),x.length>f1e&&await Promise.race(x)},R=async(Be,Ee,g)=>{let me=(async()=>{let we=async(Ae,ne,Z)=>{try{Z.innerLoop||await oe.mkdirPromise(ne,{recursive:!0});let xe=await oe.readdirPromise(Ae,{withFileTypes:!0});for(let Ne of xe){if(!Z.innerLoop&&Ne.name===fQ)continue;let ht=V.join(Ae,Ne.name),H=V.join(ne,Ne.name);Ne.isDirectory()?(Ne.name!==Di||Z&&Z.innerLoop)&&(await oe.mkdirPromise(H,{recursive:!0}),await we(ht,H,{...Z,innerLoop:!0})):Ce.value==="hardlinks-local"||Ce.value==="hardlinks-global"?await oe.linkPromise(ht,H):await oe.copyFilePromise(ht,H,g1e.default.constants.COPYFILE_FICLONE)}}catch(xe){throw Z.innerLoop||(xe.message=`While cloning ${Ae} -> ${ne} ${xe.message}`),xe}finally{Z.innerLoop||ae.tick()}};await we(Be,Ee,g)})().then(()=>x.splice(x.indexOf(me),1));x.push(me),x.length>f1e&&await Promise.race(x)},L=async(Be,Ee,g)=>{if(g)for(let[me,we]of Ee.children){let Ae=g.children.get(me);await L(V.join(Be,me),we,Ae)}else{Ee.children.has(Di)&&await AC(V.join(Be,Di),{contentsOnly:!1});let me=V.basename(Be)===Di&&p.has(V.join(V.dirname(Be)));await AC(Be,{contentsOnly:Be===A,isWorkspaceDir:me})}};for(let[Be,Ee]of p){let g=v.get(Be);for(let[me,we]of Ee.children){if(me===".")continue;let Ae=g&&g.children.get(me),ne=V.join(Be,me);await L(ne,we,Ae)}}let U=async(Be,Ee,g)=>{if(g){p1e(Ee.locator,g.locator)||await AC(Be,{contentsOnly:Ee.linkType==="HARD"});for(let[me,we]of Ee.children){let Ae=g.children.get(me);await U(V.join(Be,me),we,Ae)}}else{Ee.children.has(Di)&&await AC(V.join(Be,Di),{contentsOnly:!0});let me=V.basename(Be)===Di&&v.has(V.join(V.dirname(Be)));await AC(Be,{contentsOnly:Ee.linkType==="HARD",isWorkspaceDir:me})}};for(let[Be,Ee]of v){let g=p.get(Be);for(let[me,we]of Ee.children){if(me===".")continue;let Ae=g&&g.children.get(me);await U(V.join(Be,me),we,Ae)}}let z=new Map,te=[];for(let[Be,Ee]of E)for(let g of Ee){let{locationRoot:me,segments:we}=pQ(g,{skipPrefix:o.cwd}),Ae=v.get(me),ne=me;if(Ae){for(let Z of we)if(ne=V.join(ne,Z),Ae=Ae.children.get(Z),!Ae)break;if(Ae){let Z=p1e(Ae.locator,Be),xe=e.get(Ae.locator),Ne=xe.target,ht=ne,H=xe.linkType;if(Z)z.has(Ne)||z.set(Ne,ht);else if(Ne!==ht){let rt=G.parseLocator(Ae.locator);G.isVirtualLocator(rt)&&(rt=G.devirtualizeLocator(rt)),te.push({srcDir:Ne,dstDir:ht,linkType:H,realLocatorHash:rt.locatorHash})}}}}for(let[Be,{locations:Ee}]of e.entries())for(let g of Ee){let{locationRoot:me,segments:we}=pQ(g,{skipPrefix:o.cwd}),Ae=p.get(me),ne=v.get(me),Z=me,xe=e.get(Be),Ne=G.parseLocator(Be);G.isVirtualLocator(Ne)&&(Ne=G.devirtualizeLocator(Ne));let ht=Ne.locatorHash,H=xe.target,rt=g;if(H===rt)continue;let Te=xe.linkType;for(let Fe of we)ne=ne.children.get(Fe);if(!Ae)te.push({srcDir:H,dstDir:rt,linkType:Te,realLocatorHash:ht});else for(let Fe of we)if(Z=V.join(Z,Fe),Ae=Ae.children.get(Fe),!Ae){te.push({srcDir:H,dstDir:rt,linkType:Te,realLocatorHash:ht});break}}let ae=Zs.progressViaCounter(te.length),le=a.reportProgress(ae),ce=o.configuration.get("nmMode"),Ce={value:ce},de=o.configuration.get("winLinkType");try{let Be=Ce.value==="hardlinks-global"?`${fj(o.configuration)}/v1`:null;if(Be&&!await oe.existsPromise(Be)){await oe.mkdirpPromise(Be);for(let g=0;g<256;g++)await oe.mkdirPromise(V.join(Be,g.toString(16).padStart(2,"0")))}for(let g of te)(g.linkType==="SOFT"||!z.has(g.srcDir))&&(z.set(g.srcDir,g.dstDir),await C({...g,globalHardlinksStore:Be,nmMode:Ce,windowsLinkType:de,packageChecksum:u.get(g.realLocatorHash)||null}));await Promise.all(x),x.length=0;for(let g of te){let me=z.get(g.srcDir);g.linkType!=="SOFT"&&g.dstDir!==me&&await R(me,g.dstDir,{nmMode:Ce})}await Promise.all(x),await oe.mkdirPromise(A,{recursive:!0});let Ee=await B1t(e,v,o.cwd,{loadManifest:n});await D1t(h,Ee,o.cwd,de),await E1t(o,e,Ee,Ce,{installChangedByUser:I}),ce=="hardlinks-global"&&Ce.value=="hardlinks-local"&&a.reportWarningOnce(74,"'nmMode' has been downgraded to 'hardlinks-local' due to global cache and install folder being on different devices")}finally{le.stop()}}async function D1t(t,e,r,o){for(let a of t.keys()){if(V.contains(r,a)===null)throw new Error(`Assertion failed. Excepted bin symlink location to be inside project dir, instead it was at ${a}`);if(!e.has(a)){let n=V.join(a,Di,fQ);await oe.removePromise(n)}}for(let[a,n]of e){if(V.contains(r,a)===null)throw new Error(`Assertion failed. Excepted bin symlink location to be inside project dir, instead it was at ${a}`);let u=V.join(a,Di,fQ),A=t.get(a)||new Map;await oe.mkdirPromise(u,{recursive:!0});for(let p of A.keys())n.has(p)||(await oe.removePromise(V.join(u,p)),process.platform==="win32"&&await oe.removePromise(V.join(u,`${p}.cmd`)));for(let[p,h]of n){let E=A.get(p),I=V.join(u,p);E!==h&&(process.platform==="win32"?await(0,h1e.default)(ue.fromPortablePath(h),ue.fromPortablePath(I),{createPwshFile:!1}):(await oe.removePromise(I),await Aj(h,I,o),V.contains(r,await oe.realpathPromise(h))!==null&&await oe.chmodPromise(h,493)))}}}Ge();Pt();nA();var YB=class extends Hh{constructor(){super(...arguments);this.mode="loose"}makeInstaller(r){return new pj(r)}},pj=class extends sd{constructor(){super(...arguments);this.mode="loose"}async transformPnpSettings(r){let o=new zs({baseFs:new rA({maxOpenFiles:80,readOnlyArchives:!0})}),a=e1e(r,this.opts.project.cwd,o),{tree:n,errors:u}=FB(a,{pnpifyFs:!1,project:this.opts.project});if(!n){for(let{messageName:I,text:v}of u)this.opts.report.reportError(I,v);return}let A=new Map;r.fallbackPool=A;let p=(I,v)=>{let x=G.parseLocator(v.locator),C=G.stringifyIdent(x);C===I?A.set(I,x.reference):A.set(I,[C,x.reference])},h=V.join(this.opts.project.cwd,dr.nodeModules),E=n.get(h);if(!(typeof E>"u")){if("target"in E)throw new Error("Assertion failed: Expected the root junction point to be a directory");for(let I of E.dirList){let v=V.join(h,I),x=n.get(v);if(typeof x>"u")throw new Error("Assertion failed: Expected the child to have been registered");if("target"in x)p(I,x);else for(let C of x.dirList){let R=V.join(v,C),L=n.get(R);if(typeof L>"u")throw new Error("Assertion failed: Expected the subchild to have been registered");if("target"in L)p(`${I}/${C}`,L);else throw new Error("Assertion failed: Expected the leaf junction to be a package")}}}}};var P1t={hooks:{cleanGlobalArtifacts:async t=>{let e=fj(t);await oe.removePromise(e)}},configuration:{nmHoistingLimits:{description:"Prevents packages to be hoisted past specific levels",type:"STRING",values:["workspaces","dependencies","none"],default:"none"},nmMode:{description:"Defines in which measure Yarn must use hardlinks and symlinks when generated `node_modules` directories.",type:"STRING",values:["classic","hardlinks-local","hardlinks-global"],default:"classic"},nmSelfReferences:{description:"Defines whether the linker should generate self-referencing symlinks for workspaces.",type:"BOOLEAN",default:!0}},linkers:[GB,YB]},b1t=P1t;var f5={};Vt(f5,{NpmHttpFetcher:()=>VB,NpmRemapResolver:()=>zB,NpmSemverFetcher:()=>tp,NpmSemverResolver:()=>JB,NpmTagResolver:()=>XB,default:()=>qvt,npmConfigUtils:()=>Zn,npmHttpUtils:()=>Zr,npmPublishUtils:()=>PC});Ge();var S1e=Ze(Jn());var Wn="npm:";var Zr={};Vt(Zr,{AuthType:()=>D1e,customPackageError:()=>od,del:()=>U1t,get:()=>ad,getIdentUrl:()=>hQ,getPackageMetadata:()=>hC,handleInvalidAuthenticationError:()=>jh,post:()=>M1t,put:()=>O1t});Ge();Ge();Pt();var mj=Ze(J1()),B1e=Ze(y_()),v1e=Ze(Jn());var Zn={};Vt(Zn,{RegistryType:()=>w1e,getAuditRegistry:()=>S1t,getAuthConfiguration:()=>dj,getDefaultRegistry:()=>WB,getPublishRegistry:()=>x1t,getRegistryConfiguration:()=>I1e,getScopeConfiguration:()=>gj,getScopeRegistry:()=>fC,normalizeRegistry:()=>ac});var w1e=(o=>(o.AUDIT_REGISTRY="npmAuditRegistry",o.FETCH_REGISTRY="npmRegistryServer",o.PUBLISH_REGISTRY="npmPublishRegistry",o))(w1e||{});function ac(t){return t.replace(/\/$/,"")}function S1t({configuration:t}){return WB({configuration:t,type:"npmAuditRegistry"})}function x1t(t,{configuration:e}){return t.publishConfig?.registry?ac(t.publishConfig.registry):t.name?fC(t.name.scope,{configuration:e,type:"npmPublishRegistry"}):WB({configuration:e,type:"npmPublishRegistry"})}function fC(t,{configuration:e,type:r="npmRegistryServer"}){let o=gj(t,{configuration:e});if(o===null)return WB({configuration:e,type:r});let a=o.get(r);return a===null?WB({configuration:e,type:r}):ac(a)}function WB({configuration:t,type:e="npmRegistryServer"}){let r=t.get(e);return ac(r!==null?r:t.get("npmRegistryServer"))}function I1e(t,{configuration:e}){let r=e.get("npmRegistries"),o=ac(t),a=r.get(o);if(typeof a<"u")return a;let n=r.get(o.replace(/^[a-z]+:/,""));return typeof n<"u"?n:null}function gj(t,{configuration:e}){if(t===null)return null;let o=e.get("npmScopes").get(t);return o||null}function dj(t,{configuration:e,ident:r}){let o=r&&gj(r.scope,{configuration:e});return o?.get("npmAuthIdent")||o?.get("npmAuthToken")?o:I1e(t,{configuration:e})||e}var D1e=(a=>(a[a.NO_AUTH=0]="NO_AUTH",a[a.BEST_EFFORT=1]="BEST_EFFORT",a[a.CONFIGURATION=2]="CONFIGURATION",a[a.ALWAYS_AUTH=3]="ALWAYS_AUTH",a))(D1e||{});async function jh(t,{attemptedAs:e,registry:r,headers:o,configuration:a}){if(dQ(t))throw new Jt(41,"Invalid OTP token");if(t.originalError?.name==="HTTPError"&&t.originalError?.response.statusCode===401)throw new Jt(41,`Invalid authentication (${typeof e!="string"?`as ${await H1t(r,o,{configuration:a})}`:`attempted as ${e}`})`)}function od(t,e){let r=t.response?.statusCode;return r?r===404?"Package not found":r>=500&&r<600?`The registry appears to be down (using a ${pe.applyHyperlink(e,"local cache","https://yarnpkg.com/advanced/lexicon#local-cache")} might have protected you against such outages)`:null:null}function hQ(t){return t.scope?`/@${t.scope}%2f${t.name}`:`/${t.name}`}var P1e=new Map,k1t=new Map;async function Q1t(t){return await He.getFactoryWithDefault(P1e,t,async()=>{let e=null;try{e=await oe.readJsonPromise(t)}catch{}return e})}async function F1t(t,e,{configuration:r,cached:o,registry:a,headers:n,version:u,...A}){return await He.getFactoryWithDefault(k1t,t,async()=>await ad(hQ(e),{...A,customErrorMessage:od,configuration:r,registry:a,ident:e,headers:{...n,"If-None-Match":o?.etag,"If-Modified-Since":o?.lastModified},wrapNetworkRequest:async p=>async()=>{let h=await p();if(h.statusCode===304){if(o===null)throw new Error("Assertion failed: cachedMetadata should not be null");return{...h,body:o.metadata}}let E=R1t(JSON.parse(h.body.toString())),I={metadata:E,etag:h.headers.etag,lastModified:h.headers["last-modified"]};return P1e.set(t,Promise.resolve(I)),Promise.resolve().then(async()=>{let v=`${t}-${process.pid}.tmp`;await oe.mkdirPromise(V.dirname(v),{recursive:!0}),await oe.writeJsonPromise(v,I,{compact:!0}),await oe.renamePromise(v,t)}).catch(()=>{}),{...h,body:E}}}))}async function hC(t,{cache:e,project:r,registry:o,headers:a,version:n,...u}){let{configuration:A}=r;o=KB(A,{ident:t,registry:o});let p=N1t(A,o),h=V.join(p,`${G.slugifyIdent(t)}.json`),E=null;if(!r.lockfileNeedsRefresh&&(E=await Q1t(h),E)){if(typeof n<"u"&&typeof E.metadata.versions[n]<"u")return E.metadata;if(A.get("enableOfflineMode")){let I=structuredClone(E.metadata),v=new Set;if(e){for(let C of Object.keys(I.versions)){let R=G.makeLocator(t,`npm:${C}`),L=e.getLocatorMirrorPath(R);(!L||!oe.existsSync(L))&&(delete I.versions[C],v.add(C))}let x=I["dist-tags"].latest;if(v.has(x)){let C=Object.keys(E.metadata.versions).sort(v1e.default.compare),R=C.indexOf(x);for(;v.has(C[R])&&R>=0;)R-=1;R>=0?I["dist-tags"].latest=C[R]:delete I["dist-tags"].latest}}return I}}return await F1t(h,t,{...u,configuration:A,cached:E,registry:o,headers:a,version:n})}var b1e=["name","dist.tarball","bin","scripts","os","cpu","libc","dependencies","dependenciesMeta","optionalDependencies","peerDependencies","peerDependenciesMeta","deprecated"];function R1t(t){return{"dist-tags":t["dist-tags"],versions:Object.fromEntries(Object.entries(t.versions).map(([e,r])=>[e,(0,B1e.default)(r,b1e)]))}}var T1t=wn.makeHash(...b1e).slice(0,6);function N1t(t,e){let r=L1t(t),o=new URL(e);return V.join(r,T1t,o.hostname)}function L1t(t){return V.join(t.get("globalFolder"),"metadata/npm")}async function ad(t,{configuration:e,headers:r,ident:o,authType:a,registry:n,...u}){n=KB(e,{ident:o,registry:n}),o&&o.scope&&typeof a>"u"&&(a=1);let A=await gQ(n,{authType:a,configuration:e,ident:o});A&&(r={...r,authorization:A});try{return await sn.get(t.charAt(0)==="/"?`${n}${t}`:t,{configuration:e,headers:r,...u})}catch(p){throw await jh(p,{registry:n,configuration:e,headers:r}),p}}async function M1t(t,e,{attemptedAs:r,configuration:o,headers:a,ident:n,authType:u=3,registry:A,otp:p,...h}){A=KB(o,{ident:n,registry:A});let E=await gQ(A,{authType:u,configuration:o,ident:n});E&&(a={...a,authorization:E}),p&&(a={...a,...pC(p)});try{return await sn.post(A+t,e,{configuration:o,headers:a,...h})}catch(I){if(!dQ(I)||p)throw await jh(I,{attemptedAs:r,registry:A,configuration:o,headers:a}),I;p=await yj(I,{configuration:o});let v={...a,...pC(p)};try{return await sn.post(`${A}${t}`,e,{configuration:o,headers:v,...h})}catch(x){throw await jh(x,{attemptedAs:r,registry:A,configuration:o,headers:a}),x}}}async function O1t(t,e,{attemptedAs:r,configuration:o,headers:a,ident:n,authType:u=3,registry:A,otp:p,...h}){A=KB(o,{ident:n,registry:A});let E=await gQ(A,{authType:u,configuration:o,ident:n});E&&(a={...a,authorization:E}),p&&(a={...a,...pC(p)});try{return await sn.put(A+t,e,{configuration:o,headers:a,...h})}catch(I){if(!dQ(I))throw await jh(I,{attemptedAs:r,registry:A,configuration:o,headers:a}),I;p=await yj(I,{configuration:o});let v={...a,...pC(p)};try{return await sn.put(`${A}${t}`,e,{configuration:o,headers:v,...h})}catch(x){throw await jh(x,{attemptedAs:r,registry:A,configuration:o,headers:a}),x}}}async function U1t(t,{attemptedAs:e,configuration:r,headers:o,ident:a,authType:n=3,registry:u,otp:A,...p}){u=KB(r,{ident:a,registry:u});let h=await gQ(u,{authType:n,configuration:r,ident:a});h&&(o={...o,authorization:h}),A&&(o={...o,...pC(A)});try{return await sn.del(u+t,{configuration:r,headers:o,...p})}catch(E){if(!dQ(E)||A)throw await jh(E,{attemptedAs:e,registry:u,configuration:r,headers:o}),E;A=await yj(E,{configuration:r});let I={...o,...pC(A)};try{return await sn.del(`${u}${t}`,{configuration:r,headers:I,...p})}catch(v){throw await jh(v,{attemptedAs:e,registry:u,configuration:r,headers:o}),v}}}function KB(t,{ident:e,registry:r}){if(typeof r>"u"&&e)return fC(e.scope,{configuration:t});if(typeof r!="string")throw new Error("Assertion failed: The registry should be a string");return ac(r)}async function gQ(t,{authType:e=2,configuration:r,ident:o}){let a=dj(t,{configuration:r,ident:o}),n=_1t(a,e);if(!n)return null;let u=await r.reduceHook(A=>A.getNpmAuthenticationHeader,void 0,t,{configuration:r,ident:o});if(u)return u;if(a.get("npmAuthToken"))return`Bearer ${a.get("npmAuthToken")}`;if(a.get("npmAuthIdent")){let A=a.get("npmAuthIdent");return A.includes(":")?`Basic ${Buffer.from(A).toString("base64")}`:`Basic ${A}`}if(n&&e!==1)throw new Jt(33,"No authentication configured for request");return null}function _1t(t,e){switch(e){case 2:return t.get("npmAlwaysAuth");case 1:case 3:return!0;case 0:return!1;default:throw new Error("Unreachable")}}async function H1t(t,e,{configuration:r}){if(typeof e>"u"||typeof e.authorization>"u")return"an anonymous user";try{return(await sn.get(new URL(`${t}/-/whoami`).href,{configuration:r,headers:e,jsonResponse:!0})).username??"an unknown user"}catch{return"an unknown user"}}async function yj(t,{configuration:e}){let r=t.originalError?.response.headers["npm-notice"];if(r&&(await Rt.start({configuration:e,stdout:process.stdout,includeFooter:!1},async a=>{if(a.reportInfo(0,r.replace(/(https?:\/\/\S+)/g,pe.pretty(e,"$1",pe.Type.URL))),!process.env.YARN_IS_TEST_ENV){let n=r.match(/open (https?:\/\/\S+)/i);if(n&&Xi.openUrl){let{openNow:u}=await(0,mj.prompt)({type:"confirm",name:"openNow",message:"Do you want to try to open this url now?",required:!0,initial:!0,onCancel:()=>process.exit(130)});u&&(await Xi.openUrl(n[1])||(a.reportSeparator(),a.reportWarning(0,"We failed to automatically open the url; you'll have to open it yourself in your browser of choice.")))}}}),process.stdout.write(` +`)),process.env.YARN_IS_TEST_ENV)return process.env.YARN_INJECT_NPM_2FA_TOKEN||"";let{otp:o}=await(0,mj.prompt)({type:"password",name:"otp",message:"One-time password:",required:!0,onCancel:()=>process.exit(130)});return process.stdout.write(` +`),o}function dQ(t){if(t.originalError?.name!=="HTTPError")return!1;try{return(t.originalError?.response.headers["www-authenticate"].split(/,\s*/).map(r=>r.toLowerCase())).includes("otp")}catch{return!1}}function pC(t){return{"npm-otp":t}}var VB=class{supports(e,r){if(!e.reference.startsWith(Wn))return!1;let{selector:o,params:a}=G.parseRange(e.reference);return!(!S1e.default.valid(o)||a===null||typeof a.__archiveUrl!="string")}getLocalPath(e,r){return null}async fetch(e,r){let o=r.checksums.get(e.locatorHash)||null,[a,n,u]=await r.cache.fetchPackageFromCache(e,o,{onHit:()=>r.report.reportCacheHit(e),onMiss:()=>r.report.reportCacheMiss(e,`${G.prettyLocator(r.project.configuration,e)} can't be found in the cache and will be fetched from the remote server`),loader:()=>this.fetchFromNetwork(e,r),...r.cacheOptions});return{packageFs:a,releaseFs:n,prefixPath:G.getIdentVendorPath(e),checksum:u}}async fetchFromNetwork(e,r){let{params:o}=G.parseRange(e.reference);if(o===null||typeof o.__archiveUrl!="string")throw new Error("Assertion failed: The archiveUrl querystring parameter should have been available");let a=await ad(o.__archiveUrl,{customErrorMessage:od,configuration:r.project.configuration,ident:e});return await $i.convertToZip(a,{configuration:r.project.configuration,prefixPath:G.getIdentVendorPath(e),stripComponents:1})}};Ge();var zB=class{supportsDescriptor(e,r){return!(!e.range.startsWith(Wn)||!G.tryParseDescriptor(e.range.slice(Wn.length),!0))}supportsLocator(e,r){return!1}shouldPersistResolution(e,r){throw new Error("Unreachable")}bindDescriptor(e,r,o){return e}getResolutionDependencies(e,r){let o=r.project.configuration.normalizeDependency(G.parseDescriptor(e.range.slice(Wn.length),!0));return r.resolver.getResolutionDependencies(o,r)}async getCandidates(e,r,o){let a=o.project.configuration.normalizeDependency(G.parseDescriptor(e.range.slice(Wn.length),!0));return await o.resolver.getCandidates(a,r,o)}async getSatisfying(e,r,o,a){let n=a.project.configuration.normalizeDependency(G.parseDescriptor(e.range.slice(Wn.length),!0));return a.resolver.getSatisfying(n,r,o,a)}resolve(e,r){throw new Error("Unreachable")}};Ge();Ge();var x1e=Ze(Jn());var tp=class t{supports(e,r){if(!e.reference.startsWith(Wn))return!1;let o=new URL(e.reference);return!(!x1e.default.valid(o.pathname)||o.searchParams.has("__archiveUrl"))}getLocalPath(e,r){return null}async fetch(e,r){let o=r.checksums.get(e.locatorHash)||null,[a,n,u]=await r.cache.fetchPackageFromCache(e,o,{onHit:()=>r.report.reportCacheHit(e),onMiss:()=>r.report.reportCacheMiss(e,`${G.prettyLocator(r.project.configuration,e)} can't be found in the cache and will be fetched from the remote registry`),loader:()=>this.fetchFromNetwork(e,r),...r.cacheOptions});return{packageFs:a,releaseFs:n,prefixPath:G.getIdentVendorPath(e),checksum:u}}async fetchFromNetwork(e,r){let o;try{o=await ad(t.getLocatorUrl(e),{customErrorMessage:od,configuration:r.project.configuration,ident:e})}catch{o=await ad(t.getLocatorUrl(e).replace(/%2f/g,"/"),{customErrorMessage:od,configuration:r.project.configuration,ident:e})}return await $i.convertToZip(o,{configuration:r.project.configuration,prefixPath:G.getIdentVendorPath(e),stripComponents:1})}static isConventionalTarballUrl(e,r,{configuration:o}){let a=fC(e.scope,{configuration:o}),n=t.getLocatorUrl(e);return r=r.replace(/^https?:(\/\/(?:[^/]+\.)?npmjs.org(?:$|\/))/,"https:$1"),a=a.replace(/^https:\/\/registry\.npmjs\.org($|\/)/,"https://registry.yarnpkg.com$1"),r=r.replace(/^https:\/\/registry\.npmjs\.org($|\/)/,"https://registry.yarnpkg.com$1"),r===a+n||r===a+n.replace(/%2f/g,"/")}static getLocatorUrl(e){let r=Lr.clean(e.reference.slice(Wn.length));if(r===null)throw new Jt(10,"The npm semver resolver got selected, but the version isn't semver");return`${hQ(e)}/-/${e.name}-${r}.tgz`}};Ge();Ge();Ge();var Ej=Ze(Jn());var mQ=G.makeIdent(null,"node-gyp"),q1t=/\b(node-gyp|prebuild-install)\b/,JB=class{supportsDescriptor(e,r){return e.range.startsWith(Wn)?!!Lr.validRange(e.range.slice(Wn.length)):!1}supportsLocator(e,r){if(!e.reference.startsWith(Wn))return!1;let{selector:o}=G.parseRange(e.reference);return!!Ej.default.valid(o)}shouldPersistResolution(e,r){return!0}bindDescriptor(e,r,o){return e}getResolutionDependencies(e,r){return{}}async getCandidates(e,r,o){let a=Lr.validRange(e.range.slice(Wn.length));if(a===null)throw new Error(`Expected a valid range, got ${e.range.slice(Wn.length)}`);let n=await hC(e,{cache:o.fetchOptions?.cache,project:o.project,version:Ej.default.valid(a.raw)?a.raw:void 0}),u=He.mapAndFilter(Object.keys(n.versions),h=>{try{let E=new Lr.SemVer(h);if(a.test(E))return E}catch{}return He.mapAndFilter.skip}),A=u.filter(h=>!n.versions[h.raw].deprecated),p=A.length>0?A:u;return p.sort((h,E)=>-h.compare(E)),p.map(h=>{let E=G.makeLocator(e,`${Wn}${h.raw}`),I=n.versions[h.raw].dist.tarball;return tp.isConventionalTarballUrl(E,I,{configuration:o.project.configuration})?E:G.bindLocator(E,{__archiveUrl:I})})}async getSatisfying(e,r,o,a){let n=Lr.validRange(e.range.slice(Wn.length));if(n===null)throw new Error(`Expected a valid range, got ${e.range.slice(Wn.length)}`);return{locators:He.mapAndFilter(o,p=>{if(p.identHash!==e.identHash)return He.mapAndFilter.skip;let h=G.tryParseRange(p.reference,{requireProtocol:Wn});if(!h)return He.mapAndFilter.skip;let E=new Lr.SemVer(h.selector);return n.test(E)?{locator:p,version:E}:He.mapAndFilter.skip}).sort((p,h)=>-p.version.compare(h.version)).map(({locator:p})=>p),sorted:!0}}async resolve(e,r){let{selector:o}=G.parseRange(e.reference),a=Lr.clean(o);if(a===null)throw new Jt(10,"The npm semver resolver got selected, but the version isn't semver");let n=await hC(e,{cache:r.fetchOptions?.cache,project:r.project,version:a});if(!Object.hasOwn(n,"versions"))throw new Jt(15,'Registry returned invalid data for - missing "versions" field');if(!Object.hasOwn(n.versions,a))throw new Jt(16,`Registry failed to return reference "${a}"`);let u=new Ut;if(u.load(n.versions[a]),!u.dependencies.has(mQ.identHash)&&!u.peerDependencies.has(mQ.identHash)){for(let A of u.scripts.values())if(A.match(q1t)){u.dependencies.set(mQ.identHash,G.makeDescriptor(mQ,"latest"));break}}return{...e,version:a,languageName:"node",linkType:"HARD",conditions:u.getConditions(),dependencies:r.project.configuration.normalizeDependencyMap(u.dependencies),peerDependencies:u.peerDependencies,dependenciesMeta:u.dependenciesMeta,peerDependenciesMeta:u.peerDependenciesMeta,bin:u.bin}}};Ge();Ge();var k1e=Ze(Jn());var XB=class{supportsDescriptor(e,r){return!(!e.range.startsWith(Wn)||!ly.test(e.range.slice(Wn.length)))}supportsLocator(e,r){return!1}shouldPersistResolution(e,r){throw new Error("Unreachable")}bindDescriptor(e,r,o){return e}getResolutionDependencies(e,r){return{}}async getCandidates(e,r,o){let a=e.range.slice(Wn.length),n=await hC(e,{cache:o.fetchOptions?.cache,project:o.project});if(!Object.hasOwn(n,"dist-tags"))throw new Jt(15,'Registry returned invalid data - missing "dist-tags" field');let u=n["dist-tags"];if(!Object.hasOwn(u,a))throw new Jt(16,`Registry failed to return tag "${a}"`);let A=u[a],p=G.makeLocator(e,`${Wn}${A}`),h=n.versions[A].dist.tarball;return tp.isConventionalTarballUrl(p,h,{configuration:o.project.configuration})?[p]:[G.bindLocator(p,{__archiveUrl:h})]}async getSatisfying(e,r,o,a){let n=[];for(let u of o){if(u.identHash!==e.identHash)continue;let A=G.tryParseRange(u.reference,{requireProtocol:Wn});if(!(!A||!k1e.default.valid(A.selector))){if(A.params?.__archiveUrl){let p=G.makeRange({protocol:Wn,selector:A.selector,source:null,params:null}),[h]=await a.resolver.getCandidates(G.makeDescriptor(e,p),r,a);if(u.reference!==h.reference)continue}n.push(u)}}return{locators:n,sorted:!1}}async resolve(e,r){throw new Error("Unreachable")}};var PC={};Vt(PC,{getGitHead:()=>_vt,getPublishAccess:()=>EBe,getReadmeContent:()=>CBe,makePublishBody:()=>Uvt});Ge();Ge();Pt();var a5={};Vt(a5,{PackCommand:()=>DC,default:()=>wvt,packUtils:()=>CA});Ge();Ge();Ge();Pt();qt();var CA={};Vt(CA,{genPackList:()=>_Q,genPackStream:()=>o5,genPackageManifest:()=>aBe,hasPackScripts:()=>i5,prepareForPack:()=>s5});Ge();Pt();var n5=Ze($o()),sBe=Ze(tBe()),oBe=ve("zlib"),uvt=["/package.json","/readme","/readme.*","/license","/license.*","/licence","/licence.*","/changelog","/changelog.*"],Avt=["/package.tgz",".github",".git",".hg","node_modules",".npmignore",".gitignore",".#*",".DS_Store"];async function i5(t){return!!(An.hasWorkspaceScript(t,"prepack")||An.hasWorkspaceScript(t,"postpack"))}async function s5(t,{report:e},r){await An.maybeExecuteWorkspaceLifecycleScript(t,"prepack",{report:e});try{let o=V.join(t.cwd,Ut.fileName);await oe.existsPromise(o)&&await t.manifest.loadFile(o,{baseFs:oe}),await r()}finally{await An.maybeExecuteWorkspaceLifecycleScript(t,"postpack",{report:e})}}async function o5(t,e){typeof e>"u"&&(e=await _Q(t));let r=new Set;for(let n of t.manifest.publishConfig?.executableFiles??new Set)r.add(V.normalize(n));for(let n of t.manifest.bin.values())r.add(V.normalize(n));let o=sBe.default.pack();process.nextTick(async()=>{for(let n of e){let u=V.normalize(n),A=V.resolve(t.cwd,u),p=V.join("package",u),h=await oe.lstatPromise(A),E={name:p,mtime:new Date(Bi.SAFE_TIME*1e3)},I=r.has(u)?493:420,v,x,C=new Promise((L,U)=>{v=L,x=U}),R=L=>{L?x(L):v()};if(h.isFile()){let L;u==="package.json"?L=Buffer.from(JSON.stringify(await aBe(t),null,2)):L=await oe.readFilePromise(A),o.entry({...E,mode:I,type:"file"},L,R)}else h.isSymbolicLink()?o.entry({...E,mode:I,type:"symlink",linkname:await oe.readlinkPromise(A)},R):R(new Error(`Unsupported file type ${h.mode} for ${ue.fromPortablePath(u)}`));await C}o.finalize()});let a=(0,oBe.createGzip)();return o.pipe(a),a}async function aBe(t){let e=JSON.parse(JSON.stringify(t.manifest.raw));return await t.project.configuration.triggerHook(r=>r.beforeWorkspacePacking,t,e),e}async function _Q(t){let e=t.project,r=e.configuration,o={accept:[],reject:[]};for(let I of Avt)o.reject.push(I);for(let I of uvt)o.accept.push(I);o.reject.push(r.get("rcFilename"));let a=I=>{if(I===null||!I.startsWith(`${t.cwd}/`))return;let v=V.relative(t.cwd,I),x=V.resolve(It.root,v);o.reject.push(x)};a(V.resolve(e.cwd,dr.lockfile)),a(r.get("cacheFolder")),a(r.get("globalFolder")),a(r.get("installStatePath")),a(r.get("virtualFolder")),a(r.get("yarnPath")),await r.triggerHook(I=>I.populateYarnPaths,e,I=>{a(I)});for(let I of e.workspaces){let v=V.relative(t.cwd,I.cwd);v!==""&&!v.match(/^(\.\.)?\//)&&o.reject.push(`/${v}`)}let n={accept:[],reject:[]},u=t.manifest.publishConfig?.main??t.manifest.main,A=t.manifest.publishConfig?.module??t.manifest.module,p=t.manifest.publishConfig?.browser??t.manifest.browser,h=t.manifest.publishConfig?.bin??t.manifest.bin;u!=null&&n.accept.push(V.resolve(It.root,u)),A!=null&&n.accept.push(V.resolve(It.root,A)),typeof p=="string"&&n.accept.push(V.resolve(It.root,p));for(let I of h.values())n.accept.push(V.resolve(It.root,I));if(p instanceof Map)for(let[I,v]of p.entries())n.accept.push(V.resolve(It.root,I)),typeof v=="string"&&n.accept.push(V.resolve(It.root,v));let E=t.manifest.files!==null;if(E){n.reject.push("/*");for(let I of t.manifest.files)lBe(n.accept,I,{cwd:It.root})}return await fvt(t.cwd,{hasExplicitFileList:E,globalList:o,ignoreList:n})}async function fvt(t,{hasExplicitFileList:e,globalList:r,ignoreList:o}){let a=[],n=new qu(t),u=[[It.root,[o]]];for(;u.length>0;){let[A,p]=u.pop(),h=await n.lstatPromise(A);if(!nBe(A,{globalList:r,ignoreLists:h.isDirectory()?null:p}))if(h.isDirectory()){let E=await n.readdirPromise(A),I=!1,v=!1;if(!e||A!==It.root)for(let R of E)I=I||R===".gitignore",v=v||R===".npmignore";let x=v?await rBe(n,A,".npmignore"):I?await rBe(n,A,".gitignore"):null,C=x!==null?[x].concat(p):p;nBe(A,{globalList:r,ignoreLists:p})&&(C=[...p,{accept:[],reject:["**/*"]}]);for(let R of E)u.push([V.resolve(A,R),C])}else(h.isFile()||h.isSymbolicLink())&&a.push(V.relative(It.root,A))}return a.sort()}async function rBe(t,e,r){let o={accept:[],reject:[]},a=await t.readFilePromise(V.join(e,r),"utf8");for(let n of a.split(/\n/g))lBe(o.reject,n,{cwd:e});return o}function pvt(t,{cwd:e}){let r=t[0]==="!";return r&&(t=t.slice(1)),t.match(/\.{0,1}\//)&&(t=V.resolve(e,t)),r&&(t=`!${t}`),t}function lBe(t,e,{cwd:r}){let o=e.trim();o===""||o[0]==="#"||t.push(pvt(o,{cwd:r}))}function nBe(t,{globalList:e,ignoreLists:r}){let o=UQ(t,e.accept);if(o!==0)return o===2;let a=UQ(t,e.reject);if(a!==0)return a===1;if(r!==null)for(let n of r){let u=UQ(t,n.accept);if(u!==0)return u===2;let A=UQ(t,n.reject);if(A!==0)return A===1}return!1}function UQ(t,e){let r=e,o=[];for(let a=0;a{await s5(a,{report:p},async()=>{p.reportJson({base:ue.fromPortablePath(a.cwd)});let h=await _Q(a);for(let E of h)p.reportInfo(null,ue.fromPortablePath(E)),p.reportJson({location:ue.fromPortablePath(E)});if(!this.dryRun){let E=await o5(a,h),I=oe.createWriteStream(u);E.pipe(I),await new Promise(v=>{I.on("finish",v)})}}),this.dryRun||(p.reportInfo(0,`Package archive generated in ${pe.pretty(r,u,pe.Type.PATH)}`),p.reportJson({output:ue.fromPortablePath(u)}))})).exitCode()}};function hvt(t,{workspace:e}){let r=t.replace("%s",gvt(e)).replace("%v",dvt(e));return ue.toPortablePath(r)}function gvt(t){return t.manifest.name!==null?G.slugifyIdent(t.manifest.name):"package"}function dvt(t){return t.manifest.version!==null?t.manifest.version:"unknown"}var mvt=["dependencies","devDependencies","peerDependencies"],yvt="workspace:",Evt=(t,e)=>{e.publishConfig&&(e.publishConfig.type&&(e.type=e.publishConfig.type),e.publishConfig.main&&(e.main=e.publishConfig.main),e.publishConfig.browser&&(e.browser=e.publishConfig.browser),e.publishConfig.module&&(e.module=e.publishConfig.module),e.publishConfig.exports&&(e.exports=e.publishConfig.exports),e.publishConfig.imports&&(e.imports=e.publishConfig.imports),e.publishConfig.bin&&(e.bin=e.publishConfig.bin));let r=t.project;for(let o of mvt)for(let a of t.manifest.getForScope(o).values()){let n=r.tryWorkspaceByDescriptor(a),u=G.parseRange(a.range);if(u.protocol===yvt)if(n===null){if(r.tryWorkspaceByIdent(a)===null)throw new Jt(21,`${G.prettyDescriptor(r.configuration,a)}: No local workspace found for this range`)}else{let A;G.areDescriptorsEqual(a,n.anchoredDescriptor)||u.selector==="*"?A=n.manifest.version??"0.0.0":u.selector==="~"||u.selector==="^"?A=`${u.selector}${n.manifest.version??"0.0.0"}`:A=u.selector;let p=o==="dependencies"?G.makeDescriptor(a,"unknown"):null,h=p!==null&&t.manifest.ensureDependencyMeta(p).optional?"optionalDependencies":o;e[h][G.stringifyIdent(a)]=A}}},Cvt={hooks:{beforeWorkspacePacking:Evt},commands:[DC]},wvt=Cvt;var mBe=ve("crypto"),yBe=Ze(dBe());async function Uvt(t,e,{access:r,tag:o,registry:a,gitHead:n}){let u=t.manifest.name,A=t.manifest.version,p=G.stringifyIdent(u),h=(0,mBe.createHash)("sha1").update(e).digest("hex"),E=yBe.default.fromData(e).toString(),I=r??EBe(t,u),v=await CBe(t),x=await CA.genPackageManifest(t),C=`${p}-${A}.tgz`,R=new URL(`${ac(a)}/${p}/-/${C}`);return{_id:p,_attachments:{[C]:{content_type:"application/octet-stream",data:e.toString("base64"),length:e.length}},name:p,access:I,"dist-tags":{[o]:A},versions:{[A]:{...x,_id:`${p}@${A}`,name:p,version:A,gitHead:n,dist:{shasum:h,integrity:E,tarball:R.toString()}}},readme:v}}async function _vt(t){try{let{stdout:e}=await Ur.execvp("git",["rev-parse","--revs-only","HEAD"],{cwd:t});return e.trim()===""?void 0:e.trim()}catch{return}}function EBe(t,e){let r=t.project.configuration;return t.manifest.publishConfig&&typeof t.manifest.publishConfig.access=="string"?t.manifest.publishConfig.access:r.get("npmPublishAccess")!==null?r.get("npmPublishAccess"):e.scope?"restricted":"public"}async function CBe(t){let e=ue.toPortablePath(`${t.cwd}/README.md`),r=t.manifest.name,a=`# ${G.stringifyIdent(r)} +`;try{a=await oe.readFilePromise(e,"utf8")}catch(n){if(n.code==="ENOENT")return a;throw n}return a}var A5={npmAlwaysAuth:{description:"URL of the selected npm registry (note: npm enterprise isn't supported)",type:"BOOLEAN",default:!1},npmAuthIdent:{description:"Authentication identity for the npm registry (_auth in npm and yarn v1)",type:"SECRET",default:null},npmAuthToken:{description:"Authentication token for the npm registry (_authToken in npm and yarn v1)",type:"SECRET",default:null}},wBe={npmAuditRegistry:{description:"Registry to query for audit reports",type:"STRING",default:null},npmPublishRegistry:{description:"Registry to push packages to",type:"STRING",default:null},npmRegistryServer:{description:"URL of the selected npm registry (note: npm enterprise isn't supported)",type:"STRING",default:"https://registry.yarnpkg.com"}},Hvt={configuration:{...A5,...wBe,npmScopes:{description:"Settings per package scope",type:"MAP",valueDefinition:{description:"",type:"SHAPE",properties:{...A5,...wBe}}},npmRegistries:{description:"Settings per registry",type:"MAP",normalizeKeys:ac,valueDefinition:{description:"",type:"SHAPE",properties:{...A5}}}},fetchers:[VB,tp],resolvers:[zB,JB,XB]},qvt=Hvt;var w5={};Vt(w5,{NpmAuditCommand:()=>SC,NpmInfoCommand:()=>xC,NpmLoginCommand:()=>kC,NpmLogoutCommand:()=>FC,NpmPublishCommand:()=>RC,NpmTagAddCommand:()=>NC,NpmTagListCommand:()=>TC,NpmTagRemoveCommand:()=>LC,NpmWhoamiCommand:()=>MC,default:()=>zvt,npmAuditTypes:()=>dv,npmAuditUtils:()=>HQ});Ge();Ge();qt();var m5=Ze($o());el();var dv={};Vt(dv,{Environment:()=>hv,Severity:()=>gv});var hv=(o=>(o.All="all",o.Production="production",o.Development="development",o))(hv||{}),gv=(n=>(n.Info="info",n.Low="low",n.Moderate="moderate",n.High="high",n.Critical="critical",n))(gv||{});var HQ={};Vt(HQ,{allSeverities:()=>bC,getPackages:()=>d5,getReportTree:()=>h5,getSeverityInclusions:()=>p5,getTopLevelDependencies:()=>g5});Ge();var IBe=Ze(Jn());var bC=["info","low","moderate","high","critical"];function p5(t){if(typeof t>"u")return new Set(bC);let e=bC.indexOf(t),r=bC.slice(e);return new Set(r)}function h5(t){let e={},r={children:e};for(let[o,a]of He.sortMap(Object.entries(t),n=>n[0]))for(let n of He.sortMap(a,u=>`${u.id}`))e[`${o}/${n.id}`]={value:pe.tuple(pe.Type.IDENT,G.parseIdent(o)),children:{ID:typeof n.id<"u"&&{label:"ID",value:pe.tuple(pe.Type.ID,n.id)},Issue:{label:"Issue",value:pe.tuple(pe.Type.NO_HINT,n.title)},URL:typeof n.url<"u"&&{label:"URL",value:pe.tuple(pe.Type.URL,n.url)},Severity:{label:"Severity",value:pe.tuple(pe.Type.NO_HINT,n.severity)},"Vulnerable Versions":{label:"Vulnerable Versions",value:pe.tuple(pe.Type.RANGE,n.vulnerable_versions)},"Tree Versions":{label:"Tree Versions",children:[...n.versions].sort(IBe.default.compare).map(u=>({value:pe.tuple(pe.Type.REFERENCE,u)}))},Dependents:{label:"Dependents",children:He.sortMap(n.dependents,u=>G.stringifyLocator(u)).map(u=>({value:pe.tuple(pe.Type.LOCATOR,u)}))}}};return r}function g5(t,e,{all:r,environment:o}){let a=[],n=r?t.workspaces:[e],u=["all","production"].includes(o),A=["all","development"].includes(o);for(let p of n)for(let h of p.anchoredPackage.dependencies.values())(p.manifest.devDependencies.has(h.identHash)?!A:!u)||a.push({workspace:p,dependency:h});return a}function d5(t,e,{recursive:r}){let o=new Map,a=new Set,n=[],u=(A,p)=>{let h=t.storedResolutions.get(p.descriptorHash);if(typeof h>"u")throw new Error("Assertion failed: The resolution should have been registered");if(!a.has(h))a.add(h);else return;let E=t.storedPackages.get(h);if(typeof E>"u")throw new Error("Assertion failed: The package should have been registered");if(G.ensureDevirtualizedLocator(E).reference.startsWith("npm:")&&E.version!==null){let v=G.stringifyIdent(E),x=He.getMapWithDefault(o,v);He.getArrayWithDefault(x,E.version).push(A)}if(r)for(let v of E.dependencies.values())n.push([E,v])};for(let{workspace:A,dependency:p}of e)n.push([A.anchoredLocator,p]);for(;n.length>0;){let[A,p]=n.shift();u(A,p)}return o}var SC=class extends ut{constructor(){super(...arguments);this.all=ge.Boolean("-A,--all",!1,{description:"Audit dependencies from all workspaces"});this.recursive=ge.Boolean("-R,--recursive",!1,{description:"Audit transitive dependencies as well"});this.environment=ge.String("--environment","all",{description:"Which environments to cover",validator:Js(hv)});this.json=ge.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.noDeprecations=ge.Boolean("--no-deprecations",!1,{description:"Don't warn about deprecated packages"});this.severity=ge.String("--severity","info",{description:"Minimal severity requested for packages to be displayed",validator:Js(gv)});this.excludes=ge.Array("--exclude",[],{description:"Array of glob patterns of packages to exclude from audit"});this.ignores=ge.Array("--ignore",[],{description:"Array of glob patterns of advisory ID's to ignore in the audit report"})}static{this.paths=[["npm","audit"]]}static{this.usage=it.Usage({description:"perform a vulnerability audit against the installed packages",details:` + This command checks for known security reports on the packages you use. The reports are by default extracted from the npm registry, and may or may not be relevant to your actual program (not all vulnerabilities affect all code paths). + + For consistency with our other commands the default is to only check the direct dependencies for the active workspace. To extend this search to all workspaces, use \`-A,--all\`. To extend this search to both direct and transitive dependencies, use \`-R,--recursive\`. + + Applying the \`--severity\` flag will limit the audit table to vulnerabilities of the corresponding severity and above. Valid values are ${bC.map(r=>`\`${r}\``).join(", ")}. + + If the \`--json\` flag is set, Yarn will print the output exactly as received from the registry. Regardless of this flag, the process will exit with a non-zero exit code if a report is found for the selected packages. + + If certain packages produce false positives for a particular environment, the \`--exclude\` flag can be used to exclude any number of packages from the audit. This can also be set in the configuration file with the \`npmAuditExcludePackages\` option. + + If particular advisories are needed to be ignored, the \`--ignore\` flag can be used with Advisory ID's to ignore any number of advisories in the audit report. This can also be set in the configuration file with the \`npmAuditIgnoreAdvisories\` option. + + To understand the dependency tree requiring vulnerable packages, check the raw report with the \`--json\` flag or use \`yarn why package\` to get more information as to who depends on them. + `,examples:[["Checks for known security issues with the installed packages. The output is a list of known issues.","yarn npm audit"],["Audit dependencies in all workspaces","yarn npm audit --all"],["Limit auditing to `dependencies` (excludes `devDependencies`)","yarn npm audit --environment production"],["Show audit report as valid JSON","yarn npm audit --json"],["Audit all direct and transitive dependencies","yarn npm audit --recursive"],["Output moderate (or more severe) vulnerabilities","yarn npm audit --severity moderate"],["Exclude certain packages","yarn npm audit --exclude package1 --exclude package2"],["Ignore specific advisories","yarn npm audit --ignore 1234567 --ignore 7654321"]]})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await kt.find(r,this.context.cwd);if(!a)throw new sr(o.cwd,this.context.cwd);await o.restoreInstallState();let n=g5(o,a,{all:this.all,environment:this.environment}),u=d5(o,n,{recursive:this.recursive}),A=Array.from(new Set([...r.get("npmAuditExcludePackages"),...this.excludes])),p=Object.create(null);for(let[L,U]of u)A.some(z=>m5.default.isMatch(L,z))||(p[L]=[...U.keys()]);let h=Zn.getAuditRegistry({configuration:r}),E,I=await AA.start({configuration:r,stdout:this.context.stdout},async()=>{let L=Zr.post("/-/npm/v1/security/advisories/bulk",p,{authType:Zr.AuthType.BEST_EFFORT,configuration:r,jsonResponse:!0,registry:h}),U=this.noDeprecations?[]:await Promise.all(Array.from(Object.entries(p),async([te,ae])=>{let le=await Zr.getPackageMetadata(G.parseIdent(te),{project:o});return He.mapAndFilter(ae,ce=>{let{deprecated:Ce}=le.versions[ce];return Ce?[te,ce,Ce]:He.mapAndFilter.skip})})),z=await L;for(let[te,ae,le]of U.flat(1))Object.hasOwn(z,te)&&z[te].some(ce=>Lr.satisfiesWithPrereleases(ae,ce.vulnerable_versions))||(z[te]??=[],z[te].push({id:`${te} (deprecation)`,title:le.trim()||"This package has been deprecated.",severity:"moderate",vulnerable_versions:ae}));E=z});if(I.hasErrors())return I.exitCode();let v=p5(this.severity),x=Array.from(new Set([...r.get("npmAuditIgnoreAdvisories"),...this.ignores])),C=Object.create(null);for(let[L,U]of Object.entries(E)){let z=U.filter(te=>!m5.default.isMatch(`${te.id}`,x)&&v.has(te.severity));z.length>0&&(C[L]=z.map(te=>{let ae=u.get(L);if(typeof ae>"u")throw new Error("Assertion failed: Expected the registry to only return packages that were requested");let le=[...ae.keys()].filter(Ce=>Lr.satisfiesWithPrereleases(Ce,te.vulnerable_versions)),ce=new Map;for(let Ce of le)for(let de of ae.get(Ce))ce.set(de.locatorHash,de);return{...te,versions:le,dependents:[...ce.values()]}}))}let R=Object.keys(C).length>0;return R?(fs.emitTree(h5(C),{configuration:r,json:this.json,stdout:this.context.stdout,separators:2}),1):(await Rt.start({configuration:r,includeFooter:!1,json:this.json,stdout:this.context.stdout},async L=>{L.reportInfo(1,"No audit suggestions")}),R?1:0)}};Ge();Ge();Pt();qt();var y5=Ze(Jn()),E5=ve("util"),xC=class extends ut{constructor(){super(...arguments);this.fields=ge.String("-f,--fields",{description:"A comma-separated list of manifest fields that should be displayed"});this.json=ge.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.packages=ge.Rest()}static{this.paths=[["npm","info"]]}static{this.usage=it.Usage({category:"Npm-related commands",description:"show information about a package",details:"\n This command fetches information about a package from the npm registry and prints it in a tree format.\n\n The package does not have to be installed locally, but needs to have been published (in particular, local changes will be ignored even for workspaces).\n\n Append `@` to the package argument to provide information specific to the latest version that satisfies the range or to the corresponding tagged version. If the range is invalid or if there is no version satisfying the range, the command will print a warning and fall back to the latest version.\n\n If the `-f,--fields` option is set, it's a comma-separated list of fields which will be used to only display part of the package information.\n\n By default, this command won't return the `dist`, `readme`, and `users` fields, since they are often very long. To explicitly request those fields, explicitly list them with the `--fields` flag or request the output in JSON mode.\n ",examples:[["Show all available information about react (except the `dist`, `readme`, and `users` fields)","yarn npm info react"],["Show all available information about react as valid JSON (including the `dist`, `readme`, and `users` fields)","yarn npm info react --json"],["Show all available information about react@16.12.0","yarn npm info react@16.12.0"],["Show all available information about react@next","yarn npm info react@next"],["Show the description of react","yarn npm info react --fields description"],["Show all available versions of react","yarn npm info react --fields versions"],["Show the readme of react","yarn npm info react --fields readme"],["Show a few fields of react","yarn npm info react --fields homepage,repository"]]})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins),{project:o}=await kt.find(r,this.context.cwd),a=typeof this.fields<"u"?new Set(["name",...this.fields.split(/\s*,\s*/)]):null,n=[],u=!1,A=await Rt.start({configuration:r,includeFooter:!1,json:this.json,stdout:this.context.stdout},async p=>{for(let h of this.packages){let E;if(h==="."){let ae=o.topLevelWorkspace;if(!ae.manifest.name)throw new st(`Missing ${pe.pretty(r,"name",pe.Type.CODE)} field in ${ue.fromPortablePath(V.join(ae.cwd,dr.manifest))}`);E=G.makeDescriptor(ae.manifest.name,"unknown")}else E=G.parseDescriptor(h);let I=Zr.getIdentUrl(E),v=C5(await Zr.get(I,{configuration:r,ident:E,jsonResponse:!0,customErrorMessage:Zr.customPackageError})),x=Object.keys(v.versions).sort(y5.default.compareLoose),R=v["dist-tags"].latest||x[x.length-1],L=Lr.validRange(E.range);if(L){let ae=y5.default.maxSatisfying(x,L);ae!==null?R=ae:(p.reportWarning(0,`Unmet range ${G.prettyRange(r,E.range)}; falling back to the latest version`),u=!0)}else Object.hasOwn(v["dist-tags"],E.range)?R=v["dist-tags"][E.range]:E.range!=="unknown"&&(p.reportWarning(0,`Unknown tag ${G.prettyRange(r,E.range)}; falling back to the latest version`),u=!0);let U=v.versions[R],z={...v,...U,version:R,versions:x},te;if(a!==null){te={};for(let ae of a){let le=z[ae];if(typeof le<"u")te[ae]=le;else{p.reportWarning(1,`The ${pe.pretty(r,ae,pe.Type.CODE)} field doesn't exist inside ${G.prettyIdent(r,E)}'s information`),u=!0;continue}}}else this.json||(delete z.dist,delete z.readme,delete z.users),te=z;p.reportJson(te),this.json||n.push(te)}});E5.inspect.styles.name="cyan";for(let p of n)(p!==n[0]||u)&&this.context.stdout.write(` +`),this.context.stdout.write(`${(0,E5.inspect)(p,{depth:1/0,colors:!0,compact:!1})} +`);return A.exitCode()}};function C5(t){if(Array.isArray(t)){let e=[];for(let r of t)r=C5(r),r&&e.push(r);return e}else if(typeof t=="object"&&t!==null){let e={};for(let r of Object.keys(t)){if(r.startsWith("_"))continue;let o=C5(t[r]);o&&(e[r]=o)}return e}else return t||null}Ge();Ge();qt();var BBe=Ze(J1()),kC=class extends ut{constructor(){super(...arguments);this.scope=ge.String("-s,--scope",{description:"Login to the registry configured for a given scope"});this.publish=ge.Boolean("--publish",!1,{description:"Login to the publish registry"});this.alwaysAuth=ge.Boolean("--always-auth",{description:"Set the npmAlwaysAuth configuration"})}static{this.paths=[["npm","login"]]}static{this.usage=it.Usage({category:"Npm-related commands",description:"store new login info to access the npm registry",details:"\n This command will ask you for your username, password, and 2FA One-Time-Password (when it applies). It will then modify your local configuration (in your home folder, never in the project itself) to reference the new tokens thus generated.\n\n Adding the `-s,--scope` flag will cause the authentication to be done against whatever registry is configured for the associated scope (see also `npmScopes`).\n\n Adding the `--publish` flag will cause the authentication to be done against the registry used when publishing the package (see also `publishConfig.registry` and `npmPublishRegistry`).\n ",examples:[["Login to the default registry","yarn npm login"],["Login to the registry linked to the @my-scope registry","yarn npm login --scope my-scope"],["Login to the publish registry for the current package","yarn npm login --publish"]]})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins),o=await qQ({configuration:r,cwd:this.context.cwd,publish:this.publish,scope:this.scope});return(await Rt.start({configuration:r,stdout:this.context.stdout,includeFooter:!1},async n=>{let u=await Yvt({configuration:r,registry:o,report:n,stdin:this.context.stdin,stdout:this.context.stdout}),A=await jvt(o,u,r);return await Gvt(o,A,{alwaysAuth:this.alwaysAuth,scope:this.scope}),n.reportInfo(0,"Successfully logged in")})).exitCode()}};async function qQ({scope:t,publish:e,configuration:r,cwd:o}){return t&&e?Zn.getScopeRegistry(t,{configuration:r,type:Zn.RegistryType.PUBLISH_REGISTRY}):t?Zn.getScopeRegistry(t,{configuration:r}):e?Zn.getPublishRegistry((await _y(r,o)).manifest,{configuration:r}):Zn.getDefaultRegistry({configuration:r})}async function jvt(t,e,r){let o=`/-/user/org.couchdb.user:${encodeURIComponent(e.name)}`,a={_id:`org.couchdb.user:${e.name}`,name:e.name,password:e.password,type:"user",roles:[],date:new Date().toISOString()},n={attemptedAs:e.name,configuration:r,registry:t,jsonResponse:!0,authType:Zr.AuthType.NO_AUTH};try{return(await Zr.put(o,a,n)).token}catch(E){if(!(E.originalError?.name==="HTTPError"&&E.originalError?.response.statusCode===409))throw E}let u={...n,authType:Zr.AuthType.NO_AUTH,headers:{authorization:`Basic ${Buffer.from(`${e.name}:${e.password}`).toString("base64")}`}},A=await Zr.get(o,u);for(let[E,I]of Object.entries(A))(!a[E]||E==="roles")&&(a[E]=I);let p=`${o}/-rev/${a._rev}`;return(await Zr.put(p,a,u)).token}async function Gvt(t,e,{alwaysAuth:r,scope:o}){let a=u=>A=>{let p=He.isIndexableObject(A)?A:{},h=p[u],E=He.isIndexableObject(h)?h:{};return{...p,[u]:{...E,...r!==void 0?{npmAlwaysAuth:r}:{},npmAuthToken:e}}},n=o?{npmScopes:a(o)}:{npmRegistries:a(t)};return await Ke.updateHomeConfiguration(n)}async function Yvt({configuration:t,registry:e,report:r,stdin:o,stdout:a}){r.reportInfo(0,`Logging in to ${pe.pretty(t,e,pe.Type.URL)}`);let n=!1;if(e.match(/^https:\/\/npm\.pkg\.github\.com(\/|$)/)&&(r.reportInfo(0,"You seem to be using the GitHub Package Registry. Tokens must be generated with the 'repo', 'write:packages', and 'read:packages' permissions."),n=!0),r.reportSeparator(),t.env.YARN_IS_TEST_ENV)return{name:t.env.YARN_INJECT_NPM_USER||"",password:t.env.YARN_INJECT_NPM_PASSWORD||""};let u=await(0,BBe.prompt)([{type:"input",name:"name",message:"Username:",required:!0,onCancel:()=>process.exit(130),stdin:o,stdout:a},{type:"password",name:"password",message:n?"Token:":"Password:",required:!0,onCancel:()=>process.exit(130),stdin:o,stdout:a}]);return r.reportSeparator(),u}Ge();Ge();qt();var QC=new Set(["npmAuthIdent","npmAuthToken"]),FC=class extends ut{constructor(){super(...arguments);this.scope=ge.String("-s,--scope",{description:"Logout of the registry configured for a given scope"});this.publish=ge.Boolean("--publish",!1,{description:"Logout of the publish registry"});this.all=ge.Boolean("-A,--all",!1,{description:"Logout of all registries"})}static{this.paths=[["npm","logout"]]}static{this.usage=it.Usage({category:"Npm-related commands",description:"logout of the npm registry",details:"\n This command will log you out by modifying your local configuration (in your home folder, never in the project itself) to delete all credentials linked to a registry.\n\n Adding the `-s,--scope` flag will cause the deletion to be done against whatever registry is configured for the associated scope (see also `npmScopes`).\n\n Adding the `--publish` flag will cause the deletion to be done against the registry used when publishing the package (see also `publishConfig.registry` and `npmPublishRegistry`).\n\n Adding the `-A,--all` flag will cause the deletion to be done against all registries and scopes.\n ",examples:[["Logout of the default registry","yarn npm logout"],["Logout of the @my-scope scope","yarn npm logout --scope my-scope"],["Logout of the publish registry for the current package","yarn npm logout --publish"],["Logout of all registries","yarn npm logout --all"]]})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins),o=async()=>{let n=await qQ({configuration:r,cwd:this.context.cwd,publish:this.publish,scope:this.scope}),u=await Ke.find(this.context.cwd,this.context.plugins),A=G.makeIdent(this.scope??null,"pkg");return!Zn.getAuthConfiguration(n,{configuration:u,ident:A}).get("npmAuthToken")};return(await Rt.start({configuration:r,stdout:this.context.stdout},async n=>{if(this.all&&(await Kvt(),n.reportInfo(0,"Successfully logged out from everything")),this.scope){await vBe("npmScopes",this.scope),await o()?n.reportInfo(0,`Successfully logged out from ${this.scope}`):n.reportWarning(0,"Scope authentication settings removed, but some other ones settings still apply to it");return}let u=await qQ({configuration:r,cwd:this.context.cwd,publish:this.publish});await vBe("npmRegistries",u),await o()?n.reportInfo(0,`Successfully logged out from ${u}`):n.reportWarning(0,"Registry authentication settings removed, but some other ones settings still apply to it")})).exitCode()}};function Wvt(t,e){let r=t[e];if(!He.isIndexableObject(r))return!1;let o=new Set(Object.keys(r));if([...QC].every(n=>!o.has(n)))return!1;for(let n of QC)o.delete(n);if(o.size===0)return t[e]=void 0,!0;let a={...r};for(let n of QC)delete a[n];return t[e]=a,!0}async function Kvt(){let t=e=>{let r=!1,o=He.isIndexableObject(e)?{...e}:{};o.npmAuthToken&&(delete o.npmAuthToken,r=!0);for(let a of Object.keys(o))Wvt(o,a)&&(r=!0);if(Object.keys(o).length!==0)return r?o:e};return await Ke.updateHomeConfiguration({npmRegistries:t,npmScopes:t})}async function vBe(t,e){return await Ke.updateHomeConfiguration({[t]:r=>{let o=He.isIndexableObject(r)?r:{};if(!Object.hasOwn(o,e))return r;let a=o[e],n=He.isIndexableObject(a)?a:{},u=new Set(Object.keys(n));if([...QC].every(p=>!u.has(p)))return r;for(let p of QC)u.delete(p);if(u.size===0)return Object.keys(o).length===1?void 0:{...o,[e]:void 0};let A={};for(let p of QC)A[p]=void 0;return{...o,[e]:{...n,...A}}}})}Ge();qt();var RC=class extends ut{constructor(){super(...arguments);this.access=ge.String("--access",{description:"The access for the published package (public or restricted)"});this.tag=ge.String("--tag","latest",{description:"The tag on the registry that the package should be attached to"});this.tolerateRepublish=ge.Boolean("--tolerate-republish",!1,{description:"Warn and exit when republishing an already existing version of a package"});this.otp=ge.String("--otp",{description:"The OTP token to use with the command"})}static{this.paths=[["npm","publish"]]}static{this.usage=it.Usage({category:"Npm-related commands",description:"publish the active workspace to the npm registry",details:'\n This command will pack the active workspace into a fresh archive and upload it to the npm registry.\n\n The package will by default be attached to the `latest` tag on the registry, but this behavior can be overridden by using the `--tag` option.\n\n Note that for legacy reasons scoped packages are by default published with an access set to `restricted` (aka "private packages"). This requires you to register for a paid npm plan. In case you simply wish to publish a public scoped package to the registry (for free), just add the `--access public` flag. This behavior can be enabled by default through the `npmPublishAccess` settings.\n ',examples:[["Publish the active workspace","yarn npm publish"]]})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await kt.find(r,this.context.cwd);if(!a)throw new sr(o.cwd,this.context.cwd);if(a.manifest.private)throw new st("Private workspaces cannot be published");if(a.manifest.name===null||a.manifest.version===null)throw new st("Workspaces must have valid names and versions to be published on an external registry");await o.restoreInstallState();let n=a.manifest.name,u=a.manifest.version,A=Zn.getPublishRegistry(a.manifest,{configuration:r});return(await Rt.start({configuration:r,stdout:this.context.stdout},async h=>{if(this.tolerateRepublish)try{let E=await Zr.get(Zr.getIdentUrl(n),{configuration:r,registry:A,ident:n,jsonResponse:!0});if(!Object.hasOwn(E,"versions"))throw new Jt(15,'Registry returned invalid data for - missing "versions" field');if(Object.hasOwn(E.versions,u)){h.reportWarning(0,`Registry already knows about version ${u}; skipping.`);return}}catch(E){if(E.originalError?.response?.statusCode!==404)throw E}await An.maybeExecuteWorkspaceLifecycleScript(a,"prepublish",{report:h}),await CA.prepareForPack(a,{report:h},async()=>{let E=await CA.genPackList(a);for(let R of E)h.reportInfo(null,R);let I=await CA.genPackStream(a,E),v=await He.bufferStream(I),x=await PC.getGitHead(a.cwd),C=await PC.makePublishBody(a,v,{access:this.access,tag:this.tag,registry:A,gitHead:x});await Zr.put(Zr.getIdentUrl(n),C,{configuration:r,registry:A,ident:n,otp:this.otp,jsonResponse:!0})}),h.reportInfo(0,"Package archive published")})).exitCode()}};Ge();qt();var DBe=Ze(Jn());Ge();Pt();qt();var TC=class extends ut{constructor(){super(...arguments);this.json=ge.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.package=ge.String({required:!1})}static{this.paths=[["npm","tag","list"]]}static{this.usage=it.Usage({category:"Npm-related commands",description:"list all dist-tags of a package",details:` + This command will list all tags of a package from the npm registry. + + If the package is not specified, Yarn will default to the current workspace. + `,examples:[["List all tags of package `my-pkg`","yarn npm tag list my-pkg"]]})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await kt.find(r,this.context.cwd),n;if(typeof this.package<"u")n=G.parseIdent(this.package);else{if(!a)throw new sr(o.cwd,this.context.cwd);if(!a.manifest.name)throw new st(`Missing 'name' field in ${ue.fromPortablePath(V.join(a.cwd,dr.manifest))}`);n=a.manifest.name}let u=await mv(n,r),p={children:He.sortMap(Object.entries(u),([h])=>h).map(([h,E])=>({value:pe.tuple(pe.Type.RESOLUTION,{descriptor:G.makeDescriptor(n,h),locator:G.makeLocator(n,E)})}))};return fs.emitTree(p,{configuration:r,json:this.json,stdout:this.context.stdout})}};async function mv(t,e){let r=`/-/package${Zr.getIdentUrl(t)}/dist-tags`;return Zr.get(r,{configuration:e,ident:t,jsonResponse:!0,customErrorMessage:Zr.customPackageError})}var NC=class extends ut{constructor(){super(...arguments);this.package=ge.String();this.tag=ge.String()}static{this.paths=[["npm","tag","add"]]}static{this.usage=it.Usage({category:"Npm-related commands",description:"add a tag for a specific version of a package",details:` + This command will add a tag to the npm registry for a specific version of a package. If the tag already exists, it will be overwritten. + `,examples:[["Add a `beta` tag for version `2.3.4-beta.4` of package `my-pkg`","yarn npm tag add my-pkg@2.3.4-beta.4 beta"]]})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await kt.find(r,this.context.cwd);if(!a)throw new sr(o.cwd,this.context.cwd);let n=G.parseDescriptor(this.package,!0),u=n.range;if(!DBe.default.valid(u))throw new st(`The range ${pe.pretty(r,n.range,pe.Type.RANGE)} must be a valid semver version`);let A=Zn.getPublishRegistry(a.manifest,{configuration:r}),p=pe.pretty(r,n,pe.Type.IDENT),h=pe.pretty(r,u,pe.Type.RANGE),E=pe.pretty(r,this.tag,pe.Type.CODE);return(await Rt.start({configuration:r,stdout:this.context.stdout},async v=>{let x=await mv(n,r);Object.hasOwn(x,this.tag)&&x[this.tag]===u&&v.reportWarning(0,`Tag ${E} is already set to version ${h}`);let C=`/-/package${Zr.getIdentUrl(n)}/dist-tags/${encodeURIComponent(this.tag)}`;await Zr.put(C,u,{configuration:r,registry:A,ident:n,jsonRequest:!0,jsonResponse:!0}),v.reportInfo(0,`Tag ${E} added to version ${h} of package ${p}`)})).exitCode()}};Ge();qt();var LC=class extends ut{constructor(){super(...arguments);this.package=ge.String();this.tag=ge.String()}static{this.paths=[["npm","tag","remove"]]}static{this.usage=it.Usage({category:"Npm-related commands",description:"remove a tag from a package",details:` + This command will remove a tag from a package from the npm registry. + `,examples:[["Remove the `beta` tag from package `my-pkg`","yarn npm tag remove my-pkg beta"]]})}async execute(){if(this.tag==="latest")throw new st("The 'latest' tag cannot be removed.");let r=await Ke.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await kt.find(r,this.context.cwd);if(!a)throw new sr(o.cwd,this.context.cwd);let n=G.parseIdent(this.package),u=Zn.getPublishRegistry(a.manifest,{configuration:r}),A=pe.pretty(r,this.tag,pe.Type.CODE),p=pe.pretty(r,n,pe.Type.IDENT),h=await mv(n,r);if(!Object.hasOwn(h,this.tag))throw new st(`${A} is not a tag of package ${p}`);return(await Rt.start({configuration:r,stdout:this.context.stdout},async I=>{let v=`/-/package${Zr.getIdentUrl(n)}/dist-tags/${encodeURIComponent(this.tag)}`;await Zr.del(v,{configuration:r,registry:u,ident:n,jsonResponse:!0}),I.reportInfo(0,`Tag ${A} removed from package ${p}`)})).exitCode()}};Ge();Ge();qt();var MC=class extends ut{constructor(){super(...arguments);this.scope=ge.String("-s,--scope",{description:"Print username for the registry configured for a given scope"});this.publish=ge.Boolean("--publish",!1,{description:"Print username for the publish registry"})}static{this.paths=[["npm","whoami"]]}static{this.usage=it.Usage({category:"Npm-related commands",description:"display the name of the authenticated user",details:"\n Print the username associated with the current authentication settings to the standard output.\n\n When using `-s,--scope`, the username printed will be the one that matches the authentication settings of the registry associated with the given scope (those settings can be overriden using the `npmRegistries` map, and the registry associated with the scope is configured via the `npmScopes` map).\n\n When using `--publish`, the registry we'll select will by default be the one used when publishing packages (`publishConfig.registry` or `npmPublishRegistry` if available, otherwise we'll fallback to the regular `npmRegistryServer`).\n ",examples:[["Print username for the default registry","yarn npm whoami"],["Print username for the registry on a given scope","yarn npm whoami --scope company"]]})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins),o;return this.scope&&this.publish?o=Zn.getScopeRegistry(this.scope,{configuration:r,type:Zn.RegistryType.PUBLISH_REGISTRY}):this.scope?o=Zn.getScopeRegistry(this.scope,{configuration:r}):this.publish?o=Zn.getPublishRegistry((await _y(r,this.context.cwd)).manifest,{configuration:r}):o=Zn.getDefaultRegistry({configuration:r}),(await Rt.start({configuration:r,stdout:this.context.stdout},async n=>{let u;try{u=await Zr.get("/-/whoami",{configuration:r,registry:o,authType:Zr.AuthType.ALWAYS_AUTH,jsonResponse:!0,ident:this.scope?G.makeIdent(this.scope,""):void 0})}catch(A){if(A.response?.statusCode===401||A.response?.statusCode===403){n.reportError(41,"Authentication failed - your credentials may have expired");return}else throw A}n.reportInfo(0,u.username)})).exitCode()}};var Vvt={configuration:{npmPublishAccess:{description:"Default access of the published packages",type:"STRING",default:null},npmAuditExcludePackages:{description:"Array of glob patterns of packages to exclude from npm audit",type:"STRING",default:[],isArray:!0},npmAuditIgnoreAdvisories:{description:"Array of glob patterns of advisory IDs to exclude from npm audit",type:"STRING",default:[],isArray:!0}},commands:[SC,xC,kC,FC,RC,NC,TC,LC,MC]},zvt=Vvt;var S5={};Vt(S5,{PatchCommand:()=>jC,PatchCommitCommand:()=>qC,PatchFetcher:()=>Iv,PatchResolver:()=>Bv,default:()=>pDt,patchUtils:()=>pd});Ge();Ge();Pt();nA();var pd={};Vt(pd,{applyPatchFile:()=>GQ,diffFolders:()=>P5,ensureUnpatchedDescriptor:()=>I5,ensureUnpatchedLocator:()=>WQ,extractPackageToDisk:()=>D5,extractPatchFlags:()=>FBe,isParentRequired:()=>v5,isPatchDescriptor:()=>YQ,isPatchLocator:()=>$h,loadPatchFiles:()=>wv,makeDescriptor:()=>KQ,makeLocator:()=>B5,makePatchHash:()=>b5,parseDescriptor:()=>Ev,parseLocator:()=>Cv,parsePatchFile:()=>yv,unpatchDescriptor:()=>uDt,unpatchLocator:()=>ADt});Ge();Pt();Ge();Pt();var Jvt=/^@@ -(\d+)(,(\d+))? \+(\d+)(,(\d+))? @@.*/;function OC(t){return V.relative(It.root,V.resolve(It.root,ue.toPortablePath(t)))}function Xvt(t){let e=t.trim().match(Jvt);if(!e)throw new Error(`Bad header line: '${t}'`);return{original:{start:Math.max(Number(e[1]),1),length:Number(e[3]||1)},patched:{start:Math.max(Number(e[4]),1),length:Number(e[6]||1)}}}var Zvt=420,$vt=493;var PBe=()=>({semverExclusivity:null,diffLineFromPath:null,diffLineToPath:null,oldMode:null,newMode:null,deletedFileMode:null,newFileMode:null,renameFrom:null,renameTo:null,beforeHash:null,afterHash:null,fromPath:null,toPath:null,hunks:null}),eDt=t=>({header:Xvt(t),parts:[]}),tDt={"@":"header","-":"deletion","+":"insertion"," ":"context","\\":"pragma",undefined:"context"};function rDt(t){let e=[],r=PBe(),o="parsing header",a=null,n=null;function u(){a&&(n&&(a.parts.push(n),n=null),r.hunks.push(a),a=null)}function A(){u(),e.push(r),r=PBe()}for(let p=0;p0?"patch":"mode change",z=null;switch(U){case"rename":{if(!E||!I)throw new Error("Bad parser state: rename from & to not given");e.push({type:"rename",semverExclusivity:o,fromPath:OC(E),toPath:OC(I)}),z=I}break;case"file deletion":{let te=a||C;if(!te)throw new Error("Bad parse state: no path given for file deletion");e.push({type:"file deletion",semverExclusivity:o,hunk:L&&L[0]||null,path:OC(te),mode:jQ(p),hash:v})}break;case"file creation":{let te=n||R;if(!te)throw new Error("Bad parse state: no path given for file creation");e.push({type:"file creation",semverExclusivity:o,hunk:L&&L[0]||null,path:OC(te),mode:jQ(h),hash:x})}break;case"patch":case"mode change":z=R||n;break;default:He.assertNever(U);break}z&&u&&A&&u!==A&&e.push({type:"mode change",semverExclusivity:o,path:OC(z),oldMode:jQ(u),newMode:jQ(A)}),z&&L&&L.length&&e.push({type:"patch",semverExclusivity:o,path:OC(z),hunks:L,beforeHash:v,afterHash:x})}if(e.length===0)throw new Error("Unable to parse patch file: No changes found. Make sure the patch is a valid UTF8 encoded string");return e}function jQ(t){let e=parseInt(t,8)&511;if(e!==Zvt&&e!==$vt)throw new Error(`Unexpected file mode string: ${t}`);return e}function yv(t){let e=t.split(/\n/g);return e[e.length-1]===""&&e.pop(),nDt(rDt(e))}function iDt(t){let e=0,r=0;for(let{type:o,lines:a}of t.parts)switch(o){case"context":r+=a.length,e+=a.length;break;case"deletion":e+=a.length;break;case"insertion":r+=a.length;break;default:He.assertNever(o);break}if(e!==t.header.original.length||r!==t.header.patched.length){let o=a=>a<0?a:`+${a}`;throw new Error(`hunk header integrity check failed (expected @@ ${o(t.header.original.length)} ${o(t.header.patched.length)} @@, got @@ ${o(e)} ${o(r)} @@)`)}}Ge();Pt();var UC=class extends Error{constructor(r,o){super(`Cannot apply hunk #${r+1}`);this.hunk=o}};async function _C(t,e,r){let o=await t.lstatPromise(e),a=await r();typeof a<"u"&&(e=a),await t.lutimesPromise(e,o.atime,o.mtime)}async function GQ(t,{baseFs:e=new Tn,dryRun:r=!1,version:o=null}={}){for(let a of t)if(!(a.semverExclusivity!==null&&o!==null&&!Lr.satisfiesWithPrereleases(o,a.semverExclusivity)))switch(a.type){case"file deletion":if(r){if(!e.existsSync(a.path))throw new Error(`Trying to delete a file that doesn't exist: ${a.path}`)}else await _C(e,V.dirname(a.path),async()=>{await e.unlinkPromise(a.path)});break;case"rename":if(r){if(!e.existsSync(a.fromPath))throw new Error(`Trying to move a file that doesn't exist: ${a.fromPath}`)}else await _C(e,V.dirname(a.fromPath),async()=>{await _C(e,V.dirname(a.toPath),async()=>{await _C(e,a.fromPath,async()=>(await e.movePromise(a.fromPath,a.toPath),a.toPath))})});break;case"file creation":if(r){if(e.existsSync(a.path))throw new Error(`Trying to create a file that already exists: ${a.path}`)}else{let n=a.hunk?a.hunk.parts[0].lines.join(` +`)+(a.hunk.parts[0].noNewlineAtEndOfFile?"":` +`):"";await e.mkdirpPromise(V.dirname(a.path),{chmod:493,utimes:[Bi.SAFE_TIME,Bi.SAFE_TIME]}),await e.writeFilePromise(a.path,n,{mode:a.mode}),await e.utimesPromise(a.path,Bi.SAFE_TIME,Bi.SAFE_TIME)}break;case"patch":await _C(e,a.path,async()=>{await aDt(a,{baseFs:e,dryRun:r})});break;case"mode change":{let u=(await e.statPromise(a.path)).mode;if(bBe(a.newMode)!==bBe(u))continue;await _C(e,a.path,async()=>{await e.chmodPromise(a.path,a.newMode)})}break;default:He.assertNever(a);break}}function bBe(t){return(t&64)>0}function SBe(t){return t.replace(/\s+$/,"")}function oDt(t,e){return SBe(t)===SBe(e)}async function aDt({hunks:t,path:e},{baseFs:r,dryRun:o=!1}){let a=await r.statSync(e).mode,u=(await r.readFileSync(e,"utf8")).split(/\n/),A=[],p=0,h=0;for(let I of t){let v=Math.max(h,I.header.patched.start+p),x=Math.max(0,v-h),C=Math.max(0,u.length-v-I.header.original.length),R=Math.max(x,C),L=0,U=0,z=null;for(;L<=R;){if(L<=x&&(U=v-L,z=xBe(I,u,U),z!==null)){L=-L;break}if(L<=C&&(U=v+L,z=xBe(I,u,U),z!==null))break;L+=1}if(z===null)throw new UC(t.indexOf(I),I);A.push(z),p+=L,h=U+I.header.original.length}if(o)return;let E=0;for(let I of A)for(let v of I)switch(v.type){case"splice":{let x=v.index+E;u.splice(x,v.numToDelete,...v.linesToInsert),E+=v.linesToInsert.length-v.numToDelete}break;case"pop":u.pop();break;case"push":u.push(v.line);break;default:He.assertNever(v);break}await r.writeFilePromise(e,u.join(` +`),{mode:a})}function xBe(t,e,r){let o=[];for(let a of t.parts)switch(a.type){case"context":case"deletion":{for(let n of a.lines){let u=e[r];if(u==null||!oDt(u,n))return null;r+=1}a.type==="deletion"&&(o.push({type:"splice",index:r-a.lines.length,numToDelete:a.lines.length,linesToInsert:[]}),a.noNewlineAtEndOfFile&&o.push({type:"push",line:""}))}break;case"insertion":o.push({type:"splice",index:r,numToDelete:0,linesToInsert:a.lines}),a.noNewlineAtEndOfFile&&o.push({type:"pop"});break;default:He.assertNever(a.type);break}return o}var cDt=/^builtin<([^>]+)>$/;function HC(t,e){let{protocol:r,source:o,selector:a,params:n}=G.parseRange(t);if(r!=="patch:")throw new Error("Invalid patch range");if(o===null)throw new Error("Patch locators must explicitly define their source");let u=a?a.split(/&/).map(E=>ue.toPortablePath(E)):[],A=n&&typeof n.locator=="string"?G.parseLocator(n.locator):null,p=n&&typeof n.version=="string"?n.version:null,h=e(o);return{parentLocator:A,sourceItem:h,patchPaths:u,sourceVersion:p}}function YQ(t){return t.range.startsWith("patch:")}function $h(t){return t.reference.startsWith("patch:")}function Ev(t){let{sourceItem:e,...r}=HC(t.range,G.parseDescriptor);return{...r,sourceDescriptor:e}}function Cv(t){let{sourceItem:e,...r}=HC(t.reference,G.parseLocator);return{...r,sourceLocator:e}}function uDt(t){let{sourceItem:e}=HC(t.range,G.parseDescriptor);return e}function ADt(t){let{sourceItem:e}=HC(t.reference,G.parseLocator);return e}function I5(t){if(!YQ(t))return t;let{sourceItem:e}=HC(t.range,G.parseDescriptor);return e}function WQ(t){if(!$h(t))return t;let{sourceItem:e}=HC(t.reference,G.parseLocator);return e}function kBe({parentLocator:t,sourceItem:e,patchPaths:r,sourceVersion:o,patchHash:a},n){let u=t!==null?{locator:G.stringifyLocator(t)}:{},A=typeof o<"u"?{version:o}:{},p=typeof a<"u"?{hash:a}:{};return G.makeRange({protocol:"patch:",source:n(e),selector:r.join("&"),params:{...A,...p,...u}})}function KQ(t,{parentLocator:e,sourceDescriptor:r,patchPaths:o}){return G.makeDescriptor(t,kBe({parentLocator:e,sourceItem:r,patchPaths:o},G.stringifyDescriptor))}function B5(t,{parentLocator:e,sourcePackage:r,patchPaths:o,patchHash:a}){return G.makeLocator(t,kBe({parentLocator:e,sourceItem:r,sourceVersion:r.version,patchPaths:o,patchHash:a},G.stringifyLocator))}function QBe({onAbsolute:t,onRelative:e,onProject:r,onBuiltin:o},a){let n=a.lastIndexOf("!");n!==-1&&(a=a.slice(n+1));let u=a.match(cDt);return u!==null?o(u[1]):a.startsWith("~/")?r(a.slice(2)):V.isAbsolute(a)?t(a):e(a)}function FBe(t){let e=t.lastIndexOf("!");return{optional:(e!==-1?new Set(t.slice(0,e).split(/!/)):new Set).has("optional")}}function v5(t){return QBe({onAbsolute:()=>!1,onRelative:()=>!0,onProject:()=>!1,onBuiltin:()=>!1},t)}async function wv(t,e,r){let o=t!==null?await r.fetcher.fetch(t,r):null,a=o&&o.localPath?{packageFs:new gn(It.root),prefixPath:V.relative(It.root,o.localPath)}:o;o&&o!==a&&o.releaseFs&&o.releaseFs();let n=await He.releaseAfterUseAsync(async()=>await Promise.all(e.map(async u=>{let A=FBe(u),p=await QBe({onAbsolute:async h=>await oe.readFilePromise(h,"utf8"),onRelative:async h=>{if(a===null)throw new Error("Assertion failed: The parent locator should have been fetched");return await a.packageFs.readFilePromise(V.join(a.prefixPath,h),"utf8")},onProject:async h=>await oe.readFilePromise(V.join(r.project.cwd,h),"utf8"),onBuiltin:async h=>await r.project.configuration.firstHook(E=>E.getBuiltinPatch,r.project,h)},u);return{...A,source:p}})));for(let u of n)typeof u.source=="string"&&(u.source=u.source.replace(/\r\n?/g,` +`));return n}async function D5(t,{cache:e,project:r}){let o=r.storedPackages.get(t.locatorHash);if(typeof o>"u")throw new Error("Assertion failed: Expected the package to be registered");let a=WQ(t),n=r.storedChecksums,u=new ki,A=await oe.mktempPromise(),p=V.join(A,"source"),h=V.join(A,"user"),E=V.join(A,".yarn-patch.json"),I=r.configuration.makeFetcher(),v=[];try{let x,C;if(t.locatorHash===a.locatorHash){let R=await I.fetch(t,{cache:e,project:r,fetcher:I,checksums:n,report:u});v.push(()=>R.releaseFs?.()),x=R,C=R}else x=await I.fetch(t,{cache:e,project:r,fetcher:I,checksums:n,report:u}),v.push(()=>x.releaseFs?.()),C=await I.fetch(t,{cache:e,project:r,fetcher:I,checksums:n,report:u}),v.push(()=>C.releaseFs?.());await Promise.all([oe.copyPromise(p,x.prefixPath,{baseFs:x.packageFs}),oe.copyPromise(h,C.prefixPath,{baseFs:C.packageFs}),oe.writeJsonPromise(E,{locator:G.stringifyLocator(t),version:o.version})])}finally{for(let x of v)x()}return oe.detachTemp(A),h}async function P5(t,e){let r=ue.fromPortablePath(t).replace(/\\/g,"/"),o=ue.fromPortablePath(e).replace(/\\/g,"/"),{stdout:a,stderr:n}=await Ur.execvp("git",["-c","core.safecrlf=false","diff","--src-prefix=a/","--dst-prefix=b/","--ignore-cr-at-eol","--full-index","--no-index","--no-renames","--text",r,o],{cwd:ue.toPortablePath(process.cwd()),env:{...process.env,GIT_CONFIG_NOSYSTEM:"1",HOME:"",XDG_CONFIG_HOME:"",USERPROFILE:""}});if(n.length>0)throw new Error(`Unable to diff directories. Make sure you have a recent version of 'git' available in PATH. +The following error was reported by 'git': +${n}`);let u=r.startsWith("/")?A=>A.slice(1):A=>A;return a.replace(new RegExp(`(a|b)(${He.escapeRegExp(`/${u(r)}/`)})`,"g"),"$1/").replace(new RegExp(`(a|b)${He.escapeRegExp(`/${u(o)}/`)}`,"g"),"$1/").replace(new RegExp(He.escapeRegExp(`${r}/`),"g"),"").replace(new RegExp(He.escapeRegExp(`${o}/`),"g"),"")}function b5(t,e){let r=[];for(let{source:o}of t){if(o===null)continue;let a=yv(o);for(let n of a){let{semverExclusivity:u,...A}=n;u!==null&&e!==null&&!Lr.satisfiesWithPrereleases(e,u)||r.push(JSON.stringify(A))}}return wn.makeHash(`${3}`,...r).slice(0,6)}Ge();function RBe(t,{configuration:e,report:r}){for(let o of t.parts)for(let a of o.lines)switch(o.type){case"context":r.reportInfo(null,` ${pe.pretty(e,a,"grey")}`);break;case"deletion":r.reportError(28,`- ${pe.pretty(e,a,pe.Type.REMOVED)}`);break;case"insertion":r.reportError(28,`+ ${pe.pretty(e,a,pe.Type.ADDED)}`);break;default:He.assertNever(o.type)}}var Iv=class{supports(e,r){return!!$h(e)}getLocalPath(e,r){return null}async fetch(e,r){let o=r.checksums.get(e.locatorHash)||null,[a,n,u]=await r.cache.fetchPackageFromCache(e,o,{onHit:()=>r.report.reportCacheHit(e),onMiss:()=>r.report.reportCacheMiss(e,`${G.prettyLocator(r.project.configuration,e)} can't be found in the cache and will be fetched from the disk`),loader:()=>this.patchPackage(e,r),...r.cacheOptions});return{packageFs:a,releaseFs:n,prefixPath:G.getIdentVendorPath(e),localPath:this.getLocalPath(e,r),checksum:u}}async patchPackage(e,r){let{parentLocator:o,sourceLocator:a,sourceVersion:n,patchPaths:u}=Cv(e),A=await wv(o,u,r),p=await oe.mktempPromise(),h=V.join(p,"current.zip"),E=await r.fetcher.fetch(a,r),I=G.getIdentVendorPath(e),v=new Zi(h,{create:!0,level:r.project.configuration.get("compressionLevel")});await He.releaseAfterUseAsync(async()=>{await v.copyPromise(I,E.prefixPath,{baseFs:E.packageFs,stableSort:!0})},E.releaseFs),v.saveAndClose();for(let{source:x,optional:C}of A){if(x===null)continue;let R=new Zi(h,{level:r.project.configuration.get("compressionLevel")}),L=new gn(V.resolve(It.root,I),{baseFs:R});try{await GQ(yv(x),{baseFs:L,version:n})}catch(U){if(!(U instanceof UC))throw U;let z=r.project.configuration.get("enableInlineHunks"),te=!z&&!C?" (set enableInlineHunks for details)":"",ae=`${G.prettyLocator(r.project.configuration,e)}: ${U.message}${te}`,le=ce=>{z&&RBe(U.hunk,{configuration:r.project.configuration,report:ce})};if(R.discardAndClose(),C){r.report.reportWarningOnce(66,ae,{reportExtra:le});continue}else throw new Jt(66,ae,le)}R.saveAndClose()}return new Zi(h,{level:r.project.configuration.get("compressionLevel")})}};Ge();var Bv=class{supportsDescriptor(e,r){return!!YQ(e)}supportsLocator(e,r){return!!$h(e)}shouldPersistResolution(e,r){return!1}bindDescriptor(e,r,o){let{patchPaths:a}=Ev(e);return a.every(n=>!v5(n))?e:G.bindDescriptor(e,{locator:G.stringifyLocator(r)})}getResolutionDependencies(e,r){let{sourceDescriptor:o}=Ev(e);return{sourceDescriptor:r.project.configuration.normalizeDependency(o)}}async getCandidates(e,r,o){if(!o.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let{parentLocator:a,patchPaths:n}=Ev(e),u=await wv(a,n,o.fetchOptions),A=r.sourceDescriptor;if(typeof A>"u")throw new Error("Assertion failed: The dependency should have been resolved");let p=b5(u,A.version);return[B5(e,{parentLocator:a,sourcePackage:A,patchPaths:n,patchHash:p})]}async getSatisfying(e,r,o,a){let[n]=await this.getCandidates(e,r,a);return{locators:o.filter(u=>u.locatorHash===n.locatorHash),sorted:!1}}async resolve(e,r){let{sourceLocator:o}=Cv(e);return{...await r.resolver.resolve(o,r),...e}}};Ge();Pt();qt();var qC=class extends ut{constructor(){super(...arguments);this.save=ge.Boolean("-s,--save",!1,{description:"Add the patch to your resolution entries"});this.patchFolder=ge.String()}static{this.paths=[["patch-commit"]]}static{this.usage=it.Usage({description:"generate a patch out of a directory",details:"\n By default, this will print a patchfile on stdout based on the diff between the folder passed in and the original version of the package. Such file is suitable for consumption with the `patch:` protocol.\n\n With the `-s,--save` option set, the patchfile won't be printed on stdout anymore and will instead be stored within a local file (by default kept within `.yarn/patches`, but configurable via the `patchFolder` setting). A `resolutions` entry will also be added to your top-level manifest, referencing the patched package via the `patch:` protocol.\n\n Note that only folders generated by `yarn patch` are accepted as valid input for `yarn patch-commit`.\n "})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await kt.find(r,this.context.cwd);if(!a)throw new sr(o.cwd,this.context.cwd);await o.restoreInstallState();let n=V.resolve(this.context.cwd,ue.toPortablePath(this.patchFolder)),u=V.join(n,"../source"),A=V.join(n,"../.yarn-patch.json");if(!oe.existsSync(u))throw new st("The argument folder didn't get created by 'yarn patch'");let p=await P5(u,n),h=await oe.readJsonPromise(A),E=G.parseLocator(h.locator,!0);if(!o.storedPackages.has(E.locatorHash))throw new st("No package found in the project for the given locator");if(!this.save){this.context.stdout.write(p);return}let I=r.get("patchFolder"),v=V.join(I,`${G.slugifyLocator(E)}.patch`);await oe.mkdirPromise(I,{recursive:!0}),await oe.writeFilePromise(v,p);let x=[],C=new Map;for(let R of o.storedPackages.values()){if(G.isVirtualLocator(R))continue;let L=R.dependencies.get(E.identHash);if(!L)continue;let U=G.ensureDevirtualizedDescriptor(L),z=I5(U),te=o.storedResolutions.get(z.descriptorHash);if(!te)throw new Error("Assertion failed: Expected the resolution to have been registered");if(!o.storedPackages.get(te))throw new Error("Assertion failed: Expected the package to have been registered");let le=o.tryWorkspaceByLocator(R);if(le)x.push(le);else{let ce=o.originalPackages.get(R.locatorHash);if(!ce)throw new Error("Assertion failed: Expected the original package to have been registered");let Ce=ce.dependencies.get(L.identHash);if(!Ce)throw new Error("Assertion failed: Expected the original dependency to have been registered");C.set(Ce.descriptorHash,Ce)}}for(let R of x)for(let L of Ut.hardDependencies){let U=R.manifest[L].get(E.identHash);if(!U)continue;let z=KQ(U,{parentLocator:null,sourceDescriptor:G.convertLocatorToDescriptor(E),patchPaths:[V.join(dr.home,V.relative(o.cwd,v))]});R.manifest[L].set(U.identHash,z)}for(let R of C.values()){let L=KQ(R,{parentLocator:null,sourceDescriptor:G.convertLocatorToDescriptor(E),patchPaths:[V.join(dr.home,V.relative(o.cwd,v))]});o.topLevelWorkspace.manifest.resolutions.push({pattern:{descriptor:{fullName:G.stringifyIdent(L),description:R.range}},reference:L.range})}await o.persist()}};Ge();Pt();qt();var jC=class extends ut{constructor(){super(...arguments);this.update=ge.Boolean("-u,--update",!1,{description:"Reapply local patches that already apply to this packages"});this.json=ge.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.package=ge.String()}static{this.paths=[["patch"]]}static{this.usage=it.Usage({description:"prepare a package for patching",details:"\n This command will cause a package to be extracted in a temporary directory intended to be editable at will.\n\n Once you're done with your changes, run `yarn patch-commit -s path` (with `path` being the temporary directory you received) to generate a patchfile and register it into your top-level manifest via the `patch:` protocol. Run `yarn patch-commit -h` for more details.\n\n Calling the command when you already have a patch won't import it by default (in other words, the default behavior is to reset existing patches). However, adding the `-u,--update` flag will import any current patch.\n "})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await kt.find(r,this.context.cwd),n=await Gr.find(r);if(!a)throw new sr(o.cwd,this.context.cwd);await o.restoreInstallState();let u=G.parseLocator(this.package);if(u.reference==="unknown"){let A=He.mapAndFilter([...o.storedPackages.values()],p=>p.identHash!==u.identHash?He.mapAndFilter.skip:G.isVirtualLocator(p)?He.mapAndFilter.skip:$h(p)!==this.update?He.mapAndFilter.skip:p);if(A.length===0)throw new st("No package found in the project for the given locator");if(A.length>1)throw new st(`Multiple candidate packages found; explicitly choose one of them (use \`yarn why \` to get more information as to who depends on them): +${A.map(p=>` +- ${G.prettyLocator(r,p)}`).join("")}`);u=A[0]}if(!o.storedPackages.has(u.locatorHash))throw new st("No package found in the project for the given locator");await Rt.start({configuration:r,json:this.json,stdout:this.context.stdout},async A=>{let p=WQ(u),h=await D5(u,{cache:n,project:o});A.reportJson({locator:G.stringifyLocator(p),path:ue.fromPortablePath(h)});let E=this.update?" along with its current modifications":"";A.reportInfo(0,`Package ${G.prettyLocator(r,p)} got extracted with success${E}!`),A.reportInfo(0,`You can now edit the following folder: ${pe.pretty(r,ue.fromPortablePath(h),"magenta")}`),A.reportInfo(0,`Once you are done run ${pe.pretty(r,`yarn patch-commit -s ${process.platform==="win32"?'"':""}${ue.fromPortablePath(h)}${process.platform==="win32"?'"':""}`,"cyan")} and Yarn will store a patchfile based on your changes.`)})}};var fDt={configuration:{enableInlineHunks:{description:"If true, the installs will print unmatched patch hunks",type:"BOOLEAN",default:!1},patchFolder:{description:"Folder where the patch files must be written",type:"ABSOLUTE_PATH",default:"./.yarn/patches"}},commands:[qC,jC],fetchers:[Iv],resolvers:[Bv]},pDt=fDt;var Q5={};Vt(Q5,{PnpmLinker:()=>vv,default:()=>yDt});Ge();Pt();qt();var vv=class{getCustomDataKey(){return JSON.stringify({name:"PnpmLinker",version:3})}supportsPackage(e,r){return this.isEnabled(r)}async findPackageLocation(e,r){if(!this.isEnabled(r))throw new Error("Assertion failed: Expected the pnpm linker to be enabled");let o=this.getCustomDataKey(),a=r.project.linkersCustomData.get(o);if(!a)throw new st(`The project in ${pe.pretty(r.project.configuration,`${r.project.cwd}/package.json`,pe.Type.PATH)} doesn't seem to have been installed - running an install there might help`);let n=a.pathsByLocator.get(e.locatorHash);if(typeof n>"u")throw new st(`Couldn't find ${G.prettyLocator(r.project.configuration,e)} in the currently installed pnpm map - running an install might help`);return n.packageLocation}async findPackageLocator(e,r){if(!this.isEnabled(r))return null;let o=this.getCustomDataKey(),a=r.project.linkersCustomData.get(o);if(!a)throw new st(`The project in ${pe.pretty(r.project.configuration,`${r.project.cwd}/package.json`,pe.Type.PATH)} doesn't seem to have been installed - running an install there might help`);let n=e.match(/(^.*\/node_modules\/(@[^/]*\/)?[^/]+)(\/.*$)/);if(n){let p=a.locatorByPath.get(n[1]);if(p)return p}let u=e,A=e;do{A=u,u=V.dirname(A);let p=a.locatorByPath.get(A);if(p)return p}while(u!==A);return null}makeInstaller(e){return new x5(e)}isEnabled(e){return e.project.configuration.get("nodeLinker")==="pnpm"}},x5=class{constructor(e){this.opts=e;this.asyncActions=new He.AsyncActions(10);this.customData={pathsByLocator:new Map,locatorByPath:new Map};this.indexFolderPromise=cD(oe,{indexPath:V.join(e.project.configuration.get("globalFolder"),"index")})}attachCustomData(e){}async installPackage(e,r,o){switch(e.linkType){case"SOFT":return this.installPackageSoft(e,r,o);case"HARD":return this.installPackageHard(e,r,o)}throw new Error("Assertion failed: Unsupported package link type")}async installPackageSoft(e,r,o){let a=V.resolve(r.packageFs.getRealPath(),r.prefixPath),n=this.opts.project.tryWorkspaceByLocator(e)?V.join(a,dr.nodeModules):null;return this.customData.pathsByLocator.set(e.locatorHash,{packageLocation:a,dependenciesLocation:n}),{packageLocation:a,buildRequest:null}}async installPackageHard(e,r,o){let a=hDt(e,{project:this.opts.project}),n=a.packageLocation;this.customData.locatorByPath.set(n,G.stringifyLocator(e)),this.customData.pathsByLocator.set(e.locatorHash,a),o.holdFetchResult(this.asyncActions.set(e.locatorHash,async()=>{await oe.mkdirPromise(n,{recursive:!0}),await oe.copyPromise(n,r.prefixPath,{baseFs:r.packageFs,overwrite:!1,linkStrategy:{type:"HardlinkFromIndex",indexPath:await this.indexFolderPromise,autoRepair:!0}})}));let A=G.isVirtualLocator(e)?G.devirtualizeLocator(e):e,p={manifest:await Ut.tryFind(r.prefixPath,{baseFs:r.packageFs})??new Ut,misc:{hasBindingGyp:mA.hasBindingGyp(r)}},h=this.opts.project.getDependencyMeta(A,e.version),E=mA.extractBuildRequest(e,p,h,{configuration:this.opts.project.configuration});return{packageLocation:n,buildRequest:E}}async attachInternalDependencies(e,r){if(this.opts.project.configuration.get("nodeLinker")!=="pnpm"||!TBe(e,{project:this.opts.project}))return;let o=this.customData.pathsByLocator.get(e.locatorHash);if(typeof o>"u")throw new Error(`Assertion failed: Expected the package to have been registered (${G.stringifyLocator(e)})`);let{dependenciesLocation:a}=o;a&&this.asyncActions.reduce(e.locatorHash,async n=>{await oe.mkdirPromise(a,{recursive:!0});let u=await gDt(a),A=new Map(u),p=[n],h=(I,v)=>{let x=v;TBe(v,{project:this.opts.project})||(this.opts.report.reportWarningOnce(0,"The pnpm linker doesn't support providing different versions to workspaces' peer dependencies"),x=G.devirtualizeLocator(v));let C=this.customData.pathsByLocator.get(x.locatorHash);if(typeof C>"u")throw new Error(`Assertion failed: Expected the package to have been registered (${G.stringifyLocator(v)})`);let R=G.stringifyIdent(I),L=V.join(a,R),U=V.relative(V.dirname(L),C.packageLocation),z=A.get(R);A.delete(R),p.push(Promise.resolve().then(async()=>{if(z){if(z.isSymbolicLink()&&await oe.readlinkPromise(L)===U)return;await oe.removePromise(L)}await oe.mkdirpPromise(V.dirname(L)),process.platform=="win32"&&this.opts.project.configuration.get("winLinkType")==="junctions"?await oe.symlinkPromise(C.packageLocation,L,"junction"):await oe.symlinkPromise(U,L)}))},E=!1;for(let[I,v]of r)I.identHash===e.identHash&&(E=!0),h(I,v);!E&&!this.opts.project.tryWorkspaceByLocator(e)&&h(G.convertLocatorToDescriptor(e),e),p.push(dDt(a,A)),await Promise.all(p)})}async attachExternalDependents(e,r){throw new Error("External dependencies haven't been implemented for the pnpm linker")}async finalizeInstall(){let e=LBe(this.opts.project);if(this.opts.project.configuration.get("nodeLinker")!=="pnpm")await oe.removePromise(e);else{let r;try{r=new Set(await oe.readdirPromise(e))}catch{r=new Set}for(let{dependenciesLocation:o}of this.customData.pathsByLocator.values()){if(!o)continue;let a=V.contains(e,o);if(a===null)continue;let[n]=a.split(V.sep);r.delete(n)}await Promise.all([...r].map(async o=>{await oe.removePromise(V.join(e,o))}))}return await this.asyncActions.wait(),await k5(e),this.opts.project.configuration.get("nodeLinker")!=="node-modules"&&await k5(NBe(this.opts.project)),{customData:this.customData}}};function NBe(t){return V.join(t.cwd,dr.nodeModules)}function LBe(t){return V.join(NBe(t),".store")}function hDt(t,{project:e}){let r=G.slugifyLocator(t),o=LBe(e),a=V.join(o,r,"package"),n=V.join(o,r,dr.nodeModules);return{packageLocation:a,dependenciesLocation:n}}function TBe(t,{project:e}){return!G.isVirtualLocator(t)||!e.tryWorkspaceByLocator(t)}async function gDt(t){let e=new Map,r=[];try{r=await oe.readdirPromise(t,{withFileTypes:!0})}catch(o){if(o.code!=="ENOENT")throw o}try{for(let o of r)if(!o.name.startsWith("."))if(o.name.startsWith("@")){let a=await oe.readdirPromise(V.join(t,o.name),{withFileTypes:!0});if(a.length===0)e.set(o.name,o);else for(let n of a)e.set(`${o.name}/${n.name}`,n)}else e.set(o.name,o)}catch(o){if(o.code!=="ENOENT")throw o}return e}async function dDt(t,e){let r=[],o=new Set;for(let a of e.keys()){r.push(oe.removePromise(V.join(t,a)));let n=G.tryParseIdent(a)?.scope;n&&o.add(`@${n}`)}return Promise.all(r).then(()=>Promise.all([...o].map(a=>k5(V.join(t,a)))))}async function k5(t){try{await oe.rmdirPromise(t)}catch(e){if(e.code!=="ENOENT"&&e.code!=="ENOTEMPTY")throw e}}var mDt={linkers:[vv]},yDt=mDt;var O5={};Vt(O5,{StageCommand:()=>GC,default:()=>xDt,stageUtils:()=>zQ});Ge();Pt();qt();Ge();Pt();var zQ={};Vt(zQ,{ActionType:()=>F5,checkConsensus:()=>VQ,expandDirectory:()=>N5,findConsensus:()=>L5,findVcsRoot:()=>R5,genCommitMessage:()=>M5,getCommitPrefix:()=>MBe,isYarnFile:()=>T5});Pt();var F5=(n=>(n[n.CREATE=0]="CREATE",n[n.DELETE=1]="DELETE",n[n.ADD=2]="ADD",n[n.REMOVE=3]="REMOVE",n[n.MODIFY=4]="MODIFY",n))(F5||{});async function R5(t,{marker:e}){do if(!oe.existsSync(V.join(t,e)))t=V.dirname(t);else return t;while(t!=="/");return null}function T5(t,{roots:e,names:r}){if(r.has(V.basename(t)))return!0;do if(!e.has(t))t=V.dirname(t);else return!0;while(t!=="/");return!1}function N5(t){let e=[],r=[t];for(;r.length>0;){let o=r.pop(),a=oe.readdirSync(o);for(let n of a){let u=V.resolve(o,n);oe.lstatSync(u).isDirectory()?r.push(u):e.push(u)}}return e}function VQ(t,e){let r=0,o=0;for(let a of t)a!=="wip"&&(e.test(a)?r+=1:o+=1);return r>=o}function L5(t){let e=VQ(t,/^(\w\(\w+\):\s*)?\w+s/),r=VQ(t,/^(\w\(\w+\):\s*)?[A-Z]/),o=VQ(t,/^\w\(\w+\):/);return{useThirdPerson:e,useUpperCase:r,useComponent:o}}function MBe(t){return t.useComponent?"chore(yarn): ":""}var EDt=new Map([[0,"create"],[1,"delete"],[2,"add"],[3,"remove"],[4,"update"]]);function M5(t,e){let r=MBe(t),o=[],a=e.slice().sort((n,u)=>n[0]-u[0]);for(;a.length>0;){let[n,u]=a.shift(),A=EDt.get(n);t.useUpperCase&&o.length===0&&(A=`${A[0].toUpperCase()}${A.slice(1)}`),t.useThirdPerson&&(A+="s");let p=[u];for(;a.length>0&&a[0][0]===n;){let[,E]=a.shift();p.push(E)}p.sort();let h=p.shift();p.length===1?h+=" (and one other)":p.length>1&&(h+=` (and ${p.length} others)`),o.push(`${A} ${h}`)}return`${r}${o.join(", ")}`}var CDt="Commit generated via `yarn stage`",wDt=11;async function OBe(t){let{code:e,stdout:r}=await Ur.execvp("git",["log","-1","--pretty=format:%H"],{cwd:t});return e===0?r.trim():null}async function IDt(t,e){let r=[],o=e.filter(h=>V.basename(h.path)==="package.json");for(let{action:h,path:E}of o){let I=V.relative(t,E);if(h===4){let v=await OBe(t),{stdout:x}=await Ur.execvp("git",["show",`${v}:${I}`],{cwd:t,strict:!0}),C=await Ut.fromText(x),R=await Ut.fromFile(E),L=new Map([...R.dependencies,...R.devDependencies]),U=new Map([...C.dependencies,...C.devDependencies]);for(let[z,te]of U){let ae=G.stringifyIdent(te),le=L.get(z);le?le.range!==te.range&&r.push([4,`${ae} to ${le.range}`]):r.push([3,ae])}for(let[z,te]of L)U.has(z)||r.push([2,G.stringifyIdent(te)])}else if(h===0){let v=await Ut.fromFile(E);v.name?r.push([0,G.stringifyIdent(v.name)]):r.push([0,"a package"])}else if(h===1){let v=await OBe(t),{stdout:x}=await Ur.execvp("git",["show",`${v}:${I}`],{cwd:t,strict:!0}),C=await Ut.fromText(x);C.name?r.push([1,G.stringifyIdent(C.name)]):r.push([1,"a package"])}else throw new Error("Assertion failed: Unsupported action type")}let{code:a,stdout:n}=await Ur.execvp("git",["log",`-${wDt}`,"--pretty=format:%s"],{cwd:t}),u=a===0?n.split(/\n/g).filter(h=>h!==""):[],A=L5(u);return M5(A,r)}var BDt={0:[" A ","?? "],4:[" M "],1:[" D "]},vDt={0:["A "],4:["M "],1:["D "]},UBe={async findRoot(t){return await R5(t,{marker:".git"})},async filterChanges(t,e,r,o){let{stdout:a}=await Ur.execvp("git",["status","-s"],{cwd:t,strict:!0}),n=a.toString().split(/\n/g),u=o?.staged?vDt:BDt;return[].concat(...n.map(p=>{if(p==="")return[];let h=p.slice(0,3),E=V.resolve(t,p.slice(3));if(!o?.staged&&h==="?? "&&p.endsWith("/"))return N5(E).map(I=>({action:0,path:I}));{let v=[0,4,1].find(x=>u[x].includes(h));return v!==void 0?[{action:v,path:E}]:[]}})).filter(p=>T5(p.path,{roots:e,names:r}))},async genCommitMessage(t,e){return await IDt(t,e)},async makeStage(t,e){let r=e.map(o=>ue.fromPortablePath(o.path));await Ur.execvp("git",["add","--",...r],{cwd:t,strict:!0})},async makeCommit(t,e,r){let o=e.map(a=>ue.fromPortablePath(a.path));await Ur.execvp("git",["add","-N","--",...o],{cwd:t,strict:!0}),await Ur.execvp("git",["commit","-m",`${r} + +${CDt} +`,"--",...o],{cwd:t,strict:!0})},async makeReset(t,e){let r=e.map(o=>ue.fromPortablePath(o.path));await Ur.execvp("git",["reset","HEAD","--",...r],{cwd:t,strict:!0})}};var DDt=[UBe],GC=class extends ut{constructor(){super(...arguments);this.commit=ge.Boolean("-c,--commit",!1,{description:"Commit the staged files"});this.reset=ge.Boolean("-r,--reset",!1,{description:"Remove all files from the staging area"});this.dryRun=ge.Boolean("-n,--dry-run",!1,{description:"Print the commit message and the list of modified files without staging / committing"});this.update=ge.Boolean("-u,--update",!1,{hidden:!0})}static{this.paths=[["stage"]]}static{this.usage=it.Usage({description:"add all yarn files to your vcs",details:"\n This command will add to your staging area the files belonging to Yarn (typically any modified `package.json` and `.yarnrc.yml` files, but also linker-generated files, cache data, etc). It will take your ignore list into account, so the cache files won't be added if the cache is ignored in a `.gitignore` file (assuming you use Git).\n\n Running `--reset` will instead remove them from the staging area (the changes will still be there, but won't be committed until you stage them back).\n\n Since the staging area is a non-existent concept in Mercurial, Yarn will always create a new commit when running this command on Mercurial repositories. You can get this behavior when using Git by using the `--commit` flag which will directly create a commit.\n ",examples:[["Adds all modified project files to the staging area","yarn stage"],["Creates a new commit containing all modified project files","yarn stage --commit"]]})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins),{project:o}=await kt.find(r,this.context.cwd),{driver:a,root:n}=await PDt(o.cwd),u=[r.get("cacheFolder"),r.get("globalFolder"),r.get("virtualFolder"),r.get("yarnPath")];await r.triggerHook(I=>I.populateYarnPaths,o,I=>{u.push(I)});let A=new Set;for(let I of u)for(let v of bDt(n,I))A.add(v);let p=new Set([r.get("rcFilename"),dr.lockfile,dr.manifest]),h=await a.filterChanges(n,A,p),E=await a.genCommitMessage(n,h);if(this.dryRun)if(this.commit)this.context.stdout.write(`${E} +`);else for(let I of h)this.context.stdout.write(`${ue.fromPortablePath(I.path)} +`);else if(this.reset){let I=await a.filterChanges(n,A,p,{staged:!0});I.length===0?this.context.stdout.write("No staged changes found!"):await a.makeReset(n,I)}else h.length===0?this.context.stdout.write("No changes found!"):this.commit?await a.makeCommit(n,h,E):(await a.makeStage(n,h),this.context.stdout.write(E))}};async function PDt(t){let e=null,r=null;for(let o of DDt)if((r=await o.findRoot(t))!==null){e=o;break}if(e===null||r===null)throw new st("No stage driver has been found for your current project");return{driver:e,root:r}}function bDt(t,e){let r=[];if(e===null)return r;for(;;){(e===t||e.startsWith(`${t}/`))&&r.push(e);let o;try{o=oe.statSync(e)}catch{break}if(o.isSymbolicLink())e=V.resolve(V.dirname(e),oe.readlinkSync(e));else break}return r}var SDt={commands:[GC]},xDt=SDt;var U5={};Vt(U5,{default:()=>MDt});Ge();Ge();Pt();var qBe=Ze(Jn());Ge();var _Be=Ze(YH()),kDt="e8e1bd300d860104bb8c58453ffa1eb4",QDt="OFCNCOG2CU",HBe=async(t,e)=>{let r=G.stringifyIdent(t),a=FDt(e).initIndex("npm-search");try{return(await a.getObject(r,{attributesToRetrieve:["types"]})).types?.ts==="definitely-typed"}catch{return!1}},FDt=t=>(0,_Be.default)(QDt,kDt,{requester:{async send(r){try{let o=await sn.request(r.url,r.data||null,{configuration:t,headers:r.headers});return{content:o.body,isTimedOut:!1,status:o.statusCode}}catch(o){return{content:o.response.body,isTimedOut:!1,status:o.response.statusCode}}}}});var jBe=t=>t.scope?`${t.scope}__${t.name}`:`${t.name}`,RDt=async(t,e,r,o)=>{if(r.scope==="types")return;let{project:a}=t,{configuration:n}=a;if(!(n.get("tsEnableAutoTypes")??(oe.existsSync(V.join(t.cwd,"tsconfig.json"))||oe.existsSync(V.join(a.cwd,"tsconfig.json")))))return;let A=n.makeResolver(),p={project:a,resolver:A,report:new ki};if(!await HBe(r,n))return;let E=jBe(r),I=G.parseRange(r.range).selector;if(!Lr.validRange(I)){let L=n.normalizeDependency(r),U=await A.getCandidates(L,{},p);I=G.parseRange(U[0].reference).selector}let v=qBe.default.coerce(I);if(v===null)return;let x=`${Zc.Modifier.CARET}${v.major}`,C=G.makeDescriptor(G.makeIdent("types",E),x),R=He.mapAndFind(a.workspaces,L=>{let U=L.manifest.dependencies.get(r.identHash)?.descriptorHash,z=L.manifest.devDependencies.get(r.identHash)?.descriptorHash;if(U!==r.descriptorHash&&z!==r.descriptorHash)return He.mapAndFind.skip;let te=[];for(let ae of Ut.allDependencies){let le=L.manifest[ae].get(C.identHash);typeof le>"u"||te.push([ae,le])}return te.length===0?He.mapAndFind.skip:te});if(typeof R<"u")for(let[L,U]of R)t.manifest[L].set(U.identHash,U);else{try{let L=n.normalizeDependency(C);if((await A.getCandidates(L,{},p)).length===0)return}catch{return}t.manifest[Zc.Target.DEVELOPMENT].set(C.identHash,C)}},TDt=async(t,e,r)=>{if(r.scope==="types")return;let{project:o}=t,{configuration:a}=o;if(!(a.get("tsEnableAutoTypes")??(oe.existsSync(V.join(t.cwd,"tsconfig.json"))||oe.existsSync(V.join(o.cwd,"tsconfig.json")))))return;let u=jBe(r),A=G.makeIdent("types",u);for(let p of Ut.allDependencies)typeof t.manifest[p].get(A.identHash)>"u"||t.manifest[p].delete(A.identHash)},NDt=(t,e)=>{e.publishConfig&&e.publishConfig.typings&&(e.typings=e.publishConfig.typings),e.publishConfig&&e.publishConfig.types&&(e.types=e.publishConfig.types)},LDt={configuration:{tsEnableAutoTypes:{description:"Whether Yarn should auto-install @types/ dependencies on 'yarn add'",type:"BOOLEAN",isNullable:!0,default:null}},hooks:{afterWorkspaceDependencyAddition:RDt,afterWorkspaceDependencyRemoval:TDt,beforeWorkspacePacking:NDt}},MDt=LDt;var G5={};Vt(G5,{VersionApplyCommand:()=>zC,VersionCheckCommand:()=>JC,VersionCommand:()=>XC,default:()=>rPt,versionUtils:()=>VC});Ge();Ge();qt();var VC={};Vt(VC,{Decision:()=>WC,applyPrerelease:()=>zBe,applyReleases:()=>j5,applyStrategy:()=>XQ,clearVersionFiles:()=>_5,getUndecidedDependentWorkspaces:()=>Pv,getUndecidedWorkspaces:()=>JQ,openVersionFile:()=>KC,requireMoreDecisions:()=>$Dt,resolveVersionFiles:()=>Dv,suggestStrategy:()=>q5,updateVersionFiles:()=>H5,validateReleaseDecision:()=>YC});Ge();Pt();Nl();qt();var VBe=Ze(KBe()),BA=Ze(Jn()),ZDt=/^(>=|[~^]|)(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(-(0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(\.(0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*)?(\+[0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*)?$/,WC=(u=>(u.UNDECIDED="undecided",u.DECLINE="decline",u.MAJOR="major",u.MINOR="minor",u.PATCH="patch",u.PRERELEASE="prerelease",u))(WC||{});function YC(t){let e=BA.default.valid(t);return e||He.validateEnum((0,VBe.default)(WC,"UNDECIDED"),t)}async function Dv(t,{prerelease:e=null}={}){let r=new Map,o=t.configuration.get("deferredVersionFolder");if(!oe.existsSync(o))return r;let a=await oe.readdirPromise(o);for(let n of a){if(!n.endsWith(".yml"))continue;let u=V.join(o,n),A=await oe.readFilePromise(u,"utf8"),p=Ki(A);for(let[h,E]of Object.entries(p.releases||{})){if(E==="decline")continue;let I=G.parseIdent(h),v=t.tryWorkspaceByIdent(I);if(v===null)throw new Error(`Assertion failed: Expected a release definition file to only reference existing workspaces (${V.basename(u)} references ${h})`);if(v.manifest.version===null)throw new Error(`Assertion failed: Expected the workspace to have a version (${G.prettyLocator(t.configuration,v.anchoredLocator)})`);let x=v.manifest.raw.stableVersion??v.manifest.version,C=r.get(v),R=XQ(x,YC(E));if(R===null)throw new Error(`Assertion failed: Expected ${x} to support being bumped via strategy ${E}`);let L=typeof C<"u"?BA.default.gt(R,C)?R:C:R;r.set(v,L)}}return e&&(r=new Map([...r].map(([n,u])=>[n,zBe(u,{current:n.manifest.version,prerelease:e})]))),r}async function _5(t){let e=t.configuration.get("deferredVersionFolder");oe.existsSync(e)&&await oe.removePromise(e)}async function H5(t,e){let r=new Set(e),o=t.configuration.get("deferredVersionFolder");if(!oe.existsSync(o))return;let a=await oe.readdirPromise(o);for(let n of a){if(!n.endsWith(".yml"))continue;let u=V.join(o,n),A=await oe.readFilePromise(u,"utf8"),p=Ki(A),h=p?.releases;if(h){for(let E of Object.keys(h)){let I=G.parseIdent(E),v=t.tryWorkspaceByIdent(I);(v===null||r.has(v))&&delete p.releases[E]}Object.keys(p.releases).length>0?await oe.changeFilePromise(u,Da(new Da.PreserveOrdering(p))):await oe.unlinkPromise(u)}}}async function KC(t,{allowEmpty:e=!1}={}){let r=t.configuration;if(r.projectCwd===null)throw new st("This command can only be run from within a Yarn project");let o=await ia.fetchRoot(r.projectCwd),a=o!==null?await ia.fetchBase(o,{baseRefs:r.get("changesetBaseRefs")}):null,n=o!==null?await ia.fetchChangedFiles(o,{base:a.hash,project:t}):[],u=r.get("deferredVersionFolder"),A=n.filter(x=>V.contains(u,x)!==null);if(A.length>1)throw new st(`Your current branch contains multiple versioning files; this isn't supported: +- ${A.map(x=>ue.fromPortablePath(x)).join(` +- `)}`);let p=new Set(He.mapAndFilter(n,x=>{let C=t.tryWorkspaceByFilePath(x);return C===null?He.mapAndFilter.skip:C}));if(A.length===0&&p.size===0&&!e)return null;let h=A.length===1?A[0]:V.join(u,`${wn.makeHash(Math.random().toString()).slice(0,8)}.yml`),E=oe.existsSync(h)?await oe.readFilePromise(h,"utf8"):"{}",I=Ki(E),v=new Map;for(let x of I.declined||[]){let C=G.parseIdent(x),R=t.getWorkspaceByIdent(C);v.set(R,"decline")}for(let[x,C]of Object.entries(I.releases||{})){let R=G.parseIdent(x),L=t.getWorkspaceByIdent(R);v.set(L,YC(C))}return{project:t,root:o,baseHash:a!==null?a.hash:null,baseTitle:a!==null?a.title:null,changedFiles:new Set(n),changedWorkspaces:p,releaseRoots:new Set([...p].filter(x=>x.manifest.version!==null)),releases:v,async saveAll(){let x={},C=[],R=[];for(let L of t.workspaces){if(L.manifest.version===null)continue;let U=G.stringifyIdent(L.anchoredLocator),z=v.get(L);z==="decline"?C.push(U):typeof z<"u"?x[U]=YC(z):p.has(L)&&R.push(U)}await oe.mkdirPromise(V.dirname(h),{recursive:!0}),await oe.changeFilePromise(h,Da(new Da.PreserveOrdering({releases:Object.keys(x).length>0?x:void 0,declined:C.length>0?C:void 0,undecided:R.length>0?R:void 0})))}}}function $Dt(t){return JQ(t).size>0||Pv(t).length>0}function JQ(t){let e=new Set;for(let r of t.changedWorkspaces)r.manifest.version!==null&&(t.releases.has(r)||e.add(r));return e}function Pv(t,{include:e=new Set}={}){let r=[],o=new Map(He.mapAndFilter([...t.releases],([n,u])=>u==="decline"?He.mapAndFilter.skip:[n.anchoredLocator.locatorHash,n])),a=new Map(He.mapAndFilter([...t.releases],([n,u])=>u!=="decline"?He.mapAndFilter.skip:[n.anchoredLocator.locatorHash,n]));for(let n of t.project.workspaces)if(!(!e.has(n)&&(a.has(n.anchoredLocator.locatorHash)||o.has(n.anchoredLocator.locatorHash)))&&n.manifest.version!==null)for(let u of Ut.hardDependencies)for(let A of n.manifest.getForScope(u).values()){let p=t.project.tryWorkspaceByDescriptor(A);p!==null&&o.has(p.anchoredLocator.locatorHash)&&r.push([n,p])}return r}function q5(t,e){let r=BA.default.clean(e);for(let o of Object.values(WC))if(o!=="undecided"&&o!=="decline"&&BA.default.inc(t,o)===r)return o;return null}function XQ(t,e){if(BA.default.valid(e))return e;if(t===null)throw new st(`Cannot apply the release strategy "${e}" unless the workspace already has a valid version`);if(!BA.default.valid(t))throw new st(`Cannot apply the release strategy "${e}" on a non-semver version (${t})`);let r=BA.default.inc(t,e);if(r===null)throw new st(`Cannot apply the release strategy "${e}" on the specified version (${t})`);return r}function j5(t,e,{report:r}){let o=new Map;for(let a of t.workspaces)for(let n of Ut.allDependencies)for(let u of a.manifest[n].values()){let A=t.tryWorkspaceByDescriptor(u);if(A===null||!e.has(A))continue;He.getArrayWithDefault(o,A).push([a,n,u.identHash])}for(let[a,n]of e){let u=a.manifest.version;a.manifest.version=n,BA.default.prerelease(n)===null?delete a.manifest.raw.stableVersion:a.manifest.raw.stableVersion||(a.manifest.raw.stableVersion=u);let A=a.manifest.name!==null?G.stringifyIdent(a.manifest.name):null;r.reportInfo(0,`${G.prettyLocator(t.configuration,a.anchoredLocator)}: Bumped to ${n}`),r.reportJson({cwd:ue.fromPortablePath(a.cwd),ident:A,oldVersion:u,newVersion:n});let p=o.get(a);if(!(typeof p>"u"))for(let[h,E,I]of p){let v=h.manifest[E].get(I);if(typeof v>"u")throw new Error("Assertion failed: The dependency should have existed");let x=v.range,C=!1;if(x.startsWith(ei.protocol)&&(x=x.slice(ei.protocol.length),C=!0,x===a.relativeCwd))continue;let R=x.match(ZDt);if(!R){r.reportWarning(0,`Couldn't auto-upgrade range ${x} (in ${G.prettyLocator(t.configuration,h.anchoredLocator)})`);continue}let L=`${R[1]}${n}`;C&&(L=`${ei.protocol}${L}`);let U=G.makeDescriptor(v,L);h.manifest[E].set(I,U)}}}var ePt=new Map([["%n",{extract:t=>t.length>=1?[t[0],t.slice(1)]:null,generate:(t=0)=>`${t+1}`}]]);function zBe(t,{current:e,prerelease:r}){let o=new BA.default.SemVer(e),a=o.prerelease.slice(),n=[];o.prerelease=[],o.format()!==t&&(a.length=0);let u=!0,A=r.split(/\./g);for(let p of A){let h=ePt.get(p);if(typeof h>"u")n.push(p),a[0]===p?a.shift():u=!1;else{let E=u?h.extract(a):null;E!==null&&typeof E[0]=="number"?(n.push(h.generate(E[0])),a=E[1]):(n.push(h.generate()),u=!1)}}return o.prerelease&&(o.prerelease=[]),`${t}-${n.join(".")}`}var zC=class extends ut{constructor(){super(...arguments);this.all=ge.Boolean("--all",!1,{description:"Apply the deferred version changes on all workspaces"});this.dryRun=ge.Boolean("--dry-run",!1,{description:"Print the versions without actually generating the package archive"});this.prerelease=ge.String("--prerelease",{description:"Add a prerelease identifier to new versions",tolerateBoolean:!0});this.recursive=ge.Boolean("-R,--recursive",{description:"Release the transitive workspaces as well"});this.json=ge.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"})}static{this.paths=[["version","apply"]]}static{this.usage=it.Usage({category:"Release-related commands",description:"apply all the deferred version bumps at once",details:` + This command will apply the deferred version changes and remove their definitions from the repository. + + Note that if \`--prerelease\` is set, the given prerelease identifier (by default \`rc.%n\`) will be used on all new versions and the version definitions will be kept as-is. + + By default only the current workspace will be bumped, but you can configure this behavior by using one of: + + - \`--recursive\` to also apply the version bump on its dependencies + - \`--all\` to apply the version bump on all packages in the repository + + Note that this command will also update the \`workspace:\` references across all your local workspaces, thus ensuring that they keep referring to the same workspaces even after the version bump. + `,examples:[["Apply the version change to the local workspace","yarn version apply"],["Apply the version change to all the workspaces in the local workspace","yarn version apply --all"]]})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await kt.find(r,this.context.cwd),n=await Gr.find(r);if(!a)throw new sr(o.cwd,this.context.cwd);await o.restoreInstallState({restoreResolutions:!1});let u=await Rt.start({configuration:r,json:this.json,stdout:this.context.stdout},async A=>{let p=this.prerelease?typeof this.prerelease!="boolean"?this.prerelease:"rc.%n":null,h=await Dv(o,{prerelease:p}),E=new Map;if(this.all)E=h;else{let I=this.recursive?a.getRecursiveWorkspaceDependencies():[a];for(let v of I){let x=h.get(v);typeof x<"u"&&E.set(v,x)}}if(E.size===0){let I=h.size>0?" Did you want to add --all?":"";A.reportWarning(0,`The current workspace doesn't seem to require a version bump.${I}`);return}j5(o,E,{report:A}),this.dryRun||(p||(this.all?await _5(o):await H5(o,[...E.keys()])),A.reportSeparator())});return this.dryRun||u.hasErrors()?u.exitCode():await o.installWithNewReport({json:this.json,stdout:this.context.stdout},{cache:n})}};Ge();Pt();qt();var ZQ=Ze(Jn());var JC=class extends ut{constructor(){super(...arguments);this.interactive=ge.Boolean("-i,--interactive",{description:"Open an interactive interface used to set version bumps"})}static{this.paths=[["version","check"]]}static{this.usage=it.Usage({category:"Release-related commands",description:"check that all the relevant packages have been bumped",details:"\n **Warning:** This command currently requires Git.\n\n This command will check that all the packages covered by the files listed in argument have been properly bumped or declined to bump.\n\n In the case of a bump, the check will also cover transitive packages - meaning that should `Foo` be bumped, a package `Bar` depending on `Foo` will require a decision as to whether `Bar` will need to be bumped. This check doesn't cross packages that have declined to bump.\n\n In case no arguments are passed to the function, the list of modified files will be generated by comparing the HEAD against `master`.\n ",examples:[["Check whether the modified packages need a bump","yarn version check"]]})}async execute(){return this.interactive?await this.executeInteractive():await this.executeStandard()}async executeInteractive(){GE(this.context);let{Gem:r}=await Promise.resolve().then(()=>(Zk(),Eq)),{ScrollableItems:o}=await Promise.resolve().then(()=>(rQ(),tQ)),{FocusRequest:a}=await Promise.resolve().then(()=>(wq(),$we)),{useListInput:n}=await Promise.resolve().then(()=>(eQ(),eIe)),{renderForm:u}=await Promise.resolve().then(()=>(oQ(),sQ)),{Box:A,Text:p}=await Promise.resolve().then(()=>Ze(ic())),{default:h,useCallback:E,useState:I}=await Promise.resolve().then(()=>Ze(an())),v=await Ke.find(this.context.cwd,this.context.plugins),{project:x,workspace:C}=await kt.find(v,this.context.cwd);if(!C)throw new sr(x.cwd,this.context.cwd);await x.restoreInstallState();let R=await KC(x);if(R===null||R.releaseRoots.size===0)return 0;if(R.root===null)throw new st("This command can only be run on Git repositories");let L=()=>h.createElement(A,{flexDirection:"row",paddingBottom:1},h.createElement(A,{flexDirection:"column",width:60},h.createElement(A,null,h.createElement(p,null,"Press ",h.createElement(p,{bold:!0,color:"cyanBright"},""),"/",h.createElement(p,{bold:!0,color:"cyanBright"},"")," to select workspaces.")),h.createElement(A,null,h.createElement(p,null,"Press ",h.createElement(p,{bold:!0,color:"cyanBright"},""),"/",h.createElement(p,{bold:!0,color:"cyanBright"},"")," to select release strategies."))),h.createElement(A,{flexDirection:"column"},h.createElement(A,{marginLeft:1},h.createElement(p,null,"Press ",h.createElement(p,{bold:!0,color:"cyanBright"},"")," to save.")),h.createElement(A,{marginLeft:1},h.createElement(p,null,"Press ",h.createElement(p,{bold:!0,color:"cyanBright"},"")," to abort.")))),U=({workspace:Ce,active:de,decision:Be,setDecision:Ee})=>{let g=Ce.manifest.raw.stableVersion??Ce.manifest.version;if(g===null)throw new Error(`Assertion failed: The version should have been set (${G.prettyLocator(v,Ce.anchoredLocator)})`);if(ZQ.default.prerelease(g)!==null)throw new Error(`Assertion failed: Prerelease identifiers shouldn't be found (${g})`);let me=["undecided","decline","patch","minor","major"];n(Be,me,{active:de,minus:"left",plus:"right",set:Ee});let we=Be==="undecided"?h.createElement(p,{color:"yellow"},g):Be==="decline"?h.createElement(p,{color:"green"},g):h.createElement(p,null,h.createElement(p,{color:"magenta"},g)," \u2192 ",h.createElement(p,{color:"green"},ZQ.default.valid(Be)?Be:ZQ.default.inc(g,Be)));return h.createElement(A,{flexDirection:"column"},h.createElement(A,null,h.createElement(p,null,G.prettyLocator(v,Ce.anchoredLocator)," - ",we)),h.createElement(A,null,me.map(Ae=>h.createElement(A,{key:Ae,paddingLeft:2},h.createElement(p,null,h.createElement(r,{active:Ae===Be})," ",Ae)))))},z=Ce=>{let de=new Set(R.releaseRoots),Be=new Map([...Ce].filter(([Ee])=>de.has(Ee)));for(;;){let Ee=Pv({project:R.project,releases:Be}),g=!1;if(Ee.length>0){for(let[me]of Ee)if(!de.has(me)){de.add(me),g=!0;let we=Ce.get(me);typeof we<"u"&&Be.set(me,we)}}if(!g)break}return{relevantWorkspaces:de,relevantReleases:Be}},te=()=>{let[Ce,de]=I(()=>new Map(R.releases)),Be=E((Ee,g)=>{let me=new Map(Ce);g!=="undecided"?me.set(Ee,g):me.delete(Ee);let{relevantReleases:we}=z(me);de(we)},[Ce,de]);return[Ce,Be]},ae=({workspaces:Ce,releases:de})=>{let Be=[];Be.push(`${Ce.size} total`);let Ee=0,g=0;for(let me of Ce){let we=de.get(me);typeof we>"u"?g+=1:we!=="decline"&&(Ee+=1)}return Be.push(`${Ee} release${Ee===1?"":"s"}`),Be.push(`${g} remaining`),h.createElement(p,{color:"yellow"},Be.join(", "))},ce=await u(({useSubmit:Ce})=>{let[de,Be]=te();Ce(de);let{relevantWorkspaces:Ee}=z(de),g=new Set([...Ee].filter(ne=>!R.releaseRoots.has(ne))),[me,we]=I(0),Ae=E(ne=>{switch(ne){case a.BEFORE:we(me-1);break;case a.AFTER:we(me+1);break}},[me,we]);return h.createElement(A,{flexDirection:"column"},h.createElement(L,null),h.createElement(A,null,h.createElement(p,{wrap:"wrap"},"The following files have been modified in your local checkout.")),h.createElement(A,{flexDirection:"column",marginTop:1,paddingLeft:2},[...R.changedFiles].map(ne=>h.createElement(A,{key:ne},h.createElement(p,null,h.createElement(p,{color:"grey"},ue.fromPortablePath(R.root)),ue.sep,ue.relative(ue.fromPortablePath(R.root),ue.fromPortablePath(ne)))))),R.releaseRoots.size>0&&h.createElement(h.Fragment,null,h.createElement(A,{marginTop:1},h.createElement(p,{wrap:"wrap"},"Because of those files having been modified, the following workspaces may need to be released again (note that private workspaces are also shown here, because even though they won't be published, releasing them will allow us to flag their dependents for potential re-release):")),g.size>3?h.createElement(A,{marginTop:1},h.createElement(ae,{workspaces:R.releaseRoots,releases:de})):null,h.createElement(A,{marginTop:1,flexDirection:"column"},h.createElement(o,{active:me%2===0,radius:1,size:2,onFocusRequest:Ae},[...R.releaseRoots].map(ne=>h.createElement(U,{key:ne.cwd,workspace:ne,decision:de.get(ne)||"undecided",setDecision:Z=>Be(ne,Z)}))))),g.size>0?h.createElement(h.Fragment,null,h.createElement(A,{marginTop:1},h.createElement(p,{wrap:"wrap"},"The following workspaces depend on other workspaces that have been marked for release, and thus may need to be released as well:")),h.createElement(A,null,h.createElement(p,null,"(Press ",h.createElement(p,{bold:!0,color:"cyanBright"},"")," to move the focus between the workspace groups.)")),g.size>5?h.createElement(A,{marginTop:1},h.createElement(ae,{workspaces:g,releases:de})):null,h.createElement(A,{marginTop:1,flexDirection:"column"},h.createElement(o,{active:me%2===1,radius:2,size:2,onFocusRequest:Ae},[...g].map(ne=>h.createElement(U,{key:ne.cwd,workspace:ne,decision:de.get(ne)||"undecided",setDecision:Z=>Be(ne,Z)}))))):null)},{versionFile:R},{stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr});if(typeof ce>"u")return 1;R.releases.clear();for(let[Ce,de]of ce)R.releases.set(Ce,de);await R.saveAll()}async executeStandard(){let r=await Ke.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await kt.find(r,this.context.cwd);if(!a)throw new sr(o.cwd,this.context.cwd);return await o.restoreInstallState(),(await Rt.start({configuration:r,stdout:this.context.stdout},async u=>{let A=await KC(o);if(A===null||A.releaseRoots.size===0)return;if(A.root===null)throw new st("This command can only be run on Git repositories");if(u.reportInfo(0,`Your PR was started right after ${pe.pretty(r,A.baseHash.slice(0,7),"yellow")} ${pe.pretty(r,A.baseTitle,"magenta")}`),A.changedFiles.size>0){u.reportInfo(0,"You have changed the following files since then:"),u.reportSeparator();for(let v of A.changedFiles)u.reportInfo(null,`${pe.pretty(r,ue.fromPortablePath(A.root),"gray")}${ue.sep}${ue.relative(ue.fromPortablePath(A.root),ue.fromPortablePath(v))}`)}let p=!1,h=!1,E=JQ(A);if(E.size>0){p||u.reportSeparator();for(let v of E)u.reportError(0,`${G.prettyLocator(r,v.anchoredLocator)} has been modified but doesn't have a release strategy attached`);p=!0}let I=Pv(A);for(let[v,x]of I)h||u.reportSeparator(),u.reportError(0,`${G.prettyLocator(r,v.anchoredLocator)} doesn't have a release strategy attached, but depends on ${G.prettyWorkspace(r,x)} which is planned for release.`),h=!0;(p||h)&&(u.reportSeparator(),u.reportInfo(0,"This command detected that at least some workspaces have received modifications without explicit instructions as to how they had to be released (if needed)."),u.reportInfo(0,"To correct these errors, run `yarn version check --interactive` then follow the instructions."))})).exitCode()}};Ge();qt();var $Q=Ze(Jn());var XC=class extends ut{constructor(){super(...arguments);this.deferred=ge.Boolean("-d,--deferred",{description:"Prepare the version to be bumped during the next release cycle"});this.immediate=ge.Boolean("-i,--immediate",{description:"Bump the version immediately"});this.strategy=ge.String()}static{this.paths=[["version"]]}static{this.usage=it.Usage({category:"Release-related commands",description:"apply a new version to the current package",details:"\n This command will bump the version number for the given package, following the specified strategy:\n\n - If `major`, the first number from the semver range will be increased (`X.0.0`).\n - If `minor`, the second number from the semver range will be increased (`0.X.0`).\n - If `patch`, the third number from the semver range will be increased (`0.0.X`).\n - If prefixed by `pre` (`premajor`, ...), a `-0` suffix will be set (`0.0.0-0`).\n - If `prerelease`, the suffix will be increased (`0.0.0-X`); the third number from the semver range will also be increased if there was no suffix in the previous version.\n - If `decline`, the nonce will be increased for `yarn version check` to pass without version bump.\n - If a valid semver range, it will be used as new version.\n - If unspecified, Yarn will ask you for guidance.\n\n For more information about the `--deferred` flag, consult our documentation (https://yarnpkg.com/features/release-workflow#deferred-versioning).\n ",examples:[["Immediately bump the version to the next major","yarn version major"],["Prepare the version to be bumped to the next major","yarn version major --deferred"]]})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await kt.find(r,this.context.cwd);if(!a)throw new sr(o.cwd,this.context.cwd);let n=r.get("preferDeferredVersions");this.deferred&&(n=!0),this.immediate&&(n=!1);let u=$Q.default.valid(this.strategy),A=this.strategy==="decline",p;if(u)if(a.manifest.version!==null){let E=q5(a.manifest.version,this.strategy);E!==null?p=E:p=this.strategy}else p=this.strategy;else{let E=a.manifest.version;if(!A){if(E===null)throw new st("Can't bump the version if there wasn't a version to begin with - use 0.0.0 as initial version then run the command again.");if(typeof E!="string"||!$Q.default.valid(E))throw new st(`Can't bump the version (${E}) if it's not valid semver`)}p=YC(this.strategy)}if(!n){let I=(await Dv(o)).get(a);if(typeof I<"u"&&p!=="decline"){let v=XQ(a.manifest.version,p);if($Q.default.lt(v,I))throw new st(`Can't bump the version to one that would be lower than the current deferred one (${I})`)}}let h=await KC(o,{allowEmpty:!0});return h.releases.set(a,p),await h.saveAll(),n?0:await this.cli.run(["version","apply"])}};var tPt={configuration:{deferredVersionFolder:{description:"Folder where are stored the versioning files",type:"ABSOLUTE_PATH",default:"./.yarn/versions"},preferDeferredVersions:{description:"If true, running `yarn version` will assume the `--deferred` flag unless `--immediate` is set",type:"BOOLEAN",default:!1}},commands:[zC,JC,XC]},rPt=tPt;var Y5={};Vt(Y5,{WorkspacesFocusCommand:()=>ZC,WorkspacesForeachCommand:()=>ew,default:()=>sPt});Ge();Ge();qt();var ZC=class extends ut{constructor(){super(...arguments);this.json=ge.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.production=ge.Boolean("--production",!1,{description:"Only install regular dependencies by omitting dev dependencies"});this.all=ge.Boolean("-A,--all",!1,{description:"Install the entire project"});this.workspaces=ge.Rest()}static{this.paths=[["workspaces","focus"]]}static{this.usage=it.Usage({category:"Workspace-related commands",description:"install a single workspace and its dependencies",details:"\n This command will run an install as if the specified workspaces (and all other workspaces they depend on) were the only ones in the project. If no workspaces are explicitly listed, the active one will be assumed.\n\n Note that this command is only very moderately useful when using zero-installs, since the cache will contain all the packages anyway - meaning that the only difference between a full install and a focused install would just be a few extra lines in the `.pnp.cjs` file, at the cost of introducing an extra complexity.\n\n If the `-A,--all` flag is set, the entire project will be installed. Combine with `--production` to replicate the old `yarn install --production`.\n "})}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await kt.find(r,this.context.cwd),n=await Gr.find(r);await o.restoreInstallState({restoreResolutions:!1});let u;if(this.all)u=new Set(o.workspaces);else if(this.workspaces.length===0){if(!a)throw new sr(o.cwd,this.context.cwd);u=new Set([a])}else u=new Set(this.workspaces.map(A=>o.getWorkspaceByIdent(G.parseIdent(A))));for(let A of u)for(let p of this.production?["dependencies"]:Ut.hardDependencies)for(let h of A.manifest.getForScope(p).values()){let E=o.tryWorkspaceByDescriptor(h);E!==null&&u.add(E)}for(let A of o.workspaces)u.has(A)?this.production&&A.manifest.devDependencies.clear():(A.manifest.installConfig=A.manifest.installConfig||{},A.manifest.installConfig.selfReferences=!1,A.manifest.dependencies.clear(),A.manifest.devDependencies.clear(),A.manifest.peerDependencies.clear(),A.manifest.scripts.clear());return await o.installWithNewReport({json:this.json,stdout:this.context.stdout},{cache:n,persistProject:!1})}};Ge();Ge();Ge();qt();var $C=Ze($o()),XBe=Ze(eg());el();var ew=class extends ut{constructor(){super(...arguments);this.from=ge.Array("--from",{description:"An array of glob pattern idents or paths from which to base any recursion"});this.all=ge.Boolean("-A,--all",{description:"Run the command on all workspaces of a project"});this.recursive=ge.Boolean("-R,--recursive",{description:"Run the command on the current workspace and all of its recursive dependencies"});this.worktree=ge.Boolean("-W,--worktree",{description:"Run the command on all workspaces of the current worktree"});this.verbose=ge.Counter("-v,--verbose",{description:"Increase level of logging verbosity up to 2 times"});this.parallel=ge.Boolean("-p,--parallel",!1,{description:"Run the commands in parallel"});this.interlaced=ge.Boolean("-i,--interlaced",!1,{description:"Print the output of commands in real-time instead of buffering it"});this.jobs=ge.String("-j,--jobs",{description:"The maximum number of parallel tasks that the execution will be limited to; or `unlimited`",validator:IT([Js(["unlimited"]),jw(wT(),[vT(),BT(1)])])});this.topological=ge.Boolean("-t,--topological",!1,{description:"Run the command after all workspaces it depends on (regular) have finished"});this.topologicalDev=ge.Boolean("--topological-dev",!1,{description:"Run the command after all workspaces it depends on (regular + dev) have finished"});this.include=ge.Array("--include",[],{description:"An array of glob pattern idents or paths; only matching workspaces will be traversed"});this.exclude=ge.Array("--exclude",[],{description:"An array of glob pattern idents or paths; matching workspaces won't be traversed"});this.publicOnly=ge.Boolean("--no-private",{description:"Avoid running the command on private workspaces"});this.since=ge.String("--since",{description:"Only include workspaces that have been changed since the specified ref.",tolerateBoolean:!0});this.dryRun=ge.Boolean("-n,--dry-run",{description:"Print the commands that would be run, without actually running them"});this.commandName=ge.String();this.args=ge.Proxy()}static{this.paths=[["workspaces","foreach"]]}static{this.usage=it.Usage({category:"Workspace-related commands",description:"run a command on all workspaces",details:"\n This command will run a given sub-command on current and all its descendant workspaces. Various flags can alter the exact behavior of the command:\n\n - If `-p,--parallel` is set, the commands will be ran in parallel; they'll by default be limited to a number of parallel tasks roughly equal to half your core number, but that can be overridden via `-j,--jobs`, or disabled by setting `-j unlimited`.\n\n - If `-p,--parallel` and `-i,--interlaced` are both set, Yarn will print the lines from the output as it receives them. If `-i,--interlaced` wasn't set, it would instead buffer the output from each process and print the resulting buffers only after their source processes have exited.\n\n - If `-t,--topological` is set, Yarn will only run the command after all workspaces that it depends on through the `dependencies` field have successfully finished executing. If `--topological-dev` is set, both the `dependencies` and `devDependencies` fields will be considered when figuring out the wait points.\n\n - If `-A,--all` is set, Yarn will run the command on all the workspaces of a project.\n\n - If `-R,--recursive` is set, Yarn will find workspaces to run the command on by recursively evaluating `dependencies` and `devDependencies` fields, instead of looking at the `workspaces` fields.\n\n - If `-W,--worktree` is set, Yarn will find workspaces to run the command on by looking at the current worktree.\n\n - If `--from` is set, Yarn will use the packages matching the 'from' glob as the starting point for any recursive search.\n\n - If `--since` is set, Yarn will only run the command on workspaces that have been modified since the specified ref. By default Yarn will use the refs specified by the `changesetBaseRefs` configuration option.\n\n - If `--dry-run` is set, Yarn will explain what it would do without actually doing anything.\n\n - The command may apply to only some workspaces through the use of `--include` which acts as a whitelist. The `--exclude` flag will do the opposite and will be a list of packages that mustn't execute the script. Both flags accept glob patterns (if valid Idents and supported by [micromatch](https://github.com/micromatch/micromatch)). Make sure to escape the patterns, to prevent your own shell from trying to expand them.\n\n The `-v,--verbose` flag can be passed up to twice: once to prefix output lines with the originating workspace's name, and again to include start/finish/timing log lines. Maximum verbosity is enabled by default in terminal environments.\n\n If the command is `run` and the script being run does not exist the child workspace will be skipped without error.\n ",examples:[["Publish all packages","yarn workspaces foreach -A npm publish --tolerate-republish"],["Run the build script on all descendant packages","yarn workspaces foreach -A run build"],["Run the build script on current and all descendant packages in parallel, building package dependencies first","yarn workspaces foreach -Apt run build"],["Run the build script on several packages and all their dependencies, building dependencies first","yarn workspaces foreach -Rpt --from '{workspace-a,workspace-b}' run build"]]})}static{this.schema=[Yw("all",Yu.Forbids,["from","recursive","since","worktree"],{missingIf:"undefined"}),DT(["all","recursive","since","worktree"],{missingIf:"undefined"})]}async execute(){let r=await Ke.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await kt.find(r,this.context.cwd);if(!this.all&&!a)throw new sr(o.cwd,this.context.cwd);await o.restoreInstallState();let n=this.cli.process([this.commandName,...this.args]),u=n.path.length===1&&n.path[0]==="run"&&typeof n.scriptName<"u"?n.scriptName:null;if(n.path.length===0)throw new st("Invalid subcommand name for iteration - use the 'run' keyword if you wish to execute a script");let A=Ee=>{this.dryRun&&this.context.stdout.write(`${Ee} +`)},p=()=>{let Ee=this.from.map(g=>$C.default.matcher(g));return o.workspaces.filter(g=>{let me=G.stringifyIdent(g.anchoredLocator),we=g.relativeCwd;return Ee.some(Ae=>Ae(me)||Ae(we))})},h=[];if(this.since?(A("Option --since is set; selecting the changed workspaces as root for workspace selection"),h=Array.from(await ia.fetchChangedWorkspaces({ref:this.since,project:o}))):this.from?(A("Option --from is set; selecting the specified workspaces"),h=[...p()]):this.worktree?(A("Option --worktree is set; selecting the current workspace"),h=[a]):this.recursive?(A("Option --recursive is set; selecting the current workspace"),h=[a]):this.all&&(A("Option --all is set; selecting all workspaces"),h=[...o.workspaces]),this.dryRun&&!this.all){for(let Ee of h)A(` +- ${Ee.relativeCwd} + ${G.prettyLocator(r,Ee.anchoredLocator)}`);h.length>0&&A("")}let E;if(this.recursive?this.since?(A("Option --recursive --since is set; recursively selecting all dependent workspaces"),E=new Set(h.map(Ee=>[...Ee.getRecursiveWorkspaceDependents()]).flat())):(A("Option --recursive is set; recursively selecting all transitive dependencies"),E=new Set(h.map(Ee=>[...Ee.getRecursiveWorkspaceDependencies()]).flat())):this.worktree?(A("Option --worktree is set; recursively selecting all nested workspaces"),E=new Set(h.map(Ee=>[...Ee.getRecursiveWorkspaceChildren()]).flat())):E=null,E!==null&&(h=[...new Set([...h,...E])],this.dryRun))for(let Ee of E)A(` +- ${Ee.relativeCwd} + ${G.prettyLocator(r,Ee.anchoredLocator)}`);let I=[],v=!1;if(u?.includes(":")){for(let Ee of o.workspaces)if(Ee.manifest.scripts.has(u)&&(v=!v,v===!1))break}for(let Ee of h){if(u&&!Ee.manifest.scripts.has(u)&&!v&&!(await An.getWorkspaceAccessibleBinaries(Ee)).has(u)){A(`Excluding ${Ee.relativeCwd} because it doesn't have a "${u}" script`);continue}if(!(u===r.env.npm_lifecycle_event&&Ee.cwd===a.cwd)){if(this.include.length>0&&!$C.default.isMatch(G.stringifyIdent(Ee.anchoredLocator),this.include)&&!$C.default.isMatch(Ee.relativeCwd,this.include)){A(`Excluding ${Ee.relativeCwd} because it doesn't match the --include filter`);continue}if(this.exclude.length>0&&($C.default.isMatch(G.stringifyIdent(Ee.anchoredLocator),this.exclude)||$C.default.isMatch(Ee.relativeCwd,this.exclude))){A(`Excluding ${Ee.relativeCwd} because it matches the --include filter`);continue}if(this.publicOnly&&Ee.manifest.private===!0){A(`Excluding ${Ee.relativeCwd} because it's a private workspace and --no-private was set`);continue}I.push(Ee)}}if(this.dryRun)return 0;let x=this.verbose??(this.context.stdout.isTTY?1/0:0),C=x>0,R=x>1,L=this.parallel?this.jobs==="unlimited"?1/0:Number(this.jobs)||Math.ceil(Xi.availableParallelism()/2):1,U=L===1?!1:this.parallel,z=U?this.interlaced:!0,te=(0,XBe.default)(L),ae=new Map,le=new Set,ce=0,Ce=null,de=!1,Be=await Rt.start({configuration:r,stdout:this.context.stdout,includePrefix:!1},async Ee=>{let g=async(me,{commandIndex:we})=>{if(de)return-1;!U&&R&&we>1&&Ee.reportSeparator();let Ae=nPt(me,{configuration:r,label:C,commandIndex:we}),[ne,Z]=JBe(Ee,{prefix:Ae,interlaced:z}),[xe,Ne]=JBe(Ee,{prefix:Ae,interlaced:z});try{R&&Ee.reportInfo(null,`${Ae?`${Ae} `:""}Process started`);let ht=Date.now(),H=await this.cli.run([this.commandName,...this.args],{cwd:me.cwd,stdout:ne,stderr:xe})||0;ne.end(),xe.end(),await Z,await Ne;let rt=Date.now();if(R){let Te=r.get("enableTimers")?`, completed in ${pe.pretty(r,rt-ht,pe.Type.DURATION)}`:"";Ee.reportInfo(null,`${Ae?`${Ae} `:""}Process exited (exit code ${H})${Te}`)}return H===130&&(de=!0,Ce=H),H}catch(ht){throw ne.end(),xe.end(),await Z,await Ne,ht}};for(let me of I)ae.set(me.anchoredLocator.locatorHash,me);for(;ae.size>0&&!Ee.hasErrors();){let me=[];for(let[ne,Z]of ae){if(le.has(Z.anchoredDescriptor.descriptorHash))continue;let xe=!0;if(this.topological||this.topologicalDev){let Ne=this.topologicalDev?new Map([...Z.manifest.dependencies,...Z.manifest.devDependencies]):Z.manifest.dependencies;for(let ht of Ne.values()){let H=o.tryWorkspaceByDescriptor(ht);if(xe=H===null||!ae.has(H.anchoredLocator.locatorHash),!xe)break}}if(xe&&(le.add(Z.anchoredDescriptor.descriptorHash),me.push(te(async()=>{let Ne=await g(Z,{commandIndex:++ce});return ae.delete(ne),le.delete(Z.anchoredDescriptor.descriptorHash),Ne})),!U))break}if(me.length===0){let ne=Array.from(ae.values()).map(Z=>G.prettyLocator(r,Z.anchoredLocator)).join(", ");Ee.reportError(3,`Dependency cycle detected (${ne})`);return}let Ae=(await Promise.all(me)).find(ne=>ne!==0);Ce===null&&(Ce=typeof Ae<"u"?1:Ce),(this.topological||this.topologicalDev)&&typeof Ae<"u"&&Ee.reportError(0,"The command failed for workspaces that are depended upon by other workspaces; can't satisfy the dependency graph")}});return Ce!==null?Ce:Be.exitCode()}};function JBe(t,{prefix:e,interlaced:r}){let o=t.createStreamReporter(e),a=new He.DefaultStream;a.pipe(o,{end:!1}),a.on("finish",()=>{o.end()});let n=new Promise(A=>{o.on("finish",()=>{A(a.active)})});if(r)return[a,n];let u=new He.BufferStream;return u.pipe(a,{end:!1}),u.on("finish",()=>{a.end()}),[u,n]}function nPt(t,{configuration:e,commandIndex:r,label:o}){if(!o)return null;let n=`[${G.stringifyIdent(t.anchoredLocator)}]:`,u=["#2E86AB","#A23B72","#F18F01","#C73E1D","#CCE2A3"],A=u[r%u.length];return pe.pretty(e,n,A)}var iPt={commands:[ZC,ew]},sPt=iPt;var Hy=()=>({modules:new Map([["@yarnpkg/cli",W1],["@yarnpkg/core",Y1],["@yarnpkg/fslib",kw],["@yarnpkg/libzip",p1],["@yarnpkg/parsers",Ow],["@yarnpkg/shell",E1],["clipanion",Jw],["semver",oPt],["typanion",Vo],["@yarnpkg/plugin-essentials",K8],["@yarnpkg/plugin-compat",Z8],["@yarnpkg/plugin-constraints",dH],["@yarnpkg/plugin-dlx",mH],["@yarnpkg/plugin-exec",CH],["@yarnpkg/plugin-file",IH],["@yarnpkg/plugin-git",W8],["@yarnpkg/plugin-github",DH],["@yarnpkg/plugin-http",PH],["@yarnpkg/plugin-init",bH],["@yarnpkg/plugin-interactive-tools",kq],["@yarnpkg/plugin-link",Qq],["@yarnpkg/plugin-nm",hj],["@yarnpkg/plugin-npm",f5],["@yarnpkg/plugin-npm-cli",w5],["@yarnpkg/plugin-pack",a5],["@yarnpkg/plugin-patch",S5],["@yarnpkg/plugin-pnp",rj],["@yarnpkg/plugin-pnpm",Q5],["@yarnpkg/plugin-stage",O5],["@yarnpkg/plugin-typescript",U5],["@yarnpkg/plugin-version",G5],["@yarnpkg/plugin-workspace-tools",Y5]]),plugins:new Set(["@yarnpkg/plugin-essentials","@yarnpkg/plugin-compat","@yarnpkg/plugin-constraints","@yarnpkg/plugin-dlx","@yarnpkg/plugin-exec","@yarnpkg/plugin-file","@yarnpkg/plugin-git","@yarnpkg/plugin-github","@yarnpkg/plugin-http","@yarnpkg/plugin-init","@yarnpkg/plugin-interactive-tools","@yarnpkg/plugin-link","@yarnpkg/plugin-nm","@yarnpkg/plugin-npm","@yarnpkg/plugin-npm-cli","@yarnpkg/plugin-pack","@yarnpkg/plugin-patch","@yarnpkg/plugin-pnp","@yarnpkg/plugin-pnpm","@yarnpkg/plugin-stage","@yarnpkg/plugin-typescript","@yarnpkg/plugin-version","@yarnpkg/plugin-workspace-tools"])});function eve({cwd:t,pluginConfiguration:e}){let r=new Jo({binaryLabel:"Yarn Package Manager",binaryName:"yarn",binaryVersion:nn??""});return Object.assign(r,{defaultContext:{...Jo.defaultContext,cwd:t,plugins:e,quiet:!1,stdin:process.stdin,stdout:process.stdout,stderr:process.stderr}})}function aPt(t){if(He.parseOptionalBoolean(process.env.YARN_IGNORE_NODE))return!0;let r=process.versions.node,o=">=18.12.0";if(Lr.satisfiesWithPrereleases(r,o))return!0;let a=new st(`This tool requires a Node version compatible with ${o} (got ${r}). Upgrade Node, or set \`YARN_IGNORE_NODE=1\` in your environment.`);return Jo.defaultContext.stdout.write(t.error(a)),!1}async function tve({selfPath:t,pluginConfiguration:e}){return await Ke.find(ue.toPortablePath(process.cwd()),e,{strict:!1,usePathCheck:t})}function lPt(t,e,{yarnPath:r}){if(!oe.existsSync(r))return t.error(new Error(`The "yarn-path" option has been set, but the specified location doesn't exist (${r}).`)),1;process.on("SIGINT",()=>{});let o={stdio:"inherit",env:{...process.env,YARN_IGNORE_PATH:"1"}};try{(0,ZBe.execFileSync)(process.execPath,[ue.fromPortablePath(r),...e],o)}catch(a){return a.status??1}return 0}function cPt(t,e){let r=null,o=e;return e.length>=2&&e[0]==="--cwd"?(r=ue.toPortablePath(e[1]),o=e.slice(2)):e.length>=1&&e[0].startsWith("--cwd=")?(r=ue.toPortablePath(e[0].slice(6)),o=e.slice(1)):e[0]==="add"&&e[e.length-2]==="--cwd"&&(r=ue.toPortablePath(e[e.length-1]),o=e.slice(0,e.length-2)),t.defaultContext.cwd=r!==null?V.resolve(r):V.cwd(),o}function uPt(t,{configuration:e}){if(!e.get("enableTelemetry")||$Be.isCI||!process.stdout.isTTY)return;Ke.telemetry=new Oy(e,"puba9cdc10ec5790a2cf4969dd413a47270");let o=/^@yarnpkg\/plugin-(.*)$/;for(let a of e.plugins.keys())Uy.has(a.match(o)?.[1]??"")&&Ke.telemetry?.reportPluginName(a);t.binaryVersion&&Ke.telemetry.reportVersion(t.binaryVersion)}function rve(t,{configuration:e}){for(let r of e.plugins.values())for(let o of r.commands||[])t.register(o)}async function APt(t,e,{selfPath:r,pluginConfiguration:o}){if(!aPt(t))return 1;let a=await tve({selfPath:r,pluginConfiguration:o}),n=a.get("yarnPath"),u=a.get("ignorePath");if(n&&!u)return lPt(t,e,{yarnPath:n});delete process.env.YARN_IGNORE_PATH;let A=cPt(t,e);uPt(t,{configuration:a}),rve(t,{configuration:a});let p=t.process(A,t.defaultContext);return p.help||Ke.telemetry?.reportCommandName(p.path.join(" ")),await t.run(p,t.defaultContext)}async function ihe({cwd:t=V.cwd(),pluginConfiguration:e=Hy()}={}){let r=eve({cwd:t,pluginConfiguration:e}),o=await tve({pluginConfiguration:e,selfPath:null});return rve(r,{configuration:o}),r}async function Wx(t,{cwd:e=V.cwd(),selfPath:r,pluginConfiguration:o}){let a=eve({cwd:e,pluginConfiguration:o});function n(){Jo.defaultContext.stdout.write(`ERROR: Yarn is terminating due to an unexpected empty event loop. +Please report this issue at https://github.com/yarnpkg/berry/issues.`)}process.once("beforeExit",n);try{process.exitCode=42,process.exitCode=await APt(a,t,{selfPath:r,pluginConfiguration:o})}catch(u){Jo.defaultContext.stdout.write(a.error(u)),process.exitCode=1}finally{process.off("beforeExit",n),await oe.rmtempPromise()}}Wx(process.argv.slice(2),{cwd:V.cwd(),selfPath:ue.toPortablePath(ue.resolve(process.argv[1])),pluginConfiguration:Hy()});})(); +/** + @license + Copyright (c) 2015, Rebecca Turner + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + */ +/** + @license + Copyright Node.js contributors. All rights reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. +*/ +/** + @license + The MIT License (MIT) + + Copyright (c) 2014 Blake Embrey (hello@blakeembrey.com) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ +/** + @license + Copyright Joyent, Inc. and other Node contributors. + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to permit + persons to whom the Software is furnished to do so, subject to the + following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +/*! Bundled license information: + +is-number/index.js: + (*! + * is-number + * + * Copyright (c) 2014-present, Jon Schlinkert. + * Released under the MIT License. + *) + +to-regex-range/index.js: + (*! + * to-regex-range + * + * Copyright (c) 2015-present, Jon Schlinkert. + * Released under the MIT License. + *) + +fill-range/index.js: + (*! + * fill-range + * + * Copyright (c) 2014-present, Jon Schlinkert. + * Licensed under the MIT License. + *) + +is-extglob/index.js: + (*! + * is-extglob + * + * Copyright (c) 2014-2016, Jon Schlinkert. + * Licensed under the MIT License. + *) + +is-glob/index.js: + (*! + * is-glob + * + * Copyright (c) 2014-2017, Jon Schlinkert. + * Released under the MIT License. + *) + +queue-microtask/index.js: + (*! queue-microtask. MIT License. Feross Aboukhadijeh *) + +run-parallel/index.js: + (*! run-parallel. MIT License. Feross Aboukhadijeh *) + +git-url-parse/lib/index.js: + (*! + * buildToken + * Builds OAuth token prefix (helper function) + * + * @name buildToken + * @function + * @param {GitUrl} obj The parsed Git url object. + * @return {String} token prefix + *) + +object-assign/index.js: + (* + object-assign + (c) Sindre Sorhus + @license MIT + *) + +react/cjs/react.production.min.js: + (** @license React v16.13.1 + * react.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + *) + +scheduler/cjs/scheduler.production.min.js: + (** @license React v0.18.0 + * scheduler.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + *) + +react-reconciler/cjs/react-reconciler.production.min.js: + (** @license React v0.24.0 + * react-reconciler.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + *) + +is-windows/index.js: + (*! + * is-windows + * + * Copyright © 2015-2018, Jon Schlinkert. + * Released under the MIT License. + *) +*/ diff --git a/packages/create-app/templates/default-app/.yarnrc.yml.hbs b/packages/create-app/templates/default-app/.yarnrc.yml.hbs new file mode 100644 index 0000000000..48f4a8f82b --- /dev/null +++ b/packages/create-app/templates/default-app/.yarnrc.yml.hbs @@ -0,0 +1,3 @@ +nodeLinker: node-modules + +yarnPath: .yarn/releases/yarn-4.4.1.cjs diff --git a/packages/create-app/templates/default-app/lerna.json b/packages/create-app/templates/default-app/lerna.json deleted file mode 100644 index 529a62fe38..0000000000 --- a/packages/create-app/templates/default-app/lerna.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "packages": ["packages/*", "plugins/*"], - "npmClient": "yarn", - "version": "0.1.0", - "$schema": "node_modules/lerna/schemas/lerna-schema.json" -} diff --git a/packages/create-app/templates/default-app/package.json.hbs b/packages/create-app/templates/default-app/package.json.hbs index 7841b5d4e6..7a42fed3f8 100644 --- a/packages/create-app/templates/default-app/package.json.hbs +++ b/packages/create-app/templates/default-app/package.json.hbs @@ -6,7 +6,7 @@ "node": "18 || 20" }, "scripts": { - "dev": "concurrently \"yarn start\" \"yarn start-backend\"", + "dev": "yarn workspaces foreach -A --include backend --include app --parallel -v -i run start", "start": "yarn workspace app start", "start-backend": "yarn workspace backend start", "build:backend": "yarn workspace backend build", @@ -35,8 +35,6 @@ "@backstage/e2e-test-utils": "^{{version '@backstage/e2e-test-utils'}}", "@playwright/test": "^1.32.3", "@spotify/prettier-config": "^12.0.0", - "concurrently": "^8.0.0", - "lerna": "^7.3.0", "node-gyp": "^10.0.0", "prettier": "^2.3.2", "typescript": "~5.4.0" @@ -54,5 +52,6 @@ "*.{json,md}": [ "prettier --write" ] - } + }, + "packageManager": "yarn@4.4.1" } diff --git a/packages/create-app/templates/default-app/packages/app/package.json.hbs b/packages/create-app/templates/default-app/packages/app/package.json.hbs index 08a1d58362..0601a3a4e3 100644 --- a/packages/create-app/templates/default-app/packages/app/package.json.hbs +++ b/packages/create-app/templates/default-app/packages/app/package.json.hbs @@ -50,10 +50,10 @@ "devDependencies": { "@backstage/test-utils": "^{{version '@backstage/test-utils'}}", "@playwright/test": "^1.32.3", + "@testing-library/dom": "^9.0.0", "@testing-library/jest-dom": "^6.0.0", "@testing-library/react": "^14.0.0", "@testing-library/user-event": "^14.0.0", - "@testing-library/dom": "^9.0.0", "@types/react-dom": "*", "cross-env": "^7.0.0" }, diff --git a/packages/create-app/templates/default-app/packages/backend/Dockerfile b/packages/create-app/templates/default-app/packages/backend/Dockerfile index 22fe721379..09024eb44f 100644 --- a/packages/create-app/templates/default-app/packages/backend/Dockerfile +++ b/packages/create-app/templates/default-app/packages/backend/Dockerfile @@ -3,27 +3,31 @@ # # Before building this image, be sure to have run the following commands in the repo root: # -# yarn install +# yarn install --immutable # yarn tsc # yarn build:backend # # Once the commands have been run, you can build the image using `yarn build-image` -FROM node:18-bookworm-slim +FROM node:20-bookworm-slim + +# Set Python interpreter for `node-gyp` to use +ENV PYTHON=/usr/bin/python3 # Install isolate-vm dependencies, these are needed by the @backstage/plugin-scaffolder-backend. RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ --mount=type=cache,target=/var/lib/apt,sharing=locked \ apt-get update && \ apt-get install -y --no-install-recommends python3 g++ build-essential && \ - yarn config set python /usr/bin/python3 + rm -rf /var/lib/apt/lists/* # Install sqlite3 dependencies. You can skip this if you don't use sqlite3 in the image, # in which case you should also move better-sqlite3 to "devDependencies" in package.json. RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ --mount=type=cache,target=/var/lib/apt,sharing=locked \ apt-get update && \ - apt-get install -y --no-install-recommends libsqlite3-dev + apt-get install -y --no-install-recommends libsqlite3-dev && \ + rm -rf /var/lib/apt/lists/* # From here on we use the least-privileged `node` user to run the backend. USER node @@ -33,9 +37,16 @@ USER node # If this occurs, then ensure BuildKit is enabled (`DOCKER_BUILDKIT=1`) so the app dir is correctly created as `node`. WORKDIR /app +# Copy files needed by Yarn +COPY --chown=node:node .yarn ./.yarn +COPY --chown=node:node .yarnrc.yml ./ + # This switches many Node.js dependencies to production mode. ENV NODE_ENV=production +# This disables node snapshot for Node 20 to work with the Scaffolder +ENV NODE_OPTIONS "--no-node-snapshot" + # Copy repo skeleton first, to avoid unnecessary docker cache invalidation. # The skeleton contains the package.json of each package in the monorepo, # and along with yarn.lock and the root package.json, that's enough to run yarn install. @@ -43,7 +54,7 @@ COPY --chown=node:node yarn.lock package.json packages/backend/dist/skeleton.tar RUN tar xzf skeleton.tar.gz && rm skeleton.tar.gz RUN --mount=type=cache,target=/home/node/.cache/yarn,sharing=locked,uid=1000,gid=1000 \ - yarn install --frozen-lockfile --production --network-timeout 300000 + yarn workspaces focus --all --production && rm -rf "$(yarn cache clean)" # This will include the examples, if you don't need these simply remove this line COPY --chown=node:node examples ./examples diff --git a/packages/dev-utils/CHANGELOG.md b/packages/dev-utils/CHANGELOG.md index e71ef37738..a3e03f6663 100644 --- a/packages/dev-utils/CHANGELOG.md +++ b/packages/dev-utils/CHANGELOG.md @@ -1,5 +1,72 @@ # @backstage/dev-utils +## 1.1.2-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/integration-react@1.2.0-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/app-defaults@1.5.12-next.1 + - @backstage/core-app-api@1.15.1-next.1 + - @backstage/plugin-catalog-react@1.14.0-next.1 + - @backstage/theme@0.5.8-next.0 + - @backstage/catalog-model@1.7.0 + +## 1.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/app-defaults@1.5.12-next.0 + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/plugin-catalog-react@1.13.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/core-app-api@1.15.1-next.0 + - @backstage/integration-react@1.1.32-next.0 + - @backstage/theme@0.5.7 + +## 1.1.0 + +### Minor Changes + +- 10b1452: Allow using translations in `createDevApp` + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/plugin-catalog-react@1.13.0 + - @backstage/core-app-api@1.15.0 + - @backstage/integration-react@1.1.31 + - @backstage/catalog-model@1.7.0 + - @backstage/app-defaults@1.5.11 + - @backstage/core-plugin-api@1.9.4 + - @backstage/theme@0.5.7 + +## 1.1.0-next.2 + +### Minor Changes + +- 10b1452: Allow using translations in `createDevApp` + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/plugin-catalog-react@1.13.0-next.2 + - @backstage/core-app-api@1.14.3-next.0 + - @backstage/integration-react@1.1.31-next.0 + - @backstage/app-defaults@1.5.11-next.1 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/theme@0.5.7-next.0 + - @backstage/catalog-model@1.6.0 + ## 1.0.38-next.1 ### Patch Changes diff --git a/packages/dev-utils/package.json b/packages/dev-utils/package.json index 71a4de45ca..9952f72f4d 100644 --- a/packages/dev-utils/package.json +++ b/packages/dev-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/dev-utils", - "version": "1.0.38-next.1", + "version": "1.1.2-next.1", "description": "Utilities for developing Backstage plugins.", "backstage": { "role": "web-library" @@ -46,7 +46,6 @@ "@backstage/theme": "workspace:^", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-use": "^17.2.4" }, "devDependencies": { @@ -54,13 +53,23 @@ "@backstage/test-utils": "workspace:^", "@testing-library/dom": "^10.0.0", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^15.0.0", + "@testing-library/react": "^16.0.0", "@testing-library/user-event": "^14.0.0", + "@types/react": "^18.0.0", + "react": "^18.0.2", + "react-dom": "^18.0.2", + "react-router-dom": "^6.3.0", "zen-observable": "^0.10.0" }, "peerDependencies": { + "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } } diff --git a/packages/dev-utils/api-report.md b/packages/dev-utils/report.api.md similarity index 71% rename from packages/dev-utils/api-report.md rename to packages/dev-utils/report.api.md index 0a5b3d10e8..18da50026e 100644 --- a/packages/dev-utils/api-report.md +++ b/packages/dev-utils/report.api.md @@ -16,6 +16,7 @@ import { PropsWithChildren } from 'react'; import { default as React_2 } from 'react'; import { ReactNode } from 'react'; import { SignInProviderConfig } from '@backstage/core-components'; +import { TranslationResource } from '@backstage/core-plugin-api/alpha'; // @public export function createDevApp(): DevAppBuilder; @@ -27,6 +28,7 @@ export class DevAppBuilder { addSidebarItem(sidebarItem: JSX.Element): DevAppBuilder; addSignInProvider(provider: SignInProviderConfig): this; addThemes(themes: AppTheme[]): this; + addTranslationResource(resource: TranslationResource): this; build(): ComponentType>; registerApi< Api, @@ -37,6 +39,8 @@ export class DevAppBuilder { >(factory: ApiFactory): DevAppBuilder; registerPlugin(...plugins: BackstagePlugin[]): DevAppBuilder; render(): void; + setAvailableLanguages(languages: string[]): this; + setDefaultLanguage(language: string): this; } // @public (undocumented) @@ -55,9 +59,18 @@ export const EntityGridItem: ( }, ) => JSX.Element; +// @public (undocumented) +export const SidebarLanguageSwitcher: () => React_2.JSX.Element | null; + // @public export const SidebarSignOutButton: (props: { icon?: IconComponent; text?: string; }) => React_2.JSX.Element; + +// Warnings were encountered during analysis: +// +// src/components/EntityGridItem/EntityGridItem.d.ts:5:22 - (ae-undocumented) Missing documentation for "EntityGridItem". +// src/components/SidebarLanguageSwitcher/SidebarLanguageSwitcher.d.ts:3:22 - (ae-undocumented) Missing documentation for "SidebarLanguageSwitcher". +// src/devApp/render.d.ts:8:1 - (ae-undocumented) Missing documentation for "DevAppPageOptions". ``` diff --git a/packages/dev-utils/src/components/SidebarLanguageSwitcher/SidebarLanguageSwitcher.test.tsx b/packages/dev-utils/src/components/SidebarLanguageSwitcher/SidebarLanguageSwitcher.test.tsx new file mode 100644 index 0000000000..fc620b846b --- /dev/null +++ b/packages/dev-utils/src/components/SidebarLanguageSwitcher/SidebarLanguageSwitcher.test.tsx @@ -0,0 +1,85 @@ +/* + * 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 { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; +import userEvent from '@testing-library/user-event'; +import React from 'react'; +import ObservableImpl from 'zen-observable'; +import { + AppLanguageApi, + appLanguageApiRef, +} from '@backstage/core-plugin-api/alpha'; +import { SidebarLanguageSwitcher } from './SidebarLanguageSwitcher'; + +describe('SidebarLanguageSwitcher', () => { + let languageApi: jest.Mocked; + + beforeEach(() => { + languageApi = { + getAvailableLanguages: jest.fn(), + getLanguage: jest.fn(), + language$: jest.fn(), + setLanguage: jest.fn(), + }; + + languageApi.language$.mockReturnValue( + ObservableImpl.of<{ language?: string }>({ language: 'en' }), + ); + languageApi.getLanguage.mockReturnValue({ language: 'en' }); + languageApi.getAvailableLanguages.mockReturnValue({ + languages: ['en', 'fi'], + }); + }); + + it('should display current language', async () => { + const { getByLabelText, getByRole, getByText } = await renderInTestApp( + + + , + ); + + const button = getByLabelText('Language'); + expect(button).toBeInTheDocument(); + + await userEvent.click(button); + + expect(getByRole('listbox')).toBeInTheDocument(); + expect(getByText('English')).toBeInTheDocument(); + expect(getByText('English').parentElement?.parentElement).toHaveAttribute( + 'aria-selected', + 'true', + ); + }); + + it('should select different language', async () => { + const { getByLabelText, getByRole, getByText } = await renderInTestApp( + + + , + ); + + const button = getByLabelText('Language'); + expect(button).toBeInTheDocument(); + + await userEvent.click(button); + + expect(getByRole('listbox')).toBeInTheDocument(); + + await userEvent.click(getByText('suomi')); + + expect(languageApi.setLanguage).toHaveBeenCalledWith('fi'); + }); +}); diff --git a/packages/dev-utils/src/components/SidebarLanguageSwitcher/SidebarLanguageSwitcher.tsx b/packages/dev-utils/src/components/SidebarLanguageSwitcher/SidebarLanguageSwitcher.tsx new file mode 100644 index 0000000000..71fd9a6c94 --- /dev/null +++ b/packages/dev-utils/src/components/SidebarLanguageSwitcher/SidebarLanguageSwitcher.tsx @@ -0,0 +1,109 @@ +/* + * 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 React, { useState } from 'react'; +import { appLanguageApiRef } from '@backstage/core-plugin-api/alpha'; +import TranslateIcon from '@material-ui/icons/Translate'; +import ListItemText from '@material-ui/core/ListItemText'; +import { useApi } from '@backstage/core-plugin-api'; +import useObservable from 'react-use/esm/useObservable'; +import { SidebarItem } from '@backstage/core-components'; +import Menu from '@material-ui/core/Menu'; +import MenuItem from '@material-ui/core/MenuItem'; + +/** @public */ +export const SidebarLanguageSwitcher = () => { + const languageApi = useApi(appLanguageApiRef); + + const [languageObservable] = useState(() => languageApi.language$()); + const { language: currentLanguage } = useObservable( + languageObservable, + languageApi.getLanguage(), + ); + const [anchorEl, setAnchorEl] = useState(); + + const { languages } = languageApi.getAvailableLanguages(); + + if (languages.length <= 1) { + return null; + } + + const open = Boolean(anchorEl); + + const handleClose = () => { + setAnchorEl(undefined); + }; + + const handleOpen = (event: React.MouseEvent) => { + setAnchorEl(event.currentTarget); + }; + + const handleSetLanguage = (newLanguage: string | undefined) => { + languageApi.setLanguage(newLanguage); + setAnchorEl(undefined); + }; + + const getLanguageDisplayName = (language: string) => { + try { + const names = new Intl.DisplayNames([language], { + type: 'language', + }); + return names.of(language) || language; + } catch (err) { + return language; + } + }; + + return ( + <> + + + Choose language + {languages.map(lang => { + const active = currentLanguage === lang; + return ( + handleSetLanguage(lang)} + > + {getLanguageDisplayName(lang)} + + ); + })} + + + ); +}; diff --git a/packages/backend-common/src/compat/logging/index.ts b/packages/dev-utils/src/components/SidebarLanguageSwitcher/index.ts similarity index 83% rename from packages/backend-common/src/compat/logging/index.ts rename to packages/dev-utils/src/components/SidebarLanguageSwitcher/index.ts index 10f949050c..6726e0bb9d 100644 --- a/packages/backend-common/src/compat/logging/index.ts +++ b/packages/dev-utils/src/components/SidebarLanguageSwitcher/index.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,5 +13,4 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -export { loggerToWinstonLogger } from './loggerToWinstonLogger'; +export { SidebarLanguageSwitcher } from './SidebarLanguageSwitcher'; diff --git a/packages/dev-utils/src/components/index.ts b/packages/dev-utils/src/components/index.ts index 8959b6e7b1..7a27a97e73 100644 --- a/packages/dev-utils/src/components/index.ts +++ b/packages/dev-utils/src/components/index.ts @@ -16,3 +16,4 @@ export * from './EntityGridItem'; export * from './SidebarSignOutButton'; +export * from './SidebarLanguageSwitcher'; diff --git a/packages/dev-utils/src/devApp/render.tsx b/packages/dev-utils/src/devApp/render.tsx index 3b3c993a6b..a22c4ffb71 100644 --- a/packages/dev-utils/src/devApp/render.tsx +++ b/packages/dev-utils/src/devApp/render.tsx @@ -40,6 +40,7 @@ import { IconComponent, RouteRef, } from '@backstage/core-plugin-api'; +import { TranslationResource } from '@backstage/core-plugin-api/alpha'; import { ScmIntegrationsApi, scmIntegrationsApiRef, @@ -50,7 +51,7 @@ import React, { ComponentType, PropsWithChildren, ReactNode } from 'react'; import { createRoutesFromChildren, Route } from 'react-router-dom'; import { SidebarThemeSwitcher } from './SidebarThemeSwitcher'; import 'react-dom'; -import { SidebarSignOutButton } from '../components'; +import { SidebarLanguageSwitcher, SidebarSignOutButton } from '../components'; let ReactDOMPromise: Promise< typeof import('react-dom') | typeof import('react-dom/client') @@ -98,9 +99,12 @@ export class DevAppBuilder { private readonly routes = new Array(); private readonly sidebarItems = new Array(); private readonly signInProviders = new Array(); + private readonly translationResources = new Array(); private defaultPage?: string; private themes?: Array; + private languages?: string[]; + private defaultLanguage?: string; /** * Register one or more plugins to render in the dev app @@ -193,6 +197,30 @@ export class DevAppBuilder { return this; } + /** + * Set available languages to be shown in the dev app + */ + setAvailableLanguages(languages: string[]) { + this.languages = languages; + return this; + } + + /** + * Add translation resource to the dev app + */ + addTranslationResource(resource: TranslationResource) { + this.translationResources.push(resource); + return this; + } + + /** + * Set default language for the dev app + */ + setDefaultLanguage(language: string) { + this.defaultLanguage = language; + return this; + } + /** * Build a DevApp component using the resources registered so far */ @@ -237,6 +265,11 @@ export class DevAppBuilder { bind(plugin.externalRoutes, targets); } }, + __experimentalTranslations: { + defaultLanguage: this.defaultLanguage, + availableLanguages: this.languages, + resources: this.translationResources, + }, }); const DevApp = ( @@ -252,6 +285,7 @@ export class DevAppBuilder { + diff --git a/packages/e2e-test-utils/api-report-playwright.md b/packages/e2e-test-utils/report-playwright.api.md similarity index 100% rename from packages/e2e-test-utils/api-report-playwright.md rename to packages/e2e-test-utils/report-playwright.api.md diff --git a/packages/e2e-test/CHANGELOG.md b/packages/e2e-test/CHANGELOG.md index f553c6e450..07b36cf3b2 100644 --- a/packages/e2e-test/CHANGELOG.md +++ b/packages/e2e-test/CHANGELOG.md @@ -1,5 +1,41 @@ # e2e-test +## 0.2.21-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.5.21-next.1 + - @backstage/cli-common@0.1.14 + - @backstage/errors@1.2.4 + +## 0.2.21-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.5.21-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/errors@1.2.4 + +## 0.2.20 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.5.19 + - @backstage/cli-common@0.1.14 + - @backstage/errors@1.2.4 + +## 0.2.20-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.5.19-next.2 + - @backstage/cli-common@0.1.14 + - @backstage/errors@1.2.4 + ## 0.2.20-next.1 ### Patch Changes diff --git a/packages/e2e-test/package.json b/packages/e2e-test/package.json index db0b649123..dd7fc2c8e4 100644 --- a/packages/e2e-test/package.json +++ b/packages/e2e-test/package.json @@ -1,31 +1,36 @@ { "name": "e2e-test", + "version": "0.2.21-next.1", "description": "E2E test for verifying Backstage packages", - "version": "0.2.20-next.1", - "private": true, "backstage": { "role": "cli" }, + "private": true, + "keywords": [ + "backstage" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "packages/e2e-test" }, - "keywords": [ - "backstage" - ], "license": "Apache-2.0", "main": "src/index.ts", - "scripts": { - "start": "yarn nodemon --", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", - "test:e2e": "yarn start", - "build": "backstage-cli package build", - "clean": "backstage-cli package clean" - }, "bin": "bin/e2e-test", + "scripts": { + "build": "backstage-cli package build", + "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", + "start": "yarn nodemon --", + "test": "backstage-cli package test", + "test:e2e": "yarn start" + }, + "nodemonConfig": { + "exec": "bin/e2e-test", + "ext": "ts", + "watch": "./src" + }, "dependencies": { "@backstage/cli-common": "workspace:^", "@backstage/create-app": "workspace:^", @@ -44,10 +49,5 @@ "@types/fs-extra": "^11.0.0", "@types/node": "^18.17.8", "nodemon": "^3.0.1" - }, - "nodemonConfig": { - "watch": "./src", - "exec": "bin/e2e-test", - "ext": "ts" } } diff --git a/packages/errors/api-report.md b/packages/errors/report.api.md similarity index 80% rename from packages/errors/api-report.md rename to packages/errors/report.api.md index 894aac8413..d2ba2d22ff 100644 --- a/packages/errors/api-report.md +++ b/packages/errors/report.api.md @@ -155,4 +155,16 @@ export class ServiceUnavailableError extends CustomErrorBase {} // @public export function stringifyError(error: unknown): string; + +// Warnings were encountered during analysis: +// +// src/errors/ResponseError.d.ts:32:5 - (ae-undocumented) Missing documentation for "statusCode". +// src/errors/ResponseError.d.ts:33:5 - (ae-undocumented) Missing documentation for "statusText". +// src/errors/common.d.ts:8:5 - (ae-undocumented) Missing documentation for "name". +// src/errors/common.d.ts:16:5 - (ae-undocumented) Missing documentation for "name". +// src/errors/common.d.ts:24:5 - (ae-undocumented) Missing documentation for "name". +// src/errors/common.d.ts:35:5 - (ae-undocumented) Missing documentation for "name". +// src/errors/common.d.ts:44:5 - (ae-undocumented) Missing documentation for "name". +// src/errors/common.d.ts:52:5 - (ae-undocumented) Missing documentation for "name". +// src/errors/common.d.ts:60:5 - (ae-undocumented) Missing documentation for "name". ``` diff --git a/packages/eslint-plugin/CHANGELOG.md b/packages/eslint-plugin/CHANGELOG.md index 63a7650400..f7073ce289 100644 --- a/packages/eslint-plugin/CHANGELOG.md +++ b/packages/eslint-plugin/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/eslint-plugin +## 0.1.10-next.0 + +### Patch Changes + +- 63963f6: Internal refactor to deal with `estree` upgrade + +## 0.1.9 + +### Patch Changes + +- 08895e3: Added support for linting dependencies on workspace packages with the `backstage.inline` flag. + +## 0.1.9-next.0 + +### Patch Changes + +- 08895e3: Added support for linting dependencies on workspace packages with the `backstage.inline` flag. + ## 0.1.8 ### Patch Changes diff --git a/packages/eslint-plugin/lib/getPackages.js b/packages/eslint-plugin/lib/getPackages.js index 8f4ccfacf3..3b46f41a54 100644 --- a/packages/eslint-plugin/lib/getPackages.js +++ b/packages/eslint-plugin/lib/getPackages.js @@ -21,7 +21,7 @@ const manypkg = require('@manypkg/get-packages'); /** * @typedef ExtendedPackage - * @type {import('@manypkg/get-packages').Package & { packageJson: { exports?: Record, files?: Array }}} packageJson + * @type {import('@manypkg/get-packages').Package & { packageJson: { exports?: Record, files?: Array, backstage?: { inline?: boolean } }}} packageJson */ /** diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index 0d8db000e0..52438be2fb 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/eslint-plugin", - "version": "0.1.8", + "version": "0.1.10-next.0", "description": "Backstage ESLint plugin", "publishConfig": { "access": "public" diff --git a/packages/eslint-plugin/rules/no-top-level-material-ui-4-imports.js b/packages/eslint-plugin/rules/no-top-level-material-ui-4-imports.js index 78fd3d63e9..6e0ba9ee87 100644 --- a/packages/eslint-plugin/rules/no-top-level-material-ui-4-imports.js +++ b/packages/eslint-plugin/rules/no-top-level-material-ui-4-imports.js @@ -80,11 +80,14 @@ const KNOWN_STYLES = [ /** * filter function to keep only ImportSpecifier nodes - * @param {import('estree').ImportSpecifier | import('estree').ImportDefaultSpecifier| import('estree').ImportNamespaceSpecifier} specifier + * @param {import('estree').ImportSpecifier | import('estree').ImportDefaultSpecifier | import('estree').ImportNamespaceSpecifier} specifier * @returns {specifier is import('estree').ImportSpecifier} */ function importSpecifiersFilter(specifier) { - return specifier.type === 'ImportSpecifier'; + return ( + specifier.type === 'ImportSpecifier' && + specifier.imported.type !== 'Literal' + ); } /** @@ -146,12 +149,16 @@ module.exports = { const specifiers = node.specifiers.filter(importSpecifiersFilter); - const specifiersMap = specifiers.map( + const specifiersMap = specifiers.flatMap( /** * transform ImportSpecifier to FixerValues to have a simpler object to work with - * @returns {FixerValues} + * @returns {FixerValues[]} */ s => { + if (s.imported.type === 'Literal') { + return []; + } + const value = s.imported.name; const alias = s.local.name === value ? undefined : s.local.name; @@ -165,19 +172,24 @@ module.exports = { const emitComponent = !emitProp; const emitComponentAndProp = emitProp && - specifiers.find(s => s.imported.name === propsMatch[1])?.local - .name; + specifiers.find( + s => + s.imported.type !== 'Literal' && + s.imported.name === propsMatch[1], + )?.local.name; - return { - emitComponent: emitComponent || Boolean(emitComponentAndProp), - emitProp, - value, - componentValue: propsMatch ? propsMatch[1] : undefined, - componentAlias: emitComponentAndProp - ? emitComponentAndProp - : undefined, - alias, - }; + return [ + { + emitComponent: emitComponent || Boolean(emitComponentAndProp), + emitProp, + value, + componentValue: propsMatch ? propsMatch[1] : undefined, + componentAlias: emitComponentAndProp + ? emitComponentAndProp + : undefined, + alias, + }, + ]; }, ); diff --git a/packages/eslint-plugin/rules/no-undeclared-imports.js b/packages/eslint-plugin/rules/no-undeclared-imports.js index d2c92ccb8a..b770ded365 100644 --- a/packages/eslint-plugin/rules/no-undeclared-imports.js +++ b/packages/eslint-plugin/rules/no-undeclared-imports.js @@ -22,11 +22,11 @@ const visitImports = require('../lib/visitImports'); const minimatch = require('minimatch'); const { execFileSync } = require('child_process'); -const depFields = { +const depFields = /** @type {const} */ ({ dep: 'dependencies', dev: 'devDependencies', peer: 'peerDependencies', -}; +}); const devModulePatterns = [ new minimatch.Minimatch('!src/**'), @@ -154,6 +154,124 @@ function addVersionQuery(name, flag, packages) { return `${name}@${mostCommonRange}`; } +/** + * Add missing package imports + * @param {Array<{name: string, flag: string, node: import('estree').Node}>} toAdd + * @param {import('../lib/getPackages').PackageMap} packages + * @param {import('../lib/getPackages').ExtendedPackage} localPkg + */ +function addMissingImports(toAdd, packages, localPkg) { + /** @type Record> */ + const byFlag = {}; + + for (const { name, flag } of toAdd) { + byFlag[flag] = byFlag[flag] ?? new Set(); + byFlag[flag].add(name); + } + + for (const name of byFlag[''] ?? []) { + byFlag['--dev']?.delete(name); + } + for (const name of byFlag['--peer'] ?? []) { + byFlag['']?.delete(name); + byFlag['--dev']?.delete(name); + } + + for (const [flag, names] of Object.entries(byFlag)) { + // Look up existing version queries in the repo for the same dependency + const namesWithQuery = [...names].map(name => + addVersionQuery(name, flag, packages), + ); + + // The security implication of this is a bit interesting, as crafted add-import + // directives could be used to install malicious packages. However, the same is true + // for adding malicious packages to package.json, so there's no significant difference. + execFileSync('yarn', ['add', ...(flag ? [flag] : []), ...namesWithQuery], { + cwd: localPkg.dir, + stdio: 'inherit', + }); + } +} + +/** + * Removes dependency entries pointing to inlined workspace packages. + * @param {Array<{pkg: import('../lib/getPackages').ExtendedPackage, node: import('estree').Node}>} toInline + * @param {import('../lib/getPackages').ExtendedPackage} localPkg + */ +function removeInlineImports(toInline, localPkg) { + /** @type Set */ + const toRemove = new Set(); + + for (const { pkg } of toInline) { + const name = pkg.packageJson.name; + for (const depType of Object.values(depFields)) { + if (localPkg.packageJson[depType]?.[name]) { + toRemove.add(name); + } + } + } + if (toRemove.size > 0) { + execFileSync('yarn', ['remove', ...toRemove], { + cwd: localPkg.dir, + stdio: 'inherit', + }); + } +} + +/** + * Adds dependencies that are not properly forwarded from inline dependencies. + * @param {Array<{pkg: import('../lib/getPackages').ExtendedPackage, node: import('estree').Node}>} toInline + * @param {import('../lib/getPackages').ExtendedPackage} localPkg + */ +function addForwardedInlineImports(toInline, localPkg) { + const declaredProdDeps = new Set([ + ...Object.keys(localPkg.packageJson.dependencies ?? {}), + ...Object.keys(localPkg.packageJson.peerDependencies ?? {}), + localPkg.packageJson.name, // include self + ]); + + /** @type Map> */ + const byFlagByName = new Map(); + + for (const { pkg } of toInline) { + for (const depType of /** @type {const} */ ([ + 'dependencies', + 'peerDependencies', + ])) { + for (const [depName, depQuery] of Object.entries( + pkg.packageJson[depType] ?? {}, + )) { + if (!declaredProdDeps.has(depName)) { + const flag = getAddFlagForDepsField(depType); + const byName = byFlagByName.get(flag); + if (byName) { + const query = byName.get(depName); + if (query && query !== depQuery) { + throw new Error( + `Conflicting dependency queries for inlined package dep ${depName}, got ${query} and ${depQuery}`, + ); + } else { + byName.set(depName, depQuery); + } + } else { + byFlagByName.set(flag, new Map([[depName, depQuery]])); + } + } + } + } + } + + for (const [flag, byName] of byFlagByName) { + const namesWithQuery = [...byName.entries()].map( + ([name, query]) => `${name}@${query}`, + ); + execFileSync('yarn', ['add', ...(flag ? [flag] : []), ...namesWithQuery], { + cwd: localPkg.dir, + stdio: 'inherit', + }); + } +} + /** @type {import('eslint').Rule.RuleModule} */ module.exports = { meta: { @@ -165,6 +283,8 @@ module.exports = { switch: '{{ packageName }} is declared in {{ oldDepsField }}, but should be moved to {{ depsField }} in {{ packageJsonPath }}.', switchBack: 'Switch back to import declaration', + inlineDirect: `The dependency on the inline package {{ packageName }} must not be declared in package dependencies.`, + inlineMissing: `Each production dependency from the inline package {{ packageName }} must be re-declared by this package, the following dependencies are missing: {{ missingDeps }}`, }, docs: { description: @@ -189,57 +309,48 @@ module.exports = { /** @type Array<{name: string, flag: string, node: import('estree').Node}> */ const importsToAdd = []; + /** @type Array<{pkg: import('../lib/getPackages').ExtendedPackage, node: import('estree').Node}> */ + const importsToInline = []; + return { // All missing imports that we detect are collected as we traverse, and then we use // the program exit to execute all install directives that have been found. ['Program:exit']() { - /** @type Record> */ - const byFlag = {}; + if (importsToAdd.length > 0) { + addMissingImports(importsToAdd, packages, localPkg); - for (const { name, flag } of importsToAdd) { - byFlag[flag] = byFlag[flag] ?? new Set(); - byFlag[flag].add(name); + // This switches all import directives back to the original import. + for (const added of importsToAdd) { + context.report({ + node: added.node, + messageId: 'switchBack', + fix(fixer) { + return fixer.replaceText(added.node, `'${added.name}'`); + }, + }); + } + importsToAdd.length = 0; } - for (const name of byFlag[''] ?? []) { - byFlag['--dev']?.delete(name); - } - for (const name of byFlag['--peer'] ?? []) { - byFlag['']?.delete(name); - byFlag['--dev']?.delete(name); + if (importsToInline.length > 0) { + removeInlineImports(importsToInline, localPkg); + addForwardedInlineImports(importsToInline, localPkg); + + for (const inlined of importsToInline) { + context.report({ + node: inlined.node, + messageId: 'switchBack', + fix(fixer) { + return fixer.replaceText( + inlined.node, + `'${inlined.pkg.packageJson.name}'`, + ); + }, + }); + } + importsToInline.length = 0; } - for (const [flag, names] of Object.entries(byFlag)) { - // Look up existing version queries in the repo for the same dependency - const namesWithQuery = [...names].map(name => - addVersionQuery(name, flag, packages), - ); - - // The security implication of this is a bit interesting, as crafted add-import - // directives could be used to install malicious packages. However, the same is true - // for adding malicious packages to package.json, so there's no significant difference. - execFileSync( - 'yarn', - ['add', ...(flag ? [flag] : []), ...namesWithQuery], - { - cwd: localPkg.dir, - stdio: 'inherit', - }, - ); - } - - // This switches all import directives back to the original import. - for (const added of importsToAdd) { - context.report({ - node: added.node, - messageId: 'switchBack', - fix(fixer) { - return fixer.replaceText(added.node, `'${added.name}'`); - }, - }); - } - - importsToAdd.length = 0; packages.clearCache(); }, ...visitImports(context, (node, imp) => { @@ -255,22 +366,99 @@ module.exports = { // Any import directive that is found is collected for processing later if (imp.type === 'directive') { - const parts = imp.path.split(':'); - if (parts[1] !== 'add-import') { - return; - } - const [type, name] = parts.slice(2); - if (!name.match(/^(@[-\w\.~]+\/)?[-\w\.~]*$/i)) { - throw new Error( - `Invalid package name to add as dependency: '${name}'`, - ); + const [, directive, ...args] = imp.path.split(':'); + + if (directive === 'add-import') { + const [type, name] = args; + if (!name.match(/^(@[-\w\.~]+\/)?[-\w\.~]*$/i)) { + throw new Error( + `Invalid package name to add as dependency: '${name}'`, + ); + } + + importsToAdd.push({ + flag: getAddFlagForDepsField(type).trim(), + name, + node: imp.node, + }); + } + + if (directive === 'inline-imports') { + const [name] = args; + const pkg = packages.map.get(name); + if (!pkg) { + throw new Error(`Unexpectedly missing inline package: ${name}`); + } + + importsToInline.push({ + pkg: pkg, + node: imp.node, + }); + } + + return; + } + + // Importing an internal inlined package, whose imports are inlined too + if ( + imp.type === 'internal' && + imp.package.packageJson.backstage?.inline + ) { + for (const depType of Object.values(depFields)) { + if (localPkg.packageJson[depType]?.[imp.packageName]) { + context.report({ + node, + messageId: 'inlineDirect', + data: { + packageName: imp.packageName, + }, + fix: fixer => { + return fixer.replaceText( + imp.node, + `'directive:inline-imports:${imp.packageName}'`, + ); + }, + }); + return; + } + } + + const missingDeps = []; + const declaredProdDeps = new Set([ + ...Object.keys(localPkg.packageJson.dependencies ?? {}), + ...Object.keys(localPkg.packageJson.peerDependencies ?? {}), + localPkg.packageJson.name, // include self + ]); + for (const depType of /** @type {const} */ ([ + 'dependencies', + 'peerDependencies', + ])) { + for (const depName of Object.keys( + imp.package.packageJson[depType] ?? {}, + )) { + if (!declaredProdDeps.has(depName)) { + missingDeps.push(depName); + } + } + } + + if (missingDeps.length > 0) { + context.report({ + node, + messageId: 'inlineMissing', + data: { + packageName: imp.packageName, + missingDeps: missingDeps.join(', '), + }, + fix: fixer => { + return fixer.replaceText( + imp.node, + `'directive:inline-imports:${imp.packageName}'`, + ); + }, + }); } - importsToAdd.push({ - flag: getAddFlagForDepsField(type).trim(), - name, - node: imp.node, - }); return; } diff --git a/packages/eslint-plugin/src/__fixtures__/monorepo/packages/bar/package.json b/packages/eslint-plugin/src/__fixtures__/monorepo/packages/bar/package.json index efef27047b..ba55598dc2 100644 --- a/packages/eslint-plugin/src/__fixtures__/monorepo/packages/bar/package.json +++ b/packages/eslint-plugin/src/__fixtures__/monorepo/packages/bar/package.json @@ -1,14 +1,15 @@ { "name": "@internal/bar", + "backstage": { + "role": "frontend-plugin" + }, "exports": { ".": "./src/index.ts", "./BarPage": "./src/components/Bar.tsx", "./package.json": "./package.json" }, - "backstage": { - "role": "frontend-plugin" - }, "dependencies": { + "inline-dep": "*", "react-router": "*" }, "devDependencies": { diff --git a/packages/eslint-plugin/src/__fixtures__/monorepo/packages/inline-dep-invalid-direct/package.json b/packages/eslint-plugin/src/__fixtures__/monorepo/packages/inline-dep-invalid-direct/package.json new file mode 100644 index 0000000000..352a02d66c --- /dev/null +++ b/packages/eslint-plugin/src/__fixtures__/monorepo/packages/inline-dep-invalid-direct/package.json @@ -0,0 +1,12 @@ +{ + "name": "@internal/inline-dep-direct", + "files": [ + "dist", + "type-utils" + ], + "dependencies": { + "@internal/inline": "workspace:^", + "@internal/inline-dep-valid": "workspace:^", + "react": "*" + } +} diff --git a/packages/eslint-plugin/src/__fixtures__/monorepo/packages/inline-dep-invalid-missing/package.json b/packages/eslint-plugin/src/__fixtures__/monorepo/packages/inline-dep-invalid-missing/package.json new file mode 100644 index 0000000000..595ee4a86b --- /dev/null +++ b/packages/eslint-plugin/src/__fixtures__/monorepo/packages/inline-dep-invalid-missing/package.json @@ -0,0 +1,7 @@ +{ + "name": "@internal/inline-dep-missing", + "files": [ + "dist", + "type-utils" + ] +} diff --git a/packages/eslint-plugin/src/__fixtures__/monorepo/packages/inline-dep-valid/package.json b/packages/eslint-plugin/src/__fixtures__/monorepo/packages/inline-dep-valid/package.json new file mode 100644 index 0000000000..cbb42d0080 --- /dev/null +++ b/packages/eslint-plugin/src/__fixtures__/monorepo/packages/inline-dep-valid/package.json @@ -0,0 +1,10 @@ +{ + "name": "@internal/inline-dep-valid", + "files": [ + "dist", + "type-utils" + ], + "peerDependencies": { + "react": "*" + } +} diff --git a/packages/eslint-plugin/src/__fixtures__/monorepo/packages/inline/package.json b/packages/eslint-plugin/src/__fixtures__/monorepo/packages/inline/package.json new file mode 100644 index 0000000000..fb9345f140 --- /dev/null +++ b/packages/eslint-plugin/src/__fixtures__/monorepo/packages/inline/package.json @@ -0,0 +1,16 @@ +{ + "name": "@internal/inline", + "backstage": { + "inline": true + }, + "files": [ + "dist", + "type-utils" + ], + "dependencies": { + "@internal/inline-dep-valid": "workspace:^" + }, + "peerDependencies": { + "react": "*" + } +} diff --git a/packages/eslint-plugin/src/no-undeclared-imports.test.ts b/packages/eslint-plugin/src/no-undeclared-imports.test.ts index 29e2c3a87c..ee56c34926 100644 --- a/packages/eslint-plugin/src/no-undeclared-imports.test.ts +++ b/packages/eslint-plugin/src/no-undeclared-imports.test.ts @@ -52,6 +52,12 @@ const ERR_SWITCHED = ( const ERR_SWITCH_BACK = () => ({ message: 'Switch back to import declaration', }); +const ERR_INLINE_DIRECT = (name: string) => ({ + message: `The dependency on the inline package ${name} must not be declared in package dependencies.`, +}); +const ERR_INLINE_MISSING = (name: string, missing: string) => ({ + message: `Each production dependency from the inline package ${name} must be re-declared by this package, the following dependencies are missing: ${missing}`, +}); // cwd must be restored const origDir = process.cwd(); @@ -102,6 +108,17 @@ ruleTester.run(RULE, rule, { code: `require('lod' + 'ash')`, filename: joinPath(FIXTURE, 'packages/bar/src/index.ts'), }, + { + code: `import '@internal/inline'`, + filename: joinPath(FIXTURE, 'packages/inline-dep-valid/src/index.ts'), + }, + { + code: `import '@internal/inline'`, + filename: joinPath( + FIXTURE, + 'packages/inline-dep-valid/src/index.test.ts', + ), + }, ], invalid: [ { @@ -264,6 +281,29 @@ ruleTester.run(RULE, rule, { ), ], }, + { + code: `import '@internal/inline'`, + output: `import 'directive:inline-imports:@internal/inline'`, + filename: joinPath( + FIXTURE, + 'packages/inline-dep-invalid-direct/src/index.ts', + ), + errors: [ERR_INLINE_DIRECT('@internal/inline')], + }, + { + code: `import '@internal/inline'`, + output: `import 'directive:inline-imports:@internal/inline'`, + filename: joinPath( + FIXTURE, + 'packages/inline-dep-invalid-missing/src/index.ts', + ), + errors: [ + ERR_INLINE_MISSING( + '@internal/inline', + '@internal/inline-dep-valid, react', + ), + ], + }, // Switching back to original import declarations { @@ -302,5 +342,14 @@ ruleTester.run(RULE, rule, { filename: joinPath(FIXTURE, 'packages/bar/src/index.ts'), errors: [ERR_SWITCH_BACK()], }, + { + code: `import 'directive:inline-imports:@internal/inline'`, + output: `import '@internal/inline'`, + filename: joinPath( + FIXTURE, + 'packages/inline-dep-invalid-direct/src/index.ts', + ), + errors: [ERR_SWITCH_BACK()], + }, ], }); diff --git a/packages/frontend-app-api/CHANGELOG.md b/packages/frontend-app-api/CHANGELOG.md index 9596e51ee3..5fea3c4cea 100644 --- a/packages/frontend-app-api/CHANGELOG.md +++ b/packages/frontend-app-api/CHANGELOG.md @@ -1,5 +1,102 @@ # @backstage/frontend-app-api +## 0.10.0-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/version-bridge@1.0.10-next.0 + - @backstage/core-app-api@1.15.1-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/frontend-defaults@0.1.1-next.1 + - @backstage/types@1.1.1 + +## 0.10.0-next.0 + +### Minor Changes + +- 4a5ba19: Removed deprecated `createApp` and `CreateAppFeatureLoader` from `@backstage/frontend-app-api`, use the same `createApp` and `CreateAppFeatureLoader` import from `@backstage/frontend-defaults` instead. + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/frontend-defaults@0.1.1-next.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.15.1-next.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.9 + +## 0.9.0 + +### Minor Changes + +- 7c80650: **BREAKING**: The `createSpecializedApp` function now creates a bare-bones app without any of the default app structure or APIs. To re-introduce this functionality if you need to use `createSpecializedApp` you can install the `app` plugin from `@backstage/plugin-app`. + + In addition, the `createApp` and `CreateAppFeatureLoader` exports are now deprecated as they are being moved to `@backstage/frontend-defaults`, which should be used instead. + +- 62cce6c: Removed deprecated `icons` property passing to `createApp` and `createSpecializedApp`. Use `IconBundleBlueprint.make` to create extensions instead and include them in the app. + +### Patch Changes + +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. +- 2bb9517: Introduce the `@backstage/plugin-app` package to hold all of the built-in extensions for easy consumption and overriding. +- c816e2d: Added support for new `FrontendPlugin` and `FrontendModule` types. +- f3a2b91: Moved several implementations of built-in APIs from being hardcoded in the app to instead be provided as API extensions. This moves all API-related inputs from the `app` extension to the respective API extensions. For example, extensions created with `ThemeBlueprint` are now attached to the `themes` input of `api:app-theme` rather than the `app` extension. +- 0c70949: Reverse the order of API factory initialization in order to make sure that overrides from modules take priority +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- 5446061: Internal refactor following removal of v1 extension support. The app implementation itself still supports v1 extensions at runtime. +- 948d431: Removing deprecated `namespace` parameter in favour of `pluginId` instead +- ddbeace: Added the ability to explicitly disable routes through the `bindRoutes` option by passing `false` as the route target. This also fixes a bug where route bindings in config were incorrectly prioritized above the ones in code in certain situations. +- 98850de: Added support for defining `replaces` in `createExtensionInput` which will allow extensions to redirect missing `attachTo` points to an input of the created extension. + + ```ts + export const AppThemeApi = ApiBlueprint.makeWithOverrides({ + name: 'app-theme', + inputs: { + themes: createExtensionInput([ThemeBlueprint.dataRefs.theme], { + // attachTo: { id: 'app', input: 'themes'} will be redirected to this input instead + replaces: [{ id: 'app', input: 'themes' }], + }), + }, + factory: () { + ... + } + }); + ``` + +- 4a66456: Added the `root` extension the replace the `app` extension as the root of the app. +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0 + - @backstage/core-app-api@1.15.0 + - @backstage/frontend-defaults@0.1.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/version-bridge@1.0.9 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## 0.9.0-next.2 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-app-api@1.14.3-next.0 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/frontend-defaults@0.1.0-next.1 + - @backstage/frontend-plugin-api@0.8.0-next.2 + - @backstage/version-bridge@1.0.9-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.9.0-next.1 ### Minor Changes diff --git a/packages/frontend-app-api/package.json b/packages/frontend-app-api/package.json index 140266eae6..0f0535f522 100644 --- a/packages/frontend-app-api/package.json +++ b/packages/frontend-app-api/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/frontend-app-api", - "version": "0.9.0-next.1", + "version": "0.10.0-next.1", "backstage": { "role": "web-library" }, @@ -40,19 +40,30 @@ "@backstage/frontend-plugin-api": "workspace:^", "@backstage/types": "workspace:^", "@backstage/version-bridge": "workspace:^", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "lodash": "^4.17.21" + "lodash": "^4.17.21", + "zod": "^3.22.4" }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/plugin-app": "workspace:^", "@backstage/test-utils": "workspace:^", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^15.0.0" + "@testing-library/react": "^16.0.0", + "@types/react": "^18.0.0", + "react": "^18.0.2", + "react-dom": "^18.0.2", + "react-router-dom": "^6.3.0" }, "peerDependencies": { + "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-router-dom": "6.0.0-beta.0 || ^6.3.0" }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + }, "configSchema": "config.d.ts" } diff --git a/packages/frontend-app-api/api-report.md b/packages/frontend-app-api/report.api.md similarity index 78% rename from packages/frontend-app-api/api-report.md rename to packages/frontend-app-api/report.api.md index e102d6bf20..b5e5f801e6 100644 --- a/packages/frontend-app-api/api-report.md +++ b/packages/frontend-app-api/report.api.md @@ -4,8 +4,6 @@ ```ts import { ConfigApi } from '@backstage/core-plugin-api'; -import { createApp as createApp_2 } from '@backstage/frontend-defaults'; -import { CreateAppFeatureLoader as CreateAppFeatureLoader_2 } from '@backstage/frontend-defaults'; import { ExternalRouteRef } from '@backstage/frontend-plugin-api'; import { FrontendModule } from '@backstage/frontend-plugin-api'; import { FrontendPlugin } from '@backstage/frontend-plugin-api'; @@ -13,12 +11,6 @@ import { JSX as JSX_2 } from 'react'; import { RouteRef } from '@backstage/frontend-plugin-api'; import { SubRouteRef } from '@backstage/frontend-plugin-api'; -// @public @deprecated (undocumented) -export const createApp: typeof createApp_2; - -// @public @deprecated (undocumented) -export type CreateAppFeatureLoader = CreateAppFeatureLoader_2; - // @public export type CreateAppRouteBinder = < TExternalRoutes extends { @@ -51,4 +43,8 @@ export type FrontendFeature = | { $$type: '@backstage/BackstagePlugin'; }; + +// Warnings were encountered during analysis: +// +// src/wiring/types.d.ts:3:1 - (ae-undocumented) Missing documentation for "FrontendFeature". ``` diff --git a/packages/frontend-app-api/src/routing/collectRouteIds.ts b/packages/frontend-app-api/src/routing/collectRouteIds.ts index d89834c02e..8b23e9e80b 100644 --- a/packages/frontend-app-api/src/routing/collectRouteIds.ts +++ b/packages/frontend-app-api/src/routing/collectRouteIds.ts @@ -28,8 +28,7 @@ import { import { toInternalExternalRouteRef } from '../../../frontend-plugin-api/src/routing/ExternalRouteRef'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports import { toInternalSubRouteRef } from '../../../frontend-plugin-api/src/routing/SubRouteRef'; -// eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { isInternalFrontendPlugin } from '../../../frontend-plugin-api/src/wiring/createFrontendPlugin'; +import { OpaqueFrontendPlugin } from '@internal/frontend'; import { FrontendFeature } from '../wiring'; /** @internal */ @@ -44,7 +43,7 @@ export function collectRouteIds(features: FrontendFeature[]): RouteRefsById { const externalRoutesById = new Map(); for (const feature of features) { - if (!isInternalFrontendPlugin(feature)) { + if (!OpaqueFrontendPlugin.isType(feature)) { continue; } diff --git a/packages/frontend-app-api/src/routing/resolveRouteBindings.test.ts b/packages/frontend-app-api/src/routing/resolveRouteBindings.test.ts index 908a99d3aa..6618bef152 100644 --- a/packages/frontend-app-api/src/routing/resolveRouteBindings.test.ts +++ b/packages/frontend-app-api/src/routing/resolveRouteBindings.test.ts @@ -69,6 +69,41 @@ describe('resolveRouteBindings', () => { expect(result.get(mySource)).toBe(myTarget); }); + it('prioritizes callback routes over config', () => { + const mySource = createExternalRouteRef(); + const myTarget = createRouteRef(); + + expect( + resolveRouteBindings( + ({ bind }) => { + bind({ mySource }, { mySource: false }); + }, + new ConfigReader({ + app: { routes: { bindings: { mySource: 'myTarget' } } }, + }), + { + routes: new Map([['myTarget', myTarget]]), + externalRoutes: new Map([['mySource', mySource]]), + }, + ).get(mySource), + ).toBe(undefined); + + expect( + resolveRouteBindings( + ({ bind }) => { + bind({ mySource }, { mySource: myTarget }); + }, + new ConfigReader({ + app: { routes: { bindings: { mySource: false } } }, + }), + { + routes: new Map([['myTarget', myTarget]]), + externalRoutes: new Map([['mySource', mySource]]), + }, + ).get(mySource), + ).toBe(myTarget); + }); + it('throws on invalid config', () => { expect(() => resolveRouteBindings( diff --git a/packages/frontend-app-api/src/routing/resolveRouteBindings.ts b/packages/frontend-app-api/src/routing/resolveRouteBindings.ts index a8f641daff..76d620c20c 100644 --- a/packages/frontend-app-api/src/routing/resolveRouteBindings.ts +++ b/packages/frontend-app-api/src/routing/resolveRouteBindings.ts @@ -55,13 +55,13 @@ type TargetRouteMap< [name in keyof ExternalRoutes]: ExternalRoutes[name] extends ExternalRouteRef< infer Params > - ? RouteRef | SubRouteRef + ? RouteRef | SubRouteRef | false : never; }; /** * A function that can bind from external routes of a given plugin, to concrete - * routes of other plugins. See {@link createApp}. + * routes of other plugins. See {@link @backstage/frontend-defaults#createApp}. * * @public */ @@ -82,6 +82,7 @@ export function resolveRouteBindings( routesById: RouteRefsById, ): Map { const result = new Map(); + const disabledExternalRefs = new Set(); // Perform callback bindings first with highest priority if (bindRoutes) { @@ -96,6 +97,8 @@ export function resolveRouteBindings( } if (value) { result.set(externalRoute, value); + } else if (value === false) { + disabledExternalRefs.add(externalRoute); } } }; @@ -106,7 +109,6 @@ export function resolveRouteBindings( const bindings = config .getOptionalConfig('app.routes.bindings') ?.get(); - const disabledExternalRefs = new Set(); if (bindings) { for (const [externalRefId, targetRefId] of Object.entries(bindings)) { if (!isValidTargetRefId(targetRefId)) { @@ -122,11 +124,14 @@ export function resolveRouteBindings( ); } + // Skip if binding was already defined in code + if (result.has(externalRef) || disabledExternalRefs.has(externalRef)) { + continue; + } + if (targetRefId === false) { disabledExternalRefs.add(externalRef); - - result.delete(externalRef); - } else if (!result.has(externalRef)) { + } else { const targetRef = routesById.routes.get(targetRefId); if (!targetRef) { throw new Error( diff --git a/packages/frontend-app-api/src/routing/toLegacyPlugin.ts b/packages/frontend-app-api/src/routing/toLegacyPlugin.ts index 2d04d04dda..b705fc0873 100644 --- a/packages/frontend-app-api/src/routing/toLegacyPlugin.ts +++ b/packages/frontend-app-api/src/routing/toLegacyPlugin.ts @@ -14,17 +14,17 @@ * limitations under the License. */ -import { BackstagePlugin } from '@backstage/frontend-plugin-api'; +import { FrontendPlugin } from '@backstage/frontend-plugin-api'; import { BackstagePlugin as LegacyBackstagePlugin } from '@backstage/core-plugin-api'; import { getOrCreateGlobalSingleton } from '@backstage/version-bridge'; // Make sure that we only convert each new plugin instance to its legacy equivalent once const legacyPluginStore = getOrCreateGlobalSingleton( 'legacy-plugin-compatibility-store', - () => new WeakMap(), + () => new WeakMap(), ); -export function toLegacyPlugin(plugin: BackstagePlugin): LegacyBackstagePlugin { +export function toLegacyPlugin(plugin: FrontendPlugin): LegacyBackstagePlugin { let legacy = legacyPluginStore.get(plugin); if (legacy) { return legacy; diff --git a/packages/frontend-app-api/src/tree/resolveAppNodeSpecs.test.ts b/packages/frontend-app-api/src/tree/resolveAppNodeSpecs.test.ts index e4500df6c0..a80c4cb35b 100644 --- a/packages/frontend-app-api/src/tree/resolveAppNodeSpecs.test.ts +++ b/packages/frontend-app-api/src/tree/resolveAppNodeSpecs.test.ts @@ -15,7 +15,6 @@ */ import { - createExtensionOverrides, createFrontendModule, createFrontendPlugin, Extension, @@ -276,55 +275,6 @@ describe('resolveAppNodeSpecs', () => { ]); }); - it('should apply extension overrides', () => { - const plugin = createFrontendPlugin({ - id: 'test', - extensions: [makeExtDef('a'), makeExtDef('b')], - }); - const aOverride = makeExt('test/a', 'enabled', 'other'); - const bOverride = makeExt('test/b', 'disabled', 'other'); - const cOverride = makeExt('c'); - - expect( - resolveAppNodeSpecs({ - features: [ - plugin, - createExtensionOverrides({ - extensions: [ - makeExtDef('test/a', 'enabled', 'other'), - makeExtDef('test/b', 'disabled', 'other'), - makeExtDef('c'), - ], - }), - ], - builtinExtensions: [], - parameters: [], - }), - ).toEqual([ - { - id: 'test/a', - extension: aOverride, - attachTo: { id: 'other', input: 'default' }, - source: plugin, - disabled: false, - }, - { - id: 'test/b', - extension: bOverride, - attachTo: { id: 'other', input: 'default' }, - source: plugin, - disabled: true, - }, - { - id: 'c', - extension: cOverride, - attachTo: { id: 'root', input: 'default' }, - source: undefined, - disabled: false, - }, - ]); - }); - it('should apply module overrides', () => { const plugin = createFrontendPlugin({ id: 'test', @@ -375,39 +325,6 @@ describe('resolveAppNodeSpecs', () => { ]); }); - it('should use order from configuration when rather than overrides', () => { - const result = resolveAppNodeSpecs({ - features: [ - createFrontendPlugin({ - id: 'test', - extensions: [ - makeExtDef('a', 'disabled'), - makeExtDef('b', 'disabled'), - makeExtDef('c', 'disabled'), - ], - }), - createExtensionOverrides({ - extensions: [ - makeExtDef('test/c', 'disabled'), - makeExtDef('test/b', 'disabled'), - makeExtDef('test/a', 'disabled'), - ], - }), - ], - builtinExtensions: [], - parameters: ['test/b', 'test/c', 'test/a'].map(id => ({ - id, - disabled: false, - })), - }); - - expect(result.map(r => r.extension.id)).toEqual([ - 'test/b', - 'test/c', - 'test/a', - ]); - }); - it('should use order from configuration when rather than modules', () => { const result = resolveAppNodeSpecs({ features: [ @@ -460,21 +377,6 @@ describe('resolveAppNodeSpecs', () => { ); }); - it('throws an error when a forbidden extension is overridden by overrides', () => { - expect(() => - resolveAppNodeSpecs({ - features: [ - createExtensionOverrides({ extensions: [makeExtDef('forbidden')] }), - ], - builtinExtensions: [], - parameters: [], - forbidden: new Set(['forbidden']), - }), - ).toThrow( - "It is forbidden to override the following extension(s): 'forbidden', which is done by one or more extension overrides", - ); - }); - it('throws an error when a forbidden extension is overridden by module', () => { expect(() => resolveAppNodeSpecs({ diff --git a/packages/frontend-app-api/src/tree/resolveAppNodeSpecs.ts b/packages/frontend-app-api/src/tree/resolveAppNodeSpecs.ts index bc3da52cd6..0abbbb3560 100644 --- a/packages/frontend-app-api/src/tree/resolveAppNodeSpecs.ts +++ b/packages/frontend-app-api/src/tree/resolveAppNodeSpecs.ts @@ -14,16 +14,10 @@ * limitations under the License. */ -import { Extension, ExtensionOverrides } from '@backstage/frontend-plugin-api'; -// eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { toInternalExtensionOverrides } from '../../../frontend-plugin-api/src/wiring/createExtensionOverrides'; +import { Extension } from '@backstage/frontend-plugin-api'; import { ExtensionParameters } from './readAppExtensionsConfig'; import { AppNodeSpec } from '@backstage/frontend-plugin-api'; -// eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { - isInternalFrontendPlugin, - toInternalFrontendPlugin, -} from '../../../frontend-plugin-api/src/wiring/createFrontendPlugin'; +import { OpaqueFrontendPlugin } from '@internal/frontend'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports import { isInternalFrontendModule, @@ -47,18 +41,16 @@ export function resolveAppNodeSpecs(options: { features = [], } = options; - const plugins = features.filter(isInternalFrontendPlugin); - const overrides = features.filter( - (f): f is ExtensionOverrides => - f.$$type === '@backstage/ExtensionOverrides', - ); + const plugins = features.filter(OpaqueFrontendPlugin.isType); const modules = features.filter(isInternalFrontendModule); const pluginExtensions = plugins.flatMap(source => { - return toInternalFrontendPlugin(source).extensions.map(extension => ({ - ...extension, - source, - })); + return OpaqueFrontendPlugin.toInternal(source).extensions.map( + extension => ({ + ...extension, + source, + }), + ); }); const moduleExtensions = modules.flatMap(mod => toInternalFrontendModule(mod).extensions.flatMap(extension => { @@ -71,9 +63,6 @@ export function resolveAppNodeSpecs(options: { return [{ ...extension, source }]; }), ); - const overrideExtensions = overrides.flatMap( - override => toInternalExtensionOverrides(override).extensions, - ); // Prevent core override if (pluginExtensions.some(({ id }) => forbidden.has(id))) { @@ -96,28 +85,6 @@ export function resolveAppNodeSpecs(options: { `It is forbidden to override the following extension(s): ${forbiddenStr}, which is done by a module for the following plugin(s): ${pluginsStr}`, ); } - if (overrideExtensions.some(({ id }) => forbidden.has(id))) { - const forbiddenStr = [...forbidden].map(id => `'${id}'`).join(', '); - throw new Error( - `It is forbidden to override the following extension(s): ${forbiddenStr}, which is done by one or more extension overrides`, - ); - } - - const overrideExtensionIds = overrideExtensions.map(({ id }) => id); - if (overrideExtensionIds.length !== new Set(overrideExtensionIds).size) { - const counts = new Map(); - for (const id of overrideExtensionIds) { - counts.set(id, (counts.get(id) ?? 0) + 1); - } - const duplicated = Array.from(counts.entries()) - .filter(([, count]) => count > 1) - .map(([id]) => id); - throw new Error( - `The following extensions had duplicate overrides: ${duplicated.join( - ', ', - )}`, - ); - } const configuredExtensions = [ ...pluginExtensions.map(({ source, ...extension }) => { @@ -146,33 +113,6 @@ export function resolveAppNodeSpecs(options: { }), ]; - // Install all extension overrides - for (const extension of overrideExtensions) { - const internalExtension = toInternalExtension(extension); - - // Check if our override is overriding an extension that already exists - const index = configuredExtensions.findIndex( - e => e.extension.id === extension.id, - ); - if (index !== -1) { - // Only implementation, attachment point and default disabled status are overridden, the source is kept - configuredExtensions[index].extension = internalExtension; - configuredExtensions[index].params.attachTo = internalExtension.attachTo; - configuredExtensions[index].params.disabled = internalExtension.disabled; - } else { - // Add the extension as a new one when not overriding an existing one - configuredExtensions.push({ - extension: internalExtension, - params: { - source: undefined, - attachTo: internalExtension.attachTo, - disabled: internalExtension.disabled, - config: undefined, - }, - }); - } - } - // Install all module overrides for (const extension of moduleExtensions) { const internalExtension = toInternalExtension(extension); diff --git a/packages/frontend-app-api/src/wiring/createSpecializedApp.test.tsx b/packages/frontend-app-api/src/wiring/createSpecializedApp.test.tsx index e98014f273..72594cefd1 100644 --- a/packages/frontend-app-api/src/wiring/createSpecializedApp.test.tsx +++ b/packages/frontend-app-api/src/wiring/createSpecializedApp.test.tsx @@ -25,6 +25,7 @@ import { createExternalRouteRef, createExtensionInput, useRouteRef, + analyticsApiRef, } from '@backstage/frontend-plugin-api'; import { screen, render } from '@testing-library/react'; import { createSpecializedApp } from './createSpecializedApp'; @@ -167,6 +168,75 @@ describe('createSpecializedApp', () => { expect(screen.getByText('flags:test=a,test=b')).toBeInTheDocument(); }); + it('should intitialize the APIs in the correct order to allow for overrides', () => { + const mockAnalyticsApi = jest.fn(() => ({ captureEvent: jest.fn() })); + + const app = createSpecializedApp({ + features: [ + createFrontendPlugin({ + id: 'first', + extensions: [ + ApiBlueprint.make({ + params: { + factory: createApiFactory({ + api: analyticsApiRef, + deps: {}, + factory: () => { + throw new Error('BROKEN'); + }, + }), + }, + }), + ], + }), + createFrontendPlugin({ + id: 'test', + featureFlags: [{ name: 'a' }, { name: 'b' }], + extensions: [ + createExtension({ + attachTo: { id: 'root', input: 'app' }, + output: [coreExtensionData.reactElement], + factory: ({ apis }) => { + const Component = () => { + const analytics = apis.get(analyticsApiRef); + return ( + // eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions +
+ analytics!.captureEvent({ + action: 'asd', + subject: 'asd', + context: { extensionId: 'asd', pluginId: 'asd' }, + }) + } + > + Click me +
+ ); + }; + + return [coreExtensionData.reactElement()]; + }, + }), + ApiBlueprint.make({ + params: { + factory: createApiFactory({ + api: analyticsApiRef, + deps: {}, + factory: mockAnalyticsApi, + }), + }, + }), + ], + }), + ], + }); + + render(app.createRoot()); + + expect(mockAnalyticsApi).toHaveBeenCalled(); + }); + it('should make the app structure available through the AppTreeApi', async () => { let appTreeApi: AppTreeApi | undefined = undefined; diff --git a/packages/frontend-app-api/src/wiring/createSpecializedApp.tsx b/packages/frontend-app-api/src/wiring/createSpecializedApp.tsx index 612befc597..e3f06a896d 100644 --- a/packages/frontend-app-api/src/wiring/createSpecializedApp.tsx +++ b/packages/frontend-app-api/src/wiring/createSpecializedApp.tsx @@ -41,13 +41,8 @@ import { identityApiRef, } from '@backstage/core-plugin-api'; import { ApiFactoryRegistry, ApiResolver } from '@backstage/core-app-api'; +import { OpaqueFrontendPlugin } from '@internal/frontend'; -// TODO: Get rid of all of these - -import { - createApp as _createApp, - CreateAppFeatureLoader as _CreateAppFeatureLoader, -} from '@backstage/frontend-defaults'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports import { resolveExtensionDefinition } from '../../../frontend-plugin-api/src/wiring/resolveExtensionDefinition'; @@ -58,17 +53,10 @@ import { RouteResolver } from '../routing/RouteResolver'; import { resolveRouteBindings } from '../routing/resolveRouteBindings'; import { collectRouteIds } from '../routing/collectRouteIds'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { - toInternalFrontendPlugin, - isInternalFrontendPlugin, -} from '../../../frontend-plugin-api/src/wiring/createFrontendPlugin'; -// eslint-disable-next-line @backstage/no-relative-monorepo-imports import { toInternalFrontendModule, isInternalFrontendModule, } from '../../../frontend-plugin-api/src/wiring/createFrontendModule'; -// eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { toInternalExtensionOverrides } from '../../../frontend-plugin-api/src/wiring/createExtensionOverrides'; import { getBasePath } from '../routing/getBasePath'; import { Root } from '../extensions/Root'; import { resolveAppTree } from '../tree/resolveAppTree'; @@ -93,7 +81,7 @@ function deduplicateFeatures( return features .reverse() .filter(feature => { - if (!isInternalFrontendPlugin(feature)) { + if (!OpaqueFrontendPlugin.isType(feature)) { return true; } if (seenIds.has(feature.id)) { @@ -174,19 +162,6 @@ class RouteResolutionApiProxy implements RouteResolutionApi { return this.#routeObjects; } } - -/** - * @public - * @deprecated Import from `@backstage/frontend-defaults` instead. - */ -export const createApp = _createApp; - -/** - * @public - * @deprecated Import from `@backstage/frontend-defaults` instead. - */ -export type CreateAppFeatureLoader = _CreateAppFeatureLoader; - /** * Creates an empty app without any default features. This is a low-level API is * intended for use in tests or specialized setups. Typically wou want to use @@ -240,8 +215,8 @@ export function createSpecializedApp(options?: { const featureFlagApi = apiHolder.get(featureFlagsApiRef); if (featureFlagApi) { for (const feature of features) { - if (isInternalFrontendPlugin(feature)) { - toInternalFrontendPlugin(feature).featureFlags.forEach(flag => + if (OpaqueFrontendPlugin.isType(feature)) { + OpaqueFrontendPlugin.toInternal(feature).featureFlags.forEach(flag => featureFlagApi.registerFlag({ name: flag.name, pluginId: feature.id, @@ -256,11 +231,6 @@ export function createSpecializedApp(options?: { }), ); } - if (feature.$$type === '@backstage/ExtensionOverrides') { - toInternalExtensionOverrides(feature).featureFlags.forEach(flag => - featureFlagApi.registerFlag({ name: flag.name, pluginId: '' }), - ); - } } } @@ -305,7 +275,7 @@ function createApiHolder(options: { }): ApiHolder { const factoryRegistry = new ApiFactoryRegistry(); - for (const factory of options.factories) { + for (const factory of options.factories.slice().reverse()) { factoryRegistry.register('default', factory); } diff --git a/packages/frontend-app-api/src/wiring/index.ts b/packages/frontend-app-api/src/wiring/index.ts index d76055f63b..4ecce3f184 100644 --- a/packages/frontend-app-api/src/wiring/index.ts +++ b/packages/frontend-app-api/src/wiring/index.ts @@ -14,9 +14,5 @@ * limitations under the License. */ -export { - createApp, - createSpecializedApp, - type CreateAppFeatureLoader, -} from './createSpecializedApp'; +export { createSpecializedApp } from './createSpecializedApp'; export * from './types'; diff --git a/packages/frontend-defaults/CHANGELOG.md b/packages/frontend-defaults/CHANGELOG.md index 79ea0d79eb..0c4066f25c 100644 --- a/packages/frontend-defaults/CHANGELOG.md +++ b/packages/frontend-defaults/CHANGELOG.md @@ -1,5 +1,57 @@ # @backstage/frontend-defaults +## 0.1.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.1 + - @backstage/frontend-app-api@0.10.0-next.1 + - @backstage/plugin-app@0.1.1-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## 0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/frontend-app-api@0.10.0-next.0 + - @backstage/plugin-app@0.1.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## 0.1.0 + +### Minor Changes + +- 7c80650: Initial release of this package, which provides a default app setup through the `createApp` function. This replaces the existing `createApp` method from `@backstage/frontend-app-api`. + +### Patch Changes + +- 7d19cd5: Added a new `CreateAppOptions` type for the `createApp` options. +- 7d19cd5: Added `createPublicSignInApp`, used to creating apps for the public entry point. +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0 + - @backstage/frontend-app-api@0.9.0 + - @backstage/plugin-app@0.1.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## 0.1.0-next.1 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/plugin-app@0.1.0-next.2 + - @backstage/frontend-app-api@0.9.0-next.2 + - @backstage/frontend-plugin-api@0.8.0-next.2 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + ## 0.1.0-next.0 ### Minor Changes diff --git a/packages/frontend-defaults/package.json b/packages/frontend-defaults/package.json index 7f00371525..8f502274fa 100644 --- a/packages/frontend-defaults/package.json +++ b/packages/frontend-defaults/package.json @@ -1,9 +1,9 @@ { "name": "@backstage/frontend-defaults", - "version": "0.1.0-next.0", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "version": "0.1.1-next.1", + "backstage": { + "role": "web-library" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", @@ -14,39 +14,50 @@ "url": "https://github.com/backstage/backstage", "directory": "packages/frontend-defaults" }, - "backstage": { - "role": "web-library" - }, + "license": "Apache-2.0", "sideEffects": false, - "scripts": { - "start": "backstage-cli package start", - "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", - "clean": "backstage-cli package clean", - "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" - }, - "devDependencies": { - "@backstage/cli": "workspace:^", - "@backstage/core-plugin-api": "workspace:^", - "@backstage/test-utils": "workspace:^", - "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^15.0.0" - }, + "main": "src/index.ts", + "types": "src/index.ts", "files": [ "dist" ], + "scripts": { + "build": "backstage-cli package build", + "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" + }, "dependencies": { "@backstage/config": "workspace:^", "@backstage/errors": "workspace:^", "@backstage/frontend-app-api": "workspace:^", "@backstage/frontend-plugin-api": "workspace:^", "@backstage/plugin-app": "workspace:^", - "@react-hookz/web": "^24.0.0", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0" + "@react-hookz/web": "^24.0.0" + }, + "devDependencies": { + "@backstage/cli": "workspace:^", + "@backstage/core-plugin-api": "workspace:^", + "@backstage/test-utils": "workspace:^", + "@testing-library/jest-dom": "^6.0.0", + "@testing-library/react": "^16.0.0", + "@types/react": "^18.0.0", + "react": "^18.0.2", + "react-dom": "^18.0.2", + "react-router-dom": "^6.3.0" }, "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0" + "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } } diff --git a/packages/frontend-defaults/api-report.md b/packages/frontend-defaults/report.api.md similarity index 79% rename from packages/frontend-defaults/api-report.md rename to packages/frontend-defaults/report.api.md index b99232b784..4822312294 100644 --- a/packages/frontend-defaults/api-report.md +++ b/packages/frontend-defaults/report.api.md @@ -40,4 +40,10 @@ export interface CreateAppOptions { export function createPublicSignInApp(options?: CreateAppOptions): { createRoot(): React_2.JSX.Element; }; + +// Warnings were encountered during analysis: +// +// src/createApp.d.ts:29:5 - (ae-undocumented) Missing documentation for "features". +// src/createApp.d.ts:30:5 - (ae-undocumented) Missing documentation for "configLoader". +// src/createApp.d.ts:33:5 - (ae-undocumented) Missing documentation for "bindRoutes". ``` diff --git a/packages/frontend-internal/.eslintrc.js b/packages/frontend-internal/.eslintrc.js new file mode 100644 index 0000000000..e487f765b2 --- /dev/null +++ b/packages/frontend-internal/.eslintrc.js @@ -0,0 +1,5 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname, { + rules: { + '@backstage/no-top-level-material-ui-4-imports': 'error', + }, +}); diff --git a/packages/frontend-internal/CHANGELOG.md b/packages/frontend-internal/CHANGELOG.md new file mode 100644 index 0000000000..8c8025ae27 --- /dev/null +++ b/packages/frontend-internal/CHANGELOG.md @@ -0,0 +1,37 @@ +# @internal/frontend + +## 0.0.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.1 + - @backstage/version-bridge@1.0.10-next.0 + - @backstage/types@1.1.1 + +## 0.0.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.9 + +## 0.0.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0 + - @backstage/version-bridge@1.0.9 + - @backstage/types@1.1.1 + +## 0.0.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0-next.2 + - @backstage/version-bridge@1.0.9-next.0 + - @backstage/types@1.1.1 diff --git a/packages/frontend-internal/README.md b/packages/frontend-internal/README.md new file mode 100644 index 0000000000..72e54f21cf --- /dev/null +++ b/packages/frontend-internal/README.md @@ -0,0 +1,3 @@ +# @internal/frontend + +This is an internal package used by the other frontend packages. It does not get published to NPM, but instead inlined into consuming packages due to the `backstage.inline` flag in `package.json`. diff --git a/packages/frontend-internal/catalog-info.yaml b/packages/frontend-internal/catalog-info.yaml new file mode 100644 index 0000000000..630f53275a --- /dev/null +++ b/packages/frontend-internal/catalog-info.yaml @@ -0,0 +1,9 @@ +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: internal-frontend + title: '@internal/frontend' +spec: + lifecycle: experimental + type: backstage-web-library + owner: maintainers diff --git a/packages/frontend-internal/package.json b/packages/frontend-internal/package.json new file mode 100644 index 0000000000..7abaee7b0d --- /dev/null +++ b/packages/frontend-internal/package.json @@ -0,0 +1,39 @@ +{ + "name": "@internal/frontend", + "version": "0.0.2-next.1", + "backstage": { + "role": "web-library", + "inline": true + }, + "private": true, + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "packages/frontend-internal" + }, + "license": "Apache-2.0", + "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], + "scripts": { + "lint": "backstage-cli package lint", + "test": "backstage-cli package test" + }, + "dependencies": { + "@backstage/frontend-plugin-api": "workspace:^", + "@backstage/types": "workspace:^", + "@backstage/version-bridge": "workspace:^", + "zod": "^3.22.4" + }, + "devDependencies": { + "@backstage/cli": "workspace:^", + "@backstage/frontend-app-api": "workspace:^", + "@backstage/frontend-test-utils": "workspace:^", + "@backstage/test-utils": "workspace:^", + "@testing-library/jest-dom": "^6.0.0", + "@testing-library/react": "^16.0.0" + } +} diff --git a/packages/backend-common/src/setupTests.ts b/packages/frontend-internal/src/index.ts similarity index 89% rename from packages/backend-common/src/setupTests.ts rename to packages/frontend-internal/src/index.ts index d3232290a7..a5728f2ff6 100644 --- a/packages/backend-common/src/setupTests.ts +++ b/packages/frontend-internal/src/index.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. @@ -14,4 +14,4 @@ * limitations under the License. */ -export {}; +export * from './wiring'; diff --git a/packages/frontend-internal/src/wiring/InternalExtensionDefinition.ts b/packages/frontend-internal/src/wiring/InternalExtensionDefinition.ts new file mode 100644 index 0000000000..12027e0bb6 --- /dev/null +++ b/packages/frontend-internal/src/wiring/InternalExtensionDefinition.ts @@ -0,0 +1,94 @@ +/* + * 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 { + AnyExtensionDataRef, + ApiHolder, + AppNode, + ExtensionDataValue, + ExtensionDefinition, + ExtensionDefinitionParameters, + ExtensionInput, + PortableSchema, + ResolvedExtensionInputs, +} from '@backstage/frontend-plugin-api'; +import { OpaqueType } from '@internal/opaque'; + +export const OpaqueExtensionDefinition = OpaqueType.create<{ + public: ExtensionDefinition; + versions: + | { + readonly version: 'v1'; + readonly kind?: string; + readonly namespace?: string; + readonly name?: string; + readonly attachTo: { id: string; input: string }; + readonly disabled: boolean; + readonly configSchema?: PortableSchema; + readonly inputs: { + [inputName in string]: { + $$type: '@backstage/ExtensionInput'; + extensionData: { + [name in string]: AnyExtensionDataRef; + }; + config: { optional: boolean; singleton: boolean }; + }; + }; + readonly output: { + [name in string]: AnyExtensionDataRef; + }; + factory(context: { + node: AppNode; + apis: ApiHolder; + config: object; + inputs: { + [inputName in string]: unknown; + }; + }): { + [inputName in string]: unknown; + }; + } + | { + readonly version: 'v2'; + readonly kind?: string; + readonly namespace?: string; + readonly name?: string; + readonly attachTo: { id: string; input: string }; + readonly disabled: boolean; + readonly configSchema?: PortableSchema; + readonly inputs: { + [inputName in string]: ExtensionInput< + AnyExtensionDataRef, + { optional: boolean; singleton: boolean } + >; + }; + readonly output: Array; + factory(context: { + node: AppNode; + apis: ApiHolder; + config: object; + inputs: ResolvedExtensionInputs<{ + [inputName in string]: ExtensionInput< + AnyExtensionDataRef, + { optional: boolean; singleton: boolean } + >; + }>; + }): Iterable>; + }; +}>({ + type: '@backstage/ExtensionDefinition', + versions: ['v1', 'v2'], +}); diff --git a/packages/frontend-internal/src/wiring/InternalFrontendPlugin.ts b/packages/frontend-internal/src/wiring/InternalFrontendPlugin.ts new file mode 100644 index 0000000000..a7be9614b6 --- /dev/null +++ b/packages/frontend-internal/src/wiring/InternalFrontendPlugin.ts @@ -0,0 +1,34 @@ +/* + * 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 { + Extension, + FeatureFlagConfig, + FrontendPlugin, +} from '@backstage/frontend-plugin-api'; +import { OpaqueType } from '@internal/opaque'; + +export const OpaqueFrontendPlugin = OpaqueType.create<{ + public: FrontendPlugin; + versions: { + readonly version: 'v1'; + readonly extensions: Extension[]; + readonly featureFlags: FeatureFlagConfig[]; + }; +}>({ + type: '@backstage/FrontendPlugin', + versions: ['v1'], +}); diff --git a/packages/frontend-internal/src/wiring/index.ts b/packages/frontend-internal/src/wiring/index.ts new file mode 100644 index 0000000000..37e012a9d3 --- /dev/null +++ b/packages/frontend-internal/src/wiring/index.ts @@ -0,0 +1,18 @@ +/* + * 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. + */ + +export { OpaqueExtensionDefinition } from './InternalExtensionDefinition'; +export { OpaqueFrontendPlugin } from './InternalFrontendPlugin'; diff --git a/packages/frontend-plugin-api/CHANGELOG.md b/packages/frontend-plugin-api/CHANGELOG.md index e16c08ac7a..bb73a4ffd7 100644 --- a/packages/frontend-plugin-api/CHANGELOG.md +++ b/packages/frontend-plugin-api/CHANGELOG.md @@ -1,5 +1,179 @@ # @backstage/frontend-plugin-api +## 0.9.0-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/version-bridge@1.0.10-next.0 + - @backstage/types@1.1.1 + +## 0.9.0-next.0 + +### Minor Changes + +- 4a5ba19: Removed deprecated `namespace` option from `createExtension` and `createExtensionBlueprint`, including `.make` and `.makeWithOverides`, it's no longer necessary and will use the `pluginId` instead. + + Removed deprecated `createExtensionOverrides` this should be replaced with `createFrontendModule` instead. + + Removed deprecated `BackstagePlugin` type, use `FrontendPlugin` type instead from this same package. + +- bfd4bec: **BREAKING PRODUCERS**: The `IconComponent` no longer accepts `fontSize="default"`. This has effectively been removed from Material-UI since its last two major versions, and has not worked properly for them in a long time. + + This change should not have an effect on neither users of MUI4 nor MUI5/6, since the updated interface should still let you send the respective `SvgIcon` types into interfaces where relevant (e.g. as app icons). + +### Patch Changes + +- 873e424: Internal refactor of usage of opaque types. +- 323aae8: It is now possible to override the blueprint parameters when overriding an extension created from a blueprint: + + ```ts + const myExtension = MyBlueprint.make({ + params: { + myParam: 'myDefault', + }, + }); + + const myOverride = myExtension.override({ + params: { + myParam: 'myOverride', + }, + }); + const myFactoryOverride = myExtension.override({ + factory(origFactory) { + return origFactory({ + params: { + myParam: 'myOverride', + }, + }); + }, + }); + ``` + + The provided parameters will be merged with the original parameters of the extension. + +- Updated dependencies + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.9 + +## 0.8.0 + +### Minor Changes + +- 5446061: **BREAKING**: Removed support for "v1" extensions. This means that it is no longer possible to declare inputs and outputs as objects when using `createExtension`. In addition, all extension creators except for `createComponentExtension` have been removed, use the equivalent blueprint instead. See the [1.30 migration documentation](https://backstage.io/docs/frontend-system/architecture/migrations/#130) for more information on this change. +- fec8b57: **BREAKING**: Updated the type parameters for `ExtensionDefinition` and `ExtensionBlueprint` to only have a single object parameter. The base type parameter is exported as `ExtensionDefinitionParameters` and `ExtensionBlueprintParameters` respectively. This is shipped as an immediate breaking change as we expect usage of these types to be rare, and it does not affect the runtime behavior of the API. + + This is a breaking change as it changes the type parameters. Existing usage can generally be updated as follows: + + - `ExtensionDefinition` -> `ExtensionDefinition` + - `ExtensionDefinition` -> `ExtensionDefinition` + - `ExtensionDefinition` -> `ExtensionDefinition<{ config: TConfig }>` + - `ExtensionDefinition` -> `ExtensionDefinition<{ config: TConfig, configInput: TConfigInput }>` + + If you need to infer the parameter you can use `ExtensionDefinitionParameters`, for example: + + ```ts + import { + ExtensionDefinition, + ExtensionDefinitionParameters, + } from '@backstage/frontend-plugin-api'; + + function myUtility( + ext: ExtensionDefinition, + ): T['config'] { + // ... + } + ``` + + The same patterns apply to `ExtensionBlueprint`. + + This change is made to improve the readability of API references and ability to evolve the type parameters in the future. + +### Patch Changes + +- 2bb9517: Introduce the `@backstage/plugin-app` package to hold all of the built-in extensions for easy consumption and overriding. +- c816e2d: Added `createFrontendModule` as a replacement for `createExtensionOverrides`, which is now deprecated. + + Deprecated the `BackstagePlugin` and `FrontendFeature` type in favor of `FrontendPlugin` and `FrontendFeature` from `@backstage/frontend-app-api` respectively. + +- 52f9c5a: Deprecated the `namespace` option for `createExtensionBlueprint` and `createExtension`, these are no longer required and will default to the `pluginId` instead. + + You can migrate some of your extensions that use `createExtensionOverrides` to using `createFrontendModule` instead and providing a `pluginId` there. + + ```ts + // Before + createExtensionOverrides({ + extensions: [ + createExtension({ + name: 'my-extension', + namespace: 'my-namespace', + kind: 'test', + ... + }) + ], + }); + + // After + createFrontendModule({ + pluginId: 'my-namespace', + extensions: [ + createExtension({ + name: 'my-extension', + kind: 'test', + ... + }) + ], + }); + ``` + +- f3a2b91: Moved several implementations of built-in APIs from being hardcoded in the app to instead be provided as API extensions. This moves all API-related inputs from the `app` extension to the respective API extensions. For example, extensions created with `ThemeBlueprint` are now attached to the `themes` input of `api:app-theme` rather than the `app` extension. +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- 948d431: Removing deprecated `namespace` parameter in favour of `pluginId` instead +- 043d7cd: Internal refactor +- 220f4f7: Remove unnecessary config object on IconBundleBlueprint +- 2a61422: The `factory` option is no longer required when overriding an extension. +- 98850de: Added support for defining `replaces` in `createExtensionInput` which will allow extensions to redirect missing `attachTo` points to an input of the created extension. + + ```ts + export const AppThemeApi = ApiBlueprint.makeWithOverrides({ + name: 'app-theme', + inputs: { + themes: createExtensionInput([ThemeBlueprint.dataRefs.theme], { + // attachTo: { id: 'app', input: 'themes'} will be redirected to this input instead + replaces: [{ id: 'app', input: 'themes' }], + }), + }, + factory: () { + ... + } + }); + ``` + +- 4a66456: A new `apis` parameter has been added to `factory` for extensions. This is a way to access utility APIs without being coupled to the React context. +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/version-bridge@1.0.9 + - @backstage/types@1.1.1 + +## 0.8.0-next.2 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- 043d7cd: Internal refactor +- 2a61422: The `factory` option is no longer required when overriding an extension. +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/version-bridge@1.0.9-next.0 + - @backstage/types@1.1.1 + ## 0.8.0-next.1 ### Patch Changes diff --git a/packages/frontend-plugin-api/package.json b/packages/frontend-plugin-api/package.json index 55168aed65..834006a45c 100644 --- a/packages/frontend-plugin-api/package.json +++ b/packages/frontend-plugin-api/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/frontend-plugin-api", - "version": "0.8.0-next.1", + "version": "0.9.0-next.1", "backstage": { "role": "web-library" }, @@ -36,7 +36,6 @@ "@backstage/types": "workspace:^", "@backstage/version-bridge": "workspace:^", "@material-ui/core": "^4.12.4", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "lodash": "^4.17.21", "zod": "^3.22.4", "zod-to-json-schema": "^3.21.4" @@ -47,11 +46,22 @@ "@backstage/frontend-test-utils": "workspace:^", "@backstage/test-utils": "workspace:^", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^15.0.0", - "history": "^5.3.0" + "@testing-library/react": "^16.0.0", + "@types/react": "^18.0.0", + "history": "^5.3.0", + "react": "^18.0.2", + "react-dom": "^18.0.2", + "react-router-dom": "^6.3.0" }, "peerDependencies": { + "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } } diff --git a/packages/frontend-plugin-api/api-report.md b/packages/frontend-plugin-api/report.api.md similarity index 76% rename from packages/frontend-plugin-api/api-report.md rename to packages/frontend-plugin-api/report.api.md index 75d91d28f0..5bc2a663d7 100644 --- a/packages/frontend-plugin-api/api-report.md +++ b/packages/frontend-plugin-api/report.api.md @@ -174,7 +174,6 @@ export type AnyRoutes = { // @public export const ApiBlueprint: ExtensionBlueprint<{ kind: 'api'; - namespace: undefined; name: undefined; params: { factory: AnyApiFactory; @@ -240,13 +239,12 @@ export interface AppNodeSpec { // (undocumented) readonly id: string; // (undocumented) - readonly source?: BackstagePlugin; + readonly source?: FrontendPlugin; } // @public export const AppRootElementBlueprint: ExtensionBlueprint<{ kind: 'app-root-element'; - namespace: undefined; name: undefined; params: { element: JSX.Element | (() => JSX.Element); @@ -261,7 +259,6 @@ export const AppRootElementBlueprint: ExtensionBlueprint<{ // @public export const AppRootWrapperBlueprint: ExtensionBlueprint<{ kind: 'app-root-wrapper'; - namespace: undefined; name: undefined; params: { Component: ComponentType>; @@ -320,15 +317,6 @@ export { BackstageIdentityApi }; export { BackstageIdentityResponse }; -// @public @deprecated (undocumented) -export type BackstagePlugin< - TRoutes extends AnyRoutes = AnyRoutes, - TExternalRoutes extends AnyExternalRoutes = AnyExternalRoutes, - TExtensionMap extends { - [id in string]: ExtensionDefinition; - } = {}, -> = FrontendPlugin; - export { BackstageUserIdentity }; export { bitbucketAuthApiRef }; @@ -389,7 +377,7 @@ export const coreComponentRefs: { // @public (undocumented) export type CoreErrorBoundaryFallbackProps = { - plugin?: BackstagePlugin; + plugin?: FrontendPlugin; error: Error; resetError: () => void; }; @@ -453,8 +441,8 @@ export function createComponentExtension(options: { } >; }; + params: never; kind: 'component'; - namespace: undefined; name: string; }>; @@ -493,12 +481,10 @@ export function createExtension< }, UFactoryOutput extends ExtensionDataValue, const TKind extends string | undefined = undefined, - const TNamespace extends string | undefined = undefined, const TName extends string | undefined = undefined, >( options: CreateExtensionOptions< TKind, - undefined, TName, UOutput, TInputs, @@ -520,57 +506,8 @@ export function createExtension< >; output: UOutput; inputs: TInputs; + params: never; kind: string | undefined extends TKind ? undefined : TKind; - namespace: string | undefined extends TNamespace ? undefined : TNamespace; - name: string | undefined extends TName ? undefined : TName; -}>; - -// @public @deprecated (undocumented) -export function createExtension< - UOutput extends AnyExtensionDataRef, - TInputs extends { - [inputName in string]: ExtensionInput< - AnyExtensionDataRef, - { - optional: boolean; - singleton: boolean; - } - >; - }, - TConfigSchema extends { - [key: string]: (zImpl: typeof z) => z.ZodType; - }, - UFactoryOutput extends ExtensionDataValue, - const TKind extends string | undefined = undefined, - const TNamespace extends string | undefined = undefined, - const TName extends string | undefined = undefined, ->( - options: CreateExtensionOptions< - TKind, - TNamespace, - TName, - UOutput, - TInputs, - TConfigSchema, - UFactoryOutput - >, -): ExtensionDefinition<{ - config: string extends keyof TConfigSchema - ? {} - : { - [key in keyof TConfigSchema]: z.infer>; - }; - configInput: string extends keyof TConfigSchema - ? {} - : z.input< - z.ZodObject<{ - [key in keyof TConfigSchema]: ReturnType; - }> - >; - output: UOutput; - inputs: TInputs; - kind: string | undefined extends TKind ? undefined : TKind; - namespace: string | undefined extends TNamespace ? undefined : TNamespace; name: string | undefined extends TName ? undefined : TName; }>; @@ -592,7 +529,6 @@ export function createExtensionBlueprint< }, UFactoryOutput extends ExtensionDataValue, TKind extends string, - TNamespace extends undefined = undefined, TName extends string | undefined = undefined, TDataRefs extends { [name in string]: AnyExtensionDataRef; @@ -600,7 +536,6 @@ export function createExtensionBlueprint< >( options: CreateExtensionBlueprintOptions< TKind, - undefined, TName, TParams, UOutput, @@ -611,64 +546,6 @@ export function createExtensionBlueprint< >, ): ExtensionBlueprint<{ kind: TKind; - namespace: undefined; - name: TName; - params: TParams; - output: UOutput; - inputs: string extends keyof TInputs ? {} : TInputs; - config: string extends keyof TConfigSchema - ? {} - : { - [key in keyof TConfigSchema]: z.infer>; - }; - configInput: string extends keyof TConfigSchema - ? {} - : z.input< - z.ZodObject<{ - [key in keyof TConfigSchema]: ReturnType; - }> - >; - dataRefs: TDataRefs; -}>; - -// @public @deprecated (undocumented) -export function createExtensionBlueprint< - TParams extends object, - UOutput extends AnyExtensionDataRef, - TInputs extends { - [inputName in string]: ExtensionInput< - AnyExtensionDataRef, - { - optional: boolean; - singleton: boolean; - } - >; - }, - TConfigSchema extends { - [key in string]: (zImpl: typeof z) => z.ZodType; - }, - UFactoryOutput extends ExtensionDataValue, - TKind extends string, - TNamespace extends string | undefined = undefined, - TName extends string | undefined = undefined, - TDataRefs extends { - [name in string]: AnyExtensionDataRef; - } = never, ->( - options: CreateExtensionBlueprintOptions< - TKind, - TNamespace, - TName, - TParams, - UOutput, - TInputs, - TConfigSchema, - UFactoryOutput, - TDataRefs - >, -): ExtensionBlueprint<{ - kind: TKind; - namespace: TNamespace; name: TName; params: TParams; output: UOutput; @@ -691,7 +568,6 @@ export function createExtensionBlueprint< // @public (undocumented) export type CreateExtensionBlueprintOptions< TKind extends string, - TNamespace extends string | undefined, TName extends string | undefined, TParams, UOutput extends AnyExtensionDataRef, @@ -713,7 +589,6 @@ export type CreateExtensionBlueprintOptions< }, > = { kind: TKind; - namespace?: TNamespace; attachTo: { id: string; input: string; @@ -783,7 +658,6 @@ export function createExtensionInput< // @public (undocumented) export type CreateExtensionOptions< TKind extends string | undefined, - TNamespace extends string | undefined, TName extends string | undefined, UOutput extends AnyExtensionDataRef, TInputs extends { @@ -801,7 +675,6 @@ export type CreateExtensionOptions< UFactoryOutput extends ExtensionDataValue, > = { kind?: TKind; - namespace?: TNamespace; name?: TName; attachTo: { id: string; @@ -823,11 +696,6 @@ export type CreateExtensionOptions< }): Iterable; } & VerifyExtensionFactoryOutput; -// @public @deprecated (undocumented) -export function createExtensionOverrides( - options: ExtensionOverridesOptions, -): ExtensionOverrides; - // @public export function createExternalRouteRef< TParams extends @@ -889,9 +757,6 @@ export function createFrontendPlugin< } >; -// @public @deprecated (undocumented) -export const createPlugin: typeof createFrontendPlugin; - // @public export function createRouteRef< TParams extends @@ -963,11 +828,7 @@ export interface ExtensionBlueprint< // (undocumented) dataRefs: T['dataRefs']; // (undocumented) - make< - TNewNamespace extends string | undefined, - TNewName extends string | undefined, - >(args: { - namespace?: undefined; + make(args: { name?: TNewName; attachTo?: { id: string; @@ -977,39 +838,14 @@ export interface ExtensionBlueprint< params: T['params']; }): ExtensionDefinition<{ kind: T['kind']; - namespace: undefined; name: string | undefined extends TNewName ? T['name'] : TNewName; config: T['config']; configInput: T['configInput']; output: T['output']; inputs: T['inputs']; - }>; - // @deprecated (undocumented) - make< - TNewNamespace extends string | undefined, - TNewName extends string | undefined, - >(args: { - namespace?: TNewNamespace; - name?: TNewName; - attachTo?: { - id: string; - input: string; - }; - disabled?: boolean; params: T['params']; - }): ExtensionDefinition<{ - kind: T['kind']; - namespace: string | undefined extends TNewNamespace - ? T['namespace'] - : TNewNamespace; - name: string | undefined extends TNewName ? T['name'] : TNewName; - config: T['config']; - configInput: T['configInput']; - output: T['output']; - inputs: T['inputs']; }>; makeWithOverrides< - TNewNamespace extends string | undefined, TNewName extends string | undefined, TExtensionConfigSchema extends { [key in string]: (zImpl: typeof z) => z.ZodType; @@ -1026,7 +862,6 @@ export interface ExtensionBlueprint< >; }, >(args: { - namespace?: undefined; name?: TNewName; attachTo?: { id: string; @@ -1091,104 +926,14 @@ export interface ExtensionBlueprint< output: AnyExtensionDataRef extends UNewOutput ? T['output'] : UNewOutput; inputs: T['inputs'] & TExtraInputs; kind: T['kind']; - namespace: undefined; - name: string | undefined extends TNewName ? T['name'] : TNewName; - }>; - // @deprecated (undocumented) - makeWithOverrides< - TNewNamespace extends string | undefined, - TNewName extends string | undefined, - TExtensionConfigSchema extends { - [key in string]: (zImpl: typeof z) => z.ZodType; - }, - UFactoryOutput extends ExtensionDataValue, - UNewOutput extends AnyExtensionDataRef, - TExtraInputs extends { - [inputName in string]: ExtensionInput< - AnyExtensionDataRef, - { - optional: boolean; - singleton: boolean; - } - >; - }, - >(args: { - namespace: TNewNamespace; - name?: TNewName; - attachTo?: { - id: string; - input: string; - }; - disabled?: boolean; - inputs?: TExtraInputs & { - [KName in keyof T['inputs']]?: `Error: Input '${KName & - string}' is already defined in parent definition`; - }; - output?: Array; - config?: { - schema: TExtensionConfigSchema & { - [KName in keyof T['config']]?: `Error: Config key '${KName & - string}' is already defined in parent schema`; - }; - }; - factory( - originalFactory: ( - params: T['params'], - context?: { - config?: T['config']; - inputs?: ResolveInputValueOverrides>; - }, - ) => ExtensionDataContainer>, - context: { - node: AppNode; - apis: ApiHolder; - config: T['config'] & { - [key in keyof TExtensionConfigSchema]: z.infer< - ReturnType - >; - }; - inputs: Expand>; - }, - ): Iterable & - VerifyExtensionFactoryOutput< - AnyExtensionDataRef extends UNewOutput - ? NonNullable - : UNewOutput, - UFactoryOutput - >; - }): ExtensionDefinition<{ - config: (string extends keyof TExtensionConfigSchema - ? {} - : { - [key in keyof TExtensionConfigSchema]: z.infer< - ReturnType - >; - }) & - T['config']; - configInput: (string extends keyof TExtensionConfigSchema - ? {} - : z.input< - z.ZodObject<{ - [key in keyof TExtensionConfigSchema]: ReturnType< - TExtensionConfigSchema[key] - >; - }> - >) & - T['configInput']; - output: AnyExtensionDataRef extends UNewOutput ? T['output'] : UNewOutput; - inputs: T['inputs'] & TExtraInputs; - kind: T['kind']; - namespace: string | undefined extends TNewNamespace - ? T['namespace'] - : TNewNamespace; name: string | undefined extends TNewName ? T['name'] : TNewName; + params: T['params']; }>; } // @public (undocumented) export type ExtensionBlueprintParameters = { kind: string; - namespace?: string; name?: string; params?: object; configInput?: { @@ -1306,48 +1051,62 @@ export type ExtensionDefinition< >; }, >( - args: { - attachTo?: { - id: string; - input: string; - }; - disabled?: boolean; - inputs?: TExtraInputs & { - [KName in keyof T['inputs']]?: `Error: Input '${KName & - string}' is already defined in parent definition`; - }; - output?: Array; - config?: { - schema: TExtensionConfigSchema & { - [KName in keyof T['config']]?: `Error: Config key '${KName & - string}' is already defined in parent schema`; + args: Expand< + { + attachTo?: { + id: string; + input: string; }; - }; - factory( - originalFactory: (context?: { - config?: T['config']; - inputs?: ResolveInputValueOverrides>; - }) => ExtensionDataContainer>, - context: { - node: AppNode; - apis: ApiHolder; - config: T['config'] & { - [key in keyof TExtensionConfigSchema]: z.infer< - ReturnType - >; + disabled?: boolean; + inputs?: TExtraInputs & { + [KName in keyof T['inputs']]?: `Error: Input '${KName & + string}' is already defined in parent definition`; + }; + output?: Array; + config?: { + schema: TExtensionConfigSchema & { + [KName in keyof T['config']]?: `Error: Config key '${KName & + string}' is already defined in parent schema`; }; - inputs: Expand>; - }, - ): Iterable; - } & VerifyExtensionFactoryOutput< - AnyExtensionDataRef extends UNewOutput - ? NonNullable - : UNewOutput, - UFactoryOutput - >, + }; + factory?( + originalFactory: ( + context?: Expand< + { + config?: T['config']; + inputs?: ResolveInputValueOverrides>; + } & ([T['params']] extends [never] + ? {} + : { + params?: Partial; + }) + >, + ) => ExtensionDataContainer>, + context: { + node: AppNode; + apis: ApiHolder; + config: T['config'] & { + [key in keyof TExtensionConfigSchema]: z.infer< + ReturnType + >; + }; + inputs: Expand>; + }, + ): Iterable; + } & ([T['params']] extends [never] + ? {} + : { + params?: Partial; + }) + > & + VerifyExtensionFactoryOutput< + AnyExtensionDataRef extends UNewOutput + ? NonNullable + : UNewOutput, + UFactoryOutput + >, ): ExtensionDefinition<{ kind: T['kind']; - namespace: T['namespace']; name: T['name']; output: AnyExtensionDataRef extends UNewOutput ? T['output'] : UNewOutput; inputs: T['inputs'] & TExtraInputs; @@ -1370,7 +1129,6 @@ export type ExtensionDefinition< // @public (undocumented) export type ExtensionDefinitionParameters = { kind?: string; - namespace?: string; name?: string; configInput?: { [K in string]: any; @@ -1388,6 +1146,7 @@ export type ExtensionDefinitionParameters = { } >; }; + params?: object; }; // @public (undocumented) @@ -1423,14 +1182,6 @@ export interface ExtensionOverrides { readonly $$type: '@backstage/ExtensionOverrides'; } -// @public @deprecated (undocumented) -export interface ExtensionOverridesOptions { - // (undocumented) - extensions: ExtensionDefinition[]; - // (undocumented) - featureFlags?: FeatureFlagConfig[]; -} - // @public export interface ExternalRouteRef< TParams extends AnyRouteRefParams = AnyRouteRefParams, @@ -1477,7 +1228,9 @@ export interface FrontendPlugin< TExternalRoutes extends AnyExternalRoutes = AnyExternalRoutes, TExtensionMap extends { [id in string]: ExtensionDefinition; - } = {}, + } = { + [id in string]: ExtensionDefinition; + }, > { // (undocumented) readonly $$type: '@backstage/FrontendPlugin'; @@ -1504,7 +1257,6 @@ export { googleAuthApiRef }; // @public (undocumented) export const IconBundleBlueprint: ExtensionBlueprint<{ kind: 'icon-bundle'; - namespace: undefined; name: undefined; params: { icons: { @@ -1519,14 +1271,8 @@ export const IconBundleBlueprint: ExtensionBlueprint<{ {} >; inputs: {}; - config: { - icons: string; - test: string; - }; - configInput: { - test: string; - icons?: string | undefined; - }; + config: {}; + configInput: {}; dataRefs: { icons: ConfigurableExtensionDataRef< { @@ -1539,14 +1285,9 @@ export const IconBundleBlueprint: ExtensionBlueprint<{ }>; // @public -export type IconComponent = ComponentType< - | { - fontSize?: 'large' | 'small' | 'default' | 'inherit'; - } - | { - fontSize?: 'medium' | 'large' | 'small' | 'inherit'; - } ->; +export type IconComponent = ComponentType<{ + fontSize?: 'medium' | 'large' | 'small' | 'inherit'; +}>; // @public export interface IconsApi { @@ -1568,7 +1309,6 @@ export { microsoftAuthApiRef }; // @public export const NavItemBlueprint: ExtensionBlueprint<{ kind: 'nav-item'; - namespace: undefined; name: undefined; params: { title: string; @@ -1603,7 +1343,6 @@ export const NavItemBlueprint: ExtensionBlueprint<{ // @public export const NavLogoBlueprint: ExtensionBlueprint<{ kind: 'nav-logo'; - namespace: undefined; name: undefined; params: { logoIcon: JSX.Element; @@ -1653,7 +1392,6 @@ export { OpenIdConnectApi }; // @public export const PageBlueprint: ExtensionBlueprint<{ kind: 'page'; - namespace: undefined; name: undefined; params: { defaultPath: string; @@ -1810,7 +1548,6 @@ export type RouteFunc = ( // @public (undocumented) export const RouterBlueprint: ExtensionBlueprint<{ kind: 'app-router-component'; - namespace: undefined; name: undefined; params: { Component: ComponentType>; @@ -1873,7 +1610,6 @@ export { SessionState }; // @public export const SignInPageBlueprint: ExtensionBlueprint<{ kind: 'sign-in-page'; - namespace: undefined; name: undefined; params: { loader: () => Promise>; @@ -1916,7 +1652,6 @@ export interface SubRouteRef< // @public export const ThemeBlueprint: ExtensionBlueprint<{ kind: 'theme'; - namespace: undefined; name: undefined; params: { theme: AppTheme; @@ -1933,7 +1668,6 @@ export const ThemeBlueprint: ExtensionBlueprint<{ // @public export const TranslationBlueprint: ExtensionBlueprint<{ kind: 'translation'; - namespace: undefined; name: undefined; params: { resource: TranslationResource | TranslationMessages; @@ -2013,4 +1747,106 @@ export { useTranslationRef }; export { vmwareCloudAuthApiRef }; export { withApis }; + +// Warnings were encountered during analysis: +// +// src/apis/definitions/AppTreeApi.d.ts:12:5 - (ae-undocumented) Missing documentation for "id". +// src/apis/definitions/AppTreeApi.d.ts:13:5 - (ae-undocumented) Missing documentation for "attachTo". +// src/apis/definitions/AppTreeApi.d.ts:17:5 - (ae-undocumented) Missing documentation for "extension". +// src/apis/definitions/AppTreeApi.d.ts:18:5 - (ae-undocumented) Missing documentation for "disabled". +// src/apis/definitions/AppTreeApi.d.ts:19:5 - (ae-undocumented) Missing documentation for "config". +// src/apis/definitions/AppTreeApi.d.ts:20:5 - (ae-undocumented) Missing documentation for "source". +// src/apis/definitions/AppTreeApi.d.ts:32:5 - (ae-undocumented) Missing documentation for "attachedTo". +// src/apis/definitions/AppTreeApi.d.ts:36:5 - (ae-undocumented) Missing documentation for "attachments". +// src/apis/definitions/ComponentsApi.d.ts:9:5 - (ae-undocumented) Missing documentation for "getComponent". +// src/apis/definitions/IconsApi.d.ts:8:5 - (ae-undocumented) Missing documentation for "getIcon". +// src/apis/definitions/IconsApi.d.ts:9:5 - (ae-undocumented) Missing documentation for "listIconKeys". +// src/apis/definitions/RouteResolutionApi.d.ts:19:1 - (ae-undocumented) Missing documentation for "RouteResolutionApiResolveOptions". +// src/apis/definitions/RouteResolutionApi.d.ts:29:1 - (ae-undocumented) Missing documentation for "RouteResolutionApi". +// src/apis/definitions/RouteResolutionApi.d.ts:30:5 - (ae-undocumented) Missing documentation for "resolve". +// src/blueprints/IconBundleBlueprint.d.ts:3:22 - (ae-undocumented) Missing documentation for "IconBundleBlueprint". +// src/blueprints/RouterBlueprint.d.ts:3:22 - (ae-undocumented) Missing documentation for "RouterBlueprint". +// src/components/ExtensionBoundary.d.ts:4:1 - (ae-undocumented) Missing documentation for "ExtensionBoundaryProps". +// src/components/ExtensionBoundary.d.ts:5:5 - (ae-undocumented) Missing documentation for "node". +// src/components/ExtensionBoundary.d.ts:12:5 - (ae-undocumented) Missing documentation for "children". +// src/components/ExtensionBoundary.d.ts:15:1 - (ae-undocumented) Missing documentation for "ExtensionBoundary". +// src/components/ExtensionBoundary.d.ts:17:1 - (ae-undocumented) Missing documentation for "ExtensionBoundary". +// src/components/ExtensionBoundary.d.ts:18:5 - (ae-undocumented) Missing documentation for "lazy". +// src/components/coreComponentRefs.d.ts:3:22 - (ae-undocumented) Missing documentation for "coreComponentRefs". +// src/components/createComponentRef.d.ts:2:1 - (ae-undocumented) Missing documentation for "ComponentRef". +// src/components/createComponentRef.d.ts:7:1 - (ae-undocumented) Missing documentation for "createComponentRef". +// src/extensions/createComponentExtension.d.ts:4:1 - (ae-undocumented) Missing documentation for "createComponentExtension". +// src/extensions/createComponentExtension.d.ts:31:1 - (ae-undocumented) Missing documentation for "createComponentExtension". +// src/extensions/createComponentExtension.d.ts:32:11 - (ae-undocumented) Missing documentation for "componentDataRef". +// src/routing/ExternalRouteRef.d.ts:12:5 - (ae-undocumented) Missing documentation for "$$type". +// src/routing/ExternalRouteRef.d.ts:13:5 - (ae-undocumented) Missing documentation for "T". +// src/routing/RouteRef.d.ts:12:5 - (ae-undocumented) Missing documentation for "$$type". +// src/routing/RouteRef.d.ts:13:5 - (ae-undocumented) Missing documentation for "T". +// src/routing/SubRouteRef.d.ts:13:5 - (ae-undocumented) Missing documentation for "$$type". +// src/routing/SubRouteRef.d.ts:14:5 - (ae-undocumented) Missing documentation for "T". +// src/routing/SubRouteRef.d.ts:15:5 - (ae-undocumented) Missing documentation for "path". +// src/schema/types.d.ts:3:1 - (ae-undocumented) Missing documentation for "PortableSchema". +// src/types.d.ts:11:1 - (ae-undocumented) Missing documentation for "CoreProgressProps". +// src/types.d.ts:13:1 - (ae-undocumented) Missing documentation for "CoreNotFoundErrorPageProps". +// src/types.d.ts:17:1 - (ae-undocumented) Missing documentation for "CoreErrorBoundaryFallbackProps". +// src/wiring/coreExtensionData.d.ts:4:22 - (ae-undocumented) Missing documentation for "coreExtensionData". +// src/wiring/createExtension.d.ts:31:1 - (ae-undocumented) Missing documentation for "CreateExtensionOptions". +// src/wiring/createExtension.d.ts:61:1 - (ae-undocumented) Missing documentation for "ExtensionDefinitionParameters". +// src/wiring/createExtension.d.ts:80:1 - (ae-undocumented) Missing documentation for "ExtensionDefinition". +// src/wiring/createExtension.d.ts:134:1 - (ae-undocumented) Missing documentation for "createExtension". +// src/wiring/createExtensionBlueprint.d.ts:12:1 - (ae-undocumented) Missing documentation for "CreateExtensionBlueprintOptions". +// src/wiring/createExtensionBlueprint.d.ts:45:1 - (ae-undocumented) Missing documentation for "ExtensionBlueprintParameters". +// src/wiring/createExtensionBlueprint.d.ts:69:1 - (ae-undocumented) Missing documentation for "ExtensionBlueprint". +// src/wiring/createExtensionBlueprint.d.ts:70:5 - (ae-undocumented) Missing documentation for "dataRefs". +// src/wiring/createExtensionBlueprint.d.ts:71:5 - (ae-undocumented) Missing documentation for "make". +// src/wiring/createExtensionDataContainer.d.ts:3:1 - (ae-undocumented) Missing documentation for "ExtensionDataContainer". +// src/wiring/createExtensionDataRef.d.ts:2:1 - (ae-undocumented) Missing documentation for "ExtensionDataValue". +// src/wiring/createExtensionDataRef.d.ts:8:1 - (ae-undocumented) Missing documentation for "ExtensionDataRef". +// src/wiring/createExtensionDataRef.d.ts:17:1 - (ae-undocumented) Missing documentation for "ExtensionDataRefToValue". +// src/wiring/createExtensionDataRef.d.ts:19:1 - (ae-undocumented) Missing documentation for "AnyExtensionDataRef". +// src/wiring/createExtensionDataRef.d.ts:23:1 - (ae-undocumented) Missing documentation for "ConfigurableExtensionDataRef". +// src/wiring/createExtensionDataRef.d.ts:26:5 - (ae-undocumented) Missing documentation for "optional". +// src/wiring/createExtensionDataRef.d.ts:29:5 - (ae-undocumented) Missing documentation for "__call". +// src/wiring/createExtensionDataRef.d.ts:35:1 - (ae-undocumented) Missing documentation for "createExtensionDataRef". +// src/wiring/createExtensionDataRef.d.ts:37:1 - (ae-undocumented) Missing documentation for "createExtensionDataRef". +// src/wiring/createExtensionInput.d.ts:3:1 - (ae-undocumented) Missing documentation for "ExtensionInput". +// src/wiring/createExtensionInput.d.ts:9:5 - (ae-undocumented) Missing documentation for "$$type". +// src/wiring/createExtensionInput.d.ts:10:5 - (ae-undocumented) Missing documentation for "extensionData". +// src/wiring/createExtensionInput.d.ts:11:5 - (ae-undocumented) Missing documentation for "config". +// src/wiring/createExtensionInput.d.ts:12:5 - (ae-undocumented) Missing documentation for "replaces". +// src/wiring/createExtensionInput.d.ts:18:1 - (ae-undocumented) Missing documentation for "createExtensionInput". +// src/wiring/createFrontendModule.d.ts:4:1 - (ae-undocumented) Missing documentation for "CreateFrontendModuleOptions". +// src/wiring/createFrontendModule.d.ts:5:5 - (ae-undocumented) Missing documentation for "pluginId". +// src/wiring/createFrontendModule.d.ts:6:5 - (ae-undocumented) Missing documentation for "extensions". +// src/wiring/createFrontendModule.d.ts:7:5 - (ae-undocumented) Missing documentation for "featureFlags". +// src/wiring/createFrontendModule.d.ts:10:1 - (ae-undocumented) Missing documentation for "FrontendModule". +// src/wiring/createFrontendModule.d.ts:11:5 - (ae-undocumented) Missing documentation for "$$type". +// src/wiring/createFrontendModule.d.ts:12:5 - (ae-undocumented) Missing documentation for "pluginId". +// src/wiring/createFrontendModule.d.ts:15:1 - (ae-undocumented) Missing documentation for "createFrontendModule". +// src/wiring/createFrontendPlugin.d.ts:5:1 - (ae-undocumented) Missing documentation for "FrontendPlugin". +// src/wiring/createFrontendPlugin.d.ts:10:5 - (ae-undocumented) Missing documentation for "$$type". +// src/wiring/createFrontendPlugin.d.ts:11:5 - (ae-undocumented) Missing documentation for "id". +// src/wiring/createFrontendPlugin.d.ts:12:5 - (ae-undocumented) Missing documentation for "routes". +// src/wiring/createFrontendPlugin.d.ts:13:5 - (ae-undocumented) Missing documentation for "externalRoutes". +// src/wiring/createFrontendPlugin.d.ts:14:5 - (ae-undocumented) Missing documentation for "getExtension". +// src/wiring/createFrontendPlugin.d.ts:15:5 - (ae-undocumented) Missing documentation for "withOverrides". +// src/wiring/createFrontendPlugin.d.ts:20:1 - (ae-undocumented) Missing documentation for "PluginOptions". +// src/wiring/createFrontendPlugin.d.ts:21:5 - (ae-undocumented) Missing documentation for "id". +// src/wiring/createFrontendPlugin.d.ts:22:5 - (ae-undocumented) Missing documentation for "routes". +// src/wiring/createFrontendPlugin.d.ts:23:5 - (ae-undocumented) Missing documentation for "externalRoutes". +// src/wiring/createFrontendPlugin.d.ts:24:5 - (ae-undocumented) Missing documentation for "extensions". +// src/wiring/createFrontendPlugin.d.ts:25:5 - (ae-undocumented) Missing documentation for "featureFlags". +// src/wiring/createFrontendPlugin.d.ts:28:1 - (ae-undocumented) Missing documentation for "createFrontendPlugin". +// src/wiring/resolveExtensionDefinition.d.ts:4:1 - (ae-undocumented) Missing documentation for "Extension". +// src/wiring/resolveExtensionDefinition.d.ts:5:5 - (ae-undocumented) Missing documentation for "$$type". +// src/wiring/resolveExtensionDefinition.d.ts:6:5 - (ae-undocumented) Missing documentation for "id". +// src/wiring/resolveExtensionDefinition.d.ts:7:5 - (ae-undocumented) Missing documentation for "attachTo". +// src/wiring/resolveExtensionDefinition.d.ts:11:5 - (ae-undocumented) Missing documentation for "disabled". +// src/wiring/resolveExtensionDefinition.d.ts:12:5 - (ae-undocumented) Missing documentation for "configSchema". +// src/wiring/resolveInputOverrides.d.ts:5:1 - (ae-undocumented) Missing documentation for "ResolveInputValueOverrides". +// src/wiring/types.d.ts:14:1 - (ae-undocumented) Missing documentation for "AnyRoutes". +// src/wiring/types.d.ts:18:1 - (ae-undocumented) Missing documentation for "AnyExternalRoutes". +// src/wiring/types.d.ts:28:1 - (ae-undocumented) Missing documentation for "ExtensionOverrides". +// src/wiring/types.d.ts:29:5 - (ae-undocumented) Missing documentation for "$$type". +// src/wiring/types.d.ts:35:1 - (ae-undocumented) Missing documentation for "FrontendFeature". ``` diff --git a/packages/frontend-plugin-api/src/apis/definitions/AppTreeApi.ts b/packages/frontend-plugin-api/src/apis/definitions/AppTreeApi.ts index 4b5672f894..5f25eddead 100644 --- a/packages/frontend-plugin-api/src/apis/definitions/AppTreeApi.ts +++ b/packages/frontend-plugin-api/src/apis/definitions/AppTreeApi.ts @@ -15,7 +15,7 @@ */ import { createApiRef } from '@backstage/core-plugin-api'; -import { BackstagePlugin, Extension, ExtensionDataRef } from '../../wiring'; +import { FrontendPlugin, Extension, ExtensionDataRef } from '../../wiring'; /** * The specification for this {@link AppNode} in the {@link AppTree}. @@ -32,7 +32,7 @@ export interface AppNodeSpec { readonly extension: Extension; readonly disabled: boolean; readonly config?: unknown; - readonly source?: BackstagePlugin; + readonly source?: FrontendPlugin; } /** diff --git a/packages/frontend-plugin-api/src/blueprints/ApiBlueprint.test.ts b/packages/frontend-plugin-api/src/blueprints/ApiBlueprint.test.ts index 519b7a4d1a..862f802810 100644 --- a/packages/frontend-plugin-api/src/blueprints/ApiBlueprint.test.ts +++ b/packages/frontend-plugin-api/src/blueprints/ApiBlueprint.test.ts @@ -48,7 +48,6 @@ describe('ApiBlueprint', () => { "inputs": {}, "kind": "api", "name": "test", - "namespace": undefined, "output": [ [Function], ], @@ -123,7 +122,6 @@ describe('ApiBlueprint', () => { }, "kind": "api", "name": "test", - "namespace": undefined, "output": [ [Function], ], diff --git a/packages/frontend-plugin-api/src/blueprints/AppRootElementBlueprint.test.tsx b/packages/frontend-plugin-api/src/blueprints/AppRootElementBlueprint.test.tsx index 0f4d0b2092..3d88ad3f47 100644 --- a/packages/frontend-plugin-api/src/blueprints/AppRootElementBlueprint.test.tsx +++ b/packages/frontend-plugin-api/src/blueprints/AppRootElementBlueprint.test.tsx @@ -38,7 +38,6 @@ describe('AppRootElementBlueprint', () => { "inputs": {}, "kind": "app-root-element", "name": undefined, - "namespace": undefined, "output": [ [Function], ], diff --git a/packages/frontend-plugin-api/src/blueprints/AppRootWrapperBlueprint.test.tsx b/packages/frontend-plugin-api/src/blueprints/AppRootWrapperBlueprint.test.tsx index f9214121ce..20291f5e5a 100644 --- a/packages/frontend-plugin-api/src/blueprints/AppRootWrapperBlueprint.test.tsx +++ b/packages/frontend-plugin-api/src/blueprints/AppRootWrapperBlueprint.test.tsx @@ -46,7 +46,6 @@ describe('AppRootWrapperBlueprint', () => { "inputs": {}, "kind": "app-root-wrapper", "name": undefined, - "namespace": undefined, "output": [ [Function], ], diff --git a/packages/frontend-plugin-api/src/blueprints/IconBundleBlueprint.ts b/packages/frontend-plugin-api/src/blueprints/IconBundleBlueprint.ts index 51b3b6d633..303d1a3fd2 100644 --- a/packages/frontend-plugin-api/src/blueprints/IconBundleBlueprint.ts +++ b/packages/frontend-plugin-api/src/blueprints/IconBundleBlueprint.ts @@ -26,12 +26,6 @@ export const IconBundleBlueprint = createExtensionBlueprint({ kind: 'icon-bundle', attachTo: { id: 'api:app/icons', input: 'icons' }, output: [iconsDataRef], - config: { - schema: { - icons: z => z.string().default('blob'), - test: z => z.string(), - }, - }, factory: (params: { icons: { [key in string]: IconComponent } }) => [ iconsDataRef(params.icons), ], diff --git a/packages/frontend-plugin-api/src/blueprints/NavItemBlueprint.test.tsx b/packages/frontend-plugin-api/src/blueprints/NavItemBlueprint.test.tsx index ddde2ff47d..8656cc7a33 100644 --- a/packages/frontend-plugin-api/src/blueprints/NavItemBlueprint.test.tsx +++ b/packages/frontend-plugin-api/src/blueprints/NavItemBlueprint.test.tsx @@ -56,7 +56,6 @@ describe('NavItemBlueprint', () => { "inputs": {}, "kind": "nav-item", "name": undefined, - "namespace": undefined, "output": [ [Function], ], diff --git a/packages/frontend-plugin-api/src/blueprints/NavLogoBlueprint.test.tsx b/packages/frontend-plugin-api/src/blueprints/NavLogoBlueprint.test.tsx index a08dda1201..5cf3155229 100644 --- a/packages/frontend-plugin-api/src/blueprints/NavLogoBlueprint.test.tsx +++ b/packages/frontend-plugin-api/src/blueprints/NavLogoBlueprint.test.tsx @@ -41,7 +41,6 @@ describe('NavLogoBlueprint', () => { "inputs": {}, "kind": "nav-logo", "name": undefined, - "namespace": undefined, "output": [ [Function], ], diff --git a/packages/frontend-plugin-api/src/blueprints/PageBlueprint.test.tsx b/packages/frontend-plugin-api/src/blueprints/PageBlueprint.test.tsx index c586ed8c04..de1cbe211e 100644 --- a/packages/frontend-plugin-api/src/blueprints/PageBlueprint.test.tsx +++ b/packages/frontend-plugin-api/src/blueprints/PageBlueprint.test.tsx @@ -66,7 +66,6 @@ describe('PageBlueprint', () => { "inputs": {}, "kind": "page", "name": "test-page", - "namespace": undefined, "output": [ [Function], [Function], diff --git a/packages/frontend-plugin-api/src/blueprints/RouterBlueprint.test.tsx b/packages/frontend-plugin-api/src/blueprints/RouterBlueprint.test.tsx index ab6bb1eb1f..cad6be5b8a 100644 --- a/packages/frontend-plugin-api/src/blueprints/RouterBlueprint.test.tsx +++ b/packages/frontend-plugin-api/src/blueprints/RouterBlueprint.test.tsx @@ -46,7 +46,6 @@ describe('RouterBlueprint', () => { "inputs": {}, "kind": "app-router-component", "name": undefined, - "namespace": undefined, "output": [ [Function], ], diff --git a/packages/frontend-plugin-api/src/blueprints/SignInPageBlueprint.test.tsx b/packages/frontend-plugin-api/src/blueprints/SignInPageBlueprint.test.tsx index a85b5e6f39..ffa1d7a225 100644 --- a/packages/frontend-plugin-api/src/blueprints/SignInPageBlueprint.test.tsx +++ b/packages/frontend-plugin-api/src/blueprints/SignInPageBlueprint.test.tsx @@ -42,7 +42,6 @@ describe('SignInPageBlueprint', () => { "inputs": {}, "kind": "sign-in-page", "name": undefined, - "namespace": undefined, "output": [ [Function], ], diff --git a/packages/frontend-plugin-api/src/blueprints/ThemeBlueprint.test.ts b/packages/frontend-plugin-api/src/blueprints/ThemeBlueprint.test.ts index 89c2229fab..5ec164fa8b 100644 --- a/packages/frontend-plugin-api/src/blueprints/ThemeBlueprint.test.ts +++ b/packages/frontend-plugin-api/src/blueprints/ThemeBlueprint.test.ts @@ -42,7 +42,6 @@ describe('ThemeBlueprint', () => { "inputs": {}, "kind": "theme", "name": "light", - "namespace": undefined, "output": [ [Function], ], diff --git a/packages/frontend-plugin-api/src/blueprints/TranslationBlueprint.test.ts b/packages/frontend-plugin-api/src/blueprints/TranslationBlueprint.test.ts index 6bccd68c53..07e02c1562 100644 --- a/packages/frontend-plugin-api/src/blueprints/TranslationBlueprint.test.ts +++ b/packages/frontend-plugin-api/src/blueprints/TranslationBlueprint.test.ts @@ -57,7 +57,6 @@ describe('TranslationBlueprint', () => { "inputs": {}, "kind": "translation", "name": "blob", - "namespace": undefined, "output": [ [Function], ], diff --git a/packages/frontend-plugin-api/src/components/ErrorBoundary.tsx b/packages/frontend-plugin-api/src/components/ErrorBoundary.tsx index 6b457fadc9..db352044de 100644 --- a/packages/frontend-plugin-api/src/components/ErrorBoundary.tsx +++ b/packages/frontend-plugin-api/src/components/ErrorBoundary.tsx @@ -15,11 +15,11 @@ */ import React, { Component, ComponentType, PropsWithChildren } from 'react'; -import { BackstagePlugin } from '../wiring'; +import { FrontendPlugin } from '../wiring'; import { CoreErrorBoundaryFallbackProps } from '../types'; type ErrorBoundaryProps = PropsWithChildren<{ - plugin?: BackstagePlugin; + plugin?: FrontendPlugin; Fallback: ComponentType; }>; type ErrorBoundaryState = { error?: Error }; diff --git a/packages/frontend-plugin-api/src/icons/types.test.ts b/packages/frontend-plugin-api/src/icons/types.test.ts new file mode 100644 index 0000000000..fd01e176c9 --- /dev/null +++ b/packages/frontend-plugin-api/src/icons/types.test.ts @@ -0,0 +1,73 @@ +/* + * 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 * as React from 'react'; +import { type IconComponent } from './types'; + +// Emulate the MUI4 icon type +type Mui4Icon = (props: { + fontSize?: 'default' | 'inherit' | 'large' | 'medium' | 'small'; + otherProp?: string; +}) => JSX.Element; + +// Emulate the MUI5 icon type +type Mui5Icon = (props: { + fontSize?: 'inherit' | 'large' | 'medium' | 'small'; + otherProp?: string; +}) => JSX.Element; + +// Emulate the MUI6 icon type +interface OverridableComponent

{ + ( + props: { + /** + * The component used for the root node. + * Either a string to use a HTML element or a component. + */ + component: RootComponent; + } & { stuff: number }, + ): React.JSX.Element | null; + (props: P): React.JSX.Element | null; +} +type Mui6Icon = OverridableComponent<{ + fontSize?: 'inherit' | 'large' | 'medium' | 'small'; + otherProp?: string; +}>; + +type NotAnIcon1 = (props: { + fontSize?: 'foo'; + otherProp?: string; +}) => JSX.Element; + +type NotAnIcon2 = (props: { + fontSize?: number; + otherProp?: string; +}) => JSX.Element; + +describe('IconComponent', () => { + // eslint-disable-next-line jest/expect-expect + it('should be a component type', () => { + // @ts-ignore + let icon: IconComponent; + icon = {} as Mui4Icon; + icon = {} as Mui5Icon; + icon = {} as Mui6Icon; + // @ts-expect-error + icon = {} as NotAnIcon1; + // @ts-expect-error + icon = {} as NotAnIcon2; + }); +}); diff --git a/packages/frontend-plugin-api/src/icons/types.ts b/packages/frontend-plugin-api/src/icons/types.ts index 4d54629de2..2b00e1456f 100644 --- a/packages/frontend-plugin-api/src/icons/types.ts +++ b/packages/frontend-plugin-api/src/icons/types.ts @@ -22,7 +22,7 @@ import { ComponentType } from 'react'; * * @remarks * - * The type is based on SvgIcon from Material UI, but both do not what the plugin-api + * The type is based on SvgIcon from Material UI, but we do not want the plugin-api * package to have a dependency on Material UI, nor do we want the props to be as broad * as the SvgIconProps interface. * @@ -32,14 +32,6 @@ import { ComponentType } from 'react'; * * @public */ - -export type IconComponent = ComponentType< - /* Material UI v4 */ - | { - fontSize?: 'large' | 'small' | 'default' | 'inherit'; - } - /* Material UI v5: https://mui.com/material-ui/migration/v5-component-changes/#icon */ - | { - fontSize?: 'medium' | 'large' | 'small' | 'inherit'; - } ->; +export type IconComponent = ComponentType<{ + fontSize?: 'medium' | 'large' | 'small' | 'inherit'; +}>; diff --git a/packages/frontend-plugin-api/src/types.ts b/packages/frontend-plugin-api/src/types.ts index 4d0fb1ac4b..a658760758 100644 --- a/packages/frontend-plugin-api/src/types.ts +++ b/packages/frontend-plugin-api/src/types.ts @@ -15,7 +15,7 @@ */ import { ReactNode } from 'react'; -import { BackstagePlugin } from './wiring'; +import { FrontendPlugin } from './wiring'; // TODO(Rugvip): This might be a quite useful utility type, maybe add to @backstage/types? /** @@ -34,7 +34,7 @@ export type CoreNotFoundErrorPageProps = { /** @public */ export type CoreErrorBoundaryFallbackProps = { - plugin?: BackstagePlugin; + plugin?: FrontendPlugin; error: Error; resetError: () => void; }; diff --git a/packages/frontend-plugin-api/src/wiring/createExtension.test.ts b/packages/frontend-plugin-api/src/wiring/createExtension.test.ts index 5e8aa1c57a..3eb6445fee 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtension.test.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtension.test.ts @@ -567,7 +567,7 @@ describe('createExtension', () => { }, }); - // @ts-expect-error - this should fail because string output should be merged? + // @ts-expect-error const override2 = testExtension.override({ output: [numberDataRef], factory(_, { inputs }) { @@ -681,6 +681,97 @@ describe('createExtension', () => { ).toBe('foo-hello-override-world'); }); + it('should be able to disable extension with override', () => { + const subject = createExtension({ + name: 'root', + attachTo: { id: 'ignored', input: 'ignored' }, + inputs: { + input: createExtensionInput([stringDataRef], { + singleton: true, + optional: true, + }), + }, + output: [stringDataRef.optional()], + factory({ inputs }) { + return inputs.input ?? []; + }, + }); + + const attached = createExtension({ + attachTo: { id: 'root', input: 'input' }, + output: [stringDataRef], + factory() { + return [stringDataRef('test')]; + }, + }); + + expect( + createExtensionTester(subject).add(attached).get(stringDataRef), + ).toBe('test'); + + expect( + createExtensionTester(subject) + .add(attached.override({ disabled: true })) + .get(stringDataRef), + ).toBe(undefined); + }); + + it('should complain when overriding with incompatible output', () => { + const testExtension = createExtension({ + attachTo: { id: 'root', input: 'blob' }, + output: [stringDataRef], + factory() { + return [stringDataRef('0')]; + }, + }); + + // @ts-expect-error - override output is incompatible with factory + const override = testExtension.override({ + output: [numberDataRef], + factory() { + return [stringDataRef('1')]; + }, + }); + expect(override).toBeDefined(); + + expect(() => + testExtension.override({ + output: [numberDataRef], + }), + ).toThrowErrorMatchingInlineSnapshot( + `"Refused to override output without also overriding factory"`, + ); + }); + + it('should not have params unless explicitly defined', () => { + const ext = createExtension({ + attachTo: { id: 'root', input: 'blob' }, + output: [stringDataRef], + factory() { + return [stringDataRef('0')]; + }, + }); + + ext.override({ + // @ts-expect-error - params are not allowed + params: {} as any, + }); + + ext.override({ + // @ts-expect-error - params are not provided + factory(origFactory, { params }) { + return origFactory({ + // @ts-expect-error - params are not allowed + params: { + ...params, + }, + }); + }, + }); + + expect(ext).toBeDefined(); + }); + it('should be able to override input values', () => { const outputRef = createExtensionDataRef().with({ id: 'output', diff --git a/packages/frontend-plugin-api/src/wiring/createExtension.ts b/packages/frontend-plugin-api/src/wiring/createExtension.ts index 8c79758395..16f9f341a7 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtension.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtension.ts @@ -15,7 +15,6 @@ */ import { ApiHolder, AppNode } from '../apis'; -import { PortableSchema } from '../schema'; import { Expand } from '../types'; import { ResolveInputValueOverrides, @@ -32,6 +31,13 @@ import { import { ExtensionInput } from './createExtensionInput'; import { z } from 'zod'; import { createSchemaFromZod } from '../schema/createSchemaFromZod'; +import { OpaqueExtensionDefinition } from '@internal/frontend'; + +/** + * This symbol is used to pass parameter overrides from the extension override to the blueprint factory + * @internal + */ +export const ctxParamsSymbol = Symbol('params'); /** * Convert a single extension input into a matching resolved input. @@ -109,7 +115,6 @@ export type VerifyExtensionFactoryOutput< /** @public */ export type CreateExtensionOptions< TKind extends string | undefined, - TNamespace extends string | undefined, TName extends string | undefined, UOutput extends AnyExtensionDataRef, TInputs extends { @@ -122,7 +127,6 @@ export type CreateExtensionOptions< UFactoryOutput extends ExtensionDataValue, > = { kind?: TKind; - namespace?: TNamespace; name?: TName; attachTo: { id: string; input: string }; disabled?: boolean; @@ -144,7 +148,6 @@ export type CreateExtensionOptions< /** @public */ export type ExtensionDefinitionParameters = { kind?: string; - namespace?: string; name?: string; configInput?: { [K in string]: any }; config?: { [K in string]: any }; @@ -155,6 +158,7 @@ export type ExtensionDefinitionParameters = { { optional: boolean; singleton: boolean } >; }; + params?: object; }; /** @public */ @@ -177,45 +181,55 @@ export type ExtensionDefinition< >; }, >( - args: { - attachTo?: { id: string; input: string }; - disabled?: boolean; - inputs?: TExtraInputs & { - [KName in keyof T['inputs']]?: `Error: Input '${KName & - string}' is already defined in parent definition`; - }; - output?: Array; - config?: { - schema: TExtensionConfigSchema & { - [KName in keyof T['config']]?: `Error: Config key '${KName & - string}' is already defined in parent schema`; + args: Expand< + { + attachTo?: { id: string; input: string }; + disabled?: boolean; + inputs?: TExtraInputs & { + [KName in keyof T['inputs']]?: `Error: Input '${KName & + string}' is already defined in parent definition`; }; - }; - factory( - originalFactory: (context?: { - config?: T['config']; - inputs?: ResolveInputValueOverrides>; - }) => ExtensionDataContainer>, - context: { - node: AppNode; - apis: ApiHolder; - config: T['config'] & { - [key in keyof TExtensionConfigSchema]: z.infer< - ReturnType - >; + output?: Array; + config?: { + schema: TExtensionConfigSchema & { + [KName in keyof T['config']]?: `Error: Config key '${KName & + string}' is already defined in parent schema`; }; - inputs: Expand>; - }, - ): Iterable; - } & VerifyExtensionFactoryOutput< - AnyExtensionDataRef extends UNewOutput - ? NonNullable - : UNewOutput, - UFactoryOutput - >, + }; + factory?( + originalFactory: ( + context?: Expand< + { + config?: T['config']; + inputs?: ResolveInputValueOverrides>; + } & ([T['params']] extends [never] + ? {} + : { params?: Partial }) + >, + ) => ExtensionDataContainer>, + context: { + node: AppNode; + apis: ApiHolder; + config: T['config'] & { + [key in keyof TExtensionConfigSchema]: z.infer< + ReturnType + >; + }; + inputs: Expand>; + }, + ): Iterable; + } & ([T['params']] extends [never] + ? {} + : { params?: Partial }) + > & + VerifyExtensionFactoryOutput< + AnyExtensionDataRef extends UNewOutput + ? NonNullable + : UNewOutput, + UFactoryOutput + >, ): ExtensionDefinition<{ kind: T['kind']; - namespace: T['namespace']; name: T['name']; output: AnyExtensionDataRef extends UNewOutput ? T['output'] : UNewOutput; inputs: T['inputs'] & TExtraInputs; @@ -235,84 +249,6 @@ export type ExtensionDefinition< }>; }; -/** @internal */ -export type InternalExtensionDefinition< - T extends ExtensionDefinitionParameters = ExtensionDefinitionParameters, -> = ExtensionDefinition & { - readonly kind?: string; - readonly namespace?: string; - readonly name?: string; - readonly attachTo: { id: string; input: string }; - readonly disabled: boolean; - readonly configSchema?: PortableSchema; -} & ( - | { - readonly version: 'v1'; - readonly inputs: { - [inputName in string]: { - $$type: '@backstage/ExtensionInput'; - extensionData: { - [name in string]: AnyExtensionDataRef; - }; - config: { optional: boolean; singleton: boolean }; - }; - }; - readonly output: { - [name in string]: AnyExtensionDataRef; - }; - factory(context: { - node: AppNode; - apis: ApiHolder; - config: object; - inputs: { - [inputName in string]: unknown; - }; - }): { - [inputName in string]: unknown; - }; - } - | { - readonly version: 'v2'; - readonly inputs: { - [inputName in string]: ExtensionInput< - AnyExtensionDataRef, - { optional: boolean; singleton: boolean } - >; - }; - readonly output: Array; - factory(context: { - node: AppNode; - apis: ApiHolder; - config: object; - inputs: ResolvedExtensionInputs<{ - [inputName in string]: ExtensionInput< - AnyExtensionDataRef, - { optional: boolean; singleton: boolean } - >; - }>; - }): Iterable>; - } - ); - -/** @internal */ -export function toInternalExtensionDefinition< - T extends ExtensionDefinitionParameters, ->(overrides: ExtensionDefinition): InternalExtensionDefinition { - const internal = overrides as InternalExtensionDefinition; - if (internal.$$type !== '@backstage/ExtensionDefinition') { - throw new Error( - `Invalid extension definition instance, bad type '${internal.$$type}'`, - ); - } - const version = internal.version; - if (version !== 'v1' && version !== 'v2') { - throw new Error( - `Invalid extension definition instance, bad version '${version}'`, - ); - } - return internal; -} - /** @public */ export function createExtension< UOutput extends AnyExtensionDataRef, @@ -325,12 +261,10 @@ export function createExtension< TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType }, UFactoryOutput extends ExtensionDataValue, const TKind extends string | undefined = undefined, - const TNamespace extends string | undefined = undefined, const TName extends string | undefined = undefined, >( options: CreateExtensionOptions< TKind, - undefined, TName, UOutput, TInputs, @@ -352,118 +286,10 @@ export function createExtension< >; output: UOutput; inputs: TInputs; + params: never; kind: string | undefined extends TKind ? undefined : TKind; - namespace: string | undefined extends TNamespace ? undefined : TNamespace; - name: string | undefined extends TName ? undefined : TName; -}>; -/** - * @public - * @deprecated namespace is no longer required, you can safely remove this option and it will default to the `pluginId`. It will be removed in a future release. - */ -export function createExtension< - UOutput extends AnyExtensionDataRef, - TInputs extends { - [inputName in string]: ExtensionInput< - AnyExtensionDataRef, - { optional: boolean; singleton: boolean } - >; - }, - TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType }, - UFactoryOutput extends ExtensionDataValue, - const TKind extends string | undefined = undefined, - const TNamespace extends string | undefined = undefined, - const TName extends string | undefined = undefined, ->( - options: CreateExtensionOptions< - TKind, - TNamespace, - TName, - UOutput, - TInputs, - TConfigSchema, - UFactoryOutput - >, -): ExtensionDefinition<{ - config: string extends keyof TConfigSchema - ? {} - : { - [key in keyof TConfigSchema]: z.infer>; - }; - configInput: string extends keyof TConfigSchema - ? {} - : z.input< - z.ZodObject<{ - [key in keyof TConfigSchema]: ReturnType; - }> - >; - output: UOutput; - inputs: TInputs; - kind: string | undefined extends TKind ? undefined : TKind; - namespace: string | undefined extends TNamespace ? undefined : TNamespace; - name: string | undefined extends TName ? undefined : TName; -}>; -export function createExtension< - UOutput extends AnyExtensionDataRef, - TInputs extends { - [inputName in string]: ExtensionInput< - AnyExtensionDataRef, - { optional: boolean; singleton: boolean } - >; - }, - TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType }, - UFactoryOutput extends ExtensionDataValue, - const TKind extends string | undefined = undefined, - const TNamespace extends string | undefined = undefined, - const TName extends string | undefined = undefined, ->( - options: CreateExtensionOptions< - TKind, - TNamespace, - TName, - UOutput, - TInputs, - TConfigSchema, - UFactoryOutput - >, -): ExtensionDefinition<{ - config: string extends keyof TConfigSchema - ? {} - : { - [key in keyof TConfigSchema]: z.infer>; - }; - configInput: string extends keyof TConfigSchema - ? {} - : z.input< - z.ZodObject<{ - [key in keyof TConfigSchema]: ReturnType; - }> - >; - output: UOutput; - inputs: TInputs; - kind: string | undefined extends TKind ? undefined : TKind; - namespace: string | undefined extends TNamespace ? undefined : TNamespace; name: string | undefined extends TName ? undefined : TName; }> { - type T = { - config: string extends keyof TConfigSchema - ? {} - : { - [key in keyof TConfigSchema]: z.infer>; - }; - configInput: string extends keyof TConfigSchema - ? {} - : z.input< - z.ZodObject<{ - [key in keyof TConfigSchema]: ReturnType; - }> - >; - output: UOutput; - inputs: TInputs; - kind: string | undefined extends TKind ? undefined : TKind; - namespace: string | undefined extends TNamespace ? undefined : TNamespace; - name: string | undefined extends TName ? undefined : TName; - }; - const schemaDeclaration = options.config?.schema; const configSchema = schemaDeclaration && @@ -475,12 +301,28 @@ export function createExtension< ), ); - return { - $$type: '@backstage/ExtensionDefinition', - version: 'v2', - T: undefined as unknown as T, + return OpaqueExtensionDefinition.createInstance('v2', { + T: undefined as unknown as { + config: string extends keyof TConfigSchema + ? {} + : { + [key in keyof TConfigSchema]: z.infer< + ReturnType + >; + }; + configInput: string extends keyof TConfigSchema + ? {} + : z.input< + z.ZodObject<{ + [key in keyof TConfigSchema]: ReturnType; + }> + >; + output: UOutput; + inputs: TInputs; + kind: string | undefined extends TKind ? undefined : TKind; + name: string | undefined extends TName ? undefined : TName; + }, kind: options.kind, - namespace: options.namespace, name: options.name, attachTo: options.attachTo, disabled: options.disabled ?? false, @@ -493,9 +335,6 @@ export function createExtension< if (options.kind) { parts.push(`kind=${options.kind}`); } - if (options.namespace) { - parts.push(`namespace=${options.namespace}`); - } if (options.name) { parts.push(`name=${options.name}`); } @@ -508,57 +347,64 @@ export function createExtension< 'Cannot override an extension that is not declared using the new format with outputs as an array', ); } - const newOptions = options as CreateExtensionOptions< - TKind, - TNamespace, - TName, - UOutput, - TInputs, - TConfigSchema, - UFactoryOutput - >; + + // TODO(Rugvip): Making this a type check would be optimal, but it seems + // like it's tricky to add that and still have the type + // inference work correctly for the factory output. + if (overrideOptions.output && !overrideOptions.factory) { + throw new Error( + 'Refused to override output without also overriding factory', + ); + } + // TODO(Rugvip): Similar to above, would be nice to error during type checking, but don't want to complicate the types too much + if (overrideOptions.params && overrideOptions.factory) { + throw new Error( + 'Refused to override params and factory at the same time', + ); + } return createExtension({ - kind: newOptions.kind, - namespace: newOptions.namespace, - name: newOptions.name, - attachTo: overrideOptions.attachTo ?? newOptions.attachTo, - disabled: overrideOptions.disabled ?? newOptions.disabled, - inputs: { ...overrideOptions.inputs, ...newOptions.inputs }, + kind: options.kind, + name: options.name, + attachTo: overrideOptions.attachTo ?? options.attachTo, + disabled: overrideOptions.disabled ?? options.disabled, + inputs: { ...overrideOptions.inputs, ...options.inputs }, output: (overrideOptions.output ?? - newOptions.output) as AnyExtensionDataRef[], + options.output) as AnyExtensionDataRef[], config: - newOptions.config || overrideOptions.config + options.config || overrideOptions.config ? { schema: { - ...newOptions.config?.schema, + ...options.config?.schema, ...overrideOptions.config?.schema, }, } : undefined, factory: ({ node, apis, config, inputs }) => { if (!overrideOptions.factory) { - return newOptions.factory({ + return options.factory({ node, apis, config: config as any, inputs: inputs as any, + [ctxParamsSymbol as any]: overrideOptions.params, }); } const parentResult = overrideOptions.factory( (innerContext): ExtensionDataContainer => { return createExtensionDataContainer( - newOptions.factory({ + options.factory({ node, apis, config: (innerContext?.config ?? config) as any, inputs: resolveInputOverrides( - newOptions.inputs, + options.inputs, inputs, innerContext?.inputs, ) as any, + [ctxParamsSymbol as any]: innerContext?.params, }) as Iterable, - newOptions.output, + options.output, ); }, { @@ -581,5 +427,5 @@ export function createExtension< }, }) as ExtensionDefinition; }, - } as InternalExtensionDefinition; + }); } diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx index fc77c63e97..16786f9757 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx +++ b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx @@ -27,16 +27,14 @@ import { } from './createExtensionDataRef'; import { createExtensionInput } from './createExtensionInput'; import { RouteRef } from '../routing'; -import { - ExtensionDefinition, - toInternalExtensionDefinition, -} from './createExtension'; +import { ExtensionDefinition } from './createExtension'; import { createExtensionDataContainer } from './createExtensionDataContainer'; +import { OpaqueExtensionDefinition } from '@internal/frontend'; function unused(..._any: any[]) {} function factoryOutput(ext: ExtensionDefinition, inputs: unknown = undefined) { - const int = toInternalExtensionDefinition(ext); + const int = OpaqueExtensionDefinition.toInternal(ext); if (int.version !== 'v2') { throw new Error('Expected v2 extension'); } @@ -682,7 +680,7 @@ describe('createExtensionBlueprint', () => { }, }); - const ext = toInternalExtensionDefinition( + const ext = OpaqueExtensionDefinition.toInternal( blueprint.makeWithOverrides({ output: [testDataRef2], factory(origFactory) { @@ -838,4 +836,232 @@ describe('createExtensionBlueprint', () => { ), ).toEqual([testDataRef1('foo'), testDataRef2('bar')]); }); + + it('should be possible to override extensions resulting from .make', () => { + const testDataRef1 = createExtensionDataRef().with({ id: 'test1' }); + const testDataRef2 = createExtensionDataRef().with({ id: 'test2' }); + + function getOutputs(ext: ExtensionDefinition) { + const tester = createExtensionTester(ext); + return { + test1: tester.get(testDataRef1), + test2: tester.get(testDataRef2), + }; + } + + const blueprint = createExtensionBlueprint({ + kind: 'test-extension', + attachTo: { id: 'test', input: 'default' }, + output: [testDataRef1, testDataRef2], + *factory(params: { test1: string; test2: string }) { + yield testDataRef1(params.test1); + yield testDataRef2(params.test2); + }, + }); + + const extension = blueprint.make({ + params: { + test1: 'orig-1', + test2: 'orig-2', + }, + }); + + expect(getOutputs(extension)).toEqual({ + test1: 'orig-1', + test2: 'orig-2', + }); + + expect( + getOutputs( + extension.override({ + params: { + test1: 'override-1', + test2: 'override-2', + }, + }), + ), + ).toEqual({ + test1: 'override-1', + test2: 'override-2', + }); + + // Partial override + expect( + getOutputs( + extension.override({ + params: { + test2: 'override-2', + }, + }), + ), + ).toEqual({ + test1: 'orig-1', + test2: 'override-2', + }); + + expect( + getOutputs( + extension.override({ + factory(origFactory) { + return origFactory({ + params: { + test1: 'override-1', + test2: 'override-2', + }, + }); + }, + }), + ), + ).toEqual({ + test1: 'override-1', + test2: 'override-2', + }); + + // Partial override via factory + expect( + getOutputs( + extension.override({ + factory(origFactory) { + return origFactory({ + params: { + test2: 'override-2', + }, + }); + }, + }), + ), + ).toEqual({ + test1: 'orig-1', + test2: 'override-2', + }); + + expect(() => + getOutputs( + extension.override({ + params: { + test1: 'override-1', + test2: 'override-2', + }, + factory(origFactory) { + return origFactory(); + }, + }), + ), + ).toThrow('Refused to override params and factory at the same time'); + }); + + it('should be possible to override extensions resulting from .makeWithOverrides', () => { + const testDataRef1 = createExtensionDataRef().with({ id: 'test1' }); + const testDataRef2 = createExtensionDataRef().with({ id: 'test2' }); + + function getOutputs(ext: ExtensionDefinition) { + const tester = createExtensionTester(ext); + return { + test1: tester.get(testDataRef1), + test2: tester.get(testDataRef2), + }; + } + + const blueprint = createExtensionBlueprint({ + kind: 'test-extension', + attachTo: { id: 'test', input: 'default' }, + output: [testDataRef1, testDataRef2], + *factory(params: { test1: string; test2: string }) { + yield testDataRef1(params.test1); + yield testDataRef2(params.test2); + }, + }); + + const extension = blueprint.makeWithOverrides({ + factory(origFactory) { + return origFactory({ + test1: 'orig-1', + test2: 'orig-2', + }); + }, + }); + + expect(getOutputs(extension)).toEqual({ + test1: 'orig-1', + test2: 'orig-2', + }); + + expect( + getOutputs( + extension.override({ + params: { + test1: 'override-1', + test2: 'override-2', + }, + }), + ), + ).toEqual({ + test1: 'override-1', + test2: 'override-2', + }); + + // Partial override + expect( + getOutputs( + extension.override({ + params: { + test2: 'override-2', + }, + }), + ), + ).toEqual({ + test1: 'orig-1', + test2: 'override-2', + }); + + expect( + getOutputs( + extension.override({ + factory(origFactory) { + return origFactory({ + params: { + test1: 'override-1', + test2: 'override-2', + }, + }); + }, + }), + ), + ).toEqual({ + test1: 'override-1', + test2: 'override-2', + }); + + // Partial override via factory + expect( + getOutputs( + extension.override({ + factory(origFactory) { + return origFactory({ + params: { + test2: 'override-2', + }, + }); + }, + }), + ), + ).toEqual({ + test1: 'orig-1', + test2: 'override-2', + }); + + expect(() => + getOutputs( + extension.override({ + params: { + test1: 'override-1', + test2: 'override-2', + }, + factory(origFactory) { + return origFactory(); + }, + }), + ), + ).toThrow('Refused to override params and factory at the same time'); + }); }); diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts index 40d1284b15..e22179127a 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts @@ -21,6 +21,7 @@ import { ResolvedExtensionInputs, VerifyExtensionFactoryOutput, createExtension, + ctxParamsSymbol, } from './createExtension'; import { z } from 'zod'; import { ExtensionInput } from './createExtensionInput'; @@ -42,7 +43,6 @@ import { */ export type CreateExtensionBlueprintOptions< TKind extends string, - TNamespace extends string | undefined, TName extends string | undefined, TParams, UOutput extends AnyExtensionDataRef, @@ -57,7 +57,6 @@ export type CreateExtensionBlueprintOptions< TDataRefs extends { [name in string]: AnyExtensionDataRef }, > = { kind: TKind; - namespace?: TNamespace; attachTo: { id: string; input: string }; disabled?: boolean; inputs?: TInputs; @@ -84,7 +83,6 @@ export type CreateExtensionBlueprintOptions< /** @public */ export type ExtensionBlueprintParameters = { kind: string; - namespace?: string; name?: string; params?: object; configInput?: { [K in string]: any }; @@ -107,44 +105,19 @@ export interface ExtensionBlueprint< > { dataRefs: T['dataRefs']; - make< - TNewNamespace extends string | undefined, - TNewName extends string | undefined, - >(args: { - namespace?: undefined; + make(args: { name?: TNewName; attachTo?: { id: string; input: string }; disabled?: boolean; params: T['params']; }): ExtensionDefinition<{ kind: T['kind']; - namespace: undefined; name: string | undefined extends TNewName ? T['name'] : TNewName; config: T['config']; configInput: T['configInput']; output: T['output']; inputs: T['inputs']; - }>; - /** @deprecated namespace is no longer required, you can safely remove this option and it will default to the `pluginId`. It will be removed in a future release. */ - make< - TNewNamespace extends string | undefined, - TNewName extends string | undefined, - >(args: { - namespace?: TNewNamespace; - name?: TNewName; - attachTo?: { id: string; input: string }; - disabled?: boolean; params: T['params']; - }): ExtensionDefinition<{ - kind: T['kind']; - namespace: string | undefined extends TNewNamespace - ? T['namespace'] - : TNewNamespace; - name: string | undefined extends TNewName ? T['name'] : TNewName; - config: T['config']; - configInput: T['configInput']; - output: T['output']; - inputs: T['inputs']; }>; /** @@ -154,7 +127,6 @@ export interface ExtensionBlueprint< * optionally call the original factory with the same params. */ makeWithOverrides< - TNewNamespace extends string | undefined, TNewName extends string | undefined, TExtensionConfigSchema extends { [key in string]: (zImpl: typeof z) => z.ZodType; @@ -168,7 +140,6 @@ export interface ExtensionBlueprint< >; }, >(args: { - namespace?: undefined; name?: TNewName; attachTo?: { id: string; input: string }; disabled?: boolean; @@ -230,91 +201,8 @@ export interface ExtensionBlueprint< output: AnyExtensionDataRef extends UNewOutput ? T['output'] : UNewOutput; inputs: T['inputs'] & TExtraInputs; kind: T['kind']; - namespace: undefined; - name: string | undefined extends TNewName ? T['name'] : TNewName; - }>; - /** @deprecated namespace is no longer required, you can safely remove this option and it will default to the `pluginId`. It will be removed in a future release. */ - makeWithOverrides< - TNewNamespace extends string | undefined, - TNewName extends string | undefined, - TExtensionConfigSchema extends { - [key in string]: (zImpl: typeof z) => z.ZodType; - }, - UFactoryOutput extends ExtensionDataValue, - UNewOutput extends AnyExtensionDataRef, - TExtraInputs extends { - [inputName in string]: ExtensionInput< - AnyExtensionDataRef, - { optional: boolean; singleton: boolean } - >; - }, - >(args: { - namespace: TNewNamespace; - name?: TNewName; - attachTo?: { id: string; input: string }; - disabled?: boolean; - inputs?: TExtraInputs & { - [KName in keyof T['inputs']]?: `Error: Input '${KName & - string}' is already defined in parent definition`; - }; - output?: Array; - config?: { - schema: TExtensionConfigSchema & { - [KName in keyof T['config']]?: `Error: Config key '${KName & - string}' is already defined in parent schema`; - }; - }; - factory( - originalFactory: ( - params: T['params'], - context?: { - config?: T['config']; - inputs?: ResolveInputValueOverrides>; - }, - ) => ExtensionDataContainer>, - context: { - node: AppNode; - apis: ApiHolder; - config: T['config'] & { - [key in keyof TExtensionConfigSchema]: z.infer< - ReturnType - >; - }; - inputs: Expand>; - }, - ): Iterable & - VerifyExtensionFactoryOutput< - AnyExtensionDataRef extends UNewOutput - ? NonNullable - : UNewOutput, - UFactoryOutput - >; - }): ExtensionDefinition<{ - config: (string extends keyof TExtensionConfigSchema - ? {} - : { - [key in keyof TExtensionConfigSchema]: z.infer< - ReturnType - >; - }) & - T['config']; - configInput: (string extends keyof TExtensionConfigSchema - ? {} - : z.input< - z.ZodObject<{ - [key in keyof TExtensionConfigSchema]: ReturnType< - TExtensionConfigSchema[key] - >; - }> - >) & - T['configInput']; - output: AnyExtensionDataRef extends UNewOutput ? T['output'] : UNewOutput; - inputs: T['inputs'] & TExtraInputs; - kind: T['kind']; - namespace: string | undefined extends TNewNamespace - ? T['namespace'] - : TNewNamespace; name: string | undefined extends TNewName ? T['name'] : TNewName; + params: T['params']; }>; } @@ -336,13 +224,11 @@ export function createExtensionBlueprint< TConfigSchema extends { [key in string]: (zImpl: typeof z) => z.ZodType }, UFactoryOutput extends ExtensionDataValue, TKind extends string, - TNamespace extends undefined = undefined, TName extends string | undefined = undefined, TDataRefs extends { [name in string]: AnyExtensionDataRef } = never, >( options: CreateExtensionBlueprintOptions< TKind, - undefined, TName, TParams, UOutput, @@ -353,103 +239,6 @@ export function createExtensionBlueprint< >, ): ExtensionBlueprint<{ kind: TKind; - namespace: undefined; - name: TName; - params: TParams; - output: UOutput; - inputs: string extends keyof TInputs ? {} : TInputs; - config: string extends keyof TConfigSchema - ? {} - : { [key in keyof TConfigSchema]: z.infer> }; - configInput: string extends keyof TConfigSchema - ? {} - : z.input< - z.ZodObject<{ - [key in keyof TConfigSchema]: ReturnType; - }> - >; - dataRefs: TDataRefs; -}>; -/** - * @public - * @deprecated the namespace is no longer required, you can safely remove this option and it will default to the `pluginId`. It will be removed in a future release. - */ -export function createExtensionBlueprint< - TParams extends object, - UOutput extends AnyExtensionDataRef, - TInputs extends { - [inputName in string]: ExtensionInput< - AnyExtensionDataRef, - { optional: boolean; singleton: boolean } - >; - }, - TConfigSchema extends { [key in string]: (zImpl: typeof z) => z.ZodType }, - UFactoryOutput extends ExtensionDataValue, - TKind extends string, - TNamespace extends string | undefined = undefined, - TName extends string | undefined = undefined, - TDataRefs extends { [name in string]: AnyExtensionDataRef } = never, ->( - options: CreateExtensionBlueprintOptions< - TKind, - TNamespace, - TName, - TParams, - UOutput, - TInputs, - TConfigSchema, - UFactoryOutput, - TDataRefs - >, -): ExtensionBlueprint<{ - kind: TKind; - namespace: TNamespace; - name: TName; - params: TParams; - output: UOutput; - inputs: string extends keyof TInputs ? {} : TInputs; - config: string extends keyof TConfigSchema - ? {} - : { [key in keyof TConfigSchema]: z.infer> }; - configInput: string extends keyof TConfigSchema - ? {} - : z.input< - z.ZodObject<{ - [key in keyof TConfigSchema]: ReturnType; - }> - >; - dataRefs: TDataRefs; -}>; -export function createExtensionBlueprint< - TParams extends object, - UOutput extends AnyExtensionDataRef, - TInputs extends { - [inputName in string]: ExtensionInput< - AnyExtensionDataRef, - { optional: boolean; singleton: boolean } - >; - }, - TConfigSchema extends { [key in string]: (zImpl: typeof z) => z.ZodType }, - UFactoryOutput extends ExtensionDataValue, - TKind extends string, - TNamespace extends string | undefined = undefined, - TName extends string | undefined = undefined, - TDataRefs extends { [name in string]: AnyExtensionDataRef } = never, ->( - options: CreateExtensionBlueprintOptions< - TKind, - TNamespace, - TName, - TParams, - UOutput, - TInputs, - TConfigSchema, - UFactoryOutput, - TDataRefs - >, -): ExtensionBlueprint<{ - kind: TKind; - namespace: TNamespace; name: TName; params: TParams; output: UOutput; @@ -471,7 +260,6 @@ export function createExtensionBlueprint< make(args) { return createExtension({ kind: options.kind, - namespace: args.namespace ?? options.namespace, name: args.name ?? options.name, attachTo: args.attachTo ?? options.attachTo, disabled: args.disabled ?? options.disabled, @@ -479,15 +267,15 @@ export function createExtensionBlueprint< output: options.output as AnyExtensionDataRef[], config: options.config, factory: ctx => - options.factory(args.params, ctx) as Iterable< - ExtensionDataValue - >, + options.factory( + { ...args.params, ...(ctx as any)[ctxParamsSymbol] }, + ctx, + ) as Iterable>, }) as ExtensionDefinition; }, makeWithOverrides(args) { return createExtension({ kind: options.kind, - namespace: args.namespace ?? options.namespace, name: args.name ?? options.name, attachTo: args.attachTo ?? options.attachTo, disabled: args.disabled ?? options.disabled, @@ -502,20 +290,24 @@ export function createExtensionBlueprint< }, } : undefined, - factory: ({ node, config, inputs, apis }) => { + factory: ctx => { + const { node, config, inputs, apis } = ctx; return args.factory( (innerParams, innerContext) => { return createExtensionDataContainer( - options.factory(innerParams, { - apis, - node, - config: (innerContext?.config ?? config) as any, - inputs: resolveInputOverrides( - options.inputs, - inputs, - innerContext?.inputs, - ) as any, - }) as Iterable, + options.factory( + { ...innerParams, ...(ctx as any)[ctxParamsSymbol] }, + { + apis, + node, + config: (innerContext?.config ?? config) as any, + inputs: resolveInputOverrides( + options.inputs, + inputs, + innerContext?.inputs, + ) as any, + }, + ) as Iterable, options.output, ); }, @@ -531,7 +323,6 @@ export function createExtensionBlueprint< }, } as ExtensionBlueprint<{ kind: TKind; - namespace: TNamespace; name: TName; params: TParams; output: UOutput; diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionOverrides.test.ts b/packages/frontend-plugin-api/src/wiring/createExtensionOverrides.test.ts deleted file mode 100644 index a3595fb168..0000000000 --- a/packages/frontend-plugin-api/src/wiring/createExtensionOverrides.test.ts +++ /dev/null @@ -1,136 +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 { createExtension } from './createExtension'; -import { - createExtensionOverrides, - toInternalExtensionOverrides, -} from './createExtensionOverrides'; - -describe('createExtensionOverrides', () => { - it('should create overrides without extensions', () => { - expect(createExtensionOverrides({ extensions: [] })).toMatchInlineSnapshot(` - { - "$$type": "@backstage/ExtensionOverrides", - "extensions": [], - "featureFlags": [], - "toString": [Function], - "version": "v1", - } - `); - }); - - it('should create overrides with extensions', () => { - expect( - createExtensionOverrides({ - extensions: [ - createExtension({ - name: 'a', - attachTo: { id: 'app', input: 'apis' }, - output: [], - factory: () => [], - }), - createExtension({ - namespace: 'b', - attachTo: { id: 'app', input: 'apis' }, - output: [], - factory: () => [], - }), - createExtension({ - kind: 'k', - namespace: 'c', - name: 'n', - attachTo: { id: 'app', input: 'apis' }, - output: [], - factory: () => [], - }), - ], - }), - ).toMatchInlineSnapshot(` - { - "$$type": "@backstage/ExtensionOverrides", - "extensions": [ - { - "$$type": "@backstage/Extension", - "T": undefined, - "attachTo": { - "id": "app", - "input": "apis", - }, - "configSchema": undefined, - "disabled": false, - "factory": [Function], - "id": "a", - "inputs": {}, - "output": [], - "toString": [Function], - "version": "v2", - }, - { - "$$type": "@backstage/Extension", - "T": undefined, - "attachTo": { - "id": "app", - "input": "apis", - }, - "configSchema": undefined, - "disabled": false, - "factory": [Function], - "id": "b", - "inputs": {}, - "output": [], - "toString": [Function], - "version": "v2", - }, - { - "$$type": "@backstage/Extension", - "T": undefined, - "attachTo": { - "id": "app", - "input": "apis", - }, - "configSchema": undefined, - "disabled": false, - "factory": [Function], - "id": "k:c/n", - "inputs": {}, - "output": [], - "toString": [Function], - "version": "v2", - }, - ], - "featureFlags": [], - "toString": [Function], - "version": "v1", - } - `); - }); - - it('should convert to internal overrides', () => { - const overrides = createExtensionOverrides({ - extensions: [ - createExtension({ - namespace: 'a', - attachTo: { id: 'app', input: 'apis' }, - output: [], - factory: () => [], - }), - ], - }); - const internal = toInternalExtensionOverrides(overrides); - expect(internal).toBe(overrides); - }); -}); diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionOverrides.ts b/packages/frontend-plugin-api/src/wiring/createExtensionOverrides.ts deleted file mode 100644 index 887f9b8dab..0000000000 --- a/packages/frontend-plugin-api/src/wiring/createExtensionOverrides.ts +++ /dev/null @@ -1,80 +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 { ExtensionDefinition } from './createExtension'; -import { - Extension, - resolveExtensionDefinition, -} from './resolveExtensionDefinition'; -import { ExtensionOverrides, FeatureFlagConfig } from './types'; - -/** - * @deprecated Use {@link createFrontendModule} instead. - * @public - */ -export interface ExtensionOverridesOptions { - extensions: ExtensionDefinition[]; - featureFlags?: FeatureFlagConfig[]; -} - -/** @internal */ -export interface InternalExtensionOverrides extends ExtensionOverrides { - readonly version: 'v1'; - readonly extensions: Extension[]; - readonly featureFlags: FeatureFlagConfig[]; -} - -/** - * @deprecated Use {@link createFrontendModule} instead. - * @public - */ -export function createExtensionOverrides( - options: ExtensionOverridesOptions, -): ExtensionOverrides { - const extensions = options.extensions.map(def => - resolveExtensionDefinition(def), - ); - const featureFlags = options.featureFlags ?? []; - return { - $$type: '@backstage/ExtensionOverrides', - version: 'v1', - extensions, - featureFlags, - toString() { - const ex = extensions.map(String).join(','); - const ff = featureFlags.map(f => f.name).join(','); - return `ExtensionOverrides{extensions=[${ex}],featureFlags=[${ff}]}`; - }, - } as InternalExtensionOverrides; -} - -/** @internal */ -export function toInternalExtensionOverrides( - overrides: ExtensionOverrides, -): InternalExtensionOverrides { - const internal = overrides as InternalExtensionOverrides; - if (internal.$$type !== '@backstage/ExtensionOverrides') { - throw new Error( - `Invalid extension overrides instance, bad type '${internal.$$type}'`, - ); - } - if (internal.version !== 'v1') { - throw new Error( - `Invalid extension overrides instance, bad version '${internal.version}'`, - ); - } - return internal; -} diff --git a/packages/frontend-plugin-api/src/wiring/createFrontendModule.ts b/packages/frontend-plugin-api/src/wiring/createFrontendModule.ts index aacc34ccf0..bece1539fa 100644 --- a/packages/frontend-plugin-api/src/wiring/createFrontendModule.ts +++ b/packages/frontend-plugin-api/src/wiring/createFrontendModule.ts @@ -14,11 +14,8 @@ * limitations under the License. */ -import { - ExtensionDefinition, - InternalExtensionDefinition, - toInternalExtensionDefinition, -} from './createExtension'; +import { OpaqueExtensionDefinition } from '@internal/frontend'; +import { ExtensionDefinition } from './createExtension'; import { Extension, resolveExtensionDefinition, @@ -58,11 +55,11 @@ export function createFrontendModule< const extensions = new Array>(); const extensionDefinitionsById = new Map< string, - InternalExtensionDefinition + typeof OpaqueExtensionDefinition.TInternal >(); for (const def of options.extensions ?? []) { - const internal = toInternalExtensionDefinition(def); + const internal = OpaqueExtensionDefinition.toInternal(def); const ext = resolveExtensionDefinition(def, { namespace: pluginId }); extensions.push(ext); extensionDefinitionsById.set(ext.id, { diff --git a/packages/frontend-plugin-api/src/wiring/createFrontendPlugin.test.ts b/packages/frontend-plugin-api/src/wiring/createFrontendPlugin.test.ts index c461d6fb20..65daad0586 100644 --- a/packages/frontend-plugin-api/src/wiring/createFrontendPlugin.test.ts +++ b/packages/frontend-plugin-api/src/wiring/createFrontendPlugin.test.ts @@ -15,7 +15,8 @@ */ import React from 'react'; -import { createApp } from '@backstage/frontend-app-api'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { createApp } from '../../../frontend-defaults/src/createApp'; import { screen } from '@testing-library/react'; import { FrontendPlugin, createFrontendPlugin } from './createFrontendPlugin'; import { JsonObject } from '@backstage/types'; @@ -170,7 +171,9 @@ describe('createFrontendPlugin', () => { } `); // @ts-expect-error - expect(plugin.getExtension('nonexistent')).toBeUndefined(); + expect(() => plugin.getExtension('nonexistent')).toThrow( + /Attempted to get non-existent extension/, + ); await renderWithEffects( createTestAppRoot({ diff --git a/packages/frontend-plugin-api/src/wiring/createFrontendPlugin.ts b/packages/frontend-plugin-api/src/wiring/createFrontendPlugin.ts index 03c843543d..1ab7dc8e83 100644 --- a/packages/frontend-plugin-api/src/wiring/createFrontendPlugin.ts +++ b/packages/frontend-plugin-api/src/wiring/createFrontendPlugin.ts @@ -15,10 +15,10 @@ */ import { - ExtensionDefinition, - InternalExtensionDefinition, - toInternalExtensionDefinition, -} from './createExtension'; + OpaqueExtensionDefinition, + OpaqueFrontendPlugin, +} from '@internal/frontend'; +import { ExtensionDefinition } from './createExtension'; import { Extension, ResolveExtensionId, @@ -30,7 +30,9 @@ import { AnyExternalRoutes, AnyRoutes, FeatureFlagConfig } from './types'; export interface FrontendPlugin< TRoutes extends AnyRoutes = AnyRoutes, TExternalRoutes extends AnyExternalRoutes = AnyExternalRoutes, - TExtensionMap extends { [id in string]: ExtensionDefinition } = {}, + TExtensionMap extends { [id in string]: ExtensionDefinition } = { + [id in string]: ExtensionDefinition; + }, > { readonly $$type: '@backstage/FrontendPlugin'; readonly id: string; @@ -42,15 +44,6 @@ export interface FrontendPlugin< }): FrontendPlugin; } -/** - * @public - * @deprecated Use {@link FrontendPlugin} instead. - */ -export type BackstagePlugin< - TRoutes extends AnyRoutes = AnyRoutes, - TExternalRoutes extends AnyExternalRoutes = AnyExternalRoutes, - TExtensionMap extends { [id in string]: ExtensionDefinition } = {}, -> = FrontendPlugin; /** @public */ export interface PluginOptions< TId extends string, @@ -65,16 +58,6 @@ export interface PluginOptions< featureFlags?: FeatureFlagConfig[]; } -/** @public */ -export interface InternalFrontendPlugin< - TRoutes extends AnyRoutes = AnyRoutes, - TExternalRoutes extends AnyExternalRoutes = AnyExternalRoutes, -> extends FrontendPlugin { - readonly version: 'v1'; - readonly extensions: Extension[]; - readonly featureFlags: FeatureFlagConfig[]; -} - /** @public */ export function createFrontendPlugin< TId extends string, @@ -96,11 +79,11 @@ export function createFrontendPlugin< const extensions = new Array>(); const extensionDefinitionsById = new Map< string, - InternalExtensionDefinition + typeof OpaqueExtensionDefinition.TInternal >(); for (const def of options.extensions ?? []) { - const internal = toInternalExtensionDefinition(def); + const internal = OpaqueExtensionDefinition.toInternal(def); const ext = resolveExtensionDefinition(def, { namespace: options.id }); extensions.push(ext); extensionDefinitionsById.set(ext.id, { @@ -124,16 +107,20 @@ export function createFrontendPlugin< ); } - return { - $$type: '@backstage/FrontendPlugin', - version: 'v1', + return OpaqueFrontendPlugin.createInstance('v1', { id: options.id, routes: options.routes ?? ({} as TRoutes), externalRoutes: options.externalRoutes ?? ({} as TExternalRoutes), featureFlags: options.featureFlags ?? [], - extensions, + extensions: extensions, getExtension(id) { - return extensionDefinitionsById.get(id); + const ext = extensionDefinitionsById.get(id); + if (!ext) { + throw new Error( + `Attempted to get non-existent extension '${id}' from plugin '${options.id}'`, + ); + } + return ext; }, toString() { return `Plugin{id=${options.id}}`; @@ -155,45 +142,5 @@ export function createFrontendPlugin< extensions: [...nonOverriddenExtensions, ...overrides.extensions], }); }, - } as InternalFrontendPlugin; + }); } - -/** @internal */ -export function isInternalFrontendPlugin(opaque: { - $$type: string; -}): opaque is InternalFrontendPlugin { - if ( - opaque.$$type === '@backstage/FrontendPlugin' || - opaque.$$type === '@backstage/BackstagePlugin' - ) { - // Make sure we throw if invalid - toInternalFrontendPlugin(opaque as FrontendPlugin); - return true; - } - return false; -} - -/** @internal */ -export function toInternalFrontendPlugin( - plugin: FrontendPlugin, -): InternalFrontendPlugin { - const internal = plugin as InternalFrontendPlugin; - if ( - internal.$$type !== '@backstage/FrontendPlugin' && - internal.$$type !== '@backstage/BackstagePlugin' - ) { - throw new Error(`Invalid plugin instance, bad type '${internal.$$type}'`); - } - if (internal.version !== 'v1') { - throw new Error( - `Invalid plugin instance, bad version '${internal.version}'`, - ); - } - return internal; -} - -/** - * @public - * @deprecated Use {@link createFrontendPlugin} instead. - */ -export const createPlugin = createFrontendPlugin; diff --git a/packages/frontend-plugin-api/src/wiring/index.ts b/packages/frontend-plugin-api/src/wiring/index.ts index f8ad362bac..ebbaf4429f 100644 --- a/packages/frontend-plugin-api/src/wiring/index.ts +++ b/packages/frontend-plugin-api/src/wiring/index.ts @@ -37,10 +37,8 @@ export { type ConfigurableExtensionDataRef, } from './createExtensionDataRef'; export { - createPlugin, createFrontendPlugin, type FrontendPlugin, - type BackstagePlugin, type PluginOptions, } from './createFrontendPlugin'; export { @@ -48,10 +46,6 @@ export { type FrontendModule, type CreateFrontendModuleOptions, } from './createFrontendModule'; -export { - createExtensionOverrides, - type ExtensionOverridesOptions, -} from './createExtensionOverrides'; export { type Extension } from './resolveExtensionDefinition'; export { type AnyRoutes, diff --git a/packages/frontend-plugin-api/src/wiring/resolveExtensionDefinition.test.ts b/packages/frontend-plugin-api/src/wiring/resolveExtensionDefinition.test.ts index 09c7b9e9a9..b25a7b9375 100644 --- a/packages/frontend-plugin-api/src/wiring/resolveExtensionDefinition.test.ts +++ b/packages/frontend-plugin-api/src/wiring/resolveExtensionDefinition.test.ts @@ -108,103 +108,42 @@ describe('ResolveExtensionId', () => { it('should resolve extension IDs correctly', () => { type NamedExtension< TKind extends string | undefined, - TNamespace extends string | undefined, TName extends string | undefined, > = ExtensionDefinition<{ kind: TKind; - namespace: TNamespace; name: TName; output: any; }>; - const id1: 'k:ns' = {} as ResolveExtensionId< - NamedExtension<'k', 'ns', undefined>, - undefined + NamedExtension<'k', undefined>, + 'ns' >; - const id2: 'k:n' = {} as ResolveExtensionId< - NamedExtension<'k', undefined, 'n'>, - undefined + + const id2: 'ns/n' = {} as ResolveExtensionId< + NamedExtension, + 'ns' >; - const id3: 'ns/n' = {} as ResolveExtensionId< - NamedExtension, - undefined + + const id3: 'ns' = {} as ResolveExtensionId< + NamedExtension, + 'ns' >; - const id4: never = {} as ResolveExtensionId< - NamedExtension<'k', undefined, undefined>, - undefined - >; - const id5: 'ns' = {} as ResolveExtensionId< - NamedExtension, - undefined - >; - const id6: 'n' = {} as ResolveExtensionId< - NamedExtension, - undefined - >; - const id7: 'k:ns/n' = {} as ResolveExtensionId< - NamedExtension<'k', 'ns', 'n'>, - undefined - >; - const id8: 'k:ns2' = {} as ResolveExtensionId< - NamedExtension<'k', 'ns', undefined>, - 'ns2' - >; - const id9: 'k:ns2/n' = {} as ResolveExtensionId< - NamedExtension<'k', undefined, 'n'>, - 'ns2' - >; - const ida: 'ns2/n' = {} as ResolveExtensionId< - NamedExtension, - 'ns2' - >; - const idb: 'k:ns2' = {} as ResolveExtensionId< - NamedExtension<'k', undefined, undefined>, - 'ns2' - >; - const idc: 'ns2' = {} as ResolveExtensionId< - NamedExtension, - 'ns2' - >; - const idd: 'ns2/n' = {} as ResolveExtensionId< - NamedExtension, - 'ns2' - >; - const ide: 'k:ns2/n' = {} as ResolveExtensionId< - NamedExtension<'k', 'ns', 'n'>, - 'ns2' + + const id4: 'k:ns/n' = {} as ResolveExtensionId< + NamedExtension<'k', 'n'>, + 'ns' >; const invalid1: never = {} as ResolveExtensionId< - NamedExtension, - undefined - >; - const invalid2: never = {} as ResolveExtensionId< - NamedExtension<'k', string | undefined, 'n'>, - undefined - >; - const invalid3: never = {} as ResolveExtensionId< - NamedExtension<'k', 'ns', string | undefined>, - undefined + NamedExtension<'k', string | undefined>, + 'ns' >; - expect([ - id1, - id2, - id3, - id4, - id5, - id6, - id7, - id8, - id9, - ida, - idb, - idc, - idd, - ide, - invalid1, - invalid2, - invalid3, - ]).toBeDefined(); + const invalid2: never = {} as ResolveExtensionId< + NamedExtension<'k', string>, + 'ns' + >; + + expect([id1, id2, id3, id4, invalid1, invalid2]).toBeDefined(); }); }); diff --git a/packages/frontend-plugin-api/src/wiring/resolveExtensionDefinition.ts b/packages/frontend-plugin-api/src/wiring/resolveExtensionDefinition.ts index 5a631819d7..1e8ac77a01 100644 --- a/packages/frontend-plugin-api/src/wiring/resolveExtensionDefinition.ts +++ b/packages/frontend-plugin-api/src/wiring/resolveExtensionDefinition.ts @@ -19,7 +19,6 @@ import { ExtensionDefinition, ExtensionDefinitionParameters, ResolvedExtensionInputs, - toInternalExtensionDefinition, } from './createExtension'; import { PortableSchema } from '../schema'; import { ExtensionInput } from './createExtensionInput'; @@ -27,6 +26,7 @@ import { AnyExtensionDataRef, ExtensionDataValue, } from './createExtensionDataRef'; +import { OpaqueExtensionDefinition } from '@internal/frontend'; /** @public */ export interface Extension { @@ -111,22 +111,15 @@ export function toInternalExtension( /** @ignore */ export type ResolveExtensionId< TExtension extends ExtensionDefinition, - TDefaultNamespace extends string | undefined, + TNamespace extends string, > = TExtension extends ExtensionDefinition<{ kind: infer IKind extends string | undefined; - namespace: infer INamespace extends string | undefined; name: infer IName extends string | undefined; }> - ? [string | undefined] extends [IKind | INamespace | IName] + ? [string] extends [IKind | IName] ? never : ( - ( - undefined extends TDefaultNamespace ? INamespace : TDefaultNamespace - ) extends infer ISelectedNamespace extends string - ? undefined extends IName - ? ISelectedNamespace - : `${ISelectedNamespace}/${IName}` - : IName + undefined extends IName ? TNamespace : `${TNamespace}/${IName}` ) extends infer INamePart extends string ? IKind extends string ? `${IKind}:${INamePart}` @@ -141,7 +134,7 @@ export function resolveExtensionDefinition< definition: ExtensionDefinition, context?: { namespace?: string }, ): Extension { - const internalDefinition = toInternalExtensionDefinition(definition); + const internalDefinition = OpaqueExtensionDefinition.toInternal(definition); const { name, kind, diff --git a/packages/frontend-test-utils/CHANGELOG.md b/packages/frontend-test-utils/CHANGELOG.md index fdc40b60a8..37b14f0035 100644 --- a/packages/frontend-test-utils/CHANGELOG.md +++ b/packages/frontend-test-utils/CHANGELOG.md @@ -1,5 +1,75 @@ # @backstage/frontend-test-utils +## 0.2.1-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.1 + - @backstage/frontend-app-api@0.10.0-next.1 + - @backstage/version-bridge@1.0.10-next.0 + - @backstage/test-utils@1.6.1-next.1 + - @backstage/plugin-app@0.1.1-next.1 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## 0.2.1-next.0 + +### Patch Changes + +- 873e424: Internal refactor of usage of opaque types. +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/frontend-app-api@0.10.0-next.0 + - @backstage/plugin-app@0.1.1-next.0 + - @backstage/config@1.2.0 + - @backstage/test-utils@1.6.1-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.9 + +## 0.2.0 + +### Minor Changes + +- 5446061: Removed support for testing "v1" extensions, where outputs are defined as an object rather than an array. +- e6e488c: **BREAKING**: The deprecated `.render()` method has been removed from the extension tester. + +### Patch Changes + +- 2a61422: The extension tester will no longer unconditionally enable any additional extensions that have been added. +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. +- 4a66456: Internal update to add support for passing an `ApiRegistry` when creating the node tree +- 2bb9517: Introduce the `@backstage/plugin-app` package to hold all of the built-in extensions for easy consumption and overriding. +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- 948d431: Removing deprecated `namespace` parameter in favour of `pluginId` instead +- 043d7cd: Internal refactor +- f6d1874: Added the ability to provide additional `extensions` and `features` to `renderInTestApp` +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0 + - @backstage/frontend-app-api@0.9.0 + - @backstage/plugin-app@0.1.0 + - @backstage/test-utils@1.6.0 + - @backstage/version-bridge@1.0.9 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## 0.2.0-next.2 + +### Patch Changes + +- 2a61422: The extension tester will no longer unconditionally enable any additional extensions that have been added. +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- 043d7cd: Internal refactor +- Updated dependencies + - @backstage/test-utils@1.6.0-next.1 + - @backstage/plugin-app@0.1.0-next.2 + - @backstage/frontend-app-api@0.9.0-next.2 + - @backstage/frontend-plugin-api@0.8.0-next.2 + - @backstage/version-bridge@1.0.9-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + ## 0.2.0-next.1 ### Patch Changes diff --git a/packages/frontend-test-utils/package.json b/packages/frontend-test-utils/package.json index 988ce42822..27bb592879 100644 --- a/packages/frontend-test-utils/package.json +++ b/packages/frontend-test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/frontend-test-utils", - "version": "0.2.0-next.1", + "version": "0.2.1-next.1", "backstage": { "role": "web-library" }, @@ -36,16 +36,28 @@ "@backstage/frontend-plugin-api": "workspace:^", "@backstage/plugin-app": "workspace:^", "@backstage/test-utils": "workspace:^", - "@backstage/types": "workspace:^" + "@backstage/types": "workspace:^", + "@backstage/version-bridge": "workspace:^", + "zod": "^3.22.4" }, "devDependencies": { "@backstage/cli": "workspace:^", "@testing-library/jest-dom": "^6.0.0", - "@types/react": "*" + "@types/react": "^18.0.0", + "react": "^18.0.2", + "react-dom": "^18.0.2", + "react-router-dom": "^6.3.0" }, "peerDependencies": { - "@testing-library/react": "^15.0.0", + "@testing-library/react": "^16.0.0", + "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } } diff --git a/packages/frontend-test-utils/api-report.md b/packages/frontend-test-utils/report.api.md similarity index 75% rename from packages/frontend-test-utils/api-report.md rename to packages/frontend-test-utils/report.api.md index 10b84b0981..1337e5eb4f 100644 --- a/packages/frontend-test-utils/api-report.md +++ b/packages/frontend-test-utils/report.api.md @@ -140,4 +140,20 @@ export type TestAppOptions = { }; export { withLogCollector }; + +// Warnings were encountered during analysis: +// +// src/apis/AnalyticsApi/MockAnalyticsApi.d.ts:10:5 - (ae-undocumented) Missing documentation for "captureEvent". +// src/apis/AnalyticsApi/MockAnalyticsApi.d.ts:11:5 - (ae-undocumented) Missing documentation for "getEvents". +// src/app/createExtensionTester.d.ts:4:1 - (ae-undocumented) Missing documentation for "ExtensionQuery". +// src/app/createExtensionTester.d.ts:7:5 - (ae-undocumented) Missing documentation for "node". +// src/app/createExtensionTester.d.ts:8:5 - (ae-undocumented) Missing documentation for "instance". +// src/app/createExtensionTester.d.ts:9:5 - (ae-undocumented) Missing documentation for "get". +// src/app/createExtensionTester.d.ts:12:1 - (ae-undocumented) Missing documentation for "ExtensionTester". +// src/app/createExtensionTester.d.ts:14:5 - (ae-undocumented) Missing documentation for "add". +// src/app/createExtensionTester.d.ts:17:5 - (ae-undocumented) Missing documentation for "get". +// src/app/createExtensionTester.d.ts:18:5 - (ae-undocumented) Missing documentation for "query". +// src/app/createExtensionTester.d.ts:19:5 - (ae-undocumented) Missing documentation for "reactElement". +// src/app/createExtensionTester.d.ts:22:1 - (ae-undocumented) Missing documentation for "createExtensionTester". +// src/deprecated.d.ts:5:1 - (ae-undocumented) Missing documentation for "setupRequestMockHandlers". ``` diff --git a/packages/frontend-test-utils/src/app/createExtensionTester.tsx b/packages/frontend-test-utils/src/app/createExtensionTester.tsx index f9c1b3cb89..37ec1d8fd9 100644 --- a/packages/frontend-test-utils/src/app/createExtensionTester.tsx +++ b/packages/frontend-test-utils/src/app/createExtensionTester.tsx @@ -29,8 +29,6 @@ import { JsonArray, JsonObject, JsonValue } from '@backstage/types'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports import { resolveExtensionDefinition } from '../../../frontend-plugin-api/src/wiring/resolveExtensionDefinition'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { toInternalExtensionDefinition } from '../../../frontend-plugin-api/src/wiring/createExtension'; -// eslint-disable-next-line @backstage/no-relative-monorepo-imports import { resolveAppTree } from '../../../frontend-app-api/src/tree/resolveAppTree'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports import { resolveAppNodeSpecs } from '../../../frontend-app-api/src/tree/resolveAppNodeSpecs'; @@ -39,6 +37,7 @@ import { instantiateAppNodeTree } from '../../../frontend-app-api/src/tree/insta // eslint-disable-next-line @backstage/no-relative-monorepo-imports import { readAppExtensionsConfig } from '../../../frontend-app-api/src/tree/readAppExtensionsConfig'; import { TestApiRegistry } from '@backstage/test-utils'; +import { OpaqueExtensionDefinition } from '@internal/frontend'; /** @public */ export class ExtensionQuery { @@ -106,7 +105,7 @@ export class ExtensionTester { ); } - const { name, namespace } = toInternalExtensionDefinition(extension); + const { name, namespace } = OpaqueExtensionDefinition.toInternal(extension); const definition = { ...extension, @@ -144,7 +143,7 @@ export class ExtensionTester { const tree = this.#resolveTree(); // Same fallback logic as in .add - const { name, namespace } = toInternalExtensionDefinition(extension); + const { name, namespace } = OpaqueExtensionDefinition.toInternal(extension); const definition = { ...extension, name: !namespace && !name ? 'test' : name, @@ -213,11 +212,17 @@ export class ExtensionTester { const [subject, ...rest] = this.#extensions; const extensionsConfig: JsonArray = [ - ...rest.map(extension => ({ - [extension.id]: { - config: extension.config, - }, - })), + ...rest.flatMap(extension => + extension.config + ? [ + { + [extension.id]: { + config: extension.config, + }, + }, + ] + : [], + ), { [subject.id]: { config: subject.config, diff --git a/packages/integration-aws-node/api-report.md b/packages/integration-aws-node/report.api.md similarity index 86% rename from packages/integration-aws-node/api-report.md rename to packages/integration-aws-node/report.api.md index d9ed25e193..80b1eee3ba 100644 --- a/packages/integration-aws-node/api-report.md +++ b/packages/integration-aws-node/report.api.md @@ -35,5 +35,9 @@ export class DefaultAwsCredentialsManager implements AwsCredentialsManager { ): Promise; } +// Warnings were encountered during analysis: +// +// src/DefaultAwsCredentialsManager.d.ts:12:5 - (ae-undocumented) Missing documentation for "fromConfig". + // (No @packageDocumentation comment for this package) ``` diff --git a/packages/integration-react/CHANGELOG.md b/packages/integration-react/CHANGELOG.md index a5bf99ba4d..05e7d3e386 100644 --- a/packages/integration-react/CHANGELOG.md +++ b/packages/integration-react/CHANGELOG.md @@ -1,5 +1,55 @@ # @backstage/integration-react +## 1.2.0-next.1 + +### Minor Changes + +- a11495a: Added new ScmAuth method `forBitbucketServer` that uses correct OAuth scopes by default. Also updated `forBitbucket` method to allow overriding the default OAuth scopes. + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- 3dbac17: Revert of change #26430 +- Updated dependencies + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/integration@1.15.1-next.0 + - @backstage/config@1.2.0 + +## 1.1.32-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.15.0 + +## 1.1.31 + +### Patch Changes + +- 8a9d797: Remove unnecessary broad permissions from Gitlab `SCMAuth` + + Newer versions of Gitlab (after 2019) do not require the broad api permissions to write to repos. + +- Updated dependencies + - @backstage/integration@1.15.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/config@1.2.0 + +## 1.1.31-next.0 + +### Patch Changes + +- 8a9d797: Remove unnecessary broad permissions from Gitlab `SCMAuth` + + Newer versions of Gitlab (after 2019) do not require the broad api permissions to write to repos. + +- Updated dependencies + - @backstage/integration@1.15.0-next.0 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/config@1.2.0 + ## 1.1.30 ### Patch Changes diff --git a/packages/integration-react/package.json b/packages/integration-react/package.json index 0ae77a9bd2..878a44a3ec 100644 --- a/packages/integration-react/package.json +++ b/packages/integration-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/integration-react", - "version": "1.1.30", + "version": "1.2.0-next.1", "description": "Frontend package for managing integrations towards external systems", "backstage": { "role": "web-library" @@ -37,8 +37,7 @@ "@backstage/core-plugin-api": "workspace:^", "@backstage/integration": "workspace:^", "@material-ui/core": "^4.12.2", - "@material-ui/icons": "^4.9.1", - "@types/react": "^16.13.1 || ^17.0.0" + "@material-ui/icons": "^4.9.1" }, "devDependencies": { "@backstage/cli": "workspace:^", @@ -47,11 +46,21 @@ "@backstage/test-utils": "workspace:^", "@testing-library/dom": "^10.0.0", "@testing-library/jest-dom": "^6.0.0", - "msw": "^1.0.0" + "@types/react": "^18.0.0", + "msw": "^1.0.0", + "react": "^18.0.2", + "react-dom": "^18.0.2", + "react-router-dom": "^6.3.0" }, "peerDependencies": { + "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } } diff --git a/packages/integration-react/api-report.md b/packages/integration-react/report.api.md similarity index 91% rename from packages/integration-react/api-report.md rename to packages/integration-react/report.api.md index c1a2e34907..8d02c46010 100644 --- a/packages/integration-react/api-report.md +++ b/packages/integration-react/report.api.md @@ -55,6 +55,20 @@ export class ScmAuth implements ScmAuthApi { bitbucketAuthApi: OAuthApi, options?: { host?: string; + scopeMapping?: { + default?: string[]; + repoWrite?: string[]; + }; + }, + ): ScmAuth; + static forBitbucketServer( + bitbucketAuthApi: OAuthApi, + options: { + host: string; + scopeMapping?: { + default?: string[]; + repoWrite?: string[]; + }; }, ): ScmAuth; static forGithub( diff --git a/packages/integration-react/src/api/ScmAuth.ts b/packages/integration-react/src/api/ScmAuth.ts index a22b15e400..1b68d56a6e 100644 --- a/packages/integration-react/src/api/ScmAuth.ts +++ b/packages/integration-react/src/api/ScmAuth.ts @@ -173,7 +173,7 @@ export class ScmAuth implements ScmAuthApi { const host = options?.host ?? 'gitlab.com'; return new ScmAuth('gitlab', gitlabAuthApi, host, { default: ['read_user', 'read_api', 'read_repository'], - repoWrite: ['write_repository', 'api'], + repoWrite: ['write_repository api'], }); } @@ -226,12 +226,63 @@ export class ScmAuth implements ScmAuthApi { bitbucketAuthApi: OAuthApi, options?: { host?: string; + scopeMapping?: { + default?: string[]; + repoWrite?: string[]; + }; }, ): ScmAuth { const host = options?.host ?? 'bitbucket.org'; + const defaultScopes = options?.scopeMapping?.default ?? [ + 'account', + 'team', + 'pullrequest', + 'snippet', + 'issue', + ]; + const repoWriteScopes = options?.scopeMapping?.repoWrite ?? [ + 'pullrequest:write', + 'snippet:write', + 'issue:write', + ]; return new ScmAuth('bitbucket', bitbucketAuthApi, host, { - default: ['account', 'team', 'pullrequest', 'snippet', 'issue'], - repoWrite: ['pullrequest:write', 'snippet:write', 'issue:write'], + default: defaultScopes, + repoWrite: repoWriteScopes, + }); + } + + /** + * Creates a new ScmAuth instance that handles authentication towards Bitbucket Server. + * + * The host option determines which URLs that are handled by this instance. + * + * The default scopes are: + * + * `PUBLIC_REPOS REPOS_READ` + * + * If the additional `repoWrite` permission is requested, these scopes are added: + * + * `REPO_WRITE` + */ + static forBitbucketServer( + bitbucketAuthApi: OAuthApi, + options: { + host: string; + scopeMapping?: { + default?: string[]; + repoWrite?: string[]; + }; + }, + ): ScmAuth { + return this.forBitbucket(bitbucketAuthApi, { + host: options.host, + scopeMapping: { + default: options.scopeMapping?.default ?? [ + 'PUBLIC_REPOS', + 'REPOS_READ', + ], + repoWrite: options.scopeMapping?.repoWrite ?? ['REPO_WRITE'], + }, }); } diff --git a/packages/integration/CHANGELOG.md b/packages/integration/CHANGELOG.md index 9e8fef7af8..9c3195d7f5 100644 --- a/packages/integration/CHANGELOG.md +++ b/packages/integration/CHANGELOG.md @@ -1,5 +1,51 @@ # @backstage/integration +## 1.15.1-next.0 + +### Patch Changes + +- 920004b: Updating error message for getProjectId when fetching Gitlab project from its url to be more accurate +- 090e49a: Updated functions parseHarnessUrl, getHarnessLatestCommitUrl, getHarnessFileContentsUrl and getHarnessArchiveUrl to fix parsing of urls +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## 1.15.0 + +### Minor Changes + +- 1573014: The Gerrit integration can now resolve Gitiles urls that point to the following + refs: + + - HEAD + - A SHA + - Tag + - Branch + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## 1.15.0-next.0 + +### Minor Changes + +- 1573014: The Gerrit integration can now resolve Gitiles urls that point to the following + refs: + + - HEAD + - A SHA + - Tag + - Branch + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + ## 1.14.0 ### Minor Changes diff --git a/packages/integration/package.json b/packages/integration/package.json index 83c6e4ce8b..7ca8c6f073 100644 --- a/packages/integration/package.json +++ b/packages/integration/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/integration", - "version": "1.14.0", + "version": "1.15.1-next.0", "description": "Helpers for managing integrations towards external systems", "backstage": { "role": "common-library" diff --git a/packages/integration/api-report.md b/packages/integration/report.api.md similarity index 66% rename from packages/integration/api-report.md rename to packages/integration/report.api.md index e9b67bb6c1..e14a93b9a4 100644 --- a/packages/integration/api-report.md +++ b/packages/integration/report.api.md @@ -1027,4 +1027,127 @@ export class SingleInstanceGithubCredentialsProvider static create: (config: GithubIntegrationConfig) => GithubCredentialsProvider; getCredentials(opts: { url: string }): Promise; } + +// Warnings were encountered during analysis: +// +// src/ScmIntegrations.d.ts:21:5 - (ae-undocumented) Missing documentation for "awsS3". +// src/ScmIntegrations.d.ts:22:5 - (ae-undocumented) Missing documentation for "awsCodeCommit". +// src/ScmIntegrations.d.ts:23:5 - (ae-undocumented) Missing documentation for "azure". +// src/ScmIntegrations.d.ts:27:5 - (ae-undocumented) Missing documentation for "bitbucket". +// src/ScmIntegrations.d.ts:28:5 - (ae-undocumented) Missing documentation for "bitbucketCloud". +// src/ScmIntegrations.d.ts:29:5 - (ae-undocumented) Missing documentation for "bitbucketServer". +// src/ScmIntegrations.d.ts:30:5 - (ae-undocumented) Missing documentation for "gerrit". +// src/ScmIntegrations.d.ts:31:5 - (ae-undocumented) Missing documentation for "github". +// src/ScmIntegrations.d.ts:32:5 - (ae-undocumented) Missing documentation for "gitlab". +// src/ScmIntegrations.d.ts:33:5 - (ae-undocumented) Missing documentation for "gitea". +// src/ScmIntegrations.d.ts:34:5 - (ae-undocumented) Missing documentation for "harness". +// src/ScmIntegrations.d.ts:43:5 - (ae-undocumented) Missing documentation for "fromConfig". +// src/ScmIntegrations.d.ts:45:5 - (ae-undocumented) Missing documentation for "awsS3". +// src/ScmIntegrations.d.ts:46:5 - (ae-undocumented) Missing documentation for "awsCodeCommit". +// src/ScmIntegrations.d.ts:47:5 - (ae-undocumented) Missing documentation for "azure". +// src/ScmIntegrations.d.ts:51:5 - (ae-undocumented) Missing documentation for "bitbucket". +// src/ScmIntegrations.d.ts:52:5 - (ae-undocumented) Missing documentation for "bitbucketCloud". +// src/ScmIntegrations.d.ts:53:5 - (ae-undocumented) Missing documentation for "bitbucketServer". +// src/ScmIntegrations.d.ts:54:5 - (ae-undocumented) Missing documentation for "gerrit". +// src/ScmIntegrations.d.ts:55:5 - (ae-undocumented) Missing documentation for "github". +// src/ScmIntegrations.d.ts:56:5 - (ae-undocumented) Missing documentation for "gitlab". +// src/ScmIntegrations.d.ts:57:5 - (ae-undocumented) Missing documentation for "gitea". +// src/ScmIntegrations.d.ts:58:5 - (ae-undocumented) Missing documentation for "harness". +// src/ScmIntegrations.d.ts:59:5 - (ae-undocumented) Missing documentation for "list". +// src/ScmIntegrations.d.ts:60:5 - (ae-undocumented) Missing documentation for "byUrl". +// src/ScmIntegrations.d.ts:61:5 - (ae-undocumented) Missing documentation for "byHost". +// src/ScmIntegrations.d.ts:62:5 - (ae-undocumented) Missing documentation for "resolveUrl". +// src/ScmIntegrations.d.ts:67:5 - (ae-undocumented) Missing documentation for "resolveEditUrl". +// src/awsCodeCommit/AwsCodeCommitIntegration.d.ts:10:5 - (ae-undocumented) Missing documentation for "factory". +// src/awsCodeCommit/AwsCodeCommitIntegration.d.ts:11:5 - (ae-undocumented) Missing documentation for "type". +// src/awsCodeCommit/AwsCodeCommitIntegration.d.ts:12:5 - (ae-undocumented) Missing documentation for "config". +// src/awsCodeCommit/AwsCodeCommitIntegration.d.ts:13:5 - (ae-undocumented) Missing documentation for "title". +// src/awsCodeCommit/AwsCodeCommitIntegration.d.ts:15:5 - (ae-undocumented) Missing documentation for "resolveUrl". +// src/awsCodeCommit/AwsCodeCommitIntegration.d.ts:20:5 - (ae-undocumented) Missing documentation for "resolveEditUrl". +// src/awsS3/AwsS3Integration.d.ts:10:5 - (ae-undocumented) Missing documentation for "factory". +// src/awsS3/AwsS3Integration.d.ts:11:5 - (ae-undocumented) Missing documentation for "type". +// src/awsS3/AwsS3Integration.d.ts:12:5 - (ae-undocumented) Missing documentation for "title". +// src/awsS3/AwsS3Integration.d.ts:13:5 - (ae-undocumented) Missing documentation for "config". +// src/awsS3/AwsS3Integration.d.ts:15:5 - (ae-undocumented) Missing documentation for "resolveUrl". +// src/awsS3/AwsS3Integration.d.ts:20:5 - (ae-undocumented) Missing documentation for "resolveEditUrl". +// src/azure/AzureIntegration.d.ts:10:5 - (ae-undocumented) Missing documentation for "factory". +// src/azure/AzureIntegration.d.ts:12:5 - (ae-undocumented) Missing documentation for "type". +// src/azure/AzureIntegration.d.ts:13:5 - (ae-undocumented) Missing documentation for "title". +// src/azure/AzureIntegration.d.ts:14:5 - (ae-undocumented) Missing documentation for "config". +// src/azure/AzureIntegration.d.ts:15:5 - (ae-undocumented) Missing documentation for "resolveUrl". +// src/azure/AzureIntegration.d.ts:20:5 - (ae-undocumented) Missing documentation for "resolveEditUrl". +// src/azure/DefaultAzureDevOpsCredentialsProvider.d.ts:9:5 - (ae-undocumented) Missing documentation for "fromIntegrations". +// src/azure/DefaultAzureDevOpsCredentialsProvider.d.ts:14:5 - (ae-undocumented) Missing documentation for "getCredentials". +// src/azure/types.d.ts:25:5 - (ae-undocumented) Missing documentation for "getCredentials". +// src/bitbucket/BitbucketIntegration.d.ts:11:5 - (ae-undocumented) Missing documentation for "factory". +// src/bitbucket/BitbucketIntegration.d.ts:13:5 - (ae-undocumented) Missing documentation for "type". +// src/bitbucket/BitbucketIntegration.d.ts:14:5 - (ae-undocumented) Missing documentation for "title". +// src/bitbucket/BitbucketIntegration.d.ts:15:5 - (ae-undocumented) Missing documentation for "config". +// src/bitbucket/BitbucketIntegration.d.ts:16:5 - (ae-undocumented) Missing documentation for "resolveUrl". +// src/bitbucket/BitbucketIntegration.d.ts:21:5 - (ae-undocumented) Missing documentation for "resolveEditUrl". +// src/bitbucketCloud/BitbucketCloudIntegration.d.ts:10:5 - (ae-undocumented) Missing documentation for "factory". +// src/bitbucketCloud/BitbucketCloudIntegration.d.ts:12:5 - (ae-undocumented) Missing documentation for "type". +// src/bitbucketCloud/BitbucketCloudIntegration.d.ts:13:5 - (ae-undocumented) Missing documentation for "title". +// src/bitbucketCloud/BitbucketCloudIntegration.d.ts:14:5 - (ae-undocumented) Missing documentation for "config". +// src/bitbucketCloud/BitbucketCloudIntegration.d.ts:15:5 - (ae-undocumented) Missing documentation for "resolveUrl". +// src/bitbucketCloud/BitbucketCloudIntegration.d.ts:20:5 - (ae-undocumented) Missing documentation for "resolveEditUrl". +// src/bitbucketServer/BitbucketServerIntegration.d.ts:10:5 - (ae-undocumented) Missing documentation for "factory". +// src/bitbucketServer/BitbucketServerIntegration.d.ts:12:5 - (ae-undocumented) Missing documentation for "type". +// src/bitbucketServer/BitbucketServerIntegration.d.ts:13:5 - (ae-undocumented) Missing documentation for "title". +// src/bitbucketServer/BitbucketServerIntegration.d.ts:14:5 - (ae-undocumented) Missing documentation for "config". +// src/bitbucketServer/BitbucketServerIntegration.d.ts:15:5 - (ae-undocumented) Missing documentation for "resolveUrl". +// src/bitbucketServer/BitbucketServerIntegration.d.ts:20:5 - (ae-undocumented) Missing documentation for "resolveEditUrl". +// src/gerrit/GerritIntegration.d.ts:10:5 - (ae-undocumented) Missing documentation for "factory". +// src/gerrit/GerritIntegration.d.ts:12:5 - (ae-undocumented) Missing documentation for "type". +// src/gerrit/GerritIntegration.d.ts:13:5 - (ae-undocumented) Missing documentation for "title". +// src/gerrit/GerritIntegration.d.ts:14:5 - (ae-undocumented) Missing documentation for "config". +// src/gerrit/GerritIntegration.d.ts:15:5 - (ae-undocumented) Missing documentation for "resolveUrl". +// src/gerrit/GerritIntegration.d.ts:20:5 - (ae-undocumented) Missing documentation for "resolveEditUrl". +// src/gitea/GiteaIntegration.d.ts:9:5 - (ae-undocumented) Missing documentation for "config". +// src/gitea/GiteaIntegration.d.ts:10:5 - (ae-undocumented) Missing documentation for "factory". +// src/gitea/GiteaIntegration.d.ts:12:5 - (ae-undocumented) Missing documentation for "type". +// src/gitea/GiteaIntegration.d.ts:13:5 - (ae-undocumented) Missing documentation for "title". +// src/gitea/GiteaIntegration.d.ts:14:5 - (ae-undocumented) Missing documentation for "resolveUrl". +// src/gitea/GiteaIntegration.d.ts:19:5 - (ae-undocumented) Missing documentation for "resolveEditUrl". +// src/github/DefaultGithubCredentialsProvider.d.ts:13:5 - (ae-undocumented) Missing documentation for "fromIntegrations". +// src/github/GithubIntegration.d.ts:11:5 - (ae-undocumented) Missing documentation for "factory". +// src/github/GithubIntegration.d.ts:13:5 - (ae-undocumented) Missing documentation for "type". +// src/github/GithubIntegration.d.ts:14:5 - (ae-undocumented) Missing documentation for "title". +// src/github/GithubIntegration.d.ts:15:5 - (ae-undocumented) Missing documentation for "config". +// src/github/GithubIntegration.d.ts:16:5 - (ae-undocumented) Missing documentation for "resolveUrl". +// src/github/GithubIntegration.d.ts:21:5 - (ae-undocumented) Missing documentation for "resolveEditUrl". +// src/github/GithubIntegration.d.ts:22:5 - (ae-undocumented) Missing documentation for "parseRateLimitInfo". +// src/github/SingleInstanceGithubCredentialsProvider.d.ts:12:5 - (ae-undocumented) Missing documentation for "getAllInstallations". +// src/github/SingleInstanceGithubCredentialsProvider.d.ts:13:5 - (ae-undocumented) Missing documentation for "getAppToken". +// src/github/SingleInstanceGithubCredentialsProvider.d.ts:26:5 - (ae-undocumented) Missing documentation for "create". +// src/github/types.d.ts:26:5 - (ae-undocumented) Missing documentation for "getCredentials". +// src/gitlab/DefaultGitlabCredentialsProvider.d.ts:10:5 - (ae-undocumented) Missing documentation for "fromIntegrations". +// src/gitlab/DefaultGitlabCredentialsProvider.d.ts:12:5 - (ae-undocumented) Missing documentation for "getCredentials". +// src/gitlab/GitLabIntegration.d.ts:10:5 - (ae-undocumented) Missing documentation for "factory". +// src/gitlab/GitLabIntegration.d.ts:12:5 - (ae-undocumented) Missing documentation for "type". +// src/gitlab/GitLabIntegration.d.ts:13:5 - (ae-undocumented) Missing documentation for "title". +// src/gitlab/GitLabIntegration.d.ts:14:5 - (ae-undocumented) Missing documentation for "config". +// src/gitlab/GitLabIntegration.d.ts:15:5 - (ae-undocumented) Missing documentation for "resolveUrl". +// src/gitlab/GitLabIntegration.d.ts:20:5 - (ae-undocumented) Missing documentation for "resolveEditUrl". +// src/gitlab/types.d.ts:4:1 - (ae-undocumented) Missing documentation for "GitlabCredentials". +// src/gitlab/types.d.ts:13:1 - (ae-undocumented) Missing documentation for "GitlabCredentialsProvider". +// src/gitlab/types.d.ts:14:5 - (ae-undocumented) Missing documentation for "getCredentials". +// src/harness/HarnessIntegration.d.ts:9:5 - (ae-undocumented) Missing documentation for "config". +// src/harness/HarnessIntegration.d.ts:10:5 - (ae-undocumented) Missing documentation for "factory". +// src/harness/HarnessIntegration.d.ts:12:5 - (ae-undocumented) Missing documentation for "type". +// src/harness/HarnessIntegration.d.ts:13:5 - (ae-undocumented) Missing documentation for "title". +// src/harness/HarnessIntegration.d.ts:14:5 - (ae-undocumented) Missing documentation for "resolveUrl". +// src/harness/HarnessIntegration.d.ts:19:5 - (ae-undocumented) Missing documentation for "resolveEditUrl". +// src/registry.d.ts:19:5 - (ae-undocumented) Missing documentation for "awsS3". +// src/registry.d.ts:20:5 - (ae-undocumented) Missing documentation for "awsCodeCommit". +// src/registry.d.ts:21:5 - (ae-undocumented) Missing documentation for "azure". +// src/registry.d.ts:25:5 - (ae-undocumented) Missing documentation for "bitbucket". +// src/registry.d.ts:26:5 - (ae-undocumented) Missing documentation for "bitbucketCloud". +// src/registry.d.ts:27:5 - (ae-undocumented) Missing documentation for "bitbucketServer". +// src/registry.d.ts:28:5 - (ae-undocumented) Missing documentation for "gerrit". +// src/registry.d.ts:29:5 - (ae-undocumented) Missing documentation for "github". +// src/registry.d.ts:30:5 - (ae-undocumented) Missing documentation for "gitlab". +// src/registry.d.ts:31:5 - (ae-undocumented) Missing documentation for "gitea". +// src/registry.d.ts:32:5 - (ae-undocumented) Missing documentation for "harness". +// src/types.d.ts:93:5 - (ae-undocumented) Missing documentation for "isRateLimited". ``` diff --git a/packages/integration/src/gitlab/core.ts b/packages/integration/src/gitlab/core.ts index 94f4b65d9f..c7f8dd036f 100644 --- a/packages/integration/src/gitlab/core.ts +++ b/packages/integration/src/gitlab/core.ts @@ -116,7 +116,9 @@ export async function getProjectId( const url = new URL(target); if (!url.pathname.includes('/blob/')) { - throw new Error('Please provide full path to yaml file from GitLab'); + throw new Error( + `Failed converting ${url.pathname} to a project id. Url path must include /blob/.`, + ); } try { diff --git a/packages/integration/src/harness/core.ts b/packages/integration/src/harness/core.ts index 1887a5c0d8..af2dab8a89 100644 --- a/packages/integration/src/harness/core.ts +++ b/packages/integration/src/harness/core.ts @@ -62,13 +62,19 @@ export function getHarnessFileContentsUrl( ) { const parsedUrl = parseHarnessUrl(config, url); - return `${parsedUrl.baseUrl}/gateway/code/api/v1/repos/${ - parsedUrl.accountId - }/${parsedUrl.orgName}${ - parsedUrl.projectName !== '' ? `/${parsedUrl.projectName}/` : '/' - }${parsedUrl.repoName}/+/raw/${parsedUrl.path}?routingId=${ - parsedUrl.accountId - }&git_ref=refs/heads/${parsedUrl.refString}`; + let constructedUrl = `${parsedUrl.baseUrl}/gateway/code/api/v1/repos/${parsedUrl.accountId}`; + + if (parsedUrl.orgName) { + constructedUrl += `/${parsedUrl.orgName}`; + } + + if (parsedUrl.projectName) { + constructedUrl += `/${parsedUrl.projectName}`; + } + + constructedUrl += `/${parsedUrl.repoName}/+/raw/${parsedUrl.path}?routingId=${parsedUrl.accountId}&git_ref=refs/heads/${parsedUrl.refString}`; + + return constructedUrl; } /** @@ -90,13 +96,20 @@ export function getHarnessArchiveUrl( url: string, ) { const parsedUrl = parseHarnessUrl(config, url); - return `${parsedUrl.baseUrl}/gateway/code/api/v1/repos/${ - parsedUrl.accountId - }/${parsedUrl.orgName}${ - parsedUrl.projectName !== '' ? `/${parsedUrl.projectName}/` : '/' - }${parsedUrl.repoName}/+/archive/${parsedUrl.branch}.zip?routingId=${ - parsedUrl.accountId - }`; + + let constructedUrl = `${parsedUrl.baseUrl}/gateway/code/api/v1/repos/${parsedUrl.accountId}`; + + if (parsedUrl.orgName) { + constructedUrl += `/${parsedUrl.orgName}`; + } + + if (parsedUrl.projectName) { + constructedUrl += `/${parsedUrl.projectName}`; + } + + constructedUrl += `/${parsedUrl.repoName}/+/archive/${parsedUrl.branch}.zip?routingId=${parsedUrl.accountId}`; + + return constructedUrl; } /** @@ -118,13 +131,20 @@ export function getHarnessLatestCommitUrl( url: string, ) { const parsedUrl = parseHarnessUrl(config, url); - return `${parsedUrl.baseUrl}/gateway/code/api/v1/repos/${ - parsedUrl.accountId - }/${parsedUrl.orgName}${ - parsedUrl.projectName !== '' ? `/${parsedUrl.projectName}/` : '/' - }${parsedUrl.repoName}/+/content?routingId=${ - parsedUrl.accountId - }&include_commit=true&git_ref=refs/heads/${parsedUrl.branch}`; + + let constructedUrl = `${parsedUrl.baseUrl}/gateway/code/api/v1/repos/${parsedUrl.accountId}`; + + if (parsedUrl.orgName) { + constructedUrl += `/${parsedUrl.orgName}`; + } + + if (parsedUrl.projectName) { + constructedUrl += `/${parsedUrl.projectName}`; + } + + constructedUrl += `/${parsedUrl.repoName}/+/content?routingId=${parsedUrl.accountId}&include_commit=true&git_ref=refs/heads/${parsedUrl.branch}`; + + return constructedUrl; } /** @@ -185,18 +205,20 @@ export function parseHarnessUrl( const orgNameIndex = pathSegments.findIndex(segment => segment === 'orgs'); const orgName = orgNameIndex !== -1 ? pathSegments[orgNameIndex + 1] : ''; - const projectNameIndex = pathSegments.findIndex( segment => segment === 'projects', ); const projectName = projectNameIndex !== -1 ? pathSegments[projectNameIndex + 1] : ''; - + // Adjust repoNameIndex to correctly identify the repository name const repoNameIndex = - pathSegments.findIndex(segment => segment === 'repos') + 1; + pathSegments.findIndex( + (segment, index) => + segment === 'repos' && + index > Math.max(accountIdIndex, orgNameIndex, projectNameIndex), + ) + 1; const repoName = pathSegments[repoNameIndex]; - const refAndPath = urlParts.slice( urlParts.findIndex(i => i === 'files' || i === 'edit') + 1, ); diff --git a/packages/opaque-internal/.eslintrc.js b/packages/opaque-internal/.eslintrc.js new file mode 100644 index 0000000000..e487f765b2 --- /dev/null +++ b/packages/opaque-internal/.eslintrc.js @@ -0,0 +1,5 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname, { + rules: { + '@backstage/no-top-level-material-ui-4-imports': 'error', + }, +}); diff --git a/packages/opaque-internal/README.md b/packages/opaque-internal/README.md new file mode 100644 index 0000000000..0dca55217f --- /dev/null +++ b/packages/opaque-internal/README.md @@ -0,0 +1,3 @@ +# @internal/opaque + +This is an internal package for use by other internal packages. Instances created with `OpaqueType.create` should never be exported in any public API, instead use an `@internal/*` if they need to be used in multiple packages. diff --git a/packages/opaque-internal/catalog-info.yaml b/packages/opaque-internal/catalog-info.yaml new file mode 100644 index 0000000000..b1c5d01937 --- /dev/null +++ b/packages/opaque-internal/catalog-info.yaml @@ -0,0 +1,9 @@ +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: internal-opaque + title: '@internal/opaque' +spec: + lifecycle: experimental + type: backstage-common-library + owner: maintainers diff --git a/packages/opaque-internal/package.json b/packages/opaque-internal/package.json new file mode 100644 index 0000000000..0d01c3699e --- /dev/null +++ b/packages/opaque-internal/package.json @@ -0,0 +1,30 @@ +{ + "name": "@internal/opaque", + "version": "0.0.1", + "backstage": { + "role": "common-library", + "inline": true + }, + "private": true, + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "packages/opaque-internal" + }, + "license": "Apache-2.0", + "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], + "scripts": { + "lint": "backstage-cli package lint", + "test": "backstage-cli package test" + }, + "devDependencies": { + "@backstage/cli": "workspace:^", + "@testing-library/jest-dom": "^6.0.0", + "@testing-library/react": "^16.0.0" + } +} diff --git a/packages/opaque-internal/src/OpaqueType.test.ts b/packages/opaque-internal/src/OpaqueType.test.ts new file mode 100644 index 0000000000..94fcb18d36 --- /dev/null +++ b/packages/opaque-internal/src/OpaqueType.test.ts @@ -0,0 +1,452 @@ +/* + * 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 { OpaqueType } from './OpaqueType'; + +describe('OpaqueType', () => { + it('should create a basic opaque type with a single version', () => { + type MyType = { + $$type: 'my-type'; + }; + + const OpaqueMyType = OpaqueType.create<{ + public: MyType; + versions: { + version: 'v1'; + foo: string; + }; + }>({ + type: 'my-type', + versions: ['v1'], + }); + + // @ts-expect-error - unsupported version + OpaqueMyType.createInstance('v2', { + foo: 'bar', + }); + + // @ts-expect-error - missing internal field + OpaqueMyType.createInstance('v1', {}); + + OpaqueMyType.createInstance('v1', { + // @ts-expect-error - invalid internal field + foo: 3, + }); + + const myInstance = OpaqueMyType.createInstance('v1', { + foo: 'bar', + }); + + expect(myInstance.$$type).toBe('my-type'); + // @ts-expect-error - version field not accessible + expect(myInstance.version).toBe('v1'); + // @ts-expect-error - internal field not accessible + expect(myInstance.foo).toBe('bar'); + + expect(OpaqueMyType.isType(myInstance)).toBe(true); + expect(OpaqueMyType.isType('hello')).toBe(false); + expect(OpaqueMyType.isType({ $$type: 'some-other' })).toBe(false); + expect(OpaqueMyType.isType({ $$type: 'my-type' })).toBe(true); + + const myInternal = OpaqueMyType.toInternal(myInstance); + expect(myInternal).toBe(myInstance); + // All fields accessible + expect(myInternal.$$type).toBe('my-type'); + expect(myInternal.version).toBe('v1'); + expect(myInternal.foo).toBe('bar'); + + expect(() => + OpaqueMyType.toInternal('hello'), + ).toThrowErrorMatchingInlineSnapshot( + `"Invalid opaque type, expected 'my-type', but got ''"`, + ); + expect(() => OpaqueMyType.toInternal(3)).toThrowErrorMatchingInlineSnapshot( + `"Invalid opaque type, expected 'my-type', but got ''"`, + ); + expect(() => + OpaqueMyType.toInternal(undefined), + ).toThrowErrorMatchingInlineSnapshot( + `"Invalid opaque type, expected 'my-type', but got ''"`, + ); + expect(() => + OpaqueMyType.toInternal(Symbol('wat')), + ).toThrowErrorMatchingInlineSnapshot( + `"Invalid opaque type, expected 'my-type', but got ''"`, + ); + expect(() => + OpaqueMyType.toInternal(null), + ).toThrowErrorMatchingInlineSnapshot( + `"Invalid opaque type, expected 'my-type', but got ''"`, + ); + expect(() => + OpaqueMyType.toInternal(() => {}), + ).toThrowErrorMatchingInlineSnapshot( + `"Invalid opaque type, expected 'my-type', but got ''"`, + ); + expect(() => + OpaqueMyType.toInternal({ $$type: 'some-other-type' }), + ).toThrowErrorMatchingInlineSnapshot( + `"Invalid opaque type, expected 'my-type', but got 'some-other-type'"`, + ); + expect(() => + OpaqueMyType.toInternal({ an: 'object' }), + ).toThrowErrorMatchingInlineSnapshot( + `"Invalid opaque type, expected 'my-type', but got '[object Object]'"`, + ); + expect(() => + OpaqueMyType.toInternal({ $$type: 'my-type' }), + ).toThrowErrorMatchingInlineSnapshot( + `"Invalid opaque type instance, got version undefined, expected 'v1'"`, + ); + expect(() => + OpaqueMyType.toInternal({ $$type: 'my-type', version: 'v0' }), + ).toThrowErrorMatchingInlineSnapshot( + `"Invalid opaque type instance, got version 'v0', expected 'v1'"`, + ); + expect(() => + OpaqueMyType.toInternal({ $$type: 'my-type', version: { foo: 'bar' } }), + ).toThrowErrorMatchingInlineSnapshot( + `"Invalid opaque type instance, got version '[object Object]', expected 'v1'"`, + ); + }); + + it('should create a basic opaque type with multiple versions', () => { + type MyType = { + $$type: 'my-type'; + }; + + const OpaqueMyType = OpaqueType.create<{ + public: MyType; + versions: + | { + version: 'v1'; + foo: string; + } + | { + version: 'v2'; + bar: string; + } + | { + version: 'v3'; + baz: string; + }; + }>({ + type: 'my-type', + versions: ['v1', 'v2', 'v3'], + }); + + // @ts-expect-error - unsupported version + OpaqueMyType.createInstance('v0', { + foo: 'bar', + }); + + // @ts-expect-error - missing internal field + OpaqueMyType.createInstance('v1', {}); + + OpaqueMyType.createInstance('v1', { + // @ts-expect-error - invalid internal field + foo: 3, + }); + + OpaqueMyType.createInstance('v2', { + // @ts-expect-error - version mismatch + foo: 'bar', + }); + + OpaqueMyType.createInstance('v1', { + // @ts-expect-error - version mismatch + bar: 'foo', + }); + + const myInstanceV1 = OpaqueMyType.createInstance('v1', { + foo: 'bar', + }); + + const myInstanceV2 = OpaqueMyType.createInstance('v2', { + bar: 'foo', + }); + + expect(myInstanceV1.$$type).toBe('my-type'); + // @ts-expect-error - version field not accessible + expect(myInstanceV1.version).toBe('v1'); + // @ts-expect-error - internal field not accessible + expect(myInstanceV1.foo).toBe('bar'); + + expect(myInstanceV2.$$type).toBe('my-type'); + // @ts-expect-error - version field not accessible + expect(myInstanceV2.version).toBe('v2'); + // @ts-expect-error - internal field not accessible + expect(myInstanceV2.bar).toBe('foo'); + + expect(OpaqueMyType.isType(myInstanceV1)).toBe(true); + expect(OpaqueMyType.isType(myInstanceV2)).toBe(true); + expect(OpaqueMyType.isType('hello')).toBe(false); + + const myInternalV1 = OpaqueMyType.toInternal(myInstanceV1); + expect(myInternalV1).toBe(myInstanceV1); + // All fields accessible + expect(myInternalV1.$$type).toBe('my-type'); + expect(myInternalV1.version).toBe('v1'); + // @ts-expect-error - version has not been narrowed down + expect(myInternalV1.foo).toBe('bar'); + + const myInternalV2 = OpaqueMyType.toInternal(myInstanceV2); + expect(myInternalV2).toBe(myInstanceV2); + // All fields accessible + expect(myInternalV2.$$type).toBe('my-type'); + expect(myInternalV2.version).toBe('v2'); + // @ts-expect-error - version has not been narrowed down + expect(myInternalV2.bar).toBe('foo'); + + // Narrowing the version allows access to internal fields + expect(myInternalV1.version === 'v1' && myInternalV1.foo).toBe('bar'); + expect(myInternalV2.version === 'v2' && myInternalV2.bar).toBe('foo'); + + expect(() => + OpaqueMyType.toInternal({ $$type: 'my-type' }), + ).toThrowErrorMatchingInlineSnapshot( + `"Invalid opaque type instance, got version undefined, expected 'v1', 'v2', or 'v3'"`, + ); + expect(() => + OpaqueMyType.toInternal({ $$type: 'my-type', version: 'v0' }), + ).toThrowErrorMatchingInlineSnapshot( + `"Invalid opaque type instance, got version 'v0', expected 'v1', 'v2', or 'v3'"`, + ); + }); + + it('should support undefined version for backwards compatibility', () => { + type MyType = { + $$type: 'my-type'; + }; + + const OpaqueMyType = OpaqueType.create<{ + public: MyType; + versions: { + version: undefined; + foo: string; + }; + }>({ + type: 'my-type', + versions: [undefined], + }); + + // @ts-expect-error - unsupported version + OpaqueMyType.createInstance('v1', { + foo: 'bar', + }); + + // @ts-expect-error - missing internal field + OpaqueMyType.createInstance(undefined, {}); + + OpaqueMyType.createInstance(undefined, { + // @ts-expect-error - invalid internal field + foo: 3, + }); + + const myInstance = OpaqueMyType.createInstance(undefined, { + foo: 'bar', + }); + + expect(myInstance.$$type).toBe('my-type'); + // @ts-expect-error - version field not accessible + expect(myInstance.version).toBe(undefined); + // @ts-expect-error - internal field not accessible + expect(myInstance.foo).toBe('bar'); + + expect(OpaqueMyType.isType(myInstance)).toBe(true); + expect(OpaqueMyType.isType('hello')).toBe(false); + + const myInternal = OpaqueMyType.toInternal(myInstance); + expect(myInternal).toBe(myInstance); + // All fields accessible + expect(myInternal.$$type).toBe('my-type'); + expect(myInternal.version).toBe(undefined); + expect(myInternal.foo).toBe('bar'); + + expect(OpaqueMyType.toInternal({ $$type: 'my-type' })).toBeDefined(); + expect(() => + OpaqueMyType.toInternal({ $$type: 'my-type', version: 'v0' }), + ).toThrowErrorMatchingInlineSnapshot( + `"Invalid opaque type instance, got version 'v0', expected undefined"`, + ); + }); + + it('should support undefined version mixed with defined versions', () => { + type MyType = { + $$type: 'my-type'; + }; + + const OpaqueMyType = OpaqueType.create<{ + public: MyType; + versions: + | { + version: 'v1'; + foo: string; + } + | { + version: undefined; + bar: string; + }; + }>({ + type: 'my-type', + versions: [undefined, 'v1'], + }); + + // @ts-expect-error - unsupported version + OpaqueMyType.createInstance('v0', { + foo: 'bar', + }); + + // @ts-expect-error - missing internal field + OpaqueMyType.createInstance('v1', {}); + + OpaqueMyType.createInstance('v1', { + // @ts-expect-error - invalid internal field + foo: 3, + }); + + OpaqueMyType.createInstance(undefined, { + // @ts-expect-error - version mismatch + foo: 'bar', + }); + + OpaqueMyType.createInstance('v1', { + // @ts-expect-error - version mismatch + bar: 'foo', + }); + + const myInstanceV1 = OpaqueMyType.createInstance('v1', { + foo: 'bar', + }); + + const myInstanceV2 = OpaqueMyType.createInstance(undefined, { + bar: 'foo', + }); + + expect(myInstanceV1.$$type).toBe('my-type'); + // @ts-expect-error - version field not accessible + expect(myInstanceV1.version).toBe('v1'); + // @ts-expect-error - internal field not accessible + expect(myInstanceV1.foo).toBe('bar'); + + expect(myInstanceV2.$$type).toBe('my-type'); + // @ts-expect-error - version field not accessible + expect(myInstanceV2.version).toBe(undefined); + // @ts-expect-error - internal field not accessible + expect(myInstanceV2.bar).toBe('foo'); + + expect(OpaqueMyType.isType(myInstanceV1)).toBe(true); + expect(OpaqueMyType.isType(myInstanceV2)).toBe(true); + expect(OpaqueMyType.isType('hello')).toBe(false); + + const myInternalV1 = OpaqueMyType.toInternal(myInstanceV1); + expect(myInternalV1).toBe(myInstanceV1); + // All fields accessible + expect(myInternalV1.$$type).toBe('my-type'); + expect(myInternalV1.version).toBe('v1'); + // @ts-expect-error - version has not been narrowed down + expect(myInternalV1.foo).toBe('bar'); + + const myInternalV2 = OpaqueMyType.toInternal(myInstanceV2); + expect(myInternalV2).toBe(myInstanceV2); + // All fields accessible + expect(myInternalV2.$$type).toBe('my-type'); + expect(myInternalV2.version).toBe(undefined); + // @ts-expect-error - version has not been narrowed down + expect(myInternalV2.bar).toBe('foo'); + + // Narrowing the version allows access to internal fields + expect(myInternalV1.version === 'v1' && myInternalV1.foo).toBe('bar'); + expect(myInternalV2.version === undefined && myInternalV2.bar).toBe('foo'); + + expect(OpaqueMyType.toInternal({ $$type: 'my-type' })).toBeDefined(); + expect(() => + OpaqueMyType.toInternal({ $$type: 'my-type', version: 'v3' }), + ).toThrowErrorMatchingInlineSnapshot( + `"Invalid opaque type instance, got version 'v3', expected undefined or 'v1'"`, + ); + }); + + it('should create an empty opaque type with no versions', () => { + type MyType = { + $$type: 'my-type'; + }; + + const OpaqueMyType = OpaqueType.create<{ + public: MyType; + versions: { + version: undefined; + }; + }>({ + type: 'my-type', + versions: [undefined], + }); + + // @ts-expect-error - unsupported version + OpaqueMyType.createInstance('v0', { + foo: 'bar', + }); + + const myInstance = OpaqueMyType.createInstance(undefined, {}); + + expect(myInstance.$$type).toBe('my-type'); + + expect(OpaqueMyType.isType(myInstance)).toBe(true); + expect(OpaqueMyType.isType('hello')).toBe(false); + + const myInternal = OpaqueMyType.toInternal(myInstance); + expect(myInternal).toBe(myInstance); + // All fields accessible + expect(myInternal.$$type).toBe('my-type'); + expect(myInternal.version).toBe(undefined); + }); + + it('should work with class implementations', () => { + type MyType = { + $$type: 'my-type'; + }; + + const OpaqueMyType = OpaqueType.create<{ + public: MyType; + versions: { + version: 'v1'; + getX(): number; + }; + }>({ + type: 'my-type', + versions: ['v1'], + }); + + class MyTypeImpl { + getX() { + return 4; + } + } + + const myInstance = OpaqueMyType.createInstance('v1', new MyTypeImpl()); + + expect(myInstance.$$type).toBe('my-type'); + + expect(OpaqueMyType.isType(myInstance)).toBe(true); + + const myInternal = OpaqueMyType.toInternal(myInstance); + expect(myInternal).toBe(myInstance); + + expect(myInternal.$$type).toBe('my-type'); + expect(myInternal.version).toBe('v1'); + expect(myInternal.getX()).toBe(4); + }); +}); diff --git a/packages/opaque-internal/src/OpaqueType.ts b/packages/opaque-internal/src/OpaqueType.ts new file mode 100644 index 0000000000..dd17f21da8 --- /dev/null +++ b/packages/opaque-internal/src/OpaqueType.ts @@ -0,0 +1,167 @@ +/* + * 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. + */ + +// TODO(Rugvip): This lives here temporarily, but should be moved to a more +// central location. It's useful for backend packages too so we'll need to have +// it in a common package, but it might also be that we want to make it +// available publicly too in which case it would make sense to have this be part +// of @backstage/version-bridge. The problem with exporting it from there is +// that it would need to be very stable at that point, so it might be a bit +// early to put it there already. + +/** + * A helper for working with opaque types. + */ +export class OpaqueType< + T extends { + public: { $$type: string }; + versions: { version: string | undefined }; + }, +> { + /** + * Creates a new opaque type. + * + * @param options.type The type identifier of the opaque type + * @param options.versions The available versions of the opaque type + * @returns A new opaque type helper + */ + static create< + T extends { + public: { $$type: string }; + versions: { version: string | undefined }; + }, + >(options: { + type: T['public']['$$type']; + versions: Array; + }) { + return new OpaqueType(options.type, new Set(options.versions)); + } + + #type: string; + #versions: Set; + + private constructor(type: string, versions: Set) { + this.#type = type; + this.#versions = versions; + } + + /** + * The internal version of the opaque type, used like this: `typeof MyOpaqueType.TPublic` + * + * @remarks + * + * This property is only useful for type checking, its runtime value is `undefined`. + */ + TPublic: T['public'] = undefined as any; + + /** + * The internal version of the opaque type, used like this: `typeof MyOpaqueType.TInternal` + * + * @remarks + * + * This property is only useful for type checking, its runtime value is `undefined`. + */ + TInternal: T['public'] & T['versions'] = undefined as any; + + /** + * @param value Input value expected to be an instance of this opaque type + * @returns True if the value matches this opaque type + */ + isType = (value: unknown): value is T['public'] => { + return this.#isThisInternalType(value); + }; + + /** + * @param value Input value expected to be an instance of this opaque type + * @throws If the value is not an instance of this opaque type or is of an unsupported version + * @returns The internal version of the opaque type + */ + toInternal = (value: unknown): T['public'] & T['versions'] => { + if (!this.#isThisInternalType(value)) { + throw new TypeError( + `Invalid opaque type, expected '${ + this.#type + }', but got '${this.#stringifyUnknown(value)}'`, + ); + } + + if (!this.#versions.has(value.version)) { + const versions = Array.from(this.#versions).map(this.#stringifyVersion); + if (versions.length > 1) { + versions[versions.length - 1] = `or ${versions[versions.length - 1]}`; + } + const expected = + versions.length > 2 ? versions.join(', ') : versions.join(' '); + throw new TypeError( + `Invalid opaque type instance, got version ${this.#stringifyVersion( + value.version, + )}, expected ${expected}`, + ); + } + + return value; + }; + + /** + * Creates an instance of the opaque type, returning the public type. + * + * @param version The version of the instance to create + * @param value The remaining public and internal properties of the instance + * @returns An instance of the opaque type + */ + createInstance< + TVersion extends T['versions']['version'], + TPublic extends T['public'], + >( + version: TVersion, + props: Omit & + (T['versions'] extends infer UVersion + ? UVersion extends { version: TVersion } + ? Omit + : never + : never) & + Object, // & Object to allow for object properties too, e.g. toString() + ): TPublic { + return Object.assign(props as object, { + $$type: this.#type, + ...(version && { version }), + }) as unknown as TPublic; + } + + #isThisInternalType(value: unknown): value is T['public'] & T['versions'] { + if (value === null || typeof value !== 'object') { + return false; + } + return (value as T['public']).$$type === this.#type; + } + + #stringifyUnknown(value: unknown) { + if (typeof value !== 'object') { + return `<${typeof value}>`; + } + if (value === null) { + return ''; + } + if ('$$type' in value) { + return String(value.$$type); + } + return String(value); + } + + #stringifyVersion = (version: string | undefined) => { + return version ? `'${version}'` : 'undefined'; + }; +} diff --git a/packages/backend-common/src/compat/auth/index.ts b/packages/opaque-internal/src/index.ts similarity index 89% rename from packages/backend-common/src/compat/auth/index.ts rename to packages/opaque-internal/src/index.ts index c92ecdce25..54d06588e2 100644 --- a/packages/backend-common/src/compat/auth/index.ts +++ b/packages/opaque-internal/src/index.ts @@ -14,4 +14,4 @@ * limitations under the License. */ -export { createLegacyAuthAdapters } from './createLegacyAuthAdapters'; +export { OpaqueType } from './OpaqueType'; diff --git a/packages/release-manifests/api-report.md b/packages/release-manifests/report.api.md similarity index 100% rename from packages/release-manifests/api-report.md rename to packages/release-manifests/report.api.md diff --git a/packages/repo-tools/CHANGELOG.md b/packages/repo-tools/CHANGELOG.md index 7ffae42333..8d02431a0c 100644 --- a/packages/repo-tools/CHANGELOG.md +++ b/packages/repo-tools/CHANGELOG.md @@ -1,5 +1,66 @@ # @backstage/repo-tools +## 0.10.0-next.1 + +### Minor Changes + +- 8eb3033: Adds a new command `backstage-repo-tools peer-deps` for validating your usage of peer dependencies in your plugins. It currently supports react related peer dependencies. It also has a `--fix` mode for quickly fixing any issues that it finds. + +### Patch Changes + +- 1f6706f: Properly log instructions when APIs do not match +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.8 + - @backstage/config-loader@1.9.1 + - @backstage/errors@1.2.4 + +## 0.10.0-next.0 + +### Minor Changes + +- 30c2be9: Update @microsoft/api-extractor and use their api report resolution. + Change api report format from `api-report.md` to `report.api.md` + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.8 + - @backstage/config-loader@1.9.1 + - @backstage/errors@1.2.4 + +## 0.9.7 + +### Patch Changes + +- 5c4aa2f: Updated dependency `@useoptic/openapi-utilities` to `^0.55.0`. +- 1a8837e: Avoid generating API reports for packages with `backstage.inline` set. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/cli-node@0.2.8 + - @backstage/config-loader@1.9.1 + - @backstage/cli-common@0.1.14 + - @backstage/errors@1.2.4 + +## 0.9.7-next.2 + +### Patch Changes + +- 1a8837e: Avoid generating API reports for packages with `backstage.inline` set. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/cli-node@0.2.8-next.0 + - @backstage/config-loader@1.9.1-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/cli-common@0.1.14 + - @backstage/errors@1.2.4 + ## 0.9.7-next.1 ### Patch Changes diff --git a/packages/repo-tools/cli-report.md b/packages/repo-tools/cli-report.md index 6e0e4c9b85..9266957886 100644 --- a/packages/repo-tools/cli-report.md +++ b/packages/repo-tools/cli-report.md @@ -14,6 +14,7 @@ Options: Commands: api-reports [options] [paths...] type-deps + peer-deps [options] generate-catalog-info [options] knip-reports [options] [paths...] package [command] @@ -156,6 +157,16 @@ Options: -h, --help ``` +### `backstage-repo-tools peer-deps` + +``` +Usage: backstage-repo-tools peer-deps [options] + +Options: + --fix + -h, --help +``` + ### `backstage-repo-tools repo` ``` diff --git a/packages/repo-tools/package.json b/packages/repo-tools/package.json index 89b2f0f124..71c1314c8e 100644 --- a/packages/repo-tools/package.json +++ b/packages/repo-tools/package.json @@ -1,13 +1,13 @@ { "name": "@backstage/repo-tools", + "version": "0.10.0-next.1", "description": "CLI for Backstage repo tooling ", - "version": "0.9.7-next.1", - "publishConfig": { - "access": "public" - }, "backstage": { "role": "cli" }, + "publishConfig": { + "access": "public" + }, "keywords": [ "backstage" ], @@ -50,8 +50,8 @@ "@backstage/config-loader": "workspace:^", "@backstage/errors": "workspace:^", "@manypkg/get-packages": "^1.1.3", - "@microsoft/api-documenter": "^7.22.33", - "@microsoft/api-extractor": "^7.36.4", + "@microsoft/api-documenter": "^7.25.7", + "@microsoft/api-extractor": "^7.47.2", "@openapitools/openapi-generator-cli": "^2.7.0", "@stoplight/spectral-core": "^1.18.0", "@stoplight/spectral-formatters": "^1.1.0", diff --git a/packages/repo-tools/src/commands/api-reports/api-extractor.ts b/packages/repo-tools/src/commands/api-reports/api-extractor.ts index 122f04cc7e..90c5c40fdd 100644 --- a/packages/repo-tools/src/commands/api-reports/api-extractor.ts +++ b/packages/repo-tools/src/commands/api-reports/api-extractor.ts @@ -393,21 +393,20 @@ export async function runApiExtraction({ ); const remainingReportFiles = new Set( - fs - .readdirSync(projectFolder) - .filter( - filename => - filename.match(/^(.+)-api-report\.md$/) || - filename.match(/^api-report(-.+)?\.md$/), - ), + fs.readdirSync(projectFolder).filter( + filename => + // https://regex101.com/r/QDZIV0/2 + filename !== 'knip-report.md' && + // this has to temporarily match all old api report formats + filename.match(/^.*?(api-)?report(-[^.-]+)?(.*?)\.md$/), + ), ); for (const packageEntryPoint of packageEntryPoints) { const suffix = packageEntryPoint.name === 'index' ? '' : `-${packageEntryPoint.name}`; - const reportFileName = `api-report${suffix}.md`; + const reportFileName = `report${suffix}`; const reportPath = resolvePath(projectFolder, reportFileName); - remainingReportFiles.delete(reportFileName); const warningCountBefore = await countApiReportWarnings(reportPath); @@ -485,6 +484,11 @@ export async function runApiExtraction({ ignoreMissingEntryPoint: true, }); + // remove extracted reports from current list + for (const reportConfig of extractorConfig.reportConfigs) { + remainingReportFiles.delete(reportConfig.fileName); + } + // The `packageFolder` needs to point to the location within `dist-types` in order for relative // paths to be logged. Unfortunately the `prepare` method above derives it from the `packageJsonFullPath`, // which needs to point to the actual file, so we override `packageFolder` afterwards. @@ -515,14 +519,17 @@ export async function runApiExtraction({ if (message.text.includes('The API report file is missing')) { shouldLogInstructions = true; } + + // Detect messages like the following being output by the generator: + // Warning: You have changed the API signature for this project. Please copy the file "/home/runner/work/backstage/backstage/node_modules/.cache/api-extractor/backend-test-utils/report.api.md" to "report.api.md", or perform a local build (which does this automatically). See the Git repo documentation for more info. if ( message.text.includes( - 'You have changed the public API signature for this project.', + 'You have changed the API signature for this project.', ) ) { shouldLogInstructions = true; const match = message.text.match( - /Please copy the file "(.*)" to "api-report\.md"/, + /Please copy the file "(.*)" to "report\.api\.md"/, ); if (match) { conflictingFile = match[1]; @@ -1232,6 +1239,12 @@ export async function categorizePackageDirs(packageDirs: string[]) { if (!role) { return; // Ignore packages without roles } + // TODO(Rugvip): Inlined packages are ignored because we can't handle @internal exports + // gracefully, and we don't want to have to mark all exports @public etc. + // It would be good if we could include these packages though. + if (pkgJson?.backstage?.inline) { + return; + } if (role === 'cli') { cliPackageDirs.push(dir); } else if (role !== 'frontend' && role !== 'backend') { diff --git a/packages/repo-tools/src/commands/index.ts b/packages/repo-tools/src/commands/index.ts index 5116326eea..5a69a74ff3 100644 --- a/packages/repo-tools/src/commands/index.ts +++ b/packages/repo-tools/src/commands/index.ts @@ -224,6 +224,14 @@ export function registerCommands(program: Command) { .description('Find inconsistencies in types of all packages and plugins') .action(lazy(() => import('./type-deps/type-deps').then(m => m.default))); + program + .command('peer-deps') + .description( + 'Ensure your packages are using the correct peer dependency format.', + ) + .option('--fix', 'Fix the issues found') + .action(lazy(() => import('./peer-deps/peer-deps').then(m => m.default))); + program .command('generate-catalog-info') .option( diff --git a/packages/repo-tools/src/commands/peer-deps/peer-deps.ts b/packages/repo-tools/src/commands/peer-deps/peer-deps.ts new file mode 100644 index 0000000000..70e566dd32 --- /dev/null +++ b/packages/repo-tools/src/commands/peer-deps/peer-deps.ts @@ -0,0 +1,238 @@ +/* + * 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 { resolve as resolvePath } from 'path'; +import { getPackages, Package } from '@manypkg/get-packages'; +import { writeFileSync } from 'fs'; + +type ExtendedPackageJSON = Package['packageJson'] & { + peerDependenciesMeta?: Record; + backstage?: { + role: string; + }; +}; + +const desiredLocalVersionsOfDependencies = { + '@types/react': '^18.0.0', + react: '^18.0.2', + 'react-dom': '^18.0.2', + 'react-router-dom': '^6.3.0', +}; + +const peerDependencies = { + '@types/react': '^16.13.1 || ^17.0.0 || ^18.0.0', + react: '^16.13.1 || ^17.0.0 || ^18.0.0', + 'react-dom': '^16.13.1 || ^17.0.0 || ^18.0.0', + 'react-router-dom': '6.0.0-beta.0 || ^6.3.0', +}; + +const groupsOfPeerDependencies = [['@types/react', 'react', 'react-dom']]; + +const optionalPeerDependencies = new Set(['@types/react']); + +const isOptional = (dep: string) => { + return optionalPeerDependencies.has(dep); +}; + +const isMarkedAsOptional = (dep: string, packageJson: ExtendedPackageJSON) => { + return packageJson.peerDependenciesMeta?.[dep]?.optional; +}; + +const isDevDependency = (dep: string, packageJson: ExtendedPackageJSON) => { + return !!packageJson.devDependencies?.[dep]; +}; + +const isProdDependency = (dep: string, packageJson: ExtendedPackageJSON) => { + return !!packageJson.dependencies?.[dep]; +}; + +const isPeerDependency = (dep: string, packageJson: ExtendedPackageJSON) => { + return !!packageJson.peerDependencies?.[dep]; +}; + +const isStandaloneApplication = (packageJson: ExtendedPackageJSON) => { + return ['cli', 'frontend', 'backend'].includes( + packageJson.backstage?.role || '', + ); +}; + +const matchesDependency = (dep: string, packageJson: ExtendedPackageJSON) => { + return ( + packageJson.devDependencies && + packageJson.devDependencies[dep] === + desiredLocalVersionsOfDependencies[ + dep as keyof typeof desiredLocalVersionsOfDependencies + ] + ); +}; + +const matchesPeerDependency = ( + dep: string, + packageJson: ExtendedPackageJSON, +) => { + return ( + packageJson.peerDependencies && + packageJson.peerDependencies[dep] === + peerDependencies[dep as keyof typeof peerDependencies] + ); +}; + +export default async ({ fix }: { fix: boolean }) => { + let failed = false; + const attemptToApplyFix = (fn: () => void) => { + if (fix) { + fn(); + } else { + failed = true; + } + }; + const { packages } = await getPackages(resolvePath('.')); + + const packagesWithRelevantDependencies = []; + + for (const pkg of packages) { + if (isStandaloneApplication(pkg.packageJson as ExtendedPackageJSON)) { + // Standalone applications are not expected to have peer dependencies. + continue; + } + + const dependencies = { + ...pkg.packageJson.dependencies, + ...pkg.packageJson.devDependencies, + ...pkg.packageJson.peerDependencies, + }; + for (const dep in peerDependencies) { + // Check against all packages that use dependencies that are in the peerDependencies list. + if (dependencies?.[dep]) { + packagesWithRelevantDependencies.push(pkg); + break; + } + } + } + + for (const pkg of packagesWithRelevantDependencies) { + const packageJson = pkg.packageJson as ExtendedPackageJSON; + for (const dep of Object.keys(peerDependencies)) { + // Validate that the peer dependencies are present. + if (isPeerDependency(dep, packageJson)) { + if (isOptional(dep) && !isMarkedAsOptional(dep, packageJson)) { + console.error( + `Optional peer dependency ${dep} in ${pkg.packageJson.name} is not marked as optional`, + ); + attemptToApplyFix(() => { + packageJson.peerDependenciesMeta = + packageJson.peerDependenciesMeta || {}; + packageJson.peerDependenciesMeta[dep] = { optional: true }; + }); + } else if (!isOptional(dep) && isMarkedAsOptional(dep, packageJson)) { + console.error( + `Peer dependency ${dep} in ${pkg.packageJson.name} is marked as optional but should not be`, + ); + attemptToApplyFix(() => { + packageJson.peerDependenciesMeta = + packageJson.peerDependenciesMeta || {}; + delete packageJson.peerDependenciesMeta[dep]; + }); + } + if (!isDevDependency(dep, packageJson)) { + console.error( + `Peer dependency ${dep} in ${pkg.packageJson.name} is not listed as a devDependency`, + ); + attemptToApplyFix(() => { + delete packageJson.dependencies?.[dep]; + packageJson.devDependencies = packageJson.devDependencies || {}; + packageJson.devDependencies[dep] = + desiredLocalVersionsOfDependencies[ + dep as keyof typeof desiredLocalVersionsOfDependencies + ]; + }); + } else if (isProdDependency(dep, packageJson)) { + console.error( + `Peer dependency ${dep} in ${pkg.packageJson.name} is listed as a dependency`, + ); + attemptToApplyFix(() => { + delete packageJson.dependencies?.[dep]; + }); + } + + const groups = groupsOfPeerDependencies.filter(group => + group.includes(dep), + ); + if (groups.length) { + for (const group of groups) { + for (const groupDep of group) { + if (!isPeerDependency(groupDep, packageJson)) { + console.error( + `Peer dependency ${groupDep} in ${pkg.packageJson.name} is missing`, + ); + attemptToApplyFix(() => { + packageJson.peerDependencies = + packageJson.peerDependencies || {}; + packageJson.peerDependencies[groupDep] = + peerDependencies[groupDep as keyof typeof peerDependencies]; + }); + } + } + } + } + + if (!matchesDependency(dep, packageJson)) { + console.error( + `Incorrect dependency ${dep} in ${pkg.packageJson.name}`, + ); + attemptToApplyFix(() => { + packageJson.devDependencies = packageJson.devDependencies || {}; + packageJson.devDependencies[dep] = + desiredLocalVersionsOfDependencies[ + dep as keyof typeof desiredLocalVersionsOfDependencies + ]; + }); + } + + if (!matchesPeerDependency(dep, packageJson)) { + console.error( + `Incorrect peer dependency ${dep} in ${pkg.packageJson.name}`, + ); + attemptToApplyFix(() => { + packageJson.peerDependencies = packageJson.peerDependencies || {}; + packageJson.peerDependencies[dep] = + peerDependencies[dep as keyof typeof peerDependencies]; + }); + } + } else { + console.error( + `Missing peer dependency ${dep} in ${pkg.packageJson.name}`, + ); + attemptToApplyFix(() => { + packageJson.peerDependencies = packageJson.peerDependencies || {}; + packageJson.peerDependencies[dep] = + peerDependencies[dep as keyof typeof peerDependencies]; + }); + } + } + if (fix) { + writeFileSync( + resolvePath(pkg.dir, 'package.json'), + `${JSON.stringify(packageJson, null, 2)}\n`, + ); + } + } + + if (failed) { + console.error('Some packages have incorrect peer dependencies'); + process.exit(1); + } +}; diff --git a/packages/repo-tools/src/commands/type-deps/type-deps.ts b/packages/repo-tools/src/commands/type-deps/type-deps.ts index 7b75ac37ee..877228a238 100644 --- a/packages/repo-tools/src/commands/type-deps/type-deps.ts +++ b/packages/repo-tools/src/commands/type-deps/type-deps.ts @@ -202,6 +202,14 @@ function findTypeDepErrors(typeDeps: string[], pkg: Package) { } for (const dep of deps) { + // Allow implicit declarations of these dependencies. For some packages, they may + // not be declared as a `reference types="..."` or `import ... from '@types/...' + // in the declaration file. + // Example being app-visualizer, it exports a plugin which comes from `@backstage/frontend-plugin-api`, + // the react types come from that package, but are not explicitly declared in the declaration file. + if (['@types/react'].includes(dep)) { + continue; + } errors.push( mkErr('WrongDepError', `Should be dev dep ${dep}`, { dep, diff --git a/packages/scaffolder-internal/.eslintrc.js b/packages/scaffolder-internal/.eslintrc.js new file mode 100644 index 0000000000..e487f765b2 --- /dev/null +++ b/packages/scaffolder-internal/.eslintrc.js @@ -0,0 +1,5 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname, { + rules: { + '@backstage/no-top-level-material-ui-4-imports': 'error', + }, +}); diff --git a/packages/scaffolder-internal/CHANGELOG.md b/packages/scaffolder-internal/CHANGELOG.md new file mode 100644 index 0000000000..291f528607 --- /dev/null +++ b/packages/scaffolder-internal/CHANGELOG.md @@ -0,0 +1,15 @@ +# @internal/scaffolder + +## 0.0.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-react@1.13.0-next.1 + +## 0.0.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-react@1.13.0-next.0 diff --git a/packages/scaffolder-internal/README.md b/packages/scaffolder-internal/README.md new file mode 100644 index 0000000000..e7e6abeb57 --- /dev/null +++ b/packages/scaffolder-internal/README.md @@ -0,0 +1,3 @@ +# @internal/scaffolder + +This is an internal package used by the other scaffolder packages. It does not get published to NPM, but instead inlined into consuming packages due to the `backstage.inline` flag in `package.json`. diff --git a/packages/scaffolder-internal/catalog-info.yaml b/packages/scaffolder-internal/catalog-info.yaml new file mode 100644 index 0000000000..c2c2c013d3 --- /dev/null +++ b/packages/scaffolder-internal/catalog-info.yaml @@ -0,0 +1,9 @@ +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: internal-scaffolder + title: '@internal/scaffolder' +spec: + lifecycle: experimental + type: backstage-web-library + owner: maintainers diff --git a/packages/scaffolder-internal/package.json b/packages/scaffolder-internal/package.json new file mode 100644 index 0000000000..6ece1226de --- /dev/null +++ b/packages/scaffolder-internal/package.json @@ -0,0 +1,32 @@ +{ + "name": "@internal/scaffolder", + "version": "0.0.2-next.1", + "backstage": { + "role": "web-library", + "inline": true + }, + "private": true, + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "packages/scaffolder-internal" + }, + "license": "Apache-2.0", + "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], + "scripts": { + "lint": "backstage-cli package lint", + "test": "backstage-cli package test" + }, + "dependencies": { + "@backstage/plugin-scaffolder-react": "workspace:^", + "zod": "^3.22.4" + }, + "devDependencies": { + "@backstage/cli": "workspace:^" + } +} diff --git a/packages/backend-common/src/deprecated/config/index.ts b/packages/scaffolder-internal/src/index.ts similarity index 88% rename from packages/backend-common/src/deprecated/config/index.ts rename to packages/scaffolder-internal/src/index.ts index c87193876c..a5728f2ff6 100644 --- a/packages/backend-common/src/deprecated/config/index.ts +++ b/packages/scaffolder-internal/src/index.ts @@ -14,4 +14,4 @@ * limitations under the License. */ -export { loadBackendConfig, createConfigSecretEnumerator } from './config'; +export * from './wiring'; diff --git a/packages/scaffolder-internal/src/wiring/InternalFormField.ts b/packages/scaffolder-internal/src/wiring/InternalFormField.ts new file mode 100644 index 0000000000..5d7bf1ee7d --- /dev/null +++ b/packages/scaffolder-internal/src/wiring/InternalFormField.ts @@ -0,0 +1,33 @@ +/* + * 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 { OpaqueType } from '@internal/opaque'; +import { z } from 'zod'; + +import { FormFieldExtensionData } from '@backstage/plugin-scaffolder-react/alpha'; + +/** @alpha */ +export interface FormField { + readonly $$type: '@backstage/scaffolder/FormField'; +} + +/** @alpha */ +export const OpaqueFormField = OpaqueType.create<{ + public: FormField; + versions: FormFieldExtensionData & { + readonly version: 'v1'; + }; +}>({ type: '@backstage/scaffolder/FormField', versions: ['v1'] }); diff --git a/packages/scaffolder-internal/src/wiring/index.ts b/packages/scaffolder-internal/src/wiring/index.ts new file mode 100644 index 0000000000..c85755bccf --- /dev/null +++ b/packages/scaffolder-internal/src/wiring/index.ts @@ -0,0 +1,16 @@ +/* + * 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. + */ +export { OpaqueFormField, type FormField } from './InternalFormField'; diff --git a/packages/techdocs-cli-embedded-app/CHANGELOG.md b/packages/techdocs-cli-embedded-app/CHANGELOG.md index 77a6e403bd..751e710c64 100644 --- a/packages/techdocs-cli-embedded-app/CHANGELOG.md +++ b/packages/techdocs-cli-embedded-app/CHANGELOG.md @@ -1,5 +1,81 @@ # techdocs-cli-embedded-app +## 0.2.101-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/cli@0.28.0-next.1 + - @backstage/integration-react@1.2.0-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/plugin-techdocs-react@1.2.9-next.1 + - @backstage/app-defaults@1.5.12-next.1 + - @backstage/core-app-api@1.15.1-next.1 + - @backstage/test-utils@1.6.1-next.1 + - @backstage/plugin-techdocs@1.10.11-next.1 + - @backstage/plugin-catalog@1.24.0-next.1 + - @backstage/theme@0.5.8-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + +## 0.2.101-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.24.0-next.0 + - @backstage/cli@0.28.0-next.0 + - @backstage/plugin-techdocs@1.10.10-next.0 + - @backstage/app-defaults@1.5.12-next.0 + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.15.1-next.0 + - @backstage/integration-react@1.1.32-next.0 + - @backstage/test-utils@1.6.1-next.0 + - @backstage/theme@0.5.7 + - @backstage/plugin-techdocs-react@1.2.9-next.0 + +## 0.2.100 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/plugin-techdocs@1.10.9 + - @backstage/plugin-catalog@1.23.0 + - @backstage/cli@0.27.1 + - @backstage/plugin-techdocs-react@1.2.8 + - @backstage/core-app-api@1.15.0 + - @backstage/integration-react@1.1.31 + - @backstage/catalog-model@1.7.0 + - @backstage/app-defaults@1.5.11 + - @backstage/test-utils@1.6.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/theme@0.5.7 + - @backstage/config@1.2.0 + +## 0.2.100-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/plugin-techdocs@1.10.9-next.2 + - @backstage/plugin-catalog@1.23.0-next.2 + - @backstage/cli@0.27.1-next.2 + - @backstage/core-app-api@1.14.3-next.0 + - @backstage/integration-react@1.1.31-next.0 + - @backstage/app-defaults@1.5.11-next.1 + - @backstage/test-utils@1.6.0-next.1 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/theme@0.5.7-next.0 + - @backstage/plugin-techdocs-react@1.2.8-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + ## 0.2.100-next.1 ### Patch Changes diff --git a/packages/techdocs-cli-embedded-app/package.json b/packages/techdocs-cli-embedded-app/package.json index 83bc610762..383648365e 100644 --- a/packages/techdocs-cli-embedded-app/package.json +++ b/packages/techdocs-cli-embedded-app/package.json @@ -1,17 +1,36 @@ { "name": "techdocs-cli-embedded-app", - "version": "0.2.100-next.1", - "private": true, + "version": "0.2.101-next.1", "backstage": { "role": "frontend" }, - "bundled": true, + "private": true, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "packages/techdocs-cli-embedded-app" }, + "scripts": { + "build": "backstage-cli package build --config ./app-config.yaml", + "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", + "start": "backstage-cli package start --config ./app-config.yaml", + "test": "backstage-cli package test" + }, + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + }, + "prettier": "@spotify/prettier-config", "dependencies": { "@backstage/app-defaults": "workspace:^", "@backstage/catalog-model": "workspace:^", @@ -38,30 +57,11 @@ "@backstage/cli": "workspace:^", "@testing-library/dom": "^10.0.0", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^15.0.0", + "@testing-library/react": "^16.0.0", "@testing-library/user-event": "^14.0.0", "@types/react": "*", "@types/react-dom": "*", "cross-env": "^7.0.0" }, - "scripts": { - "start": "backstage-cli package start --config ./app-config.yaml", - "build": "backstage-cli package build --config ./app-config.yaml", - "clean": "backstage-cli package clean", - "test": "backstage-cli package test", - "lint": "backstage-cli package lint" - }, - "prettier": "@spotify/prettier-config", - "browserslist": { - "production": [ - ">0.2%", - "not dead", - "not op_mini all" - ], - "development": [ - "last 1 chrome version", - "last 1 firefox version", - "last 1 safari version" - ] - } + "bundled": true } diff --git a/packages/techdocs-cli/CHANGELOG.md b/packages/techdocs-cli/CHANGELOG.md index a7c62bd94b..917c448316 100644 --- a/packages/techdocs-cli/CHANGELOG.md +++ b/packages/techdocs-cli/CHANGELOG.md @@ -1,5 +1,49 @@ # @techdocs/cli +## 1.8.20-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.1-next.1 + - @backstage/catalog-model@1.7.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/plugin-techdocs-node@1.12.12-next.1 + +## 1.8.20-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/plugin-techdocs-node@1.12.12-next.0 + +## 1.8.19 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.0 + - @backstage/plugin-techdocs-node@1.12.11 + - @backstage/catalog-model@1.7.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + +## 1.8.19-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.0-next.2 + - @backstage/plugin-techdocs-node@1.12.11-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + ## 1.8.19-next.1 ### Patch Changes diff --git a/packages/techdocs-cli/package.json b/packages/techdocs-cli/package.json index 64a6ebc772..91e68447db 100644 --- a/packages/techdocs-cli/package.json +++ b/packages/techdocs-cli/package.json @@ -1,59 +1,47 @@ { "name": "@techdocs/cli", + "version": "1.8.20-next.1", "description": "Utility CLI for managing TechDocs sites in Backstage.", - "version": "1.8.19-next.1", - "publishConfig": { - "access": "public" - }, "backstage": { "role": "cli" }, + "publishConfig": { + "access": "public" + }, + "keywords": [ + "backstage", + "techdocs" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "packages/techdocs-cli" }, - "keywords": [ - "backstage", - "techdocs" - ], "license": "Apache-2.0", "main": "dist/index.cjs.js", "types": "", - "scripts": { - "start": "nodemon --", - "build": "backstage-cli package build", - "clean": "backstage-cli package clean", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", - "test:e2e": "backstage-cli test --config cli-e2e-test.config.js", - "test:e2e:ci": "backstage-cli test --config cli-e2e-test.config.js --watchAll=false --ci", - "prepack": "./scripts/prepack.sh" - }, "bin": { "techdocs-cli": "bin/techdocs-cli" }, - "devDependencies": { - "@backstage/cli": "workspace:^", - "@types/commander": "^2.12.2", - "@types/fs-extra": "^11.0.0", - "@types/http-proxy": "^1.17.4", - "@types/node": "^18.17.8", - "@types/serve-handler": "^6.1.0", - "@types/webpack-env": "^1.15.3", - "find-process": "^1.4.5", - "nodemon": "^3.0.1", - "techdocs-cli-embedded-app": "link:../techdocs-cli-embedded-app" - }, "files": [ "bin", "dist" ], + "scripts": { + "build": "backstage-cli package build", + "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", + "prepack": "./scripts/prepack.sh", + "start": "nodemon --", + "test": "backstage-cli package test", + "test:e2e": "backstage-cli package test --config cli-e2e-test.config.js", + "test:e2e:ci": "backstage-cli package test --config cli-e2e-test.config.js --watchAll=false --ci" + }, "nodemonConfig": { - "watch": "./src", "exec": "bin/techdocs-cli", - "ext": "ts" + "ext": "ts", + "watch": "./src" }, "dependencies": { "@backstage/backend-defaults": "workspace:^", @@ -68,5 +56,17 @@ "react-dev-utils": "^12.0.0-next.60", "serve-handler": "^6.1.3", "winston": "^3.2.1" + }, + "devDependencies": { + "@backstage/cli": "workspace:^", + "@types/commander": "^2.12.2", + "@types/fs-extra": "^11.0.0", + "@types/http-proxy": "^1.17.4", + "@types/node": "^18.17.8", + "@types/serve-handler": "^6.1.0", + "@types/webpack-env": "^1.15.3", + "find-process": "^1.4.5", + "nodemon": "^3.0.1", + "techdocs-cli-embedded-app": "link:../techdocs-cli-embedded-app" } } diff --git a/packages/test-utils/CHANGELOG.md b/packages/test-utils/CHANGELOG.md index 29d38987d7..ef8b72951f 100644 --- a/packages/test-utils/CHANGELOG.md +++ b/packages/test-utils/CHANGELOG.md @@ -1,5 +1,66 @@ # @backstage/test-utils +## 1.6.1-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/plugin-permission-react@0.4.27-next.1 + - @backstage/core-app-api@1.15.1-next.1 + - @backstage/theme@0.5.8-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.8.1 + +## 1.6.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.15.1-next.0 + - @backstage/theme@0.5.7 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-permission-react@0.4.27-next.0 + +## 1.6.0 + +### Minor Changes + +- d47be30: Added the icons option to the renderInTestApp function's TestAppOptions to be forwarded to the icons option of `createApp`. + +### Patch Changes + +- b537bd7: Allow custom star icons to be provided via the `star` and `unstarred` icon overrides. See how to override existing icons in the [Backstage documentation](https://backstage.io/docs/getting-started/app-custom-theme/#custom-icons). +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-app-api@1.15.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/theme@0.5.7 + - @backstage/plugin-permission-react@0.4.26 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.8.1 + +## 1.6.0-next.1 + +### Patch Changes + +- b537bd7: Allow custom star icons to be provided via the `star` and `unstarred` icon overrides. See how to override existing icons in the [Backstage documentation](https://backstage.io/docs/getting-started/app-custom-theme/#custom-icons). +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-app-api@1.14.3-next.0 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/theme@0.5.7-next.0 + - @backstage/plugin-permission-react@0.4.26-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.8.1 + ## 1.6.0-next.0 ### Minor Changes diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index 16d1609c66..1c611fd584 100644 --- a/packages/test-utils/package.json +++ b/packages/test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/test-utils", - "version": "1.6.0-next.0", + "version": "1.6.1-next.1", "description": "Utilities to test Backstage plugins and apps.", "backstage": { "role": "web-library" @@ -58,7 +58,6 @@ "@backstage/types": "workspace:^", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "cross-fetch": "^4.0.0", "i18next": "^22.4.15", "zen-observable": "^0.10.0" @@ -66,12 +65,22 @@ "devDependencies": { "@backstage/cli": "workspace:^", "@testing-library/jest-dom": "^6.0.0", - "msw": "^1.0.0" + "@types/react": "^18.0.0", + "msw": "^1.0.0", + "react": "^18.0.2", + "react-dom": "^18.0.2", + "react-router-dom": "^6.3.0" }, "peerDependencies": { - "@testing-library/react": "^15.0.0", + "@testing-library/react": "^16.0.0", + "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } } diff --git a/packages/test-utils/api-report-alpha.md b/packages/test-utils/report-alpha.api.md similarity index 63% rename from packages/test-utils/api-report-alpha.md rename to packages/test-utils/report-alpha.api.md index 945c754f83..ba098135fb 100644 --- a/packages/test-utils/api-report-alpha.md +++ b/packages/test-utils/report-alpha.api.md @@ -28,5 +28,12 @@ export class MockTranslationApi implements TranslationApi { >(): Observable>; } +// Warnings were encountered during analysis: +// +// src/testUtils/apis/TranslationApi/MockTranslationApi.d.ts:4:1 - (ae-undocumented) Missing documentation for "MockTranslationApi". +// src/testUtils/apis/TranslationApi/MockTranslationApi.d.ts:6:5 - (ae-undocumented) Missing documentation for "create". +// src/testUtils/apis/TranslationApi/MockTranslationApi.d.ts:8:5 - (ae-undocumented) Missing documentation for "getTranslation". +// src/testUtils/apis/TranslationApi/MockTranslationApi.d.ts:11:5 - (ae-undocumented) Missing documentation for "translation$". + // (No @packageDocumentation comment for this package) ``` diff --git a/packages/test-utils/api-report.md b/packages/test-utils/report.api.md similarity index 82% rename from packages/test-utils/api-report.md rename to packages/test-utils/report.api.md index ae54c588ba..4a1f297c4e 100644 --- a/packages/test-utils/api-report.md +++ b/packages/test-utils/report.api.md @@ -83,37 +83,21 @@ export function mockBreakpoint(options: { matches: boolean }): void; // @public export class MockConfigApi implements ConfigApi { constructor(data: JsonObject); - // (undocumented) get(key?: string): T; - // (undocumented) getBoolean(key: string): boolean; - // (undocumented) getConfig(key: string): Config; - // (undocumented) getConfigArray(key: string): Config[]; - // (undocumented) getNumber(key: string): number; - // (undocumented) getOptional(key?: string): T | undefined; - // (undocumented) getOptionalBoolean(key: string): boolean | undefined; - // (undocumented) getOptionalConfig(key: string): Config | undefined; - // (undocumented) getOptionalConfigArray(key: string): Config[] | undefined; - // (undocumented) getOptionalNumber(key: string): number | undefined; - // (undocumented) getOptionalString(key: string): string | undefined; - // (undocumented) getOptionalStringArray(key: string): string[] | undefined; - // (undocumented) getString(key: string): string; - // (undocumented) getStringArray(key: string): string[]; - // (undocumented) has(key: string): boolean; - // (undocumented) keys(): string[]; } @@ -141,7 +125,6 @@ export type MockErrorApiOptions = { // @public export class MockFetchApi implements FetchApi { constructor(options?: MockFetchApiOptions); - // (undocumented) get fetch(): typeof crossFetch; } @@ -289,4 +272,21 @@ export function wrapInTestApp( Component: ComponentType | ReactNode, options?: TestAppOptions, ): ReactElement; + +// Warnings were encountered during analysis: +// +// src/deprecated.d.ts:5:1 - (ae-undocumented) Missing documentation for "setupRequestMockHandlers". +// src/testUtils/apis/AnalyticsApi/MockAnalyticsApi.d.ts:10:5 - (ae-undocumented) Missing documentation for "captureEvent". +// src/testUtils/apis/AnalyticsApi/MockAnalyticsApi.d.ts:11:5 - (ae-undocumented) Missing documentation for "getEvents". +// src/testUtils/apis/ErrorApi/MockErrorApi.d.ts:28:5 - (ae-undocumented) Missing documentation for "post". +// src/testUtils/apis/ErrorApi/MockErrorApi.d.ts:29:5 - (ae-undocumented) Missing documentation for "error$". +// src/testUtils/apis/ErrorApi/MockErrorApi.d.ts:33:5 - (ae-undocumented) Missing documentation for "getErrors". +// src/testUtils/apis/ErrorApi/MockErrorApi.d.ts:34:5 - (ae-undocumented) Missing documentation for "waitForError". +// src/testUtils/apis/PermissionApi/MockPermissionApi.d.ts:13:5 - (ae-undocumented) Missing documentation for "authorize". +// src/testUtils/apis/StorageApi/MockStorageApi.d.ts:19:5 - (ae-undocumented) Missing documentation for "create". +// src/testUtils/apis/StorageApi/MockStorageApi.d.ts:20:5 - (ae-undocumented) Missing documentation for "forBucket". +// src/testUtils/apis/StorageApi/MockStorageApi.d.ts:21:5 - (ae-undocumented) Missing documentation for "snapshot". +// src/testUtils/apis/StorageApi/MockStorageApi.d.ts:22:5 - (ae-undocumented) Missing documentation for "set". +// src/testUtils/apis/StorageApi/MockStorageApi.d.ts:23:5 - (ae-undocumented) Missing documentation for "remove". +// src/testUtils/apis/StorageApi/MockStorageApi.d.ts:24:5 - (ae-undocumented) Missing documentation for "observe$". ``` diff --git a/packages/test-utils/src/testUtils/appWrappers.tsx b/packages/test-utils/src/testUtils/appWrappers.tsx index 3a55389b74..6f9361f39b 100644 --- a/packages/test-utils/src/testUtils/appWrappers.tsx +++ b/packages/test-utils/src/testUtils/appWrappers.tsx @@ -63,6 +63,8 @@ const mockIcons = { help: MockIcon, user: MockIcon, warning: MockIcon, + star: MockIcon, + unstarred: MockIcon, }; const ErrorBoundaryFallback = ({ error }: { error: Error }) => { diff --git a/packages/theme/CHANGELOG.md b/packages/theme/CHANGELOG.md index 94d85c535a..db48fe9c40 100644 --- a/packages/theme/CHANGELOG.md +++ b/packages/theme/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/theme +## 0.5.8-next.0 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. + +## 0.5.7 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. + +## 0.5.7-next.0 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. + ## 0.5.6 ### Patch Changes diff --git a/packages/theme/package.json b/packages/theme/package.json index b199cb3061..842fc242da 100644 --- a/packages/theme/package.json +++ b/packages/theme/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/theme", - "version": "0.5.6", + "version": "0.5.8-next.0", "description": "material-ui theme for use with Backstage.", "backstage": { "role": "web-library" @@ -44,13 +44,22 @@ "@backstage/cli": "workspace:^", "@mui/styles": "^5.14.18", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^15.0.0", - "@types/react": "^16.13.1 || ^17.0.0" + "@testing-library/react": "^16.0.0", + "@types/react": "^18.0.0", + "react": "^18.0.2", + "react-dom": "^18.0.2", + "react-router-dom": "^6.3.0" }, "peerDependencies": { "@material-ui/core": "^4.12.2", "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0" + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } } diff --git a/packages/theme/api-report.md b/packages/theme/report.api.md similarity index 81% rename from packages/theme/api-report.md rename to packages/theme/report.api.md index 988569ece7..b380ce9fd1 100644 --- a/packages/theme/api-report.md +++ b/packages/theme/report.api.md @@ -459,4 +459,30 @@ export interface UnifiedThemeProviderProps { // (undocumented) theme: UnifiedTheme; } + +// Warnings were encountered during analysis: +// +// src/base/createBaseThemeOptions.d.ts:14:5 - (ae-undocumented) Missing documentation for "palette". +// src/base/createBaseThemeOptions.d.ts:15:5 - (ae-undocumented) Missing documentation for "defaultPageTheme". +// src/base/createBaseThemeOptions.d.ts:16:5 - (ae-undocumented) Missing documentation for "pageTheme". +// src/base/createBaseThemeOptions.d.ts:17:5 - (ae-undocumented) Missing documentation for "fontFamily". +// src/base/createBaseThemeOptions.d.ts:18:5 - (ae-undocumented) Missing documentation for "htmlFontSize". +// src/base/createBaseThemeOptions.d.ts:19:5 - (ae-undocumented) Missing documentation for "typography". +// src/unified/UnifiedTheme.d.ts:17:5 - (ae-undocumented) Missing documentation for "palette". +// src/unified/UnifiedTheme.d.ts:18:5 - (ae-undocumented) Missing documentation for "defaultPageTheme". +// src/unified/UnifiedTheme.d.ts:19:5 - (ae-undocumented) Missing documentation for "pageTheme". +// src/unified/UnifiedTheme.d.ts:20:5 - (ae-undocumented) Missing documentation for "fontFamily". +// src/unified/UnifiedTheme.d.ts:21:5 - (ae-undocumented) Missing documentation for "htmlFontSize". +// src/unified/UnifiedTheme.d.ts:22:5 - (ae-undocumented) Missing documentation for "components". +// src/unified/UnifiedTheme.d.ts:23:5 - (ae-undocumented) Missing documentation for "typography". +// src/unified/UnifiedThemeProvider.d.ts:9:5 - (ae-undocumented) Missing documentation for "children". +// src/unified/UnifiedThemeProvider.d.ts:10:5 - (ae-undocumented) Missing documentation for "theme". +// src/unified/UnifiedThemeProvider.d.ts:11:5 - (ae-undocumented) Missing documentation for "noCssBaseline". +// src/unified/types.d.ts:25:5 - (ae-undocumented) Missing documentation for "getTheme". +// src/v4/types.d.ts:31:5 - (ae-undocumented) Missing documentation for "palette". +// src/v4/types.d.ts:32:5 - (ae-undocumented) Missing documentation for "page". +// src/v4/types.d.ts:33:5 - (ae-undocumented) Missing documentation for "getPageTheme". +// src/v4/types.d.ts:42:5 - (ae-undocumented) Missing documentation for "palette". +// src/v4/types.d.ts:43:5 - (ae-undocumented) Missing documentation for "page". +// src/v4/types.d.ts:44:5 - (ae-undocumented) Missing documentation for "getPageTheme". ``` diff --git a/packages/types/package.json b/packages/types/package.json index f1f634af3e..2402dc84fa 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,44 +1,44 @@ { "name": "@backstage/types", - "description": "Common TypeScript types used within Backstage", "version": "1.1.1", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "Common TypeScript types used within Backstage", + "backstage": { + "role": "common-library" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "module": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "common-library" - }, + "keywords": [ + "backstage" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "packages/types" }, - "keywords": [ - "backstage" - ], + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "lint": "backstage-cli package lint", - "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "test": "backstage-cli package test" }, "devDependencies": { "@backstage/cli": "workspace:^", "@types/zen-observable": "^0.8.0", "luxon": "^3.0.0", "zen-observable": "^0.10.0" - }, - "files": [ - "dist" - ] + } } diff --git a/packages/types/api-report.md b/packages/types/report.api.md similarity index 100% rename from packages/types/api-report.md rename to packages/types/report.api.md diff --git a/packages/version-bridge/CHANGELOG.md b/packages/version-bridge/CHANGELOG.md index 86dadeac65..10a7aa5f60 100644 --- a/packages/version-bridge/CHANGELOG.md +++ b/packages/version-bridge/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/version-bridge +## 1.0.10-next.0 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. + +## 1.0.9 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. + +## 1.0.9-next.0 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. + ## 1.0.8 ### Patch Changes diff --git a/packages/version-bridge/package.json b/packages/version-bridge/package.json index c2bb341d49..4d00974baa 100644 --- a/packages/version-bridge/package.json +++ b/packages/version-bridge/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/version-bridge", - "version": "1.0.8", + "version": "1.0.10-next.0", "description": "Utilities used by @backstage packages to support multiple concurrent versions", "backstage": { "role": "web-library" @@ -35,17 +35,24 @@ "start": "backstage-cli package start", "test": "backstage-cli package test" }, - "dependencies": { - "@types/react": "^16.13.1 || ^17.0.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^15.0.0" + "@testing-library/react": "^16.0.0", + "@types/react": "^18.0.0", + "react": "^18.0.2", + "react-dom": "^18.0.2", + "react-router-dom": "^6.3.0" }, "peerDependencies": { + "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } } diff --git a/packages/version-bridge/api-report.md b/packages/version-bridge/report.api.md similarity index 100% rename from packages/version-bridge/api-report.md rename to packages/version-bridge/report.api.md diff --git a/packages/yarn-plugin/CHANGELOG.md b/packages/yarn-plugin/CHANGELOG.md index 5a2e9f417f..d32b0d3f4e 100644 --- a/packages/yarn-plugin/CHANGELOG.md +++ b/packages/yarn-plugin/CHANGELOG.md @@ -1,5 +1,14 @@ # yarn-plugin-backstage +## 0.0.2 + +### Patch Changes + +- bd32d5a: Add additional check before packing workspace to verify that all backstage:^ versions have been removed. +- Updated dependencies + - @backstage/cli-common@0.1.14 + - @backstage/release-manifests@0.0.11 + ## 0.0.1 ### Patch Changes diff --git a/packages/yarn-plugin/package.json b/packages/yarn-plugin/package.json index 206adeddbe..be24774dee 100644 --- a/packages/yarn-plugin/package.json +++ b/packages/yarn-plugin/package.json @@ -1,6 +1,6 @@ { "name": "yarn-plugin-backstage", - "version": "0.0.1", + "version": "0.0.2", "description": "Yarn plugin for working with Backstage monorepos", "backstage": { "role": "node-library" diff --git a/packages/yarn-plugin/api-report.md b/packages/yarn-plugin/report.api.md similarity index 68% rename from packages/yarn-plugin/api-report.md rename to packages/yarn-plugin/report.api.md index f0300ec9a1..b246b802bb 100644 --- a/packages/yarn-plugin/api-report.md +++ b/packages/yarn-plugin/report.api.md @@ -8,4 +8,8 @@ import { Plugin as Plugin_2 } from '@yarnpkg/core'; // @public (undocumented) const plugin: Plugin_2; export default plugin; + +// Warnings were encountered during analysis: +// +// src/index.d.ts:11:15 - (ae-undocumented) Missing documentation for "plugin". ``` diff --git a/packages/yarn-plugin/src/handlers/beforeWorkspacePacking.test.ts b/packages/yarn-plugin/src/handlers/beforeWorkspacePacking.test.ts index ca99b88437..d156182923 100644 --- a/packages/yarn-plugin/src/handlers/beforeWorkspacePacking.test.ts +++ b/packages/yarn-plugin/src/handlers/beforeWorkspacePacking.test.ts @@ -28,6 +28,14 @@ jest.mock('@backstage/release-manifests', () => ({ name: '@backstage/core', version: '3.2.1', }, + { + name: '@backstage/plugin-1', + version: '6.5.4', + }, + { + name: '@backstage/plugin-2', + version: '9.8.7', + }, ], }), })); @@ -100,7 +108,29 @@ describe('beforeWorkspacePacking', () => { await expect(() => beforeWorkspacePacking(makeWorkspace(result), result), - ).rejects.toThrow(); + ).rejects.toThrow(/unexpected version range/i); + }); + + it(`throws an error if the final manifest unexpectedly contains backstage: versions`, async () => { + const result = { + name: 'test-package', + [dependencyType]: { + get ['@backstage/core']() { + return 'backstage:^'; + }, + set ['@backstage/core'](_value: unknown) { + // ignore the attempt to set the value to + // allow testing the validation logic at + // the end of the hook. + }, + '@backstage/plugin-1': 'backstage:^', + '@backstage/plugin-2': 'backstage:^', + }, + }; + + await expect(() => + beforeWorkspacePacking(makeWorkspace(result), result), + ).rejects.toThrow(/failed to replace all "backstage:" ranges/i); }); it('converts backstage:^ versions to the corresponding package version prefixed by ^', async () => { diff --git a/packages/yarn-plugin/src/handlers/beforeWorkspacePacking.ts b/packages/yarn-plugin/src/handlers/beforeWorkspacePacking.ts index b804f64226..41014a55a6 100644 --- a/packages/yarn-plugin/src/handlers/beforeWorkspacePacking.ts +++ b/packages/yarn-plugin/src/handlers/beforeWorkspacePacking.ts @@ -15,9 +15,13 @@ */ import { Descriptor, Workspace, structUtils } from '@yarnpkg/core'; +import { some } from 'lodash'; import { getCurrentBackstageVersion, getPackageVersion } from '../util'; import { PROTOCOL } from '../constants'; +const hasBackstageVersion = (range: string) => + structUtils.parseRange(range).protocol === PROTOCOL; + const getFinalDependencyType = ( dependencyType: string, descriptor: Descriptor, @@ -69,4 +73,15 @@ export const beforeWorkspacePacking = async ( )}`; } } + + if ( + some( + ['dependencies', 'devDependencies', 'optionalDependencies'], + dependencyType => some(rawManifest[dependencyType], hasBackstageVersion), + ) + ) { + throw new Error( + `Failed to replace all "backstage:" ranges in manifest for ${rawManifest.name}`, + ); + } }; diff --git a/plugins/api-docs-module-protoc-gen-doc/CHANGELOG.md b/plugins/api-docs-module-protoc-gen-doc/CHANGELOG.md index 7ce6311e1f..b3b852ea90 100644 --- a/plugins/api-docs-module-protoc-gen-doc/CHANGELOG.md +++ b/plugins/api-docs-module-protoc-gen-doc/CHANGELOG.md @@ -1,5 +1,11 @@ # @backstage/plugin-api-docs-module-protoc-gen-doc +## 0.1.8-next.0 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. + ## 0.1.7 ### Patch Changes diff --git a/plugins/api-docs-module-protoc-gen-doc/package.json b/plugins/api-docs-module-protoc-gen-doc/package.json index ce2758e528..c3c38d7af9 100644 --- a/plugins/api-docs-module-protoc-gen-doc/package.json +++ b/plugins/api-docs-module-protoc-gen-doc/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-api-docs-module-protoc-gen-doc", - "version": "0.1.7", + "version": "0.1.8-next.0", "description": "Additional functionalities for the api-docs plugin that renders the output of the protoc-gen-doc", "backstage": { "role": "frontend-plugin-module", @@ -37,16 +37,25 @@ "test": "backstage-cli package test" }, "dependencies": { - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "grpc-docs": "^1.1.2" }, "devDependencies": { "@backstage/cli": "workspace:^", - "@testing-library/jest-dom": "^6.0.0" + "@testing-library/jest-dom": "^6.0.0", + "@types/react": "^18.0.0", + "react": "^18.0.2", + "react-dom": "^18.0.2", + "react-router-dom": "^6.3.0" }, "peerDependencies": { + "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } } diff --git a/plugins/api-docs-module-protoc-gen-doc/api-report.md b/plugins/api-docs-module-protoc-gen-doc/report.api.md similarity index 72% rename from plugins/api-docs-module-protoc-gen-doc/api-report.md rename to plugins/api-docs-module-protoc-gen-doc/report.api.md index 836f8313d8..355b867e9a 100644 --- a/plugins/api-docs-module-protoc-gen-doc/api-report.md +++ b/plugins/api-docs-module-protoc-gen-doc/report.api.md @@ -11,4 +11,8 @@ export const grpcDocsApiWidget: { title: string; component: (definition: string) => React_2.JSX.Element; }; + +// Warnings were encountered during analysis: +// +// src/widgets.d.ts:5:22 - (ae-undocumented) Missing documentation for "grpcDocsApiWidget". ``` diff --git a/plugins/api-docs/CHANGELOG.md b/plugins/api-docs/CHANGELOG.md index f75835f0a6..a0ff8b25ba 100644 --- a/plugins/api-docs/CHANGELOG.md +++ b/plugins/api-docs/CHANGELOG.md @@ -1,5 +1,72 @@ # @backstage/plugin-api-docs +## 0.11.11-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/frontend-plugin-api@0.9.0-next.1 + - @backstage/core-compat-api@0.3.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/plugin-permission-react@0.4.27-next.1 + - @backstage/plugin-catalog-react@1.14.0-next.1 + - @backstage/plugin-catalog@1.24.0-next.1 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-catalog-common@1.1.0 + +## 0.11.10-next.0 + +### Patch Changes + +- 46b5a20: Empty states updated with external link icon for learn more links +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/plugin-catalog@1.24.0-next.0 + - @backstage/core-compat-api@0.3.1-next.0 + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/plugin-catalog-react@1.13.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-permission-react@0.4.27-next.0 + +## 0.11.9 + +### Patch Changes + +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- 8a474f2: Updating docs to use `createFrontendModule` instead +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/plugin-catalog-react@1.13.0 + - @backstage/plugin-catalog@1.23.0 + - @backstage/frontend-plugin-api@0.8.0 + - @backstage/core-compat-api@0.3.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/plugin-permission-react@0.4.26 + +## 0.11.9-next.2 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- 8a474f2: Updating docs to use `createFrontendModule` instead +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/plugin-catalog-react@1.13.0-next.2 + - @backstage/plugin-catalog@1.23.0-next.2 + - @backstage/core-compat-api@0.3.0-next.2 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/frontend-plugin-api@0.8.0-next.2 + - @backstage/plugin-permission-react@0.4.26-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/plugin-catalog-common@1.0.26 + ## 0.11.9-next.1 ### Patch Changes diff --git a/plugins/api-docs/README-alpha.md b/plugins/api-docs/README-alpha.md index eb84ef8c27..d92fdb53da 100644 --- a/plugins/api-docs/README-alpha.md +++ b/plugins/api-docs/README-alpha.md @@ -203,21 +203,23 @@ The apis nav item icon can only be changed by overriding the extension, as the i Here is an example overriding the nav item extension with a custom icon component: ```tsx -import { createExtensionOverrides, createNavItemExtension } from '@backstage/backstage-plugin-api'; +import { + createFrontendModule, + createNavItemExtension, +} from '@backstage/backstage-plugin-api'; import { MyCustomApiDocsIcon } from './components'; -export default createExtensionOverrides( +export default createFrontendModule({ + pluginId: 'api-docs', extensions: [ createNavItemExtension({ - // These namespace is necessary so the system knows that this extension will override the default nav item provided by the 'api-docs' plugin - namespace: 'api-docs', // It's your choice whether to use the original extension's title or a different one title: 'APIs', // Setting a custom icon component icon: MyCustomApiDocsIcon, - }) - ] -); + }), + ], +}); ``` For more information about where to place extension overrides, see the official [documentation](https://backstage.io/docs/frontend-system/architecture/extension-overrides). @@ -273,24 +275,27 @@ The explorer page implementation can be [overridden](https://backstage.io/docs/f Here is an example overriding the APIs Explorer page component: ```tsx -import { createExtensionOverrides, createPageExtension } from '@backstage/backstage-plugin-api'; +import { + createFrontendModule, + createPageExtension, +} from '@backstage/backstage-plugin-api'; import { convertLegacyRouteRef } from '@backstage/core-compat-api'; -export default createExtensionOverrides( +export default createFrontendModule({ + pluginId: 'api-docs', extensions: [ createPageExtension({ - // These namespace is necessary so the system knows that this extension will override the default explorer page provided by the 'api-docs' plugin - namespace: 'api-docs', // Ommitting name since we are overriding a plugin index page // It's up to you whether to use the original default path or not, but links that are hardcoded to the default path won't work if you change it defaultPath: '/api-docs', // Associating the page with a different route ref may result in the sidebar item or external plugin route pointing to an unreachable page routeRef: convertLegacyRouteRef(rootRoute), // Custom page components are loaded here - loader: () => import('./components').then(m => ) - }) - ] -); + loader: () => + import('./components').then(m => ), + }), + ], +}); ``` #### Apis Entities Cards @@ -304,7 +309,7 @@ See a complete cards list below: ##### Has Apis Entity Card -An [entity card](https://github.com/backstage/backstage/blob/master/plugins/catalog-react/api-report-alpha.md) extension that renders a table of entities that have an api relation with a particular Software catalog entity. +An [entity card](https://github.com/backstage/backstage/blob/master/plugins/catalog-react/report-alpha.api.md) extension that renders a table of entities that have an api relation with a particular Software catalog entity. | Kind | Namespace | Name | Id | | ------------- | ---------- | ---------- | ------------------------------- | @@ -356,14 +361,14 @@ app: Use extension overrides for completely re-implementing the has apis entity card extension: ```tsx -import { createExtensionOverrides } from '@backstage/backstage-plugin-api'; +import { createFrontendModule } from '@backstage/backstage-plugin-api'; import { createEntityCardExtension } from '@backstage/plugin-catalog-react/alpha'; -export default createExtensionOverrides({ +export default createFrontendModule({ + pluginId: 'api-docs', extensions: [ createEntityCardExtension({ - // These namespace and name necessary so the system knows that this extension will override the default 'has-apis' entity card extension provided by the 'api-docs' plugin - namespace: 'api-docs', + // Name is necessary so the system knows that this extension will override the default 'has-apis' entity card extension provided by the 'api-docs' plugin name: 'has-apis', // Returing a custom card component loader: () => @@ -377,7 +382,7 @@ For more information about where to place extension overrides, see the official ##### Definition Entity Card -An [entity card](https://github.com/backstage/backstage/blob/master/plugins/catalog-react/api-report-alpha.md) extension that renders an entity api definition widget. +An [entity card](https://github.com/backstage/backstage/blob/master/plugins/catalog-react/report-alpha.api.md) extension that renders an entity api definition widget. | Kind | Namespace | Name | Id | | ------------- | ---------- | ------------ | --------------------------------- | @@ -429,14 +434,14 @@ app: Use extension overrides for completely re-implementing the has apis entity card extension: ```tsx -import { createExtensionOverrides } from '@backstage/backstage-plugin-api'; +import { createFrontendModule } from '@backstage/backstage-plugin-api'; import { createEntityCardExtension } from '@backstage/plugin-catalog-react/alpha'; -export default createExtensionOverrides({ +export default createFrontendModule({ + pluginId: 'api-docs', extensions: [ createEntityCardExtension({ - // These namespace and name necessary so the system knows that this extension will override the default 'definition' entity card extension provided by the 'api-docs' plugin - namespace: 'api-docs', + // Name is necessary so the system knows that this extension will override the default 'definition' entity card extension provided by the 'api-docs' plugin name: 'definition', // Returing a custom card component loader: () => @@ -450,7 +455,7 @@ For more information about where to place extension overrides, see the official ##### Provided Apis Entity Card -An [entity card](https://github.com/backstage/backstage/blob/master/plugins/catalog-react/api-report-alpha.md) extension that renders a table of apis provided by a particular Software Catalog Component. +An [entity card](https://github.com/backstage/backstage/blob/master/plugins/catalog-react/report-alpha.api.md) extension that renders a table of apis provided by a particular Software Catalog Component. | Kind | Namespace | Name | Id | | ------------- | ---------- | --------------- | ------------------------------------ | @@ -502,14 +507,14 @@ app: Use extension overrides for completely re-implementing the has apis entity card extension: ```tsx -import { createExtensionOverrides } from '@backstage/backstage-plugin-api'; +import { createFrontendModule } from '@backstage/backstage-plugin-api'; import { createEntityCardExtension } from '@backstage/plugin-catalog-react/alpha'; -export default createExtensionOverrides({ +export default createFrontendModule({ + pluginId: 'api-docs', extensions: [ createEntityCardExtension({ - // These namespace and name necessary so the system knows that this extension will override the default 'provided-apis' entity card extension provided by the 'api-docs' plugin - namespace: 'api-docs', + // Name is necessary so the system knows that this extension will override the default 'provided-apis' entity card extension provided by the 'api-docs' plugin name: 'provided-apis', // Returing a custom card component loader: () => @@ -523,7 +528,7 @@ For more information about where to place extension overrides, see the official ##### Consumed Apis Entity Card -An [entity card](https://github.com/backstage/backstage/blob/master/plugins/catalog-react/api-report-alpha.md) extension that renders a table of apis consumed by a particular Software Catalog Component. +An [entity card](https://github.com/backstage/backstage/blob/master/plugins/catalog-react/report-alpha.api.md) extension that renders a table of apis consumed by a particular Software Catalog Component. | Kind | Namespace | Name | Id | | ------------- | ---------- | --------------- | ------------------------------------ | @@ -575,14 +580,14 @@ app: Use extension overrides for completely re-implementing the has apis entity card extension: ```tsx -import { createExtensionOverrides } from '@backstage/backstage-plugin-api'; +import { createFrontendModule } from '@backstage/backstage-plugin-api'; import { createEntityCardExtension } from '@backstage/plugin-catalog-react/alpha'; -export default createExtensionOverrides({ +export default createFrontendModule({ + pluginId: 'api-docs', extensions: [ createEntityCardExtension({ - // These namespace and name necessary so the system knows that this extension will override the default 'consumed-apis' entity card extension provided by the 'api-docs' plugin - namespace: 'api-docs', + // Name is necessary so the system knows that this extension will override the default 'consumed-apis' entity card extension provided by the 'api-docs' plugin name: 'consumed-apis', // Returing a custom card component loader: () => @@ -596,7 +601,7 @@ For more information about where to place extension overrides, see the official ##### Providing Components Entity Card -An [entity card](https://github.com/backstage/backstage/blob/master/plugins/catalog-react/api-report-alpha.md) extension that renders a table of components that provides a particular Software Catalog api. +An [entity card](https://github.com/backstage/backstage/blob/master/plugins/catalog-react/report-alpha.api.md) extension that renders a table of components that provides a particular Software Catalog api. | Kind | Namespace | Name | Id | | ------------- | ---------- | ---------------------- | ------------------------------------------- | @@ -648,14 +653,14 @@ app: Use extension overrides for completely re-implementing the has apis entity card extension: ```tsx -import { createExtensionOverrides } from '@backstage/backstage-plugin-api'; +import { createFrontendModule } from '@backstage/backstage-plugin-api'; import { createEntityCardExtension } from '@backstage/plugin-catalog-react/alpha'; -export default createExtensionOverrides({ +export default createFrontendModule({ + pluginId: 'api-docs', extensions: [ createEntityCardExtension({ - // These namespace and name necessary so the system knows that this extension will override the default 'providing-components' entity card extension provided by the 'api-docs' plugin - namespace: 'api-docs', + // Name is necessary so the system knows that this extension will override the default 'providing-components' entity card extension provided by the 'api-docs' plugin name: 'providing-components', // Returing a custom card component loader: () => @@ -671,7 +676,7 @@ For more information about where to place extension overrides, see the official ##### Consuming Components Entity Card -An [entity card](https://github.com/backstage/backstage/blob/master/plugins/catalog-react/api-report-alpha.md) extension that renders a table of components that consumes a particular Software Catalog api. +An [entity card](https://github.com/backstage/backstage/blob/master/plugins/catalog-react/report-alpha.api.md) extension that renders a table of components that consumes a particular Software Catalog api. | Kind | Namespace | Name | Id | | ------------- | ---------- | ---------------------- | ------------------------------------------- | @@ -723,14 +728,14 @@ app: Use extension overrides for completely re-implementing the has apis entity card extension: ```tsx -import { createExtensionOverrides } from '@backstage/backstage-plugin-api'; +import { createFrontendModule } from '@backstage/backstage-plugin-api'; import { createEntityCardExtension } from '@backstage/plugin-catalog-react/alpha'; -export default createExtensionOverrides({ +export default createFrontendModule({ + pluginId: 'api-docs', extensions: [ createEntityCardExtension({ - // These namespace and name necessary so the system knows that this extension will override the default 'consuming-components' entity card extension provided by the 'api-docs' plugin - namespace: 'api-docs', + // Name is necessary so the system knows that this extension will override the default 'consuming-components' entity card extension provided by the 'api-docs' plugin name: 'consuming-components', // Returing a custom card component loader: () => @@ -755,7 +760,7 @@ See a complete contents list below: ##### Definition Entity Content -An [entity content](https://github.com/backstage/backstage/blob/master/plugins/catalog-react/api-report-alpha.md) extension that renders a tab in the entity page showing a particular entity api definition. +An [entity content](https://github.com/backstage/backstage/blob/master/plugins/catalog-react/report-alpha.api.md) extension that renders a tab in the entity page showing a particular entity api definition. | Kind | Namespace | Name | Id | | ---------------- | ---------- | ------------ | ------------------------------------ | @@ -812,14 +817,14 @@ app: Use extension overrides for completely re-implementing the has apis entity card extension: ```tsx -import { createExtensionOverrides } from '@backstage/backstage-plugin-api'; +import { createFrontendModule } from '@backstage/backstage-plugin-api'; import { createEntityContentExtension } from '@backstage/plugin-catalog-react/alpha'; -export default createExtensionOverrides({ +export default createFrontendModule({ + pluginId: 'api-docs', extensions: [ createEntityContentExtension({ - // These namespace and name necessary so the system knows that this extension will override the default 'definition' entity content extension provided by the 'api-docs' plugin - namespace: 'api-docs', + // Name is necessary so the system knows that this extension will override the default 'definition' entity content extension provided by the 'api-docs' plugin name: 'definition', // Returing a custom content component loader: () => @@ -892,14 +897,14 @@ app: Use extension overrides for completely re-implementing the apis entity content extension: ```tsx -import { createExtensionOverrides } from '@backstage/backstage-plugin-api'; +import { createFrontendModule } from '@backstage/backstage-plugin-api'; import { createEntityContentExtension } from '@backstage/plugin-catalog-react/alpha'; -export default createExtensionOverrides({ +export default createFrontendModule({ + pluginId: 'api-docs', extensions: [ createEntityContentExtension({ - // These namespace and name necessary so the system knows that this extension will override the default 'apis' entity content extension provided by the 'api-docs' plugin - namespace: 'api-docs', + // Name is necessary so the system knows that this extension will override the default 'apis' entity content extension provided by the 'api-docs' plugin name: 'apis', // Returing a custom content component loader: () => @@ -929,7 +934,7 @@ This is an example with a made-up renderer for SQL schemas: ```tsx import { - createExtensionOverrides, + createFrontendModule, createApiExtenion, createApiFactory, } from '@backstage/frontend-plugin-api'; @@ -941,7 +946,8 @@ import { } from '@backstage/plugin-api-docs'; import { SqlRenderer } from '...'; -export default createExtensionOverrides({ +export default createFrontendModule({ + pluginId: 'api-docs', extensions: [ createApiExtenion({ factory: createApiFactory({ @@ -982,7 +988,7 @@ Override the config api to configure a [`requestInterceptor` for Swagger UI](htt ```tsx import { - createExtensionOverrides, + createFrontendModule, createApiExtenion, createApiFactory, } from '@backstage/frontend-plugin-api'; @@ -993,7 +999,8 @@ import { } from '@backstage/plugin-api-docs'; import { ApiEntity } from '@backstage/catalog-model'; -export default createExtensionOverrides({ +export default createFrontendModule({ + pluginId: 'api-docs', extensions: [ createApiExtenion({ factory: createApiFactory({ @@ -1043,7 +1050,7 @@ If you want to limit the HTTP methods available for the `Try It Out` feature of ```tsx import { - createExtensionOverrides, + createFrontendModule, createApiExtenion, createApiFactory, } from '@backstage/frontend-plugin-api'; @@ -1054,7 +1061,8 @@ import { } from '@backstage/plugin-api-docs'; import { ApiEntity } from '@backstage/catalog-model'; -export default createExtensionOverrides({ +export default createFrontendModule({ + pluginId: 'api-docs', extensions: [ createApiExtenion({ factory: createApiFactory({ diff --git a/plugins/api-docs/package.json b/plugins/api-docs/package.json index 3a102a70e5..994c8dac35 100644 --- a/plugins/api-docs/package.json +++ b/plugins/api-docs/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-api-docs", - "version": "0.11.9-next.1", + "version": "0.11.11-next.1", "description": "A Backstage plugin that helps represent API entities in the frontend", "backstage": { "role": "frontend-plugin", @@ -67,7 +67,6 @@ "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.61", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "graphiql": "3.1.1", "graphql": "^16.0.0", "graphql-config": "^5.0.2", @@ -82,14 +81,24 @@ "@backstage/test-utils": "workspace:^", "@testing-library/dom": "^10.0.0", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^15.0.0", + "@testing-library/react": "^16.0.0", "@testing-library/user-event": "^14.0.0", "@types/highlightjs": "^10.1.0", - "@types/swagger-ui-react": "^4.18.0" + "@types/react": "^18.0.0", + "@types/swagger-ui-react": "^4.18.0", + "react": "^18.0.2", + "react-dom": "^18.0.2", + "react-router-dom": "^6.3.0" }, "peerDependencies": { + "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } } diff --git a/plugins/api-docs/api-report-alpha.md b/plugins/api-docs/report-alpha.api.md similarity index 85% rename from plugins/api-docs/api-report-alpha.md rename to plugins/api-docs/report-alpha.api.md index bb2da7bc0b..274d5d4aac 100644 --- a/plugins/api-docs/api-report-alpha.md +++ b/plugins/api-docs/report-alpha.api.md @@ -27,7 +27,6 @@ const _default: FrontendPlugin< { 'nav-item:api-docs': ExtensionDefinition<{ kind: 'nav-item'; - namespace: undefined; name: undefined; config: {}; configInput: {}; @@ -41,10 +40,14 @@ const _default: FrontendPlugin< {} >; inputs: {}; + params: { + title: string; + icon: IconComponent; + routeRef: RouteRef; + }; }>; 'api:api-docs/config': ExtensionDefinition<{ kind: 'api'; - namespace: undefined; name: 'config'; config: {}; configInput: {}; @@ -54,6 +57,9 @@ const _default: FrontendPlugin< {} >; inputs: {}; + params: { + factory: AnyApiFactory; + }; }>; 'page:api-docs': ExtensionDefinition<{ config: { @@ -90,12 +96,15 @@ const _default: FrontendPlugin< >; }; kind: 'page'; - namespace: undefined; name: undefined; + params: { + defaultPath: string; + loader: () => Promise; + routeRef?: RouteRef | undefined; + }; }>; 'entity-card:api-docs/has-apis': ExtensionDefinition<{ kind: 'entity-card'; - namespace: undefined; name: 'has-apis'; config: { filter: string | undefined; @@ -124,10 +133,13 @@ const _default: FrontendPlugin< } >; inputs: {}; + params: { + loader: () => Promise; + filter?: string | ((entity: Entity) => boolean) | undefined; + }; }>; 'entity-card:api-docs/definition': ExtensionDefinition<{ kind: 'entity-card'; - namespace: undefined; name: 'definition'; config: { filter: string | undefined; @@ -156,10 +168,13 @@ const _default: FrontendPlugin< } >; inputs: {}; + params: { + loader: () => Promise; + filter?: string | ((entity: Entity) => boolean) | undefined; + }; }>; 'entity-card:api-docs/consumed-apis': ExtensionDefinition<{ kind: 'entity-card'; - namespace: undefined; name: 'consumed-apis'; config: { filter: string | undefined; @@ -188,10 +203,13 @@ const _default: FrontendPlugin< } >; inputs: {}; + params: { + loader: () => Promise; + filter?: string | ((entity: Entity) => boolean) | undefined; + }; }>; 'entity-card:api-docs/provided-apis': ExtensionDefinition<{ kind: 'entity-card'; - namespace: undefined; name: 'provided-apis'; config: { filter: string | undefined; @@ -220,10 +238,13 @@ const _default: FrontendPlugin< } >; inputs: {}; + params: { + loader: () => Promise; + filter?: string | ((entity: Entity) => boolean) | undefined; + }; }>; 'entity-card:api-docs/consuming-components': ExtensionDefinition<{ kind: 'entity-card'; - namespace: undefined; name: 'consuming-components'; config: { filter: string | undefined; @@ -252,10 +273,13 @@ const _default: FrontendPlugin< } >; inputs: {}; + params: { + loader: () => Promise; + filter?: string | ((entity: Entity) => boolean) | undefined; + }; }>; 'entity-card:api-docs/providing-components': ExtensionDefinition<{ kind: 'entity-card'; - namespace: undefined; name: 'providing-components'; config: { filter: string | undefined; @@ -284,10 +308,13 @@ const _default: FrontendPlugin< } >; inputs: {}; + params: { + loader: () => Promise; + filter?: string | ((entity: Entity) => boolean) | undefined; + }; }>; 'entity-content:api-docs/definition': ExtensionDefinition<{ kind: 'entity-content'; - namespace: undefined; name: 'definition'; config: { path: string | undefined; @@ -333,10 +360,16 @@ const _default: FrontendPlugin< } >; inputs: {}; + params: { + loader: () => Promise; + defaultPath: string; + defaultTitle: string; + routeRef?: RouteRef | undefined; + filter?: string | ((entity: Entity) => boolean) | undefined; + }; }>; 'entity-content:api-docs/apis': ExtensionDefinition<{ kind: 'entity-content'; - namespace: undefined; name: 'apis'; config: { path: string | undefined; @@ -382,10 +415,21 @@ const _default: FrontendPlugin< } >; inputs: {}; + params: { + loader: () => Promise; + defaultPath: string; + defaultTitle: string; + routeRef?: RouteRef | undefined; + filter?: string | ((entity: Entity) => boolean) | undefined; + }; }>; } >; export default _default; +// Warnings were encountered during analysis: +// +// src/alpha.d.ts:2:15 - (ae-undocumented) Missing documentation for "_default". + // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/api-docs/api-report.md b/plugins/api-docs/report.api.md similarity index 62% rename from plugins/api-docs/api-report.md rename to plugins/api-docs/report.api.md index 3c3f245a3c..74318781c8 100644 --- a/plugins/api-docs/api-report.md +++ b/plugins/api-docs/report.api.md @@ -229,4 +229,38 @@ export const TrpcApiDefinitionWidget: ( export type TrpcApiDefinitionWidgetProps = { definition: string; }; + +// Warnings were encountered during analysis: +// +// src/components/ApiDefinitionCard/ApiDefinitionCard.d.ts:3:22 - (ae-undocumented) Missing documentation for "ApiDefinitionCard". +// src/components/ApiDefinitionCard/ApiDefinitionWidget.d.ts:3:1 - (ae-undocumented) Missing documentation for "ApiDefinitionWidget". +// src/components/ApiDefinitionCard/ApiDefinitionWidget.d.ts:10:1 - (ae-undocumented) Missing documentation for "defaultDefinitionWidgets". +// src/components/ApiDefinitionCard/ApiTypeTitle.d.ts:6:22 - (ae-undocumented) Missing documentation for "ApiTypeTitle". +// src/components/ApisCards/ConsumedApisCard.d.ts:7:22 - (ae-undocumented) Missing documentation for "ConsumedApisCard". +// src/components/ApisCards/HasApisCard.d.ts:7:22 - (ae-undocumented) Missing documentation for "HasApisCard". +// src/components/ApisCards/ProvidedApisCard.d.ts:7:22 - (ae-undocumented) Missing documentation for "ProvidedApisCard". +// src/components/AsyncApiDefinitionWidget/AsyncApiDefinition.d.ts:4:1 - (ae-undocumented) Missing documentation for "AsyncApiResolver". +// src/components/AsyncApiDefinitionWidget/AsyncApiDefinitionWidget.d.ts:4:1 - (ae-undocumented) Missing documentation for "AsyncApiDefinitionWidgetProps". +// src/components/AsyncApiDefinitionWidget/AsyncApiDefinitionWidget.d.ts:9:22 - (ae-undocumented) Missing documentation for "AsyncApiDefinitionWidget". +// src/components/ComponentsCards/ConsumingComponentsCard.d.ts:7:22 - (ae-undocumented) Missing documentation for "ConsumingComponentsCard". +// src/components/ComponentsCards/ProvidingComponentsCard.d.ts:5:22 - (ae-undocumented) Missing documentation for "ProvidingComponentsCard". +// src/components/GraphQlDefinitionWidget/GraphQlDefinitionWidget.d.ts:3:1 - (ae-undocumented) Missing documentation for "GraphQlDefinitionWidgetProps". +// src/components/GraphQlDefinitionWidget/GraphQlDefinitionWidget.d.ts:7:22 - (ae-undocumented) Missing documentation for "GraphQlDefinitionWidget". +// src/components/OpenApiDefinitionWidget/OpenApiDefinitionWidget.d.ts:3:1 - (ae-undocumented) Missing documentation for "OpenApiDefinitionWidgetProps". +// src/components/OpenApiDefinitionWidget/OpenApiDefinitionWidget.d.ts:9:22 - (ae-undocumented) Missing documentation for "OpenApiDefinitionWidget". +// src/components/PlainApiDefinitionWidget/PlainApiDefinitionWidget.d.ts:3:1 - (ae-undocumented) Missing documentation for "PlainApiDefinitionWidgetProps". +// src/components/PlainApiDefinitionWidget/PlainApiDefinitionWidget.d.ts:8:22 - (ae-undocumented) Missing documentation for "PlainApiDefinitionWidget". +// src/components/TrpcDefinitionWidget/TrpcApiDefinitionWidget.d.ts:3:1 - (ae-undocumented) Missing documentation for "TrpcApiDefinitionWidgetProps". +// src/components/TrpcDefinitionWidget/TrpcApiDefinitionWidget.d.ts:7:22 - (ae-undocumented) Missing documentation for "TrpcApiDefinitionWidget". +// src/config.d.ts:4:22 - (ae-undocumented) Missing documentation for "apiDocsConfigRef". +// src/config.d.ts:6:1 - (ae-undocumented) Missing documentation for "ApiDocsConfig". +// src/config.d.ts:7:5 - (ae-undocumented) Missing documentation for "getApiDefinitionWidget". +// src/plugin.d.ts:4:22 - (ae-undocumented) Missing documentation for "apiDocsPlugin". +// src/plugin.d.ts:10:22 - (ae-undocumented) Missing documentation for "ApiExplorerPage". +// src/plugin.d.ts:12:22 - (ae-undocumented) Missing documentation for "EntityApiDefinitionCard". +// src/plugin.d.ts:14:22 - (ae-undocumented) Missing documentation for "EntityConsumedApisCard". +// src/plugin.d.ts:21:22 - (ae-undocumented) Missing documentation for "EntityConsumingComponentsCard". +// src/plugin.d.ts:26:22 - (ae-undocumented) Missing documentation for "EntityProvidedApisCard". +// src/plugin.d.ts:33:22 - (ae-undocumented) Missing documentation for "EntityProvidingComponentsCard". +// src/plugin.d.ts:38:22 - (ae-undocumented) Missing documentation for "EntityHasApisCard". ``` diff --git a/plugins/api-docs/src/components/ApisCards/ConsumedApisCard.test.tsx b/plugins/api-docs/src/components/ApisCards/ConsumedApisCard.test.tsx index d664ce78e8..95e279bad5 100644 --- a/plugins/api-docs/src/components/ApisCards/ConsumedApisCard.test.tsx +++ b/plugins/api-docs/src/components/ApisCards/ConsumedApisCard.test.tsx @@ -62,7 +62,7 @@ describe('', () => { relations: [], }; - const { getByText } = await renderInTestApp( + const { getByText, getByRole, container } = await renderInTestApp( @@ -77,6 +77,17 @@ describe('', () => { expect(getByText(/Consumed APIs/i)).toBeInTheDocument(); expect(getByText(/does not consume any APIs/i)).toBeInTheDocument(); + + // Also render external link icon + const externalLink = getByRole('link'); + expect(externalLink).toHaveAttribute( + 'href', + 'https://backstage.io/docs/features/software-catalog/descriptor-format#specconsumesapis-optional', + ); + const externalLinkIcon: HTMLElement | null = container.querySelector( + 'svg[class*="externalLink"]', + ); + expect(externalLink).toContainElement(externalLinkIcon); }); it('shows consumed APIs', async () => { diff --git a/plugins/api-docs/src/components/ApisCards/ConsumedApisCard.tsx b/plugins/api-docs/src/components/ApisCards/ConsumedApisCard.tsx index f68e6dcb40..0e0518a58f 100644 --- a/plugins/api-docs/src/components/ApisCards/ConsumedApisCard.tsx +++ b/plugins/api-docs/src/components/ApisCards/ConsumedApisCard.tsx @@ -85,8 +85,11 @@ export const ConsumedApisCard = (props: { APIs. - - Learn how to change this. + + Learn how to change this diff --git a/plugins/api-docs/src/components/ApisCards/ProvidedApisCard.test.tsx b/plugins/api-docs/src/components/ApisCards/ProvidedApisCard.test.tsx index 3dbc4edd63..8c4f7dd26b 100644 --- a/plugins/api-docs/src/components/ApisCards/ProvidedApisCard.test.tsx +++ b/plugins/api-docs/src/components/ApisCards/ProvidedApisCard.test.tsx @@ -62,7 +62,7 @@ describe('', () => { relations: [], }; - const { getByText } = await renderInTestApp( + const { getByText, getByRole, container } = await renderInTestApp( @@ -77,6 +77,18 @@ describe('', () => { expect(getByText(/Provided APIs/i)).toBeInTheDocument(); expect(getByText(/does not provide any APIs/i)).toBeInTheDocument(); + expect(getByText(/Learn how to change this/)).toBeInTheDocument(); + + // Also render external link icon + const externalLink = getByRole('link'); + expect(externalLink).toHaveAttribute( + 'href', + 'https://backstage.io/docs/features/software-catalog/descriptor-format#specprovidesapis-optional', + ); + const externalLinkIcon: HTMLElement | null = container.querySelector( + 'svg[class*="externalLink"]', + ); + expect(externalLink).toContainElement(externalLinkIcon); }); it('shows consumed APIs', async () => { diff --git a/plugins/api-docs/src/components/ApisCards/ProvidedApisCard.tsx b/plugins/api-docs/src/components/ApisCards/ProvidedApisCard.tsx index 48099df375..f89f411488 100644 --- a/plugins/api-docs/src/components/ApisCards/ProvidedApisCard.tsx +++ b/plugins/api-docs/src/components/ApisCards/ProvidedApisCard.tsx @@ -84,11 +84,12 @@ export const ProvidedApisCard = (props: { This {entity.kind.toLocaleLowerCase('en-US')} does not provide any APIs. - - - Learn how to change this. - - + + Learn how to change this + } columns={columns} diff --git a/plugins/app-backend/CHANGELOG.md b/plugins/app-backend/CHANGELOG.md index a350fb994e..4323aed5af 100644 --- a/plugins/app-backend/CHANGELOG.md +++ b/plugins/app-backend/CHANGELOG.md @@ -1,5 +1,68 @@ # @backstage/plugin-app-backend +## 0.3.75-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-app-node@0.1.26-next.0 + +## 0.3.74 + +### Patch Changes + +- 72a8c7b: Return HTTP status 400 rather than 500 when receiving an unknown POST request. +- d3f79d1: Fixing dependency metadata with the new `@backstage/plugin-app` package +- 590fb2d: **BREAKING**: The app backend now supports the new `index.html.tmpl` output from `@backstage/cli`. If available, the `index.html` will be templated at runtime with the current configuration of the app backend. + + This is marked as a breaking change because you must now supply the app build-time configuration to the backend. This change also affects the public path behavior, where it is no longer necessary to build the app with the correct public path upfront. You now only need to supply a correct `app.baseUrl` to the app backend plugin at runtime. + + An effect that this change has is that the `index.html` will now contain and present the frontend configuration in an easily readable way, which can aid in debugging. This data was always available in the frontend, but it was injected and hidden in the static bundle. + + This templating behavior is enabled by default, but it can be disabled by setting the `app.disableConfigInjection` configuration option to `true`. + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/plugin-app-node@0.1.25 + - @backstage/config-loader@1.9.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## 0.3.74-next.2 + +### Patch Changes + +- 590fb2d: **BREAKING**: The app backend now supports the new `index.html.tmpl` output from `@backstage/cli`. If available, the `index.html` will be templated at runtime with the current configuration of the app backend. + + This is marked as a breaking change because you must now supply the app build-time configuration to the backend. This change also affects the public path behavior, where it is no longer necessary to build the app with the correct public path upfront. You now only need to supply a correct `app.baseUrl` to the app backend plugin at runtime. + + An effect that this change has is that the `index.html` will now contain and present the frontend configuration in an easily readable way, which can aid in debugging. This data was always available in the frontend, but it was injected and hidden in the static bundle. + + This templating behavior is enabled by default, but it can be disabled by setting the `app.disableConfigInjection` configuration option to `true`. + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/config-loader@1.9.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-app-node@0.1.25-next.2 + ## 0.3.74-next.1 ### Patch Changes diff --git a/plugins/app-backend/package.json b/plugins/app-backend/package.json index 4f438a7d9b..c7316a9815 100644 --- a/plugins/app-backend/package.json +++ b/plugins/app-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-app-backend", - "version": "0.3.74-next.1", + "version": "0.3.75-next.0", "description": "A Backstage backend plugin that serves the Backstage frontend app", "backstage": { "role": "backend-plugin", @@ -57,7 +57,7 @@ "test": "backstage-cli package test" }, "dependencies": { - "@backstage/backend-common": "workspace:^", + "@backstage/backend-common": "^0.25.0", "@backstage/backend-plugin-api": "workspace:^", "@backstage/config": "workspace:^", "@backstage/config-loader": "workspace:^", @@ -84,7 +84,7 @@ "@backstage/types": "workspace:^", "@types/supertest": "^2.0.8", "node-fetch": "^2.7.0", - "supertest": "^6.1.3" + "supertest": "^7.0.0" }, "configSchema": "config.d.ts" } diff --git a/plugins/app-backend/api-report-alpha.md b/plugins/app-backend/report-alpha.api.md similarity index 100% rename from plugins/app-backend/api-report-alpha.md rename to plugins/app-backend/report-alpha.api.md diff --git a/plugins/app-backend/api-report.md b/plugins/app-backend/report.api.md similarity index 65% rename from plugins/app-backend/api-report.md rename to plugins/app-backend/report.api.md index bb0ebb67db..ab36eb95d3 100644 --- a/plugins/app-backend/api-report.md +++ b/plugins/app-backend/report.api.md @@ -30,4 +30,13 @@ export interface RouterOptions { schema?: ConfigSchema; staticFallbackHandler?: express.Handler; } + +// Warnings were encountered during analysis: +// +// src/service/router.d.ts:9:1 - (ae-undocumented) Missing documentation for "RouterOptions". +// src/service/router.d.ts:10:5 - (ae-undocumented) Missing documentation for "config". +// src/service/router.d.ts:11:5 - (ae-undocumented) Missing documentation for "logger". +// src/service/router.d.ts:12:5 - (ae-undocumented) Missing documentation for "auth". +// src/service/router.d.ts:13:5 - (ae-undocumented) Missing documentation for "httpAuth". +// src/service/router.d.ts:61:1 - (ae-undocumented) Missing documentation for "createRouter". ``` diff --git a/plugins/app-backend/src/lib/config/injectConfigIntoHtml.test.ts b/plugins/app-backend/src/lib/config/injectConfigIntoHtml.test.ts index f4f2655f1c..56c916fbb9 100644 --- a/plugins/app-backend/src/lib/config/injectConfigIntoHtml.test.ts +++ b/plugins/app-backend/src/lib/config/injectConfigIntoHtml.test.ts @@ -67,6 +67,35 @@ describe('injectConfigIntoHtml', () => { } ] +`, + }); + }); + + it('should trim script tag endings from injected config', async () => { + mockDir.setContent({ + 'index.html.tmpl': '', + }); + await injectConfigIntoHtml({ + ...baseOptions, + appConfigs: [ + { + context: 'mock', + data: { x: "" }, + }, + ], + }); + expect(mockDir.content()).toMatchObject({ + 'index.html': ` + `, }); }); diff --git a/plugins/app-backend/src/lib/config/injectConfigIntoHtml.ts b/plugins/app-backend/src/lib/config/injectConfigIntoHtml.ts index 604b6a8711..c0c1ca200a 100644 --- a/plugins/app-backend/src/lib/config/injectConfigIntoHtml.ts +++ b/plugins/app-backend/src/lib/config/injectConfigIntoHtml.ts @@ -55,7 +55,14 @@ export async function injectConfigIntoHtml( '', ` `, ); diff --git a/plugins/app-backend/src/service/router.ts b/plugins/app-backend/src/service/router.ts index cd1c0e4ee2..a49a2918c7 100644 --- a/plugins/app-backend/src/service/router.ts +++ b/plugins/app-backend/src/service/router.ts @@ -42,7 +42,7 @@ import { HttpAuthService, LoggerService, } from '@backstage/backend-plugin-api'; -import { AuthenticationError } from '@backstage/errors'; +import { AuthenticationError, InputError } from '@backstage/errors'; import { injectConfig, readFrontendConfig } from '../lib/config'; // express uses mime v1 while we only have types for mime v2 @@ -220,7 +220,9 @@ export async function createRouter( req.method = 'GET'; next('router'); } else { - throw new Error('Invalid POST request to /'); + throw new InputError( + 'Invalid POST request to app-backend wildcard endpoint', + ); } }, ); diff --git a/plugins/app-node/CHANGELOG.md b/plugins/app-node/CHANGELOG.md index feae31a8ea..c90ba12e47 100644 --- a/plugins/app-node/CHANGELOG.md +++ b/plugins/app-node/CHANGELOG.md @@ -1,5 +1,30 @@ # @backstage/plugin-app-node +## 0.1.26-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config-loader@1.9.1 + +## 0.1.25 + +### Patch Changes + +- d3f79d1: Fixing dependency metadata with the new `@backstage/plugin-app` package +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/config-loader@1.9.1 + +## 0.1.25-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/config-loader@1.9.1-next.0 + ## 0.1.25-next.1 ### Patch Changes diff --git a/plugins/app-node/package.json b/plugins/app-node/package.json index 33af5bfba1..7c18c414d3 100644 --- a/plugins/app-node/package.json +++ b/plugins/app-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-app-node", - "version": "0.1.25-next.1", + "version": "0.1.26-next.0", "description": "Node.js library for the app plugin", "backstage": { "role": "node-library", diff --git a/plugins/app-node/api-report.md b/plugins/app-node/report.api.md similarity index 100% rename from plugins/app-node/api-report.md rename to plugins/app-node/report.api.md diff --git a/plugins/app-visualizer/CHANGELOG.md b/plugins/app-visualizer/CHANGELOG.md index 2afc4a1651..25eb942d52 100644 --- a/plugins/app-visualizer/CHANGELOG.md +++ b/plugins/app-visualizer/CHANGELOG.md @@ -1,5 +1,42 @@ # @backstage/plugin-app-visualizer +## 0.1.11-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/frontend-plugin-api@0.9.0-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + +## 0.1.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + +## 0.1.10 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/frontend-plugin-api@0.8.0 + - @backstage/core-plugin-api@1.9.4 + +## 0.1.10-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/frontend-plugin-api@0.8.0-next.2 + ## 0.1.10-next.1 ### Patch Changes diff --git a/plugins/app-visualizer/package.json b/plugins/app-visualizer/package.json index 3e24482eda..a23ca46189 100644 --- a/plugins/app-visualizer/package.json +++ b/plugins/app-visualizer/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-app-visualizer", - "version": "0.1.10-next.1", + "version": "0.1.11-next.1", "description": "Visualizes the Backstage app structure", "backstage": { "role": "frontend-plugin", @@ -38,15 +38,24 @@ "@backstage/core-plugin-api": "workspace:^", "@backstage/frontend-plugin-api": "workspace:^", "@material-ui/core": "^4.12.2", - "@material-ui/icons": "^4.9.1", - "@types/react": "^16.13.1 || ^17.0.0" + "@material-ui/icons": "^4.9.1" }, "devDependencies": { - "@backstage/cli": "workspace:^" + "@backstage/cli": "workspace:^", + "@types/react": "^18.0.0", + "react": "^18.0.2", + "react-dom": "^18.0.2", + "react-router-dom": "^6.3.0" }, "peerDependencies": { + "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } } diff --git a/plugins/app-visualizer/api-report.md b/plugins/app-visualizer/report.api.md similarity index 81% rename from plugins/app-visualizer/api-report.md rename to plugins/app-visualizer/report.api.md index e542674845..15f7384c42 100644 --- a/plugins/app-visualizer/api-report.md +++ b/plugins/app-visualizer/report.api.md @@ -18,7 +18,6 @@ const visualizerPlugin: FrontendPlugin< { 'page:app-visualizer': ExtensionDefinition<{ kind: 'page'; - namespace: undefined; name: undefined; config: { path: string | undefined; @@ -41,10 +40,14 @@ const visualizerPlugin: FrontendPlugin< } >; inputs: {}; + params: { + defaultPath: string; + loader: () => Promise; + routeRef?: RouteRef | undefined; + }; }>; 'nav-item:app-visualizer': ExtensionDefinition<{ kind: 'nav-item'; - namespace: undefined; name: undefined; config: {}; configInput: {}; @@ -58,10 +61,19 @@ const visualizerPlugin: FrontendPlugin< {} >; inputs: {}; + params: { + title: string; + icon: IconComponent; + routeRef: RouteRef; + }; }>; } >; export default visualizerPlugin; +// Warnings were encountered during analysis: +// +// src/plugin.d.ts:20:22 - (ae-undocumented) Missing documentation for "visualizerPlugin". + // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/app/CHANGELOG.md b/plugins/app/CHANGELOG.md index 2ff8607a13..ed72d7d1bc 100644 --- a/plugins/app/CHANGELOG.md +++ b/plugins/app/CHANGELOG.md @@ -1,5 +1,87 @@ # @backstage/plugin-app +## 0.1.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/frontend-plugin-api@0.9.0-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/plugin-permission-react@0.4.27-next.1 + - @backstage/theme@0.5.8-next.0 + +## 0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/theme@0.5.7 + - @backstage/plugin-permission-react@0.4.27-next.0 + +## 0.1.0 + +### Minor Changes + +- 2bb9517: Introduce the `@backstage/plugin-app` package to hold all of the built-in extensions for easy consumption and overriding. + +### Patch Changes + +- 52f9c5a: Deprecated the `namespace` option for `createExtensionBlueprint` and `createExtension`, these are no longer required and will default to the `pluginId` instead. + + You can migrate some of your extensions that use `createExtensionOverrides` to using `createFrontendModule` instead and providing a `pluginId` there. + + ```ts + // Before + createExtensionOverrides({ + extensions: [ + createExtension({ + name: 'my-extension', + namespace: 'my-namespace', + kind: 'test', + ... + }) + ], + }); + + // After + createFrontendModule({ + pluginId: 'my-namespace', + extensions: [ + createExtension({ + name: 'my-extension', + kind: 'test', + ... + }) + ], + }); + ``` + +- 57bf6ae: Fix issue with `AlertDisplay` and other components defined with `AppRootElementBlueprint` not being rendered when at the `SignInWrapper` +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/frontend-plugin-api@0.8.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/theme@0.5.7 + - @backstage/plugin-permission-react@0.4.26 + +## 0.1.0-next.2 + +### Patch Changes + +- 57bf6ae: Fix issue with `AlertDisplay` and other components defined with `AppRootElementBlueprint` not being rendered when at the `SignInWrapper` +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/frontend-plugin-api@0.8.0-next.2 + - @backstage/theme@0.5.7-next.0 + - @backstage/plugin-permission-react@0.4.26-next.0 + ## 0.1.0-next.1 ### Patch Changes diff --git a/plugins/app/package.json b/plugins/app/package.json index 5912cc3781..e135863867 100644 --- a/plugins/app/package.json +++ b/plugins/app/package.json @@ -1,9 +1,15 @@ { "name": "@backstage/plugin-app", - "version": "0.1.0-next.1", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "version": "0.1.1-next.1", + "backstage": { + "role": "frontend-plugin", + "pluginId": "app", + "pluginPackages": [ + "@backstage/plugin-app", + "@backstage/plugin-app-backend", + "@backstage/plugin-app-node" + ] + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", @@ -14,24 +20,21 @@ "url": "https://github.com/backstage/backstage", "directory": "plugins/app" }, - "backstage": { - "role": "frontend-plugin", - "pluginId": "app", - "pluginPackages": [ - "@backstage/plugin-app", - "@backstage/plugin-app-backend", - "@backstage/plugin-app-node" - ] - }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "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", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/core-components": "workspace:^", @@ -42,24 +45,30 @@ "@material-ui/core": "^4.9.13", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "^4.0.0-alpha.61", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/dev-utils": "workspace:^", "@backstage/frontend-test-utils": "workspace:^", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^15.0.0", + "@testing-library/react": "^16.0.0", "@testing-library/user-event": "^14.0.0", + "@types/react": "^18.0.0", "msw": "^1.0.0", - "react": "^16.13.1 || ^17.0.0 || ^18.0.0" + "react": "^18.0.2", + "react-dom": "^18.0.2", + "react-router-dom": "^6.3.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } } diff --git a/plugins/app/api-report.md b/plugins/app/report.api.md similarity index 89% rename from plugins/app/api-report.md rename to plugins/app/report.api.md index 6f2e6e0463..1ff398a346 100644 --- a/plugins/app/api-report.md +++ b/plugins/app/report.api.md @@ -46,13 +46,12 @@ const appPlugin: FrontendPlugin< } >; }; + params: never; kind: undefined; - namespace: undefined; name: undefined; }>; 'api:app/app-language': ExtensionDefinition<{ kind: 'api'; - namespace: undefined; name: 'app-language'; config: {}; configInput: {}; @@ -62,6 +61,9 @@ const appPlugin: FrontendPlugin< {} >; inputs: {}; + params: { + factory: AnyApiFactory; + }; }>; 'app/layout': ExtensionDefinition<{ config: {}; @@ -87,8 +89,8 @@ const appPlugin: FrontendPlugin< } >; }; + params: never; kind: undefined; - namespace: undefined; name: 'layout'; }>; 'app/nav': ExtensionDefinition<{ @@ -130,8 +132,8 @@ const appPlugin: FrontendPlugin< } >; }; + params: never; kind: undefined; - namespace: undefined; name: 'nav'; }>; 'app/root': ExtensionDefinition<{ @@ -195,8 +197,8 @@ const appPlugin: FrontendPlugin< } >; }; + params: never; kind: undefined; - namespace: undefined; name: 'root'; }>; 'app/routes': ExtensionDefinition<{ @@ -224,8 +226,8 @@ const appPlugin: FrontendPlugin< } >; }; + params: never; kind: undefined; - namespace: undefined; name: 'routes'; }>; 'api:app/app-theme': ExtensionDefinition<{ @@ -246,26 +248,32 @@ const appPlugin: FrontendPlugin< >; }; kind: 'api'; - namespace: undefined; name: 'app-theme'; + params: { + factory: AnyApiFactory; + }; }>; 'theme:app/light': ExtensionDefinition<{ kind: 'theme'; - namespace: undefined; name: 'light'; config: {}; configInput: {}; output: ConfigurableExtensionDataRef; inputs: {}; + params: { + theme: AppTheme; + }; }>; 'theme:app/dark': ExtensionDefinition<{ kind: 'theme'; - namespace: undefined; name: 'dark'; config: {}; configInput: {}; output: ConfigurableExtensionDataRef; inputs: {}; + params: { + theme: AppTheme; + }; }>; 'api:app/components': ExtensionDefinition<{ config: {}; @@ -292,8 +300,10 @@ const appPlugin: FrontendPlugin< >; }; kind: 'api'; - namespace: undefined; name: 'components'; + params: { + factory: AnyApiFactory; + }; }>; 'api:app/icons': ExtensionDefinition<{ config: {}; @@ -319,12 +329,13 @@ const appPlugin: FrontendPlugin< >; }; kind: 'api'; - namespace: undefined; name: 'icons'; + params: { + factory: AnyApiFactory; + }; }>; 'api:app/feature-flags': ExtensionDefinition<{ kind: 'api'; - namespace: undefined; name: 'feature-flags'; config: {}; configInput: {}; @@ -334,6 +345,9 @@ const appPlugin: FrontendPlugin< {} >; inputs: {}; + params: { + factory: AnyApiFactory; + }; }>; 'api:app/translations': ExtensionDefinition<{ config: {}; @@ -364,12 +378,13 @@ const appPlugin: FrontendPlugin< >; }; kind: 'api'; - namespace: undefined; name: 'translations'; + params: { + factory: AnyApiFactory; + }; }>; 'app-root-element:app/oauth-request-dialog': ExtensionDefinition<{ kind: 'app-root-element'; - namespace: undefined; name: 'oauth-request-dialog'; config: {}; configInput: {}; @@ -379,6 +394,9 @@ const appPlugin: FrontendPlugin< {} >; inputs: {}; + params: { + element: JSX.Element | (() => JSX.Element); + }; }>; 'app-root-element:app/alert-display': ExtensionDefinition<{ config: { @@ -412,12 +430,13 @@ const appPlugin: FrontendPlugin< >; }; kind: 'app-root-element'; - namespace: undefined; name: 'alert-display'; + params: { + element: JSX.Element | (() => JSX.Element); + }; }>; 'api:app/discovery': ExtensionDefinition<{ kind: 'api'; - namespace: undefined; name: 'discovery'; config: {}; configInput: {}; @@ -427,10 +446,12 @@ const appPlugin: FrontendPlugin< {} >; inputs: {}; + params: { + factory: AnyApiFactory; + }; }>; 'api:app/alert': ExtensionDefinition<{ kind: 'api'; - namespace: undefined; name: 'alert'; config: {}; configInput: {}; @@ -440,10 +461,12 @@ const appPlugin: FrontendPlugin< {} >; inputs: {}; + params: { + factory: AnyApiFactory; + }; }>; 'api:app/analytics': ExtensionDefinition<{ kind: 'api'; - namespace: undefined; name: 'analytics'; config: {}; configInput: {}; @@ -453,10 +476,12 @@ const appPlugin: FrontendPlugin< {} >; inputs: {}; + params: { + factory: AnyApiFactory; + }; }>; 'api:app/error': ExtensionDefinition<{ kind: 'api'; - namespace: undefined; name: 'error'; config: {}; configInput: {}; @@ -466,10 +491,12 @@ const appPlugin: FrontendPlugin< {} >; inputs: {}; + params: { + factory: AnyApiFactory; + }; }>; 'api:app/storage': ExtensionDefinition<{ kind: 'api'; - namespace: undefined; name: 'storage'; config: {}; configInput: {}; @@ -479,10 +506,12 @@ const appPlugin: FrontendPlugin< {} >; inputs: {}; + params: { + factory: AnyApiFactory; + }; }>; 'api:app/fetch': ExtensionDefinition<{ kind: 'api'; - namespace: undefined; name: 'fetch'; config: {}; configInput: {}; @@ -492,10 +521,12 @@ const appPlugin: FrontendPlugin< {} >; inputs: {}; + params: { + factory: AnyApiFactory; + }; }>; 'api:app/oauth-request': ExtensionDefinition<{ kind: 'api'; - namespace: undefined; name: 'oauth-request'; config: {}; configInput: {}; @@ -505,10 +536,12 @@ const appPlugin: FrontendPlugin< {} >; inputs: {}; + params: { + factory: AnyApiFactory; + }; }>; 'api:app/google-auth': ExtensionDefinition<{ kind: 'api'; - namespace: undefined; name: 'google-auth'; config: {}; configInput: {}; @@ -518,10 +551,12 @@ const appPlugin: FrontendPlugin< {} >; inputs: {}; + params: { + factory: AnyApiFactory; + }; }>; 'api:app/microsoft-auth': ExtensionDefinition<{ kind: 'api'; - namespace: undefined; name: 'microsoft-auth'; config: {}; configInput: {}; @@ -531,10 +566,12 @@ const appPlugin: FrontendPlugin< {} >; inputs: {}; + params: { + factory: AnyApiFactory; + }; }>; 'api:app/github-auth': ExtensionDefinition<{ kind: 'api'; - namespace: undefined; name: 'github-auth'; config: {}; configInput: {}; @@ -544,10 +581,12 @@ const appPlugin: FrontendPlugin< {} >; inputs: {}; + params: { + factory: AnyApiFactory; + }; }>; 'api:app/okta-auth': ExtensionDefinition<{ kind: 'api'; - namespace: undefined; name: 'okta-auth'; config: {}; configInput: {}; @@ -557,10 +596,12 @@ const appPlugin: FrontendPlugin< {} >; inputs: {}; + params: { + factory: AnyApiFactory; + }; }>; 'api:app/gitlab-auth': ExtensionDefinition<{ kind: 'api'; - namespace: undefined; name: 'gitlab-auth'; config: {}; configInput: {}; @@ -570,10 +611,12 @@ const appPlugin: FrontendPlugin< {} >; inputs: {}; + params: { + factory: AnyApiFactory; + }; }>; 'api:app/onelogin-auth': ExtensionDefinition<{ kind: 'api'; - namespace: undefined; name: 'onelogin-auth'; config: {}; configInput: {}; @@ -583,10 +626,12 @@ const appPlugin: FrontendPlugin< {} >; inputs: {}; + params: { + factory: AnyApiFactory; + }; }>; 'api:app/bitbucket-auth': ExtensionDefinition<{ kind: 'api'; - namespace: undefined; name: 'bitbucket-auth'; config: {}; configInput: {}; @@ -596,10 +641,12 @@ const appPlugin: FrontendPlugin< {} >; inputs: {}; + params: { + factory: AnyApiFactory; + }; }>; 'api:app/bitbucket-server-auth': ExtensionDefinition<{ kind: 'api'; - namespace: undefined; name: 'bitbucket-server-auth'; config: {}; configInput: {}; @@ -609,10 +656,12 @@ const appPlugin: FrontendPlugin< {} >; inputs: {}; + params: { + factory: AnyApiFactory; + }; }>; 'api:app/atlassian-auth': ExtensionDefinition<{ kind: 'api'; - namespace: undefined; name: 'atlassian-auth'; config: {}; configInput: {}; @@ -622,10 +671,12 @@ const appPlugin: FrontendPlugin< {} >; inputs: {}; + params: { + factory: AnyApiFactory; + }; }>; 'api:app/vmware-cloud-auth': ExtensionDefinition<{ kind: 'api'; - namespace: undefined; name: 'vmware-cloud-auth'; config: {}; configInput: {}; @@ -635,10 +686,12 @@ const appPlugin: FrontendPlugin< {} >; inputs: {}; + params: { + factory: AnyApiFactory; + }; }>; 'api:app/permission': ExtensionDefinition<{ kind: 'api'; - namespace: undefined; name: 'permission'; config: {}; configInput: {}; @@ -648,10 +701,17 @@ const appPlugin: FrontendPlugin< {} >; inputs: {}; + params: { + factory: AnyApiFactory; + }; }>; } >; export default appPlugin; +// Warnings were encountered during analysis: +// +// src/plugin.d.ts:3:22 - (ae-undocumented) Missing documentation for "appPlugin". + // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/app/src/defaultApis.ts b/plugins/app/src/defaultApis.ts index fd46ecf596..85c89a6278 100644 --- a/plugins/app/src/defaultApis.ts +++ b/plugins/app/src/defaultApis.ts @@ -318,6 +318,7 @@ export const apis = [ discoveryApi, oauthRequestApi, defaultScopes: ['REPO_READ'], + environment: configApi.getOptionalString('auth.environment'), }), }), }, diff --git a/plugins/app/src/extensions/AppRoot.tsx b/plugins/app/src/extensions/AppRoot.tsx index 014f9a1354..b973178e3a 100644 --- a/plugins/app/src/extensions/AppRoot.tsx +++ b/plugins/app/src/extensions/AppRoot.tsx @@ -16,7 +16,6 @@ import React, { ComponentType, - Fragment, PropsWithChildren, ReactNode, useState, @@ -95,15 +94,8 @@ export const AppRoot = createExtension({ }); } - let content: React.ReactNode = ( - <> - {inputs.elements.map(el => ( - - {el.get(coreExtensionData.reactElement)} - - ))} - {inputs.children.get(coreExtensionData.reactElement)} - + let content: React.ReactNode = inputs.children.get( + coreExtensionData.reactElement, ); for (const wrapper of inputs.wrappers) { @@ -120,6 +112,9 @@ export const AppRoot = createExtension({ RouterComponent={inputs.router?.get( RouterBlueprint.dataRefs.component, )} + extraElements={inputs.elements?.map(el => + el.get(coreExtensionData.reactElement), + )} > {content} , @@ -187,6 +182,7 @@ export interface AppRouterProps { children?: ReactNode; SignInPageComponent?: ComponentType; RouterComponent?: ComponentType>; + extraElements?: Array; } function DefaultRouter(props: PropsWithChildren<{}>) { @@ -210,6 +206,7 @@ export function AppRouter(props: AppRouterProps) { children, SignInPageComponent, RouterComponent = DefaultRouter, + extraElements = [], } = props; const configApi = useApi(configApiRef); @@ -260,6 +257,7 @@ export function AppRouter(props: AppRouterProps) { return ( + {...extraElements} 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 { OAuthAuthenticator } from '@backstage/plugin-auth-node'; +import { PassportOAuthAuthenticatorHelper } from '@backstage/plugin-auth-node'; +import { PassportProfile } from '@backstage/plugin-auth-node'; + +// @public (undocumented) +export const auth0Authenticator: OAuthAuthenticator< + { + helper: PassportOAuthAuthenticatorHelper; + audience: string | undefined; + connection: string | undefined; + connectionScope: string | undefined; + }, + PassportProfile +>; + +// @public (undocumented) +const authModuleAuth0Provider: BackendFeature; +export default authModuleAuth0Provider; + +// Warnings were encountered during analysis: +// +// src/authenticator.d.ts:3:22 - (ae-undocumented) Missing documentation for "auth0Authenticator". +// src/module.d.ts:2:22 - (ae-undocumented) Missing documentation for "authModuleAuth0Provider". +``` diff --git a/plugins/auth-backend-module-auth0-provider/src/authenticator.ts b/plugins/auth-backend-module-auth0-provider/src/authenticator.ts new file mode 100644 index 0000000000..a042f113f8 --- /dev/null +++ b/plugins/auth-backend-module-auth0-provider/src/authenticator.ts @@ -0,0 +1,116 @@ +/* + * 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 express from 'express'; +import { + createOAuthAuthenticator, + PassportOAuthAuthenticatorHelper, + PassportOAuthDoneCallback, + PassportProfile, +} from '@backstage/plugin-auth-node'; +import { Auth0Strategy } from './strategy'; + +/** @public */ +export const auth0Authenticator = createOAuthAuthenticator({ + defaultProfileTransform: + PassportOAuthAuthenticatorHelper.defaultProfileTransform, + initialize({ callbackUrl, config }) { + const clientID = config.getString('clientId'); + const clientSecret = config.getString('clientSecret'); + const domain = config.getString('domain'); + const audience = config.getOptionalString('audience'); + const connection = config.getOptionalString('connection'); + const connectionScope = config.getOptionalString('connectionScope'); + const callbackURL = config.getOptionalString('callbackUrl') ?? callbackUrl; + // Due to passport-auth0 forcing options.state = true, + // passport-oauth2 requires express-session to be installed + // so that the 'state' parameter of the oauth2 flow can be stored. + // This implementation of StateStore matches the NullStore found within + // passport-oauth2, which is the StateStore implementation used when options.state = false, + // allowing us to avoid using express-session in order to integrate with auth0. + const store = { + store(_req: express.Request, cb: any) { + cb(null, null); + }, + verify(_req: express.Request, _state: string, cb: any) { + cb(null, true); + }, + }; + + const helper = PassportOAuthAuthenticatorHelper.from( + new Auth0Strategy( + { + clientID, + clientSecret, + callbackURL, + domain, + store, + // We need passReqToCallback set to false to get params, but there's + // no matching type signature for that, so instead behold this beauty + passReqToCallback: false as true, + }, + ( + accessToken: string, + refreshToken: string, + params: any, + fullProfile: PassportProfile, + done: PassportOAuthDoneCallback, + ) => { + done( + undefined, + { + fullProfile, + accessToken, + params, + }, + { + refreshToken, + }, + ); + }, + ), + ); + return { helper, audience, connection, connectionScope }; + }, + + async start( + input, + { helper, audience, connection, connectionScope: connection_scope }, + ) { + return helper.start(input, { + accessType: 'offline', + prompt: 'consent', + ...(audience ? { audience } : {}), + ...(connection ? { connection } : {}), + ...(connection_scope ? { connection_scope } : {}), + }); + }, + + async authenticate( + input, + { helper, audience, connection, connectionScope: connection_scope }, + ) { + return helper.authenticate(input, { + ...(audience ? { audience } : {}), + ...(connection ? { connection } : {}), + ...(connection_scope ? { connection_scope } : {}), + }); + }, + + async refresh(input, { helper }) { + return helper.refresh(input); + }, +}); diff --git a/plugins/auth-backend-module-auth0-provider/src/index.ts b/plugins/auth-backend-module-auth0-provider/src/index.ts new file mode 100644 index 0000000000..eb8f4efcbe --- /dev/null +++ b/plugins/auth-backend-module-auth0-provider/src/index.ts @@ -0,0 +1,24 @@ +/* + * 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. + */ + +/** + * The auth0-provider backend module for the auth plugin. + * + * @packageDocumentation + */ + +export { auth0Authenticator } from './authenticator'; +export { authModuleAuth0Provider as default } from './module'; diff --git a/plugins/auth-backend-module-auth0-provider/src/module.test.ts b/plugins/auth-backend-module-auth0-provider/src/module.test.ts new file mode 100644 index 0000000000..630f1dd070 --- /dev/null +++ b/plugins/auth-backend-module-auth0-provider/src/module.test.ts @@ -0,0 +1,90 @@ +/* + * 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 authPlugin from '@backstage/plugin-auth-backend'; +import { authModuleAuth0Provider } from './module'; +import request from 'supertest'; +import { decodeOAuthState } from '@backstage/plugin-auth-node'; + +describe('authModuleAuth0Provider', () => { + it('should start', async () => { + const { server } = await startTestBackend({ + features: [ + authPlugin, + authModuleAuth0Provider, + mockServices.rootConfig.factory({ + data: { + app: { + baseUrl: 'http://localhost:3000', + }, + auth: { + providers: { + auth0: { + development: { + clientId: 'clientId', + clientSecret: 'clientSecret', + domain: 'domain', + connection: 'connection', + connectionScope: 'connectionScope', + }, + }, + }, + session: { + secret: 'secret', + }, + }, + }, + }), + ], + }); + + const agent = request.agent(server); + + const res = await agent.get('/api/auth/auth0/start?env=development'); + + expect(res.status).toEqual(302); + + const nonceCookie = agent.jar.getCookie('auth0-nonce', { + domain: 'localhost', + path: '/api/auth/auth0/handler', + script: false, + secure: false, + }); + expect(nonceCookie).toBeDefined(); + + const startUrl = new URL(res.get('location')); + expect(startUrl.origin).toBe('https://domain'); + expect(startUrl.pathname).toBe('/authorize'); + expect(Object.fromEntries(startUrl.searchParams)).toEqual({ + response_type: 'code', + scope: '', + client_id: 'clientId', + redirect_uri: `http://localhost:${server.port()}/api/auth/auth0/handler/frame`, + prompt: 'consent', + accessType: 'offline', + connection: 'connection', + connection_scope: 'connectionScope', + nonce: expect.any(String), + state: expect.any(String), + }); + + expect(decodeOAuthState(startUrl.searchParams.get('state')!)).toEqual({ + env: 'development', + nonce: decodeURIComponent(nonceCookie.value), + }); + }); +}); diff --git a/plugins/auth-backend-module-auth0-provider/src/module.ts b/plugins/auth-backend-module-auth0-provider/src/module.ts new file mode 100644 index 0000000000..fbdb752780 --- /dev/null +++ b/plugins/auth-backend-module-auth0-provider/src/module.ts @@ -0,0 +1,47 @@ +/* + * 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 { createBackendModule } from '@backstage/backend-plugin-api'; +import { + authProvidersExtensionPoint, + commonSignInResolvers, + createOAuthProviderFactory, +} from '@backstage/plugin-auth-node'; +import { auth0Authenticator } from './authenticator'; + +/** @public */ +export const authModuleAuth0Provider = createBackendModule({ + pluginId: 'auth', + moduleId: 'auth0-provider', + register(reg) { + reg.registerInit({ + deps: { + providers: authProvidersExtensionPoint, + }, + async init({ providers }) { + providers.registerProvider({ + providerId: 'auth0', + factory: createOAuthProviderFactory({ + authenticator: auth0Authenticator, + signInResolverFactories: { + ...commonSignInResolvers, + }, + }), + }); + }, + }); + }, +}); diff --git a/plugins/auth-backend-module-auth0-provider/src/strategy.ts b/plugins/auth-backend-module-auth0-provider/src/strategy.ts new file mode 100644 index 0000000000..039885dddb --- /dev/null +++ b/plugins/auth-backend-module-auth0-provider/src/strategy.ts @@ -0,0 +1,45 @@ +/* + * 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 Auth0InternalStrategy from 'passport-auth0'; +import type { StateStore } from 'passport-oauth2'; + +/** @public */ +export interface Auth0StrategyOptionsWithRequest { + clientID: string; + clientSecret: string; + callbackURL: string; + domain: string; + passReqToCallback: true; + store: StateStore; +} + +/** @public */ +export class Auth0Strategy extends Auth0InternalStrategy { + constructor( + options: Auth0StrategyOptionsWithRequest, + verify: Auth0InternalStrategy.VerifyFunction, + ) { + const optionsWithURLs = { + ...options, + authorizationURL: `https://${options.domain}/authorize`, + tokenURL: `https://${options.domain}/oauth/token`, + userInfoURL: `https://${options.domain}/userinfo`, + apiUrl: `https://${options.domain}/api`, + }; + super(optionsWithURLs, verify); + } +} diff --git a/plugins/auth-backend-module-aws-alb-provider/CHANGELOG.md b/plugins/auth-backend-module-aws-alb-provider/CHANGELOG.md index ef6008aa90..2a25a4df9e 100644 --- a/plugins/auth-backend-module-aws-alb-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-aws-alb-provider/CHANGELOG.md @@ -1,5 +1,48 @@ # @backstage/plugin-auth-backend-module-aws-alb-provider +## 0.2.1-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-auth-backend@0.23.1-next.0 + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/errors@1.2.4 + +## 0.2.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- ecbc47e: Fix a bug where the signer was checked from the payload instead of the header +- 8d1fb8d: Throw correct error when email is missing from the claims +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/plugin-auth-backend@0.23.0 + - @backstage/errors@1.2.4 + +## 0.2.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/plugin-auth-backend@0.23.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/errors@1.2.4 + ## 0.2.0-next.1 ### Patch Changes diff --git a/plugins/auth-backend-module-aws-alb-provider/package.json b/plugins/auth-backend-module-aws-alb-provider/package.json index de5fb31298..c62da2e29e 100644 --- a/plugins/auth-backend-module-aws-alb-provider/package.json +++ b/plugins/auth-backend-module-aws-alb-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-aws-alb-provider", - "version": "0.2.0-next.1", + "version": "0.2.1-next.0", "description": "The aws-alb provider module for the Backstage auth backend.", "backstage": { "role": "backend-plugin-module", @@ -37,7 +37,7 @@ "test": "backstage-cli package test" }, "dependencies": { - "@backstage/backend-common": "workspace:^", + "@backstage/backend-common": "^0.25.0", "@backstage/backend-plugin-api": "workspace:^", "@backstage/errors": "workspace:^", "@backstage/plugin-auth-backend": "workspace:^", diff --git a/plugins/auth-backend-module-aws-alb-provider/api-report.md b/plugins/auth-backend-module-aws-alb-provider/report.api.md similarity index 78% rename from plugins/auth-backend-module-aws-alb-provider/api-report.md rename to plugins/auth-backend-module-aws-alb-provider/report.api.md index b3a9ce4517..c7437a1b9d 100644 --- a/plugins/auth-backend-module-aws-alb-provider/api-report.md +++ b/plugins/auth-backend-module-aws-alb-provider/report.api.md @@ -46,4 +46,10 @@ export namespace awsAlbSignInResolvers { unknown >; } + +// Warnings were encountered during analysis: +// +// src/authenticator.d.ts:6:22 - (ae-undocumented) Missing documentation for "awsAlbAuthenticator". +// src/module.d.ts:2:22 - (ae-undocumented) Missing documentation for "authModuleAwsAlbProvider". +// src/resolvers.d.ts:8:11 - (ae-undocumented) Missing documentation for "emailMatchingUserEntityProfileEmail". ``` diff --git a/plugins/auth-backend-module-azure-easyauth-provider/CHANGELOG.md b/plugins/auth-backend-module-azure-easyauth-provider/CHANGELOG.md index cb1f2da1fb..fcb9779e22 100644 --- a/plugins/auth-backend-module-azure-easyauth-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-azure-easyauth-provider/CHANGELOG.md @@ -1,5 +1,43 @@ # @backstage/plugin-auth-backend-module-azure-easyauth-provider +## 0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/errors@1.2.4 + +## 0.2.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/catalog-model@1.7.0 + - @backstage/errors@1.2.4 + +## 0.2.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/errors@1.2.4 + ## 0.2.0-next.1 ### Patch Changes diff --git a/plugins/auth-backend-module-azure-easyauth-provider/package.json b/plugins/auth-backend-module-azure-easyauth-provider/package.json index 9688d88308..83245bfa68 100644 --- a/plugins/auth-backend-module-azure-easyauth-provider/package.json +++ b/plugins/auth-backend-module-azure-easyauth-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-azure-easyauth-provider", - "version": "0.2.0-next.1", + "version": "0.2.1-next.0", "description": "The azure-easyauth-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-azure-easyauth-provider/api-report.md b/plugins/auth-backend-module-azure-easyauth-provider/report.api.md similarity index 66% rename from plugins/auth-backend-module-azure-easyauth-provider/api-report.md rename to plugins/auth-backend-module-azure-easyauth-provider/report.api.md index 9d337e3f34..3292654787 100644 --- a/plugins/auth-backend-module-azure-easyauth-provider/api-report.md +++ b/plugins/auth-backend-module-azure-easyauth-provider/report.api.md @@ -36,5 +36,13 @@ export namespace azureEasyAuthSignInResolvers { >; } +// Warnings were encountered during analysis: +// +// src/authenticator.d.ts:5:22 - (ae-undocumented) Missing documentation for "azureEasyAuthAuthenticator". +// src/module.d.ts:2:22 - (ae-undocumented) Missing documentation for "authModuleAzureEasyAuthProvider". +// src/resolvers.d.ts:3:1 - (ae-undocumented) Missing documentation for "azureEasyAuthSignInResolvers". +// src/resolvers.d.ts:4:11 - (ae-undocumented) Missing documentation for "idMatchingUserEntityAnnotation". +// src/types.d.ts:3:1 - (ae-undocumented) Missing documentation for "AzureEasyAuthResult". + // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/auth-backend-module-bitbucket-provider/CHANGELOG.md b/plugins/auth-backend-module-bitbucket-provider/CHANGELOG.md index 92484e03fe..521f5dfe93 100644 --- a/plugins/auth-backend-module-bitbucket-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-bitbucket-provider/CHANGELOG.md @@ -1,5 +1,39 @@ # @backstage/plugin-auth-backend-module-bitbucket-provider +## 0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + +## 0.2.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + +## 0.2.0-next.2 + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + ## 0.2.0-next.1 ### Patch Changes diff --git a/plugins/auth-backend-module-bitbucket-provider/package.json b/plugins/auth-backend-module-bitbucket-provider/package.json index e2385ca6ed..42dcb65ed9 100644 --- a/plugins/auth-backend-module-bitbucket-provider/package.json +++ b/plugins/auth-backend-module-bitbucket-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-bitbucket-provider", - "version": "0.2.0-next.1", + "version": "0.2.1-next.0", "description": "The bitbucket-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", @@ -45,7 +45,7 @@ "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "@backstage/plugin-auth-backend": "workspace:^", - "supertest": "^6.3.3" + "supertest": "^7.0.0" }, "configSchema": "config.d.ts" } diff --git a/plugins/auth-backend-module-bitbucket-provider/api-report.md b/plugins/auth-backend-module-bitbucket-provider/report.api.md similarity index 82% rename from plugins/auth-backend-module-bitbucket-provider/api-report.md rename to plugins/auth-backend-module-bitbucket-provider/report.api.md index ceb4141fd9..210a292050 100644 --- a/plugins/auth-backend-module-bitbucket-provider/api-report.md +++ b/plugins/auth-backend-module-bitbucket-provider/report.api.md @@ -31,4 +31,9 @@ export namespace bitbucketSignInResolvers { unknown >; } + +// Warnings were encountered during analysis: +// +// src/authenticator.d.ts:3:22 - (ae-undocumented) Missing documentation for "bitbucketAuthenticator". +// src/module.d.ts:2:22 - (ae-undocumented) Missing documentation for "authModuleBitbucketProvider". ``` diff --git a/plugins/auth-backend-module-bitbucket-server-provider/.eslintrc.js b/plugins/auth-backend-module-bitbucket-server-provider/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/auth-backend-module-bitbucket-server-provider/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/auth-backend-module-bitbucket-server-provider/CHANGELOG.md b/plugins/auth-backend-module-bitbucket-server-provider/CHANGELOG.md new file mode 100644 index 0000000000..92daf8bb1c --- /dev/null +++ b/plugins/auth-backend-module-bitbucket-server-provider/CHANGELOG.md @@ -0,0 +1,34 @@ +# @backstage/plugin-auth-backend-module-bitbucket-server-provider + +## 0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + +## 0.1.0 + +### Minor Changes + +- 527d973: New module for `@backstage/plugin-auth-backend` that adds a `Bitbucket Server` auth provider. + +### Patch Changes + +- 0a3a13e: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + +## 0.1.0-next.0 + +### Minor Changes + +- 527d973: New module for `@backstage/plugin-auth-backend` that adds a `Bitbucket Server` auth provider. + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 diff --git a/plugins/auth-backend-module-bitbucket-server-provider/README.md b/plugins/auth-backend-module-bitbucket-server-provider/README.md new file mode 100644 index 0000000000..d3498ffc1b --- /dev/null +++ b/plugins/auth-backend-module-bitbucket-server-provider/README.md @@ -0,0 +1,8 @@ +# Auth Module: Bitbucket Server Provider + +This module provides an Bitbucket Server auth provider implementation for `@backstage/plugin-auth-backend`. + +## Links + +- [Repository](https://gitlab.com/backstage/backstage/tree/master/plugins/auth-backend-module-bitbucket-server-provider) +- [Backstage Project Homepage](https://backstage.io) diff --git a/plugins/auth-backend-module-bitbucket-server-provider/catalog-info.yaml b/plugins/auth-backend-module-bitbucket-server-provider/catalog-info.yaml new file mode 100644 index 0000000000..bcb659b1c2 --- /dev/null +++ b/plugins/auth-backend-module-bitbucket-server-provider/catalog-info.yaml @@ -0,0 +1,10 @@ +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: backstage-plugin-auth-backend-module-bitbucket-server-provider + title: '@backstage/plugin-auth-backend-module-bitbucket-server-provider' + description: The bitbucket-server-provider backend module for the auth plugin. +spec: + lifecycle: experimental + type: backstage-backend-plugin-module + owner: maintainers diff --git a/plugins/auth-backend-module-bitbucket-server-provider/config.d.ts b/plugins/auth-backend-module-bitbucket-server-provider/config.d.ts new file mode 100644 index 0000000000..ee924f47f0 --- /dev/null +++ b/plugins/auth-backend-module-bitbucket-server-provider/config.d.ts @@ -0,0 +1,34 @@ +/* + * 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. + */ + +export interface Config { + auth?: { + providers?: { + /** @visibility frontend */ + bitbucketServer?: { + [authEnv: string]: { + clientId: string; + /** + * @visibility secret + */ + clientSecret: string; + host: string; + callbackUrl?: string; + }; + }; + }; + }; +} diff --git a/plugins/auth-backend-module-bitbucket-server-provider/dev/index.ts b/plugins/auth-backend-module-bitbucket-server-provider/dev/index.ts new file mode 100644 index 0000000000..b52bbf830b --- /dev/null +++ b/plugins/auth-backend-module-bitbucket-server-provider/dev/index.ts @@ -0,0 +1,26 @@ +/* + * 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 { createBackend } from '@backstage/backend-defaults'; +import authPlugin from '@backstage/plugin-auth-backend'; +import authModuleBitbucketServerProvider from '../src'; + +const backend = createBackend(); + +backend.add(authPlugin); +backend.add(authModuleBitbucketServerProvider); + +backend.start(); diff --git a/plugins/auth-backend-module-bitbucket-server-provider/package.json b/plugins/auth-backend-module-bitbucket-server-provider/package.json new file mode 100644 index 0000000000..d18a9b0111 --- /dev/null +++ b/plugins/auth-backend-module-bitbucket-server-provider/package.json @@ -0,0 +1,52 @@ +{ + "name": "@backstage/plugin-auth-backend-module-bitbucket-server-provider", + "version": "0.1.1-next.0", + "description": "The bitbucket-server-provider backend module for the auth plugin.", + "backstage": { + "role": "backend-plugin-module", + "pluginId": "auth", + "pluginPackage": "@backstage/plugin-auth-backend" + }, + "publishConfig": { + "access": "public", + "main": "dist/index.cjs.js", + "types": "dist/index.d.ts" + }, + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/auth-backend-module-bitbucket-server-provider" + }, + "license": "Apache-2.0", + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist", + "config.d.ts" + ], + "scripts": { + "build": "backstage-cli package build", + "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" + }, + "dependencies": { + "@backstage/backend-plugin-api": "workspace:^", + "@backstage/plugin-auth-node": "workspace:^", + "node-fetch": "^2.7.0", + "passport": "^0.7.0", + "passport-oauth2": "^1.6.1" + }, + "devDependencies": { + "@backstage/backend-defaults": "workspace:^", + "@backstage/backend-test-utils": "workspace:^", + "@backstage/cli": "workspace:^", + "@backstage/plugin-auth-backend": "workspace:^", + "@types/passport-oauth2": "^1.4.15", + "supertest": "^7.0.0" + }, + "configSchema": "config.d.ts" +} diff --git a/plugins/auth-backend-module-bitbucket-server-provider/report.api.md b/plugins/auth-backend-module-bitbucket-server-provider/report.api.md new file mode 100644 index 0000000000..371873027a --- /dev/null +++ b/plugins/auth-backend-module-bitbucket-server-provider/report.api.md @@ -0,0 +1,38 @@ +## API Report File for "@backstage/plugin-auth-backend-module-bitbucket-server-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 { OAuthAuthenticator } from '@backstage/plugin-auth-node'; +import { OAuthAuthenticatorResult } from '@backstage/plugin-auth-node'; +import { PassportOAuthAuthenticatorHelper } from '@backstage/plugin-auth-node'; +import { PassportProfile } from '@backstage/plugin-auth-node'; +import { SignInResolverFactory } from '@backstage/plugin-auth-node'; + +// @public (undocumented) +const authModuleBitbucketServerProvider: BackendFeature; +export default authModuleBitbucketServerProvider; + +// @public (undocumented) +export const bitbucketServerAuthenticator: OAuthAuthenticator< + { + helper: PassportOAuthAuthenticatorHelper; + host: string; + }, + PassportProfile +>; + +// @public +export namespace bitbucketServerSignInResolvers { + const emailMatchingUserEntityProfileEmail: SignInResolverFactory< + OAuthAuthenticatorResult, + unknown + >; +} + +// Warnings were encountered during analysis: +// +// src/authenticator.d.ts:3:22 - (ae-undocumented) Missing documentation for "bitbucketServerAuthenticator". +// src/module.d.ts:2:22 - (ae-undocumented) Missing documentation for "authModuleBitbucketServerProvider". +``` diff --git a/plugins/auth-backend-module-bitbucket-server-provider/src/authenticator.ts b/plugins/auth-backend-module-bitbucket-server-provider/src/authenticator.ts new file mode 100644 index 0000000000..052100cd40 --- /dev/null +++ b/plugins/auth-backend-module-bitbucket-server-provider/src/authenticator.ts @@ -0,0 +1,93 @@ +/* + * 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 { Strategy as OAuth2Strategy, VerifyCallback } from 'passport-oauth2'; +import { + createOAuthAuthenticator, + PassportOAuthAuthenticatorHelper, + PassportProfile, +} from '@backstage/plugin-auth-node'; +import { fetchProfile } from './helpers'; + +/** @public */ +export const bitbucketServerAuthenticator = createOAuthAuthenticator({ + defaultProfileTransform: + PassportOAuthAuthenticatorHelper.defaultProfileTransform, + initialize({ callbackUrl, config }) { + const clientID = config.getString('clientId'); + const clientSecret = config.getString('clientSecret'); + const host = config.getString('host'); + const callbackURL = config.getOptionalString('callbackUrl') ?? callbackUrl; + + const helper = PassportOAuthAuthenticatorHelper.from( + new OAuth2Strategy( + { + clientID, + clientSecret, + callbackURL, + authorizationURL: `https://${host}/rest/oauth2/latest/authorize`, + tokenURL: `https://${host}/rest/oauth2/latest/token`, + }, + ( + accessToken: string, + refreshToken: string, + params: any, + fullProfile: PassportProfile, + done: VerifyCallback, + ) => { + done( + undefined, + { fullProfile, params, accessToken }, + { refreshToken }, + ); + }, + ), + ); + + return { helper, host }; + }, + + async start(input, { helper }) { + return helper.start(input, { + accessType: 'offline', + prompt: 'consent', + }); + }, + + async authenticate(input, { helper, host }) { + const result = await helper.authenticate(input); + + // The OAuth2 strategy does not return a user profile, so we fetch it manually + const fullProfile = await fetchProfile({ + host, + accessToken: result.session.accessToken, + }); + + return { ...result, fullProfile }; + }, + + async refresh(input, { helper, host }) { + const result = await helper.refresh(input); + + // The OAuth2 strategy does not return a user profile, so we fetch it manually + const fullProfile = await fetchProfile({ + host, + accessToken: result.session.accessToken, + }); + + return { ...result, fullProfile }; + }, +}); diff --git a/plugins/auth-backend-module-bitbucket-server-provider/src/helpers.ts b/plugins/auth-backend-module-bitbucket-server-provider/src/helpers.ts new file mode 100644 index 0000000000..fc16253b27 --- /dev/null +++ b/plugins/auth-backend-module-bitbucket-server-provider/src/helpers.ts @@ -0,0 +1,83 @@ +/* + * 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 fetch from 'node-fetch'; +import { PassportProfile } from '@backstage/plugin-auth-node'; + +export async function fetchProfile(options: { + host: string; + accessToken: string; +}): Promise { + const { host, accessToken } = options; + // Get current user name + let whoAmIResponse; + try { + whoAmIResponse = await fetch( + `https://${host}/plugins/servlet/applinks/whoami`, + { + headers: { + Authorization: `Bearer ${accessToken}`, + }, + }, + ); + } catch (e) { + throw new Error(`Failed to retrieve the username of the logged in user`); + } + + // A response.ok check here would be worthless as the Bitbucket API always returns 200 OK for this call + const username = whoAmIResponse.headers.get('X-Ausername'); + if (!username) { + throw new Error(`Failed to retrieve the username of the logged in user`); + } + + let userResponse; + try { + userResponse = await fetch( + `https://${host}/rest/api/latest/users/${username}?avatarSize=256`, + { + headers: { + Authorization: `Bearer ${accessToken}`, + }, + }, + ); + } catch (e) { + throw new Error(`Failed to retrieve the user '${username}'`); + } + + if (!userResponse.ok) { + throw new Error(`Failed to retrieve the user '${username}'`); + } + + const user = await userResponse.json(); + + const passportProfile = { + provider: 'bitbucketServer', + id: user.id.toString(), + displayName: user.displayName, + username: user.name, + emails: [ + { + value: user.emailAddress, + }, + ], + } as PassportProfile; + + if (user.avatarUrl) { + passportProfile.photos = [{ value: `https://${host}${user.avatarUrl}` }]; + } + + return passportProfile; +} diff --git a/plugins/auth-backend-module-bitbucket-server-provider/src/index.ts b/plugins/auth-backend-module-bitbucket-server-provider/src/index.ts new file mode 100644 index 0000000000..0d32abfe22 --- /dev/null +++ b/plugins/auth-backend-module-bitbucket-server-provider/src/index.ts @@ -0,0 +1,25 @@ +/* + * 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. + */ + +/** + * The bitbucket-server-provider backend module for the auth plugin. + * + * @packageDocumentation + */ + +export { bitbucketServerAuthenticator } from './authenticator'; +export { authModuleBitbucketServerProvider as default } from './module'; +export { bitbucketServerSignInResolvers } from './resolvers'; diff --git a/plugins/auth-backend-module-bitbucket-server-provider/src/module.test.ts b/plugins/auth-backend-module-bitbucket-server-provider/src/module.test.ts new file mode 100644 index 0000000000..ec75df92f8 --- /dev/null +++ b/plugins/auth-backend-module-bitbucket-server-provider/src/module.test.ts @@ -0,0 +1,81 @@ +/* + * 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 authPlugin from '@backstage/plugin-auth-backend'; +import { decodeOAuthState } from '@backstage/plugin-auth-node'; +import { mockServices, startTestBackend } from '@backstage/backend-test-utils'; +import { authModuleBitbucketServerProvider } from './module'; +import request from 'supertest'; + +describe('authModuleBitbucketServerProvider', () => { + it('should start', async () => { + const { server } = await startTestBackend({ + features: [ + authPlugin, + authModuleBitbucketServerProvider, + mockServices.rootConfig.factory({ + data: { + app: { + baseUrl: 'http://localhost:3000', + }, + auth: { + providers: { + bitbucketServer: { + development: { + clientId: 'cliendId', + clientSecret: 'clientSecret', + host: 'bitbucket.org', + }, + }, + }, + }, + }, + }), + ], + }); + + const agent = request.agent(server); + + const res = await agent.get( + '/api/auth/bitbucketServer/start?env=development', + ); + + expect(res.status).toEqual(302); + + const nonceCookie = agent.jar.getCookie('bitbucketServer-nonce', { + domain: 'localhost', + path: '/api/auth/bitbucketServer/handler', + script: false, + secure: false, + }); + expect(nonceCookie).toBeDefined(); + + const startUrl = new URL(res.get('location')); + expect(startUrl.origin).toBe('https://bitbucket.org'); + expect(startUrl.pathname).toBe('/rest/oauth2/latest/authorize'); + expect(Object.fromEntries(startUrl.searchParams)).toEqual({ + response_type: 'code', + client_id: 'cliendId', + redirect_uri: `http://localhost:${server.port()}/api/auth/bitbucketServer/handler/frame`, + state: expect.any(String), + }); + + expect(decodeOAuthState(startUrl.searchParams.get('state')!)).toEqual({ + env: 'development', + nonce: decodeURIComponent(nonceCookie.value), + }); + }); +}); diff --git a/plugins/auth-backend-module-bitbucket-server-provider/src/module.ts b/plugins/auth-backend-module-bitbucket-server-provider/src/module.ts new file mode 100644 index 0000000000..c49def87cd --- /dev/null +++ b/plugins/auth-backend-module-bitbucket-server-provider/src/module.ts @@ -0,0 +1,48 @@ +/* + * 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 { createBackendModule } from '@backstage/backend-plugin-api'; +import { + authProvidersExtensionPoint, + commonSignInResolvers, + createOAuthProviderFactory, +} from '@backstage/plugin-auth-node'; +import { bitbucketServerAuthenticator } from './authenticator'; +import { bitbucketServerSignInResolvers } from './resolvers'; + +/** @public */ +export const authModuleBitbucketServerProvider = createBackendModule({ + pluginId: 'auth', + moduleId: 'bitbucket-server-provider', + register(reg) { + reg.registerInit({ + deps: { + providers: authProvidersExtensionPoint, + }, + async init({ providers }) { + providers.registerProvider({ + providerId: 'bitbucketServer', + factory: createOAuthProviderFactory({ + authenticator: bitbucketServerAuthenticator, + signInResolverFactories: { + ...bitbucketServerSignInResolvers, + ...commonSignInResolvers, + }, + }), + }); + }, + }); + }, +}); diff --git a/plugins/auth-backend-module-bitbucket-server-provider/src/resolvers.ts b/plugins/auth-backend-module-bitbucket-server-provider/src/resolvers.ts new file mode 100644 index 0000000000..dc2ceef7e9 --- /dev/null +++ b/plugins/auth-backend-module-bitbucket-server-provider/src/resolvers.ts @@ -0,0 +1,55 @@ +/* + * 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 { + createSignInResolverFactory, + OAuthAuthenticatorResult, + PassportProfile, + SignInInfo, +} from '@backstage/plugin-auth-node'; + +/** + * Available sign-in resolvers for the Bitbucket Server auth provider. + * + * @public + */ +export namespace bitbucketServerSignInResolvers { + /** + * Looks up the user by matching their email to the entity email. + */ + export const emailMatchingUserEntityProfileEmail = + createSignInResolverFactory({ + create() { + return async ( + info: SignInInfo>, + ctx, + ) => { + const { profile } = info; + + if (!profile.email) { + throw new Error( + 'Login failed, user profile does not contain an email', + ); + } + + return ctx.signInWithCatalogUser({ + filter: { + 'spec.profile.email': profile.email, + }, + }); + }; + }, + }); +} diff --git a/plugins/auth-backend-module-cloudflare-access-provider/CHANGELOG.md b/plugins/auth-backend-module-cloudflare-access-provider/CHANGELOG.md index 1ed55e9d69..faea9b49c3 100644 --- a/plugins/auth-backend-module-cloudflare-access-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-cloudflare-access-provider/CHANGELOG.md @@ -1,5 +1,43 @@ # @backstage/plugin-auth-backend-module-cloudflare-access-provider +## 0.3.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## 0.3.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## 0.3.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + ## 0.3.0-next.1 ### Patch Changes diff --git a/plugins/auth-backend-module-cloudflare-access-provider/package.json b/plugins/auth-backend-module-cloudflare-access-provider/package.json index b40928a4bf..7c82ff38f0 100644 --- a/plugins/auth-backend-module-cloudflare-access-provider/package.json +++ b/plugins/auth-backend-module-cloudflare-access-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-cloudflare-access-provider", - "version": "0.3.0-next.1", + "version": "0.3.1-next.0", "description": "The cloudflare-access-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-cloudflare-access-provider/api-report.md b/plugins/auth-backend-module-cloudflare-access-provider/report.api.md similarity index 82% rename from plugins/auth-backend-module-cloudflare-access-provider/api-report.md rename to plugins/auth-backend-module-cloudflare-access-provider/report.api.md index 1547190d39..b9943b2bef 100644 --- a/plugins/auth-backend-module-cloudflare-access-provider/api-report.md +++ b/plugins/auth-backend-module-cloudflare-access-provider/report.api.md @@ -60,4 +60,10 @@ export namespace cloudflareAccessSignInResolvers { export function createCloudflareAccessAuthenticator(options?: { cache?: CacheService; }): ProxyAuthenticator; + +// Warnings were encountered during analysis: +// +// src/types.d.ts:55:1 - (ae-undocumented) Missing documentation for "CloudflareAccessGroup". +// src/types.d.ts:72:1 - (ae-undocumented) Missing documentation for "CloudflareAccessIdentityProfile". +// src/types.d.ts:81:1 - (ae-undocumented) Missing documentation for "CloudflareAccessResult". ``` diff --git a/plugins/auth-backend-module-gcp-iap-provider/CHANGELOG.md b/plugins/auth-backend-module-gcp-iap-provider/CHANGELOG.md index 32de67cf73..842c1b629c 100644 --- a/plugins/auth-backend-module-gcp-iap-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-gcp-iap-provider/CHANGELOG.md @@ -1,5 +1,43 @@ # @backstage/plugin-auth-backend-module-gcp-iap-provider +## 0.3.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## 0.3.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## 0.3.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.3.0-next.1 ### Patch Changes diff --git a/plugins/auth-backend-module-gcp-iap-provider/package.json b/plugins/auth-backend-module-gcp-iap-provider/package.json index 94e52df683..988f012563 100644 --- a/plugins/auth-backend-module-gcp-iap-provider/package.json +++ b/plugins/auth-backend-module-gcp-iap-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-gcp-iap-provider", - "version": "0.3.0-next.1", + "version": "0.3.1-next.0", "description": "A GCP IAP auth provider module for the Backstage auth backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-gcp-iap-provider/api-report.md b/plugins/auth-backend-module-gcp-iap-provider/report.api.md similarity index 84% rename from plugins/auth-backend-module-gcp-iap-provider/api-report.md rename to plugins/auth-backend-module-gcp-iap-provider/report.api.md index 1476694f99..72887276d5 100644 --- a/plugins/auth-backend-module-gcp-iap-provider/api-report.md +++ b/plugins/auth-backend-module-gcp-iap-provider/report.api.md @@ -50,5 +50,10 @@ export type GcpIapTokenInfo = { [key: string]: JsonPrimitive; }; +// Warnings were encountered during analysis: +// +// src/authenticator.d.ts:2:22 - (ae-undocumented) Missing documentation for "gcpIapAuthenticator". +// src/module.d.ts:2:22 - (ae-undocumented) Missing documentation for "authModuleGcpIapProvider". + // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/auth-backend-module-github-provider/CHANGELOG.md b/plugins/auth-backend-module-github-provider/CHANGELOG.md index b898b8b23f..c2f108ecf3 100644 --- a/plugins/auth-backend-module-github-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-github-provider/CHANGELOG.md @@ -1,5 +1,39 @@ # @backstage/plugin-auth-backend-module-github-provider +## 0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + +## 0.2.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + +## 0.2.0-next.2 + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + ## 0.2.0-next.1 ### Patch Changes diff --git a/plugins/auth-backend-module-github-provider/package.json b/plugins/auth-backend-module-github-provider/package.json index 08e3acaf8f..8a70ee82b4 100644 --- a/plugins/auth-backend-module-github-provider/package.json +++ b/plugins/auth-backend-module-github-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-github-provider", - "version": "0.2.0-next.1", + "version": "0.2.1-next.0", "description": "The github-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", @@ -43,7 +43,7 @@ "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "@backstage/plugin-auth-backend": "workspace:^", - "supertest": "^6.3.3" + "supertest": "^7.0.0" }, "configSchema": "config.d.ts" } diff --git a/plugins/auth-backend-module-github-provider/api-report.md b/plugins/auth-backend-module-github-provider/report.api.md similarity index 80% rename from plugins/auth-backend-module-github-provider/api-report.md rename to plugins/auth-backend-module-github-provider/report.api.md index 222305adfd..0578c23d3e 100644 --- a/plugins/auth-backend-module-github-provider/api-report.md +++ b/plugins/auth-backend-module-github-provider/report.api.md @@ -27,4 +27,9 @@ export namespace githubSignInResolvers { unknown >; } + +// Warnings were encountered during analysis: +// +// src/authenticator.d.ts:3:22 - (ae-undocumented) Missing documentation for "githubAuthenticator". +// src/module.d.ts:2:22 - (ae-undocumented) Missing documentation for "authModuleGithubProvider". ``` diff --git a/plugins/auth-backend-module-gitlab-provider/CHANGELOG.md b/plugins/auth-backend-module-gitlab-provider/CHANGELOG.md index 8cf6bbc41e..cfd0db044f 100644 --- a/plugins/auth-backend-module-gitlab-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-gitlab-provider/CHANGELOG.md @@ -1,5 +1,39 @@ # @backstage/plugin-auth-backend-module-gitlab-provider +## 0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + +## 0.2.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + +## 0.2.0-next.2 + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + ## 0.2.0-next.1 ### Patch Changes diff --git a/plugins/auth-backend-module-gitlab-provider/package.json b/plugins/auth-backend-module-gitlab-provider/package.json index dc562c16e8..68146cbe05 100644 --- a/plugins/auth-backend-module-gitlab-provider/package.json +++ b/plugins/auth-backend-module-gitlab-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-gitlab-provider", - "version": "0.2.0-next.1", + "version": "0.2.1-next.0", "description": "The gitlab-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", @@ -45,7 +45,7 @@ "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "@backstage/plugin-auth-backend": "workspace:^", - "supertest": "^6.3.3" + "supertest": "^7.0.0" }, "configSchema": "config.d.ts" } diff --git a/plugins/auth-backend-module-gitlab-provider/api-report.md b/plugins/auth-backend-module-gitlab-provider/report.api.md similarity index 80% rename from plugins/auth-backend-module-gitlab-provider/api-report.md rename to plugins/auth-backend-module-gitlab-provider/report.api.md index 44c5ffb214..a72c00c6e5 100644 --- a/plugins/auth-backend-module-gitlab-provider/api-report.md +++ b/plugins/auth-backend-module-gitlab-provider/report.api.md @@ -27,4 +27,9 @@ export namespace gitlabSignInResolvers { unknown >; } + +// Warnings were encountered during analysis: +// +// src/authenticator.d.ts:3:22 - (ae-undocumented) Missing documentation for "gitlabAuthenticator". +// src/module.d.ts:2:22 - (ae-undocumented) Missing documentation for "authModuleGitlabProvider". ``` diff --git a/plugins/auth-backend-module-google-provider/CHANGELOG.md b/plugins/auth-backend-module-google-provider/CHANGELOG.md index 72c422b3bc..4a20c3d9e4 100644 --- a/plugins/auth-backend-module-google-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-google-provider/CHANGELOG.md @@ -1,5 +1,39 @@ # @backstage/plugin-auth-backend-module-google-provider +## 0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + +## 0.2.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + +## 0.2.0-next.2 + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + ## 0.2.0-next.1 ### Patch Changes diff --git a/plugins/auth-backend-module-google-provider/package.json b/plugins/auth-backend-module-google-provider/package.json index 3f4305d8e5..c0ee244873 100644 --- a/plugins/auth-backend-module-google-provider/package.json +++ b/plugins/auth-backend-module-google-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-google-provider", - "version": "0.2.0-next.1", + "version": "0.2.1-next.0", "description": "A Google auth provider module for the Backstage auth backend", "backstage": { "role": "backend-plugin-module", @@ -48,7 +48,7 @@ "@backstage/cli": "workspace:^", "@backstage/plugin-auth-backend": "workspace:^", "@types/passport-google-oauth20": "^2.0.3", - "supertest": "^6.1.3" + "supertest": "^7.0.0" }, "configSchema": "config.d.ts" } diff --git a/plugins/auth-backend-module-google-provider/api-report.md b/plugins/auth-backend-module-google-provider/report.api.md similarity index 81% rename from plugins/auth-backend-module-google-provider/api-report.md rename to plugins/auth-backend-module-google-provider/report.api.md index eeefb8e837..a2fc1bbce9 100644 --- a/plugins/auth-backend-module-google-provider/api-report.md +++ b/plugins/auth-backend-module-google-provider/report.api.md @@ -28,5 +28,10 @@ export namespace googleSignInResolvers { >; } +// Warnings were encountered during analysis: +// +// src/authenticator.d.ts:3:22 - (ae-undocumented) Missing documentation for "googleAuthenticator". +// src/module.d.ts:2:22 - (ae-undocumented) Missing documentation for "authModuleGoogleProvider". + // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/auth-backend-module-guest-provider/CHANGELOG.md b/plugins/auth-backend-module-guest-provider/CHANGELOG.md index 69c7e94a3e..676f4b82ee 100644 --- a/plugins/auth-backend-module-guest-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-guest-provider/CHANGELOG.md @@ -1,5 +1,47 @@ # @backstage/plugin-auth-backend-module-guest-provider +## 0.2.1-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/errors@1.2.4 + +## 0.2.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- 339c67d: This provider will now reject authentication attempts rather than halt backend startup when `dangerouslyAllowOutsideDevelopment` is not set in production. +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/catalog-model@1.7.0 + - @backstage/errors@1.2.4 + +## 0.2.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/errors@1.2.4 + ## 0.2.0-next.1 ### Patch Changes diff --git a/plugins/auth-backend-module-guest-provider/package.json b/plugins/auth-backend-module-guest-provider/package.json index d46324f4de..a82feb2e0f 100644 --- a/plugins/auth-backend-module-guest-provider/package.json +++ b/plugins/auth-backend-module-guest-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-guest-provider", - "version": "0.2.0-next.1", + "version": "0.2.1-next.0", "description": "The guest-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", @@ -34,7 +34,7 @@ "test": "backstage-cli package test" }, "dependencies": { - "@backstage/backend-common": "workspace:^", + "@backstage/backend-common": "^0.25.0", "@backstage/backend-plugin-api": "workspace:^", "@backstage/catalog-model": "workspace:^", "@backstage/errors": "workspace:^", diff --git a/plugins/auth-backend-module-guest-provider/api-report.md b/plugins/auth-backend-module-guest-provider/report.api.md similarity index 71% rename from plugins/auth-backend-module-guest-provider/api-report.md rename to plugins/auth-backend-module-guest-provider/report.api.md index b0ba5386a2..b100e5270b 100644 --- a/plugins/auth-backend-module-guest-provider/api-report.md +++ b/plugins/auth-backend-module-guest-provider/report.api.md @@ -8,4 +8,8 @@ import { BackendFeature } from '@backstage/backend-plugin-api'; // @public (undocumented) const authModuleGuestProvider: BackendFeature; export default authModuleGuestProvider; + +// Warnings were encountered during analysis: +// +// src/module.d.ts:2:22 - (ae-undocumented) Missing documentation for "authModuleGuestProvider". ``` diff --git a/plugins/auth-backend-module-guest-provider/src/authenticator.ts b/plugins/auth-backend-module-guest-provider/src/authenticator.ts index f12e551f39..1ea2e124ab 100644 --- a/plugins/auth-backend-module-guest-provider/src/authenticator.ts +++ b/plugins/auth-backend-module-guest-provider/src/authenticator.ts @@ -15,7 +15,7 @@ */ import { createProxyAuthenticator } from '@backstage/plugin-auth-node'; -import { NotImplementedError } from '@backstage/errors'; +import { NotAllowedError } from '@backstage/errors'; export const guestAuthenticator = createProxyAuthenticator({ defaultProfileTransform: async () => { @@ -25,13 +25,14 @@ export const guestAuthenticator = createProxyAuthenticator({ const allowOutsideDev = config.getOptionalBoolean( 'dangerouslyAllowOutsideDevelopment', ); - if (process.env.NODE_ENV !== 'development' && allowOutsideDev !== true) { - throw new NotImplementedError( - 'The guest provider cannot be used outside of a development environment', + return process.env.NODE_ENV !== 'development' && allowOutsideDev !== true; + }, + async authenticate(_, disabled) { + if (disabled) { + throw new NotAllowedError( + "The guest provider cannot be used outside of a development environment unless 'auth.providers.guest.dangerouslyAllowOutsideDevelopment' is enabled", ); } - }, - async authenticate() { return { result: {} }; }, }); diff --git a/plugins/auth-backend-module-microsoft-provider/CHANGELOG.md b/plugins/auth-backend-module-microsoft-provider/CHANGELOG.md index 094eee92a8..3b741f3258 100644 --- a/plugins/auth-backend-module-microsoft-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-microsoft-provider/CHANGELOG.md @@ -1,5 +1,40 @@ # @backstage/plugin-auth-backend-module-microsoft-provider +## 0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + +## 0.2.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- 3c2d690: Allow users without defined email to be ingested by the `msgraph` catalog plugin and add `userIdMatchingUserEntityAnnotation` sign-in resolver for the Microsoft auth provider to support sign-in for users without defined email. +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + +## 0.2.0-next.2 + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + ## 0.2.0-next.1 ### Patch Changes diff --git a/plugins/auth-backend-module-microsoft-provider/config.d.ts b/plugins/auth-backend-module-microsoft-provider/config.d.ts index b1ed2d5766..f8b5f0355d 100644 --- a/plugins/auth-backend-module-microsoft-provider/config.d.ts +++ b/plugins/auth-backend-module-microsoft-provider/config.d.ts @@ -29,6 +29,7 @@ export interface Config { domainHint?: string; callbackUrl?: string; additionalScopes?: string | string[]; + skipUserProfile?: boolean; signIn?: { resolvers: Array< | { resolver: 'emailMatchingUserEntityAnnotation' } diff --git a/plugins/auth-backend-module-microsoft-provider/package.json b/plugins/auth-backend-module-microsoft-provider/package.json index 1a81038994..5263b76340 100644 --- a/plugins/auth-backend-module-microsoft-provider/package.json +++ b/plugins/auth-backend-module-microsoft-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-microsoft-provider", - "version": "0.2.0-next.1", + "version": "0.2.1-next.0", "description": "The microsoft-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", @@ -49,7 +49,7 @@ "@backstage/plugin-auth-backend": "workspace:^", "@types/passport-microsoft": "^1.0.0", "msw": "^1.0.0", - "supertest": "^6.3.3" + "supertest": "^7.0.0" }, "configSchema": "config.d.ts" } diff --git a/plugins/auth-backend-module-microsoft-provider/api-report.md b/plugins/auth-backend-module-microsoft-provider/report.api.md similarity index 78% rename from plugins/auth-backend-module-microsoft-provider/api-report.md rename to plugins/auth-backend-module-microsoft-provider/report.api.md index 6aef395d7c..3e7775cfa8 100644 --- a/plugins/auth-backend-module-microsoft-provider/api-report.md +++ b/plugins/auth-backend-module-microsoft-provider/report.api.md @@ -37,4 +37,10 @@ export namespace microsoftSignInResolvers { unknown >; } + +// Warnings were encountered during analysis: +// +// src/authenticator.d.ts:3:22 - (ae-undocumented) Missing documentation for "microsoftAuthenticator". +// src/deprecated.d.ts:5:22 - (ae-undocumented) Missing documentation for "authModuleMicrosoftProvider". +// src/module.d.ts:2:22 - (ae-undocumented) Missing documentation for "authModuleMicrosoftProvider". ``` 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 74a7ab9974..0f39aed526 100644 --- a/plugins/auth-backend-module-microsoft-provider/src/authenticator.test.ts +++ b/plugins/auth-backend-module-microsoft-provider/src/authenticator.test.ts @@ -262,7 +262,7 @@ describe('microsoftAuthenticator', () => { expect(profile.photos).toStrictEqual([{ value: photo }]); }); - it('returns access token for non-microsoft graph scope', async () => { + it('returns access token for non-microsoft graph scope', async () => { const foreignScope = 'aks-audience/user.read'; const refreshResponse = await microsoftAuthenticator.refresh( createRefreshRequest(foreignScope), @@ -274,5 +274,29 @@ describe('microsoftAuthenticator', () => { microsoftApi.generateAccessToken(foreignScope), ); }); + + it('returns access token when skipping user profile load', async () => { + // Replace implementation to set skipUserProfile config + implementation = microsoftAuthenticator.initialize({ + callbackUrl: 'https://backstage.test/callback', + config: new ConfigReader({ + tenantId: 'tenantId', + clientId: 'clientId', + clientSecret: 'clientSecret', + additionalScopes: ['User.Read.All'], + skipUserProfile: true, + }), + }); + + const refreshResponse = await microsoftAuthenticator.refresh( + createRefreshRequest(scope), + implementation, + ); + + expect(refreshResponse.fullProfile).toBeUndefined(); + expect(refreshResponse.session.accessToken).toBe( + microsoftApi.generateAccessToken(scope), + ); + }); }); }); diff --git a/plugins/auth-backend-module-microsoft-provider/src/authenticator.ts b/plugins/auth-backend-module-microsoft-provider/src/authenticator.ts index fe7dc8f7e1..5767abaaf7 100644 --- a/plugins/auth-backend-module-microsoft-provider/src/authenticator.ts +++ b/plugins/auth-backend-module-microsoft-provider/src/authenticator.ts @@ -45,31 +45,30 @@ export const microsoftAuthenticator = createOAuthAuthenticator({ const clientSecret = config.getString('clientSecret'); const tenantId = config.getString('tenantId'); const domainHint = config.getOptionalString('domainHint'); + const skipUserProfile = + config.getOptionalBoolean('skipUserProfile') ?? false; - const helper = PassportOAuthAuthenticatorHelper.from( - new ExtendedMicrosoftStrategy( - { - clientID: clientId, - clientSecret: clientSecret, - callbackURL: callbackUrl, - tenant: tenantId, - }, - ( - accessToken: string, - refreshToken: string, - params: any, - fullProfile: PassportProfile, - done: PassportOAuthDoneCallback, - ) => { - done( - undefined, - { fullProfile, params, accessToken }, - { refreshToken }, - ); - }, - ), + const strategy = new ExtendedMicrosoftStrategy( + { + clientID: clientId, + clientSecret: clientSecret, + callbackURL: callbackUrl, + tenant: tenantId, + }, + ( + accessToken: string, + refreshToken: string, + params: any, + fullProfile: PassportProfile, + done: PassportOAuthDoneCallback, + ) => { + done(undefined, { fullProfile, params, accessToken }, { refreshToken }); + }, ); + strategy.setSkipUserProfile(skipUserProfile); + const helper = PassportOAuthAuthenticatorHelper.from(strategy); + return { helper, domainHint, diff --git a/plugins/auth-backend-module-microsoft-provider/src/strategy.ts b/plugins/auth-backend-module-microsoft-provider/src/strategy.ts index d5a1aa31fe..910bd85d1d 100644 --- a/plugins/auth-backend-module-microsoft-provider/src/strategy.ts +++ b/plugins/auth-backend-module-microsoft-provider/src/strategy.ts @@ -20,6 +20,12 @@ import fetch from 'node-fetch'; import { Strategy as MicrosoftStrategy } from 'passport-microsoft'; export class ExtendedMicrosoftStrategy extends MicrosoftStrategy { + private shouldSkipUserProfile = false; + + public setSkipUserProfile(shouldSkipUserProfile: boolean): void { + this.shouldSkipUserProfile = shouldSkipUserProfile; + } + userProfile( accessToken: string, done: (err?: unknown, profile?: PassportProfile) => void, @@ -66,7 +72,7 @@ export class ExtendedMicrosoftStrategy extends MicrosoftStrategy { private skipUserProfile(accessToken: string): boolean { try { - return !this.hasGraphReadScope(accessToken); + return this.shouldSkipUserProfile || !this.hasGraphReadScope(accessToken); } catch { // If there is any error with checking the scope // we fall back to not skipping the user profile diff --git a/plugins/auth-backend-module-oauth2-provider/CHANGELOG.md b/plugins/auth-backend-module-oauth2-provider/CHANGELOG.md index 1e91fac858..d5eb620fa7 100644 --- a/plugins/auth-backend-module-oauth2-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-oauth2-provider/CHANGELOG.md @@ -1,5 +1,39 @@ # @backstage/plugin-auth-backend-module-oauth2-provider +## 0.3.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + +## 0.3.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + +## 0.3.0-next.2 + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + ## 0.3.0-next.1 ### Patch Changes diff --git a/plugins/auth-backend-module-oauth2-provider/package.json b/plugins/auth-backend-module-oauth2-provider/package.json index f5ad94f1b8..feb21cfe4e 100644 --- a/plugins/auth-backend-module-oauth2-provider/package.json +++ b/plugins/auth-backend-module-oauth2-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-oauth2-provider", - "version": "0.3.0-next.1", + "version": "0.3.1-next.0", "description": "The oauth2-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", @@ -44,7 +44,7 @@ "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "@backstage/plugin-auth-backend": "workspace:^", - "supertest": "^6.3.3" + "supertest": "^7.0.0" }, "configSchema": "config.d.ts" } diff --git a/plugins/auth-backend-module-oauth2-provider/api-report.md b/plugins/auth-backend-module-oauth2-provider/report.api.md similarity index 80% rename from plugins/auth-backend-module-oauth2-provider/api-report.md rename to plugins/auth-backend-module-oauth2-provider/report.api.md index 632591ec04..5648d043a2 100644 --- a/plugins/auth-backend-module-oauth2-provider/api-report.md +++ b/plugins/auth-backend-module-oauth2-provider/report.api.md @@ -27,4 +27,9 @@ export namespace oauth2SignInResolvers { unknown >; } + +// Warnings were encountered during analysis: +// +// src/authenticator.d.ts:3:22 - (ae-undocumented) Missing documentation for "oauth2Authenticator". +// src/module.d.ts:2:22 - (ae-undocumented) Missing documentation for "authModuleOauth2Provider". ``` diff --git a/plugins/auth-backend-module-oauth2-proxy-provider/CHANGELOG.md b/plugins/auth-backend-module-oauth2-proxy-provider/CHANGELOG.md index 240a3853f2..052a7a1797 100644 --- a/plugins/auth-backend-module-oauth2-proxy-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-oauth2-proxy-provider/CHANGELOG.md @@ -1,5 +1,40 @@ # @backstage/plugin-auth-backend-module-oauth2-proxy-provider +## 0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/errors@1.2.4 + +## 0.2.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/errors@1.2.4 + +## 0.2.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/errors@1.2.4 + ## 0.2.0-next.1 ### Patch Changes diff --git a/plugins/auth-backend-module-oauth2-proxy-provider/package.json b/plugins/auth-backend-module-oauth2-proxy-provider/package.json index 9dce1fec17..79c2a4a178 100644 --- a/plugins/auth-backend-module-oauth2-proxy-provider/package.json +++ b/plugins/auth-backend-module-oauth2-proxy-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-oauth2-proxy-provider", - "version": "0.2.0-next.1", + "version": "0.2.1-next.0", "description": "The oauth2-proxy-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-oauth2-proxy-provider/api-report.md b/plugins/auth-backend-module-oauth2-proxy-provider/report.api.md similarity index 78% rename from plugins/auth-backend-module-oauth2-proxy-provider/api-report.md rename to plugins/auth-backend-module-oauth2-proxy-provider/report.api.md index 5c5cefd734..27b3a9feb2 100644 --- a/plugins/auth-backend-module-oauth2-proxy-provider/api-report.md +++ b/plugins/auth-backend-module-oauth2-proxy-provider/report.api.md @@ -32,4 +32,9 @@ export type OAuth2ProxyResult = { headers: IncomingHttpHeaders; getHeader(name: string): string | undefined; }; + +// Warnings were encountered during analysis: +// +// src/authenticator.d.ts:10:22 - (ae-undocumented) Missing documentation for "oauth2ProxyAuthenticator". +// src/module.d.ts:2:22 - (ae-undocumented) Missing documentation for "authModuleOauth2ProxyProvider". ``` diff --git a/plugins/auth-backend-module-oauth2-proxy-provider/src/authenticator.ts b/plugins/auth-backend-module-oauth2-proxy-provider/src/authenticator.ts index 21fe52e824..c4542639d1 100644 --- a/plugins/auth-backend-module-oauth2-proxy-provider/src/authenticator.ts +++ b/plugins/auth-backend-module-oauth2-proxy-provider/src/authenticator.ts @@ -42,6 +42,15 @@ export const oauth2ProxyAuthenticator = createProxyAuthenticator({ async initialize() {}, async authenticate({ req }) { try { + // This unpacking of the JWT is just a utility provided by the + // authenticator to make the fields available to the profile transform and + // sign-in resolvers. The JWT is already validated by the upstream OAuth2 + // Proxy, and since OAuth2 Proxy doesn't provide a way to authenticate + // forwarded requests, we don't do any additional validation here but + // instead trust that there is no way for attackers to bypass the OAuth2 + // Proxy. We could validate these individual ID tokens for some of the + // upstream providers, but that is currently not in scope for this + // authenticator. const authHeader = req.header(OAUTH2_PROXY_JWT_HEADER); const jwt = authHeader?.match(/^Bearer[ ]+(\S+)$/i)?.[1]; const decodedJWT = jwt && decodeJwt(jwt); diff --git a/plugins/auth-backend-module-oidc-provider/CHANGELOG.md b/plugins/auth-backend-module-oidc-provider/CHANGELOG.md index 3b087761d0..7aba336457 100644 --- a/plugins/auth-backend-module-oidc-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-oidc-provider/CHANGELOG.md @@ -1,5 +1,45 @@ # @backstage/plugin-auth-backend-module-oidc-provider +## 0.3.1-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-auth-backend@0.23.1-next.0 + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + +## 0.3.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/plugin-auth-backend@0.23.0 + +## 0.3.0-next.2 + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/plugin-auth-backend@0.23.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + ## 0.3.0-next.1 ### Patch Changes diff --git a/plugins/auth-backend-module-oidc-provider/package.json b/plugins/auth-backend-module-oidc-provider/package.json index 1a1d6c9c8a..12a6daf332 100644 --- a/plugins/auth-backend-module-oidc-provider/package.json +++ b/plugins/auth-backend-module-oidc-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-oidc-provider", - "version": "0.3.0-next.1", + "version": "0.3.1-next.0", "description": "The oidc-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", @@ -34,7 +34,7 @@ "test": "backstage-cli package test" }, "dependencies": { - "@backstage/backend-common": "workspace:^", + "@backstage/backend-common": "^0.25.0", "@backstage/backend-plugin-api": "workspace:^", "@backstage/plugin-auth-backend": "workspace:^", "@backstage/plugin-auth-node": "workspace:^", @@ -52,7 +52,7 @@ "express-session": "^1.17.3", "jose": "^5.0.0", "msw": "^1.3.1", - "supertest": "^6.3.3" + "supertest": "^7.0.0" }, "configSchema": "config.d.ts" } diff --git a/plugins/auth-backend-module-oidc-provider/api-report.md b/plugins/auth-backend-module-oidc-provider/report.api.md similarity index 85% rename from plugins/auth-backend-module-oidc-provider/api-report.md rename to plugins/auth-backend-module-oidc-provider/report.api.md index cd0a99e7fc..df717a9e1e 100644 --- a/plugins/auth-backend-module-oidc-provider/api-report.md +++ b/plugins/auth-backend-module-oidc-provider/report.api.md @@ -46,4 +46,9 @@ export namespace oidcSignInResolvers { unknown >; } + +// Warnings were encountered during analysis: +// +// src/authenticator.d.ts:13:22 - (ae-undocumented) Missing documentation for "oidcAuthenticator". +// src/module.d.ts:2:22 - (ae-undocumented) Missing documentation for "authModuleOidcProvider". ``` diff --git a/plugins/auth-backend-module-okta-provider/CHANGELOG.md b/plugins/auth-backend-module-okta-provider/CHANGELOG.md index 08d2ef1f2f..8931c4a2bf 100644 --- a/plugins/auth-backend-module-okta-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-okta-provider/CHANGELOG.md @@ -1,5 +1,39 @@ # @backstage/plugin-auth-backend-module-okta-provider +## 0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + +## 0.1.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + +## 0.1.0-next.2 + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + ## 0.1.0-next.1 ### Patch Changes diff --git a/plugins/auth-backend-module-okta-provider/package.json b/plugins/auth-backend-module-okta-provider/package.json index 0965e1548d..1b5b46ecc8 100644 --- a/plugins/auth-backend-module-okta-provider/package.json +++ b/plugins/auth-backend-module-okta-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-okta-provider", - "version": "0.1.0-next.1", + "version": "0.1.1-next.0", "description": "The okta-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", @@ -45,7 +45,7 @@ "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "@backstage/plugin-auth-backend": "workspace:^", - "supertest": "^6.3.3" + "supertest": "^7.0.0" }, "configSchema": "config.d.ts" } diff --git a/plugins/auth-backend-module-okta-provider/api-report.md b/plugins/auth-backend-module-okta-provider/report.api.md similarity index 80% rename from plugins/auth-backend-module-okta-provider/api-report.md rename to plugins/auth-backend-module-okta-provider/report.api.md index a142265100..97e587df76 100644 --- a/plugins/auth-backend-module-okta-provider/api-report.md +++ b/plugins/auth-backend-module-okta-provider/report.api.md @@ -27,4 +27,9 @@ export namespace oktaSignInResolvers { unknown >; } + +// Warnings were encountered during analysis: +// +// src/authenticator.d.ts:3:22 - (ae-undocumented) Missing documentation for "oktaAuthenticator". +// src/module.d.ts:2:22 - (ae-undocumented) Missing documentation for "authModuleOktaProvider". ``` diff --git a/plugins/auth-backend-module-onelogin-provider/CHANGELOG.md b/plugins/auth-backend-module-onelogin-provider/CHANGELOG.md index 796813e0a3..4d344c4d72 100644 --- a/plugins/auth-backend-module-onelogin-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-onelogin-provider/CHANGELOG.md @@ -1,5 +1,39 @@ # @backstage/plugin-auth-backend-module-onelogin-provider +## 0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + +## 0.2.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + +## 0.2.0-next.2 + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + ## 0.2.0-next.1 ### Patch Changes diff --git a/plugins/auth-backend-module-onelogin-provider/package.json b/plugins/auth-backend-module-onelogin-provider/package.json index 53e8e646ca..4dae5a8805 100644 --- a/plugins/auth-backend-module-onelogin-provider/package.json +++ b/plugins/auth-backend-module-onelogin-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-onelogin-provider", - "version": "0.2.0-next.1", + "version": "0.2.1-next.0", "description": "The onelogin-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", @@ -45,7 +45,7 @@ "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "@backstage/plugin-auth-backend": "workspace:^", - "supertest": "^6.3.3" + "supertest": "^7.0.0" }, "configSchema": "config.d.ts" } diff --git a/plugins/auth-backend-module-onelogin-provider/api-report.md b/plugins/auth-backend-module-onelogin-provider/report.api.md similarity index 80% rename from plugins/auth-backend-module-onelogin-provider/api-report.md rename to plugins/auth-backend-module-onelogin-provider/report.api.md index 1991f00e0b..a636d96ae0 100644 --- a/plugins/auth-backend-module-onelogin-provider/api-report.md +++ b/plugins/auth-backend-module-onelogin-provider/report.api.md @@ -27,4 +27,9 @@ export namespace oneLoginSignInResolvers { unknown >; } + +// Warnings were encountered during analysis: +// +// src/authenticator.d.ts:3:22 - (ae-undocumented) Missing documentation for "oneLoginAuthenticator". +// src/module.d.ts:2:22 - (ae-undocumented) Missing documentation for "authModuleOneLoginProvider". ``` diff --git a/plugins/auth-backend-module-pinniped-provider/CHANGELOG.md b/plugins/auth-backend-module-pinniped-provider/CHANGELOG.md index ebbff3416d..0707122785 100644 --- a/plugins/auth-backend-module-pinniped-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-pinniped-provider/CHANGELOG.md @@ -1,5 +1,42 @@ # @backstage/plugin-auth-backend-module-pinniped-provider +## 0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + +## 0.2.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/config@1.2.0 + +## 0.2.0-next.2 + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/config@1.2.0 + ## 0.2.0-next.1 ### Patch Changes diff --git a/plugins/auth-backend-module-pinniped-provider/package.json b/plugins/auth-backend-module-pinniped-provider/package.json index 932ad93b38..7ae787e202 100644 --- a/plugins/auth-backend-module-pinniped-provider/package.json +++ b/plugins/auth-backend-module-pinniped-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-pinniped-provider", - "version": "0.2.0-next.1", + "version": "0.2.1-next.0", "description": "The pinniped-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", @@ -50,6 +50,6 @@ "jose": "^5.0.0", "msw": "^1.3.0", "passport": "^0.7.0", - "supertest": "^6.3.3" + "supertest": "^7.0.0" } } diff --git a/plugins/auth-backend-module-pinniped-provider/api-report.md b/plugins/auth-backend-module-pinniped-provider/report.api.md similarity index 67% rename from plugins/auth-backend-module-pinniped-provider/api-report.md rename to plugins/auth-backend-module-pinniped-provider/report.api.md index e15f4ee324..a0500f5e74 100644 --- a/plugins/auth-backend-module-pinniped-provider/api-report.md +++ b/plugins/auth-backend-module-pinniped-provider/report.api.md @@ -37,4 +37,12 @@ export class PinnipedStrategyCache { client: BaseClient; }>; } + +// Warnings were encountered during analysis: +// +// src/authenticator.d.ts:4:1 - (ae-undocumented) Missing documentation for "PinnipedStrategyCache". +// src/authenticator.d.ts:11:5 - (ae-undocumented) Missing documentation for "getStrategy". +// src/authenticator.d.ts:20:22 - (ae-undocumented) Missing documentation for "pinnipedAuthenticator". +// src/deprecated.d.ts:5:22 - (ae-undocumented) Missing documentation for "authModulePinnipedProvider". +// src/module.d.ts:2:22 - (ae-undocumented) Missing documentation for "authModulePinnipedProvider". ``` diff --git a/plugins/auth-backend-module-vmware-cloud-provider/CHANGELOG.md b/plugins/auth-backend-module-vmware-cloud-provider/CHANGELOG.md index 8b6540ddf3..8d1bf64acb 100644 --- a/plugins/auth-backend-module-vmware-cloud-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-vmware-cloud-provider/CHANGELOG.md @@ -1,5 +1,42 @@ # @backstage/plugin-auth-backend-module-vmware-cloud-provider +## 0.3.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + +## 0.3.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/catalog-model@1.7.0 + +## 0.3.0-next.2 + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-model@1.6.0 + ## 0.3.0-next.1 ### Patch Changes diff --git a/plugins/auth-backend-module-vmware-cloud-provider/package.json b/plugins/auth-backend-module-vmware-cloud-provider/package.json index 2f198ebacb..c4dce89eb8 100644 --- a/plugins/auth-backend-module-vmware-cloud-provider/package.json +++ b/plugins/auth-backend-module-vmware-cloud-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-vmware-cloud-provider", - "version": "0.3.0-next.1", + "version": "0.3.1-next.0", "description": "The vmware-cloud-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", @@ -48,6 +48,6 @@ "@backstage/errors": "workspace:^", "@backstage/plugin-auth-backend": "workspace:^", "msw": "^2.0.8", - "supertest": "^6.3.3" + "supertest": "^7.0.0" } } diff --git a/plugins/auth-backend-module-vmware-cloud-provider/api-report.md b/plugins/auth-backend-module-vmware-cloud-provider/report.api.md similarity index 72% rename from plugins/auth-backend-module-vmware-cloud-provider/api-report.md rename to plugins/auth-backend-module-vmware-cloud-provider/report.api.md index 2a27d8fc7c..c970b237a9 100644 --- a/plugins/auth-backend-module-vmware-cloud-provider/api-report.md +++ b/plugins/auth-backend-module-vmware-cloud-provider/report.api.md @@ -43,4 +43,12 @@ export namespace vmwareCloudSignInResolvers { export type VMwarePassportProfile = PassportProfile & { organizationId?: string; }; + +// Warnings were encountered during analysis: +// +// src/authenticator.d.ts:4:1 - (ae-undocumented) Missing documentation for "VMwareCloudAuthenticatorContext". +// src/authenticator.d.ts:5:5 - (ae-undocumented) Missing documentation for "organizationId". +// src/authenticator.d.ts:6:5 - (ae-undocumented) Missing documentation for "providerStrategy". +// src/authenticator.d.ts:7:5 - (ae-undocumented) Missing documentation for "helper". +// src/authenticator.d.ts:10:1 - (ae-undocumented) Missing documentation for "VMwarePassportProfile". ``` diff --git a/plugins/auth-backend/CHANGELOG.md b/plugins/auth-backend/CHANGELOG.md index 4244638abd..7b86e02de0 100644 --- a/plugins/auth-backend/CHANGELOG.md +++ b/plugins/auth-backend/CHANGELOG.md @@ -1,5 +1,119 @@ # @backstage/plugin-auth-backend +## 0.23.1-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-auth-backend-module-aws-alb-provider@0.2.1-next.0 + - @backstage/plugin-auth-backend-module-oidc-provider@0.3.1-next.0 + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-backend-module-atlassian-provider@0.3.1-next.0 + - @backstage/plugin-auth-backend-module-auth0-provider@0.1.1-next.0 + - @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.2.1-next.0 + - @backstage/plugin-auth-backend-module-bitbucket-provider@0.2.1-next.0 + - @backstage/plugin-auth-backend-module-bitbucket-server-provider@0.1.1-next.0 + - @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.3.1-next.0 + - @backstage/plugin-auth-backend-module-gcp-iap-provider@0.3.1-next.0 + - @backstage/plugin-auth-backend-module-github-provider@0.2.1-next.0 + - @backstage/plugin-auth-backend-module-gitlab-provider@0.2.1-next.0 + - @backstage/plugin-auth-backend-module-google-provider@0.2.1-next.0 + - @backstage/plugin-auth-backend-module-microsoft-provider@0.2.1-next.0 + - @backstage/plugin-auth-backend-module-oauth2-provider@0.3.1-next.0 + - @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.2.1-next.0 + - @backstage/plugin-auth-backend-module-okta-provider@0.1.1-next.0 + - @backstage/plugin-auth-backend-module-onelogin-provider@0.2.1-next.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + +## 0.23.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- 527d973: Migrated the `Bitbucket Server` auth provider to be implemented using the new `@backstage/plugin-auth-backend-module-bitbucket-server-provider` module. +- d908d8c: Migrated the `Auth0` auth provider to be implemented using the new `@backstage/plugin-auth-backend-module-auth0-provider` module. +- 19ff127: Internal refactor to remove dependencies on the identity and token manager services, which have been removed. Public APIs no longer require the identity service or token manager to be provided. +- 3c2d690: Allow users without defined email to be ingested by the `msgraph` catalog plugin and add `userIdMatchingUserEntityAnnotation` sign-in resolver for the Microsoft auth provider to support sign-in for users without defined email. +- 92118cd: Updated dependency `@node-saml/passport-saml` to `^5.0.0`. +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/plugin-auth-backend-module-aws-alb-provider@0.2.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/catalog-model@1.7.0 + - @backstage/catalog-client@1.7.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/plugin-auth-backend-module-auth0-provider@0.1.0 + - @backstage/plugin-auth-backend-module-microsoft-provider@0.2.0 + - @backstage/plugin-auth-backend-module-atlassian-provider@0.3.0 + - @backstage/plugin-auth-backend-module-bitbucket-provider@0.2.0 + - @backstage/plugin-auth-backend-module-github-provider@0.2.0 + - @backstage/plugin-auth-backend-module-gitlab-provider@0.2.0 + - @backstage/plugin-auth-backend-module-google-provider@0.2.0 + - @backstage/plugin-auth-backend-module-oauth2-provider@0.3.0 + - @backstage/plugin-auth-backend-module-oidc-provider@0.3.0 + - @backstage/plugin-auth-backend-module-okta-provider@0.1.0 + - @backstage/plugin-auth-backend-module-onelogin-provider@0.2.0 + - @backstage/plugin-auth-backend-module-bitbucket-server-provider@0.1.0 + - @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.2.0 + - @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.3.0 + - @backstage/plugin-auth-backend-module-gcp-iap-provider@0.3.0 + - @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.2.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## 0.23.0-next.2 + +### Patch Changes + +- 527d973: Migrated the `Bitbucket Server` auth provider to be implemented using the new `@backstage/plugin-auth-backend-module-bitbucket-server-provider` module. +- d908d8c: Migrated the `Auth0` auth provider to be implemented using the new `@backstage/plugin-auth-backend-module-auth0-provider` module. +- 92118cd: Updated dependency `@node-saml/passport-saml` to `^5.0.0`. +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-client@1.7.0-next.1 + - @backstage/plugin-auth-backend-module-auth0-provider@0.1.0-next.0 + - @backstage/plugin-auth-backend-module-atlassian-provider@0.3.0-next.2 + - @backstage/plugin-auth-backend-module-bitbucket-provider@0.2.0-next.2 + - @backstage/plugin-auth-backend-module-github-provider@0.2.0-next.2 + - @backstage/plugin-auth-backend-module-gitlab-provider@0.2.0-next.2 + - @backstage/plugin-auth-backend-module-google-provider@0.2.0-next.2 + - @backstage/plugin-auth-backend-module-microsoft-provider@0.2.0-next.2 + - @backstage/plugin-auth-backend-module-oauth2-provider@0.3.0-next.2 + - @backstage/plugin-auth-backend-module-oidc-provider@0.3.0-next.2 + - @backstage/plugin-auth-backend-module-okta-provider@0.1.0-next.2 + - @backstage/plugin-auth-backend-module-onelogin-provider@0.2.0-next.2 + - @backstage/plugin-auth-backend-module-bitbucket-server-provider@0.1.0-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-backend-module-aws-alb-provider@0.2.0-next.2 + - @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.2.0-next.2 + - @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.3.0-next.2 + - @backstage/plugin-auth-backend-module-gcp-iap-provider@0.3.0-next.2 + - @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.2.0-next.2 + - @backstage/plugin-catalog-node@1.12.7-next.2 + ## 0.23.0-next.1 ### Patch Changes diff --git a/plugins/auth-backend/package.json b/plugins/auth-backend/package.json index f090b86f4e..3dcabee5eb 100644 --- a/plugins/auth-backend/package.json +++ b/plugins/auth-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend", - "version": "0.23.0-next.1", + "version": "0.23.1-next.0", "description": "A Backstage backend plugin that handles authentication", "backstage": { "role": "backend-plugin", @@ -43,16 +43,18 @@ "test": "backstage-cli package test" }, "dependencies": { - "@backstage/backend-common": "workspace:^", + "@backstage/backend-common": "^0.25.0", "@backstage/backend-plugin-api": "workspace:^", "@backstage/catalog-client": "workspace:^", "@backstage/catalog-model": "workspace:^", "@backstage/config": "workspace:^", "@backstage/errors": "workspace:^", "@backstage/plugin-auth-backend-module-atlassian-provider": "workspace:^", + "@backstage/plugin-auth-backend-module-auth0-provider": "workspace:^", "@backstage/plugin-auth-backend-module-aws-alb-provider": "workspace:^", "@backstage/plugin-auth-backend-module-azure-easyauth-provider": "workspace:^", "@backstage/plugin-auth-backend-module-bitbucket-provider": "workspace:^", + "@backstage/plugin-auth-backend-module-bitbucket-server-provider": "workspace:^", "@backstage/plugin-auth-backend-module-cloudflare-access-provider": "workspace:^", "@backstage/plugin-auth-backend-module-gcp-iap-provider": "workspace:^", "@backstage/plugin-auth-backend-module-github-provider": "workspace:^", @@ -68,7 +70,7 @@ "@backstage/plugin-catalog-node": "workspace:^", "@backstage/types": "workspace:^", "@google-cloud/firestore": "^7.0.0", - "@node-saml/passport-saml": "^4.0.4", + "@node-saml/passport-saml": "^5.0.0", "@types/express": "^4.17.6", "@types/passport": "^1.0.3", "compression": "^1.7.4", @@ -115,7 +117,7 @@ "@types/passport-strategy": "^0.2.35", "@types/xml2js": "^0.4.7", "msw": "^1.0.0", - "supertest": "^6.1.3" + "supertest": "^7.0.0" }, "configSchema": "config.d.ts" } diff --git a/plugins/auth-backend/api-report.md b/plugins/auth-backend/report.api.md similarity index 76% rename from plugins/auth-backend/api-report.md rename to plugins/auth-backend/report.api.md index 51f80024ae..80976525d3 100644 --- a/plugins/auth-backend/api-report.md +++ b/plugins/auth-backend/report.api.md @@ -108,7 +108,7 @@ export type BitbucketPassportProfile = Profile & { }; }; -// @public (undocumented) +// @public @deprecated (undocumented) export type BitbucketServerOAuthResult = { fullProfile: Profile; params: { @@ -700,4 +700,68 @@ export const verifyNonce: (req: express.Request, providerId: string) => void; // @public @deprecated (undocumented) export type WebMessageResponse = WebMessageResponse_2; + +// Warnings were encountered during analysis: +// +// src/identity/types.d.ts:13:1 - (ae-undocumented) Missing documentation for "TokenParams". +// src/lib/flow/authFlowHelpers.d.ts:8:22 - (ae-undocumented) Missing documentation for "postMessageResponse". +// src/lib/flow/authFlowHelpers.d.ts:13:22 - (ae-undocumented) Missing documentation for "ensuresXRequestedWith". +// src/lib/flow/types.d.ts:6:1 - (ae-undocumented) Missing documentation for "WebMessageResponse". +// src/lib/oauth/OAuthAdapter.d.ts:10:1 - (ae-undocumented) Missing documentation for "OAuthAdapterOptions". +// src/lib/oauth/OAuthAdapter.d.ts:23:1 - (ae-undocumented) Missing documentation for "OAuthAdapter". +// src/lib/oauth/OAuthAdapter.d.ts:26:5 - (ae-undocumented) Missing documentation for "fromConfig". +// src/lib/oauth/OAuthAdapter.d.ts:29:5 - (ae-undocumented) Missing documentation for "start". +// src/lib/oauth/OAuthAdapter.d.ts:30:5 - (ae-undocumented) Missing documentation for "frameHandler". +// src/lib/oauth/OAuthAdapter.d.ts:31:5 - (ae-undocumented) Missing documentation for "logout". +// src/lib/oauth/OAuthAdapter.d.ts:32:5 - (ae-undocumented) Missing documentation for "refresh". +// src/lib/oauth/OAuthEnvironmentHandler.d.ts:6:22 - (ae-undocumented) Missing documentation for "OAuthEnvironmentHandler". +// src/lib/oauth/helpers.d.ts:7:22 - (ae-undocumented) Missing documentation for "readState". +// src/lib/oauth/helpers.d.ts:12:22 - (ae-undocumented) Missing documentation for "encodeState". +// src/lib/oauth/helpers.d.ts:17:22 - (ae-undocumented) Missing documentation for "verifyNonce". +// src/lib/oauth/types.d.ts:29:1 - (ae-undocumented) Missing documentation for "OAuthResult". +// src/lib/oauth/types.d.ts:44:1 - (ae-undocumented) Missing documentation for "OAuthResponse". +// src/lib/oauth/types.d.ts:53:1 - (ae-undocumented) Missing documentation for "OAuthProviderInfo". +// src/lib/oauth/types.d.ts:75:1 - (ae-undocumented) Missing documentation for "OAuthState". +// src/lib/oauth/types.d.ts:80:1 - (ae-undocumented) Missing documentation for "OAuthStartRequest". +// src/lib/oauth/types.d.ts:88:1 - (ae-undocumented) Missing documentation for "OAuthRefreshRequest". +// src/lib/oauth/types.d.ts:96:1 - (ae-undocumented) Missing documentation for "OAuthLogoutRequest". +// src/lib/oauth/types.d.ts:103:1 - (ae-undocumented) Missing documentation for "OAuthHandlers". +// src/providers/azure-easyauth/index.d.ts:7:1 - (ae-undocumented) Missing documentation for "EasyAuthResult". +// src/providers/bitbucket/provider.d.ts:9:1 - (ae-undocumented) Missing documentation for "BitbucketOAuthResult". +// src/providers/bitbucket/provider.d.ts:23:1 - (ae-undocumented) Missing documentation for "BitbucketPassportProfile". +// src/providers/bitbucketServer/provider.d.ts:9:1 - (ae-undocumented) Missing documentation for "BitbucketServerOAuthResult". +// src/providers/cloudflare-access/provider.d.ts:90:1 - (ae-undocumented) Missing documentation for "CloudflareAccessResult". +// src/providers/github/provider.d.ts:5:1 - (ae-undocumented) Missing documentation for "GithubOAuthResult". +// src/providers/oauth2-proxy/index.d.ts:7:1 - (ae-undocumented) Missing documentation for "OAuth2ProxyResult". +// src/providers/oidc/index.d.ts:7:1 - (ae-undocumented) Missing documentation for "OidcAuthResult". +// src/providers/prepareBackstageIdentityResponse.d.ts:6:22 - (ae-undocumented) Missing documentation for "prepareBackstageIdentityResponse". +// src/providers/router.d.ts:9:1 - (ae-undocumented) Missing documentation for "ProviderFactories". +// src/providers/router.d.ts:27:1 - (ae-undocumented) Missing documentation for "createOriginFilter". +// src/providers/saml/provider.d.ts:6:1 - (ae-undocumented) Missing documentation for "SamlAuthResult". +// src/providers/types.d.ts:7:1 - (ae-undocumented) Missing documentation for "AuthResolverCatalogUserQuery". +// src/providers/types.d.ts:12:1 - (ae-undocumented) Missing documentation for "AuthResolverContext". +// src/providers/types.d.ts:17:1 - (ae-undocumented) Missing documentation for "CookieConfigurer". +// src/providers/types.d.ts:22:1 - (ae-undocumented) Missing documentation for "OAuthStartResponse". +// src/providers/types.d.ts:36:1 - (ae-undocumented) Missing documentation for "AuthProviderConfig". +// src/providers/types.d.ts:41:1 - (ae-undocumented) Missing documentation for "AuthProviderRouteHandlers". +// src/providers/types.d.ts:46:1 - (ae-undocumented) Missing documentation for "AuthProviderFactory". +// src/providers/types.d.ts:51:1 - (ae-undocumented) Missing documentation for "AuthResponse". +// src/providers/types.d.ts:56:1 - (ae-undocumented) Missing documentation for "ProfileInfo". +// src/providers/types.d.ts:61:1 - (ae-undocumented) Missing documentation for "SignInInfo". +// src/providers/types.d.ts:66:1 - (ae-undocumented) Missing documentation for "SignInResolver". +// src/providers/types.d.ts:96:1 - (ae-undocumented) Missing documentation for "StateEncoder". +// src/service/router.d.ts:11:1 - (ae-undocumented) Missing documentation for "RouterOptions". +// src/service/router.d.ts:12:5 - (ae-undocumented) Missing documentation for "logger". +// src/service/router.d.ts:13:5 - (ae-undocumented) Missing documentation for "database". +// src/service/router.d.ts:14:5 - (ae-undocumented) Missing documentation for "config". +// src/service/router.d.ts:15:5 - (ae-undocumented) Missing documentation for "discovery". +// src/service/router.d.ts:16:5 - (ae-undocumented) Missing documentation for "tokenManager". +// src/service/router.d.ts:17:5 - (ae-undocumented) Missing documentation for "auth". +// src/service/router.d.ts:18:5 - (ae-undocumented) Missing documentation for "httpAuth". +// src/service/router.d.ts:19:5 - (ae-undocumented) Missing documentation for "tokenFactoryAlgorithm". +// src/service/router.d.ts:20:5 - (ae-undocumented) Missing documentation for "providerFactories". +// src/service/router.d.ts:21:5 - (ae-undocumented) Missing documentation for "disableDefaultProviderFactories". +// src/service/router.d.ts:22:5 - (ae-undocumented) Missing documentation for "catalogApi". +// src/service/router.d.ts:23:5 - (ae-undocumented) Missing documentation for "ownershipResolver". +// src/service/router.d.ts:29:1 - (ae-undocumented) Missing documentation for "createRouter". ``` diff --git a/plugins/auth-backend/src/lib/catalog/CatalogIdentityClient.test.ts b/plugins/auth-backend/src/lib/catalog/CatalogIdentityClient.test.ts index 3439578d5e..2cd58d692f 100644 --- a/plugins/auth-backend/src/lib/catalog/CatalogIdentityClient.test.ts +++ b/plugins/auth-backend/src/lib/catalog/CatalogIdentityClient.test.ts @@ -15,28 +15,15 @@ */ import { TokenManager } from '@backstage/backend-common'; -import { CatalogApi } from '@backstage/catalog-client'; import { RELATION_MEMBER_OF, UserEntity, UserEntityV1alpha1, } from '@backstage/catalog-model'; +import { catalogServiceMock } from '@backstage/plugin-catalog-node/testUtils'; import { CatalogIdentityClient } from './CatalogIdentityClient'; describe('CatalogIdentityClient', () => { - const catalogApi = { - getLocationById: jest.fn(), - getEntityByRef: jest.fn(), - getEntities: jest.fn(), - addLocation: jest.fn(), - removeLocationById: jest.fn(), - getLocationByRef: jest.fn(), - removeEntityByUid: jest.fn(), - refreshEntity: jest.fn(), - getEntityAncestors: jest.fn(), - getEntityFacets: jest.fn(), - validateEntity: jest.fn(), - }; const tokenManager: jest.Mocked = { getToken: jest.fn(), authenticate: jest.fn(), @@ -45,11 +32,15 @@ describe('CatalogIdentityClient', () => { afterEach(() => jest.resetAllMocks()); it('findUser passes through the correct search params', async () => { - catalogApi.getEntities.mockResolvedValueOnce({ items: [{} as UserEntity] }); + const catalogApi = catalogServiceMock.mock({ + getEntities: jest + .fn() + .mockResolvedValueOnce({ items: [{} as UserEntity] }), + }); tokenManager.getToken.mockResolvedValue({ token: 'my-token' }); const client = new CatalogIdentityClient({ discovery: {} as any, - catalogApi: catalogApi as Partial as CatalogApi, + catalogApi, tokenManager, }); @@ -103,12 +94,14 @@ describe('CatalogIdentityClient', () => { ], }, ]; - catalogApi.getEntities.mockResolvedValueOnce({ items: mockUsers }); + const catalogApi = catalogServiceMock.mock({ + getEntities: jest.fn().mockResolvedValueOnce({ items: mockUsers }), + }); tokenManager.getToken.mockResolvedValue({ token: 'my-token' }); const client = new CatalogIdentityClient({ discovery: {} as any, - catalogApi: catalogApi as Partial as CatalogApi, + catalogApi, tokenManager, }); diff --git a/plugins/auth-backend/src/providers/auth0/provider.ts b/plugins/auth-backend/src/providers/auth0/provider.ts index c399eb08c4..44e7c5bb6e 100644 --- a/plugins/auth-backend/src/providers/auth0/provider.ts +++ b/plugins/auth-backend/src/providers/auth0/provider.ts @@ -14,40 +14,25 @@ * limitations under the License. */ -import express from 'express'; -import passport from 'passport'; -import Auth0Strategy from './strategy'; -import { - OAuthAdapter, - OAuthProviderOptions, - OAuthHandlers, - OAuthResponse, - OAuthEnvironmentHandler, - OAuthStartRequest, - encodeState, - OAuthRefreshRequest, - OAuthResult, -} from '../../lib/oauth'; -import { - executeFetchUserProfileStrategy, - executeFrameHandlerStrategy, - executeRedirectStrategy, - executeRefreshTokenStrategy, - makeProfileInfo, - PassportDoneCallback, -} from '../../lib/passport'; -import { OAuthStartResponse, AuthHandler } from '../types'; +import { OAuthProviderOptions, OAuthResult } from '../../lib/oauth'; + +import { AuthHandler } from '../types'; import { createAuthProviderIntegration } from '../createAuthProviderIntegration'; -import { StateStore } from 'passport-oauth2'; import { AuthResolverContext, + createOAuthProviderFactory, SignInResolver, } from '@backstage/plugin-auth-node'; +import { + adaptLegacyOAuthHandler, + adaptLegacyOAuthSignInResolver, +} from '../../lib/legacy'; +import { auth0Authenticator } from '@backstage/plugin-auth-backend-module-auth0-provider'; -type PrivateInfo = { - refreshToken: string; -}; - +/** + * @public + * @deprecated The Auth0 auth provider was extracted to `@backstage/plugin-auth-backend-module-auth0-provider`. + */ export type Auth0AuthProviderOptions = OAuthProviderOptions & { domain: string; signInResolver?: SignInResolver; @@ -58,155 +43,6 @@ export type Auth0AuthProviderOptions = OAuthProviderOptions & { connectionScope?: string; }; -export class Auth0AuthProvider implements OAuthHandlers { - private readonly _strategy: Auth0Strategy; - private readonly signInResolver?: SignInResolver; - private readonly authHandler: AuthHandler; - private readonly resolverContext: AuthResolverContext; - private readonly audience?: string; - private readonly connection?: string; - private readonly connectionScope?: string; - - /** - * Due to passport-auth0 forcing options.state = true, - * passport-oauth2 requires express-session to be installed - * so that the 'state' parameter of the oauth2 flow can be stored. - * This implementation of StateStore matches the NullStore found within - * passport-oauth2, which is the StateStore implementation used when options.state = false, - * allowing us to avoid using express-session in order to integrate with auth0. - */ - private store: StateStore = { - store(_req: express.Request, cb: any) { - cb(null, null); - }, - verify(_req: express.Request, _state: string, cb: any) { - cb(null, true); - }, - }; - - constructor(options: Auth0AuthProviderOptions) { - this.signInResolver = options.signInResolver; - this.authHandler = options.authHandler; - this.resolverContext = options.resolverContext; - this.audience = options.audience; - this.connection = options.connection; - this.connectionScope = options.connectionScope; - this._strategy = new Auth0Strategy( - { - clientID: options.clientId, - clientSecret: options.clientSecret, - callbackURL: options.callbackUrl, - domain: options.domain, - // We need passReqToCallback set to false to get params, but there's - // no matching type signature for that, so instead behold this beauty - passReqToCallback: false as true, - store: this.store, - }, - ( - accessToken: any, - refreshToken: any, - params: any, - fullProfile: passport.Profile, - done: PassportDoneCallback, - ) => { - done( - undefined, - { - fullProfile, - accessToken, - refreshToken, - params, - }, - { - refreshToken, - }, - ); - }, - ); - } - - async start(req: OAuthStartRequest): Promise { - return await executeRedirectStrategy(req, this._strategy, { - accessType: 'offline', - prompt: 'consent', - scope: req.scope, - state: encodeState(req.state), - ...(this.audience ? { audience: this.audience } : {}), - ...(this.connection ? { connection: this.connection } : {}), - ...(this.connectionScope - ? { connection_scope: this.connectionScope } - : {}), - }); - } - - async handler(req: express.Request) { - const { result, privateInfo } = await executeFrameHandlerStrategy< - OAuthResult, - PrivateInfo - >(req, this._strategy, { - ...(this.audience ? { audience: this.audience } : {}), - ...(this.connection ? { connection: this.connection } : {}), - ...(this.connectionScope - ? { connection_scope: this.connectionScope } - : {}), - }); - - 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, - ); - - const fullProfile = await executeFetchUserProfileStrategy( - this._strategy, - accessToken, - ); - - return { - response: await this.handleResult({ - fullProfile, - params, - accessToken, - }), - refreshToken, - }; - } - - private async handleResult(result: OAuthResult) { - const { profile } = await this.authHandler(result, this.resolverContext); - - const response: OAuthResponse = { - providerInfo: { - idToken: result.params.id_token, - accessToken: result.accessToken, - scope: result.params.scope, - expiresInSeconds: result.params.expires_in, - }, - profile, - }; - - if (this.signInResolver) { - response.backstageIdentity = await this.signInResolver( - { - result, - profile, - }, - this.resolverContext, - ); - } - - return response; - } -} - /** * Auth provider integration for auth0 auth * @@ -230,44 +66,10 @@ export const auth0 = createAuthProviderIntegration({ resolver: SignInResolver; }; }) { - return ({ providerId, globalConfig, config, resolverContext }) => - OAuthEnvironmentHandler.mapConfig(config, envConfig => { - const clientId = envConfig.getString('clientId'); - const clientSecret = envConfig.getString('clientSecret'); - const domain = envConfig.getString('domain'); - const customCallbackUrl = envConfig.getOptionalString('callbackUrl'); - const audience = envConfig.getOptionalString('audience'); - const connection = envConfig.getOptionalString('connection'); - const connectionScope = envConfig.getOptionalString('connectionScope'); - const callbackUrl = - customCallbackUrl || - `${globalConfig.baseUrl}/${providerId}/handler/frame`; - - const authHandler: AuthHandler = options?.authHandler - ? options.authHandler - : async ({ fullProfile, params }) => ({ - profile: makeProfileInfo(fullProfile, params.id_token), - }); - - const signInResolver = options?.signIn?.resolver; - - const provider = new Auth0AuthProvider({ - clientId, - clientSecret, - callbackUrl, - domain, - authHandler, - signInResolver, - resolverContext, - audience, - connection, - connectionScope, - }); - - return OAuthAdapter.fromConfig(globalConfig, provider, { - providerId, - callbackUrl, - }); - }); + return createOAuthProviderFactory({ + authenticator: auth0Authenticator, + profileTransform: adaptLegacyOAuthHandler(options?.authHandler), + signInResolver: adaptLegacyOAuthSignInResolver(options?.signIn?.resolver), + }); }, }); diff --git a/plugins/auth-backend/src/providers/bitbucketServer/provider.test.ts b/plugins/auth-backend/src/providers/bitbucketServer/provider.test.ts deleted file mode 100644 index 3756e00b38..0000000000 --- a/plugins/auth-backend/src/providers/bitbucketServer/provider.test.ts +++ /dev/null @@ -1,390 +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 * as helpers from '../../lib/passport/PassportStrategyHelper'; -import { makeProfileInfo } from '../../lib/passport'; -import { - bitbucketServer, - BitbucketServerAuthProvider, - BitbucketServerOAuthResult, -} from './provider'; -import { setupServer } from 'msw/node'; -import { registerMswTestHooks } from '@backstage/backend-test-utils'; -import { rest } from 'msw'; -import { AuthResolverContext } from '@backstage/plugin-auth-node'; - -jest.mock('../../lib/passport/PassportStrategyHelper', () => { - return { - ...jest.requireActual('../../lib/passport/PassportStrategyHelper'), - executeFrameHandlerStrategy: jest.fn(), - executeRefreshTokenStrategy: jest.fn(), - executeFetchUserProfileStrategy: jest.fn(), - }; -}); - -const mockFrameHandler = jest.spyOn( - helpers, - 'executeFrameHandlerStrategy', -) as unknown as jest.MockedFunction< - () => Promise<{ - result: BitbucketServerOAuthResult; - privateInfo: { refreshToken?: string }; - }> ->; - -const passportProfile = { - id: '123', - username: 'john.doe', - provider: 'bitubcketServer', - displayName: 'John Doe', - emails: [{ value: 'john@doe.com' }], - photos: [{ value: 'https://bitbucket.org/user/123/avatar' }], -}; - -const mockHost = 'bitbucket.org'; -const mockBaseUrl = `https://${mockHost}`; - -const whoAmIHandler = (options?: { fail?: boolean; value?: string }) => - rest.get( - `${mockBaseUrl}/plugins/servlet/applinks/whoami`, - (_req, res, ctx) => { - if (options?.fail) { - res.networkError('error'); - } - return res( - ctx.status(200), - ctx.set('X-Ausername', options?.value ?? passportProfile.username), - ); - }, - ); - -const getUserHandler = (options?: { - fail?: boolean; - status?: number; - avatarUrl?: string; - noDisplayName?: boolean; - noUserName?: boolean; -}) => - rest.get( - `${mockBaseUrl}/rest/api/latest/users/${passportProfile.username}`, - (_req, res, ctx) => { - if (options?.fail) { - res.networkError('error'); - } - return res( - ctx.status(options?.status ?? 200), - ctx.json({ - name: options?.noUserName ? undefined : 'john.doe', - emailAddress: 'john@doe.com', - id: 123, - displayName: options?.noDisplayName ? undefined : 'John Doe', - active: true, - slug: 'john.doe', - type: 'NORMAL', - links: { - self: [ - { - href: 'https://bitbucket.org/users/john.doe', - }, - ], - }, - avatarUrl: options?.avatarUrl ?? '/user/123/avatar', - }), - ); - }, - ); - -describe('BitbucketServerAuthProvider', () => { - const provider = new BitbucketServerAuthProvider({ - resolverContext: { - signInWithCatalogUser: jest.fn(info => { - return { - token: `token-for-user:${info.filter['spec.profile.email']}`, - }; - }), - } as unknown as AuthResolverContext, - signInResolver: - bitbucketServer.resolvers.emailMatchingUserEntityProfileEmail(), - authHandler: async ({ fullProfile }) => ({ - profile: makeProfileInfo(fullProfile), - }), - callbackUrl: 'mock', - clientId: 'mock', - clientSecret: 'mock', - host: mockHost, - authorizationUrl: 'mock', - tokenUrl: 'mock', - }); - - describe('when transforming to type OAuthResponse', () => { - const server = setupServer(); - registerMswTestHooks(server); - - it('should map to a valid response', async () => { - server.use(whoAmIHandler(), getUserHandler()); - - const accessToken = '19xasczxcm9n7gacn9jdgm19me'; - const params = { scope: 'REPO_READ' }; - - const expected = { - backstageIdentity: { - token: 'token-for-user:john@doe.com', - }, - providerInfo: { - accessToken: '19xasczxcm9n7gacn9jdgm19me', - scope: 'REPO_READ', - }, - profile: { - email: 'john@doe.com', - displayName: 'John Doe', - picture: 'https://bitbucket.org/user/123/avatar', - }, - }; - - mockFrameHandler.mockResolvedValueOnce({ - result: { fullProfile: passportProfile, accessToken, params }, - privateInfo: {}, - }); - const { response } = await provider.handler({} as any); - expect(response).toEqual(expected); - }); - - it('should throw if whoami fails', async () => { - server.use(whoAmIHandler({ fail: true }), getUserHandler()); - - const accessToken = '19xasczxcm9n7gacn9jdgm19me'; - const params = { scope: 'REPO_READ' }; - mockFrameHandler.mockResolvedValueOnce({ - result: { fullProfile: passportProfile, accessToken, params }, - privateInfo: {}, - }); - - await expect(provider.handler({} as any)).rejects.toThrow( - `Failed to retrieve the username of the logged in user`, - ); - }); - - it('should throw if whoami returns an invalid response', async () => { - server.use(whoAmIHandler({ value: '' }), getUserHandler()); - - const accessToken = '19xasczxcm9n7gacn9jdgm19me'; - const params = { scope: 'REPO_READ' }; - mockFrameHandler.mockResolvedValueOnce({ - result: { fullProfile: passportProfile, accessToken, params }, - privateInfo: {}, - }); - - await expect(provider.handler({} as any)).rejects.toThrow( - `Failed to retrieve the username of the logged in user`, - ); - }); - - it('should throw if get user fails', async () => { - server.use(whoAmIHandler(), getUserHandler({ fail: true })); - const accessToken = '19xasczxcm9n7gacn9jdgm19me'; - const params = { scope: 'REPO_READ' }; - mockFrameHandler.mockResolvedValueOnce({ - result: { fullProfile: passportProfile, accessToken, params }, - privateInfo: {}, - }); - - await expect(provider.handler({} as any)).rejects.toThrow( - `Failed to retrieve the user '${passportProfile.username}'`, - ); - }); - - it('should throw if get user is not ok', async () => { - server.use(whoAmIHandler(), getUserHandler({ status: 500 })); - const accessToken = '19xasczxcm9n7gacn9jdgm19me'; - const params = { scope: 'REPO_READ' }; - mockFrameHandler.mockResolvedValueOnce({ - result: { fullProfile: passportProfile, accessToken, params }, - privateInfo: {}, - }); - - await expect(provider.handler({} as any)).rejects.toThrow( - `Failed to retrieve the user '${passportProfile.username}'`, - ); - }); - - it('should not set an avatar url if not given', async () => { - server.use(whoAmIHandler(), getUserHandler({ avatarUrl: '' })); - const accessToken = '19xasczxcm9n7gacn9jdgm19me'; - const params = { scope: 'REPO_READ' }; - - const expected = { - backstageIdentity: { - token: 'token-for-user:john@doe.com', - }, - providerInfo: { - accessToken: '19xasczxcm9n7gacn9jdgm19me', - scope: 'REPO_READ', - }, - profile: { - email: 'john@doe.com', - displayName: 'John Doe', - }, - }; - - mockFrameHandler.mockResolvedValueOnce({ - result: { fullProfile: passportProfile, accessToken, params }, - privateInfo: {}, - }); - const { response } = await provider.handler({} as any); - expect(response).toEqual(expected); - }); - - it('should fallback to the username if no displayName is given', async () => { - server.use(whoAmIHandler(), getUserHandler({ noDisplayName: true })); - - const accessToken = '19xasczxcm9n7gacn9jdgm19me'; - const params = { scope: 'REPO_READ' }; - - const expected = { - backstageIdentity: { - token: 'token-for-user:john@doe.com', - }, - providerInfo: { - accessToken: '19xasczxcm9n7gacn9jdgm19me', - scope: 'REPO_READ', - }, - profile: { - email: 'john@doe.com', - displayName: 'john.doe', - picture: 'https://bitbucket.org/user/123/avatar', - }, - }; - - mockFrameHandler.mockResolvedValueOnce({ - result: { fullProfile: passportProfile, accessToken, params }, - privateInfo: {}, - }); - const { response } = await provider.handler({} as any); - expect(response).toEqual(expected); - }); - - it('should fallback to the user id if no name is given', async () => { - server.use( - whoAmIHandler(), - getUserHandler({ noDisplayName: true, noUserName: true }), - ); - - const accessToken = '19xasczxcm9n7gacn9jdgm19me'; - const params = { scope: 'REPO_READ' }; - - const expected = { - backstageIdentity: { - token: 'token-for-user:john@doe.com', - }, - providerInfo: { - accessToken: '19xasczxcm9n7gacn9jdgm19me', - scope: 'REPO_READ', - }, - profile: { - email: 'john@doe.com', - displayName: '123', - picture: 'https://bitbucket.org/user/123/avatar', - }, - }; - - mockFrameHandler.mockResolvedValueOnce({ - result: { fullProfile: passportProfile, accessToken, params }, - privateInfo: {}, - }); - const { response } = await provider.handler({} as any); - expect(response).toEqual(expected); - }); - }); - - describe('when authenticating', () => { - const server = setupServer(); - registerMswTestHooks(server); - - it('should forward the refresh token', async () => { - server.use(whoAmIHandler(), getUserHandler()); - - const accessToken = '19xasczxcm9n7gacn9jdgm19me'; - const params = { scope: 'REPO_READ' }; - mockFrameHandler.mockResolvedValueOnce({ - result: { fullProfile: passportProfile, accessToken, params }, - privateInfo: { refreshToken: 'refresh-token' }, - }); - - const response = await provider.handler({} as any); - - const expected = { - response: { - backstageIdentity: { - token: 'token-for-user:john@doe.com', - }, - providerInfo: { - accessToken: '19xasczxcm9n7gacn9jdgm19me', - scope: 'REPO_READ', - }, - profile: { - email: 'john@doe.com', - displayName: 'John Doe', - picture: 'https://bitbucket.org/user/123/avatar', - }, - }, - refreshToken: 'refresh-token', - }; - - expect(response).toEqual(expected); - }); - - it('should forward a new refresh token on refresh', async () => { - server.use(whoAmIHandler(), getUserHandler()); - - const accessToken = '19xasczxcm9n7gacn9jdgm19me'; - const params = { scope: 'REPO_READ' }; - const mockRefreshToken = jest.spyOn( - helpers, - 'executeRefreshTokenStrategy', - ) as unknown as jest.MockedFunction<() => Promise<{}>>; - mockRefreshToken.mockResolvedValueOnce({ - accessToken, - refreshToken: 'dont-forget-to-send-refresh', - params, - }); - mockFrameHandler.mockResolvedValueOnce({ - result: { fullProfile: passportProfile, accessToken, params }, - privateInfo: { refreshToken: 'refresh-token' }, - }); - - const expected = { - response: { - backstageIdentity: { - token: 'token-for-user:john@doe.com', - }, - providerInfo: { - accessToken: '19xasczxcm9n7gacn9jdgm19me', - scope: 'REPO_READ', - }, - profile: { - email: 'john@doe.com', - displayName: 'John Doe', - picture: 'https://bitbucket.org/user/123/avatar', - }, - }, - refreshToken: 'dont-forget-to-send-refresh', - }; - const response = await provider.refresh({ scope: 'REPO_WRITE' } as any); - - expect(response).toEqual(expected); - }); - }); -}); diff --git a/plugins/auth-backend/src/providers/bitbucketServer/provider.ts b/plugins/auth-backend/src/providers/bitbucketServer/provider.ts index d66f7f33c0..c49cf5b7b1 100644 --- a/plugins/auth-backend/src/providers/bitbucketServer/provider.ts +++ b/plugins/auth-backend/src/providers/bitbucketServer/provider.ts @@ -14,40 +14,28 @@ * limitations under the License. */ -import { - encodeState, - OAuthAdapter, - OAuthEnvironmentHandler, - OAuthHandlers, - OAuthProviderOptions, - OAuthRefreshRequest, - OAuthResponse, - OAuthStartRequest, -} from '../../lib/oauth'; -import { Strategy as OAuth2Strategy, VerifyCallback } from 'passport-oauth2'; -import { - executeFetchUserProfileStrategy, - executeFrameHandlerStrategy, - executeRedirectStrategy, - executeRefreshTokenStrategy, - makeProfileInfo, -} from '../../lib/passport'; -import { AuthHandler, OAuthStartResponse } from '../types'; -import express from 'express'; -import { createAuthProviderIntegration } from '../createAuthProviderIntegration'; import { Profile as PassportProfile } from 'passport'; -import { commonByEmailResolver } from '../resolvers'; -import fetch from 'node-fetch'; import { AuthResolverContext, + createOAuthProviderFactory, SignInResolver, } from '@backstage/plugin-auth-node'; +import { + bitbucketServerAuthenticator, + bitbucketServerSignInResolvers, +} from '@backstage/plugin-auth-backend-module-bitbucket-server-provider'; +import { OAuthProviderOptions } from '../../lib/oauth'; +import { + adaptLegacyOAuthHandler, + adaptLegacyOAuthSignInResolver, +} from '../../lib/legacy'; +import { AuthHandler } from '../types'; +import { createAuthProviderIntegration } from '../createAuthProviderIntegration'; -type PrivateInfo = { - refreshToken: string; -}; - -/** @public */ +/** + * @public + * @deprecated The Bitbucket Server auth provider was extracted to `@backstage/plugin-auth-backend-module-bitbucket-server-provider`. + */ export type BitbucketServerOAuthResult = { fullProfile: PassportProfile; params: { @@ -60,6 +48,10 @@ export type BitbucketServerOAuthResult = { refreshToken?: string; }; +/** + * @public + * @deprecated The Bitbucket Server auth provider was extracted to `@backstage/plugin-auth-backend-module-bitbucket-server-provider`. + */ export type BitbucketServerAuthProviderOptions = OAuthProviderOptions & { host: string; authorizationUrl: string; @@ -69,176 +61,6 @@ export type BitbucketServerAuthProviderOptions = OAuthProviderOptions & { resolverContext: AuthResolverContext; }; -export class BitbucketServerAuthProvider implements OAuthHandlers { - private readonly signInResolver?: SignInResolver; - private readonly authHandler: AuthHandler; - private readonly resolverContext: AuthResolverContext; - private readonly strategy: OAuth2Strategy; - private readonly host: string; - - constructor(options: BitbucketServerAuthProviderOptions) { - this.signInResolver = options.signInResolver; - this.authHandler = options.authHandler; - this.resolverContext = options.resolverContext; - this.strategy = new OAuth2Strategy( - { - authorizationURL: options.authorizationUrl, - tokenURL: options.tokenUrl, - clientID: options.clientId, - clientSecret: options.clientSecret, - callbackURL: options.callbackUrl, - }, - ( - accessToken: string, - refreshToken: string, - params: any, - fullProfile: PassportProfile, - done: VerifyCallback, - ) => { - done(undefined, { fullProfile, params, accessToken }, { refreshToken }); - }, - ); - this.host = options.host; - } - - async start(req: OAuthStartRequest): Promise { - return await executeRedirectStrategy(req, this.strategy, { - accessType: 'offline', - prompt: 'consent', - scope: req.scope, - state: encodeState(req.state), - }); - } - - async handler( - req: express.Request, - ): Promise<{ response: OAuthResponse; refreshToken?: string }> { - const { result, privateInfo } = await executeFrameHandlerStrategy< - BitbucketServerOAuthResult, - PrivateInfo - >(req, this.strategy); - - return { - response: await this.handleResult(result), - refreshToken: privateInfo.refreshToken, - }; - } - - async refresh( - req: OAuthRefreshRequest, - ): Promise<{ response: OAuthResponse; refreshToken?: string }> { - const { accessToken, refreshToken, params } = - await executeRefreshTokenStrategy( - this.strategy, - req.refreshToken, - req.scope, - ); - const fullProfile = await executeFetchUserProfileStrategy( - this.strategy, - accessToken, - ); - return { - response: await this.handleResult({ - fullProfile, - params, - accessToken, - }), - refreshToken, - }; - } - - private async handleResult( - result: BitbucketServerOAuthResult, - ): Promise { - // The OAuth2 strategy does not return a user profile -> let's fetch it before calling the auth handler - result.fullProfile = await this.fetchProfile(result); - const { profile } = await this.authHandler(result, this.resolverContext); - - let backstageIdentity = undefined; - if (this.signInResolver) { - backstageIdentity = await this.signInResolver( - { result, profile }, - this.resolverContext, - ); - } - - return { - providerInfo: { - accessToken: result.accessToken, - scope: result.params.scope, - expiresInSeconds: result.params.expires_in, - }, - profile, - backstageIdentity, - }; - } - - private async fetchProfile( - result: BitbucketServerOAuthResult, - ): Promise { - // Get current user name - let whoAmIResponse; - try { - whoAmIResponse = await fetch( - `https://${this.host}/plugins/servlet/applinks/whoami`, - { - headers: { - Authorization: `Bearer ${result.accessToken}`, - }, - }, - ); - } catch (e) { - throw new Error(`Failed to retrieve the username of the logged in user`); - } - - // A response.ok check here would be worthless as the Bitbucket API always returns 200 OK for this call - const username = whoAmIResponse.headers.get('X-Ausername'); - if (!username) { - throw new Error(`Failed to retrieve the username of the logged in user`); - } - - let userResponse; - try { - userResponse = await fetch( - `https://${this.host}/rest/api/latest/users/${username}?avatarSize=256`, - { - headers: { - Authorization: `Bearer ${result.accessToken}`, - }, - }, - ); - } catch (e) { - throw new Error(`Failed to retrieve the user '${username}'`); - } - - if (!userResponse.ok) { - throw new Error(`Failed to retrieve the user '${username}'`); - } - - const user = await userResponse.json(); - - const passportProfile = { - provider: 'bitbucketServer', - id: user.id.toString(), - displayName: user.displayName, - username: user.name, - emails: [ - { - value: user.emailAddress, - }, - ], - } as PassportProfile; - - if (user.avatarUrl) { - passportProfile.photos = [ - { value: `https://${this.host}${user.avatarUrl}` }, - ]; - } - - return passportProfile; - } -} - export const bitbucketServer = createAuthProviderIntegration({ create(options?: { /** @@ -257,48 +79,38 @@ export const bitbucketServer = createAuthProviderIntegration({ resolver: SignInResolver; }; }) { - return ({ providerId, globalConfig, config, resolverContext }) => - OAuthEnvironmentHandler.mapConfig(config, envConfig => { - const clientId = envConfig.getString('clientId'); - const clientSecret = envConfig.getString('clientSecret'); - const host = envConfig.getString('host'); - const customCallbackUrl = envConfig.getOptionalString('callbackUrl'); - const callbackUrl = - customCallbackUrl || - `${globalConfig.baseUrl}/${providerId}/handler/frame`; - const authorizationUrl = `https://${host}/rest/oauth2/latest/authorize`; - const tokenUrl = `https://${host}/rest/oauth2/latest/token`; - - const authHandler: AuthHandler = - options?.authHandler - ? options.authHandler - : async ({ fullProfile }) => ({ - profile: makeProfileInfo(fullProfile), - }); - - const provider = new BitbucketServerAuthProvider({ - callbackUrl, - clientId, - clientSecret, - host, - authorizationUrl, - tokenUrl, - authHandler, - signInResolver: options?.signIn?.resolver, - resolverContext, - }); - - return OAuthAdapter.fromConfig(globalConfig, provider, { - providerId, - callbackUrl, - }); - }); + return createOAuthProviderFactory({ + authenticator: bitbucketServerAuthenticator, + profileTransform: adaptLegacyOAuthHandler(options?.authHandler), + signInResolver: adaptLegacyOAuthSignInResolver(options?.signIn?.resolver), + }); }, resolvers: { /** * Looks up the user by matching their email to the entity email. */ emailMatchingUserEntityProfileEmail: - (): SignInResolver => commonByEmailResolver, + (): SignInResolver => { + const resolver = + bitbucketServerSignInResolvers.emailMatchingUserEntityProfileEmail(); + return async (info, ctx) => { + return resolver( + { + profile: info.profile, + result: { + fullProfile: info.result.fullProfile, + session: { + accessToken: info.result.accessToken, + tokenType: info.result.params.token_type ?? 'bearer', + scope: info.result.params.scope, + expiresInSeconds: info.result.params.expires_in, + refreshToken: info.result.refreshToken, + }, + }, + }, + ctx, + ); + }; + }, }, }); diff --git a/plugins/auth-backend/src/providers/cloudflare-access/provider.ts b/plugins/auth-backend/src/providers/cloudflare-access/provider.ts index 78036ee0cd..cbc9a99517 100644 --- a/plugins/auth-backend/src/providers/cloudflare-access/provider.ts +++ b/plugins/auth-backend/src/providers/cloudflare-access/provider.ts @@ -14,7 +14,6 @@ * limitations under the License. */ -import { CacheClient } from '@backstage/backend-common'; import { cloudflareAccessSignInResolvers, createCloudflareAccessAuthenticator, @@ -25,6 +24,7 @@ import { } from '@backstage/plugin-auth-node'; import { createAuthProviderIntegration } from '../createAuthProviderIntegration'; import { AuthHandler } from '../types'; +import { CacheService } from '@backstage/backend-plugin-api'; /** * CloudflareAccessClaims @@ -145,10 +145,10 @@ export const cfAccess = createAuthProviderIntegration({ }; /** - * CacheClient object that was configured for the Backstage backend, + * Cache service object that was configured for the Backstage backend, * should be provided via the backend auth plugin. */ - cache?: CacheClient; + cache?: CacheService; }) { return createProxyAuthProviderFactory({ authenticator: createCloudflareAccessAuthenticator({ diff --git a/plugins/auth-backend/src/providers/saml/provider.ts b/plugins/auth-backend/src/providers/saml/provider.ts index d922034e2f..83166456c7 100644 --- a/plugins/auth-backend/src/providers/saml/provider.ts +++ b/plugins/auth-backend/src/providers/saml/provider.ts @@ -172,7 +172,7 @@ export const saml = createAuthProviderIntegration({ logoutUrl: config.getOptionalString('logoutUrl'), audience: config.getString('audience'), issuer: config.getString('issuer'), - cert: config.getString('cert'), + idpCert: config.getString('cert'), privateKey: config.getOptionalString('privateKey'), authnContext: config.getOptionalStringArray('authnContext'), identifierFormat: config.getOptionalString('identifierFormat'), diff --git a/plugins/auth-node/CHANGELOG.md b/plugins/auth-node/CHANGELOG.md index 4565a93cf7..bcede6f788 100644 --- a/plugins/auth-node/CHANGELOG.md +++ b/plugins/auth-node/CHANGELOG.md @@ -1,5 +1,50 @@ # @backstage/plugin-auth-node +## 0.5.3-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## 0.5.2 + +### Patch Changes + +- c46eb0f: Extend the "unable to resolve user identity" message +- d908d8c: Accepts an optional options object in the `PassportOAuthAuthenticatorHelper.authenticate` method. +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- 6f409b7: The `emailMatchingUserEntityProfileEmail` sign-in resolver will now also try matching emails with plus addressing removed. +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/catalog-client@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## 0.5.2-next.2 + +### Patch Changes + +- d908d8c: Accepts an optional options object in the `PassportOAuthAuthenticatorHelper.authenticate` method. +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-client@1.7.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.5.2-next.1 ### Patch Changes diff --git a/plugins/auth-node/package.json b/plugins/auth-node/package.json index 23818fcc31..6925fc82b6 100644 --- a/plugins/auth-node/package.json +++ b/plugins/auth-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-node", - "version": "0.5.2-next.1", + "version": "0.5.3-next.0", "backstage": { "role": "node-library", "pluginId": "auth", @@ -37,7 +37,7 @@ "test": "backstage-cli package test" }, "dependencies": { - "@backstage/backend-common": "workspace:^", + "@backstage/backend-common": "^0.25.0", "@backstage/backend-plugin-api": "workspace:^", "@backstage/catalog-client": "workspace:^", "@backstage/catalog-model": "workspace:^", @@ -62,7 +62,7 @@ "express-promise-router": "^4.1.1", "lodash": "^4.17.21", "msw": "^1.0.0", - "supertest": "^6.1.3", + "supertest": "^7.0.0", "uuid": "^9.0.0" } } diff --git a/plugins/auth-node/api-report.md b/plugins/auth-node/report.api.md similarity index 58% rename from plugins/auth-node/api-report.md rename to plugins/auth-node/report.api.md index a3750819f9..4cf9d5fd4b 100644 --- a/plugins/auth-node/api-report.md +++ b/plugins/auth-node/report.api.md @@ -503,6 +503,7 @@ export class PassportOAuthAuthenticatorHelper { // (undocumented) authenticate( input: OAuthAuthenticatorAuthenticateInput, + options?: Record, ): Promise>; // (undocumented) static defaultProfileTransform: ProfileTransform< @@ -702,4 +703,128 @@ export type WebMessageResponse = type: 'authorization_response'; error: Error; }; + +// Warnings were encountered during analysis: +// +// src/extensions/AuthOwnershipResolutionExtensionPoint.d.ts:3:1 - (ae-undocumented) Missing documentation for "AuthOwnershipResolutionExtensionPoint". +// src/extensions/AuthOwnershipResolutionExtensionPoint.d.ts:4:5 - (ae-undocumented) Missing documentation for "setAuthOwnershipResolver". +// src/extensions/AuthOwnershipResolutionExtensionPoint.d.ts:7:22 - (ae-undocumented) Missing documentation for "authOwnershipResolutionExtensionPoint". +// src/extensions/AuthProvidersExtensionPoint.d.ts:3:1 - (ae-undocumented) Missing documentation for "AuthProviderRegistrationOptions". +// src/extensions/AuthProvidersExtensionPoint.d.ts:4:5 - (ae-undocumented) Missing documentation for "providerId". +// src/extensions/AuthProvidersExtensionPoint.d.ts:5:5 - (ae-undocumented) Missing documentation for "factory". +// src/extensions/AuthProvidersExtensionPoint.d.ts:8:1 - (ae-undocumented) Missing documentation for "AuthProvidersExtensionPoint". +// src/extensions/AuthProvidersExtensionPoint.d.ts:9:5 - (ae-undocumented) Missing documentation for "registerProvider". +// src/extensions/AuthProvidersExtensionPoint.d.ts:12:22 - (ae-undocumented) Missing documentation for "authProvidersExtensionPoint". +// src/flow/sendWebMessageResponse.d.ts:17:1 - (ae-undocumented) Missing documentation for "sendWebMessageResponse". +// src/identity/DefaultIdentityClient.d.ts:35:5 - (ae-undocumented) Missing documentation for "getIdentity". +// src/identity/IdentityClient.d.ts:13:5 - (ae-undocumented) Missing documentation for "create". +// src/oauth/OAuthEnvironmentHandler.d.ts:5:1 - (ae-undocumented) Missing documentation for "OAuthEnvironmentHandler". +// src/oauth/OAuthEnvironmentHandler.d.ts:7:5 - (ae-undocumented) Missing documentation for "mapConfig". +// src/oauth/OAuthEnvironmentHandler.d.ts:9:5 - (ae-undocumented) Missing documentation for "start". +// src/oauth/OAuthEnvironmentHandler.d.ts:10:5 - (ae-undocumented) Missing documentation for "frameHandler". +// src/oauth/OAuthEnvironmentHandler.d.ts:11:5 - (ae-undocumented) Missing documentation for "refresh". +// src/oauth/OAuthEnvironmentHandler.d.ts:12:5 - (ae-undocumented) Missing documentation for "logout". +// src/oauth/PassportOAuthAuthenticatorHelper.d.ts:6:1 - (ae-undocumented) Missing documentation for "PassportOAuthResult". +// src/oauth/PassportOAuthAuthenticatorHelper.d.ts:17:1 - (ae-undocumented) Missing documentation for "PassportOAuthPrivateInfo". +// src/oauth/PassportOAuthAuthenticatorHelper.d.ts:21:1 - (ae-undocumented) Missing documentation for "PassportOAuthDoneCallback". +// src/oauth/PassportOAuthAuthenticatorHelper.d.ts:23:1 - (ae-undocumented) Missing documentation for "PassportOAuthAuthenticatorHelper". +// src/oauth/PassportOAuthAuthenticatorHelper.d.ts:25:5 - (ae-undocumented) Missing documentation for "defaultProfileTransform". +// src/oauth/PassportOAuthAuthenticatorHelper.d.ts:26:5 - (ae-undocumented) Missing documentation for "from". +// src/oauth/PassportOAuthAuthenticatorHelper.d.ts:28:5 - (ae-undocumented) Missing documentation for "start". +// src/oauth/PassportOAuthAuthenticatorHelper.d.ts:32:5 - (ae-undocumented) Missing documentation for "authenticate". +// src/oauth/PassportOAuthAuthenticatorHelper.d.ts:33:5 - (ae-undocumented) Missing documentation for "refresh". +// src/oauth/PassportOAuthAuthenticatorHelper.d.ts:34:5 - (ae-undocumented) Missing documentation for "fetchProfile". +// src/oauth/createOAuthProviderFactory.d.ts:6:1 - (ae-undocumented) Missing documentation for "createOAuthProviderFactory". +// src/oauth/createOAuthRouteHandlers.d.ts:6:1 - (ae-undocumented) Missing documentation for "OAuthRouteHandlersOptions". +// src/oauth/createOAuthRouteHandlers.d.ts:7:5 - (ae-undocumented) Missing documentation for "authenticator". +// src/oauth/createOAuthRouteHandlers.d.ts:8:5 - (ae-undocumented) Missing documentation for "appUrl". +// src/oauth/createOAuthRouteHandlers.d.ts:9:5 - (ae-undocumented) Missing documentation for "baseUrl". +// src/oauth/createOAuthRouteHandlers.d.ts:10:5 - (ae-undocumented) Missing documentation for "isOriginAllowed". +// src/oauth/createOAuthRouteHandlers.d.ts:11:5 - (ae-undocumented) Missing documentation for "providerId". +// src/oauth/createOAuthRouteHandlers.d.ts:12:5 - (ae-undocumented) Missing documentation for "config". +// src/oauth/createOAuthRouteHandlers.d.ts:13:5 - (ae-undocumented) Missing documentation for "resolverContext". +// src/oauth/createOAuthRouteHandlers.d.ts:14:5 - (ae-undocumented) Missing documentation for "additionalScopes". +// src/oauth/createOAuthRouteHandlers.d.ts:15:5 - (ae-undocumented) Missing documentation for "stateTransform". +// src/oauth/createOAuthRouteHandlers.d.ts:16:5 - (ae-undocumented) Missing documentation for "profileTransform". +// src/oauth/createOAuthRouteHandlers.d.ts:17:5 - (ae-undocumented) Missing documentation for "cookieConfigurer". +// src/oauth/createOAuthRouteHandlers.d.ts:18:5 - (ae-undocumented) Missing documentation for "signInResolver". +// src/oauth/createOAuthRouteHandlers.d.ts:21:1 - (ae-undocumented) Missing documentation for "createOAuthRouteHandlers". +// src/oauth/state.d.ts:16:1 - (ae-undocumented) Missing documentation for "OAuthStateTransform". +// src/oauth/state.d.ts:22:1 - (ae-undocumented) Missing documentation for "encodeOAuthState". +// src/oauth/state.d.ts:24:1 - (ae-undocumented) Missing documentation for "decodeOAuthState". +// src/oauth/types.d.ts:5:1 - (ae-undocumented) Missing documentation for "OAuthSession". +// src/oauth/types.d.ts:6:5 - (ae-undocumented) Missing documentation for "accessToken". +// src/oauth/types.d.ts:7:5 - (ae-undocumented) Missing documentation for "tokenType". +// src/oauth/types.d.ts:8:5 - (ae-undocumented) Missing documentation for "idToken". +// src/oauth/types.d.ts:9:5 - (ae-undocumented) Missing documentation for "scope". +// src/oauth/types.d.ts:10:5 - (ae-undocumented) Missing documentation for "expiresInSeconds". +// src/oauth/types.d.ts:11:5 - (ae-undocumented) Missing documentation for "refreshToken". +// src/oauth/types.d.ts:12:5 - (ae-undocumented) Missing documentation for "refreshTokenExpiresInSeconds". +// src/oauth/types.d.ts:15:1 - (ae-undocumented) Missing documentation for "OAuthAuthenticatorScopeOptions". +// src/oauth/types.d.ts:16:5 - (ae-undocumented) Missing documentation for "persist". +// src/oauth/types.d.ts:17:5 - (ae-undocumented) Missing documentation for "required". +// src/oauth/types.d.ts:18:5 - (ae-undocumented) Missing documentation for "transform". +// src/oauth/types.d.ts:30:1 - (ae-undocumented) Missing documentation for "OAuthAuthenticatorStartInput". +// src/oauth/types.d.ts:31:5 - (ae-undocumented) Missing documentation for "scope". +// src/oauth/types.d.ts:32:5 - (ae-undocumented) Missing documentation for "state". +// src/oauth/types.d.ts:33:5 - (ae-undocumented) Missing documentation for "req". +// src/oauth/types.d.ts:36:1 - (ae-undocumented) Missing documentation for "OAuthAuthenticatorAuthenticateInput". +// src/oauth/types.d.ts:37:5 - (ae-undocumented) Missing documentation for "req". +// src/oauth/types.d.ts:40:1 - (ae-undocumented) Missing documentation for "OAuthAuthenticatorRefreshInput". +// src/oauth/types.d.ts:41:5 - (ae-undocumented) Missing documentation for "scope". +// src/oauth/types.d.ts:42:5 - (ae-undocumented) Missing documentation for "refreshToken". +// src/oauth/types.d.ts:43:5 - (ae-undocumented) Missing documentation for "req". +// src/oauth/types.d.ts:46:1 - (ae-undocumented) Missing documentation for "OAuthAuthenticatorLogoutInput". +// src/oauth/types.d.ts:47:5 - (ae-undocumented) Missing documentation for "accessToken". +// src/oauth/types.d.ts:48:5 - (ae-undocumented) Missing documentation for "refreshToken". +// src/oauth/types.d.ts:49:5 - (ae-undocumented) Missing documentation for "req". +// src/oauth/types.d.ts:52:1 - (ae-undocumented) Missing documentation for "OAuthAuthenticatorResult". +// src/oauth/types.d.ts:53:5 - (ae-undocumented) Missing documentation for "fullProfile". +// src/oauth/types.d.ts:54:5 - (ae-undocumented) Missing documentation for "session". +// src/oauth/types.d.ts:57:1 - (ae-undocumented) Missing documentation for "OAuthAuthenticator". +// src/oauth/types.d.ts:58:5 - (ae-undocumented) Missing documentation for "defaultProfileTransform". +// src/oauth/types.d.ts:60:5 - (ae-undocumented) Missing documentation for "shouldPersistScopes". +// src/oauth/types.d.ts:61:5 - (ae-undocumented) Missing documentation for "scopes". +// src/oauth/types.d.ts:62:5 - (ae-undocumented) Missing documentation for "initialize". +// src/oauth/types.d.ts:66:5 - (ae-undocumented) Missing documentation for "start". +// src/oauth/types.d.ts:70:5 - (ae-undocumented) Missing documentation for "authenticate". +// src/oauth/types.d.ts:71:5 - (ae-undocumented) Missing documentation for "refresh". +// src/oauth/types.d.ts:72:5 - (ae-undocumented) Missing documentation for "logout". +// src/oauth/types.d.ts:75:1 - (ae-undocumented) Missing documentation for "createOAuthAuthenticator". +// src/passport/PassportHelpers.d.ts:6:1 - (ae-undocumented) Missing documentation for "PassportHelpers". +// src/passport/PassportHelpers.d.ts:8:5 - (ae-undocumented) Missing documentation for "transformProfile". +// src/passport/PassportHelpers.d.ts:9:5 - (ae-undocumented) Missing documentation for "executeRedirectStrategy". +// src/passport/PassportHelpers.d.ts:19:5 - (ae-undocumented) Missing documentation for "executeFrameHandlerStrategy". +// src/passport/PassportHelpers.d.ts:23:5 - (ae-undocumented) Missing documentation for "executeRefreshTokenStrategy". +// src/passport/PassportHelpers.d.ts:34:5 - (ae-undocumented) Missing documentation for "executeFetchUserProfileStrategy". +// src/passport/types.d.ts:3:1 - (ae-undocumented) Missing documentation for "PassportProfile". +// src/passport/types.d.ts:9:1 - (ae-undocumented) Missing documentation for "PassportDoneCallback". +// src/proxy/createProxyAuthProviderFactory.d.ts:5:1 - (ae-undocumented) Missing documentation for "createProxyAuthProviderFactory". +// src/proxy/createProxyRouteHandlers.d.ts:5:1 - (ae-undocumented) Missing documentation for "ProxyAuthRouteHandlersOptions". +// src/proxy/createProxyRouteHandlers.d.ts:6:5 - (ae-undocumented) Missing documentation for "authenticator". +// src/proxy/createProxyRouteHandlers.d.ts:7:5 - (ae-undocumented) Missing documentation for "config". +// src/proxy/createProxyRouteHandlers.d.ts:8:5 - (ae-undocumented) Missing documentation for "resolverContext". +// src/proxy/createProxyRouteHandlers.d.ts:9:5 - (ae-undocumented) Missing documentation for "signInResolver". +// src/proxy/createProxyRouteHandlers.d.ts:10:5 - (ae-undocumented) Missing documentation for "profileTransform". +// src/proxy/createProxyRouteHandlers.d.ts:13:1 - (ae-undocumented) Missing documentation for "createProxyAuthRouteHandlers". +// src/proxy/types.d.ts:5:1 - (ae-undocumented) Missing documentation for "ProxyAuthenticator". +// src/proxy/types.d.ts:6:5 - (ae-undocumented) Missing documentation for "defaultProfileTransform". +// src/proxy/types.d.ts:7:5 - (ae-undocumented) Missing documentation for "initialize". +// src/proxy/types.d.ts:10:5 - (ae-undocumented) Missing documentation for "authenticate". +// src/proxy/types.d.ts:18:1 - (ae-undocumented) Missing documentation for "createProxyAuthenticator". +// src/sign-in/createSignInResolverFactory.d.ts:5:1 - (ae-undocumented) Missing documentation for "SignInResolverFactory". +// src/sign-in/createSignInResolverFactory.d.ts:6:5 - (ae-undocumented) Missing documentation for "__call". +// src/sign-in/createSignInResolverFactory.d.ts:7:5 - (ae-undocumented) Missing documentation for "optionsJsonSchema". +// src/sign-in/createSignInResolverFactory.d.ts:10:1 - (ae-undocumented) Missing documentation for "SignInResolverFactoryOptions". +// src/sign-in/createSignInResolverFactory.d.ts:11:5 - (ae-undocumented) Missing documentation for "optionsSchema". +// src/sign-in/createSignInResolverFactory.d.ts:12:5 - (ae-undocumented) Missing documentation for "create". +// src/sign-in/createSignInResolverFactory.d.ts:15:1 - (ae-undocumented) Missing documentation for "createSignInResolverFactory". +// src/sign-in/readDeclarativeSignInResolver.d.ts:5:1 - (ae-undocumented) Missing documentation for "ReadDeclarativeSignInResolverOptions". +// src/sign-in/readDeclarativeSignInResolver.d.ts:6:5 - (ae-undocumented) Missing documentation for "config". +// src/sign-in/readDeclarativeSignInResolver.d.ts:7:5 - (ae-undocumented) Missing documentation for "signInResolverFactories". +// src/sign-in/readDeclarativeSignInResolver.d.ts:12:1 - (ae-undocumented) Missing documentation for "readDeclarativeSignInResolver". +// src/types.d.ts:139:5 - (ae-undocumented) Missing documentation for "resolveOwnershipEntityRefs". +// src/types.d.ts:204:1 - (ae-undocumented) Missing documentation for "AuthProviderConfig". +// src/types.d.ts:224:1 - (ae-undocumented) Missing documentation for "AuthProviderFactory". +// src/types.d.ts:250:1 - (ae-undocumented) Missing documentation for "ClientAuthResponse". ``` diff --git a/plugins/auth-node/src/oauth/PassportOAuthAuthenticatorHelper.ts b/plugins/auth-node/src/oauth/PassportOAuthAuthenticatorHelper.ts index c03a9cb56f..dfcdb3d297 100644 --- a/plugins/auth-node/src/oauth/PassportOAuthAuthenticatorHelper.ts +++ b/plugins/auth-node/src/oauth/PassportOAuthAuthenticatorHelper.ts @@ -85,12 +85,13 @@ export class PassportOAuthAuthenticatorHelper { async authenticate( input: OAuthAuthenticatorAuthenticateInput, + options?: Record, ): Promise> { const { result, privateInfo } = await PassportHelpers.executeFrameHandlerStrategy< PassportOAuthResult, PassportOAuthPrivateInfo - >(input.req, this.#strategy); + >(input.req, this.#strategy, options); return { fullProfile: result.fullProfile as PassportProfile, diff --git a/plugins/auth-node/src/sign-in/commonSignInResolvers.ts b/plugins/auth-node/src/sign-in/commonSignInResolvers.ts index 5b5da07c73..f664e7e33b 100644 --- a/plugins/auth-node/src/sign-in/commonSignInResolvers.ts +++ b/plugins/auth-node/src/sign-in/commonSignInResolvers.ts @@ -16,6 +16,11 @@ import { createSignInResolverFactory } from './createSignInResolverFactory'; +// This splits an email "joe+work@acme.com" into ["joe", "+work", "@acme.com"] +// so that we can remove the plus addressing. May output a shorter array: +// ["joe", "@acme.com"], if no plus addressing was found. +const reEmail = /^([^@+]+)(\+[^@]+)?(@.*)$/; + /** * A collection of common sign-in resolvers that work with any auth provider. * @@ -38,11 +43,30 @@ export namespace commonSignInResolvers { ); } - return ctx.signInWithCatalogUser({ - filter: { - 'spec.profile.email': profile.email, - }, - }); + try { + return await ctx.signInWithCatalogUser({ + filter: { + 'spec.profile.email': profile.email, + }, + }); + } catch (err) { + if (err?.name === 'NotFoundError') { + // Try removing the plus addressing from the email address + const m = profile.email.match(reEmail); + if (m?.length === 4) { + const [_, name, _plus, domain] = m; + const noPlusEmail = `${name}${domain}`; + + return ctx.signInWithCatalogUser({ + filter: { + 'spec.profile.email': noPlusEmail, + }, + }); + } + } + // Email had no plus addressing or is missing in the catalog, forward failure + throw err; + } }; }, }); diff --git a/plugins/auth-react/CHANGELOG.md b/plugins/auth-react/CHANGELOG.md index 2aac588abe..ed77363787 100644 --- a/plugins/auth-react/CHANGELOG.md +++ b/plugins/auth-react/CHANGELOG.md @@ -1,5 +1,44 @@ # @backstage/plugin-auth-react +## 0.1.7-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/errors@1.2.4 + +## 0.1.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/errors@1.2.4 + +## 0.1.6 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/errors@1.2.4 + +## 0.1.6-next.1 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/errors@1.2.4 + ## 0.1.6-next.0 ### Patch Changes diff --git a/plugins/auth-react/package.json b/plugins/auth-react/package.json index 2f76c289b3..010ae948e9 100644 --- a/plugins/auth-react/package.json +++ b/plugins/auth-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-react", - "version": "0.1.6-next.0", + "version": "0.1.7-next.1", "description": "Web library for the auth plugin", "backstage": { "role": "web-library", @@ -42,18 +42,29 @@ "@backstage/core-plugin-api": "workspace:^", "@backstage/errors": "workspace:^", "@material-ui/core": "^4.9.13", - "@react-hookz/web": "^24.0.0", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0" + "@react-hookz/web": "^24.0.0" }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/test-utils": "workspace:^", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^15.0.0", + "@testing-library/react": "^16.0.0", "@testing-library/user-event": "^14.0.0", - "msw": "^1.0.0" + "@types/react": "^18.0.0", + "msw": "^1.0.0", + "react": "^18.0.2", + "react-dom": "^18.0.2", + "react-router-dom": "^6.3.0" }, "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0" + "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } } diff --git a/plugins/auth-react/api-report.md b/plugins/auth-react/report.api.md similarity index 100% rename from plugins/auth-react/api-report.md rename to plugins/auth-react/report.api.md diff --git a/plugins/bitbucket-cloud-common/CHANGELOG.md b/plugins/bitbucket-cloud-common/CHANGELOG.md index 3de470cfba..55b3293b81 100644 --- a/plugins/bitbucket-cloud-common/CHANGELOG.md +++ b/plugins/bitbucket-cloud-common/CHANGELOG.md @@ -1,5 +1,26 @@ # @backstage/plugin-bitbucket-cloud-common +## 0.2.24-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.15.1-next.0 + +## 0.2.23 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.15.0 + +## 0.2.23-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.15.0-next.0 + ## 0.2.22 ### Patch Changes diff --git a/plugins/bitbucket-cloud-common/api-report.md b/plugins/bitbucket-cloud-common/api-report.md deleted file mode 100644 index 833a367c03..0000000000 --- a/plugins/bitbucket-cloud-common/api-report.md +++ /dev/null @@ -1,485 +0,0 @@ -## API Report File for "@backstage/plugin-bitbucket-cloud-common" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -import { BitbucketCloudIntegrationConfig } from '@backstage/integration'; - -// @public (undocumented) -export class BitbucketCloudClient { - // (undocumented) - static fromConfig( - config: BitbucketCloudIntegrationConfig, - ): BitbucketCloudClient; - // (undocumented) - listBranchesByRepository( - repository: string, - workspace: string, - options?: FilterAndSortOptions & PartialResponseOptions, - ): WithPagination; - // (undocumented) - listProjectsByWorkspace( - workspace: string, - options?: FilterAndSortOptions & PartialResponseOptions, - ): WithPagination; - // (undocumented) - listRepositoriesByWorkspace( - workspace: string, - options?: FilterAndSortOptions & PartialResponseOptions, - ): WithPagination; - // (undocumented) - listWorkspaces( - options?: FilterAndSortOptions & PartialResponseOptions, - ): WithPagination; - // (undocumented) - searchCode( - workspace: string, - query: string, - options?: FilterAndSortOptions & PartialResponseOptions, - ): WithPagination; -} - -// @public (undocumented) -export namespace Events { - // (undocumented) - export interface Change { - // (undocumented) - closed: boolean; - // (undocumented) - commits: Models.Commit[]; - // (undocumented) - created: boolean; - // (undocumented) - forced: boolean; - // (undocumented) - links: ChangeLinks; - // (undocumented) - new: Models.Branch; - // (undocumented) - old: Models.Branch; - // (undocumented) - truncated: boolean; - } - // (undocumented) - export interface ChangeLinks { - // (undocumented) - commits: Models.Link; - // (undocumented) - diff: Models.Link; - // (undocumented) - html: Models.Link; - } - // (undocumented) - export interface RepoEvent { - // (undocumented) - actor: Models.Account; - // (undocumented) - repository: Models.Repository & { - workspace: Models.Workspace; - }; - } - // (undocumented) - export interface RepoPush { - // (undocumented) - changes: Change[]; - } - // (undocumented) - export interface RepoPushEvent extends RepoEvent { - // (undocumented) - push: RepoPush; - } -} - -// @public (undocumented) -export type FilterAndSortOptions = { - q?: string; - sort?: string; -}; - -// @public (undocumented) -export namespace Models { - export interface Account extends ModelObject { - // (undocumented) - created_on?: string; - // (undocumented) - display_name?: string; - // (undocumented) - links?: AccountLinks; - // (undocumented) - username?: string; - // (undocumented) - uuid?: string; - } - export interface AccountLinks { - // (undocumented) - [key: string]: unknown; - // (undocumented) - avatar?: Link; - } - export interface Author extends ModelObject { - raw?: string; - // (undocumented) - user?: Account; - } - export interface BaseCommit extends ModelObject { - // (undocumented) - author?: Author; - // (undocumented) - date?: string; - // (undocumented) - hash?: string; - // (undocumented) - message?: string; - // (undocumented) - parents?: Array; - // (undocumented) - summary?: BaseCommitSummary; - } - // (undocumented) - export interface BaseCommitSummary { - html?: string; - markup?: BaseCommitSummaryMarkupEnum; - raw?: string; - } - const BaseCommitSummaryMarkupEnum: { - readonly Markdown: 'markdown'; - readonly Creole: 'creole'; - readonly Plaintext: 'plaintext'; - }; - export type BaseCommitSummaryMarkupEnum = - (typeof BaseCommitSummaryMarkupEnum)[keyof typeof BaseCommitSummaryMarkupEnum]; - export interface Branch { - default_merge_strategy?: string; - // (undocumented) - links?: RefLinks; - merge_strategies?: Array; - name?: string; - // (undocumented) - target?: Commit; - // (undocumented) - type: string; - } - const BranchMergeStrategiesEnum: { - readonly MergeCommit: 'merge_commit'; - readonly Squash: 'squash'; - readonly FastForward: 'fast_forward'; - }; - export type BranchMergeStrategiesEnum = - (typeof BranchMergeStrategiesEnum)[keyof typeof BranchMergeStrategiesEnum]; - export interface Commit extends BaseCommit { - // (undocumented) - participants?: Array; - // (undocumented) - repository?: Repository; - } - export interface CommitFile { - // (undocumented) - [key: string]: unknown; - // (undocumented) - attributes?: CommitFileAttributesEnum; - // (undocumented) - commit?: Commit; - escaped_path?: string; - path?: string; - // (undocumented) - type: string; - } - const // (undocumented) - CommitFileAttributesEnum: { - readonly Link: 'link'; - readonly Executable: 'executable'; - readonly Subrepository: 'subrepository'; - readonly Binary: 'binary'; - readonly Lfs: 'lfs'; - }; - // (undocumented) - export type CommitFileAttributesEnum = - (typeof CommitFileAttributesEnum)[keyof typeof CommitFileAttributesEnum]; - export interface Link { - // (undocumented) - href?: string; - // (undocumented) - name?: string; - } - export interface ModelObject { - // (undocumented) - [key: string]: unknown; - // (undocumented) - type: string; - } - export interface Paginated { - next?: string; - page?: number; - pagelen?: number; - previous?: string; - size?: number; - values?: Array | Set; - } - export interface PaginatedBranches extends Paginated { - values?: Set; - } - export interface PaginatedProjects extends Paginated { - values?: Set; - } - export interface PaginatedRepositories extends Paginated { - values?: Set; - } - export interface PaginatedWorkspaces extends Paginated { - values?: Set; - } - export interface Participant extends ModelObject { - // (undocumented) - approved?: boolean; - participated_on?: string; - // (undocumented) - role?: ParticipantRoleEnum; - // (undocumented) - state?: ParticipantStateEnum; - // (undocumented) - user?: Account; - } - const // (undocumented) - ParticipantRoleEnum: { - readonly Participant: 'PARTICIPANT'; - readonly Reviewer: 'REVIEWER'; - }; - // (undocumented) - export type ParticipantRoleEnum = - (typeof ParticipantRoleEnum)[keyof typeof ParticipantRoleEnum]; - const // (undocumented) - ParticipantStateEnum: { - readonly Approved: 'approved'; - readonly ChangesRequested: 'changes_requested'; - readonly Null: 'null'; - }; - // (undocumented) - export type ParticipantStateEnum = - (typeof ParticipantStateEnum)[keyof typeof ParticipantStateEnum]; - export interface Project extends ModelObject { - // (undocumented) - created_on?: string; - // (undocumented) - description?: string; - has_publicly_visible_repos?: boolean; - is_private?: boolean; - key?: string; - // (undocumented) - links?: ProjectLinks; - name?: string; - // (undocumented) - owner?: Team; - // (undocumented) - updated_on?: string; - uuid?: string; - } - // (undocumented) - export interface ProjectLinks { - // (undocumented) - avatar?: Link; - // (undocumented) - html?: Link; - } - // (undocumented) - export interface RefLinks { - // (undocumented) - commits?: Link; - // (undocumented) - html?: Link; - // (undocumented) - self?: Link; - } - export interface Repository extends ModelObject { - // (undocumented) - created_on?: string; - // (undocumented) - description?: string; - fork_policy?: RepositoryForkPolicyEnum; - full_name?: string; - has_issues?: boolean; - has_wiki?: boolean; - // (undocumented) - is_private?: boolean; - // (undocumented) - language?: string; - // (undocumented) - links?: RepositoryLinks; - // (undocumented) - mainbranch?: Branch; - // (undocumented) - name?: string; - // (undocumented) - owner?: Account; - // (undocumented) - parent?: Repository; - // (undocumented) - project?: Project; - // (undocumented) - scm?: RepositoryScmEnum; - // (undocumented) - size?: number; - slug?: string; - // (undocumented) - updated_on?: string; - uuid?: string; - } - const RepositoryForkPolicyEnum: { - readonly AllowForks: 'allow_forks'; - readonly NoPublicForks: 'no_public_forks'; - readonly NoForks: 'no_forks'; - }; - export type RepositoryForkPolicyEnum = - (typeof RepositoryForkPolicyEnum)[keyof typeof RepositoryForkPolicyEnum]; - const // (undocumented) - RepositoryScmEnum: { - readonly Git: 'git'; - }; - // (undocumented) - export interface RepositoryLinks { - // (undocumented) - avatar?: Link; - // (undocumented) - clone?: Array; - // (undocumented) - commits?: Link; - // (undocumented) - downloads?: Link; - // (undocumented) - forks?: Link; - // (undocumented) - hooks?: Link; - // (undocumented) - html?: Link; - // (undocumented) - pullrequests?: Link; - // (undocumented) - self?: Link; - // (undocumented) - watchers?: Link; - } - // (undocumented) - export type RepositoryScmEnum = - (typeof RepositoryScmEnum)[keyof typeof RepositoryScmEnum]; - // (undocumented) - export interface SearchCodeSearchResult { - // (undocumented) - readonly content_match_count?: number; - // (undocumented) - readonly content_matches?: Array; - // (undocumented) - file?: CommitFile; - // (undocumented) - readonly path_matches?: Array; - // (undocumented) - readonly type?: string; - } - // (undocumented) - export interface SearchContentMatch { - // (undocumented) - readonly lines?: Array; - } - // (undocumented) - export interface SearchLine { - // (undocumented) - readonly line?: number; - // (undocumented) - readonly segments?: Array; - } - // (undocumented) - export interface SearchResultPage extends Paginated { - // (undocumented) - readonly query_substituted?: boolean; - readonly values?: Array; - } - // (undocumented) - export interface SearchSegment { - // (undocumented) - readonly match?: boolean; - // (undocumented) - readonly text?: string; - } - export interface Team extends Account { - // (undocumented) - links?: TeamLinks; - } - export interface TeamLinks extends AccountLinks { - // (undocumented) - html?: Link; - // (undocumented) - members?: Link; - // (undocumented) - projects?: Link; - // (undocumented) - repositories?: Link; - // (undocumented) - self?: Link; - } - export interface Workspace extends ModelObject { - // (undocumented) - created_on?: string; - is_private?: boolean; - // (undocumented) - links?: WorkspaceLinks; - name?: string; - slug?: string; - // (undocumented) - updated_on?: string; - uuid?: string; - } - // (undocumented) - export interface WorkspaceLinks { - // (undocumented) - avatar?: Link; - // (undocumented) - html?: Link; - // (undocumented) - members?: Link; - // (undocumented) - owners?: Link; - // (undocumented) - projects?: Link; - // (undocumented) - repositories?: Link; - // (undocumented) - self?: Link; - // (undocumented) - snippets?: Link; - } -} - -// @public (undocumented) -export type PaginationOptions = { - page?: number; - pagelen?: number; -}; - -// @public (undocumented) -export type PartialResponseOptions = { - fields?: string; -}; - -// @public (undocumented) -export type RequestOptions = FilterAndSortOptions & - PaginationOptions & - PartialResponseOptions & { - [key: string]: string | number | undefined; - }; - -// @public (undocumented) -export class WithPagination< - TPage extends Models.Paginated, - TResultItem, -> { - constructor( - createUrl: (options: PaginationOptions) => URL, - fetch: (url: URL) => Promise, - ); - // (undocumented) - getPage(options?: PaginationOptions): Promise; - // (undocumented) - iteratePages(options?: PaginationOptions): AsyncGenerator; - // (undocumented) - iterateResults( - options?: PaginationOptions, - ): AsyncGenerator, void, unknown>; -} -``` diff --git a/plugins/bitbucket-cloud-common/package.json b/plugins/bitbucket-cloud-common/package.json index eeb5bd6ff6..e75ce4daff 100644 --- a/plugins/bitbucket-cloud-common/package.json +++ b/plugins/bitbucket-cloud-common/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-bitbucket-cloud-common", - "version": "0.2.22", + "version": "0.2.24-next.0", "description": "Common functionalities for bitbucket-cloud plugins", "backstage": { "role": "common-library", diff --git a/plugins/bitbucket-cloud-common/report.api.md b/plugins/bitbucket-cloud-common/report.api.md new file mode 100644 index 0000000000..ebad8ff878 --- /dev/null +++ b/plugins/bitbucket-cloud-common/report.api.md @@ -0,0 +1,635 @@ +## API Report File for "@backstage/plugin-bitbucket-cloud-common" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BitbucketCloudIntegrationConfig } from '@backstage/integration'; + +// @public (undocumented) +export class BitbucketCloudClient { + // (undocumented) + static fromConfig( + config: BitbucketCloudIntegrationConfig, + ): BitbucketCloudClient; + // (undocumented) + listBranchesByRepository( + repository: string, + workspace: string, + options?: FilterAndSortOptions & PartialResponseOptions, + ): WithPagination; + // (undocumented) + listProjectsByWorkspace( + workspace: string, + options?: FilterAndSortOptions & PartialResponseOptions, + ): WithPagination; + // (undocumented) + listRepositoriesByWorkspace( + workspace: string, + options?: FilterAndSortOptions & PartialResponseOptions, + ): WithPagination; + // (undocumented) + listWorkspaces( + options?: FilterAndSortOptions & PartialResponseOptions, + ): WithPagination; + // (undocumented) + searchCode( + workspace: string, + query: string, + options?: FilterAndSortOptions & PartialResponseOptions, + ): WithPagination; +} + +// @public (undocumented) +export namespace Events { + // (undocumented) + export interface Change { + // (undocumented) + closed: boolean; + // (undocumented) + commits: Models.Commit[]; + // (undocumented) + created: boolean; + // (undocumented) + forced: boolean; + // (undocumented) + links: ChangeLinks; + // (undocumented) + new: Models.Branch; + // (undocumented) + old: Models.Branch; + // (undocumented) + truncated: boolean; + } + // (undocumented) + export interface ChangeLinks { + // (undocumented) + commits: Models.Link; + // (undocumented) + diff: Models.Link; + // (undocumented) + html: Models.Link; + } + // (undocumented) + export interface RepoEvent { + // (undocumented) + actor: Models.Account; + // (undocumented) + repository: Models.Repository & { + workspace: Models.Workspace; + }; + } + // (undocumented) + export interface RepoPush { + // (undocumented) + changes: Change[]; + } + // (undocumented) + export interface RepoPushEvent extends RepoEvent { + // (undocumented) + push: RepoPush; + } +} + +// @public (undocumented) +export type FilterAndSortOptions = { + q?: string; + sort?: string; +}; + +// @public (undocumented) +export namespace Models { + export interface Account extends ModelObject { + // (undocumented) + created_on?: string; + // (undocumented) + display_name?: string; + // (undocumented) + links?: AccountLinks; + // (undocumented) + username?: string; + // (undocumented) + uuid?: string; + } + export interface AccountLinks { + // (undocumented) + [key: string]: unknown; + // (undocumented) + avatar?: Link; + } + export interface Author extends ModelObject { + raw?: string; + // (undocumented) + user?: Account; + } + export interface BaseCommit extends ModelObject { + // (undocumented) + author?: Author; + // (undocumented) + date?: string; + // (undocumented) + hash?: string; + // (undocumented) + message?: string; + // (undocumented) + parents?: Array; + // (undocumented) + summary?: BaseCommitSummary; + } + // (undocumented) + export interface BaseCommitSummary { + html?: string; + markup?: BaseCommitSummaryMarkupEnum; + raw?: string; + } + const BaseCommitSummaryMarkupEnum: { + readonly Markdown: 'markdown'; + readonly Creole: 'creole'; + readonly Plaintext: 'plaintext'; + }; + export type BaseCommitSummaryMarkupEnum = + (typeof BaseCommitSummaryMarkupEnum)[keyof typeof BaseCommitSummaryMarkupEnum]; + export interface Branch { + default_merge_strategy?: string; + // (undocumented) + links?: RefLinks; + merge_strategies?: Array; + name?: string; + // (undocumented) + target?: Commit; + // (undocumented) + type: string; + } + const BranchMergeStrategiesEnum: { + readonly MergeCommit: 'merge_commit'; + readonly Squash: 'squash'; + readonly FastForward: 'fast_forward'; + }; + export type BranchMergeStrategiesEnum = + (typeof BranchMergeStrategiesEnum)[keyof typeof BranchMergeStrategiesEnum]; + export interface Commit extends BaseCommit { + // (undocumented) + participants?: Array; + // (undocumented) + repository?: Repository; + } + export interface CommitFile { + // (undocumented) + [key: string]: unknown; + // (undocumented) + attributes?: CommitFileAttributesEnum; + // (undocumented) + commit?: Commit; + escaped_path?: string; + path?: string; + // (undocumented) + type: string; + } + const // (undocumented) + CommitFileAttributesEnum: { + readonly Link: 'link'; + readonly Executable: 'executable'; + readonly Subrepository: 'subrepository'; + readonly Binary: 'binary'; + readonly Lfs: 'lfs'; + }; + // (undocumented) + export type CommitFileAttributesEnum = + (typeof CommitFileAttributesEnum)[keyof typeof CommitFileAttributesEnum]; + export interface Link { + // (undocumented) + href?: string; + // (undocumented) + name?: string; + } + export interface ModelObject { + // (undocumented) + [key: string]: unknown; + // (undocumented) + type: string; + } + export interface Paginated { + next?: string; + page?: number; + pagelen?: number; + previous?: string; + size?: number; + values?: Array | Set; + } + export interface PaginatedBranches extends Paginated { + values?: Set; + } + export interface PaginatedProjects extends Paginated { + values?: Set; + } + export interface PaginatedRepositories extends Paginated { + values?: Set; + } + export interface PaginatedWorkspaces extends Paginated { + values?: Set; + } + export interface Participant extends ModelObject { + // (undocumented) + approved?: boolean; + participated_on?: string; + // (undocumented) + role?: ParticipantRoleEnum; + // (undocumented) + state?: ParticipantStateEnum; + // (undocumented) + user?: Account; + } + const // (undocumented) + ParticipantRoleEnum: { + readonly Participant: 'PARTICIPANT'; + readonly Reviewer: 'REVIEWER'; + }; + // (undocumented) + export type ParticipantRoleEnum = + (typeof ParticipantRoleEnum)[keyof typeof ParticipantRoleEnum]; + const // (undocumented) + ParticipantStateEnum: { + readonly Approved: 'approved'; + readonly ChangesRequested: 'changes_requested'; + readonly Null: 'null'; + }; + // (undocumented) + export type ParticipantStateEnum = + (typeof ParticipantStateEnum)[keyof typeof ParticipantStateEnum]; + export interface Project extends ModelObject { + // (undocumented) + created_on?: string; + // (undocumented) + description?: string; + has_publicly_visible_repos?: boolean; + is_private?: boolean; + key?: string; + // (undocumented) + links?: ProjectLinks; + name?: string; + // (undocumented) + owner?: Team; + // (undocumented) + updated_on?: string; + uuid?: string; + } + // (undocumented) + export interface ProjectLinks { + // (undocumented) + avatar?: Link; + // (undocumented) + html?: Link; + } + // (undocumented) + export interface RefLinks { + // (undocumented) + commits?: Link; + // (undocumented) + html?: Link; + // (undocumented) + self?: Link; + } + export interface Repository extends ModelObject { + // (undocumented) + created_on?: string; + // (undocumented) + description?: string; + fork_policy?: RepositoryForkPolicyEnum; + full_name?: string; + has_issues?: boolean; + has_wiki?: boolean; + // (undocumented) + is_private?: boolean; + // (undocumented) + language?: string; + // (undocumented) + links?: RepositoryLinks; + // (undocumented) + mainbranch?: Branch; + // (undocumented) + name?: string; + // (undocumented) + owner?: Account; + // (undocumented) + parent?: Repository; + // (undocumented) + project?: Project; + // (undocumented) + scm?: RepositoryScmEnum; + // (undocumented) + size?: number; + slug?: string; + // (undocumented) + updated_on?: string; + uuid?: string; + } + const RepositoryForkPolicyEnum: { + readonly AllowForks: 'allow_forks'; + readonly NoPublicForks: 'no_public_forks'; + readonly NoForks: 'no_forks'; + }; + export type RepositoryForkPolicyEnum = + (typeof RepositoryForkPolicyEnum)[keyof typeof RepositoryForkPolicyEnum]; + const // (undocumented) + RepositoryScmEnum: { + readonly Git: 'git'; + }; + // (undocumented) + export interface RepositoryLinks { + // (undocumented) + avatar?: Link; + // (undocumented) + clone?: Array; + // (undocumented) + commits?: Link; + // (undocumented) + downloads?: Link; + // (undocumented) + forks?: Link; + // (undocumented) + hooks?: Link; + // (undocumented) + html?: Link; + // (undocumented) + pullrequests?: Link; + // (undocumented) + self?: Link; + // (undocumented) + watchers?: Link; + } + // (undocumented) + export type RepositoryScmEnum = + (typeof RepositoryScmEnum)[keyof typeof RepositoryScmEnum]; + // (undocumented) + export interface SearchCodeSearchResult { + // (undocumented) + readonly content_match_count?: number; + // (undocumented) + readonly content_matches?: Array; + // (undocumented) + file?: CommitFile; + // (undocumented) + readonly path_matches?: Array; + // (undocumented) + readonly type?: string; + } + // (undocumented) + export interface SearchContentMatch { + // (undocumented) + readonly lines?: Array; + } + // (undocumented) + export interface SearchLine { + // (undocumented) + readonly line?: number; + // (undocumented) + readonly segments?: Array; + } + // (undocumented) + export interface SearchResultPage extends Paginated { + // (undocumented) + readonly query_substituted?: boolean; + readonly values?: Array; + } + // (undocumented) + export interface SearchSegment { + // (undocumented) + readonly match?: boolean; + // (undocumented) + readonly text?: string; + } + export interface Team extends Account { + // (undocumented) + links?: TeamLinks; + } + export interface TeamLinks extends AccountLinks { + // (undocumented) + html?: Link; + // (undocumented) + members?: Link; + // (undocumented) + projects?: Link; + // (undocumented) + repositories?: Link; + // (undocumented) + self?: Link; + } + export interface Workspace extends ModelObject { + // (undocumented) + created_on?: string; + is_private?: boolean; + // (undocumented) + links?: WorkspaceLinks; + name?: string; + slug?: string; + // (undocumented) + updated_on?: string; + uuid?: string; + } + // (undocumented) + export interface WorkspaceLinks { + // (undocumented) + avatar?: Link; + // (undocumented) + html?: Link; + // (undocumented) + members?: Link; + // (undocumented) + owners?: Link; + // (undocumented) + projects?: Link; + // (undocumented) + repositories?: Link; + // (undocumented) + self?: Link; + // (undocumented) + snippets?: Link; + } +} + +// @public (undocumented) +export type PaginationOptions = { + page?: number; + pagelen?: number; +}; + +// @public (undocumented) +export type PartialResponseOptions = { + fields?: string; +}; + +// @public (undocumented) +export type RequestOptions = FilterAndSortOptions & + PaginationOptions & + PartialResponseOptions & { + [key: string]: string | number | undefined; + }; + +// @public (undocumented) +export class WithPagination< + TPage extends Models.Paginated, + TResultItem, +> { + constructor( + createUrl: (options: PaginationOptions) => URL, + fetch: (url: URL) => Promise, + ); + // (undocumented) + getPage(options?: PaginationOptions): Promise; + // (undocumented) + iteratePages(options?: PaginationOptions): AsyncGenerator; + // (undocumented) + iterateResults( + options?: PaginationOptions, + ): AsyncGenerator, void, unknown>; +} + +// Warnings were encountered during analysis: +// +// src/BitbucketCloudClient.d.ts:6:1 - (ae-undocumented) Missing documentation for "BitbucketCloudClient". +// src/BitbucketCloudClient.d.ts:8:5 - (ae-undocumented) Missing documentation for "fromConfig". +// src/BitbucketCloudClient.d.ts:10:5 - (ae-undocumented) Missing documentation for "searchCode". +// src/BitbucketCloudClient.d.ts:11:5 - (ae-undocumented) Missing documentation for "listRepositoriesByWorkspace". +// src/BitbucketCloudClient.d.ts:12:5 - (ae-undocumented) Missing documentation for "listProjectsByWorkspace". +// src/BitbucketCloudClient.d.ts:13:5 - (ae-undocumented) Missing documentation for "listWorkspaces". +// src/BitbucketCloudClient.d.ts:14:5 - (ae-undocumented) Missing documentation for "listBranchesByRepository". +// src/events/index.d.ts:3:1 - (ae-undocumented) Missing documentation for "Events". +// src/events/index.d.ts:5:5 - (ae-undocumented) Missing documentation for "RepoEvent". +// src/events/index.d.ts:6:9 - (ae-undocumented) Missing documentation for "repository". +// src/events/index.d.ts:9:9 - (ae-undocumented) Missing documentation for "actor". +// src/events/index.d.ts:12:5 - (ae-undocumented) Missing documentation for "RepoPushEvent". +// src/events/index.d.ts:13:9 - (ae-undocumented) Missing documentation for "push". +// src/events/index.d.ts:16:5 - (ae-undocumented) Missing documentation for "RepoPush". +// src/events/index.d.ts:17:9 - (ae-undocumented) Missing documentation for "changes". +// src/events/index.d.ts:20:5 - (ae-undocumented) Missing documentation for "Change". +// src/events/index.d.ts:21:9 - (ae-undocumented) Missing documentation for "old". +// src/events/index.d.ts:22:9 - (ae-undocumented) Missing documentation for "new". +// src/events/index.d.ts:23:9 - (ae-undocumented) Missing documentation for "truncated". +// src/events/index.d.ts:24:9 - (ae-undocumented) Missing documentation for "created". +// src/events/index.d.ts:25:9 - (ae-undocumented) Missing documentation for "forced". +// src/events/index.d.ts:26:9 - (ae-undocumented) Missing documentation for "closed". +// src/events/index.d.ts:27:9 - (ae-undocumented) Missing documentation for "links". +// src/events/index.d.ts:28:9 - (ae-undocumented) Missing documentation for "commits". +// src/events/index.d.ts:31:5 - (ae-undocumented) Missing documentation for "ChangeLinks". +// src/events/index.d.ts:32:9 - (ae-undocumented) Missing documentation for "commits". +// src/events/index.d.ts:33:9 - (ae-undocumented) Missing documentation for "diff". +// src/events/index.d.ts:34:9 - (ae-undocumented) Missing documentation for "html". +// src/models/index.d.ts:13:1 - (ae-undocumented) Missing documentation for "Models". +// src/models/index.d.ts:19:9 - (ae-undocumented) Missing documentation for "created_on". +// src/models/index.d.ts:20:9 - (ae-undocumented) Missing documentation for "display_name". +// src/models/index.d.ts:21:9 - (ae-undocumented) Missing documentation for "links". +// src/models/index.d.ts:22:9 - (ae-undocumented) Missing documentation for "username". +// src/models/index.d.ts:23:9 - (ae-undocumented) Missing documentation for "uuid". +// src/models/index.d.ts:30:9 - (ae-undocumented) Missing documentation for "__index". +// src/models/index.d.ts:31:9 - (ae-undocumented) Missing documentation for "avatar". +// src/models/index.d.ts:42:9 - (ae-undocumented) Missing documentation for "user". +// src/models/index.d.ts:49:9 - (ae-undocumented) Missing documentation for "author". +// src/models/index.d.ts:50:9 - (ae-undocumented) Missing documentation for "date". +// src/models/index.d.ts:51:9 - (ae-undocumented) Missing documentation for "hash". +// src/models/index.d.ts:52:9 - (ae-undocumented) Missing documentation for "message". +// src/models/index.d.ts:53:9 - (ae-undocumented) Missing documentation for "parents". +// src/models/index.d.ts:54:9 - (ae-undocumented) Missing documentation for "summary". +// src/models/index.d.ts:59:5 - (ae-undocumented) Missing documentation for "BaseCommitSummary". +// src/models/index.d.ts:92:9 - (ae-undocumented) Missing documentation for "links". +// src/models/index.d.ts:97:9 - (ae-undocumented) Missing documentation for "target". +// src/models/index.d.ts:98:9 - (ae-undocumented) Missing documentation for "type". +// src/models/index.d.ts:127:9 - (ae-undocumented) Missing documentation for "participants". +// src/models/index.d.ts:128:9 - (ae-undocumented) Missing documentation for "repository". +// src/models/index.d.ts:135:9 - (ae-undocumented) Missing documentation for "__index". +// src/models/index.d.ts:136:9 - (ae-undocumented) Missing documentation for "attributes". +// src/models/index.d.ts:137:9 - (ae-undocumented) Missing documentation for "commit". +// src/models/index.d.ts:146:9 - (ae-undocumented) Missing documentation for "type". +// src/models/index.d.ts:151:11 - (ae-undocumented) Missing documentation for "CommitFileAttributesEnum". +// src/models/index.d.ts:161:5 - (ae-undocumented) Missing documentation for "CommitFileAttributesEnum". +// src/models/index.d.ts:167:9 - (ae-undocumented) Missing documentation for "href". +// src/models/index.d.ts:168:9 - (ae-undocumented) Missing documentation for "name". +// src/models/index.d.ts:175:9 - (ae-undocumented) Missing documentation for "__index". +// src/models/index.d.ts:176:9 - (ae-undocumented) Missing documentation for "type". +// src/models/index.d.ts:253:9 - (ae-undocumented) Missing documentation for "approved". +// src/models/index.d.ts:258:9 - (ae-undocumented) Missing documentation for "role". +// src/models/index.d.ts:259:9 - (ae-undocumented) Missing documentation for "state". +// src/models/index.d.ts:260:9 - (ae-undocumented) Missing documentation for "user". +// src/models/index.d.ts:265:11 - (ae-undocumented) Missing documentation for "ParticipantRoleEnum". +// src/models/index.d.ts:272:5 - (ae-undocumented) Missing documentation for "ParticipantRoleEnum". +// src/models/index.d.ts:276:11 - (ae-undocumented) Missing documentation for "ParticipantStateEnum". +// src/models/index.d.ts:284:5 - (ae-undocumented) Missing documentation for "ParticipantStateEnum". +// src/models/index.d.ts:291:9 - (ae-undocumented) Missing documentation for "created_on". +// src/models/index.d.ts:292:9 - (ae-undocumented) Missing documentation for "description". +// src/models/index.d.ts:310:9 - (ae-undocumented) Missing documentation for "links". +// src/models/index.d.ts:315:9 - (ae-undocumented) Missing documentation for "owner". +// src/models/index.d.ts:316:9 - (ae-undocumented) Missing documentation for "updated_on". +// src/models/index.d.ts:325:5 - (ae-undocumented) Missing documentation for "ProjectLinks". +// src/models/index.d.ts:326:9 - (ae-undocumented) Missing documentation for "avatar". +// src/models/index.d.ts:327:9 - (ae-undocumented) Missing documentation for "html". +// src/models/index.d.ts:332:5 - (ae-undocumented) Missing documentation for "RefLinks". +// src/models/index.d.ts:333:9 - (ae-undocumented) Missing documentation for "commits". +// src/models/index.d.ts:334:9 - (ae-undocumented) Missing documentation for "html". +// src/models/index.d.ts:335:9 - (ae-undocumented) Missing documentation for "self". +// src/models/index.d.ts:342:9 - (ae-undocumented) Missing documentation for "created_on". +// src/models/index.d.ts:343:9 - (ae-undocumented) Missing documentation for "description". +// src/models/index.d.ts:372:9 - (ae-undocumented) Missing documentation for "is_private". +// src/models/index.d.ts:373:9 - (ae-undocumented) Missing documentation for "language". +// src/models/index.d.ts:374:9 - (ae-undocumented) Missing documentation for "links". +// src/models/index.d.ts:375:9 - (ae-undocumented) Missing documentation for "mainbranch". +// src/models/index.d.ts:376:9 - (ae-undocumented) Missing documentation for "name". +// src/models/index.d.ts:377:9 - (ae-undocumented) Missing documentation for "owner". +// src/models/index.d.ts:378:9 - (ae-undocumented) Missing documentation for "parent". +// src/models/index.d.ts:379:9 - (ae-undocumented) Missing documentation for "project". +// src/models/index.d.ts:380:9 - (ae-undocumented) Missing documentation for "scm". +// src/models/index.d.ts:381:9 - (ae-undocumented) Missing documentation for "size". +// src/models/index.d.ts:386:9 - (ae-undocumented) Missing documentation for "updated_on". +// src/models/index.d.ts:421:11 - (ae-undocumented) Missing documentation for "RepositoryScmEnum". +// src/models/index.d.ts:427:5 - (ae-undocumented) Missing documentation for "RepositoryScmEnum". +// src/models/index.d.ts:431:5 - (ae-undocumented) Missing documentation for "RepositoryLinks". +// src/models/index.d.ts:432:9 - (ae-undocumented) Missing documentation for "avatar". +// src/models/index.d.ts:433:9 - (ae-undocumented) Missing documentation for "clone". +// src/models/index.d.ts:434:9 - (ae-undocumented) Missing documentation for "commits". +// src/models/index.d.ts:435:9 - (ae-undocumented) Missing documentation for "downloads". +// src/models/index.d.ts:436:9 - (ae-undocumented) Missing documentation for "forks". +// src/models/index.d.ts:437:9 - (ae-undocumented) Missing documentation for "hooks". +// src/models/index.d.ts:438:9 - (ae-undocumented) Missing documentation for "html". +// src/models/index.d.ts:439:9 - (ae-undocumented) Missing documentation for "pullrequests". +// src/models/index.d.ts:440:9 - (ae-undocumented) Missing documentation for "self". +// src/models/index.d.ts:441:9 - (ae-undocumented) Missing documentation for "watchers". +// src/models/index.d.ts:446:5 - (ae-undocumented) Missing documentation for "SearchCodeSearchResult". +// src/models/index.d.ts:447:9 - (ae-undocumented) Missing documentation for "content_match_count". +// src/models/index.d.ts:448:9 - (ae-undocumented) Missing documentation for "content_matches". +// src/models/index.d.ts:449:9 - (ae-undocumented) Missing documentation for "file". +// src/models/index.d.ts:450:9 - (ae-undocumented) Missing documentation for "path_matches". +// src/models/index.d.ts:451:9 - (ae-undocumented) Missing documentation for "type". +// src/models/index.d.ts:456:5 - (ae-undocumented) Missing documentation for "SearchContentMatch". +// src/models/index.d.ts:457:9 - (ae-undocumented) Missing documentation for "lines". +// src/models/index.d.ts:462:5 - (ae-undocumented) Missing documentation for "SearchLine". +// src/models/index.d.ts:463:9 - (ae-undocumented) Missing documentation for "line". +// src/models/index.d.ts:464:9 - (ae-undocumented) Missing documentation for "segments". +// src/models/index.d.ts:469:5 - (ae-undocumented) Missing documentation for "SearchResultPage". +// src/models/index.d.ts:470:9 - (ae-undocumented) Missing documentation for "query_substituted". +// src/models/index.d.ts:479:5 - (ae-undocumented) Missing documentation for "SearchSegment". +// src/models/index.d.ts:480:9 - (ae-undocumented) Missing documentation for "match". +// src/models/index.d.ts:481:9 - (ae-undocumented) Missing documentation for "text". +// src/models/index.d.ts:488:9 - (ae-undocumented) Missing documentation for "links". +// src/models/index.d.ts:495:9 - (ae-undocumented) Missing documentation for "html". +// src/models/index.d.ts:496:9 - (ae-undocumented) Missing documentation for "members". +// src/models/index.d.ts:497:9 - (ae-undocumented) Missing documentation for "projects". +// src/models/index.d.ts:498:9 - (ae-undocumented) Missing documentation for "repositories". +// src/models/index.d.ts:499:9 - (ae-undocumented) Missing documentation for "self". +// src/models/index.d.ts:507:9 - (ae-undocumented) Missing documentation for "created_on". +// src/models/index.d.ts:513:9 - (ae-undocumented) Missing documentation for "links". +// src/models/index.d.ts:522:9 - (ae-undocumented) Missing documentation for "updated_on". +// src/models/index.d.ts:531:5 - (ae-undocumented) Missing documentation for "WorkspaceLinks". +// src/models/index.d.ts:532:9 - (ae-undocumented) Missing documentation for "avatar". +// src/models/index.d.ts:533:9 - (ae-undocumented) Missing documentation for "html". +// src/models/index.d.ts:534:9 - (ae-undocumented) Missing documentation for "members". +// src/models/index.d.ts:535:9 - (ae-undocumented) Missing documentation for "owners". +// src/models/index.d.ts:536:9 - (ae-undocumented) Missing documentation for "projects". +// src/models/index.d.ts:537:9 - (ae-undocumented) Missing documentation for "repositories". +// src/models/index.d.ts:538:9 - (ae-undocumented) Missing documentation for "self". +// src/models/index.d.ts:539:9 - (ae-undocumented) Missing documentation for "snippets". +// src/pagination.d.ts:3:1 - (ae-undocumented) Missing documentation for "PaginationOptions". +// src/pagination.d.ts:8:1 - (ae-undocumented) Missing documentation for "WithPagination". +// src/pagination.d.ts:12:5 - (ae-undocumented) Missing documentation for "getPage". +// src/pagination.d.ts:13:5 - (ae-undocumented) Missing documentation for "iteratePages". +// src/pagination.d.ts:14:5 - (ae-undocumented) Missing documentation for "iterateResults". +// src/types.d.ts:3:1 - (ae-undocumented) Missing documentation for "FilterAndSortOptions". +// src/types.d.ts:8:1 - (ae-undocumented) Missing documentation for "PartialResponseOptions". +// src/types.d.ts:12:1 - (ae-undocumented) Missing documentation for "RequestOptions". +``` diff --git a/plugins/catalog-backend-module-aws/CHANGELOG.md b/plugins/catalog-backend-module-aws/CHANGELOG.md index aea8617e9b..cb681f73cf 100644 --- a/plugins/catalog-backend-module-aws/CHANGELOG.md +++ b/plugins/catalog-backend-module-aws/CHANGELOG.md @@ -1,5 +1,70 @@ # @backstage/plugin-catalog-backend-module-aws +## 0.4.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.1-next.1 + - @backstage/integration@1.15.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-kubernetes-common@0.8.3 + +## 0.4.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.15.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-kubernetes-common@0.8.3 + +## 0.4.2 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-defaults@0.5.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/integration@1.15.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-kubernetes-common@0.8.3 + +## 0.4.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/integration@1.15.0-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.2 + - @backstage/plugin-kubernetes-common@0.8.2 + ## 0.4.2-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-aws/package.json b/plugins/catalog-backend-module-aws/package.json index 1d9891ade3..4fc13c978f 100644 --- a/plugins/catalog-backend-module-aws/package.json +++ b/plugins/catalog-backend-module-aws/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-aws", - "version": "0.4.2-next.1", + "version": "0.4.3-next.1", "description": "A Backstage catalog backend module that helps integrate towards AWS", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-aws/api-report-alpha.md b/plugins/catalog-backend-module-aws/report-alpha.api.md similarity index 100% rename from plugins/catalog-backend-module-aws/api-report-alpha.md rename to plugins/catalog-backend-module-aws/report-alpha.api.md diff --git a/plugins/catalog-backend-module-aws/api-report.md b/plugins/catalog-backend-module-aws/report.api.md similarity index 74% rename from plugins/catalog-backend-module-aws/api-report.md rename to plugins/catalog-backend-module-aws/report.api.md index 98d757270e..3d24c71035 100644 --- a/plugins/catalog-backend-module-aws/api-report.md +++ b/plugins/catalog-backend-module-aws/report.api.md @@ -89,7 +89,6 @@ export class AwsS3DiscoveryProcessor implements CatalogProcessor { // @public export class AwsS3EntityProvider implements EntityProvider { - // (undocumented) connect(connection: EntityProviderConnection): Promise; // (undocumented) static fromConfig( @@ -100,7 +99,6 @@ export class AwsS3EntityProvider implements EntityProvider { scheduler?: SchedulerService; }, ): AwsS3EntityProvider[]; - // (undocumented) getProviderName(): string; // (undocumented) refresh(logger: LoggerService): Promise; @@ -114,4 +112,17 @@ export type EksClusterEntityTransformer = ( cluster: Cluster, accountId: string, ) => Promise; + +// Warnings were encountered during analysis: +// +// src/processors/AwsEKSClusterProcessor.d.ts:18:5 - (ae-undocumented) Missing documentation for "fromConfig". +// src/processors/AwsEKSClusterProcessor.d.ts:26:5 - (ae-undocumented) Missing documentation for "getProcessorName". +// src/processors/AwsEKSClusterProcessor.d.ts:27:5 - (ae-undocumented) Missing documentation for "readLocation". +// src/processors/AwsOrganizationCloudAccountProcessor.d.ts:17:5 - (ae-undocumented) Missing documentation for "fromConfig". +// src/processors/AwsOrganizationCloudAccountProcessor.d.ts:21:5 - (ae-undocumented) Missing documentation for "getProcessorName". +// src/processors/AwsOrganizationCloudAccountProcessor.d.ts:22:5 - (ae-undocumented) Missing documentation for "readLocation". +// src/processors/AwsS3DiscoveryProcessor.d.ts:15:5 - (ae-undocumented) Missing documentation for "getProcessorName". +// src/processors/AwsS3DiscoveryProcessor.d.ts:16:5 - (ae-undocumented) Missing documentation for "readLocation". +// src/providers/AwsS3EntityProvider.d.ts:20:5 - (ae-undocumented) Missing documentation for "fromConfig". +// src/providers/AwsS3EntityProvider.d.ts:31:5 - (ae-undocumented) Missing documentation for "refresh". ``` diff --git a/plugins/catalog-backend-module-azure/CHANGELOG.md b/plugins/catalog-backend-module-azure/CHANGELOG.md index 4215a5a156..13ae485a4c 100644 --- a/plugins/catalog-backend-module-azure/CHANGELOG.md +++ b/plugins/catalog-backend-module-azure/CHANGELOG.md @@ -1,5 +1,50 @@ # @backstage/plugin-catalog-backend-module-azure +## 0.2.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.15.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + +## 0.2.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.15.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + +## 0.2.2 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/integration@1.15.0 + - @backstage/config@1.2.0 + +## 0.2.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/integration@1.15.0-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.2 + ## 0.2.2-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-azure/package.json b/plugins/catalog-backend-module-azure/package.json index ce62913fe5..f9079e4416 100644 --- a/plugins/catalog-backend-module-azure/package.json +++ b/plugins/catalog-backend-module-azure/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-azure", - "version": "0.2.2-next.1", + "version": "0.2.3-next.1", "description": "A Backstage catalog backend module that helps integrate towards Azure", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-azure/api-report-alpha.md b/plugins/catalog-backend-module-azure/report-alpha.api.md similarity index 100% rename from plugins/catalog-backend-module-azure/api-report-alpha.md rename to plugins/catalog-backend-module-azure/report-alpha.api.md diff --git a/plugins/catalog-backend-module-azure/api-report.md b/plugins/catalog-backend-module-azure/report.api.md similarity index 74% rename from plugins/catalog-backend-module-azure/api-report.md rename to plugins/catalog-backend-module-azure/report.api.md index 9220b08ab4..f3121296a5 100644 --- a/plugins/catalog-backend-module-azure/api-report.md +++ b/plugins/catalog-backend-module-azure/report.api.md @@ -39,7 +39,6 @@ export class AzureDevOpsDiscoveryProcessor implements CatalogProcessor { // @public export class AzureDevOpsEntityProvider implements EntityProvider { - // (undocumented) connect(connection: EntityProviderConnection): Promise; // (undocumented) static fromConfig( @@ -50,9 +49,16 @@ export class AzureDevOpsEntityProvider implements EntityProvider { scheduler?: SchedulerService; }, ): AzureDevOpsEntityProvider[]; - // (undocumented) getProviderName(): string; // (undocumented) refresh(logger: LoggerService): Promise; } + +// Warnings were encountered during analysis: +// +// src/processors/AzureDevOpsDiscoveryProcessor.d.ts:26:5 - (ae-undocumented) Missing documentation for "fromConfig". +// src/processors/AzureDevOpsDiscoveryProcessor.d.ts:33:5 - (ae-undocumented) Missing documentation for "getProcessorName". +// src/processors/AzureDevOpsDiscoveryProcessor.d.ts:34:5 - (ae-undocumented) Missing documentation for "readLocation". +// src/providers/AzureDevOpsEntityProvider.d.ts:18:5 - (ae-undocumented) Missing documentation for "fromConfig". +// src/providers/AzureDevOpsEntityProvider.d.ts:29:5 - (ae-undocumented) Missing documentation for "refresh". ``` diff --git a/plugins/catalog-backend-module-backstage-openapi/CHANGELOG.md b/plugins/catalog-backend-module-backstage-openapi/CHANGELOG.md index c04f478566..b2eb03c321 100644 --- a/plugins/catalog-backend-module-backstage-openapi/CHANGELOG.md +++ b/plugins/catalog-backend-module-backstage-openapi/CHANGELOG.md @@ -1,5 +1,49 @@ # @backstage/plugin-catalog-backend-module-backstage-openapi +## 0.4.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-openapi-utils@0.1.19-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.13.1-next.0 + +## 0.4.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/backend-openapi-utils@0.1.18 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## 0.4.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/backend-openapi-utils@0.1.18-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.12.7-next.2 + ## 0.4.0-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-backstage-openapi/package.json b/plugins/catalog-backend-module-backstage-openapi/package.json index 54de9a7b3b..e72a9eb9de 100644 --- a/plugins/catalog-backend-module-backstage-openapi/package.json +++ b/plugins/catalog-backend-module-backstage-openapi/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-backstage-openapi", - "version": "0.4.0-next.1", + "version": "0.4.1-next.0", "backstage": { "role": "backend-plugin-module", "pluginId": "catalog", diff --git a/plugins/catalog-backend-module-backstage-openapi/api-report.md b/plugins/catalog-backend-module-backstage-openapi/report.api.md similarity index 65% rename from plugins/catalog-backend-module-backstage-openapi/api-report.md rename to plugins/catalog-backend-module-backstage-openapi/report.api.md index 06334182cb..88ad499e84 100644 --- a/plugins/catalog-backend-module-backstage-openapi/api-report.md +++ b/plugins/catalog-backend-module-backstage-openapi/report.api.md @@ -18,5 +18,11 @@ export type MetaApiDocsPluginOptions = { // @public (undocumented) export const metaOpenApiDocsPluginId = 'meta-api-docs'; +// Warnings were encountered during analysis: +// +// src/index.d.ts:4:1 - (ae-undocumented) Missing documentation for "MetaApiDocsPluginOptions". +// src/index.d.ts:10:22 - (ae-undocumented) Missing documentation for "metaOpenApiDocsPluginId". +// src/index.d.ts:14:22 - (ae-undocumented) Missing documentation for "catalogModuleInternalOpenApiSpec". + // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md b/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md index 8def9570bf..0a55e9351a 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md +++ b/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md @@ -1,5 +1,70 @@ # @backstage/plugin-catalog-backend-module-bitbucket-cloud +## 0.3.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.15.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.24-next.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + +## 0.3.3-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.15.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.23 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + +## 0.3.2 + +### Patch Changes + +- 19ff127: Internal refactor to remove dependencies on the identity and token manager services, which have been removed. Public APIs no longer require the identity service or token manager to be provided. +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/catalog-client@1.7.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/integration@1.15.0 + - @backstage/plugin-events-node@0.4.0 + - @backstage/config@1.2.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.23 + +## 0.3.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-client@1.7.0-next.1 + - @backstage/integration@1.15.0-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.23-next.0 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.2 + - @backstage/plugin-events-node@0.4.0-next.2 + ## 0.3.2-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-bitbucket-cloud/package.json b/plugins/catalog-backend-module-bitbucket-cloud/package.json index 04de284c56..eecb4011d5 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/package.json +++ b/plugins/catalog-backend-module-bitbucket-cloud/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-bitbucket-cloud", - "version": "0.3.2-next.1", + "version": "0.3.3-next.1", "description": "A Backstage catalog backend module that helps integrate towards Bitbucket Cloud", "backstage": { "role": "backend-plugin-module", @@ -51,7 +51,6 @@ "test": "backstage-cli package test" }, "dependencies": { - "@backstage/backend-common": "workspace:^", "@backstage/backend-plugin-api": "workspace:^", "@backstage/catalog-client": "workspace:^", "@backstage/catalog-model": "workspace:^", @@ -64,7 +63,6 @@ "uuid": "^9.0.0" }, "devDependencies": { - "@backstage/backend-common": "workspace:^", "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "@backstage/plugin-events-backend-test-utils": "workspace:^", diff --git a/plugins/catalog-backend-module-bitbucket-cloud/api-report-alpha.md b/plugins/catalog-backend-module-bitbucket-cloud/report-alpha.api.md similarity index 69% rename from plugins/catalog-backend-module-bitbucket-cloud/api-report-alpha.md rename to plugins/catalog-backend-module-bitbucket-cloud/report-alpha.api.md index 34ec7a692a..3f0a2d1514 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/api-report-alpha.md +++ b/plugins/catalog-backend-module-bitbucket-cloud/report-alpha.api.md @@ -9,5 +9,9 @@ import { BackendFeature } from '@backstage/backend-plugin-api'; const catalogModuleBitbucketCloudEntityProvider: BackendFeature; export default catalogModuleBitbucketCloudEntityProvider; +// Warnings were encountered during analysis: +// +// src/module/catalogModuleBitbucketCloudEntityProvider.d.ts:4:22 - (ae-undocumented) Missing documentation for "catalogModuleBitbucketCloudEntityProvider". + // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/catalog-backend-module-bitbucket-cloud/api-report.md b/plugins/catalog-backend-module-bitbucket-cloud/report.api.md similarity index 71% rename from plugins/catalog-backend-module-bitbucket-cloud/api-report.md rename to plugins/catalog-backend-module-bitbucket-cloud/report.api.md index bba0b754e2..d0248b3973 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/api-report.md +++ b/plugins/catalog-backend-module-bitbucket-cloud/report.api.md @@ -3,6 +3,7 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts +import { AuthService } from '@backstage/backend-plugin-api'; import { CatalogApi } from '@backstage/catalog-client'; import { Config } from '@backstage/config'; import { EntityProvider } from '@backstage/plugin-catalog-node'; @@ -12,31 +13,33 @@ import { EventsService } from '@backstage/plugin-events-node'; import { LoggerService } from '@backstage/backend-plugin-api'; import { SchedulerService } from '@backstage/backend-plugin-api'; import { SchedulerServiceTaskRunner } from '@backstage/backend-plugin-api'; -import { TokenManager } from '@backstage/backend-common'; // @public export class BitbucketCloudEntityProvider implements EntityProvider { - // (undocumented) connect(connection: EntityProviderConnection): Promise; // (undocumented) static fromConfig( config: Config, options: { - catalogApi?: CatalogApi; - events?: EventsService; + auth: AuthService; + catalogApi: CatalogApi; + events: EventsService; logger: LoggerService; schedule?: SchedulerServiceTaskRunner; scheduler?: SchedulerService; - tokenManager?: TokenManager; }, ): BitbucketCloudEntityProvider[]; - // (undocumented) getProviderName(): string; - // (undocumented) getTaskId(): string; // (undocumented) onRepoPush(event: Events.RepoPushEvent): Promise; // (undocumented) refresh(logger: LoggerService): Promise; } + +// Warnings were encountered during analysis: +// +// src/providers/BitbucketCloudEntityProvider.d.ts:26:5 - (ae-undocumented) Missing documentation for "fromConfig". +// src/providers/BitbucketCloudEntityProvider.d.ts:42:5 - (ae-undocumented) Missing documentation for "refresh". +// src/providers/BitbucketCloudEntityProvider.d.ts:44:5 - (ae-undocumented) Missing documentation for "onRepoPush". ``` diff --git a/plugins/catalog-backend-module-bitbucket-cloud/src/module/catalogModuleBitbucketCloudEntityProvider.ts b/plugins/catalog-backend-module-bitbucket-cloud/src/module/catalogModuleBitbucketCloudEntityProvider.ts index 179e74b8c0..8cc8f50d5b 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/src/module/catalogModuleBitbucketCloudEntityProvider.ts +++ b/plugins/catalog-backend-module-bitbucket-cloud/src/module/catalogModuleBitbucketCloudEntityProvider.ts @@ -34,6 +34,7 @@ export const catalogModuleBitbucketCloudEntityProvider = createBackendModule({ register(env) { env.registerInit({ deps: { + auth: coreServices.auth, catalog: catalogProcessingExtensionPoint, catalogApi: catalogServiceRef, config: coreServices.rootConfig, @@ -41,8 +42,17 @@ export const catalogModuleBitbucketCloudEntityProvider = createBackendModule({ logger: coreServices.logger, scheduler: coreServices.scheduler, }, - async init({ catalog, catalogApi, config, events, logger, scheduler }) { + async init({ + auth, + catalog, + catalogApi, + config, + events, + logger, + scheduler, + }) { const providers = BitbucketCloudEntityProvider.fromConfig(config, { + auth, catalogApi, events, logger, diff --git a/plugins/catalog-backend-module-bitbucket-cloud/src/providers/BitbucketCloudEntityProvider.test.ts b/plugins/catalog-backend-module-bitbucket-cloud/src/providers/BitbucketCloudEntityProvider.test.ts index 4fbbb67c7d..baea86715c 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/src/providers/BitbucketCloudEntityProvider.test.ts +++ b/plugins/catalog-backend-module-bitbucket-cloud/src/providers/BitbucketCloudEntityProvider.test.ts @@ -14,9 +14,7 @@ * limitations under the License. */ -import { TokenManager } from '@backstage/backend-common'; import { - SchedulerService, SchedulerServiceTaskInvocationDefinition, SchedulerServiceTaskRunner, } from '@backstage/backend-plugin-api'; @@ -24,7 +22,6 @@ import { mockServices, registerMswTestHooks, } from '@backstage/backend-test-utils'; -import { CatalogApi } from '@backstage/catalog-client'; import { Entity, LocationEntity } from '@backstage/catalog-model'; import { ConfigReader } from '@backstage/config'; import { @@ -39,6 +36,7 @@ import { ANNOTATION_BITBUCKET_CLOUD_REPO_URL, BitbucketCloudEntityProvider, } from './BitbucketCloudEntityProvider'; +import { catalogServiceMock } from '@backstage/plugin-catalog-node/testUtils'; class PersistingTaskRunner implements SchedulerServiceTaskRunner { private tasks: SchedulerServiceTaskInvocationDefinition[] = []; @@ -60,10 +58,9 @@ class PersistingTaskRunner implements SchedulerServiceTaskRunner { const logger = mockServices.logger.mock(); const server = setupServer(); +registerMswTestHooks(server); describe('BitbucketCloudEntityProvider', () => { - registerMswTestHooks(server); - const simpleConfig = new ConfigReader({ catalog: { providers: { @@ -94,11 +91,6 @@ describe('BitbucketCloudEntityProvider', () => { applyMutation: jest.fn(), refresh: jest.fn(), }; - const tokenManager = { - getToken: async () => { - return { token: 'fake-token' }; - }, - } as any as TokenManager; const repoPushEvent: Events.RepoPushEvent = { actor: { type: 'user', @@ -160,8 +152,14 @@ describe('BitbucketCloudEntityProvider', () => { }); it('no provider config', () => { + const auth = mockServices.auth.mock(); + const catalogApi = catalogServiceMock.mock(); const config = new ConfigReader({}); + const events = DefaultEventsService.create({ logger }); const providers = BitbucketCloudEntityProvider.fromConfig(config, { + auth, + catalogApi, + events, logger, schedule, }); @@ -170,7 +168,13 @@ describe('BitbucketCloudEntityProvider', () => { }); it('single simple provider config', () => { + const auth = mockServices.auth.mock(); + const catalogApi = catalogServiceMock.mock(); + const events = DefaultEventsService.create({ logger }); const providers = BitbucketCloudEntityProvider.fromConfig(simpleConfig, { + auth, + catalogApi, + events, logger, schedule, }); @@ -182,15 +186,25 @@ describe('BitbucketCloudEntityProvider', () => { }); it('fail without schedule and scheduler', () => { + const auth = mockServices.auth.mock(); + const catalogApi = catalogServiceMock.mock(); + const events = DefaultEventsService.create({ logger }); + expect(() => BitbucketCloudEntityProvider.fromConfig(simpleConfig, { + auth, + catalogApi, + events, logger, }), ).toThrow('Either schedule or scheduler must be provided.'); }); it('fail with scheduler but no schedule config', () => { - const scheduler = jest.fn() as unknown as SchedulerService; + const auth = mockServices.auth.mock(); + const catalogApi = catalogServiceMock.mock(); + const events = DefaultEventsService.create({ logger }); + const scheduler = mockServices.scheduler.mock(); const config = new ConfigReader({ catalog: { providers: { @@ -203,6 +217,9 @@ describe('BitbucketCloudEntityProvider', () => { expect(() => BitbucketCloudEntityProvider.fromConfig(config, { + auth, + catalogApi, + events, logger, scheduler, }), @@ -212,9 +229,10 @@ describe('BitbucketCloudEntityProvider', () => { }); it('single simple provider config with schedule in config', () => { - const scheduler = { - createScheduledTaskRunner: (_: any) => jest.fn(), - } as unknown as SchedulerService; + const auth = mockServices.auth.mock(); + const catalogApi = catalogServiceMock.mock(); + const events = DefaultEventsService.create({ logger }); + const scheduler = mockServices.scheduler.mock(); const config = new ConfigReader({ catalog: { providers: { @@ -230,6 +248,9 @@ describe('BitbucketCloudEntityProvider', () => { }); const providers = BitbucketCloudEntityProvider.fromConfig(config, { + auth, + catalogApi, + events, logger, scheduler, }); @@ -241,6 +262,8 @@ describe('BitbucketCloudEntityProvider', () => { }); it('multiple provider configs', () => { + const auth = mockServices.auth.mock(); + const catalogApi = catalogServiceMock.mock(); const config = new ConfigReader({ catalog: { providers: { @@ -255,7 +278,11 @@ describe('BitbucketCloudEntityProvider', () => { }, }, }); + const events = DefaultEventsService.create({ logger }); const providers = BitbucketCloudEntityProvider.fromConfig(config, { + auth, + catalogApi, + events, logger, schedule, }); @@ -270,7 +297,13 @@ describe('BitbucketCloudEntityProvider', () => { }); it('apply full update on scheduled execution', async () => { + const auth = mockServices.auth.mock(); + const catalogApi = catalogServiceMock.mock(); + const events = DefaultEventsService.create({ logger }); const provider = BitbucketCloudEntityProvider.fromConfig(defaultConfig, { + auth, + catalogApi, + events, logger, schedule, })[0]; @@ -440,8 +473,11 @@ describe('BitbucketCloudEntityProvider', () => { 'added-module/catalog-custom.yaml', ); + const auth = mockServices.auth.mock({ + getPluginRequestToken: async () => ({ token: 'fake-token' }), + }); const events = DefaultEventsService.create({ logger }); - const catalogApi = { + const catalogApi = catalogServiceMock.mock({ getEntities: async ( request: { filter: Record }, options: { token: string }, @@ -459,13 +495,13 @@ describe('BitbucketCloudEntityProvider', () => { items: [keptModule, removedModule], }; }, - }; + }); const provider = BitbucketCloudEntityProvider.fromConfig(defaultConfig, { - catalogApi: catalogApi as any as CatalogApi, + auth, + catalogApi, events, logger, schedule, - tokenManager, })[0]; server.use( @@ -573,17 +609,15 @@ describe('BitbucketCloudEntityProvider', () => { }); it('no onRepoPush update on non-matching workspace slug', async () => { - const catalogApi = { - getEntities: jest.fn(), - refreshEntity: jest.fn(), - }; + const auth = mockServices.auth.mock(); + const catalogApi = catalogServiceMock.mock(); const events = DefaultEventsService.create({ logger }); const provider = BitbucketCloudEntityProvider.fromConfig(defaultConfig, { - catalogApi: catalogApi as any as CatalogApi, + auth, + catalogApi, events, logger, schedule, - tokenManager, })[0]; await provider.connect(entityProviderConnection); @@ -606,17 +640,15 @@ describe('BitbucketCloudEntityProvider', () => { }); it('no onRepoPush update on non-matching repo slug', async () => { - const catalogApi = { - getEntities: jest.fn(), - refreshEntity: jest.fn(), - }; + const auth = mockServices.auth.mock(); + const catalogApi = catalogServiceMock.mock(); const events = DefaultEventsService.create({ logger }); const provider = BitbucketCloudEntityProvider.fromConfig(defaultConfig, { - catalogApi: catalogApi as any as CatalogApi, + auth, + catalogApi, events, logger, schedule, - tokenManager, })[0]; await provider.connect(entityProviderConnection); diff --git a/plugins/catalog-backend-module-bitbucket-cloud/src/providers/BitbucketCloudEntityProvider.ts b/plugins/catalog-backend-module-bitbucket-cloud/src/providers/BitbucketCloudEntityProvider.ts index 6b19bea4f2..b439f391ca 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/src/providers/BitbucketCloudEntityProvider.ts +++ b/plugins/catalog-backend-module-bitbucket-cloud/src/providers/BitbucketCloudEntityProvider.ts @@ -14,8 +14,8 @@ * limitations under the License. */ -import { TokenManager } from '@backstage/backend-common'; import { + AuthService, LoggerService, SchedulerService, SchedulerServiceTaskRunner, @@ -66,26 +66,25 @@ interface IngestionTarget { * @public */ export class BitbucketCloudEntityProvider implements EntityProvider { + private readonly auth: AuthService; + private readonly catalogApi: CatalogApi; private readonly client: BitbucketCloudClient; private readonly config: BitbucketCloudEntityProviderConfig; + private readonly events: EventsService; private readonly logger: LoggerService; private readonly scheduleFn: () => Promise; - private readonly catalogApi?: CatalogApi; - private readonly events?: EventsService; - private readonly tokenManager?: TokenManager; - private connection?: EntityProviderConnection; - private eventConfigErrorThrown = false; + private connection?: EntityProviderConnection; static fromConfig( config: Config, options: { - catalogApi?: CatalogApi; - events?: EventsService; + auth: AuthService; + catalogApi: CatalogApi; + events: EventsService; logger: LoggerService; schedule?: SchedulerServiceTaskRunner; scheduler?: SchedulerService; - tokenManager?: TokenManager; }, ): BitbucketCloudEntityProvider[] { const integrations = ScmIntegrations.fromConfig(config); @@ -112,35 +111,35 @@ export class BitbucketCloudEntityProvider implements EntityProvider { options.scheduler!.createScheduledTaskRunner(providerConfig.schedule!); return new BitbucketCloudEntityProvider( + options.auth, + options.catalogApi, providerConfig, + options.events, integration, options.logger, taskRunner, - options.catalogApi, - options.events, - options.tokenManager, ); }); } private constructor( + auth: AuthService, + catalogApi: CatalogApi, config: BitbucketCloudEntityProviderConfig, + events: EventsService, integration: BitbucketCloudIntegration, logger: LoggerService, taskRunner: SchedulerServiceTaskRunner, - catalogApi?: CatalogApi, - events?: EventsService, - tokenManager?: TokenManager, ) { + this.auth = auth; + this.catalogApi = catalogApi; this.client = BitbucketCloudClient.fromConfig(integration.config); this.config = config; + this.events = events; this.logger = logger.child({ target: this.getProviderName(), }); this.scheduleFn = this.createScheduleFn(taskRunner); - this.catalogApi = catalogApi; - this.events = events; - this.tokenManager = tokenManager; } private createScheduleFn( @@ -185,19 +184,17 @@ export class BitbucketCloudEntityProvider implements EntityProvider { this.connection = connection; await this.scheduleFn(); - if (this.events) { - await this.events.subscribe({ - id: this.getProviderName(), - topics: [TOPIC_REPO_PUSH], - onEvent: async params => { - if (params.topic !== TOPIC_REPO_PUSH) { - return; - } + await this.events.subscribe({ + id: this.getProviderName(), + topics: [TOPIC_REPO_PUSH], + onEvent: async params => { + if (params.topic !== TOPIC_REPO_PUSH) { + return; + } - await this.onRepoPush(params.eventPayload as Events.RepoPushEvent); - }, - }); - } + await this.onRepoPush(params.eventPayload as Events.RepoPushEvent); + }, + }); } async refresh(logger: LoggerService) { @@ -220,32 +217,12 @@ export class BitbucketCloudEntityProvider implements EntityProvider { ); } - private canHandleEvents(): boolean { - if (this.catalogApi && this.tokenManager) { - return true; - } - - // throw only once - if (!this.eventConfigErrorThrown) { - this.eventConfigErrorThrown = true; - throw new Error( - `${this.getProviderName()} not well configured to handle repo:push. Missing CatalogApi and/or TokenManager.`, - ); - } - - return false; - } - private enhanceEvent(event: Events.RepoPushEvent): void { // add missing slug event.repository.slug = event.repository.full_name!.split('/', 2)[1]; } async onRepoPush(event: Events.RepoPushEvent): Promise { - if (!this.canHandleEvents()) { - return; - } - if (!this.connection) { throw new Error('Not initialized'); } @@ -273,8 +250,7 @@ export class BitbucketCloudEntityProvider implements EntityProvider { const targets = await this.findCatalogFiles(repoSlug); - const { token } = await this.tokenManager!.getToken(); - const existing = await this.findExistingLocations(repoUrl, token); + const existing = await this.findExistingLocations(repoUrl); const added: DeferredEntity[] = this.toDeferredEntities( targets.filter( @@ -321,16 +297,20 @@ export class BitbucketCloudEntityProvider implements EntityProvider { private async findExistingLocations( repoUrl: string, - token: string, ): Promise { const filter: Record = {}; filter.kind = 'Location'; filter[`metadata.annotations.${ANNOTATION_BITBUCKET_CLOUD_REPO_URL}`] = repoUrl; - return this.catalogApi!.getEntities({ filter }, { token }).then( - result => result.items, - ) as Promise; + const { token } = await this.auth.getPluginRequestToken({ + onBehalfOf: await this.auth.getOwnServiceCredentials(), + targetPluginId: 'catalog', + }); + + return this.catalogApi + .getEntities({ filter }, { token }) + .then(result => result.items) as Promise; } private async findCatalogFiles( diff --git a/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md b/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md index e45ac208c4..cd9972ef25 100644 --- a/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md +++ b/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md @@ -1,5 +1,54 @@ # @backstage/plugin-catalog-backend-module-bitbucket-server +## 0.2.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.15.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.13.1-next.0 + +## 0.2.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.15.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + +## 0.2.2 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/integration@1.15.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## 0.2.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/integration@1.15.0-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.12.7-next.2 + ## 0.2.2-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-bitbucket-server/package.json b/plugins/catalog-backend-module-bitbucket-server/package.json index ea2c30f112..a8f570ae40 100644 --- a/plugins/catalog-backend-module-bitbucket-server/package.json +++ b/plugins/catalog-backend-module-bitbucket-server/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-bitbucket-server", - "version": "0.2.2-next.1", + "version": "0.2.3-next.1", "backstage": { "role": "backend-plugin-module", "pluginId": "catalog", diff --git a/plugins/catalog-backend-module-bitbucket-server/api-report-alpha.md b/plugins/catalog-backend-module-bitbucket-server/report-alpha.api.md similarity index 68% rename from plugins/catalog-backend-module-bitbucket-server/api-report-alpha.md rename to plugins/catalog-backend-module-bitbucket-server/report-alpha.api.md index 7edb314814..49648580f8 100644 --- a/plugins/catalog-backend-module-bitbucket-server/api-report-alpha.md +++ b/plugins/catalog-backend-module-bitbucket-server/report-alpha.api.md @@ -9,5 +9,9 @@ import { BackendFeature } from '@backstage/backend-plugin-api'; const catalogModuleBitbucketServerEntityProvider: BackendFeature; export default catalogModuleBitbucketServerEntityProvider; +// Warnings were encountered during analysis: +// +// src/module/catalogModuleBitbucketServerEntityProvider.d.ts:4:22 - (ae-undocumented) Missing documentation for "catalogModuleBitbucketServerEntityProvider". + // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/catalog-backend-module-bitbucket-server/api-report.md b/plugins/catalog-backend-module-bitbucket-server/report.api.md similarity index 70% rename from plugins/catalog-backend-module-bitbucket-server/api-report.md rename to plugins/catalog-backend-module-bitbucket-server/report.api.md index 211096639c..a7febe8e7a 100644 --- a/plugins/catalog-backend-module-bitbucket-server/api-report.md +++ b/plugins/catalog-backend-module-bitbucket-server/report.api.md @@ -49,7 +49,6 @@ export class BitbucketServerClient { // @public export class BitbucketServerEntityProvider implements EntityProvider { - // (undocumented) connect(connection: EntityProviderConnection): Promise; // (undocumented) static fromConfig( @@ -61,7 +60,6 @@ export class BitbucketServerEntityProvider implements EntityProvider { scheduler?: SchedulerService; }, ): BitbucketServerEntityProvider[]; - // (undocumented) getProviderName(): string; // (undocumented) refresh(logger: LoggerService): Promise; @@ -111,4 +109,19 @@ export type BitbucketServerRepository = { >; archived: boolean; }; + +// Warnings were encountered during analysis: +// +// src/lib/BitbucketServerClient.d.ts:11:5 - (ae-undocumented) Missing documentation for "fromConfig". +// src/lib/BitbucketServerClient.d.ts:17:5 - (ae-undocumented) Missing documentation for "listProjects". +// src/lib/BitbucketServerClient.d.ts:20:5 - (ae-undocumented) Missing documentation for "listRepositories". +// src/lib/BitbucketServerClient.d.ts:24:5 - (ae-undocumented) Missing documentation for "getFile". +// src/lib/BitbucketServerClient.d.ts:29:5 - (ae-undocumented) Missing documentation for "getRepository". +// src/lib/BitbucketServerClient.d.ts:33:5 - (ae-undocumented) Missing documentation for "resolvePath". +// src/lib/BitbucketServerClient.d.ts:48:1 - (ae-undocumented) Missing documentation for "BitbucketServerListOptions". +// src/lib/BitbucketServerClient.d.ts:56:1 - (ae-undocumented) Missing documentation for "BitbucketServerPagedResponse". +// src/lib/types.d.ts:2:1 - (ae-undocumented) Missing documentation for "BitbucketServerRepository". +// src/lib/types.d.ts:14:1 - (ae-undocumented) Missing documentation for "BitbucketServerProject". +// src/providers/BitbucketServerEntityProvider.d.ts:20:5 - (ae-undocumented) Missing documentation for "fromConfig". +// src/providers/BitbucketServerEntityProvider.d.ts:32:5 - (ae-undocumented) Missing documentation for "refresh". ``` diff --git a/plugins/catalog-backend-module-gcp/CHANGELOG.md b/plugins/catalog-backend-module-gcp/CHANGELOG.md index 6af3647bd9..0401ef7124 100644 --- a/plugins/catalog-backend-module-gcp/CHANGELOG.md +++ b/plugins/catalog-backend-module-gcp/CHANGELOG.md @@ -1,5 +1,46 @@ # @backstage/plugin-catalog-backend-module-gcp +## 0.3.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-kubernetes-common@0.8.3 + +## 0.3.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/config@1.2.0 + - @backstage/plugin-kubernetes-common@0.8.3 + +## 0.3.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-node@1.12.7-next.2 + - @backstage/plugin-kubernetes-common@0.8.2 + ## 0.3.0-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-gcp/package.json b/plugins/catalog-backend-module-gcp/package.json index 4441a7ca8b..f8e7986831 100644 --- a/plugins/catalog-backend-module-gcp/package.json +++ b/plugins/catalog-backend-module-gcp/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-gcp", - "version": "0.3.0-next.1", + "version": "0.3.1-next.0", "description": "A Backstage catalog backend module that helps integrate towards GCP", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-gcp/api-report-alpha.md b/plugins/catalog-backend-module-gcp/report-alpha.api.md similarity index 100% rename from plugins/catalog-backend-module-gcp/api-report-alpha.md rename to plugins/catalog-backend-module-gcp/report-alpha.api.md diff --git a/plugins/catalog-backend-module-gcp/api-report.md b/plugins/catalog-backend-module-gcp/report.api.md similarity index 71% rename from plugins/catalog-backend-module-gcp/api-report.md rename to plugins/catalog-backend-module-gcp/report.api.md index 6260d07c88..cf490f09ae 100644 --- a/plugins/catalog-backend-module-gcp/api-report.md +++ b/plugins/catalog-backend-module-gcp/report.api.md @@ -46,4 +46,12 @@ export class GkeEntityProvider implements EntityProvider { // (undocumented) refresh(): Promise; } + +// Warnings were encountered during analysis: +// +// src/providers/GkeEntityProvider.d.ts:17:5 - (ae-undocumented) Missing documentation for "fromConfig". +// src/providers/GkeEntityProvider.d.ts:22:5 - (ae-undocumented) Missing documentation for "fromConfigWithClient". +// src/providers/GkeEntityProvider.d.ts:28:5 - (ae-undocumented) Missing documentation for "getProviderName". +// src/providers/GkeEntityProvider.d.ts:29:5 - (ae-undocumented) Missing documentation for "connect". +// src/providers/GkeEntityProvider.d.ts:35:5 - (ae-undocumented) Missing documentation for "refresh". ``` diff --git a/plugins/catalog-backend-module-gerrit/CHANGELOG.md b/plugins/catalog-backend-module-gerrit/CHANGELOG.md index abbb586446..eaf5df883d 100644 --- a/plugins/catalog-backend-module-gerrit/CHANGELOG.md +++ b/plugins/catalog-backend-module-gerrit/CHANGELOG.md @@ -1,5 +1,51 @@ # @backstage/plugin-catalog-backend-module-gerrit +## 0.2.3-next.1 + +### Patch Changes + +- 5b6edf1: Fixed an issue preventing the provider's `schedule` config from being applied." +- Updated dependencies + - @backstage/integration@1.15.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.13.1-next.0 + +## 0.2.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.15.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + +## 0.2.2 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/integration@1.15.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## 0.2.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/integration@1.15.0-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.12.7-next.2 + ## 0.2.2-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-gerrit/config.d.ts b/plugins/catalog-backend-module-gerrit/config.d.ts index a246662b0a..8f38b47771 100644 --- a/plugins/catalog-backend-module-gerrit/config.d.ts +++ b/plugins/catalog-backend-module-gerrit/config.d.ts @@ -14,6 +14,8 @@ * limitations under the License. */ +import { SchedulerServiceTaskScheduleDefinition } from '@backstage/backend-plugin-api'; + export interface Config { catalog?: { /** @@ -41,6 +43,10 @@ export interface Config { * The branch where the provider will try to find entities. Defaults to "master". */ branch?: string; + /** + * (Optional) TaskScheduleDefinition for the discovery. + */ + schedule?: SchedulerServiceTaskScheduleDefinition; }; }; }; diff --git a/plugins/catalog-backend-module-gerrit/package.json b/plugins/catalog-backend-module-gerrit/package.json index 2937b47db0..82e196278d 100644 --- a/plugins/catalog-backend-module-gerrit/package.json +++ b/plugins/catalog-backend-module-gerrit/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-gerrit", - "version": "0.2.2-next.1", + "version": "0.2.3-next.1", "backstage": { "role": "backend-plugin-module", "pluginId": "catalog", diff --git a/plugins/catalog-backend-module-gerrit/api-report-alpha.md b/plugins/catalog-backend-module-gerrit/report-alpha.api.md similarity index 69% rename from plugins/catalog-backend-module-gerrit/api-report-alpha.md rename to plugins/catalog-backend-module-gerrit/report-alpha.api.md index 02aceb07c6..0774a27299 100644 --- a/plugins/catalog-backend-module-gerrit/api-report-alpha.md +++ b/plugins/catalog-backend-module-gerrit/report-alpha.api.md @@ -9,5 +9,9 @@ import { BackendFeature } from '@backstage/backend-plugin-api'; const catalogModuleGerritEntityProvider: BackendFeature; export default catalogModuleGerritEntityProvider; +// Warnings were encountered during analysis: +// +// src/module/catalogModuleGerritEntityProvider.d.ts:4:22 - (ae-undocumented) Missing documentation for "catalogModuleGerritEntityProvider". + // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/catalog-backend-module-gerrit/api-report.md b/plugins/catalog-backend-module-gerrit/report.api.md similarity index 65% rename from plugins/catalog-backend-module-gerrit/api-report.md rename to plugins/catalog-backend-module-gerrit/report.api.md index abf2a83e7b..56930f3357 100644 --- a/plugins/catalog-backend-module-gerrit/api-report.md +++ b/plugins/catalog-backend-module-gerrit/report.api.md @@ -29,5 +29,13 @@ export class GerritEntityProvider implements EntityProvider { refresh(logger: LoggerService): Promise; } +// Warnings were encountered during analysis: +// +// src/providers/GerritEntityProvider.d.ts:5:1 - (ae-undocumented) Missing documentation for "GerritEntityProvider". +// src/providers/GerritEntityProvider.d.ts:11:5 - (ae-undocumented) Missing documentation for "fromConfig". +// src/providers/GerritEntityProvider.d.ts:17:5 - (ae-undocumented) Missing documentation for "getProviderName". +// src/providers/GerritEntityProvider.d.ts:18:5 - (ae-undocumented) Missing documentation for "connect". +// src/providers/GerritEntityProvider.d.ts:20:5 - (ae-undocumented) Missing documentation for "refresh". + // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/catalog-backend-module-github-org/CHANGELOG.md b/plugins/catalog-backend-module-github-org/CHANGELOG.md index 5ade859371..ed7fb5cd38 100644 --- a/plugins/catalog-backend-module-github-org/CHANGELOG.md +++ b/plugins/catalog-backend-module-github-org/CHANGELOG.md @@ -1,5 +1,57 @@ # @backstage/plugin-catalog-backend-module-github-org +## 0.3.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-backend-module-github@0.7.5-next.1 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + +## 0.3.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend-module-github@0.7.4-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + +## 0.3.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/plugin-catalog-backend-module-github@0.7.3 + - @backstage/plugin-events-node@0.4.0 + - @backstage/config@1.2.0 + +## 0.3.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-backend-module-github@0.7.3-next.2 + - @backstage/plugin-catalog-node@1.12.7-next.2 + - @backstage/plugin-events-node@0.4.0-next.2 + ## 0.3.0-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-github-org/package.json b/plugins/catalog-backend-module-github-org/package.json index 37d2804e60..51653d6f0e 100644 --- a/plugins/catalog-backend-module-github-org/package.json +++ b/plugins/catalog-backend-module-github-org/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-github-org", - "version": "0.3.0-next.1", + "version": "0.3.2-next.1", "description": "The github-org backend module for the catalog plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-github-org/api-report.md b/plugins/catalog-backend-module-github-org/report.api.md similarity index 100% rename from plugins/catalog-backend-module-github-org/api-report.md rename to plugins/catalog-backend-module-github-org/report.api.md diff --git a/plugins/catalog-backend-module-github/CHANGELOG.md b/plugins/catalog-backend-module-github/CHANGELOG.md index b956c2e9e6..b03dda2a7e 100644 --- a/plugins/catalog-backend-module-github/CHANGELOG.md +++ b/plugins/catalog-backend-module-github/CHANGELOG.md @@ -1,5 +1,70 @@ # @backstage/plugin-catalog-backend-module-github +## 0.7.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.26.2-next.1 + - @backstage/integration@1.15.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + +## 0.7.4-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-catalog-backend@1.26.1-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.15.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + +## 0.7.3 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- 5edd344: Refactor to use injected catalog client in the new backend system +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-catalog-backend@1.26.0 + - @backstage/catalog-client@1.7.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/integration@1.15.0 + - @backstage/plugin-events-node@0.4.0 + - @backstage/config@1.2.0 + +## 0.7.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-client@1.7.0-next.1 + - @backstage/plugin-catalog-backend@1.26.0-next.2 + - @backstage/integration@1.15.0-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.2 + - @backstage/plugin-events-node@0.4.0-next.2 + ## 0.7.3-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-github/package.json b/plugins/catalog-backend-module-github/package.json index 16af5a72c5..502d35f7cb 100644 --- a/plugins/catalog-backend-module-github/package.json +++ b/plugins/catalog-backend-module-github/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-github", - "version": "0.7.3-next.1", + "version": "0.7.5-next.1", "description": "A Backstage catalog backend module that helps integrate towards GitHub", "backstage": { "role": "backend-plugin-module", @@ -51,7 +51,7 @@ "test": "backstage-cli package test" }, "dependencies": { - "@backstage/backend-common": "workspace:^", + "@backstage/backend-common": "^0.25.0", "@backstage/backend-plugin-api": "workspace:^", "@backstage/catalog-client": "workspace:^", "@backstage/catalog-model": "workspace:^", diff --git a/plugins/catalog-backend-module-github/api-report-alpha.md b/plugins/catalog-backend-module-github/report-alpha.api.md similarity index 100% rename from plugins/catalog-backend-module-github/api-report-alpha.md rename to plugins/catalog-backend-module-github/report-alpha.api.md diff --git a/plugins/catalog-backend-module-github/api-report.md b/plugins/catalog-backend-module-github/report.api.md similarity index 70% rename from plugins/catalog-backend-module-github/api-report.md rename to plugins/catalog-backend-module-github/report.api.md index 025d845644..4ffe434615 100644 --- a/plugins/catalog-backend-module-github/api-report.md +++ b/plugins/catalog-backend-module-github/report.api.md @@ -83,7 +83,6 @@ export class GitHubEntityProvider implements EntityProvider { // @public export class GithubEntityProvider implements EntityProvider, EventSubscriber { - // (undocumented) connect(connection: EntityProviderConnection): Promise; // (undocumented) static fromConfig( @@ -95,13 +94,10 @@ export class GithubEntityProvider implements EntityProvider, EventSubscriber { scheduler?: SchedulerService; }, ): GithubEntityProvider[]; - // (undocumented) getProviderName(): string; - // (undocumented) onEvent(params: EventParams): Promise; // (undocumented) refresh(logger: LoggerService): Promise; - // (undocumented) supportsEventTopics(): string[]; } @@ -154,14 +150,12 @@ export class GithubMultiOrgEntityProvider implements EntityProvider { teamTransformer?: TeamTransformer; alwaysUseDefaultNamespace?: boolean; }); - // (undocumented) connect(connection: EntityProviderConnection): Promise; // (undocumented) static fromConfig( config: Config, options: GithubMultiOrgEntityProviderOptions, ): GithubMultiOrgEntityProvider; - // (undocumented) getProviderName(): string; read(options?: { logger?: LoggerService }): Promise; } @@ -231,14 +225,12 @@ export class GithubOrgEntityProvider implements EntityProvider { userTransformer?: UserTransformer; teamTransformer?: TeamTransformer; }); - // (undocumented) connect(connection: EntityProviderConnection): Promise; // (undocumented) static fromConfig( config: Config, options: GithubOrgEntityProviderOptions, ): GithubOrgEntityProvider; - // (undocumented) getProviderName(): string; read(options?: { logger?: LoggerService }): Promise; } @@ -326,4 +318,41 @@ export type UserTransformer = ( item: GithubUser, ctx: TransformerContext, ) => Promise; + +// Warnings were encountered during analysis: +// +// src/analyzers/GithubLocationAnalyzer.d.ts:8:1 - (ae-undocumented) Missing documentation for "GithubLocationAnalyzerOptions". +// src/analyzers/GithubLocationAnalyzer.d.ts:17:1 - (ae-undocumented) Missing documentation for "GithubLocationAnalyzer". +// src/analyzers/GithubLocationAnalyzer.d.ts:23:5 - (ae-undocumented) Missing documentation for "supports". +// src/analyzers/GithubLocationAnalyzer.d.ts:24:5 - (ae-undocumented) Missing documentation for "analyze". +// src/deprecated.d.ts:9:1 - (ae-undocumented) Missing documentation for "GitHubOrgEntityProvider". +// src/deprecated.d.ts:10:5 - (ae-undocumented) Missing documentation for "fromConfig". +// src/deprecated.d.ts:16:1 - (ae-undocumented) Missing documentation for "GitHubOrgEntityProviderOptions". +// src/deprecated.d.ts:21:1 - (ae-undocumented) Missing documentation for "GitHubEntityProvider". +// src/deprecated.d.ts:23:5 - (ae-undocumented) Missing documentation for "fromConfig". +// src/deprecated.d.ts:29:5 - (ae-undocumented) Missing documentation for "connect". +// src/deprecated.d.ts:30:5 - (ae-undocumented) Missing documentation for "getProviderName". +// src/deprecated.d.ts:31:5 - (ae-undocumented) Missing documentation for "refresh". +// src/lib/defaultTransformers.d.ts:10:5 - (ae-undocumented) Missing documentation for "client". +// src/lib/defaultTransformers.d.ts:11:5 - (ae-undocumented) Missing documentation for "query". +// src/lib/defaultTransformers.d.ts:12:5 - (ae-undocumented) Missing documentation for "org". +// src/processors/GithubDiscoveryProcessor.d.ts:25:5 - (ae-undocumented) Missing documentation for "fromConfig". +// src/processors/GithubDiscoveryProcessor.d.ts:34:5 - (ae-undocumented) Missing documentation for "getProcessorName". +// src/processors/GithubDiscoveryProcessor.d.ts:35:5 - (ae-undocumented) Missing documentation for "readLocation". +// src/processors/GithubMultiOrgReaderProcessor.d.ts:19:5 - (ae-undocumented) Missing documentation for "fromConfig". +// src/processors/GithubMultiOrgReaderProcessor.d.ts:33:5 - (ae-undocumented) Missing documentation for "getProcessorName". +// src/processors/GithubMultiOrgReaderProcessor.d.ts:34:5 - (ae-undocumented) Missing documentation for "readLocation". +// src/processors/GithubOrgReaderProcessor.d.ts:18:5 - (ae-undocumented) Missing documentation for "fromConfig". +// src/processors/GithubOrgReaderProcessor.d.ts:27:5 - (ae-undocumented) Missing documentation for "getProcessorName". +// src/processors/GithubOrgReaderProcessor.d.ts:28:5 - (ae-undocumented) Missing documentation for "readLocation". +// src/providers/GithubEntityProvider.d.ts:21:5 - (ae-undocumented) Missing documentation for "fromConfig". +// src/providers/GithubEntityProvider.d.ts:33:5 - (ae-undocumented) Missing documentation for "refresh". +// src/providers/GithubEntityProvider.d.ts:51:8 - (tsdoc-undefined-tag) The TSDoc tag "@private" is not defined in this configuration +// src/providers/GithubEntityProvider.d.ts:60:8 - (tsdoc-undefined-tag) The TSDoc tag "@private" is not defined in this configuration +// src/providers/GithubEntityProvider.d.ts:71:8 - (tsdoc-undefined-tag) The TSDoc tag "@private" is not defined in this configuration +// src/providers/GithubEntityProvider.d.ts:81:8 - (tsdoc-undefined-tag) The TSDoc tag "@private" is not defined in this configuration +// src/providers/GithubEntityProvider.d.ts:93:8 - (tsdoc-undefined-tag) The TSDoc tag "@private" is not defined in this configuration +// src/providers/GithubEntityProvider.d.ts:102:8 - (tsdoc-undefined-tag) The TSDoc tag "@private" is not defined in this configuration +// src/providers/GithubMultiOrgEntityProvider.d.ts:84:5 - (ae-undocumented) Missing documentation for "fromConfig". +// src/providers/GithubOrgEntityProvider.d.ts:71:5 - (ae-undocumented) Missing documentation for "fromConfig". ``` diff --git a/plugins/catalog-backend-module-gitlab-org/CHANGELOG.md b/plugins/catalog-backend-module-gitlab-org/CHANGELOG.md index a96c08f602..f65f81aee0 100644 --- a/plugins/catalog-backend-module-gitlab-org/CHANGELOG.md +++ b/plugins/catalog-backend-module-gitlab-org/CHANGELOG.md @@ -1,5 +1,56 @@ # @backstage/plugin-catalog-backend-module-gitlab-org +## 0.2.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/plugin-catalog-backend-module-gitlab@0.4.3-next.1 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + +## 0.2.1-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/plugin-catalog-backend-module-gitlab@0.4.3-next.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + +## 0.2.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-catalog-backend-module-gitlab@0.4.2 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/plugin-events-node@0.4.0 + +## 0.2.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/plugin-catalog-backend-module-gitlab@0.4.2-next.2 + - @backstage/plugin-catalog-node@1.12.7-next.2 + - @backstage/plugin-events-node@0.4.0-next.2 + ## 0.2.0-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-gitlab-org/package.json b/plugins/catalog-backend-module-gitlab-org/package.json index 563ae32df9..0bd5a5b358 100644 --- a/plugins/catalog-backend-module-gitlab-org/package.json +++ b/plugins/catalog-backend-module-gitlab-org/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-gitlab-org", - "version": "0.2.0-next.1", + "version": "0.2.1-next.1", "description": "The gitlab-org backend module for the catalog plugin.", "backstage": { "role": "backend-plugin-module", @@ -33,7 +33,7 @@ "test": "backstage-cli package test" }, "dependencies": { - "@backstage/backend-common": "workspace:^", + "@backstage/backend-common": "^0.25.0", "@backstage/backend-plugin-api": "workspace:^", "@backstage/plugin-catalog-backend-module-gitlab": "workspace:^", "@backstage/plugin-catalog-node": "workspace:^", diff --git a/plugins/catalog-backend-module-gitlab-org/api-report.md b/plugins/catalog-backend-module-gitlab-org/report.api.md similarity index 100% rename from plugins/catalog-backend-module-gitlab-org/api-report.md rename to plugins/catalog-backend-module-gitlab-org/report.api.md diff --git a/plugins/catalog-backend-module-gitlab/CHANGELOG.md b/plugins/catalog-backend-module-gitlab/CHANGELOG.md index 2022e3e511..cc9c370f78 100644 --- a/plugins/catalog-backend-module-gitlab/CHANGELOG.md +++ b/plugins/catalog-backend-module-gitlab/CHANGELOG.md @@ -1,5 +1,91 @@ # @backstage/plugin-catalog-backend-module-gitlab +## 0.4.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.1-next.1 + - @backstage/integration@1.15.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + +## 0.4.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.1-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.15.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + +## 0.4.2 + +### Patch Changes + +- 53b24d9: Internal update to use the new cache manager +- 0476be3: Add the `relations` array to allow Backstage to mirror GitLab's membership behavior, including descendant, inherited, and shared-from-group memberships. + + The previous `allowInherited` config option will be deprecated in future versions. Use the `relations` array with the `INHERITED` option instead. + + ```yaml + catalog: + providers: + gitlab: + development: + relations: + - INHERITED + ``` + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- b446954: Remove dependency on backend-common +- 06cc084: Added a `includeUsersWithoutSeat` config option that allow import of users without a paid seat, e.g. for Gitlab Free on SaaS. Defaults to false +- Updated dependencies + - @backstage/backend-defaults@0.5.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/integration@1.15.0 + - @backstage/plugin-events-node@0.4.0 + - @backstage/config@1.2.0 + +## 0.4.2-next.2 + +### Patch Changes + +- 0476be3: Add the `relations` array to allow Backstage to mirror GitLab's membership behavior, including descendant, inherited, and shared-from-group memberships. + + The previous `allowInherited` config option will be deprecated in future versions. Use the `relations` array with the `INHERITED` option instead. + + ```yaml + catalog: + providers: + gitlab: + development: + relations: + - INHERITED + ``` + +- Updated dependencies + - @backstage/backend-defaults@0.5.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/integration@1.15.0-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.2 + - @backstage/plugin-events-node@0.4.0-next.2 + ## 0.4.2-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-gitlab/package.json b/plugins/catalog-backend-module-gitlab/package.json index c99443a5d9..e2238986aa 100644 --- a/plugins/catalog-backend-module-gitlab/package.json +++ b/plugins/catalog-backend-module-gitlab/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-gitlab", - "version": "0.4.2-next.1", + "version": "0.4.3-next.1", "description": "A Backstage catalog backend module that helps integrate towards GitLab", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-gitlab/api-report-alpha.md b/plugins/catalog-backend-module-gitlab/report-alpha.api.md similarity index 100% rename from plugins/catalog-backend-module-gitlab/api-report-alpha.md rename to plugins/catalog-backend-module-gitlab/report-alpha.api.md diff --git a/plugins/catalog-backend-module-gitlab/api-report.md b/plugins/catalog-backend-module-gitlab/report.api.md similarity index 64% rename from plugins/catalog-backend-module-gitlab/api-report.md rename to plugins/catalog-backend-module-gitlab/report.api.md index 8a21e237b5..0cc2f93ce1 100644 --- a/plugins/catalog-backend-module-gitlab/api-report.md +++ b/plugins/catalog-backend-module-gitlab/report.api.md @@ -107,10 +107,12 @@ export type GitlabProviderConfig = { userPattern: RegExp; groupPattern: RegExp; allowInherited?: boolean; + relations?: string[]; orgEnabled?: boolean; schedule?: SchedulerServiceTaskScheduleDefinition; skipForkedRepos?: boolean; excludeRepos?: string[]; + includeUsersWithoutSeat?: boolean; }; // @public @@ -169,4 +171,29 @@ export interface UserTransformerOptions { // (undocumented) user: GitLabUser; } + +// Warnings were encountered during analysis: +// +// src/GitLabDiscoveryProcessor.d.ts:14:5 - (ae-undocumented) Missing documentation for "fromConfig". +// src/GitLabDiscoveryProcessor.d.ts:20:5 - (ae-undocumented) Missing documentation for "getProcessorName". +// src/GitLabDiscoveryProcessor.d.ts:21:5 - (ae-undocumented) Missing documentation for "readLocation". +// src/lib/types.d.ts:48:1 - (ae-undocumented) Missing documentation for "GitLabGroupSamlIdentity". +// src/lib/types.d.ts:234:5 - (ae-undocumented) Missing documentation for "group". +// src/lib/types.d.ts:235:5 - (ae-undocumented) Missing documentation for "providerConfig". +// src/lib/types.d.ts:249:5 - (ae-undocumented) Missing documentation for "user". +// src/lib/types.d.ts:250:5 - (ae-undocumented) Missing documentation for "integrationConfig". +// src/lib/types.d.ts:251:5 - (ae-undocumented) Missing documentation for "providerConfig". +// src/lib/types.d.ts:252:5 - (ae-undocumented) Missing documentation for "groupNameTransformer". +// src/lib/types.d.ts:266:5 - (ae-undocumented) Missing documentation for "groups". +// src/lib/types.d.ts:267:5 - (ae-undocumented) Missing documentation for "providerConfig". +// src/lib/types.d.ts:268:5 - (ae-undocumented) Missing documentation for "groupNameTransformer". +// src/providers/GitlabDiscoveryEntityProvider.d.ts:21:5 - (ae-undocumented) Missing documentation for "fromConfig". +// src/providers/GitlabDiscoveryEntityProvider.d.ts:33:5 - (ae-undocumented) Missing documentation for "getProviderName". +// src/providers/GitlabDiscoveryEntityProvider.d.ts:34:5 - (ae-undocumented) Missing documentation for "connect". +// src/providers/GitlabDiscoveryEntityProvider.d.ts:75:15 - (tsdoc-param-tag-with-invalid-type) The @param block should not include a JSDoc-style '{type}' +// src/providers/GitlabDiscoveryEntityProvider.d.ts:76:30 - (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag +// src/providers/GitlabDiscoveryEntityProvider.d.ts:76:17 - (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@" +// src/providers/GitlabOrgDiscoveryEntityProvider.d.ts:21:5 - (ae-undocumented) Missing documentation for "fromConfig". +// src/providers/GitlabOrgDiscoveryEntityProvider.d.ts:31:5 - (ae-undocumented) Missing documentation for "getProviderName". +// src/providers/GitlabOrgDiscoveryEntityProvider.d.ts:32:5 - (ae-undocumented) Missing documentation for "connect". ``` diff --git a/plugins/catalog-backend-module-gitlab/src/__testUtils__/mocks.ts b/plugins/catalog-backend-module-gitlab/src/__testUtils__/mocks.ts index 4a173c6b50..3087d10f11 100644 --- a/plugins/catalog-backend-module-gitlab/src/__testUtils__/mocks.ts +++ b/plugins/catalog-backend-module-gitlab/src/__testUtils__/mocks.ts @@ -696,6 +696,31 @@ export const config_org_group_restrictUsers_true_saas = { }, }; +export const config_org_group_includeUsersWithoutSeat_true_saas = { + integrations: { + gitlab: [ + { + host: 'gitlab.com', + apiBaseUrl: 'https://gitlab.com/api/v4', + token: '1234', + }, + ], + }, + catalog: { + providers: { + gitlab: { + 'test-id': { + host: 'gitlab.com', + group: 'group1', + orgEnabled: true, + skipForkedRepos: true, + includeUsersWithoutSeat: true, + }, + }, + }, + }, +}; + export const config_org_group_selfHosted = { integrations: { gitlab: [ @@ -937,6 +962,40 @@ export const all_saas_users_response: MockObject[] = [ is_using_seat: false, membership_state: 'active', }, + { + access_level: 50, + created_at: '2023-07-15T08:58:34.984Z', + expires_at: '2023-10-26', + id: 54, + username: 'project_100_bot_23dc8057bef66e05181f39be4652577c', + name: 'Token Bot', + state: 'active', + avatar_url: 'https://secure.gravatar.com/', + web_url: + 'https://gitlab.com/project_100_bot_23dc8057bef66e05181f39be4652577c', + group_saml_identity: null, + is_using_seat: false, + membership_state: 'active', + }, + { + access_level: 30, + created_at: '2023-07-19T08:58:34.984Z', + expires_at: null, + id: 34, + username: 'testuser3', + name: 'Test User 3', + state: 'active', + avatar_url: 'https://secure.gravatar.com/', + web_url: 'https://gitlab.com/testuser3', + email: 'testuser3@example.com', + group_saml_identity: { + provider: 'group_saml', + extern_uid: '53', + saml_provider_id: 1, + }, + is_using_seat: false, + membership_state: 'active', + }, ]; export const all_groups_response: GitLabGroup[] = [ @@ -2050,6 +2109,88 @@ export const expected_full_org_scan_entities_saas: MockObject[] = [ }, ]; +export const expected_full_org_scan_entities_includeUsersWithoutSeat_saas: MockObject[] = + [ + { + entity: { + apiVersion: 'backstage.io/v1alpha1', + kind: 'User', + metadata: { + annotations: { + 'backstage.io/managed-by-location': + 'url:https://gitlab.com/testuser1', + 'backstage.io/managed-by-origin-location': + 'url:https://gitlab.com/testuser1', + 'gitlab.com/user-login': 'https://gitlab.com/testuser1', + 'gitlab.com/saml-external-uid': '51', + }, + name: 'testuser1', + }, + spec: { + memberOf: [], + profile: { + displayName: 'Test User 1', + email: 'testuser1@example.com', + picture: 'https://secure.gravatar.com/', + }, + }, + }, + locationKey: 'GitlabOrgDiscoveryEntityProvider:test-id', + }, + { + entity: { + apiVersion: 'backstage.io/v1alpha1', + kind: 'User', + metadata: { + annotations: { + 'backstage.io/managed-by-location': + 'url:https://gitlab.com/testuser2', + 'backstage.io/managed-by-origin-location': + 'url:https://gitlab.com/testuser2', + 'gitlab.com/user-login': 'https://gitlab.com/testuser2', + 'gitlab.com/saml-external-uid': '52', + }, + name: 'testuser2', + }, + spec: { + memberOf: [], + profile: { + displayName: 'Test User 2', + email: 'testuser2@example.com', + picture: 'https://secure.gravatar.com/', + }, + }, + }, + locationKey: 'GitlabOrgDiscoveryEntityProvider:test-id', + }, + { + entity: { + apiVersion: 'backstage.io/v1alpha1', + kind: 'User', + metadata: { + annotations: { + 'backstage.io/managed-by-location': + 'url:https://gitlab.com/testuser3', + 'backstage.io/managed-by-origin-location': + 'url:https://gitlab.com/testuser3', + 'gitlab.com/user-login': 'https://gitlab.com/testuser3', + 'gitlab.com/saml-external-uid': '53', + }, + name: 'testuser3', + }, + spec: { + memberOf: [], + profile: { + displayName: 'Test User 3', + email: 'testuser3@example.com', + picture: 'https://secure.gravatar.com/', + }, + }, + }, + locationKey: 'GitlabOrgDiscoveryEntityProvider:test-id', + }, + ]; + export const subgroup_saas_users_response: MockObject[] = [ { access_level: 30, diff --git a/plugins/catalog-backend-module-gitlab/src/lib/client.ts b/plugins/catalog-backend-module-gitlab/src/lib/client.ts index b5a2b69131..f2ce3d18f8 100644 --- a/plugins/catalog-backend-module-gitlab/src/lib/client.ts +++ b/plugins/catalog-backend-module-gitlab/src/lib/client.ts @@ -137,12 +137,25 @@ export class GitLabClient { async listSaaSUsers( groupPath: string, options?: CommonListOptions, + includeUsersWithoutSeat?: boolean, ): Promise> { + const botFilterRegex = /^(?:project|group)_(\w+)_bot_(\w+)$/; + return this.listGroupMembers(groupPath, { ...options, + active: true, // Users with seat are always active but for users without seat we need to filter show_seat_info: true, }).then(resp => { - resp.items = resp.items.filter(user => user.is_using_seat); + // Filter is optional to allow to import Gitlab Free users without seats + // https://github.com/backstage/backstage/issues/26438 + // Filter out API tokens https://docs.gitlab.com/ee/user/project/settings/project_access_tokens.html#bot-users-for-projects + if (includeUsersWithoutSeat) { + resp.items = resp.items.filter(user => { + return !botFilterRegex.test(user.username); + }); + } else { + resp.items = resp.items.filter(user => user.is_using_seat); + } return resp; }); } diff --git a/plugins/catalog-backend-module-gitlab/src/lib/types.ts b/plugins/catalog-backend-module-gitlab/src/lib/types.ts index 61f76d03de..423f3ff8b5 100644 --- a/plugins/catalog-backend-module-gitlab/src/lib/types.ts +++ b/plugins/catalog-backend-module-gitlab/src/lib/types.ts @@ -191,10 +191,41 @@ export type GitlabProviderConfig = { groupPattern: RegExp; /** - * If true, the provider will also ingest add inherited users to the ingested groups - */ + * If true, the provider will also add inherited (ascendant) users to the ingested groups. + * See: https://docs.gitlab.com/ee/api/graphql/reference/#groupmemberrelation + * + * @deprecated Use the `relations` array to configure group membership relations instead. + **/ allowInherited?: boolean; + /** + * Specifies the types of group membership relations that should be included when ingesting data. + * + * The following values are valid: + * - 'DIRECT': Direct members of the group. This is the default relation and is always included. + * - 'INHERITED': Members inherited from parent (ascendant) groups. + * - 'DESCENDANTS': Members from child (descendant) groups. + * - 'SHARED_FROM_GROUPS': Members shared from other groups. + * + * See: https://docs.gitlab.com/ee/api/graphql/reference/#groupmemberrelation + * + * If the `relations` array is provided in the app-config.yaml, it should contain any combination of the above values. + * The 'DIRECT' relation is automatically included and cannot be excluded, even if not specified. + * Example configuration: + * + * ```yaml + * catalog: + * providers: + * gitlab: + * development: + * relations: + * - INHERITED + * - DESCENDANTS + * - SHARED_FROM_GROUPS + * ``` + */ + relations?: string[]; + orgEnabled?: boolean; schedule?: SchedulerServiceTaskScheduleDefinition; /** @@ -206,6 +237,13 @@ export type GitlabProviderConfig = { * Paths should not start or end with a slash. */ excludeRepos?: string[]; + + /** + * If true, users without a seat will be included in the catalog. + * Group/Application Access Tokens are still filtered out but you might find service accounts or other users without a seat. + * Defaults to `false` + */ + includeUsersWithoutSeat?: boolean; }; /** diff --git a/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.test.ts b/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.test.ts index a080948d65..a15894b236 100644 --- a/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.test.ts +++ b/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.test.ts @@ -400,6 +400,40 @@ describe('GitlabOrgDiscoveryEntityProvider - refresh', () => { }); }); + // This needs to return all users, including those without a seat but filter out the bot users + it('SaaS: should get users without a seat if includeUsersWithoutSeat true', async () => { + const config = new ConfigReader( + mock.config_org_group_includeUsersWithoutSeat_true_saas, + ); + const schedule = new PersistingTaskRunner(); + const entityProviderConnection: EntityProviderConnection = { + applyMutation: jest.fn(), + refresh: jest.fn(), + }; + const provider = GitlabOrgDiscoveryEntityProvider.fromConfig(config, { + logger, + schedule, + })[0]; + expect(provider.getProviderName()).toEqual( + 'GitlabOrgDiscoveryEntityProvider:test-id', + ); + + await provider.connect(entityProviderConnection); + + const taskDef = schedule.getTasks()[0]; + expect(taskDef.id).toEqual( + 'GitlabOrgDiscoveryEntityProvider:test-id:refresh', + ); + await (taskDef.fn as () => Promise)(); + + expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes(1); + expect(entityProviderConnection.applyMutation).toHaveBeenCalledWith({ + type: 'full', + entities: + mock.expected_full_org_scan_entities_includeUsersWithoutSeat_saas, // + }); + }); + // This should return all members of the self-hosted instance regardless of the group set -> expected_full_members_group_org_scan_entities // All instance members, but only the group entities below the config.group it('Self-hosted: should get all instance users when restrictUsersToGroup is not set', async () => { diff --git a/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.ts b/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.ts index 7f06079f42..277a5a8c51 100644 --- a/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.ts +++ b/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.ts @@ -400,7 +400,12 @@ export class GitlabOrgDiscoveryEntityProvider implements EntityProvider { ? rootGroupSplit[rootGroupSplit.length - 1] : rootGroupSplit[0]; users = paginated( - options => this.gitLabClient.listSaaSUsers(rootGroup, options), + options => + this.gitLabClient.listSaaSUsers( + rootGroup, + options, + this.config.includeUsersWithoutSeat, + ), { page: 1, per_page: 100, @@ -445,9 +450,7 @@ export class GitlabOrgDiscoveryEntityProvider implements EntityProvider { let groupUsers: PagedResponse = { items: [] }; try { - const relations = this.config.allowInherited - ? ['DIRECT', 'INHERITED'] - : ['DIRECT']; + const relations = this.getRelations(this.config); groupUsers = await this.gitLabClient.getGroupMembers( group.full_path, relations, @@ -724,9 +727,7 @@ export class GitlabOrgDiscoveryEntityProvider implements EntityProvider { return; } - const relations = this.config.allowInherited - ? ['DIRECT', 'INHERITED'] - : ['DIRECT']; + const relations = this.getRelations(this.config); // fetch group members from GitLab const groupMembers = await this.gitLabClient.getGroupMembers( @@ -802,4 +803,15 @@ export class GitlabOrgDiscoveryEntityProvider implements EntityProvider { entity, ) as Entity; } + + private getRelations(config: any) { + if (Array.isArray(config.relations)) { + // filter out duplicates + const relationsSet = new Set(['DIRECT', ...config.relations]); + return Array.from(relationsSet); + } + + // TODO: remove this fallback in the next major version by ensuring the method returns only `['DIRECT']` if no `relations` array is provided. + return ['DIRECT', ...(config.allowInherited ? ['INHERITED'] : [])]; + } } diff --git a/plugins/catalog-backend-module-gitlab/src/providers/config.test.ts b/plugins/catalog-backend-module-gitlab/src/providers/config.test.ts index 28df8c88b7..4b7c73ec80 100644 --- a/plugins/catalog-backend-module-gitlab/src/providers/config.test.ts +++ b/plugins/catalog-backend-module-gitlab/src/providers/config.test.ts @@ -58,10 +58,12 @@ describe('config', () => { userPattern: /[\s\S]*/, orgEnabled: false, allowInherited: false, + relations: [], schedule: undefined, skipForkedRepos: false, excludeRepos: [], restrictUsersToGroup: false, + includeUsersWithoutSeat: false, }), ); }); @@ -77,6 +79,7 @@ describe('config', () => { branch: 'not-master', fallbackBranch: 'main', entityFilename: 'custom-file.yaml', + includeUsersWithoutSeat: true, }, }, }, @@ -98,10 +101,12 @@ describe('config', () => { userPattern: /[\s\S]*/, orgEnabled: false, allowInherited: false, + relations: [], schedule: undefined, skipForkedRepos: false, excludeRepos: [], restrictUsersToGroup: false, + includeUsersWithoutSeat: true, }), ); }); @@ -139,10 +144,12 @@ describe('config', () => { userPattern: /[\s\S]*/, orgEnabled: false, allowInherited: false, + relations: [], schedule: undefined, restrictUsersToGroup: false, excludeRepos: [], skipForkedRepos: true, + includeUsersWithoutSeat: false, }), ); }); @@ -181,10 +188,12 @@ describe('config', () => { userPattern: /[\s\S]*/, orgEnabled: false, allowInherited: false, + relations: [], schedule: undefined, restrictUsersToGroup: false, skipForkedRepos: false, excludeRepos: ['foo/bar', 'quz/qux'], + includeUsersWithoutSeat: false, }), ); }); @@ -224,9 +233,11 @@ describe('config', () => { userPattern: /[\s\S]*/, orgEnabled: false, allowInherited: false, + relations: [], skipForkedRepos: false, restrictUsersToGroup: false, excludeRepos: [], + includeUsersWithoutSeat: false, schedule: { frequency: { minutes: 30 }, timeout: { diff --git a/plugins/catalog-backend-module-gitlab/src/providers/config.ts b/plugins/catalog-backend-module-gitlab/src/providers/config.ts index c0fac9a166..dd1f6d67d7 100644 --- a/plugins/catalog-backend-module-gitlab/src/providers/config.ts +++ b/plugins/catalog-backend-module-gitlab/src/providers/config.ts @@ -45,6 +45,8 @@ function readGitlabConfig(id: string, config: Config): GitlabProviderConfig { const orgEnabled: boolean = config.getOptionalBoolean('orgEnabled') ?? false; const allowInherited: boolean = config.getOptionalBoolean('allowInherited') ?? false; + const relations: string[] = config.getOptionalStringArray('relations') ?? []; + const skipForkedRepos: boolean = config.getOptionalBoolean('skipForkedRepos') ?? false; const excludeRepos: string[] = @@ -58,6 +60,9 @@ function readGitlabConfig(id: string, config: Config): GitlabProviderConfig { const restrictUsersToGroup = config.getOptionalBoolean('restrictUsersToGroup') ?? false; + const includeUsersWithoutSeat = + config.getOptionalBoolean('includeUsersWithoutSeat') ?? false; + return { id, group, @@ -71,9 +76,11 @@ function readGitlabConfig(id: string, config: Config): GitlabProviderConfig { schedule, orgEnabled, allowInherited, + relations, skipForkedRepos, excludeRepos, restrictUsersToGroup, + includeUsersWithoutSeat, }; } diff --git a/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md b/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md index 2b01b76534..767b059e01 100644 --- a/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md +++ b/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md @@ -1,5 +1,66 @@ # @backstage/plugin-catalog-backend-module-incremental-ingestion +## 0.5.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.26.2-next.1 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/plugin-permission-common@0.8.1 + +## 0.5.4-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-catalog-backend@1.26.1-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-permission-common@0.8.1 + +## 0.5.3 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- 4b28e39: Updated the README to include documentation for the new backend support +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-catalog-backend@1.26.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/plugin-events-node@0.4.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.8.1 + +## 0.5.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/plugin-catalog-backend@1.26.0-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.12.7-next.2 + - @backstage/plugin-events-node@0.4.0-next.2 + - @backstage/plugin-permission-common@0.8.1 + ## 0.5.3-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-incremental-ingestion/package.json b/plugins/catalog-backend-module-incremental-ingestion/package.json index fe7370ac8f..a22819e786 100644 --- a/plugins/catalog-backend-module-incremental-ingestion/package.json +++ b/plugins/catalog-backend-module-incremental-ingestion/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-incremental-ingestion", - "version": "0.5.3-next.1", + "version": "0.5.5-next.1", "description": "An entity provider for streaming large asset sources into the catalog", "backstage": { "role": "backend-plugin-module", @@ -51,7 +51,7 @@ "test": "backstage-cli package test" }, "dependencies": { - "@backstage/backend-common": "workspace:^", + "@backstage/backend-common": "^0.25.0", "@backstage/backend-plugin-api": "workspace:^", "@backstage/catalog-model": "workspace:^", "@backstage/config": "workspace:^", diff --git a/plugins/catalog-backend-module-incremental-ingestion/api-report-alpha.md b/plugins/catalog-backend-module-incremental-ingestion/report-alpha.api.md similarity index 100% rename from plugins/catalog-backend-module-incremental-ingestion/api-report-alpha.md rename to plugins/catalog-backend-module-incremental-ingestion/report-alpha.api.md diff --git a/plugins/catalog-backend-module-incremental-ingestion/api-report.md b/plugins/catalog-backend-module-incremental-ingestion/report.api.md similarity index 82% rename from plugins/catalog-backend-module-incremental-ingestion/api-report.md rename to plugins/catalog-backend-module-incremental-ingestion/report.api.md index 22b497b2f7..7160ff504f 100644 --- a/plugins/catalog-backend-module-incremental-ingestion/api-report.md +++ b/plugins/catalog-backend-module-incremental-ingestion/report.api.md @@ -94,4 +94,12 @@ export type PluginEnvironment = { reader: UrlReaderService; permissions: PermissionEvaluator; }; + +// Warnings were encountered during analysis: +// +// src/service/IncrementalCatalogBuilder.d.ts:6:1 - (ae-undocumented) Missing documentation for "IncrementalCatalogBuilder". +// src/service/IncrementalCatalogBuilder.d.ts:20:5 - (ae-undocumented) Missing documentation for "build". +// src/service/IncrementalCatalogBuilder.d.ts:23:5 - (ae-undocumented) Missing documentation for "addIncrementalEntityProvider". +// src/types.d.ts:106:1 - (ae-undocumented) Missing documentation for "IncrementalEntityProviderOptions". +// src/types.d.ts:145:1 - (ae-undocumented) Missing documentation for "PluginEnvironment". ``` diff --git a/plugins/catalog-backend-module-ldap/CHANGELOG.md b/plugins/catalog-backend-module-ldap/CHANGELOG.md index f48ab34ba4..7b7c97d4e9 100644 --- a/plugins/catalog-backend-module-ldap/CHANGELOG.md +++ b/plugins/catalog-backend-module-ldap/CHANGELOG.md @@ -1,5 +1,53 @@ # @backstage/plugin-catalog-backend-module-ldap +## 0.9.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + +## 0.9.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- b50e4a8: Add support for optional configuration of `dnAttributeName` and `uuidAttributeName` in LDAP vendor +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## 0.9.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.2 + ## 0.9.0-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-ldap/config.d.ts b/plugins/catalog-backend-module-ldap/config.d.ts index 65914fdf74..e30aaab5d5 100644 --- a/plugins/catalog-backend-module-ldap/config.d.ts +++ b/plugins/catalog-backend-module-ldap/config.d.ts @@ -409,6 +409,20 @@ export interface Config { members?: string; }; }>; + /** + * Configuration for overriding the vendor-specific default attribute names. + */ + vendor?: { + /** + * Attribute name for the distinguished name (DN) of an entry, + */ + dnAttributeName?: string; + + /** + * Attribute name for the unique identifier (UUID) of an entry, + */ + uuidAttributeName?: string; + }; }>; }; @@ -638,6 +652,20 @@ export interface Config { members?: string; }; }; + /** + * Configuration for overriding the vendor-specific default attribute names. + */ + vendor?: { + /** + * Attribute name for the distinguished name (DN) of an entry, + */ + dnAttributeName?: string; + + /** + * Attribute name for the unique identifier (UUID) of an entry, + */ + uuidAttributeName?: string; + }; }; }; }; @@ -865,6 +893,20 @@ export interface Config { members?: string; }; }; + /** + * Configuration for overriding the vendor-specific default attribute names. + */ + vendor?: { + /** + * Attribute name for the distinguished name (DN) of an entry, + */ + dnAttributeName?: string; + + /** + * Attribute name for the unique identifier (UUID) of an entry, + */ + uuidAttributeName?: string; + }; }>; }; }; diff --git a/plugins/catalog-backend-module-ldap/package.json b/plugins/catalog-backend-module-ldap/package.json index c3e0f39e9f..c8487244ba 100644 --- a/plugins/catalog-backend-module-ldap/package.json +++ b/plugins/catalog-backend-module-ldap/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-ldap", - "version": "0.9.0-next.1", + "version": "0.9.1-next.0", "description": "A Backstage catalog backend module that helps integrate towards LDAP", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-ldap/api-report.md b/plugins/catalog-backend-module-ldap/report.api.md similarity index 89% rename from plugins/catalog-backend-module-ldap/api-report.md rename to plugins/catalog-backend-module-ldap/report.api.md index 40bb9d81ae..e8b20073a3 100644 --- a/plugins/catalog-backend-module-ldap/api-report.md +++ b/plugins/catalog-backend-module-ldap/report.api.md @@ -113,7 +113,6 @@ export class LdapOrgEntityProvider implements EntityProvider { userTransformer?: UserTransformer; groupTransformer?: GroupTransformer; }); - // (undocumented) connect(connection: EntityProviderConnection): Promise; // (undocumented) static fromConfig( @@ -125,7 +124,6 @@ export class LdapOrgEntityProvider implements EntityProvider { configRoot: Config, options: LdapOrgEntityProviderLegacyOptions, ): LdapOrgEntityProvider; - // (undocumented) getProviderName(): string; read(options?: { logger?: LoggerService }): Promise; } @@ -200,6 +198,7 @@ export type LdapProviderConfig = { users: UserConfig[]; groups: GroupConfig[]; schedule?: SchedulerServiceTaskScheduleDefinition; + vendor?: VendorConfig; }; // @public @@ -225,6 +224,7 @@ export function readLdapOrg( client: LdapClient, userConfig: UserConfig[], groupConfig: GroupConfig[], + vendorConfig: VendorConfig | undefined, options: { groupTransformer?: GroupTransformer; userTransformer?: UserTransformer; @@ -269,4 +269,19 @@ export type UserTransformer = ( config: UserConfig, user: SearchEntry, ) => Promise; + +// @public +export type VendorConfig = { + dnAttributeName?: string; + uuidAttributeName?: string; +}; + +// Warnings were encountered during analysis: +// +// src/ldap/client.d.ts:16:5 - (ae-undocumented) Missing documentation for "create". +// src/processors/LdapOrgEntityProvider.d.ts:107:5 - (ae-undocumented) Missing documentation for "fromConfig". +// src/processors/LdapOrgEntityProvider.d.ts:108:5 - (ae-undocumented) Missing documentation for "fromLegacyConfig". +// src/processors/LdapOrgReaderProcessor.d.ts:16:5 - (ae-undocumented) Missing documentation for "fromConfig". +// src/processors/LdapOrgReaderProcessor.d.ts:27:5 - (ae-undocumented) Missing documentation for "getProcessorName". +// src/processors/LdapOrgReaderProcessor.d.ts:28:5 - (ae-undocumented) Missing documentation for "readLocation". ``` diff --git a/plugins/catalog-backend-module-ldap/src/ldap/config.ts b/plugins/catalog-backend-module-ldap/src/ldap/config.ts index d7e1035545..6fdf682b42 100644 --- a/plugins/catalog-backend-module-ldap/src/ldap/config.ts +++ b/plugins/catalog-backend-module-ldap/src/ldap/config.ts @@ -47,6 +47,8 @@ export type LdapProviderConfig = { groups: GroupConfig[]; // Schedule configuration for refresh tasks. schedule?: SchedulerServiceTaskScheduleDefinition; + // Configuration for overriding the vendor-specific default attribute names. + vendor?: VendorConfig; }; /** @@ -161,6 +163,26 @@ export type GroupConfig = { }; }; +/** + * Configuration for LDAP vendor-specific attributes. + * + * Allows custom attribute names for distinguished names (DN) and + * universally unique identifiers (UUID) in LDAP directories. + * + * @public + */ +export type VendorConfig = { + /** + * Attribute name for the distinguished name (DN) of an entry, + */ + dnAttributeName?: string; + + /** + * Attribute name for the unique identifier (UUID) of an entry, + */ + uuidAttributeName?: string; +}; + const defaultUserConfig = { options: { scope: 'one', @@ -225,6 +247,18 @@ function readBindConfig( }; } +function readVendorConfig( + c: Config | undefined, +): LdapProviderConfig['vendor'] | undefined { + if (!c) { + return undefined; + } + return { + dnAttributeName: c.getOptionalString('dnAttributeName'), + uuidAttributeName: c.getOptionalString('uuidAttributeName'), + }; +} + function readOptionsConfig(c: Config | undefined): SearchOptions { if (!c) { return {}; @@ -375,6 +409,7 @@ export function readLdapLegacyConfig(config: Config): LdapProviderConfig[] { groups: readGroupConfig(c.getConfig('groups')).map(it => { return mergeWith({}, defaultGroupConfig, it, replaceArraysIfPresent); }), + vendor: readVendorConfig(c.getOptionalConfig('vendor')), }; return freeze(newConfig) as LdapProviderConfig; @@ -396,7 +431,6 @@ export function readProviderConfigs(config: Config): LdapProviderConfig[] { return providersConfig.keys().map(id => { const c = providersConfig.getConfig(id); - const schedule = c.has('schedule') ? readSchedulerServiceTaskScheduleDefinitionFromConfig( c.getConfig('schedule'), @@ -426,6 +460,7 @@ export function readProviderConfigs(config: Config): LdapProviderConfig[] { return mergeWith({}, defaultGroupConfig, it, replaceArraysIfPresent); }), schedule, + vendor: readVendorConfig(c.getOptionalConfig('vendor')), }; return freeze(newConfig) as LdapProviderConfig; diff --git a/plugins/catalog-backend-module-ldap/src/ldap/index.ts b/plugins/catalog-backend-module-ldap/src/ldap/index.ts index cfab5a4444..6d8fbd06d6 100644 --- a/plugins/catalog-backend-module-ldap/src/ldap/index.ts +++ b/plugins/catalog-backend-module-ldap/src/ldap/index.ts @@ -23,6 +23,7 @@ export type { UserConfig, BindConfig, TLSConfig, + VendorConfig, } from './config'; export type { LdapVendor } from './vendors'; export { diff --git a/plugins/catalog-backend-module-ldap/src/ldap/read.test.ts b/plugins/catalog-backend-module-ldap/src/ldap/read.test.ts index 1c3dfb179a..5a7e625577 100644 --- a/plugins/catalog-backend-module-ldap/src/ldap/read.test.ts +++ b/plugins/catalog-backend-module-ldap/src/ldap/read.test.ts @@ -18,7 +18,7 @@ import { GroupEntity, UserEntity } from '@backstage/catalog-model'; import { SearchEntry } from 'ldapjs'; import merge from 'lodash/merge'; import { LdapClient } from './client'; -import { GroupConfig, UserConfig } from './config'; +import { GroupConfig, UserConfig, VendorConfig } from './config'; import { LDAP_DN_ANNOTATION, LDAP_RDN_ANNOTATION, @@ -114,7 +114,7 @@ describe('readLdapUsers', () => { }, }, ]; - const { users, userMemberOf } = await readLdapUsers(client, config); + const { users, userMemberOf } = await readLdapUsers(client, config, {}); expect(users).toEqual([ expect.objectContaining({ metadata: { @@ -141,6 +141,75 @@ describe('readLdapUsers', () => { ); }); + it('override default vendor configs', async () => { + client.getVendor.mockResolvedValue(DefaultLdapVendor); + client.searchStreaming.mockImplementation(async (_dn, _opts, fn) => { + await fn( + searchEntry({ + uid: ['uid-value'], + description: ['description-value'], + cn: ['cn-value'], + mail: ['mail-value'], + avatarUrl: ['avatarUrl-value'], + memberOf: ['x', 'y', 'z'], + customDN: ['dn-value'], + customUUID: ['uuid-value'], + }), + ); + }); + const config: UserConfig[] = [ + { + dn: 'ddd', + options: {}, + map: { + rdn: 'uid', + name: 'uid', + description: 'description', + displayName: 'cn', + email: 'mail', + picture: 'avatarUrl', + memberOf: 'memberOf', + }, + }, + ]; + + const vendorConfig: VendorConfig = { + dnAttributeName: 'customDN', + uuidAttributeName: 'customUUID', + }; + + const { users, userMemberOf } = await readLdapUsers( + client, + config, + vendorConfig, + ); + expect(users).toEqual([ + expect.objectContaining({ + metadata: { + name: 'uid-value', + description: 'description-value', + annotations: { + [LDAP_DN_ANNOTATION]: 'dn-value', + [LDAP_RDN_ANNOTATION]: 'uid-value', + [LDAP_UUID_ANNOTATION]: 'uuid-value', + }, + }, + spec: { + profile: { + displayName: 'cn-value', + email: 'mail-value', + picture: 'avatarUrl-value', + }, + memberOf: [], + }, + }), + ]); + + expect(userMemberOf).toEqual( + new Map([['dn-value', new Set(['x', 'y', 'z'])]]), + ); + }); + it('transfers all attributes from Microsoft Active Directory', async () => { client.getVendor.mockResolvedValue(ActiveDirectoryVendor); client.searchStreaming.mockImplementation(async (_dn, _opts, fn) => { @@ -177,7 +246,7 @@ describe('readLdapUsers', () => { }, }, ]; - const { users, userMemberOf } = await readLdapUsers(client, config); + const { users, userMemberOf } = await readLdapUsers(client, config, {}); expect(users).toEqual([ expect.objectContaining({ metadata: { @@ -235,7 +304,7 @@ describe('readLdapUsers', () => { }, }, ]; - const { users, userMemberOf } = await readLdapUsers(client, config); + const { users, userMemberOf } = await readLdapUsers(client, config, {}); expect(users).toEqual([ expect.objectContaining({ metadata: { @@ -305,12 +374,12 @@ describe('readLdapUsers', () => { }, }, ]; - const { users } = await readLdapUsers(client, config); + const { users } = await readLdapUsers(client, config, {}); expect(users).toHaveLength(2); }); it('can process no UserConfigs', async () => { const config: UserConfig[] = []; - const { users } = await readLdapUsers(client, config); + const { users } = await readLdapUsers(client, config, {}); expect(users).toHaveLength(0); }); }); @@ -360,6 +429,7 @@ describe('readLdapGroups', () => { const { groups, groupMember, groupMemberOf } = await readLdapGroups( client, config, + {}, ); expect(groups).toEqual([ expect.objectContaining({ @@ -433,6 +503,7 @@ describe('readLdapGroups', () => { const { groups, groupMember, groupMemberOf } = await readLdapGroups( client, config, + {}, ); expect(groups).toEqual([ expect.objectContaining({ @@ -464,6 +535,81 @@ describe('readLdapGroups', () => { ); }); + it('override default vendor configs', async () => { + client.getVendor.mockResolvedValue(DefaultLdapVendor); + client.searchStreaming.mockImplementation(async (_dn, _opts, fn) => { + await fn( + searchEntry({ + cn: ['cn-value'], + description: ['description-value'], + tt: ['type-value'], + mail: ['mail-value'], + avatarUrl: ['avatarUrl-value'], + memberOf: ['x', 'y', 'z'], + member: ['e', 'f', 'g'], + customDN: ['dn-value'], + customUUID: ['uuid-value'], + }), + ); + }); + const config: GroupConfig[] = [ + { + dn: 'ddd', + options: {}, + map: { + rdn: 'cn', + name: 'cn', + description: 'description', + displayName: 'cn', + email: 'mail', + picture: 'avatarUrl', + type: 'tt', + memberOf: 'memberOf', + members: 'member', + }, + }, + ]; + + const vendorConfig: VendorConfig = { + dnAttributeName: 'customDN', + uuidAttributeName: 'customUUID', + }; + + const { groups, groupMember, groupMemberOf } = await readLdapGroups( + client, + config, + vendorConfig, + ); + expect(groups).toEqual([ + expect.objectContaining({ + metadata: { + name: 'cn-value', + description: 'description-value', + annotations: { + [LDAP_DN_ANNOTATION]: 'dn-value', + [LDAP_RDN_ANNOTATION]: 'cn-value', + [LDAP_UUID_ANNOTATION]: 'uuid-value', + }, + }, + spec: { + type: 'type-value', + profile: { + displayName: 'cn-value', + email: 'mail-value', + picture: 'avatarUrl-value', + }, + children: [], + }, + }), + ]); + expect(groupMember).toEqual( + new Map([['dn-value', new Set(['e', 'f', 'g'])]]), + ); + expect(groupMemberOf).toEqual( + new Map([['dn-value', new Set(['x', 'y', 'z'])]]), + ); + }); + it('can process a list of GroupConfigs', async () => { client.getVendor.mockResolvedValue(DefaultLdapVendor); client.searchStreaming.mockImplementation(async (_dn, _opts, fn) => { @@ -513,13 +659,13 @@ describe('readLdapGroups', () => { }, }, ]; - const { groups } = await readLdapGroups(client, config); + const { groups } = await readLdapGroups(client, config, {}); expect(groups).toHaveLength(2); }); it('can process no GroupConfigs', async () => { const config: GroupConfig[] = []; - const { groups } = await readLdapGroups(client, config); + const { groups } = await readLdapGroups(client, config, {}); expect(groups).toHaveLength(0); }); }); diff --git a/plugins/catalog-backend-module-ldap/src/ldap/read.ts b/plugins/catalog-backend-module-ldap/src/ldap/read.ts index 9e6e11a0bc..e1cfc0730e 100644 --- a/plugins/catalog-backend-module-ldap/src/ldap/read.ts +++ b/plugins/catalog-backend-module-ldap/src/ldap/read.ts @@ -24,7 +24,7 @@ import lodashSet from 'lodash/set'; import cloneDeep from 'lodash/cloneDeep'; import { buildOrgHierarchy } from './org'; import { LdapClient } from './client'; -import { GroupConfig, UserConfig } from './config'; +import { GroupConfig, UserConfig, VendorConfig } from './config'; import { LDAP_DN_ANNOTATION, LDAP_RDN_ANNOTATION, @@ -104,22 +104,29 @@ export async function defaultUserTransformer( */ export async function readLdapUsers( client: LdapClient, - config: UserConfig[], + userConfig: UserConfig[], + vendorConfig: VendorConfig | undefined, opts?: { transformer?: UserTransformer }, ): Promise<{ users: UserEntity[]; // With all relations empty userMemberOf: Map>; // DN -> DN or UUID of groups }> { - if (config.length === 0) { + if (userConfig.length === 0) { return { users: [], userMemberOf: new Map() }; } const entities: UserEntity[] = []; const userMemberOf: Map> = new Map(); - - const vendor = await client.getVendor(); + const vendorDefaults = await client.getVendor(); + const vendor: LdapVendor = { + dnAttributeName: + vendorConfig?.dnAttributeName ?? vendorDefaults.dnAttributeName, + uuidAttributeName: + vendorConfig?.uuidAttributeName ?? vendorDefaults.uuidAttributeName, + decodeStringAttribute: vendorDefaults.decodeStringAttribute, + }; const transformer = opts?.transformer ?? defaultUserTransformer; - for (const cfg of config) { + for (const cfg of userConfig) { const { dn, options, map } = cfg; await client.searchStreaming(dn, options, async user => { const entity = await transformer(vendor, cfg, user); @@ -210,7 +217,8 @@ export async function defaultGroupTransformer( */ export async function readLdapGroups( client: LdapClient, - config: GroupConfig[], + groupConfig: GroupConfig[], + vendorConfig: VendorConfig | undefined, opts?: { transformer?: GroupTransformer; }, @@ -219,17 +227,25 @@ export async function readLdapGroups( groupMemberOf: Map>; // DN -> DN or UUID of groups groupMember: Map>; // DN -> DN or UUID of groups & users }> { - if (config.length === 0) { + if (groupConfig.length === 0) { return { groups: [], groupMemberOf: new Map(), groupMember: new Map() }; } const groups: GroupEntity[] = []; const groupMemberOf: Map> = new Map(); const groupMember: Map> = new Map(); - const vendor = await client.getVendor(); + const vendorDefaults = await client.getVendor(); + const vendor: LdapVendor = { + dnAttributeName: + vendorConfig?.dnAttributeName ?? vendorDefaults.dnAttributeName, + uuidAttributeName: + vendorConfig?.uuidAttributeName ?? vendorDefaults.uuidAttributeName, + decodeStringAttribute: vendorDefaults.decodeStringAttribute, + }; + const transformer = opts?.transformer ?? defaultGroupTransformer; - for (const cfg of config) { + for (const cfg of groupConfig) { const { dn, map, options } = cfg; await client.searchStreaming(dn, options, async entry => { @@ -275,6 +291,7 @@ export async function readLdapOrg( client: LdapClient, userConfig: UserConfig[], groupConfig: GroupConfig[], + vendorConfig: VendorConfig | undefined, options: { groupTransformer?: GroupTransformer; userTransformer?: UserTransformer; @@ -287,12 +304,18 @@ export async function readLdapOrg( // Invokes the above "raw" read functions and stitches together the results // with all relations etc filled in. - const { users, userMemberOf } = await readLdapUsers(client, userConfig, { - transformer: options?.userTransformer, - }); + const { users, userMemberOf } = await readLdapUsers( + client, + userConfig, + vendorConfig, + { + transformer: options?.userTransformer, + }, + ); const { groups, groupMemberOf, groupMember } = await readLdapGroups( client, groupConfig, + vendorConfig, { transformer: options?.groupTransformer }, ); diff --git a/plugins/catalog-backend-module-ldap/src/processors/LdapOrgEntityProvider.ts b/plugins/catalog-backend-module-ldap/src/processors/LdapOrgEntityProvider.ts index 0e5fae55bb..a8d27855dc 100644 --- a/plugins/catalog-backend-module-ldap/src/processors/LdapOrgEntityProvider.ts +++ b/plugins/catalog-backend-module-ldap/src/processors/LdapOrgEntityProvider.ts @@ -294,6 +294,7 @@ export class LdapOrgEntityProvider implements EntityProvider { client, this.options.provider.users, this.options.provider.groups, + this.options.provider.vendor, { groupTransformer: this.options.groupTransformer, userTransformer: this.options.userTransformer, diff --git a/plugins/catalog-backend-module-ldap/src/processors/LdapOrgReaderProcessor.ts b/plugins/catalog-backend-module-ldap/src/processors/LdapOrgReaderProcessor.ts index acbe128e0b..56f984dabc 100644 --- a/plugins/catalog-backend-module-ldap/src/processors/LdapOrgReaderProcessor.ts +++ b/plugins/catalog-backend-module-ldap/src/processors/LdapOrgReaderProcessor.ts @@ -109,6 +109,7 @@ export class LdapOrgReaderProcessor implements CatalogProcessor { client, provider.users, provider.groups, + provider.vendor, { groupTransformer: this.groupTransformer, userTransformer: this.userTransformer, diff --git a/plugins/catalog-backend-module-logs/CHANGELOG.md b/plugins/catalog-backend-module-logs/CHANGELOG.md index 05d129c042..9b5244ac2c 100644 --- a/plugins/catalog-backend-module-logs/CHANGELOG.md +++ b/plugins/catalog-backend-module-logs/CHANGELOG.md @@ -1,5 +1,49 @@ # @backstage/plugin-catalog-backend-module-logs +## 0.1.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.26.2-next.1 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + +## 0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.26.1-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + +## 0.1.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-catalog-backend@1.26.0 + - @backstage/plugin-events-node@0.4.0 + +## 0.1.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/plugin-catalog-backend@1.26.0-next.2 + - @backstage/plugin-events-node@0.4.0-next.2 + ## 0.1.0-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-logs/package.json b/plugins/catalog-backend-module-logs/package.json index 0d4bbf6e5d..2c55c62db5 100644 --- a/plugins/catalog-backend-module-logs/package.json +++ b/plugins/catalog-backend-module-logs/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-logs", - "version": "0.1.0-next.1", + "version": "0.1.2-next.1", "description": "A module that subscribes to catalog releated events and logs them.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-logs/api-report.md b/plugins/catalog-backend-module-logs/report.api.md similarity index 100% rename from plugins/catalog-backend-module-logs/api-report.md rename to plugins/catalog-backend-module-logs/report.api.md diff --git a/plugins/catalog-backend-module-logs/src/module.ts b/plugins/catalog-backend-module-logs/src/module.ts index bdc916e958..ec4f7b9c1d 100644 --- a/plugins/catalog-backend-module-logs/src/module.ts +++ b/plugins/catalog-backend-module-logs/src/module.ts @@ -34,7 +34,6 @@ interface EventsParamsWithPayload extends EventParams { /** * A catalog module that logs catalog errors using the logger service. * - * @packageDocumentation * @public */ export const catalogModuleLogs = createBackendModule({ diff --git a/plugins/catalog-backend-module-msgraph/CHANGELOG.md b/plugins/catalog-backend-module-msgraph/CHANGELOG.md index 9cc7e6207b..dc1fc0b714 100644 --- a/plugins/catalog-backend-module-msgraph/CHANGELOG.md +++ b/plugins/catalog-backend-module-msgraph/CHANGELOG.md @@ -1,5 +1,40 @@ # @backstage/plugin-catalog-backend-module-msgraph +## 0.6.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + +## 0.6.2 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- 3c2d690: Allow users without defined email to be ingested by the `msgraph` catalog plugin and add `userIdMatchingUserEntityAnnotation` sign-in resolver for the Microsoft auth provider to support sign-in for users without defined email. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/config@1.2.0 + +## 0.6.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.2 + ## 0.6.2-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-msgraph/package.json b/plugins/catalog-backend-module-msgraph/package.json index cc8fc5abc8..7d0c96874d 100644 --- a/plugins/catalog-backend-module-msgraph/package.json +++ b/plugins/catalog-backend-module-msgraph/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-msgraph", - "version": "0.6.2-next.1", + "version": "0.6.3-next.0", "description": "A Backstage catalog backend module that helps integrate towards Microsoft Graph", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-msgraph/api-report-alpha.md b/plugins/catalog-backend-module-msgraph/report-alpha.api.md similarity index 100% rename from plugins/catalog-backend-module-msgraph/api-report-alpha.md rename to plugins/catalog-backend-module-msgraph/report-alpha.api.md diff --git a/plugins/catalog-backend-module-msgraph/api-report.md b/plugins/catalog-backend-module-msgraph/report.api.md similarity index 90% rename from plugins/catalog-backend-module-msgraph/api-report.md rename to plugins/catalog-backend-module-msgraph/report.api.md index acc3b8531b..3df99752db 100644 --- a/plugins/catalog-backend-module-msgraph/api-report.md +++ b/plugins/catalog-backend-module-msgraph/report.api.md @@ -128,14 +128,12 @@ export class MicrosoftGraphOrgEntityProvider implements EntityProvider { organizationTransformer?: OrganizationTransformer; providerConfigTransformer?: ProviderConfigTransformer; }); - // (undocumented) connect(connection: EntityProviderConnection): Promise; // (undocumented) static fromConfig( configRoot: Config, options: MicrosoftGraphOrgEntityProviderOptions, ): MicrosoftGraphOrgEntityProvider[]; - // (undocumented) getProviderName(): string; read(options?: { logger?: LoggerService }): Promise; } @@ -292,4 +290,14 @@ export type UserTransformer = ( user: MicrosoftGraph.User, userPhoto?: string, ) => Promise; + +// Warnings were encountered during analysis: +// +// src/microsoftGraph/client.d.ts:109:5 - (ae-undocumented) Missing documentation for "getUserPhoto". +// src/microsoftGraph/client.d.ts:129:5 - (ae-undocumented) Missing documentation for "getGroupPhoto". +// src/microsoftGraph/client.d.ts:176:5 - (ae-unresolved-link) The @link reference could not be resolved: The package "@backstage/plugin-catalog-backend-module-msgraph" does not have an export "entityName" +// src/processors/MicrosoftGraphOrgEntityProvider.d.ts:119:5 - (ae-undocumented) Missing documentation for "fromConfig". +// src/processors/MicrosoftGraphOrgReaderProcessor.d.ts:18:5 - (ae-undocumented) Missing documentation for "fromConfig". +// src/processors/MicrosoftGraphOrgReaderProcessor.d.ts:31:5 - (ae-undocumented) Missing documentation for "getProcessorName". +// src/processors/MicrosoftGraphOrgReaderProcessor.d.ts:32:5 - (ae-undocumented) Missing documentation for "readLocation". ``` diff --git a/plugins/catalog-backend-module-openapi/CHANGELOG.md b/plugins/catalog-backend-module-openapi/CHANGELOG.md index b1e1c3308c..ce4b51707f 100644 --- a/plugins/catalog-backend-module-openapi/CHANGELOG.md +++ b/plugins/catalog-backend-module-openapi/CHANGELOG.md @@ -1,5 +1,72 @@ # @backstage/plugin-catalog-backend-module-openapi +## 0.2.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.26.2-next.1 + - @backstage/integration@1.15.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + +## 0.2.1-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-catalog-backend@1.26.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.15.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + +## 0.2.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-catalog-backend@1.26.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/integration@1.15.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## 0.2.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/plugin-catalog-backend@1.26.0-next.2 + - @backstage/integration@1.15.0-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.2 + ## 0.2.0-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-openapi/package.json b/plugins/catalog-backend-module-openapi/package.json index f93f1e8119..c6a22326fb 100644 --- a/plugins/catalog-backend-module-openapi/package.json +++ b/plugins/catalog-backend-module-openapi/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-openapi", - "version": "0.2.0-next.1", + "version": "0.2.2-next.1", "description": "A Backstage catalog backend module that helps with OpenAPI specifications", "backstage": { "role": "backend-plugin-module", @@ -38,7 +38,7 @@ }, "dependencies": { "@apidevtools/json-schema-ref-parser": "^9.0.6", - "@backstage/backend-common": "workspace:^", + "@backstage/backend-common": "^0.25.0", "@backstage/backend-plugin-api": "workspace:^", "@backstage/catalog-model": "workspace:^", "@backstage/config": "workspace:^", diff --git a/plugins/catalog-backend-module-openapi/api-report.md b/plugins/catalog-backend-module-openapi/report.api.md similarity index 71% rename from plugins/catalog-backend-module-openapi/api-report.md rename to plugins/catalog-backend-module-openapi/report.api.md index d79d852387..c913e63294 100644 --- a/plugins/catalog-backend-module-openapi/api-report.md +++ b/plugins/catalog-backend-module-openapi/report.api.md @@ -47,5 +47,14 @@ export class OpenApiRefProcessor implements CatalogProcessor { preProcessEntity(entity: Entity, location: LocationSpec): Promise; } +// Warnings were encountered during analysis: +// +// src/OpenApiRefProcessor.d.ts:12:1 - (ae-undocumented) Missing documentation for "OpenApiRefProcessor". +// src/OpenApiRefProcessor.d.ts:16:5 - (ae-undocumented) Missing documentation for "fromConfig". +// src/OpenApiRefProcessor.d.ts:25:5 - (ae-undocumented) Missing documentation for "getProcessorName". +// src/OpenApiRefProcessor.d.ts:26:5 - (ae-undocumented) Missing documentation for "preProcessEntity". +// src/index.d.ts:8:22 - (ae-undocumented) Missing documentation for "openApiPlaceholderResolver". +// src/jsonSchemaRefPlaceholderResolver.d.ts:4:1 - (ae-undocumented) Missing documentation for "jsonSchemaRefPlaceholderResolver". + // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/catalog-backend-module-puppetdb/CHANGELOG.md b/plugins/catalog-backend-module-puppetdb/CHANGELOG.md index cfcf1acec3..eb133b2b2c 100644 --- a/plugins/catalog-backend-module-puppetdb/CHANGELOG.md +++ b/plugins/catalog-backend-module-puppetdb/CHANGELOG.md @@ -1,5 +1,42 @@ # @backstage/plugin-catalog-backend-module-puppetdb +## 0.2.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.13.1-next.0 + +## 0.2.2 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## 0.2.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.12.7-next.2 + ## 0.2.2-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-puppetdb/package.json b/plugins/catalog-backend-module-puppetdb/package.json index e9f322e4c1..e900e2a98a 100644 --- a/plugins/catalog-backend-module-puppetdb/package.json +++ b/plugins/catalog-backend-module-puppetdb/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-puppetdb", - "version": "0.2.2-next.1", + "version": "0.2.3-next.0", "description": "A Backstage catalog backend module that helps integrate towards PuppetDB", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-puppetdb/api-report-alpha.md b/plugins/catalog-backend-module-puppetdb/report-alpha.api.md similarity index 100% rename from plugins/catalog-backend-module-puppetdb/api-report-alpha.md rename to plugins/catalog-backend-module-puppetdb/report-alpha.api.md diff --git a/plugins/catalog-backend-module-puppetdb/api-report.md b/plugins/catalog-backend-module-puppetdb/report.api.md similarity index 67% rename from plugins/catalog-backend-module-puppetdb/api-report.md rename to plugins/catalog-backend-module-puppetdb/report.api.md index 691b752a6b..00874a3b2f 100644 --- a/plugins/catalog-backend-module-puppetdb/api-report.md +++ b/plugins/catalog-backend-module-puppetdb/report.api.md @@ -24,7 +24,6 @@ export const defaultResourceTransformer: ResourceTransformer; // @public export class PuppetDbEntityProvider implements EntityProvider { - // (undocumented) connect(connection: EntityProviderConnection): Promise; static fromConfig( config: Config, @@ -35,7 +34,6 @@ export class PuppetDbEntityProvider implements EntityProvider { transformer?: ResourceTransformer; }, ): PuppetDbEntityProvider[]; - // (undocumented) getProviderName(): string; refresh(logger: LoggerService): Promise; } @@ -77,4 +75,12 @@ export type ResourceTransformer = ( node: PuppetNode, config: PuppetDbEntityProviderConfig, ) => Promise; + +// Warnings were encountered during analysis: +// +// src/providers/PuppetDbEntityProvider.d.ts:39:8 - (tsdoc-undefined-tag) The TSDoc tag "@private" is not defined in this configuration +// src/providers/PuppetDbEntityProvider.d.ts:41:5 - (ae-unresolved-link) The @link reference could not be resolved: The package "@backstage/plugin-catalog-backend-module-puppetdb" does not have an export "LoggerService" +// src/providers/PuppetDbEntityProvider.d.ts:41:5 - (ae-unresolved-link) The @link reference could not be resolved: The package "@backstage/plugin-catalog-backend-module-puppetdb" does not have an export "SchedulerServiceTaskRunner" +// src/providers/PuppetDbEntityProvider.d.ts:51:8 - (tsdoc-undefined-tag) The TSDoc tag "@private" is not defined in this configuration +// src/providers/PuppetDbEntityProvider.d.ts:53:5 - (ae-unresolved-link) The @link reference could not be resolved: The package "@backstage/plugin-catalog-backend-module-puppetdb" does not have an export "SchedulerServiceTaskRunner" ``` diff --git a/plugins/catalog-backend-module-scaffolder-entity-model/CHANGELOG.md b/plugins/catalog-backend-module-scaffolder-entity-model/CHANGELOG.md index d6e8c54549..5072903466 100644 --- a/plugins/catalog-backend-module-scaffolder-entity-model/CHANGELOG.md +++ b/plugins/catalog-backend-module-scaffolder-entity-model/CHANGELOG.md @@ -1,5 +1,46 @@ # @backstage/plugin-catalog-backend-module-scaffolder-entity-model +## 0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-scaffolder-common@1.5.6 + +## 0.2.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/plugin-scaffolder-common@1.5.6 + +## 0.2.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.2 + - @backstage/plugin-scaffolder-common@1.5.5 + ## 0.2.0-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-scaffolder-entity-model/package.json b/plugins/catalog-backend-module-scaffolder-entity-model/package.json index 3855e64192..d1474909ab 100644 --- a/plugins/catalog-backend-module-scaffolder-entity-model/package.json +++ b/plugins/catalog-backend-module-scaffolder-entity-model/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-scaffolder-entity-model", - "version": "0.2.0-next.1", + "version": "0.2.1-next.0", "description": "Adds support for the scaffolder specific entity model (e.g. the Template kind) to the catalog backend plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-scaffolder-entity-model/api-report.md b/plugins/catalog-backend-module-scaffolder-entity-model/report.api.md similarity index 70% rename from plugins/catalog-backend-module-scaffolder-entity-model/api-report.md rename to plugins/catalog-backend-module-scaffolder-entity-model/report.api.md index 49542b0396..e4af5d5ef5 100644 --- a/plugins/catalog-backend-module-scaffolder-entity-model/api-report.md +++ b/plugins/catalog-backend-module-scaffolder-entity-model/report.api.md @@ -26,4 +26,10 @@ export class ScaffolderEntitiesProcessor implements CatalogProcessor { // (undocumented) validateEntityKind(entity: Entity): Promise; } + +// Warnings were encountered during analysis: +// +// src/processor/ScaffolderEntitiesProcessor.d.ts:10:5 - (ae-undocumented) Missing documentation for "getProcessorName". +// src/processor/ScaffolderEntitiesProcessor.d.ts:12:5 - (ae-undocumented) Missing documentation for "validateEntityKind". +// src/processor/ScaffolderEntitiesProcessor.d.ts:13:5 - (ae-undocumented) Missing documentation for "postProcessEntity". ``` diff --git a/plugins/catalog-backend-module-unprocessed/CHANGELOG.md b/plugins/catalog-backend-module-unprocessed/CHANGELOG.md index 401f93077d..4f4b6220b8 100644 --- a/plugins/catalog-backend-module-unprocessed/CHANGELOG.md +++ b/plugins/catalog-backend-module-unprocessed/CHANGELOG.md @@ -1,5 +1,55 @@ # @backstage/plugin-catalog-backend-module-unprocessed +## 0.5.1-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-catalog-unprocessed-entities-common@0.0.4 + - @backstage/plugin-permission-common@0.8.1 + +## 0.5.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-unprocessed-entities-common@0.0.4 + - @backstage/plugin-permission-common@0.8.1 + +## 0.5.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.12.7-next.2 + - @backstage/plugin-catalog-unprocessed-entities-common@0.0.4 + - @backstage/plugin-permission-common@0.8.1 + ## 0.5.0-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-unprocessed/package.json b/plugins/catalog-backend-module-unprocessed/package.json index 78a9c345ce..16364bcba6 100644 --- a/plugins/catalog-backend-module-unprocessed/package.json +++ b/plugins/catalog-backend-module-unprocessed/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-unprocessed", - "version": "0.5.0-next.1", + "version": "0.5.1-next.0", "description": "Backstage Catalog module to view unprocessed entities", "backstage": { "role": "backend-plugin-module", @@ -33,7 +33,7 @@ "test": "backstage-cli package test" }, "dependencies": { - "@backstage/backend-common": "workspace:^", + "@backstage/backend-common": "^0.25.0", "@backstage/backend-plugin-api": "workspace:^", "@backstage/catalog-model": "workspace:^", "@backstage/errors": "workspace:^", diff --git a/plugins/catalog-backend-module-unprocessed/api-report.md b/plugins/catalog-backend-module-unprocessed/report.api.md similarity index 79% rename from plugins/catalog-backend-module-unprocessed/api-report.md rename to plugins/catalog-backend-module-unprocessed/report.api.md index 493082ac7c..ea3a9d974c 100644 --- a/plugins/catalog-backend-module-unprocessed/api-report.md +++ b/plugins/catalog-backend-module-unprocessed/report.api.md @@ -27,4 +27,9 @@ export class UnprocessedEntitiesModule { // (undocumented) registerRoutes(): void; } + +// Warnings were encountered during analysis: +// +// src/UnprocessedEntitiesModule.d.ts:15:5 - (ae-undocumented) Missing documentation for "create". +// src/UnprocessedEntitiesModule.d.ts:26:5 - (ae-undocumented) Missing documentation for "registerRoutes". ``` diff --git a/plugins/catalog-backend/CHANGELOG.md b/plugins/catalog-backend/CHANGELOG.md index d2987d1182..6cfef6f9f9 100644 --- a/plugins/catalog-backend/CHANGELOG.md +++ b/plugins/catalog-backend/CHANGELOG.md @@ -1,5 +1,109 @@ # @backstage/plugin-catalog-backend +## 1.26.2-next.1 + +### Patch Changes + +- 62747f8: Fixed a bug where the concurrency limiter for URL reading was not honored +- 8206f49: Fix a bug where etags were expiring too soon in the URL reader +- Updated dependencies + - @backstage/integration@1.15.1-next.0 + - @backstage/backend-openapi-utils@0.1.19-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-permission-node@0.8.4-next.0 + - @backstage/plugin-search-backend-module-catalog@0.2.3-next.1 + +## 1.26.1-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-search-backend-module-catalog@0.2.3-next.0 + - @backstage/plugin-permission-node@0.8.4-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/backend-openapi-utils@0.1.19-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.15.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-permission-common@0.8.1 + +## 1.26.0 + +### Minor Changes + +- 74acf06: Add `dependencyOf` prop to catalog model for Component kind to enable building relationship graphs with both directions using `dependsOn` and `dependencyOf`. +- 78475c3: Allow offset mode paging in entity list provider +- bd35cdb: The `analyze-location` endpoint is now protected by the `catalog.location.analyze` permission. + The `validate-entity` endpoint is now protected by the `catalog.entity.validate` permission. + +### Patch Changes + +- 1882cfe: Moved `getEntities` ordering to utilize database instead of having it inside catalog client + + Please note that the latest version of `@backstage/catalog-client` will not order the entities in the same way as before. This is because the ordering is now done in the database query instead of in the client. If you rely on the ordering of the entities, you may need to update your backend plugin or code to handle this change. + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- 53cce86: Fixed an issue with the by-query call, where ordering by a field that does not exist on all entities led to not all results being returned +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/catalog-client@1.7.0 + - @backstage/plugin-search-backend-module-catalog@0.2.2 + - @backstage/plugin-permission-node@0.8.3 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/integration@1.15.0 + - @backstage/backend-openapi-utils@0.1.18 + - @backstage/plugin-events-node@0.4.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.8.1 + +## 1.26.0-next.2 + +### Minor Changes + +- 78475c3: Allow offset mode paging in entity list provider + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-client@1.7.0-next.1 + - @backstage/integration@1.15.0-next.0 + - @backstage/backend-openapi-utils@0.1.18-next.2 + - @backstage/plugin-permission-node@0.8.3-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.2 + - @backstage/plugin-events-node@0.4.0-next.2 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-backend-module-catalog@0.2.2-next.2 + ## 1.25.3-next.1 ### Patch Changes diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json index e3a09b65ec..59b922b308 100644 --- a/plugins/catalog-backend/package.json +++ b/plugins/catalog-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend", - "version": "1.25.3-next.1", + "version": "1.26.2-next.1", "description": "The Backstage backend plugin that provides the Backstage catalog", "backstage": { "role": "backend-plugin", @@ -61,7 +61,7 @@ "test": "backstage-cli package test" }, "dependencies": { - "@backstage/backend-common": "workspace:^", + "@backstage/backend-common": "^0.25.0", "@backstage/backend-openapi-utils": "workspace:^", "@backstage/backend-plugin-api": "workspace:^", "@backstage/catalog-client": "workspace:^", @@ -112,7 +112,7 @@ "better-sqlite3": "^11.0.0", "luxon": "^3.0.0", "msw": "^1.0.0", - "supertest": "^6.1.3", + "supertest": "^7.0.0", "wait-for-expect": "^3.0.2", "winston": "^3.13.0" }, diff --git a/plugins/catalog-backend/api-report-alpha.md b/plugins/catalog-backend/report-alpha.api.md similarity index 100% rename from plugins/catalog-backend/api-report-alpha.md rename to plugins/catalog-backend/report-alpha.api.md diff --git a/plugins/catalog-backend/api-report.md b/plugins/catalog-backend/report.api.md similarity index 67% rename from plugins/catalog-backend/api-report.md rename to plugins/catalog-backend/report.api.md index 7717066d2a..6fff29f6f8 100644 --- a/plugins/catalog-backend/api-report.md +++ b/plugins/catalog-backend/report.api.md @@ -478,4 +478,85 @@ export class UrlReaderProcessor implements CatalogProcessor_2 { cache: CatalogProcessorCache_2, ): Promise; } + +// Warnings were encountered during analysis: +// +// src/constants.d.ts:2:22 - (ae-undocumented) Missing documentation for "CATALOG_CONFLICTS_TOPIC". +// src/constants.d.ts:4:22 - (ae-undocumented) Missing documentation for "CATALOG_ERRORS_TOPIC". +// src/deprecated.d.ts:8:22 - (ae-undocumented) Missing documentation for "locationSpecToMetadataName". +// src/deprecated.d.ts:13:22 - (ae-undocumented) Missing documentation for "locationSpecToLocationEntity". +// src/deprecated.d.ts:18:22 - (ae-undocumented) Missing documentation for "processingResult". +// src/deprecated.d.ts:31:1 - (ae-undocumented) Missing documentation for "EntitiesSearchFilter". +// src/deprecated.d.ts:36:1 - (ae-undocumented) Missing documentation for "EntityFilter". +// src/deprecated.d.ts:41:1 - (ae-undocumented) Missing documentation for "DeferredEntity". +// src/deprecated.d.ts:46:1 - (ae-undocumented) Missing documentation for "EntityRelationSpec". +// src/deprecated.d.ts:51:1 - (ae-undocumented) Missing documentation for "CatalogProcessor". +// src/deprecated.d.ts:56:1 - (ae-undocumented) Missing documentation for "CatalogProcessorParser". +// src/deprecated.d.ts:61:1 - (ae-undocumented) Missing documentation for "CatalogProcessorCache". +// src/deprecated.d.ts:66:1 - (ae-undocumented) Missing documentation for "CatalogProcessorEmit". +// src/deprecated.d.ts:71:1 - (ae-undocumented) Missing documentation for "CatalogProcessorLocationResult". +// src/deprecated.d.ts:76:1 - (ae-undocumented) Missing documentation for "CatalogProcessorEntityResult". +// src/deprecated.d.ts:81:1 - (ae-undocumented) Missing documentation for "CatalogProcessorRelationResult". +// src/deprecated.d.ts:86:1 - (ae-undocumented) Missing documentation for "CatalogProcessorErrorResult". +// src/deprecated.d.ts:91:1 - (ae-undocumented) Missing documentation for "CatalogProcessorRefreshKeysResult". +// src/deprecated.d.ts:96:1 - (ae-undocumented) Missing documentation for "CatalogProcessorResult". +// src/deprecated.d.ts:101:1 - (ae-undocumented) Missing documentation for "EntityProvider". +// src/deprecated.d.ts:106:1 - (ae-undocumented) Missing documentation for "EntityProviderConnection". +// src/deprecated.d.ts:111:1 - (ae-undocumented) Missing documentation for "EntityProviderMutation". +// src/deprecated.d.ts:129:1 - (ae-undocumented) Missing documentation for "AnalyzeOptions". +// src/deprecated.d.ts:134:1 - (ae-undocumented) Missing documentation for "LocationAnalyzer". +// src/deprecated.d.ts:139:1 - (ae-undocumented) Missing documentation for "ScmLocationAnalyzer". +// src/deprecated.d.ts:144:1 - (ae-undocumented) Missing documentation for "PlaceholderResolver". +// src/deprecated.d.ts:149:1 - (ae-undocumented) Missing documentation for "PlaceholderResolverParams". +// src/deprecated.d.ts:154:1 - (ae-undocumented) Missing documentation for "PlaceholderResolverRead". +// src/deprecated.d.ts:159:1 - (ae-undocumented) Missing documentation for "PlaceholderResolverResolveUrl". +// src/deprecated.d.ts:164:1 - (ae-undocumented) Missing documentation for "AnalyzeLocationRequest". +// src/deprecated.d.ts:169:1 - (ae-undocumented) Missing documentation for "AnalyzeLocationResponse". +// src/deprecated.d.ts:202:22 - (ae-undocumented) Missing documentation for "DefaultCatalogCollatorFactory". +// src/deprecated.d.ts:207:22 - (ae-undocumented) Missing documentation for "defaultCatalogCollatorEntityTransformer". +// src/deprecated.d.ts:212:1 - (ae-undocumented) Missing documentation for "DefaultCatalogCollatorFactoryOptions". +// src/deprecated.d.ts:217:1 - (ae-undocumented) Missing documentation for "CatalogCollatorEntityTransformer". +// src/processing/types.d.ts:31:5 - (ae-undocumented) Missing documentation for "start". +// src/processing/types.d.ts:32:5 - (ae-undocumented) Missing documentation for "stop". +// src/processors/AnnotateLocationEntityProcessor.d.ts:6:1 - (ae-undocumented) Missing documentation for "AnnotateLocationEntityProcessor". +// src/processors/AnnotateLocationEntityProcessor.d.ts:11:5 - (ae-undocumented) Missing documentation for "getProcessorName". +// src/processors/AnnotateLocationEntityProcessor.d.ts:12:5 - (ae-undocumented) Missing documentation for "preProcessEntity". +// src/processors/AnnotateScmSlugEntityProcessor.d.ts:7:1 - (ae-undocumented) Missing documentation for "AnnotateScmSlugEntityProcessor". +// src/processors/AnnotateScmSlugEntityProcessor.d.ts:13:5 - (ae-undocumented) Missing documentation for "getProcessorName". +// src/processors/AnnotateScmSlugEntityProcessor.d.ts:14:5 - (ae-undocumented) Missing documentation for "fromConfig". +// src/processors/AnnotateScmSlugEntityProcessor.d.ts:17:5 - (ae-undocumented) Missing documentation for "preProcessEntity". +// src/processors/BuiltinKindsEntityProcessor.d.ts:5:1 - (ae-undocumented) Missing documentation for "BuiltinKindsEntityProcessor". +// src/processors/BuiltinKindsEntityProcessor.d.ts:7:5 - (ae-undocumented) Missing documentation for "getProcessorName". +// src/processors/BuiltinKindsEntityProcessor.d.ts:8:5 - (ae-undocumented) Missing documentation for "validateEntityKind". +// src/processors/BuiltinKindsEntityProcessor.d.ts:9:5 - (ae-undocumented) Missing documentation for "postProcessEntity". +// src/processors/CodeOwnersProcessor.d.ts:8:1 - (ae-undocumented) Missing documentation for "CodeOwnersProcessor". +// src/processors/CodeOwnersProcessor.d.ts:12:5 - (ae-undocumented) Missing documentation for "fromConfig". +// src/processors/CodeOwnersProcessor.d.ts:21:5 - (ae-undocumented) Missing documentation for "getProcessorName". +// src/processors/CodeOwnersProcessor.d.ts:22:5 - (ae-undocumented) Missing documentation for "preProcessEntity". +// src/processors/FileReaderProcessor.d.ts:4:1 - (ae-undocumented) Missing documentation for "FileReaderProcessor". +// src/processors/FileReaderProcessor.d.ts:5:5 - (ae-undocumented) Missing documentation for "getProcessorName". +// src/processors/FileReaderProcessor.d.ts:6:5 - (ae-undocumented) Missing documentation for "readLocation". +// src/processors/LocationEntityProcessor.d.ts:10:1 - (ae-undocumented) Missing documentation for "LocationEntityProcessorOptions". +// src/processors/LocationEntityProcessor.d.ts:28:5 - (ae-undocumented) Missing documentation for "getProcessorName". +// src/processors/LocationEntityProcessor.d.ts:29:5 - (ae-undocumented) Missing documentation for "postProcessEntity". +// src/processors/PlaceholderProcessor.d.ts:8:1 - (ae-undocumented) Missing documentation for "PlaceholderProcessorOptions". +// src/processors/PlaceholderProcessor.d.ts:21:5 - (ae-undocumented) Missing documentation for "getProcessorName". +// src/processors/PlaceholderProcessor.d.ts:22:5 - (ae-undocumented) Missing documentation for "preProcessEntity". +// src/processors/UrlReaderProcessor.d.ts:5:1 - (ae-undocumented) Missing documentation for "UrlReaderProcessor". +// src/processors/UrlReaderProcessor.d.ts:12:5 - (ae-undocumented) Missing documentation for "getProcessorName". +// src/processors/UrlReaderProcessor.d.ts:13:5 - (ae-undocumented) Missing documentation for "readLocation". +// src/search/DefaultCatalogCollator.d.ts:11:1 - (ae-undocumented) Missing documentation for "DefaultCatalogCollator". +// src/search/DefaultCatalogCollator.d.ts:12:5 - (ae-undocumented) Missing documentation for "discovery". +// src/search/DefaultCatalogCollator.d.ts:13:5 - (ae-undocumented) Missing documentation for "locationTemplate". +// src/search/DefaultCatalogCollator.d.ts:14:5 - (ae-undocumented) Missing documentation for "filter". +// src/search/DefaultCatalogCollator.d.ts:15:5 - (ae-undocumented) Missing documentation for "catalogClient". +// src/search/DefaultCatalogCollator.d.ts:16:5 - (ae-undocumented) Missing documentation for "type". +// src/search/DefaultCatalogCollator.d.ts:17:5 - (ae-undocumented) Missing documentation for "visibilityPermission". +// src/search/DefaultCatalogCollator.d.ts:18:5 - (ae-undocumented) Missing documentation for "tokenManager". +// src/search/DefaultCatalogCollator.d.ts:19:5 - (ae-undocumented) Missing documentation for "fromConfig". +// src/search/DefaultCatalogCollator.d.ts:31:5 - (ae-undocumented) Missing documentation for "applyArgsToFormat". +// src/search/DefaultCatalogCollator.d.ts:33:5 - (ae-undocumented) Missing documentation for "execute". +// src/service/CatalogBuilder.d.ts:19:1 - (ae-undocumented) Missing documentation for "CatalogEnvironment". +// src/service/CatalogBuilder.d.ts:233:5 - (ae-undocumented) Missing documentation for "subscribe". +// src/util/parse.d.ts:6:1 - (ae-undocumented) Missing documentation for "parseEntityYaml". ``` diff --git a/plugins/catalog-backend/src/catalog/types.ts b/plugins/catalog-backend/src/catalog/types.ts index 9cc83098b3..a02c74c0c1 100644 --- a/plugins/catalog-backend/src/catalog/types.ts +++ b/plugins/catalog-backend/src/catalog/types.ts @@ -196,6 +196,7 @@ export interface QueryEntitiesInitialRequest { credentials: BackstageCredentials; fields?: (entity: Entity) => Entity; limit?: number; + offset?: number; filter?: EntityFilter; orderFields?: EntityOrder[]; fullTextFilter?: { diff --git a/plugins/catalog-backend/src/index.ts b/plugins/catalog-backend/src/index.ts index d3ffa9a974..e3374a6a8b 100644 --- a/plugins/catalog-backend/src/index.ts +++ b/plugins/catalog-backend/src/index.ts @@ -20,9 +20,10 @@ * @packageDocumentation */ -export * from './modules'; +export * from './processors'; export * from './processing'; export * from './search'; export * from './service'; export * from './deprecated'; export * from './constants'; +export * from './util'; diff --git a/plugins/catalog-backend/src/modules/codeowners/index.ts b/plugins/catalog-backend/src/modules/codeowners/index.ts deleted file mode 100644 index 6b7569ff07..0000000000 --- a/plugins/catalog-backend/src/modules/codeowners/index.ts +++ /dev/null @@ -1,17 +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. - */ - -export { CodeOwnersProcessor } from './CodeOwnersProcessor'; diff --git a/plugins/catalog-backend/src/modules/index.ts b/plugins/catalog-backend/src/modules/index.ts deleted file mode 100644 index 10ebf65fed..0000000000 --- a/plugins/catalog-backend/src/modules/index.ts +++ /dev/null @@ -1,18 +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. - */ - -export * from './codeowners'; -export * from './core'; diff --git a/plugins/catalog-backend/src/processing/DefaultCatalogProcessingOrchestrator.test.ts b/plugins/catalog-backend/src/processing/DefaultCatalogProcessingOrchestrator.test.ts index e8d05e3f25..31d7c34b94 100644 --- a/plugins/catalog-backend/src/processing/DefaultCatalogProcessingOrchestrator.test.ts +++ b/plugins/catalog-backend/src/processing/DefaultCatalogProcessingOrchestrator.test.ts @@ -33,7 +33,7 @@ import { } from '@backstage/plugin-catalog-node'; import { CatalogRulesEnforcer } from '../ingestion/CatalogRules'; import { DefaultCatalogProcessingOrchestrator } from './DefaultCatalogProcessingOrchestrator'; -import { defaultEntityDataParser } from '../modules/util/parse'; +import { defaultEntityDataParser } from '../util/parse'; import { ConfigReader } from '@backstage/config'; import { InputError } from '@backstage/errors'; import { mockServices } from '@backstage/backend-test-utils'; diff --git a/plugins/catalog-backend/src/processing/index.ts b/plugins/catalog-backend/src/processing/index.ts index 5ed8831779..6e5893c976 100644 --- a/plugins/catalog-backend/src/processing/index.ts +++ b/plugins/catalog-backend/src/processing/index.ts @@ -15,6 +15,5 @@ */ export type { CatalogProcessingEngine } from './types'; - export { createRandomProcessingInterval } from './refresh'; export type { ProcessingIntervalFunction } from './refresh'; diff --git a/plugins/catalog-backend/src/modules/core/AnnotateLocationEntityProcessor.test.ts b/plugins/catalog-backend/src/processors/AnnotateLocationEntityProcessor.test.ts similarity index 100% rename from plugins/catalog-backend/src/modules/core/AnnotateLocationEntityProcessor.test.ts rename to plugins/catalog-backend/src/processors/AnnotateLocationEntityProcessor.test.ts diff --git a/plugins/catalog-backend/src/modules/core/AnnotateLocationEntityProcessor.ts b/plugins/catalog-backend/src/processors/AnnotateLocationEntityProcessor.ts similarity index 100% rename from plugins/catalog-backend/src/modules/core/AnnotateLocationEntityProcessor.ts rename to plugins/catalog-backend/src/processors/AnnotateLocationEntityProcessor.ts diff --git a/plugins/catalog-backend/src/modules/core/AnnotateScmSlugEntityProcessor.test.ts b/plugins/catalog-backend/src/processors/AnnotateScmSlugEntityProcessor.test.ts similarity index 100% rename from plugins/catalog-backend/src/modules/core/AnnotateScmSlugEntityProcessor.test.ts rename to plugins/catalog-backend/src/processors/AnnotateScmSlugEntityProcessor.test.ts diff --git a/plugins/catalog-backend/src/modules/core/AnnotateScmSlugEntityProcessor.ts b/plugins/catalog-backend/src/processors/AnnotateScmSlugEntityProcessor.ts similarity index 100% rename from plugins/catalog-backend/src/modules/core/AnnotateScmSlugEntityProcessor.ts rename to plugins/catalog-backend/src/processors/AnnotateScmSlugEntityProcessor.ts diff --git a/plugins/catalog-backend/src/modules/core/BuiltinKindsEntityProcessor.test.ts b/plugins/catalog-backend/src/processors/BuiltinKindsEntityProcessor.test.ts similarity index 90% rename from plugins/catalog-backend/src/modules/core/BuiltinKindsEntityProcessor.test.ts rename to plugins/catalog-backend/src/processors/BuiltinKindsEntityProcessor.test.ts index e0368d40a6..8fefb62bfc 100644 --- a/plugins/catalog-backend/src/modules/core/BuiltinKindsEntityProcessor.test.ts +++ b/plugins/catalog-backend/src/processors/BuiltinKindsEntityProcessor.test.ts @@ -46,13 +46,14 @@ describe('BuiltinKindsEntityProcessor', () => { providesApis: ['b'], consumesApis: ['c'], dependsOn: ['Resource:r', 'Component:d'], + dependencyOf: ['Resource:f', 'Component:g'], system: 's', }, }; await processor.postProcessEntity(entity, location, emit); - expect(emit).toHaveBeenCalledTimes(14); + expect(emit).toHaveBeenCalledTimes(18); expect(emit).toHaveBeenCalledWith({ type: 'relation', relation: { @@ -133,6 +134,38 @@ describe('BuiltinKindsEntityProcessor', () => { target: { kind: 'Component', namespace: 'default', name: 'n' }, }, }); + expect(emit).toHaveBeenCalledWith({ + type: 'relation', + relation: { + source: { kind: 'Component', namespace: 'default', name: 'n' }, + type: 'dependencyOf', + target: { kind: 'Resource', namespace: 'default', name: 'f' }, + }, + }); + expect(emit).toHaveBeenCalledWith({ + type: 'relation', + relation: { + source: { kind: 'Resource', namespace: 'default', name: 'f' }, + type: 'dependsOn', + target: { kind: 'Component', namespace: 'default', name: 'n' }, + }, + }); + expect(emit).toHaveBeenCalledWith({ + type: 'relation', + relation: { + source: { kind: 'Component', namespace: 'default', name: 'n' }, + type: 'dependencyOf', + target: { kind: 'Component', namespace: 'default', name: 'g' }, + }, + }); + expect(emit).toHaveBeenCalledWith({ + type: 'relation', + relation: { + source: { kind: 'Component', namespace: 'default', name: 'g' }, + type: 'dependsOn', + target: { kind: 'Component', namespace: 'default', name: 'n' }, + }, + }); expect(emit).toHaveBeenCalledWith({ type: 'relation', relation: { @@ -190,6 +223,29 @@ describe('BuiltinKindsEntityProcessor', () => { ); }); + it('generates an error for component entities with unspecified dependencyOf entity reference kinds', async () => { + const entity: ComponentEntity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { name: 'n' }, + spec: { + type: 'service', + owner: 'o', + subcomponentOf: 's', + lifecycle: 'l', + providesApis: ['b'], + consumesApis: ['c'], + dependencyOf: ['y'], + system: 's', + }, + }; + await expect( + processor.postProcessEntity(entity, location, emit), + ).rejects.toThrow( + 'Entity reference "y" had missing or empty kind (e.g. did not start with "component:" or similar)', + ); + }); + it('generates relations for api entities', async () => { const entity: ApiEntity = { apiVersion: 'backstage.io/v1alpha1', diff --git a/plugins/catalog-backend/src/modules/core/BuiltinKindsEntityProcessor.ts b/plugins/catalog-backend/src/processors/BuiltinKindsEntityProcessor.ts similarity index 97% rename from plugins/catalog-backend/src/modules/core/BuiltinKindsEntityProcessor.ts rename to plugins/catalog-backend/src/processors/BuiltinKindsEntityProcessor.ts index c9ea0dbdc1..fd1195a13a 100644 --- a/plugins/catalog-backend/src/modules/core/BuiltinKindsEntityProcessor.ts +++ b/plugins/catalog-backend/src/processors/BuiltinKindsEntityProcessor.ts @@ -166,6 +166,12 @@ export class BuiltinKindsEntityProcessor implements CatalogProcessor { RELATION_DEPENDS_ON, RELATION_DEPENDENCY_OF, ); + doEmit( + component.spec.dependencyOf, + { defaultNamespace: selfRef.namespace }, + RELATION_DEPENDENCY_OF, + RELATION_DEPENDS_ON, + ); doEmit( component.spec.system, { defaultKind: 'System', defaultNamespace: selfRef.namespace }, diff --git a/plugins/catalog-backend/src/modules/codeowners/CodeOwnersProcessor.test.ts b/plugins/catalog-backend/src/processors/CodeOwnersProcessor.test.ts similarity index 100% rename from plugins/catalog-backend/src/modules/codeowners/CodeOwnersProcessor.test.ts rename to plugins/catalog-backend/src/processors/CodeOwnersProcessor.test.ts diff --git a/plugins/catalog-backend/src/modules/codeowners/CodeOwnersProcessor.ts b/plugins/catalog-backend/src/processors/CodeOwnersProcessor.ts similarity index 98% rename from plugins/catalog-backend/src/modules/codeowners/CodeOwnersProcessor.ts rename to plugins/catalog-backend/src/processors/CodeOwnersProcessor.ts index 9b8d2a3bbf..f6dc27101c 100644 --- a/plugins/catalog-backend/src/modules/codeowners/CodeOwnersProcessor.ts +++ b/plugins/catalog-backend/src/processors/CodeOwnersProcessor.ts @@ -22,7 +22,7 @@ import { } from '@backstage/integration'; import { LocationSpec } from '@backstage/plugin-catalog-common'; import { CatalogProcessor } from '@backstage/plugin-catalog-node'; -import { findCodeOwnerByTarget } from './lib'; +import { findCodeOwnerByTarget } from './codeowners'; import { LoggerService, UrlReaderService } from '@backstage/backend-plugin-api'; const ALLOWED_KINDS = ['API', 'Component', 'Domain', 'Resource', 'System']; diff --git a/plugins/catalog-backend/src/modules/core/FileReaderProcessor.test.ts b/plugins/catalog-backend/src/processors/FileReaderProcessor.test.ts similarity index 100% rename from plugins/catalog-backend/src/modules/core/FileReaderProcessor.test.ts rename to plugins/catalog-backend/src/processors/FileReaderProcessor.test.ts diff --git a/plugins/catalog-backend/src/modules/core/FileReaderProcessor.ts b/plugins/catalog-backend/src/processors/FileReaderProcessor.ts similarity index 100% rename from plugins/catalog-backend/src/modules/core/FileReaderProcessor.ts rename to plugins/catalog-backend/src/processors/FileReaderProcessor.ts diff --git a/plugins/catalog-backend/src/modules/core/LocationEntityProcessor.test.ts b/plugins/catalog-backend/src/processors/LocationEntityProcessor.test.ts similarity index 100% rename from plugins/catalog-backend/src/modules/core/LocationEntityProcessor.test.ts rename to plugins/catalog-backend/src/processors/LocationEntityProcessor.test.ts diff --git a/plugins/catalog-backend/src/modules/core/LocationEntityProcessor.ts b/plugins/catalog-backend/src/processors/LocationEntityProcessor.ts similarity index 100% rename from plugins/catalog-backend/src/modules/core/LocationEntityProcessor.ts rename to plugins/catalog-backend/src/processors/LocationEntityProcessor.ts diff --git a/plugins/catalog-backend/src/modules/core/PlaceholderProcessor.test.ts b/plugins/catalog-backend/src/processors/PlaceholderProcessor.test.ts similarity index 100% rename from plugins/catalog-backend/src/modules/core/PlaceholderProcessor.test.ts rename to plugins/catalog-backend/src/processors/PlaceholderProcessor.test.ts diff --git a/plugins/catalog-backend/src/modules/core/PlaceholderProcessor.ts b/plugins/catalog-backend/src/processors/PlaceholderProcessor.ts similarity index 100% rename from plugins/catalog-backend/src/modules/core/PlaceholderProcessor.ts rename to plugins/catalog-backend/src/processors/PlaceholderProcessor.ts diff --git a/plugins/catalog-backend/src/modules/core/UrlReaderProcessor.test.ts b/plugins/catalog-backend/src/processors/UrlReaderProcessor.test.ts similarity index 99% rename from plugins/catalog-backend/src/modules/core/UrlReaderProcessor.test.ts rename to plugins/catalog-backend/src/processors/UrlReaderProcessor.test.ts index 7e895c5344..545888e7cb 100644 --- a/plugins/catalog-backend/src/modules/core/UrlReaderProcessor.test.ts +++ b/plugins/catalog-backend/src/processors/UrlReaderProcessor.test.ts @@ -149,7 +149,7 @@ describe('UrlReaderProcessor', () => { expect(mockCache.get).toHaveBeenCalledWith('v1'); expect(mockCache.get).toHaveBeenCalledTimes(1); - expect(mockCache.set).toHaveBeenCalledTimes(0); + expect(mockCache.set).toHaveBeenCalledTimes(1); }); it('should fail load from url with error', async () => { diff --git a/plugins/catalog-backend/src/modules/core/UrlReaderProcessor.ts b/plugins/catalog-backend/src/processors/UrlReaderProcessor.ts similarity index 93% rename from plugins/catalog-backend/src/modules/core/UrlReaderProcessor.ts rename to plugins/catalog-backend/src/processors/UrlReaderProcessor.ts index b623098171..e817e19616 100644 --- a/plugins/catalog-backend/src/modules/core/UrlReaderProcessor.ts +++ b/plugins/catalog-backend/src/processors/UrlReaderProcessor.ts @@ -16,7 +16,7 @@ import { Entity } from '@backstage/catalog-model'; import { assertError } from '@backstage/errors'; -import limiterFactory from 'p-limit'; +import limiterFactory, { Limit } from 'p-limit'; import { LocationSpec } from '@backstage/plugin-catalog-common'; import parseGitUrl from 'git-url-parse'; import { @@ -44,12 +44,18 @@ type CacheItem = { /** @public */ export class UrlReaderProcessor implements CatalogProcessor { + // This limiter is used for only consuming a limited number of read streams + // concurrently. + #limiter: Limit; + constructor( private readonly options: { reader: UrlReaderService; logger: LoggerService; }, - ) {} + ) { + this.#limiter = limiterFactory(5); + } getProcessorName() { return 'url-reader'; @@ -105,6 +111,7 @@ export class UrlReaderProcessor implements CatalogProcessor { emit(parseResult); } emit(processingResult.refresh(`${location.type}:${location.target}`)); + await cache.set(CACHE_KEY, cacheItem); } else if (error.name === 'NotFoundError') { if (!optional) { emit(processingResult.notFoundError(location, message)); @@ -126,11 +133,10 @@ export class UrlReaderProcessor implements CatalogProcessor { const { filepath } = parseGitUrl(location); if (filepath?.match(/[*?]/)) { - const limiter = limiterFactory(5); const response = await this.options.reader.search(location, { etag }); const output = response.files.map(async file => ({ url: file.url, - data: await limiter(file.content), + data: await this.#limiter(file.content), })); return { response: await Promise.all(output), etag: response.etag }; } diff --git a/plugins/catalog-backend/src/modules/core/__fixtures__/fileReaderProcessor/awsS3/awsS3-mock-object.txt b/plugins/catalog-backend/src/processors/__fixtures__/fileReaderProcessor/awsS3/awsS3-mock-object.txt similarity index 100% rename from plugins/catalog-backend/src/modules/core/__fixtures__/fileReaderProcessor/awsS3/awsS3-mock-object.txt rename to plugins/catalog-backend/src/processors/__fixtures__/fileReaderProcessor/awsS3/awsS3-mock-object.txt diff --git a/plugins/catalog-backend/src/modules/core/__fixtures__/fileReaderProcessor/component.yaml b/plugins/catalog-backend/src/processors/__fixtures__/fileReaderProcessor/component.yaml similarity index 100% rename from plugins/catalog-backend/src/modules/core/__fixtures__/fileReaderProcessor/component.yaml rename to plugins/catalog-backend/src/processors/__fixtures__/fileReaderProcessor/component.yaml diff --git a/plugins/catalog-backend/src/modules/core/__fixtures__/fileReaderProcessor/dir/api.yaml b/plugins/catalog-backend/src/processors/__fixtures__/fileReaderProcessor/dir/api.yaml similarity index 100% rename from plugins/catalog-backend/src/modules/core/__fixtures__/fileReaderProcessor/dir/api.yaml rename to plugins/catalog-backend/src/processors/__fixtures__/fileReaderProcessor/dir/api.yaml diff --git a/plugins/catalog-backend/src/modules/core/__fixtures__/fileReaderProcessor/test.txt b/plugins/catalog-backend/src/processors/__fixtures__/fileReaderProcessor/test.txt similarity index 100% rename from plugins/catalog-backend/src/modules/core/__fixtures__/fileReaderProcessor/test.txt rename to plugins/catalog-backend/src/processors/__fixtures__/fileReaderProcessor/test.txt diff --git a/plugins/catalog-backend/src/modules/codeowners/lib/index.ts b/plugins/catalog-backend/src/processors/codeowners/index.ts similarity index 100% rename from plugins/catalog-backend/src/modules/codeowners/lib/index.ts rename to plugins/catalog-backend/src/processors/codeowners/index.ts diff --git a/plugins/catalog-backend/src/modules/codeowners/lib/read.test.ts b/plugins/catalog-backend/src/processors/codeowners/read.test.ts similarity index 100% rename from plugins/catalog-backend/src/modules/codeowners/lib/read.test.ts rename to plugins/catalog-backend/src/processors/codeowners/read.test.ts diff --git a/plugins/catalog-backend/src/modules/codeowners/lib/read.ts b/plugins/catalog-backend/src/processors/codeowners/read.ts similarity index 100% rename from plugins/catalog-backend/src/modules/codeowners/lib/read.ts rename to plugins/catalog-backend/src/processors/codeowners/read.ts diff --git a/plugins/catalog-backend/src/modules/codeowners/lib/resolve.test.ts b/plugins/catalog-backend/src/processors/codeowners/resolve.test.ts similarity index 100% rename from plugins/catalog-backend/src/modules/codeowners/lib/resolve.test.ts rename to plugins/catalog-backend/src/processors/codeowners/resolve.test.ts diff --git a/plugins/catalog-backend/src/modules/codeowners/lib/resolve.ts b/plugins/catalog-backend/src/processors/codeowners/resolve.ts similarity index 100% rename from plugins/catalog-backend/src/modules/codeowners/lib/resolve.ts rename to plugins/catalog-backend/src/processors/codeowners/resolve.ts diff --git a/plugins/catalog-backend/src/modules/codeowners/lib/scm.ts b/plugins/catalog-backend/src/processors/codeowners/scm.ts similarity index 100% rename from plugins/catalog-backend/src/modules/codeowners/lib/scm.ts rename to plugins/catalog-backend/src/processors/codeowners/scm.ts diff --git a/plugins/catalog-backend/src/modules/core/index.ts b/plugins/catalog-backend/src/processors/index.ts similarity index 92% rename from plugins/catalog-backend/src/modules/core/index.ts rename to plugins/catalog-backend/src/processors/index.ts index e410c3824d..ee2204f20f 100644 --- a/plugins/catalog-backend/src/modules/core/index.ts +++ b/plugins/catalog-backend/src/processors/index.ts @@ -1,5 +1,5 @@ /* - * Copyright 2020 The Backstage Authors + * 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. @@ -17,11 +17,11 @@ export { AnnotateLocationEntityProcessor } from './AnnotateLocationEntityProcessor'; export { AnnotateScmSlugEntityProcessor } from './AnnotateScmSlugEntityProcessor'; export { BuiltinKindsEntityProcessor } from './BuiltinKindsEntityProcessor'; +export { CodeOwnersProcessor } from './CodeOwnersProcessor'; export { FileReaderProcessor } from './FileReaderProcessor'; export { LocationEntityProcessor } from './LocationEntityProcessor'; export type { LocationEntityProcessorOptions } from './LocationEntityProcessor'; export { PlaceholderProcessor } from './PlaceholderProcessor'; export type { PlaceholderProcessorOptions } from './PlaceholderProcessor'; export { UrlReaderProcessor } from './UrlReaderProcessor'; -export { parseEntityYaml } from '../util/parse'; export { transformLegacyPolicyToProcessor } from './transformLegacyPolicyToProcessor'; diff --git a/plugins/catalog-backend/src/modules/core/transformLegacyPolicyToProcessor.test.ts b/plugins/catalog-backend/src/processors/transformLegacyPolicyToProcessor.test.ts similarity index 100% rename from plugins/catalog-backend/src/modules/core/transformLegacyPolicyToProcessor.test.ts rename to plugins/catalog-backend/src/processors/transformLegacyPolicyToProcessor.test.ts diff --git a/plugins/catalog-backend/src/modules/core/transformLegacyPolicyToProcessor.ts b/plugins/catalog-backend/src/processors/transformLegacyPolicyToProcessor.ts similarity index 100% rename from plugins/catalog-backend/src/modules/core/transformLegacyPolicyToProcessor.ts rename to plugins/catalog-backend/src/processors/transformLegacyPolicyToProcessor.ts diff --git a/plugins/catalog-backend/src/modules/core/ConfigLocationEntityProvider.test.ts b/plugins/catalog-backend/src/providers/ConfigLocationEntityProvider.test.ts similarity index 100% rename from plugins/catalog-backend/src/modules/core/ConfigLocationEntityProvider.test.ts rename to plugins/catalog-backend/src/providers/ConfigLocationEntityProvider.test.ts diff --git a/plugins/catalog-backend/src/modules/core/ConfigLocationEntityProvider.ts b/plugins/catalog-backend/src/providers/ConfigLocationEntityProvider.ts similarity index 94% rename from plugins/catalog-backend/src/modules/core/ConfigLocationEntityProvider.ts rename to plugins/catalog-backend/src/providers/ConfigLocationEntityProvider.ts index 38f02195f3..9273beaf7f 100644 --- a/plugins/catalog-backend/src/modules/core/ConfigLocationEntityProvider.ts +++ b/plugins/catalog-backend/src/providers/ConfigLocationEntityProvider.ts @@ -16,12 +16,12 @@ import { Config } from '@backstage/config'; import path from 'path'; -import { getEntityLocationRef } from '../../processing/util'; +import { getEntityLocationRef } from '../processing/util'; import { EntityProvider, EntityProviderConnection, } from '@backstage/plugin-catalog-node'; -import { locationSpecToLocationEntity } from '../../util/conversion'; +import { locationSpecToLocationEntity } from '../util/conversion'; export class ConfigLocationEntityProvider implements EntityProvider { constructor(private readonly config: Config) {} diff --git a/plugins/catalog-backend/src/modules/core/DefaultLocationStore.test.ts b/plugins/catalog-backend/src/providers/DefaultLocationStore.test.ts similarity index 98% rename from plugins/catalog-backend/src/modules/core/DefaultLocationStore.test.ts rename to plugins/catalog-backend/src/providers/DefaultLocationStore.test.ts index dafd6e13d8..4f302308ae 100644 --- a/plugins/catalog-backend/src/modules/core/DefaultLocationStore.test.ts +++ b/plugins/catalog-backend/src/providers/DefaultLocationStore.test.ts @@ -17,13 +17,13 @@ import { TestDatabaseId, TestDatabases } from '@backstage/backend-test-utils'; import { ANNOTATION_ORIGIN_LOCATION } from '@backstage/catalog-model'; import { v4 as uuid } from 'uuid'; -import { applyDatabaseMigrations } from '../../database/migrations'; +import { applyDatabaseMigrations } from '../database/migrations'; import { DbFinalEntitiesRow, DbLocationsRow, DbRefreshStateRow, DbSearchRow, -} from '../../database/tables'; +} from '../database/tables'; import { DefaultLocationStore } from './DefaultLocationStore'; jest.setTimeout(60_000); diff --git a/plugins/catalog-backend/src/modules/core/DefaultLocationStore.ts b/plugins/catalog-backend/src/providers/DefaultLocationStore.ts similarity index 96% rename from plugins/catalog-backend/src/modules/core/DefaultLocationStore.ts rename to plugins/catalog-backend/src/providers/DefaultLocationStore.ts index fcf576b93e..2b3459ecb1 100644 --- a/plugins/catalog-backend/src/modules/core/DefaultLocationStore.ts +++ b/plugins/catalog-backend/src/providers/DefaultLocationStore.ts @@ -22,14 +22,14 @@ import { DbLocationsRow, DbRefreshStateRow, DbSearchRow, -} from '../../database/tables'; -import { getEntityLocationRef } from '../../processing/util'; +} from '../database/tables'; +import { getEntityLocationRef } from '../processing/util'; import { EntityProvider, EntityProviderConnection, } from '@backstage/plugin-catalog-node'; -import { locationSpecToLocationEntity } from '../../util/conversion'; -import { LocationInput, LocationStore } from '../../service/types'; +import { locationSpecToLocationEntity } from '../util/conversion'; +import { LocationInput, LocationStore } from '../service/types'; import { ANNOTATION_ORIGIN_LOCATION, CompoundEntityRef, diff --git a/plugins/catalog-backend/src/schema/openapi.generated.ts b/plugins/catalog-backend/src/schema/openapi.generated.ts index 550db58f2e..f3bd46c05c 100644 --- a/plugins/catalog-backend/src/schema/openapi.generated.ts +++ b/plugins/catalog-backend/src/schema/openapi.generated.ts @@ -1149,6 +1149,9 @@ export const spec = { { $ref: '#/components/parameters/limit', }, + { + $ref: '#/components/parameters/offset', + }, { $ref: '#/components/parameters/orderField', }, diff --git a/plugins/catalog-backend/src/schema/openapi.yaml b/plugins/catalog-backend/src/schema/openapi.yaml index 75dc1d9bbc..b02f561bc3 100644 --- a/plugins/catalog-backend/src/schema/openapi.yaml +++ b/plugins/catalog-backend/src/schema/openapi.yaml @@ -885,6 +885,7 @@ paths: parameters: - $ref: '#/components/parameters/fields' - $ref: '#/components/parameters/limit' + - $ref: '#/components/parameters/offset' - $ref: '#/components/parameters/orderField' - $ref: '#/components/parameters/cursor' - $ref: '#/components/parameters/filter' diff --git a/plugins/catalog-backend/src/service/AuthorizedLocationAnalyzer.test.ts b/plugins/catalog-backend/src/service/AuthorizedLocationAnalyzer.test.ts new file mode 100644 index 0000000000..1583049080 --- /dev/null +++ b/plugins/catalog-backend/src/service/AuthorizedLocationAnalyzer.test.ts @@ -0,0 +1,86 @@ +/* + * 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 { NotAllowedError } from '@backstage/errors'; +import { AuthorizeResult } from '@backstage/plugin-permission-common'; +import { AuthorizedLocationAnalyzer } from './AuthorizedLocationAnalyzer'; +import { ServerPermissionClient } from '@backstage/plugin-permission-node'; +import { mockCredentials } from '@backstage/backend-test-utils'; + +describe('AuthorizedLocationAnalyzer', () => { + const locationAnalyzerService = { + analyzeLocation: jest.fn(), + }; + const permissionApi = { + authorize: jest.fn(), + }; + + afterEach(() => { + jest.clearAllMocks(); + }); + + it('throws Authorization Error on deny', async () => { + permissionApi.authorize.mockResolvedValueOnce([ + { + result: AuthorizeResult.DENY, + }, + ]); + const authorizedService = new AuthorizedLocationAnalyzer( + locationAnalyzerService, + permissionApi as unknown as ServerPermissionClient, + ); + await expect(() => + authorizedService.analyzeLocation( + { + location: { + type: 'url', + target: 'https://example.com/path/to/your/catalog-info.yaml', + presence: 'required', + }, + catalogFilename: 'catalog-info.yaml', + }, + mockCredentials.none(), + ), + ).rejects.toThrow(NotAllowedError); + }); + + it('calls analyzeLocation on allow', async () => { + permissionApi.authorize.mockResolvedValueOnce([ + { + result: AuthorizeResult.ALLOW, + }, + ]); + const authorizedService = new AuthorizedLocationAnalyzer( + locationAnalyzerService, + permissionApi as unknown as ServerPermissionClient, + ); + const analyzeLocationRequest = { + location: { + type: 'url', + target: 'https://example.com/path/to/your/catalog-info.yaml', + }, + catalogFilename: 'catalog-info.yaml', + }; + await authorizedService.analyzeLocation( + analyzeLocationRequest, + mockCredentials.none(), + ); + expect(locationAnalyzerService.analyzeLocation).toHaveBeenCalledWith( + analyzeLocationRequest, + mockCredentials.none(), + ); + }); +}); diff --git a/plugins/catalog-backend/src/service/AuthorizedLocationAnalyzer.ts b/plugins/catalog-backend/src/service/AuthorizedLocationAnalyzer.ts new file mode 100644 index 0000000000..dc9af81dcd --- /dev/null +++ b/plugins/catalog-backend/src/service/AuthorizedLocationAnalyzer.ts @@ -0,0 +1,53 @@ +/* + * 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 { NotAllowedError } from '@backstage/errors'; +import { catalogLocationAnalyzePermission } from '@backstage/plugin-catalog-common/alpha'; +import { AuthorizeResult } from '@backstage/plugin-permission-common'; +import { + BackstageCredentials, + PermissionsService, +} from '@backstage/backend-plugin-api'; +import { LocationAnalyzer } from '@backstage/plugin-catalog-node'; +import { AnalyzeLocationRequest } from '@backstage/plugin-catalog-common'; +import { AnalyzeLocationResponse } from '@backstage/plugin-catalog-common'; + +export class AuthorizedLocationAnalyzer implements LocationAnalyzer { + constructor( + private readonly service: LocationAnalyzer, + private readonly permissionApi: PermissionsService, + ) {} + + async analyzeLocation( + request: AnalyzeLocationRequest, + credentials: BackstageCredentials, + ): Promise { + const authorizeDecision = ( + await this.permissionApi.authorize( + [ + { + permission: catalogLocationAnalyzePermission, + }, + ], + { credentials: credentials }, + ) + )[0]; + if (authorizeDecision.result !== AuthorizeResult.ALLOW) { + throw new NotAllowedError(); + } + return this.service.analyzeLocation(request, credentials); + } +} diff --git a/plugins/catalog-backend/src/service/AuthorizedValidationService.test.ts b/plugins/catalog-backend/src/service/AuthorizedValidationService.test.ts new file mode 100644 index 0000000000..1e4f74a97b --- /dev/null +++ b/plugins/catalog-backend/src/service/AuthorizedValidationService.test.ts @@ -0,0 +1,101 @@ +/* + * 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 { NotAllowedError } from '@backstage/errors'; +import { AuthorizeResult } from '@backstage/plugin-permission-common'; +import { ServerPermissionClient } from '@backstage/plugin-permission-node'; +import { mockCredentials } from '@backstage/backend-test-utils'; +import { AuthorizedValidationService } from './AuthorizedValidationService'; + +describe('AuthorizedValidationService', () => { + const orchestratorService = { + process: jest.fn(), + }; + const permissionApi = { + authorize: jest.fn(), + }; + + afterEach(() => { + jest.clearAllMocks(); + }); + + it('throws Authorization Error on deny', async () => { + permissionApi.authorize.mockResolvedValueOnce([ + { + result: AuthorizeResult.DENY, + }, + ]); + const authorizedService = new AuthorizedValidationService( + orchestratorService, + permissionApi as unknown as ServerPermissionClient, + ); + const entityProcessingRequest = { + entity: { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + name: 'your-entity-name', + namespace: 'default', + description: 'your-entity-description', + }, + spec: { + type: 'service', + owner: 'team-a', + }, + }, + }; + await expect(() => + authorizedService.process( + entityProcessingRequest, + mockCredentials.none(), + ), + ).rejects.toThrow(NotAllowedError); + }); + + it('calls process on allow', async () => { + permissionApi.authorize.mockResolvedValueOnce([ + { + result: AuthorizeResult.ALLOW, + }, + ]); + const authorizedService = new AuthorizedValidationService( + orchestratorService, + permissionApi as unknown as ServerPermissionClient, + ); + const entityProcessingRequest = { + entity: { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + name: 'your-entity-name', + namespace: 'default', + description: 'your-entity-description', + }, + spec: { + type: 'service', + owner: 'team-a', + }, + }, + }; + await authorizedService.process( + entityProcessingRequest, + mockCredentials.none(), + ); + expect(orchestratorService.process).toHaveBeenCalledWith( + entityProcessingRequest, + ); + }); +}); diff --git a/plugins/catalog-backend/src/service/AuthorizedValidationService.ts b/plugins/catalog-backend/src/service/AuthorizedValidationService.ts new file mode 100644 index 0000000000..870368c9ee --- /dev/null +++ b/plugins/catalog-backend/src/service/AuthorizedValidationService.ts @@ -0,0 +1,55 @@ +/* + * 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 { NotAllowedError } from '@backstage/errors'; +import { catalogEntityValidatePermission } from '@backstage/plugin-catalog-common/alpha'; +import { AuthorizeResult } from '@backstage/plugin-permission-common'; +import { + CatalogProcessingOrchestrator, + EntityProcessingRequest, + EntityProcessingResult, +} from '../processing/types'; +import { + BackstageCredentials, + PermissionsService, +} from '@backstage/backend-plugin-api'; + +export class AuthorizedValidationService { + constructor( + private readonly service: CatalogProcessingOrchestrator, + private readonly permissionApi: PermissionsService, + ) {} + + async process( + request: EntityProcessingRequest, + credentials: BackstageCredentials, + ): Promise { + const authorizeDecision = ( + await this.permissionApi.authorize( + [ + { + permission: catalogEntityValidatePermission, + }, + ], + { credentials }, + ) + )[0]; + + if (authorizeDecision.result !== AuthorizeResult.ALLOW) { + throw new NotAllowedError(); + } + return this.service.process(request); + } +} diff --git a/plugins/catalog-backend/src/service/CatalogBuilder.ts b/plugins/catalog-backend/src/service/CatalogBuilder.ts index 8f020c8c7c..c404bfaa0d 100644 --- a/plugins/catalog-backend/src/service/CatalogBuilder.ts +++ b/plugins/catalog-backend/src/service/CatalogBuilder.ts @@ -52,16 +52,17 @@ import { FileReaderProcessor, PlaceholderProcessor, UrlReaderProcessor, -} from '../modules'; -import { ConfigLocationEntityProvider } from '../modules/core/ConfigLocationEntityProvider'; -import { DefaultLocationStore } from '../modules/core/DefaultLocationStore'; +} from '../processors'; +import { ConfigLocationEntityProvider } from '../providers/ConfigLocationEntityProvider'; +import { DefaultLocationStore } from '../providers/DefaultLocationStore'; import { RepoLocationAnalyzer } from '../ingestion/LocationAnalyzer'; +import { AuthorizedLocationAnalyzer } from './AuthorizedLocationAnalyzer'; import { jsonPlaceholderResolver, textPlaceholderResolver, yamlPlaceholderResolver, -} from '../modules/core/PlaceholderProcessor'; -import { defaultEntityDataParser } from '../modules/util/parse'; +} from '../processors/PlaceholderProcessor'; +import { defaultEntityDataParser } from '../util/parse'; import { CatalogProcessingEngine, createRandomProcessingInterval, @@ -515,15 +516,7 @@ export class CatalogBuilder { }); const integrations = ScmIntegrations.fromConfig(config); const rulesEnforcer = DefaultCatalogRulesEnforcer.fromConfig(config); - const orchestrator = new DefaultCatalogProcessingOrchestrator({ - processors, - integrations, - rulesEnforcer, - logger, - parser, - policy, - legacySingleProcessorValidation: this.legacySingleProcessorValidation, - }); + const unauthorizedEntitiesCatalog = new DefaultEntitiesCatalog({ database: dbClient, logger, @@ -540,6 +533,16 @@ export class CatalogBuilder { permissionsService = toPermissionEvaluator(permissions); } + const orchestrator = new DefaultCatalogProcessingOrchestrator({ + processors, + integrations, + rulesEnforcer, + logger, + parser, + policy, + legacySingleProcessorValidation: this.legacySingleProcessorValidation, + }); + const entitiesCatalog = new AuthorizedEntitiesCatalog( unauthorizedEntitiesCatalog, permissionsService, @@ -599,7 +602,10 @@ export class CatalogBuilder { const locationAnalyzer = this.locationAnalyzer ?? - new RepoLocationAnalyzer(logger, integrations, this.locationAnalyzers); + new AuthorizedLocationAnalyzer( + new RepoLocationAnalyzer(logger, integrations, this.locationAnalyzers), + permissionsService, + ); const locationService = new AuthorizedLocationService( new DefaultLocationService(locationStore, orchestrator, { allowedLocationTypes: this.allowedLocationType, @@ -622,6 +628,7 @@ export class CatalogBuilder { permissionIntegrationRouter, auth, httpAuth, + permissionsService, }); await connectEntityProviders(providerDatabase, entityProviders); diff --git a/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.ts b/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.ts index f9f731e3e4..c71f242969 100644 --- a/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.ts +++ b/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.ts @@ -495,6 +495,12 @@ export class DefaultEntitiesCatalog implements EntitiesCatalog { ]); } + if ( + isQueryEntitiesInitialRequest(request) && + request.offset !== undefined + ) { + dbQuery.offset(request.offset); + } // fetch an extra item to check if there are more items. dbQuery.limit(isFetchingBackwards ? limit : limit + 1); diff --git a/plugins/catalog-backend/src/service/createRouter.test.ts b/plugins/catalog-backend/src/service/createRouter.test.ts index 5687bc1f85..9cc0717807 100644 --- a/plugins/catalog-backend/src/service/createRouter.test.ts +++ b/plugins/catalog-backend/src/service/createRouter.test.ts @@ -42,6 +42,7 @@ import { wrapInOpenApiTestServer } from '@backstage/backend-openapi-utils'; import { Server } from 'http'; import { mockCredentials, mockServices } from '@backstage/backend-test-utils'; import { LocationAnalyzer } from '@backstage/plugin-catalog-node'; +import { PermissionsService } from '@backstage/backend-plugin-api'; describe('createRouter readonly disabled', () => { let entitiesCatalog: jest.Mocked; @@ -50,6 +51,7 @@ describe('createRouter readonly disabled', () => { let app: express.Express | Server; let refreshService: RefreshService; let locationAnalyzer: jest.Mocked; + let permissionsService: jest.Mocked; beforeAll(async () => { entitiesCatalog = { @@ -71,6 +73,11 @@ describe('createRouter readonly disabled', () => { locationAnalyzer = { analyzeLocation: jest.fn(), }; + permissionsService = { + authorize: jest.fn(), + authorizeConditional: jest.fn(), + }; + refreshService = { refresh: jest.fn() }; orchestrator = { process: jest.fn() }; const router = await createRouter({ @@ -84,6 +91,7 @@ describe('createRouter readonly disabled', () => { auth: mockServices.auth(), httpAuth: mockServices.httpAuth(), locationAnalyzer, + permissionsService: permissionsService, }); app = wrapInOpenApiTestServer(express().use(router)); }); @@ -725,6 +733,12 @@ describe('createRouter readonly disabled', () => { metadata: { name: 'n' }, }; + permissionsService.authorize.mockResolvedValueOnce([ + { + result: AuthorizeResult.ALLOW, + }, + ]); + orchestrator.process.mockResolvedValueOnce({ ok: true, state: {}, @@ -765,6 +779,12 @@ describe('createRouter readonly disabled', () => { metadata: { name: 'invalid*name' }, }; + permissionsService.authorize.mockResolvedValueOnce([ + { + result: AuthorizeResult.ALLOW, + }, + ]); + orchestrator.process.mockResolvedValueOnce({ ok: false, errors: [new Error('Invalid entity name')], @@ -802,6 +822,12 @@ describe('createRouter readonly disabled', () => { metadata: { name: 'n' }, }; + permissionsService.authorize.mockResolvedValueOnce([ + { + result: AuthorizeResult.ALLOW, + }, + ]); + const response = await request(app) .post('/validate-entity') .send({ entity, location: null }); @@ -848,6 +874,7 @@ describe('createRouter readonly enabled', () => { let entitiesCatalog: jest.Mocked; let app: express.Express; let locationService: jest.Mocked; + let permissionsService: jest.Mocked; beforeAll(async () => { entitiesCatalog = { @@ -877,6 +904,7 @@ describe('createRouter readonly enabled', () => { permissionIntegrationRouter: express.Router(), auth: mockServices.auth(), httpAuth: mockServices.httpAuth(), + permissionsService: permissionsService, }); app = express().use(router); }); @@ -1046,6 +1074,7 @@ describe('NextRouter permissioning', () => { let locationService: jest.Mocked; let app: express.Express; let refreshService: RefreshService; + let permissionsService: jest.Mocked; const fakeRule = createPermissionRule({ name: 'FAKE_RULE', @@ -1092,6 +1121,7 @@ describe('NextRouter permissioning', () => { }), auth: mockServices.auth(), httpAuth: mockServices.httpAuth(), + permissionsService: permissionsService, }); app = express().use(router); }); diff --git a/plugins/catalog-backend/src/service/createRouter.ts b/plugins/catalog-backend/src/service/createRouter.ts index 8207db879d..4a89cfc6cb 100644 --- a/plugins/catalog-backend/src/service/createRouter.ts +++ b/plugins/catalog-backend/src/service/createRouter.ts @@ -53,8 +53,10 @@ import { HttpAuthService, LoggerService, SchedulerService, + PermissionsService, } from '@backstage/backend-plugin-api'; import { LocationAnalyzer } from '@backstage/plugin-catalog-node'; +import { AuthorizedValidationService } from './AuthorizedValidationService'; /** * Options used by {@link createRouter}. @@ -74,6 +76,7 @@ export interface RouterOptions { permissionIntegrationRouter?: express.Router; auth: AuthService; httpAuth: HttpAuthService; + permissionsService: PermissionsService; } /** @@ -98,6 +101,7 @@ export async function createRouter( config, logger, permissionIntegrationRouter, + permissionsService, auth, httpAuth, } = options; @@ -154,6 +158,7 @@ export async function createRouter( const { items, pageInfo, totalItems } = await entitiesCatalog.queryEntities({ limit: req.query.limit, + offset: req.query.offset, ...parseQueryEntitiesParams(req.query), credentials: await httpAuth.credentials(req), }); @@ -300,9 +305,13 @@ export async function createRouter( location: locationInput, catalogFilename: z.string().optional(), }); + const credentials = await httpAuth.credentials(req); const parsedBody = schema.parse(body); try { - const output = await locationAnalyzer.analyzeLocation(parsedBody); + const output = await locationAnalyzer.analyzeLocation( + parsedBody, + credentials, + ); res.status(200).json(output); } catch (err) { if ( @@ -341,19 +350,27 @@ export async function createRouter( }); } - const processingResult = await orchestrator.process({ - entity: { - ...entity, - metadata: { - ...entity.metadata, - annotations: { - [ANNOTATION_LOCATION]: body.location, - [ANNOTATION_ORIGIN_LOCATION]: body.location, - ...entity.metadata.annotations, + const credentials = await httpAuth.credentials(req); + const authorizedValidationService = new AuthorizedValidationService( + orchestrator, + permissionsService, + ); + const processingResult = await authorizedValidationService.process( + { + entity: { + ...entity, + metadata: { + ...entity.metadata, + annotations: { + [ANNOTATION_LOCATION]: body.location, + [ANNOTATION_ORIGIN_LOCATION]: body.location, + ...entity.metadata.annotations, + }, }, }, }, - }); + credentials, + ); if (!processingResult.ok) res.status(400).json({ diff --git a/plugins/catalog-backend/src/service/request/parseEntityFilterParams.ts b/plugins/catalog-backend/src/service/request/parseEntityFilterParams.ts index cfd9aa0aa5..8666712f80 100644 --- a/plugins/catalog-backend/src/service/request/parseEntityFilterParams.ts +++ b/plugins/catalog-backend/src/service/request/parseEntityFilterParams.ts @@ -60,7 +60,7 @@ export function parseEntityFilterString( return undefined; } - const filtersByKey: Record = {}; + const filtersByKey = new Map(); for (const statement of statements) { const equalsIndex = statement.indexOf('='); @@ -79,8 +79,11 @@ export function parseEntityFilterString( ); } - const f = - key in filtersByKey ? filtersByKey[key] : (filtersByKey[key] = { key }); + let f = filtersByKey.get(key); + if (!f) { + f = { key }; + filtersByKey.set(key, f); + } if (value !== undefined) { f.values = f.values || []; @@ -88,5 +91,5 @@ export function parseEntityFilterString( } } - return Object.values(filtersByKey); + return Array.from(filtersByKey.values()); } diff --git a/plugins/catalog-backend/src/tests/integration.test.ts b/plugins/catalog-backend/src/tests/integration.test.ts index 0c07b0fd4d..d278fb4f0a 100644 --- a/plugins/catalog-backend/src/tests/integration.test.ts +++ b/plugins/catalog-backend/src/tests/integration.test.ts @@ -40,7 +40,7 @@ import { DefaultProviderDatabase } from '../database/DefaultProviderDatabase'; import { applyDatabaseMigrations } from '../database/migrations'; import { RefreshStateItem } from '../database/types'; import { DefaultCatalogRulesEnforcer } from '../ingestion/CatalogRules'; -import { defaultEntityDataParser } from '../modules/util/parse'; +import { defaultEntityDataParser } from '../util/parse'; import { DefaultCatalogProcessingEngine, ProgressTracker, diff --git a/plugins/catalog-backend/src/tests/performance/getEntitiesPerformance.test.ts b/plugins/catalog-backend/src/tests/performance/getEntitiesPerformance.test.ts new file mode 100644 index 0000000000..47fd664b71 --- /dev/null +++ b/plugins/catalog-backend/src/tests/performance/getEntitiesPerformance.test.ts @@ -0,0 +1,146 @@ +/* + * 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 { describePerformanceTest, performanceTraceEnabled } from './lib/env'; +import { startTestBackend, TestDatabases } from '@backstage/backend-test-utils'; +import { applyDatabaseMigrations } from '../../database/migrations'; +import { + SyntheticLoadEntitiesProcessor, + SyntheticLoadEntitiesProvider, + SyntheticLoadOptions, +} from './lib/catalogModuleSyntheticLoadEntities'; +import { CatalogClient } from '@backstage/catalog-client'; +import { + coreServices, + createBackendModule, + createServiceFactory, +} from '@backstage/backend-plugin-api'; +import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha'; +import { Knex } from 'knex'; + +jest.setTimeout(600_000); + +const traceLog: typeof console.log = performanceTraceEnabled + ? console.log + : () => {}; + +const completionPolling = async (load: SyntheticLoadOptions, knex: Knex) => { + const { baseEntitiesCount, childrenCount } = load; + const expectedTotal = baseEntitiesCount + baseEntitiesCount * childrenCount; + + return new Promise((resolve, reject) => { + const interval = setInterval(async () => { + try { + const stitchedCount = await knex('final_entities') + .count({ count: '*' }) + .whereNotNull('final_entity') + .then(rows => Number(rows[0].count)); + + if (stitchedCount === expectedTotal) { + clearInterval(interval); + resolve(); + } + } catch (error) { + clearInterval(interval); + reject(error); + } + }, 1000); + }); +}; + +describePerformanceTest('getEntitiesPerformanceTest', () => { + const databases = TestDatabases.create({ + ids: [/* 'MYSQL_8', */ 'POSTGRES_16', /* 'POSTGRES_12',*/ 'SQLITE_3'], + disableDocker: false, + }); + + it.each(databases.eachSupportedId())( + 'fetch entities, %p', + async databaseId => { + const knex = await databases.init(databaseId); + await applyDatabaseMigrations(knex); + + const load: SyntheticLoadOptions = { + baseEntitiesCount: 2000, + baseRelationsCount: 3, + baseRelationsSkew: 0.3, + childrenCount: 3, + }; + + traceLog('Starting test backend'); + + const backend = await startTestBackend({ + features: [ + import('@backstage/plugin-catalog-backend/alpha'), + createServiceFactory({ + service: coreServices.database, + deps: {}, + factory: () => ({ getClient: async () => knex }), + }), + createBackendModule({ + pluginId: 'catalog', + moduleId: 'synthetic-load-entities', + register(reg) { + reg.registerInit({ + deps: { + catalog: catalogProcessingExtensionPoint, + }, + async init({ catalog }) { + catalog.addEntityProvider( + new SyntheticLoadEntitiesProvider(load, {}), + ); + catalog.addProcessor( + new SyntheticLoadEntitiesProcessor(load), + ); + }, + }); + }, + }), + ], + }); + + const expectedTotal = + load.baseEntitiesCount + load.baseEntitiesCount * load.childrenCount; + traceLog(`Waiting for completion polling of ${expectedTotal} entities`); + + await expect(completionPolling(load, knex)).resolves.toBeUndefined(); + + const client = new CatalogClient({ + discoveryApi: { + getBaseUrl: jest + .fn() + .mockResolvedValue( + `http://localhost:${backend.server.port()}/api/catalog`, + ), + }, + }); + const start = Date.now(); + traceLog(`[${databaseId}] Starting to fetch ${expectedTotal} entities`); + + // Fetch all entities + const response = await client.getEntities(); + expect(response.items).toHaveLength(expectedTotal); + + const fetchDuration = Date.now() - start; + traceLog( + `[${databaseId}] Fetched ${expectedTotal} entities in ${fetchDuration}ms`, + ); + + await backend.stop(); + await knex.destroy(); + }, + ); +}); diff --git a/plugins/catalog-backend/src/tests/performance/lib/env.ts b/plugins/catalog-backend/src/tests/performance/lib/env.ts index c272930292..a1b4e72260 100644 --- a/plugins/catalog-backend/src/tests/performance/lib/env.ts +++ b/plugins/catalog-backend/src/tests/performance/lib/env.ts @@ -14,9 +14,16 @@ * limitations under the License. */ -export const performanceTraceEnabled = !!process.env.PERFORMANCE_TRACE; +import yn from 'yn'; -export const describePerformanceTest: jest.Describe = process.env - .PERFORMANCE_TEST +export const performanceTraceEnabled = yn(process.env.PERFORMANCE_TRACE, { + default: false, +}); + +export const performanceTestEnabled = yn(process.env.PERFORMANCE_TEST, { + default: false, +}); + +export const describePerformanceTest: jest.Describe = performanceTestEnabled ? describe : describe.skip; diff --git a/packages/backend-common/src/alpha.ts b/plugins/catalog-backend/src/util/index.ts similarity index 87% rename from packages/backend-common/src/alpha.ts rename to plugins/catalog-backend/src/util/index.ts index 0fd15459fe..b0e291ac60 100644 --- a/packages/backend-common/src/alpha.ts +++ b/plugins/catalog-backend/src/util/index.ts @@ -1,5 +1,5 @@ /* - * Copyright 2023 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. @@ -14,4 +14,4 @@ * limitations under the License. */ -export * from './deprecated/context'; +export { parseEntityYaml } from './parse'; diff --git a/plugins/catalog-backend/src/modules/util/parse.test.ts b/plugins/catalog-backend/src/util/parse.test.ts similarity index 100% rename from plugins/catalog-backend/src/modules/util/parse.test.ts rename to plugins/catalog-backend/src/util/parse.test.ts diff --git a/plugins/catalog-backend/src/modules/util/parse.ts b/plugins/catalog-backend/src/util/parse.ts similarity index 100% rename from plugins/catalog-backend/src/modules/util/parse.ts rename to plugins/catalog-backend/src/util/parse.ts diff --git a/plugins/catalog-common/CHANGELOG.md b/plugins/catalog-common/CHANGELOG.md index f15f53aef4..ca71821feb 100644 --- a/plugins/catalog-common/CHANGELOG.md +++ b/plugins/catalog-common/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-catalog-common +## 1.1.0 + +### Minor Changes + +- bd35cdb: The `analyze-location` endpoint is now protected by the `catalog.location.analyze` permission. + The `validate-entity` endpoint is now protected by the `catalog.entity.validate` permission. + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-common@1.2.14 + ## 1.0.26 ### Patch Changes diff --git a/plugins/catalog-common/package.json b/plugins/catalog-common/package.json index b9917b9d35..6e69dd0ef8 100644 --- a/plugins/catalog-common/package.json +++ b/plugins/catalog-common/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-common", - "version": "1.0.26", + "version": "1.1.0", "description": "Common functionalities for the catalog plugin", "backstage": { "role": "common-library", diff --git a/plugins/catalog-common/api-report-alpha.md b/plugins/catalog-common/report-alpha.api.md similarity index 89% rename from plugins/catalog-common/api-report-alpha.md rename to plugins/catalog-common/report-alpha.api.md index 12e0806a9c..86e606dd84 100644 --- a/plugins/catalog-common/api-report-alpha.md +++ b/plugins/catalog-common/report-alpha.api.md @@ -23,6 +23,12 @@ export const catalogEntityReadPermission: ResourcePermission<'catalog-entity'>; // @alpha export const catalogEntityRefreshPermission: ResourcePermission<'catalog-entity'>; +// @alpha +export const catalogEntityValidatePermission: BasicPermission; + +// @alpha +export const catalogLocationAnalyzePermission: BasicPermission; + // @alpha export const catalogLocationCreatePermission: BasicPermission; diff --git a/plugins/catalog-common/api-report.md b/plugins/catalog-common/report.api.md similarity index 60% rename from plugins/catalog-common/api-report.md rename to plugins/catalog-common/report.api.md index 231c8aac34..95b1d9b6c6 100644 --- a/plugins/catalog-common/api-report.md +++ b/plugins/catalog-common/report.api.md @@ -64,4 +64,16 @@ export type LocationSpec = { target: string; presence?: 'optional' | 'required'; }; + +// Warnings were encountered during analysis: +// +// src/ingestion/LocationAnalyzer.d.ts:5:1 - (ae-undocumented) Missing documentation for "AnalyzeLocationRequest". +// src/ingestion/LocationAnalyzer.d.ts:10:1 - (ae-undocumented) Missing documentation for "AnalyzeLocationResponse". +// src/ingestion/LocationAnalyzer.d.ts:39:1 - (ae-undocumented) Missing documentation for "AnalyzeLocationEntityField". +// src/search/CatalogEntityDocument.d.ts:9:5 - (ae-undocumented) Missing documentation for "componentType". +// src/search/CatalogEntityDocument.d.ts:10:5 - (ae-undocumented) Missing documentation for "type". +// src/search/CatalogEntityDocument.d.ts:11:5 - (ae-undocumented) Missing documentation for "namespace". +// src/search/CatalogEntityDocument.d.ts:12:5 - (ae-undocumented) Missing documentation for "kind". +// src/search/CatalogEntityDocument.d.ts:13:5 - (ae-undocumented) Missing documentation for "lifecycle". +// src/search/CatalogEntityDocument.d.ts:14:5 - (ae-undocumented) Missing documentation for "owner". ``` diff --git a/plugins/catalog-common/src/alpha.ts b/plugins/catalog-common/src/alpha.ts index 2dfc028332..8a3ed17431 100644 --- a/plugins/catalog-common/src/alpha.ts +++ b/plugins/catalog-common/src/alpha.ts @@ -20,9 +20,11 @@ export { catalogEntityCreatePermission, catalogEntityDeletePermission, catalogEntityRefreshPermission, + catalogEntityValidatePermission, catalogLocationReadPermission, catalogLocationCreatePermission, catalogLocationDeletePermission, + catalogLocationAnalyzePermission, catalogPermissions, } from './permissions'; export type { CatalogEntityPermission } from './permissions'; diff --git a/plugins/catalog-common/src/permissions.ts b/plugins/catalog-common/src/permissions.ts index 3082c0da70..fa86268f61 100644 --- a/plugins/catalog-common/src/permissions.ts +++ b/plugins/catalog-common/src/permissions.ts @@ -91,6 +91,15 @@ export const catalogEntityRefreshPermission = createPermission({ resourceType: RESOURCE_TYPE_CATALOG_ENTITY, }); +/** + * This permission is used to authorize validating catalog entities. + * @alpha + */ +export const catalogEntityValidatePermission = createPermission({ + name: 'catalog.entity.validate', + attributes: {}, +}); + /** * This permission is used to designate actions that involve reading one or more * locations from the catalog. @@ -118,6 +127,15 @@ export const catalogLocationCreatePermission = createPermission({ }, }); +/** + * This permission is used to authorize analyzing catalog locations. + * @alpha + */ +export const catalogLocationAnalyzePermission = createPermission({ + name: 'catalog.location.analyze', + attributes: {}, +}); + /** * This permission is used to designate actions that involve deleting locations * from the catalog. @@ -139,7 +157,9 @@ export const catalogPermissions = [ catalogEntityCreatePermission, catalogEntityDeletePermission, catalogEntityRefreshPermission, + catalogEntityValidatePermission, catalogLocationReadPermission, catalogLocationCreatePermission, catalogLocationDeletePermission, + catalogLocationAnalyzePermission, ]; diff --git a/plugins/catalog-graph/CHANGELOG.md b/plugins/catalog-graph/CHANGELOG.md index dd6cfdaf24..37fc6c8a47 100644 --- a/plugins/catalog-graph/CHANGELOG.md +++ b/plugins/catalog-graph/CHANGELOG.md @@ -1,5 +1,69 @@ # @backstage/plugin-catalog-graph +## 0.4.11-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/frontend-plugin-api@0.9.0-next.1 + - @backstage/core-compat-api@0.3.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/plugin-catalog-react@1.14.0-next.1 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/types@1.1.1 + +## 0.4.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/core-compat-api@0.3.1-next.0 + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/plugin-catalog-react@1.13.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/types@1.1.1 + +## 0.4.9 + +### Patch Changes + +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. +- da91078: Fixed a bug in the `CatalogGraphPage` component where, after clicking on some nodes, clicking the back button would break the navigation. This issue caused the entire navigation to fail and behaved differently across various browsers. +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- 8a474f2: Updating docs to use `createFrontendModule` instead +- a159180: Added missing items to `overridableComponents` +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/plugin-catalog-react@1.13.0 + - @backstage/frontend-plugin-api@0.8.0 + - @backstage/core-compat-api@0.3.0 + - @backstage/catalog-model@1.7.0 + - @backstage/catalog-client@1.7.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/types@1.1.1 + +## 0.4.9-next.2 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- 8a474f2: Updating docs to use `createFrontendModule` instead +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/plugin-catalog-react@1.13.0-next.2 + - @backstage/catalog-client@1.7.0-next.1 + - @backstage/core-compat-api@0.3.0-next.2 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/frontend-plugin-api@0.8.0-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/types@1.1.1 + ## 0.4.9-next.1 ### Patch Changes diff --git a/plugins/catalog-graph/README-alpha.md b/plugins/catalog-graph/README-alpha.md index 784066c44f..06de696dcc 100644 --- a/plugins/catalog-graph/README-alpha.md +++ b/plugins/catalog-graph/README-alpha.md @@ -198,23 +198,28 @@ Overriding the card extension allows you to modify how it is implemented. Here is an example overriding the card extension with a custom component: ```tsx -import { createExtensionOverrides, createSchemaFromZod } from '@backstage/backstage-plugin-api'; +import { + createFrontendModule, + createSchemaFromZod, +} from '@backstage/backstage-plugin-api'; import { createEntityCardExtension } from '@backstage/plugin-catalog-react/alpha'; -export default createExtensionOverrides( +export default createFrontendModule({ + pluginId: 'catalog-graph', extensions: [ createEntityCardExtension({ - // These namespace and name are necessary so the system knows that this extension will replace the default 'entity-relations' card extension provided by the 'catalog-graph' plugin - namespace: 'catalog-graph', name: 'entity-relations', - configSchema: createSchemaFromZod(z => z.object({ - filter: z.string().optional(), - // Ommitting the rest of default configs for simplicity in this example - })), - loader: () => import('./components').then(m => ) - }) - ] -); + configSchema: createSchemaFromZod(z => + z.object({ + filter: z.string().optional(), + // Ommitting the rest of default configs for simplicity in this example + }), + ), + loader: () => + import('./components').then(m => ), + }), + ], +}); ``` For more information about where to place extension overrides, see the official [documentation](https://backstage.io/docs/frontend-system/architecture/extension-overrides). @@ -292,16 +297,15 @@ Overriding the page extension allows you to modify how it is implemented. Here is example overriding the page extension with a custom component: ```tsx -import { createExtensionOverrides, createPageExtension, createSchemaFromZod } from '@backstage/backstage-plugin-api'; +import { createFrontendModule, createPageExtension, createSchemaFromZod } from '@backstage/backstage-plugin-api'; import { convertLegacyRouteRef } from '@backstage/core-compat-api'; import { catalogGraphRouteRef } from '@backstage/plugin-catalog-graph'; -export default createExtensionOverrides( +export default createFrontendModule({ + pluginId: 'catalog-graph', extensions: [ createPageExtension({ // Ommiting name since it is an index page - // This namespace is necessary so the system knows that this extension will replace the default 'catalog-graph' page extension - namespace: 'catalog-graph', defaultPath: '/catalog-graph', routeRef: convertLegacyRouteRef(catalogGraphRouteRef), createSchemaFromZod(z => z.object({ @@ -311,7 +315,7 @@ export default createExtensionOverrides( loader: () => import('./components').then(m => ) }) ] -); +}); ``` For more information about where to place extension overrides, see the official [documentation](https://backstage.io/docs/frontend-system/architecture/extension-overrides). diff --git a/plugins/catalog-graph/package.json b/plugins/catalog-graph/package.json index 74b9054492..32f7898e2b 100644 --- a/plugins/catalog-graph/package.json +++ b/plugins/catalog-graph/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-graph", - "version": "0.4.9-next.1", + "version": "0.4.11-next.1", "backstage": { "role": "frontend-plugin", "pluginId": "catalog-graph", @@ -60,7 +60,6 @@ "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.61", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "classnames": "^2.3.1", "lodash": "^4.17.15", "p-limit": "^3.1.0", @@ -75,12 +74,22 @@ "@backstage/test-utils": "workspace:^", "@testing-library/dom": "^10.0.0", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^15.0.0", - "@testing-library/user-event": "^14.0.0" + "@testing-library/react": "^16.0.0", + "@testing-library/user-event": "^14.0.0", + "@types/react": "^18.0.0", + "react": "^18.0.2", + "react-dom": "^18.0.2", + "react-router-dom": "^6.3.0" }, "peerDependencies": { + "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } } diff --git a/plugins/catalog-graph/api-report-alpha.md b/plugins/catalog-graph/report-alpha.api.md similarity index 92% rename from plugins/catalog-graph/api-report-alpha.md rename to plugins/catalog-graph/report-alpha.api.md index 65f8af3764..944fa203f1 100644 --- a/plugins/catalog-graph/api-report-alpha.md +++ b/plugins/catalog-graph/report-alpha.api.md @@ -89,8 +89,11 @@ const _default: FrontendPlugin< >; }; kind: 'entity-card'; - namespace: undefined; name: 'relations'; + params: { + loader: () => Promise; + filter?: string | ((entity: Entity) => boolean) | undefined; + }; }>; 'page:catalog-graph': ExtensionDefinition<{ config: { @@ -151,12 +154,20 @@ const _default: FrontendPlugin< >; }; kind: 'page'; - namespace: undefined; name: undefined; + params: { + defaultPath: string; + loader: () => Promise; + routeRef?: RouteRef | undefined; + }; }>; } >; export default _default; +// Warnings were encountered during analysis: +// +// src/alpha.d.ts:3:15 - (ae-undocumented) Missing documentation for "_default". + // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/catalog-graph/api-report.md b/plugins/catalog-graph/report.api.md similarity index 80% rename from plugins/catalog-graph/api-report.md rename to plugins/catalog-graph/report.api.md index 205ffed089..8812394d4f 100644 --- a/plugins/catalog-graph/api-report.md +++ b/plugins/catalog-graph/report.api.md @@ -60,6 +60,12 @@ export const catalogGraphPlugin: BackstagePlugin< // @public export const catalogGraphRouteRef: RouteRef; +// @public (undocumented) +export type CustomLabelClassKey = 'text' | 'secondary'; + +// @public (undocumented) +export type CustomNodeClassKey = 'node' | 'text' | 'clickable'; + // @public export enum Direction { BOTTOM_TOP = 'BT', @@ -107,6 +113,9 @@ export const EntityRelationsGraph: ( props: EntityRelationsGraphProps, ) => React_2.JSX.Element; +// @public (undocumented) +export type EntityRelationsGraphClassKey = 'progress' | 'container' | 'graph'; + // @public (undocumented) export type EntityRelationsGraphProps = { rootEntityNames: CompoundEntityRef | CompoundEntityRef[]; @@ -129,4 +138,11 @@ export type EntityRelationsGraphProps = { // @public export type RelationPairs = [string, string][]; + +// Warnings were encountered during analysis: +// +// src/components/EntityRelationsGraph/DefaultRenderLabel.d.ts:5:1 - (ae-undocumented) Missing documentation for "CustomLabelClassKey". +// src/components/EntityRelationsGraph/DefaultRenderNode.d.ts:5:1 - (ae-undocumented) Missing documentation for "CustomNodeClassKey". +// src/components/EntityRelationsGraph/EntityRelationsGraph.d.ts:7:1 - (ae-undocumented) Missing documentation for "EntityRelationsGraphClassKey". +// src/components/EntityRelationsGraph/EntityRelationsGraph.d.ts:11:1 - (ae-undocumented) Missing documentation for "EntityRelationsGraphProps". ``` diff --git a/plugins/catalog-graph/src/components/CatalogGraphCard/CatalogGraphCard.tsx b/plugins/catalog-graph/src/components/CatalogGraphCard/CatalogGraphCard.tsx index 7c7f4c6063..2276d19757 100644 --- a/plugins/catalog-graph/src/components/CatalogGraphCard/CatalogGraphCard.tsx +++ b/plugins/catalog-graph/src/components/CatalogGraphCard/CatalogGraphCard.tsx @@ -39,6 +39,9 @@ import { } from '../EntityRelationsGraph'; import { EntityRelationsGraphProps } from '../EntityRelationsGraph'; +/** @public */ +export type CatalogGraphCardClassKey = 'card' | 'graph'; + const useStyles = makeStyles( { card: ({ height }) => ({ diff --git a/plugins/catalog-graph/src/components/CatalogGraphCard/index.ts b/plugins/catalog-graph/src/components/CatalogGraphCard/index.ts index 725f90331f..53db3719a7 100644 --- a/plugins/catalog-graph/src/components/CatalogGraphCard/index.ts +++ b/plugins/catalog-graph/src/components/CatalogGraphCard/index.ts @@ -14,3 +14,4 @@ * limitations under the License. */ export { CatalogGraphCard } from './CatalogGraphCard'; +export type { CatalogGraphCardClassKey } from './CatalogGraphCard'; diff --git a/plugins/catalog-graph/src/components/CatalogGraphPage/CatalogGraphPage.tsx b/plugins/catalog-graph/src/components/CatalogGraphPage/CatalogGraphPage.tsx index ad673b192a..23363668a6 100644 --- a/plugins/catalog-graph/src/components/CatalogGraphPage/CatalogGraphPage.tsx +++ b/plugins/catalog-graph/src/components/CatalogGraphPage/CatalogGraphPage.tsx @@ -51,6 +51,16 @@ import { SelectedRelationsFilter } from './SelectedRelationsFilter'; import { SwitchFilter } from './SwitchFilter'; import { useCatalogGraphPage } from './useCatalogGraphPage'; +/** @public */ +export type CatalogGraphPageClassKey = + | 'content' + | 'container' + | 'fullHeight' + | 'graphWrapper' + | 'graph' + | 'legend' + | 'filters'; + const useStyles = makeStyles( theme => ({ content: { diff --git a/plugins/catalog-graph/src/components/CatalogGraphPage/MaxDepthFilter.tsx b/plugins/catalog-graph/src/components/CatalogGraphPage/MaxDepthFilter.tsx index 51ee4643b5..5f7b891d72 100644 --- a/plugins/catalog-graph/src/components/CatalogGraphPage/MaxDepthFilter.tsx +++ b/plugins/catalog-graph/src/components/CatalogGraphPage/MaxDepthFilter.tsx @@ -28,6 +28,9 @@ export type Props = { onChange: (value: number) => void; }; +/** @public */ +export type MaxDepthFilterClassKey = 'formControl'; + const useStyles = makeStyles( { formControl: { diff --git a/plugins/catalog-graph/src/components/CatalogGraphPage/SelectedKindsFilter.tsx b/plugins/catalog-graph/src/components/CatalogGraphPage/SelectedKindsFilter.tsx index 1a38e4e31f..e0b7f7fa55 100644 --- a/plugins/catalog-graph/src/components/CatalogGraphPage/SelectedKindsFilter.tsx +++ b/plugins/catalog-graph/src/components/CatalogGraphPage/SelectedKindsFilter.tsx @@ -28,6 +28,9 @@ import Autocomplete from '@material-ui/lab/Autocomplete'; import React, { useCallback, useEffect, useMemo } from 'react'; import useAsync from 'react-use/esm/useAsync'; +/** @public */ +export type SelectedKindsFilterClassKey = 'formControl'; + const useStyles = makeStyles( { formControl: { diff --git a/plugins/catalog-graph/src/components/CatalogGraphPage/SelectedRelationsFilter.tsx b/plugins/catalog-graph/src/components/CatalogGraphPage/SelectedRelationsFilter.tsx index 74adfd0226..af67c0ef8b 100644 --- a/plugins/catalog-graph/src/components/CatalogGraphPage/SelectedRelationsFilter.tsx +++ b/plugins/catalog-graph/src/components/CatalogGraphPage/SelectedRelationsFilter.tsx @@ -26,6 +26,9 @@ import Autocomplete from '@material-ui/lab/Autocomplete'; import React, { useCallback, useMemo } from 'react'; import { RelationPairs } from '../EntityRelationsGraph'; +/** @public */ +export type SelectedRelationsFilterClassKey = 'formControl'; + const useStyles = makeStyles( { formControl: { diff --git a/plugins/catalog-graph/src/components/CatalogGraphPage/SwitchFilter.tsx b/plugins/catalog-graph/src/components/CatalogGraphPage/SwitchFilter.tsx index 4427d87a59..b2878f1934 100644 --- a/plugins/catalog-graph/src/components/CatalogGraphPage/SwitchFilter.tsx +++ b/plugins/catalog-graph/src/components/CatalogGraphPage/SwitchFilter.tsx @@ -25,6 +25,9 @@ export type Props = { onChange: (value: boolean) => void; }; +/** @public */ +export type SwitchFilterClassKey = 'root'; + const useStyles = makeStyles( { root: { diff --git a/plugins/catalog-graph/src/components/CatalogGraphPage/index.ts b/plugins/catalog-graph/src/components/CatalogGraphPage/index.ts index 9e59ad3a13..496e79aab4 100644 --- a/plugins/catalog-graph/src/components/CatalogGraphPage/index.ts +++ b/plugins/catalog-graph/src/components/CatalogGraphPage/index.ts @@ -14,3 +14,8 @@ * limitations under the License. */ export { CatalogGraphPage } from './CatalogGraphPage'; +export type { CatalogGraphPageClassKey } from './CatalogGraphPage'; +export type { MaxDepthFilterClassKey } from './MaxDepthFilter'; +export type { SelectedKindsFilterClassKey } from './SelectedKindsFilter'; +export type { SelectedRelationsFilterClassKey } from './SelectedRelationsFilter'; +export type { SwitchFilterClassKey } from './SwitchFilter'; diff --git a/plugins/catalog-graph/src/components/EntityRelationsGraph/DefaultRenderLabel.tsx b/plugins/catalog-graph/src/components/EntityRelationsGraph/DefaultRenderLabel.tsx index ae01a113dd..14b88e59b3 100644 --- a/plugins/catalog-graph/src/components/EntityRelationsGraph/DefaultRenderLabel.tsx +++ b/plugins/catalog-graph/src/components/EntityRelationsGraph/DefaultRenderLabel.tsx @@ -19,6 +19,9 @@ import React from 'react'; import { EntityEdgeData } from './types'; import classNames from 'classnames'; +/** @public */ +export type CustomLabelClassKey = 'text' | 'secondary'; + const useStyles = makeStyles( theme => ({ text: { diff --git a/plugins/catalog-graph/src/components/EntityRelationsGraph/DefaultRenderNode.tsx b/plugins/catalog-graph/src/components/EntityRelationsGraph/DefaultRenderNode.tsx index bc3311d33f..dcdba40f9a 100644 --- a/plugins/catalog-graph/src/components/EntityRelationsGraph/DefaultRenderNode.tsx +++ b/plugins/catalog-graph/src/components/EntityRelationsGraph/DefaultRenderNode.tsx @@ -23,6 +23,9 @@ import { EntityIcon } from './EntityIcon'; import { EntityNodeData } from './types'; import { DEFAULT_NAMESPACE } from '@backstage/catalog-model'; +/** @public */ +export type CustomNodeClassKey = 'node' | 'text' | 'clickable'; + const useStyles = makeStyles( theme => ({ node: { diff --git a/plugins/catalog-graph/src/components/EntityRelationsGraph/EntityRelationsGraph.tsx b/plugins/catalog-graph/src/components/EntityRelationsGraph/EntityRelationsGraph.tsx index 51de7cc47f..699c4d9b30 100644 --- a/plugins/catalog-graph/src/components/EntityRelationsGraph/EntityRelationsGraph.tsx +++ b/plugins/catalog-graph/src/components/EntityRelationsGraph/EntityRelationsGraph.tsx @@ -34,6 +34,9 @@ import { ALL_RELATION_PAIRS, RelationPairs } from './relations'; import { Direction, EntityEdge, EntityNode } from './types'; import { useEntityRelationNodesAndEdges } from './useEntityRelationNodesAndEdges'; +/** @public */ +export type EntityRelationsGraphClassKey = 'progress' | 'container' | 'graph'; + const useStyles = makeStyles( theme => ({ progress: { diff --git a/plugins/catalog-graph/src/components/EntityRelationsGraph/index.ts b/plugins/catalog-graph/src/components/EntityRelationsGraph/index.ts index 06227babe3..7477d22f87 100644 --- a/plugins/catalog-graph/src/components/EntityRelationsGraph/index.ts +++ b/plugins/catalog-graph/src/components/EntityRelationsGraph/index.ts @@ -14,7 +14,10 @@ * limitations under the License. */ export { EntityRelationsGraph } from './EntityRelationsGraph'; -export type { EntityRelationsGraphProps } from './EntityRelationsGraph'; +export type { + EntityRelationsGraphProps, + EntityRelationsGraphClassKey, +} from './EntityRelationsGraph'; export { ALL_RELATION_PAIRS } from './relations'; export type { RelationPairs } from './relations'; export { Direction } from './types'; @@ -24,3 +27,5 @@ export type { EntityNodeData, EntityNode, } from './types'; +export type { CustomLabelClassKey } from './DefaultRenderLabel'; +export type { CustomNodeClassKey } from './DefaultRenderNode'; diff --git a/plugins/catalog-graph/src/overridableComponents.ts b/plugins/catalog-graph/src/overridableComponents.ts new file mode 100644 index 0000000000..1b92ae5389 --- /dev/null +++ b/plugins/catalog-graph/src/overridableComponents.ts @@ -0,0 +1,55 @@ +/* + * 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 { Overrides } from '@material-ui/core/styles/overrides'; +import { StyleRules } from '@material-ui/core/styles/withStyles'; +import { CatalogGraphCardClassKey } from './components/CatalogGraphCard'; +import { + CatalogGraphPageClassKey, + MaxDepthFilterClassKey, + SelectedKindsFilterClassKey, + SelectedRelationsFilterClassKey, + SwitchFilterClassKey, +} from './components/CatalogGraphPage'; +import { + CustomLabelClassKey, + CustomNodeClassKey, + EntityRelationsGraphClassKey, +} from './components'; + +/** @public */ +export type PluginCatalogGraphComponentsNameToClassKey = { + PluginCatalogGraphEntityRelationsGraph: EntityRelationsGraphClassKey; + PluginCatalogGraphCustomNode: CustomNodeClassKey; + PluginCatalogGraphCustomLabel: CustomLabelClassKey; + PluginCatalogGraphSwitchFilter: SwitchFilterClassKey; + PluginCatalogGraphSelectedRelationsFilter: SelectedRelationsFilterClassKey; + PluginCatalogGraphSelectedKindsFilter: SelectedKindsFilterClassKey; + PluginCatalogGraphMaxDepthFilter: MaxDepthFilterClassKey; + PluginCatalogGraphCatalogGraphPage: CatalogGraphPageClassKey; + PluginCatalogGraphCatalogGraphCard: CatalogGraphCardClassKey; +}; + +/** @public */ +export type BackstageOverrides = Overrides & { + [Name in keyof PluginCatalogGraphComponentsNameToClassKey]?: Partial< + StyleRules + >; +}; + +declare module '@backstage/theme' { + interface OverrideComponentNameToClassKeys + extends PluginCatalogGraphComponentsNameToClassKey {} +} diff --git a/plugins/catalog-import/CHANGELOG.md b/plugins/catalog-import/CHANGELOG.md index 0456c5ee24..e23c35845e 100644 --- a/plugins/catalog-import/CHANGELOG.md +++ b/plugins/catalog-import/CHANGELOG.md @@ -1,5 +1,83 @@ # @backstage/plugin-catalog-import +## 0.12.5-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/frontend-plugin-api@0.9.0-next.1 + - @backstage/integration-react@1.2.0-next.1 + - @backstage/core-compat-api@0.3.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/plugin-catalog-react@1.14.0-next.1 + - @backstage/integration@1.15.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.1.0 + +## 0.12.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/core-compat-api@0.3.1-next.0 + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/plugin-catalog-react@1.13.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.15.0 + - @backstage/integration-react@1.1.32-next.0 + - @backstage/plugin-catalog-common@1.1.0 + +## 0.12.3 + +### Patch Changes + +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. +- f3c90da: Support button title should be contained in a single menu item +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/plugin-catalog-react@1.13.0 + - @backstage/frontend-plugin-api@0.8.0 + - @backstage/core-compat-api@0.3.0 + - @backstage/integration-react@1.1.31 + - @backstage/catalog-model@1.7.0 + - @backstage/catalog-client@1.7.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/integration@1.15.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## 0.12.3-next.2 + +### Patch Changes + +- f3c90da: Support button title should be contained in a single menu item +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/plugin-catalog-react@1.13.0-next.2 + - @backstage/integration-react@1.1.31-next.0 + - @backstage/catalog-client@1.7.0-next.1 + - @backstage/integration@1.15.0-next.0 + - @backstage/core-compat-api@0.3.0-next.2 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/frontend-plugin-api@0.8.0-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.0.26 + ## 0.12.3-next.1 ### Patch Changes diff --git a/plugins/catalog-import/package.json b/plugins/catalog-import/package.json index 32e183e7d9..689055d9a2 100644 --- a/plugins/catalog-import/package.json +++ b/plugins/catalog-import/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-import", - "version": "0.12.3-next.1", + "version": "0.12.5-next.1", "description": "A Backstage plugin the helps you import entities into your catalog", "backstage": { "role": "frontend-plugin", @@ -70,7 +70,6 @@ "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.61", "@octokit/rest": "^19.0.3", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "git-url-parse": "^14.0.0", "js-base64": "^3.6.0", "lodash": "^4.17.21", @@ -86,14 +85,24 @@ "@backstage/test-utils": "workspace:^", "@testing-library/dom": "^10.0.0", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^15.0.0", + "@testing-library/react": "^16.0.0", "@testing-library/user-event": "^14.0.0", - "msw": "^1.0.0" + "@types/react": "^18.0.0", + "msw": "^1.0.0", + "react": "^18.0.2", + "react-dom": "^18.0.2", + "react-router-dom": "^6.3.0" }, "peerDependencies": { + "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-router-dom": "6.0.0-beta.0 || ^6.3.0" }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + }, "configSchema": "config.d.ts" } diff --git a/plugins/catalog-import/api-report-alpha.md b/plugins/catalog-import/report-alpha.api.md similarity index 83% rename from plugins/catalog-import/api-report-alpha.md rename to plugins/catalog-import/report-alpha.api.md index 3eed9ce3e4..d966e04e7e 100644 --- a/plugins/catalog-import/api-report-alpha.md +++ b/plugins/catalog-import/report-alpha.api.md @@ -20,7 +20,6 @@ const _default: FrontendPlugin< { 'api:catalog-import': ExtensionDefinition<{ kind: 'api'; - namespace: undefined; name: undefined; config: {}; configInput: {}; @@ -30,10 +29,12 @@ const _default: FrontendPlugin< {} >; inputs: {}; + params: { + factory: AnyApiFactory; + }; }>; 'page:catalog-import': ExtensionDefinition<{ kind: 'page'; - namespace: undefined; name: undefined; config: { path: string | undefined; @@ -56,10 +57,19 @@ const _default: FrontendPlugin< } >; inputs: {}; + params: { + defaultPath: string; + loader: () => Promise; + routeRef?: RouteRef | undefined; + }; }>; } >; export default _default; +// Warnings were encountered during analysis: +// +// src/alpha.d.ts:3:15 - (ae-undocumented) Missing documentation for "_default". + // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/catalog-import/api-report.md b/plugins/catalog-import/report.api.md similarity index 62% rename from plugins/catalog-import/api-report.md rename to plugins/catalog-import/report.api.md index c61aa97b06..8c26da769d 100644 --- a/plugins/catalog-import/api-report.md +++ b/plugins/catalog-import/report.api.md @@ -366,4 +366,46 @@ export interface StepPrepareCreatePullRequestProps { // Warnings were encountered during analysis: // // src/api/CatalogImportApi.d.ts:25:5 - (ae-forgotten-export) The symbol "PartialEntity" needs to be exported by the entry point index.d.ts +// src/api/CatalogImportApi.d.ts:33:5 - (ae-undocumented) Missing documentation for "analyzeUrl". +// src/api/CatalogImportApi.d.ts:34:5 - (ae-undocumented) Missing documentation for "preparePullRequest". +// src/api/CatalogImportApi.d.ts:38:5 - (ae-undocumented) Missing documentation for "submitPullRequest". +// src/api/CatalogImportClient.d.ts:26:5 - (ae-undocumented) Missing documentation for "analyzeUrl". +// src/api/CatalogImportClient.d.ts:27:5 - (ae-undocumented) Missing documentation for "preparePullRequest". +// src/api/CatalogImportClient.d.ts:31:5 - (ae-undocumented) Missing documentation for "submitPullRequest". +// src/components/EntityListComponent/EntityListComponent.d.ts:9:5 - (ae-undocumented) Missing documentation for "locations". +// src/components/EntityListComponent/EntityListComponent.d.ts:13:5 - (ae-undocumented) Missing documentation for "locationListItemIcon". +// src/components/EntityListComponent/EntityListComponent.d.ts:14:5 - (ae-undocumented) Missing documentation for "collapsed". +// src/components/EntityListComponent/EntityListComponent.d.ts:15:5 - (ae-undocumented) Missing documentation for "firstListItem". +// src/components/EntityListComponent/EntityListComponent.d.ts:16:5 - (ae-undocumented) Missing documentation for "onItemClick". +// src/components/EntityListComponent/EntityListComponent.d.ts:17:5 - (ae-undocumented) Missing documentation for "withLinks". +// src/components/ImportInfoCard/ImportInfoCard.d.ts:8:5 - (ae-undocumented) Missing documentation for "exampleLocationUrl". +// src/components/ImportInfoCard/ImportInfoCard.d.ts:9:5 - (ae-undocumented) Missing documentation for "exampleRepositoryUrl". +// src/components/ImportStepper/ImportStepper.d.ts:11:5 - (ae-undocumented) Missing documentation for "initialUrl". +// src/components/ImportStepper/ImportStepper.d.ts:12:5 - (ae-undocumented) Missing documentation for "generateStepper". +// src/components/ImportStepper/ImportStepper.d.ts:13:5 - (ae-undocumented) Missing documentation for "variant". +// src/components/StepInitAnalyzeUrl/StepInitAnalyzeUrl.d.ts:10:5 - (ae-undocumented) Missing documentation for "onAnalysis". +// src/components/StepInitAnalyzeUrl/StepInitAnalyzeUrl.d.ts:13:5 - (ae-undocumented) Missing documentation for "disablePullRequest". +// src/components/StepInitAnalyzeUrl/StepInitAnalyzeUrl.d.ts:14:5 - (ae-undocumented) Missing documentation for "analysisUrl". +// src/components/StepInitAnalyzeUrl/StepInitAnalyzeUrl.d.ts:15:5 - (ae-undocumented) Missing documentation for "exampleLocationUrl". +// src/components/StepPrepareCreatePullRequest/AutocompleteTextField.d.ts:10:5 - (ae-undocumented) Missing documentation for "name". +// src/components/StepPrepareCreatePullRequest/AutocompleteTextField.d.ts:11:5 - (ae-undocumented) Missing documentation for "options". +// src/components/StepPrepareCreatePullRequest/AutocompleteTextField.d.ts:12:5 - (ae-undocumented) Missing documentation for "required". +// src/components/StepPrepareCreatePullRequest/AutocompleteTextField.d.ts:13:5 - (ae-undocumented) Missing documentation for "errors". +// src/components/StepPrepareCreatePullRequest/AutocompleteTextField.d.ts:14:5 - (ae-undocumented) Missing documentation for "rules". +// src/components/StepPrepareCreatePullRequest/AutocompleteTextField.d.ts:15:5 - (ae-undocumented) Missing documentation for "loading". +// src/components/StepPrepareCreatePullRequest/AutocompleteTextField.d.ts:16:5 - (ae-undocumented) Missing documentation for "loadingText". +// src/components/StepPrepareCreatePullRequest/AutocompleteTextField.d.ts:17:5 - (ae-undocumented) Missing documentation for "helperText". +// src/components/StepPrepareCreatePullRequest/AutocompleteTextField.d.ts:18:5 - (ae-undocumented) Missing documentation for "errorHelperText". +// src/components/StepPrepareCreatePullRequest/AutocompleteTextField.d.ts:19:5 - (ae-undocumented) Missing documentation for "textFieldProps". +// src/components/StepPrepareCreatePullRequest/PreviewCatalogInfoComponent.d.ts:9:5 - (ae-undocumented) Missing documentation for "repositoryUrl". +// src/components/StepPrepareCreatePullRequest/PreviewCatalogInfoComponent.d.ts:10:5 - (ae-undocumented) Missing documentation for "entities". +// src/components/StepPrepareCreatePullRequest/PreviewCatalogInfoComponent.d.ts:11:5 - (ae-undocumented) Missing documentation for "classes". +// src/components/StepPrepareCreatePullRequest/PreviewPullRequestComponent.d.ts:8:5 - (ae-undocumented) Missing documentation for "title". +// src/components/StepPrepareCreatePullRequest/PreviewPullRequestComponent.d.ts:9:5 - (ae-undocumented) Missing documentation for "description". +// src/components/StepPrepareCreatePullRequest/PreviewPullRequestComponent.d.ts:10:5 - (ae-undocumented) Missing documentation for "classes". +// src/components/StepPrepareCreatePullRequest/StepPrepareCreatePullRequest.d.ts:20:5 - (ae-undocumented) Missing documentation for "analyzeResult". +// src/components/StepPrepareCreatePullRequest/StepPrepareCreatePullRequest.d.ts:23:5 - (ae-undocumented) Missing documentation for "onPrepare". +// src/components/StepPrepareCreatePullRequest/StepPrepareCreatePullRequest.d.ts:26:5 - (ae-undocumented) Missing documentation for "onGoBack". +// src/components/StepPrepareCreatePullRequest/StepPrepareCreatePullRequest.d.ts:27:5 - (ae-undocumented) Missing documentation for "renderFormFields". +// src/components/useImportState.d.ts:80:1 - (ae-undocumented) Missing documentation for "ImportState". ``` diff --git a/plugins/catalog-import/src/components/DefaultImportPage/DefaultImportPage.tsx b/plugins/catalog-import/src/components/DefaultImportPage/DefaultImportPage.tsx index 680ce16ae4..fa89ac2caf 100644 --- a/plugins/catalog-import/src/components/DefaultImportPage/DefaultImportPage.tsx +++ b/plugins/catalog-import/src/components/DefaultImportPage/DefaultImportPage.tsx @@ -40,6 +40,8 @@ export const DefaultImportPage = () => { const isMobile = useMediaQuery(theme.breakpoints.down('sm')); const appTitle = configApi.getOptionalString('app.title') || 'Backstage'; + const supportTitle = `Start tracking your component in ${appTitle} by adding it to the software catalog.`; + const contentItems = [ @@ -55,10 +57,7 @@ export const DefaultImportPage = () => {

- - Start tracking your component in {appTitle} by adding it to the - software catalog. - + {supportTitle} diff --git a/plugins/catalog-node/CHANGELOG.md b/plugins/catalog-node/CHANGELOG.md index b4472333fd..6adb452cbd 100644 --- a/plugins/catalog-node/CHANGELOG.md +++ b/plugins/catalog-node/CHANGELOG.md @@ -1,5 +1,53 @@ # @backstage/plugin-catalog-node +## 1.13.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-node@0.8.4-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-permission-common@0.8.1 + +## 1.13.0 + +### Minor Changes + +- bd35cdb: The `analyze-location` endpoint is now protected by the `catalog.location.analyze` permission. + The `validate-entity` endpoint is now protected by the `catalog.entity.validate` permission. +- 29e57c7: Add catalog service mocks under the `/testUtils` subpath export. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/catalog-client@1.7.0 + - @backstage/plugin-permission-node@0.8.3 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.8.1 + +## 1.12.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-client@1.7.0-next.1 + - @backstage/plugin-permission-node@0.8.3-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-permission-common@0.8.1 + ## 1.12.7-next.1 ### Patch Changes diff --git a/plugins/catalog-node/package.json b/plugins/catalog-node/package.json index 25f8d699ab..3c7052b78b 100644 --- a/plugins/catalog-node/package.json +++ b/plugins/catalog-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-node", - "version": "1.12.7-next.1", + "version": "1.13.1-next.0", "description": "The plugin-catalog-node module for @backstage/plugin-catalog-backend", "backstage": { "role": "node-library", @@ -26,6 +26,7 @@ "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.ts", + "./testUtils": "./src/testUtils.ts", "./package.json": "./package.json" }, "main": "src/index.ts", @@ -35,6 +36,9 @@ "alpha": [ "src/alpha.ts" ], + "testUtils": [ + "src/testUtils.ts" + ], "package.json": [ "package.json" ] diff --git a/plugins/catalog-node/api-report-alpha.md b/plugins/catalog-node/report-alpha.api.md similarity index 67% rename from plugins/catalog-node/api-report-alpha.md rename to plugins/catalog-node/report-alpha.api.md index ba02079ceb..4ef79f1f3c 100644 --- a/plugins/catalog-node/api-report-alpha.md +++ b/plugins/catalog-node/report-alpha.api.md @@ -98,5 +98,25 @@ export const catalogProcessingExtensionPoint: ExtensionPoint; +// Warnings were encountered during analysis: +// +// src/extensions.d.ts:8:1 - (ae-undocumented) Missing documentation for "CatalogLocationsExtensionPoint". +// src/extensions.d.ts:18:22 - (ae-undocumented) Missing documentation for "catalogLocationsExtensionPoint". +// src/extensions.d.ts:22:1 - (ae-undocumented) Missing documentation for "CatalogProcessingExtensionPoint". +// src/extensions.d.ts:23:5 - (ae-undocumented) Missing documentation for "addProcessor". +// src/extensions.d.ts:24:5 - (ae-undocumented) Missing documentation for "addEntityProvider". +// src/extensions.d.ts:25:5 - (ae-undocumented) Missing documentation for "addPlaceholderResolver". +// src/extensions.d.ts:26:5 - (ae-undocumented) Missing documentation for "setOnProcessingErrorHandler". +// src/extensions.d.ts:32:1 - (ae-undocumented) Missing documentation for "CatalogModelExtensionPoint". +// src/extensions.d.ts:50:22 - (ae-undocumented) Missing documentation for "catalogProcessingExtensionPoint". +// src/extensions.d.ts:54:1 - (ae-undocumented) Missing documentation for "CatalogAnalysisExtensionPoint". +// src/extensions.d.ts:77:22 - (ae-undocumented) Missing documentation for "catalogAnalysisExtensionPoint". +// src/extensions.d.ts:79:22 - (ae-undocumented) Missing documentation for "catalogModelExtensionPoint". +// src/extensions.d.ts:83:1 - (ae-undocumented) Missing documentation for "CatalogPermissionRuleInput". +// src/extensions.d.ts:87:1 - (ae-undocumented) Missing documentation for "CatalogPermissionExtensionPoint". +// src/extensions.d.ts:88:5 - (ae-undocumented) Missing documentation for "addPermissions". +// src/extensions.d.ts:89:5 - (ae-undocumented) Missing documentation for "addPermissionRules". +// src/extensions.d.ts:94:22 - (ae-undocumented) Missing documentation for "catalogPermissionExtensionPoint". + // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/catalog-node/report-testUtils.api.md b/plugins/catalog-node/report-testUtils.api.md new file mode 100644 index 0000000000..c1dfb0bd7a --- /dev/null +++ b/plugins/catalog-node/report-testUtils.api.md @@ -0,0 +1,27 @@ +## API Report File for "@backstage/plugin-catalog-node" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { CatalogApi } from '@backstage/catalog-client'; +import { Entity } from '@backstage/catalog-model'; +import { ServiceFactory } from '@backstage/backend-plugin-api'; +import { ServiceMock } from '@backstage/backend-test-utils'; + +// @public +export function catalogServiceMock(options?: { + entities?: Entity[]; +}): CatalogApi; + +// @public +export namespace catalogServiceMock { + const factory: (options?: { + entities?: Entity[]; + }) => ServiceFactory; + const mock: ( + partialImpl?: Partial | undefined, + ) => ServiceMock; +} + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/catalog-node/api-report.md b/plugins/catalog-node/report.api.md similarity index 77% rename from plugins/catalog-node/api-report.md rename to plugins/catalog-node/report.api.md index 7c1c8b5911..3702f933ee 100644 --- a/plugins/catalog-node/api-report.md +++ b/plugins/catalog-node/report.api.md @@ -8,6 +8,7 @@ import { AnalyzeLocationExistingEntity } from '@backstage/plugin-catalog-common'; import { AnalyzeLocationRequest } from '@backstage/plugin-catalog-common'; import { AnalyzeLocationResponse } from '@backstage/plugin-catalog-common'; +import { BackstageCredentials } from '@backstage/backend-plugin-api'; import { CompoundEntityRef } from '@backstage/catalog-model'; import { Entity } from '@backstage/catalog-model'; import { JsonValue } from '@backstage/types'; @@ -172,6 +173,7 @@ export type EntityRelationSpec = { export type LocationAnalyzer = { analyzeLocation( location: AnalyzeLocationRequest, + credentials: BackstageCredentials, ): Promise; }; @@ -241,4 +243,22 @@ export type ScmLocationAnalyzer = { existing: AnalyzeLocationExistingEntity[]; }>; }; + +// Warnings were encountered during analysis: +// +// src/api/processor.d.ts:10:1 - (ae-undocumented) Missing documentation for "CatalogProcessor". +// src/api/processor.d.ts:105:1 - (ae-undocumented) Missing documentation for "CatalogProcessorEmit". +// src/api/processor.d.ts:107:1 - (ae-undocumented) Missing documentation for "CatalogProcessorLocationResult". +// src/api/processor.d.ts:112:1 - (ae-undocumented) Missing documentation for "CatalogProcessorEntityResult". +// src/api/processor.d.ts:118:1 - (ae-undocumented) Missing documentation for "CatalogProcessorRelationResult". +// src/api/processor.d.ts:123:1 - (ae-undocumented) Missing documentation for "CatalogProcessorErrorResult". +// src/api/processor.d.ts:129:1 - (ae-undocumented) Missing documentation for "CatalogProcessorRefreshKeysResult". +// src/api/processor.d.ts:134:1 - (ae-undocumented) Missing documentation for "CatalogProcessorResult". +// src/processing/types.d.ts:17:1 - (ae-undocumented) Missing documentation for "PlaceholderResolverRead". +// src/processing/types.d.ts:19:1 - (ae-undocumented) Missing documentation for "PlaceholderResolverResolveUrl". +// src/processing/types.d.ts:21:1 - (ae-undocumented) Missing documentation for "PlaceholderResolverParams". +// src/processing/types.d.ts:30:1 - (ae-undocumented) Missing documentation for "PlaceholderResolver". +// src/processing/types.d.ts:32:1 - (ae-undocumented) Missing documentation for "LocationAnalyzer". +// src/processing/types.d.ts:42:1 - (ae-undocumented) Missing documentation for "AnalyzeOptions". +// src/processing/types.d.ts:47:1 - (ae-undocumented) Missing documentation for "ScmLocationAnalyzer". ``` diff --git a/plugins/catalog-node/src/processing/types.ts b/plugins/catalog-node/src/processing/types.ts index e3d3c305fc..625effc4df 100644 --- a/plugins/catalog-node/src/processing/types.ts +++ b/plugins/catalog-node/src/processing/types.ts @@ -22,6 +22,7 @@ import { } from '@backstage/plugin-catalog-common'; import { JsonValue } from '@backstage/types'; import { CatalogProcessorEmit } from '../api'; +import { BackstageCredentials } from '@backstage/backend-plugin-api'; /** * Entities that are not yet processed. @@ -66,6 +67,7 @@ export type LocationAnalyzer = { */ analyzeLocation( location: AnalyzeLocationRequest, + credentials: BackstageCredentials, ): Promise; }; diff --git a/plugins/catalog-node/src/testUtils.ts b/plugins/catalog-node/src/testUtils.ts new file mode 100644 index 0000000000..de60594701 --- /dev/null +++ b/plugins/catalog-node/src/testUtils.ts @@ -0,0 +1,17 @@ +/* + * 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. + */ + +export { catalogServiceMock } from './testUtils/catalogServiceMock'; diff --git a/plugins/catalog-node/src/testUtils/catalogServiceMock.test.ts b/plugins/catalog-node/src/testUtils/catalogServiceMock.test.ts new file mode 100644 index 0000000000..47850dd600 --- /dev/null +++ b/plugins/catalog-node/src/testUtils/catalogServiceMock.test.ts @@ -0,0 +1,63 @@ +/* + * 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 { Entity } from '@backstage/catalog-model'; +import { catalogServiceMock } from './catalogServiceMock'; + +const entity1: Entity = { + apiVersion: 'v1', + kind: 'CustomKind', + metadata: { + namespace: 'default', + name: 'e1', + uid: 'u1', + }, +}; + +const entity2: Entity = { + apiVersion: 'v1', + kind: 'CustomKind', + metadata: { + namespace: 'default', + name: 'e2', + uid: 'u2', + }, +}; + +const entities = [entity1, entity2]; + +describe('catalogServiceMock', () => { + it('exports the expected functionality', async () => { + const emptyFake = catalogServiceMock(); + const notEmptyFake = catalogServiceMock({ entities }); + + await expect(emptyFake.getEntities()).resolves.toEqual({ items: [] }); + await expect(notEmptyFake.getEntities()).resolves.toEqual({ + items: entities, + }); + + const mock = catalogServiceMock.mock(); + expect(mock.getEntities).toHaveBeenCalledTimes(0); + expect(mock.getEntities()).toBeUndefined(); + mock.getEntities.mockResolvedValue({ items: entities }); + await expect(mock.getEntities()).resolves.toEqual({ items: entities }); + + const mock2 = catalogServiceMock.mock({ + getEntities: async () => ({ items: [entity1] }), + }); + await expect(mock2.getEntities()).resolves.toEqual({ items: [entity1] }); + }); +}); diff --git a/plugins/catalog-node/src/testUtils/catalogServiceMock.ts b/plugins/catalog-node/src/testUtils/catalogServiceMock.ts new file mode 100644 index 0000000000..b9988572ac --- /dev/null +++ b/plugins/catalog-node/src/testUtils/catalogServiceMock.ts @@ -0,0 +1,104 @@ +/* + * 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 { + ServiceRef, + createServiceFactory, +} from '@backstage/backend-plugin-api'; +import { InMemoryCatalogClient } from '@backstage/catalog-client/testUtils'; +import { Entity } from '@backstage/catalog-model'; +import { catalogServiceRef } from '@backstage/plugin-catalog-node/alpha'; +// eslint-disable-next-line @backstage/no-undeclared-imports +import { ServiceMock } from '@backstage/backend-test-utils'; +import { CatalogApi } from '@backstage/catalog-client'; + +/** @internal */ +function simpleMock( + ref: ServiceRef, + mockFactory: () => jest.Mocked, +): (partialImpl?: Partial) => ServiceMock { + return partialImpl => { + const mock = mockFactory(); + if (partialImpl) { + for (const [key, impl] of Object.entries(partialImpl)) { + if (typeof impl === 'function') { + (mock as any)[key].mockImplementation(impl); + } else { + (mock as any)[key] = impl; + } + } + } + return Object.assign(mock, { + factory: createServiceFactory({ + service: ref, + deps: {}, + factory: () => mock, + }), + }) as ServiceMock; + }; +} + +/** + * Creates a fake catalog client that handles entities in memory storage. Note + * that this client may be severely limited in functionality, and advanced + * functions may not be available at all. + * + * @public + */ +export function catalogServiceMock(options?: { + entities?: Entity[]; +}): CatalogApi { + return new InMemoryCatalogClient(options); +} + +/** + * A collection of mock functionality for the catalog service. + * + * @public + */ +export namespace catalogServiceMock { + /** + * Creates a fake catalog client that handles entities in memory storage. Note + * that this client may be severely limited in functionality, and advanced + * functions may not be available at all. + */ + export const factory = (options?: { entities?: Entity[] }) => + createServiceFactory({ + service: catalogServiceRef, + deps: {}, + factory: () => new InMemoryCatalogClient(options), + }); + /** + * Creates a catalog client whose methods are mock functions, possibly with + * some of them overloaded by the caller. + */ + export const mock = simpleMock(catalogServiceRef, () => ({ + getEntities: jest.fn(), + getEntitiesByRefs: jest.fn(), + queryEntities: jest.fn(), + getEntityAncestors: jest.fn(), + getEntityByRef: jest.fn(), + removeEntityByUid: jest.fn(), + refreshEntity: jest.fn(), + getEntityFacets: jest.fn(), + getLocationById: jest.fn(), + getLocationByRef: jest.fn(), + addLocation: jest.fn(), + removeLocationById: jest.fn(), + getLocationByEntity: jest.fn(), + validateEntity: jest.fn(), + })); +} diff --git a/plugins/catalog-react/CHANGELOG.md b/plugins/catalog-react/CHANGELOG.md index 5027678cbe..6a68c053ab 100644 --- a/plugins/catalog-react/CHANGELOG.md +++ b/plugins/catalog-react/CHANGELOG.md @@ -1,5 +1,104 @@ # @backstage/plugin-catalog-react +## 1.14.0-next.1 + +### Minor Changes + +- 6812980: Added a new prop, `disableTooltip` to the `EntityRefLink` component + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/frontend-plugin-api@0.9.0-next.1 + - @backstage/integration-react@1.2.0-next.1 + - @backstage/core-compat-api@0.3.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/plugin-permission-react@0.4.27-next.1 + - @backstage/version-bridge@1.0.10-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-permission-common@0.8.1 + +## 1.13.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/core-compat-api@0.3.1-next.0 + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.32-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.9 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-permission-react@0.4.27-next.0 + +## 1.13.0 + +### Minor Changes + +- 78475c3: Allow offset mode paging in entity list provider + +### Patch Changes + +- c891b69: Add `FavoriteToggle` in `core-components` to standardise favorite marking +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. +- b537bd7: Allow custom star icons to be provided via the `star` and `unstarred` icon overrides. See how to override existing icons in the [Backstage documentation](https://backstage.io/docs/getting-started/app-custom-theme/#custom-icons). +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- 5446061: The `/alpha` export no longer export extension creators for the new frontend system, existing usage should be switched to use the equivalent extension blueprint instead. For more information see the [new frontend system 1.30 migration documentation](https://backstage.io/docs/frontend-system/architecture/migrations#130). +- a159180: Added missing items to `overridableComponents` +- ae9b6cb: Small internal fix to better work with recent `lodash` versions +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/frontend-plugin-api@0.8.0 + - @backstage/core-compat-api@0.3.0 + - @backstage/integration-react@1.1.31 + - @backstage/catalog-model@1.7.0 + - @backstage/catalog-client@1.7.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/version-bridge@1.0.9 + - @backstage/plugin-permission-react@0.4.26 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.8.1 + +## 1.13.0-next.2 + +### Minor Changes + +- 78475c3: Allow offset mode paging in entity list provider + +### Patch Changes + +- c891b69: Add `FavoriteToggle` in `core-components` to standardise favorite marking +- b537bd7: Allow custom star icons to be provided via the `star` and `unstarred` icon overrides. See how to override existing icons in the [Backstage documentation](https://backstage.io/docs/getting-started/app-custom-theme/#custom-icons). +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/integration-react@1.1.31-next.0 + - @backstage/catalog-client@1.7.0-next.1 + - @backstage/core-compat-api@0.3.0-next.2 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/frontend-plugin-api@0.8.0-next.2 + - @backstage/version-bridge@1.0.9-next.0 + - @backstage/plugin-permission-react@0.4.26-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-permission-common@0.8.1 + ## 1.12.4-next.1 ### Patch Changes diff --git a/plugins/catalog-react/package.json b/plugins/catalog-react/package.json index ba4aff5c42..c959e22b9e 100644 --- a/plugins/catalog-react/package.json +++ b/plugins/catalog-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-react", - "version": "1.12.4-next.1", + "version": "1.14.0-next.1", "description": "A frontend library that helps other Backstage plugins interact with the catalog", "backstage": { "role": "web-library", @@ -74,7 +74,6 @@ "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.61", "@react-hookz/web": "^24.0.0", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "classnames": "^2.2.6", "lodash": "^4.17.21", "material-ui-popup-state": "^1.9.3", @@ -92,14 +91,24 @@ "@backstage/test-utils": "workspace:^", "@testing-library/dom": "^10.0.0", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^15.0.0", + "@testing-library/react": "^16.0.0", "@testing-library/user-event": "^14.0.0", + "@types/react": "^18.0.0", "@types/zen-observable": "^0.8.0", + "react": "^18.0.2", + "react-dom": "^18.0.2", + "react-router-dom": "^6.3.0", "react-test-renderer": "^16.13.1" }, "peerDependencies": { + "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } } diff --git a/plugins/catalog-react/api-report-alpha.md b/plugins/catalog-react/report-alpha.api.md similarity index 95% rename from plugins/catalog-react/api-report-alpha.md rename to plugins/catalog-react/report-alpha.api.md index 5dec3ab99d..6eec97b815 100644 --- a/plugins/catalog-react/api-report-alpha.md +++ b/plugins/catalog-react/report-alpha.api.md @@ -101,7 +101,6 @@ export function convertLegacyEntityContentExtension( // @alpha export const EntityCardBlueprint: ExtensionBlueprint<{ kind: 'entity-card'; - namespace: undefined; name: undefined; params: { loader: () => Promise; @@ -147,7 +146,6 @@ export const EntityCardBlueprint: ExtensionBlueprint<{ // @alpha export const EntityContentBlueprint: ExtensionBlueprint<{ kind: 'entity-content'; - namespace: undefined; name: undefined; params: { loader: () => Promise; @@ -223,5 +221,11 @@ export function useEntityPermission( error?: Error; }; +// Warnings were encountered during analysis: +// +// src/alpha/converters/convertLegacyEntityCardExtension.d.ts:5:1 - (ae-undocumented) Missing documentation for "convertLegacyEntityCardExtension". +// src/alpha/converters/convertLegacyEntityContentExtension.d.ts:5:1 - (ae-undocumented) Missing documentation for "convertLegacyEntityContentExtension". +// src/translation.d.ts:2:22 - (ae-undocumented) Missing documentation for "catalogReactTranslationRef". + // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/catalog-react/api-report.md b/plugins/catalog-react/report.api.md similarity index 62% rename from plugins/catalog-react/api-report.md rename to plugins/catalog-react/report.api.md index 79aad53c33..0fbb27e70e 100644 --- a/plugins/catalog-react/api-report.md +++ b/plugins/catalog-react/report.api.md @@ -92,8 +92,10 @@ export type CatalogReactComponentsNameToClassKey = { CatalogReactEntitySearchBar: CatalogReactEntitySearchBarClassKey; CatalogReactEntityTagPicker: CatalogReactEntityTagPickerClassKey; CatalogReactEntityOwnerPicker: CatalogReactEntityOwnerPickerClassKey; + CatalogReactFixedWidthFormControlLabel: FixedWidthFormControlLabelClassKey; CatalogReactEntityProcessingStatusPicker: CatalogReactEntityProcessingStatusPickerClassKey; CatalogReactEntityAutocompletePickerClassKey: CatalogReactEntityAutocompletePickerClassKey; + CatalogReactMissingAnnotationEmptyState: MissingAnnotationEmptyStateClassKey; }; // @public (undocumented) @@ -307,8 +309,26 @@ export type EntityListContextProps< prev?: () => void; }; totalItems?: number; + limit: number; + offset?: number; + setLimit: (limit: number) => void; + setOffset?: (offset: number) => void; + paginationMode: PaginationMode; }; +// @public (undocumented) +export type EntityListPagination = + | boolean + | { + mode?: 'cursor'; + limit?: number; + } + | { + mode: 'offset'; + limit?: number; + offset?: number; + }; + // @public export const EntityListProvider: ( props: EntityListProviderProps, @@ -316,11 +336,7 @@ export const EntityListProvider: ( // @public (undocumented) export type EntityListProviderProps = PropsWithChildren<{ - pagination?: - | boolean - | { - limit?: number; - }; + pagination?: EntityListPagination; }>; // @public (undocumented) @@ -440,6 +456,7 @@ export type EntityRefLinkProps = { title?: string; children?: React_2.ReactNode; hideIcon?: boolean; + disableTooltip?: boolean; } & Omit; // @public @@ -635,6 +652,9 @@ export type FavoriteEntityProps = ComponentProps & { entity: Entity; }; +// @public (undocumented) +export type FixedWidthFormControlLabelClassKey = 'label' | 'root'; + // @public export function getEntityRelations( entity: Entity | undefined, @@ -692,6 +712,9 @@ export class MockStarredEntitiesApi implements StarredEntitiesApi { toggleStarred(entityRef: string): Promise; } +// @public (undocumented) +export type PaginationMode = 'cursor' | 'offset' | 'none'; + // @public export interface StarredEntitiesApi { starredEntitie$(): Observable>; @@ -817,4 +840,118 @@ export function useStarredEntity( toggleStarredEntity: () => void; isStarredEntity: boolean; }; + +// Warnings were encountered during analysis: +// +// src/apis/StarredEntitiesApi/MockStarredEntitiesApi.d.ts:12:5 - (ae-undocumented) Missing documentation for "toggleStarred". +// src/apis/StarredEntitiesApi/MockStarredEntitiesApi.d.ts:13:5 - (ae-undocumented) Missing documentation for "starredEntitie$". +// src/components/CatalogFilterLayout/CatalogFilterLayout.d.ts:15:22 - (ae-undocumented) Missing documentation for "CatalogFilterLayout". +// src/components/DefaultFilters/DefaultFilters.d.ts:16:22 - (ae-undocumented) Missing documentation for "DefaultFilters". +// src/components/EntityAutocompletePicker/EntityAutocompletePicker.d.ts:6:1 - (ae-undocumented) Missing documentation for "AllowedEntityFilters". +// src/components/EntityAutocompletePicker/EntityAutocompletePicker.d.ts:12:1 - (ae-undocumented) Missing documentation for "EntityAutocompletePickerProps". +// src/components/EntityAutocompletePicker/EntityAutocompletePicker.d.ts:25:1 - (ae-undocumented) Missing documentation for "CatalogReactEntityAutocompletePickerClassKey". +// src/components/EntityAutocompletePicker/EntityAutocompletePicker.d.ts:27:1 - (ae-undocumented) Missing documentation for "EntityAutocompletePicker". +// src/components/EntityKindPicker/EntityKindPicker.d.ts:13:5 - (ae-undocumented) Missing documentation for "initialFilter". +// src/components/EntityKindPicker/EntityKindPicker.d.ts:14:5 - (ae-undocumented) Missing documentation for "hidden". +// src/components/EntityKindPicker/EntityKindPicker.d.ts:17:22 - (ae-undocumented) Missing documentation for "EntityKindPicker". +// src/components/EntityLifecyclePicker/EntityLifecyclePicker.d.ts:3:1 - (ae-undocumented) Missing documentation for "CatalogReactEntityLifecyclePickerClassKey". +// src/components/EntityLifecyclePicker/EntityLifecyclePicker.d.ts:5:22 - (ae-undocumented) Missing documentation for "EntityLifecyclePicker". +// src/components/EntityNamespacePicker/EntityNamespacePicker.d.ts:3:1 - (ae-undocumented) Missing documentation for "CatalogReactEntityNamespacePickerClassKey". +// src/components/EntityNamespacePicker/EntityNamespacePicker.d.ts:10:5 - (ae-undocumented) Missing documentation for "initiallySelectedNamespaces". +// src/components/EntityNamespacePicker/EntityNamespacePicker.d.ts:13:22 - (ae-undocumented) Missing documentation for "EntityNamespacePicker". +// src/components/EntityOwnerPicker/EntityOwnerPicker.d.ts:3:1 - (ae-undocumented) Missing documentation for "CatalogReactEntityOwnerPickerClassKey". +// src/components/EntityOwnerPicker/EntityOwnerPicker.d.ts:5:1 - (ae-undocumented) Missing documentation for "FixedWidthFormControlLabelClassKey". +// src/components/EntityOwnerPicker/EntityOwnerPicker.d.ts:9:1 - (ae-undocumented) Missing documentation for "EntityOwnerPickerProps". +// src/components/EntityOwnerPicker/EntityOwnerPicker.d.ts:13:22 - (ae-undocumented) Missing documentation for "EntityOwnerPicker". +// src/components/EntityProcessingStatusPicker/EntityProcessingStatusPicker.d.ts:3:1 - (ae-undocumented) Missing documentation for "CatalogReactEntityProcessingStatusPickerClassKey". +// src/components/EntityProcessingStatusPicker/EntityProcessingStatusPicker.d.ts:5:22 - (ae-undocumented) Missing documentation for "EntityProcessingStatusPicker". +// src/components/EntityRefLink/humanize.d.ts:8:1 - (ae-undocumented) Missing documentation for "humanizeEntityRef". +// src/components/EntitySearchBar/EntitySearchBar.d.ts:3:1 - (ae-undocumented) Missing documentation for "CatalogReactEntitySearchBarClassKey". +// src/components/EntityTable/EntityTable.d.ts:10:5 - (ae-undocumented) Missing documentation for "title". +// src/components/EntityTable/EntityTable.d.ts:11:5 - (ae-undocumented) Missing documentation for "variant". +// src/components/EntityTable/EntityTable.d.ts:12:5 - (ae-undocumented) Missing documentation for "entities". +// src/components/EntityTable/EntityTable.d.ts:13:5 - (ae-undocumented) Missing documentation for "emptyContent". +// src/components/EntityTable/EntityTable.d.ts:14:5 - (ae-undocumented) Missing documentation for "columns". +// src/components/EntityTable/EntityTable.d.ts:15:5 - (ae-undocumented) Missing documentation for "tableOptions". +// src/components/EntityTable/columns.d.ts:4:22 - (ae-undocumented) Missing documentation for "columnFactories". +// src/components/EntityTagPicker/EntityTagPicker.d.ts:3:1 - (ae-undocumented) Missing documentation for "CatalogReactEntityTagPickerClassKey". +// src/components/EntityTagPicker/EntityTagPicker.d.ts:5:1 - (ae-undocumented) Missing documentation for "EntityTagPickerProps". +// src/components/EntityTagPicker/EntityTagPicker.d.ts:9:22 - (ae-undocumented) Missing documentation for "EntityTagPicker". +// src/components/EntityTypePicker/EntityTypePicker.d.ts:8:5 - (ae-undocumented) Missing documentation for "initialFilter". +// src/components/EntityTypePicker/EntityTypePicker.d.ts:9:5 - (ae-undocumented) Missing documentation for "hidden". +// src/components/EntityTypePicker/EntityTypePicker.d.ts:12:22 - (ae-undocumented) Missing documentation for "EntityTypePicker". +// src/components/FavoriteEntity/FavoriteEntity.d.ts:5:1 - (ae-undocumented) Missing documentation for "FavoriteEntityProps". +// src/components/MissingAnnotationEmptyState/MissingAnnotationEmptyState.d.ts:3:1 - (ae-undocumented) Missing documentation for "MissingAnnotationEmptyStateClassKey". +// src/components/UnregisterEntityDialog/UnregisterEntityDialog.d.ts:4:1 - (ae-undocumented) Missing documentation for "UnregisterEntityDialogProps". +// src/components/UnregisterEntityDialog/UnregisterEntityDialog.d.ts:11:22 - (ae-undocumented) Missing documentation for "UnregisterEntityDialog". +// src/components/UserListPicker/UserListPicker.d.ts:5:1 - (ae-undocumented) Missing documentation for "CatalogReactUserListPickerClassKey". +// src/components/UserListPicker/UserListPicker.d.ts:15:1 - (ae-undocumented) Missing documentation for "UserListPickerProps". +// src/components/UserListPicker/UserListPicker.d.ts:20:22 - (ae-undocumented) Missing documentation for "UserListPicker". +// src/filters.d.ts:8:5 - (ae-undocumented) Missing documentation for "value". +// src/filters.d.ts:10:5 - (ae-undocumented) Missing documentation for "getCatalogFilters". +// src/filters.d.ts:11:5 - (ae-undocumented) Missing documentation for "toQueryValue". +// src/filters.d.ts:18:5 - (ae-undocumented) Missing documentation for "value". +// src/filters.d.ts:20:5 - (ae-undocumented) Missing documentation for "getTypes". +// src/filters.d.ts:21:5 - (ae-undocumented) Missing documentation for "getCatalogFilters". +// src/filters.d.ts:22:5 - (ae-undocumented) Missing documentation for "toQueryValue". +// src/filters.d.ts:29:5 - (ae-undocumented) Missing documentation for "values". +// src/filters.d.ts:31:5 - (ae-undocumented) Missing documentation for "filterEntity". +// src/filters.d.ts:32:5 - (ae-undocumented) Missing documentation for "getCatalogFilters". +// src/filters.d.ts:33:5 - (ae-undocumented) Missing documentation for "toQueryValue". +// src/filters.d.ts:40:5 - (ae-undocumented) Missing documentation for "value". +// src/filters.d.ts:42:5 - (ae-undocumented) Missing documentation for "filterEntity". +// src/filters.d.ts:43:5 - (ae-undocumented) Missing documentation for "getFullTextFilters". +// src/filters.d.ts:47:5 - (ae-undocumented) Missing documentation for "toQueryValue". +// src/filters.d.ts:57:5 - (ae-undocumented) Missing documentation for "values". +// src/filters.d.ts:59:5 - (ae-undocumented) Missing documentation for "getCatalogFilters". +// src/filters.d.ts:60:5 - (ae-undocumented) Missing documentation for "filterEntity". +// src/filters.d.ts:72:5 - (ae-undocumented) Missing documentation for "values". +// src/filters.d.ts:74:5 - (ae-undocumented) Missing documentation for "getCatalogFilters". +// src/filters.d.ts:75:5 - (ae-undocumented) Missing documentation for "filterEntity". +// src/filters.d.ts:76:5 - (ae-undocumented) Missing documentation for "toQueryValue". +// src/filters.d.ts:83:5 - (ae-undocumented) Missing documentation for "values". +// src/filters.d.ts:85:5 - (ae-undocumented) Missing documentation for "getCatalogFilters". +// src/filters.d.ts:86:5 - (ae-undocumented) Missing documentation for "filterEntity". +// src/filters.d.ts:87:5 - (ae-undocumented) Missing documentation for "toQueryValue". +// src/filters.d.ts:92:1 - (ae-undocumented) Missing documentation for "EntityUserFilter". +// src/filters.d.ts:93:5 - (ae-undocumented) Missing documentation for "value". +// src/filters.d.ts:94:5 - (ae-undocumented) Missing documentation for "refs". +// src/filters.d.ts:96:5 - (ae-undocumented) Missing documentation for "owned". +// src/filters.d.ts:97:5 - (ae-undocumented) Missing documentation for "all". +// src/filters.d.ts:98:5 - (ae-undocumented) Missing documentation for "starred". +// src/filters.d.ts:99:5 - (ae-undocumented) Missing documentation for "getCatalogFilters". +// src/filters.d.ts:100:5 - (ae-undocumented) Missing documentation for "filterEntity". +// src/filters.d.ts:101:5 - (ae-undocumented) Missing documentation for "toQueryValue". +// src/filters.d.ts:109:5 - (ae-undocumented) Missing documentation for "value". +// src/filters.d.ts:110:5 - (ae-undocumented) Missing documentation for "isOwnedEntity". +// src/filters.d.ts:111:5 - (ae-undocumented) Missing documentation for "isStarredEntity". +// src/filters.d.ts:113:5 - (ae-undocumented) Missing documentation for "filterEntity". +// src/filters.d.ts:114:5 - (ae-undocumented) Missing documentation for "toQueryValue". +// src/filters.d.ts:121:5 - (ae-undocumented) Missing documentation for "value". +// src/filters.d.ts:123:5 - (ae-undocumented) Missing documentation for "getCatalogFilters". +// src/filters.d.ts:124:5 - (ae-undocumented) Missing documentation for "filterEntity". +// src/filters.d.ts:131:5 - (ae-undocumented) Missing documentation for "value". +// src/filters.d.ts:133:5 - (ae-undocumented) Missing documentation for "filterEntity". +// src/hooks/useEntity.d.ts:4:1 - (ae-undocumented) Missing documentation for "EntityLoadingStatus". +// src/hooks/useEntity.d.ts:16:5 - (ae-undocumented) Missing documentation for "children". +// src/hooks/useEntity.d.ts:17:5 - (ae-undocumented) Missing documentation for "entity". +// src/hooks/useEntity.d.ts:18:5 - (ae-undocumented) Missing documentation for "loading". +// src/hooks/useEntity.d.ts:19:5 - (ae-undocumented) Missing documentation for "error". +// src/hooks/useEntity.d.ts:20:5 - (ae-undocumented) Missing documentation for "refresh". +// src/hooks/useEntity.d.ts:34:5 - (ae-undocumented) Missing documentation for "children". +// src/hooks/useEntity.d.ts:35:5 - (ae-undocumented) Missing documentation for "entity". +// src/hooks/useEntityListProvider.d.ts:6:1 - (ae-undocumented) Missing documentation for "DefaultEntityFilters". +// src/hooks/useEntityListProvider.d.ts:19:1 - (ae-undocumented) Missing documentation for "PaginationMode". +// src/hooks/useEntityListProvider.d.ts:21:1 - (ae-undocumented) Missing documentation for "EntityListContextProps". +// src/hooks/useEntityListProvider.d.ts:65:1 - (ae-undocumented) Missing documentation for "EntityListProviderProps". +// src/hooks/useStarredEntities.d.ts:3:1 - (ae-undocumented) Missing documentation for "useStarredEntities". +// src/hooks/useStarredEntity.d.ts:3:1 - (ae-undocumented) Missing documentation for "useStarredEntity". +// src/overridableComponents.d.ts:6:1 - (ae-undocumented) Missing documentation for "CatalogReactComponentsNameToClassKey". +// src/overridableComponents.d.ts:19:1 - (ae-undocumented) Missing documentation for "BackstageOverrides". +// src/testUtils/providers.d.ts:4:1 - (ae-undocumented) Missing documentation for "MockEntityListContextProvider". +// src/types.d.ts:3:1 - (ae-undocumented) Missing documentation for "EntityFilter". +// src/types.d.ts:25:1 - (ae-undocumented) Missing documentation for "UserListFilterKind". +// src/types.d.ts:27:1 - (ae-undocumented) Missing documentation for "EntityListPagination". +// src/utils/getEntitySourceLocation.d.ts:4:1 - (ae-undocumented) Missing documentation for "EntitySourceLocation". +// src/utils/getEntitySourceLocation.d.ts:9:1 - (ae-undocumented) Missing documentation for "getEntitySourceLocation". ``` diff --git a/plugins/catalog-react/src/alpha/blueprints/EntityCardBlueprint.test.tsx b/plugins/catalog-react/src/alpha/blueprints/EntityCardBlueprint.test.tsx index 2ab87b20ae..9f012f6055 100644 --- a/plugins/catalog-react/src/alpha/blueprints/EntityCardBlueprint.test.tsx +++ b/plugins/catalog-react/src/alpha/blueprints/EntityCardBlueprint.test.tsx @@ -63,7 +63,6 @@ describe('EntityCardBlueprint', () => { "inputs": {}, "kind": "entity-card", "name": "test", - "namespace": undefined, "output": [ [Function], { diff --git a/plugins/catalog-react/src/alpha/blueprints/EntityContentBlueprint.test.tsx b/plugins/catalog-react/src/alpha/blueprints/EntityContentBlueprint.test.tsx index cc86f01501..0b5873b6b3 100644 --- a/plugins/catalog-react/src/alpha/blueprints/EntityContentBlueprint.test.tsx +++ b/plugins/catalog-react/src/alpha/blueprints/EntityContentBlueprint.test.tsx @@ -71,7 +71,6 @@ describe('EntityContentBlueprint', () => { "inputs": {}, "kind": "entity-content", "name": "test", - "namespace": undefined, "output": [ [Function], [Function], diff --git a/plugins/catalog-react/src/components/EntityLifecyclePicker/EntityLifecyclePicker.tsx b/plugins/catalog-react/src/components/EntityLifecyclePicker/EntityLifecyclePicker.tsx index 2d8a0dea32..6af5bc2b08 100644 --- a/plugins/catalog-react/src/components/EntityLifecyclePicker/EntityLifecyclePicker.tsx +++ b/plugins/catalog-react/src/components/EntityLifecyclePicker/EntityLifecyclePicker.tsx @@ -28,9 +28,7 @@ const useStyles = makeStyles( { input: {}, }, - { - name: 'CatalogReactEntityLifecyclePicker', - }, + { name: 'CatalogReactEntityLifecyclePicker' }, ); /** @public */ diff --git a/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.tsx b/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.tsx index 1b78630f9e..565472b152 100644 --- a/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.tsx +++ b/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.tsx @@ -58,11 +58,12 @@ const useStyles = makeStyles( overflow: 'hidden', }, }, - { - name: 'CatalogReactEntityOwnerPicker', - }, + { name: 'CatalogReactEntityOwnerPicker' }, ); +/** @public */ +export type FixedWidthFormControlLabelClassKey = 'label' | 'root'; + const FixedWidthFormControlLabel = withStyles( _theme => ({ label: { diff --git a/plugins/catalog-react/src/components/EntityOwnerPicker/index.ts b/plugins/catalog-react/src/components/EntityOwnerPicker/index.ts index 8685d838cd..80caf828d9 100644 --- a/plugins/catalog-react/src/components/EntityOwnerPicker/index.ts +++ b/plugins/catalog-react/src/components/EntityOwnerPicker/index.ts @@ -18,4 +18,5 @@ export { EntityOwnerPicker } from './EntityOwnerPicker'; export type { CatalogReactEntityOwnerPickerClassKey, EntityOwnerPickerProps, + FixedWidthFormControlLabelClassKey, } from './EntityOwnerPicker'; diff --git a/plugins/catalog-react/src/components/EntityProcessingStatusPicker/EntityProcessingStatusPicker.tsx b/plugins/catalog-react/src/components/EntityProcessingStatusPicker/EntityProcessingStatusPicker.tsx index 20190a9907..76b7aa1885 100644 --- a/plugins/catalog-react/src/components/EntityProcessingStatusPicker/EntityProcessingStatusPicker.tsx +++ b/plugins/catalog-react/src/components/EntityProcessingStatusPicker/EntityProcessingStatusPicker.tsx @@ -39,9 +39,7 @@ const useStyles = makeStyles( input: {}, label: {}, }, - { - name: 'CatalogReactEntityProcessingStatusPickerPicker', - }, + { name: 'CatalogReactEntityProcessingStatusPickerPicker' }, ); const icon = ; diff --git a/plugins/catalog-react/src/components/EntityRefLink/EntityRefLink.tsx b/plugins/catalog-react/src/components/EntityRefLink/EntityRefLink.tsx index c5af47e870..10aa1976f5 100644 --- a/plugins/catalog-react/src/components/EntityRefLink/EntityRefLink.tsx +++ b/plugins/catalog-react/src/components/EntityRefLink/EntityRefLink.tsx @@ -39,6 +39,7 @@ export type EntityRefLinkProps = { title?: string; children?: React.ReactNode; hideIcon?: boolean; + disableTooltip?: boolean; } & Omit; /** @@ -55,6 +56,7 @@ export const EntityRefLink = forwardRef( title, children, hideIcon, + disableTooltip, ...linkProps } = props; const entityRoute = useEntityRoute(props.entityRef); @@ -65,6 +67,7 @@ export const EntityRefLink = forwardRef( defaultKind={defaultKind} defaultNamespace={defaultNamespace} hideIcon={hideIcon} + disableTooltip={disableTooltip} /> ); diff --git a/plugins/catalog-react/src/components/EntitySearchBar/EntitySearchBar.tsx b/plugins/catalog-react/src/components/EntitySearchBar/EntitySearchBar.tsx index abde5430bc..5239387d2b 100644 --- a/plugins/catalog-react/src/components/EntitySearchBar/EntitySearchBar.tsx +++ b/plugins/catalog-react/src/components/EntitySearchBar/EntitySearchBar.tsx @@ -40,9 +40,7 @@ const useStyles = makeStyles( }, input: {}, }), - { - name: 'CatalogReactEntitySearchBar', - }, + { name: 'CatalogReactEntitySearchBar' }, ); /** diff --git a/plugins/catalog-react/src/components/FavoriteEntity/FavoriteEntity.tsx b/plugins/catalog-react/src/components/FavoriteEntity/FavoriteEntity.tsx index ab674ff98e..f0d59247ad 100644 --- a/plugins/catalog-react/src/components/FavoriteEntity/FavoriteEntity.tsx +++ b/plugins/catalog-react/src/components/FavoriteEntity/FavoriteEntity.tsx @@ -16,26 +16,17 @@ import { Entity, stringifyEntityRef } from '@backstage/catalog-model'; import IconButton from '@material-ui/core/IconButton'; -import Tooltip from '@material-ui/core/Tooltip'; -import { withStyles } from '@material-ui/core/styles'; -import Star from '@material-ui/icons/Star'; -import StarBorder from '@material-ui/icons/StarBorder'; import React, { ComponentProps } from 'react'; import { useStarredEntity } from '../../hooks/useStarredEntity'; import { catalogReactTranslationRef } from '../../translation'; import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; +import { FavoriteToggle } from '@backstage/core-components'; /** @public */ export type FavoriteEntityProps = ComponentProps & { entity: Entity; }; -const YellowStar = withStyles({ - root: { - color: '#f3ba37', - }, -})(Star); - /** * IconButton for showing if a current entity is starred and adding/removing it from the favorite entities * @param props - MaterialUI IconButton props extended by required `entity` prop @@ -56,16 +47,12 @@ export const FavoriteEntity = (props: FavoriteEntityProps) => { )}`; return ( - toggleStarredEntity()} - > - - {isStarredEntity ? : } - - + /> ); }; diff --git a/plugins/catalog-react/src/components/UserListPicker/UserListPicker.tsx b/plugins/catalog-react/src/components/UserListPicker/UserListPicker.tsx index c6b515aa67..ce61229891 100644 --- a/plugins/catalog-react/src/components/UserListPicker/UserListPicker.tsx +++ b/plugins/catalog-react/src/components/UserListPicker/UserListPicker.tsx @@ -28,7 +28,7 @@ import MenuItem from '@material-ui/core/MenuItem'; import Typography from '@material-ui/core/Typography'; import { makeStyles } from '@material-ui/core/styles'; import SettingsIcon from '@material-ui/icons/Settings'; -import StarIcon from '@material-ui/icons/Star'; +import { StarIcon } from '@backstage/core-components'; import React, { Fragment, useEffect, useMemo, useState } from 'react'; import { EntityUserFilter } from '../../filters'; import { useEntityList } from '../../hooks'; @@ -74,9 +74,7 @@ const useStyles = makeStyles( margin: theme.spacing(1, 1, 2, 1), }, }), - { - name: 'CatalogReactUserListPicker', - }, + { name: 'CatalogReactUserListPicker' }, ); export type ButtonGroup = { diff --git a/plugins/catalog-react/src/hooks/index.ts b/plugins/catalog-react/src/hooks/index.ts index c3021f8992..befcce520d 100644 --- a/plugins/catalog-react/src/hooks/index.ts +++ b/plugins/catalog-react/src/hooks/index.ts @@ -33,6 +33,7 @@ export type { DefaultEntityFilters, EntityListContextProps, EntityListProviderProps, + PaginationMode, } from './useEntityListProvider'; export { useEntityTypeFilter } from './useEntityTypeFilter'; export { useRelatedEntities } from './useRelatedEntities'; diff --git a/plugins/catalog-react/src/hooks/useEntityListProvider.test.tsx b/plugins/catalog-react/src/hooks/useEntityListProvider.test.tsx index 9afa81e2dd..762fba1897 100644 --- a/plugins/catalog-react/src/hooks/useEntityListProvider.test.tsx +++ b/plugins/catalog-react/src/hooks/useEntityListProvider.test.tsx @@ -31,7 +31,7 @@ import qs from 'qs'; import React, { PropsWithChildren } from 'react'; import { MemoryRouter } from 'react-router-dom'; import { catalogApiRef } from '../api'; -import { starredEntitiesApiRef, MockStarredEntitiesApi } from '../apis'; +import { MockStarredEntitiesApi, starredEntitiesApiRef } from '../apis'; import { EntityKindFilter, EntityTextFilter, @@ -42,6 +42,7 @@ import { EntityListProvider, useEntityList } from './useEntityListProvider'; import { useMountEffect } from '@react-hookz/web'; import { translationApiRef } from '@backstage/core-plugin-api/alpha'; import { MockTranslationApi } from '@backstage/test-utils/alpha'; +import { EntityListPagination } from '../types'; const entities: Entity[] = [ { @@ -91,7 +92,7 @@ const mockCatalogApi: Partial> = { }; const createWrapper = - (options: { location?: string; pagination: boolean }) => + (options: { location?: string; pagination: EntityListPagination }) => (props: PropsWithChildren) => { const InitialFiltersWrapper = ({ children }: PropsWithChildren) => { const { updateFilters } = useEntityList(); @@ -556,3 +557,232 @@ describe('', () => { }); }); }); + +describe('', () => { + const origReplaceState = window.history.replaceState; + const pagination: EntityListPagination = { mode: 'offset' }; + const limit = 20; + const orderFields = [{ field: 'metadata.name', order: 'asc' }]; + + beforeEach(() => { + window.history.replaceState = jest.fn(); + }); + afterEach(() => { + window.history.replaceState = origReplaceState; + }); + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('sends search text to the backend', async () => { + const { result } = renderHook(() => useEntityList(), { + wrapper: createWrapper({ pagination }), + initialProps: { + userFilter: 'all', + }, + }); + + act(() => + result.current.updateFilters({ + text: new EntityTextFilter('2'), + }), + ); + + await waitFor(() => { + expect(mockCatalogApi.getEntities).not.toHaveBeenCalledTimes(1); + expect(result.current.entities.length).toBe(1); + expect(mockCatalogApi.queryEntities).toHaveBeenCalledTimes(1); + expect(mockCatalogApi.queryEntities).toHaveBeenCalledWith({ + filter: { kind: 'component' }, + limit, + orderFields, + fullTextFilter: { + term: '2', + fields: [ + 'metadata.name', + 'metadata.title', + 'spec.profile.displayName', + ], + }, + }); + }); + }); + + it('should send backend filters', async () => { + const { result } = renderHook(() => useEntityList(), { + wrapper: createWrapper({ pagination }), + }); + + await waitFor(() => { + expect(result.current.backendEntities.length).toBe(2); + }); + + expect(result.current.entities.length).toBe(2); + expect(mockCatalogApi.queryEntities).toHaveBeenCalledTimes(1); + expect(mockCatalogApi.queryEntities).toHaveBeenCalledWith({ + filter: { kind: 'component' }, + limit, + orderFields, + }); + }); + + it('resolves frontend filters', async () => { + const { result } = renderHook(() => useEntityList(), { + wrapper: createWrapper({ pagination }), + initialProps: { + userFilter: 'all', + }, + }); + + act(() => + result.current.updateFilters({ + user: EntityUserFilter.owned(ownershipEntityRefs), + }), + ); + + await waitFor(() => { + expect(result.current.backendEntities.length).toBe(2); + expect(result.current.entities.length).toBe(1); + expect(mockCatalogApi.queryEntities).toHaveBeenCalledTimes(1); + }); + }); + + it('resolves query param filter values', async () => { + const query = qs.stringify({ + filters: { kind: 'component', type: 'service' }, + }); + const { result } = renderHook(() => useEntityList(), { + wrapper: createWrapper({ + location: `/catalog?${query}`, + pagination, + }), + }); + + await waitFor(() => { + expect(result.current.queryParameters).toBeTruthy(); + }); + expect(result.current.queryParameters).toEqual({ + kind: 'component', + type: 'service', + }); + }); + + it('fetch when frontend filters change', async () => { + const { result } = renderHook(() => useEntityList(), { + wrapper: createWrapper({ pagination }), + }); + + await waitFor(() => { + expect(result.current.entities.length).toBe(2); + expect(mockCatalogApi.queryEntities).toHaveBeenCalledTimes(1); + }); + + act(() => + result.current.updateFilters({ + user: EntityUserFilter.owned(ownershipEntityRefs), + }), + ); + + await waitFor(() => { + expect(result.current.entities.length).toBe(1); + }); + + await waitFor(() => { + expect(mockCatalogApi.queryEntities).toHaveBeenCalledTimes(2); + }); + }); + + it('fetch when limit change', async () => { + const { result } = renderHook(() => useEntityList(), { + wrapper: createWrapper({ pagination }), + }); + + await waitFor(() => { + expect(result.current.entities.length).toBe(2); + expect(mockCatalogApi.queryEntities).toHaveBeenCalledTimes(1); + }); + + act(() => result.current.setLimit(50)); + + await waitFor(() => { + expect(result.current.entities.length).toBe(2); + }); + + await waitFor(() => { + expect(mockCatalogApi.queryEntities).toHaveBeenCalledTimes(2); + expect(result.current.limit).toEqual(50); + }); + }); + + it('debounces multiple filter changes', async () => { + const { result } = renderHook(() => useEntityList(), { + wrapper: createWrapper({ pagination }), + }); + + await waitFor(() => { + expect(result.current.backendEntities.length).toBeGreaterThan(0); + }); + expect(result.current.backendEntities.length).toBe(2); + expect(mockCatalogApi.queryEntities).toHaveBeenCalledTimes(1); + + await act(async () => { + result.current.updateFilters({ kind: new EntityKindFilter('api') }); + result.current.updateFilters({ type: new EntityTypeFilter('service') }); + }); + + await waitFor(() => { + expect(mockCatalogApi.queryEntities).toHaveBeenNthCalledWith(2, { + filter: { kind: 'api', 'spec.type': ['service'] }, + limit, + orderFields, + }); + }); + }); + + it('debounces multiple offset changes', async () => { + const { result } = renderHook(() => useEntityList(), { + wrapper: createWrapper({ pagination }), + }); + + await waitFor(() => { + expect(result.current.backendEntities.length).toBeGreaterThan(0); + }); + expect(result.current.backendEntities.length).toBe(2); + expect(mockCatalogApi.queryEntities).toHaveBeenCalledTimes(1); + + await act(async () => { + result.current.setOffset!(5); + result.current.setOffset!(10); + }); + + await waitFor(() => { + expect(mockCatalogApi.queryEntities).toHaveBeenNthCalledWith(2, { + filter: { kind: 'component' }, + limit, + offset: 10, + orderFields, + }); + expect(result.current.offset).toEqual(10); + }); + }); + + it('returns an error on catalogApi failure', async () => { + const { result } = renderHook(() => useEntityList(), { + wrapper: createWrapper({ pagination }), + }); + + await waitFor(() => { + expect(result.current.backendEntities.length).toBeGreaterThan(0); + }); + expect(result.current.backendEntities.length).toBe(2); + + mockCatalogApi.queryEntities!.mockRejectedValueOnce('error'); + act(() => { + result.current.updateFilters({ kind: new EntityKindFilter('api') }); + }); + await waitFor(() => { + expect(result.current.error).toBeDefined(); + }); + }); +}); diff --git a/plugins/catalog-react/src/hooks/useEntityListProvider.tsx b/plugins/catalog-react/src/hooks/useEntityListProvider.tsx index da2a37381c..274ec52a18 100644 --- a/plugins/catalog-react/src/hooks/useEntityListProvider.tsx +++ b/plugins/catalog-react/src/hooks/useEntityListProvider.tsx @@ -34,16 +34,16 @@ import { EntityErrorFilter, EntityKindFilter, EntityLifecycleFilter, + EntityNamespaceFilter, EntityOrphanFilter, EntityOwnerFilter, EntityTagFilter, EntityTextFilter, EntityTypeFilter, - UserListFilter, - EntityNamespaceFilter, EntityUserFilter, + UserListFilter, } from '../filters'; -import { EntityFilter } from '../types'; +import { EntityFilter, EntityListPagination } from '../types'; import { reduceBackendCatalogFilters, reduceCatalogFilters, @@ -66,6 +66,9 @@ export type DefaultEntityFilters = { namespace?: EntityNamespaceFilter; }; +/** @public */ +export type PaginationMode = 'cursor' | 'offset' | 'none'; + /** @public */ export type EntityListContextProps< EntityFilters extends DefaultEntityFilters = DefaultEntityFilters, @@ -108,8 +111,12 @@ export type EntityListContextProps< next?: () => void; prev?: () => void; }; - totalItems?: number; + limit: number; + offset?: number; + setLimit: (limit: number) => void; + setOffset?: (offset: number) => void; + paginationMode: PaginationMode; }; /** @@ -127,13 +134,15 @@ type OutputState = { backendEntities: Entity[]; pageInfo?: QueryEntitiesResponse['pageInfo']; totalItems?: number; + offset?: number; + limit?: number; }; /** * @public */ export type EntityListProviderProps = PropsWithChildren<{ - pagination?: boolean | { limit?: number }; + pagination?: EntityListPagination; }>; /** @@ -155,31 +164,62 @@ export const EntityListProvider = ( // update of the URL or two catalog sidebar links with different catalog filters. const location = useLocation(); - const enablePagination = - props.pagination === true || typeof props.pagination === 'object'; + const getPaginationMode = (): PaginationMode => { + if (props.pagination === true) { + return 'cursor'; + } + return typeof props.pagination === 'object' + ? props.pagination.mode ?? 'cursor' + : 'none'; + }; - const limit = - props.pagination && - typeof props.pagination === 'object' && - typeof props.pagination.limit === 'number' - ? props.pagination.limit - : 20; + const paginationMode: PaginationMode = getPaginationMode(); + const paginationLimit = + typeof props.pagination === 'object' ? props.pagination.limit ?? 20 : 20; - const { queryParameters, cursor: initialCursor } = useMemo(() => { + const { + queryParameters, + cursor: initialCursor, + offset: initialOffset, + limit: initialLimit, + } = useMemo(() => { const parsed = qs.parse(location.search, { ignoreQueryPrefix: true, }); + let limit = paginationLimit; + if (typeof parsed.limit === 'string') { + const queryLimit = Number.parseInt(parsed.limit, 10); + if (!isNaN(queryLimit)) { + limit = queryLimit; + } + } + + const offset = + typeof parsed.offset === 'string' && paginationMode === 'offset' + ? Number.parseInt(parsed.offset, 10) + : undefined; + return { queryParameters: (parsed.filters ?? {}) as Record< string, string | string[] >, - cursor: typeof parsed.cursor === 'string' ? parsed.cursor : undefined, + cursor: + typeof parsed.cursor === 'string' && paginationMode === 'cursor' + ? parsed.cursor + : undefined, + offset: + paginationMode === 'offset' && offset && !isNaN(offset) + ? offset + : undefined, + limit, }; - }, [location]); + }, [paginationMode, location.search, paginationLimit]); const [cursor, setCursor] = useState(initialCursor); + const [offset, setOffset] = useState(initialOffset); + const [limit, setLimit] = useState(initialLimit); const [outputState, setOutputState] = useState>( () => { @@ -187,7 +227,9 @@ export const EntityListProvider = ( appliedFilters: {} as EntityFilters, entities: [], backendEntities: [], - pageInfo: enablePagination ? {} : undefined, + pageInfo: paginationMode === 'cursor' ? {} : undefined, + offset, + limit, }; }, ); @@ -212,7 +254,7 @@ export const EntityListProvider = ( {} as Record, ); - if (enablePagination) { + if (paginationMode !== 'none') { if (cursor) { if (cursor !== outputState.appliedCursor) { const entityFilter = reduceEntityFilters(compacted); @@ -236,10 +278,14 @@ export const EntityListProvider = ( compact(Object.values(outputState.appliedFilters)), ); - if (!isEqual(previousBackendFilter, backendFilter)) { + if ( + paginationMode === 'offset' || + !isEqual(previousBackendFilter, backendFilter) + ) { const response = await catalogApi.queryEntities({ ...backendFilter, limit, + offset, orderFields: [{ field: 'metadata.name', order: 'asc' }], }); setOutputState({ @@ -248,6 +294,8 @@ export const EntityListProvider = ( entities: response.items.filter(entityFilter), pageInfo: response.pageInfo, totalItems: response.totalItems, + limit, + offset, }); } } @@ -290,7 +338,7 @@ export const EntityListProvider = ( ignoreQueryPrefix: true, }); const newParams = qs.stringify( - { ...oldParams, filters: queryParams, cursor }, + { ...oldParams, filters: queryParams, cursor, offset, limit }, { addQueryPrefix: true, arrayFormat: 'repeat' }, ); const newUrl = `${window.location.pathname}${newParams}`; @@ -308,14 +356,16 @@ export const EntityListProvider = ( requestedFilters, outputState, cursor, - enablePagination, + paginationMode, + limit, + offset, ], { loading: true }, ); // Slight debounce on the refresh, since (especially on page load) several // filters will be calling this in rapid succession. - useDebounce(refresh, 10, [requestedFilters, cursor]); + useDebounce(refresh, 10, [requestedFilters, cursor, limit, offset]); const updateFilters = useCallback( ( @@ -339,7 +389,7 @@ export const EntityListProvider = ( ); const pageInfo = useMemo(() => { - if (!enablePagination) { + if (paginationMode !== 'cursor') { return undefined; } @@ -349,7 +399,7 @@ export const EntityListProvider = ( prev: prevCursor ? () => setCursor(prevCursor) : undefined, next: nextCursor ? () => setCursor(nextCursor) : undefined, }; - }, [enablePagination, outputState.pageInfo]); + }, [paginationMode, outputState.pageInfo]); const value = useMemo( () => ({ @@ -362,8 +412,25 @@ export const EntityListProvider = ( error, pageInfo, totalItems: outputState.totalItems, + limit, + offset, + setLimit, + setOffset, + paginationMode, }), - [outputState, updateFilters, queryParameters, loading, error, pageInfo], + [ + outputState, + updateFilters, + queryParameters, + loading, + error, + pageInfo, + limit, + offset, + paginationMode, + setLimit, + setOffset, + ], ); return ( diff --git a/plugins/catalog-react/src/overridableComponents.ts b/plugins/catalog-react/src/overridableComponents.ts index b45fd30103..1b27a350da 100644 --- a/plugins/catalog-react/src/overridableComponents.ts +++ b/plugins/catalog-react/src/overridableComponents.ts @@ -25,6 +25,8 @@ import { CatalogReactEntityTagPickerClassKey, CatalogReactEntityOwnerPickerClassKey, CatalogReactEntityProcessingStatusPickerClassKey, + FixedWidthFormControlLabelClassKey, + MissingAnnotationEmptyStateClassKey, } from './components'; import { CatalogReactEntityAutocompletePickerClassKey } from './components/EntityAutocompletePicker/EntityAutocompletePicker'; @@ -36,8 +38,10 @@ export type CatalogReactComponentsNameToClassKey = { CatalogReactEntitySearchBar: CatalogReactEntitySearchBarClassKey; CatalogReactEntityTagPicker: CatalogReactEntityTagPickerClassKey; CatalogReactEntityOwnerPicker: CatalogReactEntityOwnerPickerClassKey; + CatalogReactFixedWidthFormControlLabel: FixedWidthFormControlLabelClassKey; CatalogReactEntityProcessingStatusPicker: CatalogReactEntityProcessingStatusPickerClassKey; CatalogReactEntityAutocompletePickerClassKey: CatalogReactEntityAutocompletePickerClassKey; + CatalogReactMissingAnnotationEmptyState: MissingAnnotationEmptyStateClassKey; }; /** @public */ diff --git a/plugins/catalog-react/src/testUtils/providers.tsx b/plugins/catalog-react/src/testUtils/providers.tsx index 6b88168207..9bb46dc6e5 100644 --- a/plugins/catalog-react/src/testUtils/providers.tsx +++ b/plugins/catalog-react/src/testUtils/providers.tsx @@ -73,6 +73,11 @@ export function MockEntityListContextProvider< error: value?.error, totalItems: value?.totalItems ?? (value?.entities ?? defaultValues.entities).length, + limit: value?.limit ?? 20, + offset: value?.offset, + setLimit: value?.setLimit ?? (() => {}), + setOffset: value?.setOffset, + paginationMode: value?.paginationMode ?? 'none', }), [value, defaultValues, filters, updateFilters], ); diff --git a/plugins/catalog-react/src/types.ts b/plugins/catalog-react/src/types.ts index 41c7d75f0d..57b21b634e 100644 --- a/plugins/catalog-react/src/types.ts +++ b/plugins/catalog-react/src/types.ts @@ -46,3 +46,9 @@ export type EntityFilter = { /** @public */ export type UserListFilterKind = 'owned' | 'starred' | 'all'; + +/** @public */ +export type EntityListPagination = + | boolean + | { mode?: 'cursor'; limit?: number } + | { mode: 'offset'; limit?: number; offset?: number }; diff --git a/plugins/catalog-unprocessed-entities-common/api-report.md b/plugins/catalog-unprocessed-entities-common/report.api.md similarity index 100% rename from plugins/catalog-unprocessed-entities-common/api-report.md rename to plugins/catalog-unprocessed-entities-common/report.api.md diff --git a/plugins/catalog-unprocessed-entities/CHANGELOG.md b/plugins/catalog-unprocessed-entities/CHANGELOG.md index 74cab9fbfb..583596b119 100644 --- a/plugins/catalog-unprocessed-entities/CHANGELOG.md +++ b/plugins/catalog-unprocessed-entities/CHANGELOG.md @@ -1,5 +1,53 @@ # @backstage/plugin-catalog-unprocessed-entities +## 0.2.9-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/catalog-model@1.7.0 + - @backstage/errors@1.2.4 + +## 0.2.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/errors@1.2.4 + +## 0.2.8 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- 4f08c85: Show additional info on DevTools unprocessed entities table + + - Location path (so that it's easier to search the failed entity from the YAML URL) + - Time info of last discovery and next refresh time so that users can be aware of it and can sort the errors based on the time. + +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/catalog-model@1.7.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/errors@1.2.4 + +## 0.2.8-next.1 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/errors@1.2.4 + ## 0.2.8-next.0 ### Patch Changes diff --git a/plugins/catalog-unprocessed-entities/package.json b/plugins/catalog-unprocessed-entities/package.json index ed3c14655e..a6e034c894 100644 --- a/plugins/catalog-unprocessed-entities/package.json +++ b/plugins/catalog-unprocessed-entities/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-unprocessed-entities", - "version": "0.2.8-next.0", + "version": "0.2.9-next.1", "backstage": { "role": "frontend-plugin", "pluginId": "catalog-unprocessed-entities", @@ -44,7 +44,6 @@ "@material-ui/core": "^4.9.13", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "^4.0.0-alpha.60", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "luxon": "^3.5.0", "react-use": "^17.2.4" }, @@ -52,11 +51,21 @@ "@backstage/cli": "workspace:^", "@backstage/dev-utils": "workspace:^", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^15.0.0" + "@testing-library/react": "^16.0.0", + "@types/react": "^18.0.0", + "react": "^18.0.2", + "react-dom": "^18.0.2", + "react-router-dom": "^6.3.0" }, "peerDependencies": { + "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } } diff --git a/plugins/catalog-unprocessed-entities/api-report.md b/plugins/catalog-unprocessed-entities/report.api.md similarity index 91% rename from plugins/catalog-unprocessed-entities/api-report.md rename to plugins/catalog-unprocessed-entities/report.api.md index 7d8f6299da..dd0386204a 100644 --- a/plugins/catalog-unprocessed-entities/api-report.md +++ b/plugins/catalog-unprocessed-entities/report.api.md @@ -73,5 +73,9 @@ export type UnprocessedEntityError = { }; }; +// Warnings were encountered during analysis: +// +// src/components/UnprocessedEntities.d.ts:3:22 - (ae-undocumented) Missing documentation for "UnprocessedEntitiesContent". + // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/catalog/CHANGELOG.md b/plugins/catalog/CHANGELOG.md index 5aa877ad13..c11a203b84 100644 --- a/plugins/catalog/CHANGELOG.md +++ b/plugins/catalog/CHANGELOG.md @@ -1,5 +1,112 @@ # @backstage/plugin-catalog +## 1.24.0-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/frontend-plugin-api@0.9.0-next.1 + - @backstage/integration-react@1.2.0-next.1 + - @backstage/core-compat-api@0.3.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/plugin-permission-react@0.4.27-next.1 + - @backstage/plugin-catalog-react@1.14.0-next.1 + - @backstage/plugin-search-react@1.8.1-next.1 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-scaffolder-common@1.5.6 + - @backstage/plugin-search-common@1.2.14 + +## 1.24.0-next.0 + +### Minor Changes + +- 71f9f0c: Updated default columns for location entities to remove description and tags from the catalog table view. + +### Patch Changes + +- 46b5a20: Empty states updated with external link icon for learn more links +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/core-compat-api@0.3.1-next.0 + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/plugin-catalog-react@1.13.1-next.0 + - @backstage/plugin-search-react@1.8.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.32-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-permission-react@0.4.27-next.0 + - @backstage/plugin-scaffolder-common@1.5.6 + - @backstage/plugin-search-common@1.2.14 + +## 1.23.0 + +### Minor Changes + +- 78475c3: Allow offset mode paging in entity list provider + +### Patch Changes + +- c891b69: Add `FavoriteToggle` in `core-components` to standardise favorite marking +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- 5446061: The `/alpha` export no longer export extension creators for the new frontend system, existing usage should be switched to use the equivalent extension blueprint instead. For more information see the [new frontend system 1.30 migration documentation](https://backstage.io/docs/frontend-system/architecture/migrations#130). +- 0ff53c8: Enable loading state for paginated catalog tables by passing `isLoading` prop +- 180a45f: Entity presentation api now only fetches fields that are required to display entity title +- a159180: Added missing items to `overridableComponents` +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/plugin-catalog-react@1.13.0 + - @backstage/frontend-plugin-api@0.8.0 + - @backstage/core-compat-api@0.3.0 + - @backstage/plugin-search-react@1.8.0 + - @backstage/integration-react@1.1.31 + - @backstage/catalog-model@1.7.0 + - @backstage/catalog-client@1.7.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/plugin-permission-react@0.4.26 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.6 + - @backstage/plugin-search-common@1.2.14 + +## 1.23.0-next.2 + +### Minor Changes + +- 78475c3: Allow offset mode paging in entity list provider + +### Patch Changes + +- c891b69: Add `FavoriteToggle` in `core-components` to standardise favorite marking +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/plugin-catalog-react@1.13.0-next.2 + - @backstage/integration-react@1.1.31-next.0 + - @backstage/catalog-client@1.7.0-next.1 + - @backstage/plugin-search-react@1.8.0-next.2 + - @backstage/core-compat-api@0.3.0-next.2 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/frontend-plugin-api@0.8.0-next.2 + - @backstage/plugin-permission-react@0.4.26-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-scaffolder-common@1.5.5 + - @backstage/plugin-search-common@1.2.14 + ## 1.22.1-next.1 ### Patch Changes diff --git a/plugins/catalog/package.json b/plugins/catalog/package.json index 50e897be8d..e85ce75182 100644 --- a/plugins/catalog/package.json +++ b/plugins/catalog/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog", - "version": "1.22.1-next.1", + "version": "1.24.0-next.1", "description": "The Backstage plugin for browsing the Backstage catalog", "backstage": { "role": "frontend-plugin", @@ -77,7 +77,6 @@ "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.61", "@mui/utils": "^5.14.15", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "dataloader": "^2.0.0", "expiry-map": "^2.0.0", "history": "^5.0.0", @@ -95,15 +94,25 @@ "@backstage/test-utils": "workspace:^", "@testing-library/dom": "^10.0.0", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^15.0.0", + "@testing-library/react": "^16.0.0", "@testing-library/user-event": "^14.0.0", "@types/pluralize": "^0.0.33", + "@types/react": "^18.0.0", + "react": "^18.0.2", + "react-dom": "^18.0.2", + "react-router-dom": "^6.3.0", "swr": "^2.2.5" }, "peerDependencies": { + "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-router-dom": "6.0.0-beta.0 || ^6.3.0" }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + }, "configSchema": "config.d.ts" } diff --git a/plugins/catalog/api-report-alpha.md b/plugins/catalog/report-alpha.api.md similarity index 88% rename from plugins/catalog/api-report-alpha.md rename to plugins/catalog/report-alpha.api.md index 62e631dd4a..b7fa14d003 100644 --- a/plugins/catalog/api-report-alpha.md +++ b/plugins/catalog/report-alpha.api.md @@ -20,12 +20,12 @@ import { JSX as JSX_2 } from 'react'; import { RouteRef } from '@backstage/frontend-plugin-api'; import { SearchResultItemExtensionComponent } from '@backstage/plugin-search-react/alpha'; import { SearchResultItemExtensionPredicate } from '@backstage/plugin-search-react/alpha'; +import { SearchResultListItemBlueprintParams } from '@backstage/plugin-search-react/alpha'; import { TranslationRef } from '@backstage/core-plugin-api/alpha'; // @alpha export const CatalogFilterBlueprint: ExtensionBlueprint<{ kind: 'catalog-filter'; - namespace: undefined; name: undefined; params: { loader: () => Promise; @@ -113,7 +113,7 @@ export const catalogTranslationRef: TranslationRef< readonly 'hasSubdomainsCard.emptyMessage': 'No subdomain is part of this domain'; readonly 'hasSystemsCard.title': 'Has systems'; readonly 'hasSystemsCard.emptyMessage': 'No system is part of this domain'; - readonly 'relatedEntitiesCard.emptyHelpLinkTitle': 'Learn how to change this.'; + readonly 'relatedEntitiesCard.emptyHelpLinkTitle': 'Learn how to change this'; readonly 'systemDiagramCard.title': 'System Diagram'; readonly 'systemDiagramCard.description': 'Use pinch & zoo to move around the diagram.'; readonly 'systemDiagramCard.edgeLabels.dependsOn': 'depends on'; @@ -148,7 +148,6 @@ const _default: FrontendPlugin< { 'api:catalog': ExtensionDefinition<{ kind: 'api'; - namespace: undefined; name: undefined; config: {}; configInput: {}; @@ -158,10 +157,12 @@ const _default: FrontendPlugin< {} >; inputs: {}; + params: { + factory: AnyApiFactory; + }; }>; 'nav-item:catalog': ExtensionDefinition<{ kind: 'nav-item'; - namespace: undefined; name: undefined; config: {}; configInput: {}; @@ -175,10 +176,14 @@ const _default: FrontendPlugin< {} >; inputs: {}; + params: { + title: string; + icon: IconComponent; + routeRef: RouteRef; + }; }>; 'api:catalog/starred-entities': ExtensionDefinition<{ kind: 'api'; - namespace: undefined; name: 'starred-entities'; config: {}; configInput: {}; @@ -188,10 +193,12 @@ const _default: FrontendPlugin< {} >; inputs: {}; + params: { + factory: AnyApiFactory; + }; }>; 'api:catalog/entity-presentation': ExtensionDefinition<{ kind: 'api'; - namespace: undefined; name: 'entity-presentation'; config: {}; configInput: {}; @@ -201,10 +208,12 @@ const _default: FrontendPlugin< {} >; inputs: {}; + params: { + factory: AnyApiFactory; + }; }>; 'entity-card:catalog/about': ExtensionDefinition<{ kind: 'entity-card'; - namespace: undefined; name: 'about'; config: { filter: string | undefined; @@ -229,10 +238,13 @@ const _default: FrontendPlugin< } >; inputs: {}; + params: { + loader: () => Promise; + filter?: string | ((entity: Entity) => boolean) | undefined; + }; }>; 'entity-card:catalog/links': ExtensionDefinition<{ kind: 'entity-card'; - namespace: undefined; name: 'links'; config: { filter: string | undefined; @@ -257,10 +269,13 @@ const _default: FrontendPlugin< } >; inputs: {}; + params: { + loader: () => Promise; + filter?: string | ((entity: Entity) => boolean) | undefined; + }; }>; 'entity-card:catalog/labels': ExtensionDefinition<{ kind: 'entity-card'; - namespace: undefined; name: 'labels'; config: { filter: string | undefined; @@ -285,10 +300,13 @@ const _default: FrontendPlugin< } >; inputs: {}; + params: { + loader: () => Promise; + filter?: string | ((entity: Entity) => boolean) | undefined; + }; }>; 'entity-card:catalog/depends-on-components': ExtensionDefinition<{ kind: 'entity-card'; - namespace: undefined; name: 'depends-on-components'; config: { filter: string | undefined; @@ -313,10 +331,13 @@ const _default: FrontendPlugin< } >; inputs: {}; + params: { + loader: () => Promise; + filter?: string | ((entity: Entity) => boolean) | undefined; + }; }>; 'entity-card:catalog/depends-on-resources': ExtensionDefinition<{ kind: 'entity-card'; - namespace: undefined; name: 'depends-on-resources'; config: { filter: string | undefined; @@ -341,10 +362,13 @@ const _default: FrontendPlugin< } >; inputs: {}; + params: { + loader: () => Promise; + filter?: string | ((entity: Entity) => boolean) | undefined; + }; }>; 'entity-card:catalog/has-components': ExtensionDefinition<{ kind: 'entity-card'; - namespace: undefined; name: 'has-components'; config: { filter: string | undefined; @@ -369,10 +393,13 @@ const _default: FrontendPlugin< } >; inputs: {}; + params: { + loader: () => Promise; + filter?: string | ((entity: Entity) => boolean) | undefined; + }; }>; 'entity-card:catalog/has-resources': ExtensionDefinition<{ kind: 'entity-card'; - namespace: undefined; name: 'has-resources'; config: { filter: string | undefined; @@ -397,10 +424,13 @@ const _default: FrontendPlugin< } >; inputs: {}; + params: { + loader: () => Promise; + filter?: string | ((entity: Entity) => boolean) | undefined; + }; }>; 'entity-card:catalog/has-subcomponents': ExtensionDefinition<{ kind: 'entity-card'; - namespace: undefined; name: 'has-subcomponents'; config: { filter: string | undefined; @@ -425,10 +455,13 @@ const _default: FrontendPlugin< } >; inputs: {}; + params: { + loader: () => Promise; + filter?: string | ((entity: Entity) => boolean) | undefined; + }; }>; 'entity-card:catalog/has-subdomains': ExtensionDefinition<{ kind: 'entity-card'; - namespace: undefined; name: 'has-subdomains'; config: { filter: string | undefined; @@ -453,10 +486,13 @@ const _default: FrontendPlugin< } >; inputs: {}; + params: { + loader: () => Promise; + filter?: string | ((entity: Entity) => boolean) | undefined; + }; }>; 'entity-card:catalog/has-systems': ExtensionDefinition<{ kind: 'entity-card'; - namespace: undefined; name: 'has-systems'; config: { filter: string | undefined; @@ -481,6 +517,10 @@ const _default: FrontendPlugin< } >; inputs: {}; + params: { + loader: () => Promise; + filter?: string | ((entity: Entity) => boolean) | undefined; + }; }>; 'entity-content:catalog/overview': ExtensionDefinition<{ config: { @@ -546,12 +586,17 @@ const _default: FrontendPlugin< >; }; kind: 'entity-content'; - namespace: undefined; name: 'overview'; + params: { + loader: () => Promise; + defaultPath: string; + defaultTitle: string; + routeRef?: RouteRef | undefined; + filter?: string | ((entity: Entity) => boolean) | undefined; + }; }>; 'catalog-filter:catalog/tag': ExtensionDefinition<{ kind: 'catalog-filter'; - namespace: undefined; name: 'tag'; config: {}; configInput: {}; @@ -561,6 +606,9 @@ const _default: FrontendPlugin< {} >; inputs: {}; + params: { + loader: () => Promise; + }; }>; 'catalog-filter:catalog/kind': ExtensionDefinition<{ config: { @@ -584,12 +632,13 @@ const _default: FrontendPlugin< >; }; kind: 'catalog-filter'; - namespace: undefined; name: 'kind'; + params: { + loader: () => Promise; + }; }>; 'catalog-filter:catalog/type': ExtensionDefinition<{ kind: 'catalog-filter'; - namespace: undefined; name: 'type'; config: {}; configInput: {}; @@ -599,6 +648,9 @@ const _default: FrontendPlugin< {} >; inputs: {}; + params: { + loader: () => Promise; + }; }>; 'catalog-filter:catalog/mode': ExtensionDefinition<{ config: { @@ -622,12 +674,13 @@ const _default: FrontendPlugin< >; }; kind: 'catalog-filter'; - namespace: undefined; name: 'mode'; + params: { + loader: () => Promise; + }; }>; 'catalog-filter:catalog/namespace': ExtensionDefinition<{ kind: 'catalog-filter'; - namespace: undefined; name: 'namespace'; config: {}; configInput: {}; @@ -637,10 +690,12 @@ const _default: FrontendPlugin< {} >; inputs: {}; + params: { + loader: () => Promise; + }; }>; 'catalog-filter:catalog/lifecycle': ExtensionDefinition<{ kind: 'catalog-filter'; - namespace: undefined; name: 'lifecycle'; config: {}; configInput: {}; @@ -650,10 +705,12 @@ const _default: FrontendPlugin< {} >; inputs: {}; + params: { + loader: () => Promise; + }; }>; 'catalog-filter:catalog/processing-status': ExtensionDefinition<{ kind: 'catalog-filter'; - namespace: undefined; name: 'processing-status'; config: {}; configInput: {}; @@ -663,6 +720,9 @@ const _default: FrontendPlugin< {} >; inputs: {}; + params: { + loader: () => Promise; + }; }>; 'catalog-filter:catalog/list': ExtensionDefinition<{ config: { @@ -686,8 +746,10 @@ const _default: FrontendPlugin< >; }; kind: 'catalog-filter'; - namespace: undefined; name: 'list'; + params: { + loader: () => Promise; + }; }>; 'page:catalog': ExtensionDefinition<{ config: { @@ -716,8 +778,12 @@ const _default: FrontendPlugin< >; }; kind: 'page'; - namespace: undefined; name: undefined; + params: { + defaultPath: string; + loader: () => Promise; + routeRef?: RouteRef | undefined; + }; }>; 'page:catalog/entity': ExtensionDefinition<{ config: { @@ -773,12 +839,15 @@ const _default: FrontendPlugin< >; }; kind: 'page'; - namespace: undefined; name: 'entity'; + params: { + defaultPath: string; + loader: () => Promise; + routeRef?: RouteRef | undefined; + }; }>; 'search-result-list-item:catalog': ExtensionDefinition<{ kind: 'search-result-list-item'; - namespace: undefined; name: undefined; config: { noTrack: boolean; @@ -795,10 +864,16 @@ const _default: FrontendPlugin< {} >; inputs: {}; + params: SearchResultListItemBlueprintParams; }>; } >; export default _default; +// Warnings were encountered during analysis: +// +// src/alpha/plugin.d.ts:3:15 - (ae-undocumented) Missing documentation for "_default". +// src/alpha/translation.d.ts:2:22 - (ae-undocumented) Missing documentation for "catalogTranslationRef". + // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/catalog/api-report.md b/plugins/catalog/report.api.md similarity index 52% rename from plugins/catalog/api-report.md rename to plugins/catalog/report.api.md index 541cb08887..a7538900a0 100644 --- a/plugins/catalog/api-report.md +++ b/plugins/catalog/report.api.md @@ -12,6 +12,7 @@ import { ComponentEntity } from '@backstage/catalog-model'; import { CompoundEntityRef } from '@backstage/catalog-model'; import { Entity } from '@backstage/catalog-model'; import { EntityListContextProps } from '@backstage/plugin-catalog-react'; +import { EntityListPagination } from '@backstage/plugin-catalog-react'; import { EntityOwnerPickerProps } from '@backstage/plugin-catalog-react'; import { EntityPresentationApi } from '@backstage/plugin-catalog-react'; import { EntityRefPresentation } from '@backstage/plugin-catalog-react'; @@ -133,6 +134,12 @@ export const CatalogSearchResultListItem: ( props: SearchResultListItemExtensionProps, ) => JSX.Element | null; +// @public (undocumented) +export type CatalogSearchResultListItemClassKey = + | 'item' + | 'flexContainer' + | 'itemText'; + // @public export interface CatalogSearchResultListItemProps { // (undocumented) @@ -222,6 +229,9 @@ export interface CatalogTableRow { }; } +// @public (undocumented) +export type CatalogTableToolbarClassKey = 'root' | 'text'; + // @public (undocumented) export type ColumnBreakpoints = Record; @@ -244,11 +254,7 @@ export interface DefaultCatalogPageProps { // (undocumented) ownerPickerMode?: EntityOwnerPickerProps['mode']; // (undocumented) - pagination?: - | boolean - | { - limit?: number; - }; + pagination?: EntityListPagination; // (undocumented) tableOptions?: TableProps['options']; } @@ -259,7 +265,6 @@ export class DefaultEntityPresentationApi implements EntityPresentationApi { options: DefaultEntityPresentationApiOptions, ): EntityPresentationApi; static createLocal(): EntityPresentationApi; - // (undocumented) forEntity( entityOrRef: Entity | string, context?: { @@ -394,6 +399,9 @@ export interface EntityLabelsCardProps { variant?: InfoCardVariants; } +// @public (undocumented) +export type EntityLabelsEmptyStateClassKey = 'code'; + // @public export const EntityLayout: { (props: EntityLayoutProps): React_2.JSX.Element; @@ -629,6 +637,9 @@ export type PluginCatalogComponentsNameToClassKey = { PluginCatalogEntityLinksEmptyState: EntityLinksEmptyStateClassKey; PluginCatalogSystemDiagramCard: SystemDiagramCardClassKey; PluginCatalogEntityContextMenu: EntityContextMenuClassKey; + PluginCatalogSearchResultListItem: CatalogSearchResultListItemClassKey; + PluginCatalogTableToolbar: CatalogTableToolbarClassKey; + PluginCatalogEntityLabelsEmptyState: EntityLabelsEmptyStateClassKey; }; // @public (undocumented) @@ -656,4 +667,131 @@ export type SystemDiagramCardClassKey = | 'componentNode' | 'apiNode' | 'resourceNode'; + +// Warnings were encountered during analysis: +// +// src/apis/StarredEntitiesApi/DefaultStarredEntitiesApi.d.ts:15:5 - (ae-undocumented) Missing documentation for "toggleStarred". +// src/apis/StarredEntitiesApi/DefaultStarredEntitiesApi.d.ts:16:5 - (ae-undocumented) Missing documentation for "starredEntitie$". +// src/components/AboutCard/AboutCard.d.ts:9:5 - (ae-undocumented) Missing documentation for "variant". +// src/components/AboutCard/AboutContent.d.ts:9:5 - (ae-undocumented) Missing documentation for "entity". +// src/components/AboutCard/AboutContent.d.ts:12:1 - (ae-undocumented) Missing documentation for "AboutContent". +// src/components/AboutCard/AboutField.d.ts:8:5 - (ae-undocumented) Missing documentation for "label". +// src/components/AboutCard/AboutField.d.ts:9:5 - (ae-undocumented) Missing documentation for "value". +// src/components/AboutCard/AboutField.d.ts:10:5 - (ae-undocumented) Missing documentation for "gridSizes". +// src/components/AboutCard/AboutField.d.ts:11:5 - (ae-undocumented) Missing documentation for "children". +// src/components/AboutCard/AboutField.d.ts:14:1 - (ae-undocumented) Missing documentation for "AboutField". +// src/components/CatalogKindHeader/CatalogKindHeader.d.ts:23:1 - (ae-undocumented) Missing documentation for "CatalogKindHeader". +// src/components/CatalogPage/DefaultCatalogPage.d.ts:12:5 - (ae-undocumented) Missing documentation for "initiallySelectedFilter". +// src/components/CatalogPage/DefaultCatalogPage.d.ts:13:5 - (ae-undocumented) Missing documentation for "columns". +// src/components/CatalogPage/DefaultCatalogPage.d.ts:14:5 - (ae-undocumented) Missing documentation for "actions". +// src/components/CatalogPage/DefaultCatalogPage.d.ts:15:5 - (ae-undocumented) Missing documentation for "initialKind". +// src/components/CatalogPage/DefaultCatalogPage.d.ts:16:5 - (ae-undocumented) Missing documentation for "tableOptions". +// src/components/CatalogPage/DefaultCatalogPage.d.ts:17:5 - (ae-undocumented) Missing documentation for "emptyContent". +// src/components/CatalogPage/DefaultCatalogPage.d.ts:18:5 - (ae-undocumented) Missing documentation for "ownerPickerMode". +// src/components/CatalogPage/DefaultCatalogPage.d.ts:19:5 - (ae-undocumented) Missing documentation for "filters". +// src/components/CatalogPage/DefaultCatalogPage.d.ts:20:5 - (ae-undocumented) Missing documentation for "initiallySelectedNamespaces". +// src/components/CatalogPage/DefaultCatalogPage.d.ts:21:5 - (ae-undocumented) Missing documentation for "pagination". +// src/components/CatalogSearchResultListItem/CatalogSearchResultListItem.d.ts:4:1 - (ae-undocumented) Missing documentation for "CatalogSearchResultListItemClassKey". +// src/components/CatalogSearchResultListItem/CatalogSearchResultListItem.d.ts:11:5 - (ae-undocumented) Missing documentation for "icon". +// src/components/CatalogSearchResultListItem/CatalogSearchResultListItem.d.ts:12:5 - (ae-undocumented) Missing documentation for "result". +// src/components/CatalogSearchResultListItem/CatalogSearchResultListItem.d.ts:13:5 - (ae-undocumented) Missing documentation for "highlight". +// src/components/CatalogSearchResultListItem/CatalogSearchResultListItem.d.ts:14:5 - (ae-undocumented) Missing documentation for "rank". +// src/components/CatalogSearchResultListItem/CatalogSearchResultListItem.d.ts:15:5 - (ae-undocumented) Missing documentation for "lineClamp". +// src/components/CatalogTable/CatalogTable.d.ts:10:5 - (ae-undocumented) Missing documentation for "columns". +// src/components/CatalogTable/CatalogTable.d.ts:11:5 - (ae-undocumented) Missing documentation for "actions". +// src/components/CatalogTable/CatalogTable.d.ts:12:5 - (ae-undocumented) Missing documentation for "tableOptions". +// src/components/CatalogTable/CatalogTable.d.ts:13:5 - (ae-undocumented) Missing documentation for "emptyContent". +// src/components/CatalogTable/CatalogTable.d.ts:14:5 - (ae-undocumented) Missing documentation for "subtitle". +// src/components/CatalogTable/CatalogTable.d.ts:17:22 - (ae-undocumented) Missing documentation for "CatalogTable". +// src/components/CatalogTable/CatalogTableToolbar.d.ts:3:1 - (ae-undocumented) Missing documentation for "CatalogTableToolbarClassKey". +// src/components/CatalogTable/types.d.ts:5:1 - (ae-undocumented) Missing documentation for "CatalogTableRow". +// src/components/CatalogTable/types.d.ts:6:5 - (ae-undocumented) Missing documentation for "entity". +// src/components/CatalogTable/types.d.ts:7:5 - (ae-undocumented) Missing documentation for "resolved". +// src/components/DependencyOfComponentsCard/DependencyOfComponentsCard.d.ts:5:1 - (ae-undocumented) Missing documentation for "DependencyOfComponentsCardProps". +// src/components/DependencyOfComponentsCard/DependencyOfComponentsCard.d.ts:6:5 - (ae-undocumented) Missing documentation for "variant". +// src/components/DependencyOfComponentsCard/DependencyOfComponentsCard.d.ts:7:5 - (ae-undocumented) Missing documentation for "title". +// src/components/DependencyOfComponentsCard/DependencyOfComponentsCard.d.ts:8:5 - (ae-undocumented) Missing documentation for "columns". +// src/components/DependencyOfComponentsCard/DependencyOfComponentsCard.d.ts:9:5 - (ae-undocumented) Missing documentation for "tableOptions". +// src/components/DependsOnComponentsCard/DependsOnComponentsCard.d.ts:5:1 - (ae-undocumented) Missing documentation for "DependsOnComponentsCardProps". +// src/components/DependsOnComponentsCard/DependsOnComponentsCard.d.ts:6:5 - (ae-undocumented) Missing documentation for "variant". +// src/components/DependsOnComponentsCard/DependsOnComponentsCard.d.ts:7:5 - (ae-undocumented) Missing documentation for "title". +// src/components/DependsOnComponentsCard/DependsOnComponentsCard.d.ts:8:5 - (ae-undocumented) Missing documentation for "columns". +// src/components/DependsOnComponentsCard/DependsOnComponentsCard.d.ts:9:5 - (ae-undocumented) Missing documentation for "tableOptions". +// src/components/DependsOnResourcesCard/DependsOnResourcesCard.d.ts:5:1 - (ae-undocumented) Missing documentation for "DependsOnResourcesCardProps". +// src/components/DependsOnResourcesCard/DependsOnResourcesCard.d.ts:6:5 - (ae-undocumented) Missing documentation for "variant". +// src/components/DependsOnResourcesCard/DependsOnResourcesCard.d.ts:7:5 - (ae-undocumented) Missing documentation for "title". +// src/components/DependsOnResourcesCard/DependsOnResourcesCard.d.ts:8:5 - (ae-undocumented) Missing documentation for "columns". +// src/components/DependsOnResourcesCard/DependsOnResourcesCard.d.ts:9:5 - (ae-undocumented) Missing documentation for "tableOptions". +// src/components/EntityContextMenu/EntityContextMenu.d.ts:5:1 - (ae-undocumented) Missing documentation for "EntityContextMenuClassKey". +// src/components/EntityLabelsCard/EntityLabelsCard.d.ts:4:1 - (ae-undocumented) Missing documentation for "EntityLabelsCardProps". +// src/components/EntityLabelsCard/EntityLabelsCard.d.ts:5:5 - (ae-undocumented) Missing documentation for "variant". +// src/components/EntityLabelsCard/EntityLabelsCard.d.ts:6:5 - (ae-undocumented) Missing documentation for "title". +// src/components/EntityLabelsCard/EntityLabelsEmptyState.d.ts:3:1 - (ae-undocumented) Missing documentation for "EntityLabelsEmptyStateClassKey". +// src/components/EntityLayout/EntityLayout.d.ts:6:1 - (ae-undocumented) Missing documentation for "EntityLayoutRouteProps". +// src/components/EntityLayout/EntityLayout.d.ts:25:1 - (ae-undocumented) Missing documentation for "EntityLayoutProps". +// src/components/EntityLayout/EntityLayout.d.ts:26:5 - (ae-undocumented) Missing documentation for "UNSTABLE_extraContextMenuItems". +// src/components/EntityLayout/EntityLayout.d.ts:27:5 - (ae-undocumented) Missing documentation for "UNSTABLE_contextMenuOptions". +// src/components/EntityLayout/EntityLayout.d.ts:28:5 - (ae-undocumented) Missing documentation for "children". +// src/components/EntityLayout/EntityLayout.d.ts:29:5 - (ae-undocumented) Missing documentation for "NotFoundComponent". +// src/components/EntityLinksCard/EntityLinksCard.d.ts:5:1 - (ae-undocumented) Missing documentation for "EntityLinksCardProps". +// src/components/EntityLinksCard/EntityLinksCard.d.ts:6:5 - (ae-undocumented) Missing documentation for "cols". +// src/components/EntityLinksCard/EntityLinksCard.d.ts:7:5 - (ae-undocumented) Missing documentation for "variant". +// src/components/EntityLinksCard/EntityLinksEmptyState.d.ts:3:1 - (ae-undocumented) Missing documentation for "EntityLinksEmptyStateClassKey". +// src/components/EntityLinksCard/types.d.ts:2:1 - (ae-undocumented) Missing documentation for "Breakpoint". +// src/components/EntityLinksCard/types.d.ts:4:1 - (ae-undocumented) Missing documentation for "ColumnBreakpoints". +// src/components/EntitySwitch/EntitySwitch.d.ts:5:1 - (ae-undocumented) Missing documentation for "EntitySwitchCaseProps". +// src/components/EntitySwitch/EntitySwitch.d.ts:6:5 - (ae-undocumented) Missing documentation for "if". +// src/components/EntitySwitch/EntitySwitch.d.ts:9:5 - (ae-undocumented) Missing documentation for "children". +// src/components/EntitySwitch/EntitySwitch.d.ts:16:5 - (ae-undocumented) Missing documentation for "children". +// src/components/EntitySwitch/EntitySwitch.d.ts:17:5 - (ae-undocumented) Missing documentation for "renderMultipleMatches". +// src/components/EntitySwitch/EntitySwitch.d.ts:20:22 - (ae-undocumented) Missing documentation for "EntitySwitch". +// src/components/EntitySwitch/conditions.d.ts:3:1 - (ae-undocumented) Missing documentation for "EntityPredicates". +// src/components/EntitySwitch/conditions.d.ts:4:5 - (ae-undocumented) Missing documentation for "kind". +// src/components/EntitySwitch/conditions.d.ts:5:5 - (ae-undocumented) Missing documentation for "type". +// src/components/FilteredEntityLayout/index.d.ts:6:22 - (ae-undocumented) Missing documentation for "FilteredEntityLayout". +// src/components/FilteredEntityLayout/index.d.ts:13:22 - (ae-undocumented) Missing documentation for "FilterContainer". +// src/components/FilteredEntityLayout/index.d.ts:24:22 - (ae-undocumented) Missing documentation for "EntityListContainer". +// src/components/HasComponentsCard/HasComponentsCard.d.ts:5:1 - (ae-undocumented) Missing documentation for "HasComponentsCardProps". +// src/components/HasComponentsCard/HasComponentsCard.d.ts:6:5 - (ae-undocumented) Missing documentation for "variant". +// src/components/HasComponentsCard/HasComponentsCard.d.ts:7:5 - (ae-undocumented) Missing documentation for "title". +// src/components/HasComponentsCard/HasComponentsCard.d.ts:8:5 - (ae-undocumented) Missing documentation for "columns". +// src/components/HasComponentsCard/HasComponentsCard.d.ts:9:5 - (ae-undocumented) Missing documentation for "tableOptions". +// src/components/HasResourcesCard/HasResourcesCard.d.ts:5:1 - (ae-undocumented) Missing documentation for "HasResourcesCardProps". +// src/components/HasResourcesCard/HasResourcesCard.d.ts:6:5 - (ae-undocumented) Missing documentation for "variant". +// src/components/HasResourcesCard/HasResourcesCard.d.ts:7:5 - (ae-undocumented) Missing documentation for "title". +// src/components/HasResourcesCard/HasResourcesCard.d.ts:8:5 - (ae-undocumented) Missing documentation for "columns". +// src/components/HasResourcesCard/HasResourcesCard.d.ts:9:5 - (ae-undocumented) Missing documentation for "tableOptions". +// src/components/HasSubcomponentsCard/HasSubcomponentsCard.d.ts:5:1 - (ae-undocumented) Missing documentation for "HasSubcomponentsCardProps". +// src/components/HasSubcomponentsCard/HasSubcomponentsCard.d.ts:6:5 - (ae-undocumented) Missing documentation for "variant". +// src/components/HasSubcomponentsCard/HasSubcomponentsCard.d.ts:7:5 - (ae-undocumented) Missing documentation for "title". +// src/components/HasSubcomponentsCard/HasSubcomponentsCard.d.ts:8:5 - (ae-undocumented) Missing documentation for "columns". +// src/components/HasSubcomponentsCard/HasSubcomponentsCard.d.ts:9:5 - (ae-undocumented) Missing documentation for "tableOptions". +// src/components/HasSubdomainsCard/HasSubdomainsCard.d.ts:4:1 - (ae-undocumented) Missing documentation for "HasSubdomainsCardProps". +// src/components/HasSubdomainsCard/HasSubdomainsCard.d.ts:5:5 - (ae-undocumented) Missing documentation for "variant". +// src/components/HasSubdomainsCard/HasSubdomainsCard.d.ts:6:5 - (ae-undocumented) Missing documentation for "tableOptions". +// src/components/HasSubdomainsCard/HasSubdomainsCard.d.ts:7:5 - (ae-undocumented) Missing documentation for "title". +// src/components/HasSystemsCard/HasSystemsCard.d.ts:5:1 - (ae-undocumented) Missing documentation for "HasSystemsCardProps". +// src/components/HasSystemsCard/HasSystemsCard.d.ts:6:5 - (ae-undocumented) Missing documentation for "variant". +// src/components/HasSystemsCard/HasSystemsCard.d.ts:7:5 - (ae-undocumented) Missing documentation for "title". +// src/components/HasSystemsCard/HasSystemsCard.d.ts:8:5 - (ae-undocumented) Missing documentation for "columns". +// src/components/HasSystemsCard/HasSystemsCard.d.ts:9:5 - (ae-undocumented) Missing documentation for "tableOptions". +// src/components/RelatedEntitiesCard/RelatedEntitiesCard.d.ts:5:1 - (ae-undocumented) Missing documentation for "RelatedEntitiesCardProps". +// src/components/SystemDiagramCard/SystemDiagramCard.d.ts:3:1 - (ae-undocumented) Missing documentation for "SystemDiagramCardClassKey". +// src/overridableComponents.d.ts:10:1 - (ae-undocumented) Missing documentation for "PluginCatalogComponentsNameToClassKey". +// src/overridableComponents.d.ts:19:1 - (ae-undocumented) Missing documentation for "BackstageOverrides". +// src/plugin.d.ts:17:22 - (ae-undocumented) Missing documentation for "catalogPlugin". +// src/plugin.d.ts:38:22 - (ae-undocumented) Missing documentation for "CatalogIndexPage". +// src/plugin.d.ts:40:22 - (ae-undocumented) Missing documentation for "CatalogEntityPage". +// src/plugin.d.ts:55:22 - (ae-undocumented) Missing documentation for "EntityLinksCard". +// src/plugin.d.ts:57:22 - (ae-undocumented) Missing documentation for "EntityLabelsCard". +// src/plugin.d.ts:59:22 - (ae-undocumented) Missing documentation for "EntityHasSystemsCard". +// src/plugin.d.ts:61:22 - (ae-undocumented) Missing documentation for "EntityHasComponentsCard". +// src/plugin.d.ts:63:22 - (ae-undocumented) Missing documentation for "EntityHasSubcomponentsCard". +// src/plugin.d.ts:65:22 - (ae-undocumented) Missing documentation for "EntityHasSubdomainsCard". +// src/plugin.d.ts:67:22 - (ae-undocumented) Missing documentation for "EntityHasResourcesCard". +// src/plugin.d.ts:69:22 - (ae-undocumented) Missing documentation for "EntityDependsOnComponentsCard". +// src/plugin.d.ts:71:22 - (ae-undocumented) Missing documentation for "EntityDependencyOfComponentsCard". +// src/plugin.d.ts:73:22 - (ae-undocumented) Missing documentation for "EntityDependsOnResourcesCard". +// src/plugin.d.ts:75:22 - (ae-undocumented) Missing documentation for "RelatedEntitiesCard". +// src/plugin.d.ts:77:22 - (ae-undocumented) Missing documentation for "CatalogSearchResultListItem". ``` diff --git a/plugins/catalog/src/alpha/blueprints/CatalogFilterBlueprint.test.tsx b/plugins/catalog/src/alpha/blueprints/CatalogFilterBlueprint.test.tsx index 9e3616ff8c..ef7490f030 100644 --- a/plugins/catalog/src/alpha/blueprints/CatalogFilterBlueprint.test.tsx +++ b/plugins/catalog/src/alpha/blueprints/CatalogFilterBlueprint.test.tsx @@ -47,7 +47,6 @@ describe('CatalogFilterBlueprint', () => { "inputs": {}, "kind": "catalog-filter", "name": undefined, - "namespace": undefined, "output": [ [Function], ], diff --git a/plugins/catalog/src/alpha/translation.ts b/plugins/catalog/src/alpha/translation.ts index f38a34be84..e5e6fa18e2 100644 --- a/plugins/catalog/src/alpha/translation.ts +++ b/plugins/catalog/src/alpha/translation.ts @@ -152,7 +152,7 @@ export const catalogTranslationRef = createTranslationRef({ emptyMessage: 'No system is part of this domain', }, relatedEntitiesCard: { - emptyHelpLinkTitle: 'Learn how to change this.', + emptyHelpLinkTitle: 'Learn how to change this', }, systemDiagramCard: { title: 'System Diagram', diff --git a/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx b/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx index a46a552b8d..366427d33d 100644 --- a/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx +++ b/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx @@ -26,26 +26,26 @@ import { import { configApiRef, useApi, useRouteRef } from '@backstage/core-plugin-api'; import { CatalogFilterLayout, + DefaultFilters, + EntityListPagination, EntityListProvider, - UserListFilterKind, EntityOwnerPickerProps, + UserListFilterKind, } from '@backstage/plugin-catalog-react'; import React, { ReactNode } from 'react'; import { createComponentRouteRef } from '../../routes'; import { CatalogTable, CatalogTableRow } from '../CatalogTable'; import { catalogTranslationRef } from '../../alpha/translation'; import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; - import { CatalogTableColumnsFunc } from '../CatalogTable/types'; import { catalogEntityCreatePermission } from '@backstage/plugin-catalog-common/alpha'; import { usePermission } from '@backstage/plugin-permission-react'; -import { DefaultFilters } from '@backstage/plugin-catalog-react'; /** @internal */ export type BaseCatalogPageProps = { filters: ReactNode; content?: ReactNode; - pagination?: boolean | { limit?: number }; + pagination?: EntityListPagination; }; /** @internal */ @@ -95,9 +95,9 @@ export interface DefaultCatalogPageProps { tableOptions?: TableProps['options']; emptyContent?: ReactNode; ownerPickerMode?: EntityOwnerPickerProps['mode']; - pagination?: boolean | { limit?: number }; filters?: ReactNode; initiallySelectedNamespaces?: string[]; + pagination?: EntityListPagination; } export function DefaultCatalogPage(props: DefaultCatalogPageProps) { diff --git a/plugins/catalog/src/components/CatalogSearchResultListItem/CatalogSearchResultListItem.tsx b/plugins/catalog/src/components/CatalogSearchResultListItem/CatalogSearchResultListItem.tsx index f4501bd795..a2722c8b33 100644 --- a/plugins/catalog/src/components/CatalogSearchResultListItem/CatalogSearchResultListItem.tsx +++ b/plugins/catalog/src/components/CatalogSearchResultListItem/CatalogSearchResultListItem.tsx @@ -30,6 +30,12 @@ import { HighlightedSearchResultText } from '@backstage/plugin-search-react'; import { catalogTranslationRef } from '../../alpha/translation'; import { useTranslationRef } from '@backstage/frontend-plugin-api'; +/** @public */ +export type CatalogSearchResultListItemClassKey = + | 'item' + | 'flexContainer' + | 'itemText'; + const useStyles = makeStyles( { item: { diff --git a/plugins/catalog/src/components/CatalogSearchResultListItem/index.ts b/plugins/catalog/src/components/CatalogSearchResultListItem/index.ts index ba0e6d29be..47af0e32b2 100644 --- a/plugins/catalog/src/components/CatalogSearchResultListItem/index.ts +++ b/plugins/catalog/src/components/CatalogSearchResultListItem/index.ts @@ -15,4 +15,7 @@ */ export { CatalogSearchResultListItem } from './CatalogSearchResultListItem'; -export type { CatalogSearchResultListItemProps } from './CatalogSearchResultListItem'; +export type { + CatalogSearchResultListItemProps, + CatalogSearchResultListItemClassKey, +} from './CatalogSearchResultListItem'; diff --git a/plugins/catalog/src/components/CatalogTable/CatalogTable.test.tsx b/plugins/catalog/src/components/CatalogTable/CatalogTable.test.tsx index 35639069df..fea2580d2f 100644 --- a/plugins/catalog/src/components/CatalogTable/CatalogTable.test.tsx +++ b/plugins/catalog/src/components/CatalogTable/CatalogTable.test.tsx @@ -222,14 +222,7 @@ describe('CatalogTable component', () => { }, { kind: 'location', - expectedColumns: [ - 'Name', - 'Type', - 'Targets', - 'Description', - 'Tags', - 'Actions', - ], + expectedColumns: ['Name', 'Type', 'Targets', 'Actions'], }, { kind: 'resource', diff --git a/plugins/catalog/src/components/CatalogTable/CatalogTable.tsx b/plugins/catalog/src/components/CatalogTable/CatalogTable.tsx index 1026dc5d26..2d5e78a0d6 100644 --- a/plugins/catalog/src/components/CatalogTable/CatalogTable.tsx +++ b/plugins/catalog/src/components/CatalogTable/CatalogTable.tsx @@ -35,21 +35,20 @@ import { useStarredEntities, } from '@backstage/plugin-catalog-react'; import Typography from '@material-ui/core/Typography'; -import { withStyles } from '@material-ui/core/styles'; import { visuallyHidden } from '@mui/utils'; import Edit from '@material-ui/icons/Edit'; import OpenInNew from '@material-ui/icons/OpenInNew'; -import Star from '@material-ui/icons/Star'; -import StarBorder from '@material-ui/icons/StarBorder'; import { capitalize } from 'lodash'; import pluralize from 'pluralize'; import React, { ReactNode, useMemo } from 'react'; import { columnFactories } from './columns'; import { CatalogTableColumnsFunc, CatalogTableRow } from './types'; -import { PaginatedCatalogTable } from './PaginatedCatalogTable'; +import { OffsetPaginatedCatalogTable } from './OffsetPaginatedCatalogTable'; +import { CursorPaginatedCatalogTable } from './CursorPaginatedCatalogTable'; import { defaultCatalogTableColumnsFunc } from './defaultCatalogTableColumnsFunc'; import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; import { catalogTranslationRef } from '../../alpha/translation'; +import { FavoriteToggleIcon } from '@backstage/core-components'; /** * Props for {@link CatalogTable}. @@ -64,12 +63,6 @@ export interface CatalogTableProps { subtitle?: string; } -const YellowStar = withStyles({ - root: { - color: '#f3ba37', - }, -})(Star); - const refCompare = (a: Entity, b: Entity) => { const toRef = (entity: Entity) => entity.metadata.title || @@ -90,9 +83,17 @@ export const CatalogTable = (props: CatalogTableProps) => { } = props; const { isStarredEntity, toggleStarredEntity } = useStarredEntities(); const entityListContext = useEntityList(); - const { loading, error, entities, filters, pageInfo, totalItems } = - entityListContext; - const enablePagination = !!pageInfo; + + const { + loading, + error, + entities, + filters, + pageInfo, + totalItems, + paginationMode, + } = entityListContext; + const tableColumns = useMemo( () => typeof columns === 'function' ? columns(entityListContext) : columns, @@ -160,12 +161,7 @@ export const CatalogTable = (props: CatalogTableProps) => { return { cellStyle: { paddingLeft: '1em' }, - icon: () => ( - <> - {title} - {isStarred ? : } - - ), + icon: () => , tooltip: title, onClick: () => toggleStarredEntity(entity), }; @@ -195,9 +191,24 @@ export const CatalogTable = (props: CatalogTableProps) => { ...tableOptions, }; - if (enablePagination) { + if (paginationMode === 'cursor') { return ( - + ); + } else if (paginationMode === 'offset') { + return ( + { subtitle={subtitle} options={options} data={entities.map(toEntityRow)} - next={pageInfo.next} - prev={pageInfo.prev} /> ); } diff --git a/plugins/catalog/src/components/CatalogTable/CatalogTableToolbar.tsx b/plugins/catalog/src/components/CatalogTable/CatalogTableToolbar.tsx index 16d9923727..077319a7f0 100644 --- a/plugins/catalog/src/components/CatalogTable/CatalogTableToolbar.tsx +++ b/plugins/catalog/src/components/CatalogTable/CatalogTableToolbar.tsx @@ -19,6 +19,9 @@ import Toolbar from '@material-ui/core/Toolbar'; import Typography from '@material-ui/core/Typography'; import { makeStyles } from '@material-ui/core/styles'; +/** @public */ +export type CatalogTableToolbarClassKey = 'root' | 'text'; + const useToolbarStyles = makeStyles( theme => ({ root: { @@ -34,7 +37,7 @@ const useToolbarStyles = makeStyles( textOverflow: 'ellipsis', }, }), - { name: 'BackstageTableToolbar' }, + { name: 'PluginCatalogTableToolbar' }, ); export function CatalogTableToolbar(props: { diff --git a/plugins/catalog/src/components/CatalogTable/PaginatedCatalogTable.test.tsx b/plugins/catalog/src/components/CatalogTable/CursorPaginatedCatalogTable.test.tsx similarity index 87% rename from plugins/catalog/src/components/CatalogTable/PaginatedCatalogTable.test.tsx rename to plugins/catalog/src/components/CatalogTable/CursorPaginatedCatalogTable.test.tsx index c96fe0e067..be250fddbf 100644 --- a/plugins/catalog/src/components/CatalogTable/PaginatedCatalogTable.test.tsx +++ b/plugins/catalog/src/components/CatalogTable/CursorPaginatedCatalogTable.test.tsx @@ -14,19 +14,18 @@ * limitations under the License. */ import React, { ReactNode } from 'react'; -import { fireEvent, waitFor } from '@testing-library/react'; -import { PaginatedCatalogTable } from './PaginatedCatalogTable'; -import { screen } from '@testing-library/react'; +import { fireEvent, screen, waitFor } from '@testing-library/react'; +import { CursorPaginatedCatalogTable } from './CursorPaginatedCatalogTable'; import { CatalogTableRow } from './types'; import { renderInTestApp } from '@backstage/test-utils'; import { - EntityKindFilter, - MockEntityListContextProvider, DefaultEntityFilters, + EntityKindFilter, EntityListContextProps, + MockEntityListContextProvider, } from '@backstage/plugin-catalog-react'; -describe('PaginatedCatalogTable', () => { +describe('CursorPaginatedCatalogTable', () => { const data = new Array(100).fill(0).map((_, index) => { const name = `component-${index}`; return { @@ -65,7 +64,9 @@ describe('PaginatedCatalogTable', () => { it('should display all the items', async () => { await renderInTestApp( - wrapInContext(), + wrapInContext( + , + ), ); for (const item of data) { @@ -76,7 +77,7 @@ describe('PaginatedCatalogTable', () => { it('should display and invoke the next button', async () => { const { rerender } = await renderInTestApp( wrapInContext( - { rerender( wrapInContext( - , + , ), ); @@ -108,7 +109,7 @@ describe('PaginatedCatalogTable', () => { it('should display and invoke the prev button', async () => { const { rerender } = await renderInTestApp( wrapInContext( - { rerender( wrapInContext( - , + , ), ); @@ -148,7 +149,7 @@ describe('PaginatedCatalogTable', () => { }, }} > - ); diff --git a/plugins/catalog/src/components/CatalogTable/OffsetPaginatedCatalogTable.test.tsx b/plugins/catalog/src/components/CatalogTable/OffsetPaginatedCatalogTable.test.tsx new file mode 100644 index 0000000000..3c8f51a6ad --- /dev/null +++ b/plugins/catalog/src/components/CatalogTable/OffsetPaginatedCatalogTable.test.tsx @@ -0,0 +1,109 @@ +/* + * 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, { ReactNode } from 'react'; +import { fireEvent, screen } from '@testing-library/react'; +import { CatalogTableRow } from './types'; +import { renderInTestApp } from '@backstage/test-utils'; +import { + DefaultEntityFilters, + EntityListContextProps, + MockEntityListContextProvider, +} from '@backstage/plugin-catalog-react'; +import { OffsetPaginatedCatalogTable } from './OffsetPaginatedCatalogTable'; + +describe('OffsetPaginatedCatalogTable', () => { + const data = new Array(100).fill(0).map((_, index) => { + const name = `component-${index}`; + return { + entity: { + apiVersion: '1', + kind: 'component', + metadata: { + name, + }, + }, + resolved: { + name, + entityRef: 'component:default/component', + }, + } as CatalogTableRow; + }); + + const columns = [ + { + title: 'Title', + field: 'entity.metadata.name', + searchable: true, + }, + ]; + + const wrapInContext = ( + node: ReactNode, + value?: Partial>, + ) => { + return ( + + {node} + + ); + }; + + it('should display all the items', async () => { + await renderInTestApp( + wrapInContext( + , + { + setOffset: jest.fn(), + limit: Number.MAX_SAFE_INTEGER, + offset: 0, + totalItems: data.length, + }, + ), + ); + + for (const item of data) { + expect(screen.queryByText(item.resolved.name)).toBeInTheDocument(); + } + }); + + it('should display and invoke the next and previous buttons', async () => { + const offsetFn = jest.fn(); + + await renderInTestApp( + wrapInContext( + , + { setOffset: offsetFn, limit: 10, totalItems: data.length, offset: 0 }, + ), + ); + + expect(offsetFn).toHaveBeenNthCalledWith(1, 0); + const nextButton = screen.queryAllByRole('button', { + name: 'Next Page', + })[0]; + expect(nextButton).toBeEnabled(); + + fireEvent.click(nextButton); + expect(offsetFn).toHaveBeenNthCalledWith(2, 10); + + const prevButton = screen.queryAllByRole('button', { + name: 'Previous Page', + })[0]; + expect(prevButton).toBeEnabled(); + + fireEvent.click(prevButton); + expect(offsetFn).toHaveBeenNthCalledWith(3, 0); + }); +}); diff --git a/plugins/catalog/src/components/CatalogTable/OffsetPaginatedCatalogTable.tsx b/plugins/catalog/src/components/CatalogTable/OffsetPaginatedCatalogTable.tsx new file mode 100644 index 0000000000..0faa0043a1 --- /dev/null +++ b/plugins/catalog/src/components/CatalogTable/OffsetPaginatedCatalogTable.tsx @@ -0,0 +1,74 @@ +/* + * 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, { useEffect } from 'react'; + +import { Table, TableProps } from '@backstage/core-components'; +import { CatalogTableRow } from './types'; +import { + EntityTextFilter, + useEntityList, +} from '@backstage/plugin-catalog-react'; + +/** + * @internal + */ +export function OffsetPaginatedCatalogTable( + props: TableProps, +) { + const { columns, data, isLoading } = props; + const { updateFilters, setLimit, setOffset, limit, totalItems, offset } = + useEntityList(); + const [page, setPage] = React.useState( + offset && limit ? Math.floor(offset / limit) : 0, + ); + + useEffect(() => { + if (totalItems && page * limit >= totalItems) { + setOffset!(Math.max(0, totalItems - limit)); + } else { + setOffset!(Math.max(0, page * limit)); + } + }, [setOffset, page, limit, totalItems]); + + return ( + + updateFilters({ + text: searchText ? new EntityTextFilter(searchText) : undefined, + }) + } + page={page} + onPageChange={newPage => { + setPage(newPage); + }} + onRowsPerPageChange={pageSize => { + setLimit(pageSize); + }} + totalCount={totalItems} + localization={{ pagination: { labelDisplayedRows: '' } }} + isLoading={isLoading} + /> + ); +} diff --git a/plugins/catalog/src/components/CatalogTable/defaultCatalogTableColumnsFunc.tsx b/plugins/catalog/src/components/CatalogTable/defaultCatalogTableColumnsFunc.tsx index 85f44d3f51..54dd701770 100644 --- a/plugins/catalog/src/components/CatalogTable/defaultCatalogTableColumnsFunc.tsx +++ b/plugins/catalog/src/components/CatalogTable/defaultCatalogTableColumnsFunc.tsx @@ -31,11 +31,13 @@ export const defaultCatalogTableColumnsFunc: CatalogTableColumnsFunc = ({ columnFactories.createTitleColumn({ hidden: true }), columnFactories.createNameColumn({ defaultKind: filters.kind?.value }), ...createEntitySpecificColumns(), - columnFactories.createMetadataDescriptionColumn(), - columnFactories.createTagsColumn(), ]; function createEntitySpecificColumns(): TableColumn[] { + const descriptionTagColumns = [ + columnFactories.createMetadataDescriptionColumn(), + columnFactories.createTagsColumn(), + ]; const baseColumns = [ columnFactories.createSystemColumn(), columnFactories.createOwnerColumn(), @@ -44,14 +46,15 @@ export const defaultCatalogTableColumnsFunc: CatalogTableColumnsFunc = ({ ]; switch (filters.kind?.value) { case 'user': - return []; + return [...descriptionTagColumns]; case 'domain': case 'system': - return [columnFactories.createOwnerColumn()]; + return [columnFactories.createOwnerColumn(), ...descriptionTagColumns]; case 'group': case 'template': return [ columnFactories.createSpecTypeColumn({ hidden: !showTypeColumn }), + ...descriptionTagColumns, ]; case 'location': return [ @@ -60,8 +63,12 @@ export const defaultCatalogTableColumnsFunc: CatalogTableColumnsFunc = ({ ]; default: return entities.every(entity => entity.metadata.namespace === 'default') - ? baseColumns - : [...baseColumns, columnFactories.createNamespaceColumn()]; + ? [...baseColumns, ...descriptionTagColumns] + : [ + ...baseColumns, + columnFactories.createNamespaceColumn(), + ...descriptionTagColumns, + ]; } } }; diff --git a/plugins/catalog/src/components/CatalogTable/index.ts b/plugins/catalog/src/components/CatalogTable/index.ts index f5d1ca1bb7..ac9871cdbd 100644 --- a/plugins/catalog/src/components/CatalogTable/index.ts +++ b/plugins/catalog/src/components/CatalogTable/index.ts @@ -16,4 +16,5 @@ export { CatalogTable } from './CatalogTable'; export type { CatalogTableProps } from './CatalogTable'; +export type { CatalogTableToolbarClassKey } from './CatalogTableToolbar'; export type { CatalogTableRow, CatalogTableColumnsFunc } from './types'; diff --git a/plugins/catalog/src/components/EntityLabelsCard/EntityLabelsEmptyState.tsx b/plugins/catalog/src/components/EntityLabelsCard/EntityLabelsEmptyState.tsx index d78be2d2ce..3859d54a7a 100644 --- a/plugins/catalog/src/components/EntityLabelsCard/EntityLabelsEmptyState.tsx +++ b/plugins/catalog/src/components/EntityLabelsCard/EntityLabelsEmptyState.tsx @@ -27,6 +27,9 @@ const ENTITY_YAML = `metadata: labels: javaVersion: 1.2.3`; +/** @public */ +export type EntityLabelsEmptyStateClassKey = 'code'; + const useStyles = makeStyles( theme => ({ code: { diff --git a/plugins/catalog/src/components/EntityLabelsCard/index.ts b/plugins/catalog/src/components/EntityLabelsCard/index.ts index 870819f9a7..b86d56c16c 100644 --- a/plugins/catalog/src/components/EntityLabelsCard/index.ts +++ b/plugins/catalog/src/components/EntityLabelsCard/index.ts @@ -17,3 +17,4 @@ export { EntityLabelsCard } from './EntityLabelsCard'; export * from './conditions'; export type { EntityLabelsCardProps } from './EntityLabelsCard'; +export type { EntityLabelsEmptyStateClassKey } from './EntityLabelsEmptyState'; diff --git a/plugins/catalog/src/components/RelatedEntitiesCard/RelatedEntitiesCard.tsx b/plugins/catalog/src/components/RelatedEntitiesCard/RelatedEntitiesCard.tsx index a2814527cc..5b57cbd80e 100644 --- a/plugins/catalog/src/components/RelatedEntitiesCard/RelatedEntitiesCard.tsx +++ b/plugins/catalog/src/components/RelatedEntitiesCard/RelatedEntitiesCard.tsx @@ -84,7 +84,6 @@ export const RelatedEntitiesCard = ( asRenderableEntities, tableOptions = {}, } = props; - const { t } = useTranslationRef(catalogTranslationRef); const { entity } = useEntity(); const { entities, loading, error } = useRelatedEntities(entity, { @@ -116,7 +115,7 @@ export const RelatedEntitiesCard = (
{emptyMessage} - + {t('relatedEntitiesCard.emptyHelpLinkTitle')} diff --git a/plugins/catalog/src/index.ts b/plugins/catalog/src/index.ts index 806ea40c66..f3cc7d3d0b 100644 --- a/plugins/catalog/src/index.ts +++ b/plugins/catalog/src/index.ts @@ -38,6 +38,7 @@ export * from './components/EntitySwitch'; export * from './components/FilteredEntityLayout'; export * from './overridableComponents'; export * from './components/EntityLabelsCard'; +export * from './components/CatalogSearchResultListItem'; export { CatalogEntityPage, CatalogIndexPage, diff --git a/plugins/catalog/src/overridableComponents.ts b/plugins/catalog/src/overridableComponents.ts index 0d981b1700..c700566b97 100644 --- a/plugins/catalog/src/overridableComponents.ts +++ b/plugins/catalog/src/overridableComponents.ts @@ -19,12 +19,18 @@ import { StyleRules } from '@material-ui/core/styles/withStyles'; import { EntityLinksEmptyStateClassKey } from './components/EntityLinksCard'; import { SystemDiagramCardClassKey } from './components/SystemDiagramCard'; import { EntityContextMenuClassKey } from './components/EntityContextMenu'; +import { CatalogSearchResultListItemClassKey } from './components/CatalogSearchResultListItem'; +import { CatalogTableToolbarClassKey } from './components/CatalogTable'; +import { EntityLabelsEmptyStateClassKey } from './components/EntityLabelsCard'; /** @public */ export type PluginCatalogComponentsNameToClassKey = { PluginCatalogEntityLinksEmptyState: EntityLinksEmptyStateClassKey; PluginCatalogSystemDiagramCard: SystemDiagramCardClassKey; PluginCatalogEntityContextMenu: EntityContextMenuClassKey; + PluginCatalogSearchResultListItem: CatalogSearchResultListItemClassKey; + PluginCatalogTableToolbar: CatalogTableToolbarClassKey; + PluginCatalogEntityLabelsEmptyState: EntityLabelsEmptyStateClassKey; }; /** @public */ diff --git a/plugins/config-schema/CHANGELOG.md b/plugins/config-schema/CHANGELOG.md index d97d6b764d..5106f6071d 100644 --- a/plugins/config-schema/CHANGELOG.md +++ b/plugins/config-schema/CHANGELOG.md @@ -1,5 +1,48 @@ # @backstage/plugin-config-schema +## 0.1.60-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## 0.1.60-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## 0.1.59 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## 0.1.59-next.1 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.1.59-next.0 ### Patch Changes diff --git a/plugins/config-schema/package.json b/plugins/config-schema/package.json index 614b80a190..40af57c006 100644 --- a/plugins/config-schema/package.json +++ b/plugins/config-schema/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-config-schema", - "version": "0.1.59-next.0", + "version": "0.1.60-next.1", "description": "A Backstage plugin that lets you browse the configuration schema of your app", "backstage": { "role": "frontend-plugin", @@ -44,7 +44,6 @@ "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.61", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "jsonschema": "^1.2.6", "react-use": "^17.2.4", "zen-observable": "^0.10.0" @@ -54,11 +53,21 @@ "@backstage/dev-utils": "workspace:^", "@testing-library/dom": "^10.0.0", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^15.0.0" + "@testing-library/react": "^16.0.0", + "@types/react": "^18.0.0", + "react": "^18.0.2", + "react-dom": "^18.0.2", + "react-router-dom": "^6.3.0" }, "peerDependencies": { + "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } } diff --git a/plugins/config-schema/api-report.md b/plugins/config-schema/report.api.md similarity index 60% rename from plugins/config-schema/api-report.md rename to plugins/config-schema/report.api.md index 16630ae8d0..00a7a7fe0c 100644 --- a/plugins/config-schema/api-report.md +++ b/plugins/config-schema/report.api.md @@ -44,4 +44,15 @@ export class StaticSchemaLoader implements ConfigSchemaApi { // (undocumented) schema$(): Observable; } + +// Warnings were encountered during analysis: +// +// src/api/StaticSchemaLoader.d.ts:13:5 - (ae-undocumented) Missing documentation for "schema$". +// src/api/types.d.ts:4:1 - (ae-undocumented) Missing documentation for "ConfigSchemaResult". +// src/api/types.d.ts:5:5 - (ae-undocumented) Missing documentation for "schema". +// src/api/types.d.ts:8:1 - (ae-undocumented) Missing documentation for "ConfigSchemaApi". +// src/api/types.d.ts:9:5 - (ae-undocumented) Missing documentation for "schema$". +// src/api/types.d.ts:12:22 - (ae-undocumented) Missing documentation for "configSchemaApiRef". +// src/plugin.d.ts:3:22 - (ae-undocumented) Missing documentation for "configSchemaPlugin". +// src/plugin.d.ts:7:22 - (ae-undocumented) Missing documentation for "ConfigSchemaPage". ``` diff --git a/plugins/devtools-backend/CHANGELOG.md b/plugins/devtools-backend/CHANGELOG.md index 1f7e3996bb..e007e1102b 100644 --- a/plugins/devtools-backend/CHANGELOG.md +++ b/plugins/devtools-backend/CHANGELOG.md @@ -1,5 +1,65 @@ # @backstage/plugin-devtools-backend +## 0.4.1-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-permission-node@0.8.4-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-devtools-common@0.1.12 + - @backstage/plugin-permission-common@0.8.1 + +## 0.4.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- 5d1670f: Update README installation instructions +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-permission-node@0.8.3 + - @backstage/config-loader@1.9.1 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-devtools-common@0.1.12 + - @backstage/plugin-permission-common@0.8.1 + +## 0.4.0-next.2 + +### Patch Changes + +- 5d1670f: Update README installation instructions +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/config-loader@1.9.1-next.0 + - @backstage/plugin-permission-node@0.8.3-next.2 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-devtools-common@0.1.12 + - @backstage/plugin-permission-common@0.8.1 + ## 0.4.0-next.1 ### Patch Changes diff --git a/plugins/devtools-backend/package.json b/plugins/devtools-backend/package.json index 4bde07d5f7..83a42fb4d5 100644 --- a/plugins/devtools-backend/package.json +++ b/plugins/devtools-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-devtools-backend", - "version": "0.4.0-next.1", + "version": "0.4.1-next.0", "backstage": { "role": "backend-plugin", "pluginId": "devtools", @@ -38,7 +38,7 @@ "test": "backstage-cli package test" }, "dependencies": { - "@backstage/backend-common": "workspace:^", + "@backstage/backend-common": "^0.25.0", "@backstage/backend-plugin-api": "workspace:^", "@backstage/cli-common": "workspace:^", "@backstage/config": "workspace:^", @@ -68,7 +68,7 @@ "@types/ping": "^0.4.1", "@types/supertest": "^2.0.8", "@types/yarnpkg__lockfile": "^1.1.4", - "supertest": "^6.2.4" + "supertest": "^7.0.0" }, "configSchema": "config.d.ts" } diff --git a/plugins/devtools-backend/api-report.md b/plugins/devtools-backend/report.api.md similarity index 59% rename from plugins/devtools-backend/api-report.md rename to plugins/devtools-backend/report.api.md index 5fceda3d46..1ca69d686e 100644 --- a/plugins/devtools-backend/api-report.md +++ b/plugins/devtools-backend/report.api.md @@ -48,4 +48,19 @@ export interface RouterOptions { // (undocumented) permissions: PermissionsService; } + +// Warnings were encountered during analysis: +// +// src/api/DevToolsBackendApi.d.ts:5:1 - (ae-undocumented) Missing documentation for "DevToolsBackendApi". +// src/api/DevToolsBackendApi.d.ts:9:5 - (ae-undocumented) Missing documentation for "listExternalDependencyDetails". +// src/api/DevToolsBackendApi.d.ts:12:5 - (ae-undocumented) Missing documentation for "listConfig". +// src/api/DevToolsBackendApi.d.ts:13:5 - (ae-undocumented) Missing documentation for "listInfo". +// src/service/router.d.ts:8:1 - (ae-undocumented) Missing documentation for "RouterOptions". +// src/service/router.d.ts:9:5 - (ae-undocumented) Missing documentation for "devToolsBackendApi". +// src/service/router.d.ts:10:5 - (ae-undocumented) Missing documentation for "logger". +// src/service/router.d.ts:11:5 - (ae-undocumented) Missing documentation for "config". +// src/service/router.d.ts:12:5 - (ae-undocumented) Missing documentation for "permissions". +// src/service/router.d.ts:13:5 - (ae-undocumented) Missing documentation for "discovery". +// src/service/router.d.ts:14:5 - (ae-undocumented) Missing documentation for "httpAuth". +// src/service/router.d.ts:20:1 - (ae-undocumented) Missing documentation for "createRouter". ``` diff --git a/plugins/devtools-common/api-report.md b/plugins/devtools-common/report.api.md similarity index 56% rename from plugins/devtools-common/api-report.md rename to plugins/devtools-common/report.api.md index 83af75d11a..bf71f1b87a 100644 --- a/plugins/devtools-common/api-report.md +++ b/plugins/devtools-common/report.api.md @@ -73,4 +73,20 @@ export type PackageDependency = { name: string; versions: string; }; + +// Warnings were encountered during analysis: +// +// src/permissions.d.ts:4:22 - (ae-undocumented) Missing documentation for "devToolsAdministerPermission". +// src/permissions.d.ts:8:22 - (ae-undocumented) Missing documentation for "devToolsInfoReadPermission". +// src/permissions.d.ts:12:22 - (ae-undocumented) Missing documentation for "devToolsConfigReadPermission". +// src/permissions.d.ts:16:22 - (ae-undocumented) Missing documentation for "devToolsExternalDependenciesReadPermission". +// src/types.d.ts:3:1 - (ae-undocumented) Missing documentation for "Endpoint". +// src/types.d.ts:9:1 - (ae-undocumented) Missing documentation for "ExternalDependency". +// src/types.d.ts:17:1 - (ae-undocumented) Missing documentation for "DevToolsInfo". +// src/types.d.ts:25:1 - (ae-undocumented) Missing documentation for "PackageDependency". +// src/types.d.ts:30:1 - (ae-undocumented) Missing documentation for "ExternalDependencyStatus". +// src/types.d.ts:31:5 - (ae-undocumented) Missing documentation for "healthy". +// src/types.d.ts:32:5 - (ae-undocumented) Missing documentation for "unhealthy". +// src/types.d.ts:35:1 - (ae-undocumented) Missing documentation for "ConfigInfo". +// src/types.d.ts:40:1 - (ae-undocumented) Missing documentation for "ConfigError". ``` diff --git a/plugins/devtools/CHANGELOG.md b/plugins/devtools/CHANGELOG.md index 4fa8e6b609..55541f4629 100644 --- a/plugins/devtools/CHANGELOG.md +++ b/plugins/devtools/CHANGELOG.md @@ -1,5 +1,60 @@ # @backstage/plugin-devtools +## 0.1.19-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/frontend-plugin-api@0.9.0-next.1 + - @backstage/core-compat-api@0.3.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/plugin-permission-react@0.4.27-next.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-devtools-common@0.1.12 + +## 0.1.19-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/core-compat-api@0.3.1-next.0 + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-devtools-common@0.1.12 + - @backstage/plugin-permission-react@0.4.27-next.0 + +## 0.1.18 + +### Patch Changes + +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. +- 019d9ad: Minor dockerfile syntax update +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/frontend-plugin-api@0.8.0 + - @backstage/core-compat-api@0.3.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/plugin-permission-react@0.4.26 + - @backstage/errors@1.2.4 + - @backstage/plugin-devtools-common@0.1.12 + +## 0.1.18-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/core-compat-api@0.3.0-next.2 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/frontend-plugin-api@0.8.0-next.2 + - @backstage/plugin-permission-react@0.4.26-next.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-devtools-common@0.1.12 + ## 0.1.18-next.1 ### Patch Changes diff --git a/plugins/devtools/package.json b/plugins/devtools/package.json index 19ec9d93c6..f5bf285ed7 100644 --- a/plugins/devtools/package.json +++ b/plugins/devtools/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-devtools", - "version": "0.1.18-next.1", + "version": "0.1.19-next.1", "backstage": { "role": "frontend-plugin", "pluginId": "devtools", @@ -67,12 +67,21 @@ "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/dev-utils": "workspace:^", - "@testing-library/jest-dom": "^6.0.0" + "@testing-library/jest-dom": "^6.0.0", + "@types/react": "^18.0.0", + "react": "^18.0.2", + "react-dom": "^18.0.2", + "react-router-dom": "^6.3.0" }, "peerDependencies": { "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } } diff --git a/plugins/devtools/api-report-alpha.md b/plugins/devtools/report-alpha.api.md similarity index 82% rename from plugins/devtools/api-report-alpha.md rename to plugins/devtools/report-alpha.api.md index 7fb16734f1..aa1806277e 100644 --- a/plugins/devtools/api-report-alpha.md +++ b/plugins/devtools/report-alpha.api.md @@ -21,7 +21,6 @@ const _default: FrontendPlugin< { 'api:devtools': ExtensionDefinition<{ kind: 'api'; - namespace: undefined; name: undefined; config: {}; configInput: {}; @@ -31,10 +30,12 @@ const _default: FrontendPlugin< {} >; inputs: {}; + params: { + factory: AnyApiFactory; + }; }>; 'page:devtools': ExtensionDefinition<{ kind: 'page'; - namespace: undefined; name: undefined; config: { path: string | undefined; @@ -57,10 +58,14 @@ const _default: FrontendPlugin< } >; inputs: {}; + params: { + defaultPath: string; + loader: () => Promise; + routeRef?: RouteRef | undefined; + }; }>; 'nav-item:devtools': ExtensionDefinition<{ kind: 'nav-item'; - namespace: undefined; name: undefined; config: {}; configInput: {}; @@ -74,10 +79,19 @@ const _default: FrontendPlugin< {} >; inputs: {}; + params: { + title: string; + icon: IconComponent; + routeRef: RouteRef; + }; }>; } >; export default _default; +// Warnings were encountered during analysis: +// +// src/alpha/plugin.d.ts:53:15 - (ae-undocumented) Missing documentation for "_default". + // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/devtools/api-report.md b/plugins/devtools/report.api.md similarity index 62% rename from plugins/devtools/api-report.md rename to plugins/devtools/report.api.md index bba36a5a9a..75dfdc32f6 100644 --- a/plugins/devtools/api-report.md +++ b/plugins/devtools/report.api.md @@ -57,4 +57,14 @@ export type SubRoute = { } >; }; + +// Warnings were encountered during analysis: +// +// src/components/Content/ConfigContent/ConfigContent.d.ts:7:22 - (ae-undocumented) Missing documentation for "ConfigContent". +// src/components/Content/ExternalDependenciesContent/ExternalDependenciesContent.d.ts:5:22 - (ae-undocumented) Missing documentation for "ExternalDependenciesContent". +// src/components/Content/InfoContent/InfoContent.d.ts:3:22 - (ae-undocumented) Missing documentation for "InfoContent". +// src/components/DevToolsLayout/DevToolsLayout.d.ts:4:1 - (ae-undocumented) Missing documentation for "SubRoute". +// src/components/DevToolsLayout/DevToolsLayout.d.ts:13:1 - (ae-undocumented) Missing documentation for "DevToolsLayoutProps". +// src/plugin.d.ts:3:22 - (ae-undocumented) Missing documentation for "devToolsPlugin". +// src/plugin.d.ts:7:22 - (ae-undocumented) Missing documentation for "DevToolsPage". ``` diff --git a/plugins/events-backend-module-aws-sqs/CHANGELOG.md b/plugins/events-backend-module-aws-sqs/CHANGELOG.md index 46182e1880..176df94002 100644 --- a/plugins/events-backend-module-aws-sqs/CHANGELOG.md +++ b/plugins/events-backend-module-aws-sqs/CHANGELOG.md @@ -1,5 +1,39 @@ # @backstage/plugin-events-backend-module-aws-sqs +## 0.4.3-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## 0.4.2 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-events-node@0.4.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## 0.4.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.4.0-next.2 + ## 0.4.2-next.1 ### Patch Changes diff --git a/plugins/events-backend-module-aws-sqs/package.json b/plugins/events-backend-module-aws-sqs/package.json index d84cb7d717..b131be935b 100644 --- a/plugins/events-backend-module-aws-sqs/package.json +++ b/plugins/events-backend-module-aws-sqs/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend-module-aws-sqs", - "version": "0.4.2-next.1", + "version": "0.4.3-next.0", "backstage": { "role": "backend-plugin-module", "pluginId": "events", @@ -48,7 +48,6 @@ }, "dependencies": { "@aws-sdk/client-sqs": "^3.350.0", - "@backstage/backend-common": "workspace:^", "@backstage/backend-plugin-api": "workspace:^", "@backstage/config": "workspace:^", "@backstage/plugin-events-node": "workspace:^", @@ -57,7 +56,6 @@ }, "devDependencies": { "@aws-sdk/types": "^3.347.0", - "@backstage/backend-common": "workspace:^", "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "@backstage/plugin-events-backend-test-utils": "workspace:^", diff --git a/plugins/events-backend-module-aws-sqs/api-report-alpha.md b/plugins/events-backend-module-aws-sqs/report-alpha.api.md similarity index 100% rename from plugins/events-backend-module-aws-sqs/api-report-alpha.md rename to plugins/events-backend-module-aws-sqs/report-alpha.api.md diff --git a/plugins/events-backend-module-aws-sqs/api-report.md b/plugins/events-backend-module-aws-sqs/report.api.md similarity index 71% rename from plugins/events-backend-module-aws-sqs/api-report.md rename to plugins/events-backend-module-aws-sqs/report.api.md index ac806bf01b..eee183519d 100644 --- a/plugins/events-backend-module-aws-sqs/api-report.md +++ b/plugins/events-backend-module-aws-sqs/report.api.md @@ -20,4 +20,9 @@ export class AwsSqsConsumingEventPublisher { // (undocumented) start(): Promise; } + +// Warnings were encountered during analysis: +// +// src/publisher/AwsSqsConsumingEventPublisher.d.ts:21:5 - (ae-undocumented) Missing documentation for "fromConfig". +// src/publisher/AwsSqsConsumingEventPublisher.d.ts:28:5 - (ae-undocumented) Missing documentation for "start". ``` diff --git a/plugins/events-backend-module-azure/CHANGELOG.md b/plugins/events-backend-module-azure/CHANGELOG.md index 73e6a9c135..336a8a6d94 100644 --- a/plugins/events-backend-module-azure/CHANGELOG.md +++ b/plugins/events-backend-module-azure/CHANGELOG.md @@ -1,5 +1,30 @@ # @backstage/plugin-events-backend-module-azure +## 0.2.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + +## 0.2.11 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-events-node@0.4.0 + +## 0.2.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/plugin-events-node@0.4.0-next.2 + ## 0.2.11-next.1 ### Patch Changes diff --git a/plugins/events-backend-module-azure/package.json b/plugins/events-backend-module-azure/package.json index 7fe1c40108..51ac31dc08 100644 --- a/plugins/events-backend-module-azure/package.json +++ b/plugins/events-backend-module-azure/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend-module-azure", - "version": "0.2.11-next.1", + "version": "0.2.12-next.0", "backstage": { "role": "backend-plugin-module", "pluginId": "events", diff --git a/plugins/events-backend-module-azure/api-report-alpha.md b/plugins/events-backend-module-azure/report-alpha.api.md similarity index 100% rename from plugins/events-backend-module-azure/api-report-alpha.md rename to plugins/events-backend-module-azure/report-alpha.api.md diff --git a/plugins/events-backend-module-azure/api-report.md b/plugins/events-backend-module-azure/report.api.md similarity index 70% rename from plugins/events-backend-module-azure/api-report.md rename to plugins/events-backend-module-azure/report.api.md index 66529ef2d4..0ad4d4e9fd 100644 --- a/plugins/events-backend-module-azure/api-report.md +++ b/plugins/events-backend-module-azure/report.api.md @@ -15,4 +15,9 @@ export class AzureDevOpsEventRouter extends SubTopicEventRouter { // (undocumented) protected getSubscriberId(): string; } + +// Warnings were encountered during analysis: +// +// src/router/AzureDevOpsEventRouter.d.ts:13:5 - (ae-undocumented) Missing documentation for "getSubscriberId". +// src/router/AzureDevOpsEventRouter.d.ts:14:5 - (ae-undocumented) Missing documentation for "determineSubTopic". ``` diff --git a/plugins/events-backend-module-bitbucket-cloud/CHANGELOG.md b/plugins/events-backend-module-bitbucket-cloud/CHANGELOG.md index 594e9a85dd..362e7ebd90 100644 --- a/plugins/events-backend-module-bitbucket-cloud/CHANGELOG.md +++ b/plugins/events-backend-module-bitbucket-cloud/CHANGELOG.md @@ -1,5 +1,30 @@ # @backstage/plugin-events-backend-module-bitbucket-cloud +## 0.2.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + +## 0.2.11 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-events-node@0.4.0 + +## 0.2.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/plugin-events-node@0.4.0-next.2 + ## 0.2.11-next.1 ### Patch Changes diff --git a/plugins/events-backend-module-bitbucket-cloud/package.json b/plugins/events-backend-module-bitbucket-cloud/package.json index 25df31c5fc..08ceeeff33 100644 --- a/plugins/events-backend-module-bitbucket-cloud/package.json +++ b/plugins/events-backend-module-bitbucket-cloud/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend-module-bitbucket-cloud", - "version": "0.2.11-next.1", + "version": "0.2.12-next.0", "backstage": { "role": "backend-plugin-module", "pluginId": "events", diff --git a/plugins/events-backend-module-bitbucket-cloud/api-report-alpha.md b/plugins/events-backend-module-bitbucket-cloud/report-alpha.api.md similarity index 100% rename from plugins/events-backend-module-bitbucket-cloud/api-report-alpha.md rename to plugins/events-backend-module-bitbucket-cloud/report-alpha.api.md diff --git a/plugins/events-backend-module-bitbucket-cloud/api-report.md b/plugins/events-backend-module-bitbucket-cloud/report.api.md similarity index 70% rename from plugins/events-backend-module-bitbucket-cloud/api-report.md rename to plugins/events-backend-module-bitbucket-cloud/report.api.md index ba4f61d739..51aa7f27cb 100644 --- a/plugins/events-backend-module-bitbucket-cloud/api-report.md +++ b/plugins/events-backend-module-bitbucket-cloud/report.api.md @@ -15,4 +15,9 @@ export class BitbucketCloudEventRouter extends SubTopicEventRouter { // (undocumented) protected getSubscriberId(): string; } + +// Warnings were encountered during analysis: +// +// src/router/BitbucketCloudEventRouter.d.ts:13:5 - (ae-undocumented) Missing documentation for "getSubscriberId". +// src/router/BitbucketCloudEventRouter.d.ts:14:5 - (ae-undocumented) Missing documentation for "determineSubTopic". ``` diff --git a/plugins/events-backend-module-gerrit/CHANGELOG.md b/plugins/events-backend-module-gerrit/CHANGELOG.md index f8b842415c..7bcc732795 100644 --- a/plugins/events-backend-module-gerrit/CHANGELOG.md +++ b/plugins/events-backend-module-gerrit/CHANGELOG.md @@ -1,5 +1,30 @@ # @backstage/plugin-events-backend-module-gerrit +## 0.2.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + +## 0.2.11 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-events-node@0.4.0 + +## 0.2.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/plugin-events-node@0.4.0-next.2 + ## 0.2.11-next.1 ### Patch Changes diff --git a/plugins/events-backend-module-gerrit/package.json b/plugins/events-backend-module-gerrit/package.json index 3d1358f055..8052734395 100644 --- a/plugins/events-backend-module-gerrit/package.json +++ b/plugins/events-backend-module-gerrit/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend-module-gerrit", - "version": "0.2.11-next.1", + "version": "0.2.12-next.0", "backstage": { "role": "backend-plugin-module", "pluginId": "events", diff --git a/plugins/events-backend-module-gerrit/api-report-alpha.md b/plugins/events-backend-module-gerrit/report-alpha.api.md similarity index 100% rename from plugins/events-backend-module-gerrit/api-report-alpha.md rename to plugins/events-backend-module-gerrit/report-alpha.api.md diff --git a/plugins/events-backend-module-gerrit/api-report.md b/plugins/events-backend-module-gerrit/report.api.md similarity index 71% rename from plugins/events-backend-module-gerrit/api-report.md rename to plugins/events-backend-module-gerrit/report.api.md index c75857aa43..7a3f75ca6f 100644 --- a/plugins/events-backend-module-gerrit/api-report.md +++ b/plugins/events-backend-module-gerrit/report.api.md @@ -15,4 +15,9 @@ export class GerritEventRouter extends SubTopicEventRouter { // (undocumented) protected getSubscriberId(): string; } + +// Warnings were encountered during analysis: +// +// src/router/GerritEventRouter.d.ts:13:5 - (ae-undocumented) Missing documentation for "getSubscriberId". +// src/router/GerritEventRouter.d.ts:14:5 - (ae-undocumented) Missing documentation for "determineSubTopic". ``` diff --git a/plugins/events-backend-module-github/CHANGELOG.md b/plugins/events-backend-module-github/CHANGELOG.md index 9f7b6ae04b..f80dbcc120 100644 --- a/plugins/events-backend-module-github/CHANGELOG.md +++ b/plugins/events-backend-module-github/CHANGELOG.md @@ -1,5 +1,34 @@ # @backstage/plugin-events-backend-module-github +## 0.2.12-next.0 + +### Patch Changes + +- 2f88f88: Updated backend installation instructions. +- Updated dependencies + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + +## 0.2.11 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-events-node@0.4.0 + - @backstage/config@1.2.0 + +## 0.2.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/config@1.2.0 + - @backstage/plugin-events-node@0.4.0-next.2 + ## 0.2.11-next.1 ### Patch Changes diff --git a/plugins/events-backend-module-github/README.md b/plugins/events-backend-module-github/README.md index fec27b62e3..adc91da4ec 100644 --- a/plugins/events-backend-module-github/README.md +++ b/plugins/events-backend-module-github/README.md @@ -33,7 +33,7 @@ yarn --cwd packages/backend add @backstage/plugin-events-backend-module-github // packages/backend/src/index.ts import { eventsModuleGithubEventRouter } from '@backstage/plugin-events-backend-module-github/alpha'; // ... -backend.add(eventsModuleGithubEventRouter()); +backend.add(eventsModuleGithubEventRouter); ``` #### Legacy Backend System @@ -50,7 +50,7 @@ await eventRouter.subscribe(); // packages/backend/src/index.ts import { eventsModuleGithubWebhook } from '@backstage/plugin-events-backend-module-github/alpha'; // ... -backend.add(eventsModuleGithubWebhook()); +backend.add(eventsModuleGithubWebhook); ``` #### Legacy Backend System diff --git a/plugins/events-backend-module-github/package.json b/plugins/events-backend-module-github/package.json index 877840e806..89eb9b2439 100644 --- a/plugins/events-backend-module-github/package.json +++ b/plugins/events-backend-module-github/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend-module-github", - "version": "0.2.11-next.1", + "version": "0.2.12-next.0", "backstage": { "role": "backend-plugin-module", "pluginId": "events", diff --git a/plugins/events-backend-module-github/api-report-alpha.md b/plugins/events-backend-module-github/report-alpha.api.md similarity index 100% rename from plugins/events-backend-module-github/api-report-alpha.md rename to plugins/events-backend-module-github/report-alpha.api.md diff --git a/plugins/events-backend-module-github/api-report.md b/plugins/events-backend-module-github/report.api.md similarity index 76% rename from plugins/events-backend-module-github/api-report.md rename to plugins/events-backend-module-github/report.api.md index 5341f86039..a3b8adaaa5 100644 --- a/plugins/events-backend-module-github/api-report.md +++ b/plugins/events-backend-module-github/report.api.md @@ -22,4 +22,9 @@ export class GithubEventRouter extends SubTopicEventRouter { // (undocumented) protected getSubscriberId(): string; } + +// Warnings were encountered during analysis: +// +// src/router/GithubEventRouter.d.ts:13:5 - (ae-undocumented) Missing documentation for "getSubscriberId". +// src/router/GithubEventRouter.d.ts:14:5 - (ae-undocumented) Missing documentation for "determineSubTopic". ``` diff --git a/plugins/events-backend-module-gitlab/CHANGELOG.md b/plugins/events-backend-module-gitlab/CHANGELOG.md index 4231baf2a8..8388606685 100644 --- a/plugins/events-backend-module-gitlab/CHANGELOG.md +++ b/plugins/events-backend-module-gitlab/CHANGELOG.md @@ -1,5 +1,34 @@ # @backstage/plugin-events-backend-module-gitlab +## 0.2.12-next.0 + +### Patch Changes + +- 2f88f88: Updated backend installation instructions. +- Updated dependencies + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + +## 0.2.11 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-events-node@0.4.0 + - @backstage/config@1.2.0 + +## 0.2.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/config@1.2.0 + - @backstage/plugin-events-node@0.4.0-next.2 + ## 0.2.11-next.1 ### Patch Changes diff --git a/plugins/events-backend-module-gitlab/README.md b/plugins/events-backend-module-gitlab/README.md index 73d5bf2d87..eeede370c0 100644 --- a/plugins/events-backend-module-gitlab/README.md +++ b/plugins/events-backend-module-gitlab/README.md @@ -32,7 +32,7 @@ yarn --cwd packages/backend add @backstage/plugin-events-backend-module-gitlab // packages/backend/src/index.ts import { eventsModuleGitlabEventRouter } from '@backstage/plugin-events-backend-module-gitlab/alpha'; // ... -backend.add(eventsModuleGitlabEventRouter()); +backend.add(eventsModuleGitlabEventRouter); ``` #### Legacy Backend System @@ -49,7 +49,7 @@ await eventRouter.subscribe(); // packages/backend/src/index.ts import { eventsModuleGitlabWebhook } from '@backstage/plugin-events-backend-module-gitlab/alpha'; // ... -backend.add(eventsModuleGitlabWebhook()); +backend.add(eventsModuleGitlabWebhook); ``` #### Legacy Backend System diff --git a/plugins/events-backend-module-gitlab/package.json b/plugins/events-backend-module-gitlab/package.json index 86a988074a..42bb8e5f44 100644 --- a/plugins/events-backend-module-gitlab/package.json +++ b/plugins/events-backend-module-gitlab/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend-module-gitlab", - "version": "0.2.11-next.1", + "version": "0.2.12-next.0", "backstage": { "role": "backend-plugin-module", "pluginId": "events", diff --git a/plugins/events-backend-module-gitlab/api-report-alpha.md b/plugins/events-backend-module-gitlab/report-alpha.api.md similarity index 100% rename from plugins/events-backend-module-gitlab/api-report-alpha.md rename to plugins/events-backend-module-gitlab/report-alpha.api.md diff --git a/plugins/events-backend-module-gitlab/api-report.md b/plugins/events-backend-module-gitlab/report.api.md similarity index 76% rename from plugins/events-backend-module-gitlab/api-report.md rename to plugins/events-backend-module-gitlab/report.api.md index f348436375..9753380364 100644 --- a/plugins/events-backend-module-gitlab/api-report.md +++ b/plugins/events-backend-module-gitlab/report.api.md @@ -20,4 +20,9 @@ export class GitlabEventRouter extends SubTopicEventRouter { // (undocumented) protected getSubscriberId(): string; } + +// Warnings were encountered during analysis: +// +// src/router/GitlabEventRouter.d.ts:13:5 - (ae-undocumented) Missing documentation for "getSubscriberId". +// src/router/GitlabEventRouter.d.ts:14:5 - (ae-undocumented) Missing documentation for "determineSubTopic". ``` diff --git a/plugins/events-backend-test-utils/CHANGELOG.md b/plugins/events-backend-test-utils/CHANGELOG.md index 5dafcc9f52..c5bc0b1fd8 100644 --- a/plugins/events-backend-test-utils/CHANGELOG.md +++ b/plugins/events-backend-test-utils/CHANGELOG.md @@ -1,5 +1,26 @@ # @backstage/plugin-events-backend-test-utils +## 0.1.36-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.1-next.0 + +## 0.1.35 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.0 + +## 0.1.35-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.0-next.2 + ## 0.1.35-next.1 ### Patch Changes diff --git a/plugins/events-backend-test-utils/api-report.md b/plugins/events-backend-test-utils/api-report.md deleted file mode 100644 index 9630c3d4e2..0000000000 --- a/plugins/events-backend-test-utils/api-report.md +++ /dev/null @@ -1,63 +0,0 @@ -## API Report File for "@backstage/plugin-events-backend-test-utils" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -import { EventBroker } from '@backstage/plugin-events-node'; -import { EventParams } from '@backstage/plugin-events-node'; -import { EventPublisher } from '@backstage/plugin-events-node'; -import { EventsService } from '@backstage/plugin-events-node'; -import { EventsServiceSubscribeOptions } from '@backstage/plugin-events-node'; -import { EventSubscriber } from '@backstage/plugin-events-node'; - -// @public @deprecated (undocumented) -export class TestEventBroker implements EventBroker { - // (undocumented) - publish(params: EventParams): Promise; - // (undocumented) - readonly published: EventParams[]; - // (undocumented) - subscribe( - ...subscribers: Array> - ): void; - // (undocumented) - readonly subscribed: EventSubscriber[]; -} - -// @public @deprecated (undocumented) -export class TestEventPublisher implements EventPublisher { - // (undocumented) - get eventBroker(): EventBroker | undefined; - // (undocumented) - setEventBroker(eventBroker: EventBroker): Promise; -} - -// @public (undocumented) -export class TestEventsService implements EventsService { - // (undocumented) - publish(params: EventParams): Promise; - // (undocumented) - get published(): EventParams[]; - // (undocumented) - reset(): void; - // (undocumented) - subscribe(options: EventsServiceSubscribeOptions): Promise; - // (undocumented) - get subscribed(): EventsServiceSubscribeOptions[]; -} - -// @public @deprecated (undocumented) -export class TestEventSubscriber implements EventSubscriber { - constructor(name: string, topics: string[]); - // (undocumented) - readonly name: string; - // (undocumented) - onEvent(params: EventParams): Promise; - // (undocumented) - readonly receivedEvents: Record; - // (undocumented) - supportsEventTopics(): string[]; - // (undocumented) - readonly topics: string[]; -} -``` diff --git a/plugins/events-backend-test-utils/package.json b/plugins/events-backend-test-utils/package.json index b174bc989e..2cd57ed302 100644 --- a/plugins/events-backend-test-utils/package.json +++ b/plugins/events-backend-test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend-test-utils", - "version": "0.1.35-next.1", + "version": "0.1.36-next.0", "description": "The plugin-events-backend-test-utils for @backstage/plugin-events-node", "backstage": { "role": "node-library", diff --git a/plugins/events-backend-test-utils/report.api.md b/plugins/events-backend-test-utils/report.api.md new file mode 100644 index 0000000000..d88a9dbee0 --- /dev/null +++ b/plugins/events-backend-test-utils/report.api.md @@ -0,0 +1,86 @@ +## API Report File for "@backstage/plugin-events-backend-test-utils" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { EventBroker } from '@backstage/plugin-events-node'; +import { EventParams } from '@backstage/plugin-events-node'; +import { EventPublisher } from '@backstage/plugin-events-node'; +import { EventsService } from '@backstage/plugin-events-node'; +import { EventsServiceSubscribeOptions } from '@backstage/plugin-events-node'; +import { EventSubscriber } from '@backstage/plugin-events-node'; + +// @public @deprecated (undocumented) +export class TestEventBroker implements EventBroker { + // (undocumented) + publish(params: EventParams): Promise; + // (undocumented) + readonly published: EventParams[]; + // (undocumented) + subscribe( + ...subscribers: Array> + ): void; + // (undocumented) + readonly subscribed: EventSubscriber[]; +} + +// @public @deprecated (undocumented) +export class TestEventPublisher implements EventPublisher { + // (undocumented) + get eventBroker(): EventBroker | undefined; + // (undocumented) + setEventBroker(eventBroker: EventBroker): Promise; +} + +// @public (undocumented) +export class TestEventsService implements EventsService { + // (undocumented) + publish(params: EventParams): Promise; + // (undocumented) + get published(): EventParams[]; + // (undocumented) + reset(): void; + // (undocumented) + subscribe(options: EventsServiceSubscribeOptions): Promise; + // (undocumented) + get subscribed(): EventsServiceSubscribeOptions[]; +} + +// @public @deprecated (undocumented) +export class TestEventSubscriber implements EventSubscriber { + constructor(name: string, topics: string[]); + // (undocumented) + readonly name: string; + // (undocumented) + onEvent(params: EventParams): Promise; + // (undocumented) + readonly receivedEvents: Record; + // (undocumented) + supportsEventTopics(): string[]; + // (undocumented) + readonly topics: string[]; +} + +// Warnings were encountered during analysis: +// +// src/testUtils/TestEventBroker.d.ts:6:1 - (ae-undocumented) Missing documentation for "TestEventBroker". +// src/testUtils/TestEventBroker.d.ts:7:5 - (ae-undocumented) Missing documentation for "published". +// src/testUtils/TestEventBroker.d.ts:8:5 - (ae-undocumented) Missing documentation for "subscribed". +// src/testUtils/TestEventBroker.d.ts:9:5 - (ae-undocumented) Missing documentation for "publish". +// src/testUtils/TestEventBroker.d.ts:10:5 - (ae-undocumented) Missing documentation for "subscribe". +// src/testUtils/TestEventPublisher.d.ts:6:1 - (ae-undocumented) Missing documentation for "TestEventPublisher". +// src/testUtils/TestEventPublisher.d.ts:8:5 - (ae-undocumented) Missing documentation for "setEventBroker". +// src/testUtils/TestEventPublisher.d.ts:9:5 - (ae-undocumented) Missing documentation for "eventBroker". +// src/testUtils/TestEventSubscriber.d.ts:6:1 - (ae-undocumented) Missing documentation for "TestEventSubscriber". +// src/testUtils/TestEventSubscriber.d.ts:7:5 - (ae-undocumented) Missing documentation for "name". +// src/testUtils/TestEventSubscriber.d.ts:8:5 - (ae-undocumented) Missing documentation for "topics". +// src/testUtils/TestEventSubscriber.d.ts:9:5 - (ae-undocumented) Missing documentation for "receivedEvents". +// src/testUtils/TestEventSubscriber.d.ts:11:5 - (ae-undocumented) Missing documentation for "supportsEventTopics". +// src/testUtils/TestEventSubscriber.d.ts:12:5 - (ae-undocumented) Missing documentation for "onEvent". +// src/testUtils/TestEventsService.d.ts:3:1 - (ae-undocumented) Missing documentation for "TestEventsService". +// src/testUtils/TestEventsService.d.ts:5:5 - (ae-undocumented) Missing documentation for "publish". +// src/testUtils/TestEventsService.d.ts:6:5 - (ae-undocumented) Missing documentation for "subscribe". +// src/testUtils/TestEventsService.d.ts:7:5 - (ae-undocumented) Missing documentation for "published". +// src/testUtils/TestEventsService.d.ts:8:5 - (ae-undocumented) Missing documentation for "subscribed". +// src/testUtils/TestEventsService.d.ts:9:5 - (ae-undocumented) Missing documentation for "reset". +``` diff --git a/plugins/events-backend/CHANGELOG.md b/plugins/events-backend/CHANGELOG.md index 14fa485178..645cd6af10 100644 --- a/plugins/events-backend/CHANGELOG.md +++ b/plugins/events-backend/CHANGELOG.md @@ -1,5 +1,47 @@ # @backstage/plugin-events-backend +## 0.3.13-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- 5c728ee: The events backend now has its own built-in event bus for distributing events across multiple backend instances. It exposes a new HTTP API under `/bus/v1/` for publishing and reading events from the bus, as well as its own storage and notification mechanism for events. + + The backing event store for the bus only supports scaled deployment if PostgreSQL is used as the DBMS. If SQLite or MySQL is used, the event bus will fall back to an in-memory store that does not support multiple backend instances. + + The default `EventsService` implementation from `@backstage/plugin-events-node` has also been updated to use the new events bus. + +- Updated dependencies + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/backend-openapi-utils@0.1.19-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## 0.3.12 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-events-node@0.4.0 + - @backstage/config@1.2.0 + +## 0.3.12-next.2 + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/config@1.2.0 + - @backstage/plugin-events-node@0.4.0-next.2 + ## 0.3.12-next.1 ### Patch Changes diff --git a/plugins/events-backend/dev/index.ts b/plugins/events-backend/dev/index.ts new file mode 100644 index 0000000000..d75834884e --- /dev/null +++ b/plugins/events-backend/dev/index.ts @@ -0,0 +1,151 @@ +/* + * 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 { WinstonLogger } from '@backstage/backend-defaults/rootLogger'; +import { createBackend } from '@backstage/backend-defaults'; +import { + coreServices, + createBackendPlugin, + createServiceFactory, +} from '@backstage/backend-plugin-api'; +import { mockServices } from '@backstage/backend-test-utils'; +import { eventsServiceRef } from '@backstage/plugin-events-node'; + +function makeBackend(port: number) { + const backend = createBackend(); + + backend.add( + mockServices.rootConfig.factory({ + data: { + backend: { + baseUrl: `http://localhost:${port}`, + listen: { port }, + database: { + client: 'pg', + connection: { + host: 'localhost', + port: 5432, + user: process.env.USER || 'postgres', + }, + }, + }, + }, + }), + ); + backend.add( + createServiceFactory({ + service: coreServices.rootLogger, + deps: {}, + async factory() { + return WinstonLogger.create({ + meta: { + service: 'backstage', + port, + }, + // level: 'debug', + format: WinstonLogger.colorFormat(), + }); + }, + }), + ); + backend.add(import('../src/alpha')); + + return backend; +} + +const backend7008 = makeBackend(7008); +backend7008.add( + createBackendPlugin({ + pluginId: 'producer', + register(reg) { + reg.registerInit({ + deps: { + events: eventsServiceRef, + logger: coreServices.logger, + rootLifecycle: coreServices.rootLifecycle, + }, + async init({ events, logger, rootLifecycle }) { + rootLifecycle.addStartupHook(async () => { + const publish = () => { + logger.info(`Publishing event to topic 'test'`); + events + .publish({ + eventPayload: { foo: 'bar' }, + topic: 'test', + }) + .catch(error => { + logger.error(`Failed to publish event from producer`, error); + }); + }; + publish(); + setInterval(publish, 10000); + }); + }, + }); + }, + }), +); +backend7008.start(); + +const backend7009 = makeBackend(7009); +backend7009.add( + createBackendPlugin({ + pluginId: 'consumer', + register(reg) { + reg.registerInit({ + deps: { + events: eventsServiceRef, + logger: coreServices.logger, + }, + async init({ events, logger }) { + await events.subscribe({ + id: 'test', + topics: ['test'], + async onEvent(event) { + logger.info(`Received event: ${JSON.stringify(event)}`); + }, + }); + }, + }); + }, + }), +); +backend7009.start(); + +const backend7010 = makeBackend(7010); +backend7010.add( + createBackendPlugin({ + pluginId: 'consumer', + register(reg) { + reg.registerInit({ + deps: { + events: eventsServiceRef, + logger: coreServices.logger, + }, + async init({ events, logger }) { + await events.subscribe({ + id: 'test', + topics: ['test'], + async onEvent(event) { + logger.info(`Received event: ${JSON.stringify(event)}`); + }, + }); + }, + }); + }, + }), +); +backend7010.start(); diff --git a/plugins/events-backend/migrations/20240523100528_init.js b/plugins/events-backend/migrations/20240523100528_init.js new file mode 100644 index 0000000000..9fbef79a75 --- /dev/null +++ b/plugins/events-backend/migrations/20240523100528_init.js @@ -0,0 +1,98 @@ +/* + * 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. + */ + +// @ts-check + +/** + * @param { import("knex").Knex } knex + * @returns { Promise } + */ +exports.up = async function up(knex) { + // The event bus only supports PostgresSQL + if (knex.client.config.client === 'pg') { + await knex.schema.createTable('event_bus_events', table => { + table.comment('Events published to the events bus'); + table + .bigIncrements('id') + .primary() + .comment('The unique ID of this event'); + table + .text('created_by') + .notNullable() + .comment('The principal that published the event'); + table + .dateTime('created_at') + .defaultTo(knex.fn.now()) + .notNullable() + .comment('The time that the event was created'); + table.text('topic').notNullable().comment('The topic of the event'); + table + .text('data_json') + .notNullable() + .comment('The payload data of this event'); + table + .specificType('notified_subscribers', 'text ARRAY') + .comment( + 'The IDs of the subscribers that have already consumed this event', + ); + + table.index('topic', 'event_bus_events_topic_idx'); + }); + + await knex.schema.createTable('event_bus_subscriptions', table => { + table.comment('Subscriptions to the event bus'); + table + .string('id') + .primary() + .notNullable() + .comment('The unique ID of this particular subscription'); + table + .text('created_by') + .notNullable() + .comment('The principal that created the subscription'); + table + .dateTime('created_at') + .defaultTo(knex.fn.now()) + .notNullable() + .comment('The time that the subscription was created'); + table + .dateTime('updated_at') + .defaultTo(knex.fn.now()) + .notNullable() + .comment('The time that the subscription was last updated'); + table + .bigInteger('read_until') + .notNullable() + .comment( + 'The sequence counter until which the subscription has read events', + ); + table + .specificType('topics', 'text ARRAY') + .comment('The topics that this subscriber is interested in'); + }); + } +}; + +/** + * @param { import("knex").Knex } knex + * @returns { Promise } + */ +exports.down = async function down(knex) { + if (knex.client.config.client === 'pg') { + await knex.schema.dropTable('event_bus_subscriptions'); + await knex.schema.dropTable('event_bus_events'); + } +}; diff --git a/plugins/events-backend/package.json b/plugins/events-backend/package.json index ee057c91fd..0f035e3539 100644 --- a/plugins/events-backend/package.json +++ b/plugins/events-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend", - "version": "0.3.12-next.1", + "version": "0.3.13-next.0", "backstage": { "role": "backend-plugin", "pluginId": "events", @@ -39,11 +39,13 @@ }, "files": [ "config.d.ts", - "dist" + "dist", + "migrations" ], "scripts": { "build": "backstage-cli package build", "clean": "backstage-cli package clean", + "generate": "backstage-repo-tools package schema openapi generate --server --client-package plugins/events-node", "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", @@ -51,21 +53,27 @@ "test": "backstage-cli package test" }, "dependencies": { - "@backstage/backend-common": "workspace:^", + "@backstage/backend-common": "^0.25.0", + "@backstage/backend-openapi-utils": "workspace:^", "@backstage/backend-plugin-api": "workspace:^", "@backstage/config": "workspace:^", + "@backstage/errors": "workspace:^", "@backstage/plugin-events-node": "workspace:^", + "@backstage/types": "workspace:^", "@types/express": "^4.17.6", "express": "^4.17.1", "express-promise-router": "^4.1.0", + "knex": "^3.0.0", "winston": "^3.2.1" }, "devDependencies": { - "@backstage/backend-common": "workspace:^", + "@backstage/backend-app-api": "workspace:^", + "@backstage/backend-defaults": "workspace:^", "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "@backstage/plugin-events-backend-test-utils": "workspace:^", - "supertest": "^6.1.3" + "@backstage/repo-tools": "workspace:^", + "supertest": "^7.0.0" }, "configSchema": "config.d.ts" } diff --git a/plugins/events-backend/api-report-alpha.md b/plugins/events-backend/report-alpha.api.md similarity index 100% rename from plugins/events-backend/api-report-alpha.md rename to plugins/events-backend/report-alpha.api.md diff --git a/plugins/events-backend/api-report.md b/plugins/events-backend/report.api.md similarity index 70% rename from plugins/events-backend/api-report.md rename to plugins/events-backend/report.api.md index 8b5d4e8d31..5511d8c410 100644 --- a/plugins/events-backend/api-report.md +++ b/plugins/events-backend/report.api.md @@ -56,4 +56,14 @@ export class HttpPostIngressEventPublisher { logger: LoggerService; }): HttpPostIngressEventPublisher; } + +// Warnings were encountered during analysis: +// +// src/service/DefaultEventBroker.d.ts:21:5 - (ae-undocumented) Missing documentation for "publish". +// src/service/DefaultEventBroker.d.ts:22:5 - (ae-undocumented) Missing documentation for "subscribe". +// src/service/EventsBackend.d.ts:14:5 - (ae-undocumented) Missing documentation for "setEventBroker". +// src/service/EventsBackend.d.ts:15:5 - (ae-undocumented) Missing documentation for "addPublishers". +// src/service/EventsBackend.d.ts:16:5 - (ae-undocumented) Missing documentation for "addSubscribers". +// src/service/http/HttpPostIngressEventPublisher.d.ts:15:5 - (ae-undocumented) Missing documentation for "fromConfig". +// src/service/http/HttpPostIngressEventPublisher.d.ts:24:5 - (ae-undocumented) Missing documentation for "bind". ``` diff --git a/plugins/events-backend/src/migrations.test.ts b/plugins/events-backend/src/migrations.test.ts new file mode 100644 index 0000000000..1c90260ed3 --- /dev/null +++ b/plugins/events-backend/src/migrations.test.ts @@ -0,0 +1,101 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Knex } from 'knex'; +import { TestDatabases } from '@backstage/backend-test-utils'; +import fs from 'fs'; + +const migrationsDir = `${__dirname}/../migrations`; +const migrationsFiles = fs.readdirSync(migrationsDir).sort(); + +async function migrateUpOnce(knex: Knex): Promise { + await knex.migrate.up({ directory: migrationsDir }); +} + +async function migrateDownOnce(knex: Knex): Promise { + await knex.migrate.down({ directory: migrationsDir }); +} + +async function migrateUntilBefore(knex: Knex, target: string): Promise { + const index = migrationsFiles.indexOf(target); + if (index === -1) { + throw new Error(`Migration ${target} not found`); + } + for (let i = 0; i < index; i++) { + await migrateUpOnce(knex); + } +} + +jest.setTimeout(60_000); + +describe('migrations', () => { + const databases = TestDatabases.create({ + ids: ['POSTGRES_9', 'POSTGRES_13', 'POSTGRES_16'], + }); + + it.each(databases.eachSupportedId())( + '20240523100528_init.js, %p', + async databaseId => { + const knex = await databases.init(databaseId); + + await migrateUntilBefore(knex, '20240523100528_init.js'); + await migrateUpOnce(knex); + + await knex('event_bus_events').insert({ + topic: 'test', + created_by: 'abc', + data_json: JSON.stringify({ message: 'hello' }), + notified_subscribers: ['tester'], + }); + await knex('event_bus_subscriptions').insert({ + id: 'tester', + created_by: 'abc', + read_until: '5', + topics: ['test', 'test2'], + }); + + await expect(knex('event_bus_events')).resolves.toEqual([ + { + id: '1', + created_by: 'abc', + topic: 'test', + data_json: JSON.stringify({ message: 'hello' }), + created_at: expect.anything(), + notified_subscribers: ['tester'], + }, + ]); + await expect(knex('event_bus_subscriptions')).resolves.toEqual([ + { + id: 'tester', + created_by: 'abc', + created_at: expect.anything(), + updated_at: expect.anything(), + read_until: '5', + topics: ['test', 'test2'], + }, + ]); + + await migrateDownOnce(knex); + + // This looks odd - you might expect a .toThrow at the end but that + // actually is flaky for some reason specifically on sqlite when + // performing multiple runs in sequence + await expect(knex('event_bus_events')).rejects.toEqual(expect.anything()); + + await knex.destroy(); + }, + ); +}); diff --git a/plugins/events-backend/src/schema/openapi.generated.ts b/plugins/events-backend/src/schema/openapi.generated.ts new file mode 100644 index 0000000000..8f8d6c6a82 --- /dev/null +++ b/plugins/events-backend/src/schema/openapi.generated.ts @@ -0,0 +1,291 @@ +/* + * 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. + */ + +// ****************************************************************** +// * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. * +// ****************************************************************** +import { createValidatedOpenApiRouter } from '@backstage/backend-openapi-utils'; + +export const spec = { + openapi: '3.0.3', + info: { + title: 'events', + version: '1', + description: 'The Backstage backend plugin that powers the events system.', + license: { + name: 'Apache-2.0', + url: 'http://www.apache.org/licenses/LICENSE-2.0.html', + }, + contact: {}, + }, + servers: [ + { + url: '/', + }, + ], + components: { + examples: {}, + headers: {}, + parameters: { + subscriptionId: { + name: 'subscriptionId', + in: 'path', + required: true, + allowReserved: true, + schema: { + type: 'string', + }, + }, + }, + requestBodies: {}, + responses: { + ErrorResponse: { + description: 'An error response from the backend.', + content: { + 'application/json; charset=utf-8': { + schema: { + $ref: '#/components/schemas/Error', + }, + }, + }, + }, + }, + schemas: { + Event: { + type: 'object', + required: ['topic', 'payload'], + properties: { + topic: { + type: 'string', + description: 'The topic that the event is published on', + }, + payload: { + description: 'The event payload', + }, + }, + }, + Error: { + type: 'object', + properties: { + error: { + type: 'object', + properties: { + name: { + type: 'string', + }, + message: { + type: 'string', + }, + }, + required: ['name', 'message'], + }, + request: { + type: 'object', + properties: { + method: { + type: 'string', + }, + url: { + type: 'string', + }, + }, + required: ['method', 'url'], + }, + response: { + type: 'object', + properties: { + statusCode: { + type: 'number', + }, + }, + required: ['statusCode'], + }, + }, + required: ['error', 'request', 'response'], + }, + }, + securitySchemes: { + JWT: { + type: 'http', + scheme: 'bearer', + bearerFormat: 'JWT', + }, + }, + }, + paths: { + '/bus/v1/events': { + post: { + operationId: 'PostEvent', + description: 'Publish a new event', + responses: { + '201': { + description: 'The event was published successfully', + }, + '204': { + description: + 'The event did not need to be published as all subscribers have already been notified', + }, + default: { + $ref: '#/components/responses/ErrorResponse', + }, + }, + security: [ + {}, + { + JWT: [], + }, + ], + requestBody: { + required: true, + content: { + 'application/json': { + schema: { + type: 'object', + required: ['event'], + properties: { + event: { + $ref: '#/components/schemas/Event', + }, + notifiedSubscribers: { + type: 'array', + description: + 'The IDs of subscriptions that have already received this event', + items: { + type: 'string', + }, + }, + }, + }, + examples: { + 'Publishing a simple Event': { + value: { + event: { + topic: 'test-topic', + payload: { + myData: 'foo', + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + '/bus/v1/subscriptions/{subscriptionId}': { + put: { + operationId: 'PutSubscription', + description: + 'Ensures that the subscription exists with the provided configuration', + responses: { + '201': { + description: 'The subscription exists or was created successfully', + }, + default: { + $ref: '#/components/responses/ErrorResponse', + }, + }, + security: [ + {}, + { + JWT: [], + }, + ], + parameters: [ + { + $ref: '#/components/parameters/subscriptionId', + }, + ], + requestBody: { + required: true, + content: { + 'application/json': { + schema: { + type: 'object', + required: ['topics'], + properties: { + topics: { + type: 'array', + description: 'The topics to subscribe to', + items: { + type: 'string', + }, + }, + }, + }, + examples: { + 'Subscribing to a single topic': { + value: { + topics: ['test-topic'], + }, + }, + }, + }, + }, + }, + }, + }, + '/bus/v1/subscriptions/{subscriptionId}/events': { + get: { + operationId: 'GetSubscriptionEvents', + description: 'Get new events for the provided subscription', + responses: { + '200': { + description: 'New events', + content: { + 'application/json': { + schema: { + type: 'object', + required: ['events'], + properties: { + events: { + type: 'array', + items: { + $ref: '#/components/schemas/Event', + }, + }, + }, + }, + }, + }, + }, + '202': { + description: + 'No new events are available. Response will block until the client should try again.', + }, + default: { + $ref: '#/components/responses/ErrorResponse', + }, + }, + security: [ + {}, + { + JWT: [], + }, + ], + parameters: [ + { + $ref: '#/components/parameters/subscriptionId', + }, + ], + }, + }, + }, +} as const; +export const createOpenApiRouter = async ( + options?: Parameters['1'], +) => createValidatedOpenApiRouter(spec, options); diff --git a/plugins/events-backend/src/schema/openapi.yaml b/plugins/events-backend/src/schema/openapi.yaml new file mode 100644 index 0000000000..97f7705f87 --- /dev/null +++ b/plugins/events-backend/src/schema/openapi.yaml @@ -0,0 +1,182 @@ +openapi: 3.0.3 +info: + title: events + version: '1' + description: The Backstage backend plugin that powers the events system. + license: + name: Apache-2.0 + url: http://www.apache.org/licenses/LICENSE-2.0.html + contact: {} +servers: + - url: / +components: + examples: {} + headers: {} + parameters: + subscriptionId: + name: subscriptionId + in: path + required: true + allowReserved: true + schema: + type: string + requestBodies: {} + responses: + ErrorResponse: + description: An error response from the backend. + content: + application/json; charset=utf-8: + schema: + $ref: '#/components/schemas/Error' + schemas: + Event: + type: object + required: + - topic + - payload + properties: + topic: + type: string + description: The topic that the event is published on + payload: + description: The event payload + + Error: + type: object + properties: + error: + type: object + properties: + name: + type: string + message: + type: string + required: + - name + - message + request: + type: object + properties: + method: + type: string + url: + type: string + required: + - method + - url + response: + type: object + properties: + statusCode: + type: number + required: + - statusCode + required: + - error + - request + - response + securitySchemes: + JWT: + type: http + scheme: bearer + bearerFormat: JWT +paths: + /bus/v1/events: + post: + operationId: PostEvent + description: Publish a new event + responses: + '201': + description: The event was published successfully + '204': + description: The event did not need to be published as all subscribers have already been notified + default: + $ref: '#/components/responses/ErrorResponse' + security: + - {} + - JWT: [] + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - event + properties: + event: + $ref: '#/components/schemas/Event' + notifiedSubscribers: + type: array + description: The IDs of subscriptions that have already received this event + items: + type: string + examples: + Publishing a simple Event: + value: + event: + topic: test-topic + payload: + myData: foo + + /bus/v1/subscriptions/{subscriptionId}: + put: + operationId: PutSubscription + description: Ensures that the subscription exists with the provided configuration + responses: + '201': + description: The subscription exists or was created successfully + default: + $ref: '#/components/responses/ErrorResponse' + security: + - {} + - JWT: [] + parameters: + - $ref: '#/components/parameters/subscriptionId' + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - topics + properties: + topics: + type: array + description: The topics to subscribe to + items: + type: string + examples: + Subscribing to a single topic: + value: + topics: + - test-topic + + /bus/v1/subscriptions/{subscriptionId}/events: + get: + operationId: GetSubscriptionEvents + description: Get new events for the provided subscription + responses: + '200': + description: New events + content: + application/json: + schema: + type: object + required: + - events + properties: + events: + type: array + items: + $ref: '#/components/schemas/Event' + '202': + description: No new events are available. Response will block until the client should try again. + default: + $ref: '#/components/responses/ErrorResponse' + security: + - {} + - JWT: [] + parameters: + - $ref: '#/components/parameters/subscriptionId' diff --git a/plugins/events-backend/src/service/EventsPlugin.test.ts b/plugins/events-backend/src/service/EventsPlugin.test.ts index 48ce1090fb..2c0befe1fd 100644 --- a/plugins/events-backend/src/service/EventsPlugin.test.ts +++ b/plugins/events-backend/src/service/EventsPlugin.test.ts @@ -14,11 +14,20 @@ * limitations under the License. */ +/* eslint-disable jest/expect-expect */ + import { createBackendModule, createServiceFactory, } from '@backstage/backend-plugin-api'; -import { mockServices, startTestBackend } from '@backstage/backend-test-utils'; +import { + TestBackend, + TestDatabaseId, + TestDatabases, + mockCredentials, + mockServices, + startTestBackend, +} from '@backstage/backend-test-utils'; import { eventsServiceRef } from '@backstage/plugin-events-node'; import { eventsExtensionPoint } from '@backstage/plugin-events-node/alpha'; import { TestEventsService } from '@backstage/plugin-events-backend-test-utils'; @@ -92,4 +101,334 @@ describe('eventsPlugin', () => { test: 'fake-ext', }); }); + + describe('event bus', () => { + class ReqHelper { + constructor(private readonly backend: TestBackend) {} + + subscribe(id: string, topics: string[], options?: { auth?: string }) { + return request(this.backend.server) + .put(`/api/events/bus/v1/subscriptions/${id}`) + .set( + 'authorization', + options?.auth ?? mockCredentials.service.header(), + ) + .send({ topics }); + } + + publish( + topic: string, + payload: unknown, + options?: { notifiedSubscribers?: string[] }, + ) { + return request(this.backend.server) + .post('/api/events/bus/v1/events') + .set('authorization', mockCredentials.service.header()) + .send({ + event: { topic, payload }, + notifiedSubscribers: options?.notifiedSubscribers, + }); + } + + readEvents(id: string) { + return request(this.backend.server) + .get(`/api/events/bus/v1/subscriptions/${id}/events`) + .set('authorization', mockCredentials.service.header()) + .send(); + } + } + + const databases = TestDatabases.create({ + ids: ['SQLITE_3', 'MYSQL_8', 'POSTGRES_9', 'POSTGRES_13', 'POSTGRES_16'], + }); + + async function mockKnexFactory(databaseId: TestDatabaseId) { + const knex = await databases.init(databaseId); + return mockServices.database.mock({ + getClient: async () => knex, + }).factory; + } + + let backend: TestBackend | undefined = undefined; + afterEach(async () => { + if (backend) { + await backend.stop(); + backend = undefined; + } + }); + + it.each(databases.eachSupportedId())( + 'should be possible to publish events as a service, %p', + async databaseId => { + backend = await startTestBackend({ + features: [eventsPlugin, await mockKnexFactory(databaseId)], + }); + const helper = new ReqHelper(backend); + + await helper + .publish('test', { n: 1 }) + .set('authorization', mockCredentials.none.header()) + .expect(401); + + await helper + .publish('test', { n: 1 }) + .set('authorization', mockCredentials.user.header()) + .expect(403); + + await helper + .publish('test', { n: 1 }) + .set('authorization', mockCredentials.service.header()) + .expect(204); // 204, since there are no subscribers + }, + ); + + it.each(databases.eachSupportedId())( + 'should be possible to subscribe as a service and receive an event, %p', + async databaseId => { + backend = await startTestBackend({ + features: [eventsPlugin, await mockKnexFactory(databaseId)], + }); + const helper = new ReqHelper(backend); + + await helper + .subscribe('tester', ['test']) + .set('authorization', mockCredentials.none.header()) + .expect(401); + + await helper + .subscribe('tester', ['test']) + .set('authorization', mockCredentials.user.header()) + .expect(403); + + await helper.subscribe('tester', ['test']).expect(201); + + await helper + .readEvents('tester') + .set('authorization', mockCredentials.none.header()) + .expect(401); + + await helper + .readEvents('tester') + .set('authorization', mockCredentials.user.header()) + .expect(403); + + await helper.publish('test', { n: 1 }).expect(201); // 201, since there is a subscriber + + await helper.readEvents('tester').expect(200, { + events: [{ topic: 'test', payload: { n: 1 } }], + }); + }, + ); + + it.each(databases.eachSupportedId())( + 'should only send an event for each subscriber once, %p', + async databaseId => { + backend = await startTestBackend({ + features: [eventsPlugin, await mockKnexFactory(databaseId)], + }); + const helper = new ReqHelper(backend); + + // 2 subscribers + await helper.subscribe('tester-1', ['test']).expect(201); + await helper.subscribe('tester-2', ['test']).expect(201); + + // A single event + await helper.publish('test', { n: 1 }).expect(201); + + // Single client for subscriber 1 gets the event + await helper.readEvents('tester-1').expect(200, { + events: [{ topic: 'test', payload: { n: 1 } }], + }); + + // Two clients for subscriber 2, only one gets the event + const res1 = helper.readEvents('tester-2'); + const res2 = helper.readEvents('tester-2'); + + const res = await Promise.race([res1, res2]); + expect(res.status).toBe(200); + expect(res.body).toEqual({ + events: [{ topic: 'test', payload: { n: 1 } }], + }); + + // Post another event, which triggers the other client to return + await helper.publish('test', { n: 2 }).expect(201); + + const otherRes = await Promise.all([res1, res2]).then(rs => + rs.find(r => r !== res), + ); + expect(otherRes?.status).toBe(202); + + // Reading subscriber 2 should now return the second event only + await helper.readEvents('tester-2').expect(200, { + events: [{ topic: 'test', payload: { n: 2 } }], + }); + }, + ); + + it.each(databases.eachSupportedId())( + 'should not notify subscribers that have already consumed the event, %p', + async databaseId => { + backend = await startTestBackend({ + features: [eventsPlugin, await mockKnexFactory(databaseId)], + }); + const helper = new ReqHelper(backend); + + // 2 subscribers + await helper.subscribe('tester-1', ['test']).expect(201); + await helper.subscribe('tester-2', ['test']).expect(201); + + // A single event for each subscriber, that should not be sent to the other one + await helper + .publish( + 'test', + { for: 'tester-2' }, + { + notifiedSubscribers: ['tester-1'], + }, + ) + .expect(201); + await helper + .publish( + 'test', + { for: 'tester-1' }, + { + notifiedSubscribers: ['tester-2'], + }, + ) + .expect(201); + + // Single client for subscriber 1 gets the event + await helper.readEvents('tester-1').expect(200, { + events: [{ topic: 'test', payload: { for: 'tester-1' } }], + }); + // Single client for subscriber 2 gets the event + await helper.readEvents('tester-2').expect(200, { + events: [{ topic: 'test', payload: { for: 'tester-2' } }], + }); + }, + ); + + it.each(databases.eachSupportedId())( + 'should return multiple events in order, %p', + async databaseId => { + backend = await startTestBackend({ + features: [eventsPlugin, await mockKnexFactory(databaseId)], + }); + const helper = new ReqHelper(backend); + + // 2 subscribers + await helper.subscribe('tester', ['test']).expect(201); + + // A sequence of events published one at a time + for (let n = 0; n < 15; ++n) { + await helper.publish('test', { n }).expect(201); + } + + // Batch size it 10 + await helper.readEvents('tester').expect(200, { + events: [ + { topic: 'test', payload: { n: 0 } }, + { topic: 'test', payload: { n: 1 } }, + { topic: 'test', payload: { n: 2 } }, + { topic: 'test', payload: { n: 3 } }, + { topic: 'test', payload: { n: 4 } }, + { topic: 'test', payload: { n: 5 } }, + { topic: 'test', payload: { n: 6 } }, + { topic: 'test', payload: { n: 7 } }, + { topic: 'test', payload: { n: 8 } }, + { topic: 'test', payload: { n: 9 } }, + ], + }); + + await helper.readEvents('tester').expect(200, { + events: [ + { topic: 'test', payload: { n: 10 } }, + { topic: 'test', payload: { n: 11 } }, + { topic: 'test', payload: { n: 12 } }, + { topic: 'test', payload: { n: 13 } }, + { topic: 'test', payload: { n: 14 } }, + ], + }); + }, + ); + + it.each(databases.eachSupportedId())( + 'should skip publishing if all subscribers have already consumed the event, %p', + async databaseId => { + backend = await startTestBackend({ + features: [eventsPlugin, await mockKnexFactory(databaseId)], + }); + const helper = new ReqHelper(backend); + + await helper.subscribe('tester', ['test']).expect(201); + + await helper + .publish( + 'test', + { for: 'tester-2' }, + { notifiedSubscribers: ['tester'] }, + ) + .expect(204); + }, + ); + + it.each(databases.eachSupportedId())( + 'should time out when no events are available, %p', + async databaseId => { + backend = await startTestBackend({ + features: [eventsPlugin, await mockKnexFactory(databaseId)], + }); + const helper = new ReqHelper(backend); + await helper.subscribe('tester', ['test']).expect(201); + + jest.useFakeTimers({ + advanceTimers: true, + }); + + try { + // Can't use supertest for this one because it can't handle the partially blocking response + const res = await fetch( + `http://localhost:${backend.server.port()}/api/events/bus/v1/subscriptions/tester/events`, + { + headers: { + authorization: mockCredentials.service.header(), + }, + }, + ); + + expect(res.status).toBe(202); + + const reader = res.body!.getReader(); + const isClosed = () => + Promise.race([ + reader + .read() + .then(() => reader.closed) + .then(() => true), + new Promise(r => setTimeout(r, 100, false)), + ]); + + await expect(isClosed()).resolves.toBe(false); + await jest.advanceTimersByTimeAsync(30000); + await expect(isClosed()).resolves.toBe(false); + await jest.advanceTimersByTimeAsync(30000); + await expect(isClosed()).resolves.toBe(true); + } finally { + jest.useRealTimers(); + } + }, + ); + + it.each(databases.eachSupportedId())( + 'should refuse listen without a subscription, %p', + async databaseId => { + backend = await startTestBackend({ + features: [eventsPlugin, await mockKnexFactory(databaseId)], + }); + const helper = new ReqHelper(backend); + + await helper.readEvents('nonexistent').expect(404); + }, + ); + }); }); diff --git a/plugins/events-backend/src/service/EventsPlugin.ts b/plugins/events-backend/src/service/EventsPlugin.ts index d95dbf3efc..1369ee98ca 100644 --- a/plugins/events-backend/src/service/EventsPlugin.ts +++ b/plugins/events-backend/src/service/EventsPlugin.ts @@ -28,6 +28,7 @@ import { } from '@backstage/plugin-events-node'; import Router from 'express-promise-router'; import { HttpPostIngressEventPublisher } from './http'; +import { createEventBusRouter } from './hub'; class EventsExtensionPointImpl implements EventsExtensionPoint { #httpPostIngresses: HttpPostIngressOptions[] = []; @@ -74,10 +75,23 @@ export const eventsPlugin = createBackendPlugin({ deps: { config: coreServices.rootConfig, events: eventsServiceRef, + database: coreServices.database, logger: coreServices.logger, + scheduler: coreServices.scheduler, + lifecycle: coreServices.lifecycle, + httpAuth: coreServices.httpAuth, router: coreServices.httpRouter, }, - async init({ config, events, logger, router }) { + async init({ + config, + events, + database, + logger, + scheduler, + lifecycle, + httpAuth, + router, + }) { const ingresses = Object.fromEntries( extensionPoint.httpPostIngresses.map(ingress => [ ingress.topic, @@ -93,6 +107,17 @@ export const eventsPlugin = createBackendPlugin({ }); const eventsRouter = Router(); http.bind(eventsRouter); + + router.use( + await createEventBusRouter({ + database, + logger, + httpAuth, + scheduler, + lifecycle, + }), + ); + router.use(eventsRouter); router.addAuthPolicy({ allow: 'unauthenticated', diff --git a/plugins/events-backend/src/service/hub/DatabaseEventBusStore.test.ts b/plugins/events-backend/src/service/hub/DatabaseEventBusStore.test.ts new file mode 100644 index 0000000000..7086d90cbf --- /dev/null +++ b/plugins/events-backend/src/service/hub/DatabaseEventBusStore.test.ts @@ -0,0 +1,245 @@ +/* + * 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 { + TestDatabases, + mockCredentials, + mockServices, +} from '@backstage/backend-test-utils'; +import { DatabaseEventBusStore } from './DatabaseEventBusStore'; + +const logger = mockServices.logger.mock(); + +const databases = TestDatabases.create({ + ids: ['POSTGRES_9', 'POSTGRES_13', 'POSTGRES_16'], +}); + +describe('DatabaseEventBusStore', () => { + it.each(databases.eachSupportedId())( + 'should clean up old events, %p', + async databaseId => { + const db = await databases.init(databaseId); + const store = await DatabaseEventBusStore.forTest({ logger, db }); + + await store.upsertSubscription( + 'tester-1', + ['test'], + mockCredentials.service(), + ); + await store.upsertSubscription( + 'tester-2', + ['test'], + mockCredentials.service(), + ); + + for (let i = 0; i < 10; ++i) { + await store.publish({ + event: { topic: 'test', eventPayload: { n: i } }, + credentials: mockCredentials.service(), + }); + } + + const { events: events1 } = await store.readSubscription('tester-1'); + expect(events1.length).toBe(10); + + await store.clean(); + + await expect(store.readSubscription('tester-2')).rejects.toThrow( + "Subscription with ID 'tester-2' not found", + ); + + await store.upsertSubscription( + 'tester-3', + ['test'], + mockCredentials.service(), + ); + + // Reset read pointer to read form the beginning + await db('event_bus_subscriptions').select({ id: 'tester-3' }).update({ + read_until: 0, + }); + + const { events: events3 } = await store.readSubscription('tester-3'); + expect(events3.length).toBe(5); + }, + ); + + it.each(databases.eachSupportedId())( + 'should always clean up events outside the max age window, %p', + async databaseId => { + const db = await databases.init(databaseId); + const store = await DatabaseEventBusStore.forTest({ + logger, + db, + maxAge: 0, + }); + + await store.upsertSubscription( + 'tester-1', + ['test'], + mockCredentials.service(), + ); + await store.upsertSubscription( + 'tester-2', + ['test'], + mockCredentials.service(), + ); + + for (let i = 0; i < 10; ++i) { + await store.publish({ + event: { topic: 'test', eventPayload: { n: i } }, + credentials: mockCredentials.service(), + }); + } + + const { events: events1 } = await store.readSubscription('tester-1'); + expect(events1.length).toBe(10); + + await store.clean(); + + await expect(store.readSubscription('tester-2')).rejects.toThrow( + "Subscription with ID 'tester-2' not found", + ); + + await store.upsertSubscription( + 'tester-3', + ['test'], + mockCredentials.service(), + ); + + // Reset read pointer to read form the beginning + await db('event_bus_subscriptions').select({ id: 'tester-3' }).update({ + read_until: 0, + }); + + const { events: events3 } = await store.readSubscription('tester-3'); + expect(events3.length).toBe(0); + }, + ); + + it.each(databases.eachSupportedId())( + 'should not clean up events within the min age window, %p', + async databaseId => { + const db = await databases.init(databaseId); + const store = await DatabaseEventBusStore.forTest({ + logger, + db, + minAge: 1000, + }); + + await store.upsertSubscription( + 'tester-1', + ['test'], + mockCredentials.service(), + ); + + for (let i = 0; i < 10; ++i) { + await store.publish({ + event: { topic: 'test', eventPayload: { n: i } }, + credentials: mockCredentials.service(), + }); + } + + await store.clean(); + + const { events: events1 } = await store.readSubscription('tester-1'); + expect(events1.length).toBe(10); + }, + ); + + it.each(databases.eachSupportedId())( + 'should clean up a large number of events, %p', + async databaseId => { + const db = await databases.init(databaseId); + const store = await DatabaseEventBusStore.forTest({ + logger, + db, + }); + + const COUNT = '100000'; + + await db.raw(` + INSERT INTO event_bus_events (id, created_by, topic, data_json) + SELECT id, 'abc', 'test', '{}' + FROM generate_series(1, ${COUNT}) AS id + `); + + await expect(db('event_bus_events').count()).resolves.toEqual([ + { count: COUNT }, + ]); + + const start = Date.now(); + + await store.clean(); + + // Local testing shows this takes about 80ms, but if this is flaky we can + // reduce the count down to 10_000. + expect(Date.now() - start).toBeLessThan(500); + + await expect(db('event_bus_events').count()).resolves.toEqual([ + { count: '5' }, + ]); + }, + ); + + it.each(databases.eachSupportedId())( + 'should perform well when looking up events by topic, %p', + async databaseId => { + const db = await databases.init(databaseId); + const store = await DatabaseEventBusStore.forTest({ + logger, + db, + }); + + const COUNT = '100000'; + + // Insert 100,000 events, a lot more than we'd expect to ever have + // in a real-world scenario given our count window size is 10,000. + await db.raw(` + INSERT INTO event_bus_events (id, created_by, topic, data_json, notified_subscribers) + SELECT id, 'abc', CONCAT('test-', MOD(id, 10)), CONCAT('{"payload":{"id":"', id, '"}}'), '{"${String( + Math.random(), + ).slice(2, 6)}"}' + FROM generate_series(1, ${COUNT}) AS id + `); + await db('event_bus_subscriptions').insert({ + id: 'tester', + created_by: 'abc', + read_until: 0, + topics: ['test-5'], + }); + + const start = Date.now(); + const { events } = await store.readSubscription('tester'); + const duration = Date.now() - start; + + expect(events).toEqual([ + { topic: 'test-5', eventPayload: { id: '5' } }, + { topic: 'test-5', eventPayload: { id: '15' } }, + { topic: 'test-5', eventPayload: { id: '25' } }, + { topic: 'test-5', eventPayload: { id: '35' } }, + { topic: 'test-5', eventPayload: { id: '45' } }, + { topic: 'test-5', eventPayload: { id: '55' } }, + { topic: 'test-5', eventPayload: { id: '65' } }, + { topic: 'test-5', eventPayload: { id: '75' } }, + { topic: 'test-5', eventPayload: { id: '85' } }, + { topic: 'test-5', eventPayload: { id: '95' } }, + ]); + + expect(duration).toBeLessThan(20); + }, + ); +}); diff --git a/plugins/events-backend/src/service/hub/DatabaseEventBusStore.ts b/plugins/events-backend/src/service/hub/DatabaseEventBusStore.ts new file mode 100644 index 0000000000..107dabfc27 --- /dev/null +++ b/plugins/events-backend/src/service/hub/DatabaseEventBusStore.ts @@ -0,0 +1,622 @@ +/* + * 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 { EventParams } from '@backstage/plugin-events-node'; +import { EventBusStore } from './types'; +import { Knex } from 'knex'; +import { + BackstageCredentials, + BackstageServicePrincipal, + DatabaseService, + LifecycleService, + LoggerService, + SchedulerService, + resolvePackagePath, +} from '@backstage/backend-plugin-api'; +import { ForwardedError, NotFoundError } from '@backstage/errors'; +import { HumanDuration, durationToMilliseconds } from '@backstage/types'; + +const WINDOW_MAX_COUNT_DEFAULT = 10_000; +const WINDOW_MIN_AGE_DEFAULT = { minutes: 10 }; +const WINDOW_MAX_AGE_DEFAULT = { days: 1 }; + +const MAX_BATCH_SIZE = 10; +const LISTENER_CONNECTION_TIMEOUT_MS = 60_000; +const KEEPALIVE_INTERVAL_MS = 60_000; + +const TABLE_EVENTS = 'event_bus_events'; +const TABLE_SUBSCRIPTIONS = 'event_bus_subscriptions'; +const TOPIC_PUBLISH = 'event_bus_publish'; + +type EventsRow = { + id: string; + created_by: string; + created_at: Date; + topic: string; + data_json: string; + notified_subscribers: string[]; +}; + +type SubscriptionsRow = { + id: string; + created_by: string; + created_at: Date; + updated_at: Date; + read_until: string; + topics: string[]; +}; + +function creatorId( + credentials: BackstageCredentials, +) { + return `service=${credentials.principal.subject}`; +} + +const migrationsDir = resolvePackagePath( + '@backstage/plugin-events-backend', + 'migrations', +); + +interface InternalDbClient { + acquireRawConnection(): Promise; + destroyRawConnection(conn: InternalDbConnection): Promise; +} + +interface InternalDbConnection { + query(sql: string): Promise; + end(): Promise; + on( + event: 'notification', + listener: (event: { channel: string; payload: string }) => void, + ): void; + on(event: 'error', listener: (error: Error) => void): void; + on(event: 'end', listener: (error?: Error) => void): void; + removeAllListeners(): void; +} + +// This internal class manages a single connection to the database that all listeners share +class DatabaseEventBusListener { + readonly #client: InternalDbClient; + readonly #logger: LoggerService; + + readonly #listeners = new Set<{ + topics: Set; + resolve: (result: { topic: string }) => void; + reject: (error: Error) => void; + }>(); + + #isShuttingDown = false; + #connPromise?: Promise; + #connTimeout?: NodeJS.Timeout; + #keepaliveInterval?: NodeJS.Timeout; + + constructor(client: InternalDbClient, logger: LoggerService) { + this.#client = client; + this.#logger = logger.child({ type: 'DatabaseEventBusListener' }); + } + + async setupListener( + topics: Set, + signal: AbortSignal, + ): Promise<{ waitForUpdate(): Promise<{ topic: string }> }> { + if (this.#connTimeout) { + clearTimeout(this.#connTimeout); + this.#connTimeout = undefined; + } + + await this.#ensureConnection(); + + const updatePromise = new Promise<{ topic: string }>((resolve, reject) => { + const listener = { + topics, + resolve(result: { topic: string }) { + resolve(result); + cleanup(); + }, + reject(err: Error) { + reject(err); + cleanup(); + }, + }; + this.#listeners.add(listener); + + const onAbort = () => { + this.#listeners.delete(listener); + this.#maybeTimeoutConnection(); + reject(signal.reason); + cleanup(); + }; + + function cleanup() { + signal.removeEventListener('abort', onAbort); + } + + signal.addEventListener('abort', onAbort); + }); + + // Ignore unhandled rejections + updatePromise.catch(() => {}); + + return { waitForUpdate: () => updatePromise }; + } + + async shutdown() { + if (this.#isShuttingDown) { + return; + } + this.#isShuttingDown = true; + const conn = await this.#connPromise?.catch(() => undefined); + if (conn) { + this.#destroyConnection(conn); + } + } + + #handleNotify(topic: string) { + this.#logger.debug(`Listener received notification for topic '${topic}'`); + for (const l of this.#listeners) { + if (l.topics.has(topic)) { + l.resolve({ topic }); + this.#listeners.delete(l); + } + } + this.#maybeTimeoutConnection(); + } + + // We don't try to reconnect on error, instead we notify all listeners and let + // them try to establish a new connection + #handleError(error: Error) { + this.#logger.error( + `Listener connection failed, notifying all listeners`, + error, + ); + for (const l of this.#listeners) { + l.reject(new Error('Listener connection failed')); + } + this.#listeners.clear(); + this.#maybeTimeoutConnection(); + } + + #maybeTimeoutConnection() { + // If we don't have any listeners, destroy the connection after a timeout + if (this.#listeners.size === 0 && !this.#connTimeout) { + this.#connTimeout = setTimeout(() => { + this.#connTimeout = undefined; + this.#connPromise?.then(conn => { + this.#logger.info('Listener connection timed out, destroying'); + this.#connPromise = undefined; + this.#destroyConnection(conn); + }); + }, LISTENER_CONNECTION_TIMEOUT_MS); + } + } + + #destroyConnection(conn: InternalDbConnection) { + if (this.#keepaliveInterval) { + clearInterval(this.#keepaliveInterval); + this.#keepaliveInterval = undefined; + } + this.#client.destroyRawConnection(conn).catch(error => { + this.#logger.error(`Listener failed to destroy connection`, error); + }); + conn.removeAllListeners(); + } + + async #ensureConnection() { + if (this.#isShuttingDown) { + throw new Error('Listener is shutting down'); + } + if (this.#connPromise) { + await this.#connPromise; + return; + } + this.#connPromise = Promise.resolve().then(async () => { + const conn = await this.#client.acquireRawConnection(); + + try { + await conn.query(`LISTEN ${TOPIC_PUBLISH}`); + + // Set up a keepalive interval to make sure the connection stays alive + if (this.#keepaliveInterval) { + clearInterval(this.#keepaliveInterval); + } + this.#keepaliveInterval = setInterval(() => { + conn.query('select 1').catch(error => { + this.#connPromise = undefined; + this.#destroyConnection(conn); + this.#handleError(new ForwardedError('Keepalive failed', error)); + }); + }, KEEPALIVE_INTERVAL_MS); + + conn.on('notification', event => { + this.#handleNotify(event.payload); + }); + conn.on('error', error => { + this.#connPromise = undefined; + this.#destroyConnection(conn); + this.#handleError(error); + }); + conn.on('end', error => { + this.#connPromise = undefined; + this.#destroyConnection(conn); + this.#handleError( + error ?? new Error('Connection ended unexpectedly'), + ); + }); + return conn; + } catch (error) { + this.#destroyConnection(conn); + throw error; + } + }); + try { + await this.#connPromise; + } catch (error) { + this.#connPromise = undefined; + throw error; + } + } +} + +export class DatabaseEventBusStore implements EventBusStore { + static async create(options: { + database: DatabaseService; + logger: LoggerService; + scheduler: SchedulerService; + lifecycle: LifecycleService; + window?: { + /** Events within this range will never be deleted */ + minAge?: HumanDuration; + /** Events outside of this age will always be deleted */ + maxAge?: HumanDuration; + /** Events outside of this count will be deleted if they are outside the minAge window */ + maxCount?: number; + }; + }): Promise { + const db = await options.database.getClient(); + + if (db.client.config.client !== 'pg') { + throw new Error( + `DatabaseEventBusStore only supports PostgreSQL, got '${db.client.config.client}'`, + ); + } + + if (!options.database.migrations?.skip) { + await db.migrate.latest({ + directory: migrationsDir, + }); + } + + const listener = new DatabaseEventBusListener(db.client, options.logger); + + const store = new DatabaseEventBusStore( + db, + options.logger, + listener, + options.window?.maxCount ?? WINDOW_MAX_COUNT_DEFAULT, + durationToMilliseconds(options.window?.minAge ?? WINDOW_MIN_AGE_DEFAULT), + durationToMilliseconds(options.window?.maxAge ?? WINDOW_MAX_AGE_DEFAULT), + ); + + await options.scheduler.scheduleTask({ + id: 'event-bus-cleanup', + frequency: { seconds: 10 }, + timeout: { minutes: 1 }, + initialDelay: { seconds: 10 }, + fn: () => store.#cleanup(), + }); + + options.lifecycle.addShutdownHook(async () => { + await listener.shutdown(); + }); + + return store; + } + + /** @internal */ + static async forTest({ + db, + logger, + minAge = 0, + maxAge = 10_000, + }: { + db: Knex; + logger: LoggerService; + minAge?: number; + maxAge?: number; + }) { + await db.migrate.latest({ directory: migrationsDir }); + + const store = new DatabaseEventBusStore( + db, + logger, + new DatabaseEventBusListener(db.client, logger), + 5, + minAge, + maxAge, + ); + + return Object.assign(store, { clean: () => store.#cleanup() }); + } + + readonly #db: Knex; + readonly #logger: LoggerService; + readonly #listener: DatabaseEventBusListener; + readonly #windowMaxCount: number; + readonly #windowMinAge: number; + readonly #windowMaxAge: number; + + private constructor( + db: Knex, + logger: LoggerService, + listener: DatabaseEventBusListener, + windowMaxCount: number, + windowMinAge: number, + windowMaxAge: number, + ) { + this.#db = db; + this.#logger = logger; + this.#listener = listener; + this.#windowMaxCount = windowMaxCount; + this.#windowMinAge = windowMinAge; + this.#windowMaxAge = windowMaxAge; + } + + async publish(options: { + event: EventParams; + notifiedSubscribers?: string[]; + credentials: BackstageCredentials; + }): Promise<{ eventId: string } | undefined> { + const topic = options.event.topic; + const notifiedSubscribers = options.notifiedSubscribers ?? []; + // This query inserts a new event into the database, but only if there are + // subscribers to the topic that have not already been notified + const result = await this.#db + // There's no clean way to create a INSERT INTO .. SELECT with knex, so we end up with quite a lot of .raw(...) + .into( + this.#db.raw('?? (??, ??, ??, ??)', [ + TABLE_EVENTS, + // These are the rows that we insert, and should match the SELECT below + 'created_by', + 'topic', + 'data_json', + 'notified_subscribers', + ]), + ) + .insert( + (q: Knex.QueryBuilder) => + q + // We're not reading data to insert from anywhere else, just raw data + .select( + this.#db.raw('?', [creatorId(options.credentials)]), + this.#db.raw('?', [topic]), + this.#db.raw('?', [ + JSON.stringify({ + payload: options.event.eventPayload, + metadata: options.event.metadata, + }), + ]), + this.#db.raw('?', [notifiedSubscribers]), + ) + // The rest of this query is to check whether there are any + // subscribers that have not been notified yet + .from(TABLE_SUBSCRIPTIONS) + .whereNotIn('id', notifiedSubscribers) // Skip notified subscribers + .andWhere(this.#db.raw('? = ANY(topics)', [topic])) // Match topic + .having(this.#db.raw('count(*)'), '>', 0), // Check if there are any results + ) + .returning<{ id: string }[]>('id'); + + if (result.length === 0) { + return undefined; + } + if (result.length > 1) { + throw new Error( + `Failed to insert event, unexpectedly updated ${result.length} rows`, + ); + } + + const [{ id }] = result; + + // Notify other event bus instances that an event is available on the topic + const notifyResult = await this.#db.select( + this.#db.raw(`pg_notify(?, ?)`, [TOPIC_PUBLISH, topic]), + ); + if (notifyResult?.length !== 1) { + this.#logger.warn( + `Failed to notify subscribers of event with ID '${id}' on topic '${topic}'`, + ); + } + + return { eventId: id }; + } + + async upsertSubscription( + id: string, + topics: string[], + credentials: BackstageCredentials, + ): Promise { + const [{ max: maxId }] = await this.#db(TABLE_EVENTS).max('id'); + const result = await this.#db(TABLE_SUBSCRIPTIONS) + .insert({ + id, + created_by: creatorId(credentials), + updated_at: this.#db.fn.now(), + topics, + read_until: maxId || 0, + }) + .onConflict('id') + .merge(['created_by', 'topics', 'updated_at']) + .returning('*'); + + if (result.length !== 1) { + throw new Error( + `Failed to upsert subscription, updated ${result.length} rows`, + ); + } + } + + async readSubscription(id: string): Promise<{ events: EventParams[] }> { + // The below query selects the subscription we're reading from, locks it for + // an update, reads events for the subscription up to the limit, and then + // updates the pointer to the last read event. + // + // This is written as a plain SQL query to spare us all the horrors of + // expressing this in knex. + + const { rows: result } = await this.#db.raw<{ + rows: [] | [{ events: EventsRow[] }]; + }>( + ` + WITH subscription AS ( + SELECT topics, read_until + FROM event_bus_subscriptions + WHERE id = :id + FOR UPDATE + ), + selected_events AS ( + SELECT event_bus_events.* + FROM event_bus_events + INNER JOIN subscription + ON event_bus_events.topic = ANY(subscription.topics) + WHERE event_bus_events.id > subscription.read_until + AND NOT :id = ANY(event_bus_events.notified_subscribers) + ORDER BY event_bus_events.id ASC LIMIT :limit + ), + last_event_id AS ( + SELECT max(id) AS last_event_id + FROM selected_events + ), + events_array AS ( + SELECT json_agg(row_to_json(selected_events)) AS events + FROM selected_events + ) + UPDATE event_bus_subscriptions + SET read_until = COALESCE(last_event_id, (SELECT MAX(id) FROM event_bus_events), 0) + FROM events_array, last_event_id + WHERE event_bus_subscriptions.id = :id + RETURNING events_array.events + `, + { id, limit: MAX_BATCH_SIZE }, + ); + + if (result.length === 0) { + throw new NotFoundError(`Subscription with ID '${id}' not found`); + } else if (result.length > 1) { + throw new Error( + `Failed to read subscription, unexpectedly updated ${result.length} rows`, + ); + } + + const rows = result[0].events; + if (!rows || rows.length === 0) { + return { events: [] }; + } + + return { + events: rows.map(row => { + const { payload, metadata } = JSON.parse(row.data_json); + return { + topic: row.topic, + eventPayload: payload, + metadata, + }; + }), + }; + } + + async setupListener( + subscriptionId: string, + options: { + signal: AbortSignal; + }, + ): Promise<{ waitForUpdate(): Promise<{ topic: string }> }> { + const result = await this.#db(TABLE_SUBSCRIPTIONS) + .select('topics') + .where({ id: subscriptionId }) + .first(); + + if (!result) { + throw new NotFoundError( + `Subscription with ID '${subscriptionId}' not found`, + ); + } + + options.signal.throwIfAborted(); + + return this.#listener.setupListener( + new Set(result.topics ?? []), + options.signal, + ); + } + + async #cleanup() { + try { + const eventCount = await this.#db(TABLE_EVENTS) + .delete() + // Delete any events that are outside both the min age and size window + .orWhere(inner => + inner + .whereIn( + 'id', + this.#db + .select('id') + .from(TABLE_EVENTS) + .orderBy('id', 'desc') + .offset(this.#windowMaxCount), + ) + .andWhere( + 'created_at', + '<', + new Date(Date.now() - this.#windowMinAge), + ), + ) + // If events are outside the max age they will always be deleted + .orWhere('created_at', '<', new Date(Date.now() - this.#windowMaxAge)); + + if (eventCount > 0) { + this.#logger.info( + `Event cleanup resulted in ${eventCount} old events being deleted`, + ); + } + } catch (error) { + this.#logger.error('Event cleanup failed', error); + } + + try { + // Delete any subscribers that aren't keeping up with current events + const [{ min: minId }] = await this.#db(TABLE_EVENTS).min('id'); + + let subscriberCount; + if (minId === null) { + // No events left, remove all subscribers. This can happen if no events + // are published within the max age window. + subscriberCount = await this.#db(TABLE_SUBSCRIPTIONS).delete(); + } else { + subscriberCount = await this.#db(TABLE_SUBSCRIPTIONS) + .delete() + // Read pointer points to the ID that has been read, so we need an additional offset + .where('read_until', '<', minId - 1); + } + + if (subscriberCount > 0) { + this.#logger.info( + `Subscription cleanup resulted in ${subscriberCount} stale subscribers being deleted`, + ); + } + } catch (error) { + this.#logger.error('Subscription cleanup failed', error); + } + } +} diff --git a/plugins/events-backend/src/service/hub/MemoryEventBusStore.test.ts b/plugins/events-backend/src/service/hub/MemoryEventBusStore.test.ts new file mode 100644 index 0000000000..52d075951d --- /dev/null +++ b/plugins/events-backend/src/service/hub/MemoryEventBusStore.test.ts @@ -0,0 +1,91 @@ +/* + * 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 { EventParams } from '@backstage/plugin-events-node'; +import { MemoryEventBusStore } from './MemoryEventBusStore'; +import { mockCredentials } from '@backstage/backend-test-utils'; + +function mkEvent(message: string): EventParams { + return { + topic: 'test', + eventPayload: { message }, + }; +} + +describe('MemoryEventBusStore', () => { + it('should publish to subscribers', async () => { + const store = new MemoryEventBusStore(); + + await expect( + store.publish({ + event: mkEvent('hello'), + notifiedSubscribers: [], + credentials: mockCredentials.service(), + }), + ).resolves.toEqual(undefined); + + await expect(store.readSubscription('test')).rejects.toThrow( + 'Subscription not found', + ); + + await store.upsertSubscription('tester', ['test']); + + await expect( + store.publish({ + event: mkEvent('hello'), + notifiedSubscribers: [], + credentials: mockCredentials.service(), + }), + ).resolves.toEqual({ eventId: '1' }); + + await expect( + store.publish({ + event: mkEvent('ignored'), + notifiedSubscribers: ['tester'], + credentials: mockCredentials.service(), + }), + ).resolves.toEqual(undefined); + + await expect(store.readSubscription('tester')).resolves.toEqual({ + events: [mkEvent('hello')], + }); + }); + + it('should clean up old events', async () => { + const store = new MemoryEventBusStore({ maxEvents: 5 }); + + await store.upsertSubscription('tester', ['test']); + + for (let i = 0; i < 20; ++i) { + await expect( + store.publish({ + event: mkEvent(`hello ${i}`), + notifiedSubscribers: [], + credentials: mockCredentials.service(), + }), + ).resolves.toEqual({ eventId: String(i + 1) }); + } + + await expect(store.readSubscription('tester')).resolves.toEqual({ + events: [ + mkEvent('hello 15'), + mkEvent('hello 16'), + mkEvent('hello 17'), + mkEvent('hello 18'), + mkEvent('hello 19'), + ], + }); + }); +}); diff --git a/plugins/events-backend/src/service/hub/MemoryEventBusStore.ts b/plugins/events-backend/src/service/hub/MemoryEventBusStore.ts new file mode 100644 index 0000000000..6c999dc390 --- /dev/null +++ b/plugins/events-backend/src/service/hub/MemoryEventBusStore.ts @@ -0,0 +1,164 @@ +/* + * 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 { EventParams } from '@backstage/plugin-events-node'; +import { EventBusStore } from './types'; +import { NotFoundError } from '@backstage/errors'; +import { + BackstageCredentials, + BackstageServicePrincipal, +} from '@backstage/backend-plugin-api'; + +const MAX_BATCH_SIZE = 10; +const MAX_EVENTS_DEFAULT = 1_000; + +export class MemoryEventBusStore implements EventBusStore { + #maxEvents: number; + #events = new Array< + EventParams & { seq: number; notifiedSubscribers: Set } + >(); + #subscribers = new Map< + string, + { id: string; seq: number; topics: Set } + >(); + #listeners = new Set<{ + topics: Set; + resolve(result: { topic: string }): void; + }>(); + + constructor(options: { maxEvents?: number } = {}) { + this.#maxEvents = options.maxEvents ?? MAX_EVENTS_DEFAULT; + } + + async publish(options: { + event: EventParams; + notifiedSubscribers: string[]; + credentials: BackstageCredentials; + }): Promise<{ eventId: string } | undefined> { + const topic = options.event.topic; + const notifiedSubscribers = new Set(options.notifiedSubscribers); + + let hasOtherSubscribers = false; + for (const sub of this.#subscribers.values()) { + if (sub.topics.has(topic) && !notifiedSubscribers.has(sub.id)) { + hasOtherSubscribers = true; + break; + } + } + if (!hasOtherSubscribers) { + return undefined; + } + + const nextSeq = this.#getMaxSeq() + 1; + this.#events.push({ ...options.event, notifiedSubscribers, seq: nextSeq }); + + for (const listener of this.#listeners) { + if (listener.topics.has(topic)) { + listener.resolve({ topic }); + this.#listeners.delete(listener); + } + } + + // Trim old events + if (this.#events.length > this.#maxEvents) { + this.#events.shift(); + } + + return { eventId: String(nextSeq) }; + } + + #getMaxSeq() { + return this.#events[this.#events.length - 1]?.seq ?? 0; + } + + async upsertSubscription(id: string, topics: string[]): Promise { + const existing = this.#subscribers.get(id); + if (existing) { + existing.topics = new Set(topics); + return; + } + const sub = { + id: id, + seq: this.#getMaxSeq(), + topics: new Set(topics), + }; + this.#subscribers.set(id, sub); + } + + async readSubscription(id: string): Promise<{ events: EventParams[] }> { + const sub = this.#subscribers.get(id); + if (!sub) { + throw new NotFoundError(`Subscription not found`); + } + const events = this.#events + .filter( + event => + event.seq > sub.seq && + sub.topics.has(event.topic) && + !event.notifiedSubscribers.has(id), + ) + .slice(0, MAX_BATCH_SIZE); + + sub.seq = events[events.length - 1]?.seq ?? sub.seq; + + return { + events: events.map(({ topic, eventPayload }) => ({ + topic, + eventPayload, + })), + }; + } + + async setupListener( + subscriptionId: string, + options: { + signal: AbortSignal; + }, + ): Promise<{ waitForUpdate(): Promise<{ topic: string }> }> { + return { + waitForUpdate: async () => { + options.signal.throwIfAborted(); + + const sub = this.#subscribers.get(subscriptionId); + if (!sub) { + throw new NotFoundError(`Subscription not found`); + } + + return new Promise<{ topic: string }>((resolve, reject) => { + const listener = { + topics: sub.topics, + resolve(result: { topic: string }) { + resolve(result); + cleanup(); + }, + }; + this.#listeners.add(listener); + + const onAbort = () => { + this.#listeners.delete(listener); + reject(options.signal.reason); + cleanup(); + }; + + function cleanup() { + options.signal.removeEventListener('abort', onAbort); + } + + options.signal.addEventListener('abort', onAbort); + }); + }, + }; + } +} diff --git a/plugins/events-backend/src/service/hub/createEventBusRouter.ts b/plugins/events-backend/src/service/hub/createEventBusRouter.ts new file mode 100644 index 0000000000..4a332d5ce5 --- /dev/null +++ b/plugins/events-backend/src/service/hub/createEventBusRouter.ts @@ -0,0 +1,278 @@ +/* + * 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 { + DatabaseService, + HttpAuthService, + LifecycleService, + LoggerService, + SchedulerService, +} from '@backstage/backend-plugin-api'; +import { Handler } from 'express'; +import { createOpenApiRouter } from '../../schema/openapi.generated'; +import { MemoryEventBusStore } from './MemoryEventBusStore'; +import { DatabaseEventBusStore } from './DatabaseEventBusStore'; +import { EventBusStore } from './types'; +import { EventParams } from '@backstage/plugin-events-node'; + +const DEFAULT_NOTIFY_TIMEOUT_MS = 55_000; // Just below 60s, which is a common HTTP timeout + +/* + +# Event Bus + +This comment describes the event bus that is implemented here in the events +backend, and by default used by the events service. + +## Overview + +The events bus implements a subscription mechanism where subscribers must exist +upfront for events to be stored. It uses a single inbox for all events, with +each subscriber having its own pointer for how far into the inbox it has read. + +In order to avoid busy polling, the API uses a long-polling mechanism where a +request is left hanging until the client should try to read again. + +The event bus is not implemented with any guarantees of events being consumed, +but it does aim to make it unlikely that events are dropped + +## API + +### POST /bus/v1/events + +This endpoint is used to publish new events to the event bus on a specific +topic. It can optionally include a set of subscription IDs for subscribers that +have already been notified of the event. This is to enable an optimization where +we notify subscribers locally if possible, and avoid the need for events to be +relayed through the events bus at all of possible. + +For an event to be published and stored there must already exist a subscriber +that is subscribed to the event's topic, and that hasn't already been notified +of the event. If no such subscriber is found, the event will be discarded. + +### PUT /bus/v1/subscriptions/:subscriptionId + +This endpoint is used to create or update a subscriptions. Subscriptions are +shared across the entire bus and divided by subscription ID. Multiple clients +can be reading events from the same subscription at the same time, but only one +of those clients will receive each event. This enables division of work by using +the same subscriber ID across multiple instances, as well as broadcasting by +ensuring separate subscribers IDs. + +### GET /bus/v1/subscriptions/:subscriptionId/events + +This endpoint is used to read events from a subscription. It will return a batch +of events for the subscribed topics that have not yet been read by the +subscription. If no such events are available, the endpoint will return a 202 +response and then hang end response until an event is available or a timeout is +reached. This allows clients to call this endpoint in a loop but will keep +traffic overhead fairly low. + +## Delivery guarantees + +When reading events from the event bus, clients should always implement a +graceful shutdown where they process any events that are received from the +events endpoint before shutting down. This is also the reason that the events +endpoint does not return any events when responding with a 202 blocking the +response, because there would otherwise be a race condition where the events +might be lost in transit if the client shuts down. By always sending an empty +response and requiring the client to send another request, we ensure that the +client is prepared to halt shutdown until the request had been fully processed. + +## Local processing optimization + +When possible, events will be processed locally before sent to the event bus. +The client will also inform the bus of which subscriptions have already been +notified of the event, so that the bus can completely avoid storing an event if +it has already been fully consumed by all subscribers. + +## Automated cleanup & event window + +Events are deleted once they are outside the guaranteed storage window. By +default the window 10 minutes for all events, and 24 hours for the last 10000 +events. This ensures that the event log doesn't grow indefinitely, while still +allowing subscribers with restarts or outages to catch up to past events, +ensuring that events are likely not lost. + +Subscriptions are also cleaned up if their read pointer falls outside of the +current event window. This ensures that stale subscribers don't accumulate and +cause unnecessary storage of events. + +*/ + +async function createEventBusStore(deps: { + logger: LoggerService; + database: DatabaseService; + scheduler: SchedulerService; + lifecycle: LifecycleService; + httpAuth: HttpAuthService; +}): Promise { + const db = await deps.database.getClient(); + if (db.client.config.client === 'pg') { + deps.logger.info('Database is PostgreSQL, using database store'); + return await DatabaseEventBusStore.create(deps); + } + + deps.logger.info('Database is not PostgreSQL, using memory store'); + return new MemoryEventBusStore(); +} + +/** + * Creates a new event bus router + * @internal + */ +export async function createEventBusRouter(options: { + logger: LoggerService; + database: DatabaseService; + scheduler: SchedulerService; + lifecycle: LifecycleService; + httpAuth: HttpAuthService; + notifyTimeoutMs?: number; // for testing +}): Promise { + const { httpAuth, notifyTimeoutMs = DEFAULT_NOTIFY_TIMEOUT_MS } = options; + const logger = options.logger.child({ type: 'EventBus' }); + + const store = await createEventBusStore(options); + + const apiRouter = await createOpenApiRouter(); + + apiRouter.post('/bus/v1/events', async (req, res) => { + const credentials = await httpAuth.credentials(req, { + allow: ['service'], + }); + const topic = req.body.event.topic; + const notifiedSubscribers = req.body.notifiedSubscribers; + const result = await store.publish({ + event: { + topic, + eventPayload: req.body.event.payload, + } as EventParams, + notifiedSubscribers, + credentials, + }); + if (result) { + logger.debug( + `Published event to '${topic}' with ID '${result.eventId}'`, + { + subject: credentials.principal.subject, + }, + ); + res.status(201).end(); + } else { + if (notifiedSubscribers) { + const notified = `'${notifiedSubscribers.join("', '")}'`; + logger.debug( + `Skipped publishing of event to '${topic}', subscribers have already been notified: ${notified}`, + { subject: credentials.principal.subject }, + ); + } else { + logger.debug( + `Skipped publishing of event to '${topic}', no subscribers present`, + { subject: credentials.principal.subject }, + ); + } + res.status(204).end(); + } + }); + + apiRouter.get( + '/bus/v1/subscriptions/:subscriptionId/events', + async (req, res) => { + const credentials = await httpAuth.credentials(req, { + allow: ['service'], + }); + const id = req.params.subscriptionId; + + const controller = new AbortController(); + req.on('end', () => controller.abort()); + + // By setting up the listener first we make sure we don't miss any events + // that are published while reading. If an event is published we'll receive + // a notification, which we may ignore depending on the outcome of the read + const listener = await store.setupListener(id, { + signal: controller.signal, + }); + + // By timing out requests we make sure they don't stall or that events get stuck. + // For the caller there's no difference between a timeout and a + // notification, either way they should try reading again. + const timeout = setTimeout(() => { + controller.abort(); + }, notifyTimeoutMs); + + try { + const { events } = await store.readSubscription(id); + + logger.debug( + `Reading subscription '${id}' resulted in ${events.length} events`, + { subject: credentials.principal.subject }, + ); + + if (events.length > 0) { + res.json({ + events: events.map(event => ({ + topic: event.topic, + payload: event.eventPayload, + })), + }); + } else { + res.status(202); + res.flushHeaders(); + + try { + const { topic } = await listener.waitForUpdate(); + logger.debug( + `Received notification for subscription '${id}' for topic '${topic}'`, + { subject: credentials.principal.subject }, + ); + } catch (error) { + if (error !== controller.signal.reason) { + logger.error(`Error listening for subscription '${id}'`, error); + } + } finally { + // A small extra delay ensures a more even spread of events across + // consumers in case some consumers are faster than others + await new Promise(resolve => + setTimeout(resolve, 1 + Math.random() * 9), + ); + res.end(); + } + } + } finally { + controller.abort(); + clearTimeout(timeout); + } + }, + ); + + apiRouter.put('/bus/v1/subscriptions/:subscriptionId', async (req, res) => { + const credentials = await httpAuth.credentials(req, { + allow: ['service'], + }); + const id = req.params.subscriptionId; + + await store.upsertSubscription(id, req.body.topics, credentials); + + logger.debug( + `New subscription '${id}' for topics '${req.body.topics.join("', '")}'`, + { subject: credentials.principal.subject }, + ); + + res.status(201).end(); + }); + + return apiRouter; +} diff --git a/packages/backend-common/src/compat/index.ts b/plugins/events-backend/src/service/hub/index.ts similarity index 85% rename from packages/backend-common/src/compat/index.ts rename to plugins/events-backend/src/service/hub/index.ts index d702772335..a4f2f263f1 100644 --- a/packages/backend-common/src/compat/index.ts +++ b/plugins/events-backend/src/service/hub/index.ts @@ -14,7 +14,4 @@ * limitations under the License. */ -export * from './legacy'; -export * from './auth'; -export * from './cache'; -export * from './logging'; +export { createEventBusRouter } from './createEventBusRouter'; diff --git a/plugins/events-backend/src/service/hub/types.ts b/plugins/events-backend/src/service/hub/types.ts new file mode 100644 index 0000000000..316d9e561f --- /dev/null +++ b/plugins/events-backend/src/service/hub/types.ts @@ -0,0 +1,44 @@ +/* + * 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 { + BackstageCredentials, + BackstageServicePrincipal, +} from '@backstage/backend-plugin-api'; +import { EventParams } from '@backstage/plugin-events-node'; + +export type EventBusStore = { + publish(options: { + event: EventParams; + notifiedSubscribers?: string[]; + credentials: BackstageCredentials; + }): Promise<{ eventId: string } | undefined>; + + upsertSubscription( + subscriptionId: string, + topics: string[], + credentials: BackstageCredentials, + ): Promise; + + readSubscription(subscriptionId: string): Promise<{ events: EventParams[] }>; + + setupListener( + subscriptionId: string, + options: { + signal: AbortSignal; + }, + ): Promise<{ waitForUpdate(): Promise<{ topic: string }> }>; +}; diff --git a/plugins/events-node/CHANGELOG.md b/plugins/events-node/CHANGELOG.md index 15934678d6..2485fbb71d 100644 --- a/plugins/events-node/CHANGELOG.md +++ b/plugins/events-node/CHANGELOG.md @@ -1,5 +1,39 @@ # @backstage/plugin-events-node +## 0.4.1-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- 2f88f88: Updated backend installation instructions. +- a90ce4a: The default implementation of the `EventsService` now uses the new event bus for distributing events across multiple backend instances if the events backend plugin is installed. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## 0.4.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + +## 0.4.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + ## 0.4.0-next.1 ### Patch Changes diff --git a/plugins/events-node/README.md b/plugins/events-node/README.md index ce4d705025..b07303ff72 100644 --- a/plugins/events-node/README.md +++ b/plugins/events-node/README.md @@ -78,5 +78,5 @@ and your custom implementation: ```diff // packages/backend/src/index.ts -+ backend.add(customEventsServiceFactory()); ++ backend.add(customEventsServiceFactory); ``` diff --git a/plugins/events-node/package.json b/plugins/events-node/package.json index ce31730b78..d02945d633 100644 --- a/plugins/events-node/package.json +++ b/plugins/events-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-node", - "version": "0.4.0-next.1", + "version": "0.4.1-next.0", "description": "The plugin-events-node module for @backstage/plugin-events-backend", "backstage": { "role": "node-library", @@ -51,10 +51,14 @@ "test": "backstage-cli package test" }, "dependencies": { - "@backstage/backend-plugin-api": "workspace:^" + "@backstage/backend-plugin-api": "workspace:^", + "@backstage/errors": "workspace:^", + "@backstage/types": "workspace:^", + "cross-fetch": "^4.0.0", + "uri-template": "^2.0.0" }, "devDependencies": { - "@backstage/backend-common": "workspace:^", + "@backstage/backend-common": "^0.25.0", "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^" } diff --git a/plugins/events-node/api-report-alpha.md b/plugins/events-node/report-alpha.api.md similarity index 64% rename from plugins/events-node/api-report-alpha.md rename to plugins/events-node/report-alpha.api.md index f61048ac94..d11b170365 100644 --- a/plugins/events-node/api-report-alpha.md +++ b/plugins/events-node/report-alpha.api.md @@ -28,5 +28,14 @@ export interface EventsExtensionPoint { // @alpha (undocumented) export const eventsExtensionPoint: ExtensionPoint; +// Warnings were encountered during analysis: +// +// src/extensions.d.ts:5:1 - (ae-undocumented) Missing documentation for "EventsExtensionPoint". +// src/extensions.d.ts:9:5 - (ae-undocumented) Missing documentation for "setEventBroker". +// src/extensions.d.ts:13:5 - (ae-undocumented) Missing documentation for "addPublishers". +// src/extensions.d.ts:17:5 - (ae-undocumented) Missing documentation for "addSubscribers". +// src/extensions.d.ts:18:5 - (ae-undocumented) Missing documentation for "addHttpPostIngress". +// src/extensions.d.ts:23:22 - (ae-undocumented) Missing documentation for "eventsExtensionPoint". + // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/events-node/api-report.md b/plugins/events-node/report.api.md similarity index 58% rename from plugins/events-node/api-report.md rename to plugins/events-node/report.api.md index d8a2281faa..2c06f50d56 100644 --- a/plugins/events-node/api-report.md +++ b/plugins/events-node/report.api.md @@ -3,6 +3,9 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts +import { AuthService } from '@backstage/backend-plugin-api'; +import { DiscoveryService } from '@backstage/backend-plugin-api'; +import { LifecycleService } from '@backstage/backend-plugin-api'; import { LoggerService } from '@backstage/backend-plugin-api'; import { ServiceFactory } from '@backstage/backend-plugin-api'; import { ServiceRef } from '@backstage/backend-plugin-api'; @@ -11,7 +14,15 @@ import { ServiceRef } from '@backstage/backend-plugin-api'; export class DefaultEventsService implements EventsService { // (undocumented) static create(options: { logger: LoggerService }): DefaultEventsService; - forPlugin(pluginId: string): EventsService; + forPlugin( + pluginId: string, + options?: { + discovery: DiscoveryService; + logger: LoggerService; + auth: AuthService; + lifecycle: LifecycleService; + }, + ): EventsService; // (undocumented) publish(params: EventParams): Promise; // (undocumented) @@ -128,4 +139,26 @@ export abstract class SubTopicEventRouter extends EventRouter { // (undocumented) protected abstract determineSubTopic(params: EventParams): string | undefined; } + +// Warnings were encountered during analysis: +// +// src/api/DefaultEventsService.d.ts:16:5 - (ae-undocumented) Missing documentation for "create". +// src/api/DefaultEventsService.d.ts:31:5 - (ae-undocumented) Missing documentation for "publish". +// src/api/DefaultEventsService.d.ts:32:5 - (ae-undocumented) Missing documentation for "subscribe". +// src/api/EventParams.d.ts:4:1 - (ae-undocumented) Missing documentation for "EventParams". +// src/api/EventPublisher.d.ts:15:5 - (ae-undocumented) Missing documentation for "setEventBroker". +// src/api/EventRouter.d.ts:18:5 - (ae-undocumented) Missing documentation for "getSubscriberId". +// src/api/EventRouter.d.ts:19:5 - (ae-undocumented) Missing documentation for "determineDestinationTopic". +// src/api/EventRouter.d.ts:26:5 - (ae-undocumented) Missing documentation for "onEvent". +// src/api/EventsService.d.ts:26:1 - (ae-undocumented) Missing documentation for "EventsServiceSubscribeOptions". +// src/api/EventsService.d.ts:37:1 - (ae-undocumented) Missing documentation for "EventsServiceEventHandler". +// src/api/SubTopicEventRouter.d.ts:18:5 - (ae-undocumented) Missing documentation for "determineSubTopic". +// src/api/SubTopicEventRouter.d.ts:19:5 - (ae-undocumented) Missing documentation for "determineDestinationTopic". +// src/api/http/HttpPostIngressOptions.d.ts:5:1 - (ae-undocumented) Missing documentation for "HttpPostIngressOptions". +// src/api/http/HttpPostIngressOptions.d.ts:6:5 - (ae-undocumented) Missing documentation for "topic". +// src/api/http/HttpPostIngressOptions.d.ts:7:5 - (ae-undocumented) Missing documentation for "validator". +// src/api/http/validation/RequestDetails.d.ts:4:1 - (ae-undocumented) Missing documentation for "RequestDetails". +// src/api/http/validation/RequestRejectionDetails.d.ts:8:5 - (ae-undocumented) Missing documentation for "status". +// src/api/http/validation/RequestRejectionDetails.d.ts:9:5 - (ae-undocumented) Missing documentation for "payload". +// src/service.d.ts:10:22 - (ae-undocumented) Missing documentation for "eventsServiceFactory". ``` diff --git a/plugins/events-node/src/api/DefaultEventsService.ts b/plugins/events-node/src/api/DefaultEventsService.ts index bb5c2a0ca8..aa77d6e696 100644 --- a/plugins/events-node/src/api/DefaultEventsService.ts +++ b/plugins/events-node/src/api/DefaultEventsService.ts @@ -14,9 +14,320 @@ * limitations under the License. */ -import { LoggerService } from '@backstage/backend-plugin-api'; +import { + AuthService, + DiscoveryService, + LifecycleService, + LoggerService, +} from '@backstage/backend-plugin-api'; import { EventParams } from './EventParams'; import { EventsService, EventsServiceSubscribeOptions } from './EventsService'; +import { DefaultApiClient } from '../generated'; +import { ResponseError } from '@backstage/errors'; + +const POLL_BACKOFF_START_MS = 1_000; +const POLL_BACKOFF_MAX_MS = 60_000; +const POLL_BACKOFF_FACTOR = 2; + +/** + * Local event bus for subscribers within the same process. + * + * When publishing events we'll keep track of which subscribers we managed to + * reach locally, and forward those subscriber IDs to the events backend if it + * is in use. The events backend will then both avoid forwarding the same events + * to those subscribers again, but also avoid storing the event altogether if + * there are no other subscribers. + * @internal + */ +export class LocalEventBus { + readonly #logger: LoggerService; + + readonly #subscribers = new Map< + string, + Omit[] + >(); + + constructor(logger: LoggerService) { + this.#logger = logger; + } + + async publish( + params: EventParams, + ): Promise<{ notifiedSubscribers: string[] }> { + this.#logger.debug( + `Event received: topic=${params.topic}, metadata=${JSON.stringify( + params.metadata, + )}, payload=${JSON.stringify(params.eventPayload)}`, + ); + + if (!this.#subscribers.has(params.topic)) { + return { notifiedSubscribers: [] }; + } + + const onEventPromises: Promise[] = []; + this.#subscribers.get(params.topic)?.forEach(subscription => { + onEventPromises.push( + (async () => { + try { + await subscription.onEvent(params); + } catch (error) { + this.#logger.warn( + `Subscriber "${subscription.id}" failed to process event for topic "${params.topic}"`, + error, + ); + } + return subscription.id; + })(), + ); + }); + + return { notifiedSubscribers: await Promise.all(onEventPromises) }; + } + + async subscribe(options: EventsServiceSubscribeOptions): Promise { + options.topics.forEach(topic => { + if (!this.#subscribers.has(topic)) { + this.#subscribers.set(topic, []); + } + + this.#subscribers.get(topic)!.push({ + id: options.id, + onEvent: options.onEvent, + }); + }); + } +} + +/** + * Plugin specific events bus that delegates to the local bus, as well as the + * events backend if it is available. + */ +class PluginEventsService implements EventsService { + constructor( + private readonly pluginId: string, + private readonly localBus: LocalEventBus, + private readonly logger: LoggerService, + private client?: DefaultApiClient, + private readonly auth?: AuthService, + ) {} + + async publish(params: EventParams): Promise { + const lock = this.#getShutdownLock(); + try { + const { notifiedSubscribers } = await this.localBus.publish(params); + + if (!this.client) { + return; + } + const token = await this.#getToken(); + if (!token) { + return; + } + const res = await this.client.postEvent( + { + body: { + event: { payload: params.eventPayload, topic: params.topic }, + notifiedSubscribers, + }, + }, + { token }, + ); + + if (!res.ok) { + if (res.status === 404) { + this.logger.warn( + `Event publish request failed with status 404, events backend not found. Future events will not be persisted.`, + ); + delete this.client; + return; + } + throw await ResponseError.fromResponse(res); + } + } finally { + lock.release(); + } + } + + async subscribe(options: EventsServiceSubscribeOptions): Promise { + const subscriptionId = `${this.pluginId}.${options.id}`; + + await this.localBus.subscribe({ + id: subscriptionId, + topics: options.topics, + onEvent: options.onEvent, + }); + + if (!this.client) { + return; + } + const token = await this.#getToken(); + if (!token) { + return; + } + const res = await this.client.putSubscription( + { + path: { subscriptionId }, + body: { topics: options.topics }, + }, + { token }, + ); + if (!res.ok) { + if (res.status === 404) { + this.logger.warn( + `Event subscribe request failed with status 404, events backend not found. Will only receive events that were sent locally on this process.`, + ); + delete this.client; + return; + } + throw await ResponseError.fromResponse(res); + } + + this.#startPolling(subscriptionId, options.topics, options.onEvent); + } + + #startPolling( + subscriptionId: string, + topics: string[], + onEvent: EventsServiceSubscribeOptions['onEvent'], + ) { + let backoffMs = POLL_BACKOFF_START_MS; + const poll = async () => { + if (!this.client) { + return; + } + const lock = this.#getShutdownLock(); + try { + const token = await this.#getToken(); + if (!token) { + return; + } + const res = await this.client.getSubscriptionEvents( + { + path: { subscriptionId }, + }, + { token }, + ); + + if (!res.ok) { + if (res.status === 404) { + this.logger.info( + `Polling event subscription resulted in a 404, recreating subscription`, + ); + const putRes = await this.client.putSubscription( + { + path: { subscriptionId }, + body: { topics }, + }, + { token }, + ); + if (!putRes.ok) { + throw await ResponseError.fromResponse(res); + } + } + throw await ResponseError.fromResponse(res); + } + backoffMs = POLL_BACKOFF_START_MS; + + // 202 means there were no immediately available events, but the + // response will block until either new events are available or the + // request times out. In both cases we should should try to read events + // immediately again + if (res.status === 202) { + lock.release(); + await res.body?.getReader()?.closed; + process.nextTick(poll); + } else if (res.status === 200) { + const data = await res.json(); + if (data) { + for (const event of data.events ?? []) { + try { + await onEvent({ + topic: event.topic, + eventPayload: event.payload, + }); + } catch (error) { + this.logger.warn( + `Subscriber "${subscriptionId}" failed to process event for topic "${event.topic}"`, + error, + ); + } + } + } + process.nextTick(poll); + } else { + this.logger.warn( + `Unexpected response status ${res.status} from events backend for subscription "${subscriptionId}"`, + ); + } + } catch (error) { + this.logger.warn( + `Poll failed for subscription "${subscriptionId}", retrying in ${backoffMs.toFixed( + 0, + )}ms`, + error, + ); + setTimeout(poll, backoffMs); + backoffMs = Math.min( + backoffMs * POLL_BACKOFF_FACTOR, + POLL_BACKOFF_MAX_MS, + ); + } finally { + lock.release(); + } + }; + poll(); + } + + async #getToken() { + if (!this.auth) { + throw new Error('Auth service not available'); + } + + try { + const { token } = await this.auth.getPluginRequestToken({ + onBehalfOf: await this.auth.getOwnServiceCredentials(), + targetPluginId: 'events', + }); + return token; + } catch (error) { + // This is a bit hacky, but handles the case where new auth is used + // without legacy auth fallback, and the events backend is not installed + if (String(error).includes('Unable to generate legacy token')) { + this.logger.warn( + `The events backend is not available and neither is legacy auth. Future events will not be persisted.`, + ); + delete this.client; + return undefined; + } + throw error; + } + } + + async shutdown() { + this.#isShuttingDown = true; + await Promise.all(this.#shutdownLocks); + } + + #isShuttingDown = false; + #shutdownLocks: Promise[] = []; + + // This locking mechanism helps ensure that we are either idle or waiting for + // a blocked events call before shutting down. It increases out changes of + // never dropping any events on shutdown. + #getShutdownLock(): { release(): void } { + if (this.#isShuttingDown) { + throw new Error('Service is shutting down'); + } + + let release: () => void; + this.#shutdownLocks.push( + new Promise(resolve => { + release = resolve; + }), + ); + return { release: release! }; + } +} /** * In-process event broker which will pass the event to all registered subscribers @@ -28,15 +339,16 @@ import { EventsService, EventsServiceSubscribeOptions } from './EventsService'; */ // TODO(pjungermann): add opentelemetry? (see plugins/catalog-backend/src/util/opentelemetry.ts, etc.) export class DefaultEventsService implements EventsService { - private readonly subscribers = new Map< - string, - Omit[] - >(); - - private constructor(private readonly logger: LoggerService) {} + private constructor( + private readonly logger: LoggerService, + private readonly localBus: LocalEventBus, + ) {} static create(options: { logger: LoggerService }): DefaultEventsService { - return new DefaultEventsService(options.logger); + return new DefaultEventsService( + options.logger, + new LocalEventBus(options.logger), + ); } /** @@ -45,60 +357,40 @@ export class DefaultEventsService implements EventsService { * * @param pluginId - The plugin that the `EventService` should be created for. */ - forPlugin(pluginId: string): EventsService { - return { - publish: (params: EventParams): Promise => { - return this.publish(params); - }, - subscribe: (options: EventsServiceSubscribeOptions): Promise => { - return this.subscribe({ - ...options, - id: `${pluginId}.${options.id}`, - }); - }, - }; + forPlugin( + pluginId: string, + options?: { + discovery: DiscoveryService; + logger: LoggerService; + auth: AuthService; + lifecycle: LifecycleService; + }, + ): EventsService { + const client = + options && + new DefaultApiClient({ + discoveryApi: options.discovery, + fetchApi: { fetch }, // use native node fetch + }); + const logger = options?.logger ?? this.logger; + const service = new PluginEventsService( + pluginId, + this.localBus, + logger, + client, + options?.auth, + ); + options?.lifecycle.addShutdownHook(async () => { + await service.shutdown(); + }); + return service; } async publish(params: EventParams): Promise { - this.logger.debug( - `Event received: topic=${params.topic}, metadata=${JSON.stringify( - params.metadata, - )}, payload=${JSON.stringify(params.eventPayload)}`, - ); - - if (!this.subscribers.has(params.topic)) { - return; - } - - const onEventPromises: Promise[] = []; - this.subscribers.get(params.topic)?.forEach(subscription => { - onEventPromises.push( - (async () => { - try { - await subscription.onEvent(params); - } catch (error) { - this.logger.warn( - `Subscriber "${subscription.id}" failed to process event for topic "${params.topic}"`, - error, - ); - } - })(), - ); - }); - - await Promise.all(onEventPromises); + await this.localBus.publish(params); } async subscribe(options: EventsServiceSubscribeOptions): Promise { - options.topics.forEach(topic => { - if (!this.subscribers.has(topic)) { - this.subscribers.set(topic, []); - } - - this.subscribers.get(topic)!.push({ - id: options.id, - onEvent: options.onEvent, - }); - }); + this.localBus.subscribe(options); } } diff --git a/plugins/events-node/src/generated/apis/DefaultApi.client.ts b/plugins/events-node/src/generated/apis/DefaultApi.client.ts new file mode 100644 index 0000000000..4bdeed0c33 --- /dev/null +++ b/plugins/events-node/src/generated/apis/DefaultApi.client.ts @@ -0,0 +1,152 @@ +/* + * 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. + */ + +// ****************************************************************** +// * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. * +// ****************************************************************** +import { DiscoveryApi } from '../types/discovery'; +import { FetchApi } from '../types/fetch'; +import crossFetch from 'cross-fetch'; +import { pluginId } from '../pluginId'; +import * as parser from 'uri-template'; + +import { GetSubscriptionEvents200Response } from '../models/GetSubscriptionEvents200Response.model'; +import { PostEventRequest } from '../models/PostEventRequest.model'; +import { PutSubscriptionRequest } from '../models/PutSubscriptionRequest.model'; + +/** + * Wraps the Response type to convey a type on the json call. + * + * @public + */ +export type TypedResponse = Omit & { + json: () => Promise; +}; + +/** + * Options you can pass into a request for additional information. + * + * @public + */ +export interface RequestOptions { + token?: string; +} + +/** + * no description + */ +export class DefaultApiClient { + private readonly discoveryApi: DiscoveryApi; + private readonly fetchApi: FetchApi; + + constructor(options: { + discoveryApi: { getBaseUrl(pluginId: string): Promise }; + fetchApi?: { fetch: typeof fetch }; + }) { + this.discoveryApi = options.discoveryApi; + this.fetchApi = options.fetchApi || { fetch: crossFetch }; + } + + /** + * Get new events for the provided subscription + * @param subscriptionId + */ + public async getSubscriptionEvents( + // @ts-ignore + request: { + path: { + subscriptionId: string; + }; + }, + options?: RequestOptions, + ): Promise> { + const baseUrl = await this.discoveryApi.getBaseUrl(pluginId); + + const uriTemplate = `/bus/v1/subscriptions/{subscriptionId}/events`; + + const uri = parser.parse(uriTemplate).expand({ + subscriptionId: request.path.subscriptionId, + }); + + return await this.fetchApi.fetch(`${baseUrl}${uri}`, { + headers: { + 'Content-Type': 'application/json', + ...(options?.token && { Authorization: `Bearer ${options?.token}` }), + }, + method: 'GET', + }); + } + + /** + * Publish a new event + * @param postEventRequest + */ + public async postEvent( + // @ts-ignore + request: { + body: PostEventRequest; + }, + options?: RequestOptions, + ): Promise> { + const baseUrl = await this.discoveryApi.getBaseUrl(pluginId); + + const uriTemplate = `/bus/v1/events`; + + const uri = parser.parse(uriTemplate).expand({}); + + return await this.fetchApi.fetch(`${baseUrl}${uri}`, { + headers: { + 'Content-Type': 'application/json', + ...(options?.token && { Authorization: `Bearer ${options?.token}` }), + }, + method: 'POST', + body: JSON.stringify(request.body), + }); + } + + /** + * Ensures that the subscription exists with the provided configuration + * @param subscriptionId + * @param putSubscriptionRequest + */ + public async putSubscription( + // @ts-ignore + request: { + path: { + subscriptionId: string; + }; + body: PutSubscriptionRequest; + }, + options?: RequestOptions, + ): Promise> { + const baseUrl = await this.discoveryApi.getBaseUrl(pluginId); + + const uriTemplate = `/bus/v1/subscriptions/{subscriptionId}`; + + const uri = parser.parse(uriTemplate).expand({ + subscriptionId: request.path.subscriptionId, + }); + + return await this.fetchApi.fetch(`${baseUrl}${uri}`, { + headers: { + 'Content-Type': 'application/json', + ...(options?.token && { Authorization: `Bearer ${options?.token}` }), + }, + method: 'PUT', + body: JSON.stringify(request.body), + }); + } +} diff --git a/packages/cli/src/commands/onboard/index.ts b/plugins/events-node/src/generated/apis/index.ts similarity index 88% rename from packages/cli/src/commands/onboard/index.ts rename to plugins/events-node/src/generated/apis/index.ts index 4c23ea6e48..51dcca33fe 100644 --- a/packages/cli/src/commands/onboard/index.ts +++ b/plugins/events-node/src/generated/apis/index.ts @@ -1,5 +1,5 @@ /* - * Copyright 2023 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. @@ -14,4 +14,4 @@ * limitations under the License. */ -export { command } from './command'; +export * from './DefaultApi.client'; diff --git a/plugins/events-node/src/generated/index.ts b/plugins/events-node/src/generated/index.ts new file mode 100644 index 0000000000..bb399e97a0 --- /dev/null +++ b/plugins/events-node/src/generated/index.ts @@ -0,0 +1,18 @@ +/* + * 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. + */ + +export * from './apis'; +export * from './models'; diff --git a/plugins/events-node/src/generated/models/ErrorError.model.ts b/plugins/events-node/src/generated/models/ErrorError.model.ts new file mode 100644 index 0000000000..4bcc60b660 --- /dev/null +++ b/plugins/events-node/src/generated/models/ErrorError.model.ts @@ -0,0 +1,24 @@ +/* + * 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. + */ + +// ****************************************************************** +// * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. * +// ****************************************************************** + +export interface ErrorError { + name: string; + message: string; +} diff --git a/plugins/events-node/src/generated/models/ErrorRequest.model.ts b/plugins/events-node/src/generated/models/ErrorRequest.model.ts new file mode 100644 index 0000000000..be62627814 --- /dev/null +++ b/plugins/events-node/src/generated/models/ErrorRequest.model.ts @@ -0,0 +1,24 @@ +/* + * 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. + */ + +// ****************************************************************** +// * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. * +// ****************************************************************** + +export interface ErrorRequest { + method: string; + url: string; +} diff --git a/plugins/events-node/src/generated/models/ErrorResponse.model.ts b/plugins/events-node/src/generated/models/ErrorResponse.model.ts new file mode 100644 index 0000000000..008f8b7348 --- /dev/null +++ b/plugins/events-node/src/generated/models/ErrorResponse.model.ts @@ -0,0 +1,23 @@ +/* + * 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. + */ + +// ****************************************************************** +// * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. * +// ****************************************************************** + +export interface ErrorResponse { + statusCode: number; +} diff --git a/plugins/events-node/src/generated/models/Event.model.ts b/plugins/events-node/src/generated/models/Event.model.ts new file mode 100644 index 0000000000..a196b42db7 --- /dev/null +++ b/plugins/events-node/src/generated/models/Event.model.ts @@ -0,0 +1,30 @@ +/* + * 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. + */ + +// ****************************************************************** +// * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. * +// ****************************************************************** + +export interface Event { + /** + * The topic that the event is published on + */ + topic: string; + /** + * The event payload + */ + payload: any | null; +} diff --git a/plugins/events-node/src/generated/models/GetSubscriptionEvents200Response.model.ts b/plugins/events-node/src/generated/models/GetSubscriptionEvents200Response.model.ts new file mode 100644 index 0000000000..c9fc37f5bb --- /dev/null +++ b/plugins/events-node/src/generated/models/GetSubscriptionEvents200Response.model.ts @@ -0,0 +1,24 @@ +/* + * 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. + */ + +// ****************************************************************** +// * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. * +// ****************************************************************** +import { Event } from '../models/Event.model'; + +export interface GetSubscriptionEvents200Response { + events: Array; +} diff --git a/plugins/events-node/src/generated/models/ModelError.model.ts b/plugins/events-node/src/generated/models/ModelError.model.ts new file mode 100644 index 0000000000..88b8e76762 --- /dev/null +++ b/plugins/events-node/src/generated/models/ModelError.model.ts @@ -0,0 +1,28 @@ +/* + * 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. + */ + +// ****************************************************************** +// * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. * +// ****************************************************************** +import { ErrorError } from '../models/ErrorError.model'; +import { ErrorRequest } from '../models/ErrorRequest.model'; +import { ErrorResponse } from '../models/ErrorResponse.model'; + +export interface ModelError { + error: ErrorError; + request: ErrorRequest; + response: ErrorResponse; +} diff --git a/plugins/events-node/src/generated/models/PostEventRequest.model.ts b/plugins/events-node/src/generated/models/PostEventRequest.model.ts new file mode 100644 index 0000000000..75289ed25b --- /dev/null +++ b/plugins/events-node/src/generated/models/PostEventRequest.model.ts @@ -0,0 +1,28 @@ +/* + * 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. + */ + +// ****************************************************************** +// * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. * +// ****************************************************************** +import { Event } from '../models/Event.model'; + +export interface PostEventRequest { + event: Event; + /** + * The IDs of subscriptions that have already received this event + */ + notifiedSubscribers?: Array; +} diff --git a/plugins/events-node/src/generated/models/PutSubscriptionRequest.model.ts b/plugins/events-node/src/generated/models/PutSubscriptionRequest.model.ts new file mode 100644 index 0000000000..3de35e0f81 --- /dev/null +++ b/plugins/events-node/src/generated/models/PutSubscriptionRequest.model.ts @@ -0,0 +1,26 @@ +/* + * 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. + */ + +// ****************************************************************** +// * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. * +// ****************************************************************** + +export interface PutSubscriptionRequest { + /** + * The topics to subscribe to + */ + topics: Array; +} diff --git a/plugins/events-node/src/generated/models/index.ts b/plugins/events-node/src/generated/models/index.ts new file mode 100644 index 0000000000..5044f65fff --- /dev/null +++ b/plugins/events-node/src/generated/models/index.ts @@ -0,0 +1,24 @@ +/* + * 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. + */ + +export * from '../models/ErrorError.model'; +export * from '../models/ErrorRequest.model'; +export * from '../models/ErrorResponse.model'; +export * from '../models/Event.model'; +export * from '../models/GetSubscriptionEvents200Response.model'; +export * from '../models/ModelError.model'; +export * from '../models/PostEventRequest.model'; +export * from '../models/PutSubscriptionRequest.model'; diff --git a/plugins/events-node/src/generated/pluginId.ts b/plugins/events-node/src/generated/pluginId.ts new file mode 100644 index 0000000000..36b5433cc3 --- /dev/null +++ b/plugins/events-node/src/generated/pluginId.ts @@ -0,0 +1,17 @@ +/* + * 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. + */ + +export const pluginId = 'events'; diff --git a/packages/cli/src/commands/versions/lint.ts b/plugins/events-node/src/generated/types/discovery.ts similarity index 73% rename from packages/cli/src/commands/versions/lint.ts rename to plugins/events-node/src/generated/types/discovery.ts index 66b5fc04c4..a7f87d3780 100644 --- a/packages/cli/src/commands/versions/lint.ts +++ b/plugins/events-node/src/generated/types/discovery.ts @@ -1,5 +1,5 @@ /* - * Copyright 2020 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,8 +14,9 @@ * limitations under the License. */ -export default async () => { - throw new Error( - 'This command has been removed, please consider alternatives such as `yarn dedupe` instead.', - ); +/** + * This is a copy of the DiscoveryApi, to avoid importing core-plugin-api. + */ +export type DiscoveryApi = { + getBaseUrl(pluginId: string): Promise; }; diff --git a/plugins/events-node/src/generated/types/fetch.ts b/plugins/events-node/src/generated/types/fetch.ts new file mode 100644 index 0000000000..3de56c028e --- /dev/null +++ b/plugins/events-node/src/generated/types/fetch.ts @@ -0,0 +1,22 @@ +/* + * 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. + */ + +/** + * This is a copy of FetchApi, to avoid importing core-plugin-api. + */ +export type FetchApi = { + fetch: typeof fetch; +}; diff --git a/plugins/events-node/src/service.ts b/plugins/events-node/src/service.ts index af0e562c80..4f758f44e6 100644 --- a/plugins/events-node/src/service.ts +++ b/plugins/events-node/src/service.ts @@ -38,11 +38,23 @@ export const eventsServiceFactory = createServiceFactory({ deps: { pluginMetadata: coreServices.pluginMetadata, rootLogger: coreServices.rootLogger, + discovery: coreServices.discovery, + logger: coreServices.logger, + lifecycle: coreServices.lifecycle, + auth: coreServices.auth, }, async createRootContext({ rootLogger }) { return DefaultEventsService.create({ logger: rootLogger }); }, - async factory({ pluginMetadata }, eventsService) { - return eventsService.forPlugin(pluginMetadata.getId()); + async factory( + { pluginMetadata, discovery, logger, lifecycle, auth }, + eventsService, + ) { + return eventsService.forPlugin(pluginMetadata.getId(), { + discovery, + logger, + lifecycle, + auth, + }); }, }); diff --git a/plugins/example-todo-list-backend/CHANGELOG.md b/plugins/example-todo-list-backend/CHANGELOG.md index 3362c91a79..defe793b6d 100644 --- a/plugins/example-todo-list-backend/CHANGELOG.md +++ b/plugins/example-todo-list-backend/CHANGELOG.md @@ -1,5 +1,34 @@ # @internal/plugin-todo-list-backend +## 1.0.32-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/errors@1.2.4 + +## 1.0.31 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/errors@1.2.4 + +## 1.0.31-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/errors@1.2.4 + ## 1.0.31-next.1 ### Patch Changes diff --git a/plugins/example-todo-list-backend/api-report.md b/plugins/example-todo-list-backend/api-report.md deleted file mode 100644 index 8fa39f0cec..0000000000 --- a/plugins/example-todo-list-backend/api-report.md +++ /dev/null @@ -1,27 +0,0 @@ -## API Report File for "@internal/plugin-todo-list-backend" - -> 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 express from 'express'; -import { HttpAuthService } from '@backstage/backend-plugin-api'; -import { LoggerService } from '@backstage/backend-plugin-api'; - -// @public -export function createRouter(options: RouterOptions): Promise; - -// @public -const exampleTodoListPlugin: BackendFeature; -export default exampleTodoListPlugin; - -// @public -export interface RouterOptions { - // (undocumented) - httpAuth: HttpAuthService; - // (undocumented) - logger: LoggerService; -} - -// (No @packageDocumentation comment for this package) -``` diff --git a/plugins/example-todo-list-backend/package.json b/plugins/example-todo-list-backend/package.json index cf6e61f6ab..4bd2ffff09 100644 --- a/plugins/example-todo-list-backend/package.json +++ b/plugins/example-todo-list-backend/package.json @@ -1,6 +1,6 @@ { "name": "@internal/plugin-todo-list-backend", - "version": "1.0.31-next.1", + "version": "1.0.32-next.0", "backstage": { "role": "backend-plugin", "pluginId": "todo-list", @@ -38,7 +38,7 @@ "test": "backstage-cli package test" }, "dependencies": { - "@backstage/backend-common": "workspace:^", + "@backstage/backend-common": "^0.25.0", "@backstage/backend-plugin-api": "workspace:^", "@backstage/errors": "workspace:^", "@backstage/plugin-auth-node": "workspace:^", @@ -54,6 +54,6 @@ "@backstage/cli": "workspace:^", "@types/supertest": "^2.0.8", "@types/uuid": "^9.0.0", - "supertest": "^6.1.6" + "supertest": "^7.0.0" } } diff --git a/plugins/example-todo-list-backend/report.api.md b/plugins/example-todo-list-backend/report.api.md new file mode 100644 index 0000000000..1a61e07cd0 --- /dev/null +++ b/plugins/example-todo-list-backend/report.api.md @@ -0,0 +1,13 @@ +## API Report File for "@internal/plugin-todo-list-backend" + +> 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'; + +// @public +const exampleTodoListPlugin: BackendFeature; +export default exampleTodoListPlugin; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/example-todo-list-backend/src/index.ts b/plugins/example-todo-list-backend/src/index.ts index 156e44f70e..61c57be182 100644 --- a/plugins/example-todo-list-backend/src/index.ts +++ b/plugins/example-todo-list-backend/src/index.ts @@ -14,5 +14,4 @@ * limitations under the License. */ -export * from './service/router'; export { exampleTodoListPlugin as default } from './plugin'; diff --git a/plugins/example-todo-list-backend/src/service/router.test.ts b/plugins/example-todo-list-backend/src/service/router.test.ts index 50bacac203..46cc287bce 100644 --- a/plugins/example-todo-list-backend/src/service/router.test.ts +++ b/plugins/example-todo-list-backend/src/service/router.test.ts @@ -14,11 +14,10 @@ * limitations under the License. */ +import { mockServices } from '@backstage/backend-test-utils'; import express from 'express'; import request from 'supertest'; - import { createRouter } from './router'; -import { mockServices } from '@backstage/backend-test-utils'; describe('createRouter', () => { let app: express.Express; diff --git a/plugins/example-todo-list-backend/src/service/router.ts b/plugins/example-todo-list-backend/src/service/router.ts index 5f2d9fd37c..abadbbb4d9 100644 --- a/plugins/example-todo-list-backend/src/service/router.ts +++ b/plugins/example-todo-list-backend/src/service/router.ts @@ -23,8 +23,6 @@ import { HttpAuthService, LoggerService } from '@backstage/backend-plugin-api'; /** * Dependencies of the todo-list router - * - * @public */ export interface RouterOptions { logger: LoggerService; @@ -35,7 +33,6 @@ export interface RouterOptions { * Creates an express.Router with some endpoints * for creating, editing and deleting todo items. * - * @public * @param options - the dependencies of the router * @returns an express.Router * diff --git a/plugins/example-todo-list-backend/src/service/todos.ts b/plugins/example-todo-list-backend/src/service/todos.ts index b87ab7557e..75de25b845 100644 --- a/plugins/example-todo-list-backend/src/service/todos.ts +++ b/plugins/example-todo-list-backend/src/service/todos.ts @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { v4 as uuid } from 'uuid'; import { NotFoundError } from '@backstage/errors'; @@ -29,9 +30,7 @@ export type TodoFilter = { }; export type TodoFilters = - | { - anyOf: TodoFilters[]; - } + | { anyOf: TodoFilters[] } | { allOf: TodoFilters[] } | { not: TodoFilters } | TodoFilter; diff --git a/plugins/example-todo-list-common/package.json b/plugins/example-todo-list-common/package.json index 9bb25b7054..42c83f49d8 100644 --- a/plugins/example-todo-list-common/package.json +++ b/plugins/example-todo-list-common/package.json @@ -12,7 +12,8 @@ }, "publishConfig": { "access": "public", - "main": "dist/index.esm.js", + "main": "dist/index.cjs.js", + "module": "dist/index.esm.js", "types": "dist/index.d.ts" }, "private": true, diff --git a/plugins/example-todo-list-common/api-report.md b/plugins/example-todo-list-common/report.api.md similarity index 100% rename from plugins/example-todo-list-common/api-report.md rename to plugins/example-todo-list-common/report.api.md diff --git a/plugins/example-todo-list/CHANGELOG.md b/plugins/example-todo-list/CHANGELOG.md index b31862e9b3..299d517295 100644 --- a/plugins/example-todo-list/CHANGELOG.md +++ b/plugins/example-todo-list/CHANGELOG.md @@ -1,5 +1,37 @@ # @internal/plugin-todo-list +## 1.0.32-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + +## 1.0.32-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + +## 1.0.31 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/core-plugin-api@1.9.4 + +## 1.0.31-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/core-plugin-api@1.9.4-next.0 + ## 1.0.31-next.0 ### Patch Changes diff --git a/plugins/example-todo-list/package.json b/plugins/example-todo-list/package.json index df2fe42a29..f595447a9a 100644 --- a/plugins/example-todo-list/package.json +++ b/plugins/example-todo-list/package.json @@ -1,6 +1,6 @@ { "name": "@internal/plugin-todo-list", - "version": "1.0.31-next.0", + "version": "1.0.32-next.1", "backstage": { "role": "frontend-plugin", "pluginId": "todo-list", @@ -49,12 +49,21 @@ "@backstage/cli": "workspace:^", "@testing-library/dom": "^10.0.0", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^15.0.0", - "@types/react": "^16.13.1 || ^17.0.0" + "@testing-library/react": "^16.0.0", + "@types/react": "^18.0.0", + "react": "^18.0.2", + "react-dom": "^18.0.2", + "react-router-dom": "^6.3.0" }, "peerDependencies": { + "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } } diff --git a/plugins/example-todo-list/api-report.md b/plugins/example-todo-list/report.api.md similarity index 100% rename from plugins/example-todo-list/api-report.md rename to plugins/example-todo-list/report.api.md diff --git a/plugins/home-react/CHANGELOG.md b/plugins/home-react/CHANGELOG.md index 41a71ed633..e056be694e 100644 --- a/plugins/home-react/CHANGELOG.md +++ b/plugins/home-react/CHANGELOG.md @@ -1,5 +1,50 @@ # @backstage/plugin-home-react +## 0.1.18-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + +## 0.1.18-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + +## 0.1.17 + +### Patch Changes + +- 0a50d44: Updated dependency `@rjsf/utils` to `5.21.1`. + Updated dependency `@rjsf/core` to `5.21.1`. + Updated dependency `@rjsf/material-ui` to `5.21.1`. + Updated dependency `@rjsf/validator-ajv8` to `5.21.1`. +- fa9d8da: Updated dependency `@rjsf/utils` to `5.20.1`. + Updated dependency `@rjsf/core` to `5.20.1`. + Updated dependency `@rjsf/material-ui` to `5.20.1`. + Updated dependency `@rjsf/validator-ajv8` to `5.20.1`. +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/core-plugin-api@1.9.4 + +## 0.1.17-next.1 + +### Patch Changes + +- fa9d8da: Updated dependency `@rjsf/utils` to `5.20.1`. + Updated dependency `@rjsf/core` to `5.20.1`. + Updated dependency `@rjsf/material-ui` to `5.20.1`. + Updated dependency `@rjsf/validator-ajv8` to `5.20.1`. +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/core-plugin-api@1.9.4-next.0 + ## 0.1.17-next.0 ### Patch Changes diff --git a/plugins/home-react/package.json b/plugins/home-react/package.json index 1af7a32d86..41eb8c53ec 100644 --- a/plugins/home-react/package.json +++ b/plugins/home-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-home-react", - "version": "0.1.17-next.0", + "version": "0.1.18-next.1", "description": "A Backstage plugin that contains react components helps you build a home page", "backstage": { "role": "web-library", @@ -46,16 +46,25 @@ "@backstage/core-plugin-api": "workspace:^", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", - "@rjsf/utils": "5.18.5", - "@types/react": "^16.13.1 || ^17.0.0" + "@rjsf/utils": "5.21.1" }, "devDependencies": { "@backstage/cli": "workspace:^", - "@types/react-grid-layout": "^1.3.2" + "@types/react": "^18.0.0", + "@types/react-grid-layout": "^1.3.2", + "react": "^18.0.2", + "react-dom": "^18.0.2", + "react-router-dom": "^6.3.0" }, "peerDependencies": { + "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } } diff --git a/plugins/home-react/api-report.md b/plugins/home-react/report.api.md similarity index 69% rename from plugins/home-react/api-report.md rename to plugins/home-react/report.api.md index 268f598a63..802d73605c 100644 --- a/plugins/home-react/api-report.md +++ b/plugins/home-react/report.api.md @@ -74,4 +74,15 @@ export const SettingsModal: (props: { componentName?: string; children: JSX.Element; }) => React_2.JSX.Element; + +// Warnings were encountered during analysis: +// +// src/components/SettingsModal.d.ts:3:22 - (ae-undocumented) Missing documentation for "SettingsModal". +// src/extensions.d.ts:6:1 - (ae-undocumented) Missing documentation for "ComponentRenderer". +// src/extensions.d.ts:12:1 - (ae-undocumented) Missing documentation for "ComponentParts". +// src/extensions.d.ts:21:1 - (ae-undocumented) Missing documentation for "RendererProps". +// src/extensions.d.ts:27:1 - (ae-undocumented) Missing documentation for "CardExtensionProps". +// src/extensions.d.ts:33:1 - (ae-undocumented) Missing documentation for "CardLayout". +// src/extensions.d.ts:48:1 - (ae-undocumented) Missing documentation for "CardSettings". +// src/extensions.d.ts:55:1 - (ae-undocumented) Missing documentation for "CardConfig". ``` diff --git a/plugins/home/CHANGELOG.md b/plugins/home/CHANGELOG.md index 51c5abe7dd..70af140344 100644 --- a/plugins/home/CHANGELOG.md +++ b/plugins/home/CHANGELOG.md @@ -1,5 +1,92 @@ # @backstage/plugin-home +## 0.7.12-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/frontend-plugin-api@0.9.0-next.1 + - @backstage/core-compat-api@0.3.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/core-app-api@1.15.1-next.1 + - @backstage/plugin-catalog-react@1.14.0-next.1 + - @backstage/plugin-home-react@0.1.18-next.1 + - @backstage/theme@0.5.8-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + +## 0.7.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/core-compat-api@0.3.1-next.0 + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/plugin-catalog-react@1.13.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.15.1-next.0 + - @backstage/theme@0.5.7 + - @backstage/plugin-home-react@0.1.18-next.0 + +## 0.7.10 + +### Patch Changes + +- c891b69: Add `FavoriteToggle` in `core-components` to standardise favorite marking +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- 0a50d44: Updated dependency `@rjsf/utils` to `5.21.1`. + Updated dependency `@rjsf/core` to `5.21.1`. + Updated dependency `@rjsf/material-ui` to `5.21.1`. + Updated dependency `@rjsf/validator-ajv8` to `5.21.1`. +- fa9d8da: Updated dependency `@rjsf/utils` to `5.20.1`. + Updated dependency `@rjsf/core` to `5.20.1`. + Updated dependency `@rjsf/material-ui` to `5.20.1`. + Updated dependency `@rjsf/validator-ajv8` to `5.20.1`. +- a159180: Added missing items to `overridableComponents` +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/plugin-catalog-react@1.13.0 + - @backstage/frontend-plugin-api@0.8.0 + - @backstage/core-app-api@1.15.0 + - @backstage/core-compat-api@0.3.0 + - @backstage/catalog-model@1.7.0 + - @backstage/catalog-client@1.7.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/theme@0.5.7 + - @backstage/plugin-home-react@0.1.17 + - @backstage/config@1.2.0 + +## 0.7.10-next.2 + +### Patch Changes + +- c891b69: Add `FavoriteToggle` in `core-components` to standardise favorite marking +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- fa9d8da: Updated dependency `@rjsf/utils` to `5.20.1`. + Updated dependency `@rjsf/core` to `5.20.1`. + Updated dependency `@rjsf/material-ui` to `5.20.1`. + Updated dependency `@rjsf/validator-ajv8` to `5.20.1`. +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/plugin-catalog-react@1.13.0-next.2 + - @backstage/core-app-api@1.14.3-next.0 + - @backstage/catalog-client@1.7.0-next.1 + - @backstage/core-compat-api@0.3.0-next.2 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/frontend-plugin-api@0.8.0-next.2 + - @backstage/theme@0.5.7-next.0 + - @backstage/plugin-home-react@0.1.17-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + ## 0.7.10-next.1 ### Patch Changes diff --git a/plugins/home/package.json b/plugins/home/package.json index 7204942d52..79147cbc5c 100644 --- a/plugins/home/package.json +++ b/plugins/home/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-home", - "version": "0.7.10-next.1", + "version": "0.7.12-next.1", "description": "A Backstage plugin that helps you build a home page", "backstage": { "role": "frontend-plugin", @@ -70,11 +70,10 @@ "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.61", - "@rjsf/core": "5.18.5", - "@rjsf/material-ui": "5.18.5", - "@rjsf/utils": "5.18.5", - "@rjsf/validator-ajv8": "5.18.5", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "@rjsf/core": "5.21.1", + "@rjsf/material-ui": "5.21.1", + "@rjsf/utils": "5.21.1", + "@rjsf/validator-ajv8": "5.21.1", "lodash": "^4.17.21", "luxon": "^3.4.3", "react-grid-layout": "1.3.4", @@ -88,14 +87,24 @@ "@backstage/test-utils": "workspace:^", "@testing-library/dom": "^10.0.0", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^15.0.0", + "@testing-library/react": "^16.0.0", "@testing-library/user-event": "^14.0.0", - "@types/react-grid-layout": "^1.3.2" + "@types/react": "^18.0.0", + "@types/react-grid-layout": "^1.3.2", + "react": "^18.0.2", + "react-dom": "^18.0.2", + "react-router-dom": "^6.3.0" }, "peerDependencies": { + "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-router-dom": "6.0.0-beta.0 || ^6.3.0" }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + }, "configSchema": "config.d.ts" } diff --git a/plugins/home/api-report-alpha.md b/plugins/home/report-alpha.api.md similarity index 84% rename from plugins/home/api-report-alpha.md rename to plugins/home/report-alpha.api.md index 7b4b157eb2..e8f8ddf6a1 100644 --- a/plugins/home/api-report-alpha.md +++ b/plugins/home/report-alpha.api.md @@ -60,8 +60,12 @@ const _default: FrontendPlugin< >; }; kind: 'page'; - namespace: undefined; name: undefined; + params: { + defaultPath: string; + loader: () => Promise; + routeRef?: RouteRef | undefined; + }; }>; } >; @@ -74,5 +78,10 @@ export const titleExtensionDataRef: ConfigurableExtensionDataRef< {} >; +// Warnings were encountered during analysis: +// +// src/alpha.d.ts:5:22 - (ae-undocumented) Missing documentation for "titleExtensionDataRef". +// src/alpha.d.ts:9:15 - (ae-undocumented) Missing documentation for "_default". + // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/home/api-report.md b/plugins/home/report.api.md similarity index 75% rename from plugins/home/api-report.md rename to plugins/home/report.api.md index 023c649ab4..985aed50ca 100644 --- a/plugins/home/api-report.md +++ b/plugins/home/report.api.md @@ -327,4 +327,34 @@ export const WelcomeTitle: ({ export type WelcomeTitleLanguageProps = { language?: string[]; }; + +// Warnings were encountered during analysis: +// +// src/api/VisitsApi.d.ts:106:22 - (ae-undocumented) Missing documentation for "visitsApiRef". +// src/api/VisitsStorageApi.d.ts:4:1 - (ae-undocumented) Missing documentation for "VisitsStorageApiOptions". +// src/api/VisitsStorageApi.d.ts:20:5 - (ae-undocumented) Missing documentation for "create". +// src/api/VisitsWebStorageApi.d.ts:4:1 - (ae-undocumented) Missing documentation for "VisitsWebStorageApiOptions". +// src/api/VisitsWebStorageApi.d.ts:14:5 - (ae-undocumented) Missing documentation for "create". +// src/assets/TemplateBackstageLogo.d.ts:3:22 - (ae-undocumented) Missing documentation for "TemplateBackstageLogo". +// src/assets/TemplateBackstageLogoIcon.d.ts:3:22 - (ae-undocumented) Missing documentation for "TemplateBackstageLogoIcon". +// src/deprecated.d.ts:7:22 - (ae-undocumented) Missing documentation for "createCardExtension". +// src/deprecated.d.ts:12:1 - (ae-undocumented) Missing documentation for "CardExtensionProps". +// src/deprecated.d.ts:17:1 - (ae-undocumented) Missing documentation for "CardLayout". +// src/deprecated.d.ts:22:1 - (ae-undocumented) Missing documentation for "CardSettings". +// src/deprecated.d.ts:27:1 - (ae-undocumented) Missing documentation for "CardConfig". +// src/deprecated.d.ts:32:1 - (ae-undocumented) Missing documentation for "ComponentParts". +// src/deprecated.d.ts:37:1 - (ae-undocumented) Missing documentation for "ComponentRenderer". +// src/deprecated.d.ts:42:1 - (ae-undocumented) Missing documentation for "RendererProps". +// src/deprecated.d.ts:47:22 - (ae-undocumented) Missing documentation for "SettingsModal". +// src/homePageComponents/HeaderWorldClock/HeaderWorldClock.d.ts:3:1 - (ae-undocumented) Missing documentation for "ClockConfig". +// src/homePageComponents/Toolkit/Context.d.ts:3:1 - (ae-undocumented) Missing documentation for "Tool". +// src/homePageComponents/VisitedByType/Content.d.ts:4:1 - (ae-undocumented) Missing documentation for "VisitedByTypeKind". +// src/homePageComponents/VisitedByType/Content.d.ts:6:1 - (ae-undocumented) Missing documentation for "VisitedByTypeProps". +// src/homePageComponents/WelcomeTitle/WelcomeTitle.d.ts:3:1 - (ae-undocumented) Missing documentation for "WelcomeTitleLanguageProps". +// src/plugin.d.ts:5:22 - (ae-undocumented) Missing documentation for "homePlugin". +// src/plugin.d.ts:9:22 - (ae-undocumented) Missing documentation for "HomepageCompositionRoot". +// src/plugin.d.ts:14:22 - (ae-undocumented) Missing documentation for "ComponentAccordion". +// src/plugin.d.ts:24:22 - (ae-undocumented) Missing documentation for "ComponentTabs". +// src/plugin.d.ts:32:22 - (ae-undocumented) Missing documentation for "ComponentTab". +// src/plugin.d.ts:53:22 - (ae-undocumented) Missing documentation for "HomePageRandomJoke". ``` diff --git a/plugins/home/src/components/StarredEntityListItem/StarredEntityListItem.tsx b/plugins/home/src/components/StarredEntityListItem/StarredEntityListItem.tsx index 579116b9a9..8081e71407 100644 --- a/plugins/home/src/components/StarredEntityListItem/StarredEntityListItem.tsx +++ b/plugins/home/src/components/StarredEntityListItem/StarredEntityListItem.tsx @@ -17,14 +17,12 @@ import { Entity, stringifyEntityRef } from '@backstage/catalog-model'; import { entityRouteParams } from '@backstage/plugin-catalog-react'; import ListItem from '@material-ui/core/ListItem'; import ListItemIcon from '@material-ui/core/ListItemIcon'; -import Tooltip from '@material-ui/core/Tooltip'; -import IconButton from '@material-ui/core/IconButton'; import ListItemText from '@material-ui/core/ListItemText'; import React from 'react'; import { Link } from 'react-router-dom'; import { entityRouteRef } from '@backstage/plugin-catalog-react'; import { useRouteRef } from '@backstage/core-plugin-api'; -import StarIcon from '@material-ui/icons/Star'; +import { FavoriteToggle } from '@backstage/core-components'; type EntityListItemProps = { entity: Entity; @@ -40,15 +38,12 @@ export const StarredEntityListItem = ({ return ( - - onToggleStarredEntity(entity)} - > - - - + onToggleStarredEntity(entity)} + /> diff --git a/plugins/home/src/homePageComponents/FeaturedDocsCard/Content.tsx b/plugins/home/src/homePageComponents/FeaturedDocsCard/Content.tsx index eae8e82966..dfd6c1b8e7 100644 --- a/plugins/home/src/homePageComponents/FeaturedDocsCard/Content.tsx +++ b/plugins/home/src/homePageComponents/FeaturedDocsCard/Content.tsx @@ -53,6 +53,12 @@ export type FeaturedDocsCardProps = { subLinkText?: string; }; +/** @public */ +export type FeaturedDocsCardClassKey = + | 'docDescription' + | 'docSubLink' + | 'docsTitleLink'; + const useStyles = makeStyles( theme => ({ docDescription: { diff --git a/plugins/home/src/homePageComponents/FeaturedDocsCard/index.ts b/plugins/home/src/homePageComponents/FeaturedDocsCard/index.ts index 5151fa370c..526fc291c9 100644 --- a/plugins/home/src/homePageComponents/FeaturedDocsCard/index.ts +++ b/plugins/home/src/homePageComponents/FeaturedDocsCard/index.ts @@ -15,4 +15,7 @@ */ export { Content } from './Content'; -export type { FeaturedDocsCardProps } from './Content'; +export type { + FeaturedDocsCardProps, + FeaturedDocsCardClassKey, +} from './Content'; diff --git a/plugins/home/src/overridableComponents.ts b/plugins/home/src/overridableComponents.ts new file mode 100644 index 0000000000..04225e048c --- /dev/null +++ b/plugins/home/src/overridableComponents.ts @@ -0,0 +1,36 @@ +/* + * 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 { Overrides } from '@material-ui/core/styles/overrides'; +import { StyleRules } from '@material-ui/core/styles/withStyles'; +import { FeaturedDocsCardClassKey } from './homePageComponents/FeaturedDocsCard'; + +/** @public */ +export type CatalogReactComponentsNameToClassKey = { + HomeFeaturedDocsCard: FeaturedDocsCardClassKey; +}; + +/** @public */ +export type BackstageOverrides = Overrides & { + [Name in keyof CatalogReactComponentsNameToClassKey]?: Partial< + StyleRules + >; +}; + +declare module '@backstage/theme' { + interface OverrideComponentNameToClassKeys + extends CatalogReactComponentsNameToClassKey {} +} diff --git a/plugins/kubernetes-backend/CHANGELOG.md b/plugins/kubernetes-backend/CHANGELOG.md index 33447a6be2..cdf9c02a99 100644 --- a/plugins/kubernetes-backend/CHANGELOG.md +++ b/plugins/kubernetes-backend/CHANGELOG.md @@ -1,5 +1,71 @@ # @backstage/plugin-kubernetes-backend +## 0.18.7-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-kubernetes-node@0.1.20-next.0 + - @backstage/plugin-permission-node@0.8.4-next.0 + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-kubernetes-common@0.8.3 + - @backstage/plugin-permission-common@0.8.1 + +## 0.18.6 + +### Patch Changes + +- a0f1f0d: Bump the `ws` library +- f55f8bf: The `KubernetesBuilder` and its related types has been marked as deprecared. This backend should instead be initialized using the new backend system. +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- ca96b66: Skip start without proper config +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/catalog-model@1.7.0 + - @backstage/catalog-client@1.7.0 + - @backstage/plugin-permission-node@0.8.3 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/plugin-kubernetes-node@0.1.19 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.8.3 + - @backstage/plugin-permission-common@0.8.1 + +## 0.18.6-next.2 + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-client@1.7.0-next.1 + - @backstage/plugin-kubernetes-node@0.1.19-next.2 + - @backstage/plugin-permission-node@0.8.3-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.12.7-next.2 + - @backstage/plugin-kubernetes-common@0.8.2 + - @backstage/plugin-permission-common@0.8.1 + ## 0.18.6-next.1 ### Patch Changes diff --git a/plugins/kubernetes-backend/package.json b/plugins/kubernetes-backend/package.json index dc42a2b7b2..98eb59a4f8 100644 --- a/plugins/kubernetes-backend/package.json +++ b/plugins/kubernetes-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-kubernetes-backend", - "version": "0.18.6-next.1", + "version": "0.18.7-next.0", "description": "A Backstage backend plugin that integrates towards Kubernetes", "backstage": { "role": "backend-plugin", @@ -62,7 +62,7 @@ "@aws-sdk/credential-providers": "^3.350.0", "@aws-sdk/signature-v4": "^3.347.0", "@azure/identity": "^4.0.0", - "@backstage/backend-common": "workspace:^", + "@backstage/backend-common": "^0.25.0", "@backstage/backend-plugin-api": "workspace:^", "@backstage/catalog-client": "workspace:^", "@backstage/catalog-model": "workspace:^", @@ -106,8 +106,8 @@ "@backstage/plugin-permission-backend-module-allow-all-policy": "workspace:^", "@types/aws4": "^1.5.1", "msw": "^1.0.0", - "supertest": "^6.1.3", - "ws": "^8.13.0" + "supertest": "^7.0.0", + "ws": "^8.18.0" }, "configSchema": "config.d.ts" } diff --git a/plugins/kubernetes-backend/api-report-alpha.md b/plugins/kubernetes-backend/report-alpha.api.md similarity index 100% rename from plugins/kubernetes-backend/api-report-alpha.md rename to plugins/kubernetes-backend/report-alpha.api.md diff --git a/plugins/kubernetes-backend/api-report.md b/plugins/kubernetes-backend/report.api.md similarity index 54% rename from plugins/kubernetes-backend/api-report.md rename to plugins/kubernetes-backend/report.api.md index 2711085b81..e01ada7e1c 100644 --- a/plugins/kubernetes-backend/api-report.md +++ b/plugins/kubernetes-backend/report.api.md @@ -425,4 +425,118 @@ export type SigningCreds = { secretAccessKey: string | undefined; sessionToken: string | undefined; }; + +// Warnings were encountered during analysis: +// +// src/auth/AksStrategy.d.ts:7:1 - (ae-undocumented) Missing documentation for "AksStrategy". +// src/auth/AksStrategy.d.ts:8:5 - (ae-undocumented) Missing documentation for "getCredential". +// src/auth/AksStrategy.d.ts:9:5 - (ae-undocumented) Missing documentation for "validateCluster". +// src/auth/AksStrategy.d.ts:10:5 - (ae-undocumented) Missing documentation for "presentAuthMetadata". +// src/auth/AnonymousStrategy.d.ts:6:1 - (ae-undocumented) Missing documentation for "AnonymousStrategy". +// src/auth/AnonymousStrategy.d.ts:7:5 - (ae-undocumented) Missing documentation for "getCredential". +// src/auth/AnonymousStrategy.d.ts:8:5 - (ae-undocumented) Missing documentation for "validateCluster". +// src/auth/AnonymousStrategy.d.ts:9:5 - (ae-undocumented) Missing documentation for "presentAuthMetadata". +// src/auth/AwsIamStrategy.d.ts:7:1 - (ae-undocumented) Missing documentation for "SigningCreds". +// src/auth/AwsIamStrategy.d.ts:16:1 - (ae-undocumented) Missing documentation for "AwsIamStrategy". +// src/auth/AwsIamStrategy.d.ts:21:5 - (ae-undocumented) Missing documentation for "getCredential". +// src/auth/AwsIamStrategy.d.ts:22:5 - (ae-undocumented) Missing documentation for "validateCluster". +// src/auth/AwsIamStrategy.d.ts:24:5 - (ae-undocumented) Missing documentation for "presentAuthMetadata". +// src/auth/AzureIdentityStrategy.d.ts:8:1 - (ae-undocumented) Missing documentation for "AzureIdentityStrategy". +// src/auth/AzureIdentityStrategy.d.ts:14:5 - (ae-undocumented) Missing documentation for "getCredential". +// src/auth/AzureIdentityStrategy.d.ts:15:5 - (ae-undocumented) Missing documentation for "validateCluster". +// src/auth/AzureIdentityStrategy.d.ts:19:5 - (ae-undocumented) Missing documentation for "presentAuthMetadata". +// src/auth/DispatchStrategy.d.ts:7:1 - (ae-undocumented) Missing documentation for "DispatchStrategyOptions". +// src/auth/DispatchStrategy.d.ts:19:5 - (ae-undocumented) Missing documentation for "getCredential". +// src/auth/DispatchStrategy.d.ts:20:5 - (ae-undocumented) Missing documentation for "validateCluster". +// src/auth/DispatchStrategy.d.ts:21:5 - (ae-undocumented) Missing documentation for "presentAuthMetadata". +// src/auth/GoogleServiceAccountStrategy.d.ts:6:1 - (ae-undocumented) Missing documentation for "GoogleServiceAccountStrategy". +// src/auth/GoogleServiceAccountStrategy.d.ts:7:5 - (ae-undocumented) Missing documentation for "getCredential". +// src/auth/GoogleServiceAccountStrategy.d.ts:8:5 - (ae-undocumented) Missing documentation for "validateCluster". +// src/auth/GoogleServiceAccountStrategy.d.ts:9:5 - (ae-undocumented) Missing documentation for "presentAuthMetadata". +// src/auth/GoogleStrategy.d.ts:7:1 - (ae-undocumented) Missing documentation for "GoogleStrategy". +// src/auth/GoogleStrategy.d.ts:8:5 - (ae-undocumented) Missing documentation for "getCredential". +// src/auth/GoogleStrategy.d.ts:9:5 - (ae-undocumented) Missing documentation for "validateCluster". +// src/auth/GoogleStrategy.d.ts:10:5 - (ae-undocumented) Missing documentation for "presentAuthMetadata". +// src/auth/OidcStrategy.d.ts:7:1 - (ae-undocumented) Missing documentation for "OidcStrategy". +// src/auth/OidcStrategy.d.ts:8:5 - (ae-undocumented) Missing documentation for "getCredential". +// src/auth/OidcStrategy.d.ts:9:5 - (ae-undocumented) Missing documentation for "validateCluster". +// src/auth/OidcStrategy.d.ts:10:5 - (ae-undocumented) Missing documentation for "presentAuthMetadata". +// src/auth/ServiceAccountStrategy.d.ts:6:1 - (ae-undocumented) Missing documentation for "ServiceAccountStrategy". +// src/auth/ServiceAccountStrategy.d.ts:7:5 - (ae-undocumented) Missing documentation for "getCredential". +// src/auth/ServiceAccountStrategy.d.ts:8:5 - (ae-undocumented) Missing documentation for "validateCluster". +// src/auth/ServiceAccountStrategy.d.ts:9:5 - (ae-undocumented) Missing documentation for "presentAuthMetadata". +// src/auth/types.d.ts:5:1 - (ae-undocumented) Missing documentation for "AuthenticationStrategy". +// src/auth/types.d.ts:9:1 - (ae-undocumented) Missing documentation for "KubernetesCredential". +// src/service/KubernetesBuilder.d.ts:14:1 - (ae-undocumented) Missing documentation for "KubernetesEnvironment". +// src/service/KubernetesBuilder.d.ts:15:5 - (ae-undocumented) Missing documentation for "logger". +// src/service/KubernetesBuilder.d.ts:16:5 - (ae-undocumented) Missing documentation for "config". +// src/service/KubernetesBuilder.d.ts:17:5 - (ae-undocumented) Missing documentation for "catalogApi". +// src/service/KubernetesBuilder.d.ts:18:5 - (ae-undocumented) Missing documentation for "discovery". +// src/service/KubernetesBuilder.d.ts:19:5 - (ae-undocumented) Missing documentation for "permissions". +// src/service/KubernetesBuilder.d.ts:20:5 - (ae-undocumented) Missing documentation for "auth". +// src/service/KubernetesBuilder.d.ts:21:5 - (ae-undocumented) Missing documentation for "httpAuth". +// src/service/KubernetesBuilder.d.ts:44:1 - (ae-undocumented) Missing documentation for "KubernetesBuilder". +// src/service/KubernetesBuilder.d.ts:45:5 - (ae-undocumented) Missing documentation for "env". +// src/service/KubernetesBuilder.d.ts:53:5 - (ae-undocumented) Missing documentation for "createBuilder". +// src/service/KubernetesBuilder.d.ts:55:5 - (ae-undocumented) Missing documentation for "build". +// src/service/KubernetesBuilder.d.ts:56:5 - (ae-undocumented) Missing documentation for "setClusterSupplier". +// src/service/KubernetesBuilder.d.ts:57:5 - (ae-undocumented) Missing documentation for "setDefaultClusterRefreshInterval". +// src/service/KubernetesBuilder.d.ts:58:5 - (ae-undocumented) Missing documentation for "setObjectsProvider". +// src/service/KubernetesBuilder.d.ts:59:5 - (ae-undocumented) Missing documentation for "setFetcher". +// src/service/KubernetesBuilder.d.ts:60:5 - (ae-undocumented) Missing documentation for "setServiceLocator". +// src/service/KubernetesBuilder.d.ts:61:5 - (ae-undocumented) Missing documentation for "setProxy". +// src/service/KubernetesBuilder.d.ts:62:5 - (ae-undocumented) Missing documentation for "setAuthStrategyMap". +// src/service/KubernetesBuilder.d.ts:65:5 - (ae-undocumented) Missing documentation for "addAuthStrategy". +// src/service/KubernetesBuilder.d.ts:66:5 - (ae-undocumented) Missing documentation for "buildCustomResources". +// src/service/KubernetesBuilder.d.ts:67:5 - (ae-undocumented) Missing documentation for "buildClusterSupplier". +// src/service/KubernetesBuilder.d.ts:68:5 - (ae-undocumented) Missing documentation for "buildObjectsProvider". +// src/service/KubernetesBuilder.d.ts:69:5 - (ae-undocumented) Missing documentation for "buildFetcher". +// src/service/KubernetesBuilder.d.ts:70:5 - (ae-undocumented) Missing documentation for "buildServiceLocator". +// src/service/KubernetesBuilder.d.ts:71:5 - (ae-undocumented) Missing documentation for "buildMultiTenantServiceLocator". +// src/service/KubernetesBuilder.d.ts:72:5 - (ae-undocumented) Missing documentation for "buildSingleTenantServiceLocator". +// src/service/KubernetesBuilder.d.ts:73:5 - (ae-undocumented) Missing documentation for "buildCatalogRelationServiceLocator". +// src/service/KubernetesBuilder.d.ts:74:5 - (ae-undocumented) Missing documentation for "buildHttpServiceLocator". +// src/service/KubernetesBuilder.d.ts:75:5 - (ae-undocumented) Missing documentation for "buildProxy". +// src/service/KubernetesBuilder.d.ts:76:5 - (ae-undocumented) Missing documentation for "buildRouter". +// src/service/KubernetesBuilder.d.ts:77:5 - (ae-undocumented) Missing documentation for "buildAuthStrategyMap". +// src/service/KubernetesBuilder.d.ts:80:5 - (ae-undocumented) Missing documentation for "fetchClusterDetails". +// src/service/KubernetesBuilder.d.ts:83:5 - (ae-undocumented) Missing documentation for "getServiceLocatorMethod". +// src/service/KubernetesBuilder.d.ts:84:5 - (ae-undocumented) Missing documentation for "getFetcher". +// src/service/KubernetesBuilder.d.ts:85:5 - (ae-undocumented) Missing documentation for "getClusterSupplier". +// src/service/KubernetesBuilder.d.ts:86:5 - (ae-undocumented) Missing documentation for "getServiceLocator". +// src/service/KubernetesBuilder.d.ts:87:5 - (ae-undocumented) Missing documentation for "getObjectsProvider". +// src/service/KubernetesBuilder.d.ts:88:5 - (ae-undocumented) Missing documentation for "getObjectTypesToFetch". +// src/service/KubernetesBuilder.d.ts:89:5 - (ae-undocumented) Missing documentation for "getProxy". +// src/service/KubernetesBuilder.d.ts:90:5 - (ae-undocumented) Missing documentation for "getAuthStrategyMap". +// src/service/KubernetesFanOutHandler.d.ts:9:22 - (ae-undocumented) Missing documentation for "DEFAULT_OBJECTS". +// src/service/KubernetesProxy.d.ts:50:5 - (ae-undocumented) Missing documentation for "createRequestHandler". +// src/service/router.d.ts:11:1 - (ae-undocumented) Missing documentation for "RouterOptions". +// src/service/router.d.ts:12:5 - (ae-undocumented) Missing documentation for "logger". +// src/service/router.d.ts:13:5 - (ae-undocumented) Missing documentation for "config". +// src/service/router.d.ts:14:5 - (ae-undocumented) Missing documentation for "catalogApi". +// src/service/router.d.ts:15:5 - (ae-undocumented) Missing documentation for "clusterSupplier". +// src/service/router.d.ts:16:5 - (ae-undocumented) Missing documentation for "discovery". +// src/service/router.d.ts:17:5 - (ae-undocumented) Missing documentation for "permissions". +// src/types/types.d.ts:9:1 - (ae-undocumented) Missing documentation for "ServiceLocatorMethod". +// src/types/types.d.ts:14:1 - (ae-undocumented) Missing documentation for "KubernetesObjectsProviderOptions". +// src/types/types.d.ts:15:5 - (ae-undocumented) Missing documentation for "logger". +// src/types/types.d.ts:16:5 - (ae-undocumented) Missing documentation for "config". +// src/types/types.d.ts:17:5 - (ae-undocumented) Missing documentation for "fetcher". +// src/types/types.d.ts:18:5 - (ae-undocumented) Missing documentation for "serviceLocator". +// src/types/types.d.ts:19:5 - (ae-undocumented) Missing documentation for "customResources". +// src/types/types.d.ts:20:5 - (ae-undocumented) Missing documentation for "objectTypesToFetch". +// src/types/types.d.ts:26:1 - (ae-undocumented) Missing documentation for "ObjectsByEntityRequest". +// src/types/types.d.ts:30:1 - (ae-undocumented) Missing documentation for "KubernetesObjectsProvider". +// src/types/types.d.ts:34:1 - (ae-undocumented) Missing documentation for "CustomResourcesByEntity". +// src/types/types.d.ts:39:1 - (ae-undocumented) Missing documentation for "AuthMetadata". +// src/types/types.d.ts:44:1 - (ae-undocumented) Missing documentation for "ClusterDetails". +// src/types/types.d.ts:49:1 - (ae-undocumented) Missing documentation for "KubernetesClustersSupplier". +// src/types/types.d.ts:53:1 - (ae-undocumented) Missing documentation for "KubernetesObjectTypes". +// src/types/types.d.ts:57:1 - (ae-undocumented) Missing documentation for "ObjectToFetch". +// src/types/types.d.ts:61:1 - (ae-undocumented) Missing documentation for "CustomResource". +// src/types/types.d.ts:65:1 - (ae-undocumented) Missing documentation for "ObjectFetchParams". +// src/types/types.d.ts:69:1 - (ae-undocumented) Missing documentation for "FetchResponseWrapper". +// src/types/types.d.ts:73:1 - (ae-undocumented) Missing documentation for "KubernetesFetcher". +// src/types/types.d.ts:77:1 - (ae-undocumented) Missing documentation for "ServiceLocatorRequestContext". +// src/types/types.d.ts:81:1 - (ae-undocumented) Missing documentation for "KubernetesServiceLocator". ``` diff --git a/plugins/kubernetes-backend/src/cluster-locator/CatalogClusterLocator.test.ts b/plugins/kubernetes-backend/src/cluster-locator/CatalogClusterLocator.test.ts index 5ce316099e..0d17314cef 100644 --- a/plugins/kubernetes-backend/src/cluster-locator/CatalogClusterLocator.test.ts +++ b/plugins/kubernetes-backend/src/cluster-locator/CatalogClusterLocator.test.ts @@ -22,103 +22,89 @@ import { ANNOTATION_KUBERNETES_OIDC_TOKEN_PROVIDER, } from '@backstage/plugin-kubernetes-common'; import { CatalogClusterLocator } from './CatalogClusterLocator'; -import { CatalogApi } from '@backstage/catalog-client'; import { mockCredentials, mockServices } from '@backstage/backend-test-utils'; +import { Entity } from '@backstage/catalog-model'; +import { catalogServiceMock } from '@backstage/plugin-catalog-node/testUtils'; -const mockCatalogApi = { - getEntityByRef: jest.fn(), - getEntities: async () => ({ - items: [ - { - apiVersion: 'backstage.io/v1alpha1', - kind: 'Resource', - metadata: { - annotations: { - 'kubernetes.io/api-server': 'https://apiserver.com', - 'kubernetes.io/api-server-certificate-authority': 'caData', - [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'oidc', - [ANNOTATION_KUBERNETES_OIDC_TOKEN_PROVIDER]: 'google', - 'kubernetes.io/skip-metrics-lookup': 'true', - 'kubernetes.io/skip-tls-verify': 'true', - 'kubernetes.io/dashboard-url': 'my-url', - 'kubernetes.io/dashboard-app': 'my-app', - }, - name: 'owned', - title: 'title', - namespace: 'default', - }, +const entities: Entity[] = [ + { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Resource', + metadata: { + annotations: { + 'kubernetes.io/api-server': 'https://apiserver.com', + 'kubernetes.io/api-server-certificate-authority': 'caData', + [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'oidc', + [ANNOTATION_KUBERNETES_OIDC_TOKEN_PROVIDER]: 'google', + 'kubernetes.io/skip-metrics-lookup': 'true', + 'kubernetes.io/skip-tls-verify': 'true', + 'kubernetes.io/dashboard-url': 'my-url', + 'kubernetes.io/dashboard-app': 'my-app', }, - { - apiVersion: 'backstage.io/v1alpha1', - kind: 'Resource', - metadata: { - annotations: { - 'kubernetes.io/api-server': 'https://apiserver.com', - 'kubernetes.io/api-server-certificate-authority': 'caData', - [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'aws', - [ANNOTATION_KUBERNETES_AWS_ASSUME_ROLE]: 'my-role', - [ANNOTATION_KUBERNETES_AWS_EXTERNAL_ID]: 'my-id', - [ANNOTATION_KUBERNETES_OIDC_TOKEN_PROVIDER]: 'google', - 'kubernetes.io/dashboard-url': 'my-url', - 'kubernetes.io/dashboard-app': 'my-app', - }, - name: 'owned', - namespace: 'default', - }, + name: 'owned', + title: 'title', + namespace: 'default', + }, + spec: { + type: 'kubernetes-cluster', + }, + }, + { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Resource', + metadata: { + annotations: { + 'kubernetes.io/api-server': 'https://apiserver.com', + 'kubernetes.io/api-server-certificate-authority': 'caData', + [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'aws', + [ANNOTATION_KUBERNETES_AWS_ASSUME_ROLE]: 'my-role', + [ANNOTATION_KUBERNETES_AWS_EXTERNAL_ID]: 'my-id', + [ANNOTATION_KUBERNETES_OIDC_TOKEN_PROVIDER]: 'google', + 'kubernetes.io/dashboard-url': 'my-url', + 'kubernetes.io/dashboard-app': 'my-app', }, - ], - }), -} as unknown as CatalogApi; + name: 'owned', + namespace: 'default', + }, + spec: { + type: 'kubernetes-cluster', + }, + }, +]; describe('CatalogClusterLocator', () => { it('returns empty cluster details when the cluster is empty', async () => { - const emptyMockCatalogApi = { - getEntityByRef: jest.fn(), - getEntities: async () => ({ - items: [], - }), - } as Partial as CatalogApi; - const auth = mockServices.auth(); - + const credentials = mockCredentials.user(); const clusterSupplier = CatalogClusterLocator.fromConfig( - emptyMockCatalogApi, - auth, + catalogServiceMock({ entities: [] }), + mockServices.auth(), ); - const credentials = mockCredentials.user(); - const result = await clusterSupplier.getClusters({ credentials }); - expect(result).toHaveLength(0); expect(result).toStrictEqual([]); }); it('returns the cluster details provided by annotations', async () => { - const auth = mockServices.auth(); + const credentials = mockCredentials.user(); const clusterSupplier = CatalogClusterLocator.fromConfig( - mockCatalogApi, - auth, + catalogServiceMock({ entities }), + mockServices.auth(), ); - const credentials = mockCredentials.user(); - const result = await clusterSupplier.getClusters({ credentials }); - expect(result).toHaveLength(2); expect(result[0]).toMatchSnapshot(); }); it('returns the aws cluster details provided by annotations', async () => { - const auth = mockServices.auth(); + const credentials = mockCredentials.user(); const clusterSupplier = CatalogClusterLocator.fromConfig( - mockCatalogApi, - auth, + catalogServiceMock({ entities }), + mockServices.auth(), ); - const credentials = mockCredentials.user(); - const result = await clusterSupplier.getClusters({ credentials }); - expect(result).toHaveLength(2); expect(result[1]).toMatchSnapshot(); }); diff --git a/plugins/kubernetes-backend/src/cluster-locator/index.test.ts b/plugins/kubernetes-backend/src/cluster-locator/index.test.ts index 64b4bfbd0a..7e52848bb8 100644 --- a/plugins/kubernetes-backend/src/cluster-locator/index.test.ts +++ b/plugins/kubernetes-backend/src/cluster-locator/index.test.ts @@ -15,16 +15,18 @@ */ import { Config, ConfigReader } from '@backstage/config'; -import { CatalogApi } from '@backstage/catalog-client'; -import { ANNOTATION_KUBERNETES_AUTH_PROVIDER } from '@backstage/plugin-kubernetes-common'; +import { + ANNOTATION_KUBERNETES_API_SERVER, + ANNOTATION_KUBERNETES_API_SERVER_CA, + ANNOTATION_KUBERNETES_AUTH_PROVIDER, +} from '@backstage/plugin-kubernetes-common'; import { getCombinedClusterSupplier } from './index'; import { ClusterDetails } from '../types/types'; import { AuthenticationStrategy, DispatchStrategy } from '../auth'; import { mockCredentials, mockServices } from '@backstage/backend-test-utils'; +import { catalogServiceMock } from '@backstage/plugin-catalog-node/testUtils'; describe('getCombinedClusterSupplier', () => { - let catalogApi: CatalogApi; - it('should retrieve cluster details from config', async () => { const config: Config = new ConfigReader( { @@ -62,7 +64,7 @@ describe('getCombinedClusterSupplier', () => { const clusterSupplier = getCombinedClusterSupplier( config, - catalogApi, + catalogServiceMock.mock(), mockStrategy, mockServices.logger.mock(), undefined, @@ -106,7 +108,7 @@ describe('getCombinedClusterSupplier', () => { expect(() => getCombinedClusterSupplier( config, - catalogApi, + catalogServiceMock.mock(), new DispatchStrategy({ authStrategyMap: {} }), mockServices.logger.mock(), undefined, @@ -141,31 +143,30 @@ describe('getCombinedClusterSupplier', () => { validateCluster: jest.fn().mockReturnValue([]), presentAuthMetadata: jest.fn(), }; - catalogApi = { - getEntities: jest.fn().mockResolvedValue({ - items: [{ metadata: { annotations: {}, name: 'cluster' } }], - }), - getEntitiesByRefs: jest.fn(), - queryEntities: jest.fn(), - getEntityAncestors: jest.fn(), - getEntityByRef: jest.fn(), - removeEntityByUid: jest.fn(), - refreshEntity: jest.fn(), - getEntityFacets: jest.fn(), - getLocationById: jest.fn(), - getLocationByRef: jest.fn(), - addLocation: jest.fn(), - removeLocationById: jest.fn(), - getLocationByEntity: jest.fn(), - validateEntity: jest.fn(), - }; const auth = mockServices.auth(); const credentials = mockCredentials.user(); const clusterSupplier = getCombinedClusterSupplier( config, - catalogApi, + catalogServiceMock({ + entities: [ + { + kind: 'Resource', + metadata: { + name: 'cluster', + annotations: { + [ANNOTATION_KUBERNETES_API_SERVER]: 'mock', + [ANNOTATION_KUBERNETES_API_SERVER_CA]: 'mock', + [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'mock', + }, + }, + spec: { + type: 'kubernetes-cluster', + }, + } as any, + ], + }), mockStrategy, logger, undefined, diff --git a/plugins/kubernetes-cluster/CHANGELOG.md b/plugins/kubernetes-cluster/CHANGELOG.md index e5f1848841..3ab3ed62b2 100644 --- a/plugins/kubernetes-cluster/CHANGELOG.md +++ b/plugins/kubernetes-cluster/CHANGELOG.md @@ -1,5 +1,57 @@ # @backstage/plugin-kubernetes-cluster +## 0.0.17-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- 605e0bb: Updated dependency `@kubernetes-models/base` to `^5.0.0`. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/plugin-kubernetes-react@0.4.4-next.1 + - @backstage/plugin-catalog-react@1.14.0-next.1 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-kubernetes-common@0.8.3 + +## 0.0.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/plugin-catalog-react@1.13.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-kubernetes-common@0.8.3 + - @backstage/plugin-kubernetes-react@0.4.4-next.0 + +## 0.0.15 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/plugin-catalog-react@1.13.0 + - @backstage/catalog-model@1.7.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/plugin-kubernetes-react@0.4.3 + - @backstage/plugin-kubernetes-common@0.8.3 + +## 0.0.15-next.2 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/plugin-catalog-react@1.13.0-next.2 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/plugin-kubernetes-react@0.4.3-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/plugin-kubernetes-common@0.8.2 + ## 0.0.15-next.1 ### Patch Changes diff --git a/plugins/kubernetes-cluster/package.json b/plugins/kubernetes-cluster/package.json index 29c933be61..b96abdabda 100644 --- a/plugins/kubernetes-cluster/package.json +++ b/plugins/kubernetes-cluster/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-kubernetes-cluster", - "version": "0.0.15-next.1", + "version": "0.0.17-next.1", "description": "A Backstage plugin that shows details of Kubernetes clusters", "backstage": { "role": "frontend-plugin", @@ -48,10 +48,9 @@ "@backstage/plugin-kubernetes-common": "workspace:^", "@backstage/plugin-kubernetes-react": "workspace:^", "@kubernetes-models/apimachinery": "^1.1.0", - "@kubernetes-models/base": "^4.0.1", + "@kubernetes-models/base": "^5.0.0", "@material-ui/core": "^4.12.2", "@material-ui/lab": "4.0.0-alpha.61", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "cronstrue": "^2.2.0", "js-yaml": "^4.0.0", "kubernetes-models": "^4.1.0", @@ -64,12 +63,22 @@ "@backstage/test-utils": "workspace:^", "@testing-library/dom": "^10.0.0", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^15.0.0", - "@types/node": "^16.11.26" + "@testing-library/react": "^16.0.0", + "@types/node": "^16.11.26", + "@types/react": "^18.0.0", + "react": "^18.0.2", + "react-dom": "^18.0.2", + "react-router-dom": "^6.3.0" }, "peerDependencies": { + "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } } diff --git a/plugins/kubernetes-cluster/api-report.md b/plugins/kubernetes-cluster/report.api.md similarity index 73% rename from plugins/kubernetes-cluster/api-report.md rename to plugins/kubernetes-cluster/report.api.md index 10d248097a..5e16134c2d 100644 --- a/plugins/kubernetes-cluster/api-report.md +++ b/plugins/kubernetes-cluster/report.api.md @@ -21,4 +21,9 @@ export const isKubernetesClusterAvailable: (entity: Entity) => boolean; // @public (undocumented) export const Router: () => React_2.JSX.Element; + +// Warnings were encountered during analysis: +// +// src/Router.d.ts:8:22 - (ae-undocumented) Missing documentation for "isKubernetesClusterAvailable". +// src/Router.d.ts:14:22 - (ae-undocumented) Missing documentation for "Router". ``` diff --git a/plugins/kubernetes-common/CHANGELOG.md b/plugins/kubernetes-common/CHANGELOG.md index 6b3606335c..6886f26bf3 100644 --- a/plugins/kubernetes-common/CHANGELOG.md +++ b/plugins/kubernetes-common/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-kubernetes-common +## 0.8.3 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.0 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.8.1 + ## 0.8.2 ### Patch Changes diff --git a/plugins/kubernetes-common/api-report.md b/plugins/kubernetes-common/api-report.md deleted file mode 100644 index 81e9ca28e7..0000000000 --- a/plugins/kubernetes-common/api-report.md +++ /dev/null @@ -1,468 +0,0 @@ -## API Report File for "@backstage/plugin-kubernetes-common" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -import { BasicPermission } from '@backstage/plugin-permission-common'; -import { Entity } from '@backstage/catalog-model'; -import { FetchResponse as FetchResponse_2 } from '@backstage/plugin-kubernetes-common'; -import type { JsonObject } from '@backstage/types'; -import type { JsonValue } from '@backstage/types'; -import { ObjectsByEntityResponse as ObjectsByEntityResponse_2 } from '@backstage/plugin-kubernetes-common'; -import { PodStatus } from '@kubernetes/client-node'; -import { V1ConfigMap } from '@kubernetes/client-node'; -import { V1CronJob } from '@kubernetes/client-node'; -import { V1DaemonSet } from '@kubernetes/client-node'; -import { V1Deployment } from '@kubernetes/client-node'; -import { V1Ingress } from '@kubernetes/client-node'; -import { V1Job } from '@kubernetes/client-node'; -import { V1LimitRange } from '@kubernetes/client-node'; -import { V1Pod } from '@kubernetes/client-node'; -import { V1ReplicaSet } from '@kubernetes/client-node'; -import { V1ResourceQuota } from '@kubernetes/client-node'; -import { V1Service } from '@kubernetes/client-node'; -import { V1StatefulSet } from '@kubernetes/client-node'; -import { V2HorizontalPodAutoscaler } from '@kubernetes/client-node'; - -// @public -export const ANNOTATION_KUBERNETES_API_SERVER = 'kubernetes.io/api-server'; - -// @public -export const ANNOTATION_KUBERNETES_API_SERVER_CA = - 'kubernetes.io/api-server-certificate-authority'; - -// @public -export const ANNOTATION_KUBERNETES_AUTH_PROVIDER = - 'kubernetes.io/auth-provider'; - -// @public -export const ANNOTATION_KUBERNETES_AWS_ASSUME_ROLE = - 'kubernetes.io/aws-assume-role'; - -// @public -export const ANNOTATION_KUBERNETES_AWS_CLUSTER_ID = - 'kubernetes.io/x-k8s-aws-id'; - -// @public -export const ANNOTATION_KUBERNETES_AWS_EXTERNAL_ID = - 'kubernetes.io/aws-external-id'; - -// @public -export const ANNOTATION_KUBERNETES_DASHBOARD_APP = - 'kubernetes.io/dashboard-app'; - -// @public -export const ANNOTATION_KUBERNETES_DASHBOARD_PARAMETERS = - 'kubernetes.io/dashboard-parameters'; - -// @public -export const ANNOTATION_KUBERNETES_DASHBOARD_URL = - 'kubernetes.io/dashboard-url'; - -// @public -export const ANNOTATION_KUBERNETES_OIDC_TOKEN_PROVIDER = - 'kubernetes.io/oidc-token-provider'; - -// @public -export const ANNOTATION_KUBERNETES_SKIP_METRICS_LOOKUP = - 'kubernetes.io/skip-metrics-lookup'; - -// @public -export const ANNOTATION_KUBERNETES_SKIP_TLS_VERIFY = - 'kubernetes.io/skip-tls-verify'; - -// @public (undocumented) -export type AuthProviderType = 'google' | 'serviceAccount' | 'aws' | 'azure'; - -// @public (undocumented) -export interface ClientContainerStatus { - // (undocumented) - container: string; - // (undocumented) - cpuUsage: ClientCurrentResourceUsage; - // (undocumented) - memoryUsage: ClientCurrentResourceUsage; -} - -// @public (undocumented) -export interface ClientCurrentResourceUsage { - // (undocumented) - currentUsage: number | string; - // (undocumented) - limitTotal: number | string; - // (undocumented) - requestTotal: number | string; -} - -// @public (undocumented) -export interface ClientPodStatus { - // (undocumented) - containers: ClientContainerStatus[]; - // (undocumented) - cpu: ClientCurrentResourceUsage; - // (undocumented) - memory: ClientCurrentResourceUsage; - // (undocumented) - pod: V1Pod; -} - -// @public (undocumented) -export interface ClusterAttributes { - dashboardApp?: string; - dashboardParameters?: JsonObject; - dashboardUrl?: string; - name: string; - title?: string; -} - -// @public (undocumented) -export interface ClusterObjects { - // (undocumented) - cluster: ClusterAttributes; - // (undocumented) - errors: KubernetesFetchError[]; - // (undocumented) - podMetrics: ClientPodStatus[]; - // (undocumented) - resources: FetchResponse[]; -} - -// @public (undocumented) -export interface ConfigMapFetchResponse { - // (undocumented) - resources: Array; - // (undocumented) - type: 'configmaps'; -} - -// @public (undocumented) -export interface CronJobsFetchResponse { - // (undocumented) - resources: Array; - // (undocumented) - type: 'cronjobs'; -} - -// @public (undocumented) -export interface CustomObjectsByEntityRequest { - // (undocumented) - auth: KubernetesRequestAuth; - // (undocumented) - customResources: CustomResourceMatcher[]; - // (undocumented) - entity: Entity; -} - -// @public (undocumented) -export interface CustomResourceFetchResponse { - // (undocumented) - resources: Array; - // (undocumented) - type: 'customresources'; -} - -// @public (undocumented) -export interface CustomResourceMatcher { - // (undocumented) - apiVersion: string; - // (undocumented) - group: string; - // (undocumented) - plural: string; -} - -// @public (undocumented) -export interface DaemonSetsFetchResponse { - // (undocumented) - resources: Array; - // (undocumented) - type: 'daemonsets'; -} - -// @public (undocumented) -export interface DeploymentFetchResponse { - // (undocumented) - resources: Array; - // (undocumented) - type: 'deployments'; -} - -// @public (undocumented) -export interface DeploymentResources { - // (undocumented) - deployments: V1Deployment[]; - // (undocumented) - horizontalPodAutoscalers: V2HorizontalPodAutoscaler[]; - // (undocumented) - pods: V1Pod[]; - // (undocumented) - replicaSets: V1ReplicaSet[]; -} - -// @public -export interface DetectedError { - // (undocumented) - message: string; - // (undocumented) - occurrenceCount: number; - // (undocumented) - proposedFix?: ProposedFix; - // (undocumented) - severity: ErrorSeverity; - // (undocumented) - sourceRef: ResourceRef; - // (undocumented) - type: string; -} - -// @public -export type DetectedErrorsByCluster = Map; - -// @public -export const detectErrors: ( - objects: ObjectsByEntityResponse_2, -) => DetectedErrorsByCluster; - -// @public (undocumented) -export interface DocsSolution extends ProposedFixBase { - // (undocumented) - docsLink: string; - // (undocumented) - type: 'docs'; -} - -// @public (undocumented) -export interface ErrorMapper { - // (undocumented) - detectErrors: (resource: T) => DetectedError[]; -} - -// @public -export type ErrorSeverity = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10; - -// @public (undocumented) -export interface EventsSolution extends ProposedFixBase { - // (undocumented) - podName: string; - // (undocumented) - type: 'events'; -} - -// @public (undocumented) -export type FetchResponse = - | PodFetchResponse - | ServiceFetchResponse - | ConfigMapFetchResponse - | DeploymentFetchResponse - | LimitRangeFetchResponse - | ResourceQuotaFetchResponse - | ReplicaSetsFetchResponse - | HorizontalPodAutoscalersFetchResponse - | JobsFetchResponse - | CronJobsFetchResponse - | IngressesFetchResponse - | CustomResourceFetchResponse - | StatefulSetsFetchResponse - | DaemonSetsFetchResponse - | PodStatusFetchResponse; - -// @public (undocumented) -export interface GroupedResponses extends DeploymentResources { - // (undocumented) - configMaps: V1ConfigMap[]; - // (undocumented) - cronJobs: V1CronJob[]; - // (undocumented) - customResources: any[]; - // (undocumented) - daemonSets: V1DaemonSet[]; - // (undocumented) - ingresses: V1Ingress[]; - // (undocumented) - jobs: V1Job[]; - // (undocumented) - services: V1Service[]; - // (undocumented) - statefulsets: V1StatefulSet[]; -} - -// @public (undocumented) -export const groupResponses: ( - fetchResponse: FetchResponse_2[], -) => GroupedResponses; - -// @public (undocumented) -export interface HorizontalPodAutoscalersFetchResponse { - // (undocumented) - resources: Array; - // (undocumented) - type: 'horizontalpodautoscalers'; -} - -// @public (undocumented) -export interface IngressesFetchResponse { - // (undocumented) - resources: Array; - // (undocumented) - type: 'ingresses'; -} - -// @public (undocumented) -export interface JobsFetchResponse { - // (undocumented) - resources: Array; - // (undocumented) - type: 'jobs'; -} - -// @public (undocumented) -export type KubernetesErrorTypes = - | 'BAD_REQUEST' - | 'UNAUTHORIZED_ERROR' - | 'NOT_FOUND' - | 'SYSTEM_ERROR' - | 'UNKNOWN_ERROR'; - -// @public (undocumented) -export type KubernetesFetchError = StatusError | RawFetchError; - -// @public -export const kubernetesPermissions: BasicPermission[]; - -// @public -export const kubernetesProxyPermission: BasicPermission; - -// @public (undocumented) -export type KubernetesRequestAuth = { - [providerKey: string]: JsonValue | undefined; -}; - -// @public (undocumented) -export interface KubernetesRequestBody { - // (undocumented) - auth?: KubernetesRequestAuth; - // (undocumented) - entity: Entity; -} - -// @public (undocumented) -export interface LimitRangeFetchResponse { - // (undocumented) - resources: Array; - // (undocumented) - type: 'limitranges'; -} - -// @public (undocumented) -export interface LogSolution extends ProposedFixBase { - // (undocumented) - container: string; - // (undocumented) - type: 'logs'; -} - -// @public (undocumented) -export interface ObjectsByEntityResponse { - // (undocumented) - items: ClusterObjects[]; -} - -// @public (undocumented) -export interface PodFetchResponse { - // (undocumented) - resources: Array; - // (undocumented) - type: 'pods'; -} - -// @public (undocumented) -export interface PodStatusFetchResponse { - // (undocumented) - resources: Array; - // (undocumented) - type: 'podstatus'; -} - -// @public (undocumented) -export type ProposedFix = LogSolution | DocsSolution | EventsSolution; - -// @public (undocumented) -export interface ProposedFixBase { - // (undocumented) - actions: string[]; - // (undocumented) - errorType: string; - // (undocumented) - rootCauseExplanation: string; -} - -// @public (undocumented) -export interface RawFetchError { - // (undocumented) - errorType: 'FETCH_ERROR'; - // (undocumented) - message: string; -} - -// @public (undocumented) -export interface ReplicaSetsFetchResponse { - // (undocumented) - resources: Array; - // (undocumented) - type: 'replicasets'; -} - -// @public (undocumented) -export interface ResourceQuotaFetchResponse { - // (undocumented) - resources: Array; - // (undocumented) - type: 'resourcequotas'; -} - -// @public -export interface ResourceRef { - // (undocumented) - apiGroup: string; - // (undocumented) - kind: string; - // (undocumented) - name: string; - // (undocumented) - namespace: string; -} - -// @public (undocumented) -export interface ServiceFetchResponse { - // (undocumented) - resources: Array; - // (undocumented) - type: 'services'; -} - -// @public (undocumented) -export interface StatefulSetsFetchResponse { - // (undocumented) - resources: Array; - // (undocumented) - type: 'statefulsets'; -} - -// @public (undocumented) -export interface StatusError { - // (undocumented) - errorType: KubernetesErrorTypes; - // (undocumented) - resourcePath?: string; - // (undocumented) - statusCode?: number; -} - -// @public (undocumented) -export interface WorkloadsByEntityRequest { - // (undocumented) - auth: KubernetesRequestAuth; - // (undocumented) - entity: Entity; -} -``` diff --git a/plugins/kubernetes-common/package.json b/plugins/kubernetes-common/package.json index e902879f9f..055890fef1 100644 --- a/plugins/kubernetes-common/package.json +++ b/plugins/kubernetes-common/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-kubernetes-common", - "version": "0.8.2", + "version": "0.8.3", "description": "Common functionalities for kubernetes, to be shared between kubernetes and kubernetes-backend plugin", "backstage": { "role": "common-library", diff --git a/plugins/kubernetes-common/report.api.md b/plugins/kubernetes-common/report.api.md new file mode 100644 index 0000000000..283788cfe5 --- /dev/null +++ b/plugins/kubernetes-common/report.api.md @@ -0,0 +1,604 @@ +## API Report File for "@backstage/plugin-kubernetes-common" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BasicPermission } from '@backstage/plugin-permission-common'; +import { Entity } from '@backstage/catalog-model'; +import { FetchResponse as FetchResponse_2 } from '@backstage/plugin-kubernetes-common'; +import type { JsonObject } from '@backstage/types'; +import type { JsonValue } from '@backstage/types'; +import { ObjectsByEntityResponse as ObjectsByEntityResponse_2 } from '@backstage/plugin-kubernetes-common'; +import { PodStatus } from '@kubernetes/client-node'; +import { V1ConfigMap } from '@kubernetes/client-node'; +import { V1CronJob } from '@kubernetes/client-node'; +import { V1DaemonSet } from '@kubernetes/client-node'; +import { V1Deployment } from '@kubernetes/client-node'; +import { V1Ingress } from '@kubernetes/client-node'; +import { V1Job } from '@kubernetes/client-node'; +import { V1LimitRange } from '@kubernetes/client-node'; +import { V1Pod } from '@kubernetes/client-node'; +import { V1ReplicaSet } from '@kubernetes/client-node'; +import { V1ResourceQuota } from '@kubernetes/client-node'; +import { V1Service } from '@kubernetes/client-node'; +import { V1StatefulSet } from '@kubernetes/client-node'; +import { V2HorizontalPodAutoscaler } from '@kubernetes/client-node'; + +// @public +export const ANNOTATION_KUBERNETES_API_SERVER = 'kubernetes.io/api-server'; + +// @public +export const ANNOTATION_KUBERNETES_API_SERVER_CA = + 'kubernetes.io/api-server-certificate-authority'; + +// @public +export const ANNOTATION_KUBERNETES_AUTH_PROVIDER = + 'kubernetes.io/auth-provider'; + +// @public +export const ANNOTATION_KUBERNETES_AWS_ASSUME_ROLE = + 'kubernetes.io/aws-assume-role'; + +// @public +export const ANNOTATION_KUBERNETES_AWS_CLUSTER_ID = + 'kubernetes.io/x-k8s-aws-id'; + +// @public +export const ANNOTATION_KUBERNETES_AWS_EXTERNAL_ID = + 'kubernetes.io/aws-external-id'; + +// @public +export const ANNOTATION_KUBERNETES_DASHBOARD_APP = + 'kubernetes.io/dashboard-app'; + +// @public +export const ANNOTATION_KUBERNETES_DASHBOARD_PARAMETERS = + 'kubernetes.io/dashboard-parameters'; + +// @public +export const ANNOTATION_KUBERNETES_DASHBOARD_URL = + 'kubernetes.io/dashboard-url'; + +// @public +export const ANNOTATION_KUBERNETES_OIDC_TOKEN_PROVIDER = + 'kubernetes.io/oidc-token-provider'; + +// @public +export const ANNOTATION_KUBERNETES_SKIP_METRICS_LOOKUP = + 'kubernetes.io/skip-metrics-lookup'; + +// @public +export const ANNOTATION_KUBERNETES_SKIP_TLS_VERIFY = + 'kubernetes.io/skip-tls-verify'; + +// @public (undocumented) +export type AuthProviderType = 'google' | 'serviceAccount' | 'aws' | 'azure'; + +// @public (undocumented) +export interface ClientContainerStatus { + // (undocumented) + container: string; + // (undocumented) + cpuUsage: ClientCurrentResourceUsage; + // (undocumented) + memoryUsage: ClientCurrentResourceUsage; +} + +// @public (undocumented) +export interface ClientCurrentResourceUsage { + // (undocumented) + currentUsage: number | string; + // (undocumented) + limitTotal: number | string; + // (undocumented) + requestTotal: number | string; +} + +// @public (undocumented) +export interface ClientPodStatus { + // (undocumented) + containers: ClientContainerStatus[]; + // (undocumented) + cpu: ClientCurrentResourceUsage; + // (undocumented) + memory: ClientCurrentResourceUsage; + // (undocumented) + pod: V1Pod; +} + +// @public (undocumented) +export interface ClusterAttributes { + dashboardApp?: string; + dashboardParameters?: JsonObject; + dashboardUrl?: string; + name: string; + title?: string; +} + +// @public (undocumented) +export interface ClusterObjects { + // (undocumented) + cluster: ClusterAttributes; + // (undocumented) + errors: KubernetesFetchError[]; + // (undocumented) + podMetrics: ClientPodStatus[]; + // (undocumented) + resources: FetchResponse[]; +} + +// @public (undocumented) +export interface ConfigMapFetchResponse { + // (undocumented) + resources: Array; + // (undocumented) + type: 'configmaps'; +} + +// @public (undocumented) +export interface CronJobsFetchResponse { + // (undocumented) + resources: Array; + // (undocumented) + type: 'cronjobs'; +} + +// @public (undocumented) +export interface CustomObjectsByEntityRequest { + // (undocumented) + auth: KubernetesRequestAuth; + // (undocumented) + customResources: CustomResourceMatcher[]; + // (undocumented) + entity: Entity; +} + +// @public (undocumented) +export interface CustomResourceFetchResponse { + // (undocumented) + resources: Array; + // (undocumented) + type: 'customresources'; +} + +// @public (undocumented) +export interface CustomResourceMatcher { + // (undocumented) + apiVersion: string; + // (undocumented) + group: string; + // (undocumented) + plural: string; +} + +// @public (undocumented) +export interface DaemonSetsFetchResponse { + // (undocumented) + resources: Array; + // (undocumented) + type: 'daemonsets'; +} + +// @public (undocumented) +export interface DeploymentFetchResponse { + // (undocumented) + resources: Array; + // (undocumented) + type: 'deployments'; +} + +// @public (undocumented) +export interface DeploymentResources { + // (undocumented) + deployments: V1Deployment[]; + // (undocumented) + horizontalPodAutoscalers: V2HorizontalPodAutoscaler[]; + // (undocumented) + pods: V1Pod[]; + // (undocumented) + replicaSets: V1ReplicaSet[]; +} + +// @public +export interface DetectedError { + // (undocumented) + message: string; + // (undocumented) + occurrenceCount: number; + // (undocumented) + proposedFix?: ProposedFix; + // (undocumented) + severity: ErrorSeverity; + // (undocumented) + sourceRef: ResourceRef; + // (undocumented) + type: string; +} + +// @public +export type DetectedErrorsByCluster = Map; + +// @public +export const detectErrors: ( + objects: ObjectsByEntityResponse_2, +) => DetectedErrorsByCluster; + +// @public (undocumented) +export interface DocsSolution extends ProposedFixBase { + // (undocumented) + docsLink: string; + // (undocumented) + type: 'docs'; +} + +// @public (undocumented) +export interface ErrorMapper { + // (undocumented) + detectErrors: (resource: T) => DetectedError[]; +} + +// @public +export type ErrorSeverity = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10; + +// @public (undocumented) +export interface EventsSolution extends ProposedFixBase { + // (undocumented) + podName: string; + // (undocumented) + type: 'events'; +} + +// @public (undocumented) +export type FetchResponse = + | PodFetchResponse + | ServiceFetchResponse + | ConfigMapFetchResponse + | DeploymentFetchResponse + | LimitRangeFetchResponse + | ResourceQuotaFetchResponse + | ReplicaSetsFetchResponse + | HorizontalPodAutoscalersFetchResponse + | JobsFetchResponse + | CronJobsFetchResponse + | IngressesFetchResponse + | CustomResourceFetchResponse + | StatefulSetsFetchResponse + | DaemonSetsFetchResponse + | PodStatusFetchResponse; + +// @public (undocumented) +export interface GroupedResponses extends DeploymentResources { + // (undocumented) + configMaps: V1ConfigMap[]; + // (undocumented) + cronJobs: V1CronJob[]; + // (undocumented) + customResources: any[]; + // (undocumented) + daemonSets: V1DaemonSet[]; + // (undocumented) + ingresses: V1Ingress[]; + // (undocumented) + jobs: V1Job[]; + // (undocumented) + services: V1Service[]; + // (undocumented) + statefulsets: V1StatefulSet[]; +} + +// @public (undocumented) +export const groupResponses: ( + fetchResponse: FetchResponse_2[], +) => GroupedResponses; + +// @public (undocumented) +export interface HorizontalPodAutoscalersFetchResponse { + // (undocumented) + resources: Array; + // (undocumented) + type: 'horizontalpodautoscalers'; +} + +// @public (undocumented) +export interface IngressesFetchResponse { + // (undocumented) + resources: Array; + // (undocumented) + type: 'ingresses'; +} + +// @public (undocumented) +export interface JobsFetchResponse { + // (undocumented) + resources: Array; + // (undocumented) + type: 'jobs'; +} + +// @public (undocumented) +export type KubernetesErrorTypes = + | 'BAD_REQUEST' + | 'UNAUTHORIZED_ERROR' + | 'NOT_FOUND' + | 'SYSTEM_ERROR' + | 'UNKNOWN_ERROR'; + +// @public (undocumented) +export type KubernetesFetchError = StatusError | RawFetchError; + +// @public +export const kubernetesPermissions: BasicPermission[]; + +// @public +export const kubernetesProxyPermission: BasicPermission; + +// @public (undocumented) +export type KubernetesRequestAuth = { + [providerKey: string]: JsonValue | undefined; +}; + +// @public (undocumented) +export interface KubernetesRequestBody { + // (undocumented) + auth?: KubernetesRequestAuth; + // (undocumented) + entity: Entity; +} + +// @public (undocumented) +export interface LimitRangeFetchResponse { + // (undocumented) + resources: Array; + // (undocumented) + type: 'limitranges'; +} + +// @public (undocumented) +export interface LogSolution extends ProposedFixBase { + // (undocumented) + container: string; + // (undocumented) + type: 'logs'; +} + +// @public (undocumented) +export interface ObjectsByEntityResponse { + // (undocumented) + items: ClusterObjects[]; +} + +// @public (undocumented) +export interface PodFetchResponse { + // (undocumented) + resources: Array; + // (undocumented) + type: 'pods'; +} + +// @public (undocumented) +export interface PodStatusFetchResponse { + // (undocumented) + resources: Array; + // (undocumented) + type: 'podstatus'; +} + +// @public (undocumented) +export type ProposedFix = LogSolution | DocsSolution | EventsSolution; + +// @public (undocumented) +export interface ProposedFixBase { + // (undocumented) + actions: string[]; + // (undocumented) + errorType: string; + // (undocumented) + rootCauseExplanation: string; +} + +// @public (undocumented) +export interface RawFetchError { + // (undocumented) + errorType: 'FETCH_ERROR'; + // (undocumented) + message: string; +} + +// @public (undocumented) +export interface ReplicaSetsFetchResponse { + // (undocumented) + resources: Array; + // (undocumented) + type: 'replicasets'; +} + +// @public (undocumented) +export interface ResourceQuotaFetchResponse { + // (undocumented) + resources: Array; + // (undocumented) + type: 'resourcequotas'; +} + +// @public +export interface ResourceRef { + // (undocumented) + apiGroup: string; + // (undocumented) + kind: string; + // (undocumented) + name: string; + // (undocumented) + namespace: string; +} + +// @public (undocumented) +export interface ServiceFetchResponse { + // (undocumented) + resources: Array; + // (undocumented) + type: 'services'; +} + +// @public (undocumented) +export interface StatefulSetsFetchResponse { + // (undocumented) + resources: Array; + // (undocumented) + type: 'statefulsets'; +} + +// @public (undocumented) +export interface StatusError { + // (undocumented) + errorType: KubernetesErrorTypes; + // (undocumented) + resourcePath?: string; + // (undocumented) + statusCode?: number; +} + +// @public (undocumented) +export interface WorkloadsByEntityRequest { + // (undocumented) + auth: KubernetesRequestAuth; + // (undocumented) + entity: Entity; +} + +// Warnings were encountered during analysis: +// +// src/error-detection/types.d.ts:19:5 - (ae-undocumented) Missing documentation for "name". +// src/error-detection/types.d.ts:20:5 - (ae-undocumented) Missing documentation for "namespace". +// src/error-detection/types.d.ts:21:5 - (ae-undocumented) Missing documentation for "kind". +// src/error-detection/types.d.ts:22:5 - (ae-undocumented) Missing documentation for "apiGroup". +// src/error-detection/types.d.ts:30:5 - (ae-undocumented) Missing documentation for "type". +// src/error-detection/types.d.ts:31:5 - (ae-undocumented) Missing documentation for "severity". +// src/error-detection/types.d.ts:32:5 - (ae-undocumented) Missing documentation for "message". +// src/error-detection/types.d.ts:33:5 - (ae-undocumented) Missing documentation for "proposedFix". +// src/error-detection/types.d.ts:34:5 - (ae-undocumented) Missing documentation for "sourceRef". +// src/error-detection/types.d.ts:35:5 - (ae-undocumented) Missing documentation for "occurrenceCount". +// src/error-detection/types.d.ts:38:1 - (ae-undocumented) Missing documentation for "ProposedFix". +// src/error-detection/types.d.ts:40:1 - (ae-undocumented) Missing documentation for "ProposedFixBase". +// src/error-detection/types.d.ts:41:5 - (ae-undocumented) Missing documentation for "errorType". +// src/error-detection/types.d.ts:42:5 - (ae-undocumented) Missing documentation for "rootCauseExplanation". +// src/error-detection/types.d.ts:43:5 - (ae-undocumented) Missing documentation for "actions". +// src/error-detection/types.d.ts:46:1 - (ae-undocumented) Missing documentation for "LogSolution". +// src/error-detection/types.d.ts:47:5 - (ae-undocumented) Missing documentation for "type". +// src/error-detection/types.d.ts:48:5 - (ae-undocumented) Missing documentation for "container". +// src/error-detection/types.d.ts:51:1 - (ae-undocumented) Missing documentation for "DocsSolution". +// src/error-detection/types.d.ts:52:5 - (ae-undocumented) Missing documentation for "type". +// src/error-detection/types.d.ts:53:5 - (ae-undocumented) Missing documentation for "docsLink". +// src/error-detection/types.d.ts:56:1 - (ae-undocumented) Missing documentation for "EventsSolution". +// src/error-detection/types.d.ts:57:5 - (ae-undocumented) Missing documentation for "type". +// src/error-detection/types.d.ts:58:5 - (ae-undocumented) Missing documentation for "podName". +// src/error-detection/types.d.ts:61:1 - (ae-undocumented) Missing documentation for "ErrorMapper". +// src/error-detection/types.d.ts:62:5 - (ae-undocumented) Missing documentation for "detectErrors". +// src/types.d.ts:5:1 - (ae-undocumented) Missing documentation for "KubernetesRequestAuth". +// src/types.d.ts:9:1 - (ae-undocumented) Missing documentation for "CustomResourceMatcher". +// src/types.d.ts:10:5 - (ae-undocumented) Missing documentation for "group". +// src/types.d.ts:11:5 - (ae-undocumented) Missing documentation for "apiVersion". +// src/types.d.ts:12:5 - (ae-undocumented) Missing documentation for "plural". +// src/types.d.ts:15:1 - (ae-undocumented) Missing documentation for "WorkloadsByEntityRequest". +// src/types.d.ts:16:5 - (ae-undocumented) Missing documentation for "auth". +// src/types.d.ts:17:5 - (ae-undocumented) Missing documentation for "entity". +// src/types.d.ts:20:1 - (ae-undocumented) Missing documentation for "CustomObjectsByEntityRequest". +// src/types.d.ts:21:5 - (ae-undocumented) Missing documentation for "auth". +// src/types.d.ts:22:5 - (ae-undocumented) Missing documentation for "customResources". +// src/types.d.ts:23:5 - (ae-undocumented) Missing documentation for "entity". +// src/types.d.ts:26:1 - (ae-undocumented) Missing documentation for "KubernetesRequestBody". +// src/types.d.ts:27:5 - (ae-undocumented) Missing documentation for "auth". +// src/types.d.ts:28:5 - (ae-undocumented) Missing documentation for "entity". +// src/types.d.ts:31:1 - (ae-undocumented) Missing documentation for "ClusterAttributes". +// src/types.d.ts:73:1 - (ae-undocumented) Missing documentation for "ClusterObjects". +// src/types.d.ts:74:5 - (ae-undocumented) Missing documentation for "cluster". +// src/types.d.ts:75:5 - (ae-undocumented) Missing documentation for "resources". +// src/types.d.ts:76:5 - (ae-undocumented) Missing documentation for "podMetrics". +// src/types.d.ts:77:5 - (ae-undocumented) Missing documentation for "errors". +// src/types.d.ts:80:1 - (ae-undocumented) Missing documentation for "ObjectsByEntityResponse". +// src/types.d.ts:81:5 - (ae-undocumented) Missing documentation for "items". +// src/types.d.ts:84:1 - (ae-undocumented) Missing documentation for "AuthProviderType". +// src/types.d.ts:86:1 - (ae-undocumented) Missing documentation for "FetchResponse". +// src/types.d.ts:88:1 - (ae-undocumented) Missing documentation for "PodFetchResponse". +// src/types.d.ts:89:5 - (ae-undocumented) Missing documentation for "type". +// src/types.d.ts:90:5 - (ae-undocumented) Missing documentation for "resources". +// src/types.d.ts:93:1 - (ae-undocumented) Missing documentation for "ServiceFetchResponse". +// src/types.d.ts:94:5 - (ae-undocumented) Missing documentation for "type". +// src/types.d.ts:95:5 - (ae-undocumented) Missing documentation for "resources". +// src/types.d.ts:98:1 - (ae-undocumented) Missing documentation for "ConfigMapFetchResponse". +// src/types.d.ts:99:5 - (ae-undocumented) Missing documentation for "type". +// src/types.d.ts:100:5 - (ae-undocumented) Missing documentation for "resources". +// src/types.d.ts:103:1 - (ae-undocumented) Missing documentation for "DeploymentFetchResponse". +// src/types.d.ts:104:5 - (ae-undocumented) Missing documentation for "type". +// src/types.d.ts:105:5 - (ae-undocumented) Missing documentation for "resources". +// src/types.d.ts:108:1 - (ae-undocumented) Missing documentation for "ReplicaSetsFetchResponse". +// src/types.d.ts:109:5 - (ae-undocumented) Missing documentation for "type". +// src/types.d.ts:110:5 - (ae-undocumented) Missing documentation for "resources". +// src/types.d.ts:113:1 - (ae-undocumented) Missing documentation for "LimitRangeFetchResponse". +// src/types.d.ts:114:5 - (ae-undocumented) Missing documentation for "type". +// src/types.d.ts:115:5 - (ae-undocumented) Missing documentation for "resources". +// src/types.d.ts:118:1 - (ae-undocumented) Missing documentation for "ResourceQuotaFetchResponse". +// src/types.d.ts:119:5 - (ae-undocumented) Missing documentation for "type". +// src/types.d.ts:120:5 - (ae-undocumented) Missing documentation for "resources". +// src/types.d.ts:123:1 - (ae-undocumented) Missing documentation for "HorizontalPodAutoscalersFetchResponse". +// src/types.d.ts:124:5 - (ae-undocumented) Missing documentation for "type". +// src/types.d.ts:125:5 - (ae-undocumented) Missing documentation for "resources". +// src/types.d.ts:128:1 - (ae-undocumented) Missing documentation for "JobsFetchResponse". +// src/types.d.ts:129:5 - (ae-undocumented) Missing documentation for "type". +// src/types.d.ts:130:5 - (ae-undocumented) Missing documentation for "resources". +// src/types.d.ts:133:1 - (ae-undocumented) Missing documentation for "CronJobsFetchResponse". +// src/types.d.ts:134:5 - (ae-undocumented) Missing documentation for "type". +// src/types.d.ts:135:5 - (ae-undocumented) Missing documentation for "resources". +// src/types.d.ts:138:1 - (ae-undocumented) Missing documentation for "IngressesFetchResponse". +// src/types.d.ts:139:5 - (ae-undocumented) Missing documentation for "type". +// src/types.d.ts:140:5 - (ae-undocumented) Missing documentation for "resources". +// src/types.d.ts:143:1 - (ae-undocumented) Missing documentation for "CustomResourceFetchResponse". +// src/types.d.ts:144:5 - (ae-undocumented) Missing documentation for "type". +// src/types.d.ts:145:5 - (ae-undocumented) Missing documentation for "resources". +// src/types.d.ts:148:1 - (ae-undocumented) Missing documentation for "StatefulSetsFetchResponse". +// src/types.d.ts:149:5 - (ae-undocumented) Missing documentation for "type". +// src/types.d.ts:150:5 - (ae-undocumented) Missing documentation for "resources". +// src/types.d.ts:153:1 - (ae-undocumented) Missing documentation for "DaemonSetsFetchResponse". +// src/types.d.ts:154:5 - (ae-undocumented) Missing documentation for "type". +// src/types.d.ts:155:5 - (ae-undocumented) Missing documentation for "resources". +// src/types.d.ts:158:1 - (ae-undocumented) Missing documentation for "PodStatusFetchResponse". +// src/types.d.ts:159:5 - (ae-undocumented) Missing documentation for "type". +// src/types.d.ts:160:5 - (ae-undocumented) Missing documentation for "resources". +// src/types.d.ts:163:1 - (ae-undocumented) Missing documentation for "KubernetesFetchError". +// src/types.d.ts:165:1 - (ae-undocumented) Missing documentation for "StatusError". +// src/types.d.ts:166:5 - (ae-undocumented) Missing documentation for "errorType". +// src/types.d.ts:167:5 - (ae-undocumented) Missing documentation for "statusCode". +// src/types.d.ts:168:5 - (ae-undocumented) Missing documentation for "resourcePath". +// src/types.d.ts:171:1 - (ae-undocumented) Missing documentation for "RawFetchError". +// src/types.d.ts:172:5 - (ae-undocumented) Missing documentation for "errorType". +// src/types.d.ts:173:5 - (ae-undocumented) Missing documentation for "message". +// src/types.d.ts:176:1 - (ae-undocumented) Missing documentation for "KubernetesErrorTypes". +// src/types.d.ts:178:1 - (ae-undocumented) Missing documentation for "ClientCurrentResourceUsage". +// src/types.d.ts:179:5 - (ae-undocumented) Missing documentation for "currentUsage". +// src/types.d.ts:180:5 - (ae-undocumented) Missing documentation for "requestTotal". +// src/types.d.ts:181:5 - (ae-undocumented) Missing documentation for "limitTotal". +// src/types.d.ts:184:1 - (ae-undocumented) Missing documentation for "ClientContainerStatus". +// src/types.d.ts:185:5 - (ae-undocumented) Missing documentation for "container". +// src/types.d.ts:186:5 - (ae-undocumented) Missing documentation for "cpuUsage". +// src/types.d.ts:187:5 - (ae-undocumented) Missing documentation for "memoryUsage". +// src/types.d.ts:190:1 - (ae-undocumented) Missing documentation for "ClientPodStatus". +// src/types.d.ts:191:5 - (ae-undocumented) Missing documentation for "pod". +// src/types.d.ts:192:5 - (ae-undocumented) Missing documentation for "cpu". +// src/types.d.ts:193:5 - (ae-undocumented) Missing documentation for "memory". +// src/types.d.ts:194:5 - (ae-undocumented) Missing documentation for "containers". +// src/types.d.ts:197:1 - (ae-undocumented) Missing documentation for "DeploymentResources". +// src/types.d.ts:198:5 - (ae-undocumented) Missing documentation for "pods". +// src/types.d.ts:199:5 - (ae-undocumented) Missing documentation for "replicaSets". +// src/types.d.ts:200:5 - (ae-undocumented) Missing documentation for "deployments". +// src/types.d.ts:201:5 - (ae-undocumented) Missing documentation for "horizontalPodAutoscalers". +// src/types.d.ts:204:1 - (ae-undocumented) Missing documentation for "GroupedResponses". +// src/types.d.ts:205:5 - (ae-undocumented) Missing documentation for "services". +// src/types.d.ts:206:5 - (ae-undocumented) Missing documentation for "configMaps". +// src/types.d.ts:207:5 - (ae-undocumented) Missing documentation for "ingresses". +// src/types.d.ts:208:5 - (ae-undocumented) Missing documentation for "jobs". +// src/types.d.ts:209:5 - (ae-undocumented) Missing documentation for "cronJobs". +// src/types.d.ts:210:5 - (ae-undocumented) Missing documentation for "customResources". +// src/types.d.ts:211:5 - (ae-undocumented) Missing documentation for "statefulsets". +// src/types.d.ts:212:5 - (ae-undocumented) Missing documentation for "daemonSets". +// src/util/response.d.ts:4:22 - (ae-undocumented) Missing documentation for "groupResponses". +``` diff --git a/plugins/kubernetes-node/CHANGELOG.md b/plugins/kubernetes-node/CHANGELOG.md index 8259430ff5..f6c7d44738 100644 --- a/plugins/kubernetes-node/CHANGELOG.md +++ b/plugins/kubernetes-node/CHANGELOG.md @@ -1,5 +1,38 @@ # @backstage/plugin-kubernetes-node +## 0.1.20-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.8.3 + +## 0.1.19 + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.8.3 + +## 0.1.19-next.2 + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.8.2 + ## 0.1.19-next.1 ### Patch Changes diff --git a/plugins/kubernetes-node/package.json b/plugins/kubernetes-node/package.json index cc6aa3dd65..57e26a57f0 100644 --- a/plugins/kubernetes-node/package.json +++ b/plugins/kubernetes-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-kubernetes-node", - "version": "0.1.19-next.1", + "version": "0.1.20-next.0", "description": "Node.js library for the kubernetes plugin", "backstage": { "role": "node-library", @@ -48,12 +48,12 @@ }, "devDependencies": { "@backstage/backend-app-api": "workspace:^", - "@backstage/backend-common": "workspace:^", + "@backstage/backend-common": "^0.25.0", "@backstage/backend-defaults": "workspace:^", "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "@backstage/plugin-kubernetes-backend": "workspace:^", "msw": "^1.3.1", - "supertest": "^6.1.3" + "supertest": "^7.0.0" } } diff --git a/plugins/kubernetes-node/api-report.md b/plugins/kubernetes-node/report.api.md similarity index 60% rename from plugins/kubernetes-node/api-report.md rename to plugins/kubernetes-node/report.api.md index f5b210b424..20c7f76b1f 100644 --- a/plugins/kubernetes-node/api-report.md +++ b/plugins/kubernetes-node/report.api.md @@ -282,4 +282,60 @@ export interface ServiceLocatorRequestContext { // (undocumented) objectTypesToFetch: Set; } + +// Warnings were encountered during analysis: +// +// src/auth/PinnipedHelper.d.ts:7:1 - (ae-undocumented) Missing documentation for "PinnipedClientCerts". +// src/auth/PinnipedHelper.d.ts:16:1 - (ae-undocumented) Missing documentation for "PinnipedParameters". +// src/auth/PinnipedHelper.d.ts:31:1 - (ae-undocumented) Missing documentation for "PinnipedHelper". +// src/auth/PinnipedHelper.d.ts:34:5 - (ae-undocumented) Missing documentation for "tokenCredentialRequest". +// src/extensions.d.ts:8:5 - (ae-undocumented) Missing documentation for "addObjectsProvider". +// src/extensions.d.ts:22:5 - (ae-undocumented) Missing documentation for "addClusterSupplier". +// src/extensions.d.ts:36:5 - (ae-undocumented) Missing documentation for "addAuthStrategy". +// src/extensions.d.ts:50:5 - (ae-undocumented) Missing documentation for "addFetcher". +// src/extensions.d.ts:64:5 - (ae-undocumented) Missing documentation for "addServiceLocator". +// src/types/types.d.ts:9:1 - (ae-undocumented) Missing documentation for "KubernetesObjectsProvider". +// src/types/types.d.ts:10:5 - (ae-undocumented) Missing documentation for "getKubernetesObjectsByEntity". +// src/types/types.d.ts:13:5 - (ae-undocumented) Missing documentation for "getCustomResourcesByEntity". +// src/types/types.d.ts:21:1 - (ae-undocumented) Missing documentation for "KubernetesObjectsByEntity". +// src/types/types.d.ts:22:5 - (ae-undocumented) Missing documentation for "entity". +// src/types/types.d.ts:23:5 - (ae-undocumented) Missing documentation for "auth". +// src/types/types.d.ts:29:1 - (ae-undocumented) Missing documentation for "CustomResourcesByEntity". +// src/types/types.d.ts:30:5 - (ae-undocumented) Missing documentation for "customResources". +// src/types/types.d.ts:41:1 - (ae-undocumented) Missing documentation for "ClusterDetails". +// src/types/types.d.ts:50:5 - (ae-undocumented) Missing documentation for "url". +// src/types/types.d.ts:51:5 - (ae-undocumented) Missing documentation for "authMetadata". +// src/types/types.d.ts:52:5 - (ae-undocumented) Missing documentation for "skipTLSVerify". +// src/types/types.d.ts:58:5 - (ae-undocumented) Missing documentation for "caData". +// src/types/types.d.ts:59:5 - (ae-undocumented) Missing documentation for "caFile". +// src/types/types.d.ts:131:1 - (ae-undocumented) Missing documentation for "AuthenticationStrategy". +// src/types/types.d.ts:132:5 - (ae-undocumented) Missing documentation for "getCredential". +// src/types/types.d.ts:133:5 - (ae-undocumented) Missing documentation for "validateCluster". +// src/types/types.d.ts:134:5 - (ae-undocumented) Missing documentation for "presentAuthMetadata". +// src/types/types.d.ts:140:1 - (ae-undocumented) Missing documentation for "KubernetesObjectTypes". +// src/types/types.d.ts:145:1 - (ae-undocumented) Missing documentation for "ObjectToFetch". +// src/types/types.d.ts:146:5 - (ae-undocumented) Missing documentation for "objectType". +// src/types/types.d.ts:147:5 - (ae-undocumented) Missing documentation for "group". +// src/types/types.d.ts:148:5 - (ae-undocumented) Missing documentation for "apiVersion". +// src/types/types.d.ts:149:5 - (ae-undocumented) Missing documentation for "plural". +// src/types/types.d.ts:155:1 - (ae-undocumented) Missing documentation for "CustomResource". +// src/types/types.d.ts:156:5 - (ae-undocumented) Missing documentation for "objectType". +// src/types/types.d.ts:162:1 - (ae-undocumented) Missing documentation for "ObjectFetchParams". +// src/types/types.d.ts:163:5 - (ae-undocumented) Missing documentation for "serviceId". +// src/types/types.d.ts:164:5 - (ae-undocumented) Missing documentation for "clusterDetails". +// src/types/types.d.ts:165:5 - (ae-undocumented) Missing documentation for "credential". +// src/types/types.d.ts:166:5 - (ae-undocumented) Missing documentation for "objectTypesToFetch". +// src/types/types.d.ts:167:5 - (ae-undocumented) Missing documentation for "labelSelector". +// src/types/types.d.ts:168:5 - (ae-undocumented) Missing documentation for "customResources". +// src/types/types.d.ts:169:5 - (ae-undocumented) Missing documentation for "namespace". +// src/types/types.d.ts:175:1 - (ae-undocumented) Missing documentation for "FetchResponseWrapper". +// src/types/types.d.ts:176:5 - (ae-undocumented) Missing documentation for "errors". +// src/types/types.d.ts:177:5 - (ae-undocumented) Missing documentation for "responses". +// src/types/types.d.ts:185:5 - (ae-undocumented) Missing documentation for "fetchObjectsForService". +// src/types/types.d.ts:186:5 - (ae-undocumented) Missing documentation for "fetchPodMetricsByNamespaces". +// src/types/types.d.ts:191:1 - (ae-undocumented) Missing documentation for "ServiceLocatorRequestContext". +// src/types/types.d.ts:192:5 - (ae-undocumented) Missing documentation for "objectTypesToFetch". +// src/types/types.d.ts:193:5 - (ae-undocumented) Missing documentation for "customResources". +// src/types/types.d.ts:194:5 - (ae-undocumented) Missing documentation for "credentials". +// src/types/types.d.ts:201:5 - (ae-undocumented) Missing documentation for "getClustersByEntity". ``` diff --git a/plugins/kubernetes-node/src/index.ts b/plugins/kubernetes-node/src/index.ts index e0f2688ca2..88d5307baf 100644 --- a/plugins/kubernetes-node/src/index.ts +++ b/plugins/kubernetes-node/src/index.ts @@ -23,12 +23,6 @@ // In this package you might for example export functions that // help other plugins or modules interact with your plugin. -/** - * Node.js library for the kubernetes plugin. - * - * @packageDocumentation - */ - export * from './extensions'; export * from './types'; export * from './auth'; diff --git a/plugins/kubernetes-react/CHANGELOG.md b/plugins/kubernetes-react/CHANGELOG.md index 747360d3e4..c42c2a5864 100644 --- a/plugins/kubernetes-react/CHANGELOG.md +++ b/plugins/kubernetes-react/CHANGELOG.md @@ -1,5 +1,57 @@ # @backstage/plugin-kubernetes-react +## 0.4.4-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- 605e0bb: Updated dependency `@kubernetes-models/base` to `^5.0.0`. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/catalog-model@1.7.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.8.3 + +## 0.4.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.8.3 + +## 0.4.3 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/catalog-model@1.7.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.8.3 + +## 0.4.3-next.1 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.8.2 + ## 0.4.3-next.0 ### Patch Changes diff --git a/plugins/kubernetes-react/package.json b/plugins/kubernetes-react/package.json index 8d60446945..910e371d1a 100644 --- a/plugins/kubernetes-react/package.json +++ b/plugins/kubernetes-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-kubernetes-react", - "version": "0.4.3-next.0", + "version": "0.4.4-next.1", "description": "Web library for the kubernetes-react plugin", "backstage": { "role": "web-library", @@ -48,12 +48,11 @@ "@backstage/plugin-kubernetes-common": "workspace:^", "@backstage/types": "workspace:^", "@kubernetes-models/apimachinery": "^1.1.0", - "@kubernetes-models/base": "^4.0.1", + "@kubernetes-models/base": "^5.0.0", "@kubernetes/client-node": "^0.20.0", "@material-ui/core": "^4.9.13", "@material-ui/icons": "^4.11.3", "@material-ui/lab": "^4.0.0-alpha.61", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "cronstrue": "^2.32.0", "js-yaml": "^4.1.0", "kubernetes-models": "^4.3.1", @@ -69,12 +68,24 @@ "@backstage/core-app-api": "workspace:^", "@backstage/test-utils": "workspace:^", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^15.0.0", + "@testing-library/react": "^16.0.0", + "@types/react": "^18.0.0", "jest-websocket-mock": "^2.5.0", - "msw": "^1.3.1" + "msw": "^1.3.1", + "react": "^18.0.2", + "react-dom": "^18.0.2", + "react-router-dom": "^6.3.0" }, "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0" + "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } }, "configSchema": "config.d.ts" } diff --git a/plugins/kubernetes-react/api-report.md b/plugins/kubernetes-react/report.api.md similarity index 51% rename from plugins/kubernetes-react/api-report.md rename to plugins/kubernetes-react/report.api.md index adb75a7d60..9b0080f019 100644 --- a/plugins/kubernetes-react/api-report.md +++ b/plugins/kubernetes-react/report.api.md @@ -865,4 +865,173 @@ export const usePodMetrics: ( clusterName: string, matcher: PodMetricsMatcher, ) => ClientPodStatus | undefined; + +// Warnings were encountered during analysis: +// +// src/api/KubernetesBackendClient.d.ts:6:1 - (ae-undocumented) Missing documentation for "KubernetesBackendClient". +// src/api/KubernetesBackendClient.d.ts:17:5 - (ae-undocumented) Missing documentation for "getCluster". +// src/api/KubernetesBackendClient.d.ts:23:5 - (ae-undocumented) Missing documentation for "getObjectsByEntity". +// src/api/KubernetesBackendClient.d.ts:24:5 - (ae-undocumented) Missing documentation for "getWorkloadsByEntity". +// src/api/KubernetesBackendClient.d.ts:25:5 - (ae-undocumented) Missing documentation for "getCustomObjectsByEntity". +// src/api/KubernetesBackendClient.d.ts:26:5 - (ae-undocumented) Missing documentation for "getClusters". +// src/api/KubernetesBackendClient.d.ts:30:5 - (ae-undocumented) Missing documentation for "proxy". +// src/api/KubernetesClusterLinkFormatter.d.ts:4:1 - (ae-undocumented) Missing documentation for "KubernetesClusterLinkFormatter". +// src/api/KubernetesClusterLinkFormatter.d.ts:11:5 - (ae-undocumented) Missing documentation for "formatClusterLink". +// src/api/KubernetesProxyClient.d.ts:15:5 - (ae-undocumented) Missing documentation for "getEventsByInvolvedObjectName". +// src/api/KubernetesProxyClient.d.ts:20:5 - (ae-undocumented) Missing documentation for "getPodLogs". +// src/api/formatters/AksClusterLinksFormatter.d.ts:3:1 - (ae-undocumented) Missing documentation for "AksClusterLinksFormatter". +// src/api/formatters/AksClusterLinksFormatter.d.ts:4:5 - (ae-undocumented) Missing documentation for "formatClusterLink". +// src/api/formatters/EksClusterLinksFormatter.d.ts:3:1 - (ae-undocumented) Missing documentation for "EksClusterLinksFormatter". +// src/api/formatters/EksClusterLinksFormatter.d.ts:4:5 - (ae-undocumented) Missing documentation for "formatClusterLink". +// src/api/formatters/GkeClusterLinksFormatter.d.ts:4:1 - (ae-undocumented) Missing documentation for "GkeClusterLinksFormatter". +// src/api/formatters/GkeClusterLinksFormatter.d.ts:7:5 - (ae-undocumented) Missing documentation for "formatClusterLink". +// src/api/formatters/OpenshiftClusterLinksFormatter.d.ts:3:1 - (ae-undocumented) Missing documentation for "OpenshiftClusterLinksFormatter". +// src/api/formatters/OpenshiftClusterLinksFormatter.d.ts:4:5 - (ae-undocumented) Missing documentation for "formatClusterLink". +// src/api/formatters/RancherClusterLinksFormatter.d.ts:3:1 - (ae-undocumented) Missing documentation for "RancherClusterLinksFormatter". +// src/api/formatters/RancherClusterLinksFormatter.d.ts:4:5 - (ae-undocumented) Missing documentation for "formatClusterLink". +// src/api/formatters/StandardClusterLinksFormatter.d.ts:3:1 - (ae-undocumented) Missing documentation for "StandardClusterLinksFormatter". +// src/api/formatters/StandardClusterLinksFormatter.d.ts:4:5 - (ae-undocumented) Missing documentation for "formatClusterLink". +// src/api/formatters/index.d.ts:11:22 - (ae-undocumented) Missing documentation for "DEFAULT_FORMATTER_NAME". +// src/api/formatters/index.d.ts:13:1 - (ae-undocumented) Missing documentation for "getDefaultFormatters". +// src/api/types.d.ts:5:22 - (ae-undocumented) Missing documentation for "kubernetesApiRef". +// src/api/types.d.ts:7:22 - (ae-undocumented) Missing documentation for "kubernetesProxyApiRef". +// src/api/types.d.ts:9:22 - (ae-undocumented) Missing documentation for "kubernetesClusterLinkFormatterApiRef". +// src/api/types.d.ts:11:1 - (ae-undocumented) Missing documentation for "KubernetesApi". +// src/api/types.d.ts:12:5 - (ae-undocumented) Missing documentation for "getObjectsByEntity". +// src/api/types.d.ts:13:5 - (ae-undocumented) Missing documentation for "getClusters". +// src/api/types.d.ts:18:5 - (ae-undocumented) Missing documentation for "getCluster". +// src/api/types.d.ts:24:5 - (ae-undocumented) Missing documentation for "getWorkloadsByEntity". +// src/api/types.d.ts:25:5 - (ae-undocumented) Missing documentation for "getCustomObjectsByEntity". +// src/api/types.d.ts:26:5 - (ae-undocumented) Missing documentation for "proxy". +// src/api/types.d.ts:33:1 - (ae-undocumented) Missing documentation for "KubernetesProxyApi". +// src/api/types.d.ts:34:5 - (ae-undocumented) Missing documentation for "getPodLogs". +// src/api/types.d.ts:43:5 - (ae-undocumented) Missing documentation for "getEventsByInvolvedObjectName". +// src/api/types.d.ts:52:1 - (ae-undocumented) Missing documentation for "FormatClusterLinkOptions". +// src/api/types.d.ts:60:1 - (ae-undocumented) Missing documentation for "KubernetesClusterLinkFormatterApi". +// src/api/types.d.ts:61:5 - (ae-undocumented) Missing documentation for "formatClusterLink". +// src/components/CronJobsAccordions/CronJobsAccordions.d.ts:7:1 - (ae-undocumented) Missing documentation for "CronJobsAccordionsProps". +// src/components/CronJobsAccordions/CronJobsAccordions.d.ts:15:22 - (ae-undocumented) Missing documentation for "CronJobsAccordions". +// src/components/CustomResources/CustomResources.d.ts:7:1 - (ae-undocumented) Missing documentation for "CustomResourcesProps". +// src/components/CustomResources/CustomResources.d.ts:8:5 - (ae-undocumented) Missing documentation for "children". +// src/components/CustomResources/CustomResources.d.ts:15:22 - (ae-undocumented) Missing documentation for "CustomResources". +// src/components/ErrorPanel/ErrorPanel.d.ts:8:1 - (ae-undocumented) Missing documentation for "ErrorPanelProps". +// src/components/ErrorPanel/ErrorPanel.d.ts:19:22 - (ae-undocumented) Missing documentation for "ErrorPanel". +// src/components/ErrorReporting/ErrorReporting.d.ts:8:1 - (ae-undocumented) Missing documentation for "ErrorReportingProps". +// src/components/ErrorReporting/ErrorReporting.d.ts:17:22 - (ae-undocumented) Missing documentation for "ErrorReporting". +// src/components/HorizontalPodAutoscalers/HorizontalPodAutoscalerDrawer.d.ts:4:22 - (ae-undocumented) Missing documentation for "HorizontalPodAutoscalerDrawer". +// src/components/IngressesAccordions/IngressesAccordions.d.ts:7:1 - (ae-undocumented) Missing documentation for "IngressesAccordionsProps". +// src/components/IngressesAccordions/IngressesAccordions.d.ts:13:22 - (ae-undocumented) Missing documentation for "IngressesAccordions". +// src/components/JobsAccordions/JobsAccordions.d.ts:8:1 - (ae-undocumented) Missing documentation for "JobsAccordionsProps". +// src/components/JobsAccordions/JobsAccordions.d.ts:17:22 - (ae-undocumented) Missing documentation for "JobsAccordions". +// src/components/KubernetesDrawer/KubernetesDrawer.d.ts:9:5 - (ae-undocumented) Missing documentation for "kind". +// src/components/KubernetesDrawer/KubernetesDrawer.d.ts:10:5 - (ae-undocumented) Missing documentation for "metadata". +// src/components/KubernetesDrawer/KubernetesDrawer.d.ts:18:5 - (ae-undocumented) Missing documentation for "open". +// src/components/KubernetesDrawer/KubernetesDrawer.d.ts:19:5 - (ae-undocumented) Missing documentation for "kubernetesObject". +// src/components/KubernetesDrawer/KubernetesDrawer.d.ts:20:5 - (ae-undocumented) Missing documentation for "label". +// src/components/KubernetesDrawer/KubernetesDrawer.d.ts:21:5 - (ae-undocumented) Missing documentation for "drawerContentsHeader". +// src/components/KubernetesDrawer/KubernetesDrawer.d.ts:22:5 - (ae-undocumented) Missing documentation for "children". +// src/components/KubernetesDrawer/KubernetesStructuredMetadataTableDrawer.d.ts:9:1 - (ae-undocumented) Missing documentation for "LinkErrorPanelProps". +// src/components/KubernetesDrawer/KubernetesStructuredMetadataTableDrawer.d.ts:19:22 - (ae-undocumented) Missing documentation for "LinkErrorPanel". +// src/components/KubernetesDrawer/KubernetesStructuredMetadataTableDrawer.d.ts:25:1 - (ae-undocumented) Missing documentation for "KubernetesDrawerable". +// src/components/KubernetesDrawer/KubernetesStructuredMetadataTableDrawer.d.ts:26:5 - (ae-undocumented) Missing documentation for "metadata". +// src/components/KubernetesDrawer/KubernetesStructuredMetadataTableDrawer.d.ts:32:1 - (ae-undocumented) Missing documentation for "KubernetesStructuredMetadataTableDrawerProps". +// src/components/KubernetesDrawer/KubernetesStructuredMetadataTableDrawer.d.ts:33:5 - (ae-undocumented) Missing documentation for "object". +// src/components/KubernetesDrawer/KubernetesStructuredMetadataTableDrawer.d.ts:34:5 - (ae-undocumented) Missing documentation for "renderObject". +// src/components/KubernetesDrawer/KubernetesStructuredMetadataTableDrawer.d.ts:35:5 - (ae-undocumented) Missing documentation for "buttonVariant". +// src/components/KubernetesDrawer/KubernetesStructuredMetadataTableDrawer.d.ts:36:5 - (ae-undocumented) Missing documentation for "kind". +// src/components/KubernetesDrawer/KubernetesStructuredMetadataTableDrawer.d.ts:37:5 - (ae-undocumented) Missing documentation for "expanded". +// src/components/KubernetesDrawer/KubernetesStructuredMetadataTableDrawer.d.ts:38:5 - (ae-undocumented) Missing documentation for "children". +// src/components/KubernetesDrawer/KubernetesStructuredMetadataTableDrawer.d.ts:44:22 - (ae-undocumented) Missing documentation for "KubernetesStructuredMetadataTableDrawer". +// src/components/KubernetesDrawer/ManifestYaml.d.ts:8:5 - (ae-undocumented) Missing documentation for "object". +// src/components/PodExecTerminal/PodExecTerminal.d.ts:10:5 - (ae-undocumented) Missing documentation for "cluster". +// src/components/PodExecTerminal/PodExecTerminal.d.ts:11:5 - (ae-undocumented) Missing documentation for "containerName". +// src/components/PodExecTerminal/PodExecTerminal.d.ts:12:5 - (ae-undocumented) Missing documentation for "podName". +// src/components/PodExecTerminal/PodExecTerminal.d.ts:13:5 - (ae-undocumented) Missing documentation for "podNamespace". +// src/components/Pods/ErrorList/ErrorList.d.ts:9:5 - (ae-undocumented) Missing documentation for "podAndErrors". +// src/components/Pods/Events/Events.d.ts:9:5 - (ae-undocumented) Missing documentation for "warningEventsOnly". +// src/components/Pods/Events/Events.d.ts:10:5 - (ae-undocumented) Missing documentation for "events". +// src/components/Pods/Events/Events.d.ts:24:5 - (ae-undocumented) Missing documentation for "involvedObjectName". +// src/components/Pods/Events/Events.d.ts:25:5 - (ae-undocumented) Missing documentation for "namespace". +// src/components/Pods/Events/Events.d.ts:26:5 - (ae-undocumented) Missing documentation for "clusterName". +// src/components/Pods/Events/Events.d.ts:27:5 - (ae-undocumented) Missing documentation for "warningEventsOnly". +// src/components/Pods/Events/useEvents.d.ts:7:5 - (ae-undocumented) Missing documentation for "involvedObjectName". +// src/components/Pods/Events/useEvents.d.ts:8:5 - (ae-undocumented) Missing documentation for "namespace". +// src/components/Pods/Events/useEvents.d.ts:9:5 - (ae-undocumented) Missing documentation for "clusterName". +// src/components/Pods/FixDialog/FixDialog.d.ts:10:5 - (ae-undocumented) Missing documentation for "open". +// src/components/Pods/FixDialog/FixDialog.d.ts:11:5 - (ae-undocumented) Missing documentation for "clusterName". +// src/components/Pods/FixDialog/FixDialog.d.ts:12:5 - (ae-undocumented) Missing documentation for "pod". +// src/components/Pods/FixDialog/FixDialog.d.ts:13:5 - (ae-undocumented) Missing documentation for "error". +// src/components/Pods/PodDrawer/ContainerCard.d.ts:11:5 - (ae-undocumented) Missing documentation for "podScope". +// src/components/Pods/PodDrawer/ContainerCard.d.ts:12:5 - (ae-undocumented) Missing documentation for "containerSpec". +// src/components/Pods/PodDrawer/ContainerCard.d.ts:13:5 - (ae-undocumented) Missing documentation for "containerStatus". +// src/components/Pods/PodDrawer/ContainerCard.d.ts:14:5 - (ae-undocumented) Missing documentation for "containerMetrics". +// src/components/Pods/PodDrawer/PendingPodContent.d.ts:9:5 - (ae-undocumented) Missing documentation for "pod". +// src/components/Pods/PodDrawer/PodDrawer.d.ts:9:5 - (ae-undocumented) Missing documentation for "open". +// src/components/Pods/PodDrawer/PodDrawer.d.ts:10:5 - (ae-undocumented) Missing documentation for "podAndErrors". +// src/components/Pods/PodLogs/PodLogs.d.ts:9:5 - (ae-undocumented) Missing documentation for "containerScope". +// src/components/Pods/PodLogs/PodLogs.d.ts:10:5 - (ae-undocumented) Missing documentation for "previous". +// src/components/Pods/PodLogs/PodLogsDialog.d.ts:9:5 - (ae-undocumented) Missing documentation for "containerScope". +// src/components/Pods/PodLogs/types.d.ts:8:5 - (ae-undocumented) Missing documentation for "podName". +// src/components/Pods/PodLogs/types.d.ts:9:5 - (ae-undocumented) Missing documentation for "podNamespace". +// src/components/Pods/PodLogs/types.d.ts:10:5 - (ae-undocumented) Missing documentation for "cluster". +// src/components/Pods/PodLogs/types.d.ts:18:5 - (ae-undocumented) Missing documentation for "containerName". +// src/components/Pods/PodLogs/usePodLogs.d.ts:8:5 - (ae-undocumented) Missing documentation for "containerScope". +// src/components/Pods/PodLogs/usePodLogs.d.ts:9:5 - (ae-undocumented) Missing documentation for "previous". +// src/components/Pods/PodsTable.d.ts:9:22 - (ae-undocumented) Missing documentation for "READY_COLUMNS". +// src/components/Pods/PodsTable.d.ts:15:22 - (ae-undocumented) Missing documentation for "RESOURCE_COLUMNS". +// src/components/Pods/PodsTable.d.ts:21:1 - (ae-undocumented) Missing documentation for "PodColumns". +// src/components/Pods/PodsTable.d.ts:27:1 - (ae-undocumented) Missing documentation for "PodsTablesProps". +// src/components/Pods/PodsTable.d.ts:37:22 - (ae-undocumented) Missing documentation for "PodsTable". +// src/components/Pods/types.d.ts:9:5 - (ae-undocumented) Missing documentation for "cluster". +// src/components/Pods/types.d.ts:10:5 - (ae-undocumented) Missing documentation for "pod". +// src/components/Pods/types.d.ts:11:5 - (ae-undocumented) Missing documentation for "errors". +// src/components/ResourceUtilization/ResourceUtilization.d.ts:8:5 - (ae-undocumented) Missing documentation for "compressed". +// src/components/ResourceUtilization/ResourceUtilization.d.ts:9:5 - (ae-undocumented) Missing documentation for "title". +// src/components/ResourceUtilization/ResourceUtilization.d.ts:10:5 - (ae-undocumented) Missing documentation for "usage". +// src/components/ResourceUtilization/ResourceUtilization.d.ts:11:5 - (ae-undocumented) Missing documentation for "total". +// src/components/ResourceUtilization/ResourceUtilization.d.ts:12:5 - (ae-undocumented) Missing documentation for "totalFormatted". +// src/components/ServicesAccordions/ServicesAccordions.d.ts:7:1 - (ae-undocumented) Missing documentation for "ServicesAccordionsProps". +// src/components/ServicesAccordions/ServicesAccordions.d.ts:13:22 - (ae-undocumented) Missing documentation for "ServicesAccordions". +// src/hooks/Cluster.d.ts:6:22 - (ae-undocumented) Missing documentation for "ClusterContext". +// src/hooks/GroupedResponses.d.ts:8:22 - (ae-undocumented) Missing documentation for "GroupedResponsesContext". +// src/hooks/PodNamesWithErrors.d.ts:5:22 - (ae-undocumented) Missing documentation for "PodNamesWithErrorsContext". +// src/hooks/PodNamesWithMetrics.d.ts:6:22 - (ae-undocumented) Missing documentation for "PodNamesWithMetricsContext". +// src/hooks/useKubernetesObjects.d.ts:7:1 - (ae-undocumented) Missing documentation for "KubernetesObjects". +// src/hooks/useKubernetesObjects.d.ts:8:5 - (ae-undocumented) Missing documentation for "kubernetesObjects". +// src/hooks/useKubernetesObjects.d.ts:9:5 - (ae-undocumented) Missing documentation for "loading". +// src/hooks/useKubernetesObjects.d.ts:10:5 - (ae-undocumented) Missing documentation for "error". +// src/hooks/useKubernetesObjects.d.ts:16:22 - (ae-undocumented) Missing documentation for "useKubernetesObjects". +// src/hooks/useMatchingErrors.d.ts:15:1 - (ae-undocumented) Missing documentation for "ErrorMatcher". +// src/hooks/usePodMetrics.d.ts:13:1 - (ae-undocumented) Missing documentation for "PodMetricsMatcher". +// src/kubernetes-auth-provider/AksKubernetesAuthProvider.d.ts:5:1 - (ae-undocumented) Missing documentation for "AksKubernetesAuthProvider". +// src/kubernetes-auth-provider/AksKubernetesAuthProvider.d.ts:8:5 - (ae-undocumented) Missing documentation for "decorateRequestBodyForAuth". +// src/kubernetes-auth-provider/AksKubernetesAuthProvider.d.ts:9:5 - (ae-undocumented) Missing documentation for "getCredentials". +// src/kubernetes-auth-provider/GoogleKubernetesAuthProvider.d.ts:5:1 - (ae-undocumented) Missing documentation for "GoogleKubernetesAuthProvider". +// src/kubernetes-auth-provider/GoogleKubernetesAuthProvider.d.ts:6:5 - (ae-undocumented) Missing documentation for "authProvider". +// src/kubernetes-auth-provider/GoogleKubernetesAuthProvider.d.ts:8:5 - (ae-undocumented) Missing documentation for "decorateRequestBodyForAuth". +// src/kubernetes-auth-provider/GoogleKubernetesAuthProvider.d.ts:9:5 - (ae-undocumented) Missing documentation for "getCredentials". +// src/kubernetes-auth-provider/KubernetesAuthProviders.d.ts:5:1 - (ae-undocumented) Missing documentation for "KubernetesAuthProviders". +// src/kubernetes-auth-provider/KubernetesAuthProviders.d.ts:14:5 - (ae-undocumented) Missing documentation for "decorateRequestBodyForAuth". +// src/kubernetes-auth-provider/KubernetesAuthProviders.d.ts:15:5 - (ae-undocumented) Missing documentation for "getCredentials". +// src/kubernetes-auth-provider/OidcKubernetesAuthProvider.d.ts:5:1 - (ae-undocumented) Missing documentation for "OidcKubernetesAuthProvider". +// src/kubernetes-auth-provider/OidcKubernetesAuthProvider.d.ts:6:5 - (ae-undocumented) Missing documentation for "providerName". +// src/kubernetes-auth-provider/OidcKubernetesAuthProvider.d.ts:7:5 - (ae-undocumented) Missing documentation for "authProvider". +// src/kubernetes-auth-provider/OidcKubernetesAuthProvider.d.ts:9:5 - (ae-undocumented) Missing documentation for "decorateRequestBodyForAuth". +// src/kubernetes-auth-provider/OidcKubernetesAuthProvider.d.ts:10:5 - (ae-undocumented) Missing documentation for "getCredentials". +// src/kubernetes-auth-provider/ServerSideAuthProvider.d.ts:9:5 - (ae-undocumented) Missing documentation for "decorateRequestBodyForAuth". +// src/kubernetes-auth-provider/ServerSideAuthProvider.d.ts:10:5 - (ae-undocumented) Missing documentation for "getCredentials". +// src/kubernetes-auth-provider/types.d.ts:3:1 - (ae-undocumented) Missing documentation for "KubernetesAuthProvider". +// src/kubernetes-auth-provider/types.d.ts:4:5 - (ae-undocumented) Missing documentation for "decorateRequestBodyForAuth". +// src/kubernetes-auth-provider/types.d.ts:5:5 - (ae-undocumented) Missing documentation for "getCredentials". +// src/kubernetes-auth-provider/types.d.ts:10:22 - (ae-undocumented) Missing documentation for "kubernetesAuthProvidersApiRef". +// src/kubernetes-auth-provider/types.d.ts:12:1 - (ae-undocumented) Missing documentation for "KubernetesAuthProvidersApi". +// src/kubernetes-auth-provider/types.d.ts:13:5 - (ae-undocumented) Missing documentation for "decorateRequestBodyForAuth". +// src/kubernetes-auth-provider/types.d.ts:14:5 - (ae-undocumented) Missing documentation for "getCredentials". +// src/types/types.d.ts:5:1 - (ae-undocumented) Missing documentation for "ClusterLinksFormatterOptions". +// src/types/types.d.ts:6:5 - (ae-undocumented) Missing documentation for "dashboardUrl". +// src/types/types.d.ts:7:5 - (ae-undocumented) Missing documentation for "dashboardParameters". +// src/types/types.d.ts:8:5 - (ae-undocumented) Missing documentation for "object". +// src/types/types.d.ts:9:5 - (ae-undocumented) Missing documentation for "kind". +// src/types/types.d.ts:14:1 - (ae-undocumented) Missing documentation for "ClusterLinksFormatter". +// src/types/types.d.ts:15:5 - (ae-undocumented) Missing documentation for "formatClusterLink". ``` diff --git a/plugins/kubernetes/CHANGELOG.md b/plugins/kubernetes/CHANGELOG.md index 07a229d934..8d073d852e 100644 --- a/plugins/kubernetes/CHANGELOG.md +++ b/plugins/kubernetes/CHANGELOG.md @@ -1,5 +1,67 @@ # @backstage/plugin-kubernetes +## 0.11.16-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- 605e0bb: Updated dependency `@kubernetes-models/base` to `^5.0.0`. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/frontend-plugin-api@0.9.0-next.1 + - @backstage/core-compat-api@0.3.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/plugin-kubernetes-react@0.4.4-next.1 + - @backstage/plugin-catalog-react@1.14.0-next.1 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-kubernetes-common@0.8.3 + +## 0.11.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/core-compat-api@0.3.1-next.0 + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/plugin-catalog-react@1.13.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-kubernetes-common@0.8.3 + - @backstage/plugin-kubernetes-react@0.4.4-next.0 + +## 0.11.14 + +### Patch Changes + +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. +- bfc0f42: Make k8s entity content appear on components & resources only by default in new FE system +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/plugin-catalog-react@1.13.0 + - @backstage/frontend-plugin-api@0.8.0 + - @backstage/core-compat-api@0.3.0 + - @backstage/catalog-model@1.7.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/plugin-kubernetes-react@0.4.3 + - @backstage/plugin-kubernetes-common@0.8.3 + +## 0.11.14-next.2 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/plugin-catalog-react@1.13.0-next.2 + - @backstage/core-compat-api@0.3.0-next.2 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/frontend-plugin-api@0.8.0-next.2 + - @backstage/plugin-kubernetes-react@0.4.3-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/plugin-kubernetes-common@0.8.2 + ## 0.11.14-next.1 ### Patch Changes diff --git a/plugins/kubernetes/package.json b/plugins/kubernetes/package.json index 9020737fbd..4230172199 100644 --- a/plugins/kubernetes/package.json +++ b/plugins/kubernetes/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-kubernetes", - "version": "0.11.14-next.1", + "version": "0.11.16-next.1", "description": "A Backstage plugin that integrates towards Kubernetes", "backstage": { "role": "frontend-plugin", @@ -67,10 +67,9 @@ "@backstage/plugin-kubernetes-common": "workspace:^", "@backstage/plugin-kubernetes-react": "workspace:^", "@kubernetes-models/apimachinery": "^1.1.0", - "@kubernetes-models/base": "^4.0.1", + "@kubernetes-models/base": "^5.0.0", "@kubernetes/client-node": "0.20.0", "@material-ui/core": "^4.12.2", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "cronstrue": "^2.2.0", "js-yaml": "^4.0.0", "kubernetes-models": "^4.1.0", @@ -86,11 +85,21 @@ "@backstage/test-utils": "workspace:^", "@testing-library/dom": "^10.0.0", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^15.0.0" + "@testing-library/react": "^16.0.0", + "@types/react": "^18.0.0", + "react": "^18.0.2", + "react-dom": "^18.0.2", + "react-router-dom": "^6.3.0" }, "peerDependencies": { + "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } } diff --git a/plugins/kubernetes/api-report-alpha.md b/plugins/kubernetes/report-alpha.api.md similarity index 83% rename from plugins/kubernetes/api-report-alpha.md rename to plugins/kubernetes/report-alpha.api.md index 852a5c6c1a..93919acd47 100644 --- a/plugins/kubernetes/api-report-alpha.md +++ b/plugins/kubernetes/report-alpha.api.md @@ -23,7 +23,6 @@ const _default: FrontendPlugin< { 'api:kubernetes': ExtensionDefinition<{ kind: 'api'; - namespace: undefined; name: undefined; config: {}; configInput: {}; @@ -33,10 +32,12 @@ const _default: FrontendPlugin< {} >; inputs: {}; + params: { + factory: AnyApiFactory; + }; }>; 'page:kubernetes': ExtensionDefinition<{ kind: 'page'; - namespace: undefined; name: undefined; config: { path: string | undefined; @@ -55,10 +56,14 @@ const _default: FrontendPlugin< } >; inputs: {}; + params: { + defaultPath: string; + loader: () => Promise; + routeRef?: RouteRef | undefined; + }; }>; 'entity-content:kubernetes/kubernetes': ExtensionDefinition<{ kind: 'entity-content'; - namespace: undefined; name: 'kubernetes'; config: { path: string | undefined; @@ -100,10 +105,16 @@ const _default: FrontendPlugin< } >; inputs: {}; + params: { + loader: () => Promise; + defaultPath: string; + defaultTitle: string; + routeRef?: RouteRef | undefined; + filter?: string | ((entity: Entity) => boolean) | undefined; + }; }>; 'api:kubernetes/proxy': ExtensionDefinition<{ kind: 'api'; - namespace: undefined; name: 'proxy'; config: {}; configInput: {}; @@ -113,10 +124,12 @@ const _default: FrontendPlugin< {} >; inputs: {}; + params: { + factory: AnyApiFactory; + }; }>; 'api:kubernetes/auth-providers': ExtensionDefinition<{ kind: 'api'; - namespace: undefined; name: 'auth-providers'; config: {}; configInput: {}; @@ -126,10 +139,12 @@ const _default: FrontendPlugin< {} >; inputs: {}; + params: { + factory: AnyApiFactory; + }; }>; 'api:kubernetes/cluster-link-formatter': ExtensionDefinition<{ kind: 'api'; - namespace: undefined; name: 'cluster-link-formatter'; config: {}; configInput: {}; @@ -139,10 +154,17 @@ const _default: FrontendPlugin< {} >; inputs: {}; + params: { + factory: AnyApiFactory; + }; }>; } >; export default _default; +// Warnings were encountered during analysis: +// +// src/alpha/plugin.d.ts:2:15 - (ae-undocumented) Missing documentation for "_default". + // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/kubernetes/api-report.md b/plugins/kubernetes/report.api.md similarity index 80% rename from plugins/kubernetes/api-report.md rename to plugins/kubernetes/report.api.md index 64b56cf786..e5038b674a 100644 --- a/plugins/kubernetes/api-report.md +++ b/plugins/kubernetes/report.api.md @@ -47,4 +47,11 @@ export const Router: (props: { }) => React_2.JSX.Element; export * from '@backstage/plugin-kubernetes-react'; + +// Warnings were encountered during analysis: +// +// src/Router.d.ts:3:22 - (ae-undocumented) Missing documentation for "isKubernetesAvailable". +// src/Router.d.ts:4:22 - (ae-undocumented) Missing documentation for "Router". +// src/plugin.d.ts:3:22 - (ae-undocumented) Missing documentation for "kubernetesPlugin". +// src/plugin.d.ts:17:22 - (ae-undocumented) Missing documentation for "EntityKubernetesContent". ``` diff --git a/plugins/notifications-backend-module-email/CHANGELOG.md b/plugins/notifications-backend-module-email/CHANGELOG.md index 113c7b06b4..74d452e9d6 100644 --- a/plugins/notifications-backend-module-email/CHANGELOG.md +++ b/plugins/notifications-backend-module-email/CHANGELOG.md @@ -1,5 +1,62 @@ # @backstage/plugin-notifications-backend-module-email +## 0.3.1-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-notifications-node@0.2.7-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-notifications-common@0.0.5 + +## 0.3.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- 5edd344: Refactor to use injected catalog client in the new backend system +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/catalog-client@1.7.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.6 + +## 0.3.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-client@1.7.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.12.7-next.2 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.6-next.2 + ## 0.3.0-next.1 ### Patch Changes diff --git a/plugins/notifications-backend-module-email/package.json b/plugins/notifications-backend-module-email/package.json index 9b910b0041..af4160ea52 100644 --- a/plugins/notifications-backend-module-email/package.json +++ b/plugins/notifications-backend-module-email/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-notifications-backend-module-email", - "version": "0.3.0-next.1", + "version": "0.3.1-next.0", "description": "The email backend module for the notifications plugin.", "backstage": { "role": "backend-plugin-module", @@ -36,7 +36,7 @@ "dependencies": { "@aws-sdk/client-ses": "^3.550.0", "@aws-sdk/types": "^3.347.0", - "@backstage/backend-common": "workspace:^", + "@backstage/backend-common": "^0.25.0", "@backstage/backend-plugin-api": "workspace:^", "@backstage/catalog-client": "workspace:^", "@backstage/catalog-model": "workspace:^", diff --git a/plugins/notifications-backend-module-email/api-report.md b/plugins/notifications-backend-module-email/report.api.md similarity index 57% rename from plugins/notifications-backend-module-email/api-report.md rename to plugins/notifications-backend-module-email/report.api.md index be3b58d1fd..2116bd4ef4 100644 --- a/plugins/notifications-backend-module-email/api-report.md +++ b/plugins/notifications-backend-module-email/report.api.md @@ -29,4 +29,15 @@ export interface NotificationTemplateRenderer { // (undocumented) getText?(notification: Notification_2): Promise; } + +// Warnings were encountered during analysis: +// +// src/extensions.d.ts:5:1 - (ae-undocumented) Missing documentation for "NotificationTemplateRenderer". +// src/extensions.d.ts:6:5 - (ae-undocumented) Missing documentation for "getSubject". +// src/extensions.d.ts:7:5 - (ae-undocumented) Missing documentation for "getText". +// src/extensions.d.ts:8:5 - (ae-undocumented) Missing documentation for "getHtml". +// src/extensions.d.ts:13:1 - (ae-undocumented) Missing documentation for "NotificationsEmailTemplateExtensionPoint". +// src/extensions.d.ts:14:5 - (ae-undocumented) Missing documentation for "setTemplateRenderer". +// src/extensions.d.ts:19:22 - (ae-undocumented) Missing documentation for "notificationsEmailTemplateExtensionPoint". +// src/module.d.ts:4:22 - (ae-undocumented) Missing documentation for "notificationsModuleEmail". ``` diff --git a/plugins/notifications-backend-module-email/src/processor/NotificationsEmailProcessor.test.ts b/plugins/notifications-backend-module-email/src/processor/NotificationsEmailProcessor.test.ts index 79d1110968..84728dafbf 100644 --- a/plugins/notifications-backend-module-email/src/processor/NotificationsEmailProcessor.test.ts +++ b/plugins/notifications-backend-module-email/src/processor/NotificationsEmailProcessor.test.ts @@ -18,8 +18,9 @@ import { mockServices } from '@backstage/backend-test-utils'; import { NotificationsEmailProcessor } from './NotificationsEmailProcessor'; import { ConfigReader } from '@backstage/config'; import { JsonArray } from '@backstage/types'; -import { CatalogClient } from '@backstage/catalog-client'; import { createTransport } from 'nodemailer'; +import { catalogServiceMock } from '@backstage/plugin-catalog-node/testUtils'; +import { Entity } from '@backstage/catalog-model'; const sendmailMock = jest.fn(); const mockTransport = { @@ -39,7 +40,7 @@ const DEFAULT_ENTITIES_RESPONSE = { email: 'mock@backstage.io', }, }, - }, + } as unknown as Entity, ], }; @@ -63,13 +64,7 @@ const DEFAULT_SENDMAIL_CONFIG = { describe('NotificationsEmailProcessor', () => { const logger = mockServices.logger.mock(); const auth = mockServices.auth(); - - const getEntityRefMock = jest.fn(); - const getEntitiesMock = jest.fn(); - const mockCatalogClient: Partial = { - getEntityByRef: getEntityRefMock, - getEntities: getEntitiesMock, - }; + const catalog = catalogServiceMock.mock(); beforeEach(() => { jest.resetAllMocks(); @@ -98,7 +93,7 @@ describe('NotificationsEmailProcessor', () => { }, }, }), - mockCatalogClient as unknown as CatalogClient, + catalog, auth, ); @@ -145,7 +140,7 @@ describe('NotificationsEmailProcessor', () => { }, }, }), - mockCatalogClient as unknown as CatalogClient, + catalog, auth, ); @@ -189,7 +184,7 @@ describe('NotificationsEmailProcessor', () => { }, }, }), - mockCatalogClient as unknown as CatalogClient, + catalog, auth, ); @@ -217,11 +212,13 @@ describe('NotificationsEmailProcessor', () => { it('should send user email', async () => { (createTransport as jest.Mock).mockReturnValue(mockTransport); - getEntityRefMock.mockResolvedValue(DEFAULT_ENTITIES_RESPONSE.items[0]); + catalog.getEntityByRef.mockResolvedValue( + DEFAULT_ENTITIES_RESPONSE.items[0], + ); const processor = new NotificationsEmailProcessor( logger, mockServices.rootConfig({ data: DEFAULT_SENDMAIL_CONFIG }), - mockCatalogClient as unknown as CatalogClient, + catalog, auth, ); @@ -251,7 +248,7 @@ describe('NotificationsEmailProcessor', () => { it('should send email to all', async () => { (createTransport as jest.Mock).mockReturnValue(mockTransport); - getEntitiesMock.mockResolvedValue(DEFAULT_ENTITIES_RESPONSE); + catalog.getEntities.mockResolvedValue(DEFAULT_ENTITIES_RESPONSE); const processor = new NotificationsEmailProcessor( logger, mockServices.rootConfig({ @@ -269,7 +266,7 @@ describe('NotificationsEmailProcessor', () => { }, }, }), - mockCatalogClient as unknown as CatalogClient, + catalog, auth, ); @@ -299,7 +296,7 @@ describe('NotificationsEmailProcessor', () => { it('should send email to configured addresses', async () => { (createTransport as jest.Mock).mockReturnValue(mockTransport); - getEntitiesMock.mockResolvedValue(DEFAULT_ENTITIES_RESPONSE); + catalog.getEntities.mockResolvedValue(DEFAULT_ENTITIES_RESPONSE); const processor = new NotificationsEmailProcessor( logger, mockServices.rootConfig({ @@ -318,7 +315,7 @@ describe('NotificationsEmailProcessor', () => { }, }, }), - mockCatalogClient as unknown as CatalogClient, + catalog, auth, ); @@ -348,13 +345,15 @@ describe('NotificationsEmailProcessor', () => { it('should send email with relative link to given address', async () => { (createTransport as jest.Mock).mockReturnValue(mockTransport); - getEntityRefMock.mockResolvedValue(DEFAULT_ENTITIES_RESPONSE.items[0]); + catalog.getEntityByRef.mockResolvedValue( + DEFAULT_ENTITIES_RESPONSE.items[0], + ); const processor = new NotificationsEmailProcessor( logger, mockServices.rootConfig({ data: DEFAULT_SENDMAIL_CONFIG, }), - mockCatalogClient as unknown as CatalogClient, + catalog, auth, ); @@ -413,13 +412,15 @@ describe('NotificationsEmailProcessor', () => { it('should send email with absolute link to given address', async () => { (createTransport as jest.Mock).mockReturnValue(mockTransport); - getEntityRefMock.mockResolvedValue(DEFAULT_ENTITIES_RESPONSE.items[0]); + catalog.getEntityByRef.mockResolvedValue( + DEFAULT_ENTITIES_RESPONSE.items[0], + ); const processor = new NotificationsEmailProcessor( logger, mockServices.rootConfig({ data: DEFAULT_SENDMAIL_CONFIG, }), - mockCatalogClient as unknown as CatalogClient, + catalog, auth, ); diff --git a/plugins/notifications-backend/CHANGELOG.md b/plugins/notifications-backend/CHANGELOG.md index b74489313d..84b0bc716f 100644 --- a/plugins/notifications-backend/CHANGELOG.md +++ b/plugins/notifications-backend/CHANGELOG.md @@ -1,5 +1,74 @@ # @backstage/plugin-notifications-backend +## 0.4.1-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-notifications-node@0.2.7-next.0 + - @backstage/plugin-signals-node@0.1.12-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-notifications-common@0.0.5 + +## 0.4.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- 1c6f142: Internal refactor to avoid use of insecure coding patterns. +- 4a53dd0: Implement icon in backend and show icon in table if available. +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- f195972: Validate notification link when new notification is created +- 5edd344: Refactor to use injected catalog client in the new backend system +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/plugin-signals-node@0.1.11 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/catalog-model@1.7.0 + - @backstage/catalog-client@1.7.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/plugin-events-node@0.4.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.6 + +## 0.4.0-next.2 + +### Patch Changes + +- 4a53dd0: Implement icon in backend and show icon in table if available. +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-client@1.7.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.12.7-next.2 + - @backstage/plugin-events-node@0.4.0-next.2 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.6-next.2 + - @backstage/plugin-signals-node@0.1.11-next.2 + ## 0.4.0-next.1 ### Patch Changes diff --git a/plugins/notifications-backend/migrations/20240902_addIcon.js b/plugins/notifications-backend/migrations/20240902_addIcon.js new file mode 100644 index 0000000000..a5327f8d73 --- /dev/null +++ b/plugins/notifications-backend/migrations/20240902_addIcon.js @@ -0,0 +1,33 @@ +/* + * 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. + */ + +exports.up = async function up(knex) { + await knex.schema.alterTable('notification', table => { + table.string('icon', 255).nullable(); + }); + await knex.schema.alterTable('broadcast', table => { + table.string('icon', 255).nullable(); + }); +}; + +exports.down = async function down(knex) { + await knex.schema.alterTable('notification', table => { + table.dropColumn('icon'); + }); + await knex.schema.alterTable('broadcast', table => { + table.dropColumn('icon'); + }); +}; diff --git a/plugins/notifications-backend/package.json b/plugins/notifications-backend/package.json index d91f0f7aea..9c441f237b 100644 --- a/plugins/notifications-backend/package.json +++ b/plugins/notifications-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-notifications-backend", - "version": "0.4.0-next.1", + "version": "0.4.1-next.0", "backstage": { "role": "backend-plugin", "pluginId": "notifications", @@ -38,7 +38,7 @@ "test": "backstage-cli package test" }, "dependencies": { - "@backstage/backend-common": "workspace:^", + "@backstage/backend-common": "^0.25.0", "@backstage/backend-plugin-api": "workspace:^", "@backstage/catalog-client": "workspace:^", "@backstage/catalog-model": "workspace:^", @@ -69,6 +69,6 @@ "@types/express": "^4.17.6", "@types/supertest": "^2.0.8", "msw": "^1.0.0", - "supertest": "^6.2.4" + "supertest": "^7.0.0" } } diff --git a/plugins/notifications-backend/api-report.md b/plugins/notifications-backend/report.api.md similarity index 100% rename from plugins/notifications-backend/api-report.md rename to plugins/notifications-backend/report.api.md diff --git a/plugins/notifications-backend/src/database/DatabaseNotificationsStore.test.ts b/plugins/notifications-backend/src/database/DatabaseNotificationsStore.test.ts index d4e678c8f1..0c7193c1fc 100644 --- a/plugins/notifications-backend/src/database/DatabaseNotificationsStore.test.ts +++ b/plugins/notifications-backend/src/database/DatabaseNotificationsStore.test.ts @@ -68,6 +68,7 @@ const testNotification1: Notification = { topic: 'efgh-topic', link: '/catalog', severity: 'critical', + icon: 'docs', }, }; const testNotification2: Notification = { @@ -183,6 +184,7 @@ describe.each(databases.eachSupportedId())( expect(notification?.payload?.topic).toBe('efgh-topic'); expect(notification?.payload?.link).toBe('/catalog'); expect(notification?.payload?.severity).toBe('critical'); + expect(notification?.payload?.icon).toBe('docs'); }); }); diff --git a/plugins/notifications-backend/src/database/DatabaseNotificationsStore.ts b/plugins/notifications-backend/src/database/DatabaseNotificationsStore.ts index b23f5254f4..40a76c7486 100644 --- a/plugins/notifications-backend/src/database/DatabaseNotificationsStore.ts +++ b/plugins/notifications-backend/src/database/DatabaseNotificationsStore.ts @@ -41,6 +41,7 @@ const NOTIFICATION_COLUMNS = [ 'origin', 'scope', 'topic', + 'icon', 'created', 'updated', 'user', @@ -119,6 +120,7 @@ export class DatabaseNotificationsStore implements NotificationsStore { description: notification.payload?.description, severity: normalizeSeverity(notification.payload?.severity), scope: notification.payload?.scope, + icon: notification.payload.icon, saved: notification.saved, read: notification.read, }; @@ -134,6 +136,7 @@ export class DatabaseNotificationsStore implements NotificationsStore { title: notification.payload?.title, description: notification.payload?.description, severity: normalizeSeverity(notification.payload?.severity), + icon: notification.payload.icon, scope: notification.payload?.scope, }; }; diff --git a/plugins/notifications-backend/src/service/getUsersForEntityRef.test.ts b/plugins/notifications-backend/src/service/getUsersForEntityRef.test.ts index b06d6f203b..a5ce5d3ff8 100644 --- a/plugins/notifications-backend/src/service/getUsersForEntityRef.test.ts +++ b/plugins/notifications-backend/src/service/getUsersForEntityRef.test.ts @@ -13,44 +13,40 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { mockServices } from '@backstage/backend-test-utils'; import { getUsersForEntityRef } from './getUsersForEntityRef'; -import { CatalogApi } from '@backstage/catalog-client'; import { RELATION_HAS_MEMBER, RELATION_OWNED_BY, RELATION_PARENT_OF, } from '@backstage/catalog-model'; +import { catalogServiceMock } from '@backstage/plugin-catalog-node/testUtils'; describe('getUsersForEntityRef', () => { - const catalogApiMock = { - getEntitiesByRefs: jest.fn(), - getEntityByRef: jest.fn(), - }; - const authMock = mockServices.auth(); - it('should return empty array if entityRef is null', async () => { await expect( getUsersForEntityRef(null, [], { - auth: authMock, - catalogClient: catalogApiMock as unknown as CatalogApi, + auth: mockServices.auth(), + catalogClient: catalogServiceMock.mock(), }), ).resolves.toEqual([]); }); it('should resolve users without calling catalog', async () => { + const catalogClient = catalogServiceMock.mock(); await expect( getUsersForEntityRef(['user:foo', 'user:ignored'], ['user:ignored'], { - auth: authMock, - catalogClient: catalogApiMock as unknown as CatalogApi, + auth: mockServices.auth(), + catalogClient, }), ).resolves.toEqual(['user:foo']); - expect(catalogApiMock.getEntitiesByRefs).not.toHaveBeenCalled(); + expect(catalogClient.getEntitiesByRefs).not.toHaveBeenCalled(); }); it('should resolve group entities to users', async () => { - catalogApiMock.getEntitiesByRefs.mockResolvedValueOnce({ - items: [ + const catalogClient = catalogServiceMock({ + entities: [ { apiVersion: 'backstage.io/v1alpha1', kind: 'Group', @@ -68,11 +64,6 @@ describe('getUsersForEntityRef', () => { }, ], }, - ], - }); - - catalogApiMock.getEntitiesByRefs.mockResolvedValueOnce({ - items: [ { apiVersion: 'backstage.io/v1alpha1', kind: 'Group', @@ -98,16 +89,16 @@ describe('getUsersForEntityRef', () => { 'group:default/parent_group', ['user:default/ignored'], { - auth: authMock, - catalogClient: catalogApiMock as unknown as CatalogApi, + auth: mockServices.auth(), + catalogClient, }, ), ).resolves.toEqual(['user:default/foo', 'user:default/bar']); }); it('should resolve user owner of entity from entity ref', async () => { - catalogApiMock.getEntitiesByRefs.mockResolvedValueOnce({ - items: [ + const catalogClient = catalogServiceMock({ + entities: [ { apiVersion: 'backstage.io/v1alpha1', kind: 'Component', @@ -126,15 +117,15 @@ describe('getUsersForEntityRef', () => { await expect( getUsersForEntityRef('component:default/test_component', [], { - auth: authMock, - catalogClient: catalogApiMock as unknown as CatalogApi, + auth: mockServices.auth(), + catalogClient, }), ).resolves.toEqual(['user:default/foo']); }); it('should resolve group owner of entity from entity ref', async () => { - catalogApiMock.getEntitiesByRefs.mockResolvedValueOnce({ - items: [ + const catalogClient = catalogServiceMock({ + entities: [ { apiVersion: 'backstage.io/v1alpha1', kind: 'Component', @@ -148,27 +139,26 @@ describe('getUsersForEntityRef', () => { }, ], }, - ], - }); - - catalogApiMock.getEntityByRef.mockResolvedValueOnce({ - apiVersion: 'backstage.io/v1alpha1', - kind: 'Group', - metadata: { - name: 'owner_group', - }, - relations: [ { - type: RELATION_HAS_MEMBER, - targetRef: 'user:default/foo', + apiVersion: 'backstage.io/v1alpha1', + kind: 'Group', + metadata: { + name: 'owner_group', + }, + relations: [ + { + type: RELATION_HAS_MEMBER, + targetRef: 'user:default/foo', + }, + ], }, ], }); await expect( getUsersForEntityRef('component:default/test_component', [], { - auth: authMock, - catalogClient: catalogApiMock as unknown as CatalogApi, + auth: mockServices.auth(), + catalogClient, }), ).resolves.toEqual(['user:default/foo']); }); diff --git a/plugins/notifications-backend/src/service/router.test.ts b/plugins/notifications-backend/src/service/router.test.ts index b90ebcaf50..5b7a1bb7a0 100644 --- a/plugins/notifications-backend/src/service/router.test.ts +++ b/plugins/notifications-backend/src/service/router.test.ts @@ -20,13 +20,12 @@ import { } from '@backstage/backend-common'; import express from 'express'; import request from 'supertest'; - import { createRouter } from './router'; import { ConfigReader } from '@backstage/config'; import { SignalsService } from '@backstage/plugin-signals-node'; import { mockCredentials, mockServices } from '@backstage/backend-test-utils'; import { NotificationSendOptions } from '@backstage/plugin-notifications-node'; -import { CatalogClient } from '@backstage/catalog-client'; +import { catalogServiceMock } from '@backstage/plugin-catalog-node/testUtils'; function createDatabase(): PluginDatabaseManager { return DatabaseManager.fromConfig( @@ -56,9 +55,7 @@ describe('createRouter', () => { const config = mockServices.rootConfig({ data: { app: { baseUrl: 'http://localhost' } }, }); - const catalog = new CatalogClient({ - discoveryApi: mockServices.discovery.mock(), - }); + const catalog = catalogServiceMock.mock(); beforeAll(async () => { const router = await createRouter({ diff --git a/plugins/notifications-backend/src/service/router.ts b/plugins/notifications-backend/src/service/router.ts index fb5aacb5f4..912651ab34 100644 --- a/plugins/notifications-backend/src/service/router.ts +++ b/plugins/notifications-backend/src/service/router.ts @@ -28,7 +28,7 @@ import { NotificationProcessor, NotificationSendOptions, } from '@backstage/plugin-notifications-node'; -import { InputError } from '@backstage/errors'; +import { InputError, NotFoundError } from '@backstage/errors'; import { AuthService, HttpAuthService, @@ -249,7 +249,7 @@ export async function createRouter( store.getNotifications(opts), store.getNotificationsCount(opts), ]); - res.send({ + res.json({ totalCount, notifications, }); @@ -258,7 +258,7 @@ export async function createRouter( router.get('/status', async (req: Request, res) => { const user = await getUser(req); const status = await store.getStatus({ user }); - res.send(status); + res.json(status); }); // Make sure this is the last "GET" handler @@ -271,10 +271,9 @@ export async function createRouter( }; const notifications = await store.getNotifications(opts); if (notifications.length !== 1) { - res.status(404).send({ error: 'Not found' }); - return; + throw new NotFoundError('Not found'); } - res.send(notifications[0]); + res.json(notifications[0]); }); router.post('/update', async (req, res) => { @@ -313,7 +312,7 @@ export async function createRouter( } const notifications = await store.getNotifications({ ids, user: user }); - res.status(200).send(notifications); + res.json(notifications); }); const sendBroadcastNotification = async ( diff --git a/plugins/notifications-common/api-report.md b/plugins/notifications-common/report.api.md similarity index 64% rename from plugins/notifications-common/api-report.md rename to plugins/notifications-common/report.api.md index 0f59a85849..a02bfb2eaa 100644 --- a/plugins/notifications-common/api-report.md +++ b/plugins/notifications-common/report.api.md @@ -67,4 +67,16 @@ export type NotificationStatus = { unread: number; read: number; }; + +// Warnings were encountered during analysis: +// +// src/filters.d.ts:4:22 - (ae-undocumented) Missing documentation for "getProcessorFiltersFromConfig". +// src/types.d.ts:2:1 - (ae-undocumented) Missing documentation for "NotificationSeverity". +// src/types.d.ts:4:1 - (ae-undocumented) Missing documentation for "NotificationPayload". +// src/types.d.ts:36:1 - (ae-undocumented) Missing documentation for "Notification". +// src/types.d.ts:73:1 - (ae-undocumented) Missing documentation for "NotificationStatus". +// src/types.d.ts:84:1 - (ae-undocumented) Missing documentation for "NewNotificationSignal". +// src/types.d.ts:89:1 - (ae-undocumented) Missing documentation for "NotificationReadSignal". +// src/types.d.ts:94:1 - (ae-undocumented) Missing documentation for "NotificationSignal". +// src/types.d.ts:98:1 - (ae-undocumented) Missing documentation for "NotificationProcessorFilters". ``` diff --git a/plugins/notifications-node/CHANGELOG.md b/plugins/notifications-node/CHANGELOG.md index 7066316a04..da05f50026 100644 --- a/plugins/notifications-node/CHANGELOG.md +++ b/plugins/notifications-node/CHANGELOG.md @@ -1,5 +1,41 @@ # @backstage/plugin-notifications-node +## 0.2.7-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-signals-node@0.1.12-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/plugin-notifications-common@0.0.5 + +## 0.2.6 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/plugin-signals-node@0.1.11 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/catalog-client@1.7.0 + - @backstage/plugin-notifications-common@0.0.5 + +## 0.2.6-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-client@1.7.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-signals-node@0.1.11-next.2 + ## 0.2.6-next.1 ### Patch Changes diff --git a/plugins/notifications-node/package.json b/plugins/notifications-node/package.json index 09008239ae..3c221654bb 100644 --- a/plugins/notifications-node/package.json +++ b/plugins/notifications-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-notifications-node", - "version": "0.2.6-next.1", + "version": "0.2.7-next.0", "description": "Node.js library for the notifications plugin", "backstage": { "role": "node-library", @@ -37,7 +37,7 @@ "test": "backstage-cli package test" }, "dependencies": { - "@backstage/backend-common": "workspace:^", + "@backstage/backend-common": "^0.25.0", "@backstage/backend-plugin-api": "workspace:^", "@backstage/catalog-client": "workspace:^", "@backstage/catalog-model": "workspace:^", diff --git a/plugins/notifications-node/api-report.md b/plugins/notifications-node/report.api.md similarity index 64% rename from plugins/notifications-node/api-report.md rename to plugins/notifications-node/report.api.md index 995b98bc21..869bf6c6bb 100644 --- a/plugins/notifications-node/api-report.md +++ b/plugins/notifications-node/report.api.md @@ -87,4 +87,20 @@ export interface NotificationsProcessingExtensionPoint { // @public (undocumented) export const notificationsProcessingExtensionPoint: ExtensionPoint; + +// Warnings were encountered during analysis: +// +// src/extensions.d.ts:73:1 - (ae-undocumented) Missing documentation for "NotificationsProcessingExtensionPoint". +// src/extensions.d.ts:74:5 - (ae-undocumented) Missing documentation for "addProcessor". +// src/extensions.d.ts:79:22 - (ae-undocumented) Missing documentation for "notificationsProcessingExtensionPoint". +// src/extensions.d.ts:84:1 - (ae-undocumented) Missing documentation for "NotificationProcessorFilters". +// src/lib.d.ts:3:22 - (ae-undocumented) Missing documentation for "notificationService". +// src/service/DefaultNotificationService.d.ts:5:1 - (ae-undocumented) Missing documentation for "NotificationServiceOptions". +// src/service/DefaultNotificationService.d.ts:10:1 - (ae-undocumented) Missing documentation for "NotificationRecipients". +// src/service/DefaultNotificationService.d.ts:26:1 - (ae-undocumented) Missing documentation for "NotificationSendOptions". +// src/service/DefaultNotificationService.d.ts:31:1 - (ae-undocumented) Missing documentation for "DefaultNotificationService". +// src/service/DefaultNotificationService.d.ts:35:5 - (ae-undocumented) Missing documentation for "create". +// src/service/DefaultNotificationService.d.ts:36:5 - (ae-undocumented) Missing documentation for "send". +// src/service/NotificationService.d.ts:3:1 - (ae-undocumented) Missing documentation for "NotificationService". +// src/service/NotificationService.d.ts:4:5 - (ae-undocumented) Missing documentation for "send". ``` diff --git a/plugins/notifications/CHANGELOG.md b/plugins/notifications/CHANGELOG.md index 945000c468..c1cb9ee881 100644 --- a/plugins/notifications/CHANGELOG.md +++ b/plugins/notifications/CHANGELOG.md @@ -1,5 +1,64 @@ # @backstage/plugin-notifications +## 0.3.2-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/plugin-signals-react@0.0.6-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/theme@0.5.8-next.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.5 + +## 0.3.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.7 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-signals-react@0.0.6-next.0 + +## 0.3.1 + +### Patch Changes + +- 653f60b: Severity filter label newly contains "Min severity" to better describe range instead of exact value. +- 4a53dd0: Implement icon in backend and show icon in table if available. +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/theme@0.5.7 + - @backstage/plugin-signals-react@0.0.5 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.5 + +## 0.3.1-next.2 + +### Patch Changes + +- 653f60b: Severity filter label newly contains "Min severity" to better describe range instead of exact value. +- 4a53dd0: Implement icon in backend and show icon in table if available. +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/theme@0.5.7-next.0 + - @backstage/plugin-signals-react@0.0.5-next.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.5 + ## 0.3.1-next.1 ### Patch Changes diff --git a/plugins/notifications/package.json b/plugins/notifications/package.json index 7dd72d0d97..9f2110afa6 100644 --- a/plugins/notifications/package.json +++ b/plugins/notifications/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-notifications", - "version": "0.3.1-next.1", + "version": "0.3.2-next.1", "backstage": { "role": "frontend-plugin", "pluginId": "notifications", @@ -48,7 +48,6 @@ "@material-ui/core": "^4.9.13", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "^4.0.0-alpha.61", - "@types/react": "^16.13.1 || ^17.0.0", "lodash": "^4.17.21", "material-ui-confirm": "^3.0.12", "notistack": "^3.0.1", @@ -62,12 +61,23 @@ "@backstage/plugin-signals": "workspace:^", "@backstage/test-utils": "workspace:^", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^15.0.0", + "@testing-library/react": "^16.0.0", "@testing-library/user-event": "^14.0.0", - "msw": "^1.0.0" + "@types/react": "^18.0.0", + "msw": "^1.0.0", + "react": "^18.0.2", + "react-dom": "^18.0.2", + "react-router-dom": "^6.3.0" }, "peerDependencies": { - "react": "^16.13.1 || ^17.0.0", + "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } } diff --git a/plugins/notifications/api-report.md b/plugins/notifications/report.api.md similarity index 66% rename from plugins/notifications/api-report.md rename to plugins/notifications/report.api.md index 5e06ae2616..ab1fc6d5a1 100644 --- a/plugins/notifications/api-report.md +++ b/plugins/notifications/report.api.md @@ -176,5 +176,29 @@ export function useNotificationsApi( value: T; }; +// Warnings were encountered during analysis: +// +// src/api/NotificationsApi.d.ts:3:22 - (ae-undocumented) Missing documentation for "notificationsApiRef". +// src/api/NotificationsApi.d.ts:5:1 - (ae-undocumented) Missing documentation for "GetNotificationsOptions". +// src/api/NotificationsApi.d.ts:17:1 - (ae-undocumented) Missing documentation for "UpdateNotificationsOptions". +// src/api/NotificationsApi.d.ts:23:1 - (ae-undocumented) Missing documentation for "GetNotificationsResponse". +// src/api/NotificationsApi.d.ts:28:1 - (ae-undocumented) Missing documentation for "NotificationsApi". +// src/api/NotificationsApi.d.ts:29:5 - (ae-undocumented) Missing documentation for "getNotifications". +// src/api/NotificationsApi.d.ts:30:5 - (ae-undocumented) Missing documentation for "getNotification". +// src/api/NotificationsApi.d.ts:31:5 - (ae-undocumented) Missing documentation for "getStatus". +// src/api/NotificationsApi.d.ts:32:5 - (ae-undocumented) Missing documentation for "updateNotifications". +// src/api/NotificationsClient.d.ts:5:1 - (ae-undocumented) Missing documentation for "NotificationsClient". +// src/api/NotificationsClient.d.ts:12:5 - (ae-undocumented) Missing documentation for "getNotifications". +// src/api/NotificationsClient.d.ts:13:5 - (ae-undocumented) Missing documentation for "getNotification". +// src/api/NotificationsClient.d.ts:14:5 - (ae-undocumented) Missing documentation for "getStatus". +// src/api/NotificationsClient.d.ts:15:5 - (ae-undocumented) Missing documentation for "updateNotifications". +// src/components/NotificationsPage/NotificationsPage.d.ts:3:1 - (ae-undocumented) Missing documentation for "NotificationsPageProps". +// src/components/NotificationsSideBarItem/NotificationsSideBarItem.d.ts:12:22 - (ae-undocumented) Missing documentation for "NotificationsSidebarItem". +// src/components/NotificationsTable/NotificationsTable.d.ts:5:1 - (ae-undocumented) Missing documentation for "NotificationsTableProps". +// src/components/NotificationsTable/NotificationsTable.d.ts:15:22 - (ae-undocumented) Missing documentation for "NotificationsTable". +// src/hooks/useNotificationsApi.d.ts:3:1 - (ae-undocumented) Missing documentation for "useNotificationsApi". +// src/plugin.d.ts:3:22 - (ae-undocumented) Missing documentation for "notificationsPlugin". +// src/plugin.d.ts:7:22 - (ae-undocumented) Missing documentation for "NotificationsPage". + // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/notifications/src/components/NotificationsFilters/NotificationsFilters.tsx b/plugins/notifications/src/components/NotificationsFilters/NotificationsFilters.tsx index 3175af6f6f..2676016695 100644 --- a/plugins/notifications/src/components/NotificationsFilters/NotificationsFilters.tsx +++ b/plugins/notifications/src/components/NotificationsFilters/NotificationsFilters.tsx @@ -249,10 +249,12 @@ export const NotificationsFilters = ({ - Severity + + Min severity +
= { // @public export type TaskStoreListEventsOptions = { + isTaskRecoverable?: boolean; taskId: string; after?: number | undefined; }; @@ -765,4 +839,117 @@ export type TemplatePermissionRuleInput< typeof RESOURCE_TYPE_SCAFFOLDER_TEMPLATE, TParams >; + +// Warnings were encountered during analysis: +// +// src/deprecated.d.ts:8:1 - (ae-undocumented) Missing documentation for "ActionContext". +// src/deprecated.d.ts:13:22 - (ae-undocumented) Missing documentation for "createTemplateAction". +// src/deprecated.d.ts:18:1 - (ae-undocumented) Missing documentation for "TaskSecrets". +// src/deprecated.d.ts:23:1 - (ae-undocumented) Missing documentation for "TemplateAction". +// src/lib/templating/SecureTemplater.d.ts:6:1 - (ae-undocumented) Missing documentation for "TemplateFilter". +// src/lib/templating/SecureTemplater.d.ts:11:1 - (ae-undocumented) Missing documentation for "TemplateGlobal". +// src/scaffolder/actions/TemplateActionRegistry.d.ts:8:5 - (ae-undocumented) Missing documentation for "register". +// src/scaffolder/actions/TemplateActionRegistry.d.ts:9:5 - (ae-undocumented) Missing documentation for "get". +// src/scaffolder/actions/TemplateActionRegistry.d.ts:10:5 - (ae-undocumented) Missing documentation for "list". +// src/scaffolder/actions/builtin/createBuiltinActions.d.ts:36:5 - (ae-undocumented) Missing documentation for "additionalTemplateGlobals". +// src/scaffolder/actions/deprecated.d.ts:12:22 - (ae-undocumented) Missing documentation for "createGithubActionsDispatchAction". +// src/scaffolder/actions/deprecated.d.ts:17:22 - (ae-undocumented) Missing documentation for "createGithubDeployKeyAction". +// src/scaffolder/actions/deprecated.d.ts:22:22 - (ae-undocumented) Missing documentation for "createGithubEnvironmentAction". +// src/scaffolder/actions/deprecated.d.ts:27:22 - (ae-undocumented) Missing documentation for "createGithubIssuesLabelAction". +// src/scaffolder/actions/deprecated.d.ts:32:1 - (ae-undocumented) Missing documentation for "CreateGithubPullRequestActionOptions". +// src/scaffolder/actions/deprecated.d.ts:37:22 - (ae-undocumented) Missing documentation for "createGithubRepoCreateAction". +// src/scaffolder/actions/deprecated.d.ts:42:22 - (ae-undocumented) Missing documentation for "createGithubRepoPushAction". +// src/scaffolder/actions/deprecated.d.ts:47:22 - (ae-undocumented) Missing documentation for "createGithubWebhookAction". +// src/scaffolder/actions/deprecated.d.ts:52:22 - (ae-undocumented) Missing documentation for "createPublishGithubAction". +// src/scaffolder/actions/deprecated.d.ts:57:22 - (ae-undocumented) Missing documentation for "createPublishGithubPullRequestAction". +// src/scaffolder/actions/deprecated.d.ts:79:22 - (ae-undocumented) Missing documentation for "createPublishBitbucketAction". +// src/scaffolder/actions/deprecated.d.ts:84:22 - (ae-undocumented) Missing documentation for "createPublishBitbucketCloudAction". +// src/scaffolder/actions/deprecated.d.ts:89:22 - (ae-undocumented) Missing documentation for "createPublishBitbucketServerAction". +// src/scaffolder/actions/deprecated.d.ts:94:22 - (ae-undocumented) Missing documentation for "createPublishBitbucketServerPullRequestAction". +// src/scaffolder/actions/deprecated.d.ts:99:22 - (ae-undocumented) Missing documentation for "createPublishAzureAction". +// src/scaffolder/actions/deprecated.d.ts:104:22 - (ae-undocumented) Missing documentation for "createPublishGerritAction". +// src/scaffolder/actions/deprecated.d.ts:109:22 - (ae-undocumented) Missing documentation for "createPublishGerritReviewAction". +// src/scaffolder/actions/deprecated.d.ts:114:22 - (ae-undocumented) Missing documentation for "createPublishGitlabAction". +// src/scaffolder/actions/deprecated.d.ts:119:22 - (ae-undocumented) Missing documentation for "createPublishGitlabMergeRequestAction". +// src/scaffolder/tasks/DatabaseTaskStore.d.ts:42:5 - (ae-undocumented) Missing documentation for "create". +// src/scaffolder/tasks/DatabaseTaskStore.d.ts:49:5 - (ae-undocumented) Missing documentation for "list". +// src/scaffolder/tasks/DatabaseTaskStore.d.ts:68:5 - (ae-undocumented) Missing documentation for "getTask". +// src/scaffolder/tasks/DatabaseTaskStore.d.ts:69:5 - (ae-undocumented) Missing documentation for "createTask". +// src/scaffolder/tasks/DatabaseTaskStore.d.ts:70:5 - (ae-undocumented) Missing documentation for "claimTask". +// src/scaffolder/tasks/DatabaseTaskStore.d.ts:71:5 - (ae-undocumented) Missing documentation for "heartbeatTask". +// src/scaffolder/tasks/DatabaseTaskStore.d.ts:72:5 - (ae-undocumented) Missing documentation for "listStaleTasks". +// src/scaffolder/tasks/DatabaseTaskStore.d.ts:80:5 - (ae-undocumented) Missing documentation for "completeTask". +// src/scaffolder/tasks/DatabaseTaskStore.d.ts:85:5 - (ae-undocumented) Missing documentation for "emitLogEvent". +// src/scaffolder/tasks/DatabaseTaskStore.d.ts:88:5 - (ae-undocumented) Missing documentation for "getTaskState". +// src/scaffolder/tasks/DatabaseTaskStore.d.ts:93:5 - (ae-undocumented) Missing documentation for "saveTaskState". +// src/scaffolder/tasks/DatabaseTaskStore.d.ts:97:5 - (ae-undocumented) Missing documentation for "listEvents". +// src/scaffolder/tasks/DatabaseTaskStore.d.ts:100:5 - (ae-undocumented) Missing documentation for "shutdownTask". +// src/scaffolder/tasks/DatabaseTaskStore.d.ts:101:5 - (ae-undocumented) Missing documentation for "rehydrateWorkspace". +// src/scaffolder/tasks/DatabaseTaskStore.d.ts:105:5 - (ae-undocumented) Missing documentation for "cleanWorkspace". +// src/scaffolder/tasks/DatabaseTaskStore.d.ts:108:5 - (ae-undocumented) Missing documentation for "serializeWorkspace". +// src/scaffolder/tasks/DatabaseTaskStore.d.ts:112:5 - (ae-undocumented) Missing documentation for "cancelTask". +// src/scaffolder/tasks/DatabaseTaskStore.d.ts:115:5 - (ae-undocumented) Missing documentation for "retryTask". +// src/scaffolder/tasks/DatabaseTaskStore.d.ts:118:5 - (ae-undocumented) Missing documentation for "recoverTasks". +// src/scaffolder/tasks/StorageTaskBroker.d.ts:25:5 - (ae-undocumented) Missing documentation for "create". +// src/scaffolder/tasks/StorageTaskBroker.d.ts:27:5 - (ae-undocumented) Missing documentation for "spec". +// src/scaffolder/tasks/StorageTaskBroker.d.ts:28:5 - (ae-undocumented) Missing documentation for "cancelSignal". +// src/scaffolder/tasks/StorageTaskBroker.d.ts:29:5 - (ae-undocumented) Missing documentation for "secrets". +// src/scaffolder/tasks/StorageTaskBroker.d.ts:30:5 - (ae-undocumented) Missing documentation for "createdBy". +// src/scaffolder/tasks/StorageTaskBroker.d.ts:31:5 - (ae-undocumented) Missing documentation for "getWorkspaceName". +// src/scaffolder/tasks/StorageTaskBroker.d.ts:32:5 - (ae-undocumented) Missing documentation for "rehydrateWorkspace". +// src/scaffolder/tasks/StorageTaskBroker.d.ts:36:5 - (ae-undocumented) Missing documentation for "done". +// src/scaffolder/tasks/StorageTaskBroker.d.ts:37:5 - (ae-undocumented) Missing documentation for "emitLog". +// src/scaffolder/tasks/StorageTaskBroker.d.ts:38:5 - (ae-undocumented) Missing documentation for "getTaskState". +// src/scaffolder/tasks/StorageTaskBroker.d.ts:41:5 - (ae-undocumented) Missing documentation for "updateCheckpoint". +// src/scaffolder/tasks/StorageTaskBroker.d.ts:50:5 - (ae-undocumented) Missing documentation for "serializeWorkspace". +// src/scaffolder/tasks/StorageTaskBroker.d.ts:53:5 - (ae-undocumented) Missing documentation for "cleanWorkspace". +// src/scaffolder/tasks/StorageTaskBroker.d.ts:54:5 - (ae-undocumented) Missing documentation for "complete". +// src/scaffolder/tasks/StorageTaskBroker.d.ts:56:5 - (ae-undocumented) Missing documentation for "getInitiatorCredentials". +// src/scaffolder/tasks/TaskWorker.d.ts:60:5 - (ae-undocumented) Missing documentation for "create". +// src/scaffolder/tasks/TaskWorker.d.ts:61:5 - (ae-undocumented) Missing documentation for "recoverTasks". +// src/scaffolder/tasks/TaskWorker.d.ts:62:5 - (ae-undocumented) Missing documentation for "start". +// src/scaffolder/tasks/TaskWorker.d.ts:63:5 - (ae-undocumented) Missing documentation for "stop". +// src/scaffolder/tasks/TaskWorker.d.ts:64:5 - (ae-undocumented) Missing documentation for "onReadyToClaimTask". +// src/scaffolder/tasks/TaskWorker.d.ts:65:5 - (ae-undocumented) Missing documentation for "runOneTask". +// src/scaffolder/tasks/types.d.ts:124:5 - (ae-undocumented) Missing documentation for "cancelTask". +// src/scaffolder/tasks/types.d.ts:125:5 - (ae-undocumented) Missing documentation for "createTask". +// src/scaffolder/tasks/types.d.ts:126:5 - (ae-undocumented) Missing documentation for "retryTask". +// src/scaffolder/tasks/types.d.ts:129:5 - (ae-undocumented) Missing documentation for "recoverTasks". +// src/scaffolder/tasks/types.d.ts:132:5 - (ae-undocumented) Missing documentation for "getTask". +// src/scaffolder/tasks/types.d.ts:133:5 - (ae-undocumented) Missing documentation for "claimTask". +// src/scaffolder/tasks/types.d.ts:134:5 - (ae-undocumented) Missing documentation for "completeTask". +// src/scaffolder/tasks/types.d.ts:139:5 - (ae-undocumented) Missing documentation for "heartbeatTask". +// src/scaffolder/tasks/types.d.ts:140:5 - (ae-undocumented) Missing documentation for "listStaleTasks". +// src/scaffolder/tasks/types.d.ts:147:5 - (ae-undocumented) Missing documentation for "list". +// src/scaffolder/tasks/types.d.ts:167:5 - (ae-undocumented) Missing documentation for "list". +// src/scaffolder/tasks/types.d.ts:186:5 - (ae-undocumented) Missing documentation for "emitLogEvent". +// src/scaffolder/tasks/types.d.ts:187:5 - (ae-undocumented) Missing documentation for "getTaskState". +// src/scaffolder/tasks/types.d.ts:192:5 - (ae-undocumented) Missing documentation for "saveTaskState". +// src/scaffolder/tasks/types.d.ts:196:5 - (ae-undocumented) Missing documentation for "listEvents". +// src/scaffolder/tasks/types.d.ts:199:5 - (ae-undocumented) Missing documentation for "shutdownTask". +// src/scaffolder/tasks/types.d.ts:200:5 - (ae-undocumented) Missing documentation for "rehydrateWorkspace". +// src/scaffolder/tasks/types.d.ts:204:5 - (ae-undocumented) Missing documentation for "cleanWorkspace". +// src/scaffolder/tasks/types.d.ts:207:5 - (ae-undocumented) Missing documentation for "serializeWorkspace". +// src/service/router.d.ts:17:1 - (ae-undocumented) Missing documentation for "TemplatePermissionRuleInput". +// src/service/router.d.ts:22:1 - (ae-undocumented) Missing documentation for "ActionPermissionRuleInput". +// src/service/router.d.ts:30:5 - (ae-undocumented) Missing documentation for "logger". +// src/service/router.d.ts:31:5 - (ae-undocumented) Missing documentation for "config". +// src/service/router.d.ts:32:5 - (ae-undocumented) Missing documentation for "reader". +// src/service/router.d.ts:33:5 - (ae-undocumented) Missing documentation for "lifecycle". +// src/service/router.d.ts:34:5 - (ae-undocumented) Missing documentation for "database". +// src/service/router.d.ts:35:5 - (ae-undocumented) Missing documentation for "catalogClient". +// src/service/router.d.ts:36:5 - (ae-undocumented) Missing documentation for "scheduler". +// src/service/router.d.ts:37:5 - (ae-undocumented) Missing documentation for "actions". +// src/service/router.d.ts:42:5 - (ae-undocumented) Missing documentation for "taskWorkers". +// src/service/router.d.ts:48:5 - (ae-undocumented) Missing documentation for "taskBroker". +// src/service/router.d.ts:49:5 - (ae-undocumented) Missing documentation for "additionalTemplateFilters". +// src/service/router.d.ts:50:5 - (ae-undocumented) Missing documentation for "additionalTemplateGlobals". +// src/service/router.d.ts:51:5 - (ae-undocumented) Missing documentation for "additionalWorkspaceProviders". +// src/service/router.d.ts:52:5 - (ae-undocumented) Missing documentation for "permissions". +// src/service/router.d.ts:53:5 - (ae-undocumented) Missing documentation for "permissionRules". +// src/service/router.d.ts:54:5 - (ae-undocumented) Missing documentation for "auth". +// src/service/router.d.ts:55:5 - (ae-undocumented) Missing documentation for "httpAuth". +// src/service/router.d.ts:56:5 - (ae-undocumented) Missing documentation for "identity". +// src/service/router.d.ts:57:5 - (ae-undocumented) Missing documentation for "discovery". +// src/service/router.d.ts:58:5 - (ae-undocumented) Missing documentation for "autocompleteHandlers". ``` diff --git a/plugins/scaffolder-backend/src/ScaffolderPlugin.ts b/plugins/scaffolder-backend/src/ScaffolderPlugin.ts index 27b4f6b196..cf0f557639 100644 --- a/plugins/scaffolder-backend/src/ScaffolderPlugin.ts +++ b/plugins/scaffolder-backend/src/ScaffolderPlugin.ts @@ -44,6 +44,7 @@ import { createFetchPlainAction, createFetchPlainFileAction, createFetchTemplateAction, + createFetchTemplateFileAction, createFilesystemDeleteAction, createFilesystemRenameAction, createWaitAction, @@ -149,6 +150,12 @@ export const scaffolderPlugin = createBackendPlugin({ additionalTemplateFilters, additionalTemplateGlobals, }), + createFetchTemplateFileAction({ + integrations, + reader, + additionalTemplateFilters, + additionalTemplateGlobals, + }), createDebugLogAction(), createWaitAction(), // todo(blam): maybe these should be a -catalog module? diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/fetch.examples.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/fetch.examples.test.ts index 549ed923c2..155a58cbac 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/fetch.examples.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/fetch.examples.test.ts @@ -15,24 +15,18 @@ */ import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; -import { CatalogApi } from '@backstage/catalog-client'; import { Entity } from '@backstage/catalog-model'; import { createFetchCatalogEntityAction } from './fetch'; import { examples } from './fetch.examples'; import yaml from 'yaml'; import { mockCredentials, mockServices } from '@backstage/backend-test-utils'; +import { catalogServiceMock } from '@backstage/plugin-catalog-node/testUtils'; describe('catalog:fetch examples', () => { - const getEntityByRef = jest.fn(); - const getEntitiesByRefs = jest.fn(); - - const catalogClient = { - getEntityByRef: getEntityByRef, - getEntitiesByRefs: getEntitiesByRefs, - }; + const catalogClient = catalogServiceMock.mock(); const action = createFetchCatalogEntityAction({ - catalogClient: catalogClient as unknown as CatalogApi, + catalogClient, auth: mockServices.auth(), }); @@ -46,13 +40,14 @@ describe('catalog:fetch examples', () => { const mockContext = createMockActionContext({ secrets: { backstageToken: token }, }); + beforeEach(() => { jest.resetAllMocks(); }); describe('fetch single entity', () => { it('should return entity from catalog', async () => { - getEntityByRef.mockReturnValueOnce({ + catalogClient.getEntityByRef.mockResolvedValueOnce({ metadata: { namespace: 'default', name: 'name', @@ -65,9 +60,10 @@ describe('catalog:fetch examples', () => { input: yaml.parse(examples[0].example).steps[0].input, }); - expect(getEntityByRef).toHaveBeenCalledWith('component:default/name', { - token, - }); + expect(catalogClient.getEntityByRef).toHaveBeenCalledWith( + 'component:default/name', + { token }, + ); expect(mockContext.output).toHaveBeenCalledWith('entity', { metadata: { namespace: 'default', diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/fetch.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/fetch.test.ts index 747414f206..f4ed8595c6 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/fetch.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/fetch.test.ts @@ -15,22 +15,16 @@ */ import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; -import { CatalogApi } from '@backstage/catalog-client'; import { Entity } from '@backstage/catalog-model'; import { createFetchCatalogEntityAction } from './fetch'; import { mockCredentials, mockServices } from '@backstage/backend-test-utils'; +import { catalogServiceMock } from '@backstage/plugin-catalog-node/testUtils'; describe('catalog:fetch', () => { - const getEntityByRef = jest.fn(); - const getEntitiesByRefs = jest.fn(); - - const catalogClient = { - getEntityByRef: getEntityByRef, - getEntitiesByRefs: getEntitiesByRefs, - }; + const catalogClient = catalogServiceMock.mock(); const action = createFetchCatalogEntityAction({ - catalogClient: catalogClient as unknown as CatalogApi, + catalogClient, auth: mockServices.auth(), }); @@ -51,7 +45,7 @@ describe('catalog:fetch', () => { describe('fetch single entity', () => { it('should return entity from catalog', async () => { - getEntityByRef.mockReturnValueOnce({ + catalogClient.getEntityByRef.mockResolvedValueOnce({ metadata: { namespace: 'default', name: 'test', @@ -66,9 +60,12 @@ describe('catalog:fetch', () => { }, }); - expect(getEntityByRef).toHaveBeenCalledWith('component:default/test', { - token, - }); + expect(catalogClient.getEntityByRef).toHaveBeenCalledWith( + 'component:default/test', + { + token, + }, + ); expect(mockContext.output).toHaveBeenCalledWith('entity', { metadata: { namespace: 'default', @@ -79,7 +76,7 @@ describe('catalog:fetch', () => { }); it('should throw error if entity fetch fails from catalog and optional is false', async () => { - getEntityByRef.mockImplementationOnce(() => { + catalogClient.getEntityByRef.mockImplementationOnce(() => { throw new Error('Not found'); }); @@ -92,14 +89,17 @@ describe('catalog:fetch', () => { }), ).rejects.toThrow('Not found'); - expect(getEntityByRef).toHaveBeenCalledWith('component:default/test', { - token, - }); + expect(catalogClient.getEntityByRef).toHaveBeenCalledWith( + 'component:default/test', + { + token, + }, + ); expect(mockContext.output).not.toHaveBeenCalled(); }); it('should throw error if entity not in catalog and optional is false', async () => { - getEntityByRef.mockReturnValueOnce(null); + catalogClient.getEntityByRef.mockResolvedValueOnce(null as any); await expect( action.handler({ @@ -110,9 +110,12 @@ describe('catalog:fetch', () => { }), ).rejects.toThrow('Entity component:default/test not found'); - expect(getEntityByRef).toHaveBeenCalledWith('component:default/test', { - token, - }); + expect(catalogClient.getEntityByRef).toHaveBeenCalledWith( + 'component:default/test', + { + token, + }, + ); expect(mockContext.output).not.toHaveBeenCalled(); }); @@ -124,7 +127,7 @@ describe('catalog:fetch', () => { }, kind: 'Group', } as Entity; - getEntityByRef.mockReturnValueOnce(entity); + catalogClient.getEntityByRef.mockResolvedValueOnce(entity); await action.handler({ ...mockContext, @@ -135,16 +138,19 @@ describe('catalog:fetch', () => { }, }); - expect(getEntityByRef).toHaveBeenCalledWith('group:ns/test', { - token, - }); + expect(catalogClient.getEntityByRef).toHaveBeenCalledWith( + 'group:ns/test', + { + token, + }, + ); expect(mockContext.output).toHaveBeenCalledWith('entity', entity); }); }); describe('fetch multiple entities', () => { it('should return entities from catalog', async () => { - getEntitiesByRefs.mockReturnValueOnce({ + catalogClient.getEntitiesByRefs.mockResolvedValueOnce({ items: [ { metadata: { @@ -163,7 +169,7 @@ describe('catalog:fetch', () => { }, }); - expect(getEntitiesByRefs).toHaveBeenCalledWith( + expect(catalogClient.getEntitiesByRefs).toHaveBeenCalledWith( { entityRefs: ['component:default/test'] }, { token, @@ -181,7 +187,7 @@ describe('catalog:fetch', () => { }); it('should throw error if undefined is returned for some entity', async () => { - getEntitiesByRefs.mockReturnValueOnce({ + catalogClient.getEntitiesByRefs.mockResolvedValueOnce({ items: [ { metadata: { @@ -204,7 +210,7 @@ describe('catalog:fetch', () => { }), ).rejects.toThrow('Entity component:default/test2 not found'); - expect(getEntitiesByRefs).toHaveBeenCalledWith( + expect(catalogClient.getEntitiesByRefs).toHaveBeenCalledWith( { entityRefs: ['component:default/test', 'component:default/test2'] }, { token, @@ -214,7 +220,7 @@ describe('catalog:fetch', () => { }); it('should return null in case some of the entities not found and optional is true', async () => { - getEntitiesByRefs.mockReturnValueOnce({ + catalogClient.getEntitiesByRefs.mockResolvedValueOnce({ items: [ { metadata: { @@ -235,7 +241,7 @@ describe('catalog:fetch', () => { }, }); - expect(getEntitiesByRefs).toHaveBeenCalledWith( + expect(catalogClient.getEntitiesByRefs).toHaveBeenCalledWith( { entityRefs: ['component:default/test', 'component:default/test2'] }, { token, @@ -268,7 +274,7 @@ describe('catalog:fetch', () => { }, kind: 'User', } as Entity; - getEntitiesByRefs.mockReturnValueOnce({ + catalogClient.getEntitiesByRefs.mockResolvedValueOnce({ items: [entity1, entity2], }); @@ -281,7 +287,7 @@ describe('catalog:fetch', () => { }, }); - expect(getEntitiesByRefs).toHaveBeenCalledWith( + expect(catalogClient.getEntitiesByRefs).toHaveBeenCalledWith( { entityRefs: ['group:ns/test', 'user:default/test'] }, { token, diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.examples.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.examples.test.ts index d279af78dc..27690b0df3 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.examples.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.examples.test.ts @@ -15,7 +15,6 @@ */ import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; -import { CatalogApi } from '@backstage/catalog-client'; import { ConfigReader } from '@backstage/config'; import { ScmIntegrations } from '@backstage/integration'; import { createCatalogRegisterAction } from './register'; @@ -23,6 +22,7 @@ import { Entity } from '@backstage/catalog-model'; import { examples } from './register.examples'; import yaml from 'yaml'; import { mockCredentials, mockServices } from '@backstage/backend-test-utils'; +import { catalogServiceMock } from '@backstage/plugin-catalog-node/testUtils'; describe('catalog:register', () => { const integrations = ScmIntegrations.fromConfig( @@ -33,14 +33,11 @@ describe('catalog:register', () => { }), ); - const addLocation = jest.fn(); - const catalogClient = { - addLocation: addLocation, - }; + const catalogClient = catalogServiceMock.mock(); const action = createCatalogRegisterAction({ integrations, - catalogClient: catalogClient as unknown as CatalogApi, + catalogClient, auth: mockServices.auth(), }); @@ -57,11 +54,13 @@ describe('catalog:register', () => { }); it('should register location in catalog', async () => { - addLocation + catalogClient.addLocation .mockResolvedValueOnce({ + location: null as any, entities: [], }) .mockResolvedValueOnce({ + location: null as any, entities: [ { metadata: { @@ -77,7 +76,7 @@ describe('catalog:register', () => { input: yaml.parse(examples[0].example).steps[0].input, }); - expect(addLocation).toHaveBeenNthCalledWith( + expect(catalogClient.addLocation).toHaveBeenNthCalledWith( 1, { type: 'url', @@ -86,7 +85,7 @@ describe('catalog:register', () => { }, { token }, ); - expect(addLocation).toHaveBeenNthCalledWith( + expect(catalogClient.addLocation).toHaveBeenNthCalledWith( 2, { dryRun: true, diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.test.ts index 2db232afa0..6d4f7de0d8 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.test.ts @@ -15,12 +15,12 @@ */ import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; -import { CatalogApi } from '@backstage/catalog-client'; import { ConfigReader } from '@backstage/config'; import { ScmIntegrations } from '@backstage/integration'; import { createCatalogRegisterAction } from './register'; import { Entity } from '@backstage/catalog-model'; import { mockCredentials, mockServices } from '@backstage/backend-test-utils'; +import { catalogServiceMock } from '@backstage/plugin-catalog-node/testUtils'; describe('catalog:register', () => { const integrations = ScmIntegrations.fromConfig( @@ -31,14 +31,11 @@ describe('catalog:register', () => { }), ); - const addLocation = jest.fn(); - const catalogClient = { - addLocation: addLocation, - }; + const catalogClient = catalogServiceMock.mock(); const action = createCatalogRegisterAction({ integrations, - catalogClient: catalogClient as unknown as CatalogApi, + catalogClient, auth: mockServices.auth(), }); @@ -69,11 +66,13 @@ describe('catalog:register', () => { }); it('should register location in catalog', async () => { - addLocation + catalogClient.addLocation .mockResolvedValueOnce({ + location: null as any, entities: [], }) .mockResolvedValueOnce({ + location: null as any, entities: [ { metadata: { @@ -91,7 +90,7 @@ describe('catalog:register', () => { }, }); - expect(addLocation).toHaveBeenNthCalledWith( + expect(catalogClient.addLocation).toHaveBeenNthCalledWith( 1, { type: 'url', @@ -99,7 +98,7 @@ describe('catalog:register', () => { }, { token }, ); - expect(addLocation).toHaveBeenNthCalledWith( + expect(catalogClient.addLocation).toHaveBeenNthCalledWith( 2, { dryRun: true, @@ -120,11 +119,13 @@ describe('catalog:register', () => { }); it('should return entityRef with the Component entity and not the generated location', async () => { - addLocation + catalogClient.addLocation .mockResolvedValueOnce({ + location: null as any, entities: [], }) .mockResolvedValueOnce({ + location: null as any, entities: [ { metadata: { @@ -169,11 +170,13 @@ describe('catalog:register', () => { }); it('should return entityRef with the next non-generated entity if no Component kind can be found', async () => { - addLocation + catalogClient.addLocation .mockResolvedValueOnce({ + location: null as any, entities: [], }) .mockResolvedValueOnce({ + location: null as any, entities: [ { metadata: { @@ -211,11 +214,13 @@ describe('catalog:register', () => { }); it('should return entityRef with the first entity if no non-generated entities can be found', async () => { - addLocation + catalogClient.addLocation .mockResolvedValueOnce({ + location: null as any, entities: [], }) .mockResolvedValueOnce({ + location: null as any, entities: [ { metadata: { @@ -246,11 +251,13 @@ describe('catalog:register', () => { }); it('should not return entityRef if there are no entites', async () => { - addLocation + catalogClient.addLocation .mockResolvedValueOnce({ + location: null as any, entities: [], }) .mockResolvedValueOnce({ + location: null as any, entities: [], }); await action.handler({ @@ -266,7 +273,7 @@ describe('catalog:register', () => { }); it('should ignore failures when dry running the location in the catalog if `optional` is set', async () => { - addLocation + catalogClient.addLocation .mockRejectedValueOnce(new Error('Not found')) .mockRejectedValueOnce(new Error('Not found')); await action.handler({ @@ -277,7 +284,7 @@ describe('catalog:register', () => { }, }); - expect(addLocation).toHaveBeenNthCalledWith( + expect(catalogClient.addLocation).toHaveBeenNthCalledWith( 1, { type: 'url', @@ -285,7 +292,7 @@ describe('catalog:register', () => { }, { token }, ); - expect(addLocation).toHaveBeenNthCalledWith( + expect(catalogClient.addLocation).toHaveBeenNthCalledWith( 2, { dryRun: true, @@ -302,9 +309,10 @@ describe('catalog:register', () => { }); it('should fetch entities when adding location in the catalog fails and `optional` is set', async () => { - addLocation + catalogClient.addLocation .mockRejectedValueOnce(new Error('Already registered')) .mockResolvedValueOnce({ + location: null as any, entities: [ { metadata: { @@ -323,7 +331,7 @@ describe('catalog:register', () => { }, }); - expect(addLocation).toHaveBeenNthCalledWith( + expect(catalogClient.addLocation).toHaveBeenNthCalledWith( 1, { type: 'url', @@ -331,7 +339,7 @@ describe('catalog:register', () => { }, { token }, ); - expect(addLocation).toHaveBeenNthCalledWith( + expect(catalogClient.addLocation).toHaveBeenNthCalledWith( 2, { dryRun: true, diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts index dba867c96b..59182ab46d 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts @@ -37,6 +37,7 @@ import { createFetchPlainAction, createFetchPlainFileAction, createFetchTemplateAction, + createFetchTemplateFileAction, } from './fetch'; import { createFilesystemDeleteAction, @@ -62,6 +63,7 @@ import { createPublishBitbucketAction } from '@backstage/plugin-scaffolder-backe import { createPublishBitbucketCloudAction, createBitbucketPipelinesRunAction, + createPublishBitbucketCloudPullRequestAction, } from '@backstage/plugin-scaffolder-backend-module-bitbucket-cloud'; import { @@ -157,6 +159,12 @@ export const createBuiltinActions = ( additionalTemplateFilters, additionalTemplateGlobals, }), + createFetchTemplateFileAction({ + integrations, + reader, + additionalTemplateFilters, + additionalTemplateGlobals, + }), createPublishGerritAction({ integrations, config, @@ -197,6 +205,7 @@ export const createBuiltinActions = ( integrations, config, }), + createPublishBitbucketCloudPullRequestAction({ integrations, config }), createPublishBitbucketServerAction({ integrations, config, @@ -239,6 +248,7 @@ export const createBuiltinActions = ( }), createGithubEnvironmentAction({ integrations, + catalogClient, }), createGithubDeployKeyAction({ integrations, diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/debug/log.examples.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/debug/log.examples.ts index 0e9173bfa6..c1ad6a2982 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/debug/log.examples.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/debug/log.examples.ts @@ -48,4 +48,19 @@ export const examples: TemplateExample[] = [ ], }), }, + { + description: 'List the workspace directory with file contents', + example: yaml.stringify({ + steps: [ + { + action: 'debug:log', + id: 'write-workspace-directory', + name: 'List the workspace directory with file contents', + input: { + listWorkspace: 'with-contents', + }, + }, + ], + }), + }, ]; diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/debug/log.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/debug/log.test.ts index 9c626f1dfe..4606a01e0c 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/debug/log.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/debug/log.test.ts @@ -35,8 +35,9 @@ describe('debug:log', () => { beforeEach(() => { mockDir.setContent({ - [`${mockContext.workspacePath}/README.md`]: '', - [`${mockContext.workspacePath}/a-directory/index.md`]: '', + [`${mockContext.workspacePath}/README.md`]: 'This is a README file', + [`${mockContext.workspacePath}/a-directory/index.md`]: + 'This is a markdown file', }); jest.resetAllMocks(); }); @@ -94,6 +95,34 @@ describe('debug:log', () => { ); }); + it('should log the workspace content with file contents from an example, if active', async () => { + const example = action.examples?.find( + sample => + sample.description === + 'List the workspace directory with file contents', + )?.example as string; + expect(typeof example).toEqual('string'); + const context = { + ...mockContext, + ...yaml.parse(example).steps[0], + }; + + await action.handler(context); + + expect(logger.info).toHaveBeenCalledWith( + expect.stringContaining('README.md'), + ); + expect(logger.info).toHaveBeenCalledWith( + expect.stringContaining(join('a-directory', 'index.md')), + ); + expect(logger.info).toHaveBeenCalledWith( + expect.stringContaining('This is a README file'), + ); + expect(logger.info).toHaveBeenCalledWith( + expect.stringContaining('This is a markdown file'), + ); + }); + it('should log message from an example', async () => { const example = action.examples?.find( sample => sample.description === 'Write a debug message', diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/debug/log.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/debug/log.ts index 98ab02437e..2ff64e1025 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/debug/log.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/debug/log.ts @@ -15,9 +15,11 @@ */ import { readdir, stat } from 'fs-extra'; -import { relative, join } from 'path'; +import { join, relative } from 'path'; import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; import { examples } from './log.examples'; +import fs from 'fs'; +import { z } from 'zod'; const id = 'debug:log'; @@ -32,28 +34,24 @@ const id = 'debug:log'; * @public */ export function createDebugLogAction() { - return createTemplateAction<{ message?: string; listWorkspace?: boolean }>({ + return createTemplateAction<{ + message?: string; + listWorkspace?: boolean | 'with-filenames' | 'with-contents'; + }>({ id, description: - 'Writes a message into the log or lists all files in the workspace.', + 'Writes a message into the log and/or lists all files in the workspace.', examples, schema: { - input: { - type: 'object', - properties: { - message: { - title: 'Message to output.', - type: 'string', - }, - listWorkspace: { - title: 'List all files in the workspace, if true.', - type: 'boolean', - }, - extra: { - title: 'Extra info', - }, - }, - }, + input: z.object({ + message: z.string({ description: 'Message to output.' }).optional(), + listWorkspace: z + .union([z.boolean(), z.enum(['with-filenames', 'with-contents'])], { + description: + 'List all files in the workspace. If used with "with-contents", also the file contents are listed.', + }) + .optional(), + }), }, supportsDryRun: true, async handler(ctx) { @@ -67,7 +65,14 @@ export function createDebugLogAction() { const files = await recursiveReadDir(ctx.workspacePath); ctx.logger.info( `Workspace:\n${files - .map(f => ` - ${relative(ctx.workspacePath, f)}`) + .map(f => { + const relativePath = relative(ctx.workspacePath, f); + if (ctx.input?.listWorkspace === 'with-contents') { + const content = fs.readFileSync(f, 'utf-8'); + return ` - ${relativePath}:\n\n ${content}`; + } + return ` - ${relativePath}`; + }) .join('\n')}`, ); } diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/index.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/index.ts index 67f1bc360f..dd3942a458 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/index.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/index.ts @@ -17,3 +17,4 @@ export { createFetchPlainAction } from './plain'; export { createFetchPlainFileAction } from './plainFile'; export { createFetchTemplateAction } from './template'; +export { createFetchTemplateFileAction } from './templateFile'; diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/templateFile.examples.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/templateFile.examples.test.ts new file mode 100644 index 0000000000..c7823ee9d8 --- /dev/null +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/templateFile.examples.test.ts @@ -0,0 +1,107 @@ +/* + * 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 { join as joinPath } from 'path'; +import fs from 'fs-extra'; +import { UrlReaderService } from '@backstage/backend-plugin-api'; +import { ScmIntegrations } from '@backstage/integration'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; +import { createFetchTemplateFileAction } from './templateFile'; +import { + ActionContext, + TemplateAction, + fetchFile, +} from '@backstage/plugin-scaffolder-node'; +import { examples } from './templateFile.examples'; +import yaml from 'yaml'; +import { createMockDirectory } from '@backstage/backend-test-utils'; + +jest.mock('@backstage/plugin-scaffolder-node', () => ({ + ...jest.requireActual('@backstage/plugin-scaffolder-node'), + fetchFile: jest.fn(), +})); + +type FetchTemplateInput = ReturnType< + typeof createFetchTemplateFileAction +> extends TemplateAction + ? U + : never; + +const mockFetchFile = fetchFile as jest.MockedFunction; + +describe('fetch:template:file examples', () => { + let action: TemplateAction; + + const mockDir = createMockDirectory(); + const workspacePath = mockDir.resolve('workspace'); + + const mockContext = (input: any) => + createMockActionContext({ + templateInfo: { + baseUrl: 'base-url', + entityRef: 'template:default/test-template', + }, + input, + workspacePath, + }); + + beforeEach(() => { + mockDir.clear(); + action = createFetchTemplateFileAction({ + reader: Symbol('UrlReader') as unknown as UrlReaderService, + integrations: Symbol('Integrations') as unknown as ScmIntegrations, + }); + }); + + describe('handler', () => { + describe('with valid input', () => { + let context: ActionContext; + + beforeEach(async () => { + context = mockContext(yaml.parse(examples[0].example).steps[0].input); + + mockFetchFile.mockImplementation(({ outputPath }) => { + mockDir.setContent({ + [outputPath]: + '${{ values.name }}: ${{ values.count }} ${{ values.itemList | dump }}', + }); + + return Promise.resolve(); + }); + + await action.handler(context); + }); + + it('uses fetchFile to retrieve the template content', () => { + expect(mockFetchFile).toHaveBeenCalledWith( + expect.objectContaining({ + baseUrl: context.templateInfo?.baseUrl, + fetchUrl: context.input.url, + }), + ); + }); + + it('copies files with no templating in names or content successfully', async () => { + await expect( + fs.readFile( + joinPath(workspacePath, context.input.targetPath), + 'utf-8', + ), + ).resolves.toEqual('test-project: 1234 ["first","second","third"]'); + }); + }); + }); +}); diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/templateFile.examples.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/templateFile.examples.ts new file mode 100644 index 0000000000..b2f3947f3a --- /dev/null +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/templateFile.examples.ts @@ -0,0 +1,42 @@ +/* + * 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 { TemplateExample } from '@backstage/plugin-scaffolder-node'; +import yaml from 'yaml'; + +export const examples: TemplateExample[] = [ + { + description: 'Downloads a template file and fill it out with values.', + example: yaml.stringify({ + steps: [ + { + action: 'fetch:template:file', + id: 'fetch-template-file', + name: 'Fetch template file', + input: { + url: './skeleton.txt', + targetPath: './target/skeleton.txt', + values: { + name: 'test-project', + count: 1234, + itemList: ['first', 'second', 'third'], + }, + }, + }, + ], + }), + }, +]; diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/templateFile.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/templateFile.test.ts new file mode 100644 index 0000000000..23721e685a --- /dev/null +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/templateFile.test.ts @@ -0,0 +1,251 @@ +/* + * 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. + */ + +jest.mock('@backstage/plugin-scaffolder-node', () => { + const actual = jest.requireActual('@backstage/plugin-scaffolder-node'); + return { ...actual, fetchFile: jest.fn() }; +}); + +import { join as joinPath } from 'path'; +import fs from 'fs-extra'; +import { UrlReaderService } from '@backstage/backend-plugin-api'; +import { ScmIntegrations } from '@backstage/integration'; +import { createFetchTemplateFileAction } from './templateFile'; +import { + ActionContext, + TemplateAction, + fetchFile, +} from '@backstage/plugin-scaffolder-node'; +import { createMockDirectory } from '@backstage/backend-test-utils'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; + +type FetchTemplateInput = ReturnType< + typeof createFetchTemplateFileAction +> extends TemplateAction + ? U + : never; + +const mockFetchFile = fetchFile as jest.MockedFunction; + +describe('fetch:template:file', () => { + let action: TemplateAction; + + const mockDir = createMockDirectory(); + const workspacePath = mockDir.resolve('workspace'); + const mockContext = (inputPatch: Partial = {}) => + createMockActionContext({ + templateInfo: { + baseUrl: 'base-url', + entityRef: 'template:default/test-template', + }, + input: { + url: './skeleton.txt', + targetPath: './target/skeleton.txt', + values: { + test: 'value', + }, + ...inputPatch, + }, + workspacePath, + }); + + beforeEach(() => { + mockDir.setContent({ + workspace: {}, + }); + action = createFetchTemplateFileAction({ + reader: Symbol('UrlReader') as unknown as UrlReaderService, + integrations: Symbol('Integrations') as unknown as ScmIntegrations, + }); + }); + + it(`returns a TemplateAction with the id 'fetch:template:file'`, () => { + expect(action.id).toEqual('fetch:template:file'); + }); + + describe('handler', () => { + it('should disallow a target path outside working directory', async () => { + await expect( + action.handler(mockContext({ targetPath: '../' })), + ).rejects.toThrow( + /Relative path is not allowed to refer to a directory outside its parent/, + ); + }); + + describe('valid input', () => { + let context: ActionContext; + + beforeEach(async () => { + context = mockContext({ + values: { + name: 'test-project', + count: 1234, + itemList: ['first', 'second', 'third'], + }, + token: 'mockToken', + }); + + mockFetchFile.mockImplementation(({ outputPath }) => { + mockDir.setContent({ + [outputPath]: + '${{ values.name }}: ${{ values.count }} ${{ values.itemList | dump }}', + }); + + return Promise.resolve(); + }); + + await action.handler(context); + }); + + it('uses fetchFile to retrieve the template content', () => { + expect(mockFetchFile).toHaveBeenCalledWith( + expect.objectContaining({ + baseUrl: context.templateInfo?.baseUrl, + fetchUrl: context.input.url, + }), + ); + }); + + it('passed through the token to fetchFile', () => { + expect(mockFetchFile).toHaveBeenCalledWith( + expect.objectContaining({ + token: 'mockToken', + }), + ); + }); + + it('templates content successfully', async () => { + await expect( + fs.readFile( + joinPath(workspacePath, context.input.targetPath), + 'utf-8', + ), + ).resolves.toEqual('test-project: 1234 ["first","second","third"]'); + }); + }); + + describe('with replacement of existing files', () => { + let context: ActionContext; + + beforeEach(async () => { + context = mockContext({ + url: './static-content.txt', + targetPath: './target/static-content.txt', + values: { + name: 'test-project', + count: 1234, + }, + replace: true, + }); + + mockDir.setContent({ + [joinPath(workspacePath, 'target')]: { + 'static-content.txt': 'static-content', + }, + }); + + mockFetchFile.mockImplementation(({ outputPath }) => { + mockDir.setContent({ + [outputPath]: '${{ values.name }}: ${{ values.count }}', + }); + + return Promise.resolve(); + }); + + await action.handler(context); + }); + + it('overwrites existing file', async () => { + await expect( + fs.readFile(`${workspacePath}/target/static-content.txt`, 'utf-8'), + ).resolves.toEqual('test-project: 1234'); + }); + }); + + describe('without replacement of existing files', () => { + let context: ActionContext; + + beforeEach(async () => { + context = mockContext({ + url: './static-content.txt', + targetPath: './target/static-content.txt', + values: { + name: 'test-project', + count: 1234, + }, + replace: false, + }); + + mockDir.setContent({ + [joinPath(workspacePath, 'target')]: { + 'static-content.txt': 'static-content', + }, + }); + + mockFetchFile.mockImplementation(({ outputPath }) => { + mockDir.setContent({ + [outputPath]: '${{ values.name }}: ${{ values.count }}', + }); + + return Promise.resolve(); + }); + + await action.handler(context); + }); + + it('keeps existing file', async () => { + await expect( + fs.readFile(`${workspacePath}/target/static-content.txt`, 'utf-8'), + ).resolves.toEqual('static-content'); + }); + }); + + describe('cookiecutter compatibility mode', () => { + let context: ActionContext; + + beforeEach(async () => { + context = mockContext({ + targetPath: './target/test-project.txt', + values: { + name: 'test-project', + count: 1234, + itemList: ['first', 'second', 'third'], + }, + cookiecutterCompat: true, + }); + + mockFetchFile.mockImplementation(({ outputPath }) => { + mockDir.setContent({ + [outputPath]: + 'static:{{ cookiecutter.name }}:{{ cookiecutter.count }}:{{ cookiecutter.itemList | jsonify }}', + }); + + return Promise.resolve(); + }); + + await action.handler(context); + }); + + it('copies files with cookiecutter-style templated variables successfully', async () => { + await expect( + fs.readFile(`${workspacePath}/target/test-project.txt`, 'utf-8'), + ).resolves.toEqual( + 'static:test-project:1234:["first","second","third"]', + ); + }); + }); + }); +}); diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/templateFile.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/templateFile.ts new file mode 100644 index 0000000000..5734156148 --- /dev/null +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/templateFile.ts @@ -0,0 +1,169 @@ +/* + * 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 { UrlReaderService } from '@backstage/backend-plugin-api'; +import { resolveSafeChildPath } from '@backstage/backend-plugin-api'; +import { ScmIntegrations } from '@backstage/integration'; +import { examples } from './templateFile.examples'; +import { + createTemplateAction, + fetchFile, + TemplateFilter, + TemplateGlobal, +} from '@backstage/plugin-scaffolder-node'; +import { SecureTemplater } from '../../../../lib/templating/SecureTemplater'; +import { createDefaultFilters } from '../../../../lib/templating/filters'; +import path from 'path'; +import fs from 'fs-extra'; + +/** + * Downloads a single file and templates variables into file. + * Then places the result in the workspace, or optionally in a subdirectory + * specified by the 'targetPath' input option. + * @public + */ +export function createFetchTemplateFileAction(options: { + reader: UrlReaderService; + integrations: ScmIntegrations; + additionalTemplateFilters?: Record; + additionalTemplateGlobals?: Record; +}) { + const { + reader, + integrations, + additionalTemplateFilters, + additionalTemplateGlobals, + } = options; + + const defaultTemplateFilters = createDefaultFilters({ integrations }); + + return createTemplateAction<{ + url: string; + targetPath: string; + values: any; + cookiecutterCompat?: boolean; + replace?: boolean; + trimBlocks?: boolean; + lstripBlocks?: boolean; + token?: string; + }>({ + id: 'fetch:template:file', + description: 'Downloads single file and places it in the workspace.', + examples, + schema: { + input: { + type: 'object', + required: ['url', 'targetPath'], + properties: { + url: { + title: 'Fetch URL', + description: + 'Relative path or absolute URL pointing to the single file to fetch.', + type: 'string', + }, + targetPath: { + title: 'Target Path', + description: + 'Target path within the working directory to download the file as.', + type: 'string', + }, + values: { + title: 'Template Values', + description: 'Values to pass on to the templating engine', + type: 'object', + }, + cookiecutterCompat: { + title: 'Cookiecutter compatibility mode', + description: + 'Enable features to maximise compatibility with templates built for fetch:cookiecutter', + type: 'boolean', + }, + replace: { + title: 'Replace file', + description: + 'If set, replace file in targetPath instead of overwriting existing one.', + type: 'boolean', + }, + token: { + title: 'Token', + description: + 'An optional token to use for authentication when reading the resources.', + type: 'string', + }, + }, + }, + }, + supportsDryRun: true, + async handler(ctx) { + ctx.logger.info('Fetching template file content from remote URL'); + + const workDir = await ctx.createTemporaryDirectory(); + // Write to a tmp file, render the template, then copy to workspace. + const tmpFilePath = path.join(workDir, 'tmp'); + + const outputPath = resolveSafeChildPath( + ctx.workspacePath, + ctx.input.targetPath, + ); + + if (fs.existsSync(outputPath) && !ctx.input.replace) { + ctx.logger.info( + `File ${ctx.input.targetPath} already exists in workspace, not replacing.`, + ); + return; + } + + await fetchFile({ + reader, + integrations, + baseUrl: ctx.templateInfo?.baseUrl, + fetchUrl: ctx.input.url, + outputPath: tmpFilePath, + token: ctx.input.token, + }); + + const { cookiecutterCompat, values } = ctx.input; + const context = { + [cookiecutterCompat ? 'cookiecutter' : 'values']: values, + }; + + ctx.logger.info( + `Processing template file with input values`, + ctx.input.values, + ); + + const renderTemplate = await SecureTemplater.loadRenderer({ + cookiecutterCompat, + templateFilters: { + ...defaultTemplateFilters, + ...additionalTemplateFilters, + }, + templateGlobals: additionalTemplateGlobals, + nunjucksConfigs: { + trimBlocks: ctx.input.trimBlocks, + lstripBlocks: ctx.input.lstripBlocks, + }, + }); + + const contents = await fs.readFile(tmpFilePath, 'utf-8'); + const result = renderTemplate(contents, context); + await fs.ensureDir(path.dirname(outputPath)); + await fs.outputFile(outputPath, result); + + ctx.logger.info(`Template file has been written to ${outputPath}`); + }, + }); +} diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/DatabaseTaskStore.test.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/DatabaseTaskStore.test.ts index 78a362b5c7..fbd314cbbc 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/DatabaseTaskStore.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/DatabaseTaskStore.test.ts @@ -16,7 +16,7 @@ import { DatabaseManager } from '@backstage/backend-common'; import { ConfigReader } from '@backstage/config'; -import { DatabaseTaskStore } from './DatabaseTaskStore'; +import { DatabaseTaskStore, RawDbTaskEventRow } from './DatabaseTaskStore'; import { TaskSpec } from '@backstage/plugin-scaffolder-common'; import { ConflictError } from '@backstage/errors'; import { createMockDirectory } from '@backstage/backend-test-utils'; @@ -75,6 +75,62 @@ describe('DatabaseTaskStore', () => { expect(tasks[0].id).toBeDefined(); }); + it('should allow paginating tasks', async () => { + const { store } = await createStore(); + await store.createTask({ + spec: {} as TaskSpec, + createdBy: 'me', + }); + + await store.createTask({ + spec: {} as TaskSpec, + createdBy: 'him', + }); + + const { tasks } = await store.list({ pagination: { limit: 1, offset: 0 } }); + expect(tasks.length).toBe(1); + expect(tasks[0].createdBy).toBe('me'); + expect(tasks[0].status).toBe('open'); + expect(tasks[0].id).toBeDefined(); + + const { tasks: tasks2 } = await store.list({ + pagination: { limit: 1, offset: 1 }, + }); + expect(tasks2.length).toBe(1); + expect(tasks2[0].createdBy).toBe('him'); + expect(tasks2[0].status).toBe('open'); + expect(tasks2[0].id).toBeDefined(); + }); + + it('should allow ordering tasks', async () => { + const { store } = await createStore(); + await store.createTask({ + spec: {} as TaskSpec, + createdBy: 'a', + }); + + await store.createTask({ + spec: {} as TaskSpec, + createdBy: 'b', + }); + + const { tasks } = await store.list({ + order: [{ field: 'created_by', order: 'asc' }], + }); + expect(tasks.length).toBe(2); + expect(tasks[0].createdBy).toBe('a'); + expect(tasks[0].status).toBe('open'); + expect(tasks[0].id).toBeDefined(); + + const { tasks: tasks2 } = await store.list({ + order: [{ field: 'created_by', order: 'desc' }], + }); + expect(tasks2.length).toBe(2); + expect(tasks2[0].createdBy).toBe('b'); + expect(tasks2[0].status).toBe('open'); + expect(tasks2[0].id).toBeDefined(); + }); + it('should list filtered created tasks by createdBy', async () => { const { store } = await createStore(); @@ -93,6 +149,14 @@ describe('DatabaseTaskStore', () => { expect(tasks[0].createdBy).toBe('him'); expect(tasks[0].status).toBe('open'); expect(tasks[0].id).toBeDefined(); + + const { tasks: tasks2 } = await store.list({ + filters: { createdBy: 'him' }, + }); + expect(tasks2.length).toBe(1); + expect(tasks2[0].createdBy).toBe('him'); + expect(tasks2[0].status).toBe('open'); + expect(tasks2[0].id).toBeDefined(); }); it('should list filtered created tasks by status', async () => { @@ -115,8 +179,43 @@ describe('DatabaseTaskStore', () => { eventBody: { message }, }); - const { tasks } = await store.list({ status: 'open' }); + const { tasks, totalTasks } = await store.list({ + status: 'open', + }); expect(tasks.length).toBe(1); + expect(totalTasks).toBe(1); + expect(tasks[0].createdBy).toBe('him'); + expect(tasks[0].status).toBe('open'); + expect(tasks[0].id).toBeDefined(); + + const { tasks: tasks2, totalTasks: totalTasks2 } = await store.list({ + filters: { status: ['open'] }, + }); + expect(tasks2.length).toBe(1); + expect(totalTasks2).toBe(1); + expect(tasks2[0].createdBy).toBe('him'); + expect(tasks2[0].status).toBe('open'); + expect(tasks2[0].id).toBeDefined(); + }); + + it('should limit and offset based on parameters', async () => { + const { store } = await createStore(); + + await store.createTask({ + spec: {} as TaskSpec, + createdBy: 'me', + }); + + await store.createTask({ + spec: {} as TaskSpec, + createdBy: 'him', + }); + + const { tasks, totalTasks } = await store.list({ + pagination: { limit: 1, offset: 1 }, + }); + expect(tasks.length).toBe(1); + expect(totalTasks).toBe(2); expect(tasks[0].createdBy).toBe('him'); expect(tasks[0].status).toBe('open'); expect(tasks[0].id).toBeDefined(); @@ -168,6 +267,48 @@ describe('DatabaseTaskStore', () => { expect(event.type).toBe('log'); }); + it('should be able to retied cancelled recoverable task', async () => { + const { store, manager } = await createStore(); + const client = await manager.getClient(); + + const { taskId } = await store.createTask({ + spec: { + EXPERIMENTAL_recovery: { EXPERIMENTAL_strategy: 'startOver' }, + } as TaskSpec, + createdBy: 'me#too', + }); + await store.completeTask({ taskId, status: 'cancelled', eventBody: {} }); + + await store.retryTask?.({ taskId }); + + const taskAfterRetry = await store.getTask(taskId); + expect(taskAfterRetry.status).toBe('open'); + + expect( + await client('task_events') + .where({ + task_id: taskId, + event_type: 'recovered', + }) + .select(['body', 'event_type', 'task_id']), + ).toEqual([ + { + body: JSON.stringify({ recoverStrategy: 'startOver' }), + event_type: 'recovered', + task_id: taskId, + }, + ]); + + expect( + await client('task_events') + .where({ + task_id: taskId, + }) + .andWhere(q => q.whereIn('event_type', ['cancelled', 'completion'])) + .select(['body', 'event_type', 'task_id']), + ).toEqual([]); + }); + it('should complete the task', async () => { const { store } = await createStore(); const { taskId } = await store.createTask({ diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/DatabaseTaskStore.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/DatabaseTaskStore.ts index 23fe793432..65bafca619 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/DatabaseTaskStore.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/DatabaseTaskStore.ts @@ -44,6 +44,7 @@ import { restoreWorkspace, serializeWorkspace, } from '@backstage/plugin-scaffolder-node/alpha'; +import { flattenParams } from '../../service/helpers'; const migrationsDir = resolvePackagePath( '@backstage/plugin-scaffolder-backend', @@ -183,20 +184,58 @@ export class DatabaseTaskStore implements TaskStore { async list(options: { createdBy?: string; status?: TaskStatus; - }): Promise<{ tasks: SerializedTask[] }> { - const queryBuilder = this.db('tasks'); + filters?: { + createdBy?: string | string[]; + status?: TaskStatus | TaskStatus[]; + }; + pagination?: { + limit?: number; + offset?: number; + }; + order?: { order: 'asc' | 'desc'; field: string }[]; + }): Promise<{ tasks: SerializedTask[]; totalTasks?: number }> { + const { createdBy, status, pagination, order, filters } = options ?? {}; + const queryBuilder = this.db('tasks'); - if (options.createdBy) { - queryBuilder.where({ - created_by: options.createdBy, + if (createdBy || filters?.createdBy) { + const arr: string[] = flattenParams( + createdBy, + filters?.createdBy, + ); + queryBuilder.whereIn('created_by', [...new Set(arr)]); + } + + if (status || filters?.status) { + const arr: TaskStatus[] = flattenParams( + status, + filters?.status, + ); + queryBuilder.whereIn('status', [...new Set(arr)]); + } + + if (order) { + order.forEach(f => { + queryBuilder.orderBy(f.field, f.order); }); + } else { + queryBuilder.orderBy('created_at', 'desc'); } - if (options.status) { - queryBuilder.where({ status: options.status }); + const countQuery = queryBuilder.clone(); + countQuery.count('tasks.id', { as: 'count' }); + + if (pagination?.limit !== undefined) { + queryBuilder.limit(pagination.limit); } - const results = await queryBuilder.orderBy('created_at', 'desc').select(); + if (pagination?.offset !== undefined) { + queryBuilder.offset(pagination.offset); + } + + const [results, [{ count }]] = await Promise.all([ + queryBuilder.select(), + countQuery, + ]); const tasks = results.map(result => ({ id: result.id, @@ -207,7 +246,7 @@ export class DatabaseTaskStore implements TaskStore { createdAt: parseSqlDateToIsoString(result.created_at), })); - return { tasks }; + return { tasks, totalTasks: count }; } async getTask(taskId: string): Promise { @@ -445,7 +484,7 @@ export class DatabaseTaskStore implements TaskStore { async listEvents( options: TaskStoreListEventsOptions, ): Promise<{ events: SerializedTaskEvent[] }> { - const { taskId, after } = options; + const { isTaskRecoverable, taskId, after } = options; const rawEvents = await this.db('task_events') .where({ task_id: taskId, @@ -463,6 +502,7 @@ export class DatabaseTaskStore implements TaskStore { const body = JSON.parse(event.body) as JsonObject; return { id: Number(event.id), + isTaskRecoverable, taskId, body, type: event.event_type, @@ -563,6 +603,44 @@ export class DatabaseTaskStore implements TaskStore { }); } + async retryTask?(options: { taskId: string }): Promise { + await this.db.transaction(async tx => { + const result = await tx('tasks') + .where('id', options.taskId) + .update( + { + status: 'open', + last_heartbeat_at: this.db.fn.now(), + }, + ['id', 'spec'], + ); + + for (const { id, spec } of result) { + const taskSpec = JSON.parse(spec as string) as TaskSpec; + + /** + * Once task is picked up, all event types are replayed. + * We have to remove cancelled or completion event_type as these are as actions for frontend to perform. + * In contrary, we send 'recovered' event_type to reset the state on the frontend side. + * + */ + await tx('task_events') + .where('task_id', id) + .andWhere(q => q.whereIn('event_type', ['cancelled', 'completion'])) + .del(); + + await tx('task_events').insert({ + task_id: id, + event_type: 'recovered', + body: JSON.stringify({ + recoverStrategy: + taskSpec.EXPERIMENTAL_recovery?.EXPERIMENTAL_strategy ?? 'none', + }), + }); + } + }); + } + async recoverTasks( options: TaskStoreRecoverTaskOptions, ): Promise<{ ids: string[] }> { diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.test.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.test.ts index aece424f5f..44f8836fd1 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.test.ts @@ -601,11 +601,11 @@ describe('NunjucksWorkflowRunner', () => { return Promise.resolve({ state: { checkpoints: { - ['v1.task.checkpoint.key1']: { + ['v1.task.checkpoint.test.key1']: { status: 'success', value: 'initial', }, - ['v1.task.checkpoint.key2']: { + ['v1.task.checkpoint.test2.key2']: { status: 'failed', reason: 'fatal error', }, diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.ts index 09fc162ea6..6de51ea3b6 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.ts @@ -375,7 +375,7 @@ export class NunjucksWorkflowRunner implements WorkflowRunner { keySuffix: string, fn: () => Promise, ) { - const key = `v1.task.checkpoint.${keySuffix}`; + const key = `v1.task.checkpoint.${step.id}.${keySuffix}`; try { let prevValue: U | undefined; if (prevTaskState) { diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.test.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.test.ts index ec2a81680d..c617a4a84e 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.test.ts @@ -21,8 +21,8 @@ import { import { ConfigReader } from '@backstage/config'; import { TaskSpec } from '@backstage/plugin-scaffolder-common'; import { - TaskSecrets, SerializedTaskEvent, + TaskSecrets, } from '@backstage/plugin-scaffolder-node'; import { DatabaseTaskStore } from './DatabaseTaskStore'; import { StorageTaskBroker, TaskManager } from './StorageTaskBroker'; @@ -231,6 +231,7 @@ describe('StorageTaskBroker', () => { id: taskId, }), ]), + totalTasks: 13, }); }); @@ -243,8 +244,30 @@ describe('StorageTaskBroker', () => { const task = await storage.getTask(taskId); - const promise = broker.list({ createdBy: 'user:default/foo' }); - await expect(promise).resolves.toEqual({ tasks: [task] }); + const promise = broker.list({ + filters: { createdBy: ['user:default/foo'] }, + }); + await expect(promise).resolves.toEqual({ tasks: [task], totalTasks: 1 }); + }); + + it('should list only tasks with specific status', async () => { + const broker = new StorageTaskBroker(storage, logger); + const { taskId } = await broker.dispatch({ + spec: { steps: [] } as unknown as TaskSpec, + createdBy: 'user:default/foo', + }); + + const promise = broker.list({ + filters: { status: ['open'] }, + }); + await expect(promise).resolves.toEqual({ + tasks: expect.arrayContaining([ + expect.objectContaining({ + id: taskId, + }), + ]), + totalTasks: 3, + }); }); it('should handle checkpoints in task state', async () => { diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.ts index d17fb33b3b..1da2b4b349 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.ts @@ -254,7 +254,9 @@ export interface CurrentClaimedTask { * The creator of the task. */ createdBy?: string; - + /** + * The workspace of the task. + */ workspace?: Promise; } @@ -281,16 +283,22 @@ export class StorageTaskBroker implements TaskBroker { async list(options?: { createdBy?: string; status?: TaskStatus; - }): Promise<{ tasks: SerializedTask[] }> { + filters?: { + createdBy?: string | string[]; + status?: TaskStatus | TaskStatus[]; + }; + pagination?: { + limit?: number; + offset?: number; + }; + order?: { order: 'asc' | 'desc'; field: string }[]; + }): Promise<{ tasks: SerializedTask[]; totalTasks?: number }> { if (!this.storage.list) { throw new Error( 'TaskStore does not implement the list method. Please implement the list method to be able to list tasks', ); } - return await this.storage.list({ - createdBy: options?.createdBy, - status: options?.status, - }); + return await this.storage.list(options ?? {}); } private deferredDispatch = defer(); @@ -311,7 +319,7 @@ export class StorageTaskBroker implements TaskBroker { shouldUnsubscribe = true; } - if (event.type === 'completion') { + if (event.type === 'completion' && !event.isTaskRecoverable) { shouldUnsubscribe = true; } } @@ -410,8 +418,17 @@ export class StorageTaskBroker implements TaskBroker { let cancelled = false; (async () => { + const task = await this.storage.getTask(taskId); + const isTaskRecoverable = + task.spec.EXPERIMENTAL_recovery?.EXPERIMENTAL_strategy === + 'startOver'; + while (!cancelled) { - const result = await this.storage.listEvents({ taskId, after }); + const result = await this.storage.listEvents({ + isTaskRecoverable, + taskId, + after, + }); const { events } = result; if (events.length) { after = events[events.length - 1].id; @@ -479,4 +496,9 @@ export class StorageTaskBroker implements TaskBroker { }, }); } + + async retry?(taskId: string): Promise { + await this.storage.retryTask?.({ taskId }); + this.signalDispatch(); + } } diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/WorkspaceService.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/WorkspaceService.ts index ab424806bf..bb3ce448fc 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/WorkspaceService.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/WorkspaceService.ts @@ -19,6 +19,7 @@ import { CurrentClaimedTask } from './StorageTaskBroker'; import { WorkspaceProvider } from '@backstage/plugin-scaffolder-node/alpha'; import { DatabaseWorkspaceProvider } from './DatabaseWorkspaceProvider'; import { TaskStore } from './types'; +import fs from 'fs-extra'; export interface WorkspaceService { serializeWorkspace(options: { path: string }): Promise; @@ -74,6 +75,7 @@ export class DefaultWorkspaceService implements WorkspaceService { targetPath: string; }): Promise { if (this.isWorkspaceSerializationEnabled()) { + await fs.mkdirp(options.targetPath); await this.workspaceProvider.rehydrateWorkspace(options); } } diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/types.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/types.ts index 89bcce3cc9..874793922f 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/types.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/types.ts @@ -119,6 +119,7 @@ export type TaskStoreEmitOptions = { * @public */ export type TaskStoreListEventsOptions = { + isTaskRecoverable?: boolean; taskId: string; after?: number | undefined; }; @@ -170,6 +171,8 @@ export interface TaskStore { options: TaskStoreCreateTaskOptions, ): Promise; + retryTask?(options: { taskId: string }): Promise; + recoverTasks?( options: TaskStoreRecoverTaskOptions, ): Promise<{ ids: string[] }>; @@ -190,10 +193,34 @@ export interface TaskStore { tasks: { taskId: string }[]; }>; + list?(options: { + filters?: { + createdBy?: string | string[]; + status?: TaskStatus | TaskStatus[]; + }; + pagination?: { + limit?: number; + offset?: number; + }; + order?: { order: 'asc' | 'desc'; field: string }[]; + }): Promise<{ tasks: SerializedTask[]; totalTasks?: number }>; + + /** + * @deprecated Make sure to pass `createdBy` and `status` in the `filters` parameter instead + */ list?(options: { createdBy?: string; status?: TaskStatus; - }): Promise<{ tasks: SerializedTask[] }>; + filters?: { + createdBy?: string | string[]; + status?: TaskStatus | TaskStatus[]; + }; + pagination?: { + limit?: number; + offset?: number; + }; + order?: { order: 'asc' | 'desc'; field: string }[]; + }): Promise<{ tasks: SerializedTask[]; totalTasks?: number }>; emitLogEvent(options: TaskStoreEmitOptions): Promise; diff --git a/plugins/scaffolder-backend/src/service/helpers.test.ts b/plugins/scaffolder-backend/src/service/helpers.test.ts new file mode 100644 index 0000000000..fb8d9ae406 --- /dev/null +++ b/plugins/scaffolder-backend/src/service/helpers.test.ts @@ -0,0 +1,74 @@ +/* + * 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 { flattenParams, parseNumberParam, parseStringsParam } from './helpers'; + +describe('parseStringsParam', () => { + it('should parse a single string', () => { + expect(parseStringsParam('hello', 'param')).toEqual(['hello']); + }); + + it('should parse an array of strings', () => { + expect(parseStringsParam(['hello', 'world'], 'param')).toEqual([ + 'hello', + 'world', + ]); + }); + + it('should return undefined for undefined', () => { + expect(parseStringsParam(undefined, 'param')).toBeUndefined(); + }); + + it('should throw an error for non-string values', () => { + expect(() => parseStringsParam(5, 'param')).toThrow( + 'Invalid param, not a string or array of strings', + ); + }); +}); + +describe('parseNumberParam', () => { + it('should parse a number', () => { + expect(parseNumberParam('5', 'param')).toEqual([5]); + }); + + it('should throw an error for a non-number', () => { + expect(() => parseNumberParam('hello', 'param')).toThrow( + 'Invalid param parameter "hello", expected a number or array of numbers', + ); + }); + + it('should return undefined for undefined', () => { + expect(parseNumberParam(undefined, 'param')).toBeUndefined(); + }); +}); + +describe('flattenParams', () => { + it('should flatten a single string', () => { + expect(flattenParams('hello')).toEqual(['hello']); + }); + + it('should flatten an array of strings', () => { + expect(flattenParams(['hello', 'world'])).toEqual([ + 'hello', + 'world', + ]); + }); + + it('should flatten mixed parameters', () => { + expect(flattenParams(['hello', 'world'], 'foo', undefined)).toEqual( + ['hello', 'world', 'foo'], + ); + }); +}); diff --git a/plugins/scaffolder-backend/src/service/helpers.ts b/plugins/scaffolder-backend/src/service/helpers.ts index 3412fec2d3..cd55068d98 100644 --- a/plugins/scaffolder-backend/src/service/helpers.ts +++ b/plugins/scaffolder-backend/src/service/helpers.ts @@ -16,11 +16,11 @@ import { CatalogApi } from '@backstage/catalog-client'; import { - Entity, ANNOTATION_LOCATION, - parseLocationRef, ANNOTATION_SOURCE_LOCATION, CompoundEntityRef, + Entity, + parseLocationRef, stringifyEntityRef, } from '@backstage/catalog-model'; import { Config } from '@backstage/config'; @@ -107,3 +107,44 @@ export async function findTemplate(options: { return template as TemplateEntityV1beta3; } + +/** + * Takes a single unknown parameter and makes sure that it's a single string or + * an array of strings, and returns as an array. + */ +export function parseStringsParam( + param: unknown, + paramName: string, +): string[] | undefined { + if (param === undefined) { + return undefined; + } + + const array = [param].flat(); + if (array.some(p => typeof p !== 'string')) { + throw new InputError( + `Invalid ${paramName}, not a string or array of strings`, + ); + } + + return array as string[]; +} + +export function parseNumberParam( + param: unknown, + paramName: string, +): number[] | undefined { + return parseStringsParam(param, paramName)?.map(val => { + const ret = Number.parseInt(val, 10); + if (isNaN(ret)) { + throw new InputError( + `Invalid ${paramName} parameter "${val}", expected a number or array of numbers`, + ); + } + return ret; + }); +} + +export function flattenParams(...params: (undefined | T | T[])[]): T[] { + return [...params].flat().filter(Boolean) as T[]; +} diff --git a/plugins/scaffolder-backend/src/service/router.test.ts b/plugins/scaffolder-backend/src/service/router.test.ts index 9673d19255..715ada5de1 100644 --- a/plugins/scaffolder-backend/src/service/router.test.ts +++ b/plugins/scaffolder-backend/src/service/router.test.ts @@ -19,7 +19,6 @@ import { loggerToWinstonLogger, PluginDatabaseManager, } from '@backstage/backend-common'; -import { CatalogApi } from '@backstage/catalog-client'; import { ConfigReader } from '@backstage/config'; import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common'; import express from 'express'; @@ -51,6 +50,7 @@ import { } from '@backstage/backend-test-utils'; import { AutocompleteHandler } from '@backstage/plugin-scaffolder-node/alpha'; import { UrlReaders } from '@backstage/backend-defaults/urlReader'; +import { catalogServiceMock } from '@backstage/plugin-catalog-node/testUtils'; const mockAccess = jest.fn(); @@ -91,7 +91,7 @@ describe('createRouter', () => { let app: express.Express; let loggerSpy: jest.SpyInstance; let taskBroker: TaskBroker; - const catalogClient = { getEntityByRef: jest.fn() } as unknown as CatalogApi; + const catalogClient = catalogServiceMock.mock(); const permissionApi = { authorize: jest.fn(), authorizeConditional: jest.fn(), @@ -214,21 +214,19 @@ describe('createRouter', () => { }); app = express().use(router); - jest - .spyOn(catalogClient, 'getEntityByRef') - .mockImplementation(async ref => { - const { kind } = parseEntityRef(ref); + catalogClient.getEntityByRef.mockImplementation(async ref => { + const { kind } = parseEntityRef(ref); - if (kind.toLocaleLowerCase() === 'template') { - return getMockTemplate(); - } + if (kind.toLocaleLowerCase() === 'template') { + return getMockTemplate(); + } - if (kind.toLocaleLowerCase() === 'user') { - return mockUser; - } + if (kind.toLocaleLowerCase() === 'user') { + return mockUser; + } - throw new Error(`no mock found for kind: ${kind}`); - }); + throw new Error(`no mock found for kind: ${kind}`); + }); jest .spyOn(permissionApi, 'authorizeConditional') @@ -399,11 +397,13 @@ describe('createRouter', () => { createdBy: '', }, ], + totalTasks: 1, }); const response = await request(app).get(`/v2/tasks`); expect(taskBroker.list).toHaveBeenCalledWith({ - createdBy: undefined, + filters: {}, + pagination: {}, }); expect(response.status).toEqual(200); expect(response.body).toStrictEqual({ @@ -416,6 +416,7 @@ describe('createRouter', () => { createdBy: '', }, ], + totalTasks: 1, }); }); @@ -432,15 +433,12 @@ describe('createRouter', () => { createdBy: 'user:default/foo', }, ], + totalTasks: 1, }); const response = await request(app).get( - `/v2/tasks?createdBy=user:default/foo&status=completed`, + `/v2/tasks?createdBy=user:default/foo&createdBy=user:default/bar&status=completed&status=open&limit=1&offset=0&order=desc:created_at`, ); - expect(taskBroker.list).toHaveBeenCalledWith({ - createdBy: 'user:default/foo', - status: 'completed', - }); expect(response.status).toEqual(200); expect(response.body).toStrictEqual({ @@ -453,6 +451,18 @@ describe('createRouter', () => { createdBy: 'user:default/foo', }, ], + totalTasks: 1, + }); + expect(taskBroker.list).toHaveBeenCalledWith({ + filters: { + createdBy: ['user:default/foo', 'user:default/bar'], + status: ['completed', 'open'], + }, + pagination: { + limit: 1, + offset: 0, + }, + order: [{ order: 'desc', field: 'created_at' }], }); }); }); @@ -703,8 +713,6 @@ data: {"id":1,"taskId":"a-random-id","type":"completion","createdAt":"","body":{ const mockToken = mockCredentials.user.token(); const mockTemplate = getMockTemplate(); - const catalogSpy = jest.spyOn(catalogClient, 'getEntityByRef'); - await request(app) .post('/v2/dry-run') .set('Authorization', `Bearer ${mockToken}`) @@ -717,9 +725,9 @@ data: {"id":1,"taskId":"a-random-id","type":"completion","createdAt":"","body":{ directoryContents: [], }); - expect(catalogSpy).toHaveBeenCalledTimes(1); + expect(catalogClient.getEntityByRef).toHaveBeenCalledTimes(1); - expect(catalogSpy).toHaveBeenCalledWith( + expect(catalogClient.getEntityByRef).toHaveBeenCalledWith( 'user:default/mock', expect.anything(), ); @@ -755,20 +763,18 @@ data: {"id":1,"taskId":"a-random-id","type":"completion","createdAt":"","body":{ }); app = express().use(router); - jest - .spyOn(catalogClient, 'getEntityByRef') - .mockImplementation(async ref => { - const { kind } = parseEntityRef(ref); + catalogClient.getEntityByRef.mockImplementation(async ref => { + const { kind } = parseEntityRef(ref); - if (kind.toLocaleLowerCase() === 'template') { - return getMockTemplate(); - } + if (kind.toLocaleLowerCase() === 'template') { + return getMockTemplate(); + } - if (kind.toLocaleLowerCase() === 'user') { - return mockUser; - } - throw new Error(`no mock found for kind: ${kind}`); - }); + if (kind.toLocaleLowerCase() === 'user') { + return mockUser; + } + throw new Error(`no mock found for kind: ${kind}`); + }); jest .spyOn(permissionApi, 'authorizeConditional') @@ -1198,11 +1204,13 @@ data: {"id":1,"taskId":"a-random-id","type":"completion","createdAt":"","body":{ createdBy: '', }, ], + totalTasks: 1, }); const response = await request(app).get(`/v2/tasks`); expect(taskBroker.list).toHaveBeenCalledWith({ - createdBy: undefined, + pagination: {}, + filters: {}, }); expect(response.status).toEqual(200); expect(response.body).toStrictEqual({ @@ -1215,6 +1223,7 @@ data: {"id":1,"taskId":"a-random-id","type":"completion","createdAt":"","body":{ createdBy: '', }, ], + totalTasks: 1, }); }); @@ -1231,13 +1240,17 @@ data: {"id":1,"taskId":"a-random-id","type":"completion","createdAt":"","body":{ createdBy: 'user:default/foo', }, ], + totalTasks: 1, }); const response = await request(app).get( `/v2/tasks?createdBy=user:default/foo`, ); expect(taskBroker.list).toHaveBeenCalledWith({ - createdBy: 'user:default/foo', + filters: { + createdBy: ['user:default/foo'], + }, + pagination: {}, }); expect(response.status).toEqual(200); @@ -1251,6 +1264,7 @@ data: {"id":1,"taskId":"a-random-id","type":"completion","createdAt":"","body":{ createdBy: 'user:default/foo', }, ], + totalTasks: 1, }); }); }); diff --git a/plugins/scaffolder-backend/src/service/router.ts b/plugins/scaffolder-backend/src/service/router.ts index 3eec4e4450..80406496d2 100644 --- a/plugins/scaffolder-backend/src/service/router.ts +++ b/plugins/scaffolder-backend/src/service/router.ts @@ -69,7 +69,13 @@ import { } from '../scaffolder'; import { createDryRunner } from '../scaffolder/dryrun'; import { StorageTaskBroker } from '../scaffolder/tasks/StorageTaskBroker'; -import { findTemplate, getEntityBaseUrl, getWorkingDirectory } from './helpers'; +import { + findTemplate, + getEntityBaseUrl, + getWorkingDirectory, + parseNumberParam, + parseStringsParam, +} from './helpers'; import { PermissionRuleParams } from '@backstage/plugin-permission-common'; import { createConditionAuthorizer, @@ -81,13 +87,13 @@ import { Duration } from 'luxon'; import { AuthService, BackstageCredentials, + DatabaseService, DiscoveryService, HttpAuthService, LifecycleService, PermissionsService, - UrlReaderService, SchedulerService, - DatabaseService, + UrlReaderService, } from '@backstage/backend-plugin-api'; import { IdentityApi, @@ -576,31 +582,42 @@ export async function createRouter( permissionService: permissions, }); - const [userEntityRef] = [req.query.createdBy].flat(); - if ( - typeof userEntityRef !== 'string' && - typeof userEntityRef !== 'undefined' - ) { - throw new InputError('createdBy query parameter must be a string'); - } - if (!taskBroker.list) { throw new Error( 'TaskBroker does not support listing tasks, please implement the list method on the TaskBroker.', ); } - const [statusQuery] = [req.query.status].flat(); - if ( - typeof statusQuery !== 'string' && - typeof statusQuery !== 'undefined' - ) { - throw new InputError('status query parameter must be a string'); - } + const createdBy = parseStringsParam(req.query.createdBy, 'createdBy'); + const status = parseStringsParam(req.query.status, 'status'); + + const order = parseStringsParam(req.query.order, 'order')?.map(item => { + const match = item.match(/^(asc|desc):(.+)$/); + if (!match) { + throw new InputError( + `Invalid order parameter "${item}", expected ":"`, + ); + } + + return { + order: match[1] as 'asc' | 'desc', + field: match[2], + }; + }); + + const limit = parseNumberParam(req.query.limit, 'limit'); + const offset = parseNumberParam(req.query.offset, 'offset'); const tasks = await taskBroker.list({ - createdBy: userEntityRef, - status: statusQuery ? (statusQuery as TaskStatus) : undefined, + filters: { + createdBy, + status: status ? (status as TaskStatus[]) : undefined, + }, + order, + pagination: { + limit: limit ? limit[0] : undefined, + offset: offset ? offset[0] : undefined, + }, }); res.status(200).json(tasks); @@ -635,6 +652,19 @@ export async function createRouter( await taskBroker.cancel?.(taskId); res.status(200).json({ status: 'cancelled' }); }) + .post('/v2/tasks/:taskId/retry', async (req, res) => { + const credentials = await httpAuth.credentials(req); + // Requires both read and cancel permissions + await checkPermission({ + credentials, + permissions: [taskCreatePermission, taskReadPermission], + permissionService: permissions, + }); + + const { taskId } = req.params; + await taskBroker.retry?.(taskId); + res.status(201).json({ id: taskId }); + }) .get('/v2/tasks/:taskId/eventstream', async (req, res) => { const credentials = await httpAuth.credentials(req); await checkPermission({ @@ -670,7 +700,7 @@ export async function createRouter( res.write( `event: ${event.type}\ndata: ${JSON.stringify(event)}\n\n`, ); - if (event.type === 'completion') { + if (event.type === 'completion' && !event.isTaskRecoverable) { shouldUnsubscribe = true; } } diff --git a/plugins/scaffolder-common/CHANGELOG.md b/plugins/scaffolder-common/CHANGELOG.md index 7e121a4e93..010ead4618 100644 --- a/plugins/scaffolder-common/CHANGELOG.md +++ b/plugins/scaffolder-common/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-scaffolder-common +## 1.5.6 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.0 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.8.1 + ## 1.5.5 ### Patch Changes diff --git a/plugins/scaffolder-common/package.json b/plugins/scaffolder-common/package.json index 2dced65144..e987313b16 100644 --- a/plugins/scaffolder-common/package.json +++ b/plugins/scaffolder-common/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-common", - "version": "1.5.5", + "version": "1.5.6", "description": "Common functionalities for the scaffolder, to be shared between scaffolder and scaffolder-backend plugin", "backstage": { "role": "common-library", diff --git a/plugins/scaffolder-common/api-report-alpha.md b/plugins/scaffolder-common/report-alpha.api.md similarity index 100% rename from plugins/scaffolder-common/api-report-alpha.md rename to plugins/scaffolder-common/report-alpha.api.md diff --git a/plugins/scaffolder-common/api-report.md b/plugins/scaffolder-common/report.api.md similarity index 77% rename from plugins/scaffolder-common/api-report.md rename to plugins/scaffolder-common/report.api.md index 8d7a61910d..2058c08203 100644 --- a/plugins/scaffolder-common/api-report.md +++ b/plugins/scaffolder-common/report.api.md @@ -123,4 +123,15 @@ export interface TemplatePresentationV1beta3 extends JsonObject { export interface TemplateRecoveryV1beta3 extends JsonObject { EXPERIMENTAL_strategy?: 'none' | 'startOver'; } + +// Warnings were encountered during analysis: +// +// src/TemplateEntityV1beta3.d.ts:102:5 - (ae-undocumented) Missing documentation for "id". +// src/TemplateEntityV1beta3.d.ts:103:5 - (ae-undocumented) Missing documentation for "name". +// src/TemplateEntityV1beta3.d.ts:104:5 - (ae-undocumented) Missing documentation for "action". +// src/TemplateEntityV1beta3.d.ts:105:5 - (ae-undocumented) Missing documentation for "input". +// src/TemplateEntityV1beta3.d.ts:106:5 - (ae-undocumented) Missing documentation for "if". +// src/TemplateEntityV1beta3.d.ts:107:5 - (ae-undocumented) Missing documentation for ""backstage:permissions"". +// src/TemplateEntityV1beta3.d.ts:115:5 - (ae-undocumented) Missing documentation for ""backstage:permissions"". +// src/TemplateEntityV1beta3.d.ts:123:5 - (ae-undocumented) Missing documentation for "tags". ``` diff --git a/plugins/scaffolder-node-test-utils/CHANGELOG.md b/plugins/scaffolder-node-test-utils/CHANGELOG.md index fef8549682..e69db86ff6 100644 --- a/plugins/scaffolder-node-test-utils/CHANGELOG.md +++ b/plugins/scaffolder-node-test-utils/CHANGELOG.md @@ -1,5 +1,45 @@ # @backstage/plugin-scaffolder-node-test-utils +## 0.1.13-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/backend-test-utils@1.0.1-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.5.0-next.1 + +## 0.1.13-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.5.0-next.0 + - @backstage/backend-test-utils@1.0.1-next.0 + - @backstage/types@1.1.1 + +## 0.1.12 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-test-utils@1.0.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.11 + +## 0.1.12-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-test-utils@1.0.0-next.2 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.11-next.2 + ## 0.1.12-next.1 ### Patch Changes diff --git a/plugins/scaffolder-node-test-utils/package.json b/plugins/scaffolder-node-test-utils/package.json index 4b32bf3d95..4fa6505b01 100644 --- a/plugins/scaffolder-node-test-utils/package.json +++ b/plugins/scaffolder-node-test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-node-test-utils", - "version": "0.1.12-next.1", + "version": "0.1.13-next.1", "backstage": { "role": "node-library", "pluginId": "scaffolder", @@ -40,13 +40,27 @@ "test": "backstage-cli package test" }, "dependencies": { - "@backstage/backend-common": "workspace:^", + "@backstage/backend-common": "^0.25.0", "@backstage/backend-test-utils": "workspace:^", "@backstage/plugin-scaffolder-node": "workspace:^", "@backstage/types": "workspace:^" }, "devDependencies": { "@backstage/cli": "workspace:^", - "@types/react": "*" + "@types/react": "^18.0.0", + "react": "^18.0.2", + "react-dom": "^18.0.2", + "react-router-dom": "^6.3.0" + }, + "peerDependencies": { + "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } } diff --git a/plugins/scaffolder-node-test-utils/api-report.md b/plugins/scaffolder-node-test-utils/report.api.md similarity index 100% rename from plugins/scaffolder-node-test-utils/api-report.md rename to plugins/scaffolder-node-test-utils/report.api.md diff --git a/plugins/scaffolder-node/CHANGELOG.md b/plugins/scaffolder-node/CHANGELOG.md index 887fac33d1..bea5425aa6 100644 --- a/plugins/scaffolder-node/CHANGELOG.md +++ b/plugins/scaffolder-node/CHANGELOG.md @@ -1,5 +1,61 @@ # @backstage/plugin-scaffolder-node +## 0.5.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.15.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.6 + +## 0.5.0-next.0 + +### Minor Changes + +- 3ec4e6d: Added pagination support for listing of tasks and the ability to filter on several users and task statuses. + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- 11e0752: Make it possible to manually retry the scaffolder template from the step it failed +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.15.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.6 + +## 0.4.11 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/integration@1.15.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.6 + +## 0.4.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/integration@1.15.0-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.5 + ## 0.4.11-next.1 ### Patch Changes diff --git a/plugins/scaffolder-node/package.json b/plugins/scaffolder-node/package.json index 42291dd081..6b2e884443 100644 --- a/plugins/scaffolder-node/package.json +++ b/plugins/scaffolder-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-node", - "version": "0.4.11-next.1", + "version": "0.5.0-next.1", "description": "The plugin-scaffolder-node module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "node-library", @@ -54,7 +54,7 @@ "test": "backstage-cli package test" }, "dependencies": { - "@backstage/backend-common": "workspace:^", + "@backstage/backend-common": "^0.25.0", "@backstage/backend-plugin-api": "workspace:^", "@backstage/catalog-model": "workspace:^", "@backstage/errors": "workspace:^", diff --git a/plugins/scaffolder-node/api-report-alpha.md b/plugins/scaffolder-node/report-alpha.api.md similarity index 77% rename from plugins/scaffolder-node/api-report-alpha.md rename to plugins/scaffolder-node/report-alpha.api.md index c9b8130f0e..2258515b6d 100644 --- a/plugins/scaffolder-node/api-report-alpha.md +++ b/plugins/scaffolder-node/report-alpha.api.md @@ -109,5 +109,17 @@ export interface WorkspaceProvider { }): Promise; } +// Warnings were encountered during analysis: +// +// src/alpha.d.ts:9:5 - (ae-undocumented) Missing documentation for "addActions". +// src/alpha.d.ts:23:5 - (ae-undocumented) Missing documentation for "setTaskBroker". +// src/alpha.d.ts:37:5 - (ae-undocumented) Missing documentation for "addTemplateFilters". +// src/alpha.d.ts:38:5 - (ae-undocumented) Missing documentation for "addTemplateGlobals". +// src/alpha.d.ts:64:5 - (ae-undocumented) Missing documentation for "addAutocompleteProvider". +// src/alpha.d.ts:81:5 - (ae-undocumented) Missing documentation for "serializeWorkspace". +// src/alpha.d.ts:85:5 - (ae-undocumented) Missing documentation for "cleanWorkspace". +// src/alpha.d.ts:88:5 - (ae-undocumented) Missing documentation for "rehydrateWorkspace". +// src/alpha.d.ts:99:5 - (ae-undocumented) Missing documentation for "addProviders". + // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/scaffolder-node/api-report.md b/plugins/scaffolder-node/report.api.md similarity index 68% rename from plugins/scaffolder-node/api-report.md rename to plugins/scaffolder-node/report.api.md index 8b38008eee..c6cabda02c 100644 --- a/plugins/scaffolder-node/api-report.md +++ b/plugins/scaffolder-node/report.api.md @@ -292,6 +292,7 @@ export type SerializedTask = { // @public export type SerializedTaskEvent = { id: number; + isTaskRecoverable?: boolean; taskId: string; body: JsonObject; type: TaskEventType; @@ -315,12 +316,33 @@ export interface TaskBroker { // (undocumented) get(taskId: string): Promise; // (undocumented) - list?(options?: { createdBy?: string; status?: TaskStatus }): Promise<{ + list?(options?: { + filters?: { + createdBy?: string | string[]; + status?: TaskStatus | TaskStatus[]; + }; + pagination?: { + limit?: number; + offset?: number; + }; + order?: { + order: 'asc' | 'desc'; + field: string; + }[]; + }): Promise<{ tasks: SerializedTask[]; + totalTasks?: number; + }>; + // @deprecated (undocumented) + list?(options: { createdBy?: string; status?: TaskStatus }): Promise<{ + tasks: SerializedTask[]; + totalTasks?: number; }>; // (undocumented) recoverTasks?(): Promise; // (undocumented) + retry?(taskId: string): Promise; + // (undocumented) vacuumTasks(options: { timeoutS: number }): Promise; } @@ -459,4 +481,51 @@ export type TemplateFilter = (...args: JsonValue[]) => JsonValue | undefined; export type TemplateGlobal = | ((...args: JsonValue[]) => JsonValue | undefined) | JsonValue; + +// Warnings were encountered during analysis: +// +// src/actions/createTemplateAction.d.ts:6:1 - (ae-undocumented) Missing documentation for "TemplateExample". +// src/actions/createTemplateAction.d.ts:11:1 - (ae-undocumented) Missing documentation for "TemplateActionOptions". +// src/actions/gitHelpers.d.ts:5:1 - (ae-undocumented) Missing documentation for "initRepoAndPush". +// src/actions/gitHelpers.d.ts:27:1 - (ae-undocumented) Missing documentation for "commitAndPushRepo". +// src/actions/gitHelpers.d.ts:49:1 - (ae-undocumented) Missing documentation for "cloneRepo". +// src/actions/gitHelpers.d.ts:66:1 - (ae-undocumented) Missing documentation for "createBranch". +// src/actions/gitHelpers.d.ts:80:1 - (ae-undocumented) Missing documentation for "addFiles". +// src/actions/gitHelpers.d.ts:94:1 - (ae-undocumented) Missing documentation for "commitAndPushBranch". +// src/actions/types.d.ts:60:1 - (ae-undocumented) Missing documentation for "TemplateAction". +// src/actions/util.d.ts:5:22 - (ae-undocumented) Missing documentation for "getRepoSourceDirectory". +// src/actions/util.d.ts:9:22 - (ae-undocumented) Missing documentation for "parseRepoUrl". +// src/files/serializeDirectoryContents.d.ts:6:1 - (ae-undocumented) Missing documentation for "serializeDirectoryContents". +// src/files/types.d.ts:6:1 - (ae-undocumented) Missing documentation for "SerializedFile". +// src/files/types.d.ts:7:5 - (ae-undocumented) Missing documentation for "path". +// src/files/types.d.ts:8:5 - (ae-undocumented) Missing documentation for "content". +// src/files/types.d.ts:9:5 - (ae-undocumented) Missing documentation for "executable". +// src/files/types.d.ts:10:5 - (ae-undocumented) Missing documentation for "symlink". +// src/tasks/types.d.ts:83:5 - (ae-undocumented) Missing documentation for "cancelSignal". +// src/tasks/types.d.ts:84:5 - (ae-undocumented) Missing documentation for "spec". +// src/tasks/types.d.ts:85:5 - (ae-undocumented) Missing documentation for "secrets". +// src/tasks/types.d.ts:86:5 - (ae-undocumented) Missing documentation for "createdBy". +// src/tasks/types.d.ts:87:5 - (ae-undocumented) Missing documentation for "done". +// src/tasks/types.d.ts:88:5 - (ae-undocumented) Missing documentation for "isDryRun". +// src/tasks/types.d.ts:89:5 - (ae-undocumented) Missing documentation for "complete". +// src/tasks/types.d.ts:90:5 - (ae-undocumented) Missing documentation for "emitLog". +// src/tasks/types.d.ts:91:5 - (ae-undocumented) Missing documentation for "getTaskState". +// src/tasks/types.d.ts:94:5 - (ae-undocumented) Missing documentation for "updateCheckpoint". +// src/tasks/types.d.ts:103:5 - (ae-undocumented) Missing documentation for "serializeWorkspace". +// src/tasks/types.d.ts:106:5 - (ae-undocumented) Missing documentation for "cleanWorkspace". +// src/tasks/types.d.ts:107:5 - (ae-undocumented) Missing documentation for "rehydrateWorkspace". +// src/tasks/types.d.ts:111:5 - (ae-undocumented) Missing documentation for "getWorkspaceName". +// src/tasks/types.d.ts:112:5 - (ae-undocumented) Missing documentation for "getInitiatorCredentials". +// src/tasks/types.d.ts:120:5 - (ae-undocumented) Missing documentation for "cancel". +// src/tasks/types.d.ts:121:5 - (ae-undocumented) Missing documentation for "retry". +// src/tasks/types.d.ts:122:5 - (ae-undocumented) Missing documentation for "claim". +// src/tasks/types.d.ts:123:5 - (ae-undocumented) Missing documentation for "recoverTasks". +// src/tasks/types.d.ts:124:5 - (ae-undocumented) Missing documentation for "dispatch". +// src/tasks/types.d.ts:125:5 - (ae-undocumented) Missing documentation for "vacuumTasks". +// src/tasks/types.d.ts:128:5 - (ae-undocumented) Missing documentation for "event$". +// src/tasks/types.d.ts:134:5 - (ae-undocumented) Missing documentation for "get". +// src/tasks/types.d.ts:135:5 - (ae-undocumented) Missing documentation for "list". +// src/tasks/types.d.ts:155:5 - (ae-undocumented) Missing documentation for "list". +// src/types.d.ts:3:1 - (ae-undocumented) Missing documentation for "TemplateFilter". +// src/types.d.ts:5:1 - (ae-undocumented) Missing documentation for "TemplateGlobal". ``` diff --git a/plugins/scaffolder-node/src/tasks/types.ts b/plugins/scaffolder-node/src/tasks/types.ts index 8324e352f2..b830c0633a 100644 --- a/plugins/scaffolder-node/src/tasks/types.ts +++ b/plugins/scaffolder-node/src/tasks/types.ts @@ -76,6 +76,7 @@ export type TaskEventType = 'completion' | 'log' | 'cancelled' | 'recovered'; */ export type SerializedTaskEvent = { id: number; + isTaskRecoverable?: boolean; taskId: string; body: JsonObject; type: TaskEventType; @@ -163,6 +164,8 @@ export interface TaskContext { export interface TaskBroker { cancel?(taskId: string): Promise; + retry?(taskId: string): Promise; + claim(): Promise; recoverTasks?(): Promise; @@ -181,7 +184,22 @@ export interface TaskBroker { get(taskId: string): Promise; list?(options?: { + filters?: { + createdBy?: string | string[]; + status?: TaskStatus | TaskStatus[]; + }; + pagination?: { + limit?: number; + offset?: number; + }; + order?: { order: 'asc' | 'desc'; field: string }[]; + }): Promise<{ tasks: SerializedTask[]; totalTasks?: number }>; + + /** + * @deprecated Make sure to pass `createdBy` and `status` in the `filters` parameter instead + */ + list?(options: { createdBy?: string; status?: TaskStatus; - }): Promise<{ tasks: SerializedTask[] }>; + }): Promise<{ tasks: SerializedTask[]; totalTasks?: number }>; } diff --git a/plugins/scaffolder-react/CHANGELOG.md b/plugins/scaffolder-react/CHANGELOG.md index 991cc8d10e..b74a324974 100644 --- a/plugins/scaffolder-react/CHANGELOG.md +++ b/plugins/scaffolder-react/CHANGELOG.md @@ -1,5 +1,115 @@ # @backstage/plugin-scaffolder-react +## 1.13.0-next.1 + +### Minor Changes + +- d851b5b: Renamed Template Editor to Manage Templates. + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- 785d68f: Add support for pagination in scaffolder tasks list +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/frontend-plugin-api@0.9.0-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/plugin-permission-react@0.4.27-next.1 + - @backstage/version-bridge@1.0.10-next.0 + - @backstage/plugin-catalog-react@1.14.0-next.1 + - @backstage/theme@0.5.8-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.6 + +## 1.13.0-next.0 + +### Minor Changes + +- bf6eaf3: Added support for `FormFieldBlueprint` to create field extensions in the Scaffolder plugin + +### Patch Changes + +- 11e0752: Make it possible to manually retry the scaffolder template from the step it failed +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/plugin-catalog-react@1.13.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/theme@0.5.7 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.9 + - @backstage/plugin-permission-react@0.4.27-next.0 + - @backstage/plugin-scaffolder-common@1.5.6 + +## 1.12.0 + +### Minor Changes + +- 4512f71: Add `ui:backstage.review.name` option for custom item names on scaffolder review page, and also add support for rendering the `title` property instead of the key name. +- 4baad34: Added support for `omitExtraData` and `liveOmit` for rjsf in the scaffolder + +### Patch Changes + +- 1f3c5aa: Fix scaffolder review step issue where schema options are not handled for fields on multi-step templates. +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- 0a50d44: Updated dependency `@rjsf/utils` to `5.21.1`. + Updated dependency `@rjsf/core` to `5.21.1`. + Updated dependency `@rjsf/material-ui` to `5.21.1`. + Updated dependency `@rjsf/validator-ajv8` to `5.21.1`. +- fa9d8da: Updated dependency `@rjsf/utils` to `5.20.1`. + Updated dependency `@rjsf/core` to `5.20.1`. + Updated dependency `@rjsf/material-ui` to `5.20.1`. + Updated dependency `@rjsf/validator-ajv8` to `5.20.1`. +- c2cbe1e: Updated dependency `use-immer` to `^0.10.0`. +- b0f0118: Remove unnecessary singleton wrapping of `scaffolderApiRef`. +- 3ebb64f: - Fix secret widget field not displaying as required. + - Fix secret widget not able to be required inside nested objects. + - Fix secret widget not able to be disabled. + - Support `minLength` and `maxLength` properties for secret widget. +- 8dd6ef6: Fix an issue where keys with duplicate final key parts are not all displayed in the `ReviewState`. Change the way the keys are formatted to include the full schema path, separated by `>`. +- 9a0672a: Scaffolder review page shows static amount of asterisks for secret fields. +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/plugin-catalog-react@1.13.0 + - @backstage/catalog-model@1.7.0 + - @backstage/catalog-client@1.7.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/theme@0.5.7 + - @backstage/version-bridge@1.0.9 + - @backstage/plugin-permission-react@0.4.26 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.6 + +## 1.12.0-next.2 + +### Minor Changes + +- 4baad34: Added support for `omitExtraData` and `liveOmit` for rjsf in the scaffolder + +### Patch Changes + +- 1f3c5aa: Fix scaffolder review step issue where schema options are not handled for fields on multi-step templates. +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- fa9d8da: Updated dependency `@rjsf/utils` to `5.20.1`. + Updated dependency `@rjsf/core` to `5.20.1`. + Updated dependency `@rjsf/material-ui` to `5.20.1`. + Updated dependency `@rjsf/validator-ajv8` to `5.20.1`. +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/plugin-catalog-react@1.13.0-next.2 + - @backstage/catalog-client@1.7.0-next.1 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/theme@0.5.7-next.0 + - @backstage/version-bridge@1.0.9-next.0 + - @backstage/plugin-permission-react@0.4.26-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.5 + ## 1.12.0-next.1 ### Patch Changes diff --git a/plugins/scaffolder-react/package.json b/plugins/scaffolder-react/package.json index d952986e6e..7cb40529a9 100644 --- a/plugins/scaffolder-react/package.json +++ b/plugins/scaffolder-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-react", - "version": "1.12.0-next.1", + "version": "1.13.0-next.1", "description": "A frontend library that helps other Backstage plugins interact with the Scaffolder", "backstage": { "role": "web-library", @@ -62,6 +62,7 @@ "@backstage/catalog-model": "workspace:^", "@backstage/core-components": "workspace:^", "@backstage/core-plugin-api": "workspace:^", + "@backstage/frontend-plugin-api": "workspace:^", "@backstage/plugin-catalog-react": "workspace:^", "@backstage/plugin-permission-react": "workspace:^", "@backstage/plugin-scaffolder-common": "workspace:^", @@ -72,12 +73,11 @@ "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.61", "@react-hookz/web": "^24.0.0", - "@rjsf/core": "5.18.5", - "@rjsf/material-ui": "5.18.5", - "@rjsf/utils": "5.18.5", - "@rjsf/validator-ajv8": "5.18.5", + "@rjsf/core": "5.21.1", + "@rjsf/material-ui": "5.21.1", + "@rjsf/utils": "5.21.1", + "@rjsf/validator-ajv8": "5.21.1", "@types/json-schema": "^7.0.9", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "ajv-errors": "^3.0.0", "classnames": "^2.2.6", "flatted": "3.3.1", @@ -102,15 +102,25 @@ "@backstage/test-utils": "workspace:^", "@testing-library/dom": "^10.0.0", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^15.0.0", + "@testing-library/react": "^16.0.0", "@testing-library/user-event": "^14.0.0", "@types/humanize-duration": "^3.18.1", "@types/luxon": "^3.0.0", + "@types/react": "^18.0.0", + "react": "^18.0.2", + "react-dom": "^18.0.2", + "react-router-dom": "^6.3.0", "swr": "^2.0.0" }, "peerDependencies": { + "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } } diff --git a/plugins/scaffolder-react/api-report-alpha.md b/plugins/scaffolder-react/report-alpha.api.md similarity index 56% rename from plugins/scaffolder-react/api-report-alpha.md rename to plugins/scaffolder-react/report-alpha.api.md index 545cc02e9e..75c6d08e32 100644 --- a/plugins/scaffolder-react/api-report-alpha.md +++ b/plugins/scaffolder-react/report-alpha.api.md @@ -7,10 +7,15 @@ import { ApiHolder } from '@backstage/core-plugin-api'; import { ComponentType } from 'react'; +import { ConfigurableExtensionDataRef } from '@backstage/frontend-plugin-api'; import { CustomFieldValidator } from '@backstage/plugin-scaffolder-react'; import { Dispatch } from 'react'; +import { ExtensionBlueprint } from '@backstage/frontend-plugin-api'; +import { FieldExtensionComponentProps } from '@backstage/plugin-scaffolder-react'; import { FieldExtensionOptions } from '@backstage/plugin-scaffolder-react'; +import { FieldSchema } from '@backstage/plugin-scaffolder-react'; import { FieldValidation } from '@rjsf/utils'; +import { FormField } from '@internal/scaffolder'; import { FormProps } from '@backstage/plugin-scaffolder-react'; import { IconComponent } from '@backstage/core-plugin-api'; import { JsonObject } from '@backstage/types'; @@ -34,6 +39,7 @@ import { TemplateParameterSchema } from '@backstage/plugin-scaffolder-react'; import { TemplatePresentationV1beta3 } from '@backstage/plugin-scaffolder-common'; import { UiSchema } from '@rjsf/utils'; import { WidgetProps } from '@rjsf/utils'; +import { z } from 'zod'; // @alpha (undocumented) export type BackstageOverrides = Overrides & { @@ -57,6 +63,12 @@ export const createAsyncValidators: ( // @alpha export const createFieldValidation: () => FieldValidation; +// @alpha +export function createFormField< + TReturnValue extends z.ZodType, + TUiOptions extends z.ZodType, +>(opts: FormFieldExtensionData): FormField; + // @alpha export const DefaultTemplateOutputs: (props: { output?: ScaffolderTaskOutput; @@ -76,6 +88,49 @@ export const Form: ( props: PropsWithChildren, ) => React_2.JSX.Element; +// @alpha +export const FormFieldBlueprint: ExtensionBlueprint<{ + kind: 'scaffolder-form-field'; + name: undefined; + params: { + field: () => Promise; + }; + output: ConfigurableExtensionDataRef< + () => Promise, + 'scaffolder.form-field-loader', + {} + >; + inputs: {}; + config: {}; + configInput: {}; + dataRefs: { + formFieldLoader: ConfigurableExtensionDataRef< + () => Promise, + 'scaffolder.form-field-loader', + {} + >; + }; +}>; + +// @alpha (undocumented) +export type FormFieldExtensionData< + TReturnValue extends z.ZodType = z.ZodType, + TUiOptions extends z.ZodType = z.ZodType, +> = { + name: string; + component: ( + props: FieldExtensionComponentProps< + z.output, + z.output + >, + ) => JSX.Element | null; + validation?: CustomFieldValidator< + z.output, + z.output + >; + schema?: FieldSchema, z.output>; +}; + // @alpha (undocumented) export type FormValidation = { [name: string]: FieldValidation | FormValidation; @@ -318,5 +373,51 @@ export type WorkflowProps = { | 'layouts' >; +// Warnings were encountered during analysis: +// +// src/next/blueprints/types.d.ts:5:1 - (ae-undocumented) Missing documentation for "FormFieldExtensionData". +// src/next/components/ScaffolderField/ScaffolderField.d.ts:7:5 - (ae-undocumented) Missing documentation for "rawDescription". +// src/next/components/ScaffolderField/ScaffolderField.d.ts:8:5 - (ae-undocumented) Missing documentation for "errors". +// src/next/components/ScaffolderField/ScaffolderField.d.ts:9:5 - (ae-undocumented) Missing documentation for "rawErrors". +// src/next/components/ScaffolderField/ScaffolderField.d.ts:10:5 - (ae-undocumented) Missing documentation for "help". +// src/next/components/ScaffolderField/ScaffolderField.d.ts:11:5 - (ae-undocumented) Missing documentation for "rawHelp". +// src/next/components/ScaffolderField/ScaffolderField.d.ts:12:5 - (ae-undocumented) Missing documentation for "required". +// src/next/components/ScaffolderField/ScaffolderField.d.ts:13:5 - (ae-undocumented) Missing documentation for "disabled". +// src/next/components/ScaffolderField/ScaffolderField.d.ts:14:5 - (ae-undocumented) Missing documentation for "displayLabel". +// src/next/components/ScaffolderPageContextMenu/ScaffolderPageContextMenu.d.ts:5:1 - (ae-undocumented) Missing documentation for "ScaffolderPageContextMenuProps". +// src/next/components/ScaffolderPageContextMenu/ScaffolderPageContextMenu.d.ts:14:1 - (ae-undocumented) Missing documentation for "ScaffolderPageContextMenu". +// src/next/components/Stepper/createAsyncValidators.d.ts:6:1 - (ae-undocumented) Missing documentation for "FormValidation". +// src/next/components/Stepper/createAsyncValidators.d.ts:10:22 - (ae-undocumented) Missing documentation for "createAsyncValidators". +// src/next/components/TaskSteps/TaskSteps.d.ts:10:5 - (ae-undocumented) Missing documentation for "steps". +// src/next/components/TaskSteps/TaskSteps.d.ts:11:5 - (ae-undocumented) Missing documentation for "activeStep". +// src/next/components/TaskSteps/TaskSteps.d.ts:12:5 - (ae-undocumented) Missing documentation for "isComplete". +// src/next/components/TaskSteps/TaskSteps.d.ts:13:5 - (ae-undocumented) Missing documentation for "isError". +// src/next/components/TemplateCard/TemplateCard.d.ts:9:5 - (ae-undocumented) Missing documentation for "template". +// src/next/components/TemplateCard/TemplateCard.d.ts:10:5 - (ae-undocumented) Missing documentation for "additionalLinks". +// src/next/components/TemplateCard/TemplateCard.d.ts:15:5 - (ae-undocumented) Missing documentation for "onSelected". +// src/next/components/TemplateCategoryPicker/TemplateCategoryPicker.d.ts:3:1 - (ae-undocumented) Missing documentation for "ScaffolderReactTemplateCategoryPickerClassKey". +// src/next/components/TemplateGroup/TemplateGroup.d.ts:10:5 - (ae-undocumented) Missing documentation for "templates". +// src/next/components/TemplateGroup/TemplateGroup.d.ts:18:5 - (ae-undocumented) Missing documentation for "onSelected". +// src/next/components/TemplateGroup/TemplateGroup.d.ts:19:5 - (ae-undocumented) Missing documentation for "title". +// src/next/components/TemplateGroup/TemplateGroup.d.ts:20:5 - (ae-undocumented) Missing documentation for "components". +// src/next/components/TemplateGroups/TemplateGroups.d.ts:8:1 - (ae-undocumented) Missing documentation for "TemplateGroupsProps". +// src/next/components/TemplateGroups/TemplateGroups.d.ts:9:5 - (ae-undocumented) Missing documentation for "groups". +// src/next/components/TemplateGroups/TemplateGroups.d.ts:10:5 - (ae-undocumented) Missing documentation for "templateFilter". +// src/next/components/TemplateGroups/TemplateGroups.d.ts:11:5 - (ae-undocumented) Missing documentation for "TemplateCardComponent". +// src/next/components/TemplateGroups/TemplateGroups.d.ts:14:5 - (ae-undocumented) Missing documentation for "onTemplateSelected". +// src/next/components/TemplateGroups/TemplateGroups.d.ts:15:5 - (ae-undocumented) Missing documentation for "additionalLinksForEntity". +// src/next/components/TemplateGroups/TemplateGroups.d.ts:24:22 - (ae-undocumented) Missing documentation for "TemplateGroups". +// src/next/components/Workflow/Workflow.d.ts:7:1 - (ae-undocumented) Missing documentation for "WorkflowProps". +// src/next/components/Workflow/Workflow.d.ts:20:22 - (ae-undocumented) Missing documentation for "Workflow". +// src/next/components/Workflow/Workflow.d.ts:24:22 - (ae-undocumented) Missing documentation for "EmbeddableWorkflow". +// src/next/hooks/useTemplateParameterSchema.d.ts:5:22 - (ae-undocumented) Missing documentation for "useTemplateParameterSchema". +// src/next/hooks/useTemplateSchema.d.ts:10:5 - (ae-undocumented) Missing documentation for "uiSchema". +// src/next/hooks/useTemplateSchema.d.ts:11:5 - (ae-undocumented) Missing documentation for "mergedSchema". +// src/next/hooks/useTemplateSchema.d.ts:12:5 - (ae-undocumented) Missing documentation for "schema". +// src/next/hooks/useTemplateSchema.d.ts:13:5 - (ae-undocumented) Missing documentation for "title". +// src/next/hooks/useTemplateSchema.d.ts:14:5 - (ae-undocumented) Missing documentation for "description". +// src/next/overridableComponents.d.ts:5:1 - (ae-undocumented) Missing documentation for "ScaffolderReactComponentsNameToClassKey". +// src/next/overridableComponents.d.ts:9:1 - (ae-undocumented) Missing documentation for "BackstageOverrides". + // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/scaffolder-react/api-report.md b/plugins/scaffolder-react/report.api.md similarity index 72% rename from plugins/scaffolder-react/api-report.md rename to plugins/scaffolder-react/report.api.md index a19a656d17..73573b25c4 100644 --- a/plugins/scaffolder-react/api-report.md +++ b/plugins/scaffolder-react/report.api.md @@ -6,7 +6,7 @@ /// import { ApiHolder } from '@backstage/core-plugin-api'; -import { ApiRef } from '@backstage/core-plugin-api'; +import { ApiRef } from '@backstage/frontend-plugin-api'; import { ComponentType } from 'react'; import { CustomValidator } from '@rjsf/utils'; import { ElementType } from 'react'; @@ -44,6 +44,7 @@ import { TemplatesType } from '@rjsf/utils'; import { UIOptionsType } from '@rjsf/utils'; import { UiSchema } from '@rjsf/utils'; import { ValidatorType } from '@rjsf/utils'; +import { z } from 'zod'; // @public export type Action = { @@ -125,10 +126,27 @@ export interface FieldExtensionUiSchema 'ui:options'?: TUiOptions & UIOptionsType; } +// @public +export interface FieldSchema { + // (undocumented) + readonly schema: CustomFieldExtensionSchema; + // (undocumented) + readonly TProps: FieldExtensionComponentProps; + // @deprecated (undocumented) + readonly type: FieldExtensionComponentProps; + // @deprecated (undocumented) + readonly uiOptionsType: TUiOptions; +} + // @public export type FormProps = Pick< FormProps_2, - 'transformErrors' | 'noHtml5Validate' | 'uiSchema' | 'formContext' + | 'transformErrors' + | 'noHtml5Validate' + | 'uiSchema' + | 'formContext' + | 'omitExtraData' + | 'liveOmit' >; // @public @@ -163,6 +181,15 @@ export type LogEvent = { taskId: string; }; +// @public (undocumented) +export function makeFieldSchema< + TReturnType extends z.ZodType, + TUiOptions extends z.ZodType, +>(options: { + output: (zImpl: typeof z) => TReturnType; + uiOptions?: (zImpl: typeof z) => TUiOptions; +}): FieldSchema, z.output>; + // @public export type ReviewStepProps = { disableButtons: boolean; @@ -205,9 +232,15 @@ export interface ScaffolderApi { ): Promise; listActions(): Promise; // (undocumented) - listTasks?(options: { filterByOwnership: 'owned' | 'all' }): Promise<{ + listTasks?(options: { + filterByOwnership: 'owned' | 'all'; + limit?: number; + offset?: number; + }): Promise<{ tasks: ScaffolderTask[]; + totalTasks?: number; }>; + retry?(taskId: string): Promise; scaffold( options: ScaffolderScaffoldOptions, ): Promise; @@ -427,6 +460,8 @@ export interface ScaffolderStreamLogsOptions { // (undocumented) after?: number; // (undocumented) + isTaskRecoverable?: boolean; + // (undocumented) taskId: string; } @@ -523,5 +558,50 @@ export const useTaskEventStream: (taskId: string) => TaskStream; // @public export const useTemplateSecrets: () => ScaffolderUseTemplateSecrets; +// Warnings were encountered during analysis: +// +// src/api/ref.d.ts:3:22 - (ae-undocumented) Missing documentation for "scaffolderApiRef". +// src/api/types.d.ts:53:1 - (ae-undocumented) Missing documentation for "ScaffolderOutputLink". +// src/api/types.d.ts:60:1 - (ae-undocumented) Missing documentation for "ScaffolderOutputText". +// src/api/types.d.ts:67:1 - (ae-undocumented) Missing documentation for "ScaffolderTaskOutput". +// src/api/types.d.ts:95:5 - (ae-undocumented) Missing documentation for "templateRef". +// src/api/types.d.ts:96:5 - (ae-undocumented) Missing documentation for "values". +// src/api/types.d.ts:97:5 - (ae-undocumented) Missing documentation for "secrets". +// src/api/types.d.ts:105:5 - (ae-undocumented) Missing documentation for "taskId". +// src/api/types.d.ts:113:5 - (ae-undocumented) Missing documentation for "allowedHosts". +// src/api/types.d.ts:121:5 - (ae-undocumented) Missing documentation for "integrations". +// src/api/types.d.ts:133:5 - (ae-undocumented) Missing documentation for "isTaskRecoverable". +// src/api/types.d.ts:134:5 - (ae-undocumented) Missing documentation for "taskId". +// src/api/types.d.ts:135:5 - (ae-undocumented) Missing documentation for "after". +// src/api/types.d.ts:138:1 - (ae-undocumented) Missing documentation for "ScaffolderDryRunOptions". +// src/api/types.d.ts:139:5 - (ae-undocumented) Missing documentation for "template". +// src/api/types.d.ts:140:5 - (ae-undocumented) Missing documentation for "values". +// src/api/types.d.ts:141:5 - (ae-undocumented) Missing documentation for "secrets". +// src/api/types.d.ts:142:5 - (ae-undocumented) Missing documentation for "directoryContents". +// src/api/types.d.ts:148:1 - (ae-undocumented) Missing documentation for "ScaffolderDryRunResponse". +// src/api/types.d.ts:149:5 - (ae-undocumented) Missing documentation for "directoryContents". +// src/api/types.d.ts:154:5 - (ae-undocumented) Missing documentation for "log". +// src/api/types.d.ts:155:5 - (ae-undocumented) Missing documentation for "steps". +// src/api/types.d.ts:156:5 - (ae-undocumented) Missing documentation for "output". +// src/api/types.d.ts:164:5 - (ae-undocumented) Missing documentation for "getTemplateParameterSchema". +// src/api/types.d.ts:172:5 - (ae-undocumented) Missing documentation for "getTask". +// src/api/types.d.ts:185:5 - (ae-undocumented) Missing documentation for "listTasks". +// src/api/types.d.ts:193:5 - (ae-undocumented) Missing documentation for "getIntegrationsList". +// src/api/types.d.ts:198:5 - (ae-undocumented) Missing documentation for "streamLogs". +// src/api/types.d.ts:199:5 - (ae-undocumented) Missing documentation for "dryRun". +// src/api/types.d.ts:200:5 - (ae-undocumented) Missing documentation for "autocomplete". +// src/components/types.d.ts:7:1 - (ae-undocumented) Missing documentation for "TemplateGroupFilter". +// src/extensions/types.d.ts:13:5 - (ae-undocumented) Missing documentation for "uiSchema". +// src/extensions/types.d.ts:30:5 - (ae-undocumented) Missing documentation for ""ui:options"". +// src/layouts/createScaffolderLayout.d.ts:16:5 - (ae-undocumented) Missing documentation for "name". +// src/layouts/createScaffolderLayout.d.ts:17:5 - (ae-undocumented) Missing documentation for "component". +// src/secrets/SecretsContext.d.ts:14:5 - (ae-undocumented) Missing documentation for "setSecrets". +// src/secrets/SecretsContext.d.ts:15:5 - (ae-undocumented) Missing documentation for "secrets". +// src/utils.d.ts:4:1 - (ae-undocumented) Missing documentation for "makeFieldSchema". +// src/utils.d.ts:15:5 - (ae-undocumented) Missing documentation for "type". +// src/utils.d.ts:17:5 - (ae-undocumented) Missing documentation for "uiOptionsType". +// src/utils.d.ts:18:5 - (ae-undocumented) Missing documentation for "schema". +// src/utils.d.ts:19:5 - (ae-undocumented) Missing documentation for "TProps". + // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/scaffolder-react/src/api/ref.ts b/plugins/scaffolder-react/src/api/ref.ts index c4b7853556..4cf50d377b 100644 --- a/plugins/scaffolder-react/src/api/ref.ts +++ b/plugins/scaffolder-react/src/api/ref.ts @@ -14,15 +14,10 @@ * limitations under the License. */ -import { createApiRef } from '@backstage/core-plugin-api'; +import { createApiRef } from '@backstage/frontend-plugin-api'; import { ScaffolderApi } from './types'; -import { getOrCreateGlobalSingleton } from '@backstage/version-bridge'; /** @public */ -export const scaffolderApiRef = getOrCreateGlobalSingleton( - 'scaffolder:scaffolder-api-ref', - () => - createApiRef({ - id: 'plugin.scaffolder.service', - }), -); +export const scaffolderApiRef = createApiRef({ + id: 'plugin.scaffolder.service', +}); diff --git a/plugins/scaffolder-react/src/api/types.ts b/plugins/scaffolder-react/src/api/types.ts index eaef54ff1b..bc37eed47e 100644 --- a/plugins/scaffolder-react/src/api/types.ts +++ b/plugins/scaffolder-react/src/api/types.ts @@ -161,6 +161,7 @@ export interface ScaffolderGetIntegrationsListResponse { * @public */ export interface ScaffolderStreamLogsOptions { + isTaskRecoverable?: boolean; taskId: string; after?: number; } @@ -213,9 +214,18 @@ export interface ScaffolderApi { */ cancelTask(taskId: string): Promise; + /** + * Starts the task again from the point where it failed. + * + * @param taskId - the id of the task + */ + retry?(taskId: string): Promise; + listTasks?(options: { filterByOwnership: 'owned' | 'all'; - }): Promise<{ tasks: ScaffolderTask[] }>; + limit?: number; + offset?: number; + }): Promise<{ tasks: ScaffolderTask[]; totalTasks?: number }>; getIntegrationsList( options: ScaffolderGetIntegrationsListOptions, diff --git a/plugins/scaffolder-react/src/components/types.ts b/plugins/scaffolder-react/src/components/types.ts index d5d317015d..3df6209cad 100644 --- a/plugins/scaffolder-react/src/components/types.ts +++ b/plugins/scaffolder-react/src/components/types.ts @@ -32,7 +32,12 @@ export type TemplateGroupFilter = { */ export type FormProps = Pick< SchemaFormProps, - 'transformErrors' | 'noHtml5Validate' | 'uiSchema' | 'formContext' + | 'transformErrors' + | 'noHtml5Validate' + | 'uiSchema' + | 'formContext' + | 'omitExtraData' + | 'liveOmit' >; /** diff --git a/plugins/scaffolder-react/src/hooks/useEventStream.ts b/plugins/scaffolder-react/src/hooks/useEventStream.ts index f63f6024e6..7c5ce09ab7 100644 --- a/plugins/scaffolder-react/src/hooks/useEventStream.ts +++ b/plugins/scaffolder-react/src/hooks/useEventStream.ts @@ -143,6 +143,11 @@ function reducer(draft: TaskStream, action: ReducerAction) { } case 'RECOVERED': { + draft.cancelled = false; + draft.completed = false; + draft.output = undefined; + draft.error = undefined; + for (const stepId in draft.steps) { if (draft.steps.hasOwnProperty(stepId)) { draft.steps[stepId].startedAt = undefined; @@ -185,12 +190,16 @@ export const useTaskEventStream = (taskId: string): TaskStream => { let subscription: Subscription | undefined; let logPusher: NodeJS.Timeout | undefined; let retryCount = 1; + let isTaskRecoverable = false; const startStreamLogProcess = () => scaffolderApi.getTask(taskId).then( task => { if (didCancel) { return; } + isTaskRecoverable = + task.spec.EXPERIMENTAL_recovery?.EXPERIMENTAL_strategy === + 'startOver'; dispatch({ type: 'INIT', data: task }); // TODO(blam): Use a normal fetch to fetch the current log for the event stream @@ -199,7 +208,10 @@ export const useTaskEventStream = (taskId: string): TaskStream => { // stream logs. Without this, if you have a lot of logs, it can look like the // task is being rebuilt on load as it progresses through the steps at a slower // rate whilst it builds the status from the event logs - const observable = scaffolderApi.streamLogs({ taskId }); + const observable = scaffolderApi.streamLogs({ + isTaskRecoverable, + taskId, + }); const collectedLogEvents = new Array(); @@ -270,12 +282,14 @@ export const useTaskEventStream = (taskId: string): TaskStream => { ); void startStreamLogProcess(); return () => { - didCancel = true; - if (subscription) { - subscription.unsubscribe(); - } - if (logPusher) { - clearInterval(logPusher); + if (!isTaskRecoverable) { + didCancel = true; + if (subscription) { + subscription.unsubscribe(); + } + if (logPusher) { + clearInterval(logPusher); + } } }; }, [scaffolderApi, dispatch, taskId]); diff --git a/plugins/scaffolder-react/src/index.ts b/plugins/scaffolder-react/src/index.ts index 70560cc694..e73df50fce 100644 --- a/plugins/scaffolder-react/src/index.ts +++ b/plugins/scaffolder-react/src/index.ts @@ -21,3 +21,4 @@ export * from './secrets'; export * from './api'; export * from './hooks'; export * from './layouts'; +export * from './utils'; diff --git a/plugins/scaffolder-react/src/next/blueprints/FormFieldBlueprint.tsx b/plugins/scaffolder-react/src/next/blueprints/FormFieldBlueprint.tsx new file mode 100644 index 0000000000..e99adcba82 --- /dev/null +++ b/plugins/scaffolder-react/src/next/blueprints/FormFieldBlueprint.tsx @@ -0,0 +1,56 @@ +/* + * 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 { + createExtensionBlueprint, + createExtensionDataRef, +} from '@backstage/frontend-plugin-api'; +import { z } from 'zod'; + +import { OpaqueFormField, FormField } from '@internal/scaffolder'; +import { FormFieldExtensionData } from './types'; + +const formFieldExtensionDataRef = createExtensionDataRef< + () => Promise +>().with({ + id: 'scaffolder.form-field-loader', +}); + +/** + * @alpha + * Creates extensions that are Field Extensions for the Scaffolder + * */ +export const FormFieldBlueprint = createExtensionBlueprint({ + kind: 'scaffolder-form-field', + attachTo: { id: 'api:scaffolder/form-fields', input: 'formFields' }, + dataRefs: { + formFieldLoader: formFieldExtensionDataRef, + }, + output: [formFieldExtensionDataRef], + *factory(params: { field: () => Promise }) { + yield formFieldExtensionDataRef(params.field); + }, +}); + +/** + * @alpha + * Used to create a form field binding with typechecking for compliance + */ +export function createFormField< + TReturnValue extends z.ZodType, + TUiOptions extends z.ZodType, +>(opts: FormFieldExtensionData): FormField { + return OpaqueFormField.createInstance('v1', opts); +} diff --git a/plugins/scaffolder-react/src/next/blueprints/index.ts b/plugins/scaffolder-react/src/next/blueprints/index.ts new file mode 100644 index 0000000000..165c583ac8 --- /dev/null +++ b/plugins/scaffolder-react/src/next/blueprints/index.ts @@ -0,0 +1,18 @@ +/* + * 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. + */ + +export * from './FormFieldBlueprint'; +export * from './types'; diff --git a/plugins/scaffolder-react/src/next/blueprints/types.ts b/plugins/scaffolder-react/src/next/blueprints/types.ts new file mode 100644 index 0000000000..eccf7e4606 --- /dev/null +++ b/plugins/scaffolder-react/src/next/blueprints/types.ts @@ -0,0 +1,40 @@ +/* + * 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 { z } from 'zod'; +import { + CustomFieldValidator, + FieldExtensionComponentProps, + FieldSchema, +} from '@backstage/plugin-scaffolder-react'; + +/** @alpha */ +export type FormFieldExtensionData< + TReturnValue extends z.ZodType = z.ZodType, + TUiOptions extends z.ZodType = z.ZodType, +> = { + name: string; + component: ( + props: FieldExtensionComponentProps< + z.output, + z.output + >, + ) => JSX.Element | null; + validation?: CustomFieldValidator< + z.output, + z.output + >; + schema?: FieldSchema, z.output>; +}; diff --git a/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.test.tsx b/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.test.tsx index a3fcecbe2b..7fb8ca2e3e 100644 --- a/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.test.tsx +++ b/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.test.tsx @@ -497,4 +497,109 @@ describe('ReviewState', () => { expect(queryByRole('row', { name: 'Bar test' })).toBeInTheDocument(); expect(queryByRole('row', { name: 'Foo test' })).not.toBeInTheDocument(); }); + + it('should handle options in multiple schemas', async () => { + const formState = { + foo1: 'bar1', + foo2: 'bar2', + foo3: { + foo4: 'bar4', + }, + foo5: 'bar5', + }; + + const schemas: ParsedTemplateSchema[] = [ + { + mergedSchema: { + type: 'object', + properties: { + foo1: { + type: 'string', + 'ui:backstage': { + review: { + name: 'Test 1', + }, + }, + }, + }, + }, + schema: {}, + title: 'Schema 1', + uiSchema: {}, + }, + { + mergedSchema: { + type: 'object', + properties: { + foo2: { + type: 'string', + 'ui:backstage': { + review: { + name: 'Test 2', + }, + }, + }, + foo3: { + type: 'object', + properties: { + foo4: { + type: 'string', + 'ui:backstage': { + review: { + name: 'Test 4', + }, + }, + }, + }, + }, + }, + }, + schema: {}, + title: 'Schema 2', + uiSchema: {}, + }, + { + mergedSchema: { + type: 'object', + dependencies: { + foo1: { + oneOf: [ + { + properties: { + foo5: { + type: 'string', + 'ui:backstage': { + review: { + name: 'Test 5', + }, + }, + }, + }, + }, + ], + }, + }, + }, + schema: {}, + title: 'Schema 3', + uiSchema: {}, + }, + ]; + + const { queryByRole } = render( + , + ); + + // handles options in first schema + expect(queryByRole('row', { name: 'Test 1 bar1' })).toBeInTheDocument(); + + // handles options in second schema + expect(queryByRole('row', { name: 'Test 2 bar2' })).toBeInTheDocument(); + + // handles options for nested object in second schema + expect(queryByRole('row', { name: 'Test 4 bar4' })).toBeInTheDocument(); + + // handles options for property in dependencies in third schema + expect(queryByRole('row', { name: 'Test 5 bar5' })).toBeInTheDocument(); + }); }); diff --git a/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.tsx b/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.tsx index 7d2c6042dc..1568461fb0 100644 --- a/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.tsx +++ b/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.tsx @@ -18,7 +18,7 @@ import { StructuredMetadataTable } from '@backstage/core-components'; import { JsonObject, JsonValue } from '@backstage/types'; import { Draft07 as JSONSchema } from 'json-schema-library'; import { ParsedTemplateSchema } from '../../hooks/useTemplateSchema'; -import { isJsonObject, formatKey } from './util'; +import { isJsonObject, formatKey, findSchemaForKey } from './util'; /** * The props for the {@link ReviewState} component. @@ -94,10 +94,10 @@ export const ReviewState = (props: ReviewStateProps) => { const reviewData = Object.fromEntries( Object.entries(props.formState) .flatMap(([key, value]) => { - for (const step of props.schemas) { - return processSchema(key, value, step, props.formState); - } - return [[key, value]]; + const schema = findSchemaForKey(key, props.schemas, props.formState); + return schema + ? processSchema(key, value, schema, props.formState) + : [[key, value]]; }) .filter(prop => prop.length > 0), ); diff --git a/plugins/scaffolder-react/src/next/components/ReviewState/util.test.ts b/plugins/scaffolder-react/src/next/components/ReviewState/util.test.ts index bc8001baea..cc7c0fe397 100644 --- a/plugins/scaffolder-react/src/next/components/ReviewState/util.test.ts +++ b/plugins/scaffolder-react/src/next/components/ReviewState/util.test.ts @@ -14,7 +14,8 @@ * limitations under the License. */ -import { isJsonObject, formatKey } from './util'; +import { isJsonObject, formatKey, findSchemaForKey } from './util'; +import { ParsedTemplateSchema } from '../../hooks/useTemplateSchema'; describe('isJsonObject', () => { it('should return true for non-null objects', () => { @@ -78,3 +79,95 @@ describe('formatKey', () => { expect(formatKey('parent/child@!#$%^&*()')).toBe('Parent > Child'); }); }); + +describe('findSchemaForKey', () => { + const schemas: ParsedTemplateSchema[] = [ + { + mergedSchema: { + type: 'object', + properties: { + foo: { + type: 'string', + }, + }, + }, + schema: {}, + title: 'Schema 1', + uiSchema: {}, + }, + { + mergedSchema: { + type: 'object', + properties: { + bar: { + type: 'string', + }, + hello: { + type: 'object', + properties: { + world: { + type: 'string', + }, + }, + }, + }, + }, + schema: {}, + title: 'Schema 2', + uiSchema: {}, + }, + { + mergedSchema: { + type: 'object', + dependencies: { + foo: { + oneOf: [ + { + properties: { + artifact: { + type: 'string', + }, + }, + }, + ], + }, + }, + }, + schema: {}, + title: 'Schema 3', + uiSchema: {}, + }, + ]; + + const formState = { + foo: 'value', + bar: 'value', + hello: { world: 'value' }, + artifact: 'value', + }; + + it('should return the schema for the direct key', () => { + const result = findSchemaForKey('foo', schemas, formState); + expect(result).toBe(schemas[0]); + }); + + it('should return the schema for a key in dependencies', () => { + const result = findSchemaForKey('artifact', schemas, formState); + expect(result).toBe(schemas[2]); + }); + + it('should return null if the key does not exist', () => { + const result = findSchemaForKey('nonexistentKey', schemas, formState); + expect(result).toBeNull(); + }); + + it('should return the schema for a key in the second schema', () => { + const result = findSchemaForKey('bar', schemas, formState); + expect(result).toBe(schemas[1]); + }); + + it('should return the schema for an object key', () => { + const result = findSchemaForKey('hello', schemas, formState); + expect(result).toBe(schemas[1]); + }); +}); diff --git a/plugins/scaffolder-react/src/next/components/ReviewState/util.ts b/plugins/scaffolder-react/src/next/components/ReviewState/util.ts index 44311ee206..1dbc62abe7 100644 --- a/plugins/scaffolder-react/src/next/components/ReviewState/util.ts +++ b/plugins/scaffolder-react/src/next/components/ReviewState/util.ts @@ -16,6 +16,8 @@ import { JsonObject, JsonValue } from '@backstage/types'; import { startCase } from 'lodash'; +import { ParsedTemplateSchema } from '../../hooks/useTemplateSchema'; +import { Draft07 as JSONSchema } from 'json-schema-library'; export function isJsonObject(value?: JsonValue): value is JsonObject { return typeof value === 'object' && value !== null && !Array.isArray(value); @@ -29,3 +31,46 @@ export function formatKey(key: string): string { .map(part => startCase(part)) .join(' > '); } + +export function findSchemaForKey( + key: string, + schemas: ParsedTemplateSchema[], + formState: Partial<{ [key: string]: JsonValue }>, +): ParsedTemplateSchema | null { + for (const step of schemas) { + /* + To determine if a key is defined in a schema we need to call getSchema + with an empty form state. Otherwise, it will never return undefined as it + will fallback to a default schema based on the form state. + + An exception to this is when your schema is dynamic i.e. using dependencies + because the form state is required for generating the schema. In this case, + we add only the dependencies data to the getSchema call. + */ + + const schema = step.mergedSchema; + + // Declare data to be a subset of formState + const data: typeof formState = {}; + + if (schema.dependencies && isJsonObject(schema.dependencies)) { + for (const dep in schema.dependencies) { + if (formState.hasOwnProperty(dep)) { + data[dep] = formState[dep]; // Add each dependency key from formState + } + } + } + + const draft = new JSONSchema(schema); + const res = draft.getSchema({ + pointer: `#/${key}`, + data, + }); + + if (!!res) { + return step; + } + } + + return null; // Return null if the key isn't found in any schema +} diff --git a/plugins/scaffolder-react/src/next/components/ScaffolderPageContextMenu/ScaffolderPageContextMenu.tsx b/plugins/scaffolder-react/src/next/components/ScaffolderPageContextMenu/ScaffolderPageContextMenu.tsx index 2239c86e06..12ca4135f0 100644 --- a/plugins/scaffolder-react/src/next/components/ScaffolderPageContextMenu/ScaffolderPageContextMenu.tsx +++ b/plugins/scaffolder-react/src/next/components/ScaffolderPageContextMenu/ScaffolderPageContextMenu.tsx @@ -105,7 +105,7 @@ export function ScaffolderPageContextMenu( - + )} {onActionsClicked && ( diff --git a/plugins/scaffolder-react/src/next/components/Stepper/Stepper.test.tsx b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.test.tsx index 78aef3428f..b2ec74c41a 100644 --- a/plugins/scaffolder-react/src/next/components/Stepper/Stepper.test.tsx +++ b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.test.tsx @@ -13,16 +13,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import { renderInTestApp } from '@backstage/test-utils'; +import { JsonValue } from '@backstage/types'; +import { act, fireEvent, waitFor } from '@testing-library/react'; import React from 'react'; + +import { LayoutTemplate } from '../../../layouts'; +import { SecretsContextProvider } from '../../../secrets'; import { TemplateParameterSchema } from '../../../types'; import { Stepper } from './Stepper'; -import { renderInTestApp } from '@backstage/test-utils'; -import { act, fireEvent } from '@testing-library/react'; + import type { RJSFValidationError } from '@rjsf/utils'; -import { JsonValue } from '@backstage/types'; -import { FieldExtensionComponentProps } from '../../../extensions'; -import { SecretsContextProvider } from '../../../secrets'; -import { LayoutTemplate } from '../../../layouts'; describe('Stepper', () => { it('should render the step titles for each step of the manifest', async () => { @@ -63,7 +64,7 @@ describe('Stepper', () => { expect(getByRole('button', { name: 'Next' })).toBeInTheDocument(); await act(async () => { - await fireEvent.click(getByRole('button', { name: 'Next' })); + fireEvent.click(getByRole('button', { name: 'Next' })); }); expect(getByRole('button', { name: 'Review' })).toBeInTheDocument(); @@ -102,16 +103,15 @@ describe('Stepper', () => { , ); - await fireEvent.change(getByRole('textbox', { name: 'name' }), { - target: { value: 'im a test value' }, + await act(async () => { + fireEvent.change(getByRole('textbox', { name: 'name' }), { + target: { value: 'im a test value' }, + }); + fireEvent.click(getByRole('button', { name: 'Next' })); }); await act(async () => { - await fireEvent.click(getByRole('button', { name: 'Next' })); - }); - - await act(async () => { - await fireEvent.click(getByRole('button', { name: 'Back' })); + fireEvent.click(getByRole('button', { name: 'Back' })); }); expect(getByRole('textbox', { name: 'name' })).toHaveValue( @@ -152,16 +152,15 @@ describe('Stepper', () => { , ); - await fireEvent.change(getByRole('textbox', { name: 'name' }), { - target: { value: 'im a test value' }, + await act(async () => { + fireEvent.change(getByRole('textbox', { name: 'name' }), { + target: { value: 'im a test value' }, + }); + fireEvent.click(getByRole('button', { name: 'Next' })); }); await act(async () => { - await fireEvent.click(getByRole('button', { name: 'Next' })); - }); - - await act(async () => { - await fireEvent.click(getByLabelText('Step 1')); + fireEvent.click(getByLabelText('Step 1')); }); expect(getByRole('textbox', { name: 'name' })).toHaveValue( @@ -169,38 +168,107 @@ describe('Stepper', () => { ); }); - it('should merge nested formData correctly in multiple steps', async () => { - const Repo = ({ - onChange, - }: FieldExtensionComponentProps<{ repository: string }, any>) => ( - onChange({ repository: e.target.value })} - defaultValue="" - /> + it('should omit properties that are no longer pertinent to the current step', async () => { + const manifest: TemplateParameterSchema = { + title: 'Conditional Input Form', + steps: [ + { + title: 'Conditional Input step', + schema: { + type: 'object', + properties: { + moreInfo: { + type: 'boolean', + title: 'More info', + }, + }, + dependencies: { + moreInfo: { + oneOf: [ + { + properties: { + moreInfo: { + const: true, + }, + description: { + type: 'string', + title: 'Description', + }, + }, + required: ['description'], + }, + { + properties: { + moreInfo: { + not: { + const: true, + }, + }, + }, + }, + ], + }, + }, + }, + }, + ], + }; + + const onCreate = jest.fn(); + + const { getByRole, queryByRole } = await renderInTestApp( + + + , ); - const Owner = ({ - onChange, - }: FieldExtensionComponentProps<{ owner: string }, any>) => ( - onChange({ owner: e.target.value })} - defaultValue="" - /> - ); + await act(async () => { + fireEvent.click(getByRole('checkbox', { name: 'More info' })); + fireEvent.change(getByRole('textbox', { name: 'Description' }), { + target: { value: 'My Test Description' }, + }); + fireEvent.click(getByRole('button', { name: 'Review' })); + }); + expect( + getByRole('cell', { name: 'My Test Description' }), + ).toBeInTheDocument(); + + await act(async () => { + fireEvent.click(getByRole('button', { name: 'Back' })); + }); + + await act(async () => { + fireEvent.click(getByRole('checkbox', { name: 'More info' })); + fireEvent.click(getByRole('button', { name: 'Review' })); + }); + + expect( + queryByRole('cell', { name: 'My Test Description' }), + ).not.toBeInTheDocument(); + + await act(async () => { + fireEvent.click(getByRole('button', { name: 'Create' })); + }); + + expect(onCreate).toHaveBeenCalledWith({ moreInfo: false }); + }); + + it('should merge and overwrite nested formData correctly', async () => { const manifest: TemplateParameterSchema = { steps: [ { title: 'Step 1', schema: { properties: { - first: { - type: 'object', - 'ui:field': 'Repo', + foo: { + type: 'string', + title: 'Foo - 1', }, }, }, @@ -209,9 +277,13 @@ describe('Stepper', () => { title: 'Step 2', schema: { properties: { - second: { - type: 'object', - 'ui:field': 'Owner', + foo: { + type: 'string', + title: 'Foo - 2', + }, + bar: { + type: 'string', + title: 'Bar - 2', }, }, }, @@ -220,47 +292,39 @@ describe('Stepper', () => { title: 'React JSON Schema Form Test', }; - const onCreate = jest.fn(async (values: Record) => { - expect(values).toEqual({ - first: { repository: 'Repo' }, - second: { owner: 'Owner' }, - }); - }); + const onCreate = jest.fn(); const { getByRole } = await renderInTestApp( - + , ); - await fireEvent.change(getByRole('textbox', { name: 'repo' }), { - target: { value: 'Repo' }, + await act(async () => { + fireEvent.change(getByRole('textbox', { name: 'Foo - 1' }), { + target: { value: 'value 1' }, + }); + fireEvent.click(getByRole('button', { name: 'Next' })); }); await act(async () => { - await fireEvent.click(getByRole('button', { name: 'Next' })); - }); - - await fireEvent.change(getByRole('textbox', { name: 'owner' }), { - target: { value: 'Owner' }, + fireEvent.change(getByRole('textbox', { name: 'Foo - 2' }), { + target: { value: 'value 2' }, + }); + fireEvent.change(getByRole('textbox', { name: 'Bar - 2' }), { + target: { value: 'value 2' }, + }); + fireEvent.click(getByRole('button', { name: 'Review' })); }); await act(async () => { - await fireEvent.click(getByRole('button', { name: 'Review' })); + fireEvent.click(getByRole('button', { name: 'Create' })); }); - await act(async () => { - await fireEvent.click(getByRole('button', { name: 'Create' })); + expect(onCreate).toHaveBeenCalledWith({ + foo: 'value 2', + bar: 'value 2', }); - - expect(onCreate).toHaveBeenCalled(); }); it('should render custom field extensions properly', async () => { @@ -335,13 +399,11 @@ describe('Stepper', () => { /> , ); - - act(() => { - fireEvent.click(getByRole('button', { name: 'Review' })); + fireEvent.click(getByRole('button', { name: 'Review' })); + await waitFor(() => { + expect(getByRole('progressbar')).toBeInTheDocument(); // Check if progress bar is rendered + expect(getByRole('button', { name: 'Review' })).toBeDisabled(); // Check if the button is disabled }); - - expect(getByRole('progressbar')).toBeInTheDocument(); - expect(getByRole('button', { name: 'Review' })).toBeDisabled(); }); it('should transform default error message', async () => { @@ -381,12 +443,11 @@ describe('Stepper', () => { , ); - await fireEvent.change(getByRole('textbox', { name: 'postcode' }), { - target: { value: 'invalid' }, - }); - await act(async () => { - await fireEvent.click(getByRole('button', { name: 'Review' })); + fireEvent.change(getByRole('textbox', { name: 'postcode' }), { + target: { value: 'invalid' }, + }); + fireEvent.click(getByRole('button', { name: 'Review' })); }); expect(getByText('invalid postcode')).toBeInTheDocument(); @@ -421,12 +482,12 @@ describe('Stepper', () => { , ); - await fireEvent.change(getByRole('textbox', { name: 'postcode' }), { - target: { value: 'invalid' }, - }); - await act(async () => { - await fireEvent.click(getByRole('button', { name: 'Review' })); + fireEvent.change(getByRole('textbox', { name: 'postcode' }), { + target: { value: 'invalid' }, + }); + + fireEvent.click(getByRole('button', { name: 'Review' })); }); expect(getByText('invalid postcode')).toBeInTheDocument(); @@ -494,13 +555,13 @@ describe('Stepper', () => { ); await act(async () => { - await fireEvent.click(getByRole('button', { name: 'Review' })); + fireEvent.click(getByRole('button', { name: 'Review' })); }); expect(getByRole('button', { name: 'Create' })).toBeInTheDocument(); await act(async () => { - await fireEvent.click(getByRole('button', { name: 'Create' })); + fireEvent.click(getByRole('button', { name: 'Create' })); }); // flush promises @@ -539,13 +600,13 @@ describe('Stepper', () => { ); await act(async () => { - await fireEvent.click(getByRole('button', { name: 'Inspect' })); + fireEvent.click(getByRole('button', { name: 'Inspect' })); }); expect(getByRole('button', { name: 'Make' })).toBeInTheDocument(); await act(async () => { - await fireEvent.click(getByRole('button', { name: 'Make' })); + fireEvent.click(getByRole('button', { name: 'Make' })); }); }); diff --git a/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx index 3a8858144b..a1b31d0089 100644 --- a/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx +++ b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx @@ -115,11 +115,16 @@ export const Stepper = (stepperProps: StepperProps) => { const apiHolder = useApiHolder(); const [activeStep, setActiveStep] = useState(0); const [isValidating, setIsValidating] = useState(false); - const [formState, setFormState] = useFormDataFromQuery(props.initialState); + const [initialState] = useFormDataFromQuery(props.initialState); + const [formState, setFormState] = useState<{ + [step: string]: Record; + }>(); const [errors, setErrors] = useState(); const styles = useStyles(); + const makeStepKey = (step: string | number) => `step-${step}`; + const backLabel = presentation?.buttonLabels?.backButtonText ?? backButtonText; const createLabel = @@ -155,16 +160,15 @@ export const Stepper = (stepperProps: StepperProps) => { }; const handleChange = useCallback( - (e: IChangeEvent) => - setFormState(current => ({ ...current, ...e.formData })), - [setFormState], + (e: IChangeEvent) => { + setFormState(current => ({ + ...current, + [makeStepKey(activeStep)]: e.formData, + })); + }, + [setFormState, activeStep], ); - const handleCreate = useCallback(() => { - props.onCreate(formState); - analytics.captureEvent('click', `${createLabel}`); - }, [props, formState, analytics, createLabel]); - const currentStep = useTransformSchemaToProps(steps[activeStep], { layouts }); const handleNext = async ({ @@ -191,7 +195,10 @@ export const Stepper = (stepperProps: StepperProps) => { return stepNum; }); } - setFormState(current => ({ ...current, ...formData })); + setFormState(current => ({ + ...current, + [makeStepKey(activeStep)]: formData, + })); }; const { @@ -202,6 +209,24 @@ export const Stepper = (stepperProps: StepperProps) => { const mergedUiSchema = merge({}, propUiSchema, currentStep?.uiSchema); + const mergedState = useMemo(() => { + if (!formState) { + return initialState; + } + const { [makeStepKey(activeStep)]: activeState, ...historicalState } = + formState; + const chronologicalState = { + ...historicalState, + [makeStepKey(activeStep)]: activeState, + }; + return merge({}, ...Object.values(chronologicalState)); + }, [formState, activeStep, initialState]); + + const handleCreate = useCallback(() => { + props.onCreate(mergedState); + analytics.captureEvent('click', `${createLabel}`); + }, [props, mergedState, analytics, createLabel]); + return ( <> {isValidating && } @@ -237,8 +262,8 @@ export const Stepper = (stepperProps: StepperProps) => {
{ ReviewStepComponent ? ( {}} steps={steps} @@ -282,7 +307,7 @@ export const Stepper = (stepperProps: StepperProps) => { /> ) : ( <> - +
+ + + +
+ + ); +}; diff --git a/plugins/scaffolder/src/alpha/components/TemplateEditorPage/CustomFieldsPage.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/CustomFieldsPage.tsx new file mode 100644 index 0000000000..f49b2ddf05 --- /dev/null +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/CustomFieldsPage.tsx @@ -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 React from 'react'; + +import { Page, Header, Content } from '@backstage/core-components'; +import { useRouteRef } from '@backstage/core-plugin-api'; +import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; +import { FieldExtensionOptions } from '@backstage/plugin-scaffolder-react'; + +import { editRouteRef } from '../../../routes'; +import { scaffolderTranslationRef } from '../../../translation'; + +import { CustomFieldExplorer } from './CustomFieldExplorer'; + +interface CustomFieldsPageProps { + fieldExtensions?: FieldExtensionOptions[]; +} + +export function CustomFieldsPage(props: CustomFieldsPageProps) { + const editLink = useRouteRef(editRouteRef); + const { t } = useTranslationRef(scaffolderTranslationRef); + + return ( + +
+ + + + + ); +} diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/DirectoryEditorContext.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/DirectoryEditorContext.tsx similarity index 93% rename from plugins/scaffolder/src/next/TemplateEditorPage/DirectoryEditorContext.tsx rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/DirectoryEditorContext.tsx index 0edf390bfe..bca2e04fde 100644 --- a/plugins/scaffolder/src/next/TemplateEditorPage/DirectoryEditorContext.tsx +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/DirectoryEditorContext.tsx @@ -14,13 +14,13 @@ * limitations under the License. */ -import { ErrorPanel, Progress } from '@backstage/core-components'; +import { ErrorPanel } from '@backstage/core-components'; import { useAsync, useRerender } from '@react-hookz/web'; import React, { createContext, ReactNode, useContext, useEffect } from 'react'; import { TemplateDirectoryAccess, TemplateFileAccess, -} from '../../lib/filesystem'; +} from '../../../lib/filesystem'; const MAX_SIZE = 1024 * 1024; const MAX_SIZE_MESSAGE = 'This file is too large to be displayed'; @@ -191,20 +191,17 @@ const DirectoryEditorContext = createContext( undefined, ); -export function useDirectoryEditor(): DirectoryEditor { +export function useDirectoryEditor(): DirectoryEditor | undefined { const value = useContext(DirectoryEditorContext); const rerender = useRerender(); useEffect(() => value?.subscribe(rerender), [value, rerender]); - if (!value) { - throw new Error('must be used within a DirectoryEditorProvider'); - } return value; } interface DirectoryEditorProviderProps { - directory: TemplateDirectoryAccess; + directory?: TemplateDirectoryAccess; children?: ReactNode; } @@ -212,7 +209,11 @@ export function DirectoryEditorProvider(props: DirectoryEditorProviderProps) { const { directory } = props; const [{ result, error }, { execute }] = useAsync( - async (dir: TemplateDirectoryAccess) => { + async (dir?: TemplateDirectoryAccess) => { + if (!dir) { + return undefined; + } + const manager = new DirectoryEditorManager(dir); await manager.reload(); @@ -231,8 +232,6 @@ export function DirectoryEditorProvider(props: DirectoryEditorProviderProps) { if (error) { return ; - } else if (!result) { - return ; } return ( diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/DryRunContext.test.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunContext.test.tsx similarity index 100% rename from plugins/scaffolder/src/next/TemplateEditorPage/DryRunContext.test.tsx rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunContext.test.tsx diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/DryRunContext.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunContext.tsx similarity index 100% rename from plugins/scaffolder/src/next/TemplateEditorPage/DryRunContext.tsx rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunContext.tsx diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/DryRunResults.test.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/DryRunResults.test.tsx similarity index 100% rename from plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/DryRunResults.test.tsx rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/DryRunResults.test.tsx diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/DryRunResults.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/DryRunResults.tsx similarity index 97% rename from plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/DryRunResults.tsx rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/DryRunResults.tsx index 12521e3f3f..070a7aaec8 100644 --- a/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/DryRunResults.tsx +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/DryRunResults.tsx @@ -27,7 +27,7 @@ import { useDryRun } from '../DryRunContext'; import { DryRunResultsList } from './DryRunResultsList'; import { DryRunResultsView } from './DryRunResultsView'; import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; -import { scaffolderTranslationRef } from '../../../translation'; +import { scaffolderTranslationRef } from '../../../../translation'; const useStyles = makeStyles(theme => ({ header: { diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/DryRunResultsList.test.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/DryRunResultsList.test.tsx similarity index 100% rename from plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/DryRunResultsList.test.tsx rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/DryRunResultsList.test.tsx diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/DryRunResultsList.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/DryRunResultsList.tsx similarity index 97% rename from plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/DryRunResultsList.tsx rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/DryRunResultsList.tsx index 9f44933466..8305577990 100644 --- a/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/DryRunResultsList.tsx +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/DryRunResultsList.tsx @@ -27,9 +27,9 @@ import DeleteIcon from '@material-ui/icons/Delete'; import DownloadIcon from '@material-ui/icons/GetApp'; import React from 'react'; import { useDryRun } from '../DryRunContext'; -import { downloadBlob } from '../../../lib/download'; +import { downloadBlob } from '../../../../lib/download'; import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; -import { scaffolderTranslationRef } from '../../../translation'; +import { scaffolderTranslationRef } from '../../../../translation'; const useStyles = makeStyles(theme => ({ root: { diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/DryRunResultsSplitView.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/DryRunResultsSplitView.tsx similarity index 100% rename from plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/DryRunResultsSplitView.tsx rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/DryRunResultsSplitView.tsx diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/DryRunResultsView.test.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/DryRunResultsView.test.tsx similarity index 100% rename from plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/DryRunResultsView.test.tsx rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/DryRunResultsView.test.tsx diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/DryRunResultsView.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/DryRunResultsView.tsx similarity index 97% rename from plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/DryRunResultsView.tsx rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/DryRunResultsView.tsx index 7de248dd56..422cd6faa9 100644 --- a/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/DryRunResultsView.tsx +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/DryRunResultsView.tsx @@ -26,11 +26,11 @@ import CodeMirror from '@uiw/react-codemirror'; import React, { useEffect, useMemo, useState } from 'react'; import { useDryRun } from '../DryRunContext'; import { DryRunResultsSplitView } from './DryRunResultsSplitView'; -import { FileBrowser } from '../../../components/FileBrowser'; +import { FileBrowser } from '../../../../components/FileBrowser'; import { TaskPageLinks } from './TaskPageLinks'; import { TaskStatusStepper } from './TaskStatusStepper'; import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; -import { scaffolderTranslationRef } from '../../../translation'; +import { scaffolderTranslationRef } from '../../../../translation'; const useStyles = makeStyles({ root: { diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/IconLink.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/IconLink.tsx similarity index 100% rename from plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/IconLink.tsx rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/IconLink.tsx diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/TaskPageLinks.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/TaskPageLinks.tsx similarity index 100% rename from plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/TaskPageLinks.tsx rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/TaskPageLinks.tsx diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/TaskStatusStepper.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/TaskStatusStepper.tsx similarity index 98% rename from plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/TaskStatusStepper.tsx rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/TaskStatusStepper.tsx index 7696051950..ec7d734ca4 100644 --- a/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/TaskStatusStepper.tsx +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/TaskStatusStepper.tsx @@ -32,7 +32,7 @@ import useInterval from 'react-use/esm/useInterval'; import humanizeDuration from 'humanize-duration'; import classNames from 'classnames'; import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; -import { scaffolderTranslationRef } from '../../../translation'; +import { scaffolderTranslationRef } from '../../../../translation'; const useStyles = makeStyles((theme: Theme) => createStyles({ diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/index.ts b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/index.ts similarity index 100% rename from plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/index.ts rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/DryRunResults/index.ts diff --git a/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditor.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditor.tsx new file mode 100644 index 0000000000..f2b9e5d7e2 --- /dev/null +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditor.tsx @@ -0,0 +1,97 @@ +/* + * 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 type { + FormProps, + LayoutOptions, +} from '@backstage/plugin-scaffolder-react'; +import { FieldExtensionOptions } from '@backstage/plugin-scaffolder-react'; +import { DirectoryEditorProvider } from './DirectoryEditorContext'; +import { + TemplateEditorLayout, + TemplateEditorLayoutToolbar, + TemplateEditorLayoutBrowser, + TemplateEditorLayoutFiles, + TemplateEditorLayoutPreview, + TemplateEditorLayoutConsole, +} from './TemplateEditorLayout'; +import { TemplateEditorToolbar } from './TemplateEditorToolbar'; +import { TemplateEditorToolbarFileMenu } from './TemplateEditorToolbarFileMenu'; +import { TemplateEditorBrowser } from './TemplateEditorBrowser'; +import { DryRunProvider } from './DryRunContext'; +import { TemplateEditorTextArea } from './TemplateEditorTextArea'; +import { TemplateEditorForm } from './TemplateEditorForm'; +import { DryRunResults } from './DryRunResults'; +import { useTemplateDirectory } from './useTemplateDirectory'; + +/** @public */ +export type ScaffolderTemplateEditorClassKey = + | 'root' + | 'toolbar' + | 'browser' + | 'editor' + | 'preview' + | 'results'; + +export const TemplateEditor = (props: { + layouts?: LayoutOptions[]; + formProps?: FormProps; + fieldExtensions?: FieldExtensionOptions[]; +}) => { + const { layouts, formProps, fieldExtensions } = props; + const [errorText, setErrorText] = useState(); + const { + directory, + handleOpenDirectory, + handleCreateDirectory, + handleCloseDirectory, + } = useTemplateDirectory(); + + return ( + + + + + + + + + + + + + + + + + + + + + + + + ); +}; diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorBrowser.test.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorBrowser.test.tsx similarity index 95% rename from plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorBrowser.test.tsx rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorBrowser.test.tsx index cec311a5cd..958548a131 100644 --- a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorBrowser.test.tsx +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorBrowser.test.tsx @@ -17,7 +17,7 @@ import { renderInTestApp } from '@backstage/test-utils'; import { screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React from 'react'; -import { MockFileSystemAccess } from '../../lib/filesystem/MockFileSystemAccess'; +import { MockFileSystemAccess } from '../../../lib/filesystem/MockFileSystemAccess'; import { DirectoryEditorProvider } from './DirectoryEditorContext'; import { TemplateEditorBrowser } from './TemplateEditorBrowser'; diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorBrowser.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorBrowser.tsx similarity index 73% rename from plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorBrowser.tsx rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorBrowser.tsx index 8bea86b074..8be58e45df 100644 --- a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorBrowser.tsx +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorBrowser.tsx @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import Grid from '@material-ui/core/Grid'; import Divider from '@material-ui/core/Divider'; import IconButton from '@material-ui/core/IconButton'; import Tooltip from '@material-ui/core/Tooltip'; @@ -22,40 +23,36 @@ import RefreshIcon from '@material-ui/icons/Refresh'; import SaveIcon from '@material-ui/icons/Save'; import React from 'react'; import { useDirectoryEditor } from './DirectoryEditorContext'; -import { FileBrowser } from '../../components/FileBrowser'; +import { FileBrowser } from '../../../components/FileBrowser'; import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; -import { scaffolderTranslationRef } from '../../translation'; +import { scaffolderTranslationRef } from '../../../translation'; -const useStyles = makeStyles(theme => ({ - button: { - padding: theme.spacing(1), - }, - buttons: { - display: 'flex', - flexFlow: 'row nowrap', - alignItems: 'center', - justifyContent: 'flex-start', - }, - buttonsGap: { - flex: '1 1 auto', - }, - buttonsDivider: { - marginBottom: theme.spacing(1), - }, -})); +const useStyles = makeStyles( + theme => ({ + grid: { + '& svg': { + margin: theme.spacing(1), + }, + }, + closeButton: { + marginLeft: 'auto', + }, + }), + { name: 'ScaffolderTemplateEditorBrowser' }, +); /** The local file browser for the template editor */ export function TemplateEditorBrowser(props: { onClose?: () => void }) { const classes = useStyles(); const directoryEditor = useDirectoryEditor(); - const changedFiles = directoryEditor.files.filter(file => file.dirty); + const changedFiles = directoryEditor?.files.filter(file => file.dirty); const { t } = useTranslationRef(scaffolderTranslationRef); const handleClose = () => { if (!props.onClose) { return; } - if (changedFiles.length > 0) { + if (changedFiles?.length) { // eslint-disable-next-line no-alert const accepted = window.confirm( t('templateEditorPage.templateEditorBrowser.closeConfirmMessage'), @@ -67,14 +64,18 @@ export function TemplateEditorBrowser(props: { onClose?: () => void }) { props.onClose(); }; + if (!directoryEditor) { + return null; + } + return ( <> -
+ !file.dirty)} onClick={() => directoryEditor.save()} > @@ -86,27 +87,27 @@ export function TemplateEditorBrowser(props: { onClose?: () => void }) { 'templateEditorPage.templateEditorBrowser.reloadIconTooltip', )} > - directoryEditor.reload()} - > + directoryEditor.reload()}> -
- + -
- +
+ file.path)} + filePaths={directoryEditor.files.map(file => file.path) ?? []} /> ); diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorForm.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorForm.tsx similarity index 82% rename from plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorForm.tsx rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorForm.tsx index e6149f57a1..4ae87a77e9 100644 --- a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorForm.tsx +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorForm.tsx @@ -16,13 +16,17 @@ import { useApiHolder } from '@backstage/core-plugin-api'; import { JsonObject, JsonValue } from '@backstage/types'; import { makeStyles } from '@material-ui/core/styles'; +import Paper from '@material-ui/core/Paper'; +import Typography from '@material-ui/core/Typography'; import React, { Component, ReactNode, useMemo, useState } from 'react'; import useDebounce from 'react-use/esm/useDebounce'; import yaml from 'yaml'; +import { useTranslationRef } from '@backstage/frontend-plugin-api'; import { LayoutOptions, TemplateParameterSchema, FieldExtensionOptions, + FormProps, } from '@backstage/plugin-scaffolder-react'; import { Stepper, @@ -31,19 +35,11 @@ import { import { useDryRun } from './DryRunContext'; import { useDirectoryEditor } from './DirectoryEditorContext'; +import { scaffolderTranslationRef } from '../../../translation'; + const useStyles = makeStyles({ containerWrapper: { - position: 'relative', width: '100%', - height: '100%', - }, - container: { - position: 'absolute', - top: 0, - bottom: 0, - left: 0, - right: 0, - overflow: 'auto', }, }); @@ -87,6 +83,7 @@ interface TemplateEditorFormProps { onDryRun?: (data: JsonObject) => Promise; fieldExtensions?: FieldExtensionOptions[]; layouts?: LayoutOptions[]; + formProps?: FormProps; } function isJsonObject(value: JsonValue | undefined): value is JsonObject { @@ -105,6 +102,7 @@ export function TemplateEditorForm(props: TemplateEditorFormProps) { } = props; const classes = useStyles(); const apiHolder = useApiHolder(); + const { t } = useTranslationRef(scaffolderTranslationRef); const [steps, setSteps] = useState(); @@ -179,25 +177,28 @@ export function TemplateEditorForm(props: TemplateEditorFormProps) { [contentIsSpec, content, apiHolder], ); - if (!steps) { - return null; - } - return (
-
- - { - await onDryRun?.(options); - }} - layouts={layouts} - /> - -
+ {steps ? ( + + + { + await onDryRun?.(options); + }} + layouts={layouts} + formProps={props.formProps} + /> + + + ) : ( + + {t('templateEditorForm.stepper.emptyText')} + + )}
); } @@ -206,14 +207,14 @@ export function TemplateEditorForm(props: TemplateEditorFormProps) { export function TemplateEditorFormDirectoryEditorDryRun( props: Pick< TemplateEditorFormProps, - 'setErrorText' | 'fieldExtensions' | 'layouts' + 'setErrorText' | 'fieldExtensions' | 'layouts' | 'formProps' >, ) { const { setErrorText, fieldExtensions = [], layouts } = props; const dryRun = useDryRun(); const directoryEditor = useDirectoryEditor(); - const { selectedFile } = directoryEditor; + const { selectedFile } = directoryEditor ?? {}; const handleDryRun = async (data: JsonObject) => { if (!selectedFile) { @@ -224,7 +225,7 @@ export function TemplateEditorFormDirectoryEditorDryRun( await dryRun.execute({ templateContent: selectedFile.content, values: data, - files: directoryEditor.files, + files: directoryEditor?.files ?? [], }); setErrorText(); } catch (e) { @@ -238,6 +239,10 @@ export function TemplateEditorFormDirectoryEditorDryRun( ? selectedFile.content : undefined; + if (!directoryEditor) { + return null; + } + return ( ); } diff --git a/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorIntro.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorIntro.tsx new file mode 100644 index 0000000000..f0406a58fa --- /dev/null +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorIntro.tsx @@ -0,0 +1,193 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import Card from '@material-ui/core/Card'; +import CardActionArea from '@material-ui/core/CardActionArea'; +import CardContent from '@material-ui/core/CardContent'; +import Typography from '@material-ui/core/Typography'; +import { makeStyles } from '@material-ui/core/styles'; +import { WebFileSystemAccess } from '../../../lib/filesystem'; +import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; +import { scaffolderTranslationRef } from '../../../translation'; +import CreateNewFolderIcon from '@material-ui/icons/CreateNewFolder'; +import ListAltIcon from '@material-ui/icons/ListAlt'; +import FormatListBulletedIcon from '@material-ui/icons/FormatListBulleted'; +import InfoOutlinedIcon from '@material-ui/icons/InfoOutlined'; +import CardMedia from '@material-ui/core/CardMedia'; +import PublishIcon from '@material-ui/icons/Publish'; +import SvgIcon from '@material-ui/core/SvgIcon'; +import Tooltip from '@material-ui/core/Tooltip'; + +const useStyles = makeStyles(theme => ({ + gridRoot: { + display: 'flex', + flex: 1, + alignItems: 'center', + justifyContent: 'center', + }, + cardGrid: { + maxWidth: 1000, + display: 'grid', + gridGap: theme.spacing(2), + gridAutoFlow: 'row', + [theme.breakpoints.up('md')]: { + gridTemplateRows: '1fr 1fr', + gridTemplateColumns: '1fr 1fr', + }, + }, + card: { + display: 'grid', + gridTemplateColumns: 'auto 1fr', + gridTemplateRows: '1fr', + alignItems: 'center', + margin: theme.spacing(0, 1), + marginTop: theme.spacing(2), + padding: theme.spacing(2), + }, + icon: { + justifySelf: 'center', + paddingTop: theme.spacing(1), + fontSize: 48, + }, + introText: { + textAlign: 'center', + marginTop: theme.spacing(2), + }, + infoIcon: { + position: 'absolute', + top: theme.spacing(1), + right: theme.spacing(1), + }, + cardContent: { + padding: theme.spacing(1), + }, +})); + +interface EditorIntroProps { + style?: JSX.IntrinsicElements['div']['style']; + onSelect?: ( + option: 'create-template' | 'local' | 'form' | 'field-explorer', + ) => void; +} + +function ActionCard(props: { + title: string; + description: string; + Icon: typeof SvgIcon; + action?: React.MouseEventHandler; + requireLoad?: boolean; +}) { + const supportsLoad = props.requireLoad + ? WebFileSystemAccess.isSupported() + : true; + const { t } = useTranslationRef(scaffolderTranslationRef); + + const classes = useStyles(); + const { Icon, title, description, action } = props; + return ( + + {!supportsLoad && ( + + + + )} + + + + + + + + {title} + + + {description} + + + + + ); +} +export function TemplateEditorIntro(props: EditorIntroProps) { + const classes = useStyles(); + const { t } = useTranslationRef(scaffolderTranslationRef); + + return ( +
+ + {t('templateEditorPage.templateEditorIntro.title')} + +
+
+ props.onSelect?.('local')} + /> + props.onSelect?.('create-template')} + Icon={CreateNewFolderIcon} + /> + + props.onSelect?.('form')} + /> + + props.onSelect?.('field-explorer')} + /> +
+
+
+ ); +} diff --git a/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorLayout.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorLayout.tsx new file mode 100644 index 0000000000..f77881e79a --- /dev/null +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorLayout.tsx @@ -0,0 +1,126 @@ +/* + * 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, { PropsWithChildren } from 'react'; +import { WithStyles, withStyles } from '@material-ui/core/styles'; + +export const TemplateEditorLayout = withStyles( + theme => ({ + root: { + height: '100%', + gridArea: 'pageContent', + display: 'grid', + gridTemplateAreas: ` + "toolbar" + "browser" + "editor" + "preview" + "results" + `, + [theme.breakpoints.up('md')]: { + gridTemplateAreas: ` + "toolbar toolbar toolbar" + "browser editor preview" + "results results results" + `, + gridTemplateColumns: '1fr 3fr 2fr', + gridTemplateRows: 'auto 1fr auto', + }, + }, + }), + { name: 'ScaffolderTemplateEditorLayout' }, +)(({ children, classes }: PropsWithChildren) => ( +
{children}
+)); + +export const TemplateEditorLayoutToolbar = withStyles( + { + root: { + gridArea: 'toolbar', + }, + }, + { name: 'ScaffolderTemplateEditorLayoutToolbar' }, +)(({ children, classes }: PropsWithChildren) => ( +
{children}
+)); + +export const TemplateEditorLayoutBrowser = withStyles( + theme => ({ + root: { + gridArea: 'browser', + overflow: 'auto', + [theme.breakpoints.up('md')]: { + borderRight: `1px solid ${theme.palette.divider}`, + }, + }, + }), + { name: 'ScaffolderTemplateEditorLayoutBrowser' }, +)(({ children, classes }: PropsWithChildren) => ( +
{children}
+)); + +export const TemplateEditorLayoutFiles = withStyles( + { + root: { + gridArea: 'editor', + overflow: 'auto', + }, + }, + { name: 'ScaffolderTemplateEditorLayoutFiles' }, +)(({ children, classes }: PropsWithChildren) => ( +
{children}
+)); + +export const TemplateEditorLayoutPreview = withStyles( + theme => ({ + root: { + gridArea: 'preview', + position: 'relative', + backgroundColor: theme.palette.background.default, + [theme.breakpoints.up('md')]: { + borderLeft: `1px solid ${theme.palette.divider}`, + }, + }, + scroll: { + height: '100%', + padding: theme.spacing(1), + [theme.breakpoints.up('md')]: { + position: 'absolute', + top: 0, + left: 0, + right: 0, + bottom: 0, + overflow: 'auto', + }, + }, + }), + { name: 'ScaffolderTemplateEditorLayoutPreview' }, +)(({ children, classes }: PropsWithChildren) => ( +
+
{children}
+
+)); + +export const TemplateEditorLayoutConsole = withStyles( + { + root: { + gridArea: 'results', + }, + }, + { name: 'ScaffolderTemplateEditorLayoutConsole' }, +)(({ children, classes }: PropsWithChildren) => ( +
{children}
+)); diff --git a/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorPage.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorPage.tsx new file mode 100644 index 0000000000..b17cc403f1 --- /dev/null +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorPage.tsx @@ -0,0 +1,68 @@ +/* + * 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 from 'react'; +import { makeStyles } from '@material-ui/core/styles'; +import { Content, Header, Page } from '@backstage/core-components'; +import { useRouteRef } from '@backstage/core-plugin-api'; +import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; +import { + FormProps, + FieldExtensionOptions, + type LayoutOptions, +} from '@backstage/plugin-scaffolder-react'; +import { scaffolderTranslationRef } from '../../../translation'; +import { editRouteRef } from '../../../routes'; +import { TemplateEditor } from './TemplateEditor'; + +const useStyles = makeStyles( + { + content: { + padding: 0, + }, + }, + { name: 'ScaffolderTemplateEditorToolbar' }, +); + +interface TemplatePageProps { + defaultPreviewTemplate?: string; + fieldExtensions?: FieldExtensionOptions[]; + layouts?: LayoutOptions[]; + formProps?: FormProps; +} + +export function TemplateEditorPage(props: TemplatePageProps) { + const classes = useStyles(); + const editLink = useRouteRef(editRouteRef); + const { t } = useTranslationRef(scaffolderTranslationRef); + + return ( + +
+ + + + + ); +} diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorTextArea.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorTextArea.tsx similarity index 84% rename from plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorTextArea.tsx rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorTextArea.tsx index 696b21d1df..1cca87ca4b 100644 --- a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorTextArea.tsx +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorTextArea.tsx @@ -20,6 +20,7 @@ import { showPanel } from '@codemirror/view'; import IconButton from '@material-ui/core/IconButton'; import Paper from '@material-ui/core/Paper'; import Tooltip from '@material-ui/core/Tooltip'; +import Typography from '@material-ui/core/Typography'; import { makeStyles } from '@material-ui/core/styles'; import RefreshIcon from '@material-ui/icons/Refresh'; import SaveIcon from '@material-ui/icons/Save'; @@ -28,7 +29,7 @@ import CodeMirror from '@uiw/react-codemirror'; import React, { useMemo } from 'react'; import { useDirectoryEditor } from './DirectoryEditorContext'; import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; -import { scaffolderTranslationRef } from '../../translation'; +import { scaffolderTranslationRef } from '../../../translation'; const useStyles = makeStyles(theme => ({ container: { @@ -36,12 +37,21 @@ const useStyles = makeStyles(theme => ({ width: '100%', height: '100%', }, + typography: { + padding: theme.spacing(1.5), + }, + button: { + verticalAlign: 'top', + }, codeMirror: { - position: 'absolute', - top: 0, - bottom: 0, - left: 0, - right: 0, + height: '100%', + [theme.breakpoints.up('md')]: { + position: 'absolute', + top: 0, + bottom: 0, + left: 0, + right: 0, + }, }, errorPanel: { color: theme.palette.error.main, @@ -143,9 +153,23 @@ export function TemplateEditorTextArea(props: { export function TemplateEditorDirectoryEditorTextArea(props: { errorText?: string; }) { + const classes = useStyles(); const directoryEditor = useDirectoryEditor(); + const { t } = useTranslationRef(scaffolderTranslationRef); - const actions = directoryEditor.selectedFile?.dirty + if (!directoryEditor) { + return ( + + {t('templateEditorPage.templateEditorTextArea.emptyStateParagraph')} + + ); + } + + const actions = directoryEditor?.selectedFile?.dirty ? { onSave: () => directoryEditor.save(), onReload: () => directoryEditor.reload(), @@ -158,7 +182,9 @@ export function TemplateEditorDirectoryEditorTextArea(props: { directoryEditor.selectedFile?.updateContent(content)} + onUpdate={content => + directoryEditor?.selectedFile?.updateContent(content) + } {...actions} /> ); diff --git a/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorToolbar.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorToolbar.tsx new file mode 100644 index 0000000000..b09b4d861c --- /dev/null +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorToolbar.tsx @@ -0,0 +1,171 @@ +/* + * 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, { ReactNode, useState } from 'react'; + +import { makeStyles } from '@material-ui/core/styles'; +import AppBar from '@material-ui/core/AppBar'; +import Toolbar from '@material-ui/core/Toolbar'; +import Tooltip from '@material-ui/core/Tooltip'; +import ButtonGroup from '@material-ui/core/ButtonGroup'; +import Button from '@material-ui/core/Button'; +import Drawer from '@material-ui/core/Drawer'; +import Dialog from '@material-ui/core/Dialog'; +import DialogTitle from '@material-ui/core/DialogTitle'; +import DialogContent from '@material-ui/core/DialogContent'; +import DialogContentText from '@material-ui/core/DialogContentText'; +import DialogActions from '@material-ui/core/DialogActions'; +import ExtensionIcon from '@material-ui/icons/Extension'; +import DescriptionIcon from '@material-ui/icons/Description'; + +import { useTranslationRef } from '@backstage/frontend-plugin-api'; +import { FieldExtensionOptions } from '@backstage/plugin-scaffolder-react'; + +import { ActionPageContent } from '../../../components/ActionsPage/ActionsPage'; +import { scaffolderTranslationRef } from '../../../translation'; +import { CustomFieldPlaygroud } from './CustomFieldPlaygroud'; + +const useStyles = makeStyles( + theme => ({ + paper: { + width: '90%', + padding: theme.spacing(2), + backgroundColor: theme.palette.background.default, + [theme.breakpoints.up('sm')]: { + width: '70%', + }, + [theme.breakpoints.up('md')]: { + width: '50%', + }, + }, + appbar: { + zIndex: 1, + }, + toolbar: { + display: 'grid', + gridTemplateColumns: 'auto 1fr', + gridGap: theme.spacing(1), + padding: theme.spacing(0, 1), + backgroundColor: theme.palette.background.paper, + }, + toolbarCustomActions: { + display: 'grid', + alignItems: 'center', + gridAutoFlow: 'Column', + gridGap: theme.spacing(1), + }, + toolbarDefaultActions: { + justifySelf: 'end', + }, + }), + { name: 'ScaffolderTemplateEditorToolbar' }, +); + +export function TemplateEditorToolbar(props: { + children?: ReactNode; + fieldExtensions?: FieldExtensionOptions[]; +}) { + const { children, fieldExtensions } = props; + const classes = useStyles(); + const { t } = useTranslationRef(scaffolderTranslationRef); + const [showFieldsDrawer, setShowFieldsDrawer] = useState(false); + const [showActionsDrawer, setShowActionsDrawer] = useState(false); + const [showPublishModal, setShowPublishModal] = useState(false); + + return ( + + +
{children}
+ + + + + + + + + + setShowFieldsDrawer(false)} + > + + + setShowActionsDrawer(false)} + > + + + setShowPublishModal(false)} + open={showPublishModal} + aria-labelledby="publish-dialog-title" + aria-describedby="publish-dialog-description" + > + + {t('templateEditorToolbar.addToCatalogDialogTitle')} + + + + {t( + 'templateEditorToolbar.addToCatalogDialogContent.stepsIntroduction', + )} +
    + {t( + 'templateEditorToolbar.addToCatalogDialogContent.stepsListItems', + ) + .split('\n') + .map((step, index) => ( +
  • {step}
  • + ))} +
+
+
+ + + +
+
+
+ ); +} diff --git a/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorToolbarFileMenu.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorToolbarFileMenu.tsx new file mode 100644 index 0000000000..9b8eee6162 --- /dev/null +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorToolbarFileMenu.tsx @@ -0,0 +1,109 @@ +/* + * 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, { MouseEvent, useCallback, useState } from 'react'; +import { useNavigate } from 'react-router-dom'; + +import Button from '@material-ui/core/Button'; +import Menu from '@material-ui/core/Menu'; +import MenuItem from '@material-ui/core/MenuItem'; + +import { useRouteRef } from '@backstage/core-plugin-api'; +import { useTranslationRef } from '@backstage/frontend-plugin-api'; + +import { editRouteRef } from '../../../routes'; +import { scaffolderTranslationRef } from '../../../translation'; + +export function TemplateEditorToolbarFileMenu(props: { + onOpenDirectory?: () => void; + onCreateDirectory?: () => void; + onCloseDirectory?: () => void; +}) { + const { onOpenDirectory, onCreateDirectory, onCloseDirectory } = props; + const navigate = useNavigate(); + const editLink = useRouteRef(editRouteRef); + const { t } = useTranslationRef(scaffolderTranslationRef); + const [anchorEl, setAnchorEl] = useState(null); + + const handleOpenMenu = useCallback( + (event: MouseEvent) => { + setAnchorEl(event.currentTarget); + }, + [setAnchorEl], + ); + + const handleCloseMenu = useCallback(() => { + setAnchorEl(null); + }, [setAnchorEl]); + + const handleOpenDirectory = useCallback(() => { + handleCloseMenu(); + onOpenDirectory?.(); + }, [handleCloseMenu, onOpenDirectory]); + + const handleCreateDirectory = useCallback(() => { + handleCloseMenu(); + onCreateDirectory?.(); + }, [handleCloseMenu, onCreateDirectory]); + + const handleCloseEditor = useCallback(() => { + handleCloseMenu(); + onCloseDirectory?.(); + navigate(editLink()); + }, [handleCloseMenu, onCloseDirectory, navigate, editLink]); + + return ( + <> + + + + {t('templateEditorToolbarFileMenu.options.openDirectory')} + + + {t('templateEditorToolbarFileMenu.options.createDirectory')} + + + {t('templateEditorToolbarFileMenu.options.closeEditor')} + + + + ); +} diff --git a/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorToolbarTemplatesMenu.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorToolbarTemplatesMenu.tsx new file mode 100644 index 0000000000..81ffac2c04 --- /dev/null +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorToolbarTemplatesMenu.tsx @@ -0,0 +1,110 @@ +/* + * 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, { MouseEvent, useCallback, useState } from 'react'; + +import { makeStyles } from '@material-ui/core/styles'; +import Button from '@material-ui/core/Button'; +import Menu from '@material-ui/core/Menu'; +import MenuItem from '@material-ui/core/MenuItem'; + +import { Entity } from '@backstage/catalog-model'; +import { useTranslationRef } from '@backstage/frontend-plugin-api'; +import { scaffolderTranslationRef } from '../../../translation'; + +const ITEM_HEIGHT = 48; + +const useStyles = makeStyles({ + menu: { + maxHeight: ITEM_HEIGHT * 5, + }, +}); + +export type TemplateOption = { + label: string; + value: Entity; +}; + +export function TemplateEditorToolbarTemplatesMenu(props: { + options: TemplateOption[]; + selectedOption?: TemplateOption; + onSelectOption: (option: TemplateOption) => void; +}) { + const { options, selectedOption, onSelectOption } = props; + const classes = useStyles(); + const [anchorEl, setAnchorEl] = useState(null); + const { t } = useTranslationRef(scaffolderTranslationRef); + + const handleOpenMenu = useCallback( + (event: MouseEvent) => { + setAnchorEl(event.currentTarget); + }, + [setAnchorEl], + ); + + const handleCloseMenu = useCallback(() => { + setAnchorEl(null); + }, [setAnchorEl]); + + const handleSelectOption = useCallback( + (option: TemplateOption) => { + handleCloseMenu(); + onSelectOption(option); + }, + [handleCloseMenu, onSelectOption], + ); + + return ( + <> + + + {options.map((option, index) => ( + handleSelectOption(option)} + > + {option.label} + + ))} + + + ); +} diff --git a/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateFormPage.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateFormPage.tsx new file mode 100644 index 0000000000..7558276721 --- /dev/null +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateFormPage.tsx @@ -0,0 +1,78 @@ +/* + * 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, { useCallback } from 'react'; +import { useNavigate } from 'react-router-dom'; + +import { makeStyles } from '@material-ui/core/styles'; + +import { Page, Header, Content } from '@backstage/core-components'; +import { useRouteRef } from '@backstage/core-plugin-api'; +import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; +import { + FormProps, + LayoutOptions, + FieldExtensionOptions, +} from '@backstage/plugin-scaffolder-react'; + +import { editRouteRef } from '../../../routes'; +import { scaffolderTranslationRef } from '../../../translation'; + +import { TemplateFormPreviewer } from './TemplateFormPreviewer'; + +const useStyles = makeStyles({ + root: { + padding: 0, + }, +}); + +interface TemplateFormPageProps { + layouts?: LayoutOptions[]; + formProps?: FormProps; + fieldExtensions?: FieldExtensionOptions[]; + defaultPreviewTemplate?: string; +} + +export function TemplateFormPage(props: TemplateFormPageProps) { + const classes = useStyles(); + const navigate = useNavigate(); + const editLink = useRouteRef(editRouteRef); + const { t } = useTranslationRef(scaffolderTranslationRef); + + const handleClose = useCallback(() => { + navigate(editLink()); + }, [navigate, editLink]); + + return ( + +
+ + + + + ); +} diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateFormPreviewer.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateFormPreviewer.tsx similarity index 57% rename from plugins/scaffolder/src/next/TemplateEditorPage/TemplateFormPreviewer.tsx rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateFormPreviewer.tsx index 07f2fd7f07..160a6b4db9 100644 --- a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateFormPreviewer.tsx +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateFormPreviewer.tsx @@ -13,31 +13,35 @@ * 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 from '@material-ui/core/FormControl'; -import IconButton from '@material-ui/core/IconButton'; -import InputLabel from '@material-ui/core/InputLabel'; -import LinearProgress from '@material-ui/core/LinearProgress'; -import MenuItem from '@material-ui/core/MenuItem'; -import Select from '@material-ui/core/Select'; import { makeStyles } from '@material-ui/core/styles'; -import CloseIcon from '@material-ui/icons/Close'; import React, { useCallback, useState } from 'react'; import useAsync from 'react-use/esm/useAsync'; import yaml from 'yaml'; import { LayoutOptions, FieldExtensionOptions, + FormProps, } from '@backstage/plugin-scaffolder-react'; +import { + TemplateEditorLayout, + TemplateEditorLayoutToolbar, + TemplateEditorLayoutFiles, + TemplateEditorLayoutPreview, +} from './TemplateEditorLayout'; +import { TemplateEditorToolbar } from './TemplateEditorToolbar'; +import { TemplateEditorToolbarFileMenu } from './TemplateEditorToolbarFileMenu'; +import { + TemplateOption, + TemplateEditorToolbarTemplatesMenu, +} from './TemplateEditorToolbarTemplatesMenu'; import { TemplateEditorForm } from './TemplateEditorForm'; import { TemplateEditorTextArea } from './TemplateEditorTextArea'; -import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; -import { scaffolderTranslationRef } from '../../translation'; const EXAMPLE_TEMPLATE_PARAMS_YAML = `# Edit the template parameters below to see how they will render in the scaffolder form UI parameters: @@ -78,58 +82,62 @@ steps: name: \${{parameters.name}} `; -type TemplateOption = { - label: string; - value: Entity; -}; +/** @public */ +export type ScaffolderTemplateFormPreviewerClassKey = + | 'root' + | 'toolbar' + | 'controls' + | 'textArea' + | 'preview'; -const useStyles = makeStyles(theme => ({ - root: { - gridArea: 'pageContent', - display: 'grid', - gridTemplateAreas: ` - "controls controls" +const useStyles = makeStyles( + theme => ({ + root: { + height: '100%', + gridArea: 'pageContent', + display: 'grid', + gridTemplateAreas: ` + "toolbar" + "textArea" + "preview" + `, + [theme.breakpoints.up('md')]: { + gridTemplateAreas: ` + "toolbar toolbar" "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', - }, -})); + gridTemplateRows: 'auto 1fr', + gridTemplateColumns: '1fr 1fr', + }, + }, + files: { + gridArea: 'textArea', + }, + }), + { name: 'ScaffolderTemplateFormPreviewer' }, +); export const TemplateFormPreviewer = ({ defaultPreviewTemplate = EXAMPLE_TEMPLATE_PARAMS_YAML, customFieldExtensions = [], - onClose, layouts = [], + formProps, }: { defaultPreviewTemplate?: string; customFieldExtensions?: FieldExtensionOptions[]; onClose?: () => void; layouts?: LayoutOptions[]; + formProps?: FormProps; }) => { const classes = useStyles(); - const { t } = useTranslationRef(scaffolderTranslationRef); const alertApi = useApi(alertApiRef); const catalogApi = useApi(catalogApiRef); - const [selectedTemplate, setSelectedTemplate] = useState(''); const [errorText, setErrorText] = useState(); + const [selectedTemplate, setSelectedTemplate] = useState(); const [templateOptions, setTemplateOptions] = useState([]); const [templateYaml, setTemplateYaml] = useState(defaultPreviewTemplate); - const { loading } = useAsync( + useAsync( () => catalogApi .getEntities({ @@ -165,57 +173,42 @@ export const TemplateFormPreviewer = ({ const handleSelectChange = useCallback( // TODO(Rugvip): Afaik this should be Entity, but didn't want to make runtime changes while fixing types - (selected: any) => { + (selected: TemplateOption) => { setSelectedTemplate(selected); - setTemplateYaml(yaml.stringify(selected.spec)); + setTemplateYaml(yaml.stringify(selected.value.spec)); }, - [setTemplateYaml], + [setSelectedTemplate, setTemplateYaml], ); return ( - <> - {loading && } -
-
- - - {t('templateEditorPage.templateFormPreviewer.title')} - - - - - - - -
-
- + + + + -
-
- -
-
- + + + + + + + + + ); }; diff --git a/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateIntroPage.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateIntroPage.tsx new file mode 100644 index 0000000000..b9825bc056 --- /dev/null +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateIntroPage.tsx @@ -0,0 +1,78 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React from 'react'; +import { Content, Header, Page } from '@backstage/core-components'; + +import { WebFileSystemAccess } from '../../../lib/filesystem'; + +import { TemplateEditorIntro } from './TemplateEditorIntro'; +import { useNavigate } from 'react-router-dom'; +import { useRouteRef } from '@backstage/core-plugin-api'; +import { + rootRouteRef, + editorRouteRef, + templateFormRouteRef, + customFieldsRouteRef, +} from '../../../routes'; +import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; +import { scaffolderTranslationRef } from '../../../translation'; +import { WebFileSystemStore } from '../../../lib/filesystem/WebFileSystemAccess'; +import { createExampleTemplate } from '../../../lib/filesystem/createExampleTemplate'; + +export function TemplateIntroPage() { + const navigate = useNavigate(); + const createLink = useRouteRef(rootRouteRef); + const editorLink = useRouteRef(editorRouteRef); + const templateFormLink = useRouteRef(templateFormRouteRef); + const customFieldsLink = useRouteRef(customFieldsRouteRef); + const { t } = useTranslationRef(scaffolderTranslationRef); + + return ( + +
+ + { + if (option === 'local') { + WebFileSystemAccess.requestDirectoryAccess() + .then(directory => WebFileSystemStore.setDirectory(directory)) + .then(() => navigate(editorLink())) + .catch(() => {}); + } else if (option === 'create-template') { + WebFileSystemAccess.requestDirectoryAccess() + .then(directory => { + createExampleTemplate(directory).then(() => { + WebFileSystemStore.setDirectory(directory); + navigate(editorLink()); + }); + }) + .catch(() => {}); + } else if (option === 'form') { + navigate(templateFormLink()); + } else if (option === 'field-explorer') { + navigate(customFieldsLink()); + } + }} + /> + + + ); +} diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/index.ts b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/index.ts similarity index 61% rename from plugins/scaffolder/src/next/TemplateEditorPage/index.ts rename to plugins/scaffolder/src/alpha/components/TemplateEditorPage/index.ts index 7ec6bddb64..f16f2426d7 100644 --- a/plugins/scaffolder/src/next/TemplateEditorPage/index.ts +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/index.ts @@ -15,3 +15,9 @@ */ export { TemplateEditorPage } from './TemplateEditorPage'; +export { TemplateFormPage } from './TemplateFormPage'; +export { TemplateIntroPage } from './TemplateIntroPage'; +export { CustomFieldsPage } from './CustomFieldsPage'; +export type { ScaffolderCustomFieldExplorerClassKey } from './CustomFieldExplorer'; +export type { ScaffolderTemplateEditorClassKey } from './TemplateEditor'; +export type { ScaffolderTemplateFormPreviewerClassKey } from './TemplateFormPreviewer'; diff --git a/plugins/scaffolder/src/alpha/components/TemplateEditorPage/useTemplateDirectory.ts b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/useTemplateDirectory.ts new file mode 100644 index 0000000000..812a21e437 --- /dev/null +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/useTemplateDirectory.ts @@ -0,0 +1,66 @@ +/* + * 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 { useCallback } from 'react'; +import useAsyncRetry from 'react-use/esm/useAsyncRetry'; + +import { + WebFileSystemAccess, + WebFileSystemStore, + WebDirectoryAccess, +} from '../../../lib/filesystem'; +import { createExampleTemplate } from '../../../lib/filesystem/createExampleTemplate'; + +export function useTemplateDirectory(): { + directory?: WebDirectoryAccess; + loading: boolean; + error?: Error; + handleOpenDirectory: () => void; + handleCreateDirectory: () => void; + handleCloseDirectory: () => void; +} { + const { value, loading, error, retry } = useAsyncRetry(async () => { + const directory = await WebFileSystemStore.getDirectory(); + if (!directory) return undefined; + return WebFileSystemAccess.fromHandle(directory); + }, []); + + const handleOpenDirectory = useCallback(() => { + WebFileSystemAccess.requestDirectoryAccess() + .then(WebFileSystemStore.setDirectory) + .then(retry); + }, [retry]); + + const handleCreateDirectory = useCallback(() => { + WebFileSystemAccess.requestDirectoryAccess() + .then(createExampleTemplate) + .then(WebFileSystemStore.setDirectory) + .then(retry); + }, [retry]); + + const handleCloseDirectory = useCallback(() => { + WebFileSystemStore.setDirectory(undefined).then(retry); + }, [retry]); + + return { + directory: value, + loading, + error, + handleOpenDirectory, + handleCreateDirectory, + handleCloseDirectory, + }; +} diff --git a/plugins/scaffolder/src/next/TemplateListPage/RegisterExistingButton.test.tsx b/plugins/scaffolder/src/alpha/components/TemplateListPage/RegisterExistingButton.test.tsx similarity index 100% rename from plugins/scaffolder/src/next/TemplateListPage/RegisterExistingButton.test.tsx rename to plugins/scaffolder/src/alpha/components/TemplateListPage/RegisterExistingButton.test.tsx diff --git a/plugins/scaffolder/src/next/TemplateListPage/RegisterExistingButton.tsx b/plugins/scaffolder/src/alpha/components/TemplateListPage/RegisterExistingButton.tsx similarity index 96% rename from plugins/scaffolder/src/next/TemplateListPage/RegisterExistingButton.tsx rename to plugins/scaffolder/src/alpha/components/TemplateListPage/RegisterExistingButton.tsx index abec7c47e1..126f00dde5 100644 --- a/plugins/scaffolder/src/next/TemplateListPage/RegisterExistingButton.tsx +++ b/plugins/scaffolder/src/alpha/components/TemplateListPage/RegisterExistingButton.tsx @@ -61,7 +61,7 @@ export const RegisterExistingButton = (props: RegisterExistingButtonProps) => { ) : ( - ); diff --git a/plugins/scaffolder/src/next/TemplateListPage/TemplateListPage.test.tsx b/plugins/scaffolder/src/alpha/components/TemplateListPage/TemplateListPage.test.tsx similarity index 99% rename from plugins/scaffolder/src/next/TemplateListPage/TemplateListPage.test.tsx rename to plugins/scaffolder/src/alpha/components/TemplateListPage/TemplateListPage.test.tsx index 2ad0752cc8..ba00845577 100644 --- a/plugins/scaffolder/src/next/TemplateListPage/TemplateListPage.test.tsx +++ b/plugins/scaffolder/src/alpha/components/TemplateListPage/TemplateListPage.test.tsx @@ -25,7 +25,7 @@ import { TestApiProvider, } from '@backstage/test-utils'; import React from 'react'; -import { rootRouteRef } from '../../routes'; +import { rootRouteRef } from '../../../routes'; import { TemplateListPage } from './TemplateListPage'; describe('TemplateListPage', () => { diff --git a/plugins/scaffolder/src/next/TemplateListPage/TemplateListPage.tsx b/plugins/scaffolder/src/alpha/components/TemplateListPage/TemplateListPage.tsx similarity index 97% rename from plugins/scaffolder/src/next/TemplateListPage/TemplateListPage.tsx rename to plugins/scaffolder/src/alpha/components/TemplateListPage/TemplateListPage.tsx index 4042506d1e..8d0c73f0a7 100644 --- a/plugins/scaffolder/src/next/TemplateListPage/TemplateListPage.tsx +++ b/plugins/scaffolder/src/alpha/components/TemplateListPage/TemplateListPage.tsx @@ -50,14 +50,14 @@ import { scaffolderListTaskRouteRef, selectedTemplateRouteRef, viewTechDocRouteRef, -} from '../../routes'; +} from '../../../routes'; import { parseEntityRef, stringifyEntityRef } from '@backstage/catalog-model'; import { TemplateGroupFilter } from '@backstage/plugin-scaffolder-react'; import { TranslationFunction, useTranslationRef, } from '@backstage/core-plugin-api/alpha'; -import { scaffolderTranslationRef } from '../../translation'; +import { scaffolderTranslationRef } from '../../../translation'; /** * @alpha @@ -177,7 +177,7 @@ export const TemplateListPage = (props: TemplateListPageProps) => {
- + ({ button: { diff --git a/plugins/scaffolder/src/next/TemplateWizardPage/index.ts b/plugins/scaffolder/src/alpha/components/TemplateWizardPage/index.ts similarity index 100% rename from plugins/scaffolder/src/next/TemplateWizardPage/index.ts rename to plugins/scaffolder/src/alpha/components/TemplateWizardPage/index.ts diff --git a/plugins/scaffolder/src/next/index.ts b/plugins/scaffolder/src/alpha/components/index.ts similarity index 81% rename from plugins/scaffolder/src/next/index.ts rename to plugins/scaffolder/src/alpha/components/index.ts index 2ae1b7b6c7..e3bded77e9 100644 --- a/plugins/scaffolder/src/next/index.ts +++ b/plugins/scaffolder/src/alpha/components/index.ts @@ -13,6 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +export type { + ScaffolderCustomFieldExplorerClassKey, + ScaffolderTemplateEditorClassKey, + ScaffolderTemplateFormPreviewerClassKey, +} from './TemplateEditorPage'; export * from './TemplateListPage'; export * from './TemplateWizardPage'; export * from './types'; diff --git a/plugins/scaffolder/src/next/types.ts b/plugins/scaffolder/src/alpha/components/types.ts similarity index 100% rename from plugins/scaffolder/src/next/types.ts rename to plugins/scaffolder/src/alpha/components/types.ts diff --git a/plugins/scaffolder/src/alpha/extensions.tsx b/plugins/scaffolder/src/alpha/extensions.tsx new file mode 100644 index 0000000000..191dcf407c --- /dev/null +++ b/plugins/scaffolder/src/alpha/extensions.tsx @@ -0,0 +1,52 @@ +/* + * 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 { + compatWrapper, + convertLegacyRouteRef, +} from '@backstage/core-compat-api'; +import { + NavItemBlueprint, + PageBlueprint, +} from '@backstage/frontend-plugin-api'; +import React from 'react'; +import { rootRouteRef } from '../routes'; +import CreateComponentIcon from '@material-ui/icons/AddCircleOutline'; +import { FormFieldBlueprint } from '@backstage/plugin-scaffolder-react/alpha'; + +export const scaffolderPage = PageBlueprint.make({ + params: { + routeRef: convertLegacyRouteRef(rootRouteRef), + defaultPath: '/create', + loader: () => + import('../components/Router').then(m => compatWrapper()), + }, +}); + +export const scaffolderNavItem = NavItemBlueprint.make({ + params: { + routeRef: convertLegacyRouteRef(rootRouteRef), + title: 'Create...', + icon: CreateComponentIcon, + }, +}); + +export const repoUrlPickerFormField = FormFieldBlueprint.make({ + name: 'repo-url-picker', + params: { + field: () => import('./fields/RepoUrlPicker').then(m => m.RepoUrlPicker), + }, +}); diff --git a/plugins/scaffolder/src/alpha/fields/RepoUrlPicker.ts b/plugins/scaffolder/src/alpha/fields/RepoUrlPicker.ts new file mode 100644 index 0000000000..add8408b2d --- /dev/null +++ b/plugins/scaffolder/src/alpha/fields/RepoUrlPicker.ts @@ -0,0 +1,28 @@ +/* + * 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 { createFormField } from '@backstage/plugin-scaffolder-react/alpha'; +import { RepoUrlPicker as Component } from '../../components/fields/RepoUrlPicker/RepoUrlPicker'; +import { + RepoUrlPickerFieldSchema, + repoPickerValidation, +} from '../../components'; + +export const RepoUrlPicker = createFormField({ + component: Component, + name: 'RepoUrlPicker', + validation: repoPickerValidation, + schema: RepoUrlPickerFieldSchema, +}); diff --git a/plugins/scaffolder/src/alpha/index.ts b/plugins/scaffolder/src/alpha/index.ts new file mode 100644 index 0000000000..bd3104a274 --- /dev/null +++ b/plugins/scaffolder/src/alpha/index.ts @@ -0,0 +1,27 @@ +/* + * 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. + */ +export { + type FormProps, + type TemplateListPageProps, + type TemplateWizardPageProps, + type ScaffolderCustomFieldExplorerClassKey, + type ScaffolderTemplateEditorClassKey, + type ScaffolderTemplateFormPreviewerClassKey, +} from './components'; + +export { scaffolderTranslationRef } from '../translation'; + +export { default } from './plugin'; diff --git a/plugins/scaffolder/src/alpha/plugin.tsx b/plugins/scaffolder/src/alpha/plugin.tsx new file mode 100644 index 0000000000..54e375e875 --- /dev/null +++ b/plugins/scaffolder/src/alpha/plugin.tsx @@ -0,0 +1,59 @@ +/* + * 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 { convertLegacyRouteRefs } from '@backstage/core-compat-api'; +import { createFrontendPlugin } from '@backstage/frontend-plugin-api'; +import { + rootRouteRef, + actionsRouteRef, + editRouteRef, + registerComponentRouteRef, + scaffolderListTaskRouteRef, + scaffolderTaskRouteRef, + selectedTemplateRouteRef, + viewTechDocRouteRef, +} from '../routes'; +import { scaffolderApi } from './api'; +import { + repoUrlPickerFormField, + scaffolderNavItem, + scaffolderPage, +} from './extensions'; +import { formFieldsApi } from './api/FormFieldsApi'; + +/** @alpha */ +export default createFrontendPlugin({ + id: 'scaffolder', + routes: convertLegacyRouteRefs({ + root: rootRouteRef, + selectedTemplate: selectedTemplateRouteRef, + ongoingTask: scaffolderTaskRouteRef, + actions: actionsRouteRef, + listTasks: scaffolderListTaskRouteRef, + edit: editRouteRef, + }), + externalRoutes: convertLegacyRouteRefs({ + registerComponent: registerComponentRouteRef, + viewTechDoc: viewTechDocRouteRef, + }), + extensions: [ + scaffolderApi, + scaffolderPage, + scaffolderNavItem, + formFieldsApi, + repoUrlPickerFormField, + ], +}); diff --git a/plugins/scaffolder/src/api.test.ts b/plugins/scaffolder/src/api.test.ts index 805828a9fe..1df2dacb17 100644 --- a/plugins/scaffolder/src/api.test.ts +++ b/plugins/scaffolder/src/api.test.ts @@ -356,6 +356,34 @@ describe('api', () => { const result = await apiClient.listTasks({ filterByOwnership: 'all' }); expect(result).toHaveLength(2); }); + + it('should list tasks with limit and offset', async () => { + server.use( + rest.get( + `${mockBaseUrl}/v2/tasks?limit=5&offset=0`, + (_req, res, ctx) => { + return res( + ctx.json([ + { + createdBy: null, + }, + { + createdBy: null, + }, + ]), + ); + }, + ), + ); + + const result = await apiClient.listTasks({ + filterByOwnership: 'all', + limit: 5, + offset: 0, + }); + expect(result).toHaveLength(2); + }); + it('should list task using the current user as owner', async () => { server.use( rest.get(`${mockBaseUrl}/v2/tasks`, (req, res, ctx) => { diff --git a/plugins/scaffolder/src/api.ts b/plugins/scaffolder/src/api.ts index 1809ed4c15..df032b536d 100644 --- a/plugins/scaffolder/src/api.ts +++ b/plugins/scaffolder/src/api.ts @@ -24,23 +24,22 @@ import { ResponseError } from '@backstage/errors'; import { ScmIntegrationRegistry } from '@backstage/integration'; import { Observable } from '@backstage/types'; import qs from 'qs'; +import queryString from 'qs'; import ObservableImpl from 'zen-observable'; import { ListActionsResponse, LogEvent, ScaffolderApi, + ScaffolderDryRunOptions, + ScaffolderDryRunResponse, + ScaffolderGetIntegrationsListOptions, + ScaffolderGetIntegrationsListResponse, ScaffolderScaffoldOptions, ScaffolderScaffoldResponse, ScaffolderStreamLogsOptions, - ScaffolderGetIntegrationsListOptions, - ScaffolderGetIntegrationsListResponse, ScaffolderTask, - ScaffolderDryRunOptions, - ScaffolderDryRunResponse, TemplateParameterSchema, } from '@backstage/plugin-scaffolder-react'; - -import queryString from 'qs'; import { EventSourceMessage, fetchEventSource, @@ -74,7 +73,9 @@ export class ScaffolderClient implements ScaffolderApi { async listTasks(options: { filterByOwnership: 'owned' | 'all'; - }): Promise<{ tasks: ScaffolderTask[] }> { + limit?: number; + offset?: number; + }): Promise<{ tasks: ScaffolderTask[]; totalTasks?: number }> { if (!this.identityApi) { throw new Error( 'IdentityApi is not available in the ScaffolderClient, please pass through the IdentityApi to the ScaffolderClient constructor in order to use the listTasks method', @@ -83,9 +84,12 @@ export class ScaffolderClient implements ScaffolderApi { const baseUrl = await this.discoveryApi.getBaseUrl('scaffolder'); const { userEntityRef } = await this.identityApi.getBackstageIdentity(); - const query = queryString.stringify( - options.filterByOwnership === 'owned' ? { createdBy: userEntityRef } : {}, - ); + const query = queryString.stringify({ + createdBy: + options.filterByOwnership === 'owned' ? userEntityRef : undefined, + limit: options.limit, + offset: options.offset, + }); const response = await this.fetchApi.fetch(`${baseUrl}/v2/tasks?${query}`); if (!response.ok) { @@ -217,12 +221,10 @@ export class ScaffolderClient implements ScaffolderApi { } private streamLogsEventStream({ + isTaskRecoverable, taskId, after, - }: { - taskId: string; - after?: number; - }): Observable { + }: ScaffolderStreamLogsOptions): Observable { return new ObservableImpl(subscriber => { const params = new URLSearchParams(); if (after !== undefined) { @@ -246,14 +248,14 @@ export class ScaffolderClient implements ScaffolderApi { }; const ctrl = new AbortController(); - fetchEventSource(url, { + void fetchEventSource(url, { fetch: this.fetchApi.fetch, signal: ctrl.signal, onmessage(e: EventSourceMessage) { if (e.event === 'log') { processEvent(e); return; - } else if (e.event === 'completion') { + } else if (e.event === 'completion' && !isTaskRecoverable) { processEvent(e); subscriber.complete(); ctrl.abort(); @@ -338,6 +340,21 @@ export class ScaffolderClient implements ScaffolderApi { return await response.json(); } + async retry?(taskId: string): Promise { + const baseUrl = await this.discoveryApi.getBaseUrl('scaffolder'); + const url = `${baseUrl}/v2/tasks/${encodeURIComponent(taskId)}/retry`; + + const response = await this.fetchApi.fetch(url, { + method: 'POST', + }); + + if (!response.ok) { + throw await ResponseError.fromResponse(response); + } + + return await response.json(); + } + async autocomplete({ token, resource, diff --git a/plugins/scaffolder/src/components/ActionsPage/ActionsPage.test.tsx b/plugins/scaffolder/src/components/ActionsPage/ActionsPage.test.tsx index b548bcbad4..bf056dd3b3 100644 --- a/plugins/scaffolder/src/components/ActionsPage/ActionsPage.test.tsx +++ b/plugins/scaffolder/src/components/ActionsPage/ActionsPage.test.tsx @@ -509,4 +509,81 @@ describe('TemplatePage', () => { expect(rendered.getByText('array(unknown)')).toBeInTheDocument(); }); + + it('should filter an action', async () => { + scaffolderApiMock.listActions.mockResolvedValue([ + { + id: 'githut:repo:create', + description: 'Create a new Github repository', + schema: { + input: { + type: 'object', + required: ['name'], + properties: { + name: { + title: 'Repository name', + type: 'string', + }, + }, + }, + }, + }, + { + id: 'githut:repo:push', + description: 'Push to a Github repository', + schema: { + input: { + type: 'object', + required: ['url'], + properties: { + url: { + title: 'Repository url', + type: 'string', + }, + }, + }, + }, + }, + ]); + + const rendered = await renderInTestApp( + + + , + { + mountedRoutes: { + '/create/actions': rootRouteRef, + }, + }, + ); + + expect( + rendered.getByRole('heading', { name: 'githut:repo:create' }), + ).toBeInTheDocument(); + expect( + rendered.getByRole('heading', { name: 'githut:repo:push' }), + ).toBeInTheDocument(); + + // should filter actions when searching + await userEvent.type( + rendered.getByPlaceholderText('Search for an action'), + 'create', + ); + await userEvent.keyboard('[ArrowDown][Enter]'); + expect( + rendered.getByRole('heading', { name: 'githut:repo:create' }), + ).toBeInTheDocument(); + expect( + rendered.queryByRole('heading', { name: 'githut:repo:push' }), + ).not.toBeInTheDocument(); + + // should show all actions when clearing the search + await userEvent.click(rendered.getByTitle('Clear')); + expect( + rendered.getByRole('heading', { name: 'githut:repo:create' }), + ).toBeInTheDocument(); + expect( + rendered.getByRole('heading', { name: 'githut:repo:push' }), + ).toBeInTheDocument(); + }); }); diff --git a/plugins/scaffolder/src/components/ActionsPage/ActionsPage.tsx b/plugins/scaffolder/src/components/ActionsPage/ActionsPage.tsx index 2f9bcba279..539a5697d3 100644 --- a/plugins/scaffolder/src/components/ActionsPage/ActionsPage.tsx +++ b/plugins/scaffolder/src/components/ActionsPage/ActionsPage.tsx @@ -13,9 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React, { Fragment, useState } from 'react'; +import React, { Fragment, useEffect, useState } from 'react'; import useAsync from 'react-use/esm/useAsync'; import { + Action, ActionExample, scaffolderApiRef, } from '@backstage/plugin-scaffolder-react'; @@ -38,6 +39,11 @@ import { JSONSchema7, JSONSchema7Definition } from 'json-schema'; import classNames from 'classnames'; import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; import ExpandLessIcon from '@material-ui/icons/ExpandLess'; +import LinkIcon from '@material-ui/icons/Link'; +import Autocomplete from '@material-ui/lab/Autocomplete'; +import TextField from '@material-ui/core/TextField'; +import InputAdornment from '@material-ui/core/InputAdornment'; +import SearchIcon from '@material-ui/icons/Search'; import { useApi, useRouteRef } from '@backstage/core-plugin-api'; import { @@ -46,6 +52,7 @@ import { EmptyState, ErrorPanel, Header, + Link, MarkdownContent, Page, Progress, @@ -85,6 +92,9 @@ const useStyles = makeStyles(theme => ({ color: theme.palette.error.light, }, }, + link: { + paddingLeft: theme.spacing(1), + }, })); const ExamplesTable = (props: { examples: ActionExample[] }) => { @@ -115,16 +125,28 @@ const ExamplesTable = (props: { examples: ActionExample[] }) => { ); }; -const ActionPageContent = () => { +export const ActionPageContent = () => { const api = useApi(scaffolderApiRef); const { t } = useTranslationRef(scaffolderTranslationRef); const classes = useStyles(); - const { loading, value, error } = useAsync(async () => { + const { + loading, + value = [], + error, + } = useAsync(async () => { return api.listActions(); - }); + }, [api]); + + const [selectedAction, setSelectedAction] = useState(null); const [isExpanded, setIsExpanded] = useState<{ [key: string]: boolean }>({}); + useEffect(() => { + if (value.length && window.location.hash) { + document.querySelector(window.location.hash)?.scrollIntoView(); + } + }, [value]); + if (loading) { return ; } @@ -283,60 +305,107 @@ const ActionPageContent = () => { ); }; - return value?.map(action => { - if (action.id.startsWith('legacy:')) { - return undefined; - } - - const oneOf = renderTables( - 'oneOf', - `${action.id}.input`, - action.schema?.input?.oneOf, - ); - return ( - - - {action.id} - - {action.description && } - {action.schema?.input && ( - - - {t('actionsPage.action.input')} - - {renderTable( - formatRows(`${action.id}.input`, action?.schema?.input), - )} - {oneOf} - - )} - {action.schema?.output && ( - - - {t('actionsPage.action.output')} - - {renderTable( - formatRows(`${action.id}.output`, action?.schema?.output), - )} - - )} - {action.examples && ( - - }> - - {t('actionsPage.action.examples')} - - - - - - - - - )} + return ( + <> + + option.id} + renderInput={params => ( + + + + ), + }} + /> + )} + onChange={(_event, option) => { + setSelectedAction(option); + }} + fullWidth + /> - ); - }); + {(selectedAction ? [selectedAction] : value).map(action => { + if (action.id.startsWith('legacy:')) { + return undefined; + } + + const oneOf = renderTables( + 'oneOf', + `${action.id}.input`, + action.schema?.input?.oneOf, + ); + return ( + + + + {action.id} + + + + + + {action.description && ( + + )} + {action.schema?.input && ( + + + {t('actionsPage.action.input')} + + {renderTable( + formatRows(`${action.id}.input`, action?.schema?.input), + )} + {oneOf} + + )} + {action.schema?.output && ( + + + {t('actionsPage.action.output')} + + {renderTable( + formatRows(`${action.id}.output`, action?.schema?.output), + )} + + )} + {action.examples && ( + + }> + + {t('actionsPage.action.examples')} + + + + + + + + + )} + + ); + })} + + ); }; export const ActionsPage = () => { const navigate = useNavigate(); diff --git a/plugins/scaffolder/src/components/FileBrowser/FileBrowser.tsx b/plugins/scaffolder/src/components/FileBrowser/FileBrowser.tsx index 1273b8ad09..9c5dc84249 100644 --- a/plugins/scaffolder/src/components/FileBrowser/FileBrowser.tsx +++ b/plugins/scaffolder/src/components/FileBrowser/FileBrowser.tsx @@ -21,12 +21,13 @@ import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; import ChevronRightIcon from '@material-ui/icons/ChevronRight'; import TreeItem from '@material-ui/lab/TreeItem'; -const useStyles = makeStyles({ +const useStyles = makeStyles(theme => ({ root: { whiteSpace: 'nowrap', overflowY: 'auto', + padding: theme.spacing(1), }, -}); +})); export type FileEntry = | { diff --git a/plugins/scaffolder/src/components/ListTasksPage/ListTaskPage.test.tsx b/plugins/scaffolder/src/components/ListTasksPage/ListTaskPage.test.tsx index b9c5a84da3..f7f75bc3e8 100644 --- a/plugins/scaffolder/src/components/ListTasksPage/ListTaskPage.test.tsx +++ b/plugins/scaffolder/src/components/ListTasksPage/ListTaskPage.test.tsx @@ -25,8 +25,8 @@ import React from 'react'; import { identityApiRef } from '@backstage/core-plugin-api'; import { ListTasksPage } from './ListTasksPage'; import { - scaffolderApiRef, ScaffolderApi, + scaffolderApiRef, } from '@backstage/plugin-scaffolder-react'; import { act, fireEvent } from '@testing-library/react'; import { rootRouteRef } from '../../routes'; @@ -64,7 +64,7 @@ describe('', () => { }; catalogApi.getEntityByRef.mockResolvedValue(entity); - scaffolderApiMock.listTasks.mockResolvedValue({ tasks: [] }); + scaffolderApiMock.listTasks.mockResolvedValue({ tasks: [], totalTasks: 0 }); const { getByText } = await renderInTestApp( ', () => { lastHeartbeatAt: '', }, ], + totalTasks: 1, }); scaffolderApiMock.getTemplateParameterSchema.mockResolvedValue({ @@ -145,6 +146,8 @@ describe('', () => { expect(scaffolderApiMock.listTasks).toHaveBeenCalledWith({ filterByOwnership: 'owned', + limit: 5, + offset: 0, }); expect(getByText('List template tasks')).toBeInTheDocument(); expect(getByText('All tasks that have been started')).toBeInTheDocument(); @@ -194,6 +197,7 @@ describe('', () => { lastHeartbeatAt: '', }, ], + totalTasks: 1, }) .mockResolvedValue({ tasks: [ @@ -212,6 +216,7 @@ describe('', () => { lastHeartbeatAt: '', }, ], + totalTasks: 1, }); scaffolderApiMock.getTemplateParameterSchema.mockResolvedValue({ @@ -244,6 +249,8 @@ describe('', () => { expect(scaffolderApiMock.listTasks).toHaveBeenCalledWith({ filterByOwnership: 'all', + limit: 5, + offset: 0, }); expect(await findByText('One Template')).toBeInTheDocument(); expect(await findByText('OtherUser')).toBeInTheDocument(); diff --git a/plugins/scaffolder/src/components/ListTasksPage/ListTasksPage.tsx b/plugins/scaffolder/src/components/ListTasksPage/ListTasksPage.tsx index 7bc34662ef..b07d7c7fd3 100644 --- a/plugins/scaffolder/src/components/ListTasksPage/ListTasksPage.tsx +++ b/plugins/scaffolder/src/components/ListTasksPage/ListTasksPage.tsx @@ -28,8 +28,8 @@ import { CatalogFilterLayout } from '@backstage/plugin-catalog-react'; import useAsync from 'react-use/esm/useAsync'; import React, { useState } from 'react'; import { - ScaffolderTask, scaffolderApiRef, + ScaffolderTask, } from '@backstage/plugin-scaffolder-react'; import { OwnerListPicker } from './OwnerListPicker'; import { @@ -51,6 +51,8 @@ export interface MyTaskPageProps { const ListTaskPageContent = (props: MyTaskPageProps) => { const { initiallySelectedFilter = 'owned' } = props; const { t } = useTranslationRef(scaffolderTranslationRef); + const [limit, setLimit] = useState(5); + const [page, setPage] = useState(0); const scaffolderApi = useApi(scaffolderApiRef); const rootLink = useRouteRef(rootRouteRef); @@ -58,7 +60,11 @@ const ListTaskPageContent = (props: MyTaskPageProps) => { const [ownerFilter, setOwnerFilter] = useState(initiallySelectedFilter); const { value, loading, error } = useAsync(() => { if (scaffolderApi.listTasks) { - return scaffolderApi.listTasks?.({ filterByOwnership: ownerFilter }); + return scaffolderApi.listTasks?.({ + filterByOwnership: ownerFilter, + limit, + offset: page * limit, + }); } // eslint-disable-next-line no-console @@ -66,8 +72,8 @@ const ListTaskPageContent = (props: MyTaskPageProps) => { 'listTasks is not implemented in the scaffolderApi, please make sure to implement this method.', ); - return Promise.resolve({ tasks: [] }); - }, [scaffolderApi, ownerFilter]); + return Promise.resolve({ tasks: [], totalTasks: 0 }); + }, [scaffolderApi, ownerFilter, limit, page]); if (loading) { return ; @@ -96,7 +102,15 @@ const ListTaskPageContent = (props: MyTaskPageProps) => { + onRowsPerPageChange={pageSize => { + setPage(0); + setLimit(pageSize); + }} + onPageChange={newPage => setPage(newPage)} + options={{ pageSize: limit, emptyRowsWhenPaging: false }} data={value?.tasks ?? []} + page={page} + totalCount={value?.totalTasks ?? 0} title={t('listTaskPage.content.tableTitle')} columns={[ { diff --git a/plugins/scaffolder/src/components/ListTasksPage/OwnerListPicker.tsx b/plugins/scaffolder/src/components/ListTasksPage/OwnerListPicker.tsx index 00efed45ba..44f3d46974 100644 --- a/plugins/scaffolder/src/components/ListTasksPage/OwnerListPicker.tsx +++ b/plugins/scaffolder/src/components/ListTasksPage/OwnerListPicker.tsx @@ -113,10 +113,10 @@ export const OwnerListPicker = (props: { - {group.items.map(item => ( + {group.items.map((item, index) => ( onSelectOwner(item.id as 'owned' | 'all')} selected={item.id === filter} diff --git a/plugins/scaffolder/src/components/ListTasksPage/columns/CreatedAtColumn.test.tsx b/plugins/scaffolder/src/components/ListTasksPage/columns/CreatedAtColumn.test.tsx index 9cd1353ae1..c172c2122f 100644 --- a/plugins/scaffolder/src/components/ListTasksPage/columns/CreatedAtColumn.test.tsx +++ b/plugins/scaffolder/src/components/ListTasksPage/columns/CreatedAtColumn.test.tsx @@ -13,22 +13,48 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -import { renderInTestApp } from '@backstage/test-utils'; - import React from 'react'; import { CreatedAtColumn } from './CreatedAtColumn'; -import { DateTime } from 'luxon'; +import { renderInTestApp } from '@backstage/test-utils'; describe('', () => { - it('should render the column with the time', async () => { - const props = { - createdAt: DateTime.now().toISO()!, - }; + const testDate = '2024-09-22T13:30:00Z'; - const { getByText } = await renderInTestApp(); + const mockNavigatorLanguage = (language: string) => { + jest.spyOn(window.navigator, 'language', 'get').mockReturnValue(language); + }; - const text = getByText('0 seconds ago'); - expect(text).toBeDefined(); + afterEach(() => { + jest.restoreAllMocks(); + }); + + it('should render the column using mocked locale (de-DE)', async () => { + mockNavigatorLanguage('de-DE'); + const { getByText } = await renderInTestApp( + , + ); + expect(getByText('22.9.2024, 13:30:00')).toBeDefined(); + }); + + it('should render the column with the default locale (en-US)', async () => { + mockNavigatorLanguage(''); + const { getByText } = await renderInTestApp( + , + ); + expect(getByText('9/22/2024, 1:30:00 PM')).toBeDefined(); + }); + + it('should render the column with a specified locale (fr-FR)', async () => { + const { getByText } = await renderInTestApp( + , + ); + expect(getByText('22/09/2024 13:30:00')).toBeDefined(); + }); + + it('should render the column with a specified locale (en-DE)', async () => { + const { getByText } = await renderInTestApp( + , + ); + expect(getByText('22/09/2024, 13:30:00')).toBeDefined(); }); }); diff --git a/plugins/scaffolder/src/components/ListTasksPage/columns/CreatedAtColumn.tsx b/plugins/scaffolder/src/components/ListTasksPage/columns/CreatedAtColumn.tsx index 3b47287fd6..525e4cea04 100644 --- a/plugins/scaffolder/src/components/ListTasksPage/columns/CreatedAtColumn.tsx +++ b/plugins/scaffolder/src/components/ListTasksPage/columns/CreatedAtColumn.tsx @@ -13,20 +13,26 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { DateTime, Interval } from 'luxon'; -import humanizeDuration from 'humanize-duration'; +import { DateTime } from 'luxon'; import React from 'react'; import Typography from '@material-ui/core/Typography'; -export const CreatedAtColumn = ({ createdAt }: { createdAt: string }) => { - const createdAtTime = DateTime.fromISO(createdAt); - const formatted = Interval.fromDateTimes(createdAtTime, DateTime.local()) - .toDuration() - .valueOf(); +interface CreatedAtColumnProps { + createdAt: string; + locale?: string; +} - return ( - - {humanizeDuration(formatted, { round: true })} ago - - ); +export const CreatedAtColumn: React.FC = ({ + createdAt, + locale, +}) => { + const createdAtTime = DateTime.fromISO(createdAt); + + const userLocale = locale || window.navigator.language || 'en-US'; + + const formatted = createdAtTime.setLocale(userLocale).toLocaleString({ + ...DateTime.DATETIME_SHORT_WITH_SECONDS, + }); + + return {formatted}; }; diff --git a/plugins/scaffolder/src/components/OngoingTask/ContextMenu.tsx b/plugins/scaffolder/src/components/OngoingTask/ContextMenu.tsx index e0ab01fc67..f189a6a03c 100644 --- a/plugins/scaffolder/src/components/OngoingTask/ContextMenu.tsx +++ b/plugins/scaffolder/src/components/OngoingTask/ContextMenu.tsx @@ -23,7 +23,8 @@ import Popover from '@material-ui/core/Popover'; import { makeStyles, Theme, useTheme } from '@material-ui/core/styles'; import { useAsync } from '@react-hookz/web'; import Cancel from '@material-ui/icons/Cancel'; -import Retry from '@material-ui/icons/Repeat'; +import Repeat from '@material-ui/icons/Repeat'; +import Replay from '@material-ui/icons/Replay'; import Toc from '@material-ui/icons/Toc'; import ControlPointIcon from '@material-ui/icons/ControlPoint'; import MoreVert from '@material-ui/icons/MoreVert'; @@ -41,8 +42,11 @@ import { scaffolderTranslationRef } from '../../translation'; type ContextMenuProps = { cancelEnabled?: boolean; + canRetry: boolean; + isRetryableTask: boolean; logsVisible?: boolean; buttonBarVisible?: boolean; + onRetry?: () => void; onStartOver?: () => void; onToggleLogs?: (state: boolean) => void; onToggleButtonBar?: (state: boolean) => void; @@ -58,8 +62,11 @@ const useStyles = makeStyles(() => ({ export const ContextMenu = (props: ContextMenuProps) => { const { cancelEnabled, + canRetry, + isRetryableTask, logsVisible, buttonBarVisible, + onRetry, onStartOver, onToggleLogs, onToggleButtonBar, @@ -147,10 +154,22 @@ export const ContextMenu = (props: ContextMenuProps) => { data-testid="start-over-task" > - + + {isRetryableTask && ( + + + + + + + )} ({ cancelButton: { marginRight: theme.spacing(1), }, + retryButton: { + marginRight: theme.spacing(1), + }, logsVisibilityButton: { marginRight: theme.spacing(1), }, @@ -130,6 +133,12 @@ export const OngoingTask = (props: { return 0; }, [steps]); + const isRetryableTask = + taskStream.task?.spec.EXPERIMENTAL_recovery?.EXPERIMENTAL_strategy === + 'startOver'; + + const canRetry = canReadTask && canCreateTask && isRetryableTask; + const startOver = useCallback(() => { const { namespace, name } = taskStream.task?.spec.templateInfo?.entity?.metadata ?? {}; @@ -157,6 +166,13 @@ export const OngoingTask = (props: { templateRouteRef, ]); + const [{ status: _ }, { execute: triggerRetry }] = useAsync(async () => { + if (taskId) { + analytics.captureEvent('retried', 'Template has been retried'); + await scaffolderApi.retry?.(taskId); + } + }); + const [{ status: cancelStatus }, { execute: triggerCancel }] = useAsync( async () => { if (taskId) { @@ -190,9 +206,12 @@ export const OngoingTask = (props: { > {t('ongoingTask.cancelButtonTitle')} + {isRetryableTask && ( + + )} - - ); + const ariaLabel: string | undefined = label ? undefined : 'Search'; - return ( + const inputPlaceholder = + placeholder ?? + `Search in ${configApi.getOptionalString('app.title') || 'Backstage'}`; + + const SearchIcon = useApp().getSystemIcon('search') || DefaultSearchIcon; + + const startAdornment = ( + + + + + + ); + + const clearButtonEndAdornment = ( + + + + ); + + return ( + - ); - }), -); + + ); +}); /** * Props for {@link SearchBar}. @@ -213,30 +203,30 @@ export type SearchBarProps = Partial; * * @public */ -export const SearchBar = withContext( - forwardRef((props, ref) => { - const { value: initialValue = '', onChange, ...rest } = props; +export const SearchBar = forwardRef((props: SearchBarProps, ref) => { + const { value: initialValue = '', onChange, ...rest } = props; - const { term, setTerm } = useSearch(); + const { term, setTerm } = useSearch(); - useEffect(() => { - if (initialValue) { - setTerm(String(initialValue)); + useEffect(() => { + if (initialValue) { + setTerm(String(initialValue)); + } + }, [initialValue, setTerm]); + + const handleChange = useCallback( + (newValue: string) => { + if (onChange) { + onChange(newValue); + } else { + setTerm(newValue); } - }, [initialValue, setTerm]); + }, + [onChange, setTerm], + ); - const handleChange = useCallback( - (newValue: string) => { - if (onChange) { - onChange(newValue); - } else { - setTerm(newValue); - } - }, - [onChange, setTerm], - ); - - return ( + return ( + @@ -247,6 +237,6 @@ export const SearchBar = withContext( onChange={handleChange} /> - ); - }), -); + + ); +}); diff --git a/plugins/search-react/src/overridableComponents.ts b/plugins/search-react/src/overridableComponents.ts new file mode 100644 index 0000000000..be921ebf04 --- /dev/null +++ b/plugins/search-react/src/overridableComponents.ts @@ -0,0 +1,36 @@ +/* + * 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 { Overrides } from '@material-ui/core/styles/overrides'; +import { StyleRules } from '@material-ui/core/styles/withStyles'; +import { HighlightedSearchResultTextClassKey } from './components'; + +/** @public */ +export type CatalogReactComponentsNameToClassKey = { + SearchReactHighlightedSearchResultText: HighlightedSearchResultTextClassKey; +}; + +/** @public */ +export type BackstageOverrides = Overrides & { + [Name in keyof CatalogReactComponentsNameToClassKey]?: Partial< + StyleRules + >; +}; + +declare module '@backstage/theme' { + interface OverrideComponentNameToClassKeys + extends CatalogReactComponentsNameToClassKey {} +} diff --git a/plugins/search/CHANGELOG.md b/plugins/search/CHANGELOG.md index 63397834bf..f2caf39be2 100644 --- a/plugins/search/CHANGELOG.md +++ b/plugins/search/CHANGELOG.md @@ -1,5 +1,74 @@ # @backstage/plugin-search +## 1.4.18-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/frontend-plugin-api@0.9.0-next.1 + - @backstage/core-compat-api@0.3.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/version-bridge@1.0.10-next.0 + - @backstage/plugin-catalog-react@1.14.0-next.1 + - @backstage/plugin-search-react@1.8.1-next.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-search-common@1.2.14 + +## 1.4.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/core-compat-api@0.3.1-next.0 + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/plugin-catalog-react@1.13.1-next.0 + - @backstage/plugin-search-react@1.8.1-next.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.9 + - @backstage/plugin-search-common@1.2.14 + +## 1.4.16 + +### Patch Changes + +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. +- eca03bd: Added ability to customize the search items within the SidebarSearchModal +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/plugin-catalog-react@1.13.0 + - @backstage/frontend-plugin-api@0.8.0 + - @backstage/core-compat-api@0.3.0 + - @backstage/plugin-search-react@1.8.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/version-bridge@1.0.9 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-search-common@1.2.14 + +## 1.4.16-next.2 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/plugin-catalog-react@1.13.0-next.2 + - @backstage/plugin-search-react@1.8.0-next.2 + - @backstage/core-compat-api@0.3.0-next.2 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/frontend-plugin-api@0.8.0-next.2 + - @backstage/version-bridge@1.0.9-next.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-search-common@1.2.14 + ## 1.4.16-next.1 ### Patch Changes diff --git a/plugins/search/README.md b/plugins/search/README.md index e6b664338d..0aab198994 100644 --- a/plugins/search/README.md +++ b/plugins/search/README.md @@ -30,7 +30,7 @@ This search plugin is primarily responsible for the following: - Providing a `` routable extension. - Exposing various search-related components (like ``, - ``, etc), which can be composed by a Backstage App or by + ``, etc.), which can be composed by a Backstage App or by other Backstage Plugins to power search experiences of all kinds. Don't forget, a lot of functionality is available in web libraries and backend plugins: diff --git a/plugins/search/package.json b/plugins/search/package.json index b8a76d61b8..cd5a6c4d8d 100644 --- a/plugins/search/package.json +++ b/plugins/search/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search", - "version": "1.4.16-next.1", + "version": "1.4.18-next.1", "description": "The Backstage plugin that provides your backstage app with search", "backstage": { "role": "frontend-plugin", @@ -70,7 +70,6 @@ "@backstage/version-bridge": "workspace:^", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "qs": "^6.9.4", "react-use": "^17.2.4" }, @@ -81,14 +80,24 @@ "@backstage/test-utils": "workspace:^", "@testing-library/dom": "^10.0.0", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^15.0.0", + "@testing-library/react": "^16.0.0", "@testing-library/user-event": "^14.0.0", - "history": "^5.0.0" + "@types/react": "^18.0.0", + "history": "^5.0.0", + "react": "^18.0.2", + "react-dom": "^18.0.2", + "react-router-dom": "^6.3.0" }, "peerDependencies": { + "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-router-dom": "6.0.0-beta.0 || ^6.3.0" }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + }, "configSchema": "config.d.ts" } diff --git a/plugins/search/api-report-alpha.md b/plugins/search/report-alpha.api.md similarity index 81% rename from plugins/search/api-report-alpha.md rename to plugins/search/report-alpha.api.md index fe06873bd4..1d9bd7a6f6 100644 --- a/plugins/search/api-report-alpha.md +++ b/plugins/search/report-alpha.api.md @@ -24,7 +24,6 @@ const _default: FrontendPlugin< { 'api:search': ExtensionDefinition<{ kind: 'api'; - namespace: undefined; name: undefined; config: {}; configInput: {}; @@ -34,10 +33,12 @@ const _default: FrontendPlugin< {} >; inputs: {}; + params: { + factory: AnyApiFactory; + }; }>; 'nav-item:search': ExtensionDefinition<{ kind: 'nav-item'; - namespace: undefined; name: undefined; config: {}; configInput: {}; @@ -51,6 +52,11 @@ const _default: FrontendPlugin< {} >; inputs: {}; + params: { + title: string; + icon: IconComponent; + routeRef: RouteRef; + }; }>; 'page:search': ExtensionDefinition<{ config: { @@ -94,8 +100,12 @@ const _default: FrontendPlugin< >; }; kind: 'page'; - namespace: undefined; name: undefined; + params: { + defaultPath: string; + loader: () => Promise; + routeRef?: RouteRef | undefined; + }; }>; } >; @@ -104,18 +114,19 @@ export default _default; // @alpha (undocumented) export const searchApi: ExtensionDefinition<{ kind: 'api'; - namespace: undefined; name: undefined; config: {}; configInput: {}; output: ConfigurableExtensionDataRef; inputs: {}; + params: { + factory: AnyApiFactory; + }; }>; // @alpha (undocumented) export const searchNavItem: ExtensionDefinition<{ kind: 'nav-item'; - namespace: undefined; name: undefined; config: {}; configInput: {}; @@ -129,6 +140,11 @@ export const searchNavItem: ExtensionDefinition<{ {} >; inputs: {}; + params: { + title: string; + icon: IconComponent; + routeRef: RouteRef; + }; }>; // @alpha (undocumented) @@ -170,9 +186,20 @@ export const searchPage: ExtensionDefinition<{ >; }; kind: 'page'; - namespace: undefined; name: undefined; + params: { + defaultPath: string; + loader: () => Promise; + routeRef?: RouteRef | undefined; + }; }>; +// Warnings were encountered during analysis: +// +// src/alpha.d.ts:3:22 - (ae-undocumented) Missing documentation for "searchApi". +// src/alpha.d.ts:15:22 - (ae-undocumented) Missing documentation for "searchPage". +// src/alpha.d.ts:47:22 - (ae-undocumented) Missing documentation for "searchNavItem". +// src/alpha.d.ts:65:15 - (ae-undocumented) Missing documentation for "_default". + // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/search/api-report.md b/plugins/search/report.api.md similarity index 63% rename from plugins/search/api-report.md rename to plugins/search/report.api.md index 64f596ab11..7bb1dca05e 100644 --- a/plugins/search/api-report.md +++ b/plugins/search/report.api.md @@ -12,6 +12,7 @@ import { default as React_2 } from 'react'; import { ReactNode } from 'react'; import { RouteRef } from '@backstage/core-plugin-api'; import { SearchBarBaseProps } from '@backstage/plugin-search-react'; +import { SearchResultSet } from '@backstage/plugin-search-common'; // @public (undocumented) export const HomePageSearchBar: ( @@ -31,6 +32,9 @@ export const SearchModal: (props: SearchModalProps) => React_2.JSX.Element; // @public (undocumented) export interface SearchModalChildrenProps { + resultItemComponents?: + | ReactNode + | ((resultSet: SearchResultSet) => JSX.Element); toggleModal: () => void; } @@ -39,6 +43,7 @@ export interface SearchModalProps { children?: (props: SearchModalChildrenProps) => JSX.Element; hidden?: boolean; open?: boolean; + resultItemComponents?: SearchModalChildrenProps['resultItemComponents']; toggleModal: () => void; } @@ -118,12 +123,14 @@ export const SidebarSearch: (props: SidebarSearchProps) => React_2.JSX.Element; // @public (undocumented) export const SidebarSearchModal: ( props: SidebarSearchModalProps, -) => JSX_2.Element; +) => JSX.Element | null; // @public -export type SidebarSearchModalProps = { +export type SidebarSearchModalProps = Pick< + SearchModalProps, + 'children' | 'resultItemComponents' +> & { icon?: IconComponent; - children?: (props: SearchModalChildrenProps) => JSX.Element; }; // @public @@ -133,4 +140,19 @@ export type SidebarSearchProps = { // @public export function useSearchModal(initialState?: boolean): SearchModalValue; + +// Warnings were encountered during analysis: +// +// src/components/SearchModal/SearchModal.d.ts:6:1 - (ae-undocumented) Missing documentation for "SearchModalChildrenProps". +// src/components/SearchModal/SearchModal.d.ts:19:1 - (ae-undocumented) Missing documentation for "SearchModalProps". +// src/components/SearchModal/SearchModal.d.ts:50:22 - (ae-undocumented) Missing documentation for "SearchModal". +// src/components/SearchPage/SearchPage.d.ts:6:22 - (ae-undocumented) Missing documentation for "SearchPage". +// src/components/SearchType/SearchType.Accordion.d.ts:5:1 - (ae-undocumented) Missing documentation for "SearchTypeAccordionProps". +// src/components/SearchType/SearchType.Tabs.d.ts:5:1 - (ae-undocumented) Missing documentation for "SearchTypeTabsProps". +// src/components/SearchType/SearchType.d.ts:18:15 - (ae-undocumented) Missing documentation for "SearchType". +// src/components/SidebarSearch/SidebarSearch.d.ts:14:22 - (ae-undocumented) Missing documentation for "SidebarSearch". +// src/plugin.d.ts:7:22 - (ae-undocumented) Missing documentation for "searchPlugin". +// src/plugin.d.ts:13:22 - (ae-undocumented) Missing documentation for "SearchPage". +// src/plugin.d.ts:17:22 - (ae-undocumented) Missing documentation for "SidebarSearchModal". +// src/plugin.d.ts:21:22 - (ae-undocumented) Missing documentation for "HomePageSearchBar". ``` diff --git a/plugins/search/src/components/SearchModal/SearchModal.tsx b/plugins/search/src/components/SearchModal/SearchModal.tsx index 07eec4438e..b5d932ffdb 100644 --- a/plugins/search/src/components/SearchModal/SearchModal.tsx +++ b/plugins/search/src/components/SearchModal/SearchModal.tsx @@ -34,10 +34,11 @@ import IconButton from '@material-ui/core/IconButton'; import { makeStyles } from '@material-ui/core/styles'; import ArrowForwardIcon from '@material-ui/icons/ArrowForward'; import CloseIcon from '@material-ui/icons/Close'; -import React, { useCallback, useEffect, useRef } from 'react'; +import React, { ReactNode, useCallback, useEffect, useRef } from 'react'; import { useNavigate } from 'react-router-dom'; import { rootRouteRef } from '../../plugin'; +import { SearchResultSet } from '@backstage/plugin-search-common'; /** * @public @@ -47,6 +48,13 @@ export interface SearchModalChildrenProps { * A function that should be invoked when navigating away from the modal. */ toggleModal: () => void; + + /** + * Ability to provide custom components to render the result items + */ + resultItemComponents?: + | ReactNode + | ((resultSet: SearchResultSet) => JSX.Element); } /** @@ -74,6 +82,11 @@ export interface SearchModalProps { * place of the default. */ children?: (props: SearchModalChildrenProps) => JSX.Element; + + /** + * Optional ability to pass in result item component renderers. + */ + resultItemComponents?: SearchModalChildrenProps['resultItemComponents']; } const useStyles = makeStyles(theme => ({ @@ -100,7 +113,10 @@ const useStyles = makeStyles(theme => ({ viewResultsLink: { verticalAlign: '0.5em' }, })); -export const Modal = ({ toggleModal }: SearchModalChildrenProps) => { +export const Modal = ({ + toggleModal, + resultItemComponents, +}: SearchModalChildrenProps) => { const classes = useStyles(); const navigate = useNavigate(); const { transitions } = useTheme(); @@ -163,7 +179,9 @@ export const Modal = ({ toggleModal }: SearchModalChildrenProps) => { + > + {resultItemComponents} + @@ -180,7 +198,13 @@ export const Modal = ({ toggleModal }: SearchModalChildrenProps) => { * @public */ export const SearchModal = (props: SearchModalProps) => { - const { open = true, hidden, toggleModal, children } = props; + const { + open = true, + hidden, + toggleModal, + children, + resultItemComponents, + } = props; const classes = useStyles(); @@ -199,8 +223,15 @@ export const SearchModal = (props: SearchModalProps) => { > {open && ( - {(children && children({ toggleModal })) ?? ( - + {(children && + children({ + toggleModal, + resultItemComponents: resultItemComponents || [], + })) ?? ( + )} )} diff --git a/plugins/search/src/components/SearchType/SearchType.Tabs.tsx b/plugins/search/src/components/SearchType/SearchType.Tabs.tsx index d48420bdac..077883f649 100644 --- a/plugins/search/src/components/SearchType/SearchType.Tabs.tsx +++ b/plugins/search/src/components/SearchType/SearchType.Tabs.tsx @@ -19,8 +19,9 @@ import { useSearch } from '@backstage/plugin-search-react'; import Tab from '@material-ui/core/Tab'; import Tabs from '@material-ui/core/Tabs'; import { makeStyles } from '@material-ui/core/styles'; +import { Theme } from '@material-ui/core/styles'; -const useStyles = makeStyles(theme => ({ +const useStyles = makeStyles((theme: Theme) => ({ tabs: { borderBottom: `1px solid ${theme.palette.textVerySubtle}`, }, diff --git a/plugins/search/src/components/SidebarSearchModal/SidebarSearchModal.tsx b/plugins/search/src/components/SidebarSearchModal/SidebarSearchModal.tsx index fb4afc75fd..e385a4f1fd 100644 --- a/plugins/search/src/components/SidebarSearchModal/SidebarSearchModal.tsx +++ b/plugins/search/src/components/SidebarSearchModal/SidebarSearchModal.tsx @@ -19,7 +19,7 @@ import { SidebarItem } from '@backstage/core-components'; import { IconComponent } from '@backstage/core-plugin-api'; import { SearchModal, - SearchModalChildrenProps, + SearchModalProps, SearchModalProvider, useSearchModal, } from '../SearchModal'; @@ -29,9 +29,11 @@ import { * * @public */ -export type SidebarSearchModalProps = { +export type SidebarSearchModalProps = Pick< + SearchModalProps, + 'children' | 'resultItemComponents' +> & { icon?: IconComponent; - children?: (props: SearchModalChildrenProps) => JSX.Element; }; const SidebarSearchModalContent = (props: SidebarSearchModalProps) => { @@ -49,6 +51,7 @@ const SidebarSearchModalContent = (props: SidebarSearchModalProps) => { diff --git a/plugins/search/src/plugin.ts b/plugins/search/src/plugin.ts index 1adfd2e684..d4efc3748d 100644 --- a/plugins/search/src/plugin.ts +++ b/plugins/search/src/plugin.ts @@ -25,6 +25,7 @@ import { createComponentExtension, fetchApiRef, } from '@backstage/core-plugin-api'; +import { SidebarSearchModalProps } from './components/SidebarSearchModal'; export const rootRouteRef = createRouteRef({ id: 'search', @@ -63,7 +64,9 @@ export const SearchPage = searchPlugin.provide( /** * @public */ -export const SidebarSearchModal = searchPlugin.provide( +export const SidebarSearchModal = searchPlugin.provide< + (props: SidebarSearchModalProps) => JSX.Element | null +>( createComponentExtension({ name: 'SidebarSearchModal', component: { diff --git a/plugins/signals-backend/CHANGELOG.md b/plugins/signals-backend/CHANGELOG.md index 9f67f6bcb0..3f8ebc1d9f 100644 --- a/plugins/signals-backend/CHANGELOG.md +++ b/plugins/signals-backend/CHANGELOG.md @@ -1,5 +1,57 @@ # @backstage/plugin-signals-backend +## 0.2.1-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-signals-node@0.1.12-next.0 + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## 0.2.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- a0f1f0d: Bump the `ws` library +- 3ec5ccb: The `createRouter` and its related types has been marked as deprecared. This backend should instead be initialized using the new backend system. +- 19ff127: Internal refactor to remove dependencies on the identity and token manager services, which have been removed. Public APIs no longer require the identity service or token manager to be provided. +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/plugin-signals-node@0.1.11 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/plugin-events-node@0.4.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## 0.2.0-next.2 + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.4.0-next.2 + - @backstage/plugin-signals-node@0.1.11-next.2 + ## 0.2.0-next.1 ### Patch Changes diff --git a/plugins/signals-backend/package.json b/plugins/signals-backend/package.json index be39008ad4..b883dbbfaa 100644 --- a/plugins/signals-backend/package.json +++ b/plugins/signals-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-signals-backend", - "version": "0.2.0-next.1", + "version": "0.2.1-next.0", "backstage": { "role": "backend-plugin", "pluginId": "signals", @@ -37,7 +37,7 @@ "test": "backstage-cli package test" }, "dependencies": { - "@backstage/backend-common": "workspace:^", + "@backstage/backend-common": "^0.25.0", "@backstage/backend-plugin-api": "workspace:^", "@backstage/config": "workspace:^", "@backstage/plugin-auth-node": "workspace:^", @@ -51,7 +51,7 @@ "node-fetch": "^2.7.0", "uuid": "^9.0.0", "winston": "^3.2.1", - "ws": "^8.17.0", + "ws": "^8.18.0", "yn": "^4.0.0" }, "devDependencies": { @@ -64,6 +64,6 @@ "@types/supertest": "^2.0.8", "@types/ws": "^8.5.10", "msw": "^1.0.0", - "supertest": "^6.2.4" + "supertest": "^7.0.0" } } diff --git a/plugins/signals-backend/api-report.md b/plugins/signals-backend/report.api.md similarity index 61% rename from plugins/signals-backend/api-report.md rename to plugins/signals-backend/report.api.md index 10f74ba37e..df68dcd62b 100644 --- a/plugins/signals-backend/api-report.md +++ b/plugins/signals-backend/report.api.md @@ -41,5 +41,18 @@ export interface RouterOptions { const signalsPlugin: BackendFeature; export default signalsPlugin; +// Warnings were encountered during analysis: +// +// src/deprecated.d.ts:10:1 - (ae-undocumented) Missing documentation for "RouterOptions". +// src/deprecated.d.ts:11:5 - (ae-undocumented) Missing documentation for "logger". +// src/deprecated.d.ts:12:5 - (ae-undocumented) Missing documentation for "events". +// src/deprecated.d.ts:13:5 - (ae-undocumented) Missing documentation for "identity". +// src/deprecated.d.ts:14:5 - (ae-undocumented) Missing documentation for "discovery". +// src/deprecated.d.ts:15:5 - (ae-undocumented) Missing documentation for "config". +// src/deprecated.d.ts:16:5 - (ae-undocumented) Missing documentation for "lifecycle". +// src/deprecated.d.ts:17:5 - (ae-undocumented) Missing documentation for "auth". +// src/deprecated.d.ts:18:5 - (ae-undocumented) Missing documentation for "userInfo". +// src/deprecated.d.ts:24:1 - (ae-undocumented) Missing documentation for "createRouter". + // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/signals-node/CHANGELOG.md b/plugins/signals-node/CHANGELOG.md index 6737179922..ef4a078f9a 100644 --- a/plugins/signals-node/CHANGELOG.md +++ b/plugins/signals-node/CHANGELOG.md @@ -1,5 +1,42 @@ # @backstage/plugin-signals-node +## 0.1.12-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-events-node@0.4.1-next.0 + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## 0.1.11 + +### Patch Changes + +- a0f1f0d: Bump the `ws` library +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/plugin-events-node@0.4.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## 0.1.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.4.0-next.2 + ## 0.1.11-next.1 ### Patch Changes diff --git a/plugins/signals-node/package.json b/plugins/signals-node/package.json index 705e29eb90..cd00595972 100644 --- a/plugins/signals-node/package.json +++ b/plugins/signals-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-signals-node", - "version": "0.1.11-next.1", + "version": "0.1.12-next.0", "description": "Node.js library for the signals plugin", "backstage": { "role": "node-library", @@ -37,7 +37,7 @@ "test": "backstage-cli package test" }, "dependencies": { - "@backstage/backend-common": "workspace:^", + "@backstage/backend-common": "^0.25.0", "@backstage/backend-plugin-api": "workspace:^", "@backstage/config": "workspace:^", "@backstage/plugin-auth-node": "workspace:^", @@ -45,7 +45,7 @@ "@backstage/types": "workspace:^", "express": "^4.17.1", "uuid": "^9.0.0", - "ws": "^8.14.2" + "ws": "^8.18.0" }, "devDependencies": { "@backstage/cli": "workspace:^", diff --git a/plugins/signals-node/api-report.md b/plugins/signals-node/report.api.md similarity index 64% rename from plugins/signals-node/api-report.md rename to plugins/signals-node/report.api.md index a368dd2ece..97f06a8ede 100644 --- a/plugins/signals-node/api-report.md +++ b/plugins/signals-node/report.api.md @@ -58,5 +58,17 @@ export const signalsServiceRef: ServiceRef< 'singleton' >; +// Warnings were encountered during analysis: +// +// src/DefaultSignalsService.d.ts:5:1 - (ae-undocumented) Missing documentation for "DefaultSignalsService". +// src/DefaultSignalsService.d.ts:7:5 - (ae-undocumented) Missing documentation for "create". +// src/DefaultSignalsService.d.ts:19:22 - (ae-undocumented) Missing documentation for "DefaultSignalService". +// src/SignalsService.d.ts:4:1 - (ae-undocumented) Missing documentation for "SignalsService". +// src/SignalsService.d.ts:15:1 - (ae-undocumented) Missing documentation for "SignalService". +// src/lib.d.ts:3:22 - (ae-undocumented) Missing documentation for "signalsServiceRef". +// src/lib.d.ts:8:22 - (ae-undocumented) Missing documentation for "signalService". +// src/types.d.ts:6:1 - (ae-undocumented) Missing documentation for "SignalsServiceOptions". +// src/types.d.ts:10:1 - (ae-undocumented) Missing documentation for "SignalPayload". + // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/signals-react/CHANGELOG.md b/plugins/signals-react/CHANGELOG.md index 09e4260019..005bc89b9b 100644 --- a/plugins/signals-react/CHANGELOG.md +++ b/plugins/signals-react/CHANGELOG.md @@ -1,5 +1,41 @@ # @backstage/plugin-signals-react +## 0.0.6-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/types@1.1.1 + +## 0.0.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/types@1.1.1 + +## 0.0.5 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- 0389801: Fix for `useSignal` returning the inverse value for `isSignalsAvailable`. +- Updated dependencies + - @backstage/core-plugin-api@1.9.4 + - @backstage/types@1.1.1 + +## 0.0.5-next.1 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/types@1.1.1 + ## 0.0.5-next.0 ### Patch Changes diff --git a/plugins/signals-react/package.json b/plugins/signals-react/package.json index fdea501041..94eaad39b5 100644 --- a/plugins/signals-react/package.json +++ b/plugins/signals-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-signals-react", - "version": "0.0.5-next.0", + "version": "0.0.6-next.1", "description": "Web library for the signals plugin", "backstage": { "role": "web-library", @@ -47,9 +47,21 @@ "@backstage/cli": "workspace:^", "@backstage/test-utils": "workspace:^", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^15.0.0" + "@testing-library/react": "^16.0.0", + "@types/react": "^18.0.0", + "react": "^18.0.2", + "react-dom": "^18.0.2", + "react-router-dom": "^6.3.0" }, "peerDependencies": { - "react": "^16.13.1 || ^17.0.0" + "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } } diff --git a/plugins/signals-react/api-report.md b/plugins/signals-react/report.api.md similarity index 60% rename from plugins/signals-react/api-report.md rename to plugins/signals-react/report.api.md index 87d856288b..f17f53366a 100644 --- a/plugins/signals-react/api-report.md +++ b/plugins/signals-react/report.api.md @@ -32,5 +32,14 @@ export const useSignal: ( isSignalsAvailable: boolean; }; +// Warnings were encountered during analysis: +// +// src/api/SignalApi.d.ts:3:22 - (ae-undocumented) Missing documentation for "signalApiRef". +// src/api/SignalApi.d.ts:5:1 - (ae-undocumented) Missing documentation for "SignalSubscriber". +// src/api/SignalApi.d.ts:6:5 - (ae-undocumented) Missing documentation for "unsubscribe". +// src/api/SignalApi.d.ts:9:1 - (ae-undocumented) Missing documentation for "SignalApi". +// src/api/SignalApi.d.ts:10:5 - (ae-undocumented) Missing documentation for "subscribe". +// src/hooks/useSignal.d.ts:3:22 - (ae-undocumented) Missing documentation for "useSignal". + // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/signals/CHANGELOG.md b/plugins/signals/CHANGELOG.md index f06315faab..170d241df3 100644 --- a/plugins/signals/CHANGELOG.md +++ b/plugins/signals/CHANGELOG.md @@ -1,5 +1,71 @@ # @backstage/plugin-signals +## 0.0.11-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/plugin-signals-react@0.0.6-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/theme@0.5.8-next.0 + - @backstage/types@1.1.1 + +## 0.0.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/theme@0.5.7 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.6-next.0 + +## 0.0.10 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- 5add8e1: Added a `SignalsDisplay` extension to allows the signals plugin to be installed in an app as follows: + + ```tsx + export default app.createRoot( + <> + + + + + + {routes} + + , + ); + ``` + + With this in place you can remove the explicit installation via the `plugins` option for `createApp`. + +- 3e9b1a4: Put a name on the `SignalsDisplay` component extension +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/theme@0.5.7 + - @backstage/plugin-signals-react@0.0.5 + - @backstage/types@1.1.1 + +## 0.0.10-next.2 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/theme@0.5.7-next.0 + - @backstage/plugin-signals-react@0.0.5-next.1 + - @backstage/types@1.1.1 + ## 0.0.10-next.1 ### Patch Changes diff --git a/plugins/signals/package.json b/plugins/signals/package.json index 95cab2df40..1cb2f08675 100644 --- a/plugins/signals/package.json +++ b/plugins/signals/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-signals", - "version": "0.0.10-next.1", + "version": "0.0.11-next.1", "backstage": { "role": "frontend-plugin", "pluginId": "signals", @@ -55,12 +55,24 @@ "@backstage/dev-utils": "workspace:^", "@backstage/test-utils": "workspace:^", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^15.0.0", + "@testing-library/react": "^16.0.0", "@testing-library/user-event": "^14.0.0", + "@types/react": "^18.0.0", "jest-websocket-mock": "^2.5.0", - "msw": "^1.0.0" + "msw": "^1.0.0", + "react": "^18.0.2", + "react-dom": "^18.0.2", + "react-router-dom": "^6.3.0" }, "peerDependencies": { - "react": "^16.13.1 || ^17.0.0" + "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } } diff --git a/plugins/signals/api-report.md b/plugins/signals/report.api.md similarity index 64% rename from plugins/signals/api-report.md rename to plugins/signals/report.api.md index ca7695aeec..049f50b2f2 100644 --- a/plugins/signals/api-report.md +++ b/plugins/signals/report.api.md @@ -36,5 +36,15 @@ export const SignalsDisplay: () => null; // @public (undocumented) export const signalsPlugin: BackstagePlugin<{}, {}>; +// Warnings were encountered during analysis: +// +// src/api/SignalClient.d.ts:5:1 - (ae-undocumented) Missing documentation for "SignalClient". +// src/api/SignalClient.d.ts:10:5 - (ae-undocumented) Missing documentation for "DEFAULT_CONNECT_TIMEOUT_MS". +// src/api/SignalClient.d.ts:11:5 - (ae-undocumented) Missing documentation for "DEFAULT_RECONNECT_TIMEOUT_MS". +// src/api/SignalClient.d.ts:16:5 - (ae-undocumented) Missing documentation for "create". +// src/api/SignalClient.d.ts:23:5 - (ae-undocumented) Missing documentation for "subscribe". +// src/plugin.d.ts:2:22 - (ae-undocumented) Missing documentation for "signalsPlugin". +// src/plugin.d.ts:4:22 - (ae-undocumented) Missing documentation for "SignalsDisplay". + // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/techdocs-addons-test-utils/CHANGELOG.md b/plugins/techdocs-addons-test-utils/CHANGELOG.md index 05c53b5302..7dc37d4268 100644 --- a/plugins/techdocs-addons-test-utils/CHANGELOG.md +++ b/plugins/techdocs-addons-test-utils/CHANGELOG.md @@ -1,5 +1,68 @@ # @backstage/plugin-techdocs-addons-test-utils +## 1.0.40-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/integration-react@1.2.0-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/plugin-techdocs-react@1.2.9-next.1 + - @backstage/core-app-api@1.15.1-next.1 + - @backstage/plugin-catalog-react@1.14.0-next.1 + - @backstage/plugin-search-react@1.8.1-next.1 + - @backstage/test-utils@1.6.1-next.1 + - @backstage/plugin-techdocs@1.10.11-next.1 + - @backstage/plugin-catalog@1.24.0-next.1 + +## 1.0.39-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.24.0-next.0 + - @backstage/plugin-techdocs@1.10.10-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/plugin-catalog-react@1.13.1-next.0 + - @backstage/plugin-search-react@1.8.1-next.0 + - @backstage/core-app-api@1.15.1-next.0 + - @backstage/integration-react@1.1.32-next.0 + - @backstage/test-utils@1.6.1-next.0 + - @backstage/plugin-techdocs-react@1.2.9-next.0 + +## 1.0.38 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.13.0 + - @backstage/plugin-techdocs@1.10.9 + - @backstage/plugin-catalog@1.23.0 + - @backstage/plugin-techdocs-react@1.2.8 + - @backstage/core-app-api@1.15.0 + - @backstage/plugin-search-react@1.8.0 + - @backstage/integration-react@1.1.31 + - @backstage/test-utils@1.6.0 + - @backstage/core-plugin-api@1.9.4 + +## 1.0.38-next.2 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.13.0-next.2 + - @backstage/plugin-techdocs@1.10.9-next.2 + - @backstage/plugin-catalog@1.23.0-next.2 + - @backstage/core-app-api@1.14.3-next.0 + - @backstage/integration-react@1.1.31-next.0 + - @backstage/test-utils@1.6.0-next.1 + - @backstage/plugin-search-react@1.8.0-next.2 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/plugin-techdocs-react@1.2.8-next.2 + ## 1.0.38-next.1 ### Patch Changes diff --git a/plugins/techdocs-addons-test-utils/package.json b/plugins/techdocs-addons-test-utils/package.json index 8ecfdfe90e..d1ad8e1aa4 100644 --- a/plugins/techdocs-addons-test-utils/package.json +++ b/plugins/techdocs-addons-test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs-addons-test-utils", - "version": "1.0.38-next.1", + "version": "1.0.40-next.1", "backstage": { "role": "web-library", "pluginId": "techdocs-addons", @@ -49,18 +49,27 @@ "@backstage/plugin-techdocs": "workspace:^", "@backstage/plugin-techdocs-react": "workspace:^", "@backstage/test-utils": "workspace:^", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "testing-library__dom": "^7.29.4-beta.1" }, "devDependencies": { "@backstage/cli": "workspace:^", "@testing-library/dom": "^10.0.0", - "@testing-library/jest-dom": "^6.0.0" + "@testing-library/jest-dom": "^6.0.0", + "@types/react": "^18.0.0", + "react": "^18.0.2", + "react-dom": "^18.0.2", + "react-router-dom": "^6.3.0" }, "peerDependencies": { - "@testing-library/react": "^15.0.0", + "@testing-library/react": "^16.0.0", + "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } } diff --git a/plugins/techdocs-addons-test-utils/api-report.md b/plugins/techdocs-addons-test-utils/report.api.md similarity index 100% rename from plugins/techdocs-addons-test-utils/api-report.md rename to plugins/techdocs-addons-test-utils/report.api.md diff --git a/plugins/techdocs-backend/CHANGELOG.md b/plugins/techdocs-backend/CHANGELOG.md index 703f151823..1877e692d1 100644 --- a/plugins/techdocs-backend/CHANGELOG.md +++ b/plugins/techdocs-backend/CHANGELOG.md @@ -1,5 +1,86 @@ # @backstage/plugin-techdocs-backend +## 1.10.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.15.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-backend-module-techdocs@0.2.3-next.1 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-techdocs-node@1.12.12-next.1 + +## 1.10.14-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-search-backend-module-techdocs@0.2.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.15.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-techdocs-node@1.12.12-next.0 + +## 1.10.13 + +### Patch Changes + +- 086c32d: Dedicated token for techdocs cache sync +- 5b679ac: The `createRouter` and its related types has been marked as deprecared. This backend should instead be initialized using the new backend system. +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- 5edd344: Refactor to use injected catalog client in the new backend system +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/plugin-techdocs-node@1.12.11 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/catalog-client@1.7.0 + - @backstage/plugin-search-backend-module-techdocs@0.2.2 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/integration@1.15.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-techdocs-common@0.1.0 + +## 1.10.13-next.2 + +### Patch Changes + +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-client@1.7.0-next.1 + - @backstage/plugin-techdocs-node@1.12.11-next.2 + - @backstage/integration@1.15.0-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.2 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-backend-module-techdocs@0.2.2-next.2 + - @backstage/plugin-techdocs-common@0.1.0 + ## 1.10.13-next.1 ### Patch Changes diff --git a/plugins/techdocs-backend/package.json b/plugins/techdocs-backend/package.json index 468b349f11..8ada345404 100644 --- a/plugins/techdocs-backend/package.json +++ b/plugins/techdocs-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs-backend", - "version": "1.10.13-next.1", + "version": "1.10.14-next.1", "description": "The Backstage backend plugin that renders technical documentation for your components", "backstage": { "role": "backend-plugin", @@ -58,7 +58,7 @@ "test": "backstage-cli package test" }, "dependencies": { - "@backstage/backend-common": "workspace:^", + "@backstage/backend-common": "^0.25.0", "@backstage/backend-plugin-api": "workspace:^", "@backstage/catalog-client": "workspace:^", "@backstage/catalog-model": "workspace:^", @@ -86,7 +86,7 @@ "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "msw": "^1.0.0", - "supertest": "^6.1.3" + "supertest": "^7.0.0" }, "configSchema": "config.d.ts" } diff --git a/plugins/techdocs-backend/api-report-alpha.md b/plugins/techdocs-backend/report-alpha.api.md similarity index 100% rename from plugins/techdocs-backend/api-report-alpha.md rename to plugins/techdocs-backend/report-alpha.api.md diff --git a/plugins/techdocs-backend/api-report.md b/plugins/techdocs-backend/report.api.md similarity index 77% rename from plugins/techdocs-backend/api-report.md rename to plugins/techdocs-backend/report.api.md index dceb0a4d9a..6b84666e50 100644 --- a/plugins/techdocs-backend/api-report.md +++ b/plugins/techdocs-backend/report.api.md @@ -112,4 +112,17 @@ export type TechDocsCollatorOptions = { export type TechDocsDocument = TechDocsDocument_2; export * from '@backstage/plugin-techdocs-node'; + +// Warnings were encountered during analysis: +// +// src/index.d.ts:16:1 - (ae-undocumented) Missing documentation for "DocsBuildStrategy". +// src/index.d.ts:21:1 - (ae-undocumented) Missing documentation for "ShouldBuildParameters". +// src/index.d.ts:28:1 - (ae-undocumented) Missing documentation for "TechDocsDocument". +// src/search/DefaultTechDocsCollator.d.ts:32:5 - (ae-undocumented) Missing documentation for "type". +// src/search/DefaultTechDocsCollator.d.ts:33:5 - (ae-undocumented) Missing documentation for "visibilityPermission". +// src/search/DefaultTechDocsCollator.d.ts:35:5 - (ae-undocumented) Missing documentation for "fromConfig". +// src/search/DefaultTechDocsCollator.d.ts:36:5 - (ae-undocumented) Missing documentation for "execute". +// src/search/DefaultTechDocsCollator.d.ts:37:5 - (ae-undocumented) Missing documentation for "applyArgsToFormat". +// src/search/index.d.ts:12:1 - (ae-undocumented) Missing documentation for "TechDocsCollatorFactoryOptions". +// src/search/index.d.ts:17:22 - (ae-undocumented) Missing documentation for "DefaultTechDocsCollatorFactory". ``` diff --git a/plugins/techdocs-backend/src/plugin.ts b/plugins/techdocs-backend/src/plugin.ts index 0f3def79b1..9b5ae21a52 100644 --- a/plugins/techdocs-backend/src/plugin.ts +++ b/plugins/techdocs-backend/src/plugin.ts @@ -29,6 +29,7 @@ import { Preparers, Publisher, PublisherBase, + PublisherSettings, PublisherType, RemoteProtocol, techdocsBuildsExtensionPoint, @@ -89,6 +90,7 @@ export const techdocsPlugin = createBackendPlugin({ }); let customTechdocsPublisher: PublisherBase | undefined; + const publisherSettings: PublisherSettings = {}; env.registerExtensionPoint(techdocsPublisherExtensionPoint, { registerPublisher(type: PublisherType, publisher: PublisherBase) { if (customTechdocsPublisher) { @@ -96,6 +98,12 @@ export const techdocsPlugin = createBackendPlugin({ } customTechdocsPublisher = publisher; }, + registerPublisherSettings( + publisher: T, + settings: PublisherSettings[T], + ) { + publisherSettings[publisher] = settings; + }, }); env.registerInit({ @@ -144,6 +152,7 @@ export const techdocsPlugin = createBackendPlugin({ logger: winstonLogger, discovery: discovery, customPublisher: customTechdocsPublisher, + publisherSettings, }); // checks if the publisher is working and logs the result diff --git a/plugins/techdocs-backend/src/service/CachedEntityLoader.test.ts b/plugins/techdocs-backend/src/service/CachedEntityLoader.test.ts index c4673c6fa4..492f315d58 100644 --- a/plugins/techdocs-backend/src/service/CachedEntityLoader.test.ts +++ b/plugins/techdocs-backend/src/service/CachedEntityLoader.test.ts @@ -13,20 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { CacheService } from '@backstage/backend-plugin-api'; + import { CachedEntityLoader } from './CachedEntityLoader'; -import { CatalogApi } from '@backstage/catalog-client'; import { CompoundEntityRef } from '@backstage/catalog-model'; +import { mockServices } from '@backstage/backend-test-utils'; +import { catalogServiceMock } from '@backstage/plugin-catalog-node/testUtils'; describe('CachedEntityLoader', () => { - const catalog: jest.Mocked = { - getEntityByRef: jest.fn(), - } as any; - - const cache: jest.Mocked = { - get: jest.fn(), - set: jest.fn(), - } as any; + const cache = mockServices.cache.mock(); const entityName: CompoundEntityRef = { kind: 'component', @@ -45,16 +39,15 @@ describe('CachedEntityLoader', () => { const token = 'test-token'; - const loader = new CachedEntityLoader({ catalog, cache }); - afterEach(() => { jest.resetAllMocks(); }); it('writes entities to cache', async () => { cache.get.mockResolvedValue(undefined); - catalog.getEntityByRef.mockResolvedValue(entity); + const catalog = catalogServiceMock({ entities: [entity] }); + const loader = new CachedEntityLoader({ catalog, cache }); const result = await loader.load(entityName, token); expect(result).toEqual(entity); @@ -66,8 +59,10 @@ describe('CachedEntityLoader', () => { }); it('returns entities from cache', async () => { + const catalog = catalogServiceMock.mock(); cache.get.mockResolvedValue(entity); + const loader = new CachedEntityLoader({ catalog, cache }); const result = await loader.load(entityName, token); expect(result).toEqual(entity); @@ -75,9 +70,10 @@ describe('CachedEntityLoader', () => { }); it('does not cache missing entites', async () => { + const catalog = catalogServiceMock({ entities: [] }); cache.get.mockResolvedValue(undefined); - catalog.getEntityByRef.mockResolvedValue(undefined); + const loader = new CachedEntityLoader({ catalog, cache }); const result = await loader.load(entityName, token); expect(result).toBeUndefined(); @@ -85,9 +81,10 @@ describe('CachedEntityLoader', () => { }); it('uses entity ref as cache key for anonymous users', async () => { + const catalog = catalogServiceMock({ entities: [entity] }); cache.get.mockResolvedValue(undefined); - catalog.getEntityByRef.mockResolvedValue(entity); + const loader = new CachedEntityLoader({ catalog, cache }); const result = await loader.load(entityName, undefined); expect(result).toEqual(entity); @@ -107,8 +104,9 @@ describe('CachedEntityLoader', () => { setTimeout(() => resolve(undefined), 10000); }), ); - catalog.getEntityByRef.mockResolvedValue(entity); + const catalog = catalogServiceMock({ entities: [entity] }); + const loader = new CachedEntityLoader({ catalog, cache }); const result = await loader.load(entityName, token); expect(result).toEqual(entity); diff --git a/plugins/techdocs-common/package.json b/plugins/techdocs-common/package.json index f0e3219d6b..001d1106a3 100644 --- a/plugins/techdocs-common/package.json +++ b/plugins/techdocs-common/package.json @@ -23,14 +23,14 @@ "techdocs" ], "homepage": "https://backstage.io", + "bugs": { + "url": "https://github.com/backstage/backstage/issues" + }, "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/techdocs-common" }, - "bugs": { - "url": "https://github.com/backstage/backstage/issues" - }, "license": "Apache-2.0", "sideEffects": false, "main": "src/index.ts", diff --git a/plugins/techdocs-common/api-report.md b/plugins/techdocs-common/report.api.md similarity index 59% rename from plugins/techdocs-common/api-report.md rename to plugins/techdocs-common/report.api.md index c7e1829a28..1b0ee6797a 100644 --- a/plugins/techdocs-common/api-report.md +++ b/plugins/techdocs-common/report.api.md @@ -8,4 +8,9 @@ export const TECHDOCS_ANNOTATION = 'backstage.io/techdocs-ref'; // @public (undocumented) export const TECHDOCS_EXTERNAL_ANNOTATION = 'backstage.io/techdocs-entity'; + +// Warnings were encountered during analysis: +// +// src/constants.d.ts:2:22 - (ae-undocumented) Missing documentation for "TECHDOCS_ANNOTATION". +// src/constants.d.ts:4:22 - (ae-undocumented) Missing documentation for "TECHDOCS_EXTERNAL_ANNOTATION". ``` diff --git a/plugins/techdocs-module-addons-contrib/CHANGELOG.md b/plugins/techdocs-module-addons-contrib/CHANGELOG.md index 80a556378d..cfea67be77 100644 --- a/plugins/techdocs-module-addons-contrib/CHANGELOG.md +++ b/plugins/techdocs-module-addons-contrib/CHANGELOG.md @@ -1,5 +1,52 @@ # @backstage/plugin-techdocs-module-addons-contrib +## 1.1.16-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/integration-react@1.2.0-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/plugin-techdocs-react@1.2.9-next.1 + - @backstage/integration@1.15.1-next.0 + +## 1.1.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/integration@1.15.0 + - @backstage/integration-react@1.1.32-next.0 + - @backstage/plugin-techdocs-react@1.2.9-next.0 + +## 1.1.14 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/plugin-techdocs-react@1.2.8 + - @backstage/integration-react@1.1.31 + - @backstage/integration@1.15.0 + - @backstage/core-plugin-api@1.9.4 + +## 1.1.14-next.2 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/integration-react@1.1.31-next.0 + - @backstage/integration@1.15.0-next.0 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/plugin-techdocs-react@1.2.8-next.2 + ## 1.1.14-next.1 ### Patch Changes diff --git a/plugins/techdocs-module-addons-contrib/package.json b/plugins/techdocs-module-addons-contrib/package.json index db2fc00ed9..2d239014dc 100644 --- a/plugins/techdocs-module-addons-contrib/package.json +++ b/plugins/techdocs-module-addons-contrib/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs-module-addons-contrib", - "version": "1.1.14-next.1", + "version": "1.1.16-next.1", "description": "Plugin module for contributed TechDocs Addons", "backstage": { "role": "frontend-plugin-module", @@ -56,12 +56,21 @@ "@backstage/test-utils": "workspace:^", "@testing-library/dom": "^10.0.0", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^15.0.0", - "@types/react": "^16.13.1 || ^17.0.0" + "@testing-library/react": "^16.0.0", + "@types/react": "^18.0.0", + "react": "^18.0.2", + "react-dom": "^18.0.2", + "react-router-dom": "^6.3.0" }, "peerDependencies": { + "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } } diff --git a/plugins/techdocs-module-addons-contrib/api-report.md b/plugins/techdocs-module-addons-contrib/report.api.md similarity index 100% rename from plugins/techdocs-module-addons-contrib/api-report.md rename to plugins/techdocs-module-addons-contrib/report.api.md diff --git a/plugins/techdocs-node/CHANGELOG.md b/plugins/techdocs-node/CHANGELOG.md index 5df6fd23cc..a6a928f533 100644 --- a/plugins/techdocs-node/CHANGELOG.md +++ b/plugins/techdocs-node/CHANGELOG.md @@ -1,5 +1,70 @@ # @backstage/plugin-techdocs-node +## 1.12.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.15.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-techdocs-common@0.1.0 + +## 1.12.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.15.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-techdocs-common@0.1.0 + +## 1.12.11 + +### Patch Changes + +- f715f5c: Move `TechdocsContainerRunner` from `publish` to `generate`. +- 4417dd4: Fix typo and unify TechDocs casing in doc strings +- 57da51f: Add support for mapping custom tags in the techdocs yaml parser that validates the mkdocs.yaml file +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- 3606843: Internal fixes to match `testcontainers` update +- 33ebb28: As the `@backstage/backend-common` package is deprecated, we have updated the `techdocs-node` package to stop depending on it. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/integration@1.15.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-techdocs-common@0.1.0 + +## 1.12.11-next.2 + +### Patch Changes + +- 57da51f: Add support for mapping custom tags in the techdocs yaml parser that validates the mkdocs.yaml file +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- 3606843: Internal fixes to match `testcontainers` update +- Updated dependencies + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/integration@1.15.0-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-techdocs-common@0.1.0 + ## 1.12.11-next.1 ### Patch Changes diff --git a/plugins/techdocs-node/package.json b/plugins/techdocs-node/package.json index 8fa90e66d8..a66c34935e 100644 --- a/plugins/techdocs-node/package.json +++ b/plugins/techdocs-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs-node", - "version": "1.12.11-next.1", + "version": "1.12.12-next.1", "description": "Common node.js functionalities for TechDocs, to be shared between techdocs-backend plugin and techdocs-cli", "backstage": { "role": "node-library", @@ -86,6 +86,6 @@ "@types/recursive-readdir": "^2.2.0", "@types/supertest": "^2.0.8", "aws-sdk-client-mock": "^4.0.0", - "supertest": "^6.1.3" + "supertest": "^7.0.0" } } diff --git a/plugins/techdocs-node/api-report.md b/plugins/techdocs-node/report.api.md similarity index 85% rename from plugins/techdocs-node/api-report.md rename to plugins/techdocs-node/report.api.md index ea93ddfc98..1bd93d1b57 100644 --- a/plugins/techdocs-node/api-report.md +++ b/plugins/techdocs-node/report.api.md @@ -15,6 +15,7 @@ import { IndexableDocument } from '@backstage/plugin-search-common'; import { Logger } from 'winston'; import { LoggerService } from '@backstage/backend-plugin-api'; import { ScmIntegrationRegistry } from '@backstage/integration'; +import { StorageOptions } from '@google-cloud/storage'; import { UrlReaderService } from '@backstage/backend-plugin-api'; import * as winston from 'winston'; import { Writable } from 'stream'; @@ -217,8 +218,15 @@ export type PublisherFactory = { logger: LoggerService; discovery: DiscoveryService; customPublisher?: PublisherBase | undefined; + publisherSettings?: PublisherSettings; }; +// @public +export interface PublisherSettings { + // (undocumented) + googleGcs?: StorageOptions; +} + // @public export type PublisherType = | 'local' @@ -344,6 +352,11 @@ export const techdocsPreparerExtensionPoint: ExtensionPoint( + publisher: T, + settings: PublisherSettings[T], + ): void; } // @public @@ -365,4 +378,18 @@ export class UrlPreparer implements PreparerBase { prepare(entity: Entity, options?: PreparerOptions): Promise; shouldCleanPreparedDirectory(): boolean; } + +// Warnings were encountered during analysis: +// +// src/extensions.d.ts:11:5 - (ae-undocumented) Missing documentation for "setBuildStrategy". +// src/extensions.d.ts:12:5 - (ae-undocumented) Missing documentation for "setBuildLogTransport". +// src/extensions.d.ts:26:5 - (ae-undocumented) Missing documentation for "setTechdocsGenerator". +// src/extensions.d.ts:40:5 - (ae-undocumented) Missing documentation for "registerPreparer". +// src/extensions.d.ts:54:5 - (ae-undocumented) Missing documentation for "registerPublisher". +// src/extensions.d.ts:55:5 - (ae-undocumented) Missing documentation for "registerPublisherSettings". +// src/stages/generate/index.d.ts:10:22 - (ae-undocumented) Missing documentation for "getMkDocsYml". +// src/stages/publish/publish.d.ts:10:5 - (ae-undocumented) Missing documentation for "register". +// src/stages/publish/publish.d.ts:11:5 - (ae-undocumented) Missing documentation for "get". +// src/stages/publish/types.d.ts:21:5 - (ae-undocumented) Missing documentation for "googleGcs". +// src/techdocsTypes.d.ts:39:5 - (ae-undocumented) Missing documentation for "shouldBuild". ``` diff --git a/plugins/techdocs-node/src/extensions.ts b/plugins/techdocs-node/src/extensions.ts index e9a9b1d731..60498746ad 100644 --- a/plugins/techdocs-node/src/extensions.ts +++ b/plugins/techdocs-node/src/extensions.ts @@ -23,6 +23,7 @@ import { TechdocsGenerator, } from './stages'; import * as winston from 'winston'; +import { PublisherSettings } from './stages/publish/types'; /** * Extension point type for configuring TechDocs builds. @@ -89,6 +90,10 @@ export const techdocsPreparerExtensionPoint = */ export interface TechdocsPublisherExtensionPoint { registerPublisher(type: PublisherType, publisher: PublisherBase): void; + registerPublisherSettings( + publisher: T, + settings: PublisherSettings[T], + ): void; } /** diff --git a/plugins/techdocs-node/src/stages/generate/DockerContainerRunner.ts b/plugins/techdocs-node/src/stages/generate/DockerContainerRunner.ts index b7cb7f1c86..850f51260f 100644 --- a/plugins/techdocs-node/src/stages/generate/DockerContainerRunner.ts +++ b/plugins/techdocs-node/src/stages/generate/DockerContainerRunner.ts @@ -20,6 +20,7 @@ import { ForwardedError } from '@backstage/errors'; import { PassThrough } from 'stream'; import { pipeline as pipelineStream } from 'stream'; import { promisify } from 'util'; +import { TechDocsContainerRunner } from './types'; import { Writable } from 'stream'; const pipeline = promisify(pipelineStream); @@ -31,7 +32,7 @@ export type UserOptions = { /** * @internal */ -export class DockerContainerRunner { +export class DockerContainerRunner implements TechDocsContainerRunner { private readonly dockerClient: Docker; constructor() { @@ -76,12 +77,17 @@ export class DockerContainerRunner { this.dockerClient.pull(imageName, {}, (err, stream) => { if (err) { reject(err); - return; + } else if (!stream) { + reject( + new Error( + 'Unexpeected error: no stream returned from Docker while pulling image', + ), + ); + } else { + pipeline(stream, logStream, { end: false }) + .then(resolve) + .catch(reject); } - - pipeline(stream, logStream, { end: false }) - .then(resolve) - .catch(reject); }); }); } @@ -112,7 +118,7 @@ export class DockerContainerRunner { } // Create docker environment variables array - const Env = []; + const Env = new Array(); for (const [key, value] of Object.entries(envVars)) { Env.push(`${key}=${value}`); } diff --git a/plugins/techdocs-node/src/stages/generate/__fixtures__/mkdocs_with_extensions.yml b/plugins/techdocs-node/src/stages/generate/__fixtures__/mkdocs_with_extensions.yml index d6c6858722..d1209d0c21 100644 --- a/plugins/techdocs-node/src/stages/generate/__fixtures__/mkdocs_with_extensions.yml +++ b/plugins/techdocs-node/src/stages/generate/__fixtures__/mkdocs_with_extensions.yml @@ -4,4 +4,9 @@ site_description: Test site description markdown_extensions: - pymdownx.emoji: emoji_index: !!python/name:materialx.emoji.twemoji - emoji_generator: !!python/name:materialx.emoji.to_svg + emoji_generator: !!python/object.apply:materialx.emoji.to_svg + - pymdownx.tabbed: + alternate_style: true + slugify: !!python/object/apply:pymdownx.slugs.slugify + kwds: + case: lower diff --git a/plugins/techdocs-node/src/stages/generate/generators.ts b/plugins/techdocs-node/src/stages/generate/generators.ts index 7c8d169d1e..d7b7a71eb3 100644 --- a/plugins/techdocs-node/src/stages/generate/generators.ts +++ b/plugins/techdocs-node/src/stages/generate/generators.ts @@ -24,7 +24,7 @@ import { SupportedGeneratorKey, } from './types'; import { LoggerService } from '@backstage/backend-plugin-api'; -import { TechDocsContainerRunner } from '../publish/types'; +import { TechDocsContainerRunner } from './types'; /** * Collection of docs generators diff --git a/plugins/techdocs-node/src/stages/generate/helpers.test.ts b/plugins/techdocs-node/src/stages/generate/helpers.test.ts index 755cd9d1a6..af61dae936 100644 --- a/plugins/techdocs-node/src/stages/generate/helpers.test.ts +++ b/plugins/techdocs-node/src/stages/generate/helpers.test.ts @@ -247,6 +247,10 @@ describe('helpers', () => { expect(updatedMkdocsYml.toString()).toContain( "emoji_index: !!python/name:materialx.emoji.twemoji ''", ); + expect(updatedMkdocsYml.toString()).toContain( + 'slugify: !!python/object/apply:pymdownx.slugs.slugify', + ); + expect(updatedMkdocsYml.toString()).toContain('case: lower'); }); it('should not override existing repo_url in mkdocs.yml', async () => { diff --git a/plugins/techdocs-node/src/stages/generate/helpers.ts b/plugins/techdocs-node/src/stages/generate/helpers.ts index d62b6dcccd..0cba56cfa5 100644 --- a/plugins/techdocs-node/src/stages/generate/helpers.ts +++ b/plugins/techdocs-node/src/stages/generate/helpers.ts @@ -141,6 +141,14 @@ export const MKDOCS_SCHEMA = DEFAULT_SCHEMA.extend([ instanceOf: UnknownTag, construct: (data: string, type?: string) => new UnknownTag(data, type), }), + new Type('tag:', { + kind: 'mapping', + multi: true, + representName: o => (o as UnknownTag).type, + represent: o => (o as UnknownTag).data ?? '', + instanceOf: UnknownTag, + construct: (data: string, type?: string) => new UnknownTag(data, type), + }), new Type('', { kind: 'sequence', multi: true, diff --git a/plugins/techdocs-node/src/stages/generate/index.ts b/plugins/techdocs-node/src/stages/generate/index.ts index aaf27026c2..10e1e72ed3 100644 --- a/plugins/techdocs-node/src/stages/generate/index.ts +++ b/plugins/techdocs-node/src/stages/generate/index.ts @@ -22,6 +22,7 @@ export type { GeneratorBuilder, GeneratorRunOptions, SupportedGeneratorKey, + TechDocsContainerRunner, } from './types'; import { getMkdocsYml } from './helpers'; /** diff --git a/plugins/techdocs-node/src/stages/generate/techdocs.ts b/plugins/techdocs-node/src/stages/generate/techdocs.ts index 554f1c29bd..7329878142 100644 --- a/plugins/techdocs-node/src/stages/generate/techdocs.ts +++ b/plugins/techdocs-node/src/stages/generate/techdocs.ts @@ -43,7 +43,7 @@ import { import { ForwardedError } from '@backstage/errors'; import { DockerContainerRunner } from './DockerContainerRunner'; import { LoggerService } from '@backstage/backend-plugin-api'; -import { TechDocsContainerRunner } from '../publish/types'; +import { TechDocsContainerRunner } from './types'; /** * Generates documentation files diff --git a/plugins/techdocs-node/src/stages/generate/types.ts b/plugins/techdocs-node/src/stages/generate/types.ts index c7513d2710..fd4cb62820 100644 --- a/plugins/techdocs-node/src/stages/generate/types.ts +++ b/plugins/techdocs-node/src/stages/generate/types.ts @@ -19,9 +19,11 @@ import { Writable } from 'stream'; import { Logger } from 'winston'; import { ParsedLocationAnnotation } from '../../helpers'; import { LoggerService } from '@backstage/backend-plugin-api'; -import { TechDocsContainerRunner } from '../publish/types'; -// Determines where the generator will be run +/** + * Determines where the generator will be run. `'docker'` is a shorthand for running the generator in a container. + * If no {@link GeneratorOptions.containerRunner} is specified, the internal `DockerContainerRunner` will be used. + */ export type GeneratorRunInType = 'docker' | 'local'; /** @@ -30,10 +32,6 @@ export type GeneratorRunInType = 'docker' | 'local'; */ export type GeneratorOptions = { logger: LoggerService; - /** - * @deprecated containerRunner is now instantiated in - * the generator and this option will be removed in the future - */ containerRunner?: TechDocsContainerRunner; }; @@ -104,3 +102,39 @@ export type DefaultMkdocsContent = { docs_dir: string; plugins: String[]; }; + +/** + * Handles the running of containers to generate TechDocs. + * + * Custom implementations, e.g. for Kubernetes or other execution environments, can be inspired by the internal default + * implementation `DockerContainerRunner`. + * + * @public + */ +export interface TechDocsContainerRunner { + /** + * Runs a container image to completion. + */ + runContainer(opts: { + imageName: string; + command?: string | string[]; + args: string[]; + logStream?: Writable; + mountDirs?: Record; + workingDir?: string; + envVars?: Record; + pullImage?: boolean; + defaultUser?: boolean; + pullOptions?: { + authconfig?: { + username?: string; + password?: string; + auth?: string; + email?: string; + serveraddress?: string; + [key: string]: unknown; + }; + [key: string]: unknown; + }; + }): Promise; +} diff --git a/plugins/techdocs-node/src/stages/publish/awsS3.ts b/plugins/techdocs-node/src/stages/publish/awsS3.ts index 05902c999f..edbd6da114 100644 --- a/plugins/techdocs-node/src/stages/publish/awsS3.ts +++ b/plugins/techdocs-node/src/stages/publish/awsS3.ts @@ -48,6 +48,7 @@ import { getFileTreeRecursively, getHeadersForFileExtension, getStaleFiles, + isValidContentPath, lowerCaseEntityTriplet, lowerCaseEntityTripletInStoragePath, normalizeExternalStorageRootPath, @@ -398,6 +399,12 @@ export class AwsS3Publish implements PublisherBase { : lowerCaseEntityTriplet(entityTriplet); const entityRootDir = path.posix.join(this.bucketRootPath, entityDir); + if (!isValidContentPath(this.bucketRootPath, entityRootDir)) { + this.logger.error( + `Invalid content path found while fetching TechDocs metadata: ${entityRootDir}`, + ); + throw new Error(`Metadata Not Found`); + } try { const resp = await this.storageClient.send( @@ -446,6 +453,13 @@ export class AwsS3Publish implements PublisherBase { // Prepend the root path to the relative file path const filePath = path.posix.join(this.bucketRootPath, filePathNoRoot); + if (!isValidContentPath(this.bucketRootPath, filePath)) { + this.logger.error( + `Attempted to fetch TechDocs content for a file outside of the bucket root: ${filePathNoRoot}`, + ); + res.status(404).send('File Not Found'); + return; + } // Files with different extensions (CSS, HTML) need to be served with different headers const fileExtension = path.extname(filePath); @@ -486,6 +500,12 @@ export class AwsS3Publish implements PublisherBase { : lowerCaseEntityTriplet(entityTriplet); const entityRootDir = path.posix.join(this.bucketRootPath, entityDir); + if (!isValidContentPath(this.bucketRootPath, entityRootDir)) { + this.logger.error( + `Invalid content path found while checking if docs have been generated: ${entityRootDir}`, + ); + return Promise.resolve(false); + } await this.storageClient.send( new HeadObjectCommand({ diff --git a/plugins/techdocs-node/src/stages/publish/googleStorage.test.ts b/plugins/techdocs-node/src/stages/publish/googleStorage.test.ts index f09ba160d9..322149660e 100644 --- a/plugins/techdocs-node/src/stages/publish/googleStorage.test.ts +++ b/plugins/techdocs-node/src/stages/publish/googleStorage.test.ts @@ -26,9 +26,12 @@ import { createMockDirectory, mockServices, } from '@backstage/backend-test-utils'; +import { StorageOptions } from '@google-cloud/storage'; const mockDir = createMockDirectory(); +let createdStorageOptions: Array = []; + jest.mock('@google-cloud/storage', () => { class GCSFile { constructor(private readonly filePath: string) {} @@ -118,6 +121,10 @@ jest.mock('@google-cloud/storage', () => { } class Storage { + constructor(readonly options?: StorageOptions) { + createdStorageOptions.push(options); + } + bucket(bucketName: string) { return new Bucket(bucketName); } @@ -144,10 +151,12 @@ const createPublisherFromConfig = ({ bucketName = 'bucketName', bucketRootPath = '/', legacyUseCaseSensitiveTripletPaths = false, + storageOptions = {}, }: { bucketName?: string; bucketRootPath?: string; legacyUseCaseSensitiveTripletPaths?: boolean; + storageOptions?: StorageOptions; } = {}) => { const config = new ConfigReader({ techdocs: { @@ -162,7 +171,7 @@ const createPublisherFromConfig = ({ legacyUseCaseSensitiveTripletPaths, }, }); - return GoogleGCSPublish.fromConfig(config, logger); + return GoogleGCSPublish.fromConfig(config, logger, storageOptions); }; describe('GoogleGCSPublish', () => { @@ -211,11 +220,24 @@ describe('GoogleGCSPublish', () => { }; beforeEach(() => { + createdStorageOptions = []; mockDir.setContent({ [directory]: files, }); }); + it('should pass options to storage', () => { + createPublisherFromConfig({ + storageOptions: { + userAgent: 'Test-UA', + }, + }); + + expect(createdStorageOptions.map(opt => opt?.userAgent)).toContain( + 'Test-UA', + ); + }); + describe('getReadiness', () => { it('should validate correct config', async () => { const publisher = createPublisherFromConfig(); diff --git a/plugins/techdocs-node/src/stages/publish/googleStorage.ts b/plugins/techdocs-node/src/stages/publish/googleStorage.ts index bc75a4c8bb..3eac9834d2 100644 --- a/plugins/techdocs-node/src/stages/publish/googleStorage.ts +++ b/plugins/techdocs-node/src/stages/publish/googleStorage.ts @@ -29,6 +29,7 @@ import { Readable } from 'stream'; import { getFileTreeRecursively, getHeadersForFileExtension, + isValidContentPath, lowerCaseEntityTriplet, lowerCaseEntityTripletInStoragePath, bulkStorageOperation, @@ -67,7 +68,11 @@ export class GoogleGCSPublish implements PublisherBase { this.bucketRootPath = options.bucketRootPath; } - static fromConfig(config: Config, logger: LoggerService): PublisherBase { + static fromConfig( + config: Config, + logger: LoggerService, + options?: StorageOptions, + ): PublisherBase { let bucketName = ''; try { bucketName = config.getString('techdocs.publisher.googleGcs.bucketName'); @@ -102,7 +107,7 @@ export class GoogleGCSPublish implements PublisherBase { } } - const clientOpts: StorageOptions = {}; + const clientOpts: StorageOptions = options ?? {}; if (projectId) { clientOpts.projectId = projectId; } @@ -262,6 +267,12 @@ export class GoogleGCSPublish implements PublisherBase { : lowerCaseEntityTriplet(entityTriplet); const entityRootDir = path.posix.join(this.bucketRootPath, entityDir); + if (!isValidContentPath(this.bucketRootPath, entityRootDir)) { + this.logger.error( + `Invalid content path found while fetching TechDocs metadata: ${entityRootDir}`, + ); + reject(new Error(`Metadata Not Found`)); + } const fileStreamChunks: Array = []; this.storageClient @@ -297,6 +308,13 @@ export class GoogleGCSPublish implements PublisherBase { // Prepend the root path to the relative file path const filePath = path.posix.join(this.bucketRootPath, filePathNoRoot); + if (!isValidContentPath(this.bucketRootPath, filePath)) { + this.logger.error( + `Attempted to fetch TechDocs content for a file outside of the bucket root: ${filePathNoRoot}`, + ); + res.status(404).send('File Not Found'); + return; + } // Files with different extensions (CSS, HTML) need to be served with different headers const fileExtension = path.extname(filePath); @@ -337,6 +355,12 @@ export class GoogleGCSPublish implements PublisherBase { : lowerCaseEntityTriplet(entityTriplet); const entityRootDir = path.posix.join(this.bucketRootPath, entityDir); + if (!isValidContentPath(this.bucketRootPath, entityRootDir)) { + this.logger.error( + `Invalid content path found while checking if docs have been generated: ${entityRootDir}`, + ); + resolve(false); + } this.storageClient .bucket(this.bucketName) diff --git a/plugins/techdocs-node/src/stages/publish/helpers.test.ts b/plugins/techdocs-node/src/stages/publish/helpers.test.ts index 2a74cbee61..abb1148d78 100644 --- a/plugins/techdocs-node/src/stages/publish/helpers.test.ts +++ b/plugins/techdocs-node/src/stages/publish/helpers.test.ts @@ -23,6 +23,7 @@ import { lowerCaseEntityTriplet, lowerCaseEntityTripletInStoragePath, normalizeExternalStorageRootPath, + isValidContentPath, } from './helpers'; import { createMockDirectory } from '@backstage/backend-test-utils'; @@ -306,4 +307,26 @@ describe('bulkStorageOperation', () => { expect(fn).toHaveBeenNthCalledWith(1, files[0]); expect(fn).toHaveBeenNthCalledWith(2, files[1]); }); + + describe('isValidContentPath', () => { + it('should return true when content path is the same as bucket root', () => { + expect(isValidContentPath('/s/t', '/s/t')).toBe(true); + expect(isValidContentPath('/s/t', '/s/t/c')).toBe(true); + expect(isValidContentPath('/s/t', '/s/t/c w s/f.txt')).toBe(true); + expect(isValidContentPath('/s/t w s/', '/s/t w s/f.txt')).toBe(true); + expect(isValidContentPath('/s/t w s/', '/s/t w s/c w s/f.txt')).toBe( + true, + ); + expect( + isValidContentPath('/s/t w s/', '/s/t w s/c w s/../c w s/f.txt'), + ).toBe(true); + }); + + it('should return false when content path is not a child of bucket root', () => { + expect(isValidContentPath('/s/t', '/s')).toBe(false); + expect(isValidContentPath('/s/t', '/s/t w s')).toBe(false); + expect(isValidContentPath('/s/t w s', '/s/c')).toBe(false); + expect(isValidContentPath('/s/t', '/s/t/../../c/f.txt')).toBe(false); + }); + }); }); diff --git a/plugins/techdocs-node/src/stages/publish/helpers.ts b/plugins/techdocs-node/src/stages/publish/helpers.ts index 0b9384dba3..8fab446fae 100644 --- a/plugins/techdocs-node/src/stages/publish/helpers.ts +++ b/plugins/techdocs-node/src/stages/publish/helpers.ts @@ -25,10 +25,37 @@ import recursiveReadDir from 'recursive-readdir'; */ const getContentTypeForExtension = (ext: string): string => { const defaultContentType = 'text/plain; charset=utf-8'; + const excludedTypes = [ + 'text/html', + 'text/xml', + 'image/svg+xml', + 'text/xsl', + 'application/vnd.wap.xhtml+xml', + 'multipart/x-mixed-replace', + 'text/rdf', + 'application/mathml+xml', + 'application/octet-stream', + 'application/rdf+xml', + 'application/xhtml+xml', + 'application/xml', + 'text/cache-manifest', + 'text/vtt', + ]; // Prevent sanitization bypass by preventing browsers from directly rendering // the contents of untrusted files. - if (ext.match(/htm|xml|svg/i)) { + if ( + ext.match( + /htm|xml|svg|appcache|manifest|mathml|owl|rdf|rng|vtt|xht|xsd|xsl/i, + ) + ) { + return defaultContentType; + } + + // Check again to make sure that the content type is not in the excluded mime-type list + // We use .lookup here to avoid the "; charset=..." addition + const contentType = mime.lookup(ext); + if (contentType && excludedTypes.includes(contentType)) { return defaultContentType; } @@ -230,3 +257,20 @@ export const bulkStorageOperation = async ( const limiter = createLimiter(concurrencyLimit); await Promise.all(args.map(arg => limiter(operation, arg))); }; + +// Checks content path is the same as or a child path of bucketRoot, specifically for posix paths. +export const isValidContentPath = ( + bucketRoot: string, + contentPath: string, +): boolean => { + const relativePath = path.posix.relative(bucketRoot, contentPath); + if (relativePath === '') { + // The same directory + return true; + } + + const outsideBase = relativePath.startsWith('..'); // not outside base + const differentDrive = path.posix.isAbsolute(relativePath); // on Windows, this means dir is on a different drive from base. + + return !outsideBase && !differentDrive; +}; diff --git a/plugins/techdocs-node/src/stages/publish/index.ts b/plugins/techdocs-node/src/stages/publish/index.ts index 8b6465c719..8d528b4db6 100644 --- a/plugins/techdocs-node/src/stages/publish/index.ts +++ b/plugins/techdocs-node/src/stages/publish/index.ts @@ -24,5 +24,5 @@ export type { MigrateRequest, ReadinessResponse, TechDocsMetadata, - TechDocsContainerRunner, + PublisherSettings, } from './types'; diff --git a/plugins/techdocs-node/src/stages/publish/publish.ts b/plugins/techdocs-node/src/stages/publish/publish.ts index 09a6d9b375..67315165a9 100644 --- a/plugins/techdocs-node/src/stages/publish/publish.ts +++ b/plugins/techdocs-node/src/stages/publish/publish.ts @@ -86,7 +86,11 @@ export class Publisher implements PublisherBuilder { logger.info('Creating Google Storage Bucket publisher for TechDocs'); publishers.register( publisherType, - GoogleGCSPublish.fromConfig(config, logger), + GoogleGCSPublish.fromConfig( + config, + logger, + options.publisherSettings?.googleGcs, + ), ); break; case 'awsS3': diff --git a/plugins/techdocs-node/src/stages/publish/types.ts b/plugins/techdocs-node/src/stages/publish/types.ts index 89af730404..b5b65c8e08 100644 --- a/plugins/techdocs-node/src/stages/publish/types.ts +++ b/plugins/techdocs-node/src/stages/publish/types.ts @@ -13,11 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { Writable } from 'stream'; import express from 'express'; import { Config } from '@backstage/config'; import { DiscoveryService, LoggerService } from '@backstage/backend-plugin-api'; import { Entity, CompoundEntityRef } from '@backstage/catalog-model'; +import { StorageOptions } from '@google-cloud/storage'; /** * Options for building publishers @@ -27,8 +27,17 @@ export type PublisherFactory = { logger: LoggerService; discovery: DiscoveryService; customPublisher?: PublisherBase | undefined; + publisherSettings?: PublisherSettings; }; +/** + * Additional configurations for publishers. + * @public + */ +export interface PublisherSettings { + googleGcs?: StorageOptions; +} + /** * Key for all the different types of TechDocs publishers that are supported. * @public @@ -168,36 +177,3 @@ export type PublisherBuilder = { register(type: PublisherType, publisher: PublisherBase): void; get(config: Config): PublisherBase; }; - -/** - * Handles the running of containers, on behalf of others. - * - * @public - */ -export interface TechDocsContainerRunner { - /** - * Runs a container image to completion. - */ - runContainer(opts: { - imageName: string; - command?: string | string[]; - args: string[]; - logStream?: Writable; - mountDirs?: Record; - workingDir?: string; - envVars?: Record; - pullImage?: boolean; - defaultUser?: boolean; - pullOptions?: { - authconfig?: { - username?: string; - password?: string; - auth?: string; - email?: string; - serveraddress?: string; - [key: string]: unknown; - }; - [key: string]: unknown; - }; - }): Promise; -} diff --git a/plugins/techdocs-react/CHANGELOG.md b/plugins/techdocs-react/CHANGELOG.md index 93ad0932d8..b82b929f5b 100644 --- a/plugins/techdocs-react/CHANGELOG.md +++ b/plugins/techdocs-react/CHANGELOG.md @@ -1,5 +1,53 @@ # @backstage/plugin-techdocs-react +## 1.2.9-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/version-bridge@1.0.10-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + +## 1.2.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/version-bridge@1.0.9 + +## 1.2.8 + +### Patch Changes + +- 5ee3d27: Fixed issue in useShadowRootElements which could lead to unlimited render loops +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/catalog-model@1.7.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/version-bridge@1.0.9 + - @backstage/config@1.2.0 + +## 1.2.8-next.2 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/version-bridge@1.0.9-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + ## 1.2.8-next.1 ### Patch Changes diff --git a/plugins/techdocs-react/package.json b/plugins/techdocs-react/package.json index df95b38138..2f4e7ea31b 100644 --- a/plugins/techdocs-react/package.json +++ b/plugins/techdocs-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs-react", - "version": "1.2.8-next.1", + "version": "1.2.9-next.1", "description": "Shared frontend utilities for TechDocs and Addons", "backstage": { "role": "web-library", @@ -52,7 +52,6 @@ "@backstage/version-bridge": "workspace:^", "@material-ui/core": "^4.12.2", "@material-ui/styles": "^4.11.0", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "jss": "~10.10.0", "lodash": "^4.17.21", "react-helmet": "6.1.0", @@ -63,11 +62,21 @@ "@backstage/test-utils": "workspace:^", "@backstage/theme": "workspace:^", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^15.0.0" + "@testing-library/react": "^16.0.0", + "@types/react": "^18.0.0", + "react": "^18.0.2", + "react-dom": "^18.0.2", + "react-router-dom": "^6.3.0" }, "peerDependencies": { + "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } } diff --git a/plugins/techdocs-react/api-report.md b/plugins/techdocs-react/report.api.md similarity index 85% rename from plugins/techdocs-react/api-report.md rename to plugins/techdocs-react/report.api.md index c158bbd81e..73f122068e 100644 --- a/plugins/techdocs-react/api-report.md +++ b/plugins/techdocs-react/report.api.md @@ -192,4 +192,17 @@ export const useTechDocsAddons: () => { // @public export const useTechDocsReaderPage: () => TechDocsReaderPageValue; + +// Warnings were encountered during analysis: +// +// src/api.d.ts:9:5 - (ae-undocumented) Missing documentation for "getCookie". +// src/api.d.ts:12:5 - (ae-undocumented) Missing documentation for "getApiOrigin". +// src/api.d.ts:13:5 - (ae-undocumented) Missing documentation for "getTechDocsMetadata". +// src/api.d.ts:14:5 - (ae-undocumented) Missing documentation for "getEntityMetadata". +// src/api.d.ts:34:5 - (ae-undocumented) Missing documentation for "getApiOrigin". +// src/api.d.ts:35:5 - (ae-undocumented) Missing documentation for "getStorageUrl". +// src/api.d.ts:36:5 - (ae-undocumented) Missing documentation for "getBuilder". +// src/api.d.ts:37:5 - (ae-undocumented) Missing documentation for "getEntityDocs". +// src/api.d.ts:38:5 - (ae-undocumented) Missing documentation for "syncEntityDocs". +// src/api.d.ts:39:5 - (ae-undocumented) Missing documentation for "getBaseUrl". ``` diff --git a/plugins/techdocs/CHANGELOG.md b/plugins/techdocs/CHANGELOG.md index 56fdbed8eb..e828503443 100644 --- a/plugins/techdocs/CHANGELOG.md +++ b/plugins/techdocs/CHANGELOG.md @@ -1,5 +1,113 @@ # @backstage/plugin-techdocs +## 1.10.11-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/frontend-plugin-api@0.9.0-next.1 + - @backstage/integration-react@1.2.0-next.1 + - @backstage/core-compat-api@0.3.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/plugin-techdocs-react@1.2.9-next.1 + - @backstage/plugin-catalog-react@1.14.0-next.1 + - @backstage/plugin-search-react@1.8.1-next.1 + - @backstage/plugin-auth-react@0.1.7-next.1 + - @backstage/theme@0.5.8-next.0 + - @backstage/integration@1.15.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-techdocs-common@0.1.0 + +## 1.10.10-next.0 + +### Patch Changes + +- a77cb40: Make `emptyState` input optional on `entity-content:techdocs` extension so that + the default empty state extension works correctly. +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/core-compat-api@0.3.1-next.0 + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/plugin-catalog-react@1.13.1-next.0 + - @backstage/plugin-search-react@1.8.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.15.0 + - @backstage/integration-react@1.1.32-next.0 + - @backstage/theme@0.5.7 + - @backstage/plugin-auth-react@0.1.7-next.0 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-techdocs-react@1.2.9-next.0 + +## 1.10.9 + +### Patch Changes + +- c891b69: Add `FavoriteToggle` in `core-components` to standardise favorite marking +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. +- fe94ad8: Fixes left navigation positioning when using mkdocs blog plugin +- b0206dc: Added support for setting page status with 'new' and 'deprecated' values, allowing visual indication of page status in TechDocs. To use include the following at the top of your markdown file: + + ```markdown + --- + status: new + --- + ``` + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- c7cb4c0: Add `empty-state:techdocs/entity-content` extension to allow overriding the empty state for the entity page techdocs tab. +- 97db53e: Enhanced the table hover effect with a lighter color and updated the border radius to align with Backstage's theme styling +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/plugin-catalog-react@1.13.0 + - @backstage/frontend-plugin-api@0.8.0 + - @backstage/plugin-techdocs-react@1.2.8 + - @backstage/core-compat-api@0.3.0 + - @backstage/plugin-search-react@1.8.0 + - @backstage/integration-react@1.1.31 + - @backstage/catalog-model@1.7.0 + - @backstage/integration@1.15.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/theme@0.5.7 + - @backstage/plugin-auth-react@0.1.6 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-techdocs-common@0.1.0 + +## 1.10.9-next.2 + +### Patch Changes + +- c891b69: Add `FavoriteToggle` in `core-components` to standardise favorite marking +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- 97db53e: Enhanced the table hover effect with a lighter color and updated the border radius to align with Backstage's theme styling +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/plugin-catalog-react@1.13.0-next.2 + - @backstage/integration-react@1.1.31-next.0 + - @backstage/plugin-search-react@1.8.0-next.2 + - @backstage/integration@1.15.0-next.0 + - @backstage/core-compat-api@0.3.0-next.2 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/frontend-plugin-api@0.8.0-next.2 + - @backstage/theme@0.5.7-next.0 + - @backstage/plugin-auth-react@0.1.6-next.1 + - @backstage/plugin-techdocs-react@1.2.8-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-techdocs-common@0.1.0 + ## 1.10.9-next.1 ### Patch Changes diff --git a/plugins/techdocs/package.json b/plugins/techdocs/package.json index cefc822ebf..64945f6796 100644 --- a/plugins/techdocs/package.json +++ b/plugins/techdocs/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs", - "version": "1.10.9-next.1", + "version": "1.10.11-next.1", "description": "The Backstage plugin that renders technical documentation for your components", "backstage": { "role": "frontend-plugin", @@ -80,7 +80,6 @@ "@material-ui/lab": "4.0.0-alpha.61", "@material-ui/styles": "^4.10.0", "@microsoft/fetch-event-source": "^2.0.1", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "dompurify": "^3.0.0", "git-url-parse": "^14.0.0", "jss": "~10.10.0", @@ -96,15 +95,25 @@ "@backstage/test-utils": "workspace:^", "@testing-library/dom": "^10.0.0", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^15.0.0", + "@testing-library/react": "^16.0.0", "@testing-library/user-event": "^14.0.0", "@types/dompurify": "^3.0.0", - "canvas": "^2.10.2" + "@types/react": "^18.0.0", + "canvas": "^2.10.2", + "react": "^18.0.2", + "react-dom": "^18.0.2", + "react-router-dom": "^6.3.0" }, "peerDependencies": { + "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-router-dom": "6.0.0-beta.0 || ^6.3.0" }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + }, "configSchema": "config.d.ts" } diff --git a/plugins/techdocs/api-report-alpha.md b/plugins/techdocs/report-alpha.api.md similarity index 76% rename from plugins/techdocs/api-report-alpha.md rename to plugins/techdocs/report-alpha.api.md index 6a22a9fce9..faaf6d6a83 100644 --- a/plugins/techdocs/api-report-alpha.md +++ b/plugins/techdocs/report-alpha.api.md @@ -16,6 +16,7 @@ import { default as React_2 } from 'react'; import { RouteRef } from '@backstage/frontend-plugin-api'; import { SearchResultItemExtensionComponent } from '@backstage/plugin-search-react/alpha'; import { SearchResultItemExtensionPredicate } from '@backstage/plugin-search-react/alpha'; +import { SearchResultListItemBlueprintParams } from '@backstage/plugin-search-react/alpha'; // @alpha (undocumented) const _default: FrontendPlugin< @@ -32,7 +33,6 @@ const _default: FrontendPlugin< { 'api:techdocs': ExtensionDefinition<{ kind: 'api'; - namespace: undefined; name: undefined; config: {}; configInput: {}; @@ -42,10 +42,12 @@ const _default: FrontendPlugin< {} >; inputs: {}; + params: { + factory: AnyApiFactory; + }; }>; 'page:techdocs': ExtensionDefinition<{ kind: 'page'; - namespace: undefined; name: undefined; config: { path: string | undefined; @@ -68,10 +70,14 @@ const _default: FrontendPlugin< } >; inputs: {}; + params: { + defaultPath: string; + loader: () => Promise; + routeRef?: RouteRef | undefined; + }; }>; 'nav-item:techdocs': ExtensionDefinition<{ kind: 'nav-item'; - namespace: undefined; name: undefined; config: {}; configInput: {}; @@ -85,10 +91,14 @@ const _default: FrontendPlugin< {} >; inputs: {}; + params: { + title: string; + icon: IconComponent; + routeRef: RouteRef; + }; }>; 'api:techdocs/storage': ExtensionDefinition<{ kind: 'api'; - namespace: undefined; name: 'storage'; config: {}; configInput: {}; @@ -98,6 +108,9 @@ const _default: FrontendPlugin< {} >; inputs: {}; + params: { + factory: AnyApiFactory; + }; }>; 'search-result-list-item:techdocs': ExtensionDefinition<{ config: { @@ -134,12 +147,11 @@ const _default: FrontendPlugin< >; }; kind: 'search-result-list-item'; - namespace: undefined; name: undefined; + params: SearchResultListItemBlueprintParams; }>; 'page:techdocs/reader': ExtensionDefinition<{ kind: 'page'; - namespace: undefined; name: 'reader'; config: { path: string | undefined; @@ -162,11 +174,13 @@ const _default: FrontendPlugin< } >; inputs: {}; + params: { + defaultPath: string; + loader: () => Promise; + routeRef?: RouteRef | undefined; + }; }>; 'entity-content:techdocs': ExtensionDefinition<{ - kind: 'entity-content'; - namespace: undefined; - name: undefined; config: { path: string | undefined; title: string | undefined; @@ -210,7 +224,53 @@ const _default: FrontendPlugin< optional: true; } >; - inputs: {}; + inputs: { + emptyState: ExtensionInput< + ConfigurableExtensionDataRef< + React_2.JSX.Element, + 'core.reactElement', + { + optional: true; + } + >, + { + singleton: true; + optional: true; + } + >; + }; + kind: 'entity-content'; + name: undefined; + params: { + loader: () => Promise; + defaultPath: string; + defaultTitle: string; + routeRef?: RouteRef | undefined; + filter?: string | ((entity: Entity) => boolean) | undefined; + }; + }>; + 'empty-state:techdocs/entity-content': ExtensionDefinition<{ + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + React_2.JSX.Element, + 'core.reactElement', + { + optional: true; + } + >; + inputs: { + [x: string]: ExtensionInput< + AnyExtensionDataRef, + { + optional: boolean; + singleton: boolean; + } + >; + }; + params: never; + kind: 'empty-state'; + name: 'entity-content'; }>; } >; @@ -252,9 +312,14 @@ export const techDocsSearchResultListItemExtension: ExtensionDefinition<{ >; }; kind: 'search-result-list-item'; - namespace: undefined; name: undefined; + params: SearchResultListItemBlueprintParams; }>; +// Warnings were encountered during analysis: +// +// src/alpha.d.ts:3:22 - (ae-undocumented) Missing documentation for "techDocsSearchResultListItemExtension". +// src/alpha.d.ts:35:15 - (ae-undocumented) Missing documentation for "_default". + // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/techdocs/api-report.md b/plugins/techdocs/report.api.md similarity index 82% rename from plugins/techdocs/api-report.md rename to plugins/techdocs/report.api.md index 781d8db422..3ecf2cf7d2 100644 --- a/plugins/techdocs/api-report.md +++ b/plugins/techdocs/report.api.md @@ -134,7 +134,7 @@ export type DocsTableRow = { // @public export const EmbeddedDocsRouter: ( props: PropsWithChildren<{}>, -) => React_2.JSX.Element | null; +) => React_2.JSX.Element; // @public export const EntityListDocsGrid: ( @@ -192,7 +192,7 @@ export type EntityListDocsTableProps = { // @public export const EntityTechdocsContent: (props: { children?: ReactNode; -}) => JSX_2.Element | null; +}) => JSX_2.Element; // @public export const isTechDocsAvailable: (entity: Entity) => boolean; @@ -506,4 +506,36 @@ export class TechDocsStorageClient implements TechDocsStorageApi_2 { logHandler?: (line: string) => void, ): Promise; } + +// Warnings were encountered during analysis: +// +// src/api.d.ts:31:5 - (ae-undocumented) Missing documentation for "getApiOrigin". +// src/api.d.ts:32:5 - (ae-undocumented) Missing documentation for "getStorageUrl". +// src/api.d.ts:33:5 - (ae-undocumented) Missing documentation for "getBuilder". +// src/api.d.ts:34:5 - (ae-undocumented) Missing documentation for "getEntityDocs". +// src/api.d.ts:35:5 - (ae-undocumented) Missing documentation for "syncEntityDocs". +// src/api.d.ts:36:5 - (ae-undocumented) Missing documentation for "getBaseUrl". +// src/api.d.ts:45:5 - (ae-undocumented) Missing documentation for "getApiOrigin". +// src/api.d.ts:46:5 - (ae-undocumented) Missing documentation for "getTechDocsMetadata". +// src/api.d.ts:47:5 - (ae-undocumented) Missing documentation for "getEntityMetadata". +// src/client.d.ts:11:5 - (ae-undocumented) Missing documentation for "configApi". +// src/client.d.ts:12:5 - (ae-undocumented) Missing documentation for "discoveryApi". +// src/client.d.ts:19:5 - (ae-undocumented) Missing documentation for "getCookie". +// src/client.d.ts:22:5 - (ae-undocumented) Missing documentation for "getApiOrigin". +// src/client.d.ts:49:5 - (ae-undocumented) Missing documentation for "configApi". +// src/client.d.ts:50:5 - (ae-undocumented) Missing documentation for "discoveryApi". +// src/client.d.ts:59:5 - (ae-undocumented) Missing documentation for "getApiOrigin". +// src/client.d.ts:60:5 - (ae-undocumented) Missing documentation for "getStorageUrl". +// src/client.d.ts:61:5 - (ae-undocumented) Missing documentation for "getBuilder". +// src/client.d.ts:80:5 - (ae-undocumented) Missing documentation for "getBaseUrl". +// src/home/components/TechDocsCustomHome.d.ts:16:5 - (ae-undocumented) Missing documentation for "title". +// src/home/components/TechDocsCustomHome.d.ts:17:5 - (ae-undocumented) Missing documentation for "description". +// src/home/components/TechDocsCustomHome.d.ts:18:5 - (ae-undocumented) Missing documentation for "panelType". +// src/home/components/TechDocsCustomHome.d.ts:19:5 - (ae-undocumented) Missing documentation for "panelCSS". +// src/home/components/TechDocsCustomHome.d.ts:20:5 - (ae-undocumented) Missing documentation for "filterPredicate". +// src/home/components/TechDocsCustomHome.d.ts:28:5 - (ae-undocumented) Missing documentation for "label". +// src/home/components/TechDocsCustomHome.d.ts:29:5 - (ae-undocumented) Missing documentation for "panels". +// src/index.d.ts:21:1 - (ae-undocumented) Missing documentation for "DeprecatedTechDocsMetadata". +// src/index.d.ts:27:1 - (ae-undocumented) Missing documentation for "DeprecatedTechDocsEntityMetadata". +// src/reader/components/TechDocsReaderPage/TechDocsReaderPage.d.ts:27:1 - (ae-undocumented) Missing documentation for "TechDocsReaderPageProps". ``` diff --git a/plugins/techdocs/src/Router.tsx b/plugins/techdocs/src/Router.tsx index 87a53156d6..352c9f5b73 100644 --- a/plugins/techdocs/src/Router.tsx +++ b/plugins/techdocs/src/Router.tsx @@ -56,13 +56,10 @@ export const Router = () => { ); }; -/** - * Responsible for registering route to view docs on Entity page - * - * @public - */ -export const EmbeddedDocsRouter = (props: PropsWithChildren<{}>) => { - const { children } = props; +export const EmbeddedDocsRouter = ( + props: PropsWithChildren<{ emptyState?: React.ReactElement }>, +) => { + const { children, emptyState } = props; const { entity } = useEntity(); // Using objects instead of elements, otherwise "outlet" will be null on sub-pages and add-ons won't render @@ -84,8 +81,23 @@ export const EmbeddedDocsRouter = (props: PropsWithChildren<{}>) => { entity.metadata.annotations?.[TECHDOCS_EXTERNAL_ANNOTATION]; if (!projectId) { - return ; + return ( + emptyState ?? ( + + ) + ); } return element; }; + +/** + * Responsible for registering route to view docs on Entity page + * + * @public + */ +export const LegacyEmbeddedDocsRouter = (props: PropsWithChildren<{}>) => { + // Wrap the Router to avoid exposing the emptyState prop in the non-alpha + // public API and make it easier for us to change later. + return ; +}; diff --git a/plugins/techdocs/src/alpha.tsx b/plugins/techdocs/src/alpha.tsx index b0d0d3d467..e0e1c1761e 100644 --- a/plugins/techdocs/src/alpha.tsx +++ b/plugins/techdocs/src/alpha.tsx @@ -21,8 +21,10 @@ import { ApiBlueprint, PageBlueprint, NavItemBlueprint, + createExtensionInput, + coreExtensionData, + createExtension, } from '@backstage/frontend-plugin-api'; -import { SearchResultListItemBlueprint } from '@backstage/plugin-search-react/alpha'; import { configApiRef, createApiFactory, @@ -34,6 +36,8 @@ import { convertLegacyRouteRef, convertLegacyRouteRefs, } from '@backstage/core-compat-api'; +import { EntityContentBlueprint } from '@backstage/plugin-catalog-react/alpha'; +import { SearchResultListItemBlueprint } from '@backstage/plugin-search-react/alpha'; import { techdocsApiRef, techdocsStorageApiRef, @@ -44,7 +48,6 @@ import { rootDocsRouteRef, rootRouteRef, } from './routes'; -import { EntityContentBlueprint } from '@backstage/plugin-catalog-react/alpha'; /** @alpha */ const techDocsStorageApi = ApiBlueprint.make({ @@ -152,13 +155,43 @@ const techDocsReaderPage = PageBlueprint.make({ * * @alpha */ -const techDocsEntityContent = EntityContentBlueprint.make({ - params: { - defaultPath: 'docs', - defaultTitle: 'TechDocs', - loader: () => - import('./Router').then(m => compatWrapper()), +const techDocsEntityContent = EntityContentBlueprint.makeWithOverrides({ + inputs: { + emptyState: createExtensionInput( + [coreExtensionData.reactElement.optional()], + { + singleton: true, + optional: true, + }, + ), }, + factory(originalFactory, context) { + return originalFactory( + { + defaultPath: 'docs', + defaultTitle: 'TechDocs', + loader: () => + import('./Router').then(({ EmbeddedDocsRouter }) => + compatWrapper( + , + ), + ), + }, + context, + ); + }, +}); + +const techDocsEntityContentEmptyState = createExtension({ + kind: 'empty-state', + name: 'entity-content', + attachTo: { id: 'entity-content:techdocs', input: 'emptyState' }, + output: [coreExtensionData.reactElement.optional()], + factory: () => [], }); /** @alpha */ @@ -180,6 +213,7 @@ export default createFrontendPlugin({ techDocsPage, techDocsReaderPage, techDocsEntityContent, + techDocsEntityContentEmptyState, techDocsSearchResultListItemExtension, ], routes: convertLegacyRouteRefs({ diff --git a/plugins/techdocs/src/home/components/Tables/actions.tsx b/plugins/techdocs/src/home/components/Tables/actions.tsx index c95dd8b94c..bc89d76560 100644 --- a/plugins/techdocs/src/home/components/Tables/actions.tsx +++ b/plugins/techdocs/src/home/components/Tables/actions.tsx @@ -17,15 +17,7 @@ import React from 'react'; import ShareIcon from '@material-ui/icons/Share'; import { DocsTableRow } from './types'; -import { withStyles } from '@material-ui/core/styles'; -import Star from '@material-ui/icons/Star'; -import StarBorder from '@material-ui/icons/StarBorder'; - -const YellowStar = withStyles({ - root: { - color: '#f3ba37', - }, -})(Star); +import { FavoriteToggleIcon } from '@backstage/core-components'; /** * Not directly exported, but through DocsTable.actions and EntityListDocsTable.actions @@ -52,7 +44,7 @@ export const actionFactories = { const isStarred = isStarredEntity(entity); return { cellStyle: { paddingLeft: '1em' }, - icon: () => (isStarred ? : ), + icon: () => , tooltip: isStarred ? 'Remove from favorites' : 'Add to favorites', onClick: () => toggleStarredEntity(entity), }; diff --git a/plugins/techdocs/src/index.ts b/plugins/techdocs/src/index.ts index c759d43fe9..522bcd0c99 100644 --- a/plugins/techdocs/src/index.ts +++ b/plugins/techdocs/src/index.ts @@ -41,7 +41,11 @@ export { techdocsPlugin as plugin, techdocsPlugin, } from './plugin'; -export * from './Router'; +export { + isTechDocsAvailable, + LegacyEmbeddedDocsRouter as EmbeddedDocsRouter, + Router, +} from './Router'; export type { TechDocsSearchResultListItemProps } from './search/components/TechDocsSearchResultListItem'; diff --git a/plugins/techdocs/src/plugin.ts b/plugins/techdocs/src/plugin.ts index efa6bdfc1f..91b4214336 100644 --- a/plugins/techdocs/src/plugin.ts +++ b/plugins/techdocs/src/plugin.ts @@ -103,7 +103,7 @@ export const TechdocsPage = techdocsPlugin.provide( export const EntityTechdocsContent = techdocsPlugin.provide( createRoutableExtension({ name: 'EntityTechdocsContent', - component: () => import('./Router').then(m => m.EmbeddedDocsRouter), + component: () => import('./Router').then(m => m.LegacyEmbeddedDocsRouter), mountPoint: rootCatalogDocsRouteRef, }), ); diff --git a/plugins/techdocs/src/reader/transformers/styles/rules/layout.ts b/plugins/techdocs/src/reader/transformers/styles/rules/layout.ts index 78b73cb52a..590f2a114b 100644 --- a/plugins/techdocs/src/reader/transformers/styles/rules/layout.ts +++ b/plugins/techdocs/src/reader/transformers/styles/rules/layout.ts @@ -34,11 +34,14 @@ export default ({ theme, sidebar }: RuleOptions) => ` .md-nav { font-size: calc(var(--md-typeset-font-size) * 0.9); } -.md-nav__link { +.md-nav__link:not(:has(svg)) { display: flex; align-items: center; justify-content: space-between; } +.md-nav__link:has(svg) > .md-ellipsis { + flex-grow: 1; +} .md-nav__icon { height: 20px !important; width: 20px !important; @@ -53,11 +56,21 @@ export default ({ theme, sidebar }: RuleOptions) => ` width: 20px !important; height: 20px !important; } +.md-status--updated::after { + -webkit-mask-image: var(--md-status--updated); + mask-image: var(--md-status--updated); +} .md-nav__item--active > .md-nav__link, a.md-nav__link--active { text-decoration: underline; color: var(--md-typeset-a-color); } +.md-nav__link--active > .md-status:after { + background-color: var(--md-typeset-a-color); +} +.md-nav__link[href]:hover > .md-status:after { + background-color: var(--md-accent-fg-color); +} .md-main__inner { margin-top: 0; @@ -108,6 +121,10 @@ export default ({ theme, sidebar }: RuleOptions) => ` margin-bottom: 50px; } +.md-content > .md-sidebar { + left: 16rem; +} + .md-footer { position: fixed; bottom: 0px; diff --git a/plugins/techdocs/src/reader/transformers/styles/rules/palette.ts b/plugins/techdocs/src/reader/transformers/styles/rules/palette.ts new file mode 100644 index 0000000000..fa1f69ac88 --- /dev/null +++ b/plugins/techdocs/src/reader/transformers/styles/rules/palette.ts @@ -0,0 +1,38 @@ +/* + * 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 { RuleOptions } from './types'; +import { Theme } from '@material-ui/core/styles'; + +const themeHashes: Record> = { + dark: ['#only-light', '#gh-light-mode-only'], + light: ['#only-dark', '#gh-dark-mode-only'], +}; + +export default ({ theme }: RuleOptions) => ` +/*================== Palette ==================*/ +/* + When color palette toggle is enabled in material theme for Mkdocs, there is a possibility to show conditionally + images by adding #only-dark or #only-light to resource hash. Backstage doesn't use mkdocs color palette mechanism, + so there is a need to add css rules from palette*.css manually. +*/ + +${themeHashes[theme.palette.type] + .map(hash => `img[src$="${hash}"]`) + .join(', ')} { + display: none; +} +`; diff --git a/plugins/techdocs/src/reader/transformers/styles/rules/rules.ts b/plugins/techdocs/src/reader/transformers/styles/rules/rules.ts index 917793733e..9341fd6e3e 100644 --- a/plugins/techdocs/src/reader/transformers/styles/rules/rules.ts +++ b/plugins/techdocs/src/reader/transformers/styles/rules/rules.ts @@ -20,6 +20,7 @@ import { default as layout } from './layout'; import { default as typeset } from './typeset'; import { default as animations } from './animations'; import { default as extensions } from './extensions'; +import palette from './palette'; /** * A list of style rules that will be applied to an element in the order they were added. @@ -35,4 +36,5 @@ export const rules = [ typeset, animations, extensions, + palette, ]; diff --git a/plugins/techdocs/src/reader/transformers/styles/rules/variables.ts b/plugins/techdocs/src/reader/transformers/styles/rules/variables.ts index 7ffe76c5fb..e7e47c6fc7 100644 --- a/plugins/techdocs/src/reader/transformers/styles/rules/variables.ts +++ b/plugins/techdocs/src/reader/transformers/styles/rules/variables.ts @@ -97,6 +97,12 @@ export default ({ theme }: RuleOptions) => ` --md-source-stars-icon: url('data:image/svg+xml;charset=utf-8,'); --md-source-version-icon: url('data:image/svg+xml;charset=utf-8,'); --md-version-icon: url('data:image/svg+xml;charset=utf-8,'); + + --md-status--updated: url('data:image/svg+xml;charset=utf-8,cellphone-arrow-down'); + --md-status: url('data:image/svg+xml;charset=utf-8,'); + --md-status--new: url('data:image/svg+xml;charset=utf-8,'); + --md-status--deprecated: url('data:image/svg+xml;charset=utf-8,'); + --md-status--encrypted: url('data:image/svg+xml;charset=utf-8,'); } :host > * { diff --git a/plugins/techdocs/src/reader/transformers/styles/transformer.test.tsx b/plugins/techdocs/src/reader/transformers/styles/transformer.test.tsx index b55e372212..6cfde4f09d 100644 --- a/plugins/techdocs/src/reader/transformers/styles/transformer.test.tsx +++ b/plugins/techdocs/src/reader/transformers/styles/transformer.test.tsx @@ -47,6 +47,9 @@ describe('Transformers > Styles', () => { expect(style).toHaveTextContent( '/*================== Extensions ==================*/', ); + expect(style).toHaveTextContent( + '/*================== Palette ==================*/', + ); }); it('should use headers relative font-size value as the factor for the md-typeset variable', () => { diff --git a/plugins/user-settings-backend/CHANGELOG.md b/plugins/user-settings-backend/CHANGELOG.md index 5b6283c103..611b67ad38 100644 --- a/plugins/user-settings-backend/CHANGELOG.md +++ b/plugins/user-settings-backend/CHANGELOG.md @@ -1,5 +1,68 @@ # @backstage/plugin-user-settings-backend +## 0.2.25-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.1-next.1 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/plugin-signals-node@0.1.12-next.0 + - @backstage/plugin-user-settings-common@0.0.1 + +## 0.2.25-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.1-next.0 + - @backstage/plugin-signals-node@0.1.12-next.0 + - @backstage/plugin-auth-node@0.5.3-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-user-settings-common@0.0.1 + +## 0.2.24 + +### Patch Changes + +- 5d1670f: Update README installation instructions +- 164ce3e: In preparation to stop supporting to the legacy backend system, the `createRouter` function is now deprecated and we strongly recommend you [migrate](https://backstage.io/docs/backend-system/building-backends/migrating) your backend to the new system. +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- 1b98099: Replaced usage of the deprecated identity service with the new HTTP auth service for the new backend system. +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-defaults@0.5.0 + - @backstage/plugin-signals-node@0.1.11 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/plugin-auth-node@0.5.2 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-user-settings-common@0.0.1 + +## 0.2.24-next.2 + +### Patch Changes + +- 5d1670f: Update README installation instructions +- c2b63ab: Updated dependency `supertest` to `^7.0.0`. +- Updated dependencies + - @backstage/backend-defaults@0.5.0-next.2 + - @backstage/plugin-auth-node@0.5.2-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-node@0.1.11-next.2 + - @backstage/plugin-user-settings-common@0.0.1 + ## 0.2.24-next.1 ### Patch Changes diff --git a/plugins/user-settings-backend/package.json b/plugins/user-settings-backend/package.json index dcbd3dac2d..595ec64f53 100644 --- a/plugins/user-settings-backend/package.json +++ b/plugins/user-settings-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-user-settings-backend", - "version": "0.2.24-next.1", + "version": "0.2.25-next.1", "description": "The Backstage backend plugin to manage user settings", "backstage": { "role": "backend-plugin", @@ -71,6 +71,6 @@ "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "@types/supertest": "^2.0.8", - "supertest": "^6.1.3" + "supertest": "^7.0.0" } } diff --git a/plugins/user-settings-backend/api-report-alpha.md b/plugins/user-settings-backend/report-alpha.api.md similarity index 100% rename from plugins/user-settings-backend/api-report-alpha.md rename to plugins/user-settings-backend/report-alpha.api.md diff --git a/plugins/user-settings-backend/api-report.md b/plugins/user-settings-backend/report.api.md similarity index 100% rename from plugins/user-settings-backend/api-report.md rename to plugins/user-settings-backend/report.api.md diff --git a/plugins/user-settings-common/api-report.md b/plugins/user-settings-common/report.api.md similarity index 71% rename from plugins/user-settings-common/api-report.md rename to plugins/user-settings-common/report.api.md index b69f4a4190..a984f71e47 100644 --- a/plugins/user-settings-common/api-report.md +++ b/plugins/user-settings-common/report.api.md @@ -9,5 +9,9 @@ export type UserSettingsSignal = { key: string; }; +// Warnings were encountered during analysis: +// +// src/types.d.ts:2:1 - (ae-undocumented) Missing documentation for "UserSettingsSignal". + // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/user-settings/CHANGELOG.md b/plugins/user-settings/CHANGELOG.md index 7716030af1..43501258d2 100644 --- a/plugins/user-settings/CHANGELOG.md +++ b/plugins/user-settings/CHANGELOG.md @@ -1,5 +1,79 @@ # @backstage/plugin-user-settings +## 0.8.14-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/plugin-signals-react@0.0.6-next.1 + - @backstage/frontend-plugin-api@0.9.0-next.1 + - @backstage/core-compat-api@0.3.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/core-app-api@1.15.1-next.1 + - @backstage/plugin-catalog-react@1.14.0-next.1 + - @backstage/theme@0.5.8-next.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-user-settings-common@0.0.1 + +## 0.8.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/core-compat-api@0.3.1-next.0 + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/plugin-catalog-react@1.13.1-next.0 + - @backstage/core-app-api@1.15.1-next.0 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.7 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.6-next.0 + - @backstage/plugin-user-settings-common@0.0.1 + +## 0.8.12 + +### Patch Changes + +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- da86ac2: Update README to clarify location of additional tabs example +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/plugin-catalog-react@1.13.0 + - @backstage/frontend-plugin-api@0.8.0 + - @backstage/core-app-api@1.15.0 + - @backstage/core-compat-api@0.3.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/theme@0.5.7 + - @backstage/plugin-signals-react@0.0.5 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-user-settings-common@0.0.1 + +## 0.8.12-next.2 + +### Patch Changes + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- da86ac2: Update README to clarify location of additional tabs example +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/plugin-catalog-react@1.13.0-next.2 + - @backstage/core-app-api@1.14.3-next.0 + - @backstage/core-compat-api@0.3.0-next.2 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/frontend-plugin-api@0.8.0-next.2 + - @backstage/theme@0.5.7-next.0 + - @backstage/plugin-signals-react@0.0.5-next.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-user-settings-common@0.0.1 + ## 0.8.12-next.1 ### Patch Changes diff --git a/plugins/user-settings/README.md b/plugins/user-settings/README.md index 41a6930ae3..ee26a5f332 100644 --- a/plugins/user-settings/README.md +++ b/plugins/user-settings/README.md @@ -91,7 +91,7 @@ To standardize the UI of all setting tabs, make sure you use a similar component structure as the other tabs. You can take a look at [the example extra tab](https://github.com/backstage/backstage/blob/master/packages/app/src/components/advancedSettings/AdvancedSettings.tsx) -we have created in Backstage's demo app. +we have created in Backstage's example app. To change the layout altogether, create a custom page in `packages/app/src/components/user-settings/SettingsPage.tsx`: diff --git a/plugins/user-settings/package.json b/plugins/user-settings/package.json index 404024730c..842ea63d19 100644 --- a/plugins/user-settings/package.json +++ b/plugins/user-settings/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-user-settings", - "version": "0.8.12-next.1", + "version": "0.8.14-next.1", "description": "A Backstage plugin that provides a settings page", "backstage": { "role": "frontend-plugin", @@ -69,7 +69,6 @@ "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.61", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-use": "^17.2.4", "zen-observable": "^0.10.0" }, @@ -80,15 +79,25 @@ "@backstage/test-utils": "workspace:^", "@testing-library/dom": "^10.0.0", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^15.0.0", + "@testing-library/react": "^16.0.0", "@testing-library/user-event": "^14.0.0", - "msw": "^1.0.0" + "@types/react": "^18.0.0", + "msw": "^1.0.0", + "react": "^18.0.2", + "react-dom": "^18.0.2", + "react-router-dom": "^6.3.0" }, "peerDependencies": { + "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-router-dom": "6.0.0-beta.0 || ^6.3.0" }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + }, "configSchema": { "$schema": "https://backstage.io/schema/config-v1", "title": "@backstage/user-settings", diff --git a/plugins/user-settings/api-report-alpha.md b/plugins/user-settings/report-alpha.api.md similarity index 82% rename from plugins/user-settings/api-report-alpha.md rename to plugins/user-settings/report-alpha.api.md index 199dbba582..d9dad32623 100644 --- a/plugins/user-settings/api-report-alpha.md +++ b/plugins/user-settings/report-alpha.api.md @@ -22,7 +22,6 @@ const _default: FrontendPlugin< { 'nav-item:user-settings': ExtensionDefinition<{ kind: 'nav-item'; - namespace: undefined; name: undefined; config: {}; configInput: {}; @@ -36,6 +35,11 @@ const _default: FrontendPlugin< {} >; inputs: {}; + params: { + title: string; + icon: IconComponent; + routeRef: RouteRef; + }; }>; 'page:user-settings': ExtensionDefinition<{ config: { @@ -72,8 +76,12 @@ const _default: FrontendPlugin< >; }; kind: 'page'; - namespace: undefined; name: undefined; + params: { + defaultPath: string; + loader: () => Promise; + routeRef?: RouteRef | undefined; + }; }>; } >; @@ -82,7 +90,6 @@ export default _default; // @alpha (undocumented) export const settingsNavItem: ExtensionDefinition<{ kind: 'nav-item'; - namespace: undefined; name: undefined; config: {}; configInput: {}; @@ -96,6 +103,11 @@ export const settingsNavItem: ExtensionDefinition<{ {} >; inputs: {}; + params: { + title: string; + icon: IconComponent; + routeRef: RouteRef; + }; }>; // @alpha (undocumented) @@ -115,5 +127,11 @@ export const userSettingsTranslationRef: TranslationRef< } >; +// Warnings were encountered during analysis: +// +// src/alpha.d.ts:4:22 - (ae-undocumented) Missing documentation for "settingsNavItem". +// src/alpha.d.ts:24:15 - (ae-undocumented) Missing documentation for "_default". +// src/translation.d.ts:2:22 - (ae-undocumented) Missing documentation for "userSettingsTranslationRef". + // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/user-settings/api-report.md b/plugins/user-settings/report.api.md similarity index 59% rename from plugins/user-settings/api-report.md rename to plugins/user-settings/report.api.md index cee35724bb..6169668adc 100644 --- a/plugins/user-settings/api-report.md +++ b/plugins/user-settings/report.api.md @@ -179,4 +179,36 @@ export const useUserProfile: () => displayName: string; loading: false; }; + +// Warnings were encountered during analysis: +// +// src/apis/StorageApi/UserSettingsStorage.d.ts:21:5 - (ae-undocumented) Missing documentation for "create". +// src/apis/StorageApi/UserSettingsStorage.d.ts:29:5 - (ae-undocumented) Missing documentation for "forBucket". +// src/apis/StorageApi/UserSettingsStorage.d.ts:30:5 - (ae-undocumented) Missing documentation for "remove". +// src/apis/StorageApi/UserSettingsStorage.d.ts:31:5 - (ae-undocumented) Missing documentation for "set". +// src/apis/StorageApi/UserSettingsStorage.d.ts:32:5 - (ae-undocumented) Missing documentation for "observe$". +// src/apis/StorageApi/UserSettingsStorage.d.ts:33:5 - (ae-undocumented) Missing documentation for "snapshot". +// src/components/AuthProviders/DefaultProviderSettings.d.ts:3:22 - (ae-undocumented) Missing documentation for "DefaultProviderSettings". +// src/components/AuthProviders/ProviderSettingsItem.d.ts:4:22 - (ae-undocumented) Missing documentation for "ProviderSettingsItem". +// src/components/AuthProviders/UserSettingsAuthProviders.d.ts:3:22 - (ae-undocumented) Missing documentation for "UserSettingsAuthProviders". +// src/components/FeatureFlags/UserSettingsFeatureFlags.d.ts:5:22 - (ae-undocumented) Missing documentation for "UserSettingsFeatureFlags". +// src/components/General/UserSettingsAppearanceCard.d.ts:3:22 - (ae-undocumented) Missing documentation for "UserSettingsAppearanceCard". +// src/components/General/UserSettingsGeneral.d.ts:3:22 - (ae-undocumented) Missing documentation for "UserSettingsGeneral". +// src/components/General/UserSettingsIdentityCard.d.ts:3:22 - (ae-undocumented) Missing documentation for "UserSettingsIdentityCard". +// src/components/General/UserSettingsLanguageToggle.d.ts:3:22 - (ae-undocumented) Missing documentation for "UserSettingsLanguageToggle". +// src/components/General/UserSettingsMenu.d.ts:3:22 - (ae-undocumented) Missing documentation for "UserSettingsMenu". +// src/components/General/UserSettingsPinToggle.d.ts:3:22 - (ae-undocumented) Missing documentation for "UserSettingsPinToggle". +// src/components/General/UserSettingsProfileCard.d.ts:3:22 - (ae-undocumented) Missing documentation for "UserSettingsProfileCard". +// src/components/General/UserSettingsSignInAvatar.d.ts:3:22 - (ae-undocumented) Missing documentation for "UserSettingsSignInAvatar". +// src/components/General/UserSettingsThemeToggle.d.ts:3:22 - (ae-undocumented) Missing documentation for "UserSettingsThemeToggle". +// src/components/Settings.d.ts:4:22 - (ae-undocumented) Missing documentation for "Settings". +// src/components/SettingsLayout/SettingsLayout.d.ts:4:1 - (ae-undocumented) Missing documentation for "SettingsLayoutRouteProps". +// src/components/SettingsLayout/SettingsLayout.d.ts:15:1 - (ae-undocumented) Missing documentation for "SettingsLayoutProps". +// src/components/SettingsLayout/SettingsLayout.d.ts:23:22 - (ae-undocumented) Missing documentation for "SettingsLayout". +// src/components/SettingsPage/SettingsPage.d.ts:3:22 - (ae-undocumented) Missing documentation for "SettingsPage". +// src/components/UserSettingsTab/UserSettingsTab.d.ts:3:22 - (ae-undocumented) Missing documentation for "USER_SETTINGS_TAB_KEY". +// src/components/UserSettingsTab/UserSettingsTab.d.ts:5:1 - (ae-undocumented) Missing documentation for "UserSettingsTabProps". +// src/components/useUserProfileInfo.d.ts:3:22 - (ae-undocumented) Missing documentation for "useUserProfile". +// src/plugin.d.ts:4:22 - (ae-undocumented) Missing documentation for "userSettingsPlugin". +// src/plugin.d.ts:8:22 - (ae-undocumented) Missing documentation for "UserSettingsPage". ``` diff --git a/scripts/list-backend-feature.js b/scripts/list-backend-feature.js index 53cff217b1..91bce6852b 100644 --- a/scripts/list-backend-feature.js +++ b/scripts/list-backend-feature.js @@ -52,7 +52,7 @@ async function main(args) { backendFeatureReport.alpha = false; } - const apiReportAlphaPath = join(pkg.dir, 'api-report-alpha.md'); + const apiReportAlphaPath = join(pkg.dir, 'report-alpha.api.md'); if (fs.existsSync(apiReportAlphaPath)) { const apiReportAlpha = ( await fs.readFile(apiReportAlphaPath) diff --git a/scripts/pin-workspace-versions.js b/scripts/pin-workspace-versions.js new file mode 100755 index 0000000000..cbfb0c720b --- /dev/null +++ b/scripts/pin-workspace-versions.js @@ -0,0 +1,59 @@ +#!/usr/bin/env node +/* + * 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. + */ + +// This switches all `workspace:^` dependencies in the project to instead use `workspace:*` +// This is used for next releases in order to avoid the `^` range that is otherwise likely to cause issues. +// For example, a `^0.5.0-next.0` range will match `0.5.0-next.0`, `0.5.0-next.1`, and even `0.5.2`. +// This can often lead to issues as there might be breaking changes across these versions, and in practice +// it will only be possible to install the most recent release without a lot of hassle. + +const fs = require('fs-extra'); +const { getPackages } = require('@manypkg/get-packages'); +const { resolve } = require('path'); + +const depTypes = ['dependencies', 'devDependencies', 'peerDependencies']; + +async function main() { + const rootPath = resolve(__dirname, '..'); + const { packages } = await getPackages(rootPath); + + for (const pkg of packages) { + let changed = false; + for (const depType of depTypes) { + const deps = pkg.packageJson[depType]; + if (deps) { + for (const depName of Object.keys(deps)) { + if (deps[depName] === 'workspace:^') { + deps[depName] = 'workspace:*'; + changed = true; + } + } + } + } + + if (changed) { + await fs.writeJson(resolve(pkg.dir, 'package.json'), pkg.packageJson, { + spaces: 2, + }); + } + } +} + +main(process.argv.slice(2)).catch(error => { + console.error(error.stack || error); + process.exit(1); +}); diff --git a/storybook/yarn.lock b/storybook/yarn.lock index c5e39ebea7..55e44f3a8b 100644 --- a/storybook/yarn.lock +++ b/storybook/yarn.lock @@ -2849,92 +2849,92 @@ __metadata: languageName: node linkType: hard -"@swc/core-darwin-arm64@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-darwin-arm64@npm:1.5.29" +"@swc/core-darwin-arm64@npm:1.7.26": + version: 1.7.26 + resolution: "@swc/core-darwin-arm64@npm:1.7.26" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@swc/core-darwin-x64@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-darwin-x64@npm:1.5.29" +"@swc/core-darwin-x64@npm:1.7.26": + version: 1.7.26 + resolution: "@swc/core-darwin-x64@npm:1.7.26" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@swc/core-linux-arm-gnueabihf@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-linux-arm-gnueabihf@npm:1.5.29" +"@swc/core-linux-arm-gnueabihf@npm:1.7.26": + version: 1.7.26 + resolution: "@swc/core-linux-arm-gnueabihf@npm:1.7.26" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@swc/core-linux-arm64-gnu@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-linux-arm64-gnu@npm:1.5.29" +"@swc/core-linux-arm64-gnu@npm:1.7.26": + version: 1.7.26 + resolution: "@swc/core-linux-arm64-gnu@npm:1.7.26" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-arm64-musl@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-linux-arm64-musl@npm:1.5.29" +"@swc/core-linux-arm64-musl@npm:1.7.26": + version: 1.7.26 + resolution: "@swc/core-linux-arm64-musl@npm:1.7.26" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@swc/core-linux-x64-gnu@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-linux-x64-gnu@npm:1.5.29" +"@swc/core-linux-x64-gnu@npm:1.7.26": + version: 1.7.26 + resolution: "@swc/core-linux-x64-gnu@npm:1.7.26" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-x64-musl@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-linux-x64-musl@npm:1.5.29" +"@swc/core-linux-x64-musl@npm:1.7.26": + version: 1.7.26 + resolution: "@swc/core-linux-x64-musl@npm:1.7.26" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@swc/core-win32-arm64-msvc@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-win32-arm64-msvc@npm:1.5.29" +"@swc/core-win32-arm64-msvc@npm:1.7.26": + version: 1.7.26 + resolution: "@swc/core-win32-arm64-msvc@npm:1.7.26" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@swc/core-win32-ia32-msvc@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-win32-ia32-msvc@npm:1.5.29" +"@swc/core-win32-ia32-msvc@npm:1.7.26": + version: 1.7.26 + resolution: "@swc/core-win32-ia32-msvc@npm:1.7.26" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@swc/core-win32-x64-msvc@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-win32-x64-msvc@npm:1.5.29" +"@swc/core-win32-x64-msvc@npm:1.7.26": + version: 1.7.26 + resolution: "@swc/core-win32-x64-msvc@npm:1.7.26" conditions: os=win32 & cpu=x64 languageName: node linkType: hard "@swc/core@npm:^1.3.46": - version: 1.5.29 - resolution: "@swc/core@npm:1.5.29" + version: 1.7.26 + resolution: "@swc/core@npm:1.7.26" dependencies: - "@swc/core-darwin-arm64": 1.5.29 - "@swc/core-darwin-x64": 1.5.29 - "@swc/core-linux-arm-gnueabihf": 1.5.29 - "@swc/core-linux-arm64-gnu": 1.5.29 - "@swc/core-linux-arm64-musl": 1.5.29 - "@swc/core-linux-x64-gnu": 1.5.29 - "@swc/core-linux-x64-musl": 1.5.29 - "@swc/core-win32-arm64-msvc": 1.5.29 - "@swc/core-win32-ia32-msvc": 1.5.29 - "@swc/core-win32-x64-msvc": 1.5.29 + "@swc/core-darwin-arm64": 1.7.26 + "@swc/core-darwin-x64": 1.7.26 + "@swc/core-linux-arm-gnueabihf": 1.7.26 + "@swc/core-linux-arm64-gnu": 1.7.26 + "@swc/core-linux-arm64-musl": 1.7.26 + "@swc/core-linux-x64-gnu": 1.7.26 + "@swc/core-linux-x64-musl": 1.7.26 + "@swc/core-win32-arm64-msvc": 1.7.26 + "@swc/core-win32-ia32-msvc": 1.7.26 + "@swc/core-win32-x64-msvc": 1.7.26 "@swc/counter": ^0.1.3 - "@swc/types": ^0.1.8 + "@swc/types": ^0.1.12 peerDependencies: "@swc/helpers": "*" dependenciesMeta: @@ -2961,7 +2961,7 @@ __metadata: peerDependenciesMeta: "@swc/helpers": optional: true - checksum: 19e3f8525ce4f4d9f6f3f62825b1f13e1e76146390930b6d5e663c0bb2c5e95ef3bf30268110d1444ea92b99dd95bfe5a3c6e2a3c0dd79291505dc7da1ed3dab + checksum: 8249f2af001f2b5b312ccace4e3a8575bf286bb0f67f029eb58ef8b144f73e37f766800859161ef87c0993e586055238c000ab17dddf9d3760edcfa63ffd22e6 languageName: node linkType: hard @@ -2972,12 +2972,12 @@ __metadata: languageName: node linkType: hard -"@swc/types@npm:^0.1.8": - version: 0.1.8 - resolution: "@swc/types@npm:0.1.8" +"@swc/types@npm:^0.1.12": + version: 0.1.12 + resolution: "@swc/types@npm:0.1.12" dependencies: "@swc/counter": ^0.1.3 - checksum: e564d0e37b0e28546973c6d50c7a179395912a97168d695cfe9cf1051199c8b828680cdafcb8d43948f76d3703873bafb88dfb5bc2dfe0596b4ad18fcaf90c80 + checksum: cf7f89e46f859864075d7965582baea9c5f98830f45b1046251568c9bdf1ca484b1bf37f6d3c32b7c82ecf8cd5df89d22f05268c391819c44e49911bb1a8e71a languageName: node linkType: hard @@ -4085,9 +4085,9 @@ __metadata: languageName: node linkType: hard -"body-parser@npm:1.20.2": - version: 1.20.2 - resolution: "body-parser@npm:1.20.2" +"body-parser@npm:1.20.3": + version: 1.20.3 + resolution: "body-parser@npm:1.20.3" dependencies: bytes: 3.1.2 content-type: ~1.0.5 @@ -4097,11 +4097,11 @@ __metadata: http-errors: 2.0.0 iconv-lite: 0.4.24 on-finished: 2.4.1 - qs: 6.11.0 + qs: 6.13.0 raw-body: 2.5.2 type-is: ~1.6.18 unpipe: 1.0.0 - checksum: 14d37ec638ab5c93f6099ecaed7f28f890d222c650c69306872e00b9efa081ff6c596cd9afb9930656aae4d6c4e1c17537bea12bb73c87a217cb3cfea8896737 + checksum: 1a35c59a6be8d852b00946330141c4f142c6af0f970faa87f10ad74f1ee7118078056706a05ae3093c54dabca9cd3770fa62a170a85801da1a4324f04381167d languageName: node linkType: hard @@ -4316,13 +4316,16 @@ __metadata: languageName: node linkType: hard -"call-bind@npm:^1.0.0, call-bind@npm:^1.0.2": - version: 1.0.2 - resolution: "call-bind@npm:1.0.2" +"call-bind@npm:^1.0.2, call-bind@npm:^1.0.7": + version: 1.0.7 + resolution: "call-bind@npm:1.0.7" dependencies: - function-bind: ^1.1.1 - get-intrinsic: ^1.0.2 - checksum: f8e31de9d19988a4b80f3e704788c4a2d6b6f3d17cfec4f57dc29ced450c53a49270dc66bf0fbd693329ee948dd33e6c90a329519aef17474a4d961e8d6426b0 + es-define-property: ^1.0.0 + es-errors: ^1.3.0 + function-bind: ^1.1.2 + get-intrinsic: ^1.2.4 + set-function-length: ^1.2.1 + checksum: 295c0c62b90dd6522e6db3b0ab1ce26bdf9e7404215bda13cfee25b626b5ff1a7761324d58d38b1ef1607fc65aca2d06e44d2e18d0dfc6c14b465b00d8660029 languageName: node linkType: hard @@ -5059,6 +5062,17 @@ __metadata: languageName: node linkType: hard +"define-data-property@npm:^1.1.4": + version: 1.1.4 + resolution: "define-data-property@npm:1.1.4" + dependencies: + es-define-property: ^1.0.0 + es-errors: ^1.3.0 + gopd: ^1.0.1 + checksum: 8068ee6cab694d409ac25936eb861eea704b7763f7f342adbdfe337fc27c78d7ae0eff2364b2917b58c508d723c7a074326d068eef2e45c4edcd85cf94d0313b + languageName: node + linkType: hard + "define-lazy-prop@npm:^2.0.0": version: 2.0.0 resolution: "define-lazy-prop@npm:2.0.0" @@ -5326,6 +5340,13 @@ __metadata: languageName: node linkType: hard +"encodeurl@npm:~2.0.0": + version: 2.0.0 + resolution: "encodeurl@npm:2.0.0" + checksum: abf5cd51b78082cf8af7be6785813c33b6df2068ce5191a40ca8b1afe6a86f9230af9a9ce694a5ce4665955e5c1120871826df9c128a642e09c58d592e2807fe + languageName: node + linkType: hard + "encoding@npm:^0.1.13": version: 0.1.13 resolution: "encoding@npm:0.1.13" @@ -5444,6 +5465,22 @@ __metadata: languageName: node linkType: hard +"es-define-property@npm:^1.0.0": + version: 1.0.0 + resolution: "es-define-property@npm:1.0.0" + dependencies: + get-intrinsic: ^1.2.4 + checksum: f66ece0a887b6dca71848fa71f70461357c0e4e7249696f81bad0a1f347eed7b31262af4a29f5d726dc026426f085483b6b90301855e647aa8e21936f07293c6 + languageName: node + linkType: hard + +"es-errors@npm:^1.3.0": + version: 1.3.0 + resolution: "es-errors@npm:1.3.0" + checksum: ec1414527a0ccacd7f15f4a3bc66e215f04f595ba23ca75cdae0927af099b5ec865f9f4d33e9d7e86f512f252876ac77d4281a7871531a50678132429b1271b5 + languageName: node + linkType: hard + "es-get-iterator@npm:^1.0.2, es-get-iterator@npm:^1.1.3": version: 1.1.3 resolution: "es-get-iterator@npm:1.1.3" @@ -5650,41 +5687,41 @@ __metadata: linkType: hard "express@npm:^4.17.1": - version: 4.19.2 - resolution: "express@npm:4.19.2" + version: 4.21.0 + resolution: "express@npm:4.21.0" dependencies: accepts: ~1.3.8 array-flatten: 1.1.1 - body-parser: 1.20.2 + body-parser: 1.20.3 content-disposition: 0.5.4 content-type: ~1.0.4 cookie: 0.6.0 cookie-signature: 1.0.6 debug: 2.6.9 depd: 2.0.0 - encodeurl: ~1.0.2 + encodeurl: ~2.0.0 escape-html: ~1.0.3 etag: ~1.8.1 - finalhandler: 1.2.0 + finalhandler: 1.3.1 fresh: 0.5.2 http-errors: 2.0.0 - merge-descriptors: 1.0.1 + merge-descriptors: 1.0.3 methods: ~1.1.2 on-finished: 2.4.1 parseurl: ~1.3.3 - path-to-regexp: 0.1.7 + path-to-regexp: 0.1.10 proxy-addr: ~2.0.7 - qs: 6.11.0 + qs: 6.13.0 range-parser: ~1.2.1 safe-buffer: 5.2.1 - send: 0.18.0 - serve-static: 1.15.0 + send: 0.19.0 + serve-static: 1.16.2 setprototypeof: 1.2.0 statuses: 2.0.1 type-is: ~1.6.18 utils-merge: 1.0.1 vary: ~1.1.2 - checksum: 212dbd6c2c222a96a61bc927639c95970a53b06257080bb9e2838adb3bffdb966856551fdad1ab5dd654a217c35db94f987d0aa88d48fb04d306340f5f34dca5 + checksum: 1c5212993f665809c249bf00ab550b989d1365a5b9171cdfaa26d93ee2ef10cd8add520861ec8d5da74b3194d8374e1d9d53e85ef69b89fd9c4196b87045a5d4 languageName: node linkType: hard @@ -5853,18 +5890,18 @@ __metadata: languageName: node linkType: hard -"finalhandler@npm:1.2.0": - version: 1.2.0 - resolution: "finalhandler@npm:1.2.0" +"finalhandler@npm:1.3.1": + version: 1.3.1 + resolution: "finalhandler@npm:1.3.1" dependencies: debug: 2.6.9 - encodeurl: ~1.0.2 + encodeurl: ~2.0.0 escape-html: ~1.0.3 on-finished: 2.4.1 parseurl: ~1.3.3 statuses: 2.0.1 unpipe: ~1.0.0 - checksum: 92effbfd32e22a7dff2994acedbd9bcc3aa646a3e919ea6a53238090e87097f8ef07cced90aa2cc421abdf993aefbdd5b00104d55c7c5479a8d00ed105b45716 + checksum: a8c58cd97c9cd47679a870f6833a7b417043f5a288cd6af6d0f49b476c874a506100303a128b6d3b654c3d74fa4ff2ffed68a48a27e8630cda5c918f2977dcf4 languageName: node linkType: hard @@ -6124,10 +6161,10 @@ __metadata: languageName: node linkType: hard -"function-bind@npm:^1.1.1": - version: 1.1.1 - resolution: "function-bind@npm:1.1.1" - checksum: b32fbaebb3f8ec4969f033073b43f5c8befbb58f1a79e12f1d7490358150359ebd92f49e72ff0144f65f2c48ea2a605bff2d07965f548f6474fd8efd95bf361a +"function-bind@npm:^1.1.1, function-bind@npm:^1.1.2": + version: 1.1.2 + resolution: "function-bind@npm:1.1.2" + checksum: 2b0ff4ce708d99715ad14a6d1f894e2a83242e4a52ccfcefaee5e40050562e5f6dafc1adbb4ce2d4ab47279a45dc736ab91ea5042d843c3c092820dfe032efb1 languageName: node linkType: hard @@ -6197,15 +6234,16 @@ __metadata: languageName: node linkType: hard -"get-intrinsic@npm:^1.0.2, get-intrinsic@npm:^1.1.1, get-intrinsic@npm:^1.1.3, get-intrinsic@npm:^1.2.0": - version: 1.2.1 - resolution: "get-intrinsic@npm:1.2.1" +"get-intrinsic@npm:^1.1.1, get-intrinsic@npm:^1.1.3, get-intrinsic@npm:^1.2.0, get-intrinsic@npm:^1.2.4": + version: 1.2.4 + resolution: "get-intrinsic@npm:1.2.4" dependencies: - function-bind: ^1.1.1 - has: ^1.0.3 + es-errors: ^1.3.0 + function-bind: ^1.1.2 has-proto: ^1.0.1 has-symbols: ^1.0.3 - checksum: 5b61d88552c24b0cf6fa2d1b3bc5459d7306f699de060d76442cce49a4721f52b8c560a33ab392cf5575b7810277d54ded9d4d39a1ea61855619ebc005aa7e5f + hasown: ^2.0.0 + checksum: 414e3cdf2c203d1b9d7d33111df746a4512a1aa622770b361dadddf8ed0b5aeb26c560f49ca077e24bfafb0acb55ca908d1f709216ccba33ffc548ec8a79a951 languageName: node linkType: hard @@ -6431,12 +6469,12 @@ __metadata: languageName: node linkType: hard -"has-property-descriptors@npm:^1.0.0": - version: 1.0.0 - resolution: "has-property-descriptors@npm:1.0.0" +"has-property-descriptors@npm:^1.0.0, has-property-descriptors@npm:^1.0.2": + version: 1.0.2 + resolution: "has-property-descriptors@npm:1.0.2" dependencies: - get-intrinsic: ^1.1.1 - checksum: a6d3f0a266d0294d972e354782e872e2fe1b6495b321e6ef678c9b7a06a40408a6891817350c62e752adced73a94ac903c54734fee05bf65b1905ee1368194bb + es-define-property: ^1.0.0 + checksum: fcbb246ea2838058be39887935231c6d5788babed499d0e9d0cc5737494c48aba4fe17ba1449e0d0fbbb1e36175442faa37f9c427ae357d6ccb1d895fbcd3de3 languageName: node linkType: hard @@ -6518,6 +6556,15 @@ __metadata: languageName: node linkType: hard +"hasown@npm:^2.0.0": + version: 2.0.2 + resolution: "hasown@npm:2.0.2" + dependencies: + function-bind: ^1.1.2 + checksum: e8516f776a15149ca6c6ed2ae3110c417a00b62260e222590e54aa367cbcd6ed99122020b37b7fbdf05748df57b265e70095d7bf35a47660587619b15ffb93db + languageName: node + linkType: hard + "hast-to-hyperscript@npm:^9.0.0": version: 9.0.1 resolution: "hast-to-hyperscript@npm:9.0.1" @@ -8057,10 +8104,10 @@ __metadata: languageName: node linkType: hard -"merge-descriptors@npm:1.0.1": - version: 1.0.1 - resolution: "merge-descriptors@npm:1.0.1" - checksum: 5abc259d2ae25bb06d19ce2b94a21632583c74e2a9109ee1ba7fd147aa7362b380d971e0251069f8b3eb7d48c21ac839e21fa177b335e82c76ec172e30c31a26 +"merge-descriptors@npm:1.0.3": + version: 1.0.3 + resolution: "merge-descriptors@npm:1.0.3" + checksum: 52117adbe0313d5defa771c9993fe081e2d2df9b840597e966aadafde04ae8d0e3da46bac7ca4efc37d4d2b839436582659cd49c6a43eacb3fe3050896a105d1 languageName: node linkType: hard @@ -8560,10 +8607,10 @@ __metadata: languageName: node linkType: hard -"object-inspect@npm:^1.12.0, object-inspect@npm:^1.9.0": - version: 1.12.2 - resolution: "object-inspect@npm:1.12.2" - checksum: a534fc1b8534284ed71f25ce3a496013b7ea030f3d1b77118f6b7b1713829262be9e6243acbcb3ef8c626e2b64186112cb7f6db74e37b2789b9c789ca23048b2 +"object-inspect@npm:^1.12.0, object-inspect@npm:^1.13.1": + version: 1.13.2 + resolution: "object-inspect@npm:1.13.2" + checksum: 9f850b3c045db60e0e97746e809ee4090d6ce62195af17dd1e9438ac761394a7d8ec4f7906559aea5424eaf61e35d3e53feded2ccd5f62fcc7d9670d3c8eb353 languageName: node linkType: hard @@ -9012,10 +9059,10 @@ __metadata: languageName: node linkType: hard -"path-to-regexp@npm:0.1.7": - version: 0.1.7 - resolution: "path-to-regexp@npm:0.1.7" - checksum: 69a14ea24db543e8b0f4353305c5eac6907917031340e5a8b37df688e52accd09e3cebfe1660b70d76b6bd89152f52183f28c74813dbf454ba1a01c82a38abce +"path-to-regexp@npm:0.1.10": + version: 0.1.10 + resolution: "path-to-regexp@npm:0.1.10" + checksum: ab7a3b7a0b914476d44030340b0a65d69851af2a0f33427df1476100ccb87d409c39e2182837a96b98fb38c4ef2ba6b87bdad62bb70a2c153876b8061760583c languageName: node linkType: hard @@ -9489,12 +9536,12 @@ __metadata: languageName: node linkType: hard -"qs@npm:6.11.0, qs@npm:^6.10.0": - version: 6.11.0 - resolution: "qs@npm:6.11.0" +"qs@npm:6.13.0, qs@npm:^6.10.0": + version: 6.13.0 + resolution: "qs@npm:6.13.0" dependencies: - side-channel: ^1.0.4 - checksum: 6e1f29dd5385f7488ec74ac7b6c92f4d09a90408882d0c208414a34dd33badc1a621019d4c799a3df15ab9b1d0292f97c1dd71dc7c045e69f81a8064e5af7297 + side-channel: ^1.0.6 + checksum: e9404dc0fc2849245107108ce9ec2766cde3be1b271de0bf1021d049dc5b98d1a2901e67b431ac5509f865420a7ed80b7acb3980099fe1c118a1c5d2e1432ad8 languageName: node linkType: hard @@ -10240,9 +10287,9 @@ __metadata: languageName: node linkType: hard -"send@npm:0.18.0": - version: 0.18.0 - resolution: "send@npm:0.18.0" +"send@npm:0.19.0": + version: 0.19.0 + resolution: "send@npm:0.19.0" dependencies: debug: 2.6.9 depd: 2.0.0 @@ -10257,7 +10304,7 @@ __metadata: on-finished: 2.4.1 range-parser: ~1.2.1 statuses: 2.0.1 - checksum: 74fc07ebb58566b87b078ec63e5a3e41ecd987e4272ba67b7467e86c6ad51bc6b0b0154133b6d8b08a2ddda360464f71382f7ef864700f34844a76c8027817a8 + checksum: 5ae11bd900c1c2575525e2aa622e856804e2f96a09281ec1e39610d089f53aa69e13fd8db84b52f001d0318cf4bb0b3b904ad532fc4c0014eb90d32db0cff55f languageName: node linkType: hard @@ -10292,15 +10339,15 @@ __metadata: languageName: node linkType: hard -"serve-static@npm:1.15.0": - version: 1.15.0 - resolution: "serve-static@npm:1.15.0" +"serve-static@npm:1.16.2": + version: 1.16.2 + resolution: "serve-static@npm:1.16.2" dependencies: - encodeurl: ~1.0.2 + encodeurl: ~2.0.0 escape-html: ~1.0.3 parseurl: ~1.3.3 - send: 0.18.0 - checksum: af57fc13be40d90a12562e98c0b7855cf6e8bd4c107fe9a45c212bf023058d54a1871b1c89511c3958f70626fff47faeb795f5d83f8cf88514dbaeb2b724464d + send: 0.19.0 + checksum: dffc52feb4cc5c68e66d0c7f3c1824d4e989f71050aefc9bd5f822a42c54c9b814f595fc5f2b717f4c7cc05396145f3e90422af31186a93f76cf15f707019759 languageName: node linkType: hard @@ -10311,6 +10358,20 @@ __metadata: languageName: node linkType: hard +"set-function-length@npm:^1.2.1": + version: 1.2.2 + resolution: "set-function-length@npm:1.2.2" + dependencies: + define-data-property: ^1.1.4 + es-errors: ^1.3.0 + function-bind: ^1.1.2 + get-intrinsic: ^1.2.4 + gopd: ^1.0.1 + has-property-descriptors: ^1.0.2 + checksum: a8248bdacdf84cb0fab4637774d9fb3c7a8e6089866d04c817583ff48e14149c87044ce683d7f50759a8c50fb87c7a7e173535b06169c87ef76f5fb276dfff72 + languageName: node + linkType: hard + "set-value@npm:^2.0.0, set-value@npm:^2.0.1": version: 2.0.1 resolution: "set-value@npm:2.0.1" @@ -10362,14 +10423,15 @@ __metadata: languageName: node linkType: hard -"side-channel@npm:^1.0.4": - version: 1.0.4 - resolution: "side-channel@npm:1.0.4" +"side-channel@npm:^1.0.4, side-channel@npm:^1.0.6": + version: 1.0.6 + resolution: "side-channel@npm:1.0.6" dependencies: - call-bind: ^1.0.0 - get-intrinsic: ^1.0.2 - object-inspect: ^1.9.0 - checksum: 351e41b947079c10bd0858364f32bb3a7379514c399edb64ab3dce683933483fc63fb5e4efe0a15a2e8a7e3c436b6a91736ddb8d8c6591b0460a24bb4a1ee245 + call-bind: ^1.0.7 + es-errors: ^1.3.0 + get-intrinsic: ^1.2.4 + object-inspect: ^1.13.1 + checksum: bfc1afc1827d712271453e91b7cd3878ac0efd767495fd4e594c4c2afaa7963b7b510e249572bfd54b0527e66e4a12b61b80c061389e129755f34c493aad9b97 languageName: node linkType: hard diff --git a/yarn.lock b/yarn.lock index db656c9978..6189cb8e21 100644 --- a/yarn.lock +++ b/yarn.lock @@ -500,678 +500,678 @@ __metadata: linkType: hard "@aws-sdk/client-codecommit@npm:^3.350.0": - version: 3.637.0 - resolution: "@aws-sdk/client-codecommit@npm:3.637.0" + version: 3.651.1 + resolution: "@aws-sdk/client-codecommit@npm:3.651.1" dependencies: "@aws-crypto/sha256-browser": 5.2.0 "@aws-crypto/sha256-js": 5.2.0 - "@aws-sdk/client-sso-oidc": 3.637.0 - "@aws-sdk/client-sts": 3.637.0 - "@aws-sdk/core": 3.635.0 - "@aws-sdk/credential-provider-node": 3.637.0 - "@aws-sdk/middleware-host-header": 3.620.0 - "@aws-sdk/middleware-logger": 3.609.0 - "@aws-sdk/middleware-recursion-detection": 3.620.0 - "@aws-sdk/middleware-user-agent": 3.637.0 - "@aws-sdk/region-config-resolver": 3.614.0 - "@aws-sdk/types": 3.609.0 - "@aws-sdk/util-endpoints": 3.637.0 - "@aws-sdk/util-user-agent-browser": 3.609.0 - "@aws-sdk/util-user-agent-node": 3.614.0 - "@smithy/config-resolver": ^3.0.5 - "@smithy/core": ^2.4.0 - "@smithy/fetch-http-handler": ^3.2.4 - "@smithy/hash-node": ^3.0.3 - "@smithy/invalid-dependency": ^3.0.3 - "@smithy/middleware-content-length": ^3.0.5 - "@smithy/middleware-endpoint": ^3.1.0 - "@smithy/middleware-retry": ^3.0.15 - "@smithy/middleware-serde": ^3.0.3 - "@smithy/middleware-stack": ^3.0.3 - "@smithy/node-config-provider": ^3.1.4 - "@smithy/node-http-handler": ^3.1.4 - "@smithy/protocol-http": ^4.1.0 - "@smithy/smithy-client": ^3.2.0 - "@smithy/types": ^3.3.0 - "@smithy/url-parser": ^3.0.3 + "@aws-sdk/client-sso-oidc": 3.651.1 + "@aws-sdk/client-sts": 3.651.1 + "@aws-sdk/core": 3.651.1 + "@aws-sdk/credential-provider-node": 3.651.1 + "@aws-sdk/middleware-host-header": 3.649.0 + "@aws-sdk/middleware-logger": 3.649.0 + "@aws-sdk/middleware-recursion-detection": 3.649.0 + "@aws-sdk/middleware-user-agent": 3.649.0 + "@aws-sdk/region-config-resolver": 3.649.0 + "@aws-sdk/types": 3.649.0 + "@aws-sdk/util-endpoints": 3.649.0 + "@aws-sdk/util-user-agent-browser": 3.649.0 + "@aws-sdk/util-user-agent-node": 3.649.0 + "@smithy/config-resolver": ^3.0.6 + "@smithy/core": ^2.4.1 + "@smithy/fetch-http-handler": ^3.2.5 + "@smithy/hash-node": ^3.0.4 + "@smithy/invalid-dependency": ^3.0.4 + "@smithy/middleware-content-length": ^3.0.6 + "@smithy/middleware-endpoint": ^3.1.1 + "@smithy/middleware-retry": ^3.0.16 + "@smithy/middleware-serde": ^3.0.4 + "@smithy/middleware-stack": ^3.0.4 + "@smithy/node-config-provider": ^3.1.5 + "@smithy/node-http-handler": ^3.2.0 + "@smithy/protocol-http": ^4.1.1 + "@smithy/smithy-client": ^3.3.0 + "@smithy/types": ^3.4.0 + "@smithy/url-parser": ^3.0.4 "@smithy/util-base64": ^3.0.0 "@smithy/util-body-length-browser": ^3.0.0 "@smithy/util-body-length-node": ^3.0.0 - "@smithy/util-defaults-mode-browser": ^3.0.15 - "@smithy/util-defaults-mode-node": ^3.0.15 - "@smithy/util-endpoints": ^2.0.5 - "@smithy/util-middleware": ^3.0.3 - "@smithy/util-retry": ^3.0.3 + "@smithy/util-defaults-mode-browser": ^3.0.16 + "@smithy/util-defaults-mode-node": ^3.0.16 + "@smithy/util-endpoints": ^2.1.0 + "@smithy/util-middleware": ^3.0.4 + "@smithy/util-retry": ^3.0.4 "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 uuid: ^9.0.1 - checksum: 25b9ac4e58e6d6a5ca1062253ecfee723ed7f54058f4c2f7f9c1a6af56b65de27f5c0c3a46870a0f5e652576719ed6f332a9dd5cfd5ceed451586f04a088995d + checksum: 8cfcbc721c4a2250837e47d807049eb04e1bcb4c783c9ce9daeef33a9e6d0383295edb4c7eabb37e7197c4814203febbd429a6962e7f4a692de5385d476fe97d languageName: node linkType: hard -"@aws-sdk/client-cognito-identity@npm:3.637.0": - version: 3.637.0 - resolution: "@aws-sdk/client-cognito-identity@npm:3.637.0" +"@aws-sdk/client-cognito-identity@npm:3.651.1": + version: 3.651.1 + resolution: "@aws-sdk/client-cognito-identity@npm:3.651.1" dependencies: "@aws-crypto/sha256-browser": 5.2.0 "@aws-crypto/sha256-js": 5.2.0 - "@aws-sdk/client-sso-oidc": 3.637.0 - "@aws-sdk/client-sts": 3.637.0 - "@aws-sdk/core": 3.635.0 - "@aws-sdk/credential-provider-node": 3.637.0 - "@aws-sdk/middleware-host-header": 3.620.0 - "@aws-sdk/middleware-logger": 3.609.0 - "@aws-sdk/middleware-recursion-detection": 3.620.0 - "@aws-sdk/middleware-user-agent": 3.637.0 - "@aws-sdk/region-config-resolver": 3.614.0 - "@aws-sdk/types": 3.609.0 - "@aws-sdk/util-endpoints": 3.637.0 - "@aws-sdk/util-user-agent-browser": 3.609.0 - "@aws-sdk/util-user-agent-node": 3.614.0 - "@smithy/config-resolver": ^3.0.5 - "@smithy/core": ^2.4.0 - "@smithy/fetch-http-handler": ^3.2.4 - "@smithy/hash-node": ^3.0.3 - "@smithy/invalid-dependency": ^3.0.3 - "@smithy/middleware-content-length": ^3.0.5 - "@smithy/middleware-endpoint": ^3.1.0 - "@smithy/middleware-retry": ^3.0.15 - "@smithy/middleware-serde": ^3.0.3 - "@smithy/middleware-stack": ^3.0.3 - "@smithy/node-config-provider": ^3.1.4 - "@smithy/node-http-handler": ^3.1.4 - "@smithy/protocol-http": ^4.1.0 - "@smithy/smithy-client": ^3.2.0 - "@smithy/types": ^3.3.0 - "@smithy/url-parser": ^3.0.3 + "@aws-sdk/client-sso-oidc": 3.651.1 + "@aws-sdk/client-sts": 3.651.1 + "@aws-sdk/core": 3.651.1 + "@aws-sdk/credential-provider-node": 3.651.1 + "@aws-sdk/middleware-host-header": 3.649.0 + "@aws-sdk/middleware-logger": 3.649.0 + "@aws-sdk/middleware-recursion-detection": 3.649.0 + "@aws-sdk/middleware-user-agent": 3.649.0 + "@aws-sdk/region-config-resolver": 3.649.0 + "@aws-sdk/types": 3.649.0 + "@aws-sdk/util-endpoints": 3.649.0 + "@aws-sdk/util-user-agent-browser": 3.649.0 + "@aws-sdk/util-user-agent-node": 3.649.0 + "@smithy/config-resolver": ^3.0.6 + "@smithy/core": ^2.4.1 + "@smithy/fetch-http-handler": ^3.2.5 + "@smithy/hash-node": ^3.0.4 + "@smithy/invalid-dependency": ^3.0.4 + "@smithy/middleware-content-length": ^3.0.6 + "@smithy/middleware-endpoint": ^3.1.1 + "@smithy/middleware-retry": ^3.0.16 + "@smithy/middleware-serde": ^3.0.4 + "@smithy/middleware-stack": ^3.0.4 + "@smithy/node-config-provider": ^3.1.5 + "@smithy/node-http-handler": ^3.2.0 + "@smithy/protocol-http": ^4.1.1 + "@smithy/smithy-client": ^3.3.0 + "@smithy/types": ^3.4.0 + "@smithy/url-parser": ^3.0.4 "@smithy/util-base64": ^3.0.0 "@smithy/util-body-length-browser": ^3.0.0 "@smithy/util-body-length-node": ^3.0.0 - "@smithy/util-defaults-mode-browser": ^3.0.15 - "@smithy/util-defaults-mode-node": ^3.0.15 - "@smithy/util-endpoints": ^2.0.5 - "@smithy/util-middleware": ^3.0.3 - "@smithy/util-retry": ^3.0.3 + "@smithy/util-defaults-mode-browser": ^3.0.16 + "@smithy/util-defaults-mode-node": ^3.0.16 + "@smithy/util-endpoints": ^2.1.0 + "@smithy/util-middleware": ^3.0.4 + "@smithy/util-retry": ^3.0.4 "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: cfb3b3926012340c36dcc839e529f19e31addb0566e6da49f4928510d4b683aeb2b2926576f9013442ca862d48638316b3e7f9c9737149f276b5d5d0ac5eb3d0 + checksum: 0598551e6813e71264bf42376401bfa0c699029e5538555976111746e23ca642aa274e5f5e3db7e032f2213d8407310ef716639b619a65e4a1c1bf7e1314cce3 languageName: node linkType: hard "@aws-sdk/client-eks@npm:^3.350.0": - version: 3.637.0 - resolution: "@aws-sdk/client-eks@npm:3.637.0" + version: 3.651.1 + resolution: "@aws-sdk/client-eks@npm:3.651.1" dependencies: "@aws-crypto/sha256-browser": 5.2.0 "@aws-crypto/sha256-js": 5.2.0 - "@aws-sdk/client-sso-oidc": 3.637.0 - "@aws-sdk/client-sts": 3.637.0 - "@aws-sdk/core": 3.635.0 - "@aws-sdk/credential-provider-node": 3.637.0 - "@aws-sdk/middleware-host-header": 3.620.0 - "@aws-sdk/middleware-logger": 3.609.0 - "@aws-sdk/middleware-recursion-detection": 3.620.0 - "@aws-sdk/middleware-user-agent": 3.637.0 - "@aws-sdk/region-config-resolver": 3.614.0 - "@aws-sdk/types": 3.609.0 - "@aws-sdk/util-endpoints": 3.637.0 - "@aws-sdk/util-user-agent-browser": 3.609.0 - "@aws-sdk/util-user-agent-node": 3.614.0 - "@smithy/config-resolver": ^3.0.5 - "@smithy/core": ^2.4.0 - "@smithy/fetch-http-handler": ^3.2.4 - "@smithy/hash-node": ^3.0.3 - "@smithy/invalid-dependency": ^3.0.3 - "@smithy/middleware-content-length": ^3.0.5 - "@smithy/middleware-endpoint": ^3.1.0 - "@smithy/middleware-retry": ^3.0.15 - "@smithy/middleware-serde": ^3.0.3 - "@smithy/middleware-stack": ^3.0.3 - "@smithy/node-config-provider": ^3.1.4 - "@smithy/node-http-handler": ^3.1.4 - "@smithy/protocol-http": ^4.1.0 - "@smithy/smithy-client": ^3.2.0 - "@smithy/types": ^3.3.0 - "@smithy/url-parser": ^3.0.3 + "@aws-sdk/client-sso-oidc": 3.651.1 + "@aws-sdk/client-sts": 3.651.1 + "@aws-sdk/core": 3.651.1 + "@aws-sdk/credential-provider-node": 3.651.1 + "@aws-sdk/middleware-host-header": 3.649.0 + "@aws-sdk/middleware-logger": 3.649.0 + "@aws-sdk/middleware-recursion-detection": 3.649.0 + "@aws-sdk/middleware-user-agent": 3.649.0 + "@aws-sdk/region-config-resolver": 3.649.0 + "@aws-sdk/types": 3.649.0 + "@aws-sdk/util-endpoints": 3.649.0 + "@aws-sdk/util-user-agent-browser": 3.649.0 + "@aws-sdk/util-user-agent-node": 3.649.0 + "@smithy/config-resolver": ^3.0.6 + "@smithy/core": ^2.4.1 + "@smithy/fetch-http-handler": ^3.2.5 + "@smithy/hash-node": ^3.0.4 + "@smithy/invalid-dependency": ^3.0.4 + "@smithy/middleware-content-length": ^3.0.6 + "@smithy/middleware-endpoint": ^3.1.1 + "@smithy/middleware-retry": ^3.0.16 + "@smithy/middleware-serde": ^3.0.4 + "@smithy/middleware-stack": ^3.0.4 + "@smithy/node-config-provider": ^3.1.5 + "@smithy/node-http-handler": ^3.2.0 + "@smithy/protocol-http": ^4.1.1 + "@smithy/smithy-client": ^3.3.0 + "@smithy/types": ^3.4.0 + "@smithy/url-parser": ^3.0.4 "@smithy/util-base64": ^3.0.0 "@smithy/util-body-length-browser": ^3.0.0 "@smithy/util-body-length-node": ^3.0.0 - "@smithy/util-defaults-mode-browser": ^3.0.15 - "@smithy/util-defaults-mode-node": ^3.0.15 - "@smithy/util-endpoints": ^2.0.5 - "@smithy/util-middleware": ^3.0.3 - "@smithy/util-retry": ^3.0.3 + "@smithy/util-defaults-mode-browser": ^3.0.16 + "@smithy/util-defaults-mode-node": ^3.0.16 + "@smithy/util-endpoints": ^2.1.0 + "@smithy/util-middleware": ^3.0.4 + "@smithy/util-retry": ^3.0.4 "@smithy/util-utf8": ^3.0.0 - "@smithy/util-waiter": ^3.1.2 + "@smithy/util-waiter": ^3.1.3 tslib: ^2.6.2 uuid: ^9.0.1 - checksum: 7c2f318d7b5a647c7c993ae6ae9468ed9c4d3a99b7a92035f8f3e17770025d7c80486abd56f29f018d088376ea8035beb36fec8cd9b3e30aade1bad3061cab64 + checksum: da5d256712ece4391b9695b03b15df1b1e671bf13a5d9eea95be61fbc133040ba47fc781fceae243c3f6c6ff08f17217d03498abff81bb68c5f93c773dcec89d languageName: node linkType: hard "@aws-sdk/client-organizations@npm:^3.350.0": - version: 3.638.0 - resolution: "@aws-sdk/client-organizations@npm:3.638.0" + version: 3.652.0 + resolution: "@aws-sdk/client-organizations@npm:3.652.0" dependencies: "@aws-crypto/sha256-browser": 5.2.0 "@aws-crypto/sha256-js": 5.2.0 - "@aws-sdk/client-sso-oidc": 3.637.0 - "@aws-sdk/client-sts": 3.637.0 - "@aws-sdk/core": 3.635.0 - "@aws-sdk/credential-provider-node": 3.637.0 - "@aws-sdk/middleware-host-header": 3.620.0 - "@aws-sdk/middleware-logger": 3.609.0 - "@aws-sdk/middleware-recursion-detection": 3.620.0 - "@aws-sdk/middleware-user-agent": 3.637.0 - "@aws-sdk/region-config-resolver": 3.614.0 - "@aws-sdk/types": 3.609.0 - "@aws-sdk/util-endpoints": 3.637.0 - "@aws-sdk/util-user-agent-browser": 3.609.0 - "@aws-sdk/util-user-agent-node": 3.614.0 - "@smithy/config-resolver": ^3.0.5 - "@smithy/core": ^2.4.0 - "@smithy/fetch-http-handler": ^3.2.4 - "@smithy/hash-node": ^3.0.3 - "@smithy/invalid-dependency": ^3.0.3 - "@smithy/middleware-content-length": ^3.0.5 - "@smithy/middleware-endpoint": ^3.1.0 - "@smithy/middleware-retry": ^3.0.15 - "@smithy/middleware-serde": ^3.0.3 - "@smithy/middleware-stack": ^3.0.3 - "@smithy/node-config-provider": ^3.1.4 - "@smithy/node-http-handler": ^3.1.4 - "@smithy/protocol-http": ^4.1.0 - "@smithy/smithy-client": ^3.2.0 - "@smithy/types": ^3.3.0 - "@smithy/url-parser": ^3.0.3 + "@aws-sdk/client-sso-oidc": 3.651.1 + "@aws-sdk/client-sts": 3.651.1 + "@aws-sdk/core": 3.651.1 + "@aws-sdk/credential-provider-node": 3.651.1 + "@aws-sdk/middleware-host-header": 3.649.0 + "@aws-sdk/middleware-logger": 3.649.0 + "@aws-sdk/middleware-recursion-detection": 3.649.0 + "@aws-sdk/middleware-user-agent": 3.649.0 + "@aws-sdk/region-config-resolver": 3.649.0 + "@aws-sdk/types": 3.649.0 + "@aws-sdk/util-endpoints": 3.649.0 + "@aws-sdk/util-user-agent-browser": 3.649.0 + "@aws-sdk/util-user-agent-node": 3.649.0 + "@smithy/config-resolver": ^3.0.6 + "@smithy/core": ^2.4.1 + "@smithy/fetch-http-handler": ^3.2.5 + "@smithy/hash-node": ^3.0.4 + "@smithy/invalid-dependency": ^3.0.4 + "@smithy/middleware-content-length": ^3.0.6 + "@smithy/middleware-endpoint": ^3.1.1 + "@smithy/middleware-retry": ^3.0.16 + "@smithy/middleware-serde": ^3.0.4 + "@smithy/middleware-stack": ^3.0.4 + "@smithy/node-config-provider": ^3.1.5 + "@smithy/node-http-handler": ^3.2.0 + "@smithy/protocol-http": ^4.1.1 + "@smithy/smithy-client": ^3.3.0 + "@smithy/types": ^3.4.0 + "@smithy/url-parser": ^3.0.4 "@smithy/util-base64": ^3.0.0 "@smithy/util-body-length-browser": ^3.0.0 "@smithy/util-body-length-node": ^3.0.0 - "@smithy/util-defaults-mode-browser": ^3.0.15 - "@smithy/util-defaults-mode-node": ^3.0.15 - "@smithy/util-endpoints": ^2.0.5 - "@smithy/util-middleware": ^3.0.3 - "@smithy/util-retry": ^3.0.3 + "@smithy/util-defaults-mode-browser": ^3.0.16 + "@smithy/util-defaults-mode-node": ^3.0.16 + "@smithy/util-endpoints": ^2.1.0 + "@smithy/util-middleware": ^3.0.4 + "@smithy/util-retry": ^3.0.4 "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: 91340539b3b272545b3d9ca389144f8e5640fcd8bc14ff6b0670a3614fc29e36e577f14384f61996bdd83c380dc7e167baeea8445d93ff3271198db8f0a8646a + checksum: 14353fe127d2f0aae4c13bbecc425d12c0237d4e766a6f6657a0798d95cbeec181188acb3cd12e694bbf46a926d5f0fda9d512a5595ab3af843e9307a74478cc languageName: node linkType: hard "@aws-sdk/client-s3@npm:^3.350.0": - version: 3.637.0 - resolution: "@aws-sdk/client-s3@npm:3.637.0" + version: 3.651.1 + resolution: "@aws-sdk/client-s3@npm:3.651.1" dependencies: "@aws-crypto/sha1-browser": 5.2.0 "@aws-crypto/sha256-browser": 5.2.0 "@aws-crypto/sha256-js": 5.2.0 - "@aws-sdk/client-sso-oidc": 3.637.0 - "@aws-sdk/client-sts": 3.637.0 - "@aws-sdk/core": 3.635.0 - "@aws-sdk/credential-provider-node": 3.637.0 - "@aws-sdk/middleware-bucket-endpoint": 3.620.0 - "@aws-sdk/middleware-expect-continue": 3.620.0 - "@aws-sdk/middleware-flexible-checksums": 3.620.0 - "@aws-sdk/middleware-host-header": 3.620.0 - "@aws-sdk/middleware-location-constraint": 3.609.0 - "@aws-sdk/middleware-logger": 3.609.0 - "@aws-sdk/middleware-recursion-detection": 3.620.0 - "@aws-sdk/middleware-sdk-s3": 3.635.0 - "@aws-sdk/middleware-ssec": 3.609.0 - "@aws-sdk/middleware-user-agent": 3.637.0 - "@aws-sdk/region-config-resolver": 3.614.0 - "@aws-sdk/signature-v4-multi-region": 3.635.0 - "@aws-sdk/types": 3.609.0 - "@aws-sdk/util-endpoints": 3.637.0 - "@aws-sdk/util-user-agent-browser": 3.609.0 - "@aws-sdk/util-user-agent-node": 3.614.0 - "@aws-sdk/xml-builder": 3.609.0 - "@smithy/config-resolver": ^3.0.5 - "@smithy/core": ^2.4.0 - "@smithy/eventstream-serde-browser": ^3.0.6 - "@smithy/eventstream-serde-config-resolver": ^3.0.3 - "@smithy/eventstream-serde-node": ^3.0.5 - "@smithy/fetch-http-handler": ^3.2.4 - "@smithy/hash-blob-browser": ^3.1.2 - "@smithy/hash-node": ^3.0.3 - "@smithy/hash-stream-node": ^3.1.2 - "@smithy/invalid-dependency": ^3.0.3 - "@smithy/md5-js": ^3.0.3 - "@smithy/middleware-content-length": ^3.0.5 - "@smithy/middleware-endpoint": ^3.1.0 - "@smithy/middleware-retry": ^3.0.15 - "@smithy/middleware-serde": ^3.0.3 - "@smithy/middleware-stack": ^3.0.3 - "@smithy/node-config-provider": ^3.1.4 - "@smithy/node-http-handler": ^3.1.4 - "@smithy/protocol-http": ^4.1.0 - "@smithy/smithy-client": ^3.2.0 - "@smithy/types": ^3.3.0 - "@smithy/url-parser": ^3.0.3 + "@aws-sdk/client-sso-oidc": 3.651.1 + "@aws-sdk/client-sts": 3.651.1 + "@aws-sdk/core": 3.651.1 + "@aws-sdk/credential-provider-node": 3.651.1 + "@aws-sdk/middleware-bucket-endpoint": 3.649.0 + "@aws-sdk/middleware-expect-continue": 3.649.0 + "@aws-sdk/middleware-flexible-checksums": 3.651.1 + "@aws-sdk/middleware-host-header": 3.649.0 + "@aws-sdk/middleware-location-constraint": 3.649.0 + "@aws-sdk/middleware-logger": 3.649.0 + "@aws-sdk/middleware-recursion-detection": 3.649.0 + "@aws-sdk/middleware-sdk-s3": 3.651.1 + "@aws-sdk/middleware-ssec": 3.649.0 + "@aws-sdk/middleware-user-agent": 3.649.0 + "@aws-sdk/region-config-resolver": 3.649.0 + "@aws-sdk/signature-v4-multi-region": 3.651.1 + "@aws-sdk/types": 3.649.0 + "@aws-sdk/util-endpoints": 3.649.0 + "@aws-sdk/util-user-agent-browser": 3.649.0 + "@aws-sdk/util-user-agent-node": 3.649.0 + "@aws-sdk/xml-builder": 3.649.0 + "@smithy/config-resolver": ^3.0.6 + "@smithy/core": ^2.4.1 + "@smithy/eventstream-serde-browser": ^3.0.7 + "@smithy/eventstream-serde-config-resolver": ^3.0.4 + "@smithy/eventstream-serde-node": ^3.0.6 + "@smithy/fetch-http-handler": ^3.2.5 + "@smithy/hash-blob-browser": ^3.1.3 + "@smithy/hash-node": ^3.0.4 + "@smithy/hash-stream-node": ^3.1.3 + "@smithy/invalid-dependency": ^3.0.4 + "@smithy/md5-js": ^3.0.4 + "@smithy/middleware-content-length": ^3.0.6 + "@smithy/middleware-endpoint": ^3.1.1 + "@smithy/middleware-retry": ^3.0.16 + "@smithy/middleware-serde": ^3.0.4 + "@smithy/middleware-stack": ^3.0.4 + "@smithy/node-config-provider": ^3.1.5 + "@smithy/node-http-handler": ^3.2.0 + "@smithy/protocol-http": ^4.1.1 + "@smithy/smithy-client": ^3.3.0 + "@smithy/types": ^3.4.0 + "@smithy/url-parser": ^3.0.4 "@smithy/util-base64": ^3.0.0 "@smithy/util-body-length-browser": ^3.0.0 "@smithy/util-body-length-node": ^3.0.0 - "@smithy/util-defaults-mode-browser": ^3.0.15 - "@smithy/util-defaults-mode-node": ^3.0.15 - "@smithy/util-endpoints": ^2.0.5 - "@smithy/util-middleware": ^3.0.3 - "@smithy/util-retry": ^3.0.3 - "@smithy/util-stream": ^3.1.3 + "@smithy/util-defaults-mode-browser": ^3.0.16 + "@smithy/util-defaults-mode-node": ^3.0.16 + "@smithy/util-endpoints": ^2.1.0 + "@smithy/util-middleware": ^3.0.4 + "@smithy/util-retry": ^3.0.4 + "@smithy/util-stream": ^3.1.4 "@smithy/util-utf8": ^3.0.0 - "@smithy/util-waiter": ^3.1.2 + "@smithy/util-waiter": ^3.1.3 tslib: ^2.6.2 - checksum: 244e8de633ffb291c6e9a3dc952727cc71022b81690292d3eacf719d8b395342b9912a0710c2172cf8b986b5d58ca5c40970b69e0148a881453a48c604276cb4 + checksum: 91276e10ddcf435c0dd5f1d6d507528d3b07d1f1cfbbc78518e534a6c725f89941c12495b51b8897ec3f36a1b699ff0b6f4d4b989376b11b831cfcd96382c886 languageName: node linkType: hard "@aws-sdk/client-ses@npm:^3.550.0": - version: 3.637.0 - resolution: "@aws-sdk/client-ses@npm:3.637.0" + version: 3.651.1 + resolution: "@aws-sdk/client-ses@npm:3.651.1" dependencies: "@aws-crypto/sha256-browser": 5.2.0 "@aws-crypto/sha256-js": 5.2.0 - "@aws-sdk/client-sso-oidc": 3.637.0 - "@aws-sdk/client-sts": 3.637.0 - "@aws-sdk/core": 3.635.0 - "@aws-sdk/credential-provider-node": 3.637.0 - "@aws-sdk/middleware-host-header": 3.620.0 - "@aws-sdk/middleware-logger": 3.609.0 - "@aws-sdk/middleware-recursion-detection": 3.620.0 - "@aws-sdk/middleware-user-agent": 3.637.0 - "@aws-sdk/region-config-resolver": 3.614.0 - "@aws-sdk/types": 3.609.0 - "@aws-sdk/util-endpoints": 3.637.0 - "@aws-sdk/util-user-agent-browser": 3.609.0 - "@aws-sdk/util-user-agent-node": 3.614.0 - "@smithy/config-resolver": ^3.0.5 - "@smithy/core": ^2.4.0 - "@smithy/fetch-http-handler": ^3.2.4 - "@smithy/hash-node": ^3.0.3 - "@smithy/invalid-dependency": ^3.0.3 - "@smithy/middleware-content-length": ^3.0.5 - "@smithy/middleware-endpoint": ^3.1.0 - "@smithy/middleware-retry": ^3.0.15 - "@smithy/middleware-serde": ^3.0.3 - "@smithy/middleware-stack": ^3.0.3 - "@smithy/node-config-provider": ^3.1.4 - "@smithy/node-http-handler": ^3.1.4 - "@smithy/protocol-http": ^4.1.0 - "@smithy/smithy-client": ^3.2.0 - "@smithy/types": ^3.3.0 - "@smithy/url-parser": ^3.0.3 + "@aws-sdk/client-sso-oidc": 3.651.1 + "@aws-sdk/client-sts": 3.651.1 + "@aws-sdk/core": 3.651.1 + "@aws-sdk/credential-provider-node": 3.651.1 + "@aws-sdk/middleware-host-header": 3.649.0 + "@aws-sdk/middleware-logger": 3.649.0 + "@aws-sdk/middleware-recursion-detection": 3.649.0 + "@aws-sdk/middleware-user-agent": 3.649.0 + "@aws-sdk/region-config-resolver": 3.649.0 + "@aws-sdk/types": 3.649.0 + "@aws-sdk/util-endpoints": 3.649.0 + "@aws-sdk/util-user-agent-browser": 3.649.0 + "@aws-sdk/util-user-agent-node": 3.649.0 + "@smithy/config-resolver": ^3.0.6 + "@smithy/core": ^2.4.1 + "@smithy/fetch-http-handler": ^3.2.5 + "@smithy/hash-node": ^3.0.4 + "@smithy/invalid-dependency": ^3.0.4 + "@smithy/middleware-content-length": ^3.0.6 + "@smithy/middleware-endpoint": ^3.1.1 + "@smithy/middleware-retry": ^3.0.16 + "@smithy/middleware-serde": ^3.0.4 + "@smithy/middleware-stack": ^3.0.4 + "@smithy/node-config-provider": ^3.1.5 + "@smithy/node-http-handler": ^3.2.0 + "@smithy/protocol-http": ^4.1.1 + "@smithy/smithy-client": ^3.3.0 + "@smithy/types": ^3.4.0 + "@smithy/url-parser": ^3.0.4 "@smithy/util-base64": ^3.0.0 "@smithy/util-body-length-browser": ^3.0.0 "@smithy/util-body-length-node": ^3.0.0 - "@smithy/util-defaults-mode-browser": ^3.0.15 - "@smithy/util-defaults-mode-node": ^3.0.15 - "@smithy/util-endpoints": ^2.0.5 - "@smithy/util-middleware": ^3.0.3 - "@smithy/util-retry": ^3.0.3 + "@smithy/util-defaults-mode-browser": ^3.0.16 + "@smithy/util-defaults-mode-node": ^3.0.16 + "@smithy/util-endpoints": ^2.1.0 + "@smithy/util-middleware": ^3.0.4 + "@smithy/util-retry": ^3.0.4 "@smithy/util-utf8": ^3.0.0 - "@smithy/util-waiter": ^3.1.2 + "@smithy/util-waiter": ^3.1.3 tslib: ^2.6.2 - checksum: 4ab9ae76590cdac74e5cc8f3ced77c40df741d7f31a7ac7ac24a72493e5199ce808a66824a787196deb546f6bd3a39e9e2612618b219698a6268418ef3d8e5f6 + checksum: be5aaf43f95f2975bd8efecb2966d2a7315c9c146f8d9d1f852ee62826e7d96b67330e86f967dcd4263c3d9459705439525a7b1501ce691c3b140dac48036ca8 languageName: node linkType: hard "@aws-sdk/client-sqs@npm:^3.350.0": - version: 3.637.0 - resolution: "@aws-sdk/client-sqs@npm:3.637.0" + version: 3.651.1 + resolution: "@aws-sdk/client-sqs@npm:3.651.1" dependencies: "@aws-crypto/sha256-browser": 5.2.0 "@aws-crypto/sha256-js": 5.2.0 - "@aws-sdk/client-sso-oidc": 3.637.0 - "@aws-sdk/client-sts": 3.637.0 - "@aws-sdk/core": 3.635.0 - "@aws-sdk/credential-provider-node": 3.637.0 - "@aws-sdk/middleware-host-header": 3.620.0 - "@aws-sdk/middleware-logger": 3.609.0 - "@aws-sdk/middleware-recursion-detection": 3.620.0 - "@aws-sdk/middleware-sdk-sqs": 3.635.0 - "@aws-sdk/middleware-user-agent": 3.637.0 - "@aws-sdk/region-config-resolver": 3.614.0 - "@aws-sdk/types": 3.609.0 - "@aws-sdk/util-endpoints": 3.637.0 - "@aws-sdk/util-user-agent-browser": 3.609.0 - "@aws-sdk/util-user-agent-node": 3.614.0 - "@smithy/config-resolver": ^3.0.5 - "@smithy/core": ^2.4.0 - "@smithy/fetch-http-handler": ^3.2.4 - "@smithy/hash-node": ^3.0.3 - "@smithy/invalid-dependency": ^3.0.3 - "@smithy/md5-js": ^3.0.3 - "@smithy/middleware-content-length": ^3.0.5 - "@smithy/middleware-endpoint": ^3.1.0 - "@smithy/middleware-retry": ^3.0.15 - "@smithy/middleware-serde": ^3.0.3 - "@smithy/middleware-stack": ^3.0.3 - "@smithy/node-config-provider": ^3.1.4 - "@smithy/node-http-handler": ^3.1.4 - "@smithy/protocol-http": ^4.1.0 - "@smithy/smithy-client": ^3.2.0 - "@smithy/types": ^3.3.0 - "@smithy/url-parser": ^3.0.3 + "@aws-sdk/client-sso-oidc": 3.651.1 + "@aws-sdk/client-sts": 3.651.1 + "@aws-sdk/core": 3.651.1 + "@aws-sdk/credential-provider-node": 3.651.1 + "@aws-sdk/middleware-host-header": 3.649.0 + "@aws-sdk/middleware-logger": 3.649.0 + "@aws-sdk/middleware-recursion-detection": 3.649.0 + "@aws-sdk/middleware-sdk-sqs": 3.649.0 + "@aws-sdk/middleware-user-agent": 3.649.0 + "@aws-sdk/region-config-resolver": 3.649.0 + "@aws-sdk/types": 3.649.0 + "@aws-sdk/util-endpoints": 3.649.0 + "@aws-sdk/util-user-agent-browser": 3.649.0 + "@aws-sdk/util-user-agent-node": 3.649.0 + "@smithy/config-resolver": ^3.0.6 + "@smithy/core": ^2.4.1 + "@smithy/fetch-http-handler": ^3.2.5 + "@smithy/hash-node": ^3.0.4 + "@smithy/invalid-dependency": ^3.0.4 + "@smithy/md5-js": ^3.0.4 + "@smithy/middleware-content-length": ^3.0.6 + "@smithy/middleware-endpoint": ^3.1.1 + "@smithy/middleware-retry": ^3.0.16 + "@smithy/middleware-serde": ^3.0.4 + "@smithy/middleware-stack": ^3.0.4 + "@smithy/node-config-provider": ^3.1.5 + "@smithy/node-http-handler": ^3.2.0 + "@smithy/protocol-http": ^4.1.1 + "@smithy/smithy-client": ^3.3.0 + "@smithy/types": ^3.4.0 + "@smithy/url-parser": ^3.0.4 "@smithy/util-base64": ^3.0.0 "@smithy/util-body-length-browser": ^3.0.0 "@smithy/util-body-length-node": ^3.0.0 - "@smithy/util-defaults-mode-browser": ^3.0.15 - "@smithy/util-defaults-mode-node": ^3.0.15 - "@smithy/util-endpoints": ^2.0.5 - "@smithy/util-middleware": ^3.0.3 - "@smithy/util-retry": ^3.0.3 + "@smithy/util-defaults-mode-browser": ^3.0.16 + "@smithy/util-defaults-mode-node": ^3.0.16 + "@smithy/util-endpoints": ^2.1.0 + "@smithy/util-middleware": ^3.0.4 + "@smithy/util-retry": ^3.0.4 "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: 9c64774215ece7768cdf895261a7ae3c857637e7a3da9e077b7cc31e3c1afa0772aee646d93f704d6b7ee66eca4e154af53d29b7ca9d50002ae2eff3ede94ac6 + checksum: 51fd00c806ed36dac61d56e4a342966a39a20a1047dfdbe59e4eedaaeda95ad8500ff7b2bb92f4492a182e845af688e1edbeeb5814d099d5d47aec2e4f9380e3 languageName: node linkType: hard -"@aws-sdk/client-sso-oidc@npm:3.637.0": - version: 3.637.0 - resolution: "@aws-sdk/client-sso-oidc@npm:3.637.0" +"@aws-sdk/client-sso-oidc@npm:3.651.1": + version: 3.651.1 + resolution: "@aws-sdk/client-sso-oidc@npm:3.651.1" dependencies: "@aws-crypto/sha256-browser": 5.2.0 "@aws-crypto/sha256-js": 5.2.0 - "@aws-sdk/core": 3.635.0 - "@aws-sdk/credential-provider-node": 3.637.0 - "@aws-sdk/middleware-host-header": 3.620.0 - "@aws-sdk/middleware-logger": 3.609.0 - "@aws-sdk/middleware-recursion-detection": 3.620.0 - "@aws-sdk/middleware-user-agent": 3.637.0 - "@aws-sdk/region-config-resolver": 3.614.0 - "@aws-sdk/types": 3.609.0 - "@aws-sdk/util-endpoints": 3.637.0 - "@aws-sdk/util-user-agent-browser": 3.609.0 - "@aws-sdk/util-user-agent-node": 3.614.0 - "@smithy/config-resolver": ^3.0.5 - "@smithy/core": ^2.4.0 - "@smithy/fetch-http-handler": ^3.2.4 - "@smithy/hash-node": ^3.0.3 - "@smithy/invalid-dependency": ^3.0.3 - "@smithy/middleware-content-length": ^3.0.5 - "@smithy/middleware-endpoint": ^3.1.0 - "@smithy/middleware-retry": ^3.0.15 - "@smithy/middleware-serde": ^3.0.3 - "@smithy/middleware-stack": ^3.0.3 - "@smithy/node-config-provider": ^3.1.4 - "@smithy/node-http-handler": ^3.1.4 - "@smithy/protocol-http": ^4.1.0 - "@smithy/smithy-client": ^3.2.0 - "@smithy/types": ^3.3.0 - "@smithy/url-parser": ^3.0.3 + "@aws-sdk/core": 3.651.1 + "@aws-sdk/credential-provider-node": 3.651.1 + "@aws-sdk/middleware-host-header": 3.649.0 + "@aws-sdk/middleware-logger": 3.649.0 + "@aws-sdk/middleware-recursion-detection": 3.649.0 + "@aws-sdk/middleware-user-agent": 3.649.0 + "@aws-sdk/region-config-resolver": 3.649.0 + "@aws-sdk/types": 3.649.0 + "@aws-sdk/util-endpoints": 3.649.0 + "@aws-sdk/util-user-agent-browser": 3.649.0 + "@aws-sdk/util-user-agent-node": 3.649.0 + "@smithy/config-resolver": ^3.0.6 + "@smithy/core": ^2.4.1 + "@smithy/fetch-http-handler": ^3.2.5 + "@smithy/hash-node": ^3.0.4 + "@smithy/invalid-dependency": ^3.0.4 + "@smithy/middleware-content-length": ^3.0.6 + "@smithy/middleware-endpoint": ^3.1.1 + "@smithy/middleware-retry": ^3.0.16 + "@smithy/middleware-serde": ^3.0.4 + "@smithy/middleware-stack": ^3.0.4 + "@smithy/node-config-provider": ^3.1.5 + "@smithy/node-http-handler": ^3.2.0 + "@smithy/protocol-http": ^4.1.1 + "@smithy/smithy-client": ^3.3.0 + "@smithy/types": ^3.4.0 + "@smithy/url-parser": ^3.0.4 "@smithy/util-base64": ^3.0.0 "@smithy/util-body-length-browser": ^3.0.0 "@smithy/util-body-length-node": ^3.0.0 - "@smithy/util-defaults-mode-browser": ^3.0.15 - "@smithy/util-defaults-mode-node": ^3.0.15 - "@smithy/util-endpoints": ^2.0.5 - "@smithy/util-middleware": ^3.0.3 - "@smithy/util-retry": ^3.0.3 + "@smithy/util-defaults-mode-browser": ^3.0.16 + "@smithy/util-defaults-mode-node": ^3.0.16 + "@smithy/util-endpoints": ^2.1.0 + "@smithy/util-middleware": ^3.0.4 + "@smithy/util-retry": ^3.0.4 "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 peerDependencies: - "@aws-sdk/client-sts": ^3.637.0 - checksum: d56a94144b7b3f49c1bab26fa69dfffdc6227d1c8bc6d8094590bc76f66869c3c49639833f762fcd573863866983469472693a289302da9125820d1b3a0aa86a + "@aws-sdk/client-sts": ^3.651.1 + checksum: 14d43ee5c9fe6cae9115ea9b9a4c555409429f6a0f6e10919938abc3289f3cf76b42fabe1389963b54cd0f9c77a416ff334f1c482f48988723f8ba7004d82d07 languageName: node linkType: hard -"@aws-sdk/client-sso@npm:3.637.0": - version: 3.637.0 - resolution: "@aws-sdk/client-sso@npm:3.637.0" +"@aws-sdk/client-sso@npm:3.651.1": + version: 3.651.1 + resolution: "@aws-sdk/client-sso@npm:3.651.1" dependencies: "@aws-crypto/sha256-browser": 5.2.0 "@aws-crypto/sha256-js": 5.2.0 - "@aws-sdk/core": 3.635.0 - "@aws-sdk/middleware-host-header": 3.620.0 - "@aws-sdk/middleware-logger": 3.609.0 - "@aws-sdk/middleware-recursion-detection": 3.620.0 - "@aws-sdk/middleware-user-agent": 3.637.0 - "@aws-sdk/region-config-resolver": 3.614.0 - "@aws-sdk/types": 3.609.0 - "@aws-sdk/util-endpoints": 3.637.0 - "@aws-sdk/util-user-agent-browser": 3.609.0 - "@aws-sdk/util-user-agent-node": 3.614.0 - "@smithy/config-resolver": ^3.0.5 - "@smithy/core": ^2.4.0 - "@smithy/fetch-http-handler": ^3.2.4 - "@smithy/hash-node": ^3.0.3 - "@smithy/invalid-dependency": ^3.0.3 - "@smithy/middleware-content-length": ^3.0.5 - "@smithy/middleware-endpoint": ^3.1.0 - "@smithy/middleware-retry": ^3.0.15 - "@smithy/middleware-serde": ^3.0.3 - "@smithy/middleware-stack": ^3.0.3 - "@smithy/node-config-provider": ^3.1.4 - "@smithy/node-http-handler": ^3.1.4 - "@smithy/protocol-http": ^4.1.0 - "@smithy/smithy-client": ^3.2.0 - "@smithy/types": ^3.3.0 - "@smithy/url-parser": ^3.0.3 + "@aws-sdk/core": 3.651.1 + "@aws-sdk/middleware-host-header": 3.649.0 + "@aws-sdk/middleware-logger": 3.649.0 + "@aws-sdk/middleware-recursion-detection": 3.649.0 + "@aws-sdk/middleware-user-agent": 3.649.0 + "@aws-sdk/region-config-resolver": 3.649.0 + "@aws-sdk/types": 3.649.0 + "@aws-sdk/util-endpoints": 3.649.0 + "@aws-sdk/util-user-agent-browser": 3.649.0 + "@aws-sdk/util-user-agent-node": 3.649.0 + "@smithy/config-resolver": ^3.0.6 + "@smithy/core": ^2.4.1 + "@smithy/fetch-http-handler": ^3.2.5 + "@smithy/hash-node": ^3.0.4 + "@smithy/invalid-dependency": ^3.0.4 + "@smithy/middleware-content-length": ^3.0.6 + "@smithy/middleware-endpoint": ^3.1.1 + "@smithy/middleware-retry": ^3.0.16 + "@smithy/middleware-serde": ^3.0.4 + "@smithy/middleware-stack": ^3.0.4 + "@smithy/node-config-provider": ^3.1.5 + "@smithy/node-http-handler": ^3.2.0 + "@smithy/protocol-http": ^4.1.1 + "@smithy/smithy-client": ^3.3.0 + "@smithy/types": ^3.4.0 + "@smithy/url-parser": ^3.0.4 "@smithy/util-base64": ^3.0.0 "@smithy/util-body-length-browser": ^3.0.0 "@smithy/util-body-length-node": ^3.0.0 - "@smithy/util-defaults-mode-browser": ^3.0.15 - "@smithy/util-defaults-mode-node": ^3.0.15 - "@smithy/util-endpoints": ^2.0.5 - "@smithy/util-middleware": ^3.0.3 - "@smithy/util-retry": ^3.0.3 + "@smithy/util-defaults-mode-browser": ^3.0.16 + "@smithy/util-defaults-mode-node": ^3.0.16 + "@smithy/util-endpoints": ^2.1.0 + "@smithy/util-middleware": ^3.0.4 + "@smithy/util-retry": ^3.0.4 "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: 7d8fa5ca9740fcce7f8eb22859c6315fc4a2148633af143dd7eadb12ddf84e79cb403562861090904addd3f002f0d2143541bfefe92051f9ad275ed7627dde6a + checksum: 07f4fe05e5b3d52bf34a93bb96539939d021045a3f02b7062d01edf22e13716fa82f137487096d4dd51f3e5428bd458a4fb5400246019aad5d913069ae419dcd languageName: node linkType: hard -"@aws-sdk/client-sts@npm:3.637.0, @aws-sdk/client-sts@npm:^3.350.0": - version: 3.637.0 - resolution: "@aws-sdk/client-sts@npm:3.637.0" +"@aws-sdk/client-sts@npm:3.651.1, @aws-sdk/client-sts@npm:^3.350.0": + version: 3.651.1 + resolution: "@aws-sdk/client-sts@npm:3.651.1" dependencies: "@aws-crypto/sha256-browser": 5.2.0 "@aws-crypto/sha256-js": 5.2.0 - "@aws-sdk/client-sso-oidc": 3.637.0 - "@aws-sdk/core": 3.635.0 - "@aws-sdk/credential-provider-node": 3.637.0 - "@aws-sdk/middleware-host-header": 3.620.0 - "@aws-sdk/middleware-logger": 3.609.0 - "@aws-sdk/middleware-recursion-detection": 3.620.0 - "@aws-sdk/middleware-user-agent": 3.637.0 - "@aws-sdk/region-config-resolver": 3.614.0 - "@aws-sdk/types": 3.609.0 - "@aws-sdk/util-endpoints": 3.637.0 - "@aws-sdk/util-user-agent-browser": 3.609.0 - "@aws-sdk/util-user-agent-node": 3.614.0 - "@smithy/config-resolver": ^3.0.5 - "@smithy/core": ^2.4.0 - "@smithy/fetch-http-handler": ^3.2.4 - "@smithy/hash-node": ^3.0.3 - "@smithy/invalid-dependency": ^3.0.3 - "@smithy/middleware-content-length": ^3.0.5 - "@smithy/middleware-endpoint": ^3.1.0 - "@smithy/middleware-retry": ^3.0.15 - "@smithy/middleware-serde": ^3.0.3 - "@smithy/middleware-stack": ^3.0.3 - "@smithy/node-config-provider": ^3.1.4 - "@smithy/node-http-handler": ^3.1.4 - "@smithy/protocol-http": ^4.1.0 - "@smithy/smithy-client": ^3.2.0 - "@smithy/types": ^3.3.0 - "@smithy/url-parser": ^3.0.3 + "@aws-sdk/client-sso-oidc": 3.651.1 + "@aws-sdk/core": 3.651.1 + "@aws-sdk/credential-provider-node": 3.651.1 + "@aws-sdk/middleware-host-header": 3.649.0 + "@aws-sdk/middleware-logger": 3.649.0 + "@aws-sdk/middleware-recursion-detection": 3.649.0 + "@aws-sdk/middleware-user-agent": 3.649.0 + "@aws-sdk/region-config-resolver": 3.649.0 + "@aws-sdk/types": 3.649.0 + "@aws-sdk/util-endpoints": 3.649.0 + "@aws-sdk/util-user-agent-browser": 3.649.0 + "@aws-sdk/util-user-agent-node": 3.649.0 + "@smithy/config-resolver": ^3.0.6 + "@smithy/core": ^2.4.1 + "@smithy/fetch-http-handler": ^3.2.5 + "@smithy/hash-node": ^3.0.4 + "@smithy/invalid-dependency": ^3.0.4 + "@smithy/middleware-content-length": ^3.0.6 + "@smithy/middleware-endpoint": ^3.1.1 + "@smithy/middleware-retry": ^3.0.16 + "@smithy/middleware-serde": ^3.0.4 + "@smithy/middleware-stack": ^3.0.4 + "@smithy/node-config-provider": ^3.1.5 + "@smithy/node-http-handler": ^3.2.0 + "@smithy/protocol-http": ^4.1.1 + "@smithy/smithy-client": ^3.3.0 + "@smithy/types": ^3.4.0 + "@smithy/url-parser": ^3.0.4 "@smithy/util-base64": ^3.0.0 "@smithy/util-body-length-browser": ^3.0.0 "@smithy/util-body-length-node": ^3.0.0 - "@smithy/util-defaults-mode-browser": ^3.0.15 - "@smithy/util-defaults-mode-node": ^3.0.15 - "@smithy/util-endpoints": ^2.0.5 - "@smithy/util-middleware": ^3.0.3 - "@smithy/util-retry": ^3.0.3 + "@smithy/util-defaults-mode-browser": ^3.0.16 + "@smithy/util-defaults-mode-node": ^3.0.16 + "@smithy/util-endpoints": ^2.1.0 + "@smithy/util-middleware": ^3.0.4 + "@smithy/util-retry": ^3.0.4 "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: 5045a9a11eec97690bb6fde581657f85ff9be5d11441594adbf9d95e7825c5a40c78697284e2630ce731ab687ff410b7085f4f60cea88683936a41cec0b472a1 + checksum: 90c72041373acbae6bde9132adb80d81d2fe0b466fb495ba4d383c72c7734cfc5d68b7c65c22427820842fed915877ff76b7e54975c3895913e6e2c1d79916ed languageName: node linkType: hard -"@aws-sdk/core@npm:3.635.0": - version: 3.635.0 - resolution: "@aws-sdk/core@npm:3.635.0" +"@aws-sdk/core@npm:3.651.1": + version: 3.651.1 + resolution: "@aws-sdk/core@npm:3.651.1" dependencies: - "@smithy/core": ^2.4.0 - "@smithy/node-config-provider": ^3.1.4 - "@smithy/property-provider": ^3.1.3 - "@smithy/protocol-http": ^4.1.0 - "@smithy/signature-v4": ^4.1.0 - "@smithy/smithy-client": ^3.2.0 - "@smithy/types": ^3.3.0 - "@smithy/util-middleware": ^3.0.3 + "@smithy/core": ^2.4.1 + "@smithy/node-config-provider": ^3.1.5 + "@smithy/property-provider": ^3.1.4 + "@smithy/protocol-http": ^4.1.1 + "@smithy/signature-v4": ^4.1.1 + "@smithy/smithy-client": ^3.3.0 + "@smithy/types": ^3.4.0 + "@smithy/util-middleware": ^3.0.4 fast-xml-parser: 4.4.1 tslib: ^2.6.2 - checksum: 580fd8416a9f569b4923d3ad4031eb2cd12bd0f76cd38aaf6e3e5f735bcd01d26fc27d1560a92d123b7e3e0af7b21311fafa68d24b75cd959f4d3af53a0020e0 + checksum: 529f147a2a3d0023657a51194e91bfb2dec580a902f0c8a644710bf5110c8ad43bb2c8637ba433e3cbbee459603c718679646cb8d8239815766dbfee7502e302 languageName: node linkType: hard -"@aws-sdk/credential-provider-cognito-identity@npm:3.637.0": - version: 3.637.0 - resolution: "@aws-sdk/credential-provider-cognito-identity@npm:3.637.0" +"@aws-sdk/credential-provider-cognito-identity@npm:3.651.1": + version: 3.651.1 + resolution: "@aws-sdk/credential-provider-cognito-identity@npm:3.651.1" dependencies: - "@aws-sdk/client-cognito-identity": 3.637.0 - "@aws-sdk/types": 3.609.0 - "@smithy/property-provider": ^3.1.3 - "@smithy/types": ^3.3.0 + "@aws-sdk/client-cognito-identity": 3.651.1 + "@aws-sdk/types": 3.649.0 + "@smithy/property-provider": ^3.1.4 + "@smithy/types": ^3.4.0 tslib: ^2.6.2 - checksum: 17991646b1d5d71faca2afff4459bc2bf0ae4bf5b208b2de7a5770116c32a150569dc5d31ba6c286ae0688cca7c5b8c7234b04f21c7ea1e9bef460013db61ecc + checksum: 095c36ba7594e63b4717dbb791f9c9c8f806bee3ad6cec4f95c19596ffd31ea4d24dfb3e5f2df5cb875eee30aa648e125161b9bb97c89c5a208682e0a15995dc languageName: node linkType: hard -"@aws-sdk/credential-provider-env@npm:3.620.1": - version: 3.620.1 - resolution: "@aws-sdk/credential-provider-env@npm:3.620.1" +"@aws-sdk/credential-provider-env@npm:3.649.0": + version: 3.649.0 + resolution: "@aws-sdk/credential-provider-env@npm:3.649.0" dependencies: - "@aws-sdk/types": 3.609.0 - "@smithy/property-provider": ^3.1.3 - "@smithy/types": ^3.3.0 + "@aws-sdk/types": 3.649.0 + "@smithy/property-provider": ^3.1.4 + "@smithy/types": ^3.4.0 tslib: ^2.6.2 - checksum: 3e05eeb6c6490e7759d03b7b688ef321d5e6c97929f21226e912b01aa926815312043febd505e8b43b54010b5ae2717559aba6deeea93bda7d6cf0d8a0b9fc76 + checksum: 85904f366e4de8408af515528e7e7cccf9bd1075bf4556bd7df2e987a8c84d07e6c26a6dac923cd895991f4dbad6987cdefec8812efc5e71b0745feef8fcd4a5 languageName: node linkType: hard -"@aws-sdk/credential-provider-http@npm:3.635.0": - version: 3.635.0 - resolution: "@aws-sdk/credential-provider-http@npm:3.635.0" +"@aws-sdk/credential-provider-http@npm:3.649.0": + version: 3.649.0 + resolution: "@aws-sdk/credential-provider-http@npm:3.649.0" dependencies: - "@aws-sdk/types": 3.609.0 - "@smithy/fetch-http-handler": ^3.2.4 - "@smithy/node-http-handler": ^3.1.4 - "@smithy/property-provider": ^3.1.3 - "@smithy/protocol-http": ^4.1.0 - "@smithy/smithy-client": ^3.2.0 - "@smithy/types": ^3.3.0 - "@smithy/util-stream": ^3.1.3 + "@aws-sdk/types": 3.649.0 + "@smithy/fetch-http-handler": ^3.2.5 + "@smithy/node-http-handler": ^3.2.0 + "@smithy/property-provider": ^3.1.4 + "@smithy/protocol-http": ^4.1.1 + "@smithy/smithy-client": ^3.3.0 + "@smithy/types": ^3.4.0 + "@smithy/util-stream": ^3.1.4 tslib: ^2.6.2 - checksum: 7b5b35da0ec78b0bb4b697edba8bd713aeee90b651f201313197daf9e6349b9332d03954dfd7c4bfbfa140c4f0bf90c13ae262ed180ce209f0de3b17a954dbca + checksum: c376151e2eabf334dc7c9b294fd89fbf6cdeaf929b3d6715be1a83c442ce4e112894778041e74d0cd508e50afc8a176e997487ad0b26b1398f5eeecb5c4c39e1 languageName: node linkType: hard -"@aws-sdk/credential-provider-ini@npm:3.637.0": - version: 3.637.0 - resolution: "@aws-sdk/credential-provider-ini@npm:3.637.0" +"@aws-sdk/credential-provider-ini@npm:3.651.1": + version: 3.651.1 + resolution: "@aws-sdk/credential-provider-ini@npm:3.651.1" dependencies: - "@aws-sdk/credential-provider-env": 3.620.1 - "@aws-sdk/credential-provider-http": 3.635.0 - "@aws-sdk/credential-provider-process": 3.620.1 - "@aws-sdk/credential-provider-sso": 3.637.0 - "@aws-sdk/credential-provider-web-identity": 3.621.0 - "@aws-sdk/types": 3.609.0 - "@smithy/credential-provider-imds": ^3.2.0 - "@smithy/property-provider": ^3.1.3 - "@smithy/shared-ini-file-loader": ^3.1.4 - "@smithy/types": ^3.3.0 + "@aws-sdk/credential-provider-env": 3.649.0 + "@aws-sdk/credential-provider-http": 3.649.0 + "@aws-sdk/credential-provider-process": 3.649.0 + "@aws-sdk/credential-provider-sso": 3.651.1 + "@aws-sdk/credential-provider-web-identity": 3.649.0 + "@aws-sdk/types": 3.649.0 + "@smithy/credential-provider-imds": ^3.2.1 + "@smithy/property-provider": ^3.1.4 + "@smithy/shared-ini-file-loader": ^3.1.5 + "@smithy/types": ^3.4.0 tslib: ^2.6.2 peerDependencies: - "@aws-sdk/client-sts": ^3.637.0 - checksum: ff005eb0f451f7a95e01dbdaee6ac67e3edcd8587a25d77544c03c05589e5f033a4b3aca0137d0d067ecb4f1e3ed194c06dc6e15b9a0d95bac89d613a3c26399 + "@aws-sdk/client-sts": ^3.651.1 + checksum: 7ddab585aabd579058f1d9a6d5b1cd5f5168bffa8f010319cec4eb998e2be11a2e1b775231b0e0e452764b24ea82d38e41706916365477f7e038cfd5037236da languageName: node linkType: hard -"@aws-sdk/credential-provider-node@npm:3.637.0, @aws-sdk/credential-provider-node@npm:^3.350.0": - version: 3.637.0 - resolution: "@aws-sdk/credential-provider-node@npm:3.637.0" +"@aws-sdk/credential-provider-node@npm:3.651.1, @aws-sdk/credential-provider-node@npm:^3.350.0": + version: 3.651.1 + resolution: "@aws-sdk/credential-provider-node@npm:3.651.1" dependencies: - "@aws-sdk/credential-provider-env": 3.620.1 - "@aws-sdk/credential-provider-http": 3.635.0 - "@aws-sdk/credential-provider-ini": 3.637.0 - "@aws-sdk/credential-provider-process": 3.620.1 - "@aws-sdk/credential-provider-sso": 3.637.0 - "@aws-sdk/credential-provider-web-identity": 3.621.0 - "@aws-sdk/types": 3.609.0 - "@smithy/credential-provider-imds": ^3.2.0 - "@smithy/property-provider": ^3.1.3 - "@smithy/shared-ini-file-loader": ^3.1.4 - "@smithy/types": ^3.3.0 + "@aws-sdk/credential-provider-env": 3.649.0 + "@aws-sdk/credential-provider-http": 3.649.0 + "@aws-sdk/credential-provider-ini": 3.651.1 + "@aws-sdk/credential-provider-process": 3.649.0 + "@aws-sdk/credential-provider-sso": 3.651.1 + "@aws-sdk/credential-provider-web-identity": 3.649.0 + "@aws-sdk/types": 3.649.0 + "@smithy/credential-provider-imds": ^3.2.1 + "@smithy/property-provider": ^3.1.4 + "@smithy/shared-ini-file-loader": ^3.1.5 + "@smithy/types": ^3.4.0 tslib: ^2.6.2 - checksum: 53fe4d083bc25e1d0b34ad2ca30aded81f3417fb896fbcaa1ef7209b67fedd7a81f7e00a1c87b35f0e245a8d19629c3644e14d3106cd0ee4cbea8a7c6713f9e3 + checksum: 7c0cd5283f4d2005402f263872846ce9f30bb9aadae8508990e3f19321477d7965a16111c7ec01a3532dd7bd73c2ba5703691db3de11c1ccfcdefe54f6fe084d languageName: node linkType: hard -"@aws-sdk/credential-provider-process@npm:3.620.1": - version: 3.620.1 - resolution: "@aws-sdk/credential-provider-process@npm:3.620.1" +"@aws-sdk/credential-provider-process@npm:3.649.0": + version: 3.649.0 + resolution: "@aws-sdk/credential-provider-process@npm:3.649.0" dependencies: - "@aws-sdk/types": 3.609.0 - "@smithy/property-provider": ^3.1.3 - "@smithy/shared-ini-file-loader": ^3.1.4 - "@smithy/types": ^3.3.0 + "@aws-sdk/types": 3.649.0 + "@smithy/property-provider": ^3.1.4 + "@smithy/shared-ini-file-loader": ^3.1.5 + "@smithy/types": ^3.4.0 tslib: ^2.6.2 - checksum: 1fd6d3abf35ccfaed0882ee74e4d876e8c6cfe8d8b23c574dfe98364b2a2f3226d97fe35e2d48b88dd514906595cbb5fa1e0066d989a9582f73f92117796168f + checksum: 5cb86e927aaa01df435635a74f73657a363dfaa86aaf2149ac08d35682613e62c9c6485b5855f2230e5978f98e8ac430fc7c325027211f986af9cdfef3a2aff6 languageName: node linkType: hard -"@aws-sdk/credential-provider-sso@npm:3.637.0": - version: 3.637.0 - resolution: "@aws-sdk/credential-provider-sso@npm:3.637.0" +"@aws-sdk/credential-provider-sso@npm:3.651.1": + version: 3.651.1 + resolution: "@aws-sdk/credential-provider-sso@npm:3.651.1" dependencies: - "@aws-sdk/client-sso": 3.637.0 - "@aws-sdk/token-providers": 3.614.0 - "@aws-sdk/types": 3.609.0 - "@smithy/property-provider": ^3.1.3 - "@smithy/shared-ini-file-loader": ^3.1.4 - "@smithy/types": ^3.3.0 + "@aws-sdk/client-sso": 3.651.1 + "@aws-sdk/token-providers": 3.649.0 + "@aws-sdk/types": 3.649.0 + "@smithy/property-provider": ^3.1.4 + "@smithy/shared-ini-file-loader": ^3.1.5 + "@smithy/types": ^3.4.0 tslib: ^2.6.2 - checksum: 7f8670ca253ee26e56da3011136ad8049f877a07c4d040b46ae1380ffc53502dbbacafe4f2dc84aa94b3d760abe634c36351c2a0114176a6a09fe8477317a5f8 + checksum: 0ec5e0dbd5d4353412777f73e9dff9399efaaaab951b032366f1c48ca228540ad3deee3dac45ec43c3c74e67cc12149777f56031573233cfa6c3612ebb2f3a3e languageName: node linkType: hard -"@aws-sdk/credential-provider-web-identity@npm:3.621.0": - version: 3.621.0 - resolution: "@aws-sdk/credential-provider-web-identity@npm:3.621.0" +"@aws-sdk/credential-provider-web-identity@npm:3.649.0": + version: 3.649.0 + resolution: "@aws-sdk/credential-provider-web-identity@npm:3.649.0" dependencies: - "@aws-sdk/types": 3.609.0 - "@smithy/property-provider": ^3.1.3 - "@smithy/types": ^3.3.0 + "@aws-sdk/types": 3.649.0 + "@smithy/property-provider": ^3.1.4 + "@smithy/types": ^3.4.0 tslib: ^2.6.2 peerDependencies: - "@aws-sdk/client-sts": ^3.621.0 - checksum: b1157e83b81c21f384ad95d29c646149124136c38e6395265ff8d9f5f6afec1e3e2b70c1f0be165c440058802c3871f3766c5e7ba44705ced447de221f4d04df + "@aws-sdk/client-sts": ^3.649.0 + checksum: 8df15387ce851f2d4a54c63c7e98d9f401c0b406cd9e35a58461bbb00842ae46e8074e93b4bee39793a61bfd46a01d78e3fcfffa56a60c898a0d880a36e2628f languageName: node linkType: hard "@aws-sdk/credential-providers@npm:^3.350.0": - version: 3.637.0 - resolution: "@aws-sdk/credential-providers@npm:3.637.0" + version: 3.651.1 + resolution: "@aws-sdk/credential-providers@npm:3.651.1" dependencies: - "@aws-sdk/client-cognito-identity": 3.637.0 - "@aws-sdk/client-sso": 3.637.0 - "@aws-sdk/client-sts": 3.637.0 - "@aws-sdk/credential-provider-cognito-identity": 3.637.0 - "@aws-sdk/credential-provider-env": 3.620.1 - "@aws-sdk/credential-provider-http": 3.635.0 - "@aws-sdk/credential-provider-ini": 3.637.0 - "@aws-sdk/credential-provider-node": 3.637.0 - "@aws-sdk/credential-provider-process": 3.620.1 - "@aws-sdk/credential-provider-sso": 3.637.0 - "@aws-sdk/credential-provider-web-identity": 3.621.0 - "@aws-sdk/types": 3.609.0 - "@smithy/credential-provider-imds": ^3.2.0 - "@smithy/property-provider": ^3.1.3 - "@smithy/types": ^3.3.0 + "@aws-sdk/client-cognito-identity": 3.651.1 + "@aws-sdk/client-sso": 3.651.1 + "@aws-sdk/client-sts": 3.651.1 + "@aws-sdk/credential-provider-cognito-identity": 3.651.1 + "@aws-sdk/credential-provider-env": 3.649.0 + "@aws-sdk/credential-provider-http": 3.649.0 + "@aws-sdk/credential-provider-ini": 3.651.1 + "@aws-sdk/credential-provider-node": 3.651.1 + "@aws-sdk/credential-provider-process": 3.649.0 + "@aws-sdk/credential-provider-sso": 3.651.1 + "@aws-sdk/credential-provider-web-identity": 3.649.0 + "@aws-sdk/types": 3.649.0 + "@smithy/credential-provider-imds": ^3.2.1 + "@smithy/property-provider": ^3.1.4 + "@smithy/types": ^3.4.0 tslib: ^2.6.2 - checksum: a211dbf654b5159d8cf2d933f36be35c307ca8c2f26e82f8e7420465d30c79c1c3ed14a266839684118a302f4b468ef10b7c75076eb51923cbb6c250f0d70a58 + checksum: 2a90667c901a04682a4018cd10cfb5c7c4a5bcc6adaffb0499931e7317d9bfeef1ef273aa5eeabedb4f4822c0081ac3ce585923f6f91b6cbc3d8b0459376c6fd languageName: node linkType: hard @@ -1197,34 +1197,34 @@ __metadata: linkType: hard "@aws-sdk/lib-storage@npm:^3.350.0": - version: 3.637.0 - resolution: "@aws-sdk/lib-storage@npm:3.637.0" + version: 3.651.1 + resolution: "@aws-sdk/lib-storage@npm:3.651.1" dependencies: - "@smithy/abort-controller": ^3.1.1 - "@smithy/middleware-endpoint": ^3.1.0 - "@smithy/smithy-client": ^3.2.0 + "@smithy/abort-controller": ^3.1.2 + "@smithy/middleware-endpoint": ^3.1.1 + "@smithy/smithy-client": ^3.3.0 buffer: 5.6.0 events: 3.3.0 stream-browserify: 3.0.0 tslib: ^2.6.2 peerDependencies: - "@aws-sdk/client-s3": ^3.637.0 - checksum: dc90cfe6874b4ca23f3ebac2a11ef6b751abadaaa9c04777d13b096e8ef3bb764100d06cd97f48f803cacb2642725f36e1237d00cde6ffe02bd429658c944c6a + "@aws-sdk/client-s3": ^3.651.1 + checksum: 1b418eaf0adbbb82b7a984e8346cd86fef6df15b8874220fdabfc9e0fd0edea72989731fbb14961f09d6278d705a8a3612409bcfcf200b233528374852af373b languageName: node linkType: hard -"@aws-sdk/middleware-bucket-endpoint@npm:3.620.0": - version: 3.620.0 - resolution: "@aws-sdk/middleware-bucket-endpoint@npm:3.620.0" +"@aws-sdk/middleware-bucket-endpoint@npm:3.649.0": + version: 3.649.0 + resolution: "@aws-sdk/middleware-bucket-endpoint@npm:3.649.0" dependencies: - "@aws-sdk/types": 3.609.0 + "@aws-sdk/types": 3.649.0 "@aws-sdk/util-arn-parser": 3.568.0 - "@smithy/node-config-provider": ^3.1.4 - "@smithy/protocol-http": ^4.1.0 - "@smithy/types": ^3.3.0 + "@smithy/node-config-provider": ^3.1.5 + "@smithy/protocol-http": ^4.1.1 + "@smithy/types": ^3.4.0 "@smithy/util-config-provider": ^3.0.0 tslib: ^2.6.2 - checksum: a5539ad611d3a2f7709952bf735a075a9d18ed5e9c0abe4e268bca32775a2100f3e956a264f6afb0ad0b48600f5b1d3389ec0566cd2795e6ae2dbe5af322b56b + checksum: 1cb0cb6a0e707b666b7c1e60a758991ae9f80ed4d3445f83b651cb16c6650113382d826fd38ad4a09cac217c87ae6e707f025e13803dc0b687ce4a657429ffd5 languageName: node linkType: hard @@ -1241,113 +1241,115 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-expect-continue@npm:3.620.0": - version: 3.620.0 - resolution: "@aws-sdk/middleware-expect-continue@npm:3.620.0" +"@aws-sdk/middleware-expect-continue@npm:3.649.0": + version: 3.649.0 + resolution: "@aws-sdk/middleware-expect-continue@npm:3.649.0" dependencies: - "@aws-sdk/types": 3.609.0 - "@smithy/protocol-http": ^4.1.0 - "@smithy/types": ^3.3.0 + "@aws-sdk/types": 3.649.0 + "@smithy/protocol-http": ^4.1.1 + "@smithy/types": ^3.4.0 tslib: ^2.6.2 - checksum: 739af454854562342984ac5e3c1c3dca39205344f52eda5961dae80020595062eaae6da2f76bf48ad486d92041c2a2bd30f1dd67b8b20ae043897d1d27b1a6bb + checksum: ab3a7609bc2ec2298301edac3e0077c1aef64a1437050f6153e11018ce5a544bbb34fb930b4619980c405ea49dbb0d89ffba850fd155919331085935911b3e22 languageName: node linkType: hard -"@aws-sdk/middleware-flexible-checksums@npm:3.620.0": - version: 3.620.0 - resolution: "@aws-sdk/middleware-flexible-checksums@npm:3.620.0" +"@aws-sdk/middleware-flexible-checksums@npm:3.651.1": + version: 3.651.1 + resolution: "@aws-sdk/middleware-flexible-checksums@npm:3.651.1" dependencies: "@aws-crypto/crc32": 5.2.0 "@aws-crypto/crc32c": 5.2.0 - "@aws-sdk/types": 3.609.0 + "@aws-sdk/types": 3.649.0 "@smithy/is-array-buffer": ^3.0.0 - "@smithy/protocol-http": ^4.1.0 - "@smithy/types": ^3.3.0 + "@smithy/node-config-provider": ^3.1.5 + "@smithy/protocol-http": ^4.1.1 + "@smithy/types": ^3.4.0 + "@smithy/util-middleware": ^3.0.4 "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: 2fc70ffa826d94924c0dae92ed5250c85aade93cbc15a488df81683d8f32eb7660f546569b1c2d2e878db5c8da02a83a3a98c331c5bb3adca46362e667abcbed + checksum: cb0fe0e90d99fd07f1b1e316b48ca665d5c8aef5e7f8ae1be371463332b492595a7c5c01ea9675bab8eb9c3b998afeebf73fa063be4ce130fc5f88eb0ba28152 languageName: node linkType: hard -"@aws-sdk/middleware-host-header@npm:3.620.0": - version: 3.620.0 - resolution: "@aws-sdk/middleware-host-header@npm:3.620.0" +"@aws-sdk/middleware-host-header@npm:3.649.0": + version: 3.649.0 + resolution: "@aws-sdk/middleware-host-header@npm:3.649.0" dependencies: - "@aws-sdk/types": 3.609.0 - "@smithy/protocol-http": ^4.1.0 - "@smithy/types": ^3.3.0 + "@aws-sdk/types": 3.649.0 + "@smithy/protocol-http": ^4.1.1 + "@smithy/types": ^3.4.0 tslib: ^2.6.2 - checksum: 829c2d230e5051704f45c5283c42bec657607f4e4b2dd251fda8a716be90f8c9dfd6e7d45892a9a558c35cb64711628b3d0f88b90fe8cd061382c70b473991ef + checksum: e6ace87d76c91750489241d9f0c22070e9ddcecdf5d09ca958923269b60155502690af472e5c00d565cde83fec1d5fab780cc735d62773e874d8f6980d620dce languageName: node linkType: hard -"@aws-sdk/middleware-location-constraint@npm:3.609.0": - version: 3.609.0 - resolution: "@aws-sdk/middleware-location-constraint@npm:3.609.0" +"@aws-sdk/middleware-location-constraint@npm:3.649.0": + version: 3.649.0 + resolution: "@aws-sdk/middleware-location-constraint@npm:3.649.0" dependencies: - "@aws-sdk/types": 3.609.0 - "@smithy/types": ^3.3.0 + "@aws-sdk/types": 3.649.0 + "@smithy/types": ^3.4.0 tslib: ^2.6.2 - checksum: f7962cf0b382efdf56cd07f8c0279efead02365edd7a2c124be39551b51a8359ee0d6f0399fcbf679ead3d235e24d1765f79712cf88e06c0a5432bf2d0c317d8 + checksum: b0e24674eb9e53d88a44c3d20881f69ee7d6818c143c33ccecf7031af864ae6f759f95171a2e8f8bc3d0d2902eecd88af1fd039f6dc9b7ce66fcce82a189bf2d languageName: node linkType: hard -"@aws-sdk/middleware-logger@npm:3.609.0": - version: 3.609.0 - resolution: "@aws-sdk/middleware-logger@npm:3.609.0" +"@aws-sdk/middleware-logger@npm:3.649.0": + version: 3.649.0 + resolution: "@aws-sdk/middleware-logger@npm:3.649.0" dependencies: - "@aws-sdk/types": 3.609.0 - "@smithy/types": ^3.3.0 + "@aws-sdk/types": 3.649.0 + "@smithy/types": ^3.4.0 tslib: ^2.6.2 - checksum: b6f67a2e9ba082c8aec9d45905ae45ea5a95896f1beecb0c2d7fecfe17dd8fad99513f43b11ed7fd6ca9ff7764a0fc1ce63af91b1baed92b36f7b4b5390be5c6 + checksum: 967e239cc6d8d969a0d6087c8070d6d6a66b78c79930b9963a53ed2a578955478328369a3eadb978cb9432c6c58db5972b4d3ea9ff6ece71950a5f115ff50de7 languageName: node linkType: hard -"@aws-sdk/middleware-recursion-detection@npm:3.620.0": - version: 3.620.0 - resolution: "@aws-sdk/middleware-recursion-detection@npm:3.620.0" +"@aws-sdk/middleware-recursion-detection@npm:3.649.0": + version: 3.649.0 + resolution: "@aws-sdk/middleware-recursion-detection@npm:3.649.0" dependencies: - "@aws-sdk/types": 3.609.0 - "@smithy/protocol-http": ^4.1.0 - "@smithy/types": ^3.3.0 + "@aws-sdk/types": 3.649.0 + "@smithy/protocol-http": ^4.1.1 + "@smithy/types": ^3.4.0 tslib: ^2.6.2 - checksum: 1dedbbab2f79d4c0b214ca183a45daf89e98f9a33b2a08dcd7d30e059c1bcc04a74499b49870300d5f0b827d660512582f96f857624d3feaaf194a7a92703cea + checksum: 0be3b9c23b002ced7f851e22e02832300756a83902b22851eed2e85d336fcda05af92d52eaf31bf566330e2c7bb725945b41293f84761bcc263946a5f776a8e6 languageName: node linkType: hard -"@aws-sdk/middleware-sdk-s3@npm:3.635.0": - version: 3.635.0 - resolution: "@aws-sdk/middleware-sdk-s3@npm:3.635.0" +"@aws-sdk/middleware-sdk-s3@npm:3.651.1": + version: 3.651.1 + resolution: "@aws-sdk/middleware-sdk-s3@npm:3.651.1" dependencies: - "@aws-sdk/core": 3.635.0 - "@aws-sdk/types": 3.609.0 + "@aws-sdk/core": 3.651.1 + "@aws-sdk/types": 3.649.0 "@aws-sdk/util-arn-parser": 3.568.0 - "@smithy/core": ^2.4.0 - "@smithy/node-config-provider": ^3.1.4 - "@smithy/protocol-http": ^4.1.0 - "@smithy/signature-v4": ^4.1.0 - "@smithy/smithy-client": ^3.2.0 - "@smithy/types": ^3.3.0 + "@smithy/core": ^2.4.1 + "@smithy/node-config-provider": ^3.1.5 + "@smithy/protocol-http": ^4.1.1 + "@smithy/signature-v4": ^4.1.1 + "@smithy/smithy-client": ^3.3.0 + "@smithy/types": ^3.4.0 "@smithy/util-config-provider": ^3.0.0 - "@smithy/util-middleware": ^3.0.3 - "@smithy/util-stream": ^3.1.3 + "@smithy/util-middleware": ^3.0.4 + "@smithy/util-stream": ^3.1.4 "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: c892374e0d9f64e9c0387efff645df1b50c7fb4bdca9aea0fd61696fd6b6e7f2e275d523939c0d2eda1db4c7ef81b7ec930376a8ec3cf96d2aa3e5838bca2d41 + checksum: 84f0475b4afb736e09a5025f782692555b12e641e308003e3b77911a2820ec27a4385ef812d1794e0661cc413f1031a8b7bebc42840619200447f6f0b0d5e517 languageName: node linkType: hard -"@aws-sdk/middleware-sdk-sqs@npm:3.635.0": - version: 3.635.0 - resolution: "@aws-sdk/middleware-sdk-sqs@npm:3.635.0" +"@aws-sdk/middleware-sdk-sqs@npm:3.649.0": + version: 3.649.0 + resolution: "@aws-sdk/middleware-sdk-sqs@npm:3.649.0" dependencies: - "@aws-sdk/types": 3.609.0 - "@smithy/smithy-client": ^3.2.0 - "@smithy/types": ^3.3.0 + "@aws-sdk/types": 3.649.0 + "@smithy/smithy-client": ^3.3.0 + "@smithy/types": ^3.4.0 "@smithy/util-hex-encoding": ^3.0.0 "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: 5ef3130983332fc3d7362f253091a6558bbee0b2300188fcf0d795c2ce2e064fa7425cc55bc500bd4f557f4666ae0b28578cc46791641f2e5cb8d8e04cca70b8 + checksum: 0e0b3beb7137ddba1da9d47f3101463d384032adf02fb1b7102b6bb35509d44def6eb2ac102a9e7a58c084be792e7d2df1809904d1633ffcdbe108a18bfec537 languageName: node linkType: hard @@ -1361,27 +1363,27 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-ssec@npm:3.609.0": - version: 3.609.0 - resolution: "@aws-sdk/middleware-ssec@npm:3.609.0" +"@aws-sdk/middleware-ssec@npm:3.649.0": + version: 3.649.0 + resolution: "@aws-sdk/middleware-ssec@npm:3.649.0" dependencies: - "@aws-sdk/types": 3.609.0 - "@smithy/types": ^3.3.0 + "@aws-sdk/types": 3.649.0 + "@smithy/types": ^3.4.0 tslib: ^2.6.2 - checksum: 4b40627ed103159ef0db4cc6bdc2148d1a65b786f3d1c643d34bccc79b9d265495613dc9bb34d18d5ab9b21b5d31110e495ec2b077e6e2f7603a0493254180a2 + checksum: 8254d540bd261bb70342ce529c5dd07c1567e4ee77a089a3f1d078e995be5e8a632acee8c3c6a417774ff628b3f165513b16362c3e0b5f475ac0aee872aac0bd languageName: node linkType: hard -"@aws-sdk/middleware-user-agent@npm:3.637.0": - version: 3.637.0 - resolution: "@aws-sdk/middleware-user-agent@npm:3.637.0" +"@aws-sdk/middleware-user-agent@npm:3.649.0": + version: 3.649.0 + resolution: "@aws-sdk/middleware-user-agent@npm:3.649.0" dependencies: - "@aws-sdk/types": 3.609.0 - "@aws-sdk/util-endpoints": 3.637.0 - "@smithy/protocol-http": ^4.1.0 - "@smithy/types": ^3.3.0 + "@aws-sdk/types": 3.649.0 + "@aws-sdk/util-endpoints": 3.649.0 + "@smithy/protocol-http": ^4.1.1 + "@smithy/types": ^3.4.0 tslib: ^2.6.2 - checksum: e6dfa9d45853d47fbdb60e2ee3989900dd587e7a1224392014a7cac2d07952d99c3da0c82f6099b6cc9e2b438960eda620e99e939c374b2524795f75f51ba777 + checksum: 01e00cd7e7a1f906c44b4abbda88898d775fd1493331ecba6dc6de73c5146f9bcbf9d37f212cce4b2f56aac37b270ed34cf56190e6c52cf59da772b2ac2aa48b languageName: node linkType: hard @@ -1429,31 +1431,31 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/region-config-resolver@npm:3.614.0": - version: 3.614.0 - resolution: "@aws-sdk/region-config-resolver@npm:3.614.0" +"@aws-sdk/region-config-resolver@npm:3.649.0": + version: 3.649.0 + resolution: "@aws-sdk/region-config-resolver@npm:3.649.0" dependencies: - "@aws-sdk/types": 3.609.0 - "@smithy/node-config-provider": ^3.1.4 - "@smithy/types": ^3.3.0 + "@aws-sdk/types": 3.649.0 + "@smithy/node-config-provider": ^3.1.5 + "@smithy/types": ^3.4.0 "@smithy/util-config-provider": ^3.0.0 - "@smithy/util-middleware": ^3.0.3 + "@smithy/util-middleware": ^3.0.4 tslib: ^2.6.2 - checksum: dbaca50792c99685845b21dd4a53228613e0458ee517a21db941890ee521d91eff80704f08e9ee71b6f04e70fb86362c4823750bb0b3727240af68d78d8fa4be + checksum: fcd8ae56985b1ac31308a0402492b31510ba9e0889b46d64bcc42c9c00665abc295b7ff85db8050ac4751f11c7a229bc6990e56b8ae0ee7474d53f3f75832ecf languageName: node linkType: hard -"@aws-sdk/signature-v4-multi-region@npm:3.635.0": - version: 3.635.0 - resolution: "@aws-sdk/signature-v4-multi-region@npm:3.635.0" +"@aws-sdk/signature-v4-multi-region@npm:3.651.1": + version: 3.651.1 + resolution: "@aws-sdk/signature-v4-multi-region@npm:3.651.1" dependencies: - "@aws-sdk/middleware-sdk-s3": 3.635.0 - "@aws-sdk/types": 3.609.0 - "@smithy/protocol-http": ^4.1.0 - "@smithy/signature-v4": ^4.1.0 - "@smithy/types": ^3.3.0 + "@aws-sdk/middleware-sdk-s3": 3.651.1 + "@aws-sdk/types": 3.649.0 + "@smithy/protocol-http": ^4.1.1 + "@smithy/signature-v4": ^4.1.1 + "@smithy/types": ^3.4.0 tslib: ^2.6.2 - checksum: c2f5c9e6be2f1ea9abbcb7d767d6cf2035ef1e4785ef4399180d6eb3663c2653109cabc9079f40e47067eedaa61a30b7e8b94e55659654280fea5976e1788aea + checksum: dadf53460c7f02fd2c8759f611742b564f83280296e91fcc5f88223a4db0b4dd39da9a63f3b159febf81ee193090b25f74f2f345ec0b662183dac1cf0780b610 languageName: node linkType: hard @@ -1473,18 +1475,18 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/token-providers@npm:3.614.0": - version: 3.614.0 - resolution: "@aws-sdk/token-providers@npm:3.614.0" +"@aws-sdk/token-providers@npm:3.649.0": + version: 3.649.0 + resolution: "@aws-sdk/token-providers@npm:3.649.0" dependencies: - "@aws-sdk/types": 3.609.0 - "@smithy/property-provider": ^3.1.3 - "@smithy/shared-ini-file-loader": ^3.1.4 - "@smithy/types": ^3.3.0 + "@aws-sdk/types": 3.649.0 + "@smithy/property-provider": ^3.1.4 + "@smithy/shared-ini-file-loader": ^3.1.5 + "@smithy/types": ^3.4.0 tslib: ^2.6.2 peerDependencies: - "@aws-sdk/client-sso-oidc": ^3.614.0 - checksum: 2901b8428afc3b76ff1df9ac29a2698db6bf65d1d2afcd8424b9bf187313d2a3ca747c3b205afeb5c132068b5a5a94d84ce82710f775fa0cbb79499d7fea2d64 + "@aws-sdk/client-sso-oidc": ^3.649.0 + checksum: 388cf0efd5a2915128187824bac33ff791bc8146b0ca3c16d23fbb424221c0fe7f5a53ef1e8b8c038ad8a727a7e4db189c99be652332efb8d43cd2495de7a37e languageName: node linkType: hard @@ -1498,13 +1500,13 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/types@npm:3.609.0, @aws-sdk/types@npm:^3.222.0, @aws-sdk/types@npm:^3.347.0": - version: 3.609.0 - resolution: "@aws-sdk/types@npm:3.609.0" +"@aws-sdk/types@npm:3.649.0, @aws-sdk/types@npm:^3.222.0, @aws-sdk/types@npm:^3.347.0": + version: 3.649.0 + resolution: "@aws-sdk/types@npm:3.649.0" dependencies: - "@smithy/types": ^3.3.0 + "@smithy/types": ^3.4.0 tslib: ^2.6.2 - checksum: 522768d08f104065b0ff6a37eddaa7803186014acee1c0011b3dbd3ef841e47ae694e58f608aeec8a39d22d644d759ade996fe51d18b880617778dc2dbbe1ede + checksum: d8a7ee318474a9e918cbc56ec25e9fb3518bb5f559c785986a8f336b672fa49b259386522d1b2ca828de464b0bb3744bade98e9e75183daa2e762e52d835b4b3 languageName: node linkType: hard @@ -1538,15 +1540,15 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-endpoints@npm:3.637.0": - version: 3.637.0 - resolution: "@aws-sdk/util-endpoints@npm:3.637.0" +"@aws-sdk/util-endpoints@npm:3.649.0": + version: 3.649.0 + resolution: "@aws-sdk/util-endpoints@npm:3.649.0" dependencies: - "@aws-sdk/types": 3.609.0 - "@smithy/types": ^3.3.0 - "@smithy/util-endpoints": ^2.0.5 + "@aws-sdk/types": 3.649.0 + "@smithy/types": ^3.4.0 + "@smithy/util-endpoints": ^2.1.0 tslib: ^2.6.2 - checksum: 55fe86f46f77b3d41ac5c15bbb58b7271175327dc59958ff16a58822ebe26c5ab0bc577dfaaddcbb76466702bee58cd7066eac10d6fa0b43357bddf2cd3dba2f + checksum: 8b87f828dc62aa95d4d31b9e6ec55a7feb0e61132021eb02f7ce0e7f6192b4f57f6e1516ea445eaa6839088b1955cda96042a0551390c804773fdc1a1139318e languageName: node linkType: hard @@ -1598,32 +1600,32 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-user-agent-browser@npm:3.609.0": - version: 3.609.0 - resolution: "@aws-sdk/util-user-agent-browser@npm:3.609.0" +"@aws-sdk/util-user-agent-browser@npm:3.649.0": + version: 3.649.0 + resolution: "@aws-sdk/util-user-agent-browser@npm:3.649.0" dependencies: - "@aws-sdk/types": 3.609.0 - "@smithy/types": ^3.3.0 + "@aws-sdk/types": 3.649.0 + "@smithy/types": ^3.4.0 bowser: ^2.11.0 tslib: ^2.6.2 - checksum: 75ba1ae74dd1001f47870766d92b66ac02a0a488efcf42c1a368962a7978a778d99536e880f07f7db1c2ca66cc9b1863fd3342957a22dcf78bf2f4398265a7a5 + checksum: e4b3b36b6bcf9e6362e0293ce3e6164d251c9d0bdf2cab43853d22e994f3bfab183fa6478fe8b02334886e071c70b17dd4f59a5ae30cf7f33d6def67cae22456 languageName: node linkType: hard -"@aws-sdk/util-user-agent-node@npm:3.614.0": - version: 3.614.0 - resolution: "@aws-sdk/util-user-agent-node@npm:3.614.0" +"@aws-sdk/util-user-agent-node@npm:3.649.0": + version: 3.649.0 + resolution: "@aws-sdk/util-user-agent-node@npm:3.649.0" dependencies: - "@aws-sdk/types": 3.609.0 - "@smithy/node-config-provider": ^3.1.4 - "@smithy/types": ^3.3.0 + "@aws-sdk/types": 3.649.0 + "@smithy/node-config-provider": ^3.1.5 + "@smithy/types": ^3.4.0 tslib: ^2.6.2 peerDependencies: aws-crt: ">=1.0.0" peerDependenciesMeta: aws-crt: optional: true - checksum: 1f010080c2301fd836908963a235ef39e597d959e27461d15d4958fa582ab20795022f8cb7429c183c386f558a5c125cb254a0c4e844dbc6422169f4884be34a + checksum: 1b0c475b1bdff3e8a0d1ae3c2f181477804b30a6018d980019d890db15b223a293316e93d5233c6ca6628aba80aeb2f92474b81630fd1401a8bffd9307db57d7 languageName: node linkType: hard @@ -1646,13 +1648,13 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/xml-builder@npm:3.609.0": - version: 3.609.0 - resolution: "@aws-sdk/xml-builder@npm:3.609.0" +"@aws-sdk/xml-builder@npm:3.649.0": + version: 3.649.0 + resolution: "@aws-sdk/xml-builder@npm:3.649.0" dependencies: - "@smithy/types": ^3.3.0 + "@smithy/types": ^3.4.0 tslib: ^2.6.2 - checksum: 0e9c8b7786737ff50a6cf39f7ca9a758897c2db364718364b5dad45f50a33e65bd7801348fd033af60768a5be64b454c3a7e65222e13c70d145e8df6211ca33c + checksum: e44253346ea7092c1526a60775f9d59a7a194b70d65822f5b0f8e03846ab6d127a3df3b56d61237e27e2a6a981a4f8c841b2d162f19ffd7df537e9d07ba04723 languageName: node linkType: hard @@ -1889,7 +1891,7 @@ __metadata: languageName: node linkType: hard -"@babel/core@npm:^7.11.6, @babel/core@npm:^7.12.3, @babel/core@npm:^7.19.6, @babel/core@npm:^7.24.5, @babel/core@npm:^7.24.7": +"@babel/core@npm:^7.11.6, @babel/core@npm:^7.12.3, @babel/core@npm:^7.19.6, @babel/core@npm:^7.24.7, @babel/core@npm:^7.25.2": version: 7.25.2 resolution: "@babel/core@npm:7.25.2" dependencies: @@ -2973,7 +2975,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-react-jsx-self@npm:^7.24.5": +"@babel/plugin-transform-react-jsx-self@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-react-jsx-self@npm:7.24.7" dependencies: @@ -2984,7 +2986,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-react-jsx-source@npm:^7.24.1": +"@babel/plugin-transform-react-jsx-source@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-react-jsx-source@npm:7.24.7" dependencies: @@ -3388,22 +3390,22 @@ __metadata: languageName: node linkType: hard -"@backstage-community/plugin-explore-common@npm:^0.0.4": - version: 0.0.4 - resolution: "@backstage-community/plugin-explore-common@npm:0.0.4" - checksum: 0c27253dd79dcb56236d382f7591e20eb87f374878b091a690b3fede23ff652aefa3b074a58bd5b51462cc44faab12a97ee82443dcc6106f121212417b9c4cf9 +"@backstage-community/plugin-explore-common@npm:^0.0.5": + version: 0.0.5 + resolution: "@backstage-community/plugin-explore-common@npm:0.0.5" + checksum: b849c1b2cb4cd2221dc5a7f6e3ea2d00cea529d27f2de074159b9eef5aa5d538e28f32e57878a97bdda7f0242d82a56cbfc42f52c2bdb02f455c7a0d232ecfeb languageName: node linkType: hard "@backstage-community/plugin-puppetdb@npm:^0.1.18": - version: 0.1.20 - resolution: "@backstage-community/plugin-puppetdb@npm:0.1.20" + version: 0.1.21 + resolution: "@backstage-community/plugin-puppetdb@npm:0.1.21" dependencies: - "@backstage/catalog-model": ^1.6.0 - "@backstage/core-components": ^0.14.10 - "@backstage/core-plugin-api": ^1.9.3 + "@backstage/catalog-model": ^1.7.0 + "@backstage/core-components": ^0.15.0 + "@backstage/core-plugin-api": ^1.9.4 "@backstage/errors": ^1.2.4 - "@backstage/plugin-catalog-react": ^1.12.3 + "@backstage/plugin-catalog-react": ^1.13.1 "@material-ui/core": ^4.12.2 "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react-use: ^17.2.4 @@ -3411,16 +3413,16 @@ __metadata: react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: 231855a135575bdc6eb92890602589adcf82c5eabaec7dfaef456c598454d8d05e2484ee80c3684824a9b52f62ce313d5e780722ae0553c3742ec7a89ec558c7 + checksum: 35ba13300ef26f705ebd7844bfb8e6dc9bda4db5a4d92d09a9d1dbff52c73a5c4175081fd6b3ef4612cb6018250eedd4e7e1db63b9f1339f723866813dae1595 languageName: node linkType: hard "@backstage-community/plugin-stackstorm@npm:^0.1.16": - version: 0.1.18 - resolution: "@backstage-community/plugin-stackstorm@npm:0.1.18" + version: 0.1.19 + resolution: "@backstage-community/plugin-stackstorm@npm:0.1.19" dependencies: - "@backstage/core-components": ^0.14.10 - "@backstage/core-plugin-api": ^1.9.3 + "@backstage/core-components": ^0.15.0 + "@backstage/core-plugin-api": ^1.9.4 "@backstage/errors": ^1.2.4 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -3430,7 +3432,7 @@ __metadata: react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: 9a11e4ee8c6e28df83658b91efa27d41808664a19b71b874b7a3eaa1a6befa1733f92ed14902f291e8050cc78a879357ab2fd0b37042cad9f0953d78953fcfd5 + checksum: 861f59dbdc65e8ed9cb0bbcf08761ce7ae4cc5e43b548e95e99d3411930e77ff946cf6498212d8e3347b1d95feeb2df2777c02f606e9fe224ed22e261e1e2a1d languageName: node linkType: hard @@ -3448,12 +3450,19 @@ __metadata: "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^15.0.0 - "@types/react": ^16.13.1 || ^17.0.0 + "@testing-library/react": ^16.0.0 + "@types/react": ^18.0.0 + react: ^18.0.2 + react-dom: ^18.0.2 + react-router-dom: ^6.3.0 peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft @@ -3461,7 +3470,7 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/backend-app-api@workspace:packages/backend-app-api" dependencies: - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": ^0.25.0 "@backstage/backend-defaults": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" @@ -3498,10 +3507,10 @@ __metadata: msw: ^1.0.0 node-fetch: ^2.7.0 node-forge: ^1.3.1 - path-to-regexp: ^6.2.1 + path-to-regexp: ^8.0.0 selfsigned: ^2.0.0 stoppable: ^1.1.0 - supertest: ^6.1.3 + supertest: ^7.0.0 triple-beam: ^1.4.1 uuid: ^9.0.0 winston: ^3.2.1 @@ -3509,56 +3518,38 @@ __metadata: languageName: unknown linkType: soft -"@backstage/backend-common@workspace:^, @backstage/backend-common@workspace:packages/backend-common": - version: 0.0.0-use.local - resolution: "@backstage/backend-common@workspace:packages/backend-common" +"@backstage/backend-common@npm:^0.25.0": + version: 0.25.0 + resolution: "@backstage/backend-common@npm:0.25.0" dependencies: "@aws-sdk/abort-controller": ^3.347.0 "@aws-sdk/client-codecommit": ^3.350.0 "@aws-sdk/client-s3": ^3.350.0 "@aws-sdk/credential-providers": ^3.350.0 "@aws-sdk/types": ^3.347.0 - "@aws-sdk/util-stream-node": ^3.350.0 - "@backstage/backend-dev-utils": "workspace:^" - "@backstage/backend-plugin-api": "workspace:^" - "@backstage/backend-test-utils": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/cli-common": "workspace:^" - "@backstage/config": "workspace:^" - "@backstage/config-loader": "workspace:^" - "@backstage/errors": "workspace:^" - "@backstage/integration": "workspace:^" - "@backstage/integration-aws-node": "workspace:^" - "@backstage/plugin-auth-node": "workspace:^" - "@backstage/types": "workspace:^" + "@backstage/backend-dev-utils": ^0.1.5 + "@backstage/backend-plugin-api": ^1.0.0 + "@backstage/cli-common": ^0.1.14 + "@backstage/config": ^1.2.0 + "@backstage/config-loader": ^1.9.1 + "@backstage/errors": ^1.2.4 + "@backstage/integration": ^1.15.0 + "@backstage/integration-aws-node": ^0.1.12 + "@backstage/plugin-auth-node": ^0.5.2 + "@backstage/types": ^1.1.1 "@google-cloud/storage": ^7.0.0 "@keyv/memcache": ^1.3.5 "@keyv/redis": ^2.5.3 "@kubernetes/client-node": 0.20.0 "@manypkg/get-packages": ^1.1.3 "@octokit/rest": ^19.0.3 - "@types/archiver": ^6.0.0 - "@types/base64-stream": ^1.0.2 - "@types/compression": ^1.7.0 - "@types/concat-stream": ^2.0.0 "@types/cors": ^2.8.6 "@types/dockerode": ^3.3.0 "@types/express": ^4.17.6 - "@types/fs-extra": ^11.0.0 - "@types/http-errors": ^2.0.0 "@types/luxon": ^3.0.0 - "@types/morgan": ^1.9.0 - "@types/node-forge": ^1.3.0 - "@types/pg": ^8.6.6 - "@types/stoppable": ^1.1.0 - "@types/supertest": ^2.0.8 - "@types/tar": ^6.1.1 "@types/webpack-env": ^1.15.2 - "@types/yauzl": ^2.10.0 - archiver: ^6.0.0 - aws-sdk-client-mock: ^4.0.0 + archiver: ^7.0.0 base64-stream: ^1.0.0 - better-sqlite3: ^11.0.0 compression: ^1.7.4 concat-stream: ^2.0.0 cors: ^2.8.5 @@ -3568,7 +3559,6 @@ __metadata: fs-extra: ^11.2.0 git-url-parse: ^14.0.0 helmet: ^6.0.0 - http-errors: ^2.0.0 isomorphic-git: ^1.23.0 jose: ^5.0.0 keyv: ^4.5.2 @@ -3579,18 +3569,16 @@ __metadata: minimatch: ^9.0.0 minimist: ^1.2.5 morgan: ^1.10.0 - msw: ^1.0.0 mysql2: ^3.0.0 node-fetch: ^2.7.0 node-forge: ^1.3.1 p-limit: ^3.1.0 - path-to-regexp: ^6.2.1 + path-to-regexp: ^8.0.0 pg: ^8.11.3 pg-format: ^1.0.4 raw-body: ^2.4.1 selfsigned: ^2.0.0 stoppable: ^1.1.0 - supertest: ^6.1.3 tar: ^6.1.12 triple-beam: ^1.4.1 uuid: ^9.0.0 @@ -3603,8 +3591,9 @@ __metadata: peerDependenciesMeta: pg-connection-string: optional: true - languageName: unknown - linkType: soft + checksum: 34d2b92b5fd7f6d8f25975d121634079586d022665a51b676ba47053050e0f22556f80d59a75a10e0a8f1803a718448b7aed4bd1dcd6f1d348785c97cf5a8c9d + languageName: node + linkType: hard "@backstage/backend-defaults@workspace:^, @backstage/backend-defaults@workspace:packages/backend-defaults": version: 0.0.0-use.local @@ -3617,7 +3606,7 @@ __metadata: "@aws-sdk/types": ^3.347.0 "@aws-sdk/util-stream-node": ^3.350.0 "@backstage/backend-app-api": "workspace:^" - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": ^0.25.0 "@backstage/backend-dev-utils": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" @@ -3639,6 +3628,9 @@ __metadata: "@manypkg/get-packages": ^1.1.3 "@octokit/rest": ^19.0.3 "@opentelemetry/api": ^1.3.0 + "@types/archiver": ^6.0.0 + "@types/base64-stream": ^1.0.2 + "@types/concat-stream": ^2.0.0 "@types/cors": ^2.8.6 "@types/express": ^4.17.6 "@types/http-errors": ^2.0.0 @@ -3646,7 +3638,8 @@ __metadata: "@types/node-forge": ^1.3.0 "@types/pg-format": ^1.0.5 "@types/stoppable": ^1.1.0 - archiver: ^6.0.0 + "@types/yauzl": ^2.10.0 + archiver: ^7.0.0 aws-sdk-client-mock: ^4.0.0 base64-stream: ^1.0.0 better-sqlite3: ^11.0.0 @@ -3676,14 +3669,14 @@ __metadata: node-fetch: ^2.7.0 node-forge: ^1.3.1 p-limit: ^3.1.0 - path-to-regexp: ^6.2.1 + path-to-regexp: ^8.0.0 pg: ^8.11.3 pg-connection-string: ^2.3.0 pg-format: ^1.0.4 raw-body: ^2.4.1 selfsigned: ^2.0.0 stoppable: ^1.1.0 - supertest: ^6.1.3 + supertest: ^7.0.0 tar: ^6.1.12 triple-beam: ^1.4.1 uuid: ^9.0.0 @@ -3696,7 +3689,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/backend-dev-utils@workspace:^, @backstage/backend-dev-utils@workspace:packages/backend-dev-utils": +"@backstage/backend-dev-utils@^0.1.5, @backstage/backend-dev-utils@workspace:^, @backstage/backend-dev-utils@workspace:packages/backend-dev-utils": version: 0.0.0-use.local resolution: "@backstage/backend-dev-utils@workspace:packages/backend-dev-utils" dependencies: @@ -3709,7 +3702,7 @@ __metadata: resolution: "@backstage/backend-dynamic-feature-service@workspace:packages/backend-dynamic-feature-service" dependencies: "@backstage/backend-app-api": "workspace:^" - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": ^0.25.0 "@backstage/backend-defaults": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" @@ -3757,10 +3750,29 @@ __metadata: lodash: ^4.17.21 openapi-merge: ^1.3.2 openapi3-ts: ^3.1.2 - supertest: ^6.1.3 + supertest: ^7.0.0 languageName: unknown linkType: soft +"@backstage/backend-plugin-api@npm:^1.0.0": + version: 1.0.0 + resolution: "@backstage/backend-plugin-api@npm:1.0.0" + dependencies: + "@backstage/cli-common": ^0.1.14 + "@backstage/config": ^1.2.0 + "@backstage/errors": ^1.2.4 + "@backstage/plugin-auth-node": ^0.5.2 + "@backstage/plugin-permission-common": ^0.8.1 + "@backstage/types": ^1.1.1 + "@types/express": ^4.17.6 + "@types/luxon": ^3.0.0 + express: ^4.17.1 + knex: ^3.0.0 + luxon: ^3.0.0 + checksum: b18b93fb631a81826ef9049567c5a151285d643aea820954f03e3a293d75f00ae679b2d3054fab2cf9dff476a65fad5b8841ca608b2f182f394b22dca026664a + languageName: node + linkType: hard + "@backstage/backend-plugin-api@workspace:^, @backstage/backend-plugin-api@workspace:packages/backend-plugin-api": version: 0.0.0-use.local resolution: "@backstage/backend-plugin-api@workspace:packages/backend-plugin-api" @@ -3811,7 +3823,7 @@ __metadata: mysql2: ^3.0.0 pg: ^8.11.3 pg-connection-string: ^2.3.0 - supertest: ^6.1.3 + supertest: ^7.0.0 testcontainers: ^10.0.0 textextensions: ^5.16.0 uuid: ^9.0.0 @@ -3821,19 +3833,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/catalog-client@npm:^1.6.6": - version: 1.6.6 - resolution: "@backstage/catalog-client@npm:1.6.6" - dependencies: - "@backstage/catalog-model": ^1.6.0 - "@backstage/errors": ^1.2.4 - cross-fetch: ^4.0.0 - uri-template: ^2.0.0 - checksum: 10a859979a6ec3d9bcca519ace01ca371517e56bd54a90e0d667b4ef90bee54b09495238974b4040d7dc75f8cacf0d212900b40fe6738d484ff57a739e3eec4b - languageName: node - linkType: hard - -"@backstage/catalog-client@workspace:^, @backstage/catalog-client@workspace:packages/catalog-client": +"@backstage/catalog-client@^1.7.0, @backstage/catalog-client@workspace:^, @backstage/catalog-client@workspace:packages/catalog-client": version: 0.0.0-use.local resolution: "@backstage/catalog-client@workspace:packages/catalog-client" dependencies: @@ -3846,7 +3846,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/catalog-model@^1.4.3, @backstage/catalog-model@^1.6.0, @backstage/catalog-model@workspace:^, @backstage/catalog-model@workspace:packages/catalog-model": +"@backstage/catalog-model@^1.4.3, @backstage/catalog-model@^1.7.0, @backstage/catalog-model@workspace:^, @backstage/catalog-model@workspace:packages/catalog-model": version: 0.0.0-use.local resolution: "@backstage/catalog-model@workspace:packages/catalog-model" dependencies: @@ -3861,7 +3861,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/cli-common@workspace:^, @backstage/cli-common@workspace:packages/cli-common": +"@backstage/cli-common@^0.1.14, @backstage/cli-common@workspace:^, @backstage/cli-common@workspace:packages/cli-common": version: 0.0.0-use.local resolution: "@backstage/cli-common@workspace:packages/cli-common" dependencies: @@ -3891,7 +3891,7 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/cli@workspace:packages/cli" dependencies: - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": ^0.25.0 "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" "@backstage/catalog-model": "workspace:^" @@ -3911,13 +3911,13 @@ __metadata: "@backstage/theme": "workspace:^" "@backstage/types": "workspace:^" "@manypkg/get-packages": ^1.1.3 - "@module-federation/enhanced": ^0.3.5 + "@module-federation/enhanced": ^0.6.0 "@octokit/graphql": ^5.0.0 "@octokit/graphql-schema": ^13.7.0 "@octokit/oauth-app": ^4.2.0 "@octokit/request": ^6.0.0 "@pmmmwh/react-refresh-webpack-plugin": ^0.5.7 - "@rollup/plugin-commonjs": ^25.0.0 + "@rollup/plugin-commonjs": ^26.0.0 "@rollup/plugin-json": ^6.0.0 "@rollup/plugin-node-resolve": ^15.0.0 "@rollup/plugin-yaml": ^4.0.0 @@ -3934,7 +3934,6 @@ __metadata: "@swc/helpers": ^0.5.0 "@swc/jest": ^0.2.22 "@types/cross-spawn": ^6.0.2 - "@types/diff": ^5.0.0 "@types/ejs": ^3.1.3 "@types/express": ^4.17.6 "@types/fs-extra": ^11.0.0 @@ -3953,7 +3952,7 @@ __metadata: "@types/yarnpkg__lockfile": ^1.1.4 "@typescript-eslint/eslint-plugin": ^6.12.0 "@typescript-eslint/parser": ^6.7.2 - "@vitejs/plugin-react": ^4.0.4 + "@vitejs/plugin-react": ^4.3.1 "@yarnpkg/lockfile": ^1.1.0 "@yarnpkg/parsers": ^3.0.0 bfj: ^8.0.0 @@ -3966,7 +3965,6 @@ __metadata: css-loader: ^6.5.1 ctrlc-windows: ^2.1.0 del: ^7.0.0 - diff: ^5.0.0 esbuild: ^0.23.0 esbuild-loader: ^4.0.0 eslint: ^8.6.0 @@ -3974,7 +3972,7 @@ __metadata: eslint-formatter-friendly: ^7.0.0 eslint-plugin-deprecation: ^2.0.0 eslint-plugin-import: ^2.25.4 - eslint-plugin-jest: ^27.0.0 + eslint-plugin-jest: ^28.0.0 eslint-plugin-jsx-a11y: ^6.5.1 eslint-plugin-react: ^7.28.0 eslint-plugin-react-hooks: ^4.3.0 @@ -4025,9 +4023,10 @@ __metadata: swc-loader: ^0.2.3 tar: ^6.1.12 terser-webpack-plugin: ^5.1.3 + ts-morph: ^23.0.0 util: ^0.12.3 - vite: ^4.4.9 - vite-plugin-html: ^3.2.0 + vite: ^5.0.0 + vite-plugin-html: ^3.2.2 vite-plugin-node-polyfills: ^0.22.0 webpack: ^5.70.0 webpack-dev-server: ^5.0.0 @@ -4037,9 +4036,9 @@ __metadata: yn: ^4.0.0 zod: ^3.22.4 peerDependencies: - "@vitejs/plugin-react": ^4.0.4 - vite: ^4.4.9 - vite-plugin-html: ^3.2.0 + "@vitejs/plugin-react": ^4.3.1 + vite: ^5.0.0 + vite-plugin-html: ^3.2.2 vite-plugin-node-polyfills: ^0.22.0 peerDependenciesMeta: "@vitejs/plugin-react": @@ -4072,7 +4071,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/config-loader@workspace:^, @backstage/config-loader@workspace:packages/config-loader": +"@backstage/config-loader@^1.9.1, @backstage/config-loader@workspace:^, @backstage/config-loader@workspace:packages/config-loader": version: 0.0.0-use.local resolution: "@backstage/config-loader@workspace:packages/config-loader" dependencies: @@ -4094,7 +4093,7 @@ __metadata: minimist: ^1.2.5 msw: ^1.0.0 node-fetch: ^2.7.0 - typescript-json-schema: ^0.63.0 + typescript-json-schema: ^0.65.0 yaml: ^2.0.0 zen-observable: ^0.10.0 languageName: unknown @@ -4123,18 +4122,21 @@ __metadata: "@backstage/version-bridge": "workspace:^" "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^15.0.0 + "@testing-library/react": ^16.0.0 "@testing-library/react-hooks": ^8.0.0 "@testing-library/user-event": ^14.0.0 "@types/prop-types": ^15.7.3 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + "@types/react": ^18.0.0 "@types/zen-observable": ^0.8.0 history: ^5.0.0 i18next: ^22.4.15 lodash: ^4.17.21 msw: ^1.0.0 prop-types: ^15.7.2 + react: ^18.0.2 + react-dom: ^18.0.2 react-router-beta: "npm:react-router@6.0.0-beta.0" + react-router-dom: ^6.3.0 react-router-dom-beta: "npm:react-router-dom@6.0.0-beta.0" react-router-dom-stable: "npm:react-router-dom@^6.3.0" react-router-stable: "npm:react-router@^6.3.0" @@ -4142,25 +4144,29 @@ __metadata: zen-observable: ^0.10.0 zod: ^3.22.4 peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft -"@backstage/core-compat-api@npm:^0.2.8": - version: 0.2.8 - resolution: "@backstage/core-compat-api@npm:0.2.8" +"@backstage/core-compat-api@npm:^0.3.0": + version: 0.3.0 + resolution: "@backstage/core-compat-api@npm:0.3.0" dependencies: - "@backstage/core-plugin-api": ^1.9.3 - "@backstage/frontend-plugin-api": ^0.7.0 - "@backstage/version-bridge": ^1.0.8 + "@backstage/core-plugin-api": ^1.9.4 + "@backstage/frontend-plugin-api": ^0.8.0 + "@backstage/version-bridge": ^1.0.9 "@types/react": ^16.13.1 || ^17.0.0 lodash: ^4.17.21 peerDependencies: react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: 3f0cdb7f2b68f9a173128438b8d5cad460f434b3811db9bda2ae356000a736103971e13fb4d6ab893ed44fcbede9c8e464f381b025d05f468773aa2f9790eb50 + checksum: ff9f662a007c07dc1353e376ef2c40abac84123c1442f8d4307e0f98c050d8f9b4fab4f043538014d740c2d18ef7c682df12cc4f26d0c58aca0f42413e86a001 languageName: node linkType: hard @@ -4178,15 +4184,25 @@ __metadata: "@backstage/frontend-test-utils": "workspace:^" "@backstage/plugin-catalog": "workspace:^" "@backstage/test-utils": "workspace:^" + "@backstage/types": "workspace:^" "@backstage/version-bridge": "workspace:^" "@oriflame/backstage-plugin-score-card": ^0.8.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^15.0.0 - "@types/react": ^16.13.1 || ^17.0.0 + "@testing-library/react": ^16.0.0 + "@types/react": ^18.0.0 lodash: ^4.17.21 + react: ^18.0.2 + react-dom: ^18.0.2 + react-router-dom: ^6.3.0 + zod: ^3.22.4 peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft @@ -4241,15 +4257,15 @@ __metadata: languageName: node linkType: hard -"@backstage/core-components@npm:^0.14.10": - version: 0.14.10 - resolution: "@backstage/core-components@npm:0.14.10" +"@backstage/core-components@npm:^0.15.0": + version: 0.15.0 + resolution: "@backstage/core-components@npm:0.15.0" dependencies: "@backstage/config": ^1.2.0 - "@backstage/core-plugin-api": ^1.9.3 + "@backstage/core-plugin-api": ^1.9.4 "@backstage/errors": ^1.2.4 - "@backstage/theme": ^0.5.6 - "@backstage/version-bridge": ^1.0.8 + "@backstage/theme": ^0.5.7 + "@backstage/version-bridge": ^1.0.9 "@date-io/core": ^1.3.13 "@material-table/core": ^3.1.0 "@material-ui/core": ^4.12.2 @@ -4286,7 +4302,7 @@ __metadata: react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: 303682d411b846a4892b27c1064d499dbd4eccb5a3cdc5acbb1d3247e1141f4704efc7bd286744c19818487e52a61891943156817f59e3bd6555926f7331f575 + checksum: 98887230c4475ab29795aced0ac156be828517553a61a6fc59ec058928cfc3c63e9410523f4c49cbf893268469a9c28b1bdce3311b888f06263e069987255d25 languageName: node linkType: hard @@ -4311,7 +4327,7 @@ __metadata: "@react-hookz/web": ^24.0.0 "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^15.0.0 + "@testing-library/react": ^16.0.0 "@testing-library/user-event": ^14.0.0 "@types/ansi-regex": ^5.0.0 "@types/classnames": ^2.2.9 @@ -4320,7 +4336,7 @@ __metadata: "@types/d3-zoom": ^3.0.1 "@types/dagre": ^0.7.44 "@types/google-protobuf": ^3.7.2 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + "@types/react": ^18.0.0 "@types/react-helmet": ^6.1.0 "@types/react-sparklines": ^1.7.0 "@types/react-syntax-highlighter": ^15.0.0 @@ -4342,10 +4358,13 @@ __metadata: pluralize: ^8.0.0 qs: ^6.9.4 rc-progress: 3.5.1 + react: ^18.0.2 + react-dom: ^18.0.2 react-helmet: 6.1.0 react-hook-form: ^7.12.2 react-idle-timer: 5.7.2 react-markdown: ^8.0.0 + react-router-dom: ^6.3.0 react-sparklines: ^1.7.0 react-syntax-highlighter: ^15.4.5 react-use: ^17.3.2 @@ -4355,13 +4374,35 @@ __metadata: zen-observable: ^0.10.0 zod: ^3.22.4 peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft -"@backstage/core-plugin-api@^1.8.2, @backstage/core-plugin-api@^1.9.3, @backstage/core-plugin-api@workspace:^, @backstage/core-plugin-api@workspace:packages/core-plugin-api": +"@backstage/core-plugin-api@npm:^1.8.2, @backstage/core-plugin-api@npm:^1.9.4": + version: 1.9.4 + resolution: "@backstage/core-plugin-api@npm:1.9.4" + dependencies: + "@backstage/config": ^1.2.0 + "@backstage/errors": ^1.2.4 + "@backstage/types": ^1.1.1 + "@backstage/version-bridge": ^1.0.9 + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + history: ^5.0.0 + peerDependencies: + react: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-router-dom: 6.0.0-beta.0 || ^6.3.0 + checksum: 921b1185a2b68363f2cfe66f5cfa003c2f56abb252f75b0d37d49eb586d5e1347d34e846eb72bab71df5f478f106de1fe7e0e05876e559e2c28b23d849994910 + languageName: node + linkType: hard + +"@backstage/core-plugin-api@workspace:^, @backstage/core-plugin-api@workspace:packages/core-plugin-api": version: 0.0.0-use.local resolution: "@backstage/core-plugin-api@workspace:packages/core-plugin-api" dependencies: @@ -4374,14 +4415,21 @@ __metadata: "@backstage/version-bridge": "workspace:^" "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^15.0.0 + "@testing-library/react": ^16.0.0 "@testing-library/user-event": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + "@types/react": ^18.0.0 history: ^5.0.0 + react: ^18.0.2 + react-dom: ^18.0.2 + react-router-dom: ^6.3.0 peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft @@ -4430,15 +4478,22 @@ __metadata: "@material-ui/icons": ^4.9.1 "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^15.0.0 + "@testing-library/react": ^16.0.0 "@testing-library/user-event": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + "@types/react": ^18.0.0 + react: ^18.0.2 + react-dom: ^18.0.2 + react-router-dom: ^6.3.0 react-use: ^17.2.4 zen-observable: ^0.10.0 peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft @@ -4497,12 +4552,21 @@ __metadata: "@backstage/types": "workspace:^" "@backstage/version-bridge": "workspace:^" "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^15.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + "@testing-library/react": ^16.0.0 + "@types/react": ^18.0.0 lodash: ^4.17.21 + react: ^18.0.2 + react-dom: ^18.0.2 + react-router-dom: ^6.3.0 + zod: ^3.22.4 peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft @@ -4520,21 +4584,30 @@ __metadata: "@backstage/test-utils": "workspace:^" "@react-hookz/web": ^24.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^15.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + "@testing-library/react": ^16.0.0 + "@types/react": ^18.0.0 + react: ^18.0.2 + react-dom: ^18.0.2 + react-router-dom: ^6.3.0 peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft -"@backstage/frontend-plugin-api@npm:^0.7.0": - version: 0.7.0 - resolution: "@backstage/frontend-plugin-api@npm:0.7.0" +"@backstage/frontend-plugin-api@npm:^0.8.0": + version: 0.8.0 + resolution: "@backstage/frontend-plugin-api@npm:0.8.0" dependencies: - "@backstage/core-components": ^0.14.10 - "@backstage/core-plugin-api": ^1.9.3 + "@backstage/core-components": ^0.15.0 + "@backstage/core-plugin-api": ^1.9.4 "@backstage/types": ^1.1.1 - "@backstage/version-bridge": ^1.0.8 + "@backstage/version-bridge": ^1.0.9 "@material-ui/core": ^4.12.4 "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 lodash: ^4.17.21 @@ -4543,7 +4616,7 @@ __metadata: peerDependencies: react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: 11d11db0af0d57014f9c16de37a1871d951ec70cdda70b8f25d4a52d46cdbccaf8c94656c6d2c939689c9b3e4fb668d96becfd58d1c00f1e33c39cf9bad97d4a + checksum: 2880ba13514c4620cad030e9a98d98076636e89e9cbb2aec2c44605d1b14774a9388eb43bde52f51c32070d5137134fcb5a059c1080194154dad9673ef11cf5f languageName: node linkType: hard @@ -4561,15 +4634,23 @@ __metadata: "@backstage/version-bridge": "workspace:^" "@material-ui/core": ^4.12.4 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^15.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + "@testing-library/react": ^16.0.0 + "@types/react": ^18.0.0 history: ^5.3.0 lodash: ^4.17.21 + react: ^18.0.2 + react-dom: ^18.0.2 + react-router-dom: ^6.3.0 zod: ^3.22.4 zod-to-json-schema: ^3.21.4 peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft @@ -4584,16 +4665,26 @@ __metadata: "@backstage/plugin-app": "workspace:^" "@backstage/test-utils": "workspace:^" "@backstage/types": "workspace:^" + "@backstage/version-bridge": "workspace:^" "@testing-library/jest-dom": ^6.0.0 - "@types/react": "*" + "@types/react": ^18.0.0 + react: ^18.0.2 + react-dom: ^18.0.2 + react-router-dom: ^6.3.0 + zod: ^3.22.4 peerDependencies: - "@testing-library/react": ^15.0.0 + "@testing-library/react": ^16.0.0 + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft -"@backstage/integration-aws-node@workspace:^, @backstage/integration-aws-node@workspace:packages/integration-aws-node": +"@backstage/integration-aws-node@^0.1.12, @backstage/integration-aws-node@workspace:^, @backstage/integration-aws-node@workspace:packages/integration-aws-node": version: 0.0.0-use.local resolution: "@backstage/integration-aws-node@workspace:packages/integration-aws-node" dependencies: @@ -4612,7 +4703,25 @@ __metadata: languageName: unknown linkType: soft -"@backstage/integration-react@^1.1.30, @backstage/integration-react@workspace:^, @backstage/integration-react@workspace:packages/integration-react": +"@backstage/integration-react@npm:^1.1.32": + version: 1.1.32 + resolution: "@backstage/integration-react@npm:1.1.32" + dependencies: + "@backstage/config": ^1.2.0 + "@backstage/core-plugin-api": ^1.9.4 + "@backstage/integration": ^1.15.0 + "@material-ui/core": ^4.12.2 + "@material-ui/icons": ^4.9.1 + "@types/react": ^16.13.1 || ^17.0.0 + peerDependencies: + react: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-router-dom: 6.0.0-beta.0 || ^6.3.0 + checksum: d26362ad3a8a6c8ac41b3eadf9c6d5b01e3cef3ca3e38a86bbf7b1c5e1b6e8ba5e940e74d31006faf0640a366ba8c5deb0ca6cbc58099d5f51fae6a7484944d6 + languageName: node + linkType: hard + +"@backstage/integration-react@workspace:^, @backstage/integration-react@workspace:packages/integration-react": version: 0.0.0-use.local resolution: "@backstage/integration-react@workspace:packages/integration-react" dependencies: @@ -4627,15 +4736,39 @@ __metadata: "@material-ui/icons": ^4.9.1 "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@types/react": ^16.13.1 || ^17.0.0 + "@types/react": ^18.0.0 msw: ^1.0.0 + react: ^18.0.2 + react-dom: ^18.0.2 + react-router-dom: ^6.3.0 peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft +"@backstage/integration@npm:^1.15.0": + version: 1.15.0 + resolution: "@backstage/integration@npm:1.15.0" + dependencies: + "@azure/identity": ^4.0.0 + "@backstage/config": ^1.2.0 + "@backstage/errors": ^1.2.4 + "@octokit/auth-app": ^4.0.0 + "@octokit/rest": ^19.0.3 + cross-fetch: ^4.0.0 + git-url-parse: ^14.0.0 + lodash: ^4.17.21 + luxon: ^3.0.0 + checksum: a2c5b51b1403341f56fe91bd53a1105875855642927b95277c3e8ea29d604b718c39984fd2b8cd298d6206d1f23718da10dbbb53f4ec6eb74b296e6621fc4b7e + languageName: node + linkType: hard + "@backstage/integration@workspace:^, @backstage/integration@workspace:packages/integration": version: 0.0.0-use.local resolution: "@backstage/integration@workspace:packages/integration" @@ -4662,12 +4795,19 @@ __metadata: dependencies: "@backstage/cli": "workspace:^" "@testing-library/jest-dom": ^6.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + "@types/react": ^18.0.0 grpc-docs: ^1.1.2 + react: ^18.0.2 + react-dom: ^18.0.2 + react-router-dom: ^6.3.0 peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft @@ -4695,21 +4835,28 @@ __metadata: "@material-ui/lab": 4.0.0-alpha.61 "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^15.0.0 + "@testing-library/react": ^16.0.0 "@testing-library/user-event": ^14.0.0 "@types/highlightjs": ^10.1.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + "@types/react": ^18.0.0 "@types/swagger-ui-react": ^4.18.0 graphiql: 3.1.1 graphql: ^16.0.0 graphql-config: ^5.0.2 graphql-ws: ^5.4.1 isomorphic-form-data: ^2.0.0 + react: ^18.0.2 + react-dom: ^18.0.2 + react-router-dom: ^6.3.0 swagger-ui-react: ^5.0.0 peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft @@ -4718,7 +4865,7 @@ __metadata: resolution: "@backstage/plugin-app-backend@workspace:plugins/app-backend" dependencies: "@backstage/backend-app-api": "workspace:^" - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": ^0.25.0 "@backstage/backend-defaults": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" @@ -4740,7 +4887,7 @@ __metadata: lodash: ^4.17.21 luxon: ^3.0.0 node-fetch: ^2.7.0 - supertest: ^6.1.3 + supertest: ^7.0.0 yn: ^4.0.0 languageName: unknown linkType: soft @@ -4768,11 +4915,18 @@ __metadata: "@backstage/frontend-plugin-api": "workspace:^" "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 - "@types/react": ^16.13.1 || ^17.0.0 + "@types/react": ^18.0.0 + react: ^18.0.2 + react-dom: ^18.0.2 + react-router-dom: ^6.3.0 peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft @@ -4792,15 +4946,22 @@ __metadata: "@material-ui/icons": ^4.9.1 "@material-ui/lab": ^4.0.0-alpha.61 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^15.0.0 + "@testing-library/react": ^16.0.0 "@testing-library/user-event": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + "@types/react": ^18.0.0 msw: ^1.0.0 - react: ^16.13.1 || ^17.0.0 || ^18.0.0 + react: ^18.0.2 + react-dom: ^18.0.2 + react-router-dom: ^6.3.0 react-use: ^17.2.4 peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft @@ -4817,7 +4978,26 @@ __metadata: express: ^4.18.2 passport: ^0.7.0 passport-atlassian-oauth2: ^2.1.0 - supertest: ^6.3.3 + supertest: ^7.0.0 + languageName: unknown + linkType: soft + +"@backstage/plugin-auth-backend-module-auth0-provider@workspace:^, @backstage/plugin-auth-backend-module-auth0-provider@workspace:plugins/auth-backend-module-auth0-provider": + version: 0.0.0-use.local + resolution: "@backstage/plugin-auth-backend-module-auth0-provider@workspace:plugins/auth-backend-module-auth0-provider" + dependencies: + "@backstage/backend-defaults": "workspace:^" + "@backstage/backend-plugin-api": "workspace:^" + "@backstage/backend-test-utils": "workspace:^" + "@backstage/cli": "workspace:^" + "@backstage/plugin-auth-backend": "workspace:^" + "@backstage/plugin-auth-node": "workspace:^" + "@types/passport-auth0": ^1.0.5 + "@types/passport-oauth2": ^1.4.15 + express: ^4.17.1 + passport-auth0: ^1.4.3 + passport-oauth2: ^1.6.1 + supertest: ^7.0.0 languageName: unknown linkType: soft @@ -4825,7 +5005,7 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-auth-backend-module-aws-alb-provider@workspace:plugins/auth-backend-module-aws-alb-provider" dependencies: - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": ^0.25.0 "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" "@backstage/cli": "workspace:^" @@ -4872,7 +5052,25 @@ __metadata: express: ^4.18.2 passport: ^0.7.0 passport-bitbucket-oauth2: ^0.1.2 - supertest: ^6.3.3 + supertest: ^7.0.0 + languageName: unknown + linkType: soft + +"@backstage/plugin-auth-backend-module-bitbucket-server-provider@workspace:^, @backstage/plugin-auth-backend-module-bitbucket-server-provider@workspace:plugins/auth-backend-module-bitbucket-server-provider": + version: 0.0.0-use.local + resolution: "@backstage/plugin-auth-backend-module-bitbucket-server-provider@workspace:plugins/auth-backend-module-bitbucket-server-provider" + dependencies: + "@backstage/backend-defaults": "workspace:^" + "@backstage/backend-plugin-api": "workspace:^" + "@backstage/backend-test-utils": "workspace:^" + "@backstage/cli": "workspace:^" + "@backstage/plugin-auth-backend": "workspace:^" + "@backstage/plugin-auth-node": "workspace:^" + "@types/passport-oauth2": ^1.4.15 + node-fetch: ^2.7.0 + passport: ^0.7.0 + passport-oauth2: ^1.6.1 + supertest: ^7.0.0 languageName: unknown linkType: soft @@ -4924,7 +5122,7 @@ __metadata: "@backstage/plugin-auth-backend": "workspace:^" "@backstage/plugin-auth-node": "workspace:^" passport-github2: ^0.1.12 - supertest: ^6.3.3 + supertest: ^7.0.0 languageName: unknown linkType: soft @@ -4941,7 +5139,7 @@ __metadata: express: ^4.18.2 passport: ^0.7.0 passport-gitlab2: ^5.0.0 - supertest: ^6.3.3 + supertest: ^7.0.0 languageName: unknown linkType: soft @@ -4957,7 +5155,7 @@ __metadata: "@types/passport-google-oauth20": ^2.0.3 google-auth-library: ^9.0.0 passport-google-oauth20: ^2.0.0 - supertest: ^6.1.3 + supertest: ^7.0.0 languageName: unknown linkType: soft @@ -4965,7 +5163,7 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-auth-backend-module-guest-provider@workspace:plugins/auth-backend-module-guest-provider" dependencies: - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": ^0.25.0 "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" "@backstage/catalog-model": "workspace:^" @@ -4995,7 +5193,7 @@ __metadata: msw: ^1.0.0 node-fetch: ^2.7.0 passport-microsoft: ^1.0.0 - supertest: ^6.3.3 + supertest: ^7.0.0 languageName: unknown linkType: soft @@ -5011,7 +5209,7 @@ __metadata: "@backstage/plugin-auth-node": "workspace:^" passport: ^0.7.0 passport-oauth2: ^1.6.1 - supertest: ^6.3.3 + supertest: ^7.0.0 languageName: unknown linkType: soft @@ -5032,7 +5230,7 @@ __metadata: 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-common": ^0.25.0 "@backstage/backend-defaults": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" @@ -5048,7 +5246,7 @@ __metadata: msw: ^1.3.1 openid-client: ^5.5.0 passport: ^0.7.0 - supertest: ^6.3.3 + supertest: ^7.0.0 languageName: unknown linkType: soft @@ -5065,7 +5263,7 @@ __metadata: "@davidzemon/passport-okta-oauth": ^0.0.5 express: ^4.18.2 passport: ^0.7.0 - supertest: ^6.3.3 + supertest: ^7.0.0 languageName: unknown linkType: soft @@ -5082,7 +5280,7 @@ __metadata: express: ^4.18.2 passport: ^0.7.0 passport-onelogin-oauth: ^0.0.1 - supertest: ^6.3.3 + supertest: ^7.0.0 languageName: unknown linkType: soft @@ -5105,7 +5303,7 @@ __metadata: msw: ^1.3.0 openid-client: ^5.4.3 passport: ^0.7.0 - supertest: ^6.3.3 + supertest: ^7.0.0 languageName: unknown linkType: soft @@ -5126,7 +5324,7 @@ __metadata: jose: ^5.0.0 msw: ^2.0.8 passport-oauth2: ^1.6.1 - supertest: ^6.3.3 + supertest: ^7.0.0 languageName: unknown linkType: soft @@ -5134,7 +5332,7 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-auth-backend@workspace:plugins/auth-backend" dependencies: - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": ^0.25.0 "@backstage/backend-defaults": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" @@ -5144,9 +5342,11 @@ __metadata: "@backstage/config": "workspace:^" "@backstage/errors": "workspace:^" "@backstage/plugin-auth-backend-module-atlassian-provider": "workspace:^" + "@backstage/plugin-auth-backend-module-auth0-provider": "workspace:^" "@backstage/plugin-auth-backend-module-aws-alb-provider": "workspace:^" "@backstage/plugin-auth-backend-module-azure-easyauth-provider": "workspace:^" "@backstage/plugin-auth-backend-module-bitbucket-provider": "workspace:^" + "@backstage/plugin-auth-backend-module-bitbucket-server-provider": "workspace:^" "@backstage/plugin-auth-backend-module-cloudflare-access-provider": "workspace:^" "@backstage/plugin-auth-backend-module-gcp-iap-provider": "workspace:^" "@backstage/plugin-auth-backend-module-github-provider": "workspace:^" @@ -5162,7 +5362,7 @@ __metadata: "@backstage/plugin-catalog-node": "workspace:^" "@backstage/types": "workspace:^" "@google-cloud/firestore": ^7.0.0 - "@node-saml/passport-saml": ^4.0.4 + "@node-saml/passport-saml": ^5.0.0 "@types/body-parser": ^1.19.0 "@types/cookie-parser": ^1.4.2 "@types/express": ^4.17.6 @@ -5201,18 +5401,43 @@ __metadata: passport-microsoft: ^1.0.0 passport-oauth2: ^1.6.1 passport-onelogin-oauth: ^0.0.1 - supertest: ^6.1.3 + supertest: ^7.0.0 uuid: ^9.0.0 winston: ^3.2.1 yn: ^4.0.0 languageName: unknown linkType: soft +"@backstage/plugin-auth-node@npm:^0.5.2": + version: 0.5.2 + resolution: "@backstage/plugin-auth-node@npm:0.5.2" + dependencies: + "@backstage/backend-common": ^0.25.0 + "@backstage/backend-plugin-api": ^1.0.0 + "@backstage/catalog-client": ^1.7.0 + "@backstage/catalog-model": ^1.7.0 + "@backstage/config": ^1.2.0 + "@backstage/errors": ^1.2.4 + "@backstage/types": ^1.1.1 + "@types/express": "*" + "@types/passport": ^1.0.3 + express: ^4.17.1 + jose: ^5.0.0 + lodash: ^4.17.21 + node-fetch: ^2.7.0 + passport: ^0.7.0 + winston: ^3.2.1 + zod: ^3.22.4 + zod-to-json-schema: ^3.21.4 + checksum: 4a461ac73368f673bbe4d11a8f74807429f58e5295809e80d63365df57238735f0df8c9a7b33b096b371ddddbc79f02b879c7b42600dc1a22fe85f166095ccea + languageName: node + linkType: hard + "@backstage/plugin-auth-node@workspace:^, @backstage/plugin-auth-node@workspace:plugins/auth-node": version: 0.0.0-use.local resolution: "@backstage/plugin-auth-node@workspace:plugins/auth-node" dependencies: - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": ^0.25.0 "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" "@backstage/catalog-client": "workspace:^" @@ -5231,7 +5456,7 @@ __metadata: msw: ^1.0.0 node-fetch: ^2.7.0 passport: ^0.7.0 - supertest: ^6.1.3 + supertest: ^7.0.0 uuid: ^9.0.0 winston: ^3.2.1 zod: ^3.22.4 @@ -5251,12 +5476,21 @@ __metadata: "@material-ui/core": ^4.9.13 "@react-hookz/web": ^24.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^15.0.0 + "@testing-library/react": ^16.0.0 "@testing-library/user-event": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + "@types/react": ^18.0.0 msw: ^1.0.0 + react: ^18.0.2 + react-dom: ^18.0.2 + react-router-dom: ^6.3.0 peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft @@ -5347,7 +5581,6 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-backend-module-bitbucket-cloud@workspace:plugins/catalog-backend-module-bitbucket-cloud" dependencies: - "@backstage/backend-common": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" "@backstage/catalog-client": "workspace:^" @@ -5440,7 +5673,7 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-backend-module-github@workspace:plugins/catalog-backend-module-github" dependencies: - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": ^0.25.0 "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" "@backstage/catalog-client": "workspace:^" @@ -5469,7 +5702,7 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-backend-module-gitlab-org@workspace:plugins/catalog-backend-module-gitlab-org" dependencies: - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": ^0.25.0 "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" "@backstage/cli": "workspace:^" @@ -5511,7 +5744,7 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-backend-module-incremental-ingestion@workspace:plugins/catalog-backend-module-incremental-ingestion" dependencies: - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": ^0.25.0 "@backstage/backend-defaults": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" @@ -5596,7 +5829,7 @@ __metadata: resolution: "@backstage/plugin-catalog-backend-module-openapi@workspace:plugins/catalog-backend-module-openapi" dependencies: "@apidevtools/json-schema-ref-parser": ^9.0.6 - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": ^0.25.0 "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" "@backstage/catalog-model": "workspace:^" @@ -5652,7 +5885,7 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-backend-module-unprocessed@workspace:plugins/catalog-backend-module-unprocessed" dependencies: - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": ^0.25.0 "@backstage/backend-plugin-api": "workspace:^" "@backstage/catalog-model": "workspace:^" "@backstage/cli": "workspace:^" @@ -5671,7 +5904,7 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-backend@workspace:plugins/catalog-backend" dependencies: - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": ^0.25.0 "@backstage/backend-defaults": "workspace:^" "@backstage/backend-openapi-utils": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" @@ -5714,7 +5947,7 @@ __metadata: node-fetch: ^2.7.0 p-limit: ^3.0.2 prom-client: ^15.0.0 - supertest: ^6.1.3 + supertest: ^7.0.0 uuid: ^9.0.0 wait-for-expect: ^3.0.2 winston: ^3.13.0 @@ -5724,7 +5957,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-catalog-common@^1.0.20, @backstage/plugin-catalog-common@^1.0.26, @backstage/plugin-catalog-common@workspace:^, @backstage/plugin-catalog-common@workspace:plugins/catalog-common": +"@backstage/plugin-catalog-common@^1.0.20, @backstage/plugin-catalog-common@^1.1.0, @backstage/plugin-catalog-common@workspace:^, @backstage/plugin-catalog-common@workspace:plugins/catalog-common": version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-common@workspace:plugins/catalog-common" dependencies: @@ -5757,18 +5990,25 @@ __metadata: "@material-ui/lab": 4.0.0-alpha.61 "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^15.0.0 + "@testing-library/react": ^16.0.0 "@testing-library/user-event": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + "@types/react": ^18.0.0 classnames: ^2.3.1 lodash: ^4.17.15 p-limit: ^3.1.0 qs: ^6.9.4 + react: ^18.0.2 + react-dom: ^18.0.2 + react-router-dom: ^6.3.0 react-use: ^17.2.4 peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft @@ -5799,20 +6039,27 @@ __metadata: "@octokit/rest": ^19.0.3 "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^15.0.0 + "@testing-library/react": ^16.0.0 "@testing-library/user-event": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + "@types/react": ^18.0.0 git-url-parse: ^14.0.0 js-base64: ^3.6.0 lodash: ^4.17.21 msw: ^1.0.0 + react: ^18.0.2 + react-dom: ^18.0.2 react-hook-form: ^7.12.2 + react-router-dom: ^6.3.0 react-use: ^17.2.4 yaml: ^2.0.0 peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft @@ -5833,23 +6080,23 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-catalog-react@npm:^1.12.3, @backstage/plugin-catalog-react@npm:^1.9.3": - version: 1.12.3 - resolution: "@backstage/plugin-catalog-react@npm:1.12.3" +"@backstage/plugin-catalog-react@npm:^1.13.1, @backstage/plugin-catalog-react@npm:^1.9.3": + version: 1.13.1 + resolution: "@backstage/plugin-catalog-react@npm:1.13.1" dependencies: - "@backstage/catalog-client": ^1.6.6 - "@backstage/catalog-model": ^1.6.0 - "@backstage/core-compat-api": ^0.2.8 - "@backstage/core-components": ^0.14.10 - "@backstage/core-plugin-api": ^1.9.3 + "@backstage/catalog-client": ^1.7.0 + "@backstage/catalog-model": ^1.7.0 + "@backstage/core-compat-api": ^0.3.0 + "@backstage/core-components": ^0.15.0 + "@backstage/core-plugin-api": ^1.9.4 "@backstage/errors": ^1.2.4 - "@backstage/frontend-plugin-api": ^0.7.0 - "@backstage/integration-react": ^1.1.30 - "@backstage/plugin-catalog-common": ^1.0.26 + "@backstage/frontend-plugin-api": ^0.8.0 + "@backstage/integration-react": ^1.1.32 + "@backstage/plugin-catalog-common": ^1.1.0 "@backstage/plugin-permission-common": ^0.8.1 - "@backstage/plugin-permission-react": ^0.4.25 + "@backstage/plugin-permission-react": ^0.4.26 "@backstage/types": ^1.1.1 - "@backstage/version-bridge": ^1.0.8 + "@backstage/version-bridge": ^1.0.9 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.61 @@ -5866,7 +6113,7 @@ __metadata: react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: c91126c51f8496fdc1fbf74de7334c38d691f062d2c62a623cc5bc4e8e12e8287362c41af0cf0003519f337fb78ba78644a34867c71406badc6b01d861f9c87d + checksum: d41f4d3a72f17be6a9019a4d8acaeb9d3198e2b1d0e25bd28efb3b5617d301a5798e259d4bcc077351d76e1c130e565344564bf987f4079f4b4bc040ae7a9878 languageName: node linkType: hard @@ -5898,22 +6145,29 @@ __metadata: "@react-hookz/web": ^24.0.0 "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^15.0.0 + "@testing-library/react": ^16.0.0 "@testing-library/user-event": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + "@types/react": ^18.0.0 "@types/zen-observable": ^0.8.0 classnames: ^2.2.6 lodash: ^4.17.21 material-ui-popup-state: ^1.9.3 qs: ^6.9.4 + react: ^18.0.2 + react-dom: ^18.0.2 + react-router-dom: ^6.3.0 react-test-renderer: ^16.13.1 react-use: ^17.2.4 yaml: ^2.0.0 zen-observable: ^0.10.0 peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft @@ -5940,14 +6194,21 @@ __metadata: "@material-ui/icons": ^4.9.1 "@material-ui/lab": ^4.0.0-alpha.60 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^15.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + "@testing-library/react": ^16.0.0 + "@types/react": ^18.0.0 luxon: ^3.5.0 + react: ^18.0.2 + react-dom: ^18.0.2 + react-router-dom: ^6.3.0 react-use: ^17.2.4 peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft @@ -5982,22 +6243,29 @@ __metadata: "@mui/utils": ^5.14.15 "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^15.0.0 + "@testing-library/react": ^16.0.0 "@testing-library/user-event": ^14.0.0 "@types/pluralize": ^0.0.33 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + "@types/react": ^18.0.0 dataloader: ^2.0.0 expiry-map: ^2.0.0 history: ^5.0.0 lodash: ^4.17.21 pluralize: ^8.0.0 + react: ^18.0.2 + react-dom: ^18.0.2 + react-router-dom: ^6.3.0 react-use: ^17.2.4 swr: ^2.2.5 zen-observable: ^0.10.0 peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft @@ -6016,15 +6284,22 @@ __metadata: "@material-ui/lab": 4.0.0-alpha.61 "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^15.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + "@testing-library/react": ^16.0.0 + "@types/react": ^18.0.0 jsonschema: ^1.2.6 + react: ^18.0.2 + react-dom: ^18.0.2 + react-router-dom: ^6.3.0 react-use: ^17.2.4 zen-observable: ^0.10.0 peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft @@ -6032,7 +6307,7 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-devtools-backend@workspace:plugins/devtools-backend" dependencies: - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": ^0.25.0 "@backstage/backend-defaults": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" @@ -6059,7 +6334,7 @@ __metadata: node-fetch: ^2.7.0 ping: ^0.4.1 semver: ^7.5.3 - supertest: ^6.2.4 + supertest: ^7.0.0 yn: ^4.0.0 languageName: unknown linkType: soft @@ -6091,13 +6366,20 @@ __metadata: "@material-ui/icons": ^4.9.1 "@material-ui/lab": ^4.0.0-alpha.57 "@testing-library/jest-dom": ^6.0.0 + "@types/react": ^18.0.0 + react: ^18.0.2 + react-dom: ^18.0.2 react-json-view: ^1.21.3 + react-router-dom: ^6.3.0 react-use: ^17.2.4 peerDependencies: "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft @@ -6107,7 +6389,6 @@ __metadata: dependencies: "@aws-sdk/client-sqs": ^3.350.0 "@aws-sdk/types": ^3.347.0 - "@backstage/backend-common": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" "@backstage/cli": "workspace:^" @@ -6196,17 +6477,24 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-events-backend@workspace:plugins/events-backend" dependencies: - "@backstage/backend-common": "workspace:^" + "@backstage/backend-app-api": "workspace:^" + "@backstage/backend-common": ^0.25.0 + "@backstage/backend-defaults": "workspace:^" + "@backstage/backend-openapi-utils": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^" + "@backstage/errors": "workspace:^" "@backstage/plugin-events-backend-test-utils": "workspace:^" "@backstage/plugin-events-node": "workspace:^" + "@backstage/repo-tools": "workspace:^" + "@backstage/types": "workspace:^" "@types/express": ^4.17.6 express: ^4.17.1 express-promise-router: ^4.1.0 - supertest: ^6.1.3 + knex: ^3.0.0 + supertest: ^7.0.0 winston: ^3.2.1 languageName: unknown linkType: soft @@ -6215,10 +6503,14 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-events-node@workspace:plugins/events-node" dependencies: - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": ^0.25.0 "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" "@backstage/cli": "workspace:^" + "@backstage/errors": "workspace:^" + "@backstage/types": "workspace:^" + cross-fetch: ^4.0.0 + uri-template: ^2.0.0 languageName: unknown linkType: soft @@ -6231,13 +6523,20 @@ __metadata: "@backstage/core-plugin-api": "workspace:^" "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 - "@rjsf/utils": 5.18.5 - "@types/react": ^16.13.1 || ^17.0.0 + "@rjsf/utils": 5.21.1 + "@types/react": ^18.0.0 "@types/react-grid-layout": ^1.3.2 + react: ^18.0.2 + react-dom: ^18.0.2 + react-router-dom: ^6.3.0 peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft @@ -6262,26 +6561,33 @@ __metadata: "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.61 - "@rjsf/core": 5.18.5 - "@rjsf/material-ui": 5.18.5 - "@rjsf/utils": 5.18.5 - "@rjsf/validator-ajv8": 5.18.5 + "@rjsf/core": 5.21.1 + "@rjsf/material-ui": 5.21.1 + "@rjsf/utils": 5.21.1 + "@rjsf/validator-ajv8": 5.21.1 "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^15.0.0 + "@testing-library/react": ^16.0.0 "@testing-library/user-event": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + "@types/react": ^18.0.0 "@types/react-grid-layout": ^1.3.2 lodash: ^4.17.21 luxon: ^3.4.3 + react: ^18.0.2 + react-dom: ^18.0.2 react-grid-layout: 1.3.4 react-resizable: ^3.0.4 + react-router-dom: ^6.3.0 react-use: ^17.2.4 zod: ^3.22.4 peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft @@ -6294,7 +6600,7 @@ __metadata: "@aws-sdk/signature-v4": ^3.347.0 "@azure/identity": ^4.0.0 "@backstage/backend-app-api": "workspace:^" - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": ^0.25.0 "@backstage/backend-defaults": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" @@ -6333,9 +6639,9 @@ __metadata: msw: ^1.0.0 node-fetch: ^2.7.0 stream-buffers: ^3.0.2 - supertest: ^6.1.3 + supertest: ^7.0.0 winston: ^3.2.1 - ws: ^8.13.0 + ws: ^8.18.0 yn: ^4.0.0 languageName: unknown linkType: soft @@ -6353,24 +6659,31 @@ __metadata: "@backstage/plugin-kubernetes-react": "workspace:^" "@backstage/test-utils": "workspace:^" "@kubernetes-models/apimachinery": ^1.1.0 - "@kubernetes-models/base": ^4.0.1 + "@kubernetes-models/base": ^5.0.0 "@material-ui/core": ^4.12.2 "@material-ui/lab": 4.0.0-alpha.61 "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^15.0.0 + "@testing-library/react": ^16.0.0 "@types/node": ^16.11.26 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + "@types/react": ^18.0.0 cronstrue: ^2.2.0 js-yaml: ^4.0.0 kubernetes-models: ^4.1.0 lodash: ^4.17.21 luxon: ^3.0.0 + react: ^18.0.2 + react-dom: ^18.0.2 + react-router-dom: ^6.3.0 react-use: ^17.2.4 peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft @@ -6394,7 +6707,7 @@ __metadata: resolution: "@backstage/plugin-kubernetes-node@workspace:plugins/kubernetes-node" dependencies: "@backstage/backend-app-api": "workspace:^" - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": ^0.25.0 "@backstage/backend-defaults": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" @@ -6406,7 +6719,7 @@ __metadata: "@kubernetes/client-node": ^0.20.0 msw: ^1.3.1 node-fetch: ^2.7.0 - supertest: ^6.1.3 + supertest: ^7.0.0 winston: ^3.2.1 languageName: unknown linkType: soft @@ -6425,14 +6738,14 @@ __metadata: "@backstage/test-utils": "workspace:^" "@backstage/types": "workspace:^" "@kubernetes-models/apimachinery": ^1.1.0 - "@kubernetes-models/base": ^4.0.1 + "@kubernetes-models/base": ^5.0.0 "@kubernetes/client-node": ^0.20.0 "@material-ui/core": ^4.9.13 "@material-ui/icons": ^4.11.3 "@material-ui/lab": ^4.0.0-alpha.61 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^15.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + "@testing-library/react": ^16.0.0 + "@types/react": ^18.0.0 cronstrue: ^2.32.0 jest-websocket-mock: ^2.5.0 js-yaml: ^4.1.0 @@ -6440,12 +6753,21 @@ __metadata: lodash: ^4.17.21 luxon: ^3.0.0 msw: ^1.3.1 + react: ^18.0.2 + react-dom: ^18.0.2 + react-router-dom: ^6.3.0 react-use: ^17.4.0 xterm: ^5.3.0 xterm-addon-attach: ^0.9.0 xterm-addon-fit: ^0.8.0 peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft @@ -6465,25 +6787,32 @@ __metadata: "@backstage/plugin-kubernetes-react": "workspace:^" "@backstage/test-utils": "workspace:^" "@kubernetes-models/apimachinery": ^1.1.0 - "@kubernetes-models/base": ^4.0.1 + "@kubernetes-models/base": ^5.0.0 "@kubernetes/client-node": 0.20.0 "@material-ui/core": ^4.12.2 "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^15.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + "@testing-library/react": ^16.0.0 + "@types/react": ^18.0.0 cronstrue: ^2.2.0 js-yaml: ^4.0.0 kubernetes-models: ^4.1.0 lodash: ^4.17.21 luxon: ^3.0.0 + react: ^18.0.2 + react-dom: ^18.0.2 + react-router-dom: ^6.3.0 xterm: ^5.2.1 xterm-addon-attach: ^0.9.0 xterm-addon-fit: ^0.8.0 peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft @@ -6493,7 +6822,7 @@ __metadata: dependencies: "@aws-sdk/client-ses": ^3.550.0 "@aws-sdk/types": ^3.347.0 - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": ^0.25.0 "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" "@backstage/catalog-client": "workspace:^" @@ -6516,7 +6845,7 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-notifications-backend@workspace:plugins/notifications-backend" dependencies: - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": ^0.25.0 "@backstage/backend-defaults": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" @@ -6542,7 +6871,7 @@ __metadata: knex: ^3.0.0 msw: ^1.0.0 node-fetch: ^2.7.0 - supertest: ^6.2.4 + supertest: ^7.0.0 uuid: ^9.0.0 winston: ^3.2.1 yn: ^4.0.0 @@ -6563,7 +6892,7 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-notifications-node@workspace:plugins/notifications-node" dependencies: - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": ^0.25.0 "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" "@backstage/catalog-client": "workspace:^" @@ -6599,18 +6928,26 @@ __metadata: "@material-ui/icons": ^4.9.1 "@material-ui/lab": ^4.0.0-alpha.61 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^15.0.0 + "@testing-library/react": ^16.0.0 "@testing-library/user-event": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 + "@types/react": ^18.0.0 lodash: ^4.17.21 material-ui-confirm: ^3.0.12 msw: ^1.0.0 notistack: ^3.0.1 + react: ^18.0.2 + react-dom: ^18.0.2 react-relative-time: ^0.0.9 + react-router-dom: ^6.3.0 react-use: ^17.2.4 peerDependencies: - react: ^16.13.1 || ^17.0.0 + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + react: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft @@ -6631,14 +6968,21 @@ __metadata: "@material-ui/lab": 4.0.0-alpha.61 "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^15.0.0 + "@testing-library/react": ^16.0.0 "@testing-library/user-event": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + "@types/react": ^18.0.0 + react: ^18.0.2 + react-dom: ^18.0.2 + react-router-dom: ^6.3.0 react-use: ^17.2.4 peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft @@ -6667,18 +7011,25 @@ __metadata: "@material-ui/lab": 4.0.0-alpha.61 "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^15.0.0 + "@testing-library/react": ^16.0.0 "@testing-library/user-event": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + "@types/react": ^18.0.0 lodash: ^4.17.21 p-limit: ^3.1.0 pluralize: ^8.0.0 qs: ^6.10.1 + react: ^18.0.2 + react-dom: ^18.0.2 + react-router-dom: ^6.3.0 react-use: ^17.2.4 peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft @@ -6699,7 +7050,7 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-permission-backend@workspace:plugins/permission-backend" dependencies: - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": ^0.25.0 "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" "@backstage/cli": "workspace:^" @@ -6717,7 +7068,7 @@ __metadata: lodash: ^4.17.21 msw: ^1.0.0 node-fetch: ^2.7.0 - supertest: ^6.1.6 + supertest: ^7.0.0 yn: ^4.0.0 zod: ^3.22.4 languageName: unknown @@ -6743,7 +7094,7 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-permission-node@workspace:plugins/permission-node" dependencies: - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": ^0.25.0 "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" "@backstage/cli": "workspace:^" @@ -6756,13 +7107,30 @@ __metadata: express: ^4.17.1 express-promise-router: ^4.1.0 msw: ^1.0.0 - supertest: ^6.1.3 + supertest: ^7.0.0 zod: ^3.22.4 zod-to-json-schema: ^3.20.4 languageName: unknown linkType: soft -"@backstage/plugin-permission-react@^0.4.25, @backstage/plugin-permission-react@workspace:^, @backstage/plugin-permission-react@workspace:plugins/permission-react": +"@backstage/plugin-permission-react@npm:^0.4.26": + version: 0.4.26 + resolution: "@backstage/plugin-permission-react@npm:0.4.26" + dependencies: + "@backstage/config": ^1.2.0 + "@backstage/core-plugin-api": ^1.9.4 + "@backstage/plugin-permission-common": ^0.8.1 + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + swr: ^2.0.0 + peerDependencies: + react: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-router-dom: 6.0.0-beta.0 || ^6.3.0 + checksum: ad7901bfbe10e637be017ecef55b1e2db9d9e83bde7e81b742f44e2bd71a0f24c7b27e651653b6654938a5c13729b5a89183cd9518f447c445688c052f3698d9 + languageName: node + linkType: hard + +"@backstage/plugin-permission-react@workspace:^, @backstage/plugin-permission-react@workspace:plugins/permission-react": version: 0.0.0-use.local resolution: "@backstage/plugin-permission-react@workspace:plugins/permission-react" dependencies: @@ -6772,13 +7140,20 @@ __metadata: "@backstage/plugin-permission-common": "workspace:^" "@backstage/test-utils": "workspace:^" "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^15.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + "@testing-library/react": ^16.0.0 + "@types/react": ^18.0.0 + react: ^18.0.2 + react-dom: ^18.0.2 + react-router-dom: ^6.3.0 swr: ^2.0.0 peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft @@ -6787,7 +7162,7 @@ __metadata: resolution: "@backstage/plugin-proxy-backend@workspace:plugins/proxy-backend" dependencies: "@backstage/backend-app-api": "workspace:^" - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": ^0.25.0 "@backstage/backend-defaults": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" @@ -6894,7 +7269,7 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-scaffolder-backend-module-confluence-to-markdown@workspace:plugins/scaffolder-backend-module-confluence-to-markdown" dependencies: - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": ^0.25.0 "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" "@backstage/cli": "workspace:^" @@ -6916,7 +7291,7 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-scaffolder-backend-module-cookiecutter@workspace:plugins/scaffolder-backend-module-cookiecutter" dependencies: - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": ^0.25.0 "@backstage/backend-defaults": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" @@ -6993,16 +7368,18 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-scaffolder-backend-module-github@workspace:plugins/scaffolder-backend-module-github" dependencies: - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": ^0.25.0 "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" + "@backstage/catalog-client": "workspace:^" + "@backstage/catalog-model": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^" "@backstage/errors": "workspace:^" "@backstage/integration": "workspace:^" "@backstage/plugin-scaffolder-node": "workspace:^" "@backstage/plugin-scaffolder-node-test-utils": "workspace:^" - "@octokit/webhooks": ^10.0.0 + "@octokit/webhooks": ^10.9.2 "@types/libsodium-wrappers": ^0.7.10 fs-extra: ^11.2.0 jsonschema: ^1.2.6 @@ -7017,7 +7394,7 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-scaffolder-backend-module-gitlab@workspace:plugins/scaffolder-backend-module-gitlab" dependencies: - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": ^0.25.0 "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" "@backstage/cli": "workspace:^" @@ -7040,7 +7417,7 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-scaffolder-backend-module-notifications@workspace:plugins/scaffolder-backend-module-notifications" dependencies: - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": ^0.25.0 "@backstage/backend-plugin-api": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/plugin-notifications-common": "workspace:^" @@ -7056,7 +7433,7 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-scaffolder-backend-module-rails@workspace:plugins/scaffolder-backend-module-rails" dependencies: - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": ^0.25.0 "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" "@backstage/cli": "workspace:^" @@ -7098,7 +7475,7 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-scaffolder-backend-module-yeoman@workspace:plugins/scaffolder-backend-module-yeoman" dependencies: - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": ^0.25.0 "@backstage/backend-plugin-api": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/plugin-scaffolder-node": "workspace:^" @@ -7115,7 +7492,7 @@ __metadata: resolution: "@backstage/plugin-scaffolder-backend@workspace:plugins/scaffolder-backend" dependencies: "@backstage/backend-app-api": "workspace:^" - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": ^0.25.0 "@backstage/backend-defaults": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" @@ -7168,7 +7545,7 @@ __metadata: p-queue: ^6.6.2 prom-client: ^15.0.0 strip-ansi: ^7.1.0 - supertest: ^6.1.3 + supertest: ^7.0.0 tar: ^6.1.12 triple-beam: ^1.4.1 uuid: ^9.0.0 @@ -7196,12 +7573,23 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-scaffolder-node-test-utils@workspace:plugins/scaffolder-node-test-utils" dependencies: - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": ^0.25.0 "@backstage/backend-test-utils": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/plugin-scaffolder-node": "workspace:^" "@backstage/types": "workspace:^" - "@types/react": "*" + "@types/react": ^18.0.0 + react: ^18.0.2 + react-dom: ^18.0.2 + react-router-dom: ^6.3.0 + peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + react: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft @@ -7209,7 +7597,7 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-scaffolder-node@workspace:plugins/scaffolder-node" dependencies: - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": ^0.25.0 "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" "@backstage/catalog-model": "workspace:^" @@ -7242,6 +7630,7 @@ __metadata: "@backstage/core-app-api": "workspace:^" "@backstage/core-components": "workspace:^" "@backstage/core-plugin-api": "workspace:^" + "@backstage/frontend-plugin-api": "workspace:^" "@backstage/plugin-catalog": "workspace:^" "@backstage/plugin-catalog-common": "workspace:^" "@backstage/plugin-catalog-react": "workspace:^" @@ -7256,18 +7645,18 @@ __metadata: "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.61 "@react-hookz/web": ^24.0.0 - "@rjsf/core": 5.18.5 - "@rjsf/material-ui": 5.18.5 - "@rjsf/utils": 5.18.5 - "@rjsf/validator-ajv8": 5.18.5 + "@rjsf/core": 5.21.1 + "@rjsf/material-ui": 5.21.1 + "@rjsf/utils": 5.21.1 + "@rjsf/validator-ajv8": 5.21.1 "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^15.0.0 + "@testing-library/react": ^16.0.0 "@testing-library/user-event": ^14.0.0 "@types/humanize-duration": ^3.18.1 "@types/json-schema": ^7.0.9 "@types/luxon": ^3.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + "@types/react": ^18.0.0 ajv-errors: ^3.0.0 classnames: ^2.2.6 flatted: 3.3.1 @@ -7277,6 +7666,9 @@ __metadata: lodash: ^4.17.21 luxon: ^3.0.0 qs: ^6.9.4 + react: ^18.0.2 + react-dom: ^18.0.2 + react-router-dom: ^6.3.0 react-use: ^17.2.4 swr: ^2.0.0 use-immer: ^0.10.0 @@ -7284,9 +7676,13 @@ __metadata: zod: ^3.22.4 zod-to-json-schema: ^3.20.4 peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft @@ -7323,23 +7719,24 @@ __metadata: "@material-ui/lab": 4.0.0-alpha.61 "@microsoft/fetch-event-source": ^2.0.1 "@react-hookz/web": ^24.0.0 - "@rjsf/core": 5.18.5 - "@rjsf/material-ui": 5.18.5 - "@rjsf/utils": 5.18.5 - "@rjsf/validator-ajv8": 5.18.5 + "@rjsf/core": 5.21.1 + "@rjsf/material-ui": 5.21.1 + "@rjsf/utils": 5.21.1 + "@rjsf/validator-ajv8": 5.21.1 "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^15.0.0 + "@testing-library/react": ^16.0.0 "@testing-library/user-event": ^14.0.0 "@types/humanize-duration": ^3.18.1 "@types/json-schema": ^7.0.9 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + "@types/react": ^18.0.0 "@types/react-resizable": ^3.0.8 "@types/react-window": ^1.8.8 "@uiw/react-codemirror": ^4.9.3 classnames: ^2.2.6 git-url-parse: ^14.0.0 humanize-duration: ^3.25.1 + idb-keyval: 5.0.2 json-schema: ^0.4.0 json-schema-library: ^9.0.0 jszip: ^3.10.1 @@ -7347,7 +7744,10 @@ __metadata: luxon: ^3.0.0 msw: ^1.0.0 qs: ^6.9.4 + react: ^18.0.2 + react-dom: ^18.0.2 react-resizable: ^3.0.5 + react-router-dom: ^6.3.0 react-use: ^17.2.4 react-window: ^1.8.10 swr: ^2.0.0 @@ -7356,9 +7756,13 @@ __metadata: zod: ^3.22.4 zod-to-json-schema: ^3.20.4 peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft @@ -7366,7 +7770,7 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-search-backend-module-catalog@workspace:plugins/search-backend-module-catalog" dependencies: - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": ^0.25.0 "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" "@backstage/catalog-client": "workspace:^" @@ -7387,7 +7791,6 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-search-backend-module-elasticsearch@workspace:plugins/search-backend-module-elasticsearch" dependencies: - "@backstage/backend-common": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" "@backstage/cli": "workspace:^" @@ -7410,8 +7813,8 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-search-backend-module-explore@workspace:plugins/search-backend-module-explore" dependencies: - "@backstage-community/plugin-explore-common": ^0.0.4 - "@backstage/backend-common": "workspace:^" + "@backstage-community/plugin-explore-common": ^0.0.5 + "@backstage/backend-common": ^0.25.0 "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" "@backstage/cli": "workspace:^" @@ -7427,7 +7830,7 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-search-backend-module-pg@workspace:plugins/search-backend-module-pg" dependencies: - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": ^0.25.0 "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" "@backstage/cli": "workspace:^" @@ -7444,7 +7847,7 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-search-backend-module-stack-overflow-collator@workspace:plugins/search-backend-module-stack-overflow-collator" dependencies: - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": ^0.25.0 "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" "@backstage/cli": "workspace:^" @@ -7461,7 +7864,7 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-search-backend-module-techdocs@workspace:plugins/search-backend-module-techdocs" dependencies: - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": ^0.25.0 "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" "@backstage/catalog-client": "workspace:^" @@ -7485,7 +7888,7 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-search-backend-node@workspace:plugins/search-backend-node" dependencies: - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": ^0.25.0 "@backstage/backend-defaults": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" @@ -7507,7 +7910,7 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-search-backend@workspace:plugins/search-backend" dependencies: - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": ^0.25.0 "@backstage/backend-defaults": "workspace:^" "@backstage/backend-openapi-utils": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" @@ -7527,7 +7930,7 @@ __metadata: express: ^4.17.1 lodash: ^4.17.21 qs: ^6.10.1 - supertest: ^6.1.3 + supertest: ^7.0.0 yn: ^4.0.0 zod: ^3.22.4 languageName: unknown @@ -7564,16 +7967,23 @@ __metadata: "@material-ui/lab": 4.0.0-alpha.61 "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^15.0.0 + "@testing-library/react": ^16.0.0 "@testing-library/user-event": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + "@types/react": ^18.0.0 lodash: ^4.17.21 qs: ^6.9.4 + react: ^18.0.2 + react-dom: ^18.0.2 + react-router-dom: ^6.3.0 react-use: ^17.3.2 peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft @@ -7599,16 +8009,23 @@ __metadata: "@material-ui/icons": ^4.9.1 "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^15.0.0 + "@testing-library/react": ^16.0.0 "@testing-library/user-event": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + "@types/react": ^18.0.0 history: ^5.0.0 qs: ^6.9.4 + react: ^18.0.2 + react-dom: ^18.0.2 + react-router-dom: ^6.3.0 react-use: ^17.2.4 peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft @@ -7616,7 +8033,7 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-signals-backend@workspace:plugins/signals-backend" dependencies: - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": ^0.25.0 "@backstage/backend-defaults": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" @@ -7637,10 +8054,10 @@ __metadata: http-proxy-middleware: ^2.0.0 msw: ^1.0.0 node-fetch: ^2.7.0 - supertest: ^6.2.4 + supertest: ^7.0.0 uuid: ^9.0.0 winston: ^3.2.1 - ws: ^8.17.0 + ws: ^8.18.0 yn: ^4.0.0 languageName: unknown linkType: soft @@ -7649,7 +8066,7 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-signals-node@workspace:plugins/signals-node" dependencies: - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": ^0.25.0 "@backstage/backend-plugin-api": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^" @@ -7659,7 +8076,7 @@ __metadata: "@types/express": ^4.17.21 express: ^4.17.1 uuid: ^9.0.0 - ws: ^8.14.2 + ws: ^8.18.0 languageName: unknown linkType: soft @@ -7673,9 +8090,19 @@ __metadata: "@backstage/types": "workspace:^" "@material-ui/core": ^4.12.4 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^15.0.0 + "@testing-library/react": ^16.0.0 + "@types/react": ^18.0.0 + react: ^18.0.2 + react-dom: ^18.0.2 + react-router-dom: ^6.3.0 peerDependencies: - react: ^16.13.1 || ^17.0.0 + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + react: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft @@ -7696,14 +8123,24 @@ __metadata: "@material-ui/icons": ^4.9.1 "@material-ui/lab": ^4.0.0-alpha.61 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^15.0.0 + "@testing-library/react": ^16.0.0 "@testing-library/user-event": ^14.0.0 + "@types/react": ^18.0.0 jest-websocket-mock: ^2.5.0 msw: ^1.0.0 + react: ^18.0.2 + react-dom: ^18.0.2 + react-router-dom: ^6.3.0 react-use: ^17.2.4 uuid: ^9.0.0 peerDependencies: - react: ^16.13.1 || ^17.0.0 + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + react: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft @@ -7723,13 +8160,20 @@ __metadata: "@backstage/test-utils": "workspace:^" "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + "@types/react": ^18.0.0 + react: ^18.0.2 + react-dom: ^18.0.2 + react-router-dom: ^6.3.0 testing-library__dom: ^7.29.4-beta.1 peerDependencies: - "@testing-library/react": ^15.0.0 + "@testing-library/react": ^16.0.0 + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft @@ -7737,7 +8181,7 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-techdocs-backend@workspace:plugins/techdocs-backend" dependencies: - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": ^0.25.0 "@backstage/backend-defaults": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" @@ -7762,7 +8206,7 @@ __metadata: msw: ^1.0.0 node-fetch: ^2.7.0 p-limit: ^3.1.0 - supertest: ^6.1.3 + supertest: ^7.0.0 winston: ^3.2.1 languageName: unknown linkType: soft @@ -7792,14 +8236,21 @@ __metadata: "@react-hookz/web": ^24.0.0 "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^15.0.0 - "@types/react": ^16.13.1 || ^17.0.0 + "@testing-library/react": ^16.0.0 + "@types/react": ^18.0.0 git-url-parse: ^14.0.0 photoswipe: ^5.3.7 + react: ^18.0.2 + react-dom: ^18.0.2 + react-router-dom: ^6.3.0 peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft @@ -7843,7 +8294,7 @@ __metadata: mime-types: ^2.1.27 p-limit: ^3.1.0 recursive-readdir: ^2.2.2 - supertest: ^6.1.3 + supertest: ^7.0.0 winston: ^3.2.1 languageName: unknown linkType: soft @@ -7863,16 +8314,23 @@ __metadata: "@material-ui/core": ^4.12.2 "@material-ui/styles": ^4.11.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^15.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + "@testing-library/react": ^16.0.0 + "@types/react": ^18.0.0 jss: ~10.10.0 lodash: ^4.17.21 + react: ^18.0.2 + react-dom: ^18.0.2 react-helmet: 6.1.0 + react-router-dom: ^6.3.0 react-use: ^17.2.4 peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft @@ -7908,21 +8366,28 @@ __metadata: "@microsoft/fetch-event-source": ^2.0.1 "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^15.0.0 + "@testing-library/react": ^16.0.0 "@testing-library/user-event": ^14.0.0 "@types/dompurify": ^3.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + "@types/react": ^18.0.0 canvas: ^2.10.2 dompurify: ^3.0.0 git-url-parse: ^14.0.0 jss: ~10.10.0 lodash: ^4.17.21 + react: ^18.0.2 + react-dom: ^18.0.2 react-helmet: 6.1.0 + react-router-dom: ^6.3.0 react-use: ^17.2.4 peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft @@ -7945,7 +8410,7 @@ __metadata: express: ^4.17.1 express-promise-router: ^4.1.0 knex: ^3.0.0 - supertest: ^6.1.3 + supertest: ^7.0.0 yn: ^4.0.0 languageName: unknown linkType: soft @@ -7982,16 +8447,23 @@ __metadata: "@material-ui/lab": 4.0.0-alpha.61 "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^15.0.0 + "@testing-library/react": ^16.0.0 "@testing-library/user-event": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + "@types/react": ^18.0.0 msw: ^1.0.0 + react: ^18.0.2 + react-dom: ^18.0.2 + react-router-dom: ^6.3.0 react-use: ^17.2.4 zen-observable: ^0.10.0 peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft @@ -8022,8 +8494,8 @@ __metadata: "@backstage/errors": "workspace:^" "@backstage/types": "workspace:^" "@manypkg/get-packages": ^1.1.3 - "@microsoft/api-documenter": ^7.22.33 - "@microsoft/api-extractor": ^7.36.4 + "@microsoft/api-documenter": ^7.25.7 + "@microsoft/api-extractor": ^7.47.2 "@openapitools/openapi-generator-cli": ^2.7.0 "@stoplight/spectral-core": ^1.18.0 "@stoplight/spectral-formatters": ^1.1.0 @@ -8080,20 +8552,43 @@ __metadata: "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@testing-library/jest-dom": ^6.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + "@types/react": ^18.0.0 cross-fetch: ^4.0.0 i18next: ^22.4.15 msw: ^1.0.0 + react: ^18.0.2 + react-dom: ^18.0.2 + react-router-dom: ^6.3.0 zen-observable: ^0.10.0 peerDependencies: - "@testing-library/react": ^15.0.0 + "@testing-library/react": ^16.0.0 + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft -"@backstage/theme@^0.5.0, @backstage/theme@^0.5.6, @backstage/theme@workspace:^, @backstage/theme@workspace:packages/theme": +"@backstage/theme@npm:^0.5.0, @backstage/theme@npm:^0.5.7": + version: 0.5.7 + resolution: "@backstage/theme@npm:0.5.7" + dependencies: + "@emotion/react": ^11.10.5 + "@emotion/styled": ^11.10.5 + "@mui/material": ^5.12.2 + peerDependencies: + "@material-ui/core": ^4.12.2 + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + react: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 + checksum: 5a315a198481f7b0c6f1a11bc102c36d2976cae25184ce6e28e6e44ce4a742e4d4416f19c71ac44f574a2745e30d13508a6c152f00e1facdef9c9d12dc3d0449 + languageName: node + linkType: hard + +"@backstage/theme@workspace:^, @backstage/theme@workspace:packages/theme": version: 0.0.0-use.local resolution: "@backstage/theme@workspace:packages/theme" dependencies: @@ -8103,13 +8598,20 @@ __metadata: "@mui/material": ^5.12.2 "@mui/styles": ^5.14.18 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^15.0.0 - "@types/react": ^16.13.1 || ^17.0.0 + "@testing-library/react": ^16.0.0 + "@types/react": ^18.0.0 + react: ^18.0.2 + react-dom: ^18.0.2 + react-router-dom: ^6.3.0 peerDependencies: "@material-ui/core": ^4.12.2 "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft @@ -8124,18 +8626,38 @@ __metadata: languageName: unknown linkType: soft -"@backstage/version-bridge@^1.0.7, @backstage/version-bridge@^1.0.8, @backstage/version-bridge@workspace:^, @backstage/version-bridge@workspace:packages/version-bridge": - version: 0.0.0-use.local - resolution: "@backstage/version-bridge@workspace:packages/version-bridge" +"@backstage/version-bridge@npm:^1.0.7, @backstage/version-bridge@npm:^1.0.9": + version: 1.0.9 + resolution: "@backstage/version-bridge@npm:1.0.9" dependencies: - "@backstage/cli": "workspace:^" - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^15.0.0 "@types/react": ^16.13.1 || ^17.0.0 peerDependencies: react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 + checksum: eb805a747c66a9c78654109d6774d5a7c16175240fe9441c71800d7b2b9965e6e04960af902cbaf4fc9eb15e9c665888cf6e1b7c4e4f157c8617873999545c0f + languageName: node + linkType: hard + +"@backstage/version-bridge@workspace:^, @backstage/version-bridge@workspace:packages/version-bridge": + version: 0.0.0-use.local + resolution: "@backstage/version-bridge@workspace:packages/version-bridge" + dependencies: + "@backstage/cli": "workspace:^" + "@testing-library/jest-dom": ^6.0.0 + "@testing-library/react": ^16.0.0 + "@types/react": ^18.0.0 + react: ^18.0.2 + react-dom: ^18.0.2 + react-router-dom: ^6.3.0 + peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + react: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft @@ -8791,9 +9313,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/aix-ppc64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/aix-ppc64@npm:0.20.2" +"@esbuild/aix-ppc64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/aix-ppc64@npm:0.21.5" conditions: os=aix & cpu=ppc64 languageName: node linkType: hard @@ -8805,16 +9327,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-arm64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/android-arm64@npm:0.18.20" - conditions: os=android & cpu=arm64 - languageName: node - linkType: hard - -"@esbuild/android-arm64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/android-arm64@npm:0.20.2" +"@esbuild/android-arm64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/android-arm64@npm:0.21.5" conditions: os=android & cpu=arm64 languageName: node linkType: hard @@ -8826,16 +9341,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-arm@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/android-arm@npm:0.18.20" - conditions: os=android & cpu=arm - languageName: node - linkType: hard - -"@esbuild/android-arm@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/android-arm@npm:0.20.2" +"@esbuild/android-arm@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/android-arm@npm:0.21.5" conditions: os=android & cpu=arm languageName: node linkType: hard @@ -8847,16 +9355,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-x64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/android-x64@npm:0.18.20" - conditions: os=android & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/android-x64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/android-x64@npm:0.20.2" +"@esbuild/android-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/android-x64@npm:0.21.5" conditions: os=android & cpu=x64 languageName: node linkType: hard @@ -8868,16 +9369,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/darwin-arm64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/darwin-arm64@npm:0.18.20" - conditions: os=darwin & cpu=arm64 - languageName: node - linkType: hard - -"@esbuild/darwin-arm64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/darwin-arm64@npm:0.20.2" +"@esbuild/darwin-arm64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/darwin-arm64@npm:0.21.5" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard @@ -8889,16 +9383,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/darwin-x64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/darwin-x64@npm:0.18.20" - conditions: os=darwin & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/darwin-x64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/darwin-x64@npm:0.20.2" +"@esbuild/darwin-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/darwin-x64@npm:0.21.5" conditions: os=darwin & cpu=x64 languageName: node linkType: hard @@ -8910,16 +9397,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/freebsd-arm64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/freebsd-arm64@npm:0.18.20" - conditions: os=freebsd & cpu=arm64 - languageName: node - linkType: hard - -"@esbuild/freebsd-arm64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/freebsd-arm64@npm:0.20.2" +"@esbuild/freebsd-arm64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/freebsd-arm64@npm:0.21.5" conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard @@ -8931,16 +9411,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/freebsd-x64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/freebsd-x64@npm:0.18.20" - conditions: os=freebsd & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/freebsd-x64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/freebsd-x64@npm:0.20.2" +"@esbuild/freebsd-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/freebsd-x64@npm:0.21.5" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard @@ -8952,16 +9425,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-arm64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/linux-arm64@npm:0.18.20" - conditions: os=linux & cpu=arm64 - languageName: node - linkType: hard - -"@esbuild/linux-arm64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/linux-arm64@npm:0.20.2" +"@esbuild/linux-arm64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-arm64@npm:0.21.5" conditions: os=linux & cpu=arm64 languageName: node linkType: hard @@ -8973,16 +9439,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-arm@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/linux-arm@npm:0.18.20" - conditions: os=linux & cpu=arm - languageName: node - linkType: hard - -"@esbuild/linux-arm@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/linux-arm@npm:0.20.2" +"@esbuild/linux-arm@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-arm@npm:0.21.5" conditions: os=linux & cpu=arm languageName: node linkType: hard @@ -8994,16 +9453,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-ia32@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/linux-ia32@npm:0.18.20" - conditions: os=linux & cpu=ia32 - languageName: node - linkType: hard - -"@esbuild/linux-ia32@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/linux-ia32@npm:0.20.2" +"@esbuild/linux-ia32@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-ia32@npm:0.21.5" conditions: os=linux & cpu=ia32 languageName: node linkType: hard @@ -9015,16 +9467,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-loong64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/linux-loong64@npm:0.18.20" - conditions: os=linux & cpu=loong64 - languageName: node - linkType: hard - -"@esbuild/linux-loong64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/linux-loong64@npm:0.20.2" +"@esbuild/linux-loong64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-loong64@npm:0.21.5" conditions: os=linux & cpu=loong64 languageName: node linkType: hard @@ -9036,16 +9481,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-mips64el@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/linux-mips64el@npm:0.18.20" - conditions: os=linux & cpu=mips64el - languageName: node - linkType: hard - -"@esbuild/linux-mips64el@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/linux-mips64el@npm:0.20.2" +"@esbuild/linux-mips64el@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-mips64el@npm:0.21.5" conditions: os=linux & cpu=mips64el languageName: node linkType: hard @@ -9057,16 +9495,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-ppc64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/linux-ppc64@npm:0.18.20" - conditions: os=linux & cpu=ppc64 - languageName: node - linkType: hard - -"@esbuild/linux-ppc64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/linux-ppc64@npm:0.20.2" +"@esbuild/linux-ppc64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-ppc64@npm:0.21.5" conditions: os=linux & cpu=ppc64 languageName: node linkType: hard @@ -9078,16 +9509,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-riscv64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/linux-riscv64@npm:0.18.20" - conditions: os=linux & cpu=riscv64 - languageName: node - linkType: hard - -"@esbuild/linux-riscv64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/linux-riscv64@npm:0.20.2" +"@esbuild/linux-riscv64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-riscv64@npm:0.21.5" conditions: os=linux & cpu=riscv64 languageName: node linkType: hard @@ -9099,16 +9523,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-s390x@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/linux-s390x@npm:0.18.20" - conditions: os=linux & cpu=s390x - languageName: node - linkType: hard - -"@esbuild/linux-s390x@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/linux-s390x@npm:0.20.2" +"@esbuild/linux-s390x@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-s390x@npm:0.21.5" conditions: os=linux & cpu=s390x languageName: node linkType: hard @@ -9120,16 +9537,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-x64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/linux-x64@npm:0.18.20" - conditions: os=linux & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/linux-x64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/linux-x64@npm:0.20.2" +"@esbuild/linux-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-x64@npm:0.21.5" conditions: os=linux & cpu=x64 languageName: node linkType: hard @@ -9141,16 +9551,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/netbsd-x64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/netbsd-x64@npm:0.18.20" - conditions: os=netbsd & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/netbsd-x64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/netbsd-x64@npm:0.20.2" +"@esbuild/netbsd-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/netbsd-x64@npm:0.21.5" conditions: os=netbsd & cpu=x64 languageName: node linkType: hard @@ -9169,16 +9572,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/openbsd-x64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/openbsd-x64@npm:0.18.20" - conditions: os=openbsd & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/openbsd-x64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/openbsd-x64@npm:0.20.2" +"@esbuild/openbsd-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/openbsd-x64@npm:0.21.5" conditions: os=openbsd & cpu=x64 languageName: node linkType: hard @@ -9190,16 +9586,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/sunos-x64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/sunos-x64@npm:0.18.20" - conditions: os=sunos & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/sunos-x64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/sunos-x64@npm:0.20.2" +"@esbuild/sunos-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/sunos-x64@npm:0.21.5" conditions: os=sunos & cpu=x64 languageName: node linkType: hard @@ -9211,16 +9600,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-arm64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/win32-arm64@npm:0.18.20" - conditions: os=win32 & cpu=arm64 - languageName: node - linkType: hard - -"@esbuild/win32-arm64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/win32-arm64@npm:0.20.2" +"@esbuild/win32-arm64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/win32-arm64@npm:0.21.5" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard @@ -9232,16 +9614,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-ia32@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/win32-ia32@npm:0.18.20" - conditions: os=win32 & cpu=ia32 - languageName: node - linkType: hard - -"@esbuild/win32-ia32@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/win32-ia32@npm:0.20.2" +"@esbuild/win32-ia32@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/win32-ia32@npm:0.21.5" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard @@ -9253,16 +9628,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-x64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/win32-x64@npm:0.18.20" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/win32-x64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/win32-x64@npm:0.20.2" +"@esbuild/win32-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/win32-x64@npm:0.21.5" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -9309,10 +9677,10 @@ __metadata: languageName: node linkType: hard -"@eslint/js@npm:8.57.0": - version: 8.57.0 - resolution: "@eslint/js@npm:8.57.0" - checksum: 315dc65b0e9893e2bff139bddace7ea601ad77ed47b4550e73da8c9c2d2766c7a575c3cddf17ef85b8fd6a36ff34f91729d0dcca56e73ca887c10df91a41b0bb +"@eslint/js@npm:8.57.1": + version: 8.57.1 + resolution: "@eslint/js@npm:8.57.1" + checksum: 2afb77454c06e8316793d2e8e79a0154854d35e6782a1217da274ca60b5044d2c69d6091155234ed0551a1e408f86f09dd4ece02752c59568fa403e60611e880 languageName: node linkType: hard @@ -9323,6 +9691,13 @@ __metadata: languageName: node linkType: hard +"@fastify/busboy@npm:^2.0.0": + version: 2.1.1 + resolution: "@fastify/busboy@npm:2.1.1" + checksum: 42c32ef75e906c9a4809c1e1930a5ca6d4ddc8d138e1a8c8ba5ea07f997db32210617d23b2e4a85fe376316a41a1a0439fc6ff2dedf5126d96f45a9d80754fb2 + languageName: node + linkType: hard + "@floating-ui/core@npm:^1.0.0": version: 1.6.0 resolution: "@floating-ui/core@npm:1.6.0" @@ -9393,14 +9768,14 @@ __metadata: languageName: node linkType: hard -"@gitbeaker/core@npm:^40.1.3": - version: 40.1.3 - resolution: "@gitbeaker/core@npm:40.1.3" +"@gitbeaker/core@npm:^40.2.1": + version: 40.2.1 + resolution: "@gitbeaker/core@npm:40.2.1" dependencies: - "@gitbeaker/requester-utils": ^40.1.3 + "@gitbeaker/requester-utils": ^40.2.1 qs: ^6.12.2 xcase: ^2.0.1 - checksum: 2bb114b1a9d0d5b0b5c3fed82c0880f8b8d47633605a2913c6f489931ac9be8988e8f6c07bc6e58e526d25b012868e0dbd7b5bee96d6b92658d4220e364ca691 + checksum: 40dc31705744625f88940ef1bd10faf11ec0255b18355f5d781e2346ce69b4af29b69e5611643b03435af646fed0b697ceb65361ff19d5b3bcddcb9078b49aa4 languageName: node linkType: hard @@ -9440,15 +9815,15 @@ __metadata: languageName: node linkType: hard -"@gitbeaker/requester-utils@npm:^40.1.3": - version: 40.1.3 - resolution: "@gitbeaker/requester-utils@npm:40.1.3" +"@gitbeaker/requester-utils@npm:^40.2.1": + version: 40.2.1 + resolution: "@gitbeaker/requester-utils@npm:40.2.1" dependencies: picomatch-browser: ^2.2.6 qs: ^6.12.2 rate-limiter-flexible: ^4.0.1 xcase: ^2.0.1 - checksum: fc2e312a1d7e4639b733c1df729d80b1cc2fc3305205ce0f5b6e6e366e95b73f4e3bfd62a26df308d4947151eedb0eeeb30ba64e6d62cca45c1f570a0d05773d + checksum: d83d3cfff96b693b7d63ead0fa481f837a6c4efd4c3592abd035d0ca287d9696fb47421e4500f4a46fa7de11c7d6af07d444045cc7cb67846328a4527be7a715 languageName: node linkType: hard @@ -9463,33 +9838,34 @@ __metadata: linkType: hard "@gitbeaker/rest@npm:^40.0.3": - version: 40.1.3 - resolution: "@gitbeaker/rest@npm:40.1.3" + version: 40.2.1 + resolution: "@gitbeaker/rest@npm:40.2.1" dependencies: - "@gitbeaker/core": ^40.1.3 - "@gitbeaker/requester-utils": ^40.1.3 - checksum: 1258f7877481598649122a856b24390188e7f84734538346b1dd413fad896725905ac6ab8c8cf0751e1ef4f7165347405e010dc7a735bae701871a795a885db4 + "@gitbeaker/core": ^40.2.1 + "@gitbeaker/requester-utils": ^40.2.1 + checksum: 8412e83984db12cfa7d9dc4a4114cb53651f3005e802fe99f7c5932a578690075080a17bfa256936ab7c1c638e1eca361e01dd4f25e2b4c7afc14234e9a4b71d languageName: node linkType: hard "@google-cloud/container@npm:^5.0.0": - version: 5.16.0 - resolution: "@google-cloud/container@npm:5.16.0" + version: 5.17.0 + resolution: "@google-cloud/container@npm:5.17.0" dependencies: google-gax: ^4.0.3 - checksum: 2f9410843b04d7780f9cb4a8dfcacec3aa05dcbd75dc05442fe734cddc19aa5b92122053d6df5f11ca959164eaa937f14d8140009a34b39da67ad38943c3d8e9 + checksum: 8e583f9cd1f12cf860dd9d483f4e0e8c1e4edf7191d0152c8b821c2debbe80b77eb663b45fa3526faf1d3182e5000df532628360bbae53420e090b92043c3880 languageName: node linkType: hard "@google-cloud/firestore@npm:^7.0.0": - version: 7.9.0 - resolution: "@google-cloud/firestore@npm:7.9.0" + version: 7.10.0 + resolution: "@google-cloud/firestore@npm:7.10.0" dependencies: + "@opentelemetry/api": ^1.3.0 fast-deep-equal: ^3.1.1 functional-red-black-tree: ^1.0.1 google-gax: ^4.3.3 protobufjs: ^7.2.6 - checksum: 5d0657736f1e364cd110ea6083eb8b6aeb1605ea409ea5478d5c8430bfa568c62d472b41e892d0849dfb405b06d8aba412fd57a5d1e807429ba5264c48eb2673 + checksum: c534e49c6b52b7b46366eba009e3f56e8ee10ca0501896a7794470cab32513c6a314f364ff5a3fe5a44b832ba39d1afc86d38b42be3826a615c0a59108185c7d languageName: node linkType: hard @@ -9674,17 +10050,17 @@ __metadata: linkType: hard "@graphql-tools/executor-legacy-ws@npm:^1.0.0": - version: 1.0.4 - resolution: "@graphql-tools/executor-legacy-ws@npm:1.0.4" + version: 1.1.0 + resolution: "@graphql-tools/executor-legacy-ws@npm:1.1.0" dependencies: - "@graphql-tools/utils": ^10.0.0 + "@graphql-tools/utils": ^10.3.0 "@types/ws": ^8.0.0 - isomorphic-ws: 5.0.0 + isomorphic-ws: ^5.0.0 tslib: ^2.4.0 - ws: 8.14.2 + ws: ^8.17.1 peerDependencies: graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - checksum: d271e7b0860dfa47b29ca56aa761e555c804a3223ed9f42784b2f1dcc872b15976a2c89db9b34ca26143a0b5cf6f45c771ddc23c0c012f5dabf222334c59635e + checksum: eb4acf16cf4b99f3b5fa8fc0b431e82ee7c5c424a6df4d89b73840bdbb7dcee8bff9652df986a08abecdcbec107892f3fe26c6a7adc6d447af8c6683b08b66a6 languageName: node linkType: hard @@ -9845,17 +10221,17 @@ __metadata: languageName: node linkType: hard -"@graphql-tools/utils@npm:^10.0.0, @graphql-tools/utils@npm:^10.0.2, @graphql-tools/utils@npm:^10.0.5": - version: 10.0.8 - resolution: "@graphql-tools/utils@npm:10.0.8" +"@graphql-tools/utils@npm:^10.0.0, @graphql-tools/utils@npm:^10.0.2, @graphql-tools/utils@npm:^10.0.5, @graphql-tools/utils@npm:^10.3.0": + version: 10.5.4 + resolution: "@graphql-tools/utils@npm:10.5.4" dependencies: "@graphql-typed-document-node/core": ^3.1.1 - cross-inspect: 1.0.0 + cross-inspect: 1.0.1 dset: ^3.1.2 tslib: ^2.4.0 peerDependencies: graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - checksum: 75d4f17592b5b93c1a60efb583decd96cc0f7cacfb68f483569d28bb9afd5a8d0b4e85a0136fa54c222c090d55bfc085798f1acccd5db41f7971673547cf2a34 + checksum: 56b41b276401c9010e47627b0d84336ac840d4e3e7c0124884626f11b92a20a1f1aec97712dd06d8adf5239fc39f4a86d4f4349f6a7028205e577e4c200bf070 languageName: node linkType: hard @@ -9970,14 +10346,14 @@ __metadata: languageName: node linkType: hard -"@humanwhocodes/config-array@npm:^0.11.14": - version: 0.11.14 - resolution: "@humanwhocodes/config-array@npm:0.11.14" +"@humanwhocodes/config-array@npm:^0.13.0": + version: 0.13.0 + resolution: "@humanwhocodes/config-array@npm:0.13.0" dependencies: - "@humanwhocodes/object-schema": ^2.0.2 + "@humanwhocodes/object-schema": ^2.0.3 debug: ^4.3.1 minimatch: ^3.0.5 - checksum: 861ccce9eaea5de19546653bccf75bf09fe878bc39c3aab00aeee2d2a0e654516adad38dd1098aab5e3af0145bbcbf3f309bdf4d964f8dab9dcd5834ae4c02f2 + checksum: eae69ff9134025dd2924f0b430eb324981494be26f0fddd267a33c28711c4db643242cf9fddf7dadb9d16c96b54b2d2c073e60a56477df86e0173149313bd5d6 languageName: node linkType: hard @@ -9988,10 +10364,10 @@ __metadata: languageName: node linkType: hard -"@humanwhocodes/object-schema@npm:^2.0.2": - version: 2.0.2 - resolution: "@humanwhocodes/object-schema@npm:2.0.2" - checksum: 2fc11503361b5fb4f14714c700c02a3f4c7c93e9acd6b87a29f62c522d90470f364d6161b03d1cc618b979f2ae02aed1106fd29d302695d8927e2fc8165ba8ee +"@humanwhocodes/object-schema@npm:^2.0.3": + version: 2.0.3 + resolution: "@humanwhocodes/object-schema@npm:2.0.3" + checksum: d3b78f6c5831888c6ecc899df0d03bcc25d46f3ad26a11d7ea52944dc36a35ef543fad965322174238d677a43d5c694434f6607532cff7077062513ad7022631 languageName: node linkType: hard @@ -10056,11 +10432,38 @@ __metadata: languageName: node linkType: hard +"@internal/frontend@workspace:packages/frontend-internal": + version: 0.0.0-use.local + resolution: "@internal/frontend@workspace:packages/frontend-internal" + dependencies: + "@backstage/cli": "workspace:^" + "@backstage/frontend-app-api": "workspace:^" + "@backstage/frontend-plugin-api": "workspace:^" + "@backstage/frontend-test-utils": "workspace:^" + "@backstage/test-utils": "workspace:^" + "@backstage/types": "workspace:^" + "@backstage/version-bridge": "workspace:^" + "@testing-library/jest-dom": ^6.0.0 + "@testing-library/react": ^16.0.0 + zod: ^3.22.4 + languageName: unknown + linkType: soft + +"@internal/opaque@workspace:packages/opaque-internal": + version: 0.0.0-use.local + resolution: "@internal/opaque@workspace:packages/opaque-internal" + dependencies: + "@backstage/cli": "workspace:^" + "@testing-library/jest-dom": ^6.0.0 + "@testing-library/react": ^16.0.0 + languageName: unknown + linkType: soft + "@internal/plugin-todo-list-backend@workspace:plugins/example-todo-list-backend": version: 0.0.0-use.local resolution: "@internal/plugin-todo-list-backend@workspace:plugins/example-todo-list-backend" dependencies: - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": ^0.25.0 "@backstage/backend-defaults": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" @@ -10072,7 +10475,7 @@ __metadata: "@types/uuid": ^9.0.0 express: ^4.17.1 express-promise-router: ^4.1.0 - supertest: ^6.1.6 + supertest: ^7.0.0 uuid: ^9.0.0 yn: ^4.0.0 languageName: unknown @@ -10098,13 +10501,30 @@ __metadata: "@material-ui/lab": 4.0.0-alpha.61 "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^15.0.0 - "@types/react": ^16.13.1 || ^17.0.0 + "@testing-library/react": ^16.0.0 + "@types/react": ^18.0.0 + react: ^18.0.2 + react-dom: ^18.0.2 + react-router-dom: ^6.3.0 react-use: ^17.2.4 peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true + languageName: unknown + linkType: soft + +"@internal/scaffolder@workspace:packages/scaffolder-internal": + version: 0.0.0-use.local + resolution: "@internal/scaffolder@workspace:packages/scaffolder-internal" + dependencies: + "@backstage/cli": "workspace:^" + "@backstage/plugin-scaffolder-react": "workspace:^" + zod: ^3.22.4 languageName: unknown linkType: soft @@ -10545,7 +10965,7 @@ __metadata: languageName: node linkType: hard -"@kubernetes-models/base@npm:^4.0.1, @kubernetes-models/base@npm:^4.0.4": +"@kubernetes-models/base@npm:^4.0.4": version: 4.0.4 resolution: "@kubernetes-models/base@npm:4.0.4" dependencies: @@ -10925,53 +11345,54 @@ __metadata: languageName: node linkType: hard -"@microsoft/api-documenter@npm:^7.22.33": - version: 7.22.33 - resolution: "@microsoft/api-documenter@npm:7.22.33" +"@microsoft/api-documenter@npm:^7.25.7": + version: 7.25.14 + resolution: "@microsoft/api-documenter@npm:7.25.14" dependencies: - "@microsoft/api-extractor-model": 7.27.6 - "@microsoft/tsdoc": 0.14.2 - "@rushstack/node-core-library": 3.59.7 - "@rushstack/ts-command-line": 4.15.2 - colors: ~1.2.1 + "@microsoft/api-extractor-model": 7.29.8 + "@microsoft/tsdoc": ~0.15.0 + "@rushstack/node-core-library": 5.9.0 + "@rushstack/terminal": 0.14.2 + "@rushstack/ts-command-line": 4.22.8 js-yaml: ~3.13.1 resolve: ~1.22.1 bin: api-documenter: bin/api-documenter - checksum: b2aa75823c3a5bf65ce87b56bd85dfa276ff155eb2244187e163e4eb8f4a2daf15e39e9b5d1dea13f854309d9562ab845ff6c7c8b4973e409593852c3bc058f0 + checksum: 1b4f5054c93ab77b4de196c07432d29ac40a488dd33881ad230897f4c393859ef05ab3503163ecaa4914ba4043b33070d9887bdde64a496a7d27dbcd94583622 languageName: node linkType: hard -"@microsoft/api-extractor-model@npm:7.27.6": - version: 7.27.6 - resolution: "@microsoft/api-extractor-model@npm:7.27.6" +"@microsoft/api-extractor-model@npm:7.29.8": + version: 7.29.8 + resolution: "@microsoft/api-extractor-model@npm:7.29.8" dependencies: - "@microsoft/tsdoc": 0.14.2 - "@microsoft/tsdoc-config": ~0.16.1 - "@rushstack/node-core-library": 3.59.7 - checksum: 7867feaf3a0e5accfcce3a77681248a319952a266cffc644e4f8f7df1c9e1d55adb5124df901e8cca594bb3e12d361d1fcb2bffbdbb4b20fe3113928f6535975 + "@microsoft/tsdoc": ~0.15.0 + "@microsoft/tsdoc-config": ~0.17.0 + "@rushstack/node-core-library": 5.9.0 + checksum: 95a6b5df089d8bf44555f4565a6f0eda9323917266b2f4730b606aeb2c7f36df7c2cbcae9ca48a9198af7a33442cda8ce2c791e0f4c7c92f3bdaee6c3190b1f5 languageName: node linkType: hard -"@microsoft/api-extractor@npm:^7.36.4": - version: 7.36.4 - resolution: "@microsoft/api-extractor@npm:7.36.4" +"@microsoft/api-extractor@npm:^7.47.2": + version: 7.47.9 + resolution: "@microsoft/api-extractor@npm:7.47.9" dependencies: - "@microsoft/api-extractor-model": 7.27.6 - "@microsoft/tsdoc": 0.14.2 - "@microsoft/tsdoc-config": ~0.16.1 - "@rushstack/node-core-library": 3.59.7 - "@rushstack/rig-package": 0.4.1 - "@rushstack/ts-command-line": 4.15.2 - colors: ~1.2.1 + "@microsoft/api-extractor-model": 7.29.8 + "@microsoft/tsdoc": ~0.15.0 + "@microsoft/tsdoc-config": ~0.17.0 + "@rushstack/node-core-library": 5.9.0 + "@rushstack/rig-package": 0.5.3 + "@rushstack/terminal": 0.14.2 + "@rushstack/ts-command-line": 4.22.8 lodash: ~4.17.15 + minimatch: ~3.0.3 resolve: ~1.22.1 semver: ~7.5.4 source-map: ~0.6.1 - typescript: ~5.0.4 + typescript: 5.4.2 bin: api-extractor: bin/api-extractor - checksum: 92559325cf2407fa27cb9675772956511fa35005f295cdb4dc47abd7ef9c77ba61b0f684c2e952301a76dd2cfa9e398840c8f3d9117d621300e12b0ecfbf8147 + checksum: 5e96654b388359bd9a1fb85ea7698921ca0f9dfa9c57e48fc9d28625107fea54863d57c82f4080686f190ae0d6fcd8b7fa7c070e7b8acb359b5cd62137e2bb23 languageName: node linkType: hard @@ -10989,48 +11410,50 @@ __metadata: languageName: node linkType: hard -"@microsoft/tsdoc-config@npm:~0.16.1": - version: 0.16.2 - resolution: "@microsoft/tsdoc-config@npm:0.16.2" +"@microsoft/tsdoc-config@npm:~0.17.0": + version: 0.17.0 + resolution: "@microsoft/tsdoc-config@npm:0.17.0" dependencies: - "@microsoft/tsdoc": 0.14.2 - ajv: ~6.12.6 + "@microsoft/tsdoc": 0.15.0 + ajv: ~8.12.0 jju: ~1.4.0 - resolve: ~1.19.0 - checksum: 12b0d703154076bcaac75ca42e804e4fc292672396441e54346d7eadd0d6b57f90980eda2b1bab89b224af86da34a2389f9054002e282011e795ca5919a4386f + resolve: ~1.22.2 + checksum: dd2de8247d0fc29608da83edf4ab73a21370f6ce10d089853303e91b135fdb1436ccec3bd1024f235dd3180dfe5dae7342989eadd03af55cf06f0e974e5fc213 languageName: node linkType: hard -"@microsoft/tsdoc@npm:0.14.2": - version: 0.14.2 - resolution: "@microsoft/tsdoc@npm:0.14.2" - checksum: b167c89e916ba73ee20b9c9d5dba6aa3a0de25ed3d50050e8a344dca7cd43cb2e1059bd515c820369b6e708901dd3fda476a42bc643ca74a35671ce77f724a3a +"@microsoft/tsdoc@npm:0.15.0, @microsoft/tsdoc@npm:~0.15.0": + version: 0.15.0 + resolution: "@microsoft/tsdoc@npm:0.15.0" + checksum: 3f693cff07b220b68563e3f86e9f94a9c8d0791a7446f76149c7d62ae5ed5cb4578bb48b9b5f9baa3dd9a9f77be81903c74654a41e0ca4ecf78936654952a8d4 languageName: node linkType: hard -"@module-federation/bridge-react-webpack-plugin@npm:0.3.5": - version: 0.3.5 - resolution: "@module-federation/bridge-react-webpack-plugin@npm:0.3.5" +"@module-federation/bridge-react-webpack-plugin@npm:0.6.4": + version: 0.6.4 + resolution: "@module-federation/bridge-react-webpack-plugin@npm:0.6.4" dependencies: - "@module-federation/sdk": 0.3.5 - checksum: 9fb0aab200bd63a07c1adcc71e3342c713de4806dccc2b4a8ea2eb19677b2c8753b638906ed48ab49909c753319f33792cb2afd08c0d6a80b4af742d1dc57bd1 + "@module-federation/sdk": 0.6.4 + "@types/semver": 7.5.8 + semver: 7.6.3 + checksum: aa5a8362501eb0f132cc9a730f6ae782f19df116a101737642460feeade3f2197f8e12adb10900568e7f02ba630ea4598e15438a8eabac8df7d4a04bc563142e languageName: node linkType: hard -"@module-federation/dts-plugin@npm:0.3.5": - version: 0.3.5 - resolution: "@module-federation/dts-plugin@npm:0.3.5" +"@module-federation/dts-plugin@npm:0.6.4": + version: 0.6.4 + resolution: "@module-federation/dts-plugin@npm:0.6.4" dependencies: - "@module-federation/managers": 0.3.5 - "@module-federation/sdk": 0.3.5 - "@module-federation/third-party-dts-extractor": 0.3.5 + "@module-federation/managers": 0.6.4 + "@module-federation/sdk": 0.6.4 + "@module-federation/third-party-dts-extractor": 0.6.4 adm-zip: ^0.5.10 ansi-colors: ^4.1.3 - axios: ^1.6.7 + axios: ^1.7.4 chalk: 3.0.0 fs-extra: 9.1.0 isomorphic-ws: 5.0.0 - koa: 2.11.0 + koa: 2.15.3 lodash.clonedeepwith: 4.5.0 log4js: 6.9.1 node-schedule: 2.1.1 @@ -11042,21 +11465,21 @@ __metadata: peerDependenciesMeta: vue-tsc: optional: true - checksum: 8c8e653d0818b3df14ec399d6db0b5784f202c7909112e4884f29c4e268bd9ff6b2d891677776a65ac6204bf4df9cb2f377b7cb8884c1fee98d275d8d2f28f29 + checksum: 9c96301c256e88bab8c7188542927aa5ec20d2c4fcc0dfa896a6c582fb0450c1ec75ec6e7b63bd91cee1cb8e163c8a736d174f29db8ec5c401e8608d684ca94f languageName: node linkType: hard -"@module-federation/enhanced@npm:^0.3.5": - version: 0.3.5 - resolution: "@module-federation/enhanced@npm:0.3.5" +"@module-federation/enhanced@npm:^0.6.0": + version: 0.6.4 + resolution: "@module-federation/enhanced@npm:0.6.4" dependencies: - "@module-federation/bridge-react-webpack-plugin": 0.3.5 - "@module-federation/dts-plugin": 0.3.5 - "@module-federation/managers": 0.3.5 - "@module-federation/manifest": 0.3.5 - "@module-federation/rspack": 0.3.5 - "@module-federation/runtime-tools": 0.3.5 - "@module-federation/sdk": 0.3.5 + "@module-federation/bridge-react-webpack-plugin": 0.6.4 + "@module-federation/dts-plugin": 0.6.4 + "@module-federation/managers": 0.6.4 + "@module-federation/manifest": 0.6.4 + "@module-federation/rspack": 0.6.4 + "@module-federation/runtime-tools": 0.6.4 + "@module-federation/sdk": 0.6.4 btoa: ^1.2.1 upath: 2.0.1 peerDependencies: @@ -11070,44 +11493,44 @@ __metadata: optional: true webpack: optional: true - checksum: 40130aa86c1ae2c90cf49360754f4e9688f33900087d376215c14b64d1f596141785eb7794457bb76387bb79725a60bee1271e3911d95183e9379c6454145894 + checksum: 457787b3a6bfddace6c2aa9555eecad830118b1a5b9165007935f8103fb40ca3e2fc9982b22142c323aba79c71d2d62d9b267f17f70fbaef80a22ed7753b23d1 languageName: node linkType: hard -"@module-federation/managers@npm:0.3.5": - version: 0.3.5 - resolution: "@module-federation/managers@npm:0.3.5" +"@module-federation/managers@npm:0.6.4": + version: 0.6.4 + resolution: "@module-federation/managers@npm:0.6.4" dependencies: - "@module-federation/sdk": 0.3.5 + "@module-federation/sdk": 0.6.4 find-pkg: 2.0.0 fs-extra: 9.1.0 - checksum: a60a21c2c9bf84fd0911365980e2f0e163485f0a952992e3fec242e8e7a33f0c803c62e1c463fb1326845f0077aef2d45d90eba0f6f69545e60e0ea708ebcaba + checksum: b1d56910d0370093112af4117c7a868912b327d39cf61180c5373f5e4b3e0efb81759688758b1dfc0e0ee37ab9c2b408f5b88d6bb5af9cde3654ad17d7d8333e languageName: node linkType: hard -"@module-federation/manifest@npm:0.3.5": - version: 0.3.5 - resolution: "@module-federation/manifest@npm:0.3.5" +"@module-federation/manifest@npm:0.6.4": + version: 0.6.4 + resolution: "@module-federation/manifest@npm:0.6.4" dependencies: - "@module-federation/dts-plugin": 0.3.5 - "@module-federation/managers": 0.3.5 - "@module-federation/sdk": 0.3.5 + "@module-federation/dts-plugin": 0.6.4 + "@module-federation/managers": 0.6.4 + "@module-federation/sdk": 0.6.4 chalk: 3.0.0 find-pkg: 2.0.0 - checksum: 0b0f41802630536a9a90b3e958052d2a1503bdd3927c40e1962e371ee26f2646172ef895b868fd287921a318e0bac5a513ef069517565c445fb659c150e3a257 + checksum: 4ea5e6372af3f5110e0c13120a71b7721f2bf7d2b01efa4bb67acf665bc09517bd8c87e07c0a759a1a17ed0569d273ff0fb585dd67c99c848d3e355d57def832 languageName: node linkType: hard -"@module-federation/rspack@npm:0.3.5": - version: 0.3.5 - resolution: "@module-federation/rspack@npm:0.3.5" +"@module-federation/rspack@npm:0.6.4": + version: 0.6.4 + resolution: "@module-federation/rspack@npm:0.6.4" dependencies: - "@module-federation/bridge-react-webpack-plugin": 0.3.5 - "@module-federation/dts-plugin": 0.3.5 - "@module-federation/managers": 0.3.5 - "@module-federation/manifest": 0.3.5 - "@module-federation/runtime-tools": 0.3.5 - "@module-federation/sdk": 0.3.5 + "@module-federation/bridge-react-webpack-plugin": 0.6.4 + "@module-federation/dts-plugin": 0.6.4 + "@module-federation/managers": 0.6.4 + "@module-federation/manifest": 0.6.4 + "@module-federation/runtime-tools": 0.6.4 + "@module-federation/sdk": 0.6.4 peerDependencies: typescript: ^4.9.0 || ^5.0.0 vue-tsc: ">=1.0.24" @@ -11116,54 +11539,54 @@ __metadata: optional: true vue-tsc: optional: true - checksum: 0afd72784ebbc92ab5d295de1be938cec259f7fcdc59b753af881bbf5b7f982b816c9c04b1ee5e052326556b8a4647001a623c58562c908ee7ffe316f4171df6 + checksum: c5797728ebdffdf340348d5616d8f0aed0e24cc82cbaaa5b9795afb303c3ebf83219336f77c58a4b79caeff9d753c3a5c403d18863239f67d8c0715899abdada languageName: node linkType: hard -"@module-federation/runtime-tools@npm:0.3.5": - version: 0.3.5 - resolution: "@module-federation/runtime-tools@npm:0.3.5" +"@module-federation/runtime-tools@npm:0.6.4": + version: 0.6.4 + resolution: "@module-federation/runtime-tools@npm:0.6.4" dependencies: - "@module-federation/runtime": 0.3.5 - "@module-federation/webpack-bundler-runtime": 0.3.5 - checksum: 5287783b12fff5a37d45cb904d9e004c569bb0803680c133a19002810f7c84f8bff87594dacbc473cdc813788eb8c9feb0915fb2f446ca0f4c609d0be9e33191 + "@module-federation/runtime": 0.6.4 + "@module-federation/webpack-bundler-runtime": 0.6.4 + checksum: 836f28a2a7f0a2cc349d0bf2d08e6f1bee330d8bb10afeab771ea3dbdc193b621c8411085a88bf6032fa86c7286ac3607caeb6f4d4ad29bba9fc21600e64fb42 languageName: node linkType: hard -"@module-federation/runtime@npm:0.3.5": - version: 0.3.5 - resolution: "@module-federation/runtime@npm:0.3.5" +"@module-federation/runtime@npm:0.6.4": + version: 0.6.4 + resolution: "@module-federation/runtime@npm:0.6.4" dependencies: - "@module-federation/sdk": 0.3.5 - checksum: 61ef8a6535e80d583d5d755d33f4edad0b6e4df6118f38296dbab5eb5f23a624c8ca7ceab8c00d6d7d4249179615cff7235f3554476933aabbc9b988321944ae + "@module-federation/sdk": 0.6.4 + checksum: 93c74937fded491d249c5a462ecb856e37ead07e11b74dffff871ccde5a819ca7ce5c2df64160d59baaa0eebde9c0a3976a1347a41106fdb29644d8a2dee4f6b languageName: node linkType: hard -"@module-federation/sdk@npm:0.3.5": - version: 0.3.5 - resolution: "@module-federation/sdk@npm:0.3.5" - checksum: 80f720af685def16bd80d6104dd7d831df03b1b3eedb11674a95f0e4420dbbaf732d4f619fc5e06421b36549483ab31484ad8a0490ac3033ed85ac300172be7d +"@module-federation/sdk@npm:0.6.4": + version: 0.6.4 + resolution: "@module-federation/sdk@npm:0.6.4" + checksum: 37ef2c2b794b8705b7d9b9da66adad95874987c5404b8d22baa617eabb29b8061e586879ada62b3e7207898dde1528897c3196c1f0c2bbf7526076ca6fa61672 languageName: node linkType: hard -"@module-federation/third-party-dts-extractor@npm:0.3.5": - version: 0.3.5 - resolution: "@module-federation/third-party-dts-extractor@npm:0.3.5" +"@module-federation/third-party-dts-extractor@npm:0.6.4": + version: 0.6.4 + resolution: "@module-federation/third-party-dts-extractor@npm:0.6.4" dependencies: find-pkg: 2.0.0 fs-extra: 9.1.0 resolve: 1.22.8 - checksum: f7413bee4bf77fa8576dce31580fd91a636d0db6cffa17cd5f485039c5470254410005386f4b4160298b0fced985b9d1768411a64cc96f90a0b73f2e7d1a463f + checksum: de4126122643840528a584367808f51771d1554e0d4ae55040cd1976d9e9e28bcd80eade5a72b736f35af5ae458955c3c0d0fd46dcca6c478a4c4a589da801fe languageName: node linkType: hard -"@module-federation/webpack-bundler-runtime@npm:0.3.5": - version: 0.3.5 - resolution: "@module-federation/webpack-bundler-runtime@npm:0.3.5" +"@module-federation/webpack-bundler-runtime@npm:0.6.4": + version: 0.6.4 + resolution: "@module-federation/webpack-bundler-runtime@npm:0.6.4" dependencies: - "@module-federation/runtime": 0.3.5 - "@module-federation/sdk": 0.3.5 - checksum: a4ba483be2ae1a157bcbaf1e895bbbe4c6cfe3039f6403ce543aa5163add4207c69d03f98a2b2910f21fbf61086f56c1f14ff19e44b36bb201a12ddf54ee3491 + "@module-federation/runtime": 0.6.4 + "@module-federation/sdk": 0.6.4 + checksum: b701873384c00ee2af8cb58ff46714b1686e664c9416566865edd21d868a7a8c1c1325d23da917a67c9847244f7570777ab000b357ecc61e643965e32a5db04a languageName: node linkType: hard @@ -11258,17 +11681,17 @@ __metadata: languageName: node linkType: hard -"@mswjs/interceptors@npm:^0.29.0": - version: 0.29.1 - resolution: "@mswjs/interceptors@npm:0.29.1" +"@mswjs/interceptors@npm:^0.35.8": + version: 0.35.9 + resolution: "@mswjs/interceptors@npm:0.35.9" dependencies: "@open-draft/deferred-promise": ^2.2.0 "@open-draft/logger": ^0.3.0 "@open-draft/until": ^2.0.0 is-node-process: ^1.2.0 - outvariant: ^1.2.1 + outvariant: ^1.4.3 strict-event-emitter: ^0.5.1 - checksum: c217f922c68024f6a8b526fb7df00bbfccb71e432bfb270322976dd40a9d312698e40bfd105b74df7aeb5a46276531a56ca5b8e3e9b0112f1577eb0d8d289e1f + checksum: 35b9382b94b7e3af962dc901db80bde99385645fb0b1f4cbaf64d58ff7181adb962430437db5b7d6db9db2e82399a3d1f319378d3c98e72c7ada8245180f0979 languageName: node linkType: hard @@ -11448,54 +11871,54 @@ __metadata: languageName: node linkType: hard -"@nestjs/axios@npm:3.0.2": - version: 3.0.2 - resolution: "@nestjs/axios@npm:3.0.2" +"@nestjs/axios@npm:3.0.3": + version: 3.0.3 + resolution: "@nestjs/axios@npm:3.0.3" peerDependencies: "@nestjs/common": ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 axios: ^1.3.1 rxjs: ^6.0.0 || ^7.0.0 - checksum: 285a735fb5db602b63aa4a37e161f609b2cec05b69f4bffe983617c2136ac29c0a33bb96e6276d22a656907bed5d53460e740310bc05c043dcd39c37db7cda29 + checksum: 4e4cd4a26dc53687cedcf360cf686839608ba80d7c9c7e449546299545ddad69fb2dd199f868f3de5d00bc3ab795fecda79971de1599c24f647f2c6c95a21bb9 languageName: node linkType: hard -"@nestjs/common@npm:10.3.0": - version: 10.3.0 - resolution: "@nestjs/common@npm:10.3.0" +"@nestjs/common@npm:10.4.3": + version: 10.4.3 + resolution: "@nestjs/common@npm:10.4.3" dependencies: iterare: 1.2.1 - tslib: 2.6.2 + tslib: 2.7.0 uid: 2.0.2 peerDependencies: class-transformer: "*" class-validator: "*" - reflect-metadata: ^0.1.12 + reflect-metadata: ^0.1.12 || ^0.2.0 rxjs: ^7.1.0 peerDependenciesMeta: class-transformer: optional: true class-validator: optional: true - checksum: c5444cb46bd4f4a4d28b5031f7c28a0cf9863bc2d5518910bfed6a49734f59e1ea08dd4651e2117ae82df81c933ef84f0963c5cdeee5ef1608cf1bd36ee291c5 + checksum: 980d545251c9310fb0680c07fe8a4de65033970e6db0d2bb9b9a82d54842c5e487ca94d1c147dbbdc959b745dabfa9a30a12915523cdb714c450130bc11f14b7 languageName: node linkType: hard -"@nestjs/core@npm:10.3.0": - version: 10.3.0 - resolution: "@nestjs/core@npm:10.3.0" +"@nestjs/core@npm:10.4.3": + version: 10.4.3 + resolution: "@nestjs/core@npm:10.4.3" dependencies: "@nuxtjs/opencollective": 0.3.2 fast-safe-stringify: 2.1.1 iterare: 1.2.1 - path-to-regexp: 3.2.0 - tslib: 2.6.2 + path-to-regexp: 3.3.0 + tslib: 2.7.0 uid: 2.0.2 peerDependencies: "@nestjs/common": ^10.0.0 "@nestjs/microservices": ^10.0.0 "@nestjs/platform-express": ^10.0.0 "@nestjs/websockets": ^10.0.0 - reflect-metadata: ^0.1.12 + reflect-metadata: ^0.1.12 || ^0.2.0 rxjs: ^7.1.0 peerDependenciesMeta: "@nestjs/microservices": @@ -11504,40 +11927,41 @@ __metadata: optional: true "@nestjs/websockets": optional: true - checksum: 7677b9fb97c8dec512c2a736c273ef08698b377af8c046bc5aad442ba3d35acbc17d177e76bf44a66678cae2ced2d265183e85be4190c501a195f16496df6396 + checksum: 55e2b96f9851d58e42c35d2057bca7b700ced22724e5b17745a88bf2e1f8d61d9d7a84f31b19106982c0cd3d913de165031451ff3b05da1f7c04b83988c499e5 languageName: node linkType: hard -"@node-saml/node-saml@npm:^4.0.4": - version: 4.0.5 - resolution: "@node-saml/node-saml@npm:4.0.5" +"@node-saml/node-saml@npm:^5.0.0": + version: 5.0.0 + resolution: "@node-saml/node-saml@npm:5.0.0" dependencies: - "@types/debug": ^4.1.7 - "@types/passport": ^1.0.11 - "@types/xml-crypto": ^1.4.2 - "@types/xml-encryption": ^1.2.1 - "@types/xml2js": ^0.4.11 - "@xmldom/xmldom": ^0.8.6 + "@types/debug": ^4.1.12 + "@types/qs": ^6.9.11 + "@types/xml-encryption": ^1.2.4 + "@types/xml2js": ^0.4.14 + "@xmldom/is-dom-node": ^1.0.1 + "@xmldom/xmldom": ^0.8.10 debug: ^4.3.4 - xml-crypto: ^3.0.1 + xml-crypto: ^6.0.0 xml-encryption: ^3.0.2 - xml2js: ^0.5.0 + xml2js: ^0.6.2 xmlbuilder: ^15.1.1 - checksum: 7d97575111a381ef2d0f16e1fc85ae3f84322ccba06dcb0594b00cf598e429658f45e479b78836943f69f249c08a8593e5168404acf7f1ed659ead53ceef465e + xpath: ^0.0.34 + checksum: 6a9ff9d922befc8ccb3338fe8f989eba66d3f781a3d1f39c4bd1d5c58fc1acd74ae05d94a08ef9c4ff1990ad38d0ca97135de52bbfe79196594e76f75e7b7e13 languageName: node linkType: hard -"@node-saml/passport-saml@npm:^4.0.4": - version: 4.0.4 - resolution: "@node-saml/passport-saml@npm:4.0.4" +"@node-saml/passport-saml@npm:^5.0.0": + version: 5.0.0 + resolution: "@node-saml/passport-saml@npm:5.0.0" dependencies: - "@node-saml/node-saml": ^4.0.4 - "@types/express": ^4.17.14 - "@types/passport": ^1.0.11 - "@types/passport-strategy": ^0.2.35 - passport: ^0.6.0 + "@node-saml/node-saml": ^5.0.0 + "@types/express": ^4.17.21 + "@types/passport": ^1.0.16 + "@types/passport-strategy": ^0.2.38 + passport: ^0.7.0 passport-strategy: ^1.0.0 - checksum: 75178669d7d47038c33bb0602454cb5030fc9b3ecdcae9163a35cef436bc6c22e68e57d06213e0118ff1cb0dcd2f2fa25112672ebe4cbad90578df21bec67fce + checksum: f5a5e3f731decd7cc3fa5effdd462e3265fa9da4455014041c62e678212b86200ec07e34083f6107c2db79157334e8f6af8658220bb865ad579317ca9465b05b languageName: node linkType: hard @@ -12463,7 +12887,7 @@ __metadata: languageName: node linkType: hard -"@octokit/webhooks@npm:^10.0.0": +"@octokit/webhooks@npm:^10.9.2": version: 10.9.2 resolution: "@octokit/webhooks@npm:10.9.2" dependencies: @@ -12528,14 +12952,14 @@ __metadata: linkType: hard "@openapitools/openapi-generator-cli@npm:^2.4.26, @openapitools/openapi-generator-cli@npm:^2.7.0": - version: 2.13.5 - resolution: "@openapitools/openapi-generator-cli@npm:2.13.5" + version: 2.13.12 + resolution: "@openapitools/openapi-generator-cli@npm:2.13.12" dependencies: - "@nestjs/axios": 3.0.2 - "@nestjs/common": 10.3.0 - "@nestjs/core": 10.3.0 + "@nestjs/axios": 3.0.3 + "@nestjs/common": 10.4.3 + "@nestjs/core": 10.4.3 "@nuxtjs/opencollective": 0.3.2 - axios: 1.7.4 + axios: 1.7.7 chalk: 4.1.2 commander: 8.3.0 compare-versions: 4.1.4 @@ -12543,21 +12967,21 @@ __metadata: console.table: 0.10.0 fs-extra: 10.1.0 glob: 7.2.3 - https-proxy-agent: 7.0.4 + https-proxy-agent: 7.0.5 inquirer: 8.2.6 lodash: 4.17.21 reflect-metadata: 0.1.13 rxjs: 7.8.1 - tslib: 2.6.2 + tslib: 2.7.0 bin: openapi-generator-cli: main.js - checksum: 923fcdfe29c2d349aaae28a86dd5f63a4f441233549a4575bce6760177c6c48508180c57569bcc4deb63a40d8d36049c4a9060e2884248b1b5fbab2d28954a4e + checksum: c2487abfef5dbfc8619824222424c4ab9c0accfdc77f1d6099efa7d4a0b960894351219fe75b12b5663afe4cd2136c3986297e141bf4b380fbfc4aec40704ef2 languageName: node linkType: hard "@opensearch-project/opensearch@npm:^2.2.1": - version: 2.11.0 - resolution: "@opensearch-project/opensearch@npm:2.11.0" + version: 2.12.0 + resolution: "@opensearch-project/opensearch@npm:2.12.0" dependencies: aws4: ^1.11.0 debug: ^4.3.1 @@ -12565,20 +12989,11 @@ __metadata: json11: ^1.1.2 ms: ^2.1.3 secure-json-parse: ^2.4.0 - checksum: 328a900ca3e0cc49a7486aef029a9ae6bc7ca90606e7aabb3c64acdec8ef09ece1ecc3019dd98bd553110f6757236f43c8c9a2db4ef167b3fc7ba56579404784 + checksum: 5bf64305a401a1fe2e3a9d06c2582ba5173f809cbe04ccec7e70247070ccd973c9e6a9f09a00507d0a937cc830354642e1b6e5adcac383a53bbec05b240f857b languageName: node linkType: hard -"@opentelemetry/api-logs@npm:0.52.1, @opentelemetry/api-logs@npm:^0.52.0": - version: 0.52.1 - resolution: "@opentelemetry/api-logs@npm:0.52.1" - dependencies: - "@opentelemetry/api": ^1.0.0 - checksum: 500cd35527580732921d198bd7007224402cb89fef791f0b64bea839c9f2ad796d54486ee9aee0ee6422ded3963cba793408086eda0adfec2bd1d66f9114d96c - languageName: node - linkType: hard - -"@opentelemetry/api-logs@npm:0.53.0": +"@opentelemetry/api-logs@npm:0.53.0, @opentelemetry/api-logs@npm:^0.53.0": version: 0.53.0 resolution: "@opentelemetry/api-logs@npm:0.53.0" dependencies: @@ -12594,69 +13009,60 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/auto-instrumentations-node@npm:^0.49.0": - version: 0.49.2 - resolution: "@opentelemetry/auto-instrumentations-node@npm:0.49.2" +"@opentelemetry/auto-instrumentations-node@npm:^0.50.0": + version: 0.50.0 + resolution: "@opentelemetry/auto-instrumentations-node@npm:0.50.0" dependencies: - "@opentelemetry/instrumentation": ^0.52.0 - "@opentelemetry/instrumentation-amqplib": ^0.41.0 - "@opentelemetry/instrumentation-aws-lambda": ^0.43.0 - "@opentelemetry/instrumentation-aws-sdk": ^0.43.1 - "@opentelemetry/instrumentation-bunyan": ^0.40.0 - "@opentelemetry/instrumentation-cassandra-driver": ^0.40.0 - "@opentelemetry/instrumentation-connect": ^0.38.0 - "@opentelemetry/instrumentation-cucumber": ^0.8.0 - "@opentelemetry/instrumentation-dataloader": ^0.11.0 - "@opentelemetry/instrumentation-dns": ^0.38.0 - "@opentelemetry/instrumentation-express": ^0.41.1 - "@opentelemetry/instrumentation-fastify": ^0.38.0 - "@opentelemetry/instrumentation-fs": ^0.14.0 - "@opentelemetry/instrumentation-generic-pool": ^0.38.1 - "@opentelemetry/instrumentation-graphql": ^0.42.0 - "@opentelemetry/instrumentation-grpc": ^0.52.0 - "@opentelemetry/instrumentation-hapi": ^0.40.0 - "@opentelemetry/instrumentation-http": ^0.52.0 - "@opentelemetry/instrumentation-ioredis": ^0.42.0 - "@opentelemetry/instrumentation-kafkajs": ^0.2.0 - "@opentelemetry/instrumentation-knex": ^0.39.0 - "@opentelemetry/instrumentation-koa": ^0.42.0 - "@opentelemetry/instrumentation-lru-memoizer": ^0.39.0 - "@opentelemetry/instrumentation-memcached": ^0.38.0 - "@opentelemetry/instrumentation-mongodb": ^0.46.0 - "@opentelemetry/instrumentation-mongoose": ^0.41.0 - "@opentelemetry/instrumentation-mysql": ^0.40.0 - "@opentelemetry/instrumentation-mysql2": ^0.40.0 - "@opentelemetry/instrumentation-nestjs-core": ^0.39.0 - "@opentelemetry/instrumentation-net": ^0.38.0 - "@opentelemetry/instrumentation-pg": ^0.43.0 - "@opentelemetry/instrumentation-pino": ^0.41.0 - "@opentelemetry/instrumentation-redis": ^0.41.0 - "@opentelemetry/instrumentation-redis-4": ^0.41.1 - "@opentelemetry/instrumentation-restify": ^0.40.0 - "@opentelemetry/instrumentation-router": ^0.39.0 - "@opentelemetry/instrumentation-socket.io": ^0.41.0 - "@opentelemetry/instrumentation-tedious": ^0.13.0 - "@opentelemetry/instrumentation-undici": ^0.5.0 - "@opentelemetry/instrumentation-winston": ^0.39.0 - "@opentelemetry/resource-detector-alibaba-cloud": ^0.29.0 - "@opentelemetry/resource-detector-aws": ^1.6.0 - "@opentelemetry/resource-detector-azure": ^0.2.10 - "@opentelemetry/resource-detector-container": ^0.4.0 - "@opentelemetry/resource-detector-gcp": ^0.29.10 + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/instrumentation-amqplib": ^0.42.0 + "@opentelemetry/instrumentation-aws-lambda": ^0.44.0 + "@opentelemetry/instrumentation-aws-sdk": ^0.44.0 + "@opentelemetry/instrumentation-bunyan": ^0.41.0 + "@opentelemetry/instrumentation-cassandra-driver": ^0.41.0 + "@opentelemetry/instrumentation-connect": ^0.39.0 + "@opentelemetry/instrumentation-cucumber": ^0.9.0 + "@opentelemetry/instrumentation-dataloader": ^0.12.0 + "@opentelemetry/instrumentation-dns": ^0.39.0 + "@opentelemetry/instrumentation-express": ^0.42.0 + "@opentelemetry/instrumentation-fastify": ^0.39.0 + "@opentelemetry/instrumentation-fs": ^0.15.0 + "@opentelemetry/instrumentation-generic-pool": ^0.39.0 + "@opentelemetry/instrumentation-graphql": ^0.43.0 + "@opentelemetry/instrumentation-grpc": ^0.53.0 + "@opentelemetry/instrumentation-hapi": ^0.41.0 + "@opentelemetry/instrumentation-http": ^0.53.0 + "@opentelemetry/instrumentation-ioredis": ^0.43.0 + "@opentelemetry/instrumentation-kafkajs": ^0.3.0 + "@opentelemetry/instrumentation-knex": ^0.40.0 + "@opentelemetry/instrumentation-koa": ^0.43.0 + "@opentelemetry/instrumentation-lru-memoizer": ^0.40.0 + "@opentelemetry/instrumentation-memcached": ^0.39.0 + "@opentelemetry/instrumentation-mongodb": ^0.47.0 + "@opentelemetry/instrumentation-mongoose": ^0.42.0 + "@opentelemetry/instrumentation-mysql": ^0.41.0 + "@opentelemetry/instrumentation-mysql2": ^0.41.0 + "@opentelemetry/instrumentation-nestjs-core": ^0.40.0 + "@opentelemetry/instrumentation-net": ^0.39.0 + "@opentelemetry/instrumentation-pg": ^0.44.0 + "@opentelemetry/instrumentation-pino": ^0.42.0 + "@opentelemetry/instrumentation-redis": ^0.42.0 + "@opentelemetry/instrumentation-redis-4": ^0.42.0 + "@opentelemetry/instrumentation-restify": ^0.41.0 + "@opentelemetry/instrumentation-router": ^0.40.0 + "@opentelemetry/instrumentation-socket.io": ^0.42.0 + "@opentelemetry/instrumentation-tedious": ^0.14.0 + "@opentelemetry/instrumentation-undici": ^0.6.0 + "@opentelemetry/instrumentation-winston": ^0.40.0 + "@opentelemetry/resource-detector-alibaba-cloud": ^0.29.1 + "@opentelemetry/resource-detector-aws": ^1.6.1 + "@opentelemetry/resource-detector-azure": ^0.2.11 + "@opentelemetry/resource-detector-container": ^0.4.1 + "@opentelemetry/resource-detector-gcp": ^0.29.11 "@opentelemetry/resources": ^1.24.0 - "@opentelemetry/sdk-node": ^0.52.0 + "@opentelemetry/sdk-node": ^0.53.0 peerDependencies: "@opentelemetry/api": ^1.4.1 - checksum: 383a7cac4994a48e5ca918fc84dddeb25f35c1744e1e6da186cd85b58e5b248c69d3ec92719828401877aec05913c94c51d987b5ec46d7965c9b99a1cd31af80 - languageName: node - linkType: hard - -"@opentelemetry/context-async-hooks@npm:1.25.1": - version: 1.25.1 - resolution: "@opentelemetry/context-async-hooks@npm:1.25.1" - peerDependencies: - "@opentelemetry/api": ">=1.0.0 <1.10.0" - checksum: fb2ac7381ea8203a1321e2a4989c193b6eede0b0f46bafc150e452ac5fc4645127f0ca66f60e44ff2816032afc68cbe3ab9cf235fbdffb0ad83f484729b70e82 + checksum: 0d78211226f86a33f2fc55dc53e902726f89b70eece49db55f3c79aa37a643269989c672733739d9ad83f32d26c009207b302174f64b673567c80f5c8f68ac19 languageName: node linkType: hard @@ -12680,17 +13086,6 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/core@npm:1.25.1": - version: 1.25.1 - resolution: "@opentelemetry/core@npm:1.25.1" - dependencies: - "@opentelemetry/semantic-conventions": 1.25.1 - peerDependencies: - "@opentelemetry/api": ">=1.0.0 <1.10.0" - checksum: ba1672fde4a1cfd9b55bf6070db71b808702fe59c4a70cda52a6156b2c813827954a6b4d3c3641283d394ff75a69b6359a0487459b4d26cd7d714ab3d21bc780 - languageName: node - linkType: hard - "@opentelemetry/core@npm:1.26.0, @opentelemetry/core@npm:^1.0.0, @opentelemetry/core@npm:^1.1.0, @opentelemetry/core@npm:^1.25.0, @opentelemetry/core@npm:^1.25.1, @opentelemetry/core@npm:^1.8.0": version: 1.26.0 resolution: "@opentelemetry/core@npm:1.26.0" @@ -12762,22 +13157,6 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/exporter-trace-otlp-grpc@npm:0.52.1": - version: 0.52.1 - resolution: "@opentelemetry/exporter-trace-otlp-grpc@npm:0.52.1" - dependencies: - "@grpc/grpc-js": ^1.7.1 - "@opentelemetry/core": 1.25.1 - "@opentelemetry/otlp-grpc-exporter-base": 0.52.1 - "@opentelemetry/otlp-transformer": 0.52.1 - "@opentelemetry/resources": 1.25.1 - "@opentelemetry/sdk-trace-base": 1.25.1 - peerDependencies: - "@opentelemetry/api": ^1.0.0 - checksum: c8f21e7a5802a7089c1f9f01a1f21934da7adf8526f36a16da6ba4f78e1a59e3da7c301070cd6df78d07555babb1853ab23180ea7df02eefea4ece66fccdf3d1 - languageName: node - linkType: hard - "@opentelemetry/exporter-trace-otlp-grpc@npm:0.53.0": version: 0.53.0 resolution: "@opentelemetry/exporter-trace-otlp-grpc@npm:0.53.0" @@ -12794,21 +13173,6 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/exporter-trace-otlp-http@npm:0.52.1": - version: 0.52.1 - resolution: "@opentelemetry/exporter-trace-otlp-http@npm:0.52.1" - dependencies: - "@opentelemetry/core": 1.25.1 - "@opentelemetry/otlp-exporter-base": 0.52.1 - "@opentelemetry/otlp-transformer": 0.52.1 - "@opentelemetry/resources": 1.25.1 - "@opentelemetry/sdk-trace-base": 1.25.1 - peerDependencies: - "@opentelemetry/api": ^1.0.0 - checksum: fa72c84c35268f500b8fdc4d1b388fbf7275170aa67a2b2712c1e6b0d657e208a1e1d222081f0a1860c3f204f12ff78c2f6fe622d08ea8123410f276883659e2 - languageName: node - linkType: hard - "@opentelemetry/exporter-trace-otlp-http@npm:0.53.0": version: 0.53.0 resolution: "@opentelemetry/exporter-trace-otlp-http@npm:0.53.0" @@ -12824,21 +13188,6 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/exporter-trace-otlp-proto@npm:0.52.1": - version: 0.52.1 - resolution: "@opentelemetry/exporter-trace-otlp-proto@npm:0.52.1" - dependencies: - "@opentelemetry/core": 1.25.1 - "@opentelemetry/otlp-exporter-base": 0.52.1 - "@opentelemetry/otlp-transformer": 0.52.1 - "@opentelemetry/resources": 1.25.1 - "@opentelemetry/sdk-trace-base": 1.25.1 - peerDependencies: - "@opentelemetry/api": ^1.0.0 - checksum: 1d46eb5055925fb1f4383bb65ccec7addcf53ab88f2f5e7393e4e99e72d4fe48a1d45027736d534aeb76e37c217f5a4f9deda51351afa614340196a28db55dab - languageName: node - linkType: hard - "@opentelemetry/exporter-trace-otlp-proto@npm:0.53.0": version: 0.53.0 resolution: "@opentelemetry/exporter-trace-otlp-proto@npm:0.53.0" @@ -12854,20 +13203,6 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/exporter-zipkin@npm:1.25.1": - version: 1.25.1 - resolution: "@opentelemetry/exporter-zipkin@npm:1.25.1" - dependencies: - "@opentelemetry/core": 1.25.1 - "@opentelemetry/resources": 1.25.1 - "@opentelemetry/sdk-trace-base": 1.25.1 - "@opentelemetry/semantic-conventions": 1.25.1 - peerDependencies: - "@opentelemetry/api": ^1.0.0 - checksum: 3ceade67522724642115e008e355b149b606088345c703b39ae4d7a2db3e4d883e9aa22181b49d50444bf0847ff7e0112b3ec4e5feb6acb1411038b3a3e81222 - languageName: node - linkType: hard - "@opentelemetry/exporter-zipkin@npm:1.26.0": version: 1.26.0 resolution: "@opentelemetry/exporter-zipkin@npm:1.26.0" @@ -12882,516 +13217,500 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/instrumentation-amqplib@npm:^0.41.0": - version: 0.41.0 - resolution: "@opentelemetry/instrumentation-amqplib@npm:0.41.0" +"@opentelemetry/instrumentation-amqplib@npm:^0.42.0": + version: 0.42.0 + resolution: "@opentelemetry/instrumentation-amqplib@npm:0.42.0" dependencies: "@opentelemetry/core": ^1.8.0 - "@opentelemetry/instrumentation": ^0.52.0 - "@opentelemetry/semantic-conventions": ^1.22.0 + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/semantic-conventions": ^1.27.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: aebf6727120935dd9f05e9d71dd6b2376ee8cdb56e2c8dd7c0fc6820ec1eb998cfa3e5bbb50201dc4e1c1257df293e08b8dc009888f7c55e651f0dfe33a16ede + checksum: 64c5a07cca54f2673aa9708638ba8a3dce864d69686924acb926a08f981941b080d68dcfc465b3139dc6824f239f1be9fc49257557c9bfcb460cb2c1f3b4dc80 languageName: node linkType: hard -"@opentelemetry/instrumentation-aws-lambda@npm:^0.43.0": - version: 0.43.0 - resolution: "@opentelemetry/instrumentation-aws-lambda@npm:0.43.0" +"@opentelemetry/instrumentation-aws-lambda@npm:^0.44.0": + version: 0.44.0 + resolution: "@opentelemetry/instrumentation-aws-lambda@npm:0.44.0" dependencies: - "@opentelemetry/instrumentation": ^0.52.0 + "@opentelemetry/instrumentation": ^0.53.0 "@opentelemetry/propagator-aws-xray": ^1.3.1 "@opentelemetry/resources": ^1.8.0 - "@opentelemetry/semantic-conventions": ^1.22.0 - "@types/aws-lambda": 8.10.122 + "@opentelemetry/semantic-conventions": ^1.27.0 + "@types/aws-lambda": 8.10.143 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: f2e7c8ba4a1f5a99f47071d879ac7a9180434a00c7e8db776a803e2a12e90299ad8d1ad3062626f5e8c58dd02232adc07b4a0736a26175b85a951efab5064def + checksum: 675e002c5d77cb5720d4eb53fd1a2b738bfe72de9d25140c4b6fd4a8353d03ddf29ff1bbdb72b23d26f79e92c9212731f883071dcc66b66666f29dc83f0b5954 languageName: node linkType: hard -"@opentelemetry/instrumentation-aws-sdk@npm:^0.43.1": - version: 0.43.1 - resolution: "@opentelemetry/instrumentation-aws-sdk@npm:0.43.1" +"@opentelemetry/instrumentation-aws-sdk@npm:^0.44.0": + version: 0.44.0 + resolution: "@opentelemetry/instrumentation-aws-sdk@npm:0.44.0" dependencies: "@opentelemetry/core": ^1.8.0 - "@opentelemetry/instrumentation": ^0.52.0 - "@opentelemetry/propagation-utils": ^0.30.10 - "@opentelemetry/semantic-conventions": ^1.22.0 + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/propagation-utils": ^0.30.11 + "@opentelemetry/semantic-conventions": ^1.27.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: b3c5a3893123cfff6f820be65e515d3d42cb7895a98d5c50b8d072e182dc8b8f475936df78a4180d4fa39b5d8e6e7a84b52952842bf14e7708f2c2d5e415492b + checksum: 7ab0fe1c9a93866a2bc01027d794cf5f1c59973490890982d9db82b50d555b4f896537e768df62374e365d4322e4afd4d27941910d124c6f48ac63a5212484f1 languageName: node linkType: hard -"@opentelemetry/instrumentation-bunyan@npm:^0.40.0": - version: 0.40.0 - resolution: "@opentelemetry/instrumentation-bunyan@npm:0.40.0" +"@opentelemetry/instrumentation-bunyan@npm:^0.41.0": + version: 0.41.0 + resolution: "@opentelemetry/instrumentation-bunyan@npm:0.41.0" dependencies: - "@opentelemetry/api-logs": ^0.52.0 - "@opentelemetry/instrumentation": ^0.52.0 + "@opentelemetry/api-logs": ^0.53.0 + "@opentelemetry/instrumentation": ^0.53.0 "@types/bunyan": 1.8.9 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 67c76e0c39305f069b6564f4fe8315a2b91cdedadea66e2506a9cbeaf04de2c6d86fce75fcf982e556be0fa9e4f84baf2c59b02a5870590ecbf3838d41f8b1d5 + checksum: f53f0fd1f285e6f7bd7d5a1ccb5747ea0c928c83f855dd4853b8d37b8b1e163d060a592957a89d1891e740b5dab800d0cda7d5b9db29206adb7938679e6f05e1 languageName: node linkType: hard -"@opentelemetry/instrumentation-cassandra-driver@npm:^0.40.0": - version: 0.40.0 - resolution: "@opentelemetry/instrumentation-cassandra-driver@npm:0.40.0" +"@opentelemetry/instrumentation-cassandra-driver@npm:^0.41.0": + version: 0.41.0 + resolution: "@opentelemetry/instrumentation-cassandra-driver@npm:0.41.0" dependencies: - "@opentelemetry/instrumentation": ^0.52.0 - "@opentelemetry/semantic-conventions": ^1.22.0 + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/semantic-conventions": ^1.27.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 6979a3c0c28226ace0071880d05cf0a418c119b3cf8fcea2e0398288dc7d541ac98935d1a6f9a77e80e8ea9f186e5044b9f791cd5668e3ed33406db6c0a9895f + checksum: e9c620e241938f16e667746c741480c809b959b44e8affe1b27e90c412ab898da2631307eae3fdee1f8fb928f50b88bc7c74275592beefc3fffc6c5eef83a184 languageName: node linkType: hard -"@opentelemetry/instrumentation-connect@npm:^0.38.0": - version: 0.38.0 - resolution: "@opentelemetry/instrumentation-connect@npm:0.38.0" +"@opentelemetry/instrumentation-connect@npm:^0.39.0": + version: 0.39.0 + resolution: "@opentelemetry/instrumentation-connect@npm:0.39.0" dependencies: "@opentelemetry/core": ^1.8.0 - "@opentelemetry/instrumentation": ^0.52.0 - "@opentelemetry/semantic-conventions": ^1.22.0 + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/semantic-conventions": ^1.27.0 "@types/connect": 3.4.36 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 4dff447ff9a7ee2ca94872d904df260213e8e05b27742713f8dce35593ec8f52bcb07adfb7730e7b208b8b49566e032cdee316f0ccea405e42ffc5804d222750 + checksum: 946c3d7ea0ca569942fd1e45a1f149f94fed4ee86609b4f2aedb23d67feeafe29a563beffa75d97f9b10c6b18b01c42d5eabf92d4f9f160bc938317c88ebc0de languageName: node linkType: hard -"@opentelemetry/instrumentation-cucumber@npm:^0.8.0": - version: 0.8.0 - resolution: "@opentelemetry/instrumentation-cucumber@npm:0.8.0" +"@opentelemetry/instrumentation-cucumber@npm:^0.9.0": + version: 0.9.0 + resolution: "@opentelemetry/instrumentation-cucumber@npm:0.9.0" dependencies: - "@opentelemetry/instrumentation": ^0.52.0 - "@opentelemetry/semantic-conventions": ^1.22.0 + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/semantic-conventions": ^1.27.0 peerDependencies: "@opentelemetry/api": ^1.0.0 - checksum: 951b9a1d60dfb33a3b4bdcd381e83fd89c2e820f49f86ff1317bcd1127345ec945702760cbbfdc06af75b67e17d85ab9a5f859d90f45d244e17503d0d1e3363d + checksum: 31d702a2e3404298a8410362c7834efb840ec10de56144811803207ba9e0a12af9bcac483da96a5df32143597dc0b74c32ba697b6525b3db3601edb97d192e84 languageName: node linkType: hard -"@opentelemetry/instrumentation-dataloader@npm:^0.11.0": - version: 0.11.0 - resolution: "@opentelemetry/instrumentation-dataloader@npm:0.11.0" +"@opentelemetry/instrumentation-dataloader@npm:^0.12.0": + version: 0.12.0 + resolution: "@opentelemetry/instrumentation-dataloader@npm:0.12.0" dependencies: - "@opentelemetry/instrumentation": ^0.52.0 + "@opentelemetry/instrumentation": ^0.53.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 9aa330d08cd6219ee927ab72db3d2d4d080831251bf5dde49eb6c7a1852ac7ea34b8df88d56c19e2638333b58527a90e7c459c9a1529008b74bd489385119ce1 + checksum: 7d502bd4ca6eac448bebc971d7b7b85b1e1e959bfcbf4b7927ea3fe90784aec8132d147fef2e773e468a8d20241df825edec6e0753be824b155a15d89e6f57a1 languageName: node linkType: hard -"@opentelemetry/instrumentation-dns@npm:^0.38.0": - version: 0.38.0 - resolution: "@opentelemetry/instrumentation-dns@npm:0.38.0" +"@opentelemetry/instrumentation-dns@npm:^0.39.0": + version: 0.39.0 + resolution: "@opentelemetry/instrumentation-dns@npm:0.39.0" dependencies: - "@opentelemetry/instrumentation": ^0.52.0 + "@opentelemetry/instrumentation": ^0.53.0 semver: ^7.5.4 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: e2105d6c8211525573657052dc1d64859046ab259de402b39ee901e8bcab2eafd16f6590e667f86e59db105aea7dab2a4130e2fba9c60e4588fa80cd52427360 + checksum: 691358e32532c8a830a4dc4133ae90f80bd659b4acc2db308353d3027663a4223de9e0ae7ef8c24be895b20be5995cb78f1bb86e57b32b8397b43339f58b5555 languageName: node linkType: hard -"@opentelemetry/instrumentation-express@npm:^0.41.1": - version: 0.41.1 - resolution: "@opentelemetry/instrumentation-express@npm:0.41.1" - dependencies: - "@opentelemetry/core": ^1.8.0 - "@opentelemetry/instrumentation": ^0.52.0 - "@opentelemetry/semantic-conventions": ^1.22.0 - peerDependencies: - "@opentelemetry/api": ^1.3.0 - checksum: fe2939ab377cc4b1c6dfe77cae6d23156ccd227cc9984bf03eb5f108fa048815d6dd0be9a8240bb3bd053a271789c9928a9e544725e2e099709e9b2c60d456f0 - languageName: node - linkType: hard - -"@opentelemetry/instrumentation-fastify@npm:^0.38.0": - version: 0.38.0 - resolution: "@opentelemetry/instrumentation-fastify@npm:0.38.0" - dependencies: - "@opentelemetry/core": ^1.8.0 - "@opentelemetry/instrumentation": ^0.52.0 - "@opentelemetry/semantic-conventions": ^1.22.0 - peerDependencies: - "@opentelemetry/api": ^1.3.0 - checksum: 3cd7996398d783397782fc327a336e37b1eaabee6c9d8a25daa15d86cf6634408bc790e67207548dcae61f064a4a85780d9ae51bc31414bd61e0291d22a8d3f8 - languageName: node - linkType: hard - -"@opentelemetry/instrumentation-fs@npm:^0.14.0": - version: 0.14.0 - resolution: "@opentelemetry/instrumentation-fs@npm:0.14.0" - dependencies: - "@opentelemetry/core": ^1.8.0 - "@opentelemetry/instrumentation": ^0.52.0 - peerDependencies: - "@opentelemetry/api": ^1.3.0 - checksum: cc6b90e9496bddbbc992adf3cb585b728260e6b22d35e48720e06505e2477e962bd1b62d9d1bf331c877c04ce7b393d87d2f61a3ade08519b73252a342351bf0 - languageName: node - linkType: hard - -"@opentelemetry/instrumentation-generic-pool@npm:^0.38.1": - version: 0.38.1 - resolution: "@opentelemetry/instrumentation-generic-pool@npm:0.38.1" - dependencies: - "@opentelemetry/instrumentation": ^0.52.0 - peerDependencies: - "@opentelemetry/api": ^1.3.0 - checksum: 19183c1d160d4c54d684305f6638163b5d2b84112b69e8281cd507e5ec5fa505431bc9a435f6c537bdea66a2820b4a231ed64c19da847d76e795036fcbfbd393 - languageName: node - linkType: hard - -"@opentelemetry/instrumentation-graphql@npm:^0.42.0": +"@opentelemetry/instrumentation-express@npm:^0.42.0": version: 0.42.0 - resolution: "@opentelemetry/instrumentation-graphql@npm:0.42.0" - dependencies: - "@opentelemetry/instrumentation": ^0.52.0 - peerDependencies: - "@opentelemetry/api": ^1.3.0 - checksum: cae523cf75312457dc176a1ae2e4157b41025c5d01d8174467c8a62f8031c3a90151888fcdd804778183f58618ec320a24fe78f5bb0a1a72a119dc37245be676 - languageName: node - linkType: hard - -"@opentelemetry/instrumentation-grpc@npm:^0.52.0": - version: 0.52.1 - resolution: "@opentelemetry/instrumentation-grpc@npm:0.52.1" - dependencies: - "@opentelemetry/instrumentation": 0.52.1 - "@opentelemetry/semantic-conventions": 1.25.1 - peerDependencies: - "@opentelemetry/api": ^1.3.0 - checksum: aa14515e5cb8b922f3414540fdaf986bb68f283ab05c57d5f6dad6f9a1f44c6416e5d8e4f6d2467829fb3f4afaf38c5d1c107574481297052477a34e28892cd1 - languageName: node - linkType: hard - -"@opentelemetry/instrumentation-hapi@npm:^0.40.0": - version: 0.40.0 - resolution: "@opentelemetry/instrumentation-hapi@npm:0.40.0" + resolution: "@opentelemetry/instrumentation-express@npm:0.42.0" dependencies: "@opentelemetry/core": ^1.8.0 - "@opentelemetry/instrumentation": ^0.52.0 - "@opentelemetry/semantic-conventions": ^1.22.0 + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/semantic-conventions": ^1.27.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 71ff845ca2376b5f1cf7514d649f829044dec6486e784351a26278afc092a1cd90eb0eaf34ab79afcae9244e8b126d6059ac0c7c286743ceb8e12126cf7e0255 + checksum: c4606bd593ee841eb891927f404609b05e1375b28f9e5cd179381b744d826e3a6d07d069835d02b06e2cd8de6861c0ecebaa2d3a180181733e9fdc6b80444837 languageName: node linkType: hard -"@opentelemetry/instrumentation-http@npm:^0.52.0": - version: 0.52.1 - resolution: "@opentelemetry/instrumentation-http@npm:0.52.1" +"@opentelemetry/instrumentation-fastify@npm:^0.39.0": + version: 0.39.0 + resolution: "@opentelemetry/instrumentation-fastify@npm:0.39.0" dependencies: - "@opentelemetry/core": 1.25.1 - "@opentelemetry/instrumentation": 0.52.1 - "@opentelemetry/semantic-conventions": 1.25.1 + "@opentelemetry/core": ^1.8.0 + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/semantic-conventions": ^1.27.0 + peerDependencies: + "@opentelemetry/api": ^1.3.0 + checksum: a64ffd35f01e6ae08a7de7092ef34ec186c284ebada7f8e4d87420440bbc5a00b568624e7c1dd35b00550d68ccb24ae905ad8488adb7eaf14344f334d436244e + languageName: node + linkType: hard + +"@opentelemetry/instrumentation-fs@npm:^0.15.0": + version: 0.15.0 + resolution: "@opentelemetry/instrumentation-fs@npm:0.15.0" + dependencies: + "@opentelemetry/core": ^1.8.0 + "@opentelemetry/instrumentation": ^0.53.0 + peerDependencies: + "@opentelemetry/api": ^1.3.0 + checksum: d1f50b541629e9155dcbfbdd26d5fa43d6569f835abf88ea35261e0c03c6afb89b26cd2056dda6e9c4de72a49d7e2ca0336e1dc75604256db09e0e09d2182466 + languageName: node + linkType: hard + +"@opentelemetry/instrumentation-generic-pool@npm:^0.39.0": + version: 0.39.0 + resolution: "@opentelemetry/instrumentation-generic-pool@npm:0.39.0" + dependencies: + "@opentelemetry/instrumentation": ^0.53.0 + peerDependencies: + "@opentelemetry/api": ^1.3.0 + checksum: 2d094b217afe9c1d388f06cdaca07f9801b70f0d01ee3db374f1b4f07cd18efba55e90679f0237c1f2a7db22f9ee0e564e8583161bb7d578ecea779b874e967e + languageName: node + linkType: hard + +"@opentelemetry/instrumentation-graphql@npm:^0.43.0": + version: 0.43.0 + resolution: "@opentelemetry/instrumentation-graphql@npm:0.43.0" + dependencies: + "@opentelemetry/instrumentation": ^0.53.0 + peerDependencies: + "@opentelemetry/api": ^1.3.0 + checksum: 4164f3dad9c44f3d9684750d879ba79a51949fe69179d8437f5736762cdd0156c63a8914c7accd767b090a18db45f011a9cff5e238d3240077f1c095d3c5dd28 + languageName: node + linkType: hard + +"@opentelemetry/instrumentation-grpc@npm:^0.53.0": + version: 0.53.0 + resolution: "@opentelemetry/instrumentation-grpc@npm:0.53.0" + dependencies: + "@opentelemetry/instrumentation": 0.53.0 + "@opentelemetry/semantic-conventions": 1.27.0 + peerDependencies: + "@opentelemetry/api": ^1.3.0 + checksum: 937e96ec7fe655d3599ba71ffe48d79ff068e3ce820600249ed2807d2e7b2769e0771b723e5961bcd11ae8585df26f596a39e320497a9d3299d816510bb61eca + languageName: node + linkType: hard + +"@opentelemetry/instrumentation-hapi@npm:^0.41.0": + version: 0.41.0 + resolution: "@opentelemetry/instrumentation-hapi@npm:0.41.0" + dependencies: + "@opentelemetry/core": ^1.8.0 + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/semantic-conventions": ^1.27.0 + peerDependencies: + "@opentelemetry/api": ^1.3.0 + checksum: 2195c8366d9b81a40dd6d8db041c13687932ab7ec761c9dfea13162c4000638c699dfebf384e22f985aea2d7692c742ed8090cb5bad056e5137d2db79a615380 + languageName: node + linkType: hard + +"@opentelemetry/instrumentation-http@npm:^0.53.0": + version: 0.53.0 + resolution: "@opentelemetry/instrumentation-http@npm:0.53.0" + dependencies: + "@opentelemetry/core": 1.26.0 + "@opentelemetry/instrumentation": 0.53.0 + "@opentelemetry/semantic-conventions": 1.27.0 semver: ^7.5.2 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 67a31e14d9ee4da745b7529777c1525f717b2ddf09f2a9247acaa9677f32e4a863d8f0712c95917fdbe74d8211cf650065bb3a95ef2fdd9f81630e063cbc2d4f + checksum: 4ee569f7fc8c7ce50fabaff016d33577f36e63272b0634ac45806d70bffdf38fcf09db3cd9dd27c3150f6c4547fec673c356c419a6ed2399ff2849b9487a6e89 languageName: node linkType: hard -"@opentelemetry/instrumentation-ioredis@npm:^0.42.0": - version: 0.42.0 - resolution: "@opentelemetry/instrumentation-ioredis@npm:0.42.0" +"@opentelemetry/instrumentation-ioredis@npm:^0.43.0": + version: 0.43.0 + resolution: "@opentelemetry/instrumentation-ioredis@npm:0.43.0" dependencies: - "@opentelemetry/instrumentation": ^0.52.0 + "@opentelemetry/instrumentation": ^0.53.0 "@opentelemetry/redis-common": ^0.36.2 - "@opentelemetry/semantic-conventions": ^1.23.0 + "@opentelemetry/semantic-conventions": ^1.27.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: ae4804732b4380007b09ba11051aae927da0c53cd74d556916a838fb4de4f3c2aa7156bc05c4f34e6669411835604a4587822b2b585c51042e502d0e5079c143 + checksum: 16ae17687db3b4bbe78d92667ce86f3afb212adb5eda8f17b549a06ff9e1ba3e0f146ded9e943cb781780b64853a6b7fa3b85d2c2f5e4f42fd76d651c90aa71f languageName: node linkType: hard -"@opentelemetry/instrumentation-kafkajs@npm:^0.2.0": - version: 0.2.0 - resolution: "@opentelemetry/instrumentation-kafkajs@npm:0.2.0" +"@opentelemetry/instrumentation-kafkajs@npm:^0.3.0": + version: 0.3.0 + resolution: "@opentelemetry/instrumentation-kafkajs@npm:0.3.0" dependencies: - "@opentelemetry/instrumentation": ^0.52.0 - "@opentelemetry/semantic-conventions": ^1.24.0 + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/semantic-conventions": ^1.27.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: f5790d426d87d35159954eed4368b52818f9faf5a999ade66fffc1662c12234caa79a04493266ea2995205e94051b173a831012e3a57c5a9a2417bd07a0e1378 + checksum: 9ea20f4f70edd7d47b551f56f56b6b0462e5f9dff3981462d9d061084a3bb345f1989ddc46a2d8fabebf2a9650c52ab6c6fb906a03e9176191cc71073c2bf22c languageName: node linkType: hard -"@opentelemetry/instrumentation-knex@npm:^0.39.0": - version: 0.39.0 - resolution: "@opentelemetry/instrumentation-knex@npm:0.39.0" +"@opentelemetry/instrumentation-knex@npm:^0.40.0": + version: 0.40.0 + resolution: "@opentelemetry/instrumentation-knex@npm:0.40.0" dependencies: - "@opentelemetry/instrumentation": ^0.52.0 - "@opentelemetry/semantic-conventions": ^1.22.0 + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/semantic-conventions": ^1.27.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: fd44998d57fd6403fcb90fb465cdf071da3d8cbdd161470277ffcb7a7553b04222ceb8d95285391cdb6d5abdd09d90c6fe5d6740a2248c004f163386f10fc235 + checksum: ca7f08b4a783ebb470663fa53a5418074cc04a42ad7b6f19939be04aff1c0db2070ca8b7ada17e363a412b1013149bde38bf1930f05c09cd6207a90711db0372 languageName: node linkType: hard -"@opentelemetry/instrumentation-koa@npm:^0.42.0": - version: 0.42.0 - resolution: "@opentelemetry/instrumentation-koa@npm:0.42.0" +"@opentelemetry/instrumentation-koa@npm:^0.43.0": + version: 0.43.0 + resolution: "@opentelemetry/instrumentation-koa@npm:0.43.0" dependencies: "@opentelemetry/core": ^1.8.0 - "@opentelemetry/instrumentation": ^0.52.0 - "@opentelemetry/semantic-conventions": ^1.22.0 + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/semantic-conventions": ^1.27.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 4e41f4b1c2abb4d31151ae3b5999af3247affa99fadcf87ff542a8523f108275d83a54057d79453ff56bc40938a622803562db87c826bfac9f99fb409207c6fd + checksum: 7b30d11f8cbabc1570eeca771f421c65f014d87b850cf17a8f2aec98dc84a8a43ce6fe15634f5d16944466f8da1011508367498e215b3f6378e8f8d618a12ec9 languageName: node linkType: hard -"@opentelemetry/instrumentation-lru-memoizer@npm:^0.39.0": +"@opentelemetry/instrumentation-lru-memoizer@npm:^0.40.0": + version: 0.40.0 + resolution: "@opentelemetry/instrumentation-lru-memoizer@npm:0.40.0" + dependencies: + "@opentelemetry/instrumentation": ^0.53.0 + peerDependencies: + "@opentelemetry/api": ^1.3.0 + checksum: 1a65e7c397707f9d09fe11f9fbd127d5094406ec98f84e74309c1d9869da23173c3895c851bccf9c5c1b8aeef6fc516340311f87d154832c74a344a0ed4ac9ef + languageName: node + linkType: hard + +"@opentelemetry/instrumentation-memcached@npm:^0.39.0": version: 0.39.0 - resolution: "@opentelemetry/instrumentation-lru-memoizer@npm:0.39.0" + resolution: "@opentelemetry/instrumentation-memcached@npm:0.39.0" dependencies: - "@opentelemetry/instrumentation": ^0.52.0 - peerDependencies: - "@opentelemetry/api": ^1.3.0 - checksum: 4a9b973bbf4fe77b11fafb4215bd9985f6a3c7ce487af965d98e5502e91a3fb78fc70a3f2238ef46a9c065e1555dfc08c22c39f0d1eb3925cd88c3201c8a79e5 - languageName: node - linkType: hard - -"@opentelemetry/instrumentation-memcached@npm:^0.38.0": - version: 0.38.0 - resolution: "@opentelemetry/instrumentation-memcached@npm:0.38.0" - dependencies: - "@opentelemetry/instrumentation": ^0.52.0 - "@opentelemetry/semantic-conventions": ^1.23.0 + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/semantic-conventions": ^1.27.0 "@types/memcached": ^2.2.6 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 05e8e25c809461e8aedaf3ba37eec1bbed6cec1307a28a93a986ea1828b791dc2488cd2f83b0fec678c402b7e703fc7ab884274036d0b5df48c8e70b9376648b + checksum: bbf976f90463fe1b8a64d6e20057fc1926342a1f644e4cfd160ce1b0a032269b48b754e6cd86eff41faf92bd2e3617f1572a1ef272cb5059ed21aaf7c6591ccb languageName: node linkType: hard -"@opentelemetry/instrumentation-mongodb@npm:^0.46.0": - version: 0.46.0 - resolution: "@opentelemetry/instrumentation-mongodb@npm:0.46.0" +"@opentelemetry/instrumentation-mongodb@npm:^0.47.0": + version: 0.47.0 + resolution: "@opentelemetry/instrumentation-mongodb@npm:0.47.0" dependencies: - "@opentelemetry/instrumentation": ^0.52.0 + "@opentelemetry/instrumentation": ^0.53.0 "@opentelemetry/sdk-metrics": ^1.9.1 - "@opentelemetry/semantic-conventions": ^1.22.0 + "@opentelemetry/semantic-conventions": ^1.27.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: fab5db536e2e95177a0ae0975bd8b9fc76f2d59bf89a6023547ba39071b97789859e1ac0582f86498a263611403a70b5f543b025207180770c07e178b04af5ad + checksum: 1d7c87532b5857e8d6d72272ce874f02a4b2adc8a135d07c48e432cc990a4493c110b15c842c72dfc79e33ddc63f518185b69e242e2c55521a06fe6503cb1980 languageName: node linkType: hard -"@opentelemetry/instrumentation-mongoose@npm:^0.41.0": - version: 0.41.0 - resolution: "@opentelemetry/instrumentation-mongoose@npm:0.41.0" +"@opentelemetry/instrumentation-mongoose@npm:^0.42.0": + version: 0.42.0 + resolution: "@opentelemetry/instrumentation-mongoose@npm:0.42.0" dependencies: "@opentelemetry/core": ^1.8.0 - "@opentelemetry/instrumentation": ^0.52.0 - "@opentelemetry/semantic-conventions": ^1.22.0 + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/semantic-conventions": ^1.27.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 0961538ef1a3d9798e1f70baf206f22318b9a463b2ee50b0270faca434ef974a2bac2d872bebe698cbace17594a27dee43893e11d5ede3704055463fdd781271 + checksum: 77d36437073ee589ccd73f4a10a4602afd0f4a3a89a9c572be18b2df75941f5a6885d4823094d8ffe8859801d827d0b46f93dee03f39286d89eead373edf76bb languageName: node linkType: hard -"@opentelemetry/instrumentation-mysql2@npm:^0.40.0": - version: 0.40.0 - resolution: "@opentelemetry/instrumentation-mysql2@npm:0.40.0" +"@opentelemetry/instrumentation-mysql2@npm:^0.41.0": + version: 0.41.0 + resolution: "@opentelemetry/instrumentation-mysql2@npm:0.41.0" dependencies: - "@opentelemetry/instrumentation": ^0.52.0 - "@opentelemetry/semantic-conventions": ^1.22.0 + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/semantic-conventions": ^1.27.0 "@opentelemetry/sql-common": ^0.40.1 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: acdb9883d1ab92d0bfbe507736888cc0b0d7b25c3d24c27b51add17abceff4bf15988a3cd2e54b93256f28bbc65aa172f116df9277545143e20e8d7b497e2e63 + checksum: 37c8a57fb6591ae1db353e149ad5f38ac68c5f727e313ba6d1cc403d910ae8e3b743c3234500272012ea6eecb5b838803ee493ce5096ad40bb285b09090f4a65 languageName: node linkType: hard -"@opentelemetry/instrumentation-mysql@npm:^0.40.0": +"@opentelemetry/instrumentation-mysql@npm:^0.41.0": + version: 0.41.0 + resolution: "@opentelemetry/instrumentation-mysql@npm:0.41.0" + dependencies: + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/semantic-conventions": ^1.27.0 + "@types/mysql": 2.15.26 + peerDependencies: + "@opentelemetry/api": ^1.3.0 + checksum: c8c23a1273e900902867ca4da8c026581d3f584e420a5f26ec738ace20c1a85695a411721541e63e0639d9ddbb8c3713a2bc25621886f81912014882395d3531 + languageName: node + linkType: hard + +"@opentelemetry/instrumentation-nestjs-core@npm:^0.40.0": version: 0.40.0 - resolution: "@opentelemetry/instrumentation-mysql@npm:0.40.0" + resolution: "@opentelemetry/instrumentation-nestjs-core@npm:0.40.0" dependencies: - "@opentelemetry/instrumentation": ^0.52.0 - "@opentelemetry/semantic-conventions": ^1.22.0 - "@types/mysql": 2.15.22 + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/semantic-conventions": ^1.27.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 6eeba06f7507ab9086ef18b9e37802f12ac0a9f6182d4aba3aaf71a3e0f0759cb51c044247653eb8e359383d922a12a0fc0f129b2982bae17910462450cdb189 + checksum: ce6b2d9186d95e5fa5c65efd902254c724e296172787d1fa9382a6204ae9d089e861ce8831ba6e6865d449a96a8aada7b1049568217f1bda21af3f36e01b9512 languageName: node linkType: hard -"@opentelemetry/instrumentation-nestjs-core@npm:^0.39.0": +"@opentelemetry/instrumentation-net@npm:^0.39.0": version: 0.39.0 - resolution: "@opentelemetry/instrumentation-nestjs-core@npm:0.39.0" + resolution: "@opentelemetry/instrumentation-net@npm:0.39.0" dependencies: - "@opentelemetry/instrumentation": ^0.52.0 - "@opentelemetry/semantic-conventions": ^1.23.0 + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/semantic-conventions": ^1.27.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 4394754ce3ef4747e39a59a602c744112f9d6d3ee7ef43a51f1562a977a8e2bb2944687d3dd199f0a5941517e71a84ff9ea9ce183d94b63a3311e9de6ac8e09c + checksum: ae3c7cdb4894a9aae7ea7a4d6a00cbef4afc2194539226f01f68ee78d25fb2d5debfb738b8a79a9842c4987bc4c673c7e6386d328c1e6bfc09e2613bf4677ed3 languageName: node linkType: hard -"@opentelemetry/instrumentation-net@npm:^0.38.0": - version: 0.38.0 - resolution: "@opentelemetry/instrumentation-net@npm:0.38.0" +"@opentelemetry/instrumentation-pg@npm:^0.44.0": + version: 0.44.0 + resolution: "@opentelemetry/instrumentation-pg@npm:0.44.0" dependencies: - "@opentelemetry/instrumentation": ^0.52.0 - "@opentelemetry/semantic-conventions": ^1.23.0 - peerDependencies: - "@opentelemetry/api": ^1.3.0 - checksum: 13b4e12272ec3c7c2930a4dfd5eabf843d9e008a651c6a5f778236676526a76c563af7d313bf0edb390377d62112c07382b176f64beeffd534ed4f2c04923ccb - languageName: node - linkType: hard - -"@opentelemetry/instrumentation-pg@npm:^0.43.0": - version: 0.43.0 - resolution: "@opentelemetry/instrumentation-pg@npm:0.43.0" - dependencies: - "@opentelemetry/instrumentation": ^0.52.0 - "@opentelemetry/semantic-conventions": ^1.22.0 + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/semantic-conventions": ^1.27.0 "@opentelemetry/sql-common": ^0.40.1 "@types/pg": 8.6.1 - "@types/pg-pool": 2.0.4 + "@types/pg-pool": 2.0.6 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: d255806b9e5ffd449b7ab3c7c072e919ad8a18118cdf5aec636d89a89d9ac63ef282f280d3b2dd7fa9c57e748fc0c9b38294911bf1aaff35e821079aaeacbd82 + checksum: 13cf8bacee1139b551622cb76670c627e87b37ee5ad2b6c63417d985812c7db53ce7aae23bd04156cb5c0d1a214bb8c65890fde43fbd99aac540c625216703b7 languageName: node linkType: hard -"@opentelemetry/instrumentation-pino@npm:^0.41.0": - version: 0.41.0 - resolution: "@opentelemetry/instrumentation-pino@npm:0.41.0" +"@opentelemetry/instrumentation-pino@npm:^0.42.0": + version: 0.42.0 + resolution: "@opentelemetry/instrumentation-pino@npm:0.42.0" dependencies: - "@opentelemetry/api-logs": ^0.52.0 + "@opentelemetry/api-logs": ^0.53.0 "@opentelemetry/core": ^1.25.0 - "@opentelemetry/instrumentation": ^0.52.0 + "@opentelemetry/instrumentation": ^0.53.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 1eb2a67513952e3cd7db0ea5fac39a6dffdf28f8ce514af7f39d70263780d1495773e6554bf386e6935c2f0145ca4a73cb4829f6ee91c630bbc85d5ccd164ce0 + checksum: 005146e233c53ffbf703c97d855a523fe91d9d2632b77fd0b094caec6f3646908fd03c22bea77575d4a75eac0a2aa2065c7a2d9caac45c370e9592abe9b231c1 languageName: node linkType: hard -"@opentelemetry/instrumentation-redis-4@npm:^0.41.1": - version: 0.41.1 - resolution: "@opentelemetry/instrumentation-redis-4@npm:0.41.1" +"@opentelemetry/instrumentation-redis-4@npm:^0.42.0": + version: 0.42.0 + resolution: "@opentelemetry/instrumentation-redis-4@npm:0.42.0" dependencies: - "@opentelemetry/instrumentation": ^0.52.0 + "@opentelemetry/instrumentation": ^0.53.0 "@opentelemetry/redis-common": ^0.36.2 - "@opentelemetry/semantic-conventions": ^1.22.0 + "@opentelemetry/semantic-conventions": ^1.27.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: d67c542e9ea30bf7dcfb651eba033636d8ee379a135455c314688327c6bcb6512e7f41b7e1e97cbd62475f4afda2582f9be5ac0fd87cf2e008cdfa337a5b667d + checksum: b6d92ad302c31add32b1cdfe6f6ea836367a777737beb187b178bfb65047f84263b38855cda56746b793582eb6012942c03ed91f6e8e6710058bf3eb427fba2d languageName: node linkType: hard -"@opentelemetry/instrumentation-redis@npm:^0.41.0": +"@opentelemetry/instrumentation-redis@npm:^0.42.0": + version: 0.42.0 + resolution: "@opentelemetry/instrumentation-redis@npm:0.42.0" + dependencies: + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/redis-common": ^0.36.2 + "@opentelemetry/semantic-conventions": ^1.27.0 + peerDependencies: + "@opentelemetry/api": ^1.3.0 + checksum: 1a84b516599a290de78eaf1a1db897bf2e866baaf4a77a76880b24261786f6ffa2673fcec36f360abf73d5e52104557ff957964b7b3683962b0bde2bbfbb074e + languageName: node + linkType: hard + +"@opentelemetry/instrumentation-restify@npm:^0.41.0": version: 0.41.0 - resolution: "@opentelemetry/instrumentation-redis@npm:0.41.0" - dependencies: - "@opentelemetry/instrumentation": ^0.52.0 - "@opentelemetry/redis-common": ^0.36.2 - "@opentelemetry/semantic-conventions": ^1.22.0 - peerDependencies: - "@opentelemetry/api": ^1.3.0 - checksum: a1caf71394ece352da20159e007d938fb22cea6c0c266addfa5e59dcf639c7d16404531edb1a7c94a3464db275927f8886f13e67eacedc3e94d97ff4b55c23aa - languageName: node - linkType: hard - -"@opentelemetry/instrumentation-restify@npm:^0.40.0": - version: 0.40.0 - resolution: "@opentelemetry/instrumentation-restify@npm:0.40.0" + resolution: "@opentelemetry/instrumentation-restify@npm:0.41.0" dependencies: "@opentelemetry/core": ^1.8.0 - "@opentelemetry/instrumentation": ^0.52.0 - "@opentelemetry/semantic-conventions": ^1.22.0 + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/semantic-conventions": ^1.27.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 813b755bd4510d8eef5322e1c9d0aa93407eea62a9bf4f3a82fa2ba38ecfa7e9fe287299eeef84cd4a2912ae9aceecb6392b40fb763d4329f953cb86a69eae61 + checksum: 28aac1e5bf2cdca2fa18c8423db3edb530bc338bb05a30537c24575bac12f4588d975598b020f58817393cf68354b913ca07e3720b3ff8497278887baee7b10b languageName: node linkType: hard -"@opentelemetry/instrumentation-router@npm:^0.39.0": - version: 0.39.0 - resolution: "@opentelemetry/instrumentation-router@npm:0.39.0" +"@opentelemetry/instrumentation-router@npm:^0.40.0": + version: 0.40.0 + resolution: "@opentelemetry/instrumentation-router@npm:0.40.0" dependencies: - "@opentelemetry/instrumentation": ^0.52.0 - "@opentelemetry/semantic-conventions": ^1.22.0 + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/semantic-conventions": ^1.27.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 802d4179caab4a0ae40745f200809efe6ed1a0e837483dacddb8dcecfe808f7ca42ddac9358715c8949bd59e91da2e7ef1e2afbd0203e22a48af1620f9437c10 + checksum: 7f8fb67d755cb8fa94dbe44f698d22e1ce80971071f574aa9a8b177410cf6a8ab37abd449777670705b73aa6a4272212e80d6dc3c6ec0aa7f99ce161238c7f33 languageName: node linkType: hard -"@opentelemetry/instrumentation-socket.io@npm:^0.41.0": - version: 0.41.0 - resolution: "@opentelemetry/instrumentation-socket.io@npm:0.41.0" +"@opentelemetry/instrumentation-socket.io@npm:^0.42.0": + version: 0.42.0 + resolution: "@opentelemetry/instrumentation-socket.io@npm:0.42.0" dependencies: - "@opentelemetry/instrumentation": ^0.52.0 - "@opentelemetry/semantic-conventions": ^1.22.0 + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/semantic-conventions": ^1.27.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: a50e66dabc1670906dba51bbcbabcdfdb865157b38e7086ce07275b8d3bde3263fa527a1b054ce55d8bbf8bba3ad6aba64319019015eb85299d46f1e3334f8e0 + checksum: 21f92a17b26627ac03bf19f8c5eea550bac915366919a7b7f73893f0bdd8669421e02ec0379387439a46b1e1ad05dfe8dc9a6f6784b9dc8919f8c7dc05694dd8 languageName: node linkType: hard -"@opentelemetry/instrumentation-tedious@npm:^0.13.0": - version: 0.13.0 - resolution: "@opentelemetry/instrumentation-tedious@npm:0.13.0" +"@opentelemetry/instrumentation-tedious@npm:^0.14.0": + version: 0.14.0 + resolution: "@opentelemetry/instrumentation-tedious@npm:0.14.0" dependencies: - "@opentelemetry/instrumentation": ^0.52.0 - "@opentelemetry/semantic-conventions": ^1.22.0 + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/semantic-conventions": ^1.27.0 "@types/tedious": ^4.0.14 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 71833d6989d91a4696c3c73836fc12f31930f9fe30e95d20107d5e54054d1276baeeda7ee125c4f43d9859a1337fe017d1d91899e28d506ab275a68ab84e3bee + checksum: 31d6f0d10c3c1f03c9bf3207d7b5569f23ff202f954cb5b91242d788813b5807e5fc204748d14c3b12d320fa5dc1205d4b54131847496117af54e205f025a23e languageName: node linkType: hard -"@opentelemetry/instrumentation-undici@npm:^0.5.0": - version: 0.5.0 - resolution: "@opentelemetry/instrumentation-undici@npm:0.5.0" +"@opentelemetry/instrumentation-undici@npm:^0.6.0": + version: 0.6.0 + resolution: "@opentelemetry/instrumentation-undici@npm:0.6.0" dependencies: "@opentelemetry/core": ^1.8.0 - "@opentelemetry/instrumentation": ^0.52.0 + "@opentelemetry/instrumentation": ^0.53.0 peerDependencies: "@opentelemetry/api": ^1.7.0 - checksum: 534a5f9171fcd806332096a996fe1a3ceffaef5e04c3332b82d73242909b21941c4b857e6658d75a29c140c4f5c89d39a157bc7023a774d61b559d2086137138 + checksum: b16b9ff23fbca13a18889fc302ddae3db8b22ebd9d8224b0297bd45014bb914d6bea89e55aedda6879cee1760c93bcedc2eaa12e60e88f45dd8c9e5f61a0aefd languageName: node linkType: hard -"@opentelemetry/instrumentation-winston@npm:^0.39.0": - version: 0.39.0 - resolution: "@opentelemetry/instrumentation-winston@npm:0.39.0" +"@opentelemetry/instrumentation-winston@npm:^0.40.0": + version: 0.40.0 + resolution: "@opentelemetry/instrumentation-winston@npm:0.40.0" dependencies: - "@opentelemetry/api-logs": ^0.52.0 - "@opentelemetry/instrumentation": ^0.52.0 + "@opentelemetry/api-logs": ^0.53.0 + "@opentelemetry/instrumentation": ^0.53.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: df2d28ae4dbe65294afeaee36b5b914d96473674e968f939bfd64a2288730b21911c920168b4f2e4961d8b03c988e327ae828b84a5d1875cb424b84b6fd80e1a + checksum: be7c3f6f8a5672db940b8196e9254a4188c9c6bb717a272088fe5e8319874a80a28a56b1073ad130bb2233a29d4459a754b4ea2f36855f90a679a9c379f5cf16 languageName: node linkType: hard -"@opentelemetry/instrumentation@npm:0.52.1, @opentelemetry/instrumentation@npm:^0.52.0": - version: 0.52.1 - resolution: "@opentelemetry/instrumentation@npm:0.52.1" - dependencies: - "@opentelemetry/api-logs": 0.52.1 - "@types/shimmer": ^1.0.2 - import-in-the-middle: ^1.8.1 - require-in-the-middle: ^7.1.1 - semver: ^7.5.2 - shimmer: ^1.2.1 - peerDependencies: - "@opentelemetry/api": ^1.3.0 - checksum: e8b4f202dc9355ca46714349a5e1663346e162f79706eed38015edf38fc536330fde4cc19ed7d3d6b03258c890c1dc0ba6d658d7aac3f41f1803bd03699d2701 - languageName: node - linkType: hard - -"@opentelemetry/instrumentation@npm:0.53.0": +"@opentelemetry/instrumentation@npm:0.53.0, @opentelemetry/instrumentation@npm:^0.53.0": version: 0.53.0 resolution: "@opentelemetry/instrumentation@npm:0.53.0" dependencies: @@ -13407,18 +13726,6 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/otlp-exporter-base@npm:0.52.1": - version: 0.52.1 - resolution: "@opentelemetry/otlp-exporter-base@npm:0.52.1" - dependencies: - "@opentelemetry/core": 1.25.1 - "@opentelemetry/otlp-transformer": 0.52.1 - peerDependencies: - "@opentelemetry/api": ^1.0.0 - checksum: a1629886907a393e24a91ef5adc389e093d3725dd2957bc29903442541b2a30673100b13c200c37fe0a2e2fec53ced8b47ad90064ebc49f2e9382c2b1719d3c3 - languageName: node - linkType: hard - "@opentelemetry/otlp-exporter-base@npm:0.53.0": version: 0.53.0 resolution: "@opentelemetry/otlp-exporter-base@npm:0.53.0" @@ -13431,20 +13738,6 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/otlp-grpc-exporter-base@npm:0.52.1": - version: 0.52.1 - resolution: "@opentelemetry/otlp-grpc-exporter-base@npm:0.52.1" - dependencies: - "@grpc/grpc-js": ^1.7.1 - "@opentelemetry/core": 1.25.1 - "@opentelemetry/otlp-exporter-base": 0.52.1 - "@opentelemetry/otlp-transformer": 0.52.1 - peerDependencies: - "@opentelemetry/api": ^1.0.0 - checksum: 22b1eb92ceec038807d60b7341bea7237ea903f0e2cf91b4fefbaf4cc283518b89a819da18b966a4b61915c7143e00ccc51ef909c3de5fa518b0dbe6c78abc5f - languageName: node - linkType: hard - "@opentelemetry/otlp-grpc-exporter-base@npm:0.53.0": version: 0.53.0 resolution: "@opentelemetry/otlp-grpc-exporter-base@npm:0.53.0" @@ -13459,23 +13752,6 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/otlp-transformer@npm:0.52.1": - version: 0.52.1 - resolution: "@opentelemetry/otlp-transformer@npm:0.52.1" - dependencies: - "@opentelemetry/api-logs": 0.52.1 - "@opentelemetry/core": 1.25.1 - "@opentelemetry/resources": 1.25.1 - "@opentelemetry/sdk-logs": 0.52.1 - "@opentelemetry/sdk-metrics": 1.25.1 - "@opentelemetry/sdk-trace-base": 1.25.1 - protobufjs: ^7.3.0 - peerDependencies: - "@opentelemetry/api": ">=1.3.0 <1.10.0" - checksum: 0e083ee484a79506d8ce41a8dd5d2d4d7669c380ac1ef9c313c348a6af8384365d2b90d99165590cced6453ce9192c0fe270d9cc974e9240e8ca02a6cf70151d - languageName: node - linkType: hard - "@opentelemetry/otlp-transformer@npm:0.53.0": version: 0.53.0 resolution: "@opentelemetry/otlp-transformer@npm:0.53.0" @@ -13493,12 +13769,12 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/propagation-utils@npm:^0.30.10": - version: 0.30.10 - resolution: "@opentelemetry/propagation-utils@npm:0.30.10" +"@opentelemetry/propagation-utils@npm:^0.30.11": + version: 0.30.11 + resolution: "@opentelemetry/propagation-utils@npm:0.30.11" peerDependencies: "@opentelemetry/api": ^1.0.0 - checksum: 6e193bdb6fb0c1b93d9cf5dab518ae73f152b51710081472f1cc4f74fcc30dcf545ba74881c182347ac894595f5db719a989ee9dbbc905b70218a7ddc5a625aa + checksum: 4cce9958ca40b042adda8601b651799f1a140a513dd8c085094cb88265470bf40a04ed5f84301d891fef90f59698802e20828311b6189e4ab6c741101d8ac248 languageName: node linkType: hard @@ -13513,17 +13789,6 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/propagator-b3@npm:1.25.1": - version: 1.25.1 - resolution: "@opentelemetry/propagator-b3@npm:1.25.1" - dependencies: - "@opentelemetry/core": 1.25.1 - peerDependencies: - "@opentelemetry/api": ">=1.0.0 <1.10.0" - checksum: 7aef1e192b33533dfc9fd759efc9cea65cc29f1f35c0e1a2bb4065244ed9a78b18d4a9c843c646484e61f83834d6162ae2a1ebfc40750e4eae844e5dd4b85565 - languageName: node - linkType: hard - "@opentelemetry/propagator-b3@npm:1.26.0": version: 1.26.0 resolution: "@opentelemetry/propagator-b3@npm:1.26.0" @@ -13535,17 +13800,6 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/propagator-jaeger@npm:1.25.1": - version: 1.25.1 - resolution: "@opentelemetry/propagator-jaeger@npm:1.25.1" - dependencies: - "@opentelemetry/core": 1.25.1 - peerDependencies: - "@opentelemetry/api": ">=1.0.0 <1.10.0" - checksum: 89b1e9f4daa2494ef472a16ddf1eb8cad547f78bf3255cf724113c346fe9be9965fd36ed5ffcb4098ecfec25ebb120d8e3e06a5783999cdf552f164047938028 - languageName: node - linkType: hard - "@opentelemetry/propagator-jaeger@npm:1.26.0": version: 1.26.0 resolution: "@opentelemetry/propagator-jaeger@npm:1.26.0" @@ -13564,79 +13818,67 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/resource-detector-alibaba-cloud@npm:^0.29.0": - version: 0.29.0 - resolution: "@opentelemetry/resource-detector-alibaba-cloud@npm:0.29.0" +"@opentelemetry/resource-detector-alibaba-cloud@npm:^0.29.1": + version: 0.29.1 + resolution: "@opentelemetry/resource-detector-alibaba-cloud@npm:0.29.1" dependencies: "@opentelemetry/resources": ^1.0.0 - "@opentelemetry/semantic-conventions": ^1.22.0 + "@opentelemetry/semantic-conventions": ^1.27.0 peerDependencies: "@opentelemetry/api": ^1.0.0 - checksum: aaeec6ea8e36f93bd2d38ac004fa9f53fd87c6d352977f138fe4ee67d93f64b4fb2d48a9d88b523622cfa1b307aa2ef1a4a21943f8844e98d19ae5f5cfc965a3 + checksum: 8b32490aaa18996aaed79d2b512d947ea0509c326002b98ec63fcba8ad3793e63365f338f5792bf0dd6c4141126ca491dff3bbf079fa37fdf78a772bb6c8d487 languageName: node linkType: hard -"@opentelemetry/resource-detector-aws@npm:^1.6.0": - version: 1.6.0 - resolution: "@opentelemetry/resource-detector-aws@npm:1.6.0" +"@opentelemetry/resource-detector-aws@npm:^1.6.1": + version: 1.6.1 + resolution: "@opentelemetry/resource-detector-aws@npm:1.6.1" dependencies: "@opentelemetry/core": ^1.0.0 "@opentelemetry/resources": ^1.10.0 - "@opentelemetry/semantic-conventions": ^1.22.0 + "@opentelemetry/semantic-conventions": ^1.27.0 peerDependencies: "@opentelemetry/api": ^1.0.0 - checksum: e552552fca0817874cb722bb0054b5d2e25922dea4ec42658cafdcb6465ee4015c6a56b53c6c7ab2d5f1eea4ef04018953f28bf41e4395e1a9caba6a060e0cd2 + checksum: ff466f439c2dc061e5c587226ebace5f6d88ddda923889842d6c7fc4076dd88bf27096e4f80f23e8c37bde4e309b3666c7e0fd90637f2dffa6581e9e9cf75a33 languageName: node linkType: hard -"@opentelemetry/resource-detector-azure@npm:^0.2.10": - version: 0.2.10 - resolution: "@opentelemetry/resource-detector-azure@npm:0.2.10" +"@opentelemetry/resource-detector-azure@npm:^0.2.11": + version: 0.2.11 + resolution: "@opentelemetry/resource-detector-azure@npm:0.2.11" dependencies: "@opentelemetry/core": ^1.25.1 "@opentelemetry/resources": ^1.10.1 - "@opentelemetry/semantic-conventions": ^1.22.0 + "@opentelemetry/semantic-conventions": ^1.27.0 peerDependencies: "@opentelemetry/api": ^1.0.0 - checksum: 8cb8b1d2633407414f5f9f3b250d8a31ee76d47216d6bfe396a59ee2e091eb7a6881c399b27bb47de509154ff2e43f13f6b419f6a3a9c743a2bb1a42b5775ed2 + checksum: 13515be1d57f9a9611064224e55766a7a66176d85bcbc62e7313e261c0a40e8c02e6ec024ed51f1e20ce16f3e969a601a756d2130f01b24a1e088743886903b3 languageName: node linkType: hard -"@opentelemetry/resource-detector-container@npm:^0.4.0": - version: 0.4.0 - resolution: "@opentelemetry/resource-detector-container@npm:0.4.0" +"@opentelemetry/resource-detector-container@npm:^0.4.1": + version: 0.4.1 + resolution: "@opentelemetry/resource-detector-container@npm:0.4.1" dependencies: "@opentelemetry/resources": ^1.10.0 - "@opentelemetry/semantic-conventions": ^1.22.0 + "@opentelemetry/semantic-conventions": ^1.27.0 peerDependencies: "@opentelemetry/api": ^1.0.0 - checksum: a847f147412afb6ecfabe9ee37742a3d80e83a96657c80da4c05ee5380e4cc4d596d5ff8872b45402bd550462ff1d6363bed035f04d67004c3a3e864f1eb658d + checksum: 7a8e5715469209881f63fe21745d807e821fa3cdf4bd4751b2da43078607b9498a18773a7bd47ba22e872397766d2c3bbf55d168ad0d9ad31c159979a32d62bf languageName: node linkType: hard -"@opentelemetry/resource-detector-gcp@npm:^0.29.10": - version: 0.29.10 - resolution: "@opentelemetry/resource-detector-gcp@npm:0.29.10" +"@opentelemetry/resource-detector-gcp@npm:^0.29.11": + version: 0.29.11 + resolution: "@opentelemetry/resource-detector-gcp@npm:0.29.11" dependencies: "@opentelemetry/core": ^1.0.0 "@opentelemetry/resources": ^1.0.0 - "@opentelemetry/semantic-conventions": ^1.22.0 + "@opentelemetry/semantic-conventions": ^1.27.0 gcp-metadata: ^6.0.0 peerDependencies: "@opentelemetry/api": ^1.0.0 - checksum: 68c3ae4bffb96aba16292e47a1981e115c9971457d1e5952c1cc1cd2f82e675b0f1ede55181e11a044de79ae729c9afe801f5e14ac0a70540f734c0b9e89944d - languageName: node - linkType: hard - -"@opentelemetry/resources@npm:1.25.1": - version: 1.25.1 - resolution: "@opentelemetry/resources@npm:1.25.1" - dependencies: - "@opentelemetry/core": 1.25.1 - "@opentelemetry/semantic-conventions": 1.25.1 - peerDependencies: - "@opentelemetry/api": ">=1.0.0 <1.10.0" - checksum: 806e5aabbc93afcab767dc84707f702ca51bbc93e4565eb69a8591ed2fe78439aca19c5ca0d9f044c85ed97b9efb35936fdb65bef01f5f3e68504002c8a07220 + checksum: 4e47558b767c97e9dae67f648449987cd7dd372a8d29e1ee7eefa3da6cf15d944f7f8f9a8a8f07026e7843b95958faf26739c24cabbb106e923f898abeae5132 languageName: node linkType: hard @@ -13652,19 +13894,6 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/sdk-logs@npm:0.52.1": - version: 0.52.1 - resolution: "@opentelemetry/sdk-logs@npm:0.52.1" - dependencies: - "@opentelemetry/api-logs": 0.52.1 - "@opentelemetry/core": 1.25.1 - "@opentelemetry/resources": 1.25.1 - peerDependencies: - "@opentelemetry/api": ">=1.4.0 <1.10.0" - checksum: 16bdccd8250d96df0ffcadb63b107135d207072c1da52d056f00b211ca56924413d53a529cc0e362d96bd1bf33aa801eba51b395c5cb290b8c66fb1b988a7ff6 - languageName: node - linkType: hard - "@opentelemetry/sdk-logs@npm:0.53.0": version: 0.53.0 resolution: "@opentelemetry/sdk-logs@npm:0.53.0" @@ -13678,19 +13907,6 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/sdk-metrics@npm:1.25.1": - version: 1.25.1 - resolution: "@opentelemetry/sdk-metrics@npm:1.25.1" - dependencies: - "@opentelemetry/core": 1.25.1 - "@opentelemetry/resources": 1.25.1 - lodash.merge: ^4.6.2 - peerDependencies: - "@opentelemetry/api": ">=1.3.0 <1.10.0" - checksum: efd3902d30e75bfc16e4208ffc92096743148ed8cec84900d05f98cc17ff146c711c398c3a526589433509c82399641b0759b4ba9fffc12be2e5007a55af7517 - languageName: node - linkType: hard - "@opentelemetry/sdk-metrics@npm:1.26.0, @opentelemetry/sdk-metrics@npm:^1.9.1": version: 1.26.0 resolution: "@opentelemetry/sdk-metrics@npm:1.26.0" @@ -13703,29 +13919,6 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/sdk-node@npm:^0.52.0": - version: 0.52.1 - resolution: "@opentelemetry/sdk-node@npm:0.52.1" - dependencies: - "@opentelemetry/api-logs": 0.52.1 - "@opentelemetry/core": 1.25.1 - "@opentelemetry/exporter-trace-otlp-grpc": 0.52.1 - "@opentelemetry/exporter-trace-otlp-http": 0.52.1 - "@opentelemetry/exporter-trace-otlp-proto": 0.52.1 - "@opentelemetry/exporter-zipkin": 1.25.1 - "@opentelemetry/instrumentation": 0.52.1 - "@opentelemetry/resources": 1.25.1 - "@opentelemetry/sdk-logs": 0.52.1 - "@opentelemetry/sdk-metrics": 1.25.1 - "@opentelemetry/sdk-trace-base": 1.25.1 - "@opentelemetry/sdk-trace-node": 1.25.1 - "@opentelemetry/semantic-conventions": 1.25.1 - peerDependencies: - "@opentelemetry/api": ">=1.3.0 <1.10.0" - checksum: 601f598fb0c7d50387c4d078a7f0436598c99f3a4c0eda4dd18bae00474d6ee9836adb148fb230b6bc351b8119c5dcba1f9803adfb807d19f30956c0a9a7eba5 - languageName: node - linkType: hard - "@opentelemetry/sdk-node@npm:^0.53.0": version: 0.53.0 resolution: "@opentelemetry/sdk-node@npm:0.53.0" @@ -13752,19 +13945,6 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/sdk-trace-base@npm:1.25.1": - version: 1.25.1 - resolution: "@opentelemetry/sdk-trace-base@npm:1.25.1" - dependencies: - "@opentelemetry/core": 1.25.1 - "@opentelemetry/resources": 1.25.1 - "@opentelemetry/semantic-conventions": 1.25.1 - peerDependencies: - "@opentelemetry/api": ">=1.0.0 <1.10.0" - checksum: 8ac97f7d8d36bf412c5f47ff98ded07c5dfd11602a6ae7657ec7b5f50bb6ddaa20fc682626afcf74e21b375dbad0d1d47c8e20204d5139431afec25165f6252b - languageName: node - linkType: hard - "@opentelemetry/sdk-trace-base@npm:1.26.0": version: 1.26.0 resolution: "@opentelemetry/sdk-trace-base@npm:1.26.0" @@ -13778,22 +13958,6 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/sdk-trace-node@npm:1.25.1": - version: 1.25.1 - resolution: "@opentelemetry/sdk-trace-node@npm:1.25.1" - dependencies: - "@opentelemetry/context-async-hooks": 1.25.1 - "@opentelemetry/core": 1.25.1 - "@opentelemetry/propagator-b3": 1.25.1 - "@opentelemetry/propagator-jaeger": 1.25.1 - "@opentelemetry/sdk-trace-base": 1.25.1 - semver: ^7.5.2 - peerDependencies: - "@opentelemetry/api": ">=1.0.0 <1.10.0" - checksum: f6835329651f5d888a90d95f6f86d5f660158029af2e01b68a5a0e21b2eb9dd40147dd6b0c321a12f65924c3ec1574d4ed2c6f05eea5c85280a82f3a95436bdb - languageName: node - linkType: hard - "@opentelemetry/sdk-trace-node@npm:1.26.0": version: 1.26.0 resolution: "@opentelemetry/sdk-trace-node@npm:1.26.0" @@ -13817,14 +13981,7 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/semantic-conventions@npm:1.25.1": - version: 1.25.1 - resolution: "@opentelemetry/semantic-conventions@npm:1.25.1" - checksum: fea418a4b09c55121c6da11c49dd2105116533838c484aead17e8acf8029dad711e145849812f9c61f9e48fad8e2b6cf103d2c18847ca993032ce9b27c2f863d - languageName: node - linkType: hard - -"@opentelemetry/semantic-conventions@npm:1.27.0, @opentelemetry/semantic-conventions@npm:^1.22.0, @opentelemetry/semantic-conventions@npm:^1.23.0, @opentelemetry/semantic-conventions@npm:^1.24.0": +"@opentelemetry/semantic-conventions@npm:1.27.0, @opentelemetry/semantic-conventions@npm:^1.27.0": version: 1.27.0 resolution: "@opentelemetry/semantic-conventions@npm:1.27.0" checksum: 26d85f8d13c8c64024f7a84528cff41d56afc9829e7ff8a654576404f8b2c1a9c264adcc6fa5a9551bacdd938a4a464041fa9493e0a722e5605f2c2ae6752398 @@ -13876,13 +14033,13 @@ __metadata: linkType: hard "@playwright/test@npm:^1.32.3": - version: 1.46.1 - resolution: "@playwright/test@npm:1.46.1" + version: 1.47.2 + resolution: "@playwright/test@npm:1.47.2" dependencies: - playwright: 1.46.1 + playwright: 1.47.2 bin: playwright: cli.js - checksum: 180d90c6421ee6a8c00a1ae65d91d5f69767e2de95c3f5582ac2bdf3a388e621fdd3ee00ecb7836db427bb0d4cee58111c14f133cb62150357d8e4f43e3e2295 + checksum: 4f149613c0fd4a40061425efdf5c7a257df09e1b6b797ad221597ddde52381edb69fce6645bf3b95a11eee74147a2025c1951041f29dbc717dab0cc46d9c3427 languageName: node linkType: hard @@ -14600,10 +14757,10 @@ __metadata: languageName: node linkType: hard -"@remix-run/router@npm:1.19.1": - version: 1.19.1 - resolution: "@remix-run/router@npm:1.19.1" - checksum: ebe4474ba0c1046093976b48a4eb4e39bd2f47368aacea21400126d72e133d2cfbfb50254cf1bde0b66dacdf0344452f743049d1595a22e86130668f60112376 +"@remix-run/router@npm:1.19.2": + version: 1.19.2 + resolution: "@remix-run/router@npm:1.19.2" + checksum: fb2f297b392c75b34c73981e1ef3ce31edd88448bc4ffc2fbc3386e705470d7537ca89e901ec57c07f3cca3a771151f58f7ed6bfcb3e8ef929596637984f068b languageName: node linkType: hard @@ -14621,9 +14778,9 @@ __metadata: languageName: node linkType: hard -"@rjsf/core@npm:5.18.5": - version: 5.18.5 - resolution: "@rjsf/core@npm:5.18.5" +"@rjsf/core@npm:5.21.1": + version: 5.21.1 + resolution: "@rjsf/core@npm:5.21.1" dependencies: lodash: ^4.17.21 lodash-es: ^4.17.21 @@ -14631,28 +14788,28 @@ __metadata: nanoid: ^3.3.7 prop-types: ^15.8.1 peerDependencies: - "@rjsf/utils": ^5.18.x + "@rjsf/utils": ^5.20.x react: ^16.14.0 || >=17 - checksum: 7b986ec075d5b2de503d01172abdb3e3d33d04e5298fbf80842400e682f0aecdabfe4bb8482dde8a6aed90a35f4f5574cb7b24a11d689566c0cc0599485b334a + checksum: a2372faeaeba53e83d9301b7b2fa300a37477bad18fcd55400b3aca270e8be5746590c398212ba6d53bc7f0092dc3bf28a46f17a7e8ddb0864c6590efd75f1f2 languageName: node linkType: hard -"@rjsf/material-ui@npm:5.18.5": - version: 5.18.5 - resolution: "@rjsf/material-ui@npm:5.18.5" +"@rjsf/material-ui@npm:5.21.1": + version: 5.21.1 + resolution: "@rjsf/material-ui@npm:5.21.1" peerDependencies: "@material-ui/core": ^4.12.3 "@material-ui/icons": ^4.11.2 - "@rjsf/core": ^5.18.x - "@rjsf/utils": ^5.18.x + "@rjsf/core": ^5.20.x + "@rjsf/utils": ^5.20.x react: ^16.14.0 || >=17 - checksum: 61337141bcd7bcb46013d81ae6b618919eff3f55319800511443e524876bf5c84089970e14148716de203d5def341aa15c4d102243f0b694f120f05189a3adb7 + checksum: 3ff88b9f33deb767abd640f301857f12edfe436a1252f52b70d6f60b02f1975d2becc79f2a940bb8de2fd1732481d2101104b07c09c80b61ed4c393f9df8718e languageName: node linkType: hard -"@rjsf/utils@npm:5.18.5": - version: 5.18.5 - resolution: "@rjsf/utils@npm:5.18.5" +"@rjsf/utils@npm:5.21.1": + version: 5.21.1 + resolution: "@rjsf/utils@npm:5.21.1" dependencies: json-schema-merge-allof: ^0.8.1 jsonpointer: ^5.0.1 @@ -14661,32 +14818,32 @@ __metadata: react-is: ^18.2.0 peerDependencies: react: ^16.14.0 || >=17 - checksum: 8da3ce82a0ec83e78806461db7226fd20489f6e8c41906ccde9d55c554aec3f50b8b8bac8c35e3cdf12d788c18fdad71c992f0d8b44f6161a1bf9e13598ded99 + checksum: bc0ac70a1a50f83d2425a782f6878537071922e0187026578005ca578700f8b0dc214cf72366668c7bb80374bb9409cc5233f1b1437aeadbd842f86e77e80067 languageName: node linkType: hard -"@rjsf/validator-ajv8@npm:5.18.5": - version: 5.18.5 - resolution: "@rjsf/validator-ajv8@npm:5.18.5" +"@rjsf/validator-ajv8@npm:5.21.1": + version: 5.21.1 + resolution: "@rjsf/validator-ajv8@npm:5.21.1" dependencies: ajv: ^8.12.0 ajv-formats: ^2.1.1 lodash: ^4.17.21 lodash-es: ^4.17.21 peerDependencies: - "@rjsf/utils": ^5.18.x - checksum: 350d1f8043b7bbd88cf5d7fa28560062f4141e1ef9ef004c2997b63d0281d4a1af04be4b951c2c9c4d1c56d10f0e2fbab665c7176b38e87dd6da6d5303e1c84e + "@rjsf/utils": ^5.20.x + checksum: d987a368092e561ff49ee2ab7f2b17d68d17bbedfb02356e453987cd2032fe476b1c35f0934fd5e0149ff478c7c87dfef43ff6f459fd15679a4c478cc32bd1be languageName: node linkType: hard -"@rollup/plugin-commonjs@npm:^25.0.0": - version: 25.0.8 - resolution: "@rollup/plugin-commonjs@npm:25.0.8" +"@rollup/plugin-commonjs@npm:^26.0.0": + version: 26.0.1 + resolution: "@rollup/plugin-commonjs@npm:26.0.1" dependencies: "@rollup/pluginutils": ^5.0.1 commondir: ^1.0.1 estree-walker: ^2.0.2 - glob: ^8.0.3 + glob: ^10.4.1 is-reference: 1.2.1 magic-string: ^0.30.3 peerDependencies: @@ -14694,7 +14851,7 @@ __metadata: peerDependenciesMeta: rollup: optional: true - checksum: dd105ee5625fbcaf832c0cf80be0aaf6a86bbd8fe99ff911f9ac4b78c79f26e9e99442b5aa0cc1136b5ddf89ec0b6c5728e5341ac04d687aef1b53063670b395 + checksum: 88d1349cc2cda4ad6193cce901356e4c14a830497fc01c91f38c94a871b203ffe657b29c9a98cd16787e3a6a8b45169dd0b471cb36d26d645478a177c958779a languageName: node linkType: hard @@ -14789,157 +14946,180 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-android-arm-eabi@npm:4.21.2": - version: 4.21.2 - resolution: "@rollup/rollup-android-arm-eabi@npm:4.21.2" +"@rollup/rollup-android-arm-eabi@npm:4.22.5": + version: 4.22.5 + resolution: "@rollup/rollup-android-arm-eabi@npm:4.22.5" conditions: os=android & cpu=arm languageName: node linkType: hard -"@rollup/rollup-android-arm64@npm:4.21.2": - version: 4.21.2 - resolution: "@rollup/rollup-android-arm64@npm:4.21.2" +"@rollup/rollup-android-arm64@npm:4.22.5": + version: 4.22.5 + resolution: "@rollup/rollup-android-arm64@npm:4.22.5" conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-darwin-arm64@npm:4.21.2": - version: 4.21.2 - resolution: "@rollup/rollup-darwin-arm64@npm:4.21.2" +"@rollup/rollup-darwin-arm64@npm:4.22.5": + version: 4.22.5 + resolution: "@rollup/rollup-darwin-arm64@npm:4.22.5" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-darwin-x64@npm:4.21.2": - version: 4.21.2 - resolution: "@rollup/rollup-darwin-x64@npm:4.21.2" +"@rollup/rollup-darwin-x64@npm:4.22.5": + version: 4.22.5 + resolution: "@rollup/rollup-darwin-x64@npm:4.22.5" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@rollup/rollup-linux-arm-gnueabihf@npm:4.21.2": - version: 4.21.2 - resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.21.2" +"@rollup/rollup-linux-arm-gnueabihf@npm:4.22.5": + version: 4.22.5 + resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.22.5" conditions: os=linux & cpu=arm & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-arm-musleabihf@npm:4.21.2": - version: 4.21.2 - resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.21.2" +"@rollup/rollup-linux-arm-musleabihf@npm:4.22.5": + version: 4.22.5 + resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.22.5" conditions: os=linux & cpu=arm & libc=musl languageName: node linkType: hard -"@rollup/rollup-linux-arm64-gnu@npm:4.21.2": - version: 4.21.2 - resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.21.2" +"@rollup/rollup-linux-arm64-gnu@npm:4.22.5": + version: 4.22.5 + resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.22.5" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-arm64-musl@npm:4.21.2": - version: 4.21.2 - resolution: "@rollup/rollup-linux-arm64-musl@npm:4.21.2" +"@rollup/rollup-linux-arm64-musl@npm:4.22.5": + version: 4.22.5 + resolution: "@rollup/rollup-linux-arm64-musl@npm:4.22.5" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@rollup/rollup-linux-powerpc64le-gnu@npm:4.21.2": - version: 4.21.2 - resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.21.2" +"@rollup/rollup-linux-powerpc64le-gnu@npm:4.22.5": + version: 4.22.5 + resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.22.5" conditions: os=linux & cpu=ppc64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-riscv64-gnu@npm:4.21.2": - version: 4.21.2 - resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.21.2" +"@rollup/rollup-linux-riscv64-gnu@npm:4.22.5": + version: 4.22.5 + resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.22.5" conditions: os=linux & cpu=riscv64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-s390x-gnu@npm:4.21.2": - version: 4.21.2 - resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.21.2" +"@rollup/rollup-linux-s390x-gnu@npm:4.22.5": + version: 4.22.5 + resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.22.5" conditions: os=linux & cpu=s390x & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-x64-gnu@npm:4.21.2": - version: 4.21.2 - resolution: "@rollup/rollup-linux-x64-gnu@npm:4.21.2" +"@rollup/rollup-linux-x64-gnu@npm:4.22.5": + version: 4.22.5 + resolution: "@rollup/rollup-linux-x64-gnu@npm:4.22.5" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-x64-musl@npm:4.21.2": - version: 4.21.2 - resolution: "@rollup/rollup-linux-x64-musl@npm:4.21.2" +"@rollup/rollup-linux-x64-musl@npm:4.22.5": + version: 4.22.5 + resolution: "@rollup/rollup-linux-x64-musl@npm:4.22.5" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@rollup/rollup-win32-arm64-msvc@npm:4.21.2": - version: 4.21.2 - resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.21.2" +"@rollup/rollup-win32-arm64-msvc@npm:4.22.5": + version: 4.22.5 + resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.22.5" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-win32-ia32-msvc@npm:4.21.2": - version: 4.21.2 - resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.21.2" +"@rollup/rollup-win32-ia32-msvc@npm:4.22.5": + version: 4.22.5 + resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.22.5" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@rollup/rollup-win32-x64-msvc@npm:4.21.2": - version: 4.21.2 - resolution: "@rollup/rollup-win32-x64-msvc@npm:4.21.2" +"@rollup/rollup-win32-x64-msvc@npm:4.22.5": + version: 4.22.5 + resolution: "@rollup/rollup-win32-x64-msvc@npm:4.22.5" conditions: os=win32 & cpu=x64 languageName: node linkType: hard -"@rushstack/node-core-library@npm:3.59.7": - version: 3.59.7 - resolution: "@rushstack/node-core-library@npm:3.59.7" +"@rtsao/scc@npm:^1.1.0": + version: 1.1.0 + resolution: "@rtsao/scc@npm:1.1.0" + checksum: 17d04adf404e04c1e61391ed97bca5117d4c2767a76ae3e879390d6dec7b317fcae68afbf9e98badee075d0b64fa60f287729c4942021b4d19cd01db77385c01 + languageName: node + linkType: hard + +"@rushstack/node-core-library@npm:5.9.0": + version: 5.9.0 + resolution: "@rushstack/node-core-library@npm:5.9.0" dependencies: - colors: ~1.2.1 + ajv: ~8.13.0 + ajv-draft-04: ~1.0.0 + ajv-formats: ~3.0.1 fs-extra: ~7.0.1 import-lazy: ~4.0.0 jju: ~1.4.0 resolve: ~1.22.1 semver: ~7.5.4 - z-schema: ~5.0.2 peerDependencies: "@types/node": "*" peerDependenciesMeta: "@types/node": optional: true - checksum: 57819d62fd662a6cf3306bf7d39c11204e094a2d5c2210639c2ac5baee58c183c02023203963cd0484a5623fd9f5dea7a223df843fb52b46a18508e6118cdc19 + checksum: beb558f118a796260f7df38b48b6669a94bbdb9711715785e0c5a426bd3a38c14721c03fc05e7a33883ec25a331ef0fb9e36438bb451ace021a7248a4f1fc74b languageName: node linkType: hard -"@rushstack/rig-package@npm:0.4.1": - version: 0.4.1 - resolution: "@rushstack/rig-package@npm:0.4.1" +"@rushstack/rig-package@npm:0.5.3": + version: 0.5.3 + resolution: "@rushstack/rig-package@npm:0.5.3" dependencies: resolve: ~1.22.1 strip-json-comments: ~3.1.1 - checksum: 68c5ec6c446c35939fca0444fa48e5beda736e3a5816e8b44d83df6ba8b9a2caf0ceddbdc866cd8ad3b523e42877cf6ecd467bc7839e3d618a9bb1c4b3e0b5a5 + checksum: bf3eadfc434bff273893efd22b319fe159d0e3b95729cb32ce3ad9f4ab4b6fabe3c4dd7f03ee0ddc7b480f0d989e908349eae6d6dce3500f896728a085af7aab languageName: node linkType: hard -"@rushstack/ts-command-line@npm:4.15.2": - version: 4.15.2 - resolution: "@rushstack/ts-command-line@npm:4.15.2" +"@rushstack/terminal@npm:0.14.2": + version: 0.14.2 + resolution: "@rushstack/terminal@npm:0.14.2" dependencies: + "@rushstack/node-core-library": 5.9.0 + supports-color: ~8.1.1 + peerDependencies: + "@types/node": "*" + peerDependenciesMeta: + "@types/node": + optional: true + checksum: 90d38e6979737dcd97fdfdcebcc378194eed32a994341846235769273b6446b702e53e51e18fc8a373e8ed989c5622216aa6804198b8c7ae0e65cd6b103b90a1 + languageName: node + linkType: hard + +"@rushstack/ts-command-line@npm:4.22.8": + version: 4.22.8 + resolution: "@rushstack/ts-command-line@npm:4.22.8" + dependencies: + "@rushstack/terminal": 0.14.2 "@types/argparse": 1.0.38 argparse: ~1.0.9 - colors: ~1.2.1 string-argv: ~0.3.1 - checksum: c80dcfc99630ee51c6654c58ff41f69a3bd89c38e41d9871692bc73ee3c938ced79f8b75e182e492cafb2f6ddeb0628606856af494a0259ff6fac5b248996bed + checksum: b0108e4b567c364a7c62b30dc3e4d17130b6f8ba16a0457c56b8c898ba84316e72726a4e043ca5183da7bf5d0189aed585ab3ac8bce5991b8e80ac94d333cd6c languageName: node linkType: hard @@ -15120,13 +15300,13 @@ __metadata: languageName: node linkType: hard -"@smithy/abort-controller@npm:^3.1.1": - version: 3.1.1 - resolution: "@smithy/abort-controller@npm:3.1.1" +"@smithy/abort-controller@npm:^3.1.2": + version: 3.1.2 + resolution: "@smithy/abort-controller@npm:3.1.2" dependencies: - "@smithy/types": ^3.3.0 + "@smithy/types": ^3.4.0 tslib: ^2.6.2 - checksum: 7b7497f49d58787cad858f8c5ea9931ccd44d39536db4abdd531a5abf37784469522e41d9ad1d541892caa0ed3bea750447809a0a18f4689a9543d672aa61d48 + checksum: e06fdc42198a7521e07d7b754bb23af0eaee669dee02b9eeb3d2e4431096a96747cd3d561bcfce2fb8eff8dcb6f08b57c0d70b039910bb0ea8730e2d7f2097c6 languageName: node linkType: hard @@ -15149,160 +15329,160 @@ __metadata: languageName: node linkType: hard -"@smithy/config-resolver@npm:^3.0.5": - version: 3.0.5 - resolution: "@smithy/config-resolver@npm:3.0.5" +"@smithy/config-resolver@npm:^3.0.6": + version: 3.0.6 + resolution: "@smithy/config-resolver@npm:3.0.6" dependencies: - "@smithy/node-config-provider": ^3.1.4 - "@smithy/types": ^3.3.0 + "@smithy/node-config-provider": ^3.1.5 + "@smithy/types": ^3.4.0 "@smithy/util-config-provider": ^3.0.0 - "@smithy/util-middleware": ^3.0.3 + "@smithy/util-middleware": ^3.0.4 tslib: ^2.6.2 - checksum: 96895ae0622a229655fa08f009d29a20157043020125014e84cb5ca33a10171c9724c309491214c2422d9c4c6681e7f5ec5f7faa8f45e11250449cf07f3552ec + checksum: 51ae788fec600956feb0209013ab760e54cdd417a92dd68814a51e6aad692fa3b4a1786faa22634a2e00a8d08ff71f01c0f60e30630751444fb3bf9083f2e22d languageName: node linkType: hard -"@smithy/core@npm:^2.4.0": - version: 2.4.0 - resolution: "@smithy/core@npm:2.4.0" +"@smithy/core@npm:^2.4.1": + version: 2.4.1 + resolution: "@smithy/core@npm:2.4.1" dependencies: - "@smithy/middleware-endpoint": ^3.1.0 - "@smithy/middleware-retry": ^3.0.15 - "@smithy/middleware-serde": ^3.0.3 - "@smithy/protocol-http": ^4.1.0 - "@smithy/smithy-client": ^3.2.0 - "@smithy/types": ^3.3.0 + "@smithy/middleware-endpoint": ^3.1.1 + "@smithy/middleware-retry": ^3.0.16 + "@smithy/middleware-serde": ^3.0.4 + "@smithy/protocol-http": ^4.1.1 + "@smithy/smithy-client": ^3.3.0 + "@smithy/types": ^3.4.0 "@smithy/util-body-length-browser": ^3.0.0 - "@smithy/util-middleware": ^3.0.3 + "@smithy/util-middleware": ^3.0.4 "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: 7ec00d742630feced4bb185a20f5fcb8b6706c9c22c0b86545e9c62e4dda10c8327847d55350f190c3e95d59df2b8f911893e35d5af87cf09fd6bc91e45379cf + checksum: 3fbf22e001b7acb35ecbeaf781406855a5bcd29d99d1bcccaa6880a280657871433adf9410e83f26ed7437916fd43888a83d5b7336d428baeb29de09e2e81294 languageName: node linkType: hard -"@smithy/credential-provider-imds@npm:^3.2.0": - version: 3.2.0 - resolution: "@smithy/credential-provider-imds@npm:3.2.0" +"@smithy/credential-provider-imds@npm:^3.2.1": + version: 3.2.1 + resolution: "@smithy/credential-provider-imds@npm:3.2.1" dependencies: - "@smithy/node-config-provider": ^3.1.4 - "@smithy/property-provider": ^3.1.3 - "@smithy/types": ^3.3.0 - "@smithy/url-parser": ^3.0.3 + "@smithy/node-config-provider": ^3.1.5 + "@smithy/property-provider": ^3.1.4 + "@smithy/types": ^3.4.0 + "@smithy/url-parser": ^3.0.4 tslib: ^2.6.2 - checksum: fc79919133008db91a83f2caf6eba11d704f34af5fa3dd1f7b8cc048214e805d9f20a3f302f5ed4862ee6b6c3bb28ff3a5d8c77d2f497d10f3be14915e59debe + checksum: d7bb84df18c562d8f96bc955438cb7aefe671ee88b788c60cc3f6c63ccad822acf91d20bbcf89a2430b3629e818fb42666aa6a165a8397629ee5e191ec43c3ca languageName: node linkType: hard -"@smithy/eventstream-codec@npm:^3.1.2": - version: 3.1.2 - resolution: "@smithy/eventstream-codec@npm:3.1.2" +"@smithy/eventstream-codec@npm:^3.1.3": + version: 3.1.3 + resolution: "@smithy/eventstream-codec@npm:3.1.3" dependencies: "@aws-crypto/crc32": 5.2.0 - "@smithy/types": ^3.3.0 + "@smithy/types": ^3.4.0 "@smithy/util-hex-encoding": ^3.0.0 tslib: ^2.6.2 - checksum: b0c836acbf59b57a7e2ef948a54bd441d11b75d70f1c334723c27fce1ab0ff93ea9f936976b754272b5e90413b5a169c60b1df7ecfd7d061ebaae8d5cc067d94 + checksum: da6f731617c329f7f7e25e421a4babbed1397396ebb69f0a91e19cf51cac78a78c5d269f3444c7b4dc7ab1411c1d3670cf1b6dbe1dce16520ad8ca82b8a78f8f languageName: node linkType: hard -"@smithy/eventstream-serde-browser@npm:^3.0.6": +"@smithy/eventstream-serde-browser@npm:^3.0.7": + version: 3.0.7 + resolution: "@smithy/eventstream-serde-browser@npm:3.0.7" + dependencies: + "@smithy/eventstream-serde-universal": ^3.0.6 + "@smithy/types": ^3.4.0 + tslib: ^2.6.2 + checksum: 881016c3b5e9516ce03a20f3394420e5c80e7571b0492e43b3dd0928260f8d6e857cda7fcf39af725d64d77ea40c3e48ae7aae4b2257f241902b61307d2aa414 + languageName: node + linkType: hard + +"@smithy/eventstream-serde-config-resolver@npm:^3.0.4": + version: 3.0.4 + resolution: "@smithy/eventstream-serde-config-resolver@npm:3.0.4" + dependencies: + "@smithy/types": ^3.4.0 + tslib: ^2.6.2 + checksum: 6485890fd621a9065c09c7345b0bc7764d9eb26da7befc06e37438dea7764f70559d4869bea6e50396b69f0f8bbfe408bd8b353a2f6362499026d3d2e8b68aec + languageName: node + linkType: hard + +"@smithy/eventstream-serde-node@npm:^3.0.6": version: 3.0.6 - resolution: "@smithy/eventstream-serde-browser@npm:3.0.6" + resolution: "@smithy/eventstream-serde-node@npm:3.0.6" dependencies: - "@smithy/eventstream-serde-universal": ^3.0.5 - "@smithy/types": ^3.3.0 + "@smithy/eventstream-serde-universal": ^3.0.6 + "@smithy/types": ^3.4.0 tslib: ^2.6.2 - checksum: 0d0f77fc7d277f1e8d29cfd7d745adac6ed627af8b8812dc5d821064f6d98a40e4e8c4ea0f1b67efe1070454fe19879b5edb8a892451a4b12cfa23d3bb9bcd50 + checksum: bf7a6e21ef05a1eea9ce7ae9d23ba2299e383dfe101cdafe88dda108f28d1b160397339a83ad8deec2ac6e571955bc059e3a728c8e03cb9e48e8af0929a1b674 languageName: node linkType: hard -"@smithy/eventstream-serde-config-resolver@npm:^3.0.3": - version: 3.0.3 - resolution: "@smithy/eventstream-serde-config-resolver@npm:3.0.3" +"@smithy/eventstream-serde-universal@npm:^3.0.6": + version: 3.0.6 + resolution: "@smithy/eventstream-serde-universal@npm:3.0.6" dependencies: - "@smithy/types": ^3.3.0 + "@smithy/eventstream-codec": ^3.1.3 + "@smithy/types": ^3.4.0 tslib: ^2.6.2 - checksum: c61780aa0ad8c479618d0b3fcb2b42f1f9a74dcf814dba08305107ed1f088f56aa1c346db9c72439ff18617f31b9c59c6895060e4c9765c81d759150a22674af + checksum: a1b6de94055a47a12d7b07b5a52f687721ebd999f956adf496af760bf8e382016c44130b494a346084032fb145847013848940ec8778147d8f300b885e9d4444 languageName: node linkType: hard -"@smithy/eventstream-serde-node@npm:^3.0.5": - version: 3.0.5 - resolution: "@smithy/eventstream-serde-node@npm:3.0.5" +"@smithy/fetch-http-handler@npm:^3.2.5": + version: 3.2.5 + resolution: "@smithy/fetch-http-handler@npm:3.2.5" dependencies: - "@smithy/eventstream-serde-universal": ^3.0.5 - "@smithy/types": ^3.3.0 - tslib: ^2.6.2 - checksum: ba0117495e2b9fc6b116620b1e15ade6c0aff72561d6db70c18ff4d6671a579fc6616f762918ba28b8146786aef1ba758969ac75dde80ee0099903408b2788ff - languageName: node - linkType: hard - -"@smithy/eventstream-serde-universal@npm:^3.0.5": - version: 3.0.5 - resolution: "@smithy/eventstream-serde-universal@npm:3.0.5" - dependencies: - "@smithy/eventstream-codec": ^3.1.2 - "@smithy/types": ^3.3.0 - tslib: ^2.6.2 - checksum: 8394e27de4caf49076ec664f6e1c934ce4e9cb25ab4936f47fb1cb4da8ba5b027d46da363c77210c73845cd6841e3286115789d179bb2c45c567e3d4227dac73 - languageName: node - linkType: hard - -"@smithy/fetch-http-handler@npm:^3.2.4": - version: 3.2.4 - resolution: "@smithy/fetch-http-handler@npm:3.2.4" - dependencies: - "@smithy/protocol-http": ^4.1.0 - "@smithy/querystring-builder": ^3.0.3 - "@smithy/types": ^3.3.0 + "@smithy/protocol-http": ^4.1.1 + "@smithy/querystring-builder": ^3.0.4 + "@smithy/types": ^3.4.0 "@smithy/util-base64": ^3.0.0 tslib: ^2.6.2 - checksum: 73df885c637c14353f449678a4e109aeb19945c5370a615793ca2a54a29746a78e725e324b01cfd86fc71f4afd6386da2758fccc49d247a623ecbe70f607cb74 + checksum: 1b7060035a310da90fe3b8a6326367950f05de0419aa527c1f6ce9a07573328cfb42f150055290a799db0a23dfe39af597fcf0990d076f699f176664cbc470c3 languageName: node linkType: hard -"@smithy/hash-blob-browser@npm:^3.1.2": - version: 3.1.2 - resolution: "@smithy/hash-blob-browser@npm:3.1.2" +"@smithy/hash-blob-browser@npm:^3.1.3": + version: 3.1.3 + resolution: "@smithy/hash-blob-browser@npm:3.1.3" dependencies: "@smithy/chunked-blob-reader": ^3.0.0 "@smithy/chunked-blob-reader-native": ^3.0.0 - "@smithy/types": ^3.3.0 + "@smithy/types": ^3.4.0 tslib: ^2.6.2 - checksum: 959ec975cd4b3d86e3d0288e24b460343795bc305ef38fc43f8485cd1440da4068d375c5d1dab73ae875f02e861f194512a7adf5afcd7395bbeb97897d8a809b + checksum: 7ec927c20acd5ee759dae199b4181a3638e898e994fe27f8f8675b5875635fe05531a2cca29c791273176664fb077842d94b3ae8c6c9ab1d065e2d5a69db07a8 languageName: node linkType: hard -"@smithy/hash-node@npm:^3.0.3": - version: 3.0.3 - resolution: "@smithy/hash-node@npm:3.0.3" +"@smithy/hash-node@npm:^3.0.4": + version: 3.0.4 + resolution: "@smithy/hash-node@npm:3.0.4" dependencies: - "@smithy/types": ^3.3.0 + "@smithy/types": ^3.4.0 "@smithy/util-buffer-from": ^3.0.0 "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: 203a3581bec5373e63d42e03f62129022f03d17390e9358a4e25fc1d44c43962ea80ab5bcbb91605e3025e22136bed059665a3b16835f66316f43ed391df9548 + checksum: 9e7963ed201f29b4c27fbef90ca86e5b02fa7d5d8c01c7a568e1fb8866d768d788814a0fb21b6992d7d6ca6e8898d345890b241429e989a7643959e56fd7eeb4 languageName: node linkType: hard -"@smithy/hash-stream-node@npm:^3.1.2": - version: 3.1.2 - resolution: "@smithy/hash-stream-node@npm:3.1.2" +"@smithy/hash-stream-node@npm:^3.1.3": + version: 3.1.3 + resolution: "@smithy/hash-stream-node@npm:3.1.3" dependencies: - "@smithy/types": ^3.3.0 + "@smithy/types": ^3.4.0 "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: e5284ef06548e301aa50bd06fe06bf3e2ed11ecd57f73d2d85c98cf26119c2cc0084b5b8be49d4127cb798c6011651d5361958eb6546c19b45fd6c94ea11ef47 + checksum: 53cfe795610cc3b5ed06b6f1e869989cc09580d3d549c3955d1af42b1f2a6efa7f6a010d34e95425db8c1c8f2237fc5a668a8f5bbb3738aa44fd22273b2aedb9 languageName: node linkType: hard -"@smithy/invalid-dependency@npm:^3.0.3": - version: 3.0.3 - resolution: "@smithy/invalid-dependency@npm:3.0.3" +"@smithy/invalid-dependency@npm:^3.0.4": + version: 3.0.4 + resolution: "@smithy/invalid-dependency@npm:3.0.4" dependencies: - "@smithy/types": ^3.3.0 + "@smithy/types": ^3.4.0 tslib: ^2.6.2 - checksum: 459b4ae4e47595e8a675ff2e8bfea7f58a41f77138416ea310c89e29312e08963a701cdc354324da9dd578a7995158b4421695365070d74b0276ddff7f701bba + checksum: 6ea1fec4e5315e4341c5754b23103dc1f23230cf5fa99b78417db81bc5c391cfd585c9416ef047307020950d3a2b0542b896d56558dfbdfaaf9d3667a282a239 languageName: node linkType: hard @@ -15324,89 +15504,89 @@ __metadata: languageName: node linkType: hard -"@smithy/md5-js@npm:^3.0.3": - version: 3.0.3 - resolution: "@smithy/md5-js@npm:3.0.3" +"@smithy/md5-js@npm:^3.0.4": + version: 3.0.4 + resolution: "@smithy/md5-js@npm:3.0.4" dependencies: - "@smithy/types": ^3.3.0 + "@smithy/types": ^3.4.0 "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: 52ef56439be4187cc65391f4252173ffad0ce5a2ce5f636d78e9cdfb517844889340156ddbdbbe86f63e7f7e0fc924fe6905749a1c833910784015133a467406 + checksum: 22b96112c56bc9b4bb147473a7681954af027eb31a2e74621022bbb6579113ccd2ee8ff2543630edc1701efc1d7634bd5f13a3766bb6cdde322aafb8e113eaed languageName: node linkType: hard -"@smithy/middleware-content-length@npm:^3.0.5": - version: 3.0.5 - resolution: "@smithy/middleware-content-length@npm:3.0.5" +"@smithy/middleware-content-length@npm:^3.0.6": + version: 3.0.6 + resolution: "@smithy/middleware-content-length@npm:3.0.6" dependencies: - "@smithy/protocol-http": ^4.1.0 - "@smithy/types": ^3.3.0 + "@smithy/protocol-http": ^4.1.1 + "@smithy/types": ^3.4.0 tslib: ^2.6.2 - checksum: 21c667530f5e64db300827dfe8aa5b18396d151ac489a3e634f882179fae5c0f84940e1f831f0bf7b4b6b9623283f4a516da92d89c13ba395aede8788b523cd3 + checksum: 84b7e3185a6481938db729387a2af6705cc0cfa7685c142949a292567c2c54bf79f4bf5334ade741a2842d42fd7834a570bdd15a65e01bdfdf21fd553bb8989f languageName: node linkType: hard -"@smithy/middleware-endpoint@npm:^3.1.0": - version: 3.1.0 - resolution: "@smithy/middleware-endpoint@npm:3.1.0" +"@smithy/middleware-endpoint@npm:^3.1.1": + version: 3.1.1 + resolution: "@smithy/middleware-endpoint@npm:3.1.1" dependencies: - "@smithy/middleware-serde": ^3.0.3 - "@smithy/node-config-provider": ^3.1.4 - "@smithy/shared-ini-file-loader": ^3.1.4 - "@smithy/types": ^3.3.0 - "@smithy/url-parser": ^3.0.3 - "@smithy/util-middleware": ^3.0.3 + "@smithy/middleware-serde": ^3.0.4 + "@smithy/node-config-provider": ^3.1.5 + "@smithy/shared-ini-file-loader": ^3.1.5 + "@smithy/types": ^3.4.0 + "@smithy/url-parser": ^3.0.4 + "@smithy/util-middleware": ^3.0.4 tslib: ^2.6.2 - checksum: 3271b7c1ec5d01db63439757d198e921618a2f1d4827c64fc425163e7d1bc969049d8c8ce74f3a8c0b0dac5ea3466c154f38805c8d62fe19fb9bd6af72ca2d3c + checksum: f4fdf2f471b82a127c94f5dc99ae692e58347079f764cddcbdfbff739513b396dc2e6b5d8f50c32b6f4a19afce9ec2ba3cf69c4e5e3d2755bc765807594c65a6 languageName: node linkType: hard -"@smithy/middleware-retry@npm:^3.0.15": - version: 3.0.15 - resolution: "@smithy/middleware-retry@npm:3.0.15" +"@smithy/middleware-retry@npm:^3.0.16": + version: 3.0.16 + resolution: "@smithy/middleware-retry@npm:3.0.16" dependencies: - "@smithy/node-config-provider": ^3.1.4 - "@smithy/protocol-http": ^4.1.0 - "@smithy/service-error-classification": ^3.0.3 - "@smithy/smithy-client": ^3.2.0 - "@smithy/types": ^3.3.0 - "@smithy/util-middleware": ^3.0.3 - "@smithy/util-retry": ^3.0.3 + "@smithy/node-config-provider": ^3.1.5 + "@smithy/protocol-http": ^4.1.1 + "@smithy/service-error-classification": ^3.0.4 + "@smithy/smithy-client": ^3.3.0 + "@smithy/types": ^3.4.0 + "@smithy/util-middleware": ^3.0.4 + "@smithy/util-retry": ^3.0.4 tslib: ^2.6.2 uuid: ^9.0.1 - checksum: 035dd1e2a3e9c58b3328f2035095cf09b545b6af764dd5070e5495167f74b56c73e48f13b9f9a17378a73486bdd7dcfcfcc62214f9e34df90180834ec7fbf727 + checksum: c851ba8999452de553d4a07fe03324a823ed8a70229b90445eb984da913c1ab3ffc483a43b1b00564498d4cf70a0b8819110bac9a4e360e3aa98d8d799e63b69 languageName: node linkType: hard -"@smithy/middleware-serde@npm:^3.0.3": - version: 3.0.3 - resolution: "@smithy/middleware-serde@npm:3.0.3" +"@smithy/middleware-serde@npm:^3.0.4": + version: 3.0.4 + resolution: "@smithy/middleware-serde@npm:3.0.4" dependencies: - "@smithy/types": ^3.3.0 + "@smithy/types": ^3.4.0 tslib: ^2.6.2 - checksum: 6c633bb8957e078d480888bd33d5a8c269a483a1358c2b28c62daecfd442c711c509d9e69302e6b19fc298139ee67cdda63a604e7da0e4ef9005117d8e0897cc + checksum: 6bafaad92bbc71ba38fd2196de9588d2bc1d75b609b656ff9df8854637339e6ba7c906365aa644b5c82ec20b4804b8f6575efe11b84640492f1f420f095c2e66 languageName: node linkType: hard -"@smithy/middleware-stack@npm:^3.0.3": - version: 3.0.3 - resolution: "@smithy/middleware-stack@npm:3.0.3" +"@smithy/middleware-stack@npm:^3.0.4": + version: 3.0.4 + resolution: "@smithy/middleware-stack@npm:3.0.4" dependencies: - "@smithy/types": ^3.3.0 + "@smithy/types": ^3.4.0 tslib: ^2.6.2 - checksum: f4a450e2ebca0a8a3b4e1bbfad7d7e9c45edccbe1c984a22f2228092a526120748365e8964b478357249675d8bbc28fdaa8a4a19643a3c1d86bd74e1499327c5 + checksum: ae51b994d03386e4a22feba5c7b64b934b2fb019b97af953f1fa7c9e9a692094cfc9d81d839ca7f8eccd10a41a0ea04e245b3457b1280bcf4c009b2bedd4aa9e languageName: node linkType: hard -"@smithy/node-config-provider@npm:^3.1.4": - version: 3.1.4 - resolution: "@smithy/node-config-provider@npm:3.1.4" +"@smithy/node-config-provider@npm:^3.1.5": + version: 3.1.5 + resolution: "@smithy/node-config-provider@npm:3.1.5" dependencies: - "@smithy/property-provider": ^3.1.3 - "@smithy/shared-ini-file-loader": ^3.1.4 - "@smithy/types": ^3.3.0 + "@smithy/property-provider": ^3.1.4 + "@smithy/shared-ini-file-loader": ^3.1.5 + "@smithy/types": ^3.4.0 tslib: ^2.6.2 - checksum: 7ea4e7cea93ab154ab89a9d6b2453c8f96b96db18883070d287bc5fa9cfd10091bb00006a15bb7e6ed25810fd1a133d458e45310a8eaa1727a55d4ce2be3ba09 + checksum: 808d3a8cf729977edf433810442609fed10ba263cea89bf9dccbd1bbb78b99b9e84dd9b3157d14410c612b748e79bfeb1cf7044c9d18487fc42c56febec190f8 languageName: node linkType: hard @@ -15423,26 +15603,26 @@ __metadata: languageName: node linkType: hard -"@smithy/node-http-handler@npm:^3.1.4": - version: 3.1.4 - resolution: "@smithy/node-http-handler@npm:3.1.4" +"@smithy/node-http-handler@npm:^3.2.0": + version: 3.2.0 + resolution: "@smithy/node-http-handler@npm:3.2.0" dependencies: - "@smithy/abort-controller": ^3.1.1 - "@smithy/protocol-http": ^4.1.0 - "@smithy/querystring-builder": ^3.0.3 - "@smithy/types": ^3.3.0 + "@smithy/abort-controller": ^3.1.2 + "@smithy/protocol-http": ^4.1.1 + "@smithy/querystring-builder": ^3.0.4 + "@smithy/types": ^3.4.0 tslib: ^2.6.2 - checksum: 8f2f611bef99800b122b852103c3d1ff391b91077df191ca06676bd8c4e50d7e335bf2a311f90ff6a9fa0639a812216492e5e0ecee703e89eb05a4b253c8273c + checksum: 9955b70611454d74c83eccaaa943322b9a9d09d6b8e3cb6433a99940bf8e15fce21986fcd205adce9dcddfc0a10727db4a5685cedb08ef757d1eee5e4b568988 languageName: node linkType: hard -"@smithy/property-provider@npm:^3.1.3": - version: 3.1.3 - resolution: "@smithy/property-provider@npm:3.1.3" +"@smithy/property-provider@npm:^3.1.4": + version: 3.1.4 + resolution: "@smithy/property-provider@npm:3.1.4" dependencies: - "@smithy/types": ^3.3.0 + "@smithy/types": ^3.4.0 tslib: ^2.6.2 - checksum: 37a3d92267a2a32c2cc17fd1f0ab2b336f75fb7807db88f6194efede9d6a66068658a7effb7773451404fca990924393dbbf3d57e2aca67ef2e489a85666e225 + checksum: 8933a150889e87312df03558db1c9634022274bfd2f0806ee87f3843ffd18793cad5110f4e1708c4d5d288606a3684a62a0ab43ef0819a78dcab0e7d815e3052 languageName: node linkType: hard @@ -15456,13 +15636,13 @@ __metadata: languageName: node linkType: hard -"@smithy/protocol-http@npm:^4.1.0": - version: 4.1.0 - resolution: "@smithy/protocol-http@npm:4.1.0" +"@smithy/protocol-http@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/protocol-http@npm:4.1.1" dependencies: - "@smithy/types": ^3.3.0 + "@smithy/types": ^3.4.0 tslib: ^2.6.2 - checksum: fe4f97bc35075c6e6669c12ff90a4ab3dbe620b375298795d0c1104b30d04536cf002ea81f29983895c6042c7a30eecd1d2306d3ac90bf7910ec02929233f5ad + checksum: 01306a89afa3cf1e1f84117cf3a0eca2aafcea3a6e4db4a99cb9649752d9f91e42275c8207f93876122c2f63040401399b578a7182c0fdd1db4c747856aeb6d6 languageName: node linkType: hard @@ -15477,73 +15657,73 @@ __metadata: languageName: node linkType: hard -"@smithy/querystring-builder@npm:^3.0.3": - version: 3.0.3 - resolution: "@smithy/querystring-builder@npm:3.0.3" +"@smithy/querystring-builder@npm:^3.0.4": + version: 3.0.4 + resolution: "@smithy/querystring-builder@npm:3.0.4" dependencies: - "@smithy/types": ^3.3.0 + "@smithy/types": ^3.4.0 "@smithy/util-uri-escape": ^3.0.0 tslib: ^2.6.2 - checksum: 5c46c620d87f9b4e67b8eb543667b0160fb05bbec01d62d45adb94305369dca9e82daba47d81e840fdc399fa47f9b5930ce668d65fe83ee278a1b27d59d0b5d3 + checksum: 6e39750423f5e95980f476170502398042f3717f73e88a49d24c6f204b87d81bcda981bfb652e74f16928f6a4d7034c4eea760e5f6a3abc64e41814e4f929b50 languageName: node linkType: hard -"@smithy/querystring-parser@npm:^3.0.3": - version: 3.0.3 - resolution: "@smithy/querystring-parser@npm:3.0.3" +"@smithy/querystring-parser@npm:^3.0.4": + version: 3.0.4 + resolution: "@smithy/querystring-parser@npm:3.0.4" dependencies: - "@smithy/types": ^3.3.0 + "@smithy/types": ^3.4.0 tslib: ^2.6.2 - checksum: 1de11cbc4325578b243a0e3e89b46371f4705d3df41ea51b37e8efa655d3b75253180b0fca9ceed8b3955a2d458689f551cd24fd904d0f65647c62c6b08795bf + checksum: 2abce26011e57289e0f64c9d74b42d2c0291c3e26716bb47cb0fa9c50caf98bf49ea233742ef07807cea70740a9f7864dec854eccad1695d0f2e92b6d772d7a6 languageName: node linkType: hard -"@smithy/service-error-classification@npm:^3.0.3": - version: 3.0.3 - resolution: "@smithy/service-error-classification@npm:3.0.3" +"@smithy/service-error-classification@npm:^3.0.4": + version: 3.0.4 + resolution: "@smithy/service-error-classification@npm:3.0.4" dependencies: - "@smithy/types": ^3.3.0 - checksum: 5bef710f5698c929c97865cba41f36b0c59100b9a1c4478a2d47caeb5e3a1a18077b870b365efaa45c94666f2075bc8978f7a6e8b964afbba3a4e490eb6c13eb + "@smithy/types": ^3.4.0 + checksum: 9c831542d46d537bb4716768b6009c826477603983e6ca31103f19ee1d01bc3c9d55e79d89b24b9b5e7ba2e444850d75a4bec786367eeeedac7524b721eb1f0d languageName: node linkType: hard -"@smithy/shared-ini-file-loader@npm:^3.1.4": - version: 3.1.4 - resolution: "@smithy/shared-ini-file-loader@npm:3.1.4" +"@smithy/shared-ini-file-loader@npm:^3.1.5": + version: 3.1.5 + resolution: "@smithy/shared-ini-file-loader@npm:3.1.5" dependencies: - "@smithy/types": ^3.3.0 + "@smithy/types": ^3.4.0 tslib: ^2.6.2 - checksum: c5321635f3be34e424009fc9045454a9ceec543ec20b3b9719bf3a48bbfc03b794f4545546e9c2dcb0a987de2ca5ff8999df9bf7c166c6fc7685c1fa1f068bc1 + checksum: f6e35e465cc9db8c660ebe2c8ab626fb3054ac24937608effd35af10e5fade00c19c3159eb4de2650a5434fe124fb9cee944015e5c316ca4c60715fb4023918e languageName: node linkType: hard -"@smithy/signature-v4@npm:^4.1.0": - version: 4.1.0 - resolution: "@smithy/signature-v4@npm:4.1.0" +"@smithy/signature-v4@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/signature-v4@npm:4.1.1" dependencies: "@smithy/is-array-buffer": ^3.0.0 - "@smithy/protocol-http": ^4.1.0 - "@smithy/types": ^3.3.0 + "@smithy/protocol-http": ^4.1.1 + "@smithy/types": ^3.4.0 "@smithy/util-hex-encoding": ^3.0.0 - "@smithy/util-middleware": ^3.0.3 + "@smithy/util-middleware": ^3.0.4 "@smithy/util-uri-escape": ^3.0.0 "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: 8c58bbc5b3f9eed092351f36dc0193ed2e43f916856dc95eadc65b42460a0c5f662016156034ef8a25419f95be8f6a15a7e85469358b77db236445919f66c77e + checksum: 373cfeb6ca138f526ddcbd02a5de9b722de2a9173c1908fa9d81e74257d5d8ff26acebf398b1ea4f704794335fc65caf2cd9f0d2e140847cfe5df81a785f3faf languageName: node linkType: hard -"@smithy/smithy-client@npm:^3.2.0": - version: 3.2.0 - resolution: "@smithy/smithy-client@npm:3.2.0" +"@smithy/smithy-client@npm:^3.3.0": + version: 3.3.0 + resolution: "@smithy/smithy-client@npm:3.3.0" dependencies: - "@smithy/middleware-endpoint": ^3.1.0 - "@smithy/middleware-stack": ^3.0.3 - "@smithy/protocol-http": ^4.1.0 - "@smithy/types": ^3.3.0 - "@smithy/util-stream": ^3.1.3 + "@smithy/middleware-endpoint": ^3.1.1 + "@smithy/middleware-stack": ^3.0.4 + "@smithy/protocol-http": ^4.1.1 + "@smithy/types": ^3.4.0 + "@smithy/util-stream": ^3.1.4 tslib: ^2.6.2 - checksum: 446203aae20e9d3ff9d09ed8bde1bc25be009d658ae2ba7e71678d3727cb75d2bf398b9231e41687234eac3802e795742865b0b0e1f00d30f3669a5389e6fbaa + checksum: 8192d79c9ebe2134f777282eade77b3b88cfc854ade6b6336f8f9235f9a856a492dea3bfdac83607154f0cfd957b838a366b1b9fb4b258f03092d9002f48a0ee languageName: node linkType: hard @@ -15565,23 +15745,23 @@ __metadata: languageName: node linkType: hard -"@smithy/types@npm:^3.3.0": - version: 3.3.0 - resolution: "@smithy/types@npm:3.3.0" +"@smithy/types@npm:^3.4.0": + version: 3.4.0 + resolution: "@smithy/types@npm:3.4.0" dependencies: tslib: ^2.6.2 - checksum: 29bb5f83c41e32f8d4094a2aba2d3dfbd763ab5943784a700f3fa22df0dcf0ccac1b1907f7a87fbb9f6f2269fcd4750524bcb48f892249e200ffe397c0981309 + checksum: dfce8d585b53a4e31d08b294b65ddf5983b421bc17f576530d0175f08deb63f43bcc9936743a8e430a388af70dfc3bb6c0a624adfd9e0812a6e3a3b27c60637e languageName: node linkType: hard -"@smithy/url-parser@npm:^3.0.3": - version: 3.0.3 - resolution: "@smithy/url-parser@npm:3.0.3" +"@smithy/url-parser@npm:^3.0.4": + version: 3.0.4 + resolution: "@smithy/url-parser@npm:3.0.4" dependencies: - "@smithy/querystring-parser": ^3.0.3 - "@smithy/types": ^3.3.0 + "@smithy/querystring-parser": ^3.0.4 + "@smithy/types": ^3.4.0 tslib: ^2.6.2 - checksum: 86b4bc8e6c176b56076c30233ca4cfeb98d162fe27a348ddfda5f163ce7d173b8e684aa26202bbf4e0b5695b0ad43c0cb40170ca6793652d0ea6edb00443c036 + checksum: 2685908210a391a87b52f633ba27ff600feceed61b21d1d1d8a6d180cdc9a61c90759d531a4dde37a5ab793e88fbd66ddd7de592190472f92aa3990e466b9c64 languageName: node linkType: hard @@ -15643,42 +15823,42 @@ __metadata: languageName: node linkType: hard -"@smithy/util-defaults-mode-browser@npm:^3.0.15": - version: 3.0.15 - resolution: "@smithy/util-defaults-mode-browser@npm:3.0.15" +"@smithy/util-defaults-mode-browser@npm:^3.0.16": + version: 3.0.16 + resolution: "@smithy/util-defaults-mode-browser@npm:3.0.16" dependencies: - "@smithy/property-provider": ^3.1.3 - "@smithy/smithy-client": ^3.2.0 - "@smithy/types": ^3.3.0 + "@smithy/property-provider": ^3.1.4 + "@smithy/smithy-client": ^3.3.0 + "@smithy/types": ^3.4.0 bowser: ^2.11.0 tslib: ^2.6.2 - checksum: 77a081a66110f35b1457a655556712b03b9368528dae0e2b68c1422a0c05fd9fe84b811d12bcd15bdfc7ee2a72f395d6661e1045fa907a7a177137a97feb3ce9 + checksum: d5d87ab1db11a250b9dc7fa92b7800d96ed3b23da8f14a571dd67d98dcd25c83cefd3bd230529239accc141ea43509c3b43ff136248723cfed2e4cc710d00630 languageName: node linkType: hard -"@smithy/util-defaults-mode-node@npm:^3.0.15": - version: 3.0.15 - resolution: "@smithy/util-defaults-mode-node@npm:3.0.15" +"@smithy/util-defaults-mode-node@npm:^3.0.16": + version: 3.0.16 + resolution: "@smithy/util-defaults-mode-node@npm:3.0.16" dependencies: - "@smithy/config-resolver": ^3.0.5 - "@smithy/credential-provider-imds": ^3.2.0 - "@smithy/node-config-provider": ^3.1.4 - "@smithy/property-provider": ^3.1.3 - "@smithy/smithy-client": ^3.2.0 - "@smithy/types": ^3.3.0 + "@smithy/config-resolver": ^3.0.6 + "@smithy/credential-provider-imds": ^3.2.1 + "@smithy/node-config-provider": ^3.1.5 + "@smithy/property-provider": ^3.1.4 + "@smithy/smithy-client": ^3.3.0 + "@smithy/types": ^3.4.0 tslib: ^2.6.2 - checksum: 1a58ba9d0b8e269c5689aafff54df56e10297a5937f8feea0fdf16e56559b4d48f19e4927d7ec5fbe58adcdeb820692f3dc61d61a886f0206ba0c490e2322035 + checksum: 5c21f8c138a97cea5ba16efe7943decbd43b138292b728b20ea789f7239b5716ae09778253e02e8f4d1ddb3f8aef7730fa1ab638482cfb307655d5352131d2ea languageName: node linkType: hard -"@smithy/util-endpoints@npm:^2.0.5": - version: 2.0.5 - resolution: "@smithy/util-endpoints@npm:2.0.5" +"@smithy/util-endpoints@npm:^2.1.0": + version: 2.1.0 + resolution: "@smithy/util-endpoints@npm:2.1.0" dependencies: - "@smithy/node-config-provider": ^3.1.4 - "@smithy/types": ^3.3.0 + "@smithy/node-config-provider": ^3.1.5 + "@smithy/types": ^3.4.0 tslib: ^2.6.2 - checksum: bb2a96323f52beaf2820f4e5764c865cff3ac5bca0c0df6923bb4582b0f87faf1606110cd4e36005ac43f41e9673ebdca4bbb8b913880fc2a4e0ff3301250da8 + checksum: 54dafec6c88f66522f32d6acc60225dd50180780fa8931bd3daf23e2937ce5aed6fcb8be552cd3003f858e857f96a1d35e82581b6a34edfe9100db09646aa633 languageName: node linkType: hard @@ -15691,40 +15871,40 @@ __metadata: languageName: node linkType: hard -"@smithy/util-middleware@npm:^3.0.3": - version: 3.0.3 - resolution: "@smithy/util-middleware@npm:3.0.3" +"@smithy/util-middleware@npm:^3.0.4": + version: 3.0.4 + resolution: "@smithy/util-middleware@npm:3.0.4" dependencies: - "@smithy/types": ^3.3.0 + "@smithy/types": ^3.4.0 tslib: ^2.6.2 - checksum: f37f25d65595af5ff4c3f69fa7e66545ac1651f77979e15ffbc9047e18fc668dae90458ee76add85a49ea3729c49d317e40542d5430e81e2eafe8dcae2ddb3bc + checksum: 307c775034875a0ad2361254b680fe406c91933ef62abb8832d8f30cc5f2d71e7236d1993d4b5cbbcfa2ab69486736be4c268c3b9456ce1ac4d38a33e1c63dc5 languageName: node linkType: hard -"@smithy/util-retry@npm:^3.0.3": - version: 3.0.3 - resolution: "@smithy/util-retry@npm:3.0.3" +"@smithy/util-retry@npm:^3.0.4": + version: 3.0.4 + resolution: "@smithy/util-retry@npm:3.0.4" dependencies: - "@smithy/service-error-classification": ^3.0.3 - "@smithy/types": ^3.3.0 + "@smithy/service-error-classification": ^3.0.4 + "@smithy/types": ^3.4.0 tslib: ^2.6.2 - checksum: c760595376154be67414083aa6f76094022df72987521469b124ef3ef5848c0536757dcd2006520580380db6a4d7b597a05569470c3151f71d5e678df63f4c13 + checksum: 99d45a18023b119045cd62a4a868839bd6b8bcfadb95e68f5af4d4c836576ff32e86dc006d8195965d14d005604dc0bd4b3dc4ad7f16573ebef1a1f0f13c238f languageName: node linkType: hard -"@smithy/util-stream@npm:^3.1.3": - version: 3.1.3 - resolution: "@smithy/util-stream@npm:3.1.3" +"@smithy/util-stream@npm:^3.1.4": + version: 3.1.4 + resolution: "@smithy/util-stream@npm:3.1.4" dependencies: - "@smithy/fetch-http-handler": ^3.2.4 - "@smithy/node-http-handler": ^3.1.4 - "@smithy/types": ^3.3.0 + "@smithy/fetch-http-handler": ^3.2.5 + "@smithy/node-http-handler": ^3.2.0 + "@smithy/types": ^3.4.0 "@smithy/util-base64": ^3.0.0 "@smithy/util-buffer-from": ^3.0.0 "@smithy/util-hex-encoding": ^3.0.0 "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: b663124c3b857b7744a0f2db47d091c570ff4fe4e8a8d254a7e1b8fed1d57fa4dc8fb12e496f7f607666ac5bc36d6f44a57ef3132bc882ff1d869b9bfdb5fc6e + checksum: ff49c4f42102587255d921fa574ce4ab09f8af5c1a5d1b256e304e4a2c1addd2addccf6237c52abd588ed77916b2bd5b9d2e6a290658f75fb52ab4b20a04621c languageName: node linkType: hard @@ -15766,14 +15946,14 @@ __metadata: languageName: node linkType: hard -"@smithy/util-waiter@npm:^3.1.2": - version: 3.1.2 - resolution: "@smithy/util-waiter@npm:3.1.2" +"@smithy/util-waiter@npm:^3.1.3": + version: 3.1.3 + resolution: "@smithy/util-waiter@npm:3.1.3" dependencies: - "@smithy/abort-controller": ^3.1.1 - "@smithy/types": ^3.3.0 + "@smithy/abort-controller": ^3.1.2 + "@smithy/types": ^3.4.0 tslib: ^2.6.2 - checksum: 35773b1bbbb215102555a55ce4de57cbd3e38f37546ca3e6748ce3856119019a613946b399c6d97981a0bad447ce9c41f87c276325ff4c0e5a2276ee4e9e384e + checksum: 14fd04730de5fd58325cb37e8aec4567b912c03b7cf649666274b21372859c783cf3a0da3827412afa65bcfd0be92c5cf593a1ae062b27a96bfad8ff2c7d264e languageName: node linkType: hard @@ -15910,19 +16090,19 @@ __metadata: linkType: hard "@stoplight/spectral-core@npm:^1.15.1, @stoplight/spectral-core@npm:^1.16.1, @stoplight/spectral-core@npm:^1.18.0, @stoplight/spectral-core@npm:^1.7.0, @stoplight/spectral-core@npm:^1.8.0, @stoplight/spectral-core@npm:^1.8.1": - version: 1.18.3 - resolution: "@stoplight/spectral-core@npm:1.18.3" + version: 1.19.1 + resolution: "@stoplight/spectral-core@npm:1.19.1" dependencies: "@stoplight/better-ajv-errors": 1.0.3 "@stoplight/json": ~3.21.0 "@stoplight/path": 1.3.2 "@stoplight/spectral-parsers": ^1.0.0 - "@stoplight/spectral-ref-resolver": ^1.0.0 + "@stoplight/spectral-ref-resolver": ^1.0.4 "@stoplight/spectral-runtime": ^1.0.0 "@stoplight/types": ~13.6.0 "@types/es-aggregate-error": ^1.0.2 "@types/json-schema": ^7.0.11 - ajv: ^8.6.0 + ajv: ^8.17.1 ajv-errors: ~3.0.0 ajv-formats: ~2.1.0 es-aggregate-error: ^1.0.7 @@ -15934,57 +16114,59 @@ __metadata: pony-cause: ^1.0.0 simple-eval: 1.0.0 tslib: ^2.3.0 - checksum: 321d868a6c1e3d5f009d87d02651b423b5b6f5ef75a2ad1937b52b8ddc6e83dc3fe9618b00d7d92407e2eb3380b8409dc6ce98a8628d50ebd60d15dc8c15a7b8 + checksum: 35495c3f72eacd02d74b0913ad5a8cdad7573ab06c08cc9f6b44abd68e0c8b2229df9efee11cfe8a47ffeea802ce2b3bb17e378dffe5eab47504f70abd8b492c languageName: node linkType: hard -"@stoplight/spectral-formats@npm:^1.0.0, @stoplight/spectral-formats@npm:^1.2.0, @stoplight/spectral-formats@npm:^1.5.0": - version: 1.5.0 - resolution: "@stoplight/spectral-formats@npm:1.5.0" +"@stoplight/spectral-formats@npm:^1.2.0, @stoplight/spectral-formats@npm:^1.7.0": + version: 1.7.0 + resolution: "@stoplight/spectral-formats@npm:1.7.0" dependencies: "@stoplight/json": ^3.17.0 "@stoplight/spectral-core": ^1.8.0 "@types/json-schema": ^7.0.7 tslib: ^2.3.1 - checksum: dc80c0ee37ff5708b2078aa588d3c8c895ba36b18e52f5813cd7f91d1a476629aa36f1ceaf62e8bd96987c0f7c51537bdb6780a08d32be982db230be5634c93e + checksum: eccc2a6c099c7cbdd7c0b6c48b7fbfa334cdc2323958790496aa0295af27ef42ccae8b40e05c742aa3431da724b8d494c837af1af60f86d05189853b95b7c2c9 languageName: node linkType: hard "@stoplight/spectral-formatters@npm:^1.1.0": - version: 1.3.0 - resolution: "@stoplight/spectral-formatters@npm:1.3.0" + version: 1.4.0 + resolution: "@stoplight/spectral-formatters@npm:1.4.0" dependencies: "@stoplight/path": ^1.3.2 "@stoplight/spectral-core": ^1.15.1 "@stoplight/spectral-runtime": ^1.1.0 "@stoplight/types": ^13.15.0 + "@types/markdown-escape": ^1.1.3 chalk: 4.1.2 cliui: 7.0.4 lodash: ^4.17.21 + markdown-escape: ^2.0.0 node-sarif-builder: ^2.0.3 strip-ansi: 6.0 text-table: ^0.2.0 tslib: ^2.5.0 - checksum: d56757f5204571c5d86551bb8ea56183236c9dab69d95104abcf639a4ff3a465efa5e393f68fd9032c852e0078c514b343a9eaa3aea3ecb8e465f4eeb92bd29f + checksum: fd8b0c96df54b1afa1e2c325edac6a95df0ce4c9a14e3cd46786d229259417eeec7795e7c7ccf4e896a343c5dbd06e62f8692214985acd786d19485bd512958d languageName: node linkType: hard "@stoplight/spectral-functions@npm:^1.5.1, @stoplight/spectral-functions@npm:^1.6.1, @stoplight/spectral-functions@npm:^1.7.2": - version: 1.8.0 - resolution: "@stoplight/spectral-functions@npm:1.8.0" + version: 1.9.0 + resolution: "@stoplight/spectral-functions@npm:1.9.0" dependencies: "@stoplight/better-ajv-errors": 1.0.3 "@stoplight/json": ^3.17.1 "@stoplight/spectral-core": ^1.7.0 - "@stoplight/spectral-formats": ^1.0.0 + "@stoplight/spectral-formats": ^1.7.0 "@stoplight/spectral-runtime": ^1.1.0 - ajv: ^8.6.3 + ajv: ^8.17.1 ajv-draft-04: ~1.0.0 ajv-errors: ~3.0.0 ajv-formats: ~2.1.0 lodash: ~4.17.21 tslib: ^2.3.0 - checksum: d3ca142ae79b0855992b5e1c2a4facb57f3a851afcd9f6893c5010079934ac97550a7aedff4866ba027b1f2e208572ee6791c228be7d1f472e3fc3cdb01bfa20 + checksum: 278dc6e84b3b4fdef73f6b2b2cc7071140ade604dbc938b3946203253f37c0977659a609dc148df6f73668ddcb84a809e279643a12fd3f4372e72e97973f0058 languageName: node linkType: hard @@ -16000,7 +16182,7 @@ __metadata: languageName: node linkType: hard -"@stoplight/spectral-ref-resolver@npm:^1.0.0, @stoplight/spectral-ref-resolver@npm:^1.0.3": +"@stoplight/spectral-ref-resolver@npm:^1.0.3, @stoplight/spectral-ref-resolver@npm:^1.0.4": version: 1.0.4 resolution: "@stoplight/spectral-ref-resolver@npm:1.0.4" dependencies: @@ -16014,25 +16196,25 @@ __metadata: linkType: hard "@stoplight/spectral-rulesets@npm:^1.14.1, @stoplight/spectral-rulesets@npm:^1.18.0": - version: 1.19.1 - resolution: "@stoplight/spectral-rulesets@npm:1.19.1" + version: 1.20.2 + resolution: "@stoplight/spectral-rulesets@npm:1.20.2" dependencies: "@asyncapi/specs": ^4.1.0 "@stoplight/better-ajv-errors": 1.0.3 "@stoplight/json": ^3.17.0 "@stoplight/spectral-core": ^1.8.1 - "@stoplight/spectral-formats": ^1.5.0 + "@stoplight/spectral-formats": ^1.7.0 "@stoplight/spectral-functions": ^1.5.1 "@stoplight/spectral-runtime": ^1.1.1 "@stoplight/types": ^13.6.0 "@types/json-schema": ^7.0.7 - ajv: ^8.12.0 + ajv: ^8.17.1 ajv-formats: ~2.1.0 json-schema-traverse: ^1.0.0 leven: 3.1.0 lodash: ~4.17.21 tslib: ^2.3.0 - checksum: eaecc5062701bd1317ab828dd3b6ad69544e5f0e9d9aecdfdf1da0c476557cb355d6a077731751d6c177c57fa6234f0fd28639733f196768c46e404a4376c763 + checksum: 53b8515864f7132cd727073886adbf61fcbe39543ddf6d975799c75d9ef13d91f3940d5585c81c72da3c94365fd735d8935e885a3ac388c67d03a943af37977f languageName: node linkType: hard @@ -16788,92 +16970,92 @@ __metadata: languageName: node linkType: hard -"@swc/core-darwin-arm64@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-darwin-arm64@npm:1.5.29" +"@swc/core-darwin-arm64@npm:1.7.26": + version: 1.7.26 + resolution: "@swc/core-darwin-arm64@npm:1.7.26" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@swc/core-darwin-x64@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-darwin-x64@npm:1.5.29" +"@swc/core-darwin-x64@npm:1.7.26": + version: 1.7.26 + resolution: "@swc/core-darwin-x64@npm:1.7.26" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@swc/core-linux-arm-gnueabihf@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-linux-arm-gnueabihf@npm:1.5.29" +"@swc/core-linux-arm-gnueabihf@npm:1.7.26": + version: 1.7.26 + resolution: "@swc/core-linux-arm-gnueabihf@npm:1.7.26" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@swc/core-linux-arm64-gnu@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-linux-arm64-gnu@npm:1.5.29" +"@swc/core-linux-arm64-gnu@npm:1.7.26": + version: 1.7.26 + resolution: "@swc/core-linux-arm64-gnu@npm:1.7.26" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-arm64-musl@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-linux-arm64-musl@npm:1.5.29" +"@swc/core-linux-arm64-musl@npm:1.7.26": + version: 1.7.26 + resolution: "@swc/core-linux-arm64-musl@npm:1.7.26" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@swc/core-linux-x64-gnu@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-linux-x64-gnu@npm:1.5.29" +"@swc/core-linux-x64-gnu@npm:1.7.26": + version: 1.7.26 + resolution: "@swc/core-linux-x64-gnu@npm:1.7.26" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-x64-musl@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-linux-x64-musl@npm:1.5.29" +"@swc/core-linux-x64-musl@npm:1.7.26": + version: 1.7.26 + resolution: "@swc/core-linux-x64-musl@npm:1.7.26" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@swc/core-win32-arm64-msvc@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-win32-arm64-msvc@npm:1.5.29" +"@swc/core-win32-arm64-msvc@npm:1.7.26": + version: 1.7.26 + resolution: "@swc/core-win32-arm64-msvc@npm:1.7.26" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@swc/core-win32-ia32-msvc@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-win32-ia32-msvc@npm:1.5.29" +"@swc/core-win32-ia32-msvc@npm:1.7.26": + version: 1.7.26 + resolution: "@swc/core-win32-ia32-msvc@npm:1.7.26" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@swc/core-win32-x64-msvc@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-win32-x64-msvc@npm:1.5.29" +"@swc/core-win32-x64-msvc@npm:1.7.26": + version: 1.7.26 + resolution: "@swc/core-win32-x64-msvc@npm:1.7.26" conditions: os=win32 & cpu=x64 languageName: node linkType: hard "@swc/core@npm:^1.3.46": - version: 1.5.29 - resolution: "@swc/core@npm:1.5.29" + version: 1.7.26 + resolution: "@swc/core@npm:1.7.26" dependencies: - "@swc/core-darwin-arm64": 1.5.29 - "@swc/core-darwin-x64": 1.5.29 - "@swc/core-linux-arm-gnueabihf": 1.5.29 - "@swc/core-linux-arm64-gnu": 1.5.29 - "@swc/core-linux-arm64-musl": 1.5.29 - "@swc/core-linux-x64-gnu": 1.5.29 - "@swc/core-linux-x64-musl": 1.5.29 - "@swc/core-win32-arm64-msvc": 1.5.29 - "@swc/core-win32-ia32-msvc": 1.5.29 - "@swc/core-win32-x64-msvc": 1.5.29 + "@swc/core-darwin-arm64": 1.7.26 + "@swc/core-darwin-x64": 1.7.26 + "@swc/core-linux-arm-gnueabihf": 1.7.26 + "@swc/core-linux-arm64-gnu": 1.7.26 + "@swc/core-linux-arm64-musl": 1.7.26 + "@swc/core-linux-x64-gnu": 1.7.26 + "@swc/core-linux-x64-musl": 1.7.26 + "@swc/core-win32-arm64-msvc": 1.7.26 + "@swc/core-win32-ia32-msvc": 1.7.26 + "@swc/core-win32-x64-msvc": 1.7.26 "@swc/counter": ^0.1.3 - "@swc/types": ^0.1.8 + "@swc/types": ^0.1.12 peerDependencies: "@swc/helpers": "*" dependenciesMeta: @@ -16900,7 +17082,7 @@ __metadata: peerDependenciesMeta: "@swc/helpers": optional: true - checksum: 19e3f8525ce4f4d9f6f3f62825b1f13e1e76146390930b6d5e663c0bb2c5e95ef3bf30268110d1444ea92b99dd95bfe5a3c6e2a3c0dd79291505dc7da1ed3dab + checksum: 8249f2af001f2b5b312ccace4e3a8575bf286bb0f67f029eb58ef8b144f73e37f766800859161ef87c0993e586055238c000ab17dddf9d3760edcfa63ffd22e6 languageName: node linkType: hard @@ -16912,11 +17094,11 @@ __metadata: linkType: hard "@swc/helpers@npm:^0.5.0, @swc/helpers@npm:^0.5.8": - version: 0.5.12 - resolution: "@swc/helpers@npm:0.5.12" + version: 0.5.13 + resolution: "@swc/helpers@npm:0.5.13" dependencies: tslib: ^2.4.0 - checksum: 293c0cb8f41804f94beb04a764bbcfaf316707ec43947713154ac66311590299446bf9b96ab253ce59ce9e435a0edc8cc2bf93f88dc3989f9241271507dd5fe9 + checksum: d50c2c10da6ef940af423c6b03ad9c3c94cf9de59314b1e921a7d1bcc081a6074481c9d67b655fc8fe66a73288f98b25950743792a63882bfb5793b362494fc0 languageName: node linkType: hard @@ -16933,12 +17115,12 @@ __metadata: languageName: node linkType: hard -"@swc/types@npm:^0.1.8": - version: 0.1.8 - resolution: "@swc/types@npm:0.1.8" +"@swc/types@npm:^0.1.12": + version: 0.1.12 + resolution: "@swc/types@npm:0.1.12" dependencies: "@swc/counter": ^0.1.3 - checksum: e564d0e37b0e28546973c6d50c7a179395912a97168d695cfe9cf1051199c8b828680cdafcb8d43948f76d3703873bafb88dfb5bc2dfe0596b4ad18fcaf90c80 + checksum: cf7f89e46f859864075d7965582baea9c5f98830f45b1046251568c9bdf1ca484b1bf37f6d3c32b7c82ecf8cd5df89d22f05268c391819c44e49911bb1a8e71a languageName: node linkType: hard @@ -17044,21 +17226,23 @@ __metadata: languageName: node linkType: hard -"@testing-library/react@npm:^15.0.0": - version: 15.0.7 - resolution: "@testing-library/react@npm:15.0.7" +"@testing-library/react@npm:^16.0.0": + version: 16.0.1 + resolution: "@testing-library/react@npm:16.0.1" dependencies: "@babel/runtime": ^7.12.5 - "@testing-library/dom": ^10.0.0 - "@types/react-dom": ^18.0.0 peerDependencies: + "@testing-library/dom": ^10.0.0 "@types/react": ^18.0.0 + "@types/react-dom": ^18.0.0 react: ^18.0.0 react-dom: ^18.0.0 peerDependenciesMeta: "@types/react": optional: true - checksum: eb33fd82eb811bb8612aa154e430a2c1c251d5ed45a477ef57fe20095db494ea7dcfa6b1e1e2bffb0c7ee10c86e408745d95a879be8ca8fbe301bb91e5f2e5db + "@types/react-dom": + optional: true + checksum: 1837db473ea018cf2b5d0cbfffb7a30d0d759e5a7f23aad431441c77bcc3d2533250cd003a61878fd908267df47404cedcb5914f12d79e413002c659652b37fd languageName: node linkType: hard @@ -17202,10 +17386,10 @@ __metadata: languageName: node linkType: hard -"@types/aws-lambda@npm:8.10.122, @types/aws-lambda@npm:^8.10.83": - version: 8.10.122 - resolution: "@types/aws-lambda@npm:8.10.122" - checksum: 5c2e02ae8fc0eea90fa3b1014f401a8567695e65910fb53452e813b9b58761c956fba50ac7da606b97e07d881d264ff513573d279e7116f3c6b9590fdb093f31 +"@types/aws-lambda@npm:8.10.143, @types/aws-lambda@npm:^8.10.83": + version: 8.10.143 + resolution: "@types/aws-lambda@npm:8.10.143" + checksum: b2ec1db79c57916651a47c173f14ef90564273542a455d79cc07d3eeabef11a39a3d63c3d26061335fbc557210ec4c8d4daf90bc8b51a38ef43a3299223dc3bf languageName: node linkType: hard @@ -17513,19 +17697,12 @@ __metadata: languageName: node linkType: hard -"@types/debug@npm:^4.0.0, @types/debug@npm:^4.1.7": - version: 4.1.7 - resolution: "@types/debug@npm:4.1.7" +"@types/debug@npm:^4.0.0, @types/debug@npm:^4.1.12, @types/debug@npm:^4.1.7": + version: 4.1.12 + resolution: "@types/debug@npm:4.1.12" dependencies: "@types/ms": "*" - checksum: 0a7b89d8ed72526858f0b61c6fd81f477853e8c4415bb97f48b1b5545248d2ae389931680b94b393b993a7cfe893537a200647d93defe6d87159b96812305adc - languageName: node - linkType: hard - -"@types/diff@npm:^5.0.0": - version: 5.2.1 - resolution: "@types/diff@npm:5.2.1" - checksum: 5983a323177bd691cb2194f5d55b960cd20a9c8fec653b4b038760c5809627cc9ea3578fdf10119ccbefefef193ea925f2817136eb97b17388f66b16c8480a8a + checksum: 47876a852de8240bfdaf7481357af2b88cb660d30c72e73789abf00c499d6bc7cd5e52f41c915d1b9cd8ec9fef5b05688d7b7aef17f7f272c2d04679508d1053 languageName: node linkType: hard @@ -17539,14 +17716,14 @@ __metadata: languageName: node linkType: hard -"@types/dockerode@npm:^3.3.0, @types/dockerode@npm:^3.3.24": - version: 3.3.28 - resolution: "@types/dockerode@npm:3.3.28" +"@types/dockerode@npm:^3.3.0, @types/dockerode@npm:^3.3.29": + version: 3.3.31 + resolution: "@types/dockerode@npm:3.3.31" dependencies: "@types/docker-modem": "*" "@types/node": "*" "@types/ssh2": "*" - checksum: d354d790a970b20f7e6b65554eaf851a931adb6fdce831408797b660ff58bf46e87c625ae56c8f7eb902437515cc2286a7cb171ca4e54fbc1262f2d08ab93b78 + checksum: f634f18dc0633f8324faefcde53bcd3d8f3c4bd74d31078cbeb65d2e1597f9abcf12c2158abfaea13dc816bae0f5fa08d0bb570d4214ab0df1ded90db5ebabfe languageName: node linkType: hard @@ -17601,10 +17778,10 @@ __metadata: languageName: node linkType: hard -"@types/estree@npm:*, @types/estree@npm:1.0.5, @types/estree@npm:^1.0.0, @types/estree@npm:^1.0.5": - version: 1.0.5 - resolution: "@types/estree@npm:1.0.5" - checksum: dd8b5bed28e6213b7acd0fb665a84e693554d850b0df423ac8076cc3ad5823a6bc26b0251d080bdc545af83179ede51dd3f6fa78cad2c46ed1f29624ddf3e41a +"@types/estree@npm:*, @types/estree@npm:1.0.6, @types/estree@npm:^1.0.0, @types/estree@npm:^1.0.5": + version: 1.0.6 + resolution: "@types/estree@npm:1.0.6" + checksum: 8825d6e729e16445d9a1dd2fb1db2edc5ed400799064cd4d028150701031af012ba30d6d03fe9df40f4d7a437d0de6d2b256020152b7b09bde9f2e420afdffd9 languageName: node linkType: hard @@ -17643,7 +17820,7 @@ __metadata: languageName: node linkType: hard -"@types/express@npm:*, @types/express@npm:^4.17.14, @types/express@npm:^4.17.21, @types/express@npm:^4.17.6": +"@types/express@npm:*, @types/express@npm:^4.17.21, @types/express@npm:^4.17.6": version: 4.17.21 resolution: "@types/express@npm:4.17.21" dependencies: @@ -17822,21 +17999,21 @@ __metadata: linkType: hard "@types/jest@npm:^29.5.11": - version: 29.5.12 - resolution: "@types/jest@npm:29.5.12" + version: 29.5.13 + resolution: "@types/jest@npm:29.5.13" dependencies: expect: ^29.0.0 pretty-format: ^29.0.0 - checksum: 19b1efdeed9d9a60a81edc8226cdeae5af7479e493eaed273e01243891c9651f7b8b4c08fc633a7d0d1d379b091c4179bbaa0807af62542325fd72f2dd17ce1c + checksum: 875ac23c2398cdcf22aa56c6ba24560f11d2afda226d4fa23936322dde6202f9fdbd2b91602af51c27ecba223d9fc3c1e33c9df7e47b3bf0e2aefc6baf13ce53 languageName: node linkType: hard "@types/jquery@npm:^3.3.34": - version: 3.5.30 - resolution: "@types/jquery@npm:3.5.30" + version: 3.5.31 + resolution: "@types/jquery@npm:3.5.31" dependencies: "@types/sizzle": "*" - checksum: 4594d10fa9b347062883d254a23c9259ae814ef5989ce1985f093dcc7ad4475e324ac3343aef10599c478ea4951726f0e7f79d8ed471ab04de394b7e724d6d13 + checksum: 14a682a6a00e5b0bfe7afbb359ea2ada51b6fdbd962f8ba2b6077989935bd41f395b920581538d218d3ac81e6e3929acb86db9ccb8aa55a67066da9ed55db775 languageName: node linkType: hard @@ -17958,9 +18135,9 @@ __metadata: linkType: hard "@types/lodash@npm:^4.14.151": - version: 4.17.7 - resolution: "@types/lodash@npm:4.17.7" - checksum: 09e58a119cd8a70acfb33f8623dc2fc54f74cdce3b3429b879fc2daac4807fe376190a04b9e024dd300f9a3ee1876d6623979cefe619f70654ca0fe0c47679a7 + version: 4.17.9 + resolution: "@types/lodash@npm:4.17.9" + checksum: 6d1bf3e77f0a54d97532755a74260d402d8972259c5451b74612c16cb983b73e0760e5bfe4f9e68ab15051511c867812b40715a01f9805afe6bc36c7dd676378 languageName: node linkType: hard @@ -17985,6 +18162,13 @@ __metadata: languageName: node linkType: hard +"@types/markdown-escape@npm:^1.1.3": + version: 1.1.3 + resolution: "@types/markdown-escape@npm:1.1.3" + checksum: cb2e410993271f0ccc526190391a08344f4f602be69e06fee989d36d5886866ba9ba2184054895d0ad2a12d57b02f3ccf86d7a1fe8904be48bcc1ee61b98e32f + languageName: node + linkType: hard + "@types/mdast@npm:^3.0.0, @types/mdast@npm:^3.0.3": version: 3.0.10 resolution: "@types/mdast@npm:3.0.10" @@ -18086,12 +18270,12 @@ __metadata: languageName: node linkType: hard -"@types/mysql@npm:2.15.22": - version: 2.15.22 - resolution: "@types/mysql@npm:2.15.22" +"@types/mysql@npm:2.15.26": + version: 2.15.26 + resolution: "@types/mysql@npm:2.15.26" dependencies: "@types/node": "*" - checksum: 325120f027b04052b3ed056fef096d186ecc0988d9efe110a52bd3f2233d02e17fb802ea42da7fa1ae1d150b0194cddf56ff71bfb28411bc05361f947b0635af + checksum: c43395643aca3565492a12f7bb7168cea7f5fa1b6539caabc99e657bbbea3ef330d65e8d8fc873fedfbbbed48a01ac8c1ce0d31c7989cd44a4845b32253daf6c languageName: node linkType: hard @@ -18124,12 +18308,12 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:*, @types/node@npm:>=13.7.0, @types/node@npm:^20.1.1, @types/node@npm:^20.11.16": - version: 20.12.7 - resolution: "@types/node@npm:20.12.7" +"@types/node@npm:*, @types/node@npm:>=13.7.0": + version: 22.7.4 + resolution: "@types/node@npm:22.7.4" dependencies: - undici-types: ~5.26.4 - checksum: 7cc979f7e2ca9a339ec71318c3901b9978555257929ef3666987f3e447123bc6dc92afcc89f6347e09e07d602fde7d51bcddea626c23aa2bb74aeaacfd1e1686 + undici-types: ~6.19.2 + checksum: a3f4154147639369aed08fe6f8d62eff637cf87b187bb252d7bbccdc82884626007af424b08a653c53f2182adfa0340001b4888cb7cbb942cef351210fc742a5 languageName: node linkType: hard @@ -18147,10 +18331,10 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:^16.11.26, @types/node@npm:^16.7.10, @types/node@npm:^16.9.2": - version: 16.18.74 - resolution: "@types/node@npm:16.18.74" - checksum: 33d8f157b51cb2f6907a7019e0bef0733f6ebd025f208863e6e6ea4721348902f2c7ac9eeaadff9f1e138927921e620c7f0a655475a298569d7551f2d28e35f3 +"@types/node@npm:^16.11.26, @types/node@npm:^16.7.10": + version: 16.18.112 + resolution: "@types/node@npm:16.18.112" + checksum: d634729e60d2e7bd951843fddf5fb59ae786ca707f384e8f90881b011076962b4e3fee3393e3be4be4fb7d86943893e0bda9650aea24ac692bdf407bf1a5d84d languageName: node linkType: hard @@ -18161,21 +18345,30 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:^18.17.15, @types/node@npm:^18.17.8": - version: 18.19.8 - resolution: "@types/node@npm:18.19.8" +"@types/node@npm:^18.11.9, @types/node@npm:^18.17.15, @types/node@npm:^18.17.8": + version: 18.19.54 + resolution: "@types/node@npm:18.19.54" dependencies: undici-types: ~5.26.4 - checksum: fa291495d6157a9d9393b4c3bdbf1ce12a8f661dc9da6a4fa19bcdb19af1c62bb8dbf7fb66ae135f29cd788b618e9845b83e9c47edcf39f0953a8561fdacd9a3 + checksum: d85bacc7430c2913bcd2cf293f312bc1f9108819707ac25b58404185c3b8f9ca9e3e93c396672f457c18e65f5ba86cc8363803f830207c6b7dd14fd74e1455b0 + languageName: node + linkType: hard + +"@types/node@npm:^20.1.1, @types/node@npm:^20.11.16": + version: 20.16.10 + resolution: "@types/node@npm:20.16.10" + dependencies: + undici-types: ~6.19.2 + checksum: 8b4d5a0af828871627e80da095df50ef8ae7ca458f39ccde1d060e3bf97b0bc76af9547bd5d75ce4ccb1dd80466804b2fe4f12553c11cb8691c6667effd9a9d7 languageName: node linkType: hard "@types/nodemailer@npm:^6.4.14": - version: 6.4.15 - resolution: "@types/nodemailer@npm:6.4.15" + version: 6.4.16 + resolution: "@types/nodemailer@npm:6.4.16" dependencies: "@types/node": "*" - checksum: f6f9a2f8a669703ecc3ca6359c12345b16f6b2e5691b93c406b9af7de639c02092ec00133526e6fecd8c60d884890a7cd0f967d8e64bedab46d5c3d8be0882d7 + checksum: ef34226b7b69a474a9b9b4681bcfb2461540aed92c54995b934f8072e28deff72aadd4c71522f6825938346048cfec077c69f18cfc2a3ec9f7432db11e5667a3 languageName: node linkType: hard @@ -18271,7 +18464,7 @@ __metadata: languageName: node linkType: hard -"@types/passport-strategy@npm:^0.2.35": +"@types/passport-strategy@npm:^0.2.35, @types/passport-strategy@npm:^0.2.38": version: 0.2.38 resolution: "@types/passport-strategy@npm:0.2.38" dependencies: @@ -18281,7 +18474,7 @@ __metadata: languageName: node linkType: hard -"@types/passport@npm:*, @types/passport@npm:^1.0.11, @types/passport@npm:^1.0.16, @types/passport@npm:^1.0.3": +"@types/passport@npm:*, @types/passport@npm:^1.0.16, @types/passport@npm:^1.0.3": version: 1.0.16 resolution: "@types/passport@npm:1.0.16" dependencies: @@ -18297,23 +18490,23 @@ __metadata: languageName: node linkType: hard -"@types/pg-pool@npm:2.0.4": - version: 2.0.4 - resolution: "@types/pg-pool@npm:2.0.4" +"@types/pg-pool@npm:2.0.6": + version: 2.0.6 + resolution: "@types/pg-pool@npm:2.0.6" dependencies: "@types/pg": "*" - checksum: 5ae1c49fe1820ec011f8e2a877198a62f4c9795d2cc340dff4527c26f24ee22dffe99a8ca5cdec6edb54613bded820cc51256fb668e0eb4d22794181b94fad82 + checksum: cc54ce97115effc982bd052f79901a78215e76554aca0ecc92e78eb907e4fb2962924039369cd9aaf48075f1637593ce14647c62d3a2eb03789ce5d1c6df750b languageName: node linkType: hard -"@types/pg@npm:*, @types/pg@npm:^8.6.6": - version: 8.11.8 - resolution: "@types/pg@npm:8.11.8" +"@types/pg@npm:*": + version: 8.11.10 + resolution: "@types/pg@npm:8.11.10" dependencies: "@types/node": "*" pg-protocol: "*" pg-types: ^4.0.1 - checksum: da101e985abd93ced25d9bd4bbbeb86eac37773310b910afd83971009525cfd1fff3e2ec4f072b2cea184475b6387211c38df8bfbac916d3c73b5a62b6bfb692 + checksum: b2b481784e44429b284c7fc18121372f8afe747c3ada84aaff55de3aa07e205cecf18e8623c8b61860f8eeb499305bef8f934b62c9a1911bef3f8509febef071 languageName: node linkType: hard @@ -18350,9 +18543,9 @@ __metadata: linkType: hard "@types/prop-types@npm:*, @types/prop-types@npm:^15.0.0, @types/prop-types@npm:^15.7.12, @types/prop-types@npm:^15.7.3": - version: 15.7.12 - resolution: "@types/prop-types@npm:15.7.12" - checksum: ac16cc3d0a84431ffa5cfdf89579ad1e2269549f32ce0c769321fdd078f84db4fbe1b461ed5a1a496caf09e637c0e367d600c541435716a55b1d9713f5035dfe + version: 15.7.13 + resolution: "@types/prop-types@npm:15.7.13" + checksum: 8935cad87c683c665d09a055919d617fe951cb3b2d5c00544e3a913f861a2bd8d2145b51c9aa6d2457d19f3107ab40784c40205e757232f6a80cc8b1c815513c languageName: node linkType: hard @@ -18365,10 +18558,10 @@ __metadata: languageName: node linkType: hard -"@types/qs@npm:*, @types/qs@npm:^6.9.6": - version: 6.9.15 - resolution: "@types/qs@npm:6.9.15" - checksum: 97d8208c2b82013b618e7a9fc14df6bd40a73e1385ac479b6896bafc7949a46201c15f42afd06e86a05e914f146f495f606b6fb65610cc60cf2e0ff743ec38a2 +"@types/qs@npm:*, @types/qs@npm:^6.9.11, @types/qs@npm:^6.9.6": + version: 6.9.16 + resolution: "@types/qs@npm:6.9.16" + checksum: 2e8918150c12735630f7ee16b770c72949274938c30306025f68aaf977227f41fe0c698ed93db1099e04916d582ac5a1faf7e3c7061c8d885d9169f59a184b6c languageName: node linkType: hard @@ -18491,12 +18684,12 @@ __metadata: linkType: hard "@types/react@npm:^18": - version: 18.3.4 - resolution: "@types/react@npm:18.3.4" + version: 18.3.10 + resolution: "@types/react@npm:18.3.10" dependencies: "@types/prop-types": "*" csstype: ^3.0.2 - checksum: 555ccd1af86a23c781dea0360de64b2f7a0708cdcbf9e6496744b77630065868526fd55147c727dc5ef11b7fd712b04f7898757a84c67e2eb9dfd4c4ead10d95 + checksum: 04261654b5f4bc9584e9d882c7dfd5b36dc58963f958f8c3efd24cb68c9d205bc2d57558a1479b86d7827f0e5116d5bd111791d1253583d1e1c165f0aeb48c48 languageName: node linkType: hard @@ -18578,7 +18771,7 @@ __metadata: languageName: node linkType: hard -"@types/semver@npm:^7.1.0, @types/semver@npm:^7.3.12, @types/semver@npm:^7.5.0": +"@types/semver@npm:7.5.8, @types/semver@npm:^7.1.0, @types/semver@npm:^7.3.12, @types/semver@npm:^7.5.0": version: 7.5.8 resolution: "@types/semver@npm:7.5.8" checksum: ea6f5276f5b84c55921785a3a27a3cd37afee0111dfe2bcb3e03c31819c197c782598f17f0b150a69d453c9584cd14c4c4d7b9a55d2c5e6cacd4d66fdb3b3663 @@ -18633,7 +18826,7 @@ __metadata: languageName: node linkType: hard -"@types/shimmer@npm:^1.0.2, @types/shimmer@npm:^1.2.0": +"@types/shimmer@npm:^1.2.0": version: 1.2.0 resolution: "@types/shimmer@npm:1.2.0" checksum: f081a31d826ce7bfe8cc7ba8129d2b1dffae44fd580eba4fcf741237646c4c2494ae6de2cada4b7713d138f35f4bc512dbf01311d813dee82020f97d7d8c491c @@ -18906,17 +19099,7 @@ __metadata: languageName: node linkType: hard -"@types/xml-crypto@npm:^1.4.2": - version: 1.4.6 - resolution: "@types/xml-crypto@npm:1.4.6" - dependencies: - "@types/node": "*" - xpath: 0.0.27 - checksum: e53516a2f5e4e018e164eb1cb9fc922294b9a339624e567c1c00a2b1496e9f86826210473e62ceb0b45949638c9d149da088b3598f6b3acd86e933f0a2b23f2c - languageName: node - linkType: hard - -"@types/xml-encryption@npm:^1.2.1": +"@types/xml-encryption@npm:^1.2.4": version: 1.2.4 resolution: "@types/xml-encryption@npm:1.2.4" dependencies: @@ -18925,7 +19108,7 @@ __metadata: languageName: node linkType: hard -"@types/xml2js@npm:^0.4.11, @types/xml2js@npm:^0.4.7": +"@types/xml2js@npm:^0.4.14, @types/xml2js@npm:^0.4.7": version: 0.4.14 resolution: "@types/xml2js@npm:0.4.14" dependencies: @@ -19052,6 +19235,16 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/scope-manager@npm:8.5.0": + version: 8.5.0 + resolution: "@typescript-eslint/scope-manager@npm:8.5.0" + dependencies: + "@typescript-eslint/types": 8.5.0 + "@typescript-eslint/visitor-keys": 8.5.0 + checksum: ee210599652cd21df39467c2b0eeecf97fceb13cf3402e2c11eb47ee4fe1ec9caacba7dedc0917a62febd607bd3517c6ff3a179074c7d2ac4db412d3ea7f392c + languageName: node + linkType: hard + "@typescript-eslint/type-utils@npm:6.21.0": version: 6.21.0 resolution: "@typescript-eslint/type-utils@npm:6.21.0" @@ -19083,6 +19276,13 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/types@npm:8.5.0": + version: 8.5.0 + resolution: "@typescript-eslint/types@npm:8.5.0" + checksum: 74a7ec57f867f02e1c957763a0db3f0f29d41293abb0fc1e067f4de404c0c4e07d7126fff7a10a4e1ccb9ebd45351dd7709dad42367a9defaa9a411ed1b8e29d + languageName: node + linkType: hard + "@typescript-eslint/typescript-estree@npm:5.59.8": version: 5.59.8 resolution: "@typescript-eslint/typescript-estree@npm:5.59.8" @@ -19120,6 +19320,25 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/typescript-estree@npm:8.5.0": + version: 8.5.0 + resolution: "@typescript-eslint/typescript-estree@npm:8.5.0" + dependencies: + "@typescript-eslint/types": 8.5.0 + "@typescript-eslint/visitor-keys": 8.5.0 + debug: ^4.3.4 + fast-glob: ^3.3.2 + is-glob: ^4.0.3 + minimatch: ^9.0.4 + semver: ^7.6.0 + ts-api-utils: ^1.3.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: e8a4d2fc560ab9084c4cafa7933ce17ca9906c88610282507a54c509dea4c03c00182880e34396cfb3b643264d032620dfe14ceba7cc03022ad0fd4213c5548d + languageName: node + linkType: hard + "@typescript-eslint/utils@npm:6.21.0, @typescript-eslint/utils@npm:^6.0.0": version: 6.21.0 resolution: "@typescript-eslint/utils@npm:6.21.0" @@ -19137,7 +19356,7 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/utils@npm:^5.10.0, @typescript-eslint/utils@npm:^5.58.0": +"@typescript-eslint/utils@npm:^5.58.0": version: 5.59.8 resolution: "@typescript-eslint/utils@npm:5.59.8" dependencies: @@ -19155,6 +19374,20 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/utils@npm:^6.0.0 || ^7.0.0 || ^8.0.0": + version: 8.5.0 + resolution: "@typescript-eslint/utils@npm:8.5.0" + dependencies: + "@eslint-community/eslint-utils": ^4.4.0 + "@typescript-eslint/scope-manager": 8.5.0 + "@typescript-eslint/types": 8.5.0 + "@typescript-eslint/typescript-estree": 8.5.0 + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + checksum: d91d4f29aa3275e35734dbf84dfdb2e0e5557c2ed4181e760b3d9319379f19295a79d223b06f5f3583e4de80938dfe47814a11b7fd66a737b5ca6bbe6a555632 + languageName: node + linkType: hard + "@typescript-eslint/visitor-keys@npm:5.59.8": version: 5.59.8 resolution: "@typescript-eslint/visitor-keys@npm:5.59.8" @@ -19175,9 +19408,19 @@ __metadata: languageName: node linkType: hard -"@uiw/codemirror-extensions-basic-setup@npm:4.23.0": - version: 4.23.0 - resolution: "@uiw/codemirror-extensions-basic-setup@npm:4.23.0" +"@typescript-eslint/visitor-keys@npm:8.5.0": + version: 8.5.0 + resolution: "@typescript-eslint/visitor-keys@npm:8.5.0" + dependencies: + "@typescript-eslint/types": 8.5.0 + eslint-visitor-keys: ^3.4.3 + checksum: dbba7071e9723d0e525d8b350834d95699037e9e7ba9cf2b3b4fb6cf3fd47072869874f665daca54bc084c910a4ae0acfd5670625a4cc62a173662b09f92e79e + languageName: node + linkType: hard + +"@uiw/codemirror-extensions-basic-setup@npm:4.23.2": + version: 4.23.2 + resolution: "@uiw/codemirror-extensions-basic-setup@npm:4.23.2" dependencies: "@codemirror/autocomplete": ^6.0.0 "@codemirror/commands": ^6.0.0 @@ -19194,19 +19437,19 @@ __metadata: "@codemirror/search": ">=6.0.0" "@codemirror/state": ">=6.0.0" "@codemirror/view": ">=6.0.0" - checksum: bc48d3aa82dc0b7cf9724c2806fe013423448135b38ab7d2472eb1df80d3297d75f4a45e3dbd817cb32423ebc57169a46505598e185d351ad819b59f8887c539 + checksum: c6822a94caf335d8f407b0b38b4756b76722fcd77f90d3d9bad39ca1cd8a2b220a9bbf4b6b22bdbfd422b48bf6b623cac58e65d7e4f9c909e4424c68c96c39e3 languageName: node linkType: hard "@uiw/react-codemirror@npm:^4.9.3": - version: 4.23.0 - resolution: "@uiw/react-codemirror@npm:4.23.0" + version: 4.23.2 + resolution: "@uiw/react-codemirror@npm:4.23.2" dependencies: "@babel/runtime": ^7.18.6 "@codemirror/commands": ^6.1.0 "@codemirror/state": ^6.1.1 "@codemirror/theme-one-dark": ^6.0.0 - "@uiw/codemirror-extensions-basic-setup": 4.23.0 + "@uiw/codemirror-extensions-basic-setup": 4.23.2 codemirror: ^6.0.0 peerDependencies: "@babel/runtime": ">=7.11.0" @@ -19216,7 +19459,7 @@ __metadata: codemirror: ">=6.0.0" react: ">=16.8.0" react-dom: ">=16.8.0" - checksum: b1341dee1f0257c1fd62bd3b356a207ff2bb72b9eb509c5c52cabf87b8aa23b4dac812ebb25ad7b84cddf58d8674b09842bce3c763bb63a9f8cc1d731d7de0be + checksum: 670f495a27d595ef5656c17e7b90c57e8d0476e34d97022ca6500132cc83aa86e31d2e4664b64b7c9fe0aa0251717b1d17f08d41527c439c515df89f6b0fa9aa languageName: node linkType: hard @@ -19433,18 +19676,18 @@ __metadata: languageName: node linkType: hard -"@vitejs/plugin-react@npm:^4.0.4": - version: 4.3.1 - resolution: "@vitejs/plugin-react@npm:4.3.1" +"@vitejs/plugin-react@npm:^4.3.1": + version: 4.3.2 + resolution: "@vitejs/plugin-react@npm:4.3.2" dependencies: - "@babel/core": ^7.24.5 - "@babel/plugin-transform-react-jsx-self": ^7.24.5 - "@babel/plugin-transform-react-jsx-source": ^7.24.1 + "@babel/core": ^7.25.2 + "@babel/plugin-transform-react-jsx-self": ^7.24.7 + "@babel/plugin-transform-react-jsx-source": ^7.24.7 "@types/babel__core": ^7.20.5 react-refresh: ^0.14.2 peerDependencies: vite: ^4.2.0 || ^5.0.0 - checksum: 57872e0193c7e545c5ef4852cbe1adf17a6b35406a2aba4b3acce06c173a9dabbf6ff4c72701abc11bb3cbe24a056f5054f39018f7034c9aa57133a3a7770237 + checksum: 6bd3f8ec4a5c1f9f2970217d6a7291fafb41b7760f7761b982b6835c8f9cd3874cea9eb3b6659aa75c511954fcec7707116ea32042854b1be47902ebbb781794 languageName: node linkType: hard @@ -19629,7 +19872,14 @@ __metadata: languageName: node linkType: hard -"@xmldom/xmldom@npm:^0.8.3, @xmldom/xmldom@npm:^0.8.5, @xmldom/xmldom@npm:^0.8.6, @xmldom/xmldom@npm:^0.8.8": +"@xmldom/is-dom-node@npm:^1.0.1": + version: 1.0.1 + resolution: "@xmldom/is-dom-node@npm:1.0.1" + checksum: 24a412fbd996b4de757c3905f4b4aad28578aaf6687fd4fc986f339d476dcf5153c50a4f408099c2a894961a1517c927163ec37a1ade9f73b5c0ad478b34190e + languageName: node + linkType: hard + +"@xmldom/xmldom@npm:^0.8.10, @xmldom/xmldom@npm:^0.8.3, @xmldom/xmldom@npm:^0.8.5": version: 0.8.10 resolution: "@xmldom/xmldom@npm:0.8.10" checksum: 4c136aec31fb3b49aaa53b6fcbfe524d02a1dc0d8e17ee35bd3bf35e9ce1344560481cd1efd086ad1a4821541482528672306d5e37cdbd187f33d7fadd3e2cf0 @@ -19719,19 +19969,19 @@ __metadata: linkType: hard "@yarnpkg/core@npm:^4.0.0, @yarnpkg/core@npm:^4.0.3": - version: 4.0.3 - resolution: "@yarnpkg/core@npm:4.0.3" + version: 4.1.3 + resolution: "@yarnpkg/core@npm:4.1.3" dependencies: "@arcanis/slice-ansi": ^1.1.1 "@types/semver": ^7.1.0 "@types/treeify": ^1.0.0 - "@yarnpkg/fslib": ^3.0.2 - "@yarnpkg/libzip": ^3.0.1 - "@yarnpkg/parsers": ^3.0.0 - "@yarnpkg/shell": ^4.0.0 + "@yarnpkg/fslib": ^3.1.0 + "@yarnpkg/libzip": ^3.1.0 + "@yarnpkg/parsers": ^3.0.2 + "@yarnpkg/shell": ^4.1.0 camelcase: ^5.3.1 chalk: ^3.0.0 - ci-info: ^3.2.0 + ci-info: ^4.0.0 clipanion: ^4.0.0-rc.2 cross-spawn: 7.0.3 diff: ^5.1.0 @@ -19748,7 +19998,7 @@ __metadata: treeify: ^1.1.0 tslib: ^2.4.0 tunnel: ^0.0.6 - checksum: 811956ab94e9f4b3601f304312baf816322df124cf85754ef3985110c90935b1b761c8266a06c2c5633f6edc39c8a4ceffeff50f08f036d7adf19612ce3761a3 + checksum: 789bf7c1451d24e6405a42537a53382ec76387bf2696aadd3a189e8a343768d78377ff7b363f0c9271465f6a83c8e1e913d390ad3a233f7aa3d8ce9512e5147c languageName: node linkType: hard @@ -19761,12 +20011,12 @@ __metadata: languageName: node linkType: hard -"@yarnpkg/fslib@npm:^3.0.0, @yarnpkg/fslib@npm:^3.0.1, @yarnpkg/fslib@npm:^3.0.2": - version: 3.0.2 - resolution: "@yarnpkg/fslib@npm:3.0.2" +"@yarnpkg/fslib@npm:^3.0.0, @yarnpkg/fslib@npm:^3.0.1, @yarnpkg/fslib@npm:^3.0.2, @yarnpkg/fslib@npm:^3.1.0": + version: 3.1.0 + resolution: "@yarnpkg/fslib@npm:3.1.0" dependencies: tslib: ^2.4.0 - checksum: b0795df777e43eb1c2bd8aa1d6c45f88b8a1d3922ee8bf264cdca916cc6f9455551a9499761a9c1f585aa576350d84adcc315e497fc031cdbbbc1a5c71942e1b + checksum: 5274c63731cb30283a93e1446d6796b890fc56c55ed046156b2963a527465bc3add091a1e7f471b7533c8b1aa67b8532960e64589787014dee2cf3d97a9304f6 languageName: node linkType: hard @@ -19782,16 +20032,16 @@ __metadata: languageName: node linkType: hard -"@yarnpkg/libzip@npm:^3.0.0, @yarnpkg/libzip@npm:^3.0.1": - version: 3.0.1 - resolution: "@yarnpkg/libzip@npm:3.0.1" +"@yarnpkg/libzip@npm:^3.0.0, @yarnpkg/libzip@npm:^3.0.1, @yarnpkg/libzip@npm:^3.1.0": + version: 3.1.0 + resolution: "@yarnpkg/libzip@npm:3.1.0" dependencies: "@types/emscripten": ^1.39.6 - "@yarnpkg/fslib": ^3.0.2 + "@yarnpkg/fslib": ^3.1.0 tslib: ^2.4.0 peerDependencies: - "@yarnpkg/fslib": ^3.0.2 - checksum: 932b1fc35bb60ca57d033aab7a940f7b1d7bf52a68bfff6c755fe26827c0f1b373fda33e373afabbae98de3ed31ae4f0e9ee2ef24588cd074b75fb814117827d + "@yarnpkg/fslib": ^3.1.0 + checksum: 2bb7c10b41184a079906ec4ebdadda69e4cd3b101d11aae965c08934254dbd303e51e9869fd8d799c5f58d59214cd13d67d454ad96e1c76ce9384816d58da08c languageName: node linkType: hard @@ -19813,13 +20063,13 @@ __metadata: languageName: node linkType: hard -"@yarnpkg/parsers@npm:^3.0.0": - version: 3.0.0 - resolution: "@yarnpkg/parsers@npm:3.0.0" +"@yarnpkg/parsers@npm:^3.0.0, @yarnpkg/parsers@npm:^3.0.2": + version: 3.0.2 + resolution: "@yarnpkg/parsers@npm:3.0.2" dependencies: js-yaml: ^3.10.0 tslib: ^2.4.0 - checksum: fefe5ecafb5bfa2b678ac9ba9259810fdda40142afd9d0b7e0e5cc1cce1fd824dffc52217c5e429807481d8fd18ead074bd317e64fd626335d3c9f1a320bade2 + checksum: fb40a87ae7c9f3fc0b2a6b7d84375d1c69ae8304daf598c089b52966bfb4ac94fbd2dcd87ed041970416e03d34359cb5ff16be5f5601f48d1f936213a8edaf4d languageName: node linkType: hard @@ -20202,12 +20452,12 @@ __metadata: languageName: node linkType: hard -"@yarnpkg/shell@npm:^4.0.0": - version: 4.0.0 - resolution: "@yarnpkg/shell@npm:4.0.0" +"@yarnpkg/shell@npm:^4.0.0, @yarnpkg/shell@npm:^4.1.0": + version: 4.1.0 + resolution: "@yarnpkg/shell@npm:4.1.0" dependencies: - "@yarnpkg/fslib": ^3.0.0 - "@yarnpkg/parsers": ^3.0.0 + "@yarnpkg/fslib": ^3.1.0 + "@yarnpkg/parsers": ^3.0.2 chalk: ^3.0.0 clipanion: ^4.0.0-rc.2 cross-spawn: 7.0.3 @@ -20216,7 +20466,7 @@ __metadata: tslib: ^2.4.0 bin: shell: ./lib/cli.js - checksum: 8497e278b1d3d0ffe324a3b9c878ca7165bbbe4d182f5ecb02f1bfaaf4dd18c8aaa54c33ee17bb37eb09173816dc4617b70c3fe0925f5fb99749687e2650b7a2 + checksum: d5ad721cadc6d6f1411ad98b5d8362c2c804be4e4e9ed9799debbaa96fd2413fc5beaf011e30e69f54ab66b66779ba916125dc40efcf104a4e99053b3a8c645b languageName: node linkType: hard @@ -20474,6 +20724,20 @@ __metadata: languageName: node linkType: hard +"ajv-formats@npm:~3.0.1": + version: 3.0.1 + resolution: "ajv-formats@npm:3.0.1" + dependencies: + ajv: ^8.0.0 + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + checksum: f4e1fe232d67fcafc02eafe373a7a9962351e0439dd0736647ca75c93c3da23b430b6502c255ab4315410ae330d4f3013ac9fe226c40b2524ca93a58e786d086 + languageName: node + linkType: hard + "ajv-i18n@npm:^4.2.0": version: 4.2.0 resolution: "ajv-i18n@npm:4.2.0" @@ -20503,7 +20767,7 @@ __metadata: languageName: node linkType: hard -"ajv@npm:^6.12.2, ajv@npm:^6.12.4, ajv@npm:^6.12.5, ajv@npm:^6.5.5, ajv@npm:~6.12.6": +"ajv@npm:^6.12.2, ajv@npm:^6.12.4, ajv@npm:^6.12.5, ajv@npm:^6.5.5": version: 6.12.6 resolution: "ajv@npm:6.12.6" dependencies: @@ -20527,6 +20791,30 @@ __metadata: languageName: node linkType: hard +"ajv@npm:~8.12.0": + version: 8.12.0 + resolution: "ajv@npm:8.12.0" + dependencies: + fast-deep-equal: ^3.1.1 + json-schema-traverse: ^1.0.0 + require-from-string: ^2.0.2 + uri-js: ^4.2.2 + checksum: 4dc13714e316e67537c8b31bc063f99a1d9d9a497eb4bbd55191ac0dcd5e4985bbb71570352ad6f1e76684fb6d790928f96ba3b2d4fd6e10024be9612fe3f001 + languageName: node + linkType: hard + +"ajv@npm:~8.13.0": + version: 8.13.0 + resolution: "ajv@npm:8.13.0" + dependencies: + fast-deep-equal: ^3.1.3 + json-schema-traverse: ^1.0.0 + require-from-string: ^2.0.2 + uri-js: ^4.4.1 + checksum: 6de82d0b2073e645ca3300561356ddda0234f39b35d2125a8700b650509b296f41c00ab69f53178bbe25ad688bd6ac3747ab44101f2f4bd245952e8fd6ccc3c1 + languageName: node + linkType: hard + "algoliasearch@npm:^4.2.0": version: 4.23.2 resolution: "algoliasearch@npm:4.23.2" @@ -20626,9 +20914,9 @@ __metadata: linkType: hard "ansi-regex@npm:*, ansi-regex@npm:^6.0.1": - version: 6.0.1 - resolution: "ansi-regex@npm:6.0.1" - checksum: 1ff8b7667cded1de4fa2c9ae283e979fc87036864317da86a2e546725f96406746411d0d85e87a2d12fa5abd715d90006de7fa4fa0477c92321ad3b4c7d4e169 + version: 6.1.0 + resolution: "ansi-regex@npm:6.1.0" + checksum: 495834a53b0856c02acd40446f7130cb0f8284f4a39afdab20d5dc42b2e198b1196119fe887beed8f9055c4ff2055e3b2f6d4641d0be018cdfb64fedf6fc1aac languageName: node linkType: hard @@ -20678,7 +20966,7 @@ __metadata: languageName: node linkType: hard -"any-promise@npm:^1.0.0, any-promise@npm:^1.1.0": +"any-promise@npm:^1.0.0": version: 1.3.0 resolution: "any-promise@npm:1.3.0" checksum: 0ee8a9bdbe882c90464d75d1f55cf027f5458650c4bd1f0467e65aec38ccccda07ca5844969ee77ed46d04e7dded3eaceb027e8d32f385688523fe305fa7e1de @@ -20710,12 +20998,20 @@ __metadata: "@backstage/core-components": "workspace:^" "@backstage/frontend-plugin-api": "workspace:^" "@material-ui/icons": ^4.9.1 + "@types/react": ^18.0.0 cross-fetch: ^4.0.0 msw: ^1.0.0 + react: ^18.0.2 + react-dom: ^18.0.2 + react-router-dom: ^6.3.0 peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true languageName: unknown linkType: soft @@ -20733,65 +21029,33 @@ __metadata: languageName: node linkType: hard -"archiver-utils@npm:^2.1.0": - version: 2.1.0 - resolution: "archiver-utils@npm:2.1.0" +"archiver-utils@npm:^5.0.0, archiver-utils@npm:^5.0.2": + version: 5.0.2 + resolution: "archiver-utils@npm:5.0.2" dependencies: - glob: ^7.1.4 - graceful-fs: ^4.2.0 - lazystream: ^1.0.0 - lodash.defaults: ^4.2.0 - lodash.difference: ^4.5.0 - lodash.flatten: ^4.4.0 - lodash.isplainobject: ^4.0.6 - lodash.union: ^4.6.0 - normalize-path: ^3.0.0 - readable-stream: ^2.0.0 - checksum: 5665f40bde87ee82cb638177bdccca8cc6e55edea1b94338f7e6b56a1d9367b0d9a39e42b47866eaf84b8c67669a7d250900a226207ecc30fa163b52aae859a5 - languageName: node - linkType: hard - -"archiver-utils@npm:^4.0.1": - version: 4.0.1 - resolution: "archiver-utils@npm:4.0.1" - dependencies: - glob: ^8.0.0 + glob: ^10.0.0 graceful-fs: ^4.2.0 + is-stream: ^2.0.1 lazystream: ^1.0.0 lodash: ^4.17.15 normalize-path: ^3.0.0 - readable-stream: ^3.6.0 - checksum: 2917cdf63a912c74002a4a1e6de3076a4691030b4e722efdd6d862447b61cd64c8b7688d331b1d35f8d4fc661d6e34f91bc1ffc79478fca2e48ad060acece18c + readable-stream: ^4.0.0 + checksum: 7dc4f3001dc373bd0fa7671ebf08edf6f815cbc539c78b5478a2eaa67e52e3fc0e92f562cdef2ba016c4dcb5468d3d069eb89535c6844da4a5bb0baf08ad5720 languageName: node linkType: hard -"archiver@npm:^5.3.2": - version: 5.3.2 - resolution: "archiver@npm:5.3.2" +"archiver@npm:^7.0.0, archiver@npm:^7.0.1": + version: 7.0.1 + resolution: "archiver@npm:7.0.1" dependencies: - archiver-utils: ^2.1.0 + archiver-utils: ^5.0.2 async: ^3.2.4 - buffer-crc32: ^0.2.1 - readable-stream: ^3.6.0 - readdir-glob: ^1.1.2 - tar-stream: ^2.2.0 - zip-stream: ^4.1.0 - checksum: 7d3b9b9b51cf54d88c89fbca9b0847c120bfcf9776c7025c52dd0b62f6603dc63dc0f3f1a09582f936f67e3906b46d58954cc762a255be45e8d3e14e3cb0b0b1 - languageName: node - linkType: hard - -"archiver@npm:^6.0.0": - version: 6.0.2 - resolution: "archiver@npm:6.0.2" - dependencies: - archiver-utils: ^4.0.1 - async: ^3.2.4 - buffer-crc32: ^0.2.1 - readable-stream: ^3.6.0 + buffer-crc32: ^1.0.0 + readable-stream: ^4.0.0 readdir-glob: ^1.1.2 tar-stream: ^3.0.0 - zip-stream: ^5.0.1 - checksum: 17a20a1291d9bf41e25c96f029373bec5306d6e381063b3ab06ea805d234afaf55a7829c3577dd003558c188c6631769a80c51f245175fdb8310631df36ceb4b + zip-stream: ^6.0.1 + checksum: f93bcc00f919e0bbb6bf38fddf111d6e4d1ed34721b73cc073edd37278303a7a9f67aa4abd6fd2beb80f6c88af77f2eb4f60276343f67605e3aea404e5ad93ea languageName: node linkType: hard @@ -20901,7 +21165,7 @@ __metadata: languageName: node linkType: hard -"array-includes@npm:^3.1.6, array-includes@npm:^3.1.7, array-includes@npm:^3.1.8": +"array-includes@npm:^3.1.6, array-includes@npm:^3.1.8": version: 3.1.8 resolution: "array-includes@npm:3.1.8" dependencies: @@ -20943,16 +21207,17 @@ __metadata: languageName: node linkType: hard -"array.prototype.findlastindex@npm:^1.2.3": - version: 1.2.3 - resolution: "array.prototype.findlastindex@npm:1.2.3" +"array.prototype.findlastindex@npm:^1.2.5": + version: 1.2.5 + resolution: "array.prototype.findlastindex@npm:1.2.5" dependencies: - call-bind: ^1.0.2 - define-properties: ^1.2.0 - es-abstract: ^1.22.1 - es-shim-unscopables: ^1.0.0 - get-intrinsic: ^1.2.1 - checksum: 31f35d7b370c84db56484618132041a9af401b338f51899c2e78ef7690fbba5909ee7ca3c59a7192085b328cc0c68c6fd1f6d1553db01a689a589ae510f3966e + call-bind: ^1.0.7 + define-properties: ^1.2.1 + es-abstract: ^1.23.2 + es-errors: ^1.3.0 + es-object-atoms: ^1.0.0 + es-shim-unscopables: ^1.0.2 + checksum: 2c81cff2a75deb95bf1ed89b6f5f2bfbfb882211e3b7cc59c3d6b87df774cd9d6b36949a8ae39ac476e092c1d4a4905f5ee11a86a456abb10f35f8211ae4e710 languageName: node linkType: hard @@ -21062,14 +21327,15 @@ __metadata: linkType: hard "assert@npm:^2.0.0": - version: 2.0.0 - resolution: "assert@npm:2.0.0" + version: 2.1.0 + resolution: "assert@npm:2.1.0" dependencies: - es6-object-assign: ^1.1.0 - is-nan: ^1.2.1 - object-is: ^1.0.1 - util: ^0.12.0 - checksum: bb91f181a86d10588ee16c5e09c280f9811373974c29974cbe401987ea34e966699d7989a812b0e19377b511ea0bc627f5905647ce569311824848ede382cae8 + call-bind: ^1.0.2 + is-nan: ^1.3.2 + object-is: ^1.1.5 + object.assign: ^4.1.4 + util: ^0.12.5 + checksum: 1ed1cabba9abe55f4109b3f7292b4e4f3cf2953aad8dc148c0b3c3bd676675c31b1abb32ef563b7d5a19d1715bf90d1e5f09fad2a4ee655199468902da80f7c2 languageName: node linkType: hard @@ -21283,7 +21549,7 @@ __metadata: languageName: node linkType: hard -"axe-core@npm:^4.9.1": +"axe-core@npm:^4.10.0": version: 4.10.0 resolution: "axe-core@npm:4.10.0" checksum: 7eca827fd8d98d7e4b561df65437be608155c613d8f262ae9e4a6ade02c156c7362dcbc3f71b4b526edce686f7c686280236bcff1d6725e2ef8327def72a8c41 @@ -21313,14 +21579,14 @@ __metadata: languageName: node linkType: hard -"axios@npm:1.7.4, axios@npm:^1.0.0, axios@npm:^1.4.0, axios@npm:^1.6.0, axios@npm:^1.6.7": - version: 1.7.4 - resolution: "axios@npm:1.7.4" +"axios@npm:1.7.7, axios@npm:^1.0.0, axios@npm:^1.4.0, axios@npm:^1.6.0, axios@npm:^1.7.4": + version: 1.7.7 + resolution: "axios@npm:1.7.7" dependencies: follow-redirects: ^1.15.6 form-data: ^4.0.0 proxy-from-env: ^1.1.0 - checksum: 0c17039a9acfe6a566fca8431ba5c1b455c83d30ea6157fec68a6722878fcd30f3bd32d172f6bee0c51fe75ca98e6414ddcd968a87b5606b573731629440bfaf + checksum: 882d4fe0ec694a07c7f5c1f68205eb6dc5a62aecdb632cc7a4a3d0985188ce3030e0b277e1a8260ac3f194d314ae342117660a151fabffdc5081ca0b5a8b47fe languageName: node linkType: hard @@ -21334,12 +21600,10 @@ __metadata: languageName: node linkType: hard -"axobject-query@npm:~3.1.1": - version: 3.1.1 - resolution: "axobject-query@npm:3.1.1" - dependencies: - deep-equal: ^2.0.5 - checksum: c12a5da10dc7bab75e1cda9b6a3b5fcf10eba426ddf1a17b71ef65a434ed707ede7d1c4f013ba1609e970bc8c0cddac01365080d376204314e9b294719acd8a5 +"axobject-query@npm:^4.1.0": + version: 4.1.0 + resolution: "axobject-query@npm:4.1.0" + checksum: 7d1e87bf0aa7ae7a76cd39ab627b7c48fda3dc40181303d9adce4ba1d5b5ce73b5e5403ee6626ec8e91090448c887294d6144e24b6741a976f5be9347e3ae1df languageName: node linkType: hard @@ -21675,13 +21939,13 @@ __metadata: linkType: hard "better-sqlite3@npm:^11.0.0": - version: 11.2.1 - resolution: "better-sqlite3@npm:11.2.1" + version: 11.3.0 + resolution: "better-sqlite3@npm:11.3.0" dependencies: bindings: ^1.5.0 node-gyp: latest prebuild-install: ^7.1.1 - checksum: 22259c298e76d4bc2bd993dfc9392bb80ecef948f48342804a7bd38a43ff7693089a9ea0ac0c14ebc195453aa94fce588755f6eea234d7550383b9f6ac7150a9 + checksum: 364058b4cc739abd5774f511521298eac101d1e6f0362da65b56d9135e6e0728af38c2fa182ec2b56b4c76d7f7ff8efefd753df0c1b8f0192051b06d21e5d1f7 languageName: node linkType: hard @@ -21795,9 +22059,9 @@ __metadata: languageName: node linkType: hard -"body-parser@npm:1.20.2, body-parser@npm:^1.15.2": - version: 1.20.2 - resolution: "body-parser@npm:1.20.2" +"body-parser@npm:1.20.3, body-parser@npm:^1.15.2": + version: 1.20.3 + resolution: "body-parser@npm:1.20.3" dependencies: bytes: 3.1.2 content-type: ~1.0.5 @@ -21807,11 +22071,11 @@ __metadata: http-errors: 2.0.0 iconv-lite: 0.4.24 on-finished: 2.4.1 - qs: 6.11.0 + qs: 6.13.0 raw-body: 2.5.2 type-is: ~1.6.18 unpipe: 1.0.0 - checksum: 14d37ec638ab5c93f6099ecaed7f28f890d222c650c69306872e00b9efa081ff6c596cd9afb9930656aae4d6c4e1c17537bea12bb73c87a217cb3cfea8896737 + checksum: 1a35c59a6be8d852b00946330141c4f142c6af0f970faa87f10ad74f1ee7118078056706a05ae3093c54dabca9cd3770fa62a170a85801da1a4324f04381167d languageName: node linkType: hard @@ -22046,7 +22310,14 @@ __metadata: languageName: node linkType: hard -"buffer-crc32@npm:^0.2.1, buffer-crc32@npm:^0.2.13, buffer-crc32@npm:~0.2.3": +"buffer-crc32@npm:^1.0.0": + version: 1.0.0 + resolution: "buffer-crc32@npm:1.0.0" + checksum: bc114c0e02fe621249e0b5093c70e6f12d4c2b1d8ddaf3b1b7bbe3333466700100e6b1ebdc12c050d0db845bc582c4fce8c293da487cc483f97eea027c480b23 + languageName: node + linkType: hard + +"buffer-crc32@npm:~0.2.3": version: 0.2.13 resolution: "buffer-crc32@npm:0.2.13" checksum: 06252347ae6daca3453b94e4b2f1d3754a3b146a111d81c68924c22d91889a40623264e95e67955b1cb4a68cbedf317abeabb5140a9766ed248973096db5ce1c @@ -22589,6 +22860,13 @@ __metadata: languageName: node linkType: hard +"ci-info@npm:^4.0.0": + version: 4.0.0 + resolution: "ci-info@npm:4.0.0" + checksum: 122fe41c5eb8d0b5fa0ab6fd674c5ddcf2dc59766528b062a0144ff0d913cfb210ef925ec52110e7c2a7f4e603d5f0e8b91cfe68867e196e9212fa0b94d0a08a + languageName: node + linkType: hard + "cidr-regex@npm:^3.1.1": version: 3.1.1 resolution: "cidr-regex@npm:3.1.1" @@ -23057,13 +23335,6 @@ __metadata: languageName: node linkType: hard -"colors@npm:~1.2.1": - version: 1.2.5 - resolution: "colors@npm:1.2.5" - checksum: b6e23de735f68b72d5cdf6fd854ca43d1b66d82dcf54bda0b788083b910164a040f2c4edf23c670d36a7a2d8f1b7d6e62e3292703e4642691e6ccaa1c62d8f74 - languageName: node - linkType: hard - "colorspace@npm:1.1.x": version: 1.1.2 resolution: "colorspace@npm:1.1.2" @@ -23146,7 +23417,7 @@ __metadata: languageName: node linkType: hard -"commander@npm:^2.19.0, commander@npm:^2.20.0, commander@npm:^2.7.1": +"commander@npm:^2.19.0, commander@npm:^2.20.0": version: 2.20.3 resolution: "commander@npm:2.20.3" checksum: ab8c07884e42c3a8dbc5dd9592c606176c7eb5c1ca5ff274bcf907039b2c41de3626f684ea75ccf4d361ba004bbaff1f577d5384c155f3871e456bdf27becf9e @@ -23209,27 +23480,16 @@ __metadata: languageName: node linkType: hard -"compress-commons@npm:^4.1.0": - version: 4.1.0 - resolution: "compress-commons@npm:4.1.0" - dependencies: - buffer-crc32: ^0.2.13 - crc32-stream: ^4.0.1 - normalize-path: ^3.0.0 - readable-stream: ^3.6.0 - checksum: 3348bea7a1cce04b430f6ec3125eebbc0e23bd8dd14d30ec2fb113d3733f95ae6b12d5b33ad794e7ceab70f57e38a6c2642d96a64bc83e490a3ddae8db469949 - languageName: node - linkType: hard - -"compress-commons@npm:^5.0.1": - version: 5.0.1 - resolution: "compress-commons@npm:5.0.1" +"compress-commons@npm:^6.0.2": + version: 6.0.2 + resolution: "compress-commons@npm:6.0.2" dependencies: crc-32: ^1.2.0 - crc32-stream: ^5.0.0 + crc32-stream: ^6.0.0 + is-stream: ^2.0.1 normalize-path: ^3.0.0 - readable-stream: ^3.6.0 - checksum: 65a68e56211a8d1dbe9dab0d35f1bd60a4df27aa01e6c3f0883080263e228c460758bab4f083637a380d4a96d2326722972a42ea1951360cc69728a3915f209f + readable-stream: ^4.0.0 + checksum: 37d79a54f91344ecde352588e0a128f28ce619b085acd4f887defd76978a0640e3454a42c7dcadb0191bb3f971724ae4b1f9d6ef9620034aa0427382099ac946 languageName: node linkType: hard @@ -23546,13 +23806,13 @@ __metadata: languageName: node linkType: hard -"cookies@npm:~0.8.0": - version: 0.8.0 - resolution: "cookies@npm:0.8.0" +"cookies@npm:~0.9.0": + version: 0.9.1 + resolution: "cookies@npm:0.9.1" dependencies: depd: ~2.0.0 keygrip: ~1.1.0 - checksum: 806055a44f128705265b1bc6a853058da18bf80dea3654ad99be20985b1fa1b14f86c1eef73644aab8071241f8a78acd57202b54c4c5c70769fc694fbb9c4edc + checksum: 213e4d14847b582fbd8a003203d3621a4b9fa792a315c37954e89332d38fac5bcc34ba92ef316ad6d5fe28f0187aaa115927fbbe2080744ad1707a93b4313247 languageName: node linkType: hard @@ -23702,23 +23962,13 @@ __metadata: languageName: node linkType: hard -"crc32-stream@npm:^4.0.1": - version: 4.0.1 - resolution: "crc32-stream@npm:4.0.1" +"crc32-stream@npm:^6.0.0": + version: 6.0.0 + resolution: "crc32-stream@npm:6.0.0" dependencies: crc-32: ^1.2.0 - readable-stream: ^3.4.0 - checksum: 39c2e0d5d7a3388e85ccf27ef0b30475f98902d34e7a048decc1665ff67f98f17f850059b28942fdf5582cb836eaa5184453ec35a6ea2442ce3bc10c8f1ee8a4 - languageName: node - linkType: hard - -"crc32-stream@npm:^5.0.0": - version: 5.0.0 - resolution: "crc32-stream@npm:5.0.0" - dependencies: - crc-32: ^1.2.0 - readable-stream: ^3.4.0 - checksum: 8e5dd04f22f3fbecc623492395107fbed2114f225bd606e39e8ed338f2fc1c454ac02a05741243620ab526473cb867fa86411a44a7ffcd88457cc1c2af82d0bc + readable-stream: ^4.0.0 + checksum: e6edc2f81bc387daef6d18b2ac18c2ffcb01b554d3b5c7d8d29b177505aafffba574658fdd23922767e8dab1183d1962026c98c17e17fb272794c33293ef607c languageName: node linkType: hard @@ -23848,12 +24098,12 @@ __metadata: languageName: node linkType: hard -"cross-inspect@npm:1.0.0": - version: 1.0.0 - resolution: "cross-inspect@npm:1.0.0" +"cross-inspect@npm:1.0.1": + version: 1.0.1 + resolution: "cross-inspect@npm:1.0.1" dependencies: tslib: ^2.4.0 - checksum: 975c81799549627027254eb70f1c349cefb14435d580bea6f351f510c839dcb1a9288983407bac2ad317e6eff29cf1e99299606da21f404562bfa64cec502239 + checksum: 7c1e02e0a9670b62416a3ea1df7ae880fdad3aa0a857de8932c4e5f8acd71298c7e3db9da8e9da603f5692cd1879938f5e72e34a9f5d1345987bef656d117fc1 languageName: node linkType: hard @@ -24461,7 +24711,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:4, 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.2, debug@npm:^4.3.3, debug@npm:^4.3.4, debug@npm:~4.3.6": +"debug@npm:4, 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.2, debug@npm:^4.3.3, debug@npm:^4.3.4, debug@npm:^4.3.5, debug@npm:~4.3.6": version: 4.3.6 resolution: "debug@npm:4.3.6" dependencies: @@ -24494,15 +24744,6 @@ __metadata: languageName: node linkType: hard -"debug@npm:~3.1.0": - version: 3.1.0 - resolution: "debug@npm:3.1.0" - dependencies: - ms: 2.0.0 - checksum: 0b52718ab957254a5b3ca07fc34543bc778f358620c206a08452251eb7fc193c3ea3505072acbf4350219c14e2d71ceb7bdaa0d3370aa630b50da790458d08b3 - languageName: node - linkType: hard - "debuglog@npm:^1.0.1": version: 1.0.1 resolution: "debuglog@npm:1.0.1" @@ -24643,15 +24884,6 @@ __metadata: languageName: node linkType: hard -"default-gateway@npm:^6.0.3": - version: 6.0.3 - resolution: "default-gateway@npm:6.0.3" - dependencies: - execa: ^5.0.0 - checksum: 126f8273ecac8ee9ff91ea778e8784f6cd732d77c3157e8c5bdd6ed03651b5291f71446d05bc02d04073b1e67583604db5394ea3cf992ede0088c70ea15b7378 - languageName: node - linkType: hard - "defaults@npm:^1.0.3": version: 1.0.3 resolution: "defaults@npm:1.0.3" @@ -24766,7 +24998,7 @@ __metadata: languageName: node linkType: hard -"depd@npm:2.0.0, depd@npm:~2.0.0": +"depd@npm:2.0.0, depd@npm:^2.0.0, depd@npm:~2.0.0": version: 2.0.0 resolution: "depd@npm:2.0.0" checksum: abbe19c768c97ee2eed6282d8ce3031126662252c58d711f646921c9623f9052e3e1906443066beec1095832f534e57c523b7333f8e7e0d93051ab6baef5ab3a @@ -24963,12 +25195,12 @@ __metadata: languageName: node linkType: hard -"docker-compose@npm:^0.24.6": - version: 0.24.7 - resolution: "docker-compose@npm:0.24.7" +"docker-compose@npm:^0.24.8": + version: 0.24.8 + resolution: "docker-compose@npm:0.24.8" dependencies: yaml: ^2.2.2 - checksum: 54daa1985fd7a57a1881dfdb7d294a189b9ba4e097de81127bfb4ff2f7727d249cc1514ee6a5a06c0085f9f6b5bcafe55b3e463f30b87c4d682bd8b0dac0450e + checksum: 48f3564c46490f1f51899a144deb546b61450a76bffddb378379ac7702aa34b055e0237e0dc77507df94d7ad6f1f7daeeac27730230bce9aafe2e35efeda6b45 languageName: node linkType: hard @@ -25099,9 +25331,9 @@ __metadata: linkType: hard "domain-browser@npm:^4.22.0": - version: 4.22.0 - resolution: "domain-browser@npm:4.22.0" - checksum: e7ce1c19073e17dec35cfde050a3ddaac437d3ba8b870adabf9d5682e665eab3084df05de432dedf25b34303f0a2c71ac30f1cdba61b1aea018047b10de3d988 + version: 4.23.0 + resolution: "domain-browser@npm:4.23.0" + checksum: 95b772f5fa88300240694380e06e03868573acdf86ca392a58c78602d6536dca2097ad2469a1500bd23a1329b09992de846e0b66c364cbf5711a7fee3ee5dac9 languageName: node linkType: hard @@ -25241,9 +25473,9 @@ __metadata: linkType: hard "dset@npm:^3.1.2": - version: 3.1.3 - resolution: "dset@npm:3.1.3" - checksum: 5db964a36c60c51aa3f7088bfe1dc5c0eedd9a6ef3b216935bb70ef4a7b8fc40fd2f9bb16b9a4692c9c9772cea60cfefb108d2d09fbd53c85ea8f6cd54502d6a + version: 3.1.4 + resolution: "dset@npm:3.1.4" + checksum: 9a7677e9ffd3c13ad850f7cf367aa94b39984006510e84c3c09b7b88bba0a5b3b7196d85a99d0c4cae4e47d67bdeca43dc1834a41d80f31bcdc86dd26121ecec languageName: node linkType: hard @@ -25484,6 +25716,13 @@ __metadata: languageName: node linkType: hard +"encodeurl@npm:~2.0.0": + version: 2.0.0 + resolution: "encodeurl@npm:2.0.0" + checksum: abf5cd51b78082cf8af7be6785813c33b6df2068ce5191a40ca8b1afe6a86f9230af9a9ce694a5ce4665955e5c1120871826df9c128a642e09c58d592e2807fe + languageName: node + linkType: hard + "encoding@npm:^0.1.12, encoding@npm:^0.1.13": version: 0.1.13 resolution: "encoding@npm:0.1.13" @@ -25573,13 +25812,6 @@ __metadata: languageName: node linkType: hard -"error-inject@npm:^1.0.0": - version: 1.0.0 - resolution: "error-inject@npm:1.0.0" - checksum: 258cb26c7c7e04d9b730d074926ff5e18755b6945781540fdd124cafc5015610d97e4b971eb3226469f407fd34fa899a60fbcf9ade8923ab42fa2a3c61e246cf - languageName: node - linkType: hard - "error-stack-parser@npm:^2.0.6": version: 2.0.6 resolution: "error-stack-parser@npm:2.0.6" @@ -25797,13 +26029,6 @@ __metadata: languageName: node linkType: hard -"es6-object-assign@npm:^1.1.0": - version: 1.1.0 - resolution: "es6-object-assign@npm:1.1.0" - checksum: 8d4fdf63484d78b5c64cacc2c2e1165bc7b6a64b739d2a9db6a4dc8641d99cc9efb433cdd4dc3d3d6b00bfa6ce959694e4665e3255190339945c5f33b692b5d8 - languageName: node - linkType: hard - "es6-symbol@npm:^3.1.1, es6-symbol@npm:^3.1.3": version: 3.1.3 resolution: "es6-symbol@npm:3.1.3" @@ -25827,123 +26052,46 @@ __metadata: linkType: hard "esbuild-loader@npm:^4.0.0": - version: 4.1.0 - resolution: "esbuild-loader@npm:4.1.0" + version: 4.2.2 + resolution: "esbuild-loader@npm:4.2.2" dependencies: - esbuild: ^0.20.0 + esbuild: ^0.21.0 get-tsconfig: ^4.7.0 loader-utils: ^2.0.4 webpack-sources: ^1.4.3 peerDependencies: webpack: ^4.40.0 || ^5.0.0 - checksum: 51e76c36dd1fb70545889b07e3c4b4a437aaf1a2acc836e83141f06bcb8fbf96af778cf21b37355ea724c30504ad288ba76b0554ff94af260bb12ece647de861 + checksum: 793d2482693c1c66298f63d7fdb62f2f3e314b006ade1dc3c46b46ade39777c5fba5930c2fa2752636c511997faa08d4a0f5d5b8a734b9046b3626aa6d5ab8e3 languageName: node linkType: hard -"esbuild@npm:^0.18.10": - version: 0.18.20 - resolution: "esbuild@npm:0.18.20" +"esbuild@npm:^0.21.0, esbuild@npm:^0.21.3": + version: 0.21.5 + resolution: "esbuild@npm:0.21.5" dependencies: - "@esbuild/android-arm": 0.18.20 - "@esbuild/android-arm64": 0.18.20 - "@esbuild/android-x64": 0.18.20 - "@esbuild/darwin-arm64": 0.18.20 - "@esbuild/darwin-x64": 0.18.20 - "@esbuild/freebsd-arm64": 0.18.20 - "@esbuild/freebsd-x64": 0.18.20 - "@esbuild/linux-arm": 0.18.20 - "@esbuild/linux-arm64": 0.18.20 - "@esbuild/linux-ia32": 0.18.20 - "@esbuild/linux-loong64": 0.18.20 - "@esbuild/linux-mips64el": 0.18.20 - "@esbuild/linux-ppc64": 0.18.20 - "@esbuild/linux-riscv64": 0.18.20 - "@esbuild/linux-s390x": 0.18.20 - "@esbuild/linux-x64": 0.18.20 - "@esbuild/netbsd-x64": 0.18.20 - "@esbuild/openbsd-x64": 0.18.20 - "@esbuild/sunos-x64": 0.18.20 - "@esbuild/win32-arm64": 0.18.20 - "@esbuild/win32-ia32": 0.18.20 - "@esbuild/win32-x64": 0.18.20 - dependenciesMeta: - "@esbuild/android-arm": - optional: true - "@esbuild/android-arm64": - optional: true - "@esbuild/android-x64": - optional: true - "@esbuild/darwin-arm64": - optional: true - "@esbuild/darwin-x64": - optional: true - "@esbuild/freebsd-arm64": - optional: true - "@esbuild/freebsd-x64": - optional: true - "@esbuild/linux-arm": - optional: true - "@esbuild/linux-arm64": - optional: true - "@esbuild/linux-ia32": - optional: true - "@esbuild/linux-loong64": - optional: true - "@esbuild/linux-mips64el": - optional: true - "@esbuild/linux-ppc64": - optional: true - "@esbuild/linux-riscv64": - optional: true - "@esbuild/linux-s390x": - optional: true - "@esbuild/linux-x64": - optional: true - "@esbuild/netbsd-x64": - optional: true - "@esbuild/openbsd-x64": - optional: true - "@esbuild/sunos-x64": - optional: true - "@esbuild/win32-arm64": - optional: true - "@esbuild/win32-ia32": - optional: true - "@esbuild/win32-x64": - optional: true - bin: - esbuild: bin/esbuild - checksum: 5d253614e50cdb6ec22095afd0c414f15688e7278a7eb4f3720a6dd1306b0909cf431e7b9437a90d065a31b1c57be60130f63fe3e8d0083b588571f31ee6ec7b - languageName: node - linkType: hard - -"esbuild@npm:^0.20.0": - version: 0.20.2 - resolution: "esbuild@npm:0.20.2" - dependencies: - "@esbuild/aix-ppc64": 0.20.2 - "@esbuild/android-arm": 0.20.2 - "@esbuild/android-arm64": 0.20.2 - "@esbuild/android-x64": 0.20.2 - "@esbuild/darwin-arm64": 0.20.2 - "@esbuild/darwin-x64": 0.20.2 - "@esbuild/freebsd-arm64": 0.20.2 - "@esbuild/freebsd-x64": 0.20.2 - "@esbuild/linux-arm": 0.20.2 - "@esbuild/linux-arm64": 0.20.2 - "@esbuild/linux-ia32": 0.20.2 - "@esbuild/linux-loong64": 0.20.2 - "@esbuild/linux-mips64el": 0.20.2 - "@esbuild/linux-ppc64": 0.20.2 - "@esbuild/linux-riscv64": 0.20.2 - "@esbuild/linux-s390x": 0.20.2 - "@esbuild/linux-x64": 0.20.2 - "@esbuild/netbsd-x64": 0.20.2 - "@esbuild/openbsd-x64": 0.20.2 - "@esbuild/sunos-x64": 0.20.2 - "@esbuild/win32-arm64": 0.20.2 - "@esbuild/win32-ia32": 0.20.2 - "@esbuild/win32-x64": 0.20.2 + "@esbuild/aix-ppc64": 0.21.5 + "@esbuild/android-arm": 0.21.5 + "@esbuild/android-arm64": 0.21.5 + "@esbuild/android-x64": 0.21.5 + "@esbuild/darwin-arm64": 0.21.5 + "@esbuild/darwin-x64": 0.21.5 + "@esbuild/freebsd-arm64": 0.21.5 + "@esbuild/freebsd-x64": 0.21.5 + "@esbuild/linux-arm": 0.21.5 + "@esbuild/linux-arm64": 0.21.5 + "@esbuild/linux-ia32": 0.21.5 + "@esbuild/linux-loong64": 0.21.5 + "@esbuild/linux-mips64el": 0.21.5 + "@esbuild/linux-ppc64": 0.21.5 + "@esbuild/linux-riscv64": 0.21.5 + "@esbuild/linux-s390x": 0.21.5 + "@esbuild/linux-x64": 0.21.5 + "@esbuild/netbsd-x64": 0.21.5 + "@esbuild/openbsd-x64": 0.21.5 + "@esbuild/sunos-x64": 0.21.5 + "@esbuild/win32-arm64": 0.21.5 + "@esbuild/win32-ia32": 0.21.5 + "@esbuild/win32-x64": 0.21.5 dependenciesMeta: "@esbuild/aix-ppc64": optional: true @@ -25993,7 +26141,7 @@ __metadata: optional: true bin: esbuild: bin/esbuild - checksum: bc88050fc1ca5c1bd03648f9979e514bdefb956a63aa3974373bb7b9cbac0b3aac9b9da1b5bdca0b3490e39d6b451c72815dbd6b7d7f978c91fbe9c9e9aa4e4c + checksum: 2911c7b50b23a9df59a7d6d4cdd3a4f85855787f374dce751148dbb13305e0ce7e880dde1608c2ab7a927fc6cec3587b80995f7fc87a64b455f8b70b55fd8ec1 languageName: node linkType: hard @@ -26210,15 +26358,15 @@ __metadata: languageName: node linkType: hard -"eslint-module-utils@npm:^2.8.0": - version: 2.8.0 - resolution: "eslint-module-utils@npm:2.8.0" +"eslint-module-utils@npm:^2.9.0": + version: 2.9.0 + resolution: "eslint-module-utils@npm:2.9.0" dependencies: debug: ^3.2.7 peerDependenciesMeta: eslint: optional: true - checksum: 74c6dfea7641ebcfe174be61168541a11a14aa8d72e515f5f09af55cd0d0862686104b0524aa4b8e0ce66418a44aa38a94d2588743db5fd07a6b49ffd16921d2 + checksum: 304ec1279cac62b242d9347859625235c07be8b8870306d85502375b2b4beeccda2da2f03884ec00a1820e643d87718e5a2eea149730c61aeb42ea8f4cb9f4a6 languageName: node linkType: hard @@ -26237,60 +26385,61 @@ __metadata: linkType: hard "eslint-plugin-import@npm:^2.25.4": - version: 2.29.1 - resolution: "eslint-plugin-import@npm:2.29.1" + version: 2.30.0 + resolution: "eslint-plugin-import@npm:2.30.0" dependencies: - array-includes: ^3.1.7 - array.prototype.findlastindex: ^1.2.3 + "@rtsao/scc": ^1.1.0 + array-includes: ^3.1.8 + array.prototype.findlastindex: ^1.2.5 array.prototype.flat: ^1.3.2 array.prototype.flatmap: ^1.3.2 debug: ^3.2.7 doctrine: ^2.1.0 eslint-import-resolver-node: ^0.3.9 - eslint-module-utils: ^2.8.0 - hasown: ^2.0.0 - is-core-module: ^2.13.1 + eslint-module-utils: ^2.9.0 + hasown: ^2.0.2 + is-core-module: ^2.15.1 is-glob: ^4.0.3 minimatch: ^3.1.2 - object.fromentries: ^2.0.7 - object.groupby: ^1.0.1 - object.values: ^1.1.7 + object.fromentries: ^2.0.8 + object.groupby: ^1.0.3 + object.values: ^1.2.0 semver: ^6.3.1 tsconfig-paths: ^3.15.0 peerDependencies: eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 - checksum: e65159aef808136d26d029b71c8c6e4cb5c628e65e5de77f1eb4c13a379315ae55c9c3afa847f43f4ff9df7e54515c77ffc6489c6a6f81f7dd7359267577468c + checksum: 0ec1ad69c0d22f15bc4a49ee97ae757e4adfc3181996f2c4a1ed4d5028bd99bab38e7623e58ef4477ba1db8425f441e4e986367125273efa4c5f7ad2c4467a9a languageName: node linkType: hard -"eslint-plugin-jest@npm:^27.0.0": - version: 27.9.0 - resolution: "eslint-plugin-jest@npm:27.9.0" +"eslint-plugin-jest@npm:^28.0.0": + version: 28.8.3 + resolution: "eslint-plugin-jest@npm:28.8.3" dependencies: - "@typescript-eslint/utils": ^5.10.0 + "@typescript-eslint/utils": ^6.0.0 || ^7.0.0 || ^8.0.0 peerDependencies: - "@typescript-eslint/eslint-plugin": ^5.0.0 || ^6.0.0 || ^7.0.0 - eslint: ^7.0.0 || ^8.0.0 + "@typescript-eslint/eslint-plugin": ^6.0.0 || ^7.0.0 || ^8.0.0 + eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 jest: "*" peerDependenciesMeta: "@typescript-eslint/eslint-plugin": optional: true jest: optional: true - checksum: e2a4b415105408de28ad146818fcc6f4e122f6a39c6b2216ec5c24a80393f1390298b20231b0467bc5fd730f6e24b05b89e1a6a3ce651fc159aa4174ecc233d0 + checksum: e371fcbe2127a403824b6c23b66f6b2e2cc54074c3c70a9965d48bdcdfb461670965a7d7cdddab68f09e703d3a09a281d05591b1cb4315f5246d27fd8baa84ac languageName: node linkType: hard "eslint-plugin-jsx-a11y@npm:^6.5.1": - version: 6.9.0 - resolution: "eslint-plugin-jsx-a11y@npm:6.9.0" + version: 6.10.0 + resolution: "eslint-plugin-jsx-a11y@npm:6.10.0" dependencies: aria-query: ~5.1.3 array-includes: ^3.1.8 array.prototype.flatmap: ^1.3.2 ast-types-flow: ^0.0.8 - axe-core: ^4.9.1 - axobject-query: ~3.1.1 + axe-core: ^4.10.0 + axobject-query: ^4.1.0 damerau-levenshtein: ^1.0.8 emoji-regex: ^9.2.2 es-iterator-helpers: ^1.0.19 @@ -26302,21 +26451,21 @@ __metadata: safe-regex-test: ^1.0.3 string.prototype.includes: ^2.0.0 peerDependencies: - eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 - checksum: 122cbd22bbd8c3e4a37f386ec183ada63a4ecfa7af7d40cd8a110777ac5ad5ff542f60644596a9e2582ed138a1cc6d96c5d5ca934105e29d5245d6c951ebc3ef + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 + checksum: 1009deca12ddbe3624586bc5fc3534ca98d00a5841a2563cb6abd9339b984f0a99075dc2a703a517f4087eb84d659c87e60beda17645883de2ba1d86f2b20c96 languageName: node linkType: hard -"eslint-plugin-notice@npm:^0.9.10": - version: 0.9.10 - resolution: "eslint-plugin-notice@npm:0.9.10" +"eslint-plugin-notice@npm:^1.0.0": + version: 1.0.0 + resolution: "eslint-plugin-notice@npm:1.0.0" dependencies: find-root: ^1.1.0 - lodash: ^4.17.15 + lodash: ^4.17.21 metric-lcs: ^0.1.2 peerDependencies: eslint: ">=3.0.0" - checksum: 0892ea3da8f31f57390941b6ae3472a34fe4037a21dfe73763c2e5011a08859bff4be6af50d1c54b04e16e43b10342458acb83874b806fcd5e2839be9f99c92e + checksum: 9a745463e89078d08d75cd13ce7d868b73aa3ca12e607bb2d0436512192a6c18398e47abf5e4b624fd8147d89052fe984529592c44c9b2ad836754bbf2cae5e5 languageName: node linkType: hard @@ -26330,8 +26479,8 @@ __metadata: linkType: hard "eslint-plugin-react@npm:^7.28.0": - version: 7.35.0 - resolution: "eslint-plugin-react@npm:7.35.0" + version: 7.36.1 + resolution: "eslint-plugin-react@npm:7.36.1" dependencies: array-includes: ^3.1.8 array.prototype.findlast: ^1.2.5 @@ -26353,7 +26502,7 @@ __metadata: string.prototype.repeat: ^1.0.0 peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 - checksum: cd4d3c0567e947964643dda5fc80147e058d75f06bac47c3f086ff0cd6156286c669d98e685e3834997c4043f3922b90e6374b6c3658f22abd025dbd41acc23f + checksum: bf3be414f3d639200a7d91feeaa6beec3397feed93ab22eaecef44dda37ecbd01812ed1720c72a9861fb276d3543cea69a834a66f64de3d878796fef4f4bf129 languageName: node linkType: hard @@ -26434,14 +26583,14 @@ __metadata: linkType: hard "eslint@npm:^8.33.0, eslint@npm:^8.6.0": - version: 8.57.0 - resolution: "eslint@npm:8.57.0" + version: 8.57.1 + resolution: "eslint@npm:8.57.1" dependencies: "@eslint-community/eslint-utils": ^4.2.0 "@eslint-community/regexpp": ^4.6.1 "@eslint/eslintrc": ^2.1.4 - "@eslint/js": 8.57.0 - "@humanwhocodes/config-array": ^0.11.14 + "@eslint/js": 8.57.1 + "@humanwhocodes/config-array": ^0.13.0 "@humanwhocodes/module-importer": ^1.0.1 "@nodelib/fs.walk": ^1.2.8 "@ungap/structured-clone": ^1.2.0 @@ -26477,7 +26626,7 @@ __metadata: text-table: ^0.2.0 bin: eslint: bin/eslint.js - checksum: 3a48d7ff85ab420a8447e9810d8087aea5b1df9ef68c9151732b478de698389ee656fd895635b5f2871c89ee5a2652b3f343d11e9db6f8486880374ebc74a2d9 + checksum: e2489bb7f86dd2011967759a09164e65744ef7688c310bc990612fc26953f34cc391872807486b15c06833bdff737726a23e9b4cdba5de144c311377dc41d91b languageName: node linkType: hard @@ -26697,13 +26846,12 @@ __metadata: "@octokit/rest": ^19.0.3 "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^15.0.0 + "@testing-library/react": ^16.0.0 "@testing-library/user-event": ^14.0.0 "@types/jquery": ^3.3.34 "@types/react": "*" "@types/react-dom": "*" "@types/zen-observable": ^0.8.0 - "@vitejs/plugin-react": ^4.0.4 cross-env: ^7.0.0 history: ^5.0.0 react: ^18.0.2 @@ -26711,9 +26859,6 @@ __metadata: react-router: ^6.3.0 react-router-dom: ^6.3.0 react-use: ^17.2.4 - vite: ^4.4.9 - vite-plugin-html: ^3.2.0 - vite-plugin-node-polyfills: ^0.22.0 zen-observable: ^0.10.0 languageName: unknown linkType: soft @@ -26777,13 +26922,13 @@ __metadata: "@playwright/test": ^1.32.3 "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^15.0.0 + "@testing-library/react": ^16.0.0 "@testing-library/user-event": ^14.0.0 "@types/jquery": ^3.3.34 "@types/react": "*" "@types/react-dom": "*" "@types/zen-observable": ^0.8.0 - "@vitejs/plugin-react": ^4.0.4 + "@vitejs/plugin-react": ^4.3.1 cross-env: ^7.0.0 history: ^5.0.0 react: ^18.0.2 @@ -26791,8 +26936,8 @@ __metadata: react-router: ^6.3.0 react-router-dom: ^6.3.0 react-use: ^17.2.4 - vite: ^4.4.9 - vite-plugin-html: ^3.2.0 + vite: ^5.0.0 + vite-plugin-html: ^3.2.2 vite-plugin-node-polyfills: ^0.22.0 zen-observable: ^0.10.0 languageName: unknown @@ -26802,7 +26947,7 @@ __metadata: version: 0.0.0-use.local resolution: "example-backend-legacy@workspace:packages/backend-legacy" dependencies: - "@backstage/backend-common": "workspace:^" + "@backstage/backend-common": ^0.25.0 "@backstage/backend-defaults": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/catalog-client": "workspace:^" @@ -26880,6 +27025,7 @@ __metadata: "@backstage/plugin-catalog-backend-module-scaffolder-entity-model": "workspace:^" "@backstage/plugin-catalog-backend-module-unprocessed": "workspace:^" "@backstage/plugin-devtools-backend": "workspace:^" + "@backstage/plugin-events-backend": "workspace:^" "@backstage/plugin-kubernetes-backend": "workspace:^" "@backstage/plugin-notifications-backend": "workspace:^" "@backstage/plugin-permission-backend": "workspace:^" @@ -26896,7 +27042,7 @@ __metadata: "@backstage/plugin-search-backend-node": "workspace:^" "@backstage/plugin-signals-backend": "workspace:^" "@backstage/plugin-techdocs-backend": "workspace:^" - "@opentelemetry/auto-instrumentations-node": ^0.49.0 + "@opentelemetry/auto-instrumentations-node": ^0.50.0 "@opentelemetry/exporter-prometheus": ^0.53.0 "@opentelemetry/sdk-node": ^0.53.0 example-app: "link:../app" @@ -27019,8 +27165,8 @@ __metadata: linkType: hard "express-openapi-validator@npm:^5.0.4": - version: 5.3.4 - resolution: "express-openapi-validator@npm:5.3.4" + version: 5.3.6 + resolution: "express-openapi-validator@npm:5.3.6" dependencies: "@apidevtools/json-schema-ref-parser": ^11.7.0 "@types/multer": ^1.4.11 @@ -27034,10 +27180,10 @@ __metadata: media-typer: ^1.1.0 multer: ^1.4.5-lts.1 ono: ^7.1.3 - path-to-regexp: ^6.2.2 + path-to-regexp: ^6.3.0 peerDependencies: express: "*" - checksum: 0c699e8f12d499d759e11c08009cc479d8748bb1adf9e31b72e7f1c0d56d6c6c2333e72124517724cb1d6c7bd428a1a6dfe241b15fbe16f513f373222baf2d77 + checksum: 3833bc2351fe099aed5777c1254514316425d9188ad5002e6604259b36953d8304b8804b835cddc518e8a63f1d1c2288e7a83006400c2dc7e644f2e3cadfb755 languageName: node linkType: hard @@ -27088,42 +27234,42 @@ __metadata: languageName: node linkType: hard -"express@npm:^4.14.0, express@npm:^4.17.1, express@npm:^4.17.3, express@npm:^4.18.1, express@npm:^4.18.2, express@npm:^4.19.2": - version: 4.19.2 - resolution: "express@npm:4.19.2" +"express@npm:^4.14.0, express@npm:^4.17.1, express@npm:^4.18.1, express@npm:^4.18.2, express@npm:^4.19.2": + version: 4.21.0 + resolution: "express@npm:4.21.0" dependencies: accepts: ~1.3.8 array-flatten: 1.1.1 - body-parser: 1.20.2 + body-parser: 1.20.3 content-disposition: 0.5.4 content-type: ~1.0.4 cookie: 0.6.0 cookie-signature: 1.0.6 debug: 2.6.9 depd: 2.0.0 - encodeurl: ~1.0.2 + encodeurl: ~2.0.0 escape-html: ~1.0.3 etag: ~1.8.1 - finalhandler: 1.2.0 + finalhandler: 1.3.1 fresh: 0.5.2 http-errors: 2.0.0 - merge-descriptors: 1.0.1 + merge-descriptors: 1.0.3 methods: ~1.1.2 on-finished: 2.4.1 parseurl: ~1.3.3 - path-to-regexp: 0.1.7 + path-to-regexp: 0.1.10 proxy-addr: ~2.0.7 - qs: 6.11.0 + qs: 6.13.0 range-parser: ~1.2.1 safe-buffer: 5.2.1 - send: 0.18.0 - serve-static: 1.15.0 + send: 0.19.0 + serve-static: 1.16.2 setprototypeof: 1.2.0 statuses: 2.0.1 type-is: ~1.6.18 utils-merge: 1.0.1 vary: ~1.1.2 - checksum: 212dbd6c2c222a96a61bc927639c95970a53b06257080bb9e2838adb3bffdb966856551fdad1ab5dd654a217c35db94f987d0aa88d48fb04d306340f5f34dca5 + checksum: 1c5212993f665809c249bf00ab550b989d1365a5b9171cdfaa26d93ee2ef10cd8add520861ec8d5da74b3194d8374e1d9d53e85ef69b89fd9c4196b87045a5d4 languageName: node linkType: hard @@ -27493,18 +27639,18 @@ __metadata: languageName: node linkType: hard -"finalhandler@npm:1.2.0": - version: 1.2.0 - resolution: "finalhandler@npm:1.2.0" +"finalhandler@npm:1.3.1": + version: 1.3.1 + resolution: "finalhandler@npm:1.3.1" dependencies: debug: 2.6.9 - encodeurl: ~1.0.2 + encodeurl: ~2.0.0 escape-html: ~1.0.3 on-finished: 2.4.1 parseurl: ~1.3.3 statuses: 2.0.1 unpipe: ~1.0.0 - checksum: 92effbfd32e22a7dff2994acedbd9bcc3aa646a3e919ea6a53238090e87097f8ef07cced90aa2cc421abdf993aefbdd5b00104d55c7c5479a8d00ed105b45716 + checksum: a8c58cd97c9cd47679a870f6833a7b417043f5a288cd6af6d0f49b476c874a506100303a128b6d3b654c3d74fa4ff2ffed68a48a27e8630cda5c918f2977dcf4 languageName: node linkType: hard @@ -27815,15 +27961,14 @@ __metadata: languageName: node linkType: hard -"formidable@npm:^2.1.2": - version: 2.1.2 - resolution: "formidable@npm:2.1.2" +"formidable@npm:^3.5.1": + version: 3.5.1 + resolution: "formidable@npm:3.5.1" dependencies: dezalgo: ^1.0.4 hexoid: ^1.0.0 once: ^1.4.0 - qs: ^6.11.0 - checksum: 81c8e5d89f5eb873e992893468f0de22c01678ca3d315db62be0560f9de1c77d4faefc9b1f4575098eb2263b3c81ba1024833a9fc3206297ddbac88a4f69b7a8 + checksum: 46b21496f9f985161cf7636163147b6728f9997c7e1d59433680d92619758bf6862330e6d105b5816bafcd1ab32f27ef183455991f93ef836ea731c68db62af9 languageName: node linkType: hard @@ -27993,7 +28138,7 @@ __metadata: languageName: node linkType: hard -"fsevents@npm:^2.3.2, fsevents@npm:~2.3.2": +"fsevents@npm:^2.3.2, fsevents@npm:~2.3.2, fsevents@npm:~2.3.3": version: 2.3.3 resolution: "fsevents@npm:2.3.3" dependencies: @@ -28012,7 +28157,7 @@ __metadata: languageName: node linkType: hard -"fsevents@patch:fsevents@^2.3.2#~builtin, fsevents@patch:fsevents@~2.3.2#~builtin": +"fsevents@patch:fsevents@^2.3.2#~builtin, fsevents@patch:fsevents@~2.3.2#~builtin, fsevents@patch:fsevents@~2.3.3#~builtin": version: 2.3.3 resolution: "fsevents@patch:fsevents@npm%3A2.3.3#~builtin::version=2.3.3&hash=df0bf1" dependencies: @@ -28351,22 +28496,23 @@ __metadata: languageName: node linkType: hard -"glob@npm:^10.2.2, glob@npm:^10.3.10, glob@npm:^10.3.7": - version: 10.3.10 - resolution: "glob@npm:10.3.10" +"glob@npm:^10.0.0, glob@npm:^10.2.2, glob@npm:^10.3.10, glob@npm:^10.4.1": + version: 10.4.5 + resolution: "glob@npm:10.4.5" dependencies: foreground-child: ^3.1.0 - jackspeak: ^2.3.5 - minimatch: ^9.0.1 - minipass: ^5.0.0 || ^6.0.2 || ^7.0.0 - path-scurry: ^1.10.1 + jackspeak: ^3.1.2 + minimatch: ^9.0.4 + minipass: ^7.1.2 + package-json-from-dist: ^1.0.0 + path-scurry: ^1.11.1 bin: glob: dist/esm/bin.mjs - checksum: 4f2fe2511e157b5a3f525a54092169a5f92405f24d2aed3142f4411df328baca13059f4182f1db1bf933e2c69c0bd89e57ae87edd8950cba8c7ccbe84f721cf3 + checksum: 0bc725de5e4862f9f387fd0f2b274baf16850dcd2714502ccf471ee401803997983e2c05590cb65f9675a3c6f2a58e7a53f9e365704108c6ad3cbf1d60934c4a languageName: node linkType: hard -"glob@npm:^8.0.0, glob@npm:^8.0.1, glob@npm:^8.0.3, glob@npm:^8.1.0": +"glob@npm:^8.0.1, glob@npm:^8.0.3, glob@npm:^8.1.0": version: 8.1.0 resolution: "glob@npm:8.1.0" dependencies: @@ -29384,13 +29530,13 @@ __metadata: languageName: node linkType: hard -"https-proxy-agent@npm:7.0.4, https-proxy-agent@npm:^7.0.0, https-proxy-agent@npm:^7.0.1, https-proxy-agent@npm:^7.0.2": - version: 7.0.4 - resolution: "https-proxy-agent@npm:7.0.4" +"https-proxy-agent@npm:7.0.5, https-proxy-agent@npm:^7.0.0, https-proxy-agent@npm:^7.0.1, https-proxy-agent@npm:^7.0.2": + version: 7.0.5 + resolution: "https-proxy-agent@npm:7.0.5" dependencies: agent-base: ^7.0.2 debug: 4 - checksum: daaab857a967a2519ddc724f91edbbd388d766ff141b9025b629f92b9408fc83cee8a27e11a907aede392938e9c398e240d643e178408a59e4073539cde8cfe9 + checksum: 2e1a28960f13b041a50702ee74f240add8e75146a5c37fc98f1960f0496710f6918b3a9fe1e5aba41e50f58e6df48d107edd9c405c5f0d73ac260dabf2210857 languageName: node linkType: hard @@ -29442,11 +29588,11 @@ __metadata: linkType: hard "husky@npm:^9.0.0": - version: 9.1.5 - resolution: "husky@npm:9.1.5" + version: 9.1.6 + resolution: "husky@npm:9.1.6" bin: husky: bin.js - checksum: c240018e852666dc12a93ca84751f1440bdf436468ba872c7b7b3cee54f5f1d7b4222a117988b27ca437093efdeb128778897ab0e409361336676a2c3012c8a7 + checksum: 421ccd8850378231aaefd70dbe9e4f1549b84ffe3a6897f93a202242bbc04e48bd498169aef43849411105d9fcf7c192b757d42661e28d06b934a609a4eb8771 languageName: node linkType: hard @@ -29500,6 +29646,13 @@ __metadata: languageName: node linkType: hard +"idb-keyval@npm:5.0.2": + version: 5.0.2 + resolution: "idb-keyval@npm:5.0.2" + checksum: 64ce4049fcfa9ffc8ddd23897a59278bd60420bcaff88ca653c63b725f8d6228a956bd7f474cea21befedd5abdb1bc8058ca1db5a12c4145605291dadadedbf1 + languageName: node + linkType: hard + "identity-obj-proxy@npm:3.0.0": version: 3.0.0 resolution: "identity-obj-proxy@npm:3.0.0" @@ -30064,12 +30217,12 @@ __metadata: languageName: node linkType: hard -"is-core-module@npm:^2.1.0, is-core-module@npm:^2.13.0, is-core-module@npm:^2.13.1": - version: 2.13.1 - resolution: "is-core-module@npm:2.13.1" +"is-core-module@npm:^2.13.0, is-core-module@npm:^2.15.1": + version: 2.15.1 + resolution: "is-core-module@npm:2.15.1" dependencies: - hasown: ^2.0.0 - checksum: 256559ee8a9488af90e4bad16f5583c6d59e92f0742e9e8bb4331e758521ee86b810b93bae44f390766ffbc518a0488b18d9dab7da9a5ff997d499efc9403f7c + hasown: ^2.0.2 + checksum: df134c168115690724b62018c37b2f5bba0d5745fa16960b329c5a00883a8bea6a5632fdb1e3efcce237c201826ba09f93197b7cd95577ea56b0df335be23633 languageName: node linkType: hard @@ -30267,7 +30420,7 @@ __metadata: languageName: node linkType: hard -"is-nan@npm:^1.2.1": +"is-nan@npm:^1.3.2": version: 1.3.2 resolution: "is-nan@npm:1.3.2" dependencies: @@ -30495,7 +30648,7 @@ __metadata: languageName: node linkType: hard -"is-stream@npm:^2.0.0": +"is-stream@npm:^2.0.0, is-stream@npm:^2.0.1": version: 2.0.1 resolution: "is-stream@npm:2.0.1" checksum: b8e05ccdf96ac330ea83c12450304d4a591f9958c11fd17bed240af8d5ffe08aedafa4c0f4cfccd4d28dc9d4d129daca1023633d5c11601a6cbc77521f6fae66 @@ -30862,16 +31015,16 @@ __metadata: languageName: node linkType: hard -"jackspeak@npm:^2.3.5": - version: 2.3.6 - resolution: "jackspeak@npm:2.3.6" +"jackspeak@npm:^3.1.2": + version: 3.4.3 + resolution: "jackspeak@npm:3.4.3" dependencies: "@isaacs/cliui": ^8.0.2 "@pkgjs/parseargs": ^0.11.0 dependenciesMeta: "@pkgjs/parseargs": optional: true - checksum: 57d43ad11eadc98cdfe7496612f6bbb5255ea69fe51ea431162db302c2a11011642f50cfad57288bd0aea78384a0612b16e131944ad8ecd09d619041c8531b54 + checksum: be31027fc72e7cc726206b9f560395604b82e0fddb46c4cbf9f97d049bcef607491a5afc0699612eaa4213ca5be8fd3e1e7cd187b3040988b65c9489838a7c00 languageName: node linkType: hard @@ -31441,7 +31594,7 @@ __metadata: languageName: node linkType: hard -"jose@npm:^4.15.5": +"jose@npm:^4.15.9": version: 4.15.9 resolution: "jose@npm:4.15.9" checksum: 41abe1c99baa3cf8a78ebbf93da8f8e50e417b7a26754c4afa21865d87527b8ac2baf66de2c5f6accc3f7d7158658dae7364043677236ea1d07895b040097f15 @@ -32247,8 +32400,8 @@ __metadata: linkType: hard "knip@npm:^5.0.0": - version: 5.27.5 - resolution: "knip@npm:5.27.5" + version: 5.30.6 + resolution: "knip@npm:5.30.6" dependencies: "@nodelib/fs.walk": 1.2.8 "@snyk/github-codeowners": 1.1.0 @@ -32261,7 +32414,7 @@ __metadata: picocolors: ^1.0.0 picomatch: ^4.0.1 pretty-ms: ^9.0.0 - smol-toml: ^1.1.4 + smol-toml: ^1.3.0 strip-json-comments: 5.0.1 summary: 2.1.0 zod: ^3.22.4 @@ -32272,16 +32425,7 @@ __metadata: bin: knip: bin/knip.js knip-bun: bin/knip-bun.js - checksum: a348806f33c211246a28f7f353f48c6dca74e483b7b3883132a4bc166516805ad3089f66e32d3a15e3085516d145fcd58a051948c9853ba5e4052ab0630cf957 - languageName: node - linkType: hard - -"koa-compose@npm:^3.0.0": - version: 3.2.1 - resolution: "koa-compose@npm:3.2.1" - dependencies: - any-promise: ^1.1.0 - checksum: ff8e5fc0348455acf751179c6c613eb030a5fac6406d3b49ae9e00460b7ee8770db3ef62633fd3db0306cd4a6d2a0b5152399ebd5bb5e684418f9eeeb251c2de + checksum: 9820761248882926789bdf3cf8014a32e695d94bdabc335b4b637bceaeec7922358b67027b46aa5f7f2af10460027d0d33be407d48db76e50c8d1dd8dfca95ce languageName: node linkType: hard @@ -32292,45 +32436,44 @@ __metadata: languageName: node linkType: hard -"koa-convert@npm:^1.2.0": - version: 1.2.0 - resolution: "koa-convert@npm:1.2.0" +"koa-convert@npm:^2.0.0": + version: 2.0.0 + resolution: "koa-convert@npm:2.0.0" dependencies: co: ^4.6.0 - koa-compose: ^3.0.0 - checksum: a33944dbda4ed87565985f5b37ba1122a012db872724b216b6fd8f9176d4bba42c4a9bf3c129330e45f6474d28f50ca0ed28d41b9bccd2ab5d36d6436cf0d676 + koa-compose: ^4.1.0 + checksum: 7385b3391995f59c1312142e110d5dff677f9850dbfbcf387cd36a7b0af03b5d26e82b811eb9bb008b4f3e661cdab1f8817596e46b1929da2cf6e97a2f7456ed languageName: node linkType: hard -"koa@npm:2.11.0": - version: 2.11.0 - resolution: "koa@npm:2.11.0" +"koa@npm:2.15.3": + version: 2.15.3 + resolution: "koa@npm:2.15.3" dependencies: accepts: ^1.3.5 cache-content-type: ^1.0.0 content-disposition: ~0.5.2 content-type: ^1.0.4 - cookies: ~0.8.0 - debug: ~3.1.0 + cookies: ~0.9.0 + debug: ^4.3.2 delegates: ^1.0.0 - depd: ^1.1.2 + depd: ^2.0.0 destroy: ^1.0.4 encodeurl: ^1.0.2 - error-inject: ^1.0.0 escape-html: ^1.0.3 fresh: ~0.5.2 http-assert: ^1.3.0 http-errors: ^1.6.3 is-generator-function: ^1.0.7 koa-compose: ^4.1.0 - koa-convert: ^1.2.0 + koa-convert: ^2.0.0 on-finished: ^2.3.0 only: ~0.0.2 parseurl: ^1.3.2 statuses: ^1.5.0 type-is: ^1.6.16 vary: ^1.1.2 - checksum: b08e1aea03e70fe4ff6e35dee9f9e979e8608461ee1002f6e8dd72f45fc49404873888ea9a3aab2904e24bf43522df7c601033522f4151189e4055e87f94a979 + checksum: 7c3537443b1a588cf5c3e5554b914ff2bad510323d22b41861d5e0c97d47e9c5997965f303ede8be8bd83d309a4eea1f82cd45d35d6838bc21bb1bb6a90d5d25 languageName: node linkType: hard @@ -32717,20 +32860,6 @@ __metadata: languageName: node linkType: hard -"lodash.difference@npm:^4.5.0": - version: 4.5.0 - resolution: "lodash.difference@npm:4.5.0" - checksum: ecee276aa578f300e79350805a14a51be8d1f12b3c1389a19996d8ab516f814211a5f65c68331571ecdad96522b863ccc484b55504ce8c9947212a29f8857d5a - languageName: node - linkType: hard - -"lodash.flatten@npm:^4.4.0": - version: 4.4.0 - resolution: "lodash.flatten@npm:4.4.0" - checksum: 0ac34a393d4b795d4b7421153d27c13ae67e08786c9cbb60ff5b732210d46f833598eee3fb3844bb10070e8488efe390ea53bb567377e0cb47e9e630bf0811cb - languageName: node - linkType: hard - "lodash.flattendeep@npm:^4.0.0": version: 4.4.0 resolution: "lodash.flattendeep@npm:4.4.0" @@ -32815,13 +32944,6 @@ __metadata: languageName: node linkType: hard -"lodash.isplainobject@npm:^4.0.6": - version: 4.0.6 - resolution: "lodash.isplainobject@npm:4.0.6" - checksum: 29c6351f281e0d9a1d58f1a4c8f4400924b4c79f18dfc4613624d7d54784df07efaff97c1ff2659f3e085ecf4fff493300adc4837553104cef2634110b0d5337 - languageName: node - linkType: hard - "lodash.isstring@npm:^4.0.1": version: 4.0.1 resolution: "lodash.isstring@npm:4.0.1" @@ -32878,13 +33000,6 @@ __metadata: languageName: node linkType: hard -"lodash.union@npm:^4.6.0": - version: 4.6.0 - resolution: "lodash.union@npm:4.6.0" - checksum: 1514dc6508b2614ec071a6470f36eb7a70f69bf1abb6d55bdfdc21069635a4517783654b28504c0f025059a7598d37529766888e6d5902b8ab28b712228f7b2a - languageName: node - linkType: hard - "lodash.uniq@npm:^4.5.0": version: 4.5.0 resolution: "lodash.uniq@npm:4.5.0" @@ -33054,10 +33169,10 @@ __metadata: languageName: node linkType: hard -"lru-cache@npm:^10.0.0, lru-cache@npm:^10.0.1, lru-cache@npm:^9.1.1 || ^10.0.0": - version: 10.2.0 - resolution: "lru-cache@npm:10.2.0" - checksum: eee7ddda4a7475deac51ac81d7dd78709095c6fa46e8350dc2d22462559a1faa3b81ed931d5464b13d48cbd7e08b46100b6f768c76833912bc444b99c37e25db +"lru-cache@npm:^10.0.0, lru-cache@npm:^10.0.1, lru-cache@npm:^10.2.0": + version: 10.4.3 + resolution: "lru-cache@npm:10.4.3" + checksum: 6476138d2125387a6d20f100608c2583d415a4f64a0fecf30c9e2dda976614f09cad4baa0842447bd37dd459a7bd27f57d9d8f8ce558805abd487c583f3d774a languageName: node linkType: hard @@ -33096,13 +33211,6 @@ __metadata: languageName: node linkType: hard -"lru-cache@npm:^8.0.0": - version: 8.0.5 - resolution: "lru-cache@npm:8.0.5" - checksum: 87d72196d8f46e8299c4ab576ed2ec8a07e3cbef517dc9874399c0b2470bd9bf62aacec3b67f84ed6d74aaa1ef31636d048edf996f76248fd17db72bfb631609 - languageName: node - linkType: hard - "lru-cache@npm:^9.0.0": version: 9.1.2 resolution: "lru-cache@npm:9.1.2" @@ -33119,6 +33227,13 @@ __metadata: languageName: node linkType: hard +"lru.min@npm:^1.0.0": + version: 1.1.0 + resolution: "lru.min@npm:1.1.0" + checksum: c03dcc83f031387f254856bccc8418daff716b79b67886eceb110e3af57f593f752821a7b019ea382f8f48927767ddb1869087586f4bfc5bf9c90674ca80dfa2 + languageName: node + linkType: hard + "lru_map@npm:^0.3.3": version: 0.3.3 resolution: "lru_map@npm:0.3.3" @@ -33285,6 +33400,13 @@ __metadata: languageName: node linkType: hard +"markdown-escape@npm:^2.0.0": + version: 2.0.0 + resolution: "markdown-escape@npm:2.0.0" + checksum: 74c66d817636ac5f6a275fdc79ecb1e208d907ca85289d660b515256fbc3e380eb18d29b6bbbd6a77968ee4fb5872d40ecf31e52bc9f17855bb01bb723569fa0 + languageName: node + linkType: hard + "markdown-it@npm:^12.2.0": version: 12.3.2 resolution: "markdown-it@npm:12.3.2" @@ -33664,14 +33786,7 @@ __metadata: languageName: node linkType: hard -"merge-descriptors@npm:1.0.1": - version: 1.0.1 - resolution: "merge-descriptors@npm:1.0.1" - checksum: 5abc259d2ae25bb06d19ce2b94a21632583c74e2a9109ee1ba7fd147aa7362b380d971e0251069f8b3eb7d48c21ac839e21fa177b335e82c76ec172e30c31a26 - languageName: node - linkType: hard - -"merge-descriptors@npm:^1.0.1": +"merge-descriptors@npm:1.0.3, merge-descriptors@npm:^1.0.1": version: 1.0.3 resolution: "merge-descriptors@npm:1.0.3" checksum: 52117adbe0313d5defa771c9993fe081e2d2df9b840597e966aadafde04ae8d0e3da46bac7ca4efc37d4d2b839436582659cd49c6a43eacb3fe3050896a105d1 @@ -34256,7 +34371,7 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^9.0.0, minimatch@npm:^9.0.1, minimatch@npm:^9.0.3, minimatch@npm:^9.0.4, minimatch@npm:^9.0.5": +"minimatch@npm:^9.0.0, minimatch@npm:^9.0.3, minimatch@npm:^9.0.4, minimatch@npm:^9.0.5": version: 9.0.5 resolution: "minimatch@npm:9.0.5" dependencies: @@ -34265,6 +34380,15 @@ __metadata: languageName: node linkType: hard +"minimatch@npm:~3.0.3": + version: 3.0.8 + resolution: "minimatch@npm:3.0.8" + dependencies: + brace-expansion: ^1.1.7 + checksum: 850cca179cad715133132693e6963b0db64ab0988c4d211415b087fc23a3e46321e2c5376a01bf5623d8782aba8bdf43c571e2e902e51fdce7175c7215c29f8b + languageName: node + linkType: hard + "minimist@npm:^1.2.0, minimist@npm:^1.2.3, minimist@npm:^1.2.5, minimist@npm:^1.2.6, minimist@npm:^1.2.8": version: 1.2.8 resolution: "minimist@npm:1.2.8" @@ -34397,10 +34521,10 @@ __metadata: languageName: node linkType: hard -"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3": - version: 7.0.4 - resolution: "minipass@npm:7.0.4" - checksum: 87585e258b9488caf2e7acea242fd7856bbe9a2c84a7807643513a338d66f368c7d518200ad7b70a508664d408aa000517647b2930c259a8b1f9f0984f344a21 +"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3, minipass@npm:^7.1.2": + version: 7.1.2 + resolution: "minipass@npm:7.1.2" + checksum: 2bfd325b95c555f2b4d2814d49325691c7bee937d753814861b0b49d5edcda55cbbf22b6b6a60bb91eddac8668771f03c5ff647dcd9d0f798e9548b9cdc46ee3 languageName: node linkType: hard @@ -34580,8 +34704,8 @@ __metadata: linkType: hard "msw@npm:^1.0.0, msw@npm:^1.2.1, msw@npm:^1.3.0, msw@npm:^1.3.1": - version: 1.3.3 - resolution: "msw@npm:1.3.3" + version: 1.3.4 + resolution: "msw@npm:1.3.4" dependencies: "@mswjs/cookies": ^0.2.2 "@mswjs/interceptors": ^0.17.10 @@ -34609,41 +34733,39 @@ __metadata: optional: true bin: msw: cli/index.js - checksum: cb3fda1519485f219d36c4e5ac1e1190ffe77dab66121c88cb9db0bace1ecb5a45c83db49e68e7c688b330ce43eed17d00939e09812dc710c0d4b3e59925730c + checksum: 57646ecb831e98f00387e60bad4d535e426d406ae2645340e59500c219059be225f1f02a5ff21aee9daeb7a8bdde922a00fb82930781d27e3f3fdaf6b292c25f languageName: node linkType: hard "msw@npm:^2.0.0, msw@npm:^2.0.8": - version: 2.4.2 - resolution: "msw@npm:2.4.2" + version: 2.4.9 + resolution: "msw@npm:2.4.9" dependencies: "@bundled-es-modules/cookie": ^2.0.0 "@bundled-es-modules/statuses": ^1.0.1 "@bundled-es-modules/tough-cookie": ^0.1.6 "@inquirer/confirm": ^3.0.0 - "@mswjs/interceptors": ^0.29.0 + "@mswjs/interceptors": ^0.35.8 "@open-draft/until": ^2.1.0 "@types/cookie": ^0.6.0 "@types/statuses": ^2.0.4 chalk: ^4.1.2 + graphql: ^16.8.1 headers-polyfill: ^4.0.2 is-node-process: ^1.2.0 outvariant: ^1.4.2 - path-to-regexp: ^6.2.0 + path-to-regexp: ^6.3.0 strict-event-emitter: ^0.5.1 type-fest: ^4.9.0 yargs: ^17.7.2 peerDependencies: - graphql: ">= 16.8.x" typescript: ">= 4.8.x" peerDependenciesMeta: - graphql: - optional: true typescript: optional: true bin: msw: cli/index.js - checksum: 13ea882de674ba4a4eafe261b1fa4ed0e885bc021286730a9d6454bff3688e79265d752c826b4b4536ece728eda3cae19a5ea30495bf51bdfa1caff43893bedf + checksum: add5a614ce58f5e75c65afcb59b76d0d807b9103b7fb3aaf23efd6ebd82d79415ecd9bc55dd48bcc4c31ec7ce196a75ace46d94224f0a80567c89a190e367ba8 languageName: node linkType: hard @@ -34702,19 +34824,19 @@ __metadata: linkType: hard "mysql2@npm:^3.0.0": - version: 3.11.0 - resolution: "mysql2@npm:3.11.0" + version: 3.11.3 + resolution: "mysql2@npm:3.11.3" dependencies: aws-ssl-profiles: ^1.1.1 denque: ^2.1.0 generate-function: ^2.3.1 iconv-lite: ^0.6.3 long: ^5.2.1 - lru-cache: ^8.0.0 + lru.min: ^1.0.0 named-placeholders: ^1.1.3 seq-queue: ^0.0.5 sqlstring: ^2.3.2 - checksum: 0a3e80c95ca9e26821bc11658cbd065704d5f07f76efd952fc84115cc28f8a0100f14646fb3dd577f28831b8d6d2bfe0ef46fd4273ba5dcbfbeabb311302874d + checksum: ae62b5b997da429a33f0762158db965d22daece0030e75ac8e822b0b342ad082fa5f1ead87d922d0ba93595e9d5491036916ef91457c762517f25f41afa6e2d9 languageName: node linkType: hard @@ -35106,8 +35228,8 @@ __metadata: linkType: hard "node-mocks-http@npm:^1.0.0": - version: 1.15.1 - resolution: "node-mocks-http@npm:1.15.1" + version: 1.16.0 + resolution: "node-mocks-http@npm:1.16.0" dependencies: "@types/express": ^4.17.21 "@types/node": "*" @@ -35121,7 +35243,7 @@ __metadata: parseurl: ^1.3.3 range-parser: ^1.2.0 type-is: ^1.6.18 - checksum: f6e64065abf0e1fbb6c4b954646d96fa77d4e6cd705f1c883e7147d192efed76a1e98aa2cafee77c299ba74e2563be75315cacc421527bb97917a5a48a242bbb + checksum: 21ccf1ecaaa6ee0f7c061a7063f59d59c9793a485a907c09c83ff73b12f205ef87537022a4ba8ad937d07454ee0450290093d4a66a4df21e7e8b3696d23e1a7d languageName: node linkType: hard @@ -35203,8 +35325,8 @@ __metadata: linkType: hard "nodemon@npm:^3.0.1": - version: 3.1.4 - resolution: "nodemon@npm:3.1.4" + version: 3.1.7 + resolution: "nodemon@npm:3.1.7" dependencies: chokidar: ^3.5.2 debug: ^4 @@ -35218,7 +35340,7 @@ __metadata: undefsafe: ^2.0.5 bin: nodemon: bin/nodemon.js - checksum: 3f003fc2c7bdaba559108320f188b7cb063220455e5da218ff3bf4f7468ad7059852da6e35a52b8c690cc27f6e36a433a9ad1f1bdb8096ec1ee3d930629cbeca + checksum: c500ac2feb278ddb187049ac8ede6423c1fb074cc3dabf74882568d5e93401293c10039e184a9d1bfc617c983ddb432437d396b421926914d04ebba671a7d8b8 languageName: node linkType: hard @@ -35545,7 +35667,7 @@ __metadata: languageName: node linkType: hard -"object-is@npm:^1.0.1, object-is@npm:^1.1.5": +"object-is@npm:^1.1.5": version: 1.1.6 resolution: "object-is@npm:1.1.6" dependencies: @@ -35585,7 +35707,7 @@ __metadata: languageName: node linkType: hard -"object.fromentries@npm:^2.0.7, object.fromentries@npm:^2.0.8": +"object.fromentries@npm:^2.0.8": version: 2.0.8 resolution: "object.fromentries@npm:2.0.8" dependencies: @@ -35597,19 +35719,18 @@ __metadata: languageName: node linkType: hard -"object.groupby@npm:^1.0.1": - version: 1.0.1 - resolution: "object.groupby@npm:1.0.1" +"object.groupby@npm:^1.0.3": + version: 1.0.3 + resolution: "object.groupby@npm:1.0.3" dependencies: - call-bind: ^1.0.2 - define-properties: ^1.2.0 - es-abstract: ^1.22.1 - get-intrinsic: ^1.2.1 - checksum: d7959d6eaaba358b1608066fc67ac97f23ce6f573dc8fc661f68c52be165266fcb02937076aedb0e42722fdda0bdc0bbf74778196ac04868178888e9fd3b78b5 + call-bind: ^1.0.7 + define-properties: ^1.2.1 + es-abstract: ^1.23.2 + checksum: 0d30693ca3ace29720bffd20b3130451dca7a56c612e1926c0a1a15e4306061d84410bdb1456be2656c5aca53c81b7a3661eceaa362db1bba6669c2c9b6d1982 languageName: node linkType: hard -"object.values@npm:^1.1.6, object.values@npm:^1.1.7, object.values@npm:^1.2.0": +"object.values@npm:^1.1.6, object.values@npm:^1.2.0": version: 1.2.0 resolution: "object.values@npm:1.2.0" dependencies: @@ -35826,14 +35947,14 @@ __metadata: linkType: hard "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.5 - resolution: "openid-client@npm:5.6.5" + version: 5.7.0 + resolution: "openid-client@npm:5.7.0" dependencies: - jose: ^4.15.5 + jose: ^4.15.9 lru-cache: ^6.0.0 object-hash: ^2.2.0 oidc-token-hash: ^5.0.3 - checksum: 2240079f761173b10635ce5fefbac04b6820f54e00d588ab2afdddb6c0f0ab6568e663cf1ab6a4a2297fbdbb73e42d78b8190f91dba7e1b80d287b2127fcbc7c + checksum: 63fc76918fc12f3d6e1456a0b170f417defccf6820acb4581ffc226cb8c9a18d50f76f0982d7a00cce2896c732eb2a6361ad6ea04b127b2603e56408b680ef9c languageName: node linkType: hard @@ -35912,10 +36033,10 @@ __metadata: languageName: node linkType: hard -"outvariant@npm:^1.2.1, outvariant@npm:^1.4.0, outvariant@npm:^1.4.2": - version: 1.4.2 - resolution: "outvariant@npm:1.4.2" - checksum: 5d9e2b3edb1cc8be9cbfc1c8c97e8b05137c4384bbfc56e0a465de26c5d2f023e65732ddcda9d46599b06d667fbc0de32c30d2ecd11f6f3f43bcf8ce0d320918 +"outvariant@npm:^1.2.1, outvariant@npm:^1.4.0, outvariant@npm:^1.4.2, outvariant@npm:^1.4.3": + version: 1.4.3 + resolution: "outvariant@npm:1.4.3" + checksum: 4a3551fb2b45309e585eebf88bad094dbe56ac6d3a28d59dd2e4050b431aa2beb6097a0763fce3cd82ca0f077026f380a9b60fffc306aaf430141421e7a7b6ed languageName: node linkType: hard @@ -36114,6 +36235,13 @@ __metadata: languageName: node linkType: hard +"package-json-from-dist@npm:^1.0.0": + version: 1.0.0 + resolution: "package-json-from-dist@npm:1.0.0" + checksum: ac706ec856a5a03f5261e4e48fa974f24feb044d51f84f8332e2af0af04fbdbdd5bbbfb9cbbe354190409bc8307c83a9e38c6672c3c8855f709afb0006a009ea + languageName: node + linkType: hard + "package-json@npm:^6.3.0": version: 6.5.0 resolution: "package-json@npm:6.5.0" @@ -36442,17 +36570,6 @@ __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" @@ -36541,27 +36658,27 @@ __metadata: languageName: node linkType: hard -"path-parse@npm:^1.0.6, path-parse@npm:^1.0.7": +"path-parse@npm:^1.0.7": version: 1.0.7 resolution: "path-parse@npm:1.0.7" checksum: 49abf3d81115642938a8700ec580da6e830dde670be21893c62f4e10bd7dd4c3742ddc603fe24f898cba7eb0c6bc1777f8d9ac14185d34540c6d4d80cd9cae8a languageName: node linkType: hard -"path-scurry@npm:^1.10.1": - version: 1.10.1 - resolution: "path-scurry@npm:1.10.1" +"path-scurry@npm:^1.11.1": + version: 1.11.1 + resolution: "path-scurry@npm:1.11.1" dependencies: - lru-cache: ^9.1.1 || ^10.0.0 + lru-cache: ^10.2.0 minipass: ^5.0.0 || ^6.0.2 || ^7.0.0 - checksum: e2557cff3a8fb8bc07afdd6ab163a92587884f9969b05bbbaf6fe7379348bfb09af9ed292af12ed32398b15fb443e81692047b786d1eeb6d898a51eb17ed7d90 + checksum: 890d5abcd593a7912dcce7cf7c6bf7a0b5648e3dee6caf0712c126ca0a65c7f3d7b9d769072a4d1baf370f61ce493ab5b038d59988688e0c5f3f646ee3c69023 languageName: node linkType: hard -"path-to-regexp@npm:0.1.7": - version: 0.1.7 - resolution: "path-to-regexp@npm:0.1.7" - checksum: 69a14ea24db543e8b0f4353305c5eac6907917031340e5a8b37df688e52accd09e3cebfe1660b70d76b6bd89152f52183f28c74813dbf454ba1a01c82a38abce +"path-to-regexp@npm:0.1.10": + version: 0.1.10 + resolution: "path-to-regexp@npm:0.1.10" + checksum: ab7a3b7a0b914476d44030340b0a65d69851af2a0f33427df1476100ccb87d409c39e2182837a96b98fb38c4ef2ba6b87bdad62bb70a2c153876b8061760583c languageName: node linkType: hard @@ -36572,10 +36689,10 @@ __metadata: languageName: node linkType: hard -"path-to-regexp@npm:3.2.0": - version: 3.2.0 - resolution: "path-to-regexp@npm:3.2.0" - checksum: c3d35cda3b26d9e604d789b9a1764bb9845f53ca8009d5809356b4677a3c064b0f01117a05a5b4b77bafd5ae002a82592e3f3495e885c22961f8b1dab8bd6ae7 +"path-to-regexp@npm:3.3.0": + version: 3.3.0 + resolution: "path-to-regexp@npm:3.3.0" + checksum: bb249d08804f7961dd44fb175466c900b893c56e909db8e2a66ec12b9d9a964af269eb7a50892c933f52b47315953dfdb4279639fbce20977c3625a9ef3055fe languageName: node linkType: hard @@ -36588,10 +36705,17 @@ __metadata: languageName: node linkType: hard -"path-to-regexp@npm:^6.2.0, path-to-regexp@npm:^6.2.1, path-to-regexp@npm:^6.2.2": - version: 6.2.2 - resolution: "path-to-regexp@npm:6.2.2" - checksum: b7b0005c36f5099f9ed1fb20a820d2e4ed1297ffe683ea1d678f5e976eb9544f01debb281369dabdc26da82e6453901bf71acf2c7ed14b9243536c2a45286c33 +"path-to-regexp@npm:^6.2.0, path-to-regexp@npm:^6.3.0": + version: 6.3.0 + resolution: "path-to-regexp@npm:6.3.0" + checksum: eca78602e6434a1b6799d511d375ec044e8d7e28f5a48aa5c28d57d8152fb52f3fc62fb1cfc5dfa2198e1f041c2a82ed14043d75740a2fe60e91b5089a153250 + languageName: node + linkType: hard + +"path-to-regexp@npm:^8.0.0": + version: 8.1.0 + resolution: "path-to-regexp@npm:8.1.0" + checksum: 982b784f8dff704c04c79dc3e26d51d2dba340e6bd513a8bdc48559a8543d730547d9d2355122166171eb509236e7524802ed643f8a77d527e12c69ffc74f97f languageName: node linkType: hard @@ -36671,10 +36795,10 @@ __metadata: languageName: node linkType: hard -"pg-connection-string@npm:^2.3.0, pg-connection-string@npm:^2.5.0, pg-connection-string@npm:^2.6.4": - version: 2.6.4 - resolution: "pg-connection-string@npm:2.6.4" - checksum: 2c1d2ac1add1f93076f1594d217a0980f79add05dc48de6363e1c550827c78a6ee3e3b5420da9c54858f6b678cdb348aed49732ee68158b6cdb70f1d1c748cf9 +"pg-connection-string@npm:^2.3.0, pg-connection-string@npm:^2.5.0, pg-connection-string@npm:^2.7.0": + version: 2.7.0 + resolution: "pg-connection-string@npm:2.7.0" + checksum: 68015a8874b7ca5dad456445e4114af3d2602bac2fdb8069315ecad0ff9660ec93259b9af7186606529ac4f6f72a06831e6f20897a689b16cc7fda7ca0e247fd languageName: node linkType: hard @@ -36699,19 +36823,19 @@ __metadata: languageName: node linkType: hard -"pg-pool@npm:^3.6.2": - version: 3.6.2 - resolution: "pg-pool@npm:3.6.2" +"pg-pool@npm:^3.7.0": + version: 3.7.0 + resolution: "pg-pool@npm:3.7.0" peerDependencies: pg: ">=8.0" - checksum: 5ceee4320a35fce08777d085d50a30a1253574257e1e7c5c56c915056d387d340f797115580c8d90a46691f83c39a9b4da1fd810d9ad168cc455c79c289116f4 + checksum: 66fc1a5ad0e17b72671b9a2cd4c7a856fb08d3cb82da7af0b322590ada23127ac591111e855740405fde4f06c9de888abe9f3aa685ed6038c3232578e1fce8cf languageName: node linkType: hard -"pg-protocol@npm:*, pg-protocol@npm:^1.6.1": - version: 1.6.1 - resolution: "pg-protocol@npm:1.6.1" - checksum: cce3f72cc4bdc04db9ce3fa38b2c45b745f0a95a925847b349087f52c02c4d51b7c74d8867e40639699d0c7609accfaffb6b1d221b3268d2bdc4bb8d6a2995a3 +"pg-protocol@npm:*, pg-protocol@npm:^1.7.0": + version: 1.7.0 + resolution: "pg-protocol@npm:1.7.0" + checksum: 2dba740f6fc4b7f9761682c4c42d183b444292cdc7638b373f5247ec995c8199c369953343479281da3c41611fe34130a80c8668348d49a399c164f802f76be2 languageName: node linkType: hard @@ -36744,13 +36868,13 @@ __metadata: linkType: hard "pg@npm:^8.11.3, pg@npm:^8.9.0": - version: 8.12.0 - resolution: "pg@npm:8.12.0" + version: 8.13.0 + resolution: "pg@npm:8.13.0" dependencies: pg-cloudflare: ^1.1.1 - pg-connection-string: ^2.6.4 - pg-pool: ^3.6.2 - pg-protocol: ^1.6.1 + pg-connection-string: ^2.7.0 + pg-pool: ^3.7.0 + pg-protocol: ^1.7.0 pg-types: ^2.1.0 pgpass: 1.x peerDependencies: @@ -36761,7 +36885,7 @@ __metadata: peerDependenciesMeta: pg-native: optional: true - checksum: 8450b61c787f360e22182aa853548f834f13622714868d0789a60f63743d66ae28930cdca0ef0251bfc89b04679e9074c1398f172c2937bf59b5a360337f4149 + checksum: 81560755ff4ee62b71bf1204dd696f66451574d1db56cbd5aa514ce91c6474030ee8078461b3cb85cce8d2f185be5846e0a7a707a818f5e2e3fb198a7ea795ea languageName: node linkType: hard @@ -36959,27 +37083,27 @@ __metadata: languageName: node linkType: hard -"playwright-core@npm:1.46.1": - version: 1.46.1 - resolution: "playwright-core@npm:1.46.1" +"playwright-core@npm:1.47.2": + version: 1.47.2 + resolution: "playwright-core@npm:1.47.2" bin: playwright-core: cli.js - checksum: 99a03f97d76af02b0565aa09758eb03427e13497ef7e9e9044fd1184a5f050e7545a517dd7ad8988a68b3ea76e2ba0d411f81e410b1cb29f5ac9161c49689822 + checksum: c06109a08dd672a92eb048ce7c9a1451ed701e62ff78f0d67c67ee6b06c88f0dc5422c2a7bb26e5fca05840e2adba154a25ca988e56f76c233affe61f42453a3 languageName: node linkType: hard -"playwright@npm:1.46.1": - version: 1.46.1 - resolution: "playwright@npm:1.46.1" +"playwright@npm:1.47.2": + version: 1.47.2 + resolution: "playwright@npm:1.47.2" dependencies: fsevents: 2.3.2 - playwright-core: 1.46.1 + playwright-core: 1.47.2 dependenciesMeta: fsevents: optional: true bin: playwright: cli.js - checksum: 9e721cb27f919cd92ea8c7461f4a8e97e32eade9da036baa4747f483549e33a8d77585f51e228d6639a1e28a76b0c1d59ca0a05dbd07aa3cfe427be7aaeb9ec8 + checksum: 41ec99d62c9d7282a3d0dd2444892a379be2f4c61e9045a0b1cfc5897796747d220df5af11c6a7515c56c82df02a1025a46a5da7abc17485b4e981e133588261 languageName: node linkType: hard @@ -37446,14 +37570,14 @@ __metadata: languageName: node linkType: hard -"postcss@npm:^8.1.0, postcss@npm:^8.4.27, postcss@npm:^8.4.33": - version: 8.4.41 - resolution: "postcss@npm:8.4.41" +"postcss@npm:^8.1.0, postcss@npm:^8.4.33, postcss@npm:^8.4.43": + version: 8.4.47 + resolution: "postcss@npm:8.4.47" dependencies: nanoid: ^3.3.7 - picocolors: ^1.0.1 - source-map-js: ^1.2.0 - checksum: f865894929eb0f7fc2263811cc853c13b1c75103028b3f4f26df777e27b201f1abe21cb4aa4c2e901c80a04f6fb325ee22979688fe55a70e2ea82b0a517d3b6f + picocolors: ^1.1.0 + source-map-js: ^1.2.1 + checksum: f78440a9d8f97431dd2ab1ab8e1de64f12f3eff38a3d8d4a33919b96c381046a314658d2de213a5fa5eb296b656de76a3ec269fdea27f16d5ab465b916a0f52c languageName: node linkType: hard @@ -37985,16 +38109,7 @@ __metadata: languageName: node linkType: hard -"qs@npm:6.11.0": - version: 6.11.0 - resolution: "qs@npm:6.11.0" - dependencies: - side-channel: ^1.0.4 - checksum: 6e1f29dd5385f7488ec74ac7b6c92f4d09a90408882d0c208414a34dd33badc1a621019d4c799a3df15ab9b1d0292f97c1dd71dc7c045e69f81a8064e5af7297 - languageName: node - linkType: hard - -"qs@npm:^6.10.1, qs@npm:^6.10.2, qs@npm:^6.11.0, qs@npm:^6.11.2, qs@npm:^6.12.2, qs@npm:^6.9.1, qs@npm:^6.9.4": +"qs@npm:6.13.0, qs@npm:^6.10.1, qs@npm:^6.10.2, qs@npm:^6.11.0, qs@npm:^6.11.2, qs@npm:^6.12.2, qs@npm:^6.9.1, qs@npm:^6.9.4": version: 6.13.0 resolution: "qs@npm:6.13.0" dependencies: @@ -38745,15 +38860,15 @@ __metadata: linkType: hard "react-router-dom@npm:^6.3.0": - version: 6.26.1 - resolution: "react-router-dom@npm:6.26.1" + version: 6.26.2 + resolution: "react-router-dom@npm:6.26.2" dependencies: - "@remix-run/router": 1.19.1 - react-router: 6.26.1 + "@remix-run/router": 1.19.2 + react-router: 6.26.2 peerDependencies: react: ">=16.8" react-dom: ">=16.8" - checksum: e393ab62e3239585d44d598e6bc8cc138ac8353f3dc46262680c6ad83dea35773662ada2f1c353921a05c37d1f369c0a2cb097848a6210689e9b6076550c7de0 + checksum: d65507ffb920e03212bf32d294eb608df7f6cb85c26ec24f88e8f2a2718ffedeccfe0a8e1bc8d23561d6d796f8af61a8bed4a9a0541fbfd83096ecc93eaad5c7 languageName: node linkType: hard @@ -38768,14 +38883,14 @@ __metadata: languageName: node linkType: hard -"react-router@npm:6.26.1, react-router@npm:^6.3.0": - version: 6.26.1 - resolution: "react-router@npm:6.26.1" +"react-router@npm:6.26.2, react-router@npm:^6.3.0": + version: 6.26.2 + resolution: "react-router@npm:6.26.2" dependencies: - "@remix-run/router": 1.19.1 + "@remix-run/router": 1.19.2 peerDependencies: react: ">=16.8" - checksum: 810949febc1bf2a6f8dd65f4c0532a2413d0532df462b3e78891aec81dca5a088d387b32c9922cde52bd9770f32263590993cab2383c94ddc1cdb50a20fd7adc + checksum: 80ad9db316ad11761b7d5de0c9ed61f3e4345d8984929db802d37d9a6a2174b42a952b0b01ba45833b00f8cd7b5755f198d2f0a8a62a486ebbfbacabbe379be5 languageName: node linkType: hard @@ -38955,7 +39070,7 @@ __metadata: languageName: node linkType: hard -"react@npm:^16.13.1 || ^17.0.0 || ^18.0.0, react@npm:^18.0.2": +"react@npm:^18.0.2": version: 18.3.1 resolution: "react@npm:18.3.1" dependencies: @@ -39028,16 +39143,16 @@ __metadata: languageName: node linkType: hard -"readable-stream@npm:^4.3.0": - version: 4.4.2 - resolution: "readable-stream@npm:4.4.2" +"readable-stream@npm:^4.0.0, readable-stream@npm:^4.3.0": + version: 4.5.2 + resolution: "readable-stream@npm:4.5.2" dependencies: abort-controller: ^3.0.0 buffer: ^6.0.3 events: ^3.3.0 process: ^0.11.10 string_decoder: ^1.3.0 - checksum: 6f4063763dbdb52658d22d3f49ca976420e1fbe16bbd241f744383715845350b196a2f08b8d6330f8e219153dff34b140aeefd6296da828e1041a7eab1f20d5e + checksum: c4030ccff010b83e4f33289c535f7830190773e274b3fcb6e2541475070bdfd69c98001c3b0cb78763fc00c8b62f514d96c2b10a8bd35d5ce45203a25fa1d33a languageName: node linkType: hard @@ -39419,15 +39534,15 @@ __metadata: linkType: hard "replace-in-file@npm:^7.1.0": - version: 7.1.0 - resolution: "replace-in-file@npm:7.1.0" + version: 7.2.0 + resolution: "replace-in-file@npm:7.2.0" dependencies: chalk: ^4.1.2 glob: ^8.1.0 yargs: ^17.7.2 bin: replace-in-file: bin/cli.js - checksum: 2ed61bd0cf0752b18775b52342ad36f4ee6c806f7eca0b0d085c23bafe0cb4828e4ec8f59058bde6b67d2ed5ac51e1681284f586089b58b966e2489712830db0 + checksum: 773cfff187a404a293ed0f8ee433fa6c14230b96c506455bd3a880a217b3a3ec31791b8acb3e32a629286e6d8a7825b94255f443d0873c52cb7593b05cda52ba languageName: node linkType: hard @@ -39559,7 +39674,7 @@ __metadata: languageName: node linkType: hard -"resolve@npm:1.22.8, resolve@npm:^1.1.6, resolve@npm:^1.14.2, resolve@npm:^1.17.0, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.22.1, resolve@npm:^1.22.4, resolve@npm:~1.22.1": +"resolve@npm:1.22.8, resolve@npm:^1.1.6, resolve@npm:^1.14.2, resolve@npm:^1.17.0, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.22.1, resolve@npm:^1.22.4, resolve@npm:~1.22.1, resolve@npm:~1.22.2": version: 1.22.8 resolution: "resolve@npm:1.22.8" dependencies: @@ -39585,17 +39700,7 @@ __metadata: languageName: node linkType: hard -"resolve@npm:~1.19.0": - version: 1.19.0 - resolution: "resolve@npm:1.19.0" - dependencies: - is-core-module: ^2.1.0 - path-parse: ^1.0.6 - checksum: a05b356e47b85ad3613d9e2a39a824f3c27f4fcad9c9ff6c7cc71a2e314c5904a90ab37481ad0069d03cab9eaaac6eb68aca1bc3355fdb05f1045cd50e2aacea - languageName: node - linkType: hard - -"resolve@patch:resolve@1.22.8#~builtin, resolve@patch:resolve@^1.1.6#~builtin, resolve@patch:resolve@^1.14.2#~builtin, resolve@patch:resolve@^1.17.0#~builtin, resolve@patch:resolve@^1.19.0#~builtin, resolve@patch:resolve@^1.20.0#~builtin, resolve@patch:resolve@^1.22.1#~builtin, resolve@patch:resolve@^1.22.4#~builtin, resolve@patch:resolve@~1.22.1#~builtin": +"resolve@patch:resolve@1.22.8#~builtin, resolve@patch:resolve@^1.1.6#~builtin, resolve@patch:resolve@^1.14.2#~builtin, resolve@patch:resolve@^1.17.0#~builtin, resolve@patch:resolve@^1.19.0#~builtin, resolve@patch:resolve@^1.20.0#~builtin, resolve@patch:resolve@^1.22.1#~builtin, resolve@patch:resolve@^1.22.4#~builtin, resolve@patch:resolve@~1.22.1#~builtin, resolve@patch:resolve@~1.22.2#~builtin": version: 1.22.8 resolution: "resolve@patch:resolve@npm%3A1.22.8#~builtin::version=1.22.8&hash=c3c19d" dependencies: @@ -39621,16 +39726,6 @@ __metadata: languageName: node linkType: hard -"resolve@patch:resolve@~1.19.0#~builtin": - version: 1.19.0 - resolution: "resolve@patch:resolve@npm%3A1.19.0#~builtin::version=1.19.0&hash=c3c19d" - dependencies: - is-core-module: ^2.1.0 - path-parse: ^1.0.6 - checksum: 2443b94d347e6946c87c85faf13071f605e609e0b54784829b0ed2b917d050bfc1cbaf4ecc6453f224cfa7d0c5dcd97cbb273454cd210bee68e4af15c1a5abc9 - languageName: node - linkType: hard - "responselike@npm:^1.0.2": version: 1.0.2 resolution: "responselike@npm:1.0.2" @@ -39752,17 +39847,6 @@ __metadata: languageName: node linkType: hard -"rimraf@npm:^5.0.5": - version: 5.0.5 - resolution: "rimraf@npm:5.0.5" - dependencies: - glob: ^10.3.7 - bin: - rimraf: dist/esm/bin.mjs - checksum: d66eef829b2e23b16445f34e73d75c7b7cf4cbc8834b04720def1c8f298eb0753c3d76df77325fad79d0a2c60470525d95f89c2475283ad985fd7441c32732d1 - languageName: node - linkType: hard - "rimraf@npm:~2.6.2": version: 2.6.3 resolution: "rimraf@npm:2.6.3" @@ -39900,41 +39984,27 @@ __metadata: languageName: node linkType: hard -"rollup@npm:^3.27.1": - version: 3.29.4 - resolution: "rollup@npm:3.29.4" +"rollup@npm:^4.0.0, rollup@npm:^4.20.0": + version: 4.22.5 + resolution: "rollup@npm:4.22.5" dependencies: - fsevents: ~2.3.2 - dependenciesMeta: - fsevents: - optional: true - bin: - rollup: dist/bin/rollup - checksum: 8bb20a39c8d91130825159c3823eccf4dc2295c9a0a5c4ed851a5bf2167dbf24d9a29f23461a54c955e5506395e6cc188eafc8ab0e20399d7489fb33793b184e - languageName: node - linkType: hard - -"rollup@npm:^4.0.0": - version: 4.21.2 - resolution: "rollup@npm:4.21.2" - dependencies: - "@rollup/rollup-android-arm-eabi": 4.21.2 - "@rollup/rollup-android-arm64": 4.21.2 - "@rollup/rollup-darwin-arm64": 4.21.2 - "@rollup/rollup-darwin-x64": 4.21.2 - "@rollup/rollup-linux-arm-gnueabihf": 4.21.2 - "@rollup/rollup-linux-arm-musleabihf": 4.21.2 - "@rollup/rollup-linux-arm64-gnu": 4.21.2 - "@rollup/rollup-linux-arm64-musl": 4.21.2 - "@rollup/rollup-linux-powerpc64le-gnu": 4.21.2 - "@rollup/rollup-linux-riscv64-gnu": 4.21.2 - "@rollup/rollup-linux-s390x-gnu": 4.21.2 - "@rollup/rollup-linux-x64-gnu": 4.21.2 - "@rollup/rollup-linux-x64-musl": 4.21.2 - "@rollup/rollup-win32-arm64-msvc": 4.21.2 - "@rollup/rollup-win32-ia32-msvc": 4.21.2 - "@rollup/rollup-win32-x64-msvc": 4.21.2 - "@types/estree": 1.0.5 + "@rollup/rollup-android-arm-eabi": 4.22.5 + "@rollup/rollup-android-arm64": 4.22.5 + "@rollup/rollup-darwin-arm64": 4.22.5 + "@rollup/rollup-darwin-x64": 4.22.5 + "@rollup/rollup-linux-arm-gnueabihf": 4.22.5 + "@rollup/rollup-linux-arm-musleabihf": 4.22.5 + "@rollup/rollup-linux-arm64-gnu": 4.22.5 + "@rollup/rollup-linux-arm64-musl": 4.22.5 + "@rollup/rollup-linux-powerpc64le-gnu": 4.22.5 + "@rollup/rollup-linux-riscv64-gnu": 4.22.5 + "@rollup/rollup-linux-s390x-gnu": 4.22.5 + "@rollup/rollup-linux-x64-gnu": 4.22.5 + "@rollup/rollup-linux-x64-musl": 4.22.5 + "@rollup/rollup-win32-arm64-msvc": 4.22.5 + "@rollup/rollup-win32-ia32-msvc": 4.22.5 + "@rollup/rollup-win32-x64-msvc": 4.22.5 + "@types/estree": 1.0.6 fsevents: ~2.3.2 dependenciesMeta: "@rollup/rollup-android-arm-eabi": @@ -39973,7 +40043,7 @@ __metadata: optional: true bin: rollup: dist/bin/rollup - checksum: ac83ca15495dd00d6b910e87e7f5f2c480d36977471ec11e3d207089e0aa207d34fc9bd0270f7804b268a7f7473d3bc6b65bccf474fbd1d1826a70bde2741894 + checksum: 894b3d428b5a7f1db2245f50622ce65a3ad8f754265dd1da7dce133e39b315516dbcbac51e4fe100b44d59b168bac3f36ebaeb836fc9f7057d4972f44497d046 languageName: node linkType: hard @@ -40003,7 +40073,7 @@ __metadata: cross-env: ^7.0.0 e2e-test: "workspace:*" eslint: ^8.6.0 - eslint-plugin-notice: ^0.9.10 + eslint-plugin-notice: ^1.0.0 eslint-plugin-react: ^7.28.0 eslint-plugin-testing-library: ^6.0.0 fs-extra: ^11.2.0 @@ -40339,6 +40409,15 @@ __metadata: languageName: node linkType: hard +"semver@npm:7.6.3, semver@npm:^7.1.1, semver@npm:^7.1.2, semver@npm:^7.1.3, semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8, semver@npm:^7.5.2, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0": + version: 7.6.3 + resolution: "semver@npm:7.6.3" + bin: + semver: bin/semver.js + checksum: 4110ec5d015c9438f322257b1c51fe30276e5f766a3f64c09edd1d7ea7118ecbc3f379f3b69032bacf13116dc7abc4ad8ce0d7e2bd642e26b0d271b56b61a7d8 + languageName: node + linkType: hard + "semver@npm:^5.5.0, semver@npm:^5.6.0": version: 5.7.2 resolution: "semver@npm:5.7.2" @@ -40357,18 +40436,9 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.1.1, semver@npm:^7.1.2, semver@npm:^7.1.3, semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8, semver@npm:^7.5.2, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0": - version: 7.6.3 - resolution: "semver@npm:7.6.3" - bin: - semver: bin/semver.js - checksum: 4110ec5d015c9438f322257b1c51fe30276e5f766a3f64c09edd1d7ea7118ecbc3f379f3b69032bacf13116dc7abc4ad8ce0d7e2bd642e26b0d271b56b61a7d8 - languageName: node - linkType: hard - -"send@npm:0.18.0": - version: 0.18.0 - resolution: "send@npm:0.18.0" +"send@npm:0.19.0": + version: 0.19.0 + resolution: "send@npm:0.19.0" dependencies: debug: 2.6.9 depd: 2.0.0 @@ -40383,7 +40453,7 @@ __metadata: on-finished: 2.4.1 range-parser: ~1.2.1 statuses: 2.0.1 - checksum: 74fc07ebb58566b87b078ec63e5a3e41ecd987e4272ba67b7467e86c6ad51bc6b0b0154133b6d8b08a2ddda360464f71382f7ef864700f34844a76c8027817a8 + checksum: 5ae11bd900c1c2575525e2aa622e856804e2f96a09281ec1e39610d089f53aa69e13fd8db84b52f001d0318cf4bb0b3b904ad532fc4c0014eb90d32db0cff55f languageName: node linkType: hard @@ -40452,15 +40522,15 @@ __metadata: languageName: node linkType: hard -"serve-static@npm:1.15.0": - version: 1.15.0 - resolution: "serve-static@npm:1.15.0" +"serve-static@npm:1.16.2": + version: 1.16.2 + resolution: "serve-static@npm:1.16.2" dependencies: - encodeurl: ~1.0.2 + encodeurl: ~2.0.0 escape-html: ~1.0.3 parseurl: ~1.3.3 - send: 0.18.0 - checksum: af57fc13be40d90a12562e98c0b7855cf6e8bd4c107fe9a45c212bf023058d54a1871b1c89511c3958f70626fff47faeb795f5d83f8cf88514dbaeb2b724464d + send: 0.19.0 + checksum: dffc52feb4cc5c68e66d0c7f3c1824d4e989f71050aefc9bd5f822a42c54c9b814f595fc5f2b717f4c7cc05396145f3e90422af31186a93f76cf15f707019759 languageName: node linkType: hard @@ -40831,10 +40901,10 @@ __metadata: languageName: node linkType: hard -"smol-toml@npm:^1.1.4": - version: 1.2.1 - resolution: "smol-toml@npm:1.2.1" - checksum: 12040dd8e38b6efb7a1572bfd803c6a7ac89b8d715d0614b024601165059ea3f4653dd5b87b601308dcefd20a26af8445e9be9888b52e0c4f24d1bfc6d2c4e84 +"smol-toml@npm:^1.3.0": + version: 1.3.0 + resolution: "smol-toml@npm:1.3.0" + checksum: 79e1db6b6cd32a13ad7602bfe1a02f20894fe599657a5cc2c8ffab7c3de4ba51f7426b701b513f9b859560918b36a63f7c73f7eaf6def8a1dc73db74ffd9b601 languageName: node linkType: hard @@ -40950,10 +41020,10 @@ __metadata: languageName: node linkType: hard -"source-map-js@npm:^1.2.0": - version: 1.2.0 - resolution: "source-map-js@npm:1.2.0" - checksum: 791a43306d9223792e84293b00458bf102a8946e7188f3db0e4e22d8d530b5f80a4ce468eb5ec0bf585443ad55ebbd630bf379c98db0b1f317fd902500217f97 +"source-map-js@npm:^1.2.1": + version: 1.2.1 + resolution: "source-map-js@npm:1.2.1" + checksum: 4eb0cd997cdf228bc253bcaff9340afeb706176e64868ecd20efbe6efea931465f43955612346d6b7318789e5265bdc419bc7669c1cebe3db0eb255f57efa76b languageName: node linkType: hard @@ -41883,31 +41953,30 @@ __metadata: languageName: node linkType: hard -"superagent@npm:^8.1.2": - version: 8.1.2 - resolution: "superagent@npm:8.1.2" +"superagent@npm:^9.0.1": + version: 9.0.2 + resolution: "superagent@npm:9.0.2" dependencies: component-emitter: ^1.3.0 cookiejar: ^2.1.4 debug: ^4.3.4 fast-safe-stringify: ^2.1.1 form-data: ^4.0.0 - formidable: ^2.1.2 + formidable: ^3.5.1 methods: ^1.1.2 mime: 2.6.0 qs: ^6.11.0 - semver: ^7.3.8 - checksum: f3601c5ccae34d5ba684a03703394b5d25931f4ae2e1e31a1de809f88a9400e997ece037f9accf148a21c408f950dc829db1e4e23576a7f9fe0efa79fd5c9d2f + checksum: f471461b21f034d844fd0aca332128d61e3afb75c2ee5950f3339f2a3b5ca8b23e2861224f19ad9b43f21c9184d28b7d9384af5a4fde64fdef479efdb15036db languageName: node linkType: hard -"supertest@npm:^6.1.3, supertest@npm:^6.1.6, supertest@npm:^6.2.4, supertest@npm:^6.3.3": - version: 6.3.4 - resolution: "supertest@npm:6.3.4" +"supertest@npm:^7.0.0": + version: 7.0.0 + resolution: "supertest@npm:7.0.0" dependencies: methods: ^1.1.2 - superagent: ^8.1.2 - checksum: 875c6fa7940f21e5be9bb646579cdb030d4057bf2da643e125e1f0480add1200395d2b17e10b8e54e1009efc63e047422501e9eb30e12828668498c0910f295f + superagent: ^9.0.1 + checksum: 974743aa511ec0f387135dfca05e378f6202366c81f0850dfbcc2c3d6fc690e856dda27e175c70db38510e21d87f331c0f62e1a942afea4c447953c647c26c8b languageName: node linkType: hard @@ -41938,7 +42007,7 @@ __metadata: languageName: node linkType: hard -"supports-color@npm:^8.0.0, supports-color@npm:^8.1.0, supports-color@npm:^8.1.1": +"supports-color@npm:^8.0.0, supports-color@npm:^8.1.0, supports-color@npm:^8.1.1, supports-color@npm:~8.1.1": version: 8.1.1 resolution: "supports-color@npm:8.1.1" dependencies: @@ -42111,9 +42180,9 @@ __metadata: languageName: node linkType: hard -"tar-fs@npm:^3.0.5": - version: 3.0.5 - resolution: "tar-fs@npm:3.0.5" +"tar-fs@npm:^3.0.6": + version: 3.0.6 + resolution: "tar-fs@npm:3.0.6" dependencies: bare-fs: ^2.1.1 bare-path: ^2.1.0 @@ -42124,7 +42193,7 @@ __metadata: optional: true bare-path: optional: true - checksum: e31c7e3e525fec0afecdec1cac58071809e396187725f2eba442f08a4c5649c8cd6b7ce25982f9a91bb0f055628df47c08177dd2ea4f5dafd3c22f42f8da8f00 + checksum: b4fa09c70f75caf05bf5cf87369cd2862f1ac5fb75c4ddf9d25d55999f7736a94b58ad679d384196cba837c5f5ff14086e060fafccef5474a16e2d3058ffa488 languageName: node linkType: hard @@ -42140,7 +42209,7 @@ __metadata: languageName: node linkType: hard -"tar-stream@npm:^2.0.0, tar-stream@npm:^2.0.1, tar-stream@npm:^2.1.4, tar-stream@npm:^2.2.0": +"tar-stream@npm:^2.0.0, tar-stream@npm:^2.0.1, tar-stream@npm:^2.1.4": version: 2.2.0 resolution: "tar-stream@npm:2.2.0" dependencies: @@ -42231,7 +42300,7 @@ __metadata: "@material-ui/icons": ^4.9.1 "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^15.0.0 + "@testing-library/react": ^16.0.0 "@testing-library/user-event": ^14.0.0 "@types/react": "*" "@types/react-dom": "*" @@ -42322,25 +42391,25 @@ __metadata: linkType: hard "testcontainers@npm:^10.0.0": - version: 10.8.2 - resolution: "testcontainers@npm:10.8.2" + version: 10.13.1 + resolution: "testcontainers@npm:10.13.1" dependencies: "@balena/dockerignore": ^1.0.2 - "@types/dockerode": ^3.3.24 - archiver: ^5.3.2 + "@types/dockerode": ^3.3.29 + archiver: ^7.0.1 async-lock: ^1.4.1 byline: ^5.0.0 - debug: ^4.3.4 - docker-compose: ^0.24.6 + debug: ^4.3.5 + docker-compose: ^0.24.8 dockerode: ^3.3.5 get-port: ^5.1.1 - node-fetch: ^2.7.0 proper-lockfile: ^4.1.2 properties-reader: ^2.3.0 ssh-remote-port-forward: ^1.0.4 - tar-fs: ^3.0.5 - tmp: ^0.2.1 - checksum: 3a97ad705c98abc5066577699be5e791090ef2a5c45fee3a203196fa09d0cb66c7709f6ae8168c025ed97a07f1f5f0676a34e748680514e732e90671720d34c6 + tar-fs: ^3.0.6 + tmp: ^0.2.3 + undici: ^5.28.4 + checksum: 5e2526f25574957a417fd8702c0b155dfd87ec6e55733c81be507b46e76e6df5ebcbed28b70b2a71339efae2c875b8341423885cf76df18b6be83a098010e3f5 languageName: node linkType: hard @@ -42500,12 +42569,10 @@ __metadata: languageName: node linkType: hard -"tmp@npm:^0.2.1": - version: 0.2.1 - resolution: "tmp@npm:0.2.1" - dependencies: - rimraf: ^3.0.0 - checksum: 8b1214654182575124498c87ca986ac53dc76ff36e8f0e0b67139a8d221eaecfdec108c0e6ec54d76f49f1f72ab9325500b246f562b926f85bcdfca8bf35df9e +"tmp@npm:^0.2.3": + version: 0.2.3 + resolution: "tmp@npm:0.2.3" + checksum: 73b5c96b6e52da7e104d9d44afb5d106bb1e16d9fa7d00dbeb9e6522e61b571fbdb165c756c62164be9a3bbe192b9b268c236d370a2a0955c7689cd2ae377b95 languageName: node linkType: hard @@ -42731,12 +42798,12 @@ __metadata: languageName: node linkType: hard -"ts-api-utils@npm:^1.0.1": - version: 1.0.3 - resolution: "ts-api-utils@npm:1.0.3" +"ts-api-utils@npm:^1.0.1, ts-api-utils@npm:^1.3.0": + version: 1.3.0 + resolution: "ts-api-utils@npm:1.3.0" peerDependencies: typescript: ">=4.2.0" - checksum: 441cc4489d65fd515ae6b0f4eb8690057add6f3b6a63a36073753547fb6ce0c9ea0e0530220a0b282b0eec535f52c4dfc315d35f8a4c9a91c0def0707a714ca6 + checksum: c746ddabfdffbf16cb0b0db32bb287236a19e583057f8649ee7c49995bb776e1d3ef384685181c11a1a480369e022ca97512cb08c517b2d2bd82c83754c97012 languageName: node linkType: hard @@ -42861,10 +42928,10 @@ __metadata: languageName: node linkType: hard -"tslib@npm:2.6.2, tslib@npm:^2.0.0, tslib@npm:^2.0.1, tslib@npm:^2.0.3, tslib@npm:^2.1.0, tslib@npm:^2.2.0, tslib@npm:^2.3.0, tslib@npm:^2.3.1, tslib@npm:^2.4.0, tslib@npm:^2.4.1, tslib@npm:^2.4.1 || ^1.9.3, tslib@npm:^2.5.0, tslib@npm:^2.6.0, tslib@npm:^2.6.2": - version: 2.6.2 - resolution: "tslib@npm:2.6.2" - checksum: 329ea56123005922f39642318e3d1f0f8265d1e7fcb92c633e0809521da75eeaca28d2cf96d7248229deb40e5c19adf408259f4b9640afd20d13aecc1430f3ad +"tslib@npm:2.7.0, tslib@npm:^2.0.0, tslib@npm:^2.0.1, tslib@npm:^2.0.3, tslib@npm:^2.1.0, tslib@npm:^2.2.0, tslib@npm:^2.3.0, tslib@npm:^2.3.1, tslib@npm:^2.4.0, tslib@npm:^2.4.1, tslib@npm:^2.4.1 || ^1.9.3, tslib@npm:^2.5.0, tslib@npm:^2.6.0, tslib@npm:^2.6.2": + version: 2.7.0 + resolution: "tslib@npm:2.7.0" + checksum: 1606d5c89f88d466889def78653f3aab0f88692e80bb2066d090ca6112ae250ec1cfa9dbfaab0d17b60da15a4186e8ec4d893801c67896b277c17374e36e1d28 languageName: node linkType: hard @@ -43130,41 +43197,31 @@ __metadata: languageName: node linkType: hard -"typescript-json-schema@npm:^0.63.0": - version: 0.63.0 - resolution: "typescript-json-schema@npm:0.63.0" +"typescript-json-schema@npm:^0.65.0": + version: 0.65.1 + resolution: "typescript-json-schema@npm:0.65.1" dependencies: "@types/json-schema": ^7.0.9 - "@types/node": ^16.9.2 + "@types/node": ^18.11.9 glob: ^7.1.7 path-equal: ^1.2.5 safe-stable-stringify: ^2.2.0 ts-node: ^10.9.1 - typescript: ~5.1.0 + typescript: ~5.5.0 yargs: ^17.1.1 bin: typescript-json-schema: bin/typescript-json-schema - checksum: 619ab7aece08e140ba9542c6378c335751dbff3994a23343d0af67786a0c1e682d532a436c1674ddb10bca3f34972ecac7ba529b66d0e9b3e00ca81defb3aa77 + checksum: f67af357d3ba7f7953124437f7d36e15ad4171c35b2db945a4b1b3c77114f35328825e9109a3b71150cfc2a1e942da589d956a065eb31eb1dfca6c67fa54e30f languageName: node linkType: hard -"typescript@npm:~5.0.4": - version: 5.0.4 - resolution: "typescript@npm:5.0.4" +"typescript@npm:5.4.2": + version: 5.4.2 + resolution: "typescript@npm:5.4.2" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 82b94da3f4604a8946da585f7d6c3025fff8410779e5bde2855ab130d05e4fd08938b9e593b6ebed165bda6ad9292b230984f10952cf82f0a0ca07bbeaa08172 - languageName: node - linkType: hard - -"typescript@npm:~5.1.0": - version: 5.1.6 - resolution: "typescript@npm:5.1.6" - bin: - tsc: bin/tsc - tsserver: bin/tsserver - checksum: b2f2c35096035fe1f5facd1e38922ccb8558996331405eb00a5111cc948b2e733163cc22fab5db46992aba7dd520fff637f2c1df4996ff0e134e77d3249a7350 + checksum: 96d80fde25a09bcb04d399082fb27a808a9e17c2111e43849d2aafbd642d835e4f4ef0de09b0ba795ec2a700be6c4c2c3f62bf4660c05404c948727b5bbfb32a languageName: node linkType: hard @@ -43178,23 +43235,23 @@ __metadata: languageName: node linkType: hard -"typescript@patch:typescript@~5.0.4#~builtin": - version: 5.0.4 - resolution: "typescript@patch:typescript@npm%3A5.0.4#~builtin::version=5.0.4&hash=b5f058" +"typescript@npm:~5.5.0": + version: 5.5.4 + resolution: "typescript@npm:5.5.4" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: d26b6ba97b6d163c55dbdffd9bbb4c211667ebebc743accfeb2c8c0154aace7afd097b51165a72a5bad2cf65a4612259344ff60f8e642362aa1695c760d303ac + checksum: b309040f3a1cd91c68a5a58af6b9fdd4e849b8c42d837b2c2e73f9a4f96a98c4f1ed398a9aab576ee0a4748f5690cf594e6b99dbe61de7839da748c41e6d6ca8 languageName: node linkType: hard -"typescript@patch:typescript@~5.1.0#~builtin": - version: 5.1.6 - resolution: "typescript@patch:typescript@npm%3A5.1.6#~builtin::version=5.1.6&hash=5da071" +"typescript@patch:typescript@5.4.2#~builtin": + version: 5.4.2 + resolution: "typescript@patch:typescript@npm%3A5.4.2#~builtin::version=5.4.2&hash=5adc0c" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: f53bfe97f7c8b2b6d23cf572750d4e7d1e0c5fff1c36d859d0ec84556a827b8785077bc27676bf7e71fae538e517c3ecc0f37e7f593be913d884805d931bc8be + checksum: 797ac213c03a19749181c745647b4cab03d13bf4b6b738b05a3426f46c6b540f908989e839d9b0c89d7a4ee2bdb50493b4d4898d4ef1c897c3e9d0b082e78a67 languageName: node linkType: hard @@ -43208,6 +43265,16 @@ __metadata: languageName: node linkType: hard +"typescript@patch:typescript@~5.5.0#~builtin": + version: 5.5.4 + resolution: "typescript@patch:typescript@npm%3A5.5.4#~builtin::version=5.5.4&hash=5adc0c" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: fc52962f31a5bcb716d4213bef516885e4f01f30cea797a831205fc9ef12b405a40561c40eae3127ab85ba1548e7df49df2bcdee6b84a94bfbe3a0d7eff16b14 + languageName: node + linkType: hard + "ua-parser-js@npm:^0.7.30": version: 0.7.33 resolution: "ua-parser-js@npm:0.7.33" @@ -43310,6 +43377,22 @@ __metadata: languageName: node linkType: hard +"undici-types@npm:~6.19.2": + version: 6.19.8 + resolution: "undici-types@npm:6.19.8" + checksum: de51f1b447d22571cf155dfe14ff6d12c5bdaec237c765085b439c38ca8518fc360e88c70f99469162bf2e14188a7b0bcb06e1ed2dc031042b984b0bb9544017 + languageName: node + linkType: hard + +"undici@npm:^5.28.4": + version: 5.28.4 + resolution: "undici@npm:5.28.4" + dependencies: + "@fastify/busboy": ^2.0.0 + checksum: a8193132d84540e4dc1895ecc8dbaa176e8a49d26084d6fbe48a292e28397cd19ec5d13bc13e604484e76f94f6e334b2bdc740d5f06a6e50c44072818d0c19f9 + languageName: node + linkType: hard + "uni-global@npm:^1.0.0": version: 1.0.0 resolution: "uni-global@npm:1.0.0" @@ -43808,7 +43891,7 @@ __metadata: languageName: node linkType: hard -"util@npm:^0.12.0, util@npm:^0.12.3, util@npm:^0.12.4": +"util@npm:^0.12.3, util@npm:^0.12.4, util@npm:^0.12.5": version: 0.12.5 resolution: "util@npm:0.12.5" dependencies: @@ -43957,13 +44040,6 @@ __metadata: languageName: node linkType: hard -"validator@npm:^13.7.0": - version: 13.7.0 - resolution: "validator@npm:13.7.0" - checksum: 2b83283de1222ca549a7ef57f46e8d49c6669213348db78b7045bce36a3b5843ff1e9f709ebf74574e06223461ee1f264f8cc9a26a0060a79a27de079d8286ef - languageName: node - linkType: hard - "value-or-promise@npm:1.0.11": version: 1.0.11 resolution: "value-or-promise@npm:1.0.11" @@ -44054,7 +44130,7 @@ __metadata: languageName: node linkType: hard -"vite-plugin-html@npm:^3.2.0": +"vite-plugin-html@npm:^3.2.2": version: 3.2.2 resolution: "vite-plugin-html@npm:3.2.2" dependencies: @@ -44088,19 +44164,20 @@ __metadata: languageName: node linkType: hard -"vite@npm:^4.4.9": - version: 4.5.3 - resolution: "vite@npm:4.5.3" +"vite@npm:^5.0.0": + version: 5.4.8 + resolution: "vite@npm:5.4.8" dependencies: - esbuild: ^0.18.10 - fsevents: ~2.3.2 - postcss: ^8.4.27 - rollup: ^3.27.1 + esbuild: ^0.21.3 + fsevents: ~2.3.3 + postcss: ^8.4.43 + rollup: ^4.20.0 peerDependencies: - "@types/node": ">= 14" + "@types/node": ^18.0.0 || >=20.0.0 less: "*" lightningcss: ^1.21.0 sass: "*" + sass-embedded: "*" stylus: "*" sugarss: "*" terser: ^5.4.0 @@ -44116,6 +44193,8 @@ __metadata: optional: true sass: optional: true + sass-embedded: + optional: true stylus: optional: true sugarss: @@ -44124,7 +44203,7 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: fd3f512ce48ca2a1fe60ad0376283b832de9272725fdbc65064ae9248f792de87b0f27a89573115e23e26784800daca329f8a9234d298ba6f60e808a9c63883c + checksum: b5686ff76a60d53092dc13a5c1e5627165226b8e3da7736931adf87bbe58d383bca386383cea134750108c2d42750c916db3f2314ac90a9477d693950145f140 languageName: node linkType: hard @@ -44282,9 +44361,9 @@ __metadata: languageName: node linkType: hard -"webpack-dev-middleware@npm:^7.1.0": - version: 7.2.1 - resolution: "webpack-dev-middleware@npm:7.2.1" +"webpack-dev-middleware@npm:^7.4.2": + version: 7.4.2 + resolution: "webpack-dev-middleware@npm:7.4.2" dependencies: colorette: ^2.0.10 memfs: ^4.6.0 @@ -44297,13 +44376,13 @@ __metadata: peerDependenciesMeta: webpack: optional: true - checksum: bb8c75f7ceabc13ee2c3bc9648190e05a0a8c6d40b940ef72b09ea858a63d16bcb434b49995f1025125a1c3a1c8d40274beb5d26ef2fb1458b19e7f6fe3a91fe + checksum: 39314ec5e4468d177dd61fb51af87ec097e920fe0f0dc101e1bf71796740a7e49fd4f7f939cf91e130232714d6d2fffd948d72dc65dec10f87ac30339929f018 languageName: node linkType: hard "webpack-dev-server@npm:^5.0.0": - version: 5.0.4 - resolution: "webpack-dev-server@npm:5.0.4" + version: 5.1.0 + resolution: "webpack-dev-server@npm:5.1.0" dependencies: "@types/bonjour": ^3.5.13 "@types/connect-history-api-fallback": ^1.5.4 @@ -44318,8 +44397,7 @@ __metadata: colorette: ^2.0.10 compression: ^1.7.4 connect-history-api-fallback: ^2.0.0 - default-gateway: ^6.0.3 - express: ^4.17.3 + express: ^4.19.2 graceful-fs: ^4.2.6 html-entities: ^2.4.0 http-proxy-middleware: ^2.0.3 @@ -44327,14 +44405,13 @@ __metadata: launch-editor: ^2.6.1 open: ^10.0.3 p-retry: ^6.2.0 - rimraf: ^5.0.5 schema-utils: ^4.2.0 selfsigned: ^2.4.1 serve-index: ^1.9.1 sockjs: ^0.3.24 spdy: ^4.0.2 - webpack-dev-middleware: ^7.1.0 - ws: ^8.16.0 + webpack-dev-middleware: ^7.4.2 + ws: ^8.18.0 peerDependencies: webpack: ^5.0.0 peerDependenciesMeta: @@ -44344,7 +44421,7 @@ __metadata: optional: true bin: webpack-dev-server: bin/webpack-dev-server.js - checksum: b3535d01e8d895f4ce6d74b5f76e29398b712476216cd6d459365e5cc2f2fb1e49240aef6c23b2b943b04dbf768d7d18301af3eb064038bde4e11d03c241202d + checksum: 3128fffeb76b97cc4c506607f81bb644437f6961cf310915e22ecaf79a45c185893d7fc8e1844183fb44827061ec2f3d321e937840f02d4989959a09551a8e35 languageName: node linkType: hard @@ -44735,7 +44812,7 @@ __metadata: languageName: node linkType: hard -"ws@npm:*, ws@npm:^8.11.0, ws@npm:^8.12.0, ws@npm:^8.13.0, ws@npm:^8.14.2, ws@npm:^8.16.0, ws@npm:^8.17.0, ws@npm:^8.8.0": +"ws@npm:*, ws@npm:^8.11.0, ws@npm:^8.12.0, ws@npm:^8.13.0, ws@npm:^8.17.1, ws@npm:^8.18.0, ws@npm:^8.8.0": version: 8.18.0 resolution: "ws@npm:8.18.0" peerDependencies: @@ -44750,21 +44827,6 @@ __metadata: languageName: node linkType: hard -"ws@npm:8.14.2": - version: 8.14.2 - resolution: "ws@npm:8.14.2" - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: ">=5.0.2" - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - checksum: 3ca0dad26e8cc6515ff392b622a1467430814c463b3368b0258e33696b1d4bed7510bc7030f7b72838b9fdeb8dbd8839cbf808367d6aae2e1d668ce741d4308b - languageName: node - linkType: hard - "ws@npm:8.17.1": version: 8.17.1 resolution: "ws@npm:8.17.1" @@ -44818,13 +44880,14 @@ __metadata: languageName: node linkType: hard -"xml-crypto@npm:^3.0.1": - version: 3.2.0 - resolution: "xml-crypto@npm:3.2.0" +"xml-crypto@npm:^6.0.0": + version: 6.0.0 + resolution: "xml-crypto@npm:6.0.0" dependencies: - "@xmldom/xmldom": ^0.8.8 - xpath: 0.0.32 - checksum: 6c4974a7518307ea006dcfc1405f61c6738b45574b4d9d1e62f53b602bfcf894d34017f99d618f26f67c40a5e6d78e6228116ded2768b2ca5b2df5c8bf7774b7 + "@xmldom/is-dom-node": ^1.0.1 + "@xmldom/xmldom": ^0.8.10 + xpath: ^0.0.33 + checksum: 1c679ed66e4cea6309602cf8d536973f7832b69bd400310802365af972c9a0261c9a456c64015e0e92b8c93f168f9f13a355bbbd04d1219ca61c2a3f544d1208 languageName: node linkType: hard @@ -44853,13 +44916,13 @@ __metadata: languageName: node linkType: hard -"xml2js@npm:^0.5.0": - version: 0.5.0 - resolution: "xml2js@npm:0.5.0" +"xml2js@npm:^0.6.2": + version: 0.6.2 + resolution: "xml2js@npm:0.6.2" dependencies: sax: ">=0.6.0" xmlbuilder: ~11.0.0 - checksum: 1aa71d62e5bc2d89138e3929b9ea46459157727759cbc62ef99484b778641c0cd21fb637696c052d901a22f82d092a3e740a16b4ce218e81ac59b933535124ea + checksum: 458a83806193008edff44562c0bdb982801d61ee7867ae58fd35fab781e69e17f40dfeb8fc05391a4648c9c54012066d3955fe5d993ffbe4dc63399023f32ac2 languageName: node linkType: hard @@ -44891,13 +44954,6 @@ __metadata: languageName: node linkType: hard -"xpath@npm:0.0.27": - version: 0.0.27 - resolution: "xpath@npm:0.0.27" - checksum: 51f45d211a9a552a8f6a12a474061e89bafb07e0aecd4bad18a557411feb975919c158e1a66e4ea0542198c6ed442481d9f709c625cca57b97aaedeaeded902e - languageName: node - linkType: hard - "xpath@npm:0.0.32": version: 0.0.32 resolution: "xpath@npm:0.0.32" @@ -44905,6 +44961,20 @@ __metadata: languageName: node linkType: hard +"xpath@npm:^0.0.33": + version: 0.0.33 + resolution: "xpath@npm:0.0.33" + checksum: 075cd553819302b9df0ae11526b666016ee286b72e0600a923c7565d847fcfa7ff195db3065ec86b9a12f1f81bfc82f1a316fc53442a8572c31582e87ccaec4a + languageName: node + linkType: hard + +"xpath@npm:^0.0.34": + version: 0.0.34 + resolution: "xpath@npm:0.0.34" + checksum: c10ae2b7be442460462e80a9ef79ca1c9b529abcf696ec3859cddd5a52b64b7e55a54c2c5352ac9c5d195939e2b3aefe708a7428780d7ec0ae7565257ab2a224 + languageName: node + linkType: hard + "xtend@npm:^4.0.0, xtend@npm:^4.0.2": version: 4.0.2 resolution: "xtend@npm:4.0.2" @@ -44995,11 +45065,11 @@ __metadata: linkType: hard "yaml@npm:^2.0.0, yaml@npm:^2.0.0-10, yaml@npm:^2.1.1, yaml@npm:^2.2.1, yaml@npm:^2.2.2, yaml@npm:^2.3.2, yaml@npm:^2.3.3, yaml@npm:~2.5.0": - version: 2.5.0 - resolution: "yaml@npm:2.5.0" + version: 2.5.1 + resolution: "yaml@npm:2.5.1" bin: yaml: bin.mjs - checksum: a116dca5c61641d9bf1f1016c6e71daeb1ed4915f5930ed237d45ab7a605aa5d92c332ff64879a6cd088cabede008c778774e3060ffeb4cd617d28088e4b2d83 + checksum: 31275223863fbd0b47ba9d2b248fbdf085db8d899e4ca43fff8a3a009497c5741084da6871d11f40e555d61360951c4c910b98216c1325d2c94753c0036d8172 languageName: node linkType: hard @@ -45181,23 +45251,6 @@ __metadata: languageName: node linkType: hard -"z-schema@npm:~5.0.2": - version: 5.0.2 - resolution: "z-schema@npm:5.0.2" - dependencies: - commander: ^2.7.1 - lodash.get: ^4.4.2 - lodash.isequal: ^4.5.0 - validator: ^13.7.0 - dependenciesMeta: - commander: - optional: true - bin: - z-schema: bin/z-schema - checksum: 084b2f16043ac0a892914ee29cc0b4fafd9338133eec0345cd6ced25e814f647fa67be1090ad5f606759c2c1f2f8c28127960ba187f437f1caf6fb8cd45d7336 - languageName: node - linkType: hard - "zen-observable@npm:^0.10.0": version: 0.10.0 resolution: "zen-observable@npm:0.10.0" @@ -45212,34 +45265,23 @@ __metadata: languageName: node linkType: hard -"zip-stream@npm:^4.1.0": - version: 4.1.0 - resolution: "zip-stream@npm:4.1.0" +"zip-stream@npm:^6.0.1": + version: 6.0.1 + resolution: "zip-stream@npm:6.0.1" dependencies: - archiver-utils: ^2.1.0 - compress-commons: ^4.1.0 - readable-stream: ^3.6.0 - checksum: 4a73da856738b0634700b52f4ab3fe0bf0a532bea6820ad962d0bda0163d2d5525df4859f89a7238e204a378384e12551985049790c1894c3ac191866e85887f - languageName: node - linkType: hard - -"zip-stream@npm:^5.0.1": - version: 5.0.1 - resolution: "zip-stream@npm:5.0.1" - dependencies: - archiver-utils: ^4.0.1 - compress-commons: ^5.0.1 - readable-stream: ^3.6.0 - checksum: 116cee5a2c1ecce7aa440b665470653f58ef56670c6aafa1b5491c9f9335992352145502af5fa865ac82f46336905e37fb7cbc649c2be72e2152c6b91802995c + archiver-utils: ^5.0.0 + compress-commons: ^6.0.2 + readable-stream: ^4.0.0 + checksum: aa5abd6a89590eadeba040afbc375f53337f12637e5e98330012a12d9886cde7a3ccc28bd91aafab50576035bbb1de39a9a316eecf2411c8b9009c9f94f0db27 languageName: node linkType: hard "zod-to-json-schema@npm:^3.20.4, zod-to-json-schema@npm:^3.21.4": - version: 3.23.2 - resolution: "zod-to-json-schema@npm:3.23.2" + version: 3.23.3 + resolution: "zod-to-json-schema@npm:3.23.3" peerDependencies: zod: ^3.23.3 - checksum: 6dc87a6045f5dcca23d009f2e212f3f5dbb790b1e80488162560359f30aa2babb6a2ea8d44953e9193c6c923300c58e5ae157a9dc089d0bcf5e2437b3158ca1b + checksum: 0d51cf64b54fd39e86434cd5d2239c2981808e6461d022e4c68a1dec67fff28ef2b7bb5733dfd40eb50d6ce6d252288f3989d67134fa81401c36469bb26f13ec languageName: node linkType: hard