diff --git a/.changeset/angry-cycles-call.md b/.changeset/angry-cycles-call.md new file mode 100644 index 0000000000..e8db20b701 --- /dev/null +++ b/.changeset/angry-cycles-call.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Preserve directory structure for CommonJS build output, just like ESM. This makes the build output more stable and easier to browse, and allows for more effective tree shaking and lazy imports. diff --git a/.changeset/calm-owls-move.md b/.changeset/calm-owls-move.md new file mode 100644 index 0000000000..bd7fb72508 --- /dev/null +++ b/.changeset/calm-owls-move.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli-node': patch +--- + +Added new `lockfile.getDependencyTreeHash(name)` utility. diff --git a/.changeset/chilled-melons-smash.md b/.changeset/chilled-melons-smash.md new file mode 100644 index 0000000000..ca8f02ff37 --- /dev/null +++ b/.changeset/chilled-melons-smash.md @@ -0,0 +1,20 @@ +--- +'@backstage/plugin-scaffolder-backend-module-github': patch +--- + +Add `github:branch-protection:create` scaffolder action to set branch protection on an existing repository. Example usage: + +```yaml +- id: set-branch-protection + name: Set Branch Protection + action: github:branch-protection:create + input: + repoUrl: 'github.com?repo=backstage&owner=backstage' + branch: master + enforceAdmins: true # default + requiredApprovingReviewCount: 1 # default + requireBranchesToBeUpToDate: true # default + requireCodeOwnerReviews: true + dismissStaleReviews: true + requiredConversationResolution: true +``` 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/crash-loop-baby.md b/.changeset/crash-loop-baby.md new file mode 100644 index 0000000000..4f629c7f92 --- /dev/null +++ b/.changeset/crash-loop-baby.md @@ -0,0 +1,6 @@ +--- +'@backstage/backend-app-api': patch +'@backstage/backend-defaults': patch +--- + +Plugin lifecycle shutdown hooks are now performed before root lifecycle shutdown hooks. diff --git a/.changeset/crash-loop-honey.md b/.changeset/crash-loop-honey.md new file mode 100644 index 0000000000..60f9f04600 --- /dev/null +++ b/.changeset/crash-loop-honey.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-defaults': patch +--- + +The database manager now attempts to close any database connections in a root lifecycle shutdown hook. diff --git a/.changeset/crash-loop-yeah.md b/.changeset/crash-loop-yeah.md new file mode 100644 index 0000000000..098bc01bae --- /dev/null +++ b/.changeset/crash-loop-yeah.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-defaults': patch +--- + +The task scheduler now attempts to abort any tasks if it detects that Backstage is being shut down. 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/create-app-1728387650.md b/.changeset/create-app-1728387650.md new file mode 100644 index 0000000000..b50d431d4b --- /dev/null +++ b/.changeset/create-app-1728387650.md @@ -0,0 +1,5 @@ +--- +'@backstage/create-app': patch +--- + +Bumped create-app version. diff --git a/.changeset/cuddly-stingrays-smell.md b/.changeset/cuddly-stingrays-smell.md new file mode 100644 index 0000000000..5a8a8ac236 --- /dev/null +++ b/.changeset/cuddly-stingrays-smell.md @@ -0,0 +1,18 @@ +--- +'@backstage/plugin-auth-backend-module-cloudflare-access-provider': patch +'@backstage/plugin-auth-backend-module-vmware-cloud-provider': patch +'@backstage/plugin-auth-backend-module-atlassian-provider': patch +'@backstage/plugin-auth-backend-module-bitbucket-provider': patch +'@backstage/plugin-auth-backend-module-microsoft-provider': patch +'@backstage/plugin-auth-backend-module-onelogin-provider': patch +'@backstage/plugin-auth-backend-module-aws-alb-provider': patch +'@backstage/plugin-auth-backend-module-gcp-iap-provider': patch +'@backstage/plugin-auth-backend-module-github-provider': patch +'@backstage/plugin-auth-backend-module-gitlab-provider': patch +'@backstage/plugin-auth-backend-module-google-provider': patch +'@backstage/plugin-auth-backend-module-oauth2-provider': patch +'@backstage/plugin-auth-backend-module-oidc-provider': patch +'@backstage/plugin-auth-backend-module-okta-provider': patch +--- + +Updated configuration schema to include the new `allowedDomains` option for the `emailLocalPartMatchingUserEntityName` sign-in resolver. diff --git a/.changeset/curly-tomatoes-reply.md b/.changeset/curly-tomatoes-reply.md new file mode 100644 index 0000000000..386e2b6109 --- /dev/null +++ b/.changeset/curly-tomatoes-reply.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend': patch +--- + +handle step.if: false 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-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/dependabot-a3fd85a.md b/.changeset/dependabot-a3fd85a.md new file mode 100644 index 0000000000..8ff0c9dfa2 --- /dev/null +++ b/.changeset/dependabot-a3fd85a.md @@ -0,0 +1,7 @@ +--- +'@backstage/backend-app-api': patch +'@backstage/backend-defaults': patch +'@backstage/backend-test-utils': patch +--- + +build(deps): bump `cookie` from 0.6.0 to 0.7.0 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/eight-clocks-complain.md b/.changeset/eight-clocks-complain.md new file mode 100644 index 0000000000..b7044481ac --- /dev/null +++ b/.changeset/eight-clocks-complain.md @@ -0,0 +1,5 @@ +--- +'@backstage/eslint-plugin': patch +--- + +Exclude `@material-ui/data-grid` diff --git a/.changeset/eighty-mice-turn.md b/.changeset/eighty-mice-turn.md new file mode 100644 index 0000000000..cec3835641 --- /dev/null +++ b/.changeset/eighty-mice-turn.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +Add tests for the `TemplateEditorToolbarTemplatesMenu` component. diff --git a/.changeset/eleven-beds-play.md b/.changeset/eleven-beds-play.md new file mode 100644 index 0000000000..fd51922cb4 --- /dev/null +++ b/.changeset/eleven-beds-play.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-search-backend': patch +--- + +Fix to schema to allow arbitrary query parameters. 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/flat-seals-type.md b/.changeset/flat-seals-type.md new file mode 100644 index 0000000000..9574c74fc9 --- /dev/null +++ b/.changeset/flat-seals-type.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-node': patch +--- + +Added a new `allowedDomains` option for the common `emailLocalPartMatchingUserEntityName` sign-in resolver. diff --git a/.changeset/fluffy-dolphins-battle.md b/.changeset/fluffy-dolphins-battle.md new file mode 100644 index 0000000000..b247d549e5 --- /dev/null +++ b/.changeset/fluffy-dolphins-battle.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +Add tests for the new pages header navigation. diff --git a/.changeset/friendly-coins-approve.md b/.changeset/friendly-coins-approve.md new file mode 100644 index 0000000000..71a8240089 --- /dev/null +++ b/.changeset/friendly-coins-approve.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-app-backend': patch +--- + +Fixed unexpected behaviour where configuration supplied with `APP_CONFIG_*` environment variables where not filtered by the configuration schema. 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/great-eagles-repair.md b/.changeset/great-eagles-repair.md new file mode 100644 index 0000000000..886fb5df7a --- /dev/null +++ b/.changeset/great-eagles-repair.md @@ -0,0 +1,5 @@ +--- +'@backstage/frontend-test-utils': patch +--- + +Added an `ApiMock`, analogous to `ServiceMock` from the backend test utils. 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-cooks-sort.md b/.changeset/green-cooks-sort.md new file mode 100644 index 0000000000..51dd86ac2e --- /dev/null +++ b/.changeset/green-cooks-sort.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog': minor +--- + +Adding negation keyword for entity filtering diff --git a/.changeset/healthy-shoes-judge.md b/.changeset/healthy-shoes-judge.md new file mode 100644 index 0000000000..eebd89a23d --- /dev/null +++ b/.changeset/healthy-shoes-judge.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend-module-bitbucket-server': patch +--- + +Add `reviewers` input parameter to `publish:bitbucketServer:pull-request` diff --git a/.changeset/healthy-years-search.md b/.changeset/healthy-years-search.md new file mode 100644 index 0000000000..a613d11eea --- /dev/null +++ b/.changeset/healthy-years-search.md @@ -0,0 +1,7 @@ +--- +'@backstage/plugin-catalog-react': minor +--- + +Add catalog service mocks under the `/testUtils` subpath export. + +You can now use e.g. `const catalog = catalogApiMock.mock()` in your test and then do assertions on `catalog.getEntities` without awkward type casting. 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/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/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/lovely-bees-walk.md b/.changeset/lovely-bees-walk.md new file mode 100644 index 0000000000..223acf1769 --- /dev/null +++ b/.changeset/lovely-bees-walk.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-node': patch +--- + +Documentation for the `testUtils` named export diff --git a/.changeset/neat-geckos-end.md b/.changeset/neat-geckos-end.md new file mode 100644 index 0000000000..02a281b447 --- /dev/null +++ b/.changeset/neat-geckos-end.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Tweaked the new package feature detection to not be active when building backend packages. 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/olive-walls-wave.md b/.changeset/olive-walls-wave.md new file mode 100644 index 0000000000..f7dc5434a6 --- /dev/null +++ b/.changeset/olive-walls-wave.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-home': minor +--- + +**BREAKING** Implement usage of unused `limit` query parameter in visits API `.list()` function 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/pre.json b/.changeset/pre.json index 706cec0de5..e1c8fb99d1 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -195,41 +195,120 @@ "@internal/scaffolder": "0.0.1" }, "changesets": [ + "angry-cycles-call", + "angry-mayflies-collect", "angry-windows-decide", "big-rules-nail", "breezy-bulldogs-smell", "brown-frogs-walk", + "calm-owls-move", "chair-fairs-drive", "chilled-dolphins-join", + "chilled-melons-smash", "clever-paws-stare", + "cold-nails-rescue", + "crash-loop-baby", + "crash-loop-honey", + "crash-loop-yeah", + "create-app-1727774359", + "create-app-1728387650", + "cuddly-stingrays-smell", + "curly-foxes-brake", + "curly-tomatoes-reply", + "cyan-cooks-sing", "cyan-peaches-lay", + "cyan-vans-study", + "dependabot-a3fd85a", "dry-frogs-drum", "early-drinks-kneel", + "early-sloths-cross", + "eight-clocks-complain", "eight-steaks-chew", + "eighty-mice-turn", + "eleven-beds-play", "eleven-pugs-hear", "fair-chairs-drive", + "famous-bobcats-remain", "fifty-trainers-watch", "five-gorillas-pay", + "five-turkeys-taste", + "flat-eels-exist", + "flat-seals-type", + "fluffy-dolphins-battle", "fluffy-pears-cry", + "four-moons-watch", + "friendly-coins-approve", + "friendly-cougars-return", "funny-rocks-train", "fuzzy-elephants-tease", "giant-kiwis-retire", + "gold-pots-end", + "great-eagles-repair", + "green-bottles-live", + "green-cooks-sort", "happy-ligers-think", + "healthy-shoes-judge", + "healthy-years-search", + "heavy-ties-tell", + "honest-impalas-rescue", + "hungry-buckets-repair", + "large-hats-reply", "large-plants-rhyme", "light-rats-travel", "long-humans-hunt", + "loud-hotels-tan", + "lovely-bees-walk", "nasty-lamps-greet", + "neat-geckos-end", + "nice-badgers-travel", + "olive-walls-wave", "polite-days-flash", + "poor-dodos-wait", + "pretty-buses-repair", + "pretty-plants-hammer", + "purple-toys-heal", + "quiet-dingos-bathe", + "quiet-needles-impress", + "rare-crabs-cheat", + "rare-rabbits-flow", + "renovate-156753b", + "renovate-7874fad", + "renovate-85a184e", + "renovate-87a3bd2", + "renovate-9f7136b", + "renovate-f88b005", "rich-deers-attend", + "rich-needles-collect", + "rotten-camels-deny", + "rude-apricots-eat", + "sharp-lamps-fix", "shy-olives-swim", + "shy-plants-retire", + "silly-geckos-learn", + "silly-readers-build", + "slimy-ravens-end", "slow-gorillas-thank", "slow-trees-compare", + "small-donkeys-attack", + "smart-jobs-sit", + "sour-grapes-trade", "sour-phones-fix", + "stale-ravens-clap", "stale-roses-serve", "strange-bees-attack", "strong-monkeys-melt", "sweet-chicken-smash", + "ten-apes-turn", + "ten-rings-look", + "thick-tables-give", "thirty-pets-fry", - "tiny-pugs-kick" + "thirty-pianos-mix", + "tiny-pugs-kick", + "tough-fireants-itch", + "tough-pillows-sip", + "tricky-shoes-lie", + "twenty-cups-knock", + "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/purple-toys-heal.md b/.changeset/purple-toys-heal.md new file mode 100644 index 0000000000..4a57dca64f --- /dev/null +++ b/.changeset/purple-toys-heal.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-backend-module-vmware-cloud-provider': minor +--- + +**BREAKING**: The `profileEmailMatchingUserEntityEmail` sign-in resolver has been removed as it was using an insecure fallback for resolving user identities. See https://backstage.io/docs/auth/identity-resolver#sign-in-without-users-in-the-catalog for how to create a custom sign-in resolver if needed as a replacement. diff --git a/.changeset/quiet-needles-impress.md b/.changeset/quiet-needles-impress.md new file mode 100644 index 0000000000..a79fe97b91 --- /dev/null +++ b/.changeset/quiet-needles-impress.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend-module-gitlab': minor +--- + +declare correct type (number) for publish:gitlab output.projectId 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-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/renovate-7874fad.md b/.changeset/renovate-7874fad.md new file mode 100644 index 0000000000..b7ccd5fe95 --- /dev/null +++ b/.changeset/renovate-7874fad.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs-node': patch +--- + +Updated dependency `@smithy/node-http-handler` to `^3.0.0`. diff --git a/.changeset/renovate-85a184e.md b/.changeset/renovate-85a184e.md new file mode 100644 index 0000000000..91b575e6db --- /dev/null +++ b/.changeset/renovate-85a184e.md @@ -0,0 +1,15 @@ +--- +'@backstage/backend-defaults': patch +'@backstage/cli': patch +'@backstage/integration': patch +'@backstage/plugin-catalog-backend-module-github': patch +'@backstage/plugin-catalog-backend': patch +'@backstage/plugin-catalog-import': patch +'@backstage/plugin-scaffolder-backend-module-confluence-to-markdown': patch +'@backstage/plugin-scaffolder': patch +'@backstage/plugin-techdocs-module-addons-contrib': patch +'@backstage/plugin-techdocs-node': patch +'@backstage/plugin-techdocs': patch +--- + +Updated dependency `git-url-parse` to `^15.0.0`. diff --git a/.changeset/renovate-87a3bd2.md b/.changeset/renovate-87a3bd2.md new file mode 100644 index 0000000000..c14def75b7 --- /dev/null +++ b/.changeset/renovate-87a3bd2.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend-module-azure': patch +--- + +Updated dependency `azure-devops-node-api` to `^14.0.0`. diff --git a/.changeset/renovate-9f7136b.md b/.changeset/renovate-9f7136b.md new file mode 100644 index 0000000000..a1efc81de7 --- /dev/null +++ b/.changeset/renovate-9f7136b.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-search-backend-module-explore': patch +--- + +Updated dependency `@backstage-community/plugin-explore-common` to `^0.0.6`. diff --git a/.changeset/renovate-f88b005.md b/.changeset/renovate-f88b005.md new file mode 100644 index 0000000000..b62080e8da --- /dev/null +++ b/.changeset/renovate-f88b005.md @@ -0,0 +1,7 @@ +--- +'@backstage/plugin-kubernetes-cluster': patch +'@backstage/plugin-kubernetes-react': patch +'@backstage/plugin-kubernetes': patch +--- + +Updated dependency `@kubernetes-models/apimachinery` to `^2.0.0`. diff --git a/.changeset/rotten-camels-deny.md b/.changeset/rotten-camels-deny.md new file mode 100644 index 0000000000..f5660d953a --- /dev/null +++ b/.changeset/rotten-camels-deny.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Support `--max-warnings` flag for package linting 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/sharp-lamps-fix.md b/.changeset/sharp-lamps-fix.md new file mode 100644 index 0000000000..52de6690fe --- /dev/null +++ b/.changeset/sharp-lamps-fix.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +Add tests for the `useTemplateDirectory` hook. diff --git a/.changeset/shy-plants-retire.md b/.changeset/shy-plants-retire.md new file mode 100644 index 0000000000..77427452f5 --- /dev/null +++ b/.changeset/shy-plants-retire.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-search': patch +--- + +Updated the default SearchType.Accordion behavior to remain open after result type selection. This is a UX improvement to reduce the number of clicks needed when toggling result type filters. diff --git a/.changeset/silly-geckos-learn.md b/.changeset/silly-geckos-learn.md new file mode 100644 index 0000000000..53d4301b5c --- /dev/null +++ b/.changeset/silly-geckos-learn.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-user-settings': patch +--- + +`useUserProfile` will now use the user's picture stored in the catalog as a fallback if the identity provider doesn't return a picture. 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/slimy-ravens-end.md b/.changeset/slimy-ravens-end.md new file mode 100644 index 0000000000..65e02079b1 --- /dev/null +++ b/.changeset/slimy-ravens-end.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-techdocs': minor +'@backstage/theme': minor +--- + +Adds support for custom background colors in code blocks and inline code within TechDocs. diff --git a/.changeset/small-donkeys-attack.md b/.changeset/small-donkeys-attack.md new file mode 100644 index 0000000000..ecfc969452 --- /dev/null +++ b/.changeset/small-donkeys-attack.md @@ -0,0 +1,7 @@ +--- +'@backstage/cli': patch +--- + +Added a new `--successCache` option to the `backstage-cli repo test` and `backstage-cli repo lint` commands. The cache keeps track of successful runs and avoids re-running for individual packages if they haven't changed. This option is intended only to be used in CI. + +In addition a `--successCacheDir ` option has also been added to be able to override the default cache directory. diff --git a/.changeset/smart-jobs-sit.md b/.changeset/smart-jobs-sit.md new file mode 100644 index 0000000000..edd21e67b5 --- /dev/null +++ b/.changeset/smart-jobs-sit.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-openapi-utils': minor +--- + +Improved support for OpenAPI validation during Jest tests. Now, OpenAPI validation can happen as you are writing your Jest tests - you no longer have to run `repo schema openapi test`. 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/stale-ravens-clap.md b/.changeset/stale-ravens-clap.md new file mode 100644 index 0000000000..3abb16a04d --- /dev/null +++ b/.changeset/stale-ravens-clap.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend': patch +--- + +Update catalog search table in transaction diff --git a/.changeset/ten-apes-turn.md b/.changeset/ten-apes-turn.md new file mode 100644 index 0000000000..750f48beba --- /dev/null +++ b/.changeset/ten-apes-turn.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Disabled parsing of input source maps in the SWC transform for Jest. diff --git a/.changeset/ten-rings-look.md b/.changeset/ten-rings-look.md new file mode 100644 index 0000000000..d3f6e059bd --- /dev/null +++ b/.changeset/ten-rings-look.md @@ -0,0 +1,5 @@ +--- +'@backstage/catalog-client': patch +--- + +Add missing doc string to API diff --git a/.changeset/thick-tables-give.md b/.changeset/thick-tables-give.md new file mode 100644 index 0000000000..e6b4026e51 --- /dev/null +++ b/.changeset/thick-tables-give.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-node': patch +--- + +Use `branch` function instead of `checkout` function when creating branch diff --git a/.changeset/thirty-pianos-mix.md b/.changeset/thirty-pianos-mix.md new file mode 100644 index 0000000000..147307ac9e --- /dev/null +++ b/.changeset/thirty-pianos-mix.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-techdocs-module-addons-contrib': patch +'@backstage/plugin-techdocs': patch +--- + +Use more of the available space for the navigation sidebar. 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-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-shoes-lie.md b/.changeset/tricky-shoes-lie.md new file mode 100644 index 0000000000..d7a17f0345 --- /dev/null +++ b/.changeset/tricky-shoes-lie.md @@ -0,0 +1,10 @@ +--- +'@backstage/plugin-catalog-graph': patch +--- + +Added InfoCard `action` attribute for CatalogGraphCard + +```tsx +const action = + , + ); + + expect( + screen.getByRole('button', { name: 'Custom action' }), + ).toBeInTheDocument(); + }); +}); diff --git a/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorToolbar.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorToolbar.tsx index a33915ae01..b09b4d861c 100644 --- a/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorToolbar.tsx +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorToolbar.tsx @@ -31,18 +31,25 @@ import DialogActions from '@material-ui/core/DialogActions'; import ExtensionIcon from '@material-ui/icons/Extension'; import DescriptionIcon from '@material-ui/icons/Description'; -import { Link } from '@backstage/core-components'; +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: '40%', + 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, @@ -73,6 +80,7 @@ export function TemplateEditorToolbar(props: { }) { 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); @@ -81,22 +89,26 @@ export function TemplateEditorToolbar(props: {
{children}
- - + + - + - + - Publish changes + + {t('templateEditorToolbar.addToCatalogDialogTitle')} + - Follow the instructions below to create or update a template: -
    -
  1. Save the template files in a local directory
  2. -
  3. - Create a pull request to a new or existing git repository -
  4. -
  5. - If the template already exists, the changes will be reflected - in the software catalog once the pull request gets merged -
  6. -
  7. - But if you are creating a new template, follow this{' '} - - documentation - {' '} - to register the new template repository in software catalog -
  8. -
+ {t( + 'templateEditorToolbar.addToCatalogDialogContent.stepsIntroduction', + )} +
    + {t( + 'templateEditorToolbar.addToCatalogDialogContent.stepsListItems', + ) + .split('\n') + .map((step, index) => ( +
  • {step}
  • + ))} +
- diff --git a/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorToolbarFileMenu.test.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorToolbarFileMenu.test.tsx new file mode 100644 index 0000000000..6483b9acff --- /dev/null +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorToolbarFileMenu.test.tsx @@ -0,0 +1,153 @@ +/* + * 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 { screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { renderInTestApp } from '@backstage/test-utils'; +import { TemplateEditorToolbarFileMenu } from './TemplateEditorToolbarFileMenu'; +import { rootRouteRef } from '../../../routes'; + +describe('TemplateEditorToolbarFileMenu', () => { + it('should disable open directory by default', async () => { + await renderInTestApp(, { + mountedRoutes: { + '/': rootRouteRef, + }, + }); + + expect( + screen.queryByRole('menuitem', { name: 'Open template directory' }), + ).not.toBeInTheDocument(); + + await userEvent.click(screen.getByRole('button', { name: 'File' })); + + expect( + screen.getByRole('menuitem', { name: 'Open template directory' }), + ).toHaveAttribute('aria-disabled', 'true'); + }); + + it('should disable create directory by default', async () => { + await renderInTestApp(, { + mountedRoutes: { + '/': rootRouteRef, + }, + }); + + expect( + screen.queryByRole('menuitem', { name: 'Create template directory' }), + ).not.toBeInTheDocument(); + + await userEvent.click(screen.getByRole('button', { name: 'File' })); + + expect( + screen.getByRole('menuitem', { name: 'Create template directory' }), + ).toHaveAttribute('aria-disabled', 'true'); + }); + + it('should disable close editor by default', async () => { + await renderInTestApp(, { + mountedRoutes: { + '/': rootRouteRef, + }, + }); + + expect( + screen.queryByRole('menuitem', { name: 'Close template editor' }), + ).not.toBeInTheDocument(); + + await userEvent.click(screen.getByRole('button', { name: 'File' })); + + expect( + screen.getByRole('menuitem', { name: 'Close template editor' }), + ).toHaveAttribute('aria-disabled', 'true'); + }); + + it('should have an option to open the directory', async () => { + const onOpenDirectory = jest.fn(); + + await renderInTestApp( + , + { + mountedRoutes: { + '/': rootRouteRef, + }, + }, + ); + + expect( + screen.queryByRole('menuitem', { name: 'Open template directory' }), + ).not.toBeInTheDocument(); + + await userEvent.click(screen.getByRole('button', { name: 'File' })); + + await userEvent.click( + screen.getByRole('menuitem', { name: 'Open template directory' }), + ); + + expect(onOpenDirectory).toHaveBeenCalled(); + }); + + it('should have an option to create the directory', async () => { + const onCreateDirectory = jest.fn(); + + await renderInTestApp( + , + { + mountedRoutes: { + '/': rootRouteRef, + }, + }, + ); + + expect( + screen.queryByRole('menuitem', { name: 'Create template directory' }), + ).not.toBeInTheDocument(); + + await userEvent.click(screen.getByRole('button', { name: 'File' })); + + await userEvent.click( + screen.getByRole('menuitem', { name: 'Create template directory' }), + ); + + expect(onCreateDirectory).toHaveBeenCalled(); + }); + + it('should have an option to close the editor', async () => { + const onCloseDirectory = jest.fn(); + + await renderInTestApp( + , + { + mountedRoutes: { + '/': rootRouteRef, + }, + }, + ); + + expect( + screen.queryByRole('menuitem', { name: 'Close template editor' }), + ).not.toBeInTheDocument(); + + await userEvent.click(screen.getByRole('button', { name: 'File' })); + + await userEvent.click( + screen.getByRole('menuitem', { name: 'Close template editor' }), + ); + + expect(onCloseDirectory).toHaveBeenCalled(); + }); +}); 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..f2bdfca6a2 --- /dev/null +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorToolbarFileMenu.tsx @@ -0,0 +1,102 @@ +/* + * 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 Button from '@material-ui/core/Button'; +import Menu from '@material-ui/core/Menu'; +import MenuItem from '@material-ui/core/MenuItem'; + +import { useTranslationRef } from '@backstage/frontend-plugin-api'; + +import { scaffolderTranslationRef } from '../../../translation'; + +export function TemplateEditorToolbarFileMenu(props: { + onOpenDirectory?: () => void; + onCreateDirectory?: () => void; + onCloseDirectory?: () => void; +}) { + const { onOpenDirectory, onCreateDirectory, onCloseDirectory } = props; + 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?.(); + }, [handleCloseMenu, onCloseDirectory]); + + return ( + <> + + + + {t('templateEditorToolbarFileMenu.options.openDirectory')} + + + {t('templateEditorToolbarFileMenu.options.createDirectory')} + + + {t('templateEditorToolbarFileMenu.options.closeEditor')} + + + + ); +} diff --git a/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorToolbarTemplatesMenu.test.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorToolbarTemplatesMenu.test.tsx new file mode 100644 index 0000000000..5e6acc1712 --- /dev/null +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorToolbarTemplatesMenu.test.tsx @@ -0,0 +1,318 @@ +/* + * 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 { screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { renderInTestApp } from '@backstage/test-utils'; +import { + TemplateEditorToolbarTemplatesMenu, + TemplateOption, +} from './TemplateEditorToolbarTemplatesMenu'; + +describe('TemplateEditorToolbarTemplatesMenu', () => { + const options: TemplateOption[] = [ + { + label: 'Create React App Template', + value: { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Template', + metadata: { + namespace: 'default', + name: 'create-react-app-template', + title: 'Create React App Template', + }, + spec: { + parameters: [ + { + title: 'Provide some simple information', + required: ['component_id', 'owner'], + properties: { + component_id: { + title: 'Name', + type: 'string', + description: 'Unique name of the component', + 'ui:field': 'EntityNamePicker', + }, + description: { + title: 'Description', + type: 'string', + description: + 'Help others understand what this website is for.', + }, + owner: { + title: 'Owner', + type: 'string', + description: 'Owner of the component', + 'ui:field': 'OwnerPicker', + 'ui:options': { + allowedKinds: ['Group'], + }, + }, + }, + }, + { + title: 'Choose a location', + required: ['repoUrl'], + properties: { + repoUrl: { + title: 'Repository Location', + type: 'string', + 'ui:field': 'RepoUrlPicker', + 'ui:options': { + allowedHosts: ['github.com'], + }, + }, + }, + }, + ], + steps: [ + { + id: 'template', + name: 'Fetch Skeleton + Template', + action: 'fetch:template', + input: { + url: './skeleton', + copyWithoutRender: ['.github/workflows/*'], + values: { + component_id: '${{ parameters.component_id }}', + description: '${{ parameters.description }}', + destination: '${{ parameters.repoUrl | parseRepoUrl }}', + owner: '${{ parameters.owner }}', + }, + }, + }, + { + id: 'publish', + name: 'Publish', + action: 'publish:github', + input: { + allowedHosts: ['github.com'], + description: 'This is ${{ parameters.component_id }}', + repoUrl: '${{ parameters.repoUrl }}', + }, + }, + { + id: 'register', + name: 'Register', + action: 'catalog:register', + input: { + repoContentsUrl: '${{ steps.publish.output.repoContentsUrl }}', + catalogInfoPath: '/catalog-info.yaml', + }, + }, + ], + output: { + links: [ + { + title: 'Repository', + url: '${{ steps.publish.output.remoteUrl }}', + }, + { + title: 'Open in catalog', + icon: 'catalog', + entityRef: '${{ steps.register.output.entityRef }}', + }, + ], + }, + }, + }, + }, + { + label: 'React SSR Template', + value: { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Template', + metadata: { + namespace: 'default', + name: 'react-ssr-template', + title: 'React SSR Template', + }, + spec: { + parameters: [ + { + title: 'Provide some simple information', + required: ['component_id', 'owner'], + properties: { + component_id: { + title: 'Name', + type: 'string', + description: 'Unique name of the component', + 'ui:field': 'EntityNamePicker', + }, + description: { + title: 'Description', + type: 'string', + description: + 'Help others understand what this website is for.', + }, + owner: { + title: 'Owner', + type: 'string', + description: 'Owner of the component', + 'ui:field': 'OwnerPicker', + 'ui:options': { + allowedKinds: ['Group'], + }, + }, + }, + }, + { + title: 'Choose a location', + required: ['repoUrl'], + properties: { + repoUrl: { + title: 'Repository Location', + type: 'string', + 'ui:field': 'RepoUrlPicker', + 'ui:options': { + allowedHosts: ['github.com'], + }, + }, + }, + }, + ], + steps: [ + { + id: 'template', + name: 'Fetch Skeleton + Template', + action: 'fetch:template', + input: { + url: './skeleton', + copyWithoutRender: ['.github/workflows/*'], + values: { + component_id: '${{ parameters.component_id }}', + description: '${{ parameters.description }}', + destination: '${{ parameters.repoUrl | parseRepoUrl }}', + owner: '${{ parameters.owner }}', + }, + }, + }, + { + id: 'publish', + name: 'Publish', + action: 'publish:github', + input: { + allowedHosts: ['github.com'], + description: 'This is ${{ parameters.component_id }}', + repoUrl: '${{ parameters.repoUrl }}', + }, + }, + { + id: 'register', + name: 'Register', + action: 'catalog:register', + input: { + repoContentsUrl: '${{ steps.publish.output.repoContentsUrl }}', + catalogInfoPath: '/catalog-info.yaml', + }, + }, + ], + output: { + links: [ + { + title: 'Repository', + url: '${{ steps.publish.output.remoteUrl }}', + }, + { + title: 'Open in catalog', + icon: 'catalog', + entityRef: '${{ steps.register.output.entityRef }}', + }, + ], + }, + }, + }, + }, + ]; + + const onSelectOption = jest.fn(); + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should render an item for each option', async () => { + await renderInTestApp( + , + ); + + for (const option of options) { + expect( + screen.queryByRole('menuitem', { name: option.label }), + ).not.toBeInTheDocument(); + } + + await userEvent.click(screen.getByRole('button', { name: 'Templates' })); + + for (const option of options) { + expect( + screen.getByRole('menuitem', { name: option.label }), + ).toBeInTheDocument(); + } + }); + + it('should call "onSelectOption" when a option is selected', async () => { + await renderInTestApp( + , + ); + + for (const option of options) { + expect( + screen.queryByRole('menuitem', { name: option.label }), + ).not.toBeInTheDocument(); + } + + await userEvent.click(screen.getByRole('button', { name: 'Templates' })); + + await userEvent.click( + screen.getByRole('menuitem', { name: options[0].label }), + ); + + expect(onSelectOption).toHaveBeenCalledTimes(1); + expect(onSelectOption).toHaveBeenCalledWith(options[0]); + }); + + it('should highlight the passed selected option', async () => { + const selectedOption = options[0]; + + await renderInTestApp( + , + ); + + await userEvent.click(screen.getByRole('button', { name: 'Templates' })); + + expect( + screen.getByRole('menuitem', { name: selectedOption.label }), + ).toHaveAttribute('aria-selected', 'true'); + + for (const option of options.splice(1)) { + expect( + screen.getByRole('menuitem', { name: option.label }), + ).toHaveAttribute('aria-selected', 'false'); + } + }); +}); 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..4a71aba5e5 --- /dev/null +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateEditorToolbarTemplatesMenu.tsx @@ -0,0 +1,117 @@ +/* + * 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 isSelectedOption = useCallback( + (option: TemplateOption) => { + return !!selectedOption && selectedOption.value === option.value; + }, + [selectedOption], + ); + + 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.test.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateFormPage.test.tsx new file mode 100644 index 0000000000..35e2772873 --- /dev/null +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateFormPage.test.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 React from 'react'; +import { screen } from '@testing-library/react'; +import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; +import { TemplateFormPage } from './TemplateFormPage'; +import { rootRouteRef } from '../../../routes'; +import { catalogApiRef } from '@backstage/plugin-catalog-react'; + +describe('TemplateFormPage', () => { + const catalogApiMock = { getEntities: jest.fn().mockResolvedValue([]) }; + + it('Should render without exploding', async () => { + await renderInTestApp( + + + , + { + mountedRoutes: { + '/': rootRouteRef, + }, + }, + ); + expect( + screen.getByRole('heading', { name: 'Template Editor' }), + ).toBeInTheDocument(); + }); + + it('Should have an link back to the edit page', async () => { + await renderInTestApp( + + + , + { + mountedRoutes: { + '/': rootRouteRef, + }, + routeEntries: ['/edit'], + }, + ); + expect( + screen.getByRole('link', { name: /Manage Templates/ }), + ).toHaveAttribute('href', '/edit'); + }); +}); diff --git a/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateFormPage.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateFormPage.tsx index b1f98878ad..7558276721 100644 --- a/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateFormPage.tsx +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateFormPage.tsx @@ -61,6 +61,8 @@ export function TemplateFormPage(props: TemplateFormPageProps) {
{ const classes = useStyles(); - const { t } = useTranslationRef(scaffolderTranslationRef); const alertApi = useApi(alertApiRef); const catalogApi = useApi(catalogApiRef); + const navigate = useNavigate(); + const editLink = useRouteRef(editRouteRef); + const [errorText, setErrorText] = useState(); - const [selectedTemplate, setSelectedTemplate] = - useState(null); + const [selectedTemplate, setSelectedTemplate] = useState(); const [templateOptions, setTemplateOptions] = useState([]); const [templateYaml, setTemplateYaml] = useState(defaultPreviewTemplate); - const { loading } = useAsync( + const handleCloseDirectory = useCallback(() => { + navigate(editLink()); + }, [navigate, editLink]); + + useAsync( () => catalogApi .getEntities({ @@ -196,76 +186,44 @@ 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 && } - -
- - - - - - - - } - renderValue={selected => { - if (!selected) { - return t('templateEditorPage.templateFormPreviewer.title'); - } - return (selected as Entity).metadata.title; - }} - inputProps={{ - 'aria-label': t( - 'templateEditorPage.templateFormPreviewer.title', - ), - }} - > - {templateOptions.map((option, index) => ( - - {option.label} - - ))} - - - -
-
- + + + -
-
-
- -
-
-
- + + + + + + + + + + ); }; diff --git a/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateIntroPage.test.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateIntroPage.test.tsx new file mode 100644 index 0000000000..f85c37233e --- /dev/null +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateIntroPage.test.tsx @@ -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 React from 'react'; +import { screen } from '@testing-library/react'; +import { renderInTestApp } from '@backstage/test-utils'; +import { TemplateIntroPage } from './TemplateIntroPage'; +import { rootRouteRef } from '../../../routes'; + +describe('TemplateIntroPage', () => { + it('Should render without exploding', async () => { + await renderInTestApp(, { + mountedRoutes: { + '/': rootRouteRef, + }, + }); + expect( + screen.getByRole('heading', { name: 'Manage Templates' }), + ).toBeInTheDocument(); + }); + + it('Should have an link back to the create page', async () => { + await renderInTestApp(, { + mountedRoutes: { + '/': rootRouteRef, + }, + }); + expect(screen.getByRole('link', { name: /Scaffolder/ })).toHaveAttribute( + 'href', + '/', + ); + }); + + it('Should have an action to load a template directory', async () => { + await renderInTestApp(, { + mountedRoutes: { + '/': rootRouteRef, + }, + }); + expect( + screen.getByRole('button', { name: /Load Template Directory/ }), + ).toBeInTheDocument(); + }); + + it('Should have an action to create a template directory', async () => { + await renderInTestApp(, { + mountedRoutes: { + '/': rootRouteRef, + }, + }); + expect( + screen.getByRole('button', { name: /Create New Template/ }), + ).toBeInTheDocument(); + }); + + it('Should have an action to open the template playground', async () => { + await renderInTestApp(, { + mountedRoutes: { + '/': rootRouteRef, + }, + }); + expect( + screen.getByRole('button', { name: /Template Form Playground/ }), + ).toBeInTheDocument(); + }); + + it('Should have an action to open the custom fields explorer', async () => { + await renderInTestApp(, { + mountedRoutes: { + '/': rootRouteRef, + }, + }); + + expect( + screen.getByRole('button', { name: /Custom Field Explorer/ }), + ).toBeInTheDocument(); + }); +}); 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..28e4969718 --- /dev/null +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplateIntroPage.tsx @@ -0,0 +1,80 @@ +/* + * 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, { useCallback } from 'react'; +import { Content, Header, Page } from '@backstage/core-components'; + +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 { useTemplateDirectory } from './useTemplateDirectory'; + +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); + const { openDirectory, createDirectory } = useTemplateDirectory(); + + const handleSelect = useCallback( + (option: 'create-template' | 'local' | 'form' | 'field-explorer') => { + if (option === 'local') { + openDirectory() + .then(() => navigate(editorLink())) + .catch(() => {}); + } else if (option === 'create-template') { + createDirectory() + .then(() => navigate(editorLink())) + .catch(() => {}); + } else if (option === 'form') { + navigate(templateFormLink()); + } else if (option === 'field-explorer') { + navigate(customFieldsLink()); + } + }, + [ + openDirectory, + createDirectory, + navigate, + editorLink, + templateFormLink, + customFieldsLink, + ], + ); + + return ( + +
+ + + + + ); +} diff --git a/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplatePage.tsx b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplatePage.tsx deleted file mode 100644 index b70ceba163..0000000000 --- a/plugins/scaffolder/src/alpha/components/TemplateEditorPage/TemplatePage.tsx +++ /dev/null @@ -1,95 +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 React, { useCallback } from 'react'; -import useAsyncRetry from 'react-use/esm/useAsyncRetry'; - -import { Page, Header, Content, Progress } from '@backstage/core-components'; -import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; -import { - FormProps, - FieldExtensionOptions, - type LayoutOptions, -} from '@backstage/plugin-scaffolder-react'; - -import { scaffolderTranslationRef } from '../../../translation'; -import { - WebFileSystemAccess, - WebFileSystemStore, -} from '../../../lib/filesystem'; -import { TemplateEditor } from './TemplateEditor'; - -import { makeStyles } from '@material-ui/core/styles'; - -const useStyles = makeStyles( - { - content: { - padding: 0, - }, - }, - { name: 'ScaffolderTemplateEditorToolbar' }, -); - -interface TemplatePageProps { - defaultPreviewTemplate?: string; - fieldExtensions?: FieldExtensionOptions[]; - layouts?: LayoutOptions[]; - formProps?: FormProps; -} - -export function TemplatePage(props: TemplatePageProps) { - const classes = useStyles(); - const { t } = useTranslationRef(scaffolderTranslationRef); - - const { value, loading, retry } = useAsyncRetry(async () => { - const directory = await WebFileSystemStore.getDirectory(); - if (!directory) return undefined; - return WebFileSystemAccess.fromHandle(directory); - }, []); - - const handleLoadDirectory = useCallback(() => { - WebFileSystemAccess.requestDirectoryAccess() - .then(WebFileSystemStore.setDirectory) - .then(retry); - }, [retry]); - - const handleCloseDirectory = useCallback(() => { - WebFileSystemStore.setDirectory(undefined).then(retry); - }, [retry]); - - return ( - -
- - {loading ? ( - - ) : ( - - )} - - - ); -} diff --git a/plugins/scaffolder/src/alpha/components/TemplateEditorPage/index.ts b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/index.ts index 84ab74da98..f16f2426d7 100644 --- a/plugins/scaffolder/src/alpha/components/TemplateEditorPage/index.ts +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/index.ts @@ -14,9 +14,9 @@ * limitations under the License. */ -export { TemplatePage } from './TemplatePage'; -export { TemplateFormPage } from './TemplateFormPage'; 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'; diff --git a/plugins/scaffolder/src/alpha/components/TemplateEditorPage/useTemplateDirectory.test.ts b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/useTemplateDirectory.test.ts new file mode 100644 index 0000000000..bdc1534f27 --- /dev/null +++ b/plugins/scaffolder/src/alpha/components/TemplateEditorPage/useTemplateDirectory.test.ts @@ -0,0 +1,133 @@ +/* + * 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 { act, renderHook, waitFor } from '@testing-library/react'; +import { useTemplateDirectory } from './useTemplateDirectory'; +import { + createExampleTemplate, + TemplateDirectoryAccess, + WebFileSystemStore, +} from '../../../lib/filesystem'; +import { + IterableDirectoryHandle, + WebFileSystemAccess, +} from '../../../lib/filesystem/WebFileSystemAccess'; + +jest.mock('../../../lib/filesystem/createExampleTemplate'); + +describe('useTemplateDirectory', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should return undefined when there is no existing directory in the file system store', async () => { + jest.spyOn(WebFileSystemStore, 'getDirectory').mockResolvedValue(undefined); + + const { result } = renderHook(() => useTemplateDirectory()); + + expect(result.current.directory).toBeUndefined(); + expect(result.current.loading).toBeTruthy(); + expect(result.current.error).toBeUndefined(); + + await waitFor(() => expect(result.current.loading).toBeFalsy()); + + expect(result.current.directory).toBeUndefined(); + expect(result.current.error).toBeUndefined(); + }); + + it('should return an access when there is existing directory in the file system store', async () => { + const handle = {} as IterableDirectoryHandle; + + jest.spyOn(WebFileSystemStore, 'getDirectory').mockResolvedValue(handle); + + const { result } = renderHook(() => useTemplateDirectory()); + + await waitFor(() => expect(result.current.loading).toBeFalsy()); + + expect(result.current.directory).toMatchObject({ handle }); + expect(result.current.error).toBeUndefined(); + }); + + it('should handle opening a directory', async () => { + const handle = {}; + jest + .spyOn(WebFileSystemStore, 'getDirectory') + .mockResolvedValue(handle as IterableDirectoryHandle); + const setDirectory = jest + .spyOn(WebFileSystemStore, 'setDirectory') + .mockResolvedValue(undefined); + const requestDirectoryAccess = jest + .spyOn(WebFileSystemAccess, 'requestDirectoryAccess') + .mockResolvedValue(handle as TemplateDirectoryAccess); + + const { result } = renderHook(() => useTemplateDirectory()); + + expect(result.current.directory).toBeUndefined(); + + await act(async () => { + result.current.openDirectory(); + }); + + expect(requestDirectoryAccess).toHaveBeenCalled(); + expect(setDirectory).toHaveBeenCalledWith(handle); + + await waitFor(() => expect(result.current.directory).toBeDefined()); + }); + + it('should handle creating a directory', async () => { + const handle = {}; + (createExampleTemplate as jest.Mock).mockResolvedValue(handle); + jest + .spyOn(WebFileSystemStore, 'getDirectory') + .mockResolvedValue(handle as IterableDirectoryHandle); + const setDirectory = jest + .spyOn(WebFileSystemStore, 'setDirectory') + .mockResolvedValue(undefined); + const requestDirectoryAccess = jest + .spyOn(WebFileSystemAccess, 'requestDirectoryAccess') + .mockResolvedValue(handle as TemplateDirectoryAccess); + + const { result } = renderHook(() => useTemplateDirectory()); + + await act(async () => { + result.current.createDirectory(); + }); + + expect(requestDirectoryAccess).toHaveBeenCalled(); + expect(setDirectory).toHaveBeenCalledWith(handle); + expect(createExampleTemplate).toHaveBeenCalledWith(handle); + }); + + it('should handle closing a directory', async () => { + jest.spyOn(WebFileSystemStore, 'getDirectory').mockResolvedValue(undefined); + + const setDirectory = jest + .spyOn(WebFileSystemStore, 'setDirectory') + .mockResolvedValue(undefined); + + const { result } = renderHook(() => useTemplateDirectory()); + + expect(setDirectory).not.toHaveBeenCalled(); + expect(result.current.directory).toBeUndefined(); + + await act(async () => { + result.current.closeDirectory(); + }); + + expect(setDirectory).toHaveBeenCalledWith(undefined); + await waitFor(() => expect(result.current.directory).toBeUndefined()); + }); +}); 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..eefb37568d --- /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 { + WebFileSystemStore, + WebFileSystemAccess, + WebDirectoryAccess, + createExampleTemplate, +} from '../../../lib/filesystem'; + +export function useTemplateDirectory(): { + directory?: WebDirectoryAccess; + loading: boolean; + error?: Error; + openDirectory: () => Promise; + createDirectory: () => Promise; + closeDirectory: () => Promise; +} { + const { value, loading, error, retry } = useAsyncRetry(async () => { + const directory = await WebFileSystemStore.getDirectory(); + if (!directory) return undefined; + return WebFileSystemAccess.fromHandle(directory); + }, []); + + const openDirectory = useCallback(() => { + return WebFileSystemAccess.requestDirectoryAccess() + .then(WebFileSystemStore.setDirectory) + .then(retry); + }, [retry]); + + const createDirectory = useCallback(() => { + return WebFileSystemAccess.requestDirectoryAccess() + .then(createExampleTemplate) + .then(WebFileSystemStore.setDirectory) + .then(retry); + }, [retry]); + + const closeDirectory = useCallback(() => { + return WebFileSystemStore.setDirectory(undefined).then(retry); + }, [retry]); + + return { + directory: value, + loading, + error, + openDirectory, + createDirectory, + closeDirectory, + }; +} diff --git a/plugins/scaffolder/src/alpha/components/TemplateListPage/RegisterExistingButton.tsx b/plugins/scaffolder/src/alpha/components/TemplateListPage/RegisterExistingButton.tsx index abec7c47e1..126f00dde5 100644 --- a/plugins/scaffolder/src/alpha/components/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/alpha/components/TemplateListPage/TemplateListPage.test.tsx b/plugins/scaffolder/src/alpha/components/TemplateListPage/TemplateListPage.test.tsx index ba00845577..6079ec2e1d 100644 --- a/plugins/scaffolder/src/alpha/components/TemplateListPage/TemplateListPage.test.tsx +++ b/plugins/scaffolder/src/alpha/components/TemplateListPage/TemplateListPage.test.tsx @@ -13,11 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { DefaultStarredEntitiesApi } from '@backstage/plugin-catalog'; import { catalogApiRef, starredEntitiesApiRef, } from '@backstage/plugin-catalog-react'; +import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils'; import { permissionApiRef } from '@backstage/plugin-permission-react'; import { MockStorageApi, @@ -29,26 +31,18 @@ import { rootRouteRef } from '../../../routes'; import { TemplateListPage } from './TemplateListPage'; describe('TemplateListPage', () => { - const mockCatalogApi = { - getEntities: async () => ({ - items: [ - { - apiVersion: 'scaffolder.backstage.io/v1beta3', - kind: 'Template', - metadata: { name: 'blob', tags: ['blob'] }, - spec: { - type: 'service', - }, + const mockCatalogApi = catalogApiMock({ + entities: [ + { + apiVersion: 'scaffolder.backstage.io/v1beta3', + kind: 'Template', + metadata: { name: 'blob', tags: ['blob'] }, + spec: { + type: 'service', }, - ], - }), - getEntityFacets: async () => ({ - facets: { 'spec.type': [{ value: 'service', count: 1 }] }, - }), - getEntitiesByRefs: async () => ({ - items: [], - }), - }; + }, + ], + }); it('should render the search bar for templates', async () => { const { getByPlaceholderText } = await renderInTestApp( diff --git a/plugins/scaffolder/src/alpha/components/TemplateWizardPage/TemplateWizardPage.test.tsx b/plugins/scaffolder/src/alpha/components/TemplateWizardPage/TemplateWizardPage.test.tsx index 689a96b95d..750efd70d0 100644 --- a/plugins/scaffolder/src/alpha/components/TemplateWizardPage/TemplateWizardPage.test.tsx +++ b/plugins/scaffolder/src/alpha/components/TemplateWizardPage/TemplateWizardPage.test.tsx @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { ApiProvider } from '@backstage/core-app-api'; import { analyticsApiRef } from '@backstage/core-plugin-api'; import { @@ -30,8 +31,8 @@ import { import { TemplateWizardPage } from './TemplateWizardPage'; import { rootRouteRef } from '../../../routes'; import { ANNOTATION_EDIT_URL } from '@backstage/catalog-model'; -import { CatalogApi } from '@backstage/catalog-client'; import { catalogApiRef } from '@backstage/plugin-catalog-react'; +import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils'; jest.mock('react-router-dom', () => { return { @@ -54,16 +55,14 @@ const scaffolderApiMock: jest.Mocked = { autocomplete: jest.fn(), }; -const catalogApiMock: jest.Mocked = { - getEntityByRef: jest.fn(), -} as any; +const catalogApi = catalogApiMock.mock(); const analyticsMock = new MockAnalyticsApi(); const apis = TestApiRegistry.from( [scaffolderApiRef, scaffolderApiMock], - [catalogApiRef, catalogApiMock], + [catalogApiRef, catalogApi], [analyticsApiRef, analyticsMock], - [catalogApiRef, catalogApiMock], + [catalogApiRef, catalogApi], ); const entityRefResponse = { @@ -100,7 +99,7 @@ describe('TemplateWizardPage', () => { ], title: 'React JSON Schema Form Test', }); - catalogApiMock.getEntityByRef.mockResolvedValue(entityRefResponse); + catalogApi.getEntityByRef.mockResolvedValue(entityRefResponse); const { findByRole, getByRole } = await renderInTestApp( @@ -147,7 +146,7 @@ describe('TemplateWizardPage', () => { }); describe('scaffolder page context menu', () => { it('should render if editUrl is set to url', async () => { - catalogApiMock.getEntityByRef.mockResolvedValue({ + catalogApi.getEntityByRef.mockResolvedValue({ apiVersion: 'v1', kind: 'service', metadata: { @@ -177,7 +176,7 @@ describe('TemplateWizardPage', () => { expect(queryByTestId('menu-button')).toBeInTheDocument(); }); it('should not render if editUrl is undefined', async () => { - catalogApiMock.getEntityByRef.mockResolvedValue({ + catalogApi.getEntityByRef.mockResolvedValue({ apiVersion: 'v1', kind: 'service', metadata: { 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 93db7386f3..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) { 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 0949d948fc..539a5697d3 100644 --- a/plugins/scaffolder/src/components/ActionsPage/ActionsPage.tsx +++ b/plugins/scaffolder/src/components/ActionsPage/ActionsPage.tsx @@ -16,6 +16,7 @@ import React, { Fragment, useEffect, useState } from 'react'; import useAsync from 'react-use/esm/useAsync'; import { + Action, ActionExample, scaffolderApiRef, } from '@backstage/plugin-scaffolder-react'; @@ -39,6 +40,10 @@ 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 { @@ -125,14 +130,19 @@ export const ActionPageContent = () => { 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 && window.location.hash) { + if (value.length && window.location.hash) { document.querySelector(window.location.hash)?.scrollIntoView(); } }, [value]); @@ -295,71 +305,107 @@ export 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/ListTasksPage/ListTaskPage.test.tsx b/plugins/scaffolder/src/components/ListTasksPage/ListTaskPage.test.tsx index b9c5a84da3..96374662a4 100644 --- a/plugins/scaffolder/src/components/ListTasksPage/ListTaskPage.test.tsx +++ b/plugins/scaffolder/src/components/ListTasksPage/ListTaskPage.test.tsx @@ -16,25 +16,20 @@ import { Entity } from '@backstage/catalog-model'; import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; -import { - CatalogApi, - catalogApiRef, - entityRouteRef, -} from '@backstage/plugin-catalog-react'; +import { catalogApiRef, entityRouteRef } from '@backstage/plugin-catalog-react'; +import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils'; 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'; describe('', () => { - const catalogApi: jest.Mocked = { - getEntityByRef: jest.fn(), - } as any; + const catalogApi = catalogApiMock.mock(); const identityApi = { getBackstageIdentity: jest.fn(), @@ -64,7 +59,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 +141,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 +192,7 @@ describe('', () => { lastHeartbeatAt: '', }, ], + totalTasks: 1, }) .mockResolvedValue({ tasks: [ @@ -212,6 +211,7 @@ describe('', () => { lastHeartbeatAt: '', }, ], + totalTasks: 1, }); scaffolderApiMock.getTemplateParameterSchema.mockResolvedValue({ @@ -244,6 +244,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/columns/OwnerEntityColumn.test.tsx b/plugins/scaffolder/src/components/ListTasksPage/columns/OwnerEntityColumn.test.tsx index 84b86599d5..35eb9ce0b7 100644 --- a/plugins/scaffolder/src/components/ListTasksPage/columns/OwnerEntityColumn.test.tsx +++ b/plugins/scaffolder/src/components/ListTasksPage/columns/OwnerEntityColumn.test.tsx @@ -16,19 +16,14 @@ import { Entity } from '@backstage/catalog-model'; import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; -import { - CatalogApi, - catalogApiRef, - entityRouteRef, -} from '@backstage/plugin-catalog-react'; +import { catalogApiRef, entityRouteRef } from '@backstage/plugin-catalog-react'; +import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils'; import React from 'react'; import { OwnerEntityColumn } from './OwnerEntityColumn'; import { identityApiRef } from '@backstage/core-plugin-api'; describe('', () => { - const catalogApi: jest.Mocked = { - getEntityByRef: jest.fn(), - } as any; + const catalogApi = catalogApiMock.mock(); const identityApi = { getBackstageIdentity: jest.fn(), diff --git a/plugins/scaffolder/src/components/Router/Router.tsx b/plugins/scaffolder/src/components/Router/Router.tsx index e79d930795..5766e3d043 100644 --- a/plugins/scaffolder/src/components/Router/Router.tsx +++ b/plugins/scaffolder/src/components/Router/Router.tsx @@ -54,8 +54,8 @@ import { import { TemplateListPage, TemplateWizardPage } from '../../alpha/components'; import { OngoingTask } from '../OngoingTask'; import { - TemplatePage, TemplateFormPage, + TemplateIntroPage, TemplateEditorPage, CustomFieldsPage, } from '../../alpha/components/TemplateEditorPage'; @@ -171,7 +171,7 @@ export const Router = (props: PropsWithChildren) => { path={editRouteRef.path} element={ - + } /> @@ -205,7 +205,7 @@ export const Router = (props: PropsWithChildren) => { path={editorRouteRef.path} element={ - ({ apiVersion: 'scaffolder.backstage.io/v1beta3', @@ -36,7 +36,10 @@ const makeEntity = (kind: string, namespace: string, name: string): Entity => ({ }); describe('', () => { - let entities: Entity[]; + const entities: Entity[] = [ + makeEntity('Group', 'default', 'team-a'), + makeEntity('Group', 'default', 'squad-b'), + ]; const onChange = jest.fn(); const schema = {}; const required = false; @@ -46,23 +49,13 @@ describe('', () => { let props: FieldProps; - const catalogApi: jest.Mocked = { - getLocationById: jest.fn(), - getEntityByName: jest.fn(), + const catalogApi = catalogApiMock.mock({ getEntities: jest.fn(async () => ({ items: entities })), - addLocation: jest.fn(), - getLocationByRef: jest.fn(), - removeEntityByUid: jest.fn(), - } as any; + }); let Wrapper: React.ComponentType>; beforeEach(() => { - entities = [ - makeEntity('Group', 'default', 'team-a'), - makeEntity('Group', 'default', 'squad-b'), - ]; - Wrapper = ({ children }: { children?: React.ReactNode }) => ( ', () => { rawErrors, formData, } as unknown as FieldProps; - - catalogApi.getEntities.mockResolvedValue({ items: entities }); }); it('searches for all entities', async () => { diff --git a/plugins/scaffolder/src/components/fields/EntityPicker/EntityPicker.tsx b/plugins/scaffolder/src/components/fields/EntityPicker/EntityPicker.tsx index b97b776b19..2ef5171c7b 100644 --- a/plugins/scaffolder/src/components/fields/EntityPicker/EntityPicker.tsx +++ b/plugins/scaffolder/src/components/fields/EntityPicker/EntityPicker.tsx @@ -190,7 +190,7 @@ export const EntityPicker = (props: EntityPickerProps) => { typeof option === 'string' ? option : entities?.entityRefToPresentation.get(stringifyEntityRef(option)) - ?.entityRef! + ?.primaryTitle! } autoSelect freeSolo={allowArbitraryValues} diff --git a/plugins/scaffolder/src/components/fields/MultiEntityPicker/MultiEntityPicker.test.tsx b/plugins/scaffolder/src/components/fields/MultiEntityPicker/MultiEntityPicker.test.tsx index edd777652b..74b9dadda3 100644 --- a/plugins/scaffolder/src/components/fields/MultiEntityPicker/MultiEntityPicker.test.tsx +++ b/plugins/scaffolder/src/components/fields/MultiEntityPicker/MultiEntityPicker.test.tsx @@ -17,7 +17,6 @@ import { CATALOG_FILTER_EXISTS } from '@backstage/catalog-client'; import { Entity } from '@backstage/catalog-model'; import { - CatalogApi, catalogApiRef, entityPresentationApiRef, } from '@backstage/plugin-catalog-react'; @@ -30,6 +29,7 @@ import { MultiEntityPicker } from './MultiEntityPicker'; import { MultiEntityPickerProps } from './schema'; import { ScaffolderRJSFFieldProps as FieldProps } from '@backstage/plugin-scaffolder-react'; import { DefaultEntityPresentationApi } from '@backstage/plugin-catalog'; +import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils'; const makeEntity = (kind: string, namespace: string, name: string): Entity => ({ apiVersion: 'scaffolder.backstage.io/v1beta3', @@ -38,7 +38,10 @@ const makeEntity = (kind: string, namespace: string, name: string): Entity => ({ }); describe('', () => { - let entities: Entity[]; + const entities: Entity[] = [ + makeEntity('Group', 'default', 'team-a'), + makeEntity('Group', 'default', 'squad-b'), + ]; const onChange = jest.fn(); const schema = {}; const required = false; @@ -48,22 +51,12 @@ describe('', () => { let props: FieldProps; - const catalogApi: jest.Mocked = { - getLocationById: jest.fn(), - getEntityByName: jest.fn(), + const catalogApi = catalogApiMock.mock({ getEntities: jest.fn(async () => ({ items: entities })), - addLocation: jest.fn(), - getLocationByRef: jest.fn(), - removeEntityByUid: jest.fn(), - } as any; + }); let Wrapper: React.ComponentType>; beforeEach(() => { - entities = [ - makeEntity('Group', 'default', 'team-a'), - makeEntity('Group', 'default', 'squad-b'), - ]; - Wrapper = ({ children }: { children?: React.ReactNode }) => ( ', () => { rawErrors, formData, } as unknown as FieldProps; - - catalogApi.getEntities.mockResolvedValue({ items: entities }); }); it('searches for all entities', async () => { diff --git a/plugins/scaffolder/src/components/fields/MyGroupsPicker/MyGroupsPicker.test.tsx b/plugins/scaffolder/src/components/fields/MyGroupsPicker/MyGroupsPicker.test.tsx index 74af578a21..d4a37d0752 100644 --- a/plugins/scaffolder/src/components/fields/MyGroupsPicker/MyGroupsPicker.test.tsx +++ b/plugins/scaffolder/src/components/fields/MyGroupsPicker/MyGroupsPicker.test.tsx @@ -16,7 +16,7 @@ import React from 'react'; import { waitFor } from '@testing-library/react'; -import { CatalogApi } from '@backstage/catalog-client'; +import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils'; import { MyGroupsPicker } from './MyGroupsPicker'; import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; import { @@ -60,9 +60,9 @@ describe('', () => { const schema = {}; const required = false; - const catalogApi: jest.Mocked = { + const catalogApi = catalogApiMock.mock({ getEntities: jest.fn(async () => ({ items: entities })), - } as any; + }); const mockErrorApi: jest.Mocked = { post: jest.fn(), diff --git a/plugins/scaffolder/src/components/fields/OwnerPicker/OwnerPicker.test.tsx b/plugins/scaffolder/src/components/fields/OwnerPicker/OwnerPicker.test.tsx index 79105e05c3..329448b224 100644 --- a/plugins/scaffolder/src/components/fields/OwnerPicker/OwnerPicker.test.tsx +++ b/plugins/scaffolder/src/components/fields/OwnerPicker/OwnerPicker.test.tsx @@ -17,10 +17,10 @@ import { type EntityFilterQuery } from '@backstage/catalog-client'; import { Entity } from '@backstage/catalog-model'; import { - CatalogApi, catalogApiRef, entityPresentationApiRef, } from '@backstage/plugin-catalog-react'; +import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils'; import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; import { ScaffolderRJSFFieldProps as FieldProps } from '@backstage/plugin-scaffolder-react'; import React from 'react'; @@ -34,7 +34,10 @@ const makeEntity = (kind: string, namespace: string, name: string): Entity => ({ }); describe('', () => { - let entities: Entity[]; + const entities: Entity[] = [ + makeEntity('Group', 'default', 'team-a'), + makeEntity('Group', 'default', 'squad-b'), + ]; const onChange = jest.fn(); const schema = {}; const required = false; @@ -52,22 +55,12 @@ describe('', () => { let props: FieldProps; - const catalogApi: jest.Mocked = { - getLocationById: jest.fn(), - getEntityByName: jest.fn(), + const catalogApi = catalogApiMock.mock({ getEntities: jest.fn(async () => ({ items: entities })), - addLocation: jest.fn(), - getLocationByRef: jest.fn(), - removeEntityByUid: jest.fn(), - } as any; + }); let Wrapper: React.ComponentType>; beforeEach(() => { - entities = [ - makeEntity('Group', 'default', 'team-a'), - makeEntity('Group', 'default', 'squad-b'), - ]; - Wrapper = ({ children }: { children?: React.ReactNode }) => ( ', () => { rawErrors, formData, } as unknown as FieldProps; - - catalogApi.getEntities.mockResolvedValue({ items: entities }); }); it('searches for users and groups', async () => { @@ -134,8 +125,6 @@ describe('', () => { rawErrors, formData, } as unknown as FieldProps; - - catalogApi.getEntities.mockResolvedValue({ items: entities }); }); it('searches for users', async () => { @@ -228,8 +217,6 @@ describe('', () => { rawErrors, formData, } as unknown as FieldProps; - - catalogApi.getEntities.mockResolvedValue({ items: entities }); }); it('searches for users and groups or teams and business units', async () => { diff --git a/plugins/scaffolder/src/lib/filesystem/WebFileSystemAccess.ts b/plugins/scaffolder/src/lib/filesystem/WebFileSystemAccess.ts index fe5c69b452..c304e7b394 100644 --- a/plugins/scaffolder/src/lib/filesystem/WebFileSystemAccess.ts +++ b/plugins/scaffolder/src/lib/filesystem/WebFileSystemAccess.ts @@ -14,7 +14,6 @@ * limitations under the License. */ -import { get, set } from 'idb-keyval'; import { TemplateDirectoryAccess, TemplateFileAccess } from './types'; type WritableFileHandle = FileSystemFileHandle & { @@ -25,7 +24,7 @@ type WritableFileHandle = FileSystemFileHandle & { }; // A nicer type than the one from the TS lib -interface IterableDirectoryHandle extends FileSystemDirectoryHandle { +export interface IterableDirectoryHandle extends FileSystemDirectoryHandle { values(): AsyncIterable< | ({ kind: 'file' } & WritableFileHandle) | ({ kind: 'directory' } & IterableDirectoryHandle) @@ -53,7 +52,8 @@ class WebFileAccess implements TemplateFileAccess { } } -class WebDirectoryAccess implements TemplateDirectoryAccess { +/** @internal */ +export class WebDirectoryAccess implements TemplateDirectoryAccess { constructor(private readonly handle: IterableDirectoryHandle) {} async listFiles(): Promise { @@ -123,16 +123,3 @@ export class WebFileSystemAccess { private constructor() {} } - -export class WebFileSystemStore { - private static readonly key = 'scalfolder-template-editor-directory'; - - static async getDirectory(): Promise { - const directory = await get(WebFileSystemStore.key); - return directory.handle; - } - - static async setDirectory(directory: TemplateDirectoryAccess | undefined) { - return set(WebFileSystemStore.key, directory); - } -} diff --git a/plugins/scaffolder/src/lib/filesystem/WebFileSystemStore.ts b/plugins/scaffolder/src/lib/filesystem/WebFileSystemStore.ts new file mode 100644 index 0000000000..1ea90dcf76 --- /dev/null +++ b/plugins/scaffolder/src/lib/filesystem/WebFileSystemStore.ts @@ -0,0 +1,32 @@ +/* + * 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 { get, set } from 'idb-keyval'; +import { TemplateDirectoryAccess } from './types'; +import { IterableDirectoryHandle } from './WebFileSystemAccess'; + +export class WebFileSystemStore { + private static readonly key = 'scalfolder-template-editor-directory'; + + static async getDirectory(): Promise { + const directory = await get(WebFileSystemStore.key); + return directory.handle; + } + + static async setDirectory(directory: TemplateDirectoryAccess | undefined) { + return set(WebFileSystemStore.key, directory); + } +} diff --git a/plugins/scaffolder/src/lib/filesystem/createExampleTemplate.ts b/plugins/scaffolder/src/lib/filesystem/createExampleTemplate.ts index b93d678d5e..e3d0053d69 100644 --- a/plugins/scaffolder/src/lib/filesystem/createExampleTemplate.ts +++ b/plugins/scaffolder/src/lib/filesystem/createExampleTemplate.ts @@ -91,4 +91,5 @@ export async function createExampleTemplate( for (const [name, data] of Object.entries(files)) { await directory.createFile({ name, data }); } + return directory; } diff --git a/plugins/scaffolder/src/lib/filesystem/index.ts b/plugins/scaffolder/src/lib/filesystem/index.ts index 29f72294ea..4f44ab1ccd 100644 --- a/plugins/scaffolder/src/lib/filesystem/index.ts +++ b/plugins/scaffolder/src/lib/filesystem/index.ts @@ -14,6 +14,8 @@ * limitations under the License. */ -export type { TemplateFileAccess, TemplateDirectoryAccess } from './types'; export { blobToBase64 } from './helpers'; -export { WebFileSystemAccess, WebFileSystemStore } from './WebFileSystemAccess'; +export { createExampleTemplate } from './createExampleTemplate'; +export type { TemplateFileAccess, TemplateDirectoryAccess } from './types'; +export { WebFileSystemStore } from './WebFileSystemStore'; +export { WebDirectoryAccess, WebFileSystemAccess } from './WebFileSystemAccess'; diff --git a/plugins/scaffolder/src/translation.ts b/plugins/scaffolder/src/translation.ts index 11c13194ce..7299d3245a 100644 --- a/plugins/scaffolder/src/translation.ts +++ b/plugins/scaffolder/src/translation.ts @@ -29,6 +29,7 @@ export const scaffolderTranslationRef = createTranslationRef({ description: 'There are no actions installed or there was an issue communicating with backend.', }, + searchFieldPlaceholder: 'Search for an action', tableCell: { name: 'Name', title: 'Title', @@ -194,12 +195,21 @@ export const scaffolderTranslationRef = createTranslationRef({ templateTypePicker: { title: 'Categories', }, + templateIntroPage: { + title: 'Manage Templates', + subtitle: + 'Edit, preview, and try out templates, forms, and custom fields', + }, templateFormPage: { - title: 'Template Form Playground', - subtitle: 'Edit, preview, and try out templates and template forms', + title: 'Template Editor', + subtitle: 'Edit, preview, and try out templates forms', + }, + templateCustomFieldPage: { + title: 'Custom Field Explorer', + subtitle: 'Edit, preview, and try out custom fields', }, templateEditorPage: { - title: 'Manage Templates', + title: 'Template Editor', subtitle: 'Edit, preview, and try out templates and template forms', dryRunResults: { title: 'Dry-run results', @@ -253,7 +263,7 @@ export const scaffolderTranslationRef = createTranslationRef({ unsupportedTooltip: 'Only supported in some Chromium-based browsers', }, formEditor: { - title: 'Template playground', + title: 'Template Form Playground', description: 'Preview and edit a template form, either using a sample template or by loading a template from the catalog.', }, @@ -266,6 +276,7 @@ export const scaffolderTranslationRef = createTranslationRef({ templateEditorTextArea: { saveIconTooltip: 'Save file', refreshIconTooltip: 'Reload file', + emptyStateParagraph: 'Please select an action on the file menu.', }, templateFormPreviewer: { title: 'Load Existing Template', @@ -298,5 +309,33 @@ export const scaffolderTranslationRef = createTranslationRef({ editConfigurationTitle: 'Edit Configuration', }, }, + templateEditorToolbar: { + customFieldExplorerTooltip: 'Custom Fields Explorer', + installedActionsDocumentationTooltip: 'Installed Actions Documentation', + addToCatalogButton: 'Publish', + addToCatalogDialogTitle: 'Publish changes', + addToCatalogDialogContent: { + stepsIntroduction: + 'Follow the instructions below to create or update a template:', + stepsListItems: + 'Save the template files in a local directory\nCreate a pull request to a new or existing git repository\nIf the template already exists, the changes will be reflected in the software catalog once the pull request gets merged\nBut if you are creating a new template, follow the documentation linked below to register the new template repository in software catalog', + }, + addToCatalogDialogActions: { + documentationButton: 'Go to the documentation', + documentationUrl: + 'https://backstage.io/docs/features/software-templates/adding-templates/', + }, + }, + templateEditorToolbarFileMenu: { + button: 'File', + options: { + openDirectory: 'Open template directory', + createDirectory: 'Create template directory', + closeEditor: 'Close template editor', + }, + }, + templateEditorToolbarTemplatesMenu: { + button: 'Templates', + }, }, }); diff --git a/plugins/search-backend-module-catalog/CHANGELOG.md b/plugins/search-backend-module-catalog/CHANGELOG.md index d00e1d9335..a8efc75f48 100644 --- a/plugins/search-backend-module-catalog/CHANGELOG.md +++ b/plugins/search-backend-module-catalog/CHANGELOG.md @@ -1,5 +1,37 @@ # @backstage/plugin-search-backend-module-catalog +## 0.2.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.13.1-next.1 + - @backstage/catalog-client@1.7.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.1 + - @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-permission-common@0.8.1 + - @backstage/plugin-search-backend-node@1.3.3-next.2 + - @backstage/plugin-search-common@1.2.14 + +## 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 + ## 0.2.3-next.0 ### Patch Changes diff --git a/plugins/search-backend-module-catalog/package.json b/plugins/search-backend-module-catalog/package.json index ff6fed6987..172b8064e0 100644 --- a/plugins/search-backend-module-catalog/package.json +++ b/plugins/search-backend-module-catalog/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-module-catalog", - "version": "0.2.3-next.0", + "version": "0.2.3-next.2", "description": "A module for the search backend that exports catalog modules", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/search-backend-module-elasticsearch/CHANGELOG.md b/plugins/search-backend-module-elasticsearch/CHANGELOG.md index 5c360d54d3..47f9845d1b 100644 --- a/plugins/search-backend-module-elasticsearch/CHANGELOG.md +++ b/plugins/search-backend-module-elasticsearch/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/plugin-search-backend-module-elasticsearch +## 1.5.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.1 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-backend-node@1.3.3-next.2 + - @backstage/plugin-search-common@1.2.14 + +## 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 + ## 1.5.7-next.0 ### Patch Changes diff --git a/plugins/search-backend-module-elasticsearch/package.json b/plugins/search-backend-module-elasticsearch/package.json index a54779d766..61dc522801 100644 --- a/plugins/search-backend-module-elasticsearch/package.json +++ b/plugins/search-backend-module-elasticsearch/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-module-elasticsearch", - "version": "1.5.7-next.0", + "version": "1.5.7-next.2", "description": "A module for the search backend that implements search using ElasticSearch", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/search-backend-module-explore/CHANGELOG.md b/plugins/search-backend-module-explore/CHANGELOG.md index 5abe14369a..ab867b1efe 100644 --- a/plugins/search-backend-module-explore/CHANGELOG.md +++ b/plugins/search-backend-module-explore/CHANGELOG.md @@ -1,5 +1,26 @@ # @backstage/plugin-search-backend-module-explore +## 0.2.3-next.2 + +### Patch Changes + +- c052931: Updated dependency `@backstage-community/plugin-explore-common` to `^0.0.6`. +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-search-backend-node@1.3.3-next.2 + - @backstage/plugin-search-common@1.2.14 + +## 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 + ## 0.2.3-next.0 ### Patch Changes diff --git a/plugins/search-backend-module-explore/package.json b/plugins/search-backend-module-explore/package.json index 695d86a688..b8539084ce 100644 --- a/plugins/search-backend-module-explore/package.json +++ b/plugins/search-backend-module-explore/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-module-explore", - "version": "0.2.3-next.0", + "version": "0.2.3-next.2", "description": "A module for the search backend that exports explore modules", "backstage": { "role": "backend-plugin-module", @@ -48,7 +48,7 @@ "test": "backstage-cli package test" }, "dependencies": { - "@backstage-community/plugin-explore-common": "^0.0.5", + "@backstage-community/plugin-explore-common": "^0.0.6", "@backstage/backend-common": "^0.25.0", "@backstage/backend-plugin-api": "workspace:^", "@backstage/config": "workspace:^", diff --git a/plugins/search-backend-module-pg/CHANGELOG.md b/plugins/search-backend-module-pg/CHANGELOG.md index 25f1cd1430..6fc6f91ec5 100644 --- a/plugins/search-backend-module-pg/CHANGELOG.md +++ b/plugins/search-backend-module-pg/CHANGELOG.md @@ -1,5 +1,25 @@ # @backstage/plugin-search-backend-module-pg +## 0.5.36-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-search-backend-node@1.3.3-next.2 + - @backstage/plugin-search-common@1.2.14 + +## 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 + ## 0.5.36-next.0 ### Patch Changes diff --git a/plugins/search-backend-module-pg/package.json b/plugins/search-backend-module-pg/package.json index 4665bda3d4..314a0005b2 100644 --- a/plugins/search-backend-module-pg/package.json +++ b/plugins/search-backend-module-pg/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-module-pg", - "version": "0.5.36-next.0", + "version": "0.5.36-next.2", "description": "A module for the search backend that implements search using PostgreSQL", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/search-backend-module-stack-overflow-collator/CHANGELOG.md b/plugins/search-backend-module-stack-overflow-collator/CHANGELOG.md index 781292337b..01865494ec 100644 --- a/plugins/search-backend-module-stack-overflow-collator/CHANGELOG.md +++ b/plugins/search-backend-module-stack-overflow-collator/CHANGELOG.md @@ -1,5 +1,25 @@ # @backstage/plugin-search-backend-module-stack-overflow-collator +## 0.3.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.1-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-search-backend-node@1.3.3-next.2 + - @backstage/plugin-search-common@1.2.14 + +## 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 + ## 0.3.1-next.0 ### Patch Changes diff --git a/plugins/search-backend-module-stack-overflow-collator/package.json b/plugins/search-backend-module-stack-overflow-collator/package.json index f164f9f391..03227e5230 100644 --- a/plugins/search-backend-module-stack-overflow-collator/package.json +++ b/plugins/search-backend-module-stack-overflow-collator/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-module-stack-overflow-collator", - "version": "0.3.1-next.0", + "version": "0.3.1-next.2", "description": "A module for the search backend that exports stack overflow modules", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/search-backend-module-techdocs/CHANGELOG.md b/plugins/search-backend-module-techdocs/CHANGELOG.md index 3ceae39057..a876840832 100644 --- a/plugins/search-backend-module-techdocs/CHANGELOG.md +++ b/plugins/search-backend-module-techdocs/CHANGELOG.md @@ -1,5 +1,37 @@ # @backstage/plugin-search-backend-module-techdocs +## 0.2.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.13.1-next.1 + - @backstage/plugin-techdocs-node@1.12.12-next.2 + - @backstage/catalog-client@1.7.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.1 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.1.0 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-backend-node@1.3.3-next.2 + - @backstage/plugin-search-common@1.2.14 + +## 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 + ## 0.2.3-next.0 ### Patch Changes diff --git a/plugins/search-backend-module-techdocs/package.json b/plugins/search-backend-module-techdocs/package.json index 078ab1e11f..3b718c5deb 100644 --- a/plugins/search-backend-module-techdocs/package.json +++ b/plugins/search-backend-module-techdocs/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-module-techdocs", - "version": "0.2.3-next.0", + "version": "0.2.3-next.2", "description": "A module for the search backend that exports techdocs modules", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/search-backend-node/CHANGELOG.md b/plugins/search-backend-node/CHANGELOG.md index a27e703815..ada18cb40d 100644 --- a/plugins/search-backend-node/CHANGELOG.md +++ b/plugins/search-backend-node/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-search-backend-node +## 1.3.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.1-next.2 + - @backstage/backend-plugin-api@1.0.1-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-common@1.2.14 + +## 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 + ## 1.3.3-next.0 ### Patch Changes diff --git a/plugins/search-backend-node/package.json b/plugins/search-backend-node/package.json index e6ecdf1f4e..aa4ecb2676 100644 --- a/plugins/search-backend-node/package.json +++ b/plugins/search-backend-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-node", - "version": "1.3.3-next.0", + "version": "1.3.3-next.2", "description": "A library for Backstage backend plugins that want to interact with the search backend plugin", "backstage": { "role": "node-library", diff --git a/plugins/search-backend/CHANGELOG.md b/plugins/search-backend/CHANGELOG.md index deb3409a23..48f1809187 100644 --- a/plugins/search-backend/CHANGELOG.md +++ b/plugins/search-backend/CHANGELOG.md @@ -1,5 +1,38 @@ # @backstage/plugin-search-backend +## 1.5.18-next.2 + +### Patch Changes + +- 66af016: Fix to schema to allow arbitrary query parameters. +- Updated dependencies + - @backstage/backend-defaults@0.5.1-next.2 + - @backstage/backend-openapi-utils@0.2.0-next.1 + - @backstage/backend-plugin-api@1.0.1-next.1 + - @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.1 + - @backstage/plugin-search-backend-node@1.3.3-next.2 + - @backstage/plugin-search-common@1.2.14 + +## 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 + ## 1.5.18-next.0 ### Patch Changes diff --git a/plugins/search-backend/optic.yml b/plugins/search-backend/optic.yml deleted file mode 100644 index 75f20f1bb8..0000000000 --- a/plugins/search-backend/optic.yml +++ /dev/null @@ -1,15 +0,0 @@ -ruleset: - - breaking-changes -capture: - src/schema/openapi.yaml: - # 🔧 Runnable example with simple get requests. - # Run with "PORT=3000 optic capture src/schema/openapi.yaml --update interactive" in 'plugins/search-backend' - # You can change the server and the 'requests' section to experiment - server: - # This will not be used by 'backstage-repo-tools schema openapi test', but may be useful for interactive updates. - url: http://localhost:3000 - requests: - # ℹ️ Requests should be sent to the Optic proxy, the address of which is injected into 'run.command's env as OPTIC_PROXY (or the value of 'run.proxy_variable'). - run: - # 🔧 Specify a command that will generate traffic - command: yarn backstage-cli package test --no-watch "src/service/router.test.ts" "src/service/createRouter.test.ts" diff --git a/plugins/search-backend/package.json b/plugins/search-backend/package.json index d4c2e51da6..835081e5a2 100644 --- a/plugins/search-backend/package.json +++ b/plugins/search-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend", - "version": "1.5.18-next.0", + "version": "1.5.18-next.2", "description": "The Backstage backend plugin that provides your backstage app with search", "backstage": { "role": "backend-plugin", diff --git a/plugins/search-backend/src/schema/openapi.generated.ts b/plugins/search-backend/src/schema/openapi.generated.ts index 8ad27546d6..1e6adfb08f 100644 --- a/plugins/search-backend/src/schema/openapi.generated.ts +++ b/plugins/search-backend/src/schema/openapi.generated.ts @@ -208,7 +208,6 @@ export const spec = { in: 'query', required: false, style: 'deepObject', - explode: true, allowReserved: true, schema: { $ref: '#/components/schemas/JsonObject', @@ -244,6 +243,18 @@ export const spec = { type: 'integer', }, }, + { + name: 'unknown', + in: 'query', + required: false, + style: 'form', + explode: true, + allowReserved: true, + schema: { + type: 'object', + additionalProperties: true, + }, + }, ], }, }, diff --git a/plugins/search-backend/src/schema/openapi.yaml b/plugins/search-backend/src/schema/openapi.yaml index 358f94fcf6..cbf3db273a 100644 --- a/plugins/search-backend/src/schema/openapi.yaml +++ b/plugins/search-backend/src/schema/openapi.yaml @@ -140,7 +140,6 @@ paths: in: query required: false style: deepObject - explode: true allowReserved: true schema: # JsonObject is used here instead of the full ZOD schema definition as @@ -167,3 +166,13 @@ paths: allowReserved: true schema: type: integer + - name: unknown + in: query + required: false + # explode form is the equivalent to allow any extra query parameters + style: form + explode: true + allowReserved: true + schema: + type: object + additionalProperties: true diff --git a/plugins/search-backend/src/service/router.test.ts b/plugins/search-backend/src/service/router.test.ts index d22fc17e54..5b6900ede1 100644 --- a/plugins/search-backend/src/service/router.test.ts +++ b/plugins/search-backend/src/service/router.test.ts @@ -23,7 +23,7 @@ import { import express from 'express'; import request from 'supertest'; import { createRouter } from './router'; -import { wrapInOpenApiTestServer } from '@backstage/backend-openapi-utils'; +import { wrapServer } from '@backstage/backend-openapi-utils'; import { Server } from 'http'; import { mockCredentials, @@ -87,9 +87,7 @@ describe('createRouter', () => { auth: mockServices.auth(), httpAuth: mockServices.httpAuth(), }); - app = wrapInOpenApiTestServer( - express().use(router).use(mockErrorHandler()), - ); + app = await wrapServer(express().use(router).use(mockErrorHandler())); }); beforeEach(() => { diff --git a/plugins/search-react/CHANGELOG.md b/plugins/search-react/CHANGELOG.md index 76e2c40e8f..d05aa61cd6 100644 --- a/plugins/search-react/CHANGELOG.md +++ b/plugins/search-react/CHANGELOG.md @@ -1,5 +1,32 @@ # @backstage/plugin-search-react +## 1.8.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.6.0-next.1 + - @backstage/core-components@0.15.1-next.2 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/frontend-plugin-api@0.9.0-next.2 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.10-next.0 + - @backstage/plugin-search-common@1.2.14 + +## 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 + ## 1.8.1-next.0 ### Patch Changes diff --git a/plugins/search-react/package.json b/plugins/search-react/package.json index 2b4f5de145..dddb2e6470 100644 --- a/plugins/search-react/package.json +++ b/plugins/search-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-react", - "version": "1.8.1-next.0", + "version": "1.8.1-next.2", "backstage": { "role": "web-library", "pluginId": "search", @@ -66,7 +66,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", "lodash": "^4.17.21", "qs": "^6.9.4", "react-use": "^17.3.2" @@ -80,11 +79,21 @@ "@testing-library/dom": "^10.0.0", "@testing-library/jest-dom": "^6.0.0", "@testing-library/react": "^16.0.0", - "@testing-library/user-event": "^14.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/search/CHANGELOG.md b/plugins/search/CHANGELOG.md index b0e9c1f9d6..ee8ed57c73 100644 --- a/plugins/search/CHANGELOG.md +++ b/plugins/search/CHANGELOG.md @@ -1,5 +1,39 @@ # @backstage/plugin-search +## 1.4.18-next.2 + +### Patch Changes + +- 88d03d8: Updated the default SearchType.Accordion behavior to remain open after result type selection. This is a UX improvement to reduce the number of clicks needed when toggling result type filters. +- Updated dependencies + - @backstage/plugin-catalog-react@1.14.0-next.2 + - @backstage/core-compat-api@0.3.1-next.2 + - @backstage/core-components@0.15.1-next.2 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.9.0-next.2 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.10-next.0 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-search-react@1.8.1-next.2 + +## 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 diff --git a/plugins/search/package.json b/plugins/search/package.json index cc9e8df9b7..d4b6b6b833 100644 --- a/plugins/search/package.json +++ b/plugins/search/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search", - "version": "1.4.17-next.0", + "version": "1.4.18-next.2", "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" }, @@ -83,12 +82,22 @@ "@testing-library/jest-dom": "^6.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/src/components/SearchType/SearchType.Accordion.test.tsx b/plugins/search/src/components/SearchType/SearchType.Accordion.test.tsx index 556a9550a0..453b766791 100644 --- a/plugins/search/src/components/SearchType/SearchType.Accordion.test.tsx +++ b/plugins/search/src/components/SearchType/SearchType.Accordion.test.tsx @@ -140,18 +140,6 @@ describe('SearchType.Accordion', () => { expect(setPageCursorMock).toHaveBeenCalledWith(undefined); }); - it('should collapse when a new type is selected', async () => { - const { getByText, queryByText } = render( - - - , - ); - - await user.click(getByText(expectedType.name)); - - expect(queryByText('Collapse')).not.toBeInTheDocument(); - }); - it('should show result counts if enabled', async () => { const { getAllByText } = render( diff --git a/plugins/search/src/components/SearchType/SearchType.Accordion.tsx b/plugins/search/src/components/SearchType/SearchType.Accordion.tsx index f9a07b6dcd..bdd13f2fb2 100644 --- a/plugins/search/src/components/SearchType/SearchType.Accordion.tsx +++ b/plugins/search/src/components/SearchType/SearchType.Accordion.tsx @@ -96,7 +96,6 @@ export const SearchTypeAccordion = (props: SearchTypeAccordionProps) => { return () => { setTypes(type !== '' ? [type] : []); setPageCursor(undefined); - setExpanded(false); }; }; diff --git a/plugins/signals-backend/CHANGELOG.md b/plugins/signals-backend/CHANGELOG.md index 3f8ebc1d9f..f5218925ff 100644 --- a/plugins/signals-backend/CHANGELOG.md +++ b/plugins/signals-backend/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-signals-backend +## 0.2.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.3-next.1 + - @backstage/backend-plugin-api@1.0.1-next.1 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.4.1-next.1 + - @backstage/plugin-signals-node@0.1.12-next.1 + ## 0.2.1-next.0 ### Patch Changes diff --git a/plugins/signals-backend/package.json b/plugins/signals-backend/package.json index b883dbbfaa..3888ead2d1 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.1-next.0", + "version": "0.2.1-next.1", "backstage": { "role": "backend-plugin", "pluginId": "signals", diff --git a/plugins/signals-node/CHANGELOG.md b/plugins/signals-node/CHANGELOG.md index ef4a078f9a..e4b6a0dac1 100644 --- a/plugins/signals-node/CHANGELOG.md +++ b/plugins/signals-node/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-signals-node +## 0.1.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.3-next.1 + - @backstage/backend-plugin-api@1.0.1-next.1 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.4.1-next.1 + ## 0.1.12-next.0 ### Patch Changes diff --git a/plugins/signals-node/package.json b/plugins/signals-node/package.json index cd00595972..1e3f154c17 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.12-next.0", + "version": "0.1.12-next.1", "description": "Node.js library for the signals plugin", "backstage": { "role": "node-library", diff --git a/plugins/signals-react/CHANGELOG.md b/plugins/signals-react/CHANGELOG.md index 3cb505e301..005bc89b9b 100644 --- a/plugins/signals-react/CHANGELOG.md +++ b/plugins/signals-react/CHANGELOG.md @@ -1,5 +1,14 @@ # @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 diff --git a/plugins/signals-react/package.json b/plugins/signals-react/package.json index 96a54b3fed..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.6-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": "^16.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/CHANGELOG.md b/plugins/signals/CHANGELOG.md index 1e7578288d..a949e6d190 100644 --- a/plugins/signals/CHANGELOG.md +++ b/plugins/signals/CHANGELOG.md @@ -1,5 +1,28 @@ # @backstage/plugin-signals +## 0.0.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.6.0-next.1 + - @backstage/core-components@0.15.1-next.2 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.6-next.1 + +## 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 diff --git a/plugins/signals/package.json b/plugins/signals/package.json index 471aecc4eb..5aafdb51a4 100644 --- a/plugins/signals/package.json +++ b/plugins/signals/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-signals", - "version": "0.0.11-next.0", + "version": "0.0.11-next.2", "backstage": { "role": "frontend-plugin", "pluginId": "signals", @@ -57,10 +57,22 @@ "@testing-library/jest-dom": "^6.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/techdocs-addons-test-utils/CHANGELOG.md b/plugins/techdocs-addons-test-utils/CHANGELOG.md index 94323cea16..294152c962 100644 --- a/plugins/techdocs-addons-test-utils/CHANGELOG.md +++ b/plugins/techdocs-addons-test-utils/CHANGELOG.md @@ -1,5 +1,36 @@ # @backstage/plugin-techdocs-addons-test-utils +## 1.0.40-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.24.0-next.2 + - @backstage/plugin-catalog-react@1.14.0-next.2 + - @backstage/plugin-techdocs@1.11.0-next.2 + - @backstage/core-app-api@1.15.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/integration-react@1.2.0-next.2 + - @backstage/test-utils@1.6.1-next.2 + - @backstage/plugin-search-react@1.8.1-next.2 + - @backstage/plugin-techdocs-react@1.2.9-next.2 + +## 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 diff --git a/plugins/techdocs-addons-test-utils/package.json b/plugins/techdocs-addons-test-utils/package.json index ea61f6d6d4..735cbe048e 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.39-next.0", + "version": "1.0.40-next.2", "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": "^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-backend/CHANGELOG.md b/plugins/techdocs-backend/CHANGELOG.md index 53b4e27a5e..6260c752a6 100644 --- a/plugins/techdocs-backend/CHANGELOG.md +++ b/plugins/techdocs-backend/CHANGELOG.md @@ -1,5 +1,42 @@ # @backstage/plugin-techdocs-backend +## 1.10.14-next.2 + +### Patch Changes + +- fbdc631: Allow to pass StorageOptions to GCS Publisher +- Updated dependencies + - @backstage/plugin-catalog-node@1.13.1-next.1 + - @backstage/plugin-techdocs-node@1.12.12-next.2 + - @backstage/integration@1.15.1-next.1 + - @backstage/catalog-client@1.7.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.1 + - @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-permission-common@0.8.1 + - @backstage/plugin-search-backend-module-techdocs@0.2.3-next.2 + - @backstage/plugin-techdocs-common@0.1.0 + +## 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 diff --git a/plugins/techdocs-backend/package.json b/plugins/techdocs-backend/package.json index d941f84e2d..476d72f527 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.14-next.0", + "version": "1.10.14-next.2", "description": "The Backstage backend plugin that renders technical documentation for your components", "backstage": { "role": "backend-plugin", 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-module-addons-contrib/CHANGELOG.md b/plugins/techdocs-module-addons-contrib/CHANGELOG.md index 603a91278e..31314cd7b7 100644 --- a/plugins/techdocs-module-addons-contrib/CHANGELOG.md +++ b/plugins/techdocs-module-addons-contrib/CHANGELOG.md @@ -1,5 +1,30 @@ # @backstage/plugin-techdocs-module-addons-contrib +## 1.1.16-next.2 + +### Patch Changes + +- 720a2f9: Updated dependency `git-url-parse` to `^15.0.0`. +- e8b4966: Use more of the available space for the navigation sidebar. +- Updated dependencies + - @backstage/integration@1.15.1-next.1 + - @backstage/core-components@0.15.1-next.2 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/integration-react@1.2.0-next.2 + - @backstage/plugin-techdocs-react@1.2.9-next.2 + +## 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 diff --git a/plugins/techdocs-module-addons-contrib/package.json b/plugins/techdocs-module-addons-contrib/package.json index a4a58184d5..8ef105d527 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.15-next.0", + "version": "1.1.16-next.2", "description": "Plugin module for contributed TechDocs Addons", "backstage": { "role": "frontend-plugin-module", @@ -47,7 +47,7 @@ "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@react-hookz/web": "^24.0.0", - "git-url-parse": "^14.0.0", + "git-url-parse": "^15.0.0", "photoswipe": "^5.3.7" }, "devDependencies": { @@ -57,11 +57,20 @@ "@testing-library/dom": "^10.0.0", "@testing-library/jest-dom": "^6.0.0", "@testing-library/react": "^16.0.0", - "@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 + } } } diff --git a/plugins/techdocs-module-addons-contrib/src/ExpandableNavigation/ExpandableNavigation.tsx b/plugins/techdocs-module-addons-contrib/src/ExpandableNavigation/ExpandableNavigation.tsx index 802e377f42..6cdf87a49f 100644 --- a/plugins/techdocs-module-addons-contrib/src/ExpandableNavigation/ExpandableNavigation.tsx +++ b/plugins/techdocs-module-addons-contrib/src/ExpandableNavigation/ExpandableNavigation.tsx @@ -30,8 +30,9 @@ const EXPANDABLE_NAVIGATION_LOCAL_STORAGE = const StyledButton = withStyles({ root: { position: 'absolute', - left: '220px', + left: '13.7rem', // Sidebar inner width (15.1em) minus the different margins/paddings top: '19px', + zIndex: 2, padding: 0, minWidth: 0, }, diff --git a/plugins/techdocs-node/CHANGELOG.md b/plugins/techdocs-node/CHANGELOG.md index 4f68e735f8..e81d1cbf50 100644 --- a/plugins/techdocs-node/CHANGELOG.md +++ b/plugins/techdocs-node/CHANGELOG.md @@ -1,5 +1,36 @@ # @backstage/plugin-techdocs-node +## 1.12.12-next.2 + +### Patch Changes + +- 7774828: Updated dependency `@smithy/node-http-handler` to `^3.0.0`. +- 720a2f9: Updated dependency `git-url-parse` to `^15.0.0`. +- fbdc631: Allow to pass StorageOptions to GCS Publisher +- Updated dependencies + - @backstage/integration@1.15.1-next.1 + - @backstage/backend-plugin-api@1.0.1-next.1 + - @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.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 diff --git a/plugins/techdocs-node/package.json b/plugins/techdocs-node/package.json index e807b7abb0..b523753801 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.12-next.0", + "version": "1.12.12-next.2", "description": "Common node.js functionalities for TechDocs, to be shared between techdocs-backend plugin and techdocs-cli", "backstage": { "role": "node-library", @@ -62,13 +62,13 @@ "@backstage/plugin-search-common": "workspace:^", "@backstage/plugin-techdocs-common": "workspace:^", "@google-cloud/storage": "^7.0.0", - "@smithy/node-http-handler": "^2.1.7", + "@smithy/node-http-handler": "^3.0.0", "@trendyol-js/openstack-swift-sdk": "^0.0.7", "@types/express": "^4.17.6", "dockerode": "^4.0.0", "express": "^4.17.1", "fs-extra": "^11.2.0", - "git-url-parse": "^14.0.0", + "git-url-parse": "^15.0.0", "hpagent": "^1.2.0", "js-yaml": "^4.0.0", "json5": "^2.1.3", diff --git a/plugins/techdocs-node/report.api.md b/plugins/techdocs-node/report.api.md index ad6e01636f..1bd93d1b57 100644 --- a/plugins/techdocs-node/report.api.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 @@ -368,13 +381,15 @@ export class UrlPreparer implements PreparerBase { // Warnings were encountered during analysis: // -// src/extensions.d.ts:10:5 - (ae-undocumented) Missing documentation for "setBuildStrategy". -// src/extensions.d.ts:11:5 - (ae-undocumented) Missing documentation for "setBuildLogTransport". -// src/extensions.d.ts:25:5 - (ae-undocumented) Missing documentation for "setTechdocsGenerator". -// src/extensions.d.ts:39:5 - (ae-undocumented) Missing documentation for "registerPreparer". -// src/extensions.d.ts:53:5 - (ae-undocumented) Missing documentation for "registerPublisher". +// 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/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 519b0f8c6b..3eac9834d2 100644 --- a/plugins/techdocs-node/src/stages/publish/googleStorage.ts +++ b/plugins/techdocs-node/src/stages/publish/googleStorage.ts @@ -68,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'); @@ -103,7 +107,7 @@ export class GoogleGCSPublish implements PublisherBase { } } - const clientOpts: StorageOptions = {}; + const clientOpts: StorageOptions = options ?? {}; if (projectId) { clientOpts.projectId = projectId; } diff --git a/plugins/techdocs-node/src/stages/publish/index.ts b/plugins/techdocs-node/src/stages/publish/index.ts index 7f6859367f..8d528b4db6 100644 --- a/plugins/techdocs-node/src/stages/publish/index.ts +++ b/plugins/techdocs-node/src/stages/publish/index.ts @@ -24,4 +24,5 @@ export type { MigrateRequest, ReadinessResponse, TechDocsMetadata, + 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 720f1b218a..b5b65c8e08 100644 --- a/plugins/techdocs-node/src/stages/publish/types.ts +++ b/plugins/techdocs-node/src/stages/publish/types.ts @@ -17,6 +17,7 @@ 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 @@ -26,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 diff --git a/plugins/techdocs-react/CHANGELOG.md b/plugins/techdocs-react/CHANGELOG.md index 88e73fd070..7426563d01 100644 --- a/plugins/techdocs-react/CHANGELOG.md +++ b/plugins/techdocs-react/CHANGELOG.md @@ -1,5 +1,28 @@ # @backstage/plugin-techdocs-react +## 1.2.9-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/core-components@0.15.1-next.2 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/version-bridge@1.0.10-next.0 + +## 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 diff --git a/plugins/techdocs-react/package.json b/plugins/techdocs-react/package.json index 0c196707f0..c8b2eec414 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.9-next.0", + "version": "1.2.9-next.2", "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": "^16.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/CHANGELOG.md b/plugins/techdocs/CHANGELOG.md index 044ede047d..bf5de10189 100644 --- a/plugins/techdocs/CHANGELOG.md +++ b/plugins/techdocs/CHANGELOG.md @@ -1,5 +1,57 @@ # @backstage/plugin-techdocs +## 1.11.0-next.2 + +### Minor Changes + +- e77ff3d: Adds support for custom background colors in code blocks and inline code within TechDocs. + +### Patch Changes + +- e918061: Add support for mkdocs material palette conditional hashes. +- 720a2f9: Updated dependency `git-url-parse` to `^15.0.0`. +- e8b4966: Use more of the available space for the navigation sidebar. +- Updated dependencies + - @backstage/plugin-catalog-react@1.14.0-next.2 + - @backstage/integration@1.15.1-next.1 + - @backstage/theme@0.6.0-next.1 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/core-compat-api@0.3.1-next.2 + - @backstage/core-components@0.15.1-next.2 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.9.0-next.2 + - @backstage/integration-react@1.2.0-next.2 + - @backstage/plugin-auth-react@0.1.7-next.2 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-search-react@1.8.1-next.2 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-techdocs-react@1.2.9-next.2 + +## 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 diff --git a/plugins/techdocs/package.json b/plugins/techdocs/package.json index a6e6179c87..7b6f9276e2 100644 --- a/plugins/techdocs/package.json +++ b/plugins/techdocs/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs", - "version": "1.10.10-next.0", + "version": "1.11.0-next.2", "description": "The Backstage plugin that renders technical documentation for your components", "backstage": { "role": "frontend-plugin", @@ -80,9 +80,8 @@ "@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", + "git-url-parse": "^15.0.0", "jss": "~10.10.0", "lodash": "^4.17.21", "react-helmet": "6.1.0", @@ -99,12 +98,22 @@ "@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/src/home/components/DefaultTechDocsHome.test.tsx b/plugins/techdocs/src/home/components/DefaultTechDocsHome.test.tsx index 1f073e184d..513a56265c 100644 --- a/plugins/techdocs/src/home/components/DefaultTechDocsHome.test.tsx +++ b/plugins/techdocs/src/home/components/DefaultTechDocsHome.test.tsx @@ -21,11 +21,11 @@ import { storageApiRef, } from '@backstage/core-plugin-api'; import { - CatalogApi, catalogApiRef, starredEntitiesApiRef, MockStarredEntitiesApi, } from '@backstage/plugin-catalog-react'; +import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils'; import { MockStorageApi, renderInTestApp, @@ -36,22 +36,18 @@ import React from 'react'; import { rootDocsRouteRef } from '../../routes'; import { DefaultTechDocsHome } from './DefaultTechDocsHome'; -const mockCatalogApi: Partial = { - getEntityFacets: async () => ({ facets: { 'relations.ownedBy': [] } }), - getEntitiesByRefs: () => Promise.resolve({ items: [] }), - getEntities: async () => ({ - items: [ - { - apiVersion: 'version', - kind: 'User', - metadata: { - name: 'owned', - namespace: 'default', - }, +const mockCatalogApi = catalogApiMock({ + entities: [ + { + apiVersion: 'version', + kind: 'User', + metadata: { + name: 'owned', + namespace: 'default', }, - ], - }), -}; + }, + ], +}); describe('TechDocs Home', () => { const configApi: ConfigApi = new ConfigReader({ diff --git a/plugins/techdocs/src/home/components/Grids/EntityListDocsGrid.test.tsx b/plugins/techdocs/src/home/components/Grids/EntityListDocsGrid.test.tsx index acaf01b318..947c81ae85 100644 --- a/plugins/techdocs/src/home/components/Grids/EntityListDocsGrid.test.tsx +++ b/plugins/techdocs/src/home/components/Grids/EntityListDocsGrid.test.tsx @@ -21,12 +21,14 @@ import { storageApiRef, } from '@backstage/core-plugin-api'; import { - CatalogApi, catalogApiRef, starredEntitiesApiRef, - MockEntityListContextProvider, MockStarredEntitiesApi, } from '@backstage/plugin-catalog-react'; +import { + MockEntityListContextProvider, + catalogApiMock, +} from '@backstage/plugin-catalog-react/testUtils'; import { MockStorageApi, renderInTestApp, @@ -62,12 +64,7 @@ const entities = [ }, ]; -const mockCatalogApi = { - getEntityByRef: () => Promise.resolve(), - getEntities: async () => ({ - items: entities, - }), -} as Partial; +const mockCatalogApi = catalogApiMock({ entities }); describe('Entity List Docs Grid', () => { beforeEach(() => { diff --git a/plugins/techdocs/src/home/components/TechDocsCustomHome.test.tsx b/plugins/techdocs/src/home/components/TechDocsCustomHome.test.tsx index 6f09a70b5e..409d68a593 100644 --- a/plugins/techdocs/src/home/components/TechDocsCustomHome.test.tsx +++ b/plugins/techdocs/src/home/components/TechDocsCustomHome.test.tsx @@ -14,7 +14,8 @@ * limitations under the License. */ -import { CatalogApi, catalogApiRef } from '@backstage/plugin-catalog-react'; +import { catalogApiRef } from '@backstage/plugin-catalog-react'; +import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils'; import { renderInTestApp, TestApiRegistry } from '@backstage/test-utils'; import { screen } from '@testing-library/react'; import React from 'react'; @@ -22,21 +23,18 @@ import { TechDocsCustomHome, PanelType } from './TechDocsCustomHome'; import { ApiProvider } from '@backstage/core-app-api'; import { rootDocsRouteRef } from '../../routes'; -const mockCatalogApi = { - getEntityByRef: jest.fn(), - getEntities: async () => ({ - items: [ - { - apiVersion: 'version', - kind: 'User', - metadata: { - name: 'owned', - namespace: 'default', - }, +const mockCatalogApi = catalogApiMock({ + entities: [ + { + apiVersion: 'version', + kind: 'User', + metadata: { + name: 'owned', + namespace: 'default', }, - ], - }), -} as Partial; + }, + ], +}); describe('TechDocsCustomHome', () => { const apiRegistry = TestApiRegistry.from([catalogApiRef, mockCatalogApi]); diff --git a/plugins/techdocs/src/reader/transformers/styles/rules/layout.ts b/plugins/techdocs/src/reader/transformers/styles/rules/layout.ts index 590f2a114b..1a326c62b8 100644 --- a/plugins/techdocs/src/reader/transformers/styles/rules/layout.ts +++ b/plugins/techdocs/src/reader/transformers/styles/rules/layout.ts @@ -86,9 +86,14 @@ export default ({ theme, sidebar }: RuleOptions) => ` scrollbar-width: thin; } .md-sidebar .md-sidebar__scrollwrap { - width: calc(12.1rem); + width: calc(16rem); overflow-y: hidden; } +@supports selector(::-webkit-scrollbar) { + [dir=ltr] .md-sidebar__inner { + padding-right: calc(100% - 15.1rem); + } +} .md-sidebar--secondary { right: ${theme.spacing(3)}px; } @@ -202,18 +207,22 @@ export default ({ theme, sidebar }: RuleOptions) => ` height: 100%; } .md-sidebar--primary { - width: 12.1rem !important; + width: 16rem !important; z-index: 200; left: ${ sidebar.isPinned - ? `calc(-12.1rem + ${SIDEBAR_WIDTH})` - : 'calc(-12.1rem + 72px)' + ? `calc(-16rem + ${SIDEBAR_WIDTH})` + : 'calc(-16rem + 72px)' } !important; } .md-sidebar--secondary:not([hidden]) { display: none; } + [data-md-toggle=drawer]:checked~.md-container .md-sidebar--primary { + transform: translateX(16rem); + } + .md-content { max-width: 100%; margin-left: 0; @@ -241,8 +250,8 @@ export default ({ theme, sidebar }: RuleOptions) => ` @media screen and (max-width: 600px) { .md-sidebar--primary { - left: -12.1rem !important; - width: 12.1rem; + left: -16rem !important; + width: 16rem; } } 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 e7e47c6fc7..c419d5f71b 100644 --- a/plugins/techdocs/src/reader/transformers/styles/rules/variables.ts +++ b/plugins/techdocs/src/reader/transformers/styles/rules/variables.ts @@ -108,7 +108,9 @@ export default ({ theme }: RuleOptions) => ` :host > * { /* CODE */ --md-code-fg-color: ${theme.palette.text.primary}; - --md-code-bg-color: ${theme.palette.background.paper}; + --md-code-bg-color: ${ + theme.palette.code?.background ?? theme.palette.background.paper + }; --md-code-hl-color: ${alpha(theme.palette.warning.main, 0.5)}; --md-code-hl-color--light: var(--md-code-hl-color); --md-code-hl-keyword-color: ${ 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 813b94a21a..5c1c7a108f 100644 --- a/plugins/user-settings-backend/CHANGELOG.md +++ b/plugins/user-settings-backend/CHANGELOG.md @@ -1,5 +1,33 @@ # @backstage/plugin-user-settings-backend +## 0.2.25-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.1-next.2 + - @backstage/plugin-auth-node@0.5.3-next.1 + - @backstage/backend-plugin-api@1.0.1-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-node@0.1.12-next.1 + - @backstage/plugin-user-settings-common@0.0.1 + +## 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 diff --git a/plugins/user-settings-backend/package.json b/plugins/user-settings-backend/package.json index 88c7533b11..3f0f5b6467 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.25-next.0", + "version": "0.2.25-next.2", "description": "The Backstage backend plugin to manage user settings", "backstage": { "role": "backend-plugin", diff --git a/plugins/user-settings/CHANGELOG.md b/plugins/user-settings/CHANGELOG.md index de1d1b4210..acfdf800cf 100644 --- a/plugins/user-settings/CHANGELOG.md +++ b/plugins/user-settings/CHANGELOG.md @@ -1,5 +1,42 @@ # @backstage/plugin-user-settings +## 0.8.14-next.2 + +### Patch Changes + +- 0040632: `useUserProfile` will now use the user's picture stored in the catalog as a fallback if the identity provider doesn't return a picture. +- Updated dependencies + - @backstage/plugin-catalog-react@1.14.0-next.2 + - @backstage/theme@0.6.0-next.1 + - @backstage/catalog-model@1.7.0 + - @backstage/core-app-api@1.15.1-next.1 + - @backstage/core-compat-api@0.3.1-next.2 + - @backstage/core-components@0.15.1-next.2 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.9.0-next.2 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.6-next.1 + - @backstage/plugin-user-settings-common@0.0.1 + +## 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 diff --git a/plugins/user-settings/dev/index.tsx b/plugins/user-settings/dev/index.tsx index 90be1e3bad..d7041e96a8 100644 --- a/plugins/user-settings/dev/index.tsx +++ b/plugins/user-settings/dev/index.tsx @@ -17,10 +17,37 @@ import React from 'react'; import { CatalogEntityPage } from '@backstage/plugin-catalog'; import { createDevApp } from '@backstage/dev-utils'; -import { userSettingsPlugin, UserSettingsPage } from '../src/plugin'; +import { UserSettingsPage, userSettingsPlugin } from '../src'; +import { CatalogApi, catalogApiRef } from '@backstage/plugin-catalog-react'; +import { + CompoundEntityRef, + Entity, + UserEntity, +} from '@backstage/catalog-model'; +const userEntity: UserEntity = { + apiVersion: 'backstage.io/v1beta1', + kind: 'User', + metadata: { + name: 'Guest', + }, + spec: {}, +}; createDevApp() .registerPlugin(userSettingsPlugin) + .registerApi({ + api: catalogApiRef, + deps: {}, + factory() { + return { + async getEntityByRef( + _: string | CompoundEntityRef, + ): Promise { + return userEntity; + }, + } as Partial as unknown as CatalogApi; + }, + }) .addPage({ title: 'Settings', path: '/settings', diff --git a/plugins/user-settings/package.json b/plugins/user-settings/package.json index 4c20c2f0f3..309c4f4899 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.13-next.0", + "version": "0.8.14-next.2", "description": "A Backstage plugin that provides a settings page", "backstage": { "role": "frontend-plugin", @@ -55,6 +55,7 @@ "test": "backstage-cli package test" }, "dependencies": { + "@backstage/catalog-model": "workspace:^", "@backstage/core-app-api": "workspace:^", "@backstage/core-compat-api": "workspace:^", "@backstage/core-components": "workspace:^", @@ -69,7 +70,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" }, @@ -82,13 +82,23 @@ "@testing-library/jest-dom": "^6.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/src/components/DefaultSettingsPage/DefaultSettingsPage.test.tsx b/plugins/user-settings/src/components/DefaultSettingsPage/DefaultSettingsPage.test.tsx index e31c9f26fd..14b7b7b48b 100644 --- a/plugins/user-settings/src/components/DefaultSettingsPage/DefaultSettingsPage.test.tsx +++ b/plugins/user-settings/src/components/DefaultSettingsPage/DefaultSettingsPage.test.tsx @@ -15,24 +15,33 @@ */ import React from 'react'; -import { renderInTestApp } from '@backstage/test-utils'; +import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; import { DefaultSettingsPage } from './DefaultSettingsPage'; import { UserSettingsTab } from '../UserSettingsTab'; import { useOutlet } from 'react-router-dom'; import { SettingsLayout } from '../SettingsLayout'; +import { CatalogApi, catalogApiRef } from '@backstage/plugin-catalog-react'; jest.mock('react-router-dom', () => ({ ...jest.requireActual('react-router-dom'), useOutlet: jest.fn().mockReturnValue(undefined), })); +const catalogApiMock: jest.Mocked = { + getEntityByRef: jest.fn(), +} as any; + describe('', () => { beforeEach(() => { (useOutlet as jest.Mock).mockReset(); }); it('should render the settings page with 3 tabs', async () => { - const { container } = await renderInTestApp(); + const { container } = await renderInTestApp( + + + , + ); const tabs = container.querySelectorAll('[class*=MuiTabs-root] a'); expect(tabs).toHaveLength(3); @@ -45,7 +54,9 @@ describe('', () => { ); const { container } = await renderInTestApp( - , + + + , ); const tabs = container.querySelectorAll('[class*=MuiTabs-root] a'); @@ -60,7 +71,9 @@ describe('', () => { ); const { container } = await renderInTestApp( - , + + + , ); const tabs = container.querySelectorAll('[class*=MuiTabs-root] a'); diff --git a/plugins/user-settings/src/components/General/UserSettingsIdentityCard.test.tsx b/plugins/user-settings/src/components/General/UserSettingsIdentityCard.test.tsx index 1be797980b..b1a811d7fa 100644 --- a/plugins/user-settings/src/components/General/UserSettingsIdentityCard.test.tsx +++ b/plugins/user-settings/src/components/General/UserSettingsIdentityCard.test.tsx @@ -20,19 +20,27 @@ import React from 'react'; import { UserSettingsIdentityCard } from './UserSettingsIdentityCard'; import { ApiProvider } from '@backstage/core-app-api'; import { identityApiRef } from '@backstage/core-plugin-api'; -import { entityRouteRef } from '@backstage/plugin-catalog-react'; +import { catalogApiRef, entityRouteRef } from '@backstage/plugin-catalog-react'; -const apiRegistry = TestApiRegistry.from([ - identityApiRef, - { - getProfileInfo: jest.fn(async () => ({})), - getBackstageIdentity: jest.fn(async () => ({ - type: 'user' as const, - userEntityRef: 'foo:bar/foobar', - ownershipEntityRefs: ['user:default/test-ownership'], - })), - }, -]); +const apiRegistry = TestApiRegistry.from( + [ + identityApiRef, + { + getProfileInfo: jest.fn(async () => ({})), + getBackstageIdentity: jest.fn(async () => ({ + type: 'user' as const, + userEntityRef: 'foo:bar/foobar', + ownershipEntityRefs: ['user:default/test-ownership'], + })), + }, + ], + [ + catalogApiRef, + { + getEntityByRef: jest.fn(), + }, + ], +); describe('', () => { it('displays an identity card', async () => { diff --git a/plugins/user-settings/src/components/General/UserSettingsProfileCard.test.tsx b/plugins/user-settings/src/components/General/UserSettingsProfileCard.test.tsx new file mode 100644 index 0000000000..582daadad7 --- /dev/null +++ b/plugins/user-settings/src/components/General/UserSettingsProfileCard.test.tsx @@ -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 { renderInTestApp, TestApiRegistry } from '@backstage/test-utils'; +import { screen } from '@testing-library/react'; +import React from 'react'; +import { identityApiRef } from '@backstage/core-plugin-api'; +import { catalogApiRef, entityRouteRef } from '@backstage/plugin-catalog-react'; +import { ApiProvider } from '@backstage/core-app-api'; +import { UserSettingsProfileCard } from './UserSettingsProfileCard'; + +const apiRegistry = TestApiRegistry.from( + [ + identityApiRef, + { + getProfileInfo: jest.fn(async () => ({})), + getBackstageIdentity: jest.fn(async () => ({ + type: 'user' as const, + userEntityRef: 'foo:bar/foobar', + ownershipEntityRefs: ['user:default/test-ownership'], + })), + }, + ], + [ + catalogApiRef, + { + getEntityByRef: jest.fn(async () => { + return { + apiVersion: 'backstage.io/v1beta1', + kind: 'User', + metadata: { + name: 'Guest', + annotations: {}, + }, + spec: { + profile: { + picture: 'https://example.com/avatar.png', + }, + }, + }; + }), + }, + ], +); + +describe('', () => { + it('displays avatar if it exists in user entity', async () => { + await renderInTestApp( + + + , + { + mountedRoutes: { '/catalog/:namespace/:kind/:name': entityRouteRef }, + }, + ); + expect(screen.getByAltText('Profile picture')).toHaveAttribute( + 'src', + 'https://example.com/avatar.png', + ); + }); +}); diff --git a/plugins/user-settings/src/components/SettingsPage/SettingsPage.test.tsx b/plugins/user-settings/src/components/SettingsPage/SettingsPage.test.tsx index d4b941c850..acdb6c3f87 100644 --- a/plugins/user-settings/src/components/SettingsPage/SettingsPage.test.tsx +++ b/plugins/user-settings/src/components/SettingsPage/SettingsPage.test.tsx @@ -15,29 +15,42 @@ */ import React from 'react'; -import { renderInTestApp } from '@backstage/test-utils'; +import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; import { SettingsPage } from './SettingsPage'; import { UserSettingsTab } from '../UserSettingsTab'; import { useOutlet } from 'react-router-dom'; import { SettingsLayout } from '../SettingsLayout'; import { screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { entityRouteRef } from '@backstage/plugin-catalog-react'; +import { + CatalogApi, + catalogApiRef, + entityRouteRef, +} from '@backstage/plugin-catalog-react'; jest.mock('react-router-dom', () => ({ ...jest.requireActual('react-router-dom'), useOutlet: jest.fn().mockReturnValue(undefined), })); +const catalogApiMock: jest.Mocked = { + getEntityByRef: jest.fn(), +} as any; + describe('', () => { beforeEach(() => { (useOutlet as jest.Mock).mockReset(); }); it('should render the default settings page with 3 tabs', async () => { - const { container } = await renderInTestApp(, { - mountedRoutes: { '/catalog/:namespace/:kind/:name': entityRouteRef }, - }); + const { container } = await renderInTestApp( + + + , + { + mountedRoutes: { '/catalog/:namespace/:kind/:name': entityRouteRef }, + }, + ); const tabs = container.querySelectorAll('[class*=MuiTabs-root] a'); expect(tabs).toHaveLength(3); @@ -50,9 +63,14 @@ describe('', () => { ); (useOutlet as jest.Mock).mockReturnValue(advancedTabRoute); - const { container } = await renderInTestApp(, { - mountedRoutes: { '/catalog/:namespace/:kind/:name': entityRouteRef }, - }); + const { container } = await renderInTestApp( + + + , + { + mountedRoutes: { '/catalog/:namespace/:kind/:name': entityRouteRef }, + }, + ); const tabs = container.querySelectorAll('[class*=MuiTabs-root] a'); expect(tabs).toHaveLength(4); @@ -66,9 +84,14 @@ describe('', () => { ); (useOutlet as jest.Mock).mockReturnValue(advancedTabRoute); - const { container } = await renderInTestApp(, { - mountedRoutes: { '/catalog/:namespace/:kind/:name': entityRouteRef }, - }); + const { container } = await renderInTestApp( + + + , + { + mountedRoutes: { '/catalog/:namespace/:kind/:name': entityRouteRef }, + }, + ); const tabs = container.querySelectorAll('[class*=MuiTabs-root] a'); expect(tabs).toHaveLength(4); @@ -91,9 +114,14 @@ describe('', () => { ); (useOutlet as jest.Mock).mockReturnValue(customLayout); - const { container } = await renderInTestApp(, { - mountedRoutes: { '/catalog/:namespace/:kind/:name': entityRouteRef }, - }); + const { container } = await renderInTestApp( + + + , + { + mountedRoutes: { '/catalog/:namespace/:kind/:name': entityRouteRef }, + }, + ); const tabs = container.querySelectorAll('[class*=MuiTabs-root] a'); expect(tabs).toHaveLength(2); diff --git a/plugins/user-settings/src/components/useUserProfileInfo.ts b/plugins/user-settings/src/components/useUserProfileInfo.ts index ee4578cd6b..e368b9e688 100644 --- a/plugins/user-settings/src/components/useUserProfileInfo.ts +++ b/plugins/user-settings/src/components/useUserProfileInfo.ts @@ -22,16 +22,33 @@ import { } from '@backstage/core-plugin-api'; import { useEffect } from 'react'; import useAsync from 'react-use/esm/useAsync'; +import { catalogApiRef } from '@backstage/plugin-catalog-react'; +import { UserEntity } from '@backstage/catalog-model'; /** @public */ export const useUserProfile = () => { const identityApi = useApi(identityApiRef); const alertApi = useApi(alertApiRef); + const catalogApi = useApi(catalogApiRef); const { value, loading, error } = useAsync(async () => { + let identityProfile = await identityApi.getProfileInfo(); + const backStageIdentity = await identityApi.getBackstageIdentity(); + const catalogProfile = (await catalogApi.getEntityByRef( + backStageIdentity.userEntityRef, + )) as unknown as UserEntity; + if ( + identityProfile.picture === undefined && + catalogProfile?.spec?.profile?.picture + ) { + identityProfile = { + ...identityProfile, + picture: catalogProfile.spec.profile.picture, + }; + } return { - profile: await identityApi.getProfileInfo(), - identity: await identityApi.getBackstageIdentity(), + profile: identityProfile, + identity: backStageIdentity, }; }, []); diff --git a/yarn.lock b/yarn.lock index 2544f782b9..6862360cca 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1891,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: @@ -2975,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: @@ -2986,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: @@ -3390,22 +3390,22 @@ __metadata: languageName: node linkType: hard -"@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 +"@backstage-community/plugin-explore-common@npm:^0.0.6": + version: 0.0.6 + resolution: "@backstage-community/plugin-explore-common@npm:0.0.6" + checksum: f476264bec3b5471619f19fe16e0af13bd86be933f4922461056dff01de9d6efdb17246856cee649046299c763a2b10ceb9652215558c2d7c077385407449b31 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 @@ -3413,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 @@ -3432,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 @@ -3451,11 +3451,18 @@ __metadata: "@material-ui/icons": ^4.9.1 "@testing-library/jest-dom": ^6.0.0 "@testing-library/react": ^16.0.0 - "@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 @@ -3483,7 +3490,7 @@ __metadata: "@types/node-forge": ^1.3.0 "@types/stoppable": ^1.1.0 compression: ^1.7.4 - cookie: ^0.6.0 + cookie: ^0.7.0 cors: ^2.8.5 express: ^4.17.1 express-promise-router: ^4.1.0 @@ -3638,13 +3645,13 @@ __metadata: better-sqlite3: ^11.0.0 compression: ^1.7.4 concat-stream: ^2.0.0 - cookie: ^0.6.0 + cookie: ^0.7.0 cors: ^2.8.5 cron: ^3.0.0 express: ^4.17.1 express-promise-router: ^4.1.0 fs-extra: ^11.2.0 - git-url-parse: ^14.0.0 + git-url-parse: ^15.0.0 helmet: ^6.0.0 http-errors: ^2.0.0 isomorphic-git: ^1.23.0 @@ -3731,16 +3738,23 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/backend-openapi-utils@workspace:packages/backend-openapi-utils" dependencies: + "@apidevtools/swagger-parser": ^10.1.0 "@backstage/backend-plugin-api": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/errors": "workspace:^" + "@backstage/test-utils": "workspace:^" + "@backstage/types": "workspace:^" "@types/express": ^4.17.6 "@types/express-serve-static-core": ^4.17.5 + ajv: ^8.16.0 express: ^4.17.1 express-openapi-validator: ^5.0.4 express-promise-router: ^4.1.0 + get-port: ^5.1.1 json-schema-to-ts: ^3.0.0 lodash: ^4.17.21 + mockttp: ^3.13.0 + msw: ^1.0.0 openapi-merge: ^1.3.2 openapi3-ts: ^3.1.2 supertest: ^7.0.0 @@ -3807,7 +3821,7 @@ __metadata: "@types/qs": ^6.9.6 "@types/supertest": ^2.0.8 better-sqlite3: ^11.0.0 - cookie: ^0.6.0 + cookie: ^0.7.0 express: ^4.17.1 fs-extra: ^11.0.0 keyv: ^4.5.2 @@ -3826,7 +3840,19 @@ __metadata: languageName: unknown linkType: soft -"@backstage/catalog-client@^1.7.0, @backstage/catalog-client@workspace:^, @backstage/catalog-client@workspace:packages/catalog-client": +"@backstage/catalog-client@npm:^1.7.0": + version: 1.7.0 + resolution: "@backstage/catalog-client@npm:1.7.0" + dependencies: + "@backstage/catalog-model": ^1.7.0 + "@backstage/errors": ^1.2.4 + cross-fetch: ^4.0.0 + uri-template: ^2.0.0 + checksum: 66a0570c57281fbf7b59786ebf2dd97efbb5c7c7393025e14a605d38f1bf2317974c319da138146e21d31ac83c3214223631211ebbee36fc96c84bd803acd913 + languageName: node + linkType: hard + +"@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: @@ -3839,7 +3865,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/catalog-model@^1.4.3, @backstage/catalog-model@^1.6.0, @backstage/catalog-model@^1.7.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: @@ -3974,13 +4000,14 @@ __metadata: express: ^4.17.1 fork-ts-checker-webpack-plugin: ^9.0.0 fs-extra: ^11.2.0 - git-url-parse: ^14.0.0 + git-url-parse: ^15.0.0 glob: ^7.1.7 global-agent: ^3.0.0 handlebars: ^4.7.3 html-webpack-plugin: ^5.3.1 inquirer: ^8.2.0 jest: ^29.7.0 + jest-cli: ^29.7.0 jest-css-modules: ^2.1.0 jest-environment-jsdom: ^29.0.2 jest-runtime: ^29.0.2 @@ -4025,6 +4052,7 @@ __metadata: webpack-dev-server: ^5.0.0 webpack-node-externals: ^3.0.0 yaml: ^2.0.0 + yargs: ^16.2.0 yml-loader: ^2.1.0 yn: ^4.0.0 zod: ^3.22.4 @@ -4119,14 +4147,17 @@ __metadata: "@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" @@ -4134,9 +4165,13 @@ __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 @@ -4175,12 +4210,20 @@ __metadata: "@oriflame/backstage-plugin-score-card": ^0.8.0 "@testing-library/jest-dom": ^6.0.0 "@testing-library/react": ^16.0.0 - "@types/react": ^16.13.1 || ^17.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 @@ -4235,55 +4278,6 @@ __metadata: languageName: node linkType: hard -"@backstage/core-components@npm:^0.14.10": - version: 0.14.10 - resolution: "@backstage/core-components@npm:0.14.10" - dependencies: - "@backstage/config": ^1.2.0 - "@backstage/core-plugin-api": ^1.9.3 - "@backstage/errors": ^1.2.4 - "@backstage/theme": ^0.5.6 - "@backstage/version-bridge": ^1.0.8 - "@date-io/core": ^1.3.13 - "@material-table/core": ^3.1.0 - "@material-ui/core": ^4.12.2 - "@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 - d3-selection: ^3.0.0 - d3-shape: ^3.0.0 - d3-zoom: ^3.0.0 - dagre: ^0.8.5 - linkify-react: 4.1.3 - linkifyjs: 4.1.3 - lodash: ^4.17.21 - pluralize: ^8.0.0 - qs: ^6.9.4 - rc-progress: 3.5.1 - react-helmet: 6.1.0 - react-hook-form: ^7.12.2 - react-idle-timer: 5.7.2 - react-markdown: ^8.0.0 - react-sparklines: ^1.7.0 - react-syntax-highlighter: ^15.4.5 - react-use: ^17.3.2 - react-virtualized-auto-sizer: ^1.0.11 - react-window: ^1.8.6 - remark-gfm: ^3.0.1 - 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 - checksum: 303682d411b846a4892b27c1064d499dbd4eccb5a3cdc5acbb1d3247e1141f4704efc7bd286744c19818487e52a61891943156817f59e3bd6555926f7331f575 - languageName: node - linkType: hard - "@backstage/core-components@npm:^0.15.0": version: 0.15.0 resolution: "@backstage/core-components@npm:0.15.0" @@ -4363,7 +4357,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 @@ -4385,10 +4379,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 @@ -4398,13 +4395,17 @@ __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@npm:^1.8.2, @backstage/core-plugin-api@npm:^1.9.3, @backstage/core-plugin-api@npm:^1.9.4": +"@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: @@ -4437,12 +4438,19 @@ __metadata: "@testing-library/jest-dom": ^6.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 @@ -4493,13 +4501,20 @@ __metadata: "@testing-library/jest-dom": ^6.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 @@ -4559,12 +4574,20 @@ __metadata: "@backstage/version-bridge": "workspace:^" "@testing-library/jest-dom": ^6.0.0 "@testing-library/react": ^16.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.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 @@ -4583,9 +4606,18 @@ __metadata: "@react-hookz/web": ^24.0.0 "@testing-library/jest-dom": ^6.0.0 "@testing-library/react": ^16.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 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 @@ -4624,14 +4656,22 @@ __metadata: "@material-ui/core": ^4.12.4 "@testing-library/jest-dom": ^6.0.0 "@testing-library/react": ^16.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.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 @@ -4648,12 +4688,21 @@ __metadata: "@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": ^16.0.0 + "@types/jest": "*" + "@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 @@ -4676,9 +4725,9 @@ __metadata: languageName: unknown linkType: soft -"@backstage/integration-react@npm:^1.1.31": - version: 1.1.31 - resolution: "@backstage/integration-react@npm:1.1.31" +"@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 @@ -4690,7 +4739,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: a31313bc3cd2189535eee6150ad49963f3172fa33d1c1f1c7f93e46b891c67ead9e0ea810bcfcbd6dc5ceabebb2036b0d562ec2088b0559d48c22e8b65e09bd1 + checksum: d26362ad3a8a6c8ac41b3eadf9c6d5b01e3cef3ca3e38a86bbf7b1c5e1b6e8ba5e940e74d31006faf0640a366ba8c5deb0ca6cbc58099d5f51fae6a7484944d6 languageName: node linkType: hard @@ -4709,16 +4758,40 @@ __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@^1.15.0, @backstage/integration@workspace:^, @backstage/integration@workspace:packages/integration": +"@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" dependencies: @@ -4731,7 +4804,7 @@ __metadata: "@octokit/rest": ^19.0.3 "@types/luxon": ^3.0.0 cross-fetch: ^4.0.0 - git-url-parse: ^14.0.0 + git-url-parse: ^15.0.0 lodash: ^4.17.21 luxon: ^3.0.0 msw: ^1.0.0 @@ -4744,12 +4817,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 @@ -4780,18 +4860,25 @@ __metadata: "@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 @@ -4850,11 +4937,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 @@ -4876,13 +4970,20 @@ __metadata: "@testing-library/jest-dom": ^6.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 @@ -5382,6 +5483,7 @@ __metadata: winston: ^3.2.1 zod: ^3.22.4 zod-to-json-schema: ^3.21.4 + zod-validation-error: ^3.4.0 languageName: unknown linkType: soft @@ -5399,10 +5501,19 @@ __metadata: "@testing-library/jest-dom": ^6.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 @@ -5493,7 +5604,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": ^0.25.0 "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" "@backstage/catalog-client": "workspace:^" @@ -5601,7 +5711,7 @@ __metadata: "@octokit/graphql": ^5.0.0 "@octokit/rest": ^19.0.3 "@types/lodash": ^4.14.151 - git-url-parse: ^14.0.0 + git-url-parse: ^15.0.0 lodash: ^4.17.21 luxon: ^3.0.0 minimatch: ^9.0.0 @@ -5850,7 +5960,7 @@ __metadata: express: ^4.17.1 fast-json-stable-stringify: ^2.1.0 fs-extra: ^11.2.0 - git-url-parse: ^14.0.0 + git-url-parse: ^15.0.0 glob: ^7.1.6 knex: ^3.0.0 lodash: ^4.17.21 @@ -5905,16 +6015,23 @@ __metadata: "@testing-library/jest-dom": ^6.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 @@ -5947,18 +6064,25 @@ __metadata: "@testing-library/jest-dom": ^6.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 - git-url-parse: ^14.0.0 + "@types/react": ^18.0.0 + git-url-parse: ^15.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 @@ -5979,9 +6103,9 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-catalog-react@npm:^1.12.3, @backstage/plugin-catalog-react@npm:^1.9.3": - version: 1.13.0 - resolution: "@backstage/plugin-catalog-react@npm:1.13.0" +"@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.7.0 "@backstage/catalog-model": ^1.7.0 @@ -5990,7 +6114,7 @@ __metadata: "@backstage/core-plugin-api": ^1.9.4 "@backstage/errors": ^1.2.4 "@backstage/frontend-plugin-api": ^0.8.0 - "@backstage/integration-react": ^1.1.31 + "@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.26 @@ -6012,7 +6136,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: e86fdfdab9f2b0fcbc68b0521acbc3c2ba95ab4206aabb09f307021960776f0aca6335cdb47b27c506b4a32f88768716839fe1e09e156d8970414da94992f0b9 + checksum: d41f4d3a72f17be6a9019a4d8acaeb9d3198e2b1d0e25bd28efb3b5617d301a5798e259d4bcc077351d76e1c130e565344564bf987f4079f4b4bc040ae7a9878 languageName: node linkType: hard @@ -6046,20 +6170,27 @@ __metadata: "@testing-library/jest-dom": ^6.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 @@ -6087,13 +6218,20 @@ __metadata: "@material-ui/lab": ^4.0.0-alpha.60 "@testing-library/jest-dom": ^6.0.0 "@testing-library/react": ^16.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.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 @@ -6131,19 +6269,26 @@ __metadata: "@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 @@ -6163,14 +6308,21 @@ __metadata: "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 "@testing-library/react": ^16.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.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 @@ -6237,13 +6389,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 @@ -6388,12 +6547,19 @@ __metadata: "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@rjsf/utils": 5.21.1 - "@types/react": ^16.13.1 || ^17.0.0 + "@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 @@ -6426,18 +6592,25 @@ __metadata: "@testing-library/jest-dom": ^6.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 @@ -6508,7 +6681,7 @@ __metadata: "@backstage/plugin-kubernetes-common": "workspace:^" "@backstage/plugin-kubernetes-react": "workspace:^" "@backstage/test-utils": "workspace:^" - "@kubernetes-models/apimachinery": ^1.1.0 + "@kubernetes-models/apimachinery": ^2.0.0 "@kubernetes-models/base": ^5.0.0 "@material-ui/core": ^4.12.2 "@material-ui/lab": 4.0.0-alpha.61 @@ -6516,17 +6689,24 @@ __metadata: "@testing-library/jest-dom": ^6.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 @@ -6580,7 +6760,7 @@ __metadata: "@backstage/plugin-kubernetes-common": "workspace:^" "@backstage/test-utils": "workspace:^" "@backstage/types": "workspace:^" - "@kubernetes-models/apimachinery": ^1.1.0 + "@kubernetes-models/apimachinery": ^2.0.0 "@kubernetes-models/base": ^5.0.0 "@kubernetes/client-node": ^0.20.0 "@material-ui/core": ^4.9.13 @@ -6588,7 +6768,7 @@ __metadata: "@material-ui/lab": ^4.0.0-alpha.61 "@testing-library/jest-dom": ^6.0.0 "@testing-library/react": ^16.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + "@types/react": ^18.0.0 cronstrue: ^2.32.0 jest-websocket-mock: ^2.5.0 js-yaml: ^4.1.0 @@ -6596,12 +6776,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 @@ -6620,26 +6809,33 @@ __metadata: "@backstage/plugin-kubernetes-common": "workspace:^" "@backstage/plugin-kubernetes-react": "workspace:^" "@backstage/test-utils": "workspace:^" - "@kubernetes-models/apimachinery": ^1.1.0 + "@kubernetes-models/apimachinery": ^2.0.0 "@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": ^16.0.0 - "@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 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 @@ -6757,16 +6953,24 @@ __metadata: "@testing-library/jest-dom": ^6.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 @@ -6789,12 +6993,19 @@ __metadata: "@testing-library/jest-dom": ^6.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 @@ -6825,16 +7036,23 @@ __metadata: "@testing-library/jest-dom": ^6.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 @@ -6946,12 +7164,19 @@ __metadata: "@backstage/test-utils": "workspace:^" "@testing-library/jest-dom": ^6.0.0 "@testing-library/react": ^16.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 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 @@ -6998,7 +7223,7 @@ __metadata: "@backstage/integration": "workspace:^" "@backstage/plugin-scaffolder-node": "workspace:^" "@backstage/plugin-scaffolder-node-test-utils": "workspace:^" - azure-devops-node-api: ^12.0.0 + azure-devops-node-api: ^14.0.0 yaml: ^2.0.0 languageName: unknown linkType: soft @@ -7077,7 +7302,7 @@ __metadata: "@backstage/plugin-scaffolder-node": "workspace:^" "@backstage/plugin-scaffolder-node-test-utils": "workspace:^" fs-extra: ^11.2.0 - git-url-parse: ^14.0.0 + git-url-parse: ^15.0.0 msw: ^1.0.0 node-fetch: ^2.7.0 node-html-markdown: ^1.3.0 @@ -7376,7 +7601,18 @@ __metadata: "@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 @@ -7443,7 +7679,7 @@ __metadata: "@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 @@ -7453,6 +7689,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 @@ -7460,9 +7699,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 @@ -7509,12 +7752,12 @@ __metadata: "@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 + git-url-parse: ^15.0.0 humanize-duration: ^3.25.1 idb-keyval: 5.0.2 json-schema: ^0.4.0 @@ -7524,7 +7767,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 @@ -7533,9 +7779,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 @@ -7586,7 +7836,7 @@ __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.5 + "@backstage-community/plugin-explore-common": ^0.0.6 "@backstage/backend-common": ^0.25.0 "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" @@ -7742,14 +7992,21 @@ __metadata: "@testing-library/jest-dom": ^6.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 @@ -7777,14 +8034,21 @@ __metadata: "@testing-library/jest-dom": ^6.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 @@ -7850,8 +8114,18 @@ __metadata: "@material-ui/core": ^4.12.4 "@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 + "@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 @@ -7874,12 +8148,22 @@ __metadata: "@testing-library/jest-dom": ^6.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 @@ -7899,13 +8183,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": ^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 @@ -7969,13 +8260,20 @@ __metadata: "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 "@testing-library/react": ^16.0.0 - "@types/react": ^16.13.1 || ^17.0.0 - git-url-parse: ^14.0.0 + "@types/react": ^18.0.0 + git-url-parse: ^15.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 @@ -8000,7 +8298,7 @@ __metadata: "@backstage/plugin-search-common": "workspace:^" "@backstage/plugin-techdocs-common": "workspace:^" "@google-cloud/storage": ^7.0.0 - "@smithy/node-http-handler": ^2.1.7 + "@smithy/node-http-handler": ^3.0.0 "@trendyol-js/openstack-swift-sdk": ^0.0.7 "@types/express": ^4.17.6 "@types/fs-extra": ^11.0.0 @@ -8012,7 +8310,7 @@ __metadata: dockerode: ^4.0.0 express: ^4.17.1 fs-extra: ^11.2.0 - git-url-parse: ^14.0.0 + git-url-parse: ^15.0.0 hpagent: ^1.2.0 js-yaml: ^4.0.0 json5: ^2.1.3 @@ -8040,15 +8338,22 @@ __metadata: "@material-ui/styles": ^4.11.0 "@testing-library/jest-dom": ^6.0.0 "@testing-library/react": ^16.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.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 @@ -8087,18 +8392,25 @@ __metadata: "@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 + git-url-parse: ^15.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 @@ -8138,6 +8450,7 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-user-settings@workspace:plugins/user-settings" dependencies: + "@backstage/catalog-model": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/core-app-api": "workspace:^" "@backstage/core-compat-api": "workspace:^" @@ -8160,14 +8473,21 @@ __metadata: "@testing-library/jest-dom": ^6.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 @@ -8256,20 +8576,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": ^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@^0.5.7, @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: @@ -8280,12 +8623,19 @@ __metadata: "@mui/styles": ^5.14.18 "@testing-library/jest-dom": ^6.0.0 "@testing-library/react": ^16.0.0 - "@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: "@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 @@ -8300,18 +8650,38 @@ __metadata: languageName: unknown linkType: soft -"@backstage/version-bridge@^1.0.7, @backstage/version-bridge@^1.0.8, @backstage/version-bridge@^1.0.9, @backstage/version-bridge@workspace:^, @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: + "@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": ^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 @@ -8409,8 +8779,8 @@ __metadata: linkType: hard "@changesets/cli@npm:^2.14.0": - version: 2.27.8 - resolution: "@changesets/cli@npm:2.27.8" + version: 2.27.9 + resolution: "@changesets/cli@npm:2.27.9" dependencies: "@changesets/apply-release-plan": ^7.0.5 "@changesets/assemble-release-plan": ^6.0.4 @@ -8427,14 +8797,12 @@ __metadata: "@changesets/types": ^6.0.0 "@changesets/write": ^0.3.2 "@manypkg/get-packages": ^1.1.3 - "@types/semver": ^7.5.0 ansi-colors: ^4.1.3 ci-info: ^3.7.0 enquirer: ^2.3.0 external-editor: ^3.1.0 fs-extra: ^7.0.1 mri: ^1.2.0 - outdent: ^0.5.0 p-limit: ^2.2.0 package-manager-detector: ^0.2.0 picocolors: ^1.1.0 @@ -8444,7 +8812,7 @@ __metadata: term-size: ^2.1.0 bin: changeset: bin.js - checksum: b58386716b337976d5797debd4a418fb257bec1e6c9932b99eac7725dd5a76fceff32691c625f897fd4baa78aa2bfba9747fbacf7d8193197f9246b36d31c013 + checksum: 4bd36c152f9f93716b001f3ed849717588d2a9eb97f058e86f95ba6a43d8e4311073174251150aabb96f0a1ab5f8ab5ee6a32f85fc9248363f92b3826227cb9d languageName: node linkType: hard @@ -8630,8 +8998,8 @@ __metadata: linkType: hard "@codemirror/language@npm:^6.0.0": - version: 6.10.2 - resolution: "@codemirror/language@npm:6.10.2" + version: 6.10.3 + resolution: "@codemirror/language@npm:6.10.3" dependencies: "@codemirror/state": ^6.0.0 "@codemirror/view": ^6.23.0 @@ -8639,7 +9007,7 @@ __metadata: "@lezer/highlight": ^1.0.0 "@lezer/lr": ^1.0.0 style-mod: ^4.0.0 - checksum: 4e60afb75fb56519f59d9d85e0aa03f0c8d017e0da0f3f8f321baf35a776801fcec9787f3d0c029eba12aa766fba98b0fe86fc3111b43e0812b554184c0e8d67 + checksum: 53fb72299500f63706f78c888d6b5fd81043ea11ea2fa4c72c13c6d4794bb6f4ec29450208c56b4f40e839984b3dc73505262803fa61416baf588da389a7c577 languageName: node linkType: hard @@ -8694,13 +9062,13 @@ __metadata: linkType: hard "@codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.23.0": - version: 6.33.0 - resolution: "@codemirror/view@npm:6.33.0" + version: 6.34.1 + resolution: "@codemirror/view@npm:6.34.1" dependencies: "@codemirror/state": ^6.4.0 style-mod: ^4.1.0 w3c-keyname: ^2.2.4 - checksum: e28896a7fb40df8e7221fbebfc2cd92c10c6963948e20f3a4300e99c897fbddd091f4fc90cc30eeaf90d07c61dcf6170cd3c164810606fa07337ffb970ffdac2 + checksum: 5c7bf199f0b45a3cc192f08c2ac89e5ab972f313cb4f2c979edf6e05b27bccd60c6cb42d5dacb6813ef3a928d75476eb0a00ffdeffd7431c8e9f44bab4f6e12e languageName: node linkType: hard @@ -9960,12 +10328,12 @@ __metadata: languageName: node linkType: hard -"@httptoolkit/httpolyglot@npm:^2.0.1, @httptoolkit/httpolyglot@npm:^2.1.1": - version: 2.1.1 - resolution: "@httptoolkit/httpolyglot@npm:2.1.1" +"@httptoolkit/httpolyglot@npm:^2.0.1, @httptoolkit/httpolyglot@npm:^2.2.1": + version: 2.2.1 + resolution: "@httptoolkit/httpolyglot@npm:2.2.1" dependencies: - "@types/node": ^16.7.10 - checksum: 138ccd61355de334c509e2fc4ac9ade9e1aa6aa770ed2271e0bd1d883ed815eb742d0a4de37837edd03a9a243c05d6da32c5febe970f4518c46e2d76e6ff10d5 + "@types/node": "*" + checksum: 5b3882657e37953bd7089d91ac6cd24cec36480deab114e6b69a4b3d9e4ab09db568500e5e96713869fb4a8fe40b5ecc1661cc39ee621ef40ed0e38b55e0257e languageName: node linkType: hard @@ -10156,12 +10524,19 @@ __metadata: "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 "@testing-library/react": ^16.0.0 - "@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 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 @@ -10590,17 +10965,6 @@ __metadata: languageName: node linkType: hard -"@kubernetes-models/apimachinery@npm:^1.1.0": - version: 1.2.2 - resolution: "@kubernetes-models/apimachinery@npm:1.2.2" - dependencies: - "@kubernetes-models/base": ^4.0.4 - "@kubernetes-models/validate": ^3.1.2 - tslib: ^2.4.0 - checksum: 57387bb8a1f43b740506877d2557a188122512dd2f05c54e3076e0d6cf9a2112f7c5cbbba762c8f4fee22845fcf1302b97537a9e24cfd18b6a99d51a1360136a - languageName: node - linkType: hard - "@kubernetes-models/apimachinery@npm:^2.0.0": version: 2.0.0 resolution: "@kubernetes-models/apimachinery@npm:2.0.0" @@ -10612,17 +10976,6 @@ __metadata: languageName: node linkType: hard -"@kubernetes-models/base@npm:^4.0.4": - version: 4.0.4 - resolution: "@kubernetes-models/base@npm:4.0.4" - dependencies: - "@kubernetes-models/validate": ^3.1.2 - is-plain-object: ^5.0.0 - tslib: ^2.4.0 - checksum: 15d531118e8a85eda8fd9602de4ba0e61e794d52218df7acb9842fe3c2fad5e788f3468768e8287405c6228625cce5cb1d91d923499e401a1a0f55287b2e6b5a - languageName: node - linkType: hard - "@kubernetes-models/base@npm:^5.0.0": version: 5.0.0 resolution: "@kubernetes-models/base@npm:5.0.0" @@ -10634,18 +10987,6 @@ __metadata: languageName: node linkType: hard -"@kubernetes-models/validate@npm:^3.1.2": - version: 3.1.2 - resolution: "@kubernetes-models/validate@npm:3.1.2" - dependencies: - ajv: ^8.12.0 - ajv-formats: ^2.1.1 - ajv-formats-draft2019: ^1.6.1 - tslib: ^2.4.0 - checksum: 44bd7e45aa9716448532f5afc6510398a7eed77c23df67acd94acde4e940c3284a879cc62372fb3dcb67c12d2d10e43900bdd98bc39d1177492c9f2d48b63d4e - languageName: node - linkType: hard - "@kubernetes-models/validate@npm:^4.0.0": version: 4.0.0 resolution: "@kubernetes-models/validate@npm:4.0.0" @@ -11328,9 +11669,9 @@ __metadata: languageName: node linkType: hard -"@mswjs/interceptors@npm:^0.35.6": - version: 0.35.6 - resolution: "@mswjs/interceptors@npm:0.35.6" +"@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 @@ -11338,7 +11679,7 @@ __metadata: is-node-process: ^1.2.0 outvariant: ^1.4.3 strict-event-emitter: ^0.5.1 - checksum: aee024149ae5f034d628e8685a4e12ab4eca6706a5d1ba459987fcc7994f93c3598cf21099352a776657b92cbb410eab0d3231f3ab2317056c6a399e0dd3f118 + checksum: 35b9382b94b7e3af962dc901db80bde99385645fb0b1f4cbaf64d58ff7181adb962430437db5b7d6db9db2e82399a3d1f319378d3c98e72c7ada8245180f0979 languageName: node linkType: hard @@ -14593,114 +14934,114 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-android-arm-eabi@npm:4.22.4": - version: 4.22.4 - resolution: "@rollup/rollup-android-arm-eabi@npm:4.22.4" +"@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.22.4": - version: 4.22.4 - resolution: "@rollup/rollup-android-arm64@npm:4.22.4" +"@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.22.4": - version: 4.22.4 - resolution: "@rollup/rollup-darwin-arm64@npm:4.22.4" +"@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.22.4": - version: 4.22.4 - resolution: "@rollup/rollup-darwin-x64@npm:4.22.4" +"@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.22.4": - version: 4.22.4 - resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.22.4" +"@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.22.4": - version: 4.22.4 - resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.22.4" +"@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.22.4": - version: 4.22.4 - resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.22.4" +"@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.22.4": - version: 4.22.4 - resolution: "@rollup/rollup-linux-arm64-musl@npm:4.22.4" +"@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.22.4": - version: 4.22.4 - resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.22.4" +"@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.22.4": - version: 4.22.4 - resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.22.4" +"@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.22.4": - version: 4.22.4 - resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.22.4" +"@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.22.4": - version: 4.22.4 - resolution: "@rollup/rollup-linux-x64-gnu@npm:4.22.4" +"@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.22.4": - version: 4.22.4 - resolution: "@rollup/rollup-linux-x64-musl@npm:4.22.4" +"@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.22.4": - version: 4.22.4 - resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.22.4" +"@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.22.4": - version: 4.22.4 - resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.22.4" +"@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.22.4": - version: 4.22.4 - resolution: "@rollup/rollup-win32-x64-msvc@npm:4.22.4" +"@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 @@ -14937,16 +15278,6 @@ __metadata: languageName: node linkType: hard -"@smithy/abort-controller@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/abort-controller@npm:2.2.0" - dependencies: - "@smithy/types": ^2.12.0 - tslib: ^2.6.2 - checksum: d0d7fcaa7b67b04c9ad825017110cc294ff06af07f8054ac3b75d8de88ff5fbef1d08f5c1ae672db1839d14ce25f277c459d2b7b7263cbe9e6c3d4518a19230e - languageName: node - linkType: hard - "@smithy/abort-controller@npm:^3.1.2": version: 3.1.2 resolution: "@smithy/abort-controller@npm:3.1.2" @@ -15237,20 +15568,7 @@ __metadata: languageName: node linkType: hard -"@smithy/node-http-handler@npm:^2.1.7": - version: 2.5.0 - resolution: "@smithy/node-http-handler@npm:2.5.0" - dependencies: - "@smithy/abort-controller": ^2.2.0 - "@smithy/protocol-http": ^3.3.0 - "@smithy/querystring-builder": ^2.2.0 - "@smithy/types": ^2.12.0 - tslib: ^2.6.2 - checksum: 2e63fafdac5bef62181994af2ec065b0f7f04eaed88fb2990a21a9925226fead5013cf4f232b527f3f4d9ffb68ccbe8cd263ad22a7351d36b0dc23e975929a0c - languageName: node - linkType: hard - -"@smithy/node-http-handler@npm:^3.2.0": +"@smithy/node-http-handler@npm:^3.0.0, @smithy/node-http-handler@npm:^3.2.0": version: 3.2.0 resolution: "@smithy/node-http-handler@npm:3.2.0" dependencies: @@ -15273,16 +15591,6 @@ __metadata: languageName: node linkType: hard -"@smithy/protocol-http@npm:^3.3.0": - version: 3.3.0 - resolution: "@smithy/protocol-http@npm:3.3.0" - dependencies: - "@smithy/types": ^2.12.0 - tslib: ^2.6.2 - checksum: 6c1aaaee9f6ecfb841766938312268f30cbda253f172de7467463aae7d7bfea19a801ab570f3737334e992d2d0ee7446e6af6a6fd82b08533790c489289dff76 - languageName: node - linkType: hard - "@smithy/protocol-http@npm:^4.1.1": version: 4.1.1 resolution: "@smithy/protocol-http@npm:4.1.1" @@ -15293,17 +15601,6 @@ __metadata: languageName: node linkType: hard -"@smithy/querystring-builder@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/querystring-builder@npm:2.2.0" - dependencies: - "@smithy/types": ^2.12.0 - "@smithy/util-uri-escape": ^2.2.0 - tslib: ^2.6.2 - checksum: db492903302a694a0e982c37b9a74314160c5ee485742f24f8b6d0da66f121e7ff8588742a3a1964f6b983c15cacd52b883c5efa714882a754f575da7a7e014d - languageName: node - linkType: hard - "@smithy/querystring-builder@npm:^3.0.4": version: 3.0.4 resolution: "@smithy/querystring-builder@npm:3.0.4" @@ -15383,15 +15680,6 @@ __metadata: languageName: node linkType: hard -"@smithy/types@npm:^2.12.0": - version: 2.12.0 - resolution: "@smithy/types@npm:2.12.0" - dependencies: - tslib: ^2.6.2 - checksum: 2dd93746624d87afbf51c22116fc69f82e95004b78cf681c4a283d908155c22a2b7a3afbd64a3aff7deefb6619276f186e212422ad200df3b42c32ef5330374e - languageName: node - linkType: hard - "@smithy/types@npm:^3.4.0": version: 3.4.0 resolution: "@smithy/types@npm:3.4.0" @@ -15555,15 +15843,6 @@ __metadata: languageName: node linkType: hard -"@smithy/util-uri-escape@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/util-uri-escape@npm:2.2.0" - dependencies: - tslib: ^2.6.2 - checksum: bade35312d75d1c84226f2a81b70dfef91766c02ecb6c6854b6f920cddb423e01963f7d0c183d523b5991f8e7ca93bcf73f8b3c6923979152b8350c9f3c24fd6 - languageName: node - linkType: hard - "@smithy/util-uri-escape@npm:^3.0.0": version: 3.0.0 resolution: "@smithy/util-uri-escape@npm:3.0.0" @@ -17425,10 +17704,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 @@ -17782,9 +18061,9 @@ __metadata: linkType: hard "@types/lodash@npm:^4.14.151": - version: 4.17.9 - resolution: "@types/lodash@npm:4.17.9" - checksum: 6d1bf3e77f0a54d97532755a74260d402d8972259c5451b74612c16cb983b73e0760e5bfe4f9e68ab15051511c867812b40715a01f9805afe6bc36c7dd676378 + version: 4.17.10 + resolution: "@types/lodash@npm:4.17.10" + checksum: 4600f2f25270c8fee6953e363d318149a5f0f1b1bb820aa2f42d7ada6e4f7de31848bb5ffc2c687b40bd73aa982167bdd6e6d8d456e72abe0c660ec77d1fa7e9 languageName: node linkType: hard @@ -17956,11 +18235,11 @@ __metadata: linkType: hard "@types/node@npm:*, @types/node@npm:>=13.7.0": - version: 22.5.4 - resolution: "@types/node@npm:22.5.4" + version: 22.7.4 + resolution: "@types/node@npm:22.7.4" dependencies: undici-types: ~6.19.2 - checksum: 77ac225c38c428200036780036da0bc6764e2721cfa8f528c7e7da7cfefe01a32a5791e28a54efbeedbc977949058d7db902b2e00139298225d4686cee4ae6db + checksum: a3f4154147639369aed08fe6f8d62eff637cf87b187bb252d7bbccdc82884626007af424b08a653c53f2182adfa0340001b4888cb7cbb942cef351210fc742a5 languageName: node linkType: hard @@ -17978,10 +18257,10 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:^16.11.26, @types/node@npm:^16.7.10": - version: 16.18.108 - resolution: "@types/node@npm:16.18.108" - checksum: 5029ce7b0d247690360f2698da4fe765ef5cd5e2409b63b3a45e90bbf7bbaaf3497e769336fb7725be04a221d6e934e3a4616ec7fc205812943def3ea9d70862 +"@types/node@npm:^16.11.26": + version: 16.18.112 + resolution: "@types/node@npm:16.18.112" + checksum: d634729e60d2e7bd951843fddf5fb59ae786ca707f384e8f90881b011076962b4e3fee3393e3be4be4fb7d86943893e0bda9650aea24ac692bdf407bf1a5d84d languageName: node linkType: hard @@ -17993,20 +18272,20 @@ __metadata: linkType: hard "@types/node@npm:^18.11.9, @types/node@npm:^18.17.15, @types/node@npm:^18.17.8": - version: 18.19.50 - resolution: "@types/node@npm:18.19.50" + version: 18.19.54 + resolution: "@types/node@npm:18.19.54" dependencies: undici-types: ~5.26.4 - checksum: 73bdd2b46fb96816a1f7309e1b609f0832a29739c87df7daa729ff497160be143e02cf18486a0112e1981b092358aed3ca0716b532aff93c7e05f7dbb4f7586a + checksum: d85bacc7430c2913bcd2cf293f312bc1f9108819707ac25b58404185c3b8f9ca9e3e93c396672f457c18e65f5ba86cc8363803f830207c6b7dd14fd74e1455b0 languageName: node linkType: hard "@types/node@npm:^20.1.1, @types/node@npm:^20.11.16": - version: 20.16.5 - resolution: "@types/node@npm:20.16.5" + version: 20.16.10 + resolution: "@types/node@npm:20.16.10" dependencies: undici-types: ~6.19.2 - checksum: f38b7bd8c4993dcf38943afa2ffdd7dfd18fc94f8f3f28d0c1045a10d39871a6cc1b8f8d3bf0c7ed848457d0e1d283482f6ca125579c13fed1b7575d23e8e8f5 + checksum: 8b4d5a0af828871627e80da095df50ef8ae7ca458f39ccde1d060e3bf97b0bc76af9547bd5d75ce4ccb1dd80466804b2fe4f12553c11cb8691c6667effd9a9d7 languageName: node linkType: hard @@ -18331,12 +18610,12 @@ __metadata: linkType: hard "@types/react@npm:^18": - version: 18.3.7 - resolution: "@types/react@npm:18.3.7" + version: 18.3.10 + resolution: "@types/react@npm:18.3.10" dependencies: "@types/prop-types": "*" csstype: ^3.0.2 - checksum: 027cf84d8309c4d0a9b16ec26f71de0950e2d748293bbc4dac42519f77d0bec099aeb5fb1c0bcb891725973e53085c1aedea5c3a16bca215c2fc2ecf68c7ec6e + checksum: 04261654b5f4bc9584e9d882c7dfd5b36dc58963f958f8c3efd24cb68c9d205bc2d57558a1479b86d7827f0e5116d5bd111791d1253583d1e1c165f0aeb48c48 languageName: node linkType: hard @@ -19324,17 +19603,17 @@ __metadata: linkType: hard "@vitejs/plugin-react@npm:^4.3.1": - version: 4.3.1 - resolution: "@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 @@ -19616,19 +19895,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 @@ -19645,7 +19924,7 @@ __metadata: treeify: ^1.1.0 tslib: ^2.4.0 tunnel: ^0.0.6 - checksum: 811956ab94e9f4b3601f304312baf816322df124cf85754ef3985110c90935b1b761c8266a06c2c5633f6edc39c8a4ceffeff50f08f036d7adf19612ce3761a3 + checksum: 789bf7c1451d24e6405a42537a53382ec76387bf2696aadd3a189e8a343768d78377ff7b363f0c9271465f6a83c8e1e913d390ad3a233f7aa3d8ce9512e5147c languageName: node linkType: hard @@ -19658,12 +19937,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 @@ -19679,16 +19958,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 @@ -19710,13 +19989,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 @@ -20099,12 +20378,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 @@ -20113,7 +20392,7 @@ __metadata: tslib: ^2.4.0 bin: shell: ./lib/cli.js - checksum: 8497e278b1d3d0ffe324a3b9c878ca7165bbbe4d182f5ecb02f1bfaaf4dd18c8aaa54c33ee17bb37eb09173816dc4617b70c3fe0925f5fb99749687e2650b7a2 + checksum: d5ad721cadc6d6f1411ad98b5d8362c2c804be4e4e9ed9799debbaa96fd2413fc5beaf011e30e69f54ab66b66779ba916125dc40efcf104a4e99053b3a8c645b languageName: node linkType: hard @@ -20426,7 +20705,7 @@ __metadata: languageName: node linkType: hard -"ajv@npm:^8.0.0, ajv@npm:^8.10.0, ajv@npm:^8.11.0, ajv@npm:^8.12.0, ajv@npm:^8.17.1, ajv@npm:^8.6.0, ajv@npm:^8.6.3, ajv@npm:^8.9.0": +"ajv@npm:^8.0.0, ajv@npm:^8.10.0, ajv@npm:^8.11.0, ajv@npm:^8.12.0, ajv@npm:^8.16.0, ajv@npm:^8.17.1, ajv@npm:^8.6.0, ajv@npm:^8.6.3, ajv@npm:^8.9.0": version: 8.17.1 resolution: "ajv@npm:8.17.1" dependencies: @@ -20645,12 +20924,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 @@ -21042,6 +21329,15 @@ __metadata: languageName: node linkType: hard +"async-mutex@npm:^0.5.0": + version: 0.5.0 + resolution: "async-mutex@npm:0.5.0" + dependencies: + tslib: ^2.4.0 + checksum: be1587f4875f3bb15e34e9fcce82eac2966daef4432c8d0046e61947fb9a1b95405284601bc7ce4869319249bc07c75100880191db6af11d1498931ac2a2f9ea + languageName: node + linkType: hard + "async-retry@npm:^1.3.3": version: 1.3.3 resolution: "async-retry@npm:1.3.3" @@ -21051,7 +21347,7 @@ __metadata: languageName: node linkType: hard -"async@npm:^2.6.2, async@npm:^2.6.4": +"async@npm:^2.6.4": version: 2.6.4 resolution: "async@npm:2.6.4" dependencies: @@ -21246,13 +21542,13 @@ __metadata: languageName: node linkType: hard -"azure-devops-node-api@npm:^12.0.0": - version: 12.5.0 - resolution: "azure-devops-node-api@npm:12.5.0" +"azure-devops-node-api@npm:^14.0.0": + version: 14.0.2 + resolution: "azure-devops-node-api@npm:14.0.2" dependencies: tunnel: 0.0.6 - typed-rest-client: ^1.8.4 - checksum: 7c2c3ae21eaf1bc3627ba4ea87bdac1085a3594eacf40eb6d7b11292f057988db38f718f4597733c6861d854c28bfe146bcf3964a13adddebe1085270bb63097 + typed-rest-client: ^2.0.1 + checksum: 26f39c7772d313befd49696fe2a1e91a8ffd75cfeb0c7f305a7102867f1090d299544361663b14e99bbebbf5855d1fc56ead0e4e32ee53bc83b487cdbe30d254 languageName: node linkType: hard @@ -21807,10 +22103,10 @@ __metadata: languageName: node linkType: hard -"brotli-wasm@npm:^1.1.0": - version: 1.3.1 - resolution: "brotli-wasm@npm:1.3.1" - checksum: ec2931a989ee6f0bb52c2aabf23a0d230232d3bd69fb68ee3dab9542fc9ae2d4085d0e5338f71520c25a4a26cf1cfc991ce02910c24d63d42c7915c5722a3713 +"brotli-wasm@npm:^3.0.0": + version: 3.0.1 + resolution: "brotli-wasm@npm:3.0.1" + checksum: 48191b27265de8ffc59c940f9efef3a931448b6a15c26a4e360192fc3f0968e073c11fe0926510d019c305cc1d9c6d65df4d3e5752648a91cb0bbcccff7a8460 languageName: node linkType: hard @@ -22499,6 +22795,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" @@ -23410,7 +23713,7 @@ __metadata: languageName: node linkType: hard -"cookie@npm:0.6.0, cookie@npm:^0.6.0, cookie@npm:~0.6.0": +"cookie@npm:0.6.0, cookie@npm:~0.6.0": version: 0.6.0 resolution: "cookie@npm:0.6.0" checksum: f56a7d32a07db5458e79c726b77e3c2eff655c36792f2b6c58d351fb5f61531e5b1ab7f46987150136e366c65213cbe31729e02a3eaed630c3bf7334635fb410 @@ -23431,6 +23734,13 @@ __metadata: languageName: node linkType: hard +"cookie@npm:^0.7.0": + version: 0.7.2 + resolution: "cookie@npm:0.7.2" + checksum: 9bf8555e33530affd571ea37b615ccad9b9a34febbf2c950c86787088eb00a8973690833b0f8ebd6b69b753c62669ea60cec89178c1fb007bf0749abed74f93e + languageName: node + linkType: hard + "cookiejar@npm:^2.1.4": version: 2.1.4 resolution: "cookiejar@npm:2.1.4" @@ -24367,7 +24677,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:^3.1.1, debug@npm:^3.2.7": +"debug@npm:^3.2.7": version: 3.2.7 resolution: "debug@npm:3.2.7" dependencies: @@ -24665,13 +24975,13 @@ __metadata: languageName: node linkType: hard -"des.js@npm:^1.0.0": - version: 1.0.1 - resolution: "des.js@npm:1.0.1" +"des.js@npm:^1.0.0, des.js@npm:^1.1.0": + version: 1.1.0 + resolution: "des.js@npm:1.1.0" dependencies: inherits: ^2.0.1 minimalistic-assert: ^1.0.0 - checksum: 1ec2eedd7ed6bd61dd5e0519fd4c96124e93bb22de8a9d211b02d63e5dd152824853d919bb2090f965cc0e3eb9c515950a9836b332020d810f9c71feb0fd7df4 + checksum: 0e9c1584b70d31e20f20a613fc9ef60fbc6a147dfec9e448a168794a4b97ac04d8dc47ea008f1fa93b0f8aaf7c1ead632a5e59ce1913a6079d2d244c9f5ebe33 languageName: node linkType: hard @@ -24682,12 +24992,12 @@ __metadata: languageName: node linkType: hard -"destroyable-server@npm:^1.0.0": - version: 1.0.0 - resolution: "destroyable-server@npm:1.0.0" +"destroyable-server@npm:^1.0.2": + version: 1.0.2 + resolution: "destroyable-server@npm:1.0.2" dependencies: "@types/node": "*" - checksum: ac81b26f616a9d0aaa9cb759fa5a5a186f887025362329f7ddc909f53090f4aea0d1b75c4dda23e210faee536e2d7352de017261e1625b7b18108f0e630efa1f + checksum: 81fd70b9132d43c3633a7a819adfe1fc68b52a55154ff8a36f42f4655e7b71b8468559888caadfd324c1aa824f0d236796a8f356e8a00e7438649e647ea654b2 languageName: node linkType: hard @@ -26622,7 +26932,7 @@ __metadata: "@types/express": ^4.17.6 "@types/express-serve-static-core": ^4.17.5 "@types/luxon": ^3.0.0 - azure-devops-node-api: ^12.0.0 + azure-devops-node-api: ^14.0.0 better-sqlite3: ^11.0.0 dockerode: ^4.0.0 example-app: "link:../app" @@ -28082,6 +28392,15 @@ __metadata: languageName: node linkType: hard +"git-url-parse@npm:^15.0.0": + version: 15.0.0 + resolution: "git-url-parse@npm:15.0.0" + dependencies: + git-up: ^7.0.0 + checksum: 4379e9b0a1297b62d603630341a7ce1a6e17901114ee7bb70a611f62ea0fd3b3649ac754891d2746fd42031a21e97ddc0092287a04cc028cbf37df8f6be65a9e + languageName: node + linkType: hard + "github-from-package@npm:0.0.0": version: 0.0.0 resolution: "github-from-package@npm:0.0.0" @@ -28986,14 +29305,14 @@ __metadata: languageName: node linkType: hard -"http-encoding@npm:^1.5.1": - version: 1.5.1 - resolution: "http-encoding@npm:1.5.1" +"http-encoding@npm:^2.0.1": + version: 2.0.1 + resolution: "http-encoding@npm:2.0.1" dependencies: - brotli-wasm: ^1.1.0 + brotli-wasm: ^3.0.0 pify: ^5.0.0 - zstd-codec: ^0.1.4 - checksum: 534aa2facb0ae529fa88b9778867472247711626b90030fd4351572c6147fb5e895d9d2e305e7dc5cc993345f2fbdb17ca99345651bf76dbac39a07f552af2ac + zstd-codec: ^0.1.5 + checksum: c34a1cd81ad1c08e6c6aba5aef3f4d4bc4a6c84f8b3511776eb62006beeee48a104ce1630e3c8497f66d5c0913195dea596e776336dd5a598bd7fe06d27e1395 languageName: node linkType: hard @@ -29145,13 +29464,13 @@ __metadata: languageName: node linkType: hard -"http2-wrapper@npm:^2.2.0": - version: 2.2.0 - resolution: "http2-wrapper@npm:2.2.0" +"http2-wrapper@npm:^2.2.1": + version: 2.2.1 + resolution: "http2-wrapper@npm:2.2.1" dependencies: quick-lru: ^5.1.1 resolve-alpn: ^1.2.0 - checksum: 6fd20e5cb6a58151715b3581e06a62a47df943187d2d1f69e538a50cccb7175dd334ecfde7900a37d18f3e13a1a199518a2c211f39860e81e9a16210c199cfaa + checksum: e95e55e22c6fd61182ce81fecb9b7da3af680d479febe8ad870d05f7ebbc9f076e455193766f4e7934e50913bf1d8da3ba121fb5cd2928892390b58cf9d5c509 languageName: node linkType: hard @@ -31268,6 +31587,13 @@ __metadata: languageName: node linkType: hard +"js-md4@npm:^0.3.2": + version: 0.3.2 + resolution: "js-md4@npm:0.3.2" + checksum: aa7b7cbd738b105f86fc0fa50ce2a7a6b6b329ff3f713d1bd38b12c2a72929bab5a16e658a03830faa8d656356aa89b4f77f1fbf05ffa8d095bda6d831441c2d + languageName: node + linkType: hard + "js-tokens@npm:^3.0.0 || ^4.0.0, js-tokens@npm:^4.0.0": version: 4.0.0 resolution: "js-tokens@npm:4.0.0" @@ -32032,8 +32358,8 @@ __metadata: linkType: hard "knip@npm:^5.0.0": - version: 5.30.2 - resolution: "knip@npm:5.30.2" + version: 5.30.6 + resolution: "knip@npm:5.30.6" dependencies: "@nodelib/fs.walk": 1.2.8 "@snyk/github-codeowners": 1.1.0 @@ -32046,7 +32372,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 @@ -32057,7 +32383,7 @@ __metadata: bin: knip: bin/knip.js knip-bun: bin/knip-bun.js - checksum: fafb6ee078c1e9f24e83c08c6b97c7ad82ef78d043eff6a064639e08354a4b81cbb132d705acc53874d0f0d02dc690d960f75efe8783ac349fde491bcbf1b742 + checksum: 9820761248882926789bdf3cf8014a32e695d94bdabc335b4b637bceaeec7922358b67027b46aa5f7f2af10460027d0d33be407d48db76e50c8d1dd8dfca95ce languageName: node linkType: hard @@ -34188,7 +34514,7 @@ __metadata: languageName: node linkType: hard -"mkdirp@npm:^0.5.1, mkdirp@npm:^0.5.4, mkdirp@npm:^0.5.5, mkdirp@npm:^0.5.6": +"mkdirp@npm:^0.5.1, mkdirp@npm:^0.5.4, mkdirp@npm:^0.5.6": version: 0.5.6 resolution: "mkdirp@npm:0.5.6" dependencies: @@ -34224,17 +34550,18 @@ __metadata: languageName: node linkType: hard -"mockttp@npm:^3.9.1": - version: 3.9.4 - resolution: "mockttp@npm:3.9.4" +"mockttp@npm:^3.13.0, mockttp@npm:^3.9.1": + version: 3.15.2 + resolution: "mockttp@npm:3.15.2" dependencies: "@graphql-tools/schema": ^8.5.0 "@graphql-tools/utils": ^8.8.0 - "@httptoolkit/httpolyglot": ^2.1.1 + "@httptoolkit/httpolyglot": ^2.2.1 "@httptoolkit/subscriptions-transport-ws": ^0.11.2 "@httptoolkit/websocket-stream": ^6.0.1 "@types/cors": ^2.8.6 "@types/node": "*" + async-mutex: ^0.5.0 base64-arraybuffer: ^0.1.5 body-parser: ^1.15.2 cacheable-lookup: ^6.0.0 @@ -34243,14 +34570,15 @@ __metadata: cors: ^2.8.4 cors-gate: ^1.1.3 cross-fetch: ^3.1.5 - destroyable-server: ^1.0.0 + destroyable-server: ^1.0.2 express: ^4.14.0 + fast-json-patch: ^3.1.1 graphql: ^14.0.2 || ^15.5 graphql-http: ^1.22.0 graphql-subscriptions: ^1.1.0 graphql-tag: ^2.12.6 - http-encoding: ^1.5.1 - http2-wrapper: ^2.2.0 + http-encoding: ^2.0.1 + http2-wrapper: ^2.2.1 https-proxy-agent: ^5.0.1 isomorphic-ws: ^4.0.1 lodash: ^4.16.4 @@ -34260,16 +34588,17 @@ __metadata: pac-proxy-agent: ^7.0.0 parse-multipart-data: ^1.4.0 performance-now: ^2.1.0 - portfinder: 1.0.28 + portfinder: ^1.0.32 read-tls-client-hello: ^1.0.0 semver: ^7.5.3 socks-proxy-agent: ^7.0.0 typed-error: ^3.0.2 + urlpattern-polyfill: ^8.0.0 uuid: ^8.3.2 ws: ^8.8.0 bin: mockttp: dist/admin/admin-bin.js - checksum: 2e0b984d77a94e6a754e44c85a7ff2ded13ba42fd6cabf125b677a8a57eff543c896bf3ecb522799d3efbe18733bf019fbe707044f098fdd5e8e4bc2c0b1df4f + checksum: 96b90e0515e7ac1b73954e9e01010424d51d9563f8e850e620b06ba864bf064401e1a1af89e103724b956bfa3bee790cb452366df100bf01122f333e04c3aee8 languageName: node linkType: hard @@ -34370,14 +34699,14 @@ __metadata: linkType: hard "msw@npm:^2.0.0, msw@npm:^2.0.8": - version: 2.4.8 - resolution: "msw@npm:2.4.8" + 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.35.6 + "@mswjs/interceptors": ^0.35.8 "@open-draft/until": ^2.1.0 "@types/cookie": ^0.6.0 "@types/statuses": ^2.0.4 @@ -34397,7 +34726,7 @@ __metadata: optional: true bin: msw: cli/index.js - checksum: 3cfc2588715aa1a006032b6e255ce6dc899e51f6fea0b69bb0df8b635d9a332227b3463f5017577ca82076afb489dfd036fb9cc156c89f482fb5e8a44de97ad8 + checksum: add5a614ce58f5e75c65afcb59b76d0d807b9103b7fb3aaf23efd6ebd82d79415ecd9bc55dd48bcc4c31ec7ce196a75ace46d94224f0a80567c89a190e367ba8 languageName: node linkType: hard @@ -34860,11 +35189,9 @@ __metadata: linkType: hard "node-mocks-http@npm:^1.0.0": - version: 1.16.0 - resolution: "node-mocks-http@npm:1.16.0" + version: 1.16.1 + resolution: "node-mocks-http@npm:1.16.1" dependencies: - "@types/express": ^4.17.21 - "@types/node": "*" accepts: ^1.3.7 content-disposition: ^0.5.3 depd: ^1.1.0 @@ -34875,7 +35202,15 @@ __metadata: parseurl: ^1.3.3 range-parser: ^1.2.0 type-is: ^1.6.18 - checksum: 21ccf1ecaaa6ee0f7c061a7063f59d59c9793a485a907c09c83ff73b12f205ef87537022a4ba8ad937d07454ee0450290093d4a66a4df21e7e8b3696d23e1a7d + peerDependencies: + "@types/express": ^4.17.21 || ^5.0.0 + "@types/node": "*" + peerDependenciesMeta: + "@types/express": + optional: true + "@types/node": + optional: true + checksum: 198030725eac236062eb3547a7d5cec2d6f2d44bf05efab0ea621e90f671d6966dca2873faaea9bcbb5dde92a222aff0610a01d453c2f76b0bc5dbdf4bd8057a languageName: node linkType: hard @@ -34957,8 +35292,8 @@ __metadata: linkType: hard "nodemon@npm:^3.0.1": - version: 3.1.5 - resolution: "nodemon@npm:3.1.5" + version: 3.1.7 + resolution: "nodemon@npm:3.1.7" dependencies: chokidar: ^3.5.2 debug: ^4 @@ -34972,7 +35307,7 @@ __metadata: undefsafe: ^2.0.5 bin: nodemon: bin/nodemon.js - checksum: 56a41473b4990efebe8341f1da360af49d3b9e62c164d76ef6ec7f81efeca56c990dd4f275f03ddd1afde83d27c1ed3abe9c73d712fbebe08406c459b9f030ab + checksum: c500ac2feb278ddb187049ac8ede6423c1fb074cc3dabf74882568d5e93401293c10039e184a9d1bfc617c983ddb432437d396b421926914d04ebba671a7d8b8 languageName: node linkType: hard @@ -36772,17 +37107,6 @@ __metadata: languageName: node linkType: hard -"portfinder@npm:1.0.28": - version: 1.0.28 - resolution: "portfinder@npm:1.0.28" - dependencies: - async: ^2.6.2 - debug: ^3.1.1 - mkdirp: ^0.5.5 - checksum: 91fef602f13f8f4c64385d0ad2a36cc9dc6be0b8d10a2628ee2c3c7b9917ab4fefb458815b82cea2abf4b785cd11c9b4e2d917ac6fa06f14b6fa880ca8f8928c - languageName: node - linkType: hard - "portfinder@npm:^1.0.28, portfinder@npm:^1.0.32": version: 1.0.32 resolution: "portfinder@npm:1.0.32" @@ -37741,7 +38065,7 @@ __metadata: languageName: node linkType: hard -"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": +"qs@npm:6.13.0, qs@npm:^6.10.1, qs@npm:^6.10.2, qs@npm:^6.10.3, qs@npm:^6.11.0, qs@npm:^6.11.2, qs@npm:^6.12.2, qs@npm:^6.9.4": version: 6.13.0 resolution: "qs@npm:6.13.0" dependencies: @@ -38702,7 +39026,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: @@ -39617,26 +39941,26 @@ __metadata: linkType: hard "rollup@npm:^4.0.0, rollup@npm:^4.20.0": - version: 4.22.4 - resolution: "rollup@npm:4.22.4" + version: 4.22.5 + resolution: "rollup@npm:4.22.5" dependencies: - "@rollup/rollup-android-arm-eabi": 4.22.4 - "@rollup/rollup-android-arm64": 4.22.4 - "@rollup/rollup-darwin-arm64": 4.22.4 - "@rollup/rollup-darwin-x64": 4.22.4 - "@rollup/rollup-linux-arm-gnueabihf": 4.22.4 - "@rollup/rollup-linux-arm-musleabihf": 4.22.4 - "@rollup/rollup-linux-arm64-gnu": 4.22.4 - "@rollup/rollup-linux-arm64-musl": 4.22.4 - "@rollup/rollup-linux-powerpc64le-gnu": 4.22.4 - "@rollup/rollup-linux-riscv64-gnu": 4.22.4 - "@rollup/rollup-linux-s390x-gnu": 4.22.4 - "@rollup/rollup-linux-x64-gnu": 4.22.4 - "@rollup/rollup-linux-x64-musl": 4.22.4 - "@rollup/rollup-win32-arm64-msvc": 4.22.4 - "@rollup/rollup-win32-ia32-msvc": 4.22.4 - "@rollup/rollup-win32-x64-msvc": 4.22.4 - "@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": @@ -39675,7 +39999,7 @@ __metadata: optional: true bin: rollup: dist/bin/rollup - checksum: b093b518deb1fd0c0455eef746abe9efa3a2cd7e2b65a4ace9e8fa5d60b3d6da2406816de2c6c1d553609f22cf730f1c5839a05a1ff60003c504486172238d1a + checksum: 894b3d428b5a7f1db2245f50622ce65a3ad8f754265dd1da7dce133e39b315516dbcbac51e4fe100b44d59b168bac3f36ebaeb836fc9f7057d4972f44497d046 languageName: node linkType: hard @@ -40533,10 +40857,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 @@ -42793,14 +43117,16 @@ __metadata: languageName: node linkType: hard -"typed-rest-client@npm:^1.8.4": - version: 1.8.4 - resolution: "typed-rest-client@npm:1.8.4" +"typed-rest-client@npm:^2.0.1": + version: 2.0.2 + resolution: "typed-rest-client@npm:2.0.2" dependencies: - qs: ^6.9.1 + des.js: ^1.1.0 + js-md4: ^0.3.2 + qs: ^6.10.3 tunnel: 0.0.6 underscore: ^1.12.1 - checksum: 238e2139724310fed39756ae734fbc811e803abaa7598720ad6cc5ab7f160d415d8107551422b186f6b2e08c5761c0e7b66ca47d60b2ccd952bb5e20d3b92f3c + checksum: f1d9a0ffd5b7266f01df9ea4eb08b8da04793cf6902d82b3c6a46d1328cdefe80bb0cfc8f96afa645077c234ec218d8b16f642da35c1e2f1adf3d61a5904d8d1 languageName: node linkType: hard @@ -43385,6 +43711,13 @@ __metadata: languageName: node linkType: hard +"urlpattern-polyfill@npm:^8.0.0": + version: 8.0.2 + resolution: "urlpattern-polyfill@npm:8.0.2" + checksum: d2cc0905a613c77e330c426e8697ee522dd9640eda79ac51160a0f6350e103f09b8c327623880989f8ba7325e8d95267b745aa280fdcc2aead80b023e16bd09d + languageName: node + linkType: hard + "urlpattern-polyfill@npm:^9.0.0": version: 9.0.0 resolution: "urlpattern-polyfill@npm:9.0.0" @@ -43797,8 +44130,8 @@ __metadata: linkType: hard "vite@npm:^5.0.0": - version: 5.4.6 - resolution: "vite@npm:5.4.6" + version: 5.4.8 + resolution: "vite@npm:5.4.8" dependencies: esbuild: ^0.21.3 fsevents: ~2.3.3 @@ -43835,7 +44168,7 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: ea293748f624b3bb53e68d30ddc55e7addeaa38bbcde06d900e6d476bef3d0550de2a67f5316680dbeae483afedd3e735fb91b65004659f62bece537ed038a59 + checksum: b5686ff76a60d53092dc13a5c1e5627165226b8e3da7736931adf87bbe58d383bca386383cea134750108c2d42750c916db3f2314ac90a9477d693950145f140 languageName: node linkType: hard @@ -44917,12 +45250,12 @@ __metadata: languageName: node linkType: hard -"zod-validation-error@npm:^3.0.3": - version: 3.1.0 - resolution: "zod-validation-error@npm:3.1.0" +"zod-validation-error@npm:^3.0.3, zod-validation-error@npm:^3.4.0": + version: 3.4.0 + resolution: "zod-validation-error@npm:3.4.0" peerDependencies: zod: ^3.18.0 - checksum: 84df01c91d594701eaf7f5f007be881e47f7adef2e3f3765f7be031cb78033f9be0924273106cb81b586d8020da9885dbb81b3da363f00a51df00f26274f2b23 + checksum: b07fbfc39582dbdf6972f5f5f0c3bac9e6b5e6d2e55ef3dd891fd08f1966ebf1023a4bc270e9b569eaa48ed1684ac2252c9f260b0bd07b167671596e6e4d0fa8 languageName: node linkType: hard @@ -44933,10 +45266,10 @@ __metadata: languageName: node linkType: hard -"zstd-codec@npm:^0.1.4": - version: 0.1.4 - resolution: "zstd-codec@npm:0.1.4" - checksum: 8689bc0defc4f387d1be990b8b8ca8ca56690d17dfc8dd4703db798465b92a21e64e54e886acfaa376147d9d07d879a68627b09fddc34a0c93f0dc5c610a790c +"zstd-codec@npm:^0.1.5": + version: 0.1.5 + resolution: "zstd-codec@npm:0.1.5" + checksum: ba62bf643c3ca9759fedc090b73a0c3b1e506364fcae902a70b112c1f5b30bc6aabff3184808cc4430f2ab6644cabae979368152ae908c1d8ef39cd8c3223c85 languageName: node linkType: hard