From 11d5f326824ef9cceacdebea225e4df753ae9249 Mon Sep 17 00:00:00 2001 From: Chrissy Weeks <5051062+fevrin@users.noreply.github.com> Date: Tue, 1 Aug 2023 13:08:50 -0400 Subject: [PATCH 01/73] docs: fix a link to the frontend Backstage plugin Signed-off-by: Fevrin <5051062+fevrin@users.noreply.github.com> --- plugins/catalog-backend/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/catalog-backend/README.md b/plugins/catalog-backend/README.md index 1e2bce3142..cd921499d3 100644 --- a/plugins/catalog-backend/README.md +++ b/plugins/catalog-backend/README.md @@ -86,5 +86,5 @@ some example entities. ## Links -- [catalog](https://github.com/backstage/backstage/tree/master/plugins/catalog-backend) +- [catalog](https://github.com/backstage/backstage/tree/master/plugins/catalog) is the frontend interface for this plugin. From 832eef72485bf971cab75b9f9141829fdf079ba8 Mon Sep 17 00:00:00 2001 From: tperehinets Date: Tue, 15 Aug 2023 18:01:47 +0300 Subject: [PATCH 02/73] Added title to props for HasCards. Signed-off-by: tperehinets --- .changeset/chilly-parrots-yell.md | 5 +++++ .../components/HasComponentsCard/HasComponentsCard.tsx | 4 ++-- .../src/components/HasResourcesCard/HasResourcesCard.tsx | 4 ++-- .../HasSubcomponentsCard/HasSubcomponentsCard.tsx | 8 ++++++-- .../src/components/HasSystemsCard/HasSystemsCard.tsx | 4 ++-- 5 files changed, 17 insertions(+), 8 deletions(-) create mode 100644 .changeset/chilly-parrots-yell.md diff --git a/.changeset/chilly-parrots-yell.md b/.changeset/chilly-parrots-yell.md new file mode 100644 index 0000000000..fe4c760923 --- /dev/null +++ b/.changeset/chilly-parrots-yell.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog': patch +--- + +Added title to props for `HasCards`. diff --git a/plugins/catalog/src/components/HasComponentsCard/HasComponentsCard.tsx b/plugins/catalog/src/components/HasComponentsCard/HasComponentsCard.tsx index 9654152a5c..e1f25b6835 100644 --- a/plugins/catalog/src/components/HasComponentsCard/HasComponentsCard.tsx +++ b/plugins/catalog/src/components/HasComponentsCard/HasComponentsCard.tsx @@ -30,11 +30,11 @@ export interface HasComponentsCardProps { } export function HasComponentsCard(props: HasComponentsCardProps) { - const { variant = 'gridItem' } = props; + const { variant = 'gridItem', title = 'Has components' } = props; return ( Date: Tue, 15 Aug 2023 18:12:59 +0300 Subject: [PATCH 03/73] added props Signed-off-by: tperehinets --- .../src/components/HasComponentsCard/HasComponentsCard.tsx | 1 + .../catalog/src/components/HasResourcesCard/HasResourcesCard.tsx | 1 + .../src/components/HasSubcomponentsCard/HasSubcomponentsCard.tsx | 1 + plugins/catalog/src/components/HasSystemsCard/HasSystemsCard.tsx | 1 + 4 files changed, 4 insertions(+) diff --git a/plugins/catalog/src/components/HasComponentsCard/HasComponentsCard.tsx b/plugins/catalog/src/components/HasComponentsCard/HasComponentsCard.tsx index e1f25b6835..9071dac030 100644 --- a/plugins/catalog/src/components/HasComponentsCard/HasComponentsCard.tsx +++ b/plugins/catalog/src/components/HasComponentsCard/HasComponentsCard.tsx @@ -27,6 +27,7 @@ import { /** @public */ export interface HasComponentsCardProps { variant?: InfoCardVariants; + title?: string; } export function HasComponentsCard(props: HasComponentsCardProps) { diff --git a/plugins/catalog/src/components/HasResourcesCard/HasResourcesCard.tsx b/plugins/catalog/src/components/HasResourcesCard/HasResourcesCard.tsx index 9cbcec9719..5af7eec258 100644 --- a/plugins/catalog/src/components/HasResourcesCard/HasResourcesCard.tsx +++ b/plugins/catalog/src/components/HasResourcesCard/HasResourcesCard.tsx @@ -27,6 +27,7 @@ import { /** @public */ export interface HasResourcesCardProps { variant?: InfoCardVariants; + title?: string; } export function HasResourcesCard(props: HasResourcesCardProps) { diff --git a/plugins/catalog/src/components/HasSubcomponentsCard/HasSubcomponentsCard.tsx b/plugins/catalog/src/components/HasSubcomponentsCard/HasSubcomponentsCard.tsx index 588cb153ab..ac40c82435 100644 --- a/plugins/catalog/src/components/HasSubcomponentsCard/HasSubcomponentsCard.tsx +++ b/plugins/catalog/src/components/HasSubcomponentsCard/HasSubcomponentsCard.tsx @@ -27,6 +27,7 @@ import { export interface HasSubcomponentsCardProps { variant?: InfoCardVariants; tableOptions?: TableOptions; + title?: string; } export function HasSubcomponentsCard(props: HasSubcomponentsCardProps) { diff --git a/plugins/catalog/src/components/HasSystemsCard/HasSystemsCard.tsx b/plugins/catalog/src/components/HasSystemsCard/HasSystemsCard.tsx index e8d4f4b210..d6da465ffa 100644 --- a/plugins/catalog/src/components/HasSystemsCard/HasSystemsCard.tsx +++ b/plugins/catalog/src/components/HasSystemsCard/HasSystemsCard.tsx @@ -27,6 +27,7 @@ import { /** @public */ export interface HasSystemsCardProps { variant?: InfoCardVariants; + title?: string; } export function HasSystemsCard(props: HasSystemsCardProps) { From b4a65815e354a1c7e1587bf02adf87ee2a1ea599 Mon Sep 17 00:00:00 2001 From: Dmitry Gusev Date: Tue, 15 Aug 2023 18:34:24 +0300 Subject: [PATCH 04/73] Fix techdocs footer link width Signed-off-by: Dmitry Gusev --- plugins/techdocs/src/reader/transformers/styles/rules/layout.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/techdocs/src/reader/transformers/styles/rules/layout.ts b/plugins/techdocs/src/reader/transformers/styles/rules/layout.ts index cce6af7d6f..d78f8222f8 100644 --- a/plugins/techdocs/src/reader/transformers/styles/rules/layout.ts +++ b/plugins/techdocs/src/reader/transformers/styles/rules/layout.ts @@ -120,7 +120,7 @@ export default ({ theme, sidebar }: RuleOptions) => ` .md-footer__title { background-color: unset; } -.md-footer-nav__link { +.md-footer-nav__link, .md-footer__link { width: 16rem; } From 88c9525a36f3a472d768486ca3bc9fdab74c51b6 Mon Sep 17 00:00:00 2001 From: Dmitry Gusev Date: Tue, 15 Aug 2023 18:51:03 +0300 Subject: [PATCH 05/73] Add changeset Signed-off-by: Dmitry Gusev --- .changeset/eight-radios-listen.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/eight-radios-listen.md diff --git a/.changeset/eight-radios-listen.md b/.changeset/eight-radios-listen.md new file mode 100644 index 0000000000..0421a561c0 --- /dev/null +++ b/.changeset/eight-radios-listen.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs': patch +--- + +Fixed bug in styles that caused next and previous links in footer to overlap page content. From b8741985cb56b56eabbeaaa4af436f93c9a9b267 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 16 Aug 2023 04:07:09 +0000 Subject: [PATCH 06/73] fix(deps): update swc monorepo Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 92 +++++++++++++++++++++++++++---------------------------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/yarn.lock b/yarn.lock index 3bb3052421..6645480389 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15905,90 +15905,90 @@ __metadata: languageName: node linkType: hard -"@swc/core-darwin-arm64@npm:1.3.74": - version: 1.3.74 - resolution: "@swc/core-darwin-arm64@npm:1.3.74" +"@swc/core-darwin-arm64@npm:1.3.77": + version: 1.3.77 + resolution: "@swc/core-darwin-arm64@npm:1.3.77" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@swc/core-darwin-x64@npm:1.3.74": - version: 1.3.74 - resolution: "@swc/core-darwin-x64@npm:1.3.74" +"@swc/core-darwin-x64@npm:1.3.77": + version: 1.3.77 + resolution: "@swc/core-darwin-x64@npm:1.3.77" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@swc/core-linux-arm-gnueabihf@npm:1.3.74": - version: 1.3.74 - resolution: "@swc/core-linux-arm-gnueabihf@npm:1.3.74" +"@swc/core-linux-arm-gnueabihf@npm:1.3.77": + version: 1.3.77 + resolution: "@swc/core-linux-arm-gnueabihf@npm:1.3.77" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@swc/core-linux-arm64-gnu@npm:1.3.74": - version: 1.3.74 - resolution: "@swc/core-linux-arm64-gnu@npm:1.3.74" +"@swc/core-linux-arm64-gnu@npm:1.3.77": + version: 1.3.77 + resolution: "@swc/core-linux-arm64-gnu@npm:1.3.77" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-arm64-musl@npm:1.3.74": - version: 1.3.74 - resolution: "@swc/core-linux-arm64-musl@npm:1.3.74" +"@swc/core-linux-arm64-musl@npm:1.3.77": + version: 1.3.77 + resolution: "@swc/core-linux-arm64-musl@npm:1.3.77" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@swc/core-linux-x64-gnu@npm:1.3.74": - version: 1.3.74 - resolution: "@swc/core-linux-x64-gnu@npm:1.3.74" +"@swc/core-linux-x64-gnu@npm:1.3.77": + version: 1.3.77 + resolution: "@swc/core-linux-x64-gnu@npm:1.3.77" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-x64-musl@npm:1.3.74": - version: 1.3.74 - resolution: "@swc/core-linux-x64-musl@npm:1.3.74" +"@swc/core-linux-x64-musl@npm:1.3.77": + version: 1.3.77 + resolution: "@swc/core-linux-x64-musl@npm:1.3.77" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@swc/core-win32-arm64-msvc@npm:1.3.74": - version: 1.3.74 - resolution: "@swc/core-win32-arm64-msvc@npm:1.3.74" +"@swc/core-win32-arm64-msvc@npm:1.3.77": + version: 1.3.77 + resolution: "@swc/core-win32-arm64-msvc@npm:1.3.77" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@swc/core-win32-ia32-msvc@npm:1.3.74": - version: 1.3.74 - resolution: "@swc/core-win32-ia32-msvc@npm:1.3.74" +"@swc/core-win32-ia32-msvc@npm:1.3.77": + version: 1.3.77 + resolution: "@swc/core-win32-ia32-msvc@npm:1.3.77" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@swc/core-win32-x64-msvc@npm:1.3.74": - version: 1.3.74 - resolution: "@swc/core-win32-x64-msvc@npm:1.3.74" +"@swc/core-win32-x64-msvc@npm:1.3.77": + version: 1.3.77 + resolution: "@swc/core-win32-x64-msvc@npm:1.3.77" conditions: os=win32 & cpu=x64 languageName: node linkType: hard "@swc/core@npm:^1.3.46": - version: 1.3.74 - resolution: "@swc/core@npm:1.3.74" + version: 1.3.77 + resolution: "@swc/core@npm:1.3.77" dependencies: - "@swc/core-darwin-arm64": 1.3.74 - "@swc/core-darwin-x64": 1.3.74 - "@swc/core-linux-arm-gnueabihf": 1.3.74 - "@swc/core-linux-arm64-gnu": 1.3.74 - "@swc/core-linux-arm64-musl": 1.3.74 - "@swc/core-linux-x64-gnu": 1.3.74 - "@swc/core-linux-x64-musl": 1.3.74 - "@swc/core-win32-arm64-msvc": 1.3.74 - "@swc/core-win32-ia32-msvc": 1.3.74 - "@swc/core-win32-x64-msvc": 1.3.74 + "@swc/core-darwin-arm64": 1.3.77 + "@swc/core-darwin-x64": 1.3.77 + "@swc/core-linux-arm-gnueabihf": 1.3.77 + "@swc/core-linux-arm64-gnu": 1.3.77 + "@swc/core-linux-arm64-musl": 1.3.77 + "@swc/core-linux-x64-gnu": 1.3.77 + "@swc/core-linux-x64-musl": 1.3.77 + "@swc/core-win32-arm64-msvc": 1.3.77 + "@swc/core-win32-ia32-msvc": 1.3.77 + "@swc/core-win32-x64-msvc": 1.3.77 peerDependencies: "@swc/helpers": ^0.5.0 dependenciesMeta: @@ -16015,7 +16015,7 @@ __metadata: peerDependenciesMeta: "@swc/helpers": optional: true - checksum: fd61d65fbfceb372178a14cfa998c649481a728e33b68bad90fed0ff05b34fb432f88dafb0c2257d54c4de49cdcdd12d2b5fe66f79abc553656445910f163adb + checksum: 95841974c6734c154426b7d3ee33e3b8a58ea870382918b18dd546de38160ed80b1079f35d3e8a4000d11d8ec3ed1e8bf5af6c83b5cb766dd925a42827e250db languageName: node linkType: hard @@ -16029,14 +16029,14 @@ __metadata: linkType: hard "@swc/jest@npm:^0.2.22": - version: 0.2.28 - resolution: "@swc/jest@npm:0.2.28" + version: 0.2.29 + resolution: "@swc/jest@npm:0.2.29" dependencies: "@jest/create-cache-key-function": ^27.4.2 jsonc-parser: ^3.2.0 peerDependencies: "@swc/core": "*" - checksum: 9f9fe7e091077079511e602afe0d0f270c5a274197fe6d55e7f8a8a0f44aadc70f726d8c2571b0eb2af8030d2bba601786adff2d811d6c01f27395c94c746edd + checksum: 9eaad322310f34e81f67d41411a7d60663341af1bd9fb65456faa914c936d849d6f643fa3b942a187d52e71e62c33097098c639d25c2047fa874f49bf51cec76 languageName: node linkType: hard From 8adadd87b81b2e947217b39ddba859ec49d54c77 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 16 Aug 2023 11:51:38 +0200 Subject: [PATCH 07/73] workflows: send discord notification if version packages fail Signed-off-by: Patrik Oldsberg --- .github/workflows/sync_version-packages.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/sync_version-packages.yml b/.github/workflows/sync_version-packages.yml index 22421925c7..6d662ea05f 100644 --- a/.github/workflows/sync_version-packages.yml +++ b/.github/workflows/sync_version-packages.yml @@ -27,3 +27,11 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GH_SERVICE_ACCOUNT_TOKEN }} HUSKY: '0' + + - name: Discord notification + if: ${{ failure() }} + uses: Ilshidur/action-discord@0.3.2 + env: + DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }} + with: + args: 'Version Packages Sync Failed https://github.com/{{GITHUB_REPOSITORY}}/actions/runs/{{GITHUB_RUN_ID}}' From 986ff20cc81fe9c90f91473426e352264ac92a05 Mon Sep 17 00:00:00 2001 From: tperehinets Date: Wed, 16 Aug 2023 14:54:11 +0300 Subject: [PATCH 08/73] Updated documentation Signed-off-by: tperehinets --- plugins/catalog/api-report.md | 8 ++++++++ plugins/scaffolder-backend-module-gitlab/api-report.md | 6 +++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/plugins/catalog/api-report.md b/plugins/catalog/api-report.md index 3e33b16d8b..4fd49e147a 100644 --- a/plugins/catalog/api-report.md +++ b/plugins/catalog/api-report.md @@ -445,6 +445,8 @@ export function hasCatalogProcessingErrors( // @public (undocumented) export interface HasComponentsCardProps { + // (undocumented) + title?: string; // (undocumented) variant?: InfoCardVariants; } @@ -462,6 +464,8 @@ export function hasRelationWarnings( // @public (undocumented) export interface HasResourcesCardProps { + // (undocumented) + title?: string; // (undocumented) variant?: InfoCardVariants; } @@ -471,11 +475,15 @@ export interface HasSubcomponentsCardProps { // (undocumented) tableOptions?: TableOptions; // (undocumented) + title?: string; + // (undocumented) variant?: InfoCardVariants; } // @public (undocumented) export interface HasSystemsCardProps { + // (undocumented) + title?: string; // (undocumented) variant?: InfoCardVariants; } diff --git a/plugins/scaffolder-backend-module-gitlab/api-report.md b/plugins/scaffolder-backend-module-gitlab/api-report.md index eccada5d51..f7cf6024ec 100644 --- a/plugins/scaffolder-backend-module-gitlab/api-report.md +++ b/plugins/scaffolder-backend-module-gitlab/api-report.md @@ -26,8 +26,8 @@ export const createGitlabProjectAccessTokenAction: (options: { integrations: ScmIntegrationRegistry; }) => TemplateAction< { - repoUrl: string; projectId: string | number; + repoUrl: string; token?: string | undefined; name?: string | undefined; accessLevel?: number | undefined; @@ -44,8 +44,8 @@ export const createGitlabProjectDeployTokenAction: (options: { }) => TemplateAction< { name: string; - repoUrl: string; projectId: string | number; + repoUrl: string; token?: string | undefined; username?: string | undefined; scopes?: string[] | undefined; @@ -63,8 +63,8 @@ export const createGitlabProjectVariableAction: (options: { { key: string; value: string; - repoUrl: string; projectId: string | number; + repoUrl: string; variableType: string; token?: string | undefined; variableProtected?: boolean | undefined; From 1b1898a07a51a45e4ca08205ccb9fa5e2d92b905 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 16 Aug 2023 12:10:26 +0000 Subject: [PATCH 09/73] Update dependency swagger-ui-react to v5.3.2 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/yarn.lock b/yarn.lock index 8a220323d7..f13edd7ac6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9604,10 +9604,10 @@ __metadata: languageName: node linkType: hard -"@braintree/sanitize-url@npm:=6.0.2": - version: 6.0.2 - resolution: "@braintree/sanitize-url@npm:6.0.2" - checksum: 6a9dfd4081cc96516eeb281d1a83d3b5f1ad3d2837adf968fcc2ba18889ee833554f9c641b4083c36d3360a932e4504ddf25b0b51e9933c3742622df82cf7c9a +"@braintree/sanitize-url@npm:=6.0.4": + version: 6.0.4 + resolution: "@braintree/sanitize-url@npm:6.0.4" + checksum: f5ec6048973722ea1c46ae555d2e9eb848d7fa258994f8ea7d6db9514ee754ea3ef344ef71b3696d486776bcb839f3124e79f67c6b5b2814ed2da220b340627c languageName: node linkType: hard @@ -39959,11 +39959,11 @@ __metadata: linkType: hard "swagger-ui-react@npm:^5.0.0": - version: 5.3.1 - resolution: "swagger-ui-react@npm:5.3.1" + version: 5.3.2 + resolution: "swagger-ui-react@npm:5.3.2" dependencies: "@babel/runtime-corejs3": ^7.22.6 - "@braintree/sanitize-url": =6.0.2 + "@braintree/sanitize-url": =6.0.4 base64-js: ^1.5.1 classnames: ^2.3.1 css.escape: 1.5.1 @@ -39999,7 +39999,7 @@ __metadata: peerDependencies: react: ">=17.0.0" react-dom: ">=17.0.0" - checksum: 6f27e72bbd537a0c9d9d091d4632b4a09d95077c59815330186c495d67e17fd4dd1af649d5e8d93a61c896163d81d3faa2ae402418c3e7f43853b7d840712f7c + checksum: d01e011cfd3915bbd17f0a0c886062a292cbef99f0feff247a18eea457bf4500f9d8fe932977cfc6e68b19197d8e52809ca58f269f9fe3128347901ee3cf621b languageName: node linkType: hard From fd365326d06b9a3343196cfaea7a867631ca8683 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 16 Aug 2023 12:11:07 +0000 Subject: [PATCH 10/73] Update graphqlcodegenerator monorepo to v3.3.1 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/yarn.lock b/yarn.lock index 8a220323d7..fed1f7eb66 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10890,8 +10890,8 @@ __metadata: linkType: hard "@graphql-codegen/cli@npm:^3.0.0": - version: 3.3.0 - resolution: "@graphql-codegen/cli@npm:3.3.0" + version: 3.3.1 + resolution: "@graphql-codegen/cli@npm:3.3.1" dependencies: "@babel/generator": ^7.18.13 "@babel/template": ^7.18.10 @@ -10935,7 +10935,7 @@ __metadata: graphql-code-generator: cjs/bin.js graphql-codegen: cjs/bin.js graphql-codegen-esm: esm/bin.js - checksum: 7c3ae7ba62cfb5576e6c1fc78f81a2c59d399415b9ef2ba55818af00aff2337a047a61b1cedb6e89e73dac30d9a00e57045ff6052245934bc4c5cf35c9762250 + checksum: cc3c0b8f1fd8150591b35b549a04577e84ac9c30396ad100196f594f741dd34e69ec9b1335ec41c00afe4ecf1d7e3505c1859fa244bdef1d10753d2b441de962 languageName: node linkType: hard @@ -10954,18 +10954,18 @@ __metadata: linkType: hard "@graphql-codegen/graphql-modules-preset@npm:^3.0.0": - version: 3.1.2 - resolution: "@graphql-codegen/graphql-modules-preset@npm:3.1.2" + version: 3.1.3 + resolution: "@graphql-codegen/graphql-modules-preset@npm:3.1.3" dependencies: "@graphql-codegen/plugin-helpers": ^4.2.0 - "@graphql-codegen/visitor-plugin-common": 3.1.0 + "@graphql-codegen/visitor-plugin-common": 3.1.1 "@graphql-tools/utils": ^9.0.0 change-case-all: 1.0.15 parse-filepath: ^1.0.2 tslib: ~2.5.0 peerDependencies: graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - checksum: d3b4e9fe169742ce7973466045793ff0823c690f0736ba22aef3d4578be498746df108726ccad0c190d1c45a33816ab4e010b9c6e9931ced06ef7489d85a3691 + checksum: 6e7303a850984c3c414a96784f499dab188d94cf3d13b6f44cb3c59de4b5f127080df610a316554511cfe669283ac745d8b2537afbe6d8113e58f4b30a27c28b languageName: node linkType: hard @@ -10999,39 +10999,39 @@ __metadata: linkType: hard "@graphql-codegen/typescript-resolvers@npm:^3.0.0": - version: 3.2.0 - resolution: "@graphql-codegen/typescript-resolvers@npm:3.2.0" + version: 3.2.1 + resolution: "@graphql-codegen/typescript-resolvers@npm:3.2.1" dependencies: "@graphql-codegen/plugin-helpers": ^4.2.0 - "@graphql-codegen/typescript": ^3.0.3 - "@graphql-codegen/visitor-plugin-common": 3.1.0 + "@graphql-codegen/typescript": ^3.0.4 + "@graphql-codegen/visitor-plugin-common": 3.1.1 "@graphql-tools/utils": ^9.0.0 auto-bind: ~4.0.0 tslib: ~2.5.0 peerDependencies: graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - checksum: d866b95775c95d1685e832a1d24df2a1e98feb67f35ef20a5d590c42b7314307b48399531b0cdc004e0be1062769ffe1e1a4757863ed1ca1f575dcd5e08b014d + checksum: a84f8fc68fe778beabbf537f1312699a220a3a605d972403075d8307fb7fe9aec73ae2eb5b42dea9f3a7c91deabfe6e1271d607e1b2c84b346686107f39354fb languageName: node linkType: hard -"@graphql-codegen/typescript@npm:^3.0.0, @graphql-codegen/typescript@npm:^3.0.3": - version: 3.0.3 - resolution: "@graphql-codegen/typescript@npm:3.0.3" +"@graphql-codegen/typescript@npm:^3.0.0, @graphql-codegen/typescript@npm:^3.0.4": + version: 3.0.4 + resolution: "@graphql-codegen/typescript@npm:3.0.4" dependencies: "@graphql-codegen/plugin-helpers": ^4.2.0 "@graphql-codegen/schema-ast": ^3.0.1 - "@graphql-codegen/visitor-plugin-common": 3.1.0 + "@graphql-codegen/visitor-plugin-common": 3.1.1 auto-bind: ~4.0.0 tslib: ~2.5.0 peerDependencies: graphql: ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - checksum: 5d292379b5f25f1df0dfdec62211f7e304a85910b6e30dcb28e89478dd15b565f05993913d9b8cf7f08b1e9166242f08e9cb68bd9688f486bd5eada7c6f82442 + checksum: ede5311c5f620e16c3e98f51bdcedc7fd42f2c552a8ca5a946f757dc9709c384a12d32d088769d04041461d3318159ad0644f70056aea1877ee80a0bdc48de1f languageName: node linkType: hard -"@graphql-codegen/visitor-plugin-common@npm:3.1.0": - version: 3.1.0 - resolution: "@graphql-codegen/visitor-plugin-common@npm:3.1.0" +"@graphql-codegen/visitor-plugin-common@npm:3.1.1": + version: 3.1.1 + resolution: "@graphql-codegen/visitor-plugin-common@npm:3.1.1" dependencies: "@graphql-codegen/plugin-helpers": ^4.2.0 "@graphql-tools/optimize": ^1.3.0 @@ -11045,7 +11045,7 @@ __metadata: tslib: ~2.5.0 peerDependencies: graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - checksum: 7532666c578680cda538d7b859ee7d5541113f3972f0f2396affa4dd6823a2e2d6f8b715c685912652b0906722dfafb4375c462aa3b4f991a12ec0a28f1b7ba7 + checksum: 8dbef75ba0576a7de5e134b53778d64d818084df01e74554adc979f08db8446e9734889575c820449b6ef9febd6a9005fb89c7c9c101a9e398c195b5c3279353 languageName: node linkType: hard From 0778a40940ff529f73d9e6ca74dbf83001ebba97 Mon Sep 17 00:00:00 2001 From: tperehinets Date: Wed, 16 Aug 2023 15:15:33 +0300 Subject: [PATCH 11/73] Updated more documentation. Signed-off-by: tperehinets --- plugins/scaffolder-backend-module-gitlab/api-report.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/scaffolder-backend-module-gitlab/api-report.md b/plugins/scaffolder-backend-module-gitlab/api-report.md index f7cf6024ec..eccada5d51 100644 --- a/plugins/scaffolder-backend-module-gitlab/api-report.md +++ b/plugins/scaffolder-backend-module-gitlab/api-report.md @@ -26,8 +26,8 @@ export const createGitlabProjectAccessTokenAction: (options: { integrations: ScmIntegrationRegistry; }) => TemplateAction< { - projectId: string | number; repoUrl: string; + projectId: string | number; token?: string | undefined; name?: string | undefined; accessLevel?: number | undefined; @@ -44,8 +44,8 @@ export const createGitlabProjectDeployTokenAction: (options: { }) => TemplateAction< { name: string; - projectId: string | number; repoUrl: string; + projectId: string | number; token?: string | undefined; username?: string | undefined; scopes?: string[] | undefined; @@ -63,8 +63,8 @@ export const createGitlabProjectVariableAction: (options: { { key: string; value: string; - projectId: string | number; repoUrl: string; + projectId: string | number; variableType: string; token?: string | undefined; variableProtected?: boolean | undefined; From 0bba0e75dc135c19264e0ab29eb4a888c186a094 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 16 Aug 2023 13:14:57 +0000 Subject: [PATCH 12/73] Update aws-sdk-js-v3 monorepo to v3.391.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 1254 +++++++++++++++++++++++++++-------------------------- 1 file changed, 642 insertions(+), 612 deletions(-) diff --git a/yarn.lock b/yarn.lock index f13edd7ac6..964b564bff 100644 --- a/yarn.lock +++ b/yarn.lock @@ -569,457 +569,457 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/client-cognito-identity@npm:3.387.0": - version: 3.387.0 - resolution: "@aws-sdk/client-cognito-identity@npm:3.387.0" +"@aws-sdk/client-cognito-identity@npm:3.391.0": + version: 3.391.0 + resolution: "@aws-sdk/client-cognito-identity@npm:3.391.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/client-sts": 3.387.0 - "@aws-sdk/credential-provider-node": 3.387.0 - "@aws-sdk/middleware-host-header": 3.387.0 - "@aws-sdk/middleware-logger": 3.387.0 - "@aws-sdk/middleware-recursion-detection": 3.387.0 - "@aws-sdk/middleware-signing": 3.387.0 - "@aws-sdk/middleware-user-agent": 3.387.0 - "@aws-sdk/types": 3.387.0 - "@aws-sdk/util-endpoints": 3.387.0 - "@aws-sdk/util-user-agent-browser": 3.387.0 - "@aws-sdk/util-user-agent-node": 3.387.0 - "@smithy/config-resolver": ^2.0.2 - "@smithy/fetch-http-handler": ^2.0.2 - "@smithy/hash-node": ^2.0.2 - "@smithy/invalid-dependency": ^2.0.2 - "@smithy/middleware-content-length": ^2.0.2 - "@smithy/middleware-endpoint": ^2.0.2 - "@smithy/middleware-retry": ^2.0.2 - "@smithy/middleware-serde": ^2.0.2 + "@aws-sdk/client-sts": 3.391.0 + "@aws-sdk/credential-provider-node": 3.391.0 + "@aws-sdk/middleware-host-header": 3.391.0 + "@aws-sdk/middleware-logger": 3.391.0 + "@aws-sdk/middleware-recursion-detection": 3.391.0 + "@aws-sdk/middleware-signing": 3.391.0 + "@aws-sdk/middleware-user-agent": 3.391.0 + "@aws-sdk/types": 3.391.0 + "@aws-sdk/util-endpoints": 3.391.0 + "@aws-sdk/util-user-agent-browser": 3.391.0 + "@aws-sdk/util-user-agent-node": 3.391.0 + "@smithy/config-resolver": ^2.0.3 + "@smithy/fetch-http-handler": ^2.0.3 + "@smithy/hash-node": ^2.0.3 + "@smithy/invalid-dependency": ^2.0.3 + "@smithy/middleware-content-length": ^2.0.3 + "@smithy/middleware-endpoint": ^2.0.3 + "@smithy/middleware-retry": ^2.0.3 + "@smithy/middleware-serde": ^2.0.3 "@smithy/middleware-stack": ^2.0.0 - "@smithy/node-config-provider": ^2.0.2 - "@smithy/node-http-handler": ^2.0.2 - "@smithy/protocol-http": ^2.0.2 - "@smithy/smithy-client": ^2.0.2 - "@smithy/types": ^2.1.0 - "@smithy/url-parser": ^2.0.2 + "@smithy/node-config-provider": ^2.0.3 + "@smithy/node-http-handler": ^2.0.3 + "@smithy/protocol-http": ^2.0.3 + "@smithy/smithy-client": ^2.0.3 + "@smithy/types": ^2.2.0 + "@smithy/url-parser": ^2.0.3 "@smithy/util-base64": ^2.0.0 "@smithy/util-body-length-browser": ^2.0.0 "@smithy/util-body-length-node": ^2.0.0 - "@smithy/util-defaults-mode-browser": ^2.0.2 - "@smithy/util-defaults-mode-node": ^2.0.2 + "@smithy/util-defaults-mode-browser": ^2.0.3 + "@smithy/util-defaults-mode-node": ^2.0.3 "@smithy/util-retry": ^2.0.0 "@smithy/util-utf8": ^2.0.0 tslib: ^2.5.0 - checksum: 88be8e754b0f65bef93cf00f87336aa66b6e7d52d78f6bef132716f528f908318628f87316d0feae2d4a8fcf0ba2d2362ecae4bdea193eb8f14ed43eaa2deee1 + checksum: 62cb9721b48b3615679604be11358ca75453798b8a7b2e124afe6fcf46d8224395b77acc956707a00dc3feac54b676517e4e99de62591ac04d186b778e434461 languageName: node linkType: hard "@aws-sdk/client-eks@npm:^3.350.0": - version: 3.387.0 - resolution: "@aws-sdk/client-eks@npm:3.387.0" + version: 3.391.0 + resolution: "@aws-sdk/client-eks@npm:3.391.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/client-sts": 3.387.0 - "@aws-sdk/credential-provider-node": 3.387.0 - "@aws-sdk/middleware-host-header": 3.387.0 - "@aws-sdk/middleware-logger": 3.387.0 - "@aws-sdk/middleware-recursion-detection": 3.387.0 - "@aws-sdk/middleware-signing": 3.387.0 - "@aws-sdk/middleware-user-agent": 3.387.0 - "@aws-sdk/types": 3.387.0 - "@aws-sdk/util-endpoints": 3.387.0 - "@aws-sdk/util-user-agent-browser": 3.387.0 - "@aws-sdk/util-user-agent-node": 3.387.0 - "@smithy/config-resolver": ^2.0.2 - "@smithy/fetch-http-handler": ^2.0.2 - "@smithy/hash-node": ^2.0.2 - "@smithy/invalid-dependency": ^2.0.2 - "@smithy/middleware-content-length": ^2.0.2 - "@smithy/middleware-endpoint": ^2.0.2 - "@smithy/middleware-retry": ^2.0.2 - "@smithy/middleware-serde": ^2.0.2 + "@aws-sdk/client-sts": 3.391.0 + "@aws-sdk/credential-provider-node": 3.391.0 + "@aws-sdk/middleware-host-header": 3.391.0 + "@aws-sdk/middleware-logger": 3.391.0 + "@aws-sdk/middleware-recursion-detection": 3.391.0 + "@aws-sdk/middleware-signing": 3.391.0 + "@aws-sdk/middleware-user-agent": 3.391.0 + "@aws-sdk/types": 3.391.0 + "@aws-sdk/util-endpoints": 3.391.0 + "@aws-sdk/util-user-agent-browser": 3.391.0 + "@aws-sdk/util-user-agent-node": 3.391.0 + "@smithy/config-resolver": ^2.0.3 + "@smithy/fetch-http-handler": ^2.0.3 + "@smithy/hash-node": ^2.0.3 + "@smithy/invalid-dependency": ^2.0.3 + "@smithy/middleware-content-length": ^2.0.3 + "@smithy/middleware-endpoint": ^2.0.3 + "@smithy/middleware-retry": ^2.0.3 + "@smithy/middleware-serde": ^2.0.3 "@smithy/middleware-stack": ^2.0.0 - "@smithy/node-config-provider": ^2.0.2 - "@smithy/node-http-handler": ^2.0.2 - "@smithy/protocol-http": ^2.0.2 - "@smithy/smithy-client": ^2.0.2 - "@smithy/types": ^2.1.0 - "@smithy/url-parser": ^2.0.2 + "@smithy/node-config-provider": ^2.0.3 + "@smithy/node-http-handler": ^2.0.3 + "@smithy/protocol-http": ^2.0.3 + "@smithy/smithy-client": ^2.0.3 + "@smithy/types": ^2.2.0 + "@smithy/url-parser": ^2.0.3 "@smithy/util-base64": ^2.0.0 "@smithy/util-body-length-browser": ^2.0.0 "@smithy/util-body-length-node": ^2.0.0 - "@smithy/util-defaults-mode-browser": ^2.0.2 - "@smithy/util-defaults-mode-node": ^2.0.2 + "@smithy/util-defaults-mode-browser": ^2.0.3 + "@smithy/util-defaults-mode-node": ^2.0.3 "@smithy/util-retry": ^2.0.0 "@smithy/util-utf8": ^2.0.0 - "@smithy/util-waiter": ^2.0.2 + "@smithy/util-waiter": ^2.0.3 tslib: ^2.5.0 uuid: ^8.3.2 - checksum: f4a8a64d7c7bfef23c4fb610156a4b80c14728870bf67346ee052082f136f02776aba89600adc79dae803d1e96c351f16a0dc4a0ddbe9df09a198644966d4fc3 + checksum: b1b4ad33d34068c12492065eca485f9973122b0fedc76e3806e4886fec60be0c912b81c4b7e584f3f4fdbbe5ba7f10e009798f45fc62653347df01e449a5e7cf languageName: node linkType: hard "@aws-sdk/client-organizations@npm:^3.350.0": - version: 3.387.0 - resolution: "@aws-sdk/client-organizations@npm:3.387.0" + version: 3.391.0 + resolution: "@aws-sdk/client-organizations@npm:3.391.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/client-sts": 3.387.0 - "@aws-sdk/credential-provider-node": 3.387.0 - "@aws-sdk/middleware-host-header": 3.387.0 - "@aws-sdk/middleware-logger": 3.387.0 - "@aws-sdk/middleware-recursion-detection": 3.387.0 - "@aws-sdk/middleware-signing": 3.387.0 - "@aws-sdk/middleware-user-agent": 3.387.0 - "@aws-sdk/types": 3.387.0 - "@aws-sdk/util-endpoints": 3.387.0 - "@aws-sdk/util-user-agent-browser": 3.387.0 - "@aws-sdk/util-user-agent-node": 3.387.0 - "@smithy/config-resolver": ^2.0.2 - "@smithy/fetch-http-handler": ^2.0.2 - "@smithy/hash-node": ^2.0.2 - "@smithy/invalid-dependency": ^2.0.2 - "@smithy/middleware-content-length": ^2.0.2 - "@smithy/middleware-endpoint": ^2.0.2 - "@smithy/middleware-retry": ^2.0.2 - "@smithy/middleware-serde": ^2.0.2 + "@aws-sdk/client-sts": 3.391.0 + "@aws-sdk/credential-provider-node": 3.391.0 + "@aws-sdk/middleware-host-header": 3.391.0 + "@aws-sdk/middleware-logger": 3.391.0 + "@aws-sdk/middleware-recursion-detection": 3.391.0 + "@aws-sdk/middleware-signing": 3.391.0 + "@aws-sdk/middleware-user-agent": 3.391.0 + "@aws-sdk/types": 3.391.0 + "@aws-sdk/util-endpoints": 3.391.0 + "@aws-sdk/util-user-agent-browser": 3.391.0 + "@aws-sdk/util-user-agent-node": 3.391.0 + "@smithy/config-resolver": ^2.0.3 + "@smithy/fetch-http-handler": ^2.0.3 + "@smithy/hash-node": ^2.0.3 + "@smithy/invalid-dependency": ^2.0.3 + "@smithy/middleware-content-length": ^2.0.3 + "@smithy/middleware-endpoint": ^2.0.3 + "@smithy/middleware-retry": ^2.0.3 + "@smithy/middleware-serde": ^2.0.3 "@smithy/middleware-stack": ^2.0.0 - "@smithy/node-config-provider": ^2.0.2 - "@smithy/node-http-handler": ^2.0.2 - "@smithy/protocol-http": ^2.0.2 - "@smithy/smithy-client": ^2.0.2 - "@smithy/types": ^2.1.0 - "@smithy/url-parser": ^2.0.2 + "@smithy/node-config-provider": ^2.0.3 + "@smithy/node-http-handler": ^2.0.3 + "@smithy/protocol-http": ^2.0.3 + "@smithy/smithy-client": ^2.0.3 + "@smithy/types": ^2.2.0 + "@smithy/url-parser": ^2.0.3 "@smithy/util-base64": ^2.0.0 "@smithy/util-body-length-browser": ^2.0.0 "@smithy/util-body-length-node": ^2.0.0 - "@smithy/util-defaults-mode-browser": ^2.0.2 - "@smithy/util-defaults-mode-node": ^2.0.2 + "@smithy/util-defaults-mode-browser": ^2.0.3 + "@smithy/util-defaults-mode-node": ^2.0.3 "@smithy/util-retry": ^2.0.0 "@smithy/util-utf8": ^2.0.0 tslib: ^2.5.0 - checksum: 095de70f230113d1b035a25c93074e6953a06b99deb0bf39928c661e05710c7678defbdbb58dbb6919e6f4633fbc9a26a684b07821ba69e244e14733ba978eaa + checksum: 69fc34393c063be11879cb6892943567babfd726955678df2253b1e6a92a3367cd54c43f047e1a17af5ca78d426baa22052580fdc517813c8a7026802ad1fb97 languageName: node linkType: hard "@aws-sdk/client-s3@npm:^3.350.0": - version: 3.387.0 - resolution: "@aws-sdk/client-s3@npm:3.387.0" + version: 3.391.0 + resolution: "@aws-sdk/client-s3@npm:3.391.0" dependencies: "@aws-crypto/sha1-browser": 3.0.0 "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/client-sts": 3.387.0 - "@aws-sdk/credential-provider-node": 3.387.0 - "@aws-sdk/middleware-bucket-endpoint": 3.387.0 - "@aws-sdk/middleware-expect-continue": 3.387.0 - "@aws-sdk/middleware-flexible-checksums": 3.387.0 - "@aws-sdk/middleware-host-header": 3.387.0 - "@aws-sdk/middleware-location-constraint": 3.387.0 - "@aws-sdk/middleware-logger": 3.387.0 - "@aws-sdk/middleware-recursion-detection": 3.387.0 - "@aws-sdk/middleware-sdk-s3": 3.387.0 - "@aws-sdk/middleware-signing": 3.387.0 - "@aws-sdk/middleware-ssec": 3.387.0 - "@aws-sdk/middleware-user-agent": 3.387.0 - "@aws-sdk/signature-v4-multi-region": 3.387.0 - "@aws-sdk/types": 3.387.0 - "@aws-sdk/util-endpoints": 3.387.0 - "@aws-sdk/util-user-agent-browser": 3.387.0 - "@aws-sdk/util-user-agent-node": 3.387.0 + "@aws-sdk/client-sts": 3.391.0 + "@aws-sdk/credential-provider-node": 3.391.0 + "@aws-sdk/middleware-bucket-endpoint": 3.391.0 + "@aws-sdk/middleware-expect-continue": 3.391.0 + "@aws-sdk/middleware-flexible-checksums": 3.391.0 + "@aws-sdk/middleware-host-header": 3.391.0 + "@aws-sdk/middleware-location-constraint": 3.391.0 + "@aws-sdk/middleware-logger": 3.391.0 + "@aws-sdk/middleware-recursion-detection": 3.391.0 + "@aws-sdk/middleware-sdk-s3": 3.391.0 + "@aws-sdk/middleware-signing": 3.391.0 + "@aws-sdk/middleware-ssec": 3.391.0 + "@aws-sdk/middleware-user-agent": 3.391.0 + "@aws-sdk/signature-v4-multi-region": 3.391.0 + "@aws-sdk/types": 3.391.0 + "@aws-sdk/util-endpoints": 3.391.0 + "@aws-sdk/util-user-agent-browser": 3.391.0 + "@aws-sdk/util-user-agent-node": 3.391.0 "@aws-sdk/xml-builder": 3.310.0 - "@smithy/config-resolver": ^2.0.2 - "@smithy/eventstream-serde-browser": ^2.0.2 - "@smithy/eventstream-serde-config-resolver": ^2.0.2 - "@smithy/eventstream-serde-node": ^2.0.2 - "@smithy/fetch-http-handler": ^2.0.2 - "@smithy/hash-blob-browser": ^2.0.2 - "@smithy/hash-node": ^2.0.2 - "@smithy/hash-stream-node": ^2.0.2 - "@smithy/invalid-dependency": ^2.0.2 - "@smithy/md5-js": ^2.0.2 - "@smithy/middleware-content-length": ^2.0.2 - "@smithy/middleware-endpoint": ^2.0.2 - "@smithy/middleware-retry": ^2.0.2 - "@smithy/middleware-serde": ^2.0.2 + "@smithy/config-resolver": ^2.0.3 + "@smithy/eventstream-serde-browser": ^2.0.3 + "@smithy/eventstream-serde-config-resolver": ^2.0.3 + "@smithy/eventstream-serde-node": ^2.0.3 + "@smithy/fetch-http-handler": ^2.0.3 + "@smithy/hash-blob-browser": ^2.0.3 + "@smithy/hash-node": ^2.0.3 + "@smithy/hash-stream-node": ^2.0.3 + "@smithy/invalid-dependency": ^2.0.3 + "@smithy/md5-js": ^2.0.3 + "@smithy/middleware-content-length": ^2.0.3 + "@smithy/middleware-endpoint": ^2.0.3 + "@smithy/middleware-retry": ^2.0.3 + "@smithy/middleware-serde": ^2.0.3 "@smithy/middleware-stack": ^2.0.0 - "@smithy/node-config-provider": ^2.0.2 - "@smithy/node-http-handler": ^2.0.2 - "@smithy/protocol-http": ^2.0.2 - "@smithy/smithy-client": ^2.0.2 - "@smithy/types": ^2.1.0 - "@smithy/url-parser": ^2.0.2 + "@smithy/node-config-provider": ^2.0.3 + "@smithy/node-http-handler": ^2.0.3 + "@smithy/protocol-http": ^2.0.3 + "@smithy/smithy-client": ^2.0.3 + "@smithy/types": ^2.2.0 + "@smithy/url-parser": ^2.0.3 "@smithy/util-base64": ^2.0.0 "@smithy/util-body-length-browser": ^2.0.0 "@smithy/util-body-length-node": ^2.0.0 - "@smithy/util-defaults-mode-browser": ^2.0.2 - "@smithy/util-defaults-mode-node": ^2.0.2 + "@smithy/util-defaults-mode-browser": ^2.0.3 + "@smithy/util-defaults-mode-node": ^2.0.3 "@smithy/util-retry": ^2.0.0 - "@smithy/util-stream": ^2.0.2 + "@smithy/util-stream": ^2.0.3 "@smithy/util-utf8": ^2.0.0 - "@smithy/util-waiter": ^2.0.2 + "@smithy/util-waiter": ^2.0.3 fast-xml-parser: 4.2.5 tslib: ^2.5.0 - checksum: cc0600dfc971b203bb737850613ab986811b36014f4f42e8cebca71d05baf7ef3d618687ae43c50694b1341f339a44671813187dff6910d24130418d755dd265 + checksum: 7210fdd27a91fa6be6d86f6846a5afd52e1e951ba18e2e0664af432a4bc24092c411a5bed2db070664978f74ff71a3d586609531860a044a6540a4138587c5a8 languageName: node linkType: hard "@aws-sdk/client-sqs@npm:^3.350.0": - version: 3.387.0 - resolution: "@aws-sdk/client-sqs@npm:3.387.0" + version: 3.391.0 + resolution: "@aws-sdk/client-sqs@npm:3.391.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/client-sts": 3.387.0 - "@aws-sdk/credential-provider-node": 3.387.0 - "@aws-sdk/middleware-host-header": 3.387.0 - "@aws-sdk/middleware-logger": 3.387.0 - "@aws-sdk/middleware-recursion-detection": 3.387.0 - "@aws-sdk/middleware-sdk-sqs": 3.387.0 - "@aws-sdk/middleware-signing": 3.387.0 - "@aws-sdk/middleware-user-agent": 3.387.0 - "@aws-sdk/types": 3.387.0 - "@aws-sdk/util-endpoints": 3.387.0 - "@aws-sdk/util-user-agent-browser": 3.387.0 - "@aws-sdk/util-user-agent-node": 3.387.0 - "@smithy/config-resolver": ^2.0.2 - "@smithy/fetch-http-handler": ^2.0.2 - "@smithy/hash-node": ^2.0.2 - "@smithy/invalid-dependency": ^2.0.2 - "@smithy/md5-js": ^2.0.2 - "@smithy/middleware-content-length": ^2.0.2 - "@smithy/middleware-endpoint": ^2.0.2 - "@smithy/middleware-retry": ^2.0.2 - "@smithy/middleware-serde": ^2.0.2 + "@aws-sdk/client-sts": 3.391.0 + "@aws-sdk/credential-provider-node": 3.391.0 + "@aws-sdk/middleware-host-header": 3.391.0 + "@aws-sdk/middleware-logger": 3.391.0 + "@aws-sdk/middleware-recursion-detection": 3.391.0 + "@aws-sdk/middleware-sdk-sqs": 3.391.0 + "@aws-sdk/middleware-signing": 3.391.0 + "@aws-sdk/middleware-user-agent": 3.391.0 + "@aws-sdk/types": 3.391.0 + "@aws-sdk/util-endpoints": 3.391.0 + "@aws-sdk/util-user-agent-browser": 3.391.0 + "@aws-sdk/util-user-agent-node": 3.391.0 + "@smithy/config-resolver": ^2.0.3 + "@smithy/fetch-http-handler": ^2.0.3 + "@smithy/hash-node": ^2.0.3 + "@smithy/invalid-dependency": ^2.0.3 + "@smithy/md5-js": ^2.0.3 + "@smithy/middleware-content-length": ^2.0.3 + "@smithy/middleware-endpoint": ^2.0.3 + "@smithy/middleware-retry": ^2.0.3 + "@smithy/middleware-serde": ^2.0.3 "@smithy/middleware-stack": ^2.0.0 - "@smithy/node-config-provider": ^2.0.2 - "@smithy/node-http-handler": ^2.0.2 - "@smithy/protocol-http": ^2.0.2 - "@smithy/smithy-client": ^2.0.2 - "@smithy/types": ^2.1.0 - "@smithy/url-parser": ^2.0.2 + "@smithy/node-config-provider": ^2.0.3 + "@smithy/node-http-handler": ^2.0.3 + "@smithy/protocol-http": ^2.0.3 + "@smithy/smithy-client": ^2.0.3 + "@smithy/types": ^2.2.0 + "@smithy/url-parser": ^2.0.3 "@smithy/util-base64": ^2.0.0 "@smithy/util-body-length-browser": ^2.0.0 "@smithy/util-body-length-node": ^2.0.0 - "@smithy/util-defaults-mode-browser": ^2.0.2 - "@smithy/util-defaults-mode-node": ^2.0.2 + "@smithy/util-defaults-mode-browser": ^2.0.3 + "@smithy/util-defaults-mode-node": ^2.0.3 "@smithy/util-retry": ^2.0.0 "@smithy/util-utf8": ^2.0.0 fast-xml-parser: 4.2.5 tslib: ^2.5.0 - checksum: 3382ad67ec9679b73a571e0389db1ae80f21fa28beb3a13e3107ce72021705f37c3aacb06b3a3cfb4bc751de0453a443e30f315d5b2cb319abcd3454158c3518 + checksum: 1bcbcf6e3a8a031cc8facf099ba5fa45fca69ac2235b3c37dd267b09db00f9f3483b3e01026f3a93acd4d68bc6dfa110feea550f90a4ee0f51c4414eb0e280fd languageName: node linkType: hard -"@aws-sdk/client-sso@npm:3.387.0": - version: 3.387.0 - resolution: "@aws-sdk/client-sso@npm:3.387.0" +"@aws-sdk/client-sso@npm:3.391.0": + version: 3.391.0 + resolution: "@aws-sdk/client-sso@npm:3.391.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/middleware-host-header": 3.387.0 - "@aws-sdk/middleware-logger": 3.387.0 - "@aws-sdk/middleware-recursion-detection": 3.387.0 - "@aws-sdk/middleware-user-agent": 3.387.0 - "@aws-sdk/types": 3.387.0 - "@aws-sdk/util-endpoints": 3.387.0 - "@aws-sdk/util-user-agent-browser": 3.387.0 - "@aws-sdk/util-user-agent-node": 3.387.0 - "@smithy/config-resolver": ^2.0.2 - "@smithy/fetch-http-handler": ^2.0.2 - "@smithy/hash-node": ^2.0.2 - "@smithy/invalid-dependency": ^2.0.2 - "@smithy/middleware-content-length": ^2.0.2 - "@smithy/middleware-endpoint": ^2.0.2 - "@smithy/middleware-retry": ^2.0.2 - "@smithy/middleware-serde": ^2.0.2 + "@aws-sdk/middleware-host-header": 3.391.0 + "@aws-sdk/middleware-logger": 3.391.0 + "@aws-sdk/middleware-recursion-detection": 3.391.0 + "@aws-sdk/middleware-user-agent": 3.391.0 + "@aws-sdk/types": 3.391.0 + "@aws-sdk/util-endpoints": 3.391.0 + "@aws-sdk/util-user-agent-browser": 3.391.0 + "@aws-sdk/util-user-agent-node": 3.391.0 + "@smithy/config-resolver": ^2.0.3 + "@smithy/fetch-http-handler": ^2.0.3 + "@smithy/hash-node": ^2.0.3 + "@smithy/invalid-dependency": ^2.0.3 + "@smithy/middleware-content-length": ^2.0.3 + "@smithy/middleware-endpoint": ^2.0.3 + "@smithy/middleware-retry": ^2.0.3 + "@smithy/middleware-serde": ^2.0.3 "@smithy/middleware-stack": ^2.0.0 - "@smithy/node-config-provider": ^2.0.2 - "@smithy/node-http-handler": ^2.0.2 - "@smithy/protocol-http": ^2.0.2 - "@smithy/smithy-client": ^2.0.2 - "@smithy/types": ^2.1.0 - "@smithy/url-parser": ^2.0.2 + "@smithy/node-config-provider": ^2.0.3 + "@smithy/node-http-handler": ^2.0.3 + "@smithy/protocol-http": ^2.0.3 + "@smithy/smithy-client": ^2.0.3 + "@smithy/types": ^2.2.0 + "@smithy/url-parser": ^2.0.3 "@smithy/util-base64": ^2.0.0 "@smithy/util-body-length-browser": ^2.0.0 "@smithy/util-body-length-node": ^2.0.0 - "@smithy/util-defaults-mode-browser": ^2.0.2 - "@smithy/util-defaults-mode-node": ^2.0.2 + "@smithy/util-defaults-mode-browser": ^2.0.3 + "@smithy/util-defaults-mode-node": ^2.0.3 "@smithy/util-retry": ^2.0.0 "@smithy/util-utf8": ^2.0.0 tslib: ^2.5.0 - checksum: ca4750675bc39e7201b4b611cd642cb5f37413138a09670499c00ea637509aab0bd54a7b96e6b4a2bec810f12c9c87d0519fc6cad0a7f8a86ecad4bf8047a7ac + checksum: 6cfcc63d172ede2144924652ceb664839b7c5abe4085caadc878c99137561f0394eecb96c93c51f7ca6aa408bf7dfe4e03409f9e9a4349cef1e62a0e8b4991a8 languageName: node linkType: hard -"@aws-sdk/client-sts@npm:3.387.0, @aws-sdk/client-sts@npm:^3.350.0": - version: 3.387.0 - resolution: "@aws-sdk/client-sts@npm:3.387.0" +"@aws-sdk/client-sts@npm:3.391.0, @aws-sdk/client-sts@npm:^3.350.0": + version: 3.391.0 + resolution: "@aws-sdk/client-sts@npm:3.391.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/credential-provider-node": 3.387.0 - "@aws-sdk/middleware-host-header": 3.387.0 - "@aws-sdk/middleware-logger": 3.387.0 - "@aws-sdk/middleware-recursion-detection": 3.387.0 - "@aws-sdk/middleware-sdk-sts": 3.387.0 - "@aws-sdk/middleware-signing": 3.387.0 - "@aws-sdk/middleware-user-agent": 3.387.0 - "@aws-sdk/types": 3.387.0 - "@aws-sdk/util-endpoints": 3.387.0 - "@aws-sdk/util-user-agent-browser": 3.387.0 - "@aws-sdk/util-user-agent-node": 3.387.0 - "@smithy/config-resolver": ^2.0.2 - "@smithy/fetch-http-handler": ^2.0.2 - "@smithy/hash-node": ^2.0.2 - "@smithy/invalid-dependency": ^2.0.2 - "@smithy/middleware-content-length": ^2.0.2 - "@smithy/middleware-endpoint": ^2.0.2 - "@smithy/middleware-retry": ^2.0.2 - "@smithy/middleware-serde": ^2.0.2 + "@aws-sdk/credential-provider-node": 3.391.0 + "@aws-sdk/middleware-host-header": 3.391.0 + "@aws-sdk/middleware-logger": 3.391.0 + "@aws-sdk/middleware-recursion-detection": 3.391.0 + "@aws-sdk/middleware-sdk-sts": 3.391.0 + "@aws-sdk/middleware-signing": 3.391.0 + "@aws-sdk/middleware-user-agent": 3.391.0 + "@aws-sdk/types": 3.391.0 + "@aws-sdk/util-endpoints": 3.391.0 + "@aws-sdk/util-user-agent-browser": 3.391.0 + "@aws-sdk/util-user-agent-node": 3.391.0 + "@smithy/config-resolver": ^2.0.3 + "@smithy/fetch-http-handler": ^2.0.3 + "@smithy/hash-node": ^2.0.3 + "@smithy/invalid-dependency": ^2.0.3 + "@smithy/middleware-content-length": ^2.0.3 + "@smithy/middleware-endpoint": ^2.0.3 + "@smithy/middleware-retry": ^2.0.3 + "@smithy/middleware-serde": ^2.0.3 "@smithy/middleware-stack": ^2.0.0 - "@smithy/node-config-provider": ^2.0.2 - "@smithy/node-http-handler": ^2.0.2 - "@smithy/protocol-http": ^2.0.2 - "@smithy/smithy-client": ^2.0.2 - "@smithy/types": ^2.1.0 - "@smithy/url-parser": ^2.0.2 + "@smithy/node-config-provider": ^2.0.3 + "@smithy/node-http-handler": ^2.0.3 + "@smithy/protocol-http": ^2.0.3 + "@smithy/smithy-client": ^2.0.3 + "@smithy/types": ^2.2.0 + "@smithy/url-parser": ^2.0.3 "@smithy/util-base64": ^2.0.0 "@smithy/util-body-length-browser": ^2.0.0 "@smithy/util-body-length-node": ^2.0.0 - "@smithy/util-defaults-mode-browser": ^2.0.2 - "@smithy/util-defaults-mode-node": ^2.0.2 + "@smithy/util-defaults-mode-browser": ^2.0.3 + "@smithy/util-defaults-mode-node": ^2.0.3 "@smithy/util-retry": ^2.0.0 "@smithy/util-utf8": ^2.0.0 fast-xml-parser: 4.2.5 tslib: ^2.5.0 - checksum: 6f3a0a36c7d2881b438e64a2b6cb11f809c4bc406af27fb692d5d3a7cebb93fc5b26f235ee5a4f3eea620b0c07d015ce11e2d8f32c79b3ea01221fe8548c2421 + checksum: 5f4d1660a1c614ca89e4d35c440fbc58ed0c254fb0406a7165d3827fe6b0b990615995cd78816f746e985b405863eb7de0cabd085fe395ffb3c2739035913f40 languageName: node linkType: hard -"@aws-sdk/credential-provider-cognito-identity@npm:3.387.0": - version: 3.387.0 - resolution: "@aws-sdk/credential-provider-cognito-identity@npm:3.387.0" +"@aws-sdk/credential-provider-cognito-identity@npm:3.391.0": + version: 3.391.0 + resolution: "@aws-sdk/credential-provider-cognito-identity@npm:3.391.0" dependencies: - "@aws-sdk/client-cognito-identity": 3.387.0 - "@aws-sdk/types": 3.387.0 + "@aws-sdk/client-cognito-identity": 3.391.0 + "@aws-sdk/types": 3.391.0 "@smithy/property-provider": ^2.0.0 - "@smithy/types": ^2.1.0 + "@smithy/types": ^2.2.0 tslib: ^2.5.0 - checksum: 126a72f6b6515237aa128c22fe6b0fbdfefbfb39950da8686187f567fdbaa6cb18d41437b67e80bd66e4f5d2eae0018587585700e0950c2a639e04092f31445e + checksum: 3168dd179a3a4e3cd0e46afb3bea47d4e0e991a978911ed8610e93bd449c0529f7abff852d6adcb3e0a0ea1d17a84a1535f9ce935620764100e66ffd20d42640 languageName: node linkType: hard -"@aws-sdk/credential-provider-env@npm:3.387.0": - version: 3.387.0 - resolution: "@aws-sdk/credential-provider-env@npm:3.387.0" +"@aws-sdk/credential-provider-env@npm:3.391.0": + version: 3.391.0 + resolution: "@aws-sdk/credential-provider-env@npm:3.391.0" dependencies: - "@aws-sdk/types": 3.387.0 + "@aws-sdk/types": 3.391.0 "@smithy/property-provider": ^2.0.0 - "@smithy/types": ^2.1.0 + "@smithy/types": ^2.2.0 tslib: ^2.5.0 - checksum: 7cfa4c87224a8632741d8fd1c25384a59413581b94eb79e1547a4f9b3542c2b27559c097a09f747f4b1617a3c382795f17aebc290b5e35a8a5fae1f93736449f + checksum: 08c797255225d26181687a355f3771d126914e58ed3532087535f88a5185439c273d80530e40540ea142613835f52fb6fe076324d1c356d452a2247a0a17a274 languageName: node linkType: hard -"@aws-sdk/credential-provider-ini@npm:3.387.0": - version: 3.387.0 - resolution: "@aws-sdk/credential-provider-ini@npm:3.387.0" +"@aws-sdk/credential-provider-ini@npm:3.391.0": + version: 3.391.0 + resolution: "@aws-sdk/credential-provider-ini@npm:3.391.0" dependencies: - "@aws-sdk/credential-provider-env": 3.387.0 - "@aws-sdk/credential-provider-process": 3.387.0 - "@aws-sdk/credential-provider-sso": 3.387.0 - "@aws-sdk/credential-provider-web-identity": 3.387.0 - "@aws-sdk/types": 3.387.0 + "@aws-sdk/credential-provider-env": 3.391.0 + "@aws-sdk/credential-provider-process": 3.391.0 + "@aws-sdk/credential-provider-sso": 3.391.0 + "@aws-sdk/credential-provider-web-identity": 3.391.0 + "@aws-sdk/types": 3.391.0 "@smithy/credential-provider-imds": ^2.0.0 "@smithy/property-provider": ^2.0.0 "@smithy/shared-ini-file-loader": ^2.0.0 - "@smithy/types": ^2.1.0 + "@smithy/types": ^2.2.0 tslib: ^2.5.0 - checksum: 40e69ca6081d24016b0a56fab6cca9b6cd2d5ca2cf17ab2e3e99a99e351d78d86d38f5e424a6c26355d099c6e060e24c56ff3064b6b1fbc2cad9c89b1dd655c4 + checksum: d1832002b5c61a12bc9139db3a21b1baeaa358684118e518dceab08baccf8c134d32e0397f362357a4a3c468fdb74cc5978287b47d5414ec4fc5e14fe1a16a05 languageName: node linkType: hard -"@aws-sdk/credential-provider-node@npm:3.387.0, @aws-sdk/credential-provider-node@npm:^3.350.0": - version: 3.387.0 - resolution: "@aws-sdk/credential-provider-node@npm:3.387.0" +"@aws-sdk/credential-provider-node@npm:3.391.0, @aws-sdk/credential-provider-node@npm:^3.350.0": + version: 3.391.0 + resolution: "@aws-sdk/credential-provider-node@npm:3.391.0" dependencies: - "@aws-sdk/credential-provider-env": 3.387.0 - "@aws-sdk/credential-provider-ini": 3.387.0 - "@aws-sdk/credential-provider-process": 3.387.0 - "@aws-sdk/credential-provider-sso": 3.387.0 - "@aws-sdk/credential-provider-web-identity": 3.387.0 - "@aws-sdk/types": 3.387.0 + "@aws-sdk/credential-provider-env": 3.391.0 + "@aws-sdk/credential-provider-ini": 3.391.0 + "@aws-sdk/credential-provider-process": 3.391.0 + "@aws-sdk/credential-provider-sso": 3.391.0 + "@aws-sdk/credential-provider-web-identity": 3.391.0 + "@aws-sdk/types": 3.391.0 "@smithy/credential-provider-imds": ^2.0.0 "@smithy/property-provider": ^2.0.0 "@smithy/shared-ini-file-loader": ^2.0.0 - "@smithy/types": ^2.1.0 + "@smithy/types": ^2.2.0 tslib: ^2.5.0 - checksum: cdc3f29c6be304e39cb42f8b53227f607e8bb10d0fae542614d76b322e1a75718d70a4726d97cb24d6e3da51245b837dcb07cfaf34eb8600d290267c8987a06a + checksum: 92d1cdefdd3b11208ccac18373ea10fee78a3a71e45b8d06a1c5d8cff7e7738277075eeb166a7cdd31b7b6e2d3b28d50a0d17d38db622b392a095b86296a2649 languageName: node linkType: hard -"@aws-sdk/credential-provider-process@npm:3.387.0": - version: 3.387.0 - resolution: "@aws-sdk/credential-provider-process@npm:3.387.0" +"@aws-sdk/credential-provider-process@npm:3.391.0": + version: 3.391.0 + resolution: "@aws-sdk/credential-provider-process@npm:3.391.0" dependencies: - "@aws-sdk/types": 3.387.0 + "@aws-sdk/types": 3.391.0 "@smithy/property-provider": ^2.0.0 "@smithy/shared-ini-file-loader": ^2.0.0 - "@smithy/types": ^2.1.0 + "@smithy/types": ^2.2.0 tslib: ^2.5.0 - checksum: 90b5c902b659dd6d39b6e81503fa4587ed5bb7c4b6a7ecb648561e8ca7a82c621b0b65496855cba3e68d63e1c432e26d40c89c0194e5952f31b52cbd20bca8ae + checksum: 67237867667f5f73d7ebc13b92f80f2c9fe58fa764dc7a7f9bb0a6d2c7060c4de014b9b718d07d79744804189f8d39fbe863034d21eda6ecc61f1e551d991532 languageName: node linkType: hard -"@aws-sdk/credential-provider-sso@npm:3.387.0": - version: 3.387.0 - resolution: "@aws-sdk/credential-provider-sso@npm:3.387.0" +"@aws-sdk/credential-provider-sso@npm:3.391.0": + version: 3.391.0 + resolution: "@aws-sdk/credential-provider-sso@npm:3.391.0" dependencies: - "@aws-sdk/client-sso": 3.387.0 - "@aws-sdk/token-providers": 3.387.0 - "@aws-sdk/types": 3.387.0 + "@aws-sdk/client-sso": 3.391.0 + "@aws-sdk/token-providers": 3.391.0 + "@aws-sdk/types": 3.391.0 "@smithy/property-provider": ^2.0.0 "@smithy/shared-ini-file-loader": ^2.0.0 - "@smithy/types": ^2.1.0 + "@smithy/types": ^2.2.0 tslib: ^2.5.0 - checksum: 740d16079be50a43a23b59c10d44fabca3da67ee251f2b6975d7b58909554c66e0c8a40f6e9457d85f2997a63cf435bcbf82e53d9d2f7c7005f243dbe5305fff + checksum: c6dcb8ccf4644e72f6628ccc1f166585dd5594a2aa6ec0640f3f2b36b254a811482cd5291116ad9f3667b0e536bfd29048f7f366702926b58279af3a580ca3ec languageName: node linkType: hard -"@aws-sdk/credential-provider-web-identity@npm:3.387.0": - version: 3.387.0 - resolution: "@aws-sdk/credential-provider-web-identity@npm:3.387.0" +"@aws-sdk/credential-provider-web-identity@npm:3.391.0": + version: 3.391.0 + resolution: "@aws-sdk/credential-provider-web-identity@npm:3.391.0" dependencies: - "@aws-sdk/types": 3.387.0 + "@aws-sdk/types": 3.391.0 "@smithy/property-provider": ^2.0.0 - "@smithy/types": ^2.1.0 + "@smithy/types": ^2.2.0 tslib: ^2.5.0 - checksum: 47cf13e4275ee948750c78c147fe70a64698197ed86bc38c29269e745001775cf4261e763e6dd37235ed50adc5638add08b3c04d6bb9af1cf1ef7c79f0cd336b + checksum: e568db62051d848d801f4948ecbf5680926d342fce4c7a608df9f91e3c3ae20b6ff43647a2a24c52b711e324018b0dc02c461d36f679987f6acf9985bc76d737 languageName: node linkType: hard "@aws-sdk/credential-providers@npm:^3.350.0": - version: 3.387.0 - resolution: "@aws-sdk/credential-providers@npm:3.387.0" + version: 3.391.0 + resolution: "@aws-sdk/credential-providers@npm:3.391.0" dependencies: - "@aws-sdk/client-cognito-identity": 3.387.0 - "@aws-sdk/client-sso": 3.387.0 - "@aws-sdk/client-sts": 3.387.0 - "@aws-sdk/credential-provider-cognito-identity": 3.387.0 - "@aws-sdk/credential-provider-env": 3.387.0 - "@aws-sdk/credential-provider-ini": 3.387.0 - "@aws-sdk/credential-provider-node": 3.387.0 - "@aws-sdk/credential-provider-process": 3.387.0 - "@aws-sdk/credential-provider-sso": 3.387.0 - "@aws-sdk/credential-provider-web-identity": 3.387.0 - "@aws-sdk/types": 3.387.0 + "@aws-sdk/client-cognito-identity": 3.391.0 + "@aws-sdk/client-sso": 3.391.0 + "@aws-sdk/client-sts": 3.391.0 + "@aws-sdk/credential-provider-cognito-identity": 3.391.0 + "@aws-sdk/credential-provider-env": 3.391.0 + "@aws-sdk/credential-provider-ini": 3.391.0 + "@aws-sdk/credential-provider-node": 3.391.0 + "@aws-sdk/credential-provider-process": 3.391.0 + "@aws-sdk/credential-provider-sso": 3.391.0 + "@aws-sdk/credential-provider-web-identity": 3.391.0 + "@aws-sdk/types": 3.391.0 "@smithy/credential-provider-imds": ^2.0.0 "@smithy/property-provider": ^2.0.0 - "@smithy/types": ^2.1.0 + "@smithy/types": ^2.2.0 tslib: ^2.5.0 - checksum: 761260e185f932cddc523d3e1491497cf3ff147496af354aed2ddd43da5a86218dbc2eccec00a71c166070dd24261795c2eb227ab986761478bd138ccb3fa9af + checksum: d090648d10c2e0e602234faa5e6d26e0834a5cc2c6d26df52d79fbde6733fe8dfbf1fb89e68449848a2078e643ac587ff57ccd157ea7a3324c419033333b1b3a languageName: node linkType: hard @@ -1045,33 +1045,33 @@ __metadata: linkType: hard "@aws-sdk/lib-storage@npm:^3.350.0": - version: 3.387.0 - resolution: "@aws-sdk/lib-storage@npm:3.387.0" + version: 3.391.0 + resolution: "@aws-sdk/lib-storage@npm:3.391.0" dependencies: "@smithy/abort-controller": ^2.0.1 - "@smithy/middleware-endpoint": ^2.0.2 - "@smithy/smithy-client": ^2.0.2 + "@smithy/middleware-endpoint": ^2.0.3 + "@smithy/smithy-client": ^2.0.3 buffer: 5.6.0 events: 3.3.0 stream-browserify: 3.0.0 tslib: ^2.5.0 peerDependencies: "@aws-sdk/client-s3": ^3.0.0 - checksum: aa753c2e6f9db051fe893ab2352a3c7c84ca53089ba837b972e1ae5911af71bb978002ea07ed59f673b3773fe3d1fbd2ce2fff251b671f672655cfbf9b48626e + checksum: 2447a727a003c78e456ebfaedfdb5724b60a1ec6b88f726a11bf65af133b6c80c3a0e652571869c44226c2e36094361ce32db9981bbcb840c77b1f8c1f85c236 languageName: node linkType: hard -"@aws-sdk/middleware-bucket-endpoint@npm:3.387.0": - version: 3.387.0 - resolution: "@aws-sdk/middleware-bucket-endpoint@npm:3.387.0" +"@aws-sdk/middleware-bucket-endpoint@npm:3.391.0": + version: 3.391.0 + resolution: "@aws-sdk/middleware-bucket-endpoint@npm:3.391.0" dependencies: - "@aws-sdk/types": 3.387.0 + "@aws-sdk/types": 3.391.0 "@aws-sdk/util-arn-parser": 3.310.0 - "@smithy/protocol-http": ^2.0.2 - "@smithy/types": ^2.1.0 + "@smithy/protocol-http": ^2.0.3 + "@smithy/types": ^2.2.0 "@smithy/util-config-provider": ^2.0.0 tslib: ^2.5.0 - checksum: 61b134bb6ba13d8007f1e8bd9a9c4ab4041c66fa184deaf7a0796297c218f14eb175f957038577909ac94e16fdf97d115f698a2d629ce1d4122593fba86f192e + checksum: dc2d48f091565ebcc957ee5da467f35edef4b35f42cfdbb526b2f0f00c4d983c7d59587d31994d92d6f054ecb772d46dde526a34165dd86aaec03dc7d4ae9e33 languageName: node linkType: hard @@ -1088,115 +1088,115 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-expect-continue@npm:3.387.0": - version: 3.387.0 - resolution: "@aws-sdk/middleware-expect-continue@npm:3.387.0" +"@aws-sdk/middleware-expect-continue@npm:3.391.0": + version: 3.391.0 + resolution: "@aws-sdk/middleware-expect-continue@npm:3.391.0" dependencies: - "@aws-sdk/types": 3.387.0 - "@smithy/protocol-http": ^2.0.2 - "@smithy/types": ^2.1.0 + "@aws-sdk/types": 3.391.0 + "@smithy/protocol-http": ^2.0.3 + "@smithy/types": ^2.2.0 tslib: ^2.5.0 - checksum: 48644c0809702b9b82c9d43bad3a3919868295914550d5c0ce72dbefa39dd24daf4aa02b7a431e1856e7bff3c3bff93ea1d06936f7a20213c1ddbea14cf6b1ad + checksum: 7b093e3b8caf60d0f24732fe06af8882b1f9679bc357c450fbbcfc4a0658521c5d1ed853f9b81dc658429e4eb3c84c9bc06f972680c8603be7726adbb4dc7daa languageName: node linkType: hard -"@aws-sdk/middleware-flexible-checksums@npm:3.387.0": - version: 3.387.0 - resolution: "@aws-sdk/middleware-flexible-checksums@npm:3.387.0" +"@aws-sdk/middleware-flexible-checksums@npm:3.391.0": + version: 3.391.0 + resolution: "@aws-sdk/middleware-flexible-checksums@npm:3.391.0" dependencies: "@aws-crypto/crc32": 3.0.0 "@aws-crypto/crc32c": 3.0.0 - "@aws-sdk/types": 3.387.0 + "@aws-sdk/types": 3.391.0 "@smithy/is-array-buffer": ^2.0.0 - "@smithy/protocol-http": ^2.0.2 - "@smithy/types": ^2.1.0 + "@smithy/protocol-http": ^2.0.3 + "@smithy/types": ^2.2.0 "@smithy/util-utf8": ^2.0.0 tslib: ^2.5.0 - checksum: 056a4558750f3c6bf676154778de813bbed2897d5a79efbe142ea6f99643fdf98b4367f602bb61a3cecd5e22ea2b680b842a0cfc5cf8f828d936626d8d4126ea + checksum: 52f98aea34d4acfab3566513021e7412542c33a6118b591a609eef0fb16bb128e971dff0dc97bb9214fda914d3fd3251924b1959b26c6eab493850b3b2d02546 languageName: node linkType: hard -"@aws-sdk/middleware-host-header@npm:3.387.0": - version: 3.387.0 - resolution: "@aws-sdk/middleware-host-header@npm:3.387.0" +"@aws-sdk/middleware-host-header@npm:3.391.0": + version: 3.391.0 + resolution: "@aws-sdk/middleware-host-header@npm:3.391.0" dependencies: - "@aws-sdk/types": 3.387.0 - "@smithy/protocol-http": ^2.0.2 - "@smithy/types": ^2.1.0 + "@aws-sdk/types": 3.391.0 + "@smithy/protocol-http": ^2.0.3 + "@smithy/types": ^2.2.0 tslib: ^2.5.0 - checksum: 91fdffa0051d1c426533170b1770c174abffc822b6e8e0cf0b850536a32c9fdea3241279494e2511232a46260b2320546bb9a59b2d4ee05a72f3cedabe6fa1a1 + checksum: c8dc6fab8125da76b3f98192d10a15351f2b2afb17a5e9770e7b4039b1f80144c5ff2aaea5cfecdb94890df13fa700c51452e88f2ad2c1eb45445a1d5448ca4a languageName: node linkType: hard -"@aws-sdk/middleware-location-constraint@npm:3.387.0": - version: 3.387.0 - resolution: "@aws-sdk/middleware-location-constraint@npm:3.387.0" +"@aws-sdk/middleware-location-constraint@npm:3.391.0": + version: 3.391.0 + resolution: "@aws-sdk/middleware-location-constraint@npm:3.391.0" dependencies: - "@aws-sdk/types": 3.387.0 - "@smithy/types": ^2.1.0 + "@aws-sdk/types": 3.391.0 + "@smithy/types": ^2.2.0 tslib: ^2.5.0 - checksum: 4027555e3c0ba089711a93ce0ca0ab4527052ff67fe7d390b59d305f238109b9f4aec63ac1e51b6e5a88026c2417967dc7091178061d096fbb3ee23ca2947555 + checksum: ce945bc089f58e01b08ac5dbe1e55d3ca9a2695b039bbe1bd9ecc21afc28465a2fabaf55eb21fb6b64ae5298ff94b29ecc33f61e564bcfa733096323d97f0855 languageName: node linkType: hard -"@aws-sdk/middleware-logger@npm:3.387.0": - version: 3.387.0 - resolution: "@aws-sdk/middleware-logger@npm:3.387.0" +"@aws-sdk/middleware-logger@npm:3.391.0": + version: 3.391.0 + resolution: "@aws-sdk/middleware-logger@npm:3.391.0" dependencies: - "@aws-sdk/types": 3.387.0 - "@smithy/types": ^2.1.0 + "@aws-sdk/types": 3.391.0 + "@smithy/types": ^2.2.0 tslib: ^2.5.0 - checksum: 75812390856559eaf9e8259f3d335c97268783d2e175dbd4568271e8f321a7a34754fcfcff0f70726a751c0418f6787ddbd7f1ebb3b644530e743edb5da63c2b + checksum: 81955beeadfef9e72df6852b9b5b50b79e9358ed4df672f6763ec29a706128cd176a8a02727e225828c6170b325255b14047db421560889e9d5c9e2860f74b02 languageName: node linkType: hard -"@aws-sdk/middleware-recursion-detection@npm:3.387.0": - version: 3.387.0 - resolution: "@aws-sdk/middleware-recursion-detection@npm:3.387.0" +"@aws-sdk/middleware-recursion-detection@npm:3.391.0": + version: 3.391.0 + resolution: "@aws-sdk/middleware-recursion-detection@npm:3.391.0" dependencies: - "@aws-sdk/types": 3.387.0 - "@smithy/protocol-http": ^2.0.2 - "@smithy/types": ^2.1.0 + "@aws-sdk/types": 3.391.0 + "@smithy/protocol-http": ^2.0.3 + "@smithy/types": ^2.2.0 tslib: ^2.5.0 - checksum: dd6ed9eb8969181f3adf5820f66db38ab544fda03f44bec87e6efdb194f01184094dc2d3ce150e9f045a75decb99e37a9a1dc8b37a78f8722caae8367c9db8d9 + checksum: 3eab16f976594dd25260a6852f207ab83fff27866acef67019dae017d1326af5cf948bd5d8eb5f681add1c9e663adfef1235483dae7208cfa38872b92aef2f57 languageName: node linkType: hard -"@aws-sdk/middleware-sdk-s3@npm:3.387.0": - version: 3.387.0 - resolution: "@aws-sdk/middleware-sdk-s3@npm:3.387.0" +"@aws-sdk/middleware-sdk-s3@npm:3.391.0": + version: 3.391.0 + resolution: "@aws-sdk/middleware-sdk-s3@npm:3.391.0" dependencies: - "@aws-sdk/types": 3.387.0 + "@aws-sdk/types": 3.391.0 "@aws-sdk/util-arn-parser": 3.310.0 - "@smithy/protocol-http": ^2.0.2 - "@smithy/types": ^2.1.0 + "@smithy/protocol-http": ^2.0.3 + "@smithy/types": ^2.2.0 tslib: ^2.5.0 - checksum: 674ebd73ed89f8375b5a7f15135a65e61736b8bc58f076504a050e9cb679da867ba256e6dc8c46b2a403c3a2fbed0667e40bb3b40bf79bc54a669650f09d97ac + checksum: da2879718b8fa0c96518f2f9745dd7182e27a56905bd9ac74b62197884d9fc1dce7242d7d709637fb1e9d13cfd70a3904127530217f020d5a44e2be0b65d316d languageName: node linkType: hard -"@aws-sdk/middleware-sdk-sqs@npm:3.387.0": - version: 3.387.0 - resolution: "@aws-sdk/middleware-sdk-sqs@npm:3.387.0" +"@aws-sdk/middleware-sdk-sqs@npm:3.391.0": + version: 3.391.0 + resolution: "@aws-sdk/middleware-sdk-sqs@npm:3.391.0" dependencies: - "@aws-sdk/types": 3.387.0 - "@smithy/types": ^2.1.0 + "@aws-sdk/types": 3.391.0 + "@smithy/types": ^2.2.0 "@smithy/util-hex-encoding": ^2.0.0 "@smithy/util-utf8": ^2.0.0 tslib: ^2.5.0 - checksum: fa734414df1c597c8fbcdff5131cfb240682a99d6d2302096040a05ff64742383f6812e8e41a7b1d32421b5556a138fd9241bced7eb35a29bcbca5376bb793b1 + checksum: 6b9fd7572e90d80eacb99246d6d84240def247505ac381720266fed278a25c28addc67c5a2660114b763457cc48caa72ccd5137d5c9b504fce331e00da6e2a8c languageName: node linkType: hard -"@aws-sdk/middleware-sdk-sts@npm:3.387.0": - version: 3.387.0 - resolution: "@aws-sdk/middleware-sdk-sts@npm:3.387.0" +"@aws-sdk/middleware-sdk-sts@npm:3.391.0": + version: 3.391.0 + resolution: "@aws-sdk/middleware-sdk-sts@npm:3.391.0" dependencies: - "@aws-sdk/middleware-signing": 3.387.0 - "@aws-sdk/types": 3.387.0 - "@smithy/types": ^2.1.0 + "@aws-sdk/middleware-signing": 3.391.0 + "@aws-sdk/types": 3.391.0 + "@smithy/types": ^2.2.0 tslib: ^2.5.0 - checksum: b9d5e4af2e10f980ef19add7eccd7f04eb5e42987c238acb17093b1d4239ae3430fb25e1c34ef915cd3420a2e93d59cf6570c1f9275bf5345733b1b030876cb5 + checksum: dd6f1572ea4306f6add42902743eaa4325ad47e7d497961578d104ae9c96c0bca10521ab2c7e723896ccb85f14ec38d866218c7582a6acd394df75ff5fc8ee24 languageName: node linkType: hard @@ -1210,42 +1210,42 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-signing@npm:3.387.0": - version: 3.387.0 - resolution: "@aws-sdk/middleware-signing@npm:3.387.0" +"@aws-sdk/middleware-signing@npm:3.391.0": + version: 3.391.0 + resolution: "@aws-sdk/middleware-signing@npm:3.391.0" dependencies: - "@aws-sdk/types": 3.387.0 + "@aws-sdk/types": 3.391.0 "@smithy/property-provider": ^2.0.0 - "@smithy/protocol-http": ^2.0.2 + "@smithy/protocol-http": ^2.0.3 "@smithy/signature-v4": ^2.0.0 - "@smithy/types": ^2.1.0 + "@smithy/types": ^2.2.0 "@smithy/util-middleware": ^2.0.0 tslib: ^2.5.0 - checksum: 3553748d92a64232df572f2b56d122943db9520d31b224f263ecce5711368de9d8bddc51facde9bf8a7d1075c3c381a96e65d4ad8d7f14f097d8f7e484c712e4 + checksum: aa76b0aeac670cffc472f7d7197edef2656d155bab38ebcfdb17f7573bdd23ecbf2cb29cbcf97cd15643bdf5cf7ed4cf5fb020db598e42e81e6502140669057e languageName: node linkType: hard -"@aws-sdk/middleware-ssec@npm:3.387.0": - version: 3.387.0 - resolution: "@aws-sdk/middleware-ssec@npm:3.387.0" +"@aws-sdk/middleware-ssec@npm:3.391.0": + version: 3.391.0 + resolution: "@aws-sdk/middleware-ssec@npm:3.391.0" dependencies: - "@aws-sdk/types": 3.387.0 - "@smithy/types": ^2.1.0 + "@aws-sdk/types": 3.391.0 + "@smithy/types": ^2.2.0 tslib: ^2.5.0 - checksum: 362b2c5faf5a606734d72104071a6a5aaaab7ecb8eb36507f1db32e22f842898fa589916b59e239f8cbbccdbf4743c978ad2fab2e434d14f3397f71086df31f4 + checksum: c6c0c7bc2210d22ef76d4c9725c99fb4b2debe750463077be077709adfaace851aadafb307b5d24ae0641bb67068f5fe24f1c15a72ed686b561f00281263b8b7 languageName: node linkType: hard -"@aws-sdk/middleware-user-agent@npm:3.387.0": - version: 3.387.0 - resolution: "@aws-sdk/middleware-user-agent@npm:3.387.0" +"@aws-sdk/middleware-user-agent@npm:3.391.0": + version: 3.391.0 + resolution: "@aws-sdk/middleware-user-agent@npm:3.391.0" dependencies: - "@aws-sdk/types": 3.387.0 - "@aws-sdk/util-endpoints": 3.387.0 - "@smithy/protocol-http": ^2.0.2 - "@smithy/types": ^2.1.0 + "@aws-sdk/types": 3.391.0 + "@aws-sdk/util-endpoints": 3.391.0 + "@smithy/protocol-http": ^2.0.3 + "@smithy/types": ^2.2.0 tslib: ^2.5.0 - checksum: 54cb1ddbd743bf70a28c1eebd6d1bc0adfad79b2bff0553737d238de01a83e11c9130c38526d4236457fa124d6024fd0c09607d796808dfe43821c75387d8fba + checksum: 33cda72f937173c6770976c233d627d587d2c943a70126b6eebd6225fb7ee982ad96e0c3125bb231b4b6f5bbd0da392ebded1149194aa952fe325d2cd993386e languageName: node linkType: hard @@ -1293,21 +1293,21 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/signature-v4-multi-region@npm:3.387.0": - version: 3.387.0 - resolution: "@aws-sdk/signature-v4-multi-region@npm:3.387.0" +"@aws-sdk/signature-v4-multi-region@npm:3.391.0": + version: 3.391.0 + resolution: "@aws-sdk/signature-v4-multi-region@npm:3.391.0" dependencies: - "@aws-sdk/types": 3.387.0 - "@smithy/protocol-http": ^2.0.2 + "@aws-sdk/types": 3.391.0 + "@smithy/protocol-http": ^2.0.3 "@smithy/signature-v4": ^2.0.0 - "@smithy/types": ^2.1.0 + "@smithy/types": ^2.2.0 tslib: ^2.5.0 peerDependencies: "@aws-sdk/signature-v4-crt": ^3.118.0 peerDependenciesMeta: "@aws-sdk/signature-v4-crt": optional: true - checksum: a520eb8a564edd12169addef6c449c236e6c86a657f7e1cda0331eff8adfa925e1ff4a201f4adbedd6f078fe5ceb89f933a268e5c4b61c92ff60ae47132ff5ae + checksum: 3c3533b317603e267d19a0b1a90ed6da464cf6b6d7459be8b5e1f01b0fe38fcd3cd5d8c62d0e4b5a279786aca981a5fe1dc609fc55b9892485ee0c1e335d3d46 languageName: node linkType: hard @@ -1327,16 +1327,46 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/token-providers@npm:3.387.0": - version: 3.387.0 - resolution: "@aws-sdk/token-providers@npm:3.387.0" +"@aws-sdk/token-providers@npm:3.391.0": + version: 3.391.0 + resolution: "@aws-sdk/token-providers@npm:3.391.0" dependencies: - "@aws-sdk/types": 3.387.0 + "@aws-crypto/sha256-browser": 3.0.0 + "@aws-crypto/sha256-js": 3.0.0 + "@aws-sdk/middleware-host-header": 3.391.0 + "@aws-sdk/middleware-logger": 3.391.0 + "@aws-sdk/middleware-recursion-detection": 3.391.0 + "@aws-sdk/middleware-user-agent": 3.391.0 + "@aws-sdk/types": 3.391.0 + "@aws-sdk/util-endpoints": 3.391.0 + "@aws-sdk/util-user-agent-browser": 3.391.0 + "@aws-sdk/util-user-agent-node": 3.391.0 + "@smithy/config-resolver": ^2.0.3 + "@smithy/fetch-http-handler": ^2.0.3 + "@smithy/hash-node": ^2.0.3 + "@smithy/invalid-dependency": ^2.0.3 + "@smithy/middleware-content-length": ^2.0.3 + "@smithy/middleware-endpoint": ^2.0.3 + "@smithy/middleware-retry": ^2.0.3 + "@smithy/middleware-serde": ^2.0.3 + "@smithy/middleware-stack": ^2.0.0 + "@smithy/node-config-provider": ^2.0.3 + "@smithy/node-http-handler": ^2.0.3 "@smithy/property-provider": ^2.0.0 + "@smithy/protocol-http": ^2.0.3 "@smithy/shared-ini-file-loader": ^2.0.0 - "@smithy/types": ^2.1.0 + "@smithy/smithy-client": ^2.0.3 + "@smithy/types": ^2.2.0 + "@smithy/url-parser": ^2.0.3 + "@smithy/util-base64": ^2.0.0 + "@smithy/util-body-length-browser": ^2.0.0 + "@smithy/util-body-length-node": ^2.0.0 + "@smithy/util-defaults-mode-browser": ^2.0.3 + "@smithy/util-defaults-mode-node": ^2.0.3 + "@smithy/util-retry": ^2.0.0 + "@smithy/util-utf8": ^2.0.0 tslib: ^2.5.0 - checksum: dffbaa98da3bd30fdedab88093d3ae94b4fdad1dd12b30fd5dbf7cfb01d1e219e3f5abe403ca71514bfa1f92818dde97a6d9c9d2cda35f2cbd43882750017bc2 + checksum: 4d929e006519fb25ee337a459f6e0dca6aa0a1e1a839605d8a3857b37b7aa77a032a6810a65023b2802827bf3190940dbee1e585bf86edfb2541be753bea1989 languageName: node linkType: hard @@ -1350,13 +1380,13 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/types@npm:3.387.0, @aws-sdk/types@npm:^3.222.0, @aws-sdk/types@npm:^3.347.0": - version: 3.387.0 - resolution: "@aws-sdk/types@npm:3.387.0" +"@aws-sdk/types@npm:3.391.0, @aws-sdk/types@npm:^3.222.0, @aws-sdk/types@npm:^3.347.0": + version: 3.391.0 + resolution: "@aws-sdk/types@npm:3.391.0" dependencies: - "@smithy/types": ^2.1.0 + "@smithy/types": ^2.2.0 tslib: ^2.5.0 - checksum: 39c5c3eea4cd8705c0c9dafa187ac6e14585a1bb6d162bbda8dc3ea5522020302ccd3ff7c8b425225c625d2b83ae6e6f6b71f621da790830a8a55ed5643197ec + checksum: 3539807ba0d515e0788da7e234c83578b761cf02b4bc2ede04755a39e44cc22dfc2edd0a48d333a090dc87c0f540cef957cd3c8009a12f38017438b50563fcbb languageName: node linkType: hard @@ -1390,13 +1420,13 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-endpoints@npm:3.387.0": - version: 3.387.0 - resolution: "@aws-sdk/util-endpoints@npm:3.387.0" +"@aws-sdk/util-endpoints@npm:3.391.0": + version: 3.391.0 + resolution: "@aws-sdk/util-endpoints@npm:3.391.0" dependencies: - "@aws-sdk/types": 3.387.0 + "@aws-sdk/types": 3.391.0 tslib: ^2.5.0 - checksum: 15c3250f096ca4ed7a832294cc3b609e62004f8888781cbd5ee907bd325bb5b999867aa7c8fdd5b806e92424f2561f5dd8ae3ebbb876044289d36163180fa2a5 + checksum: fa2a096d21ea2944e5c0a87e22c78f84c3383941a8b85b7e48ccc9c2a623a458f0e5de8150eede33bbe37b3a7e93d2089824bd1dc4c3d3d49c77b45ffcb412d9 languageName: node linkType: hard @@ -1448,32 +1478,32 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-user-agent-browser@npm:3.387.0": - version: 3.387.0 - resolution: "@aws-sdk/util-user-agent-browser@npm:3.387.0" +"@aws-sdk/util-user-agent-browser@npm:3.391.0": + version: 3.391.0 + resolution: "@aws-sdk/util-user-agent-browser@npm:3.391.0" dependencies: - "@aws-sdk/types": 3.387.0 - "@smithy/types": ^2.1.0 + "@aws-sdk/types": 3.391.0 + "@smithy/types": ^2.2.0 bowser: ^2.11.0 tslib: ^2.5.0 - checksum: a7ab9c2d98c4e00f7ac8aab8f08e8f0472d026573c0790aa6036557de0dae5c6e89a3989e00937725badbefcfdfd4fa5e5a996e5e11a043a3d594b5956cfae2c + checksum: 2cc35bebec3efce878e2ea30571e72d670ed815cf3655928063943f73b1302ad485fd40dd068dfb93e49e9f7283eca2bdc4a13a22ee77fa7fd1c1fd95298abb1 languageName: node linkType: hard -"@aws-sdk/util-user-agent-node@npm:3.387.0": - version: 3.387.0 - resolution: "@aws-sdk/util-user-agent-node@npm:3.387.0" +"@aws-sdk/util-user-agent-node@npm:3.391.0": + version: 3.391.0 + resolution: "@aws-sdk/util-user-agent-node@npm:3.391.0" dependencies: - "@aws-sdk/types": 3.387.0 - "@smithy/node-config-provider": ^2.0.2 - "@smithy/types": ^2.1.0 + "@aws-sdk/types": 3.391.0 + "@smithy/node-config-provider": ^2.0.3 + "@smithy/types": ^2.2.0 tslib: ^2.5.0 peerDependencies: aws-crt: ">=1.0.0" peerDependenciesMeta: aws-crt: optional: true - checksum: abe3cf2d058ff0a907780ee2100b0d5805d7878c434115cda645d2fe0a57226dd7cf86c2d795ef75d8062914d89c8d71752789b355317586417b92482e05c98f + checksum: 2e59bea8dee6e2a4aaaeec61fbe5bfacb6c3dcebfc2d9e624dc7039855c5793f5d7b064eb08c3a066a954c948ba1f6b6c93c7cf14ceb6713d45fdce110f6a928 languageName: node linkType: hard @@ -14594,13 +14624,13 @@ __metadata: languageName: node linkType: hard -"@smithy/abort-controller@npm:^2.0.1, @smithy/abort-controller@npm:^2.0.2": - version: 2.0.2 - resolution: "@smithy/abort-controller@npm:2.0.2" +"@smithy/abort-controller@npm:^2.0.1, @smithy/abort-controller@npm:^2.0.4": + version: 2.0.4 + resolution: "@smithy/abort-controller@npm:2.0.4" dependencies: - "@smithy/types": ^2.1.0 + "@smithy/types": ^2.2.1 tslib: ^2.5.0 - checksum: 68a331dc59decd842b2eecae3ff8705340d9504048a0e5af31286e9505e2473f81d96bfb2dd395161529adee5413bf6aaed7e264debd0862113325c85e0771da + checksum: b1121708af27d151535bdd997d99a7c71ceadc057f77352cfd09cccfb5a92bc05612370c78a8642bfcbb22dff5e6b9a5c38e5856b9f48bd0fb5cebdb9a4bb75e languageName: node linkType: hard @@ -14623,141 +14653,141 @@ __metadata: languageName: node linkType: hard -"@smithy/config-resolver@npm:^2.0.2": - version: 2.0.2 - resolution: "@smithy/config-resolver@npm:2.0.2" +"@smithy/config-resolver@npm:^2.0.3, @smithy/config-resolver@npm:^2.0.4": + version: 2.0.4 + resolution: "@smithy/config-resolver@npm:2.0.4" dependencies: - "@smithy/types": ^2.1.0 + "@smithy/types": ^2.2.1 "@smithy/util-config-provider": ^2.0.0 "@smithy/util-middleware": ^2.0.0 tslib: ^2.5.0 - checksum: deb7ecab3d3f2ce57304d99605e55739c94356105c8106c8ca9bb5c0fc329e2b4153788a12bb8600187c51645b9a5be799571c8e380cc4458d110c37f127c75b + checksum: a153a6baf80f7f17439312fea5f379abbcb0778313897e3ab8d5c4eb24496c2ce1d6c1005764eb802221fdb57814fb6a558f26e6cb02b80cdd1af9a83bda7480 languageName: node linkType: hard -"@smithy/credential-provider-imds@npm:^2.0.0, @smithy/credential-provider-imds@npm:^2.0.2": - version: 2.0.2 - resolution: "@smithy/credential-provider-imds@npm:2.0.2" +"@smithy/credential-provider-imds@npm:^2.0.0, @smithy/credential-provider-imds@npm:^2.0.4": + version: 2.0.4 + resolution: "@smithy/credential-provider-imds@npm:2.0.4" dependencies: - "@smithy/node-config-provider": ^2.0.2 - "@smithy/property-provider": ^2.0.2 - "@smithy/types": ^2.1.0 - "@smithy/url-parser": ^2.0.2 + "@smithy/node-config-provider": ^2.0.4 + "@smithy/property-provider": ^2.0.4 + "@smithy/types": ^2.2.1 + "@smithy/url-parser": ^2.0.4 tslib: ^2.5.0 - checksum: 519fd53a74e7fdb4a5e39bf4d0554983231919d80e2b9e324976a14ec41d4e0e4de6c9272af10820c220810ba30a9803a901c677b9994b8893aded10e1b36505 + checksum: 72c208836e1b7ee3a1466be1f41691c97a7ede67a16d902475cd46f7b732334703a96dc74e246ba350ea88811bc96f34e3a9f3290f3510d2004b9b004dba7ac7 languageName: node linkType: hard -"@smithy/eventstream-codec@npm:^2.0.1, @smithy/eventstream-codec@npm:^2.0.2": - version: 2.0.2 - resolution: "@smithy/eventstream-codec@npm:2.0.2" +"@smithy/eventstream-codec@npm:^2.0.1, @smithy/eventstream-codec@npm:^2.0.4": + version: 2.0.4 + resolution: "@smithy/eventstream-codec@npm:2.0.4" dependencies: "@aws-crypto/crc32": 3.0.0 - "@smithy/types": ^2.1.0 + "@smithy/types": ^2.2.1 "@smithy/util-hex-encoding": ^2.0.0 tslib: ^2.5.0 - checksum: aa9136264c1f9a3bc8b9bc175d28b10d0ce72377593b4ed32d11b1753723a88e6305991ab0c6822d986f31edb914355df6bec8fb65ffe1f66c2ce6dab0768668 + checksum: 7bd5ac65de1ef611939a413c6cf6c3bb583c89cae521f0b202cd167a95d748446d5a829dc31285e9b5c9bd0d1cce58c288e5c1a7957cb26a433e34a64b8c4676 languageName: node linkType: hard -"@smithy/eventstream-serde-browser@npm:^2.0.2": - version: 2.0.2 - resolution: "@smithy/eventstream-serde-browser@npm:2.0.2" +"@smithy/eventstream-serde-browser@npm:^2.0.3": + version: 2.0.4 + resolution: "@smithy/eventstream-serde-browser@npm:2.0.4" dependencies: - "@smithy/eventstream-serde-universal": ^2.0.2 - "@smithy/types": ^2.1.0 + "@smithy/eventstream-serde-universal": ^2.0.4 + "@smithy/types": ^2.2.1 tslib: ^2.5.0 - checksum: b21c97d9e02fe3ba9110cbea35f674b3746c36eafde2874e878fcea03f7c1d1f34f38797df38b8b04dcc19576aa9f568e3e241f79aac696169941c4f44132d08 + checksum: 7795f1de75d6173198fb6698d24962a2cd5f6c7f796ff24be048b42821457287923e6542cd4d77179b437089408e5924a0ffb7e2b5473f781b5f7c8c7829e0b6 languageName: node linkType: hard -"@smithy/eventstream-serde-config-resolver@npm:^2.0.2": - version: 2.0.2 - resolution: "@smithy/eventstream-serde-config-resolver@npm:2.0.2" +"@smithy/eventstream-serde-config-resolver@npm:^2.0.3": + version: 2.0.4 + resolution: "@smithy/eventstream-serde-config-resolver@npm:2.0.4" dependencies: - "@smithy/types": ^2.1.0 + "@smithy/types": ^2.2.1 tslib: ^2.5.0 - checksum: 707e6e39e2ccb832db06f82bbf96c655548052458bf3f8b8b00e32461747b1fab1be9ec60a5ddbff8770e48b2cd153277bc81b203765d66b78fc2f76252ce8b9 + checksum: d52392e42285aefa3874385111d30e99cdde0c35dfbc857439ccb7c03badcc47fe0b75124f369c6f4f4a0071ec88b3fa9266c0167238c0093bbd938461006782 languageName: node linkType: hard -"@smithy/eventstream-serde-node@npm:^2.0.2": - version: 2.0.2 - resolution: "@smithy/eventstream-serde-node@npm:2.0.2" +"@smithy/eventstream-serde-node@npm:^2.0.3": + version: 2.0.4 + resolution: "@smithy/eventstream-serde-node@npm:2.0.4" dependencies: - "@smithy/eventstream-serde-universal": ^2.0.2 - "@smithy/types": ^2.1.0 + "@smithy/eventstream-serde-universal": ^2.0.4 + "@smithy/types": ^2.2.1 tslib: ^2.5.0 - checksum: dfda607f0d76098616341c1e6f3012242c58f1d3211a464631f4d337f7113bce7f0380fe5cdf5b6e4e391beb54562d1a96494ca8d2af847f1f13264f362365aa + checksum: 932dfa9b2e57e29f139479a5d177794d19a2fa807aa2f1b52fd5d50eb1d6abe53b289940384299f825c8f6e3be7d1b252b20f7ad711d9230d0f0606b13d9e1ee languageName: node linkType: hard -"@smithy/eventstream-serde-universal@npm:^2.0.2": - version: 2.0.2 - resolution: "@smithy/eventstream-serde-universal@npm:2.0.2" +"@smithy/eventstream-serde-universal@npm:^2.0.4": + version: 2.0.4 + resolution: "@smithy/eventstream-serde-universal@npm:2.0.4" dependencies: - "@smithy/eventstream-codec": ^2.0.2 - "@smithy/types": ^2.1.0 + "@smithy/eventstream-codec": ^2.0.4 + "@smithy/types": ^2.2.1 tslib: ^2.5.0 - checksum: 887d03832126054fdfd6426ee3153eec54ecfcddeb04c63c69f6f1fcc23e0b8af737dce7c8ae07ca456f1e0be63614498280b77ff5c919793a0633b1d7d11a2c + checksum: 015a781c745aa371e4c7ad92da66939d46ac1a5864d14317e4c47c9f9ec3fac032defce3545fdfd144422cacfa0e4272c68f45b90a8da50769a25041a2482b9d languageName: node linkType: hard -"@smithy/fetch-http-handler@npm:^2.0.2": - version: 2.0.2 - resolution: "@smithy/fetch-http-handler@npm:2.0.2" +"@smithy/fetch-http-handler@npm:^2.0.3, @smithy/fetch-http-handler@npm:^2.0.4": + version: 2.0.4 + resolution: "@smithy/fetch-http-handler@npm:2.0.4" dependencies: - "@smithy/protocol-http": ^2.0.2 - "@smithy/querystring-builder": ^2.0.2 - "@smithy/types": ^2.1.0 + "@smithy/protocol-http": ^2.0.4 + "@smithy/querystring-builder": ^2.0.4 + "@smithy/types": ^2.2.1 "@smithy/util-base64": ^2.0.0 tslib: ^2.5.0 - checksum: 2c7c97c02bc347b420c51a052b97884e70cfbed25475e68d5a1e8f46b1b0873d727c4989b4a71aaa5e5e1ba055c423f989f5b01bf105176580acc9d5cc80eb72 + checksum: e1f68057af85dc03762a1b6afc661224c97ccf84efae51bb3bd7dae97624e0c85added8d4595bf970d8f6262ae5ee034f461487c2a8207678e03b7d0c1b9a11d languageName: node linkType: hard -"@smithy/hash-blob-browser@npm:^2.0.2": - version: 2.0.2 - resolution: "@smithy/hash-blob-browser@npm:2.0.2" +"@smithy/hash-blob-browser@npm:^2.0.3": + version: 2.0.4 + resolution: "@smithy/hash-blob-browser@npm:2.0.4" dependencies: "@smithy/chunked-blob-reader": ^2.0.0 "@smithy/chunked-blob-reader-native": ^2.0.0 - "@smithy/types": ^2.1.0 + "@smithy/types": ^2.2.1 tslib: ^2.5.0 - checksum: add61e1fbdcaf5b019bb8ad4d1dbb70cbc59c65f039cab2ac9fc4617333ce7a3aa356d51b737732560d23db29f7afbd5c1addb4db738ec21dfa2cad5dd82ca05 + checksum: d7ce36a111ba7cb0133f2447c3bfb85e7543d0778547cf1de118bb02bc8b3808d96fa117a82fa41caca224782dfd4473594cc0eaf49b9cea1bb9f6cde9e50917 languageName: node linkType: hard -"@smithy/hash-node@npm:^2.0.2": - version: 2.0.2 - resolution: "@smithy/hash-node@npm:2.0.2" +"@smithy/hash-node@npm:^2.0.3": + version: 2.0.4 + resolution: "@smithy/hash-node@npm:2.0.4" dependencies: - "@smithy/types": ^2.1.0 + "@smithy/types": ^2.2.1 "@smithy/util-buffer-from": ^2.0.0 "@smithy/util-utf8": ^2.0.0 tslib: ^2.5.0 - checksum: 2917822fcc965596755a284cbae8376adb0d1ebc5998ae8a5682e4385f29eaac4408b24e560eced4b7fb8a279fa4453277dc3853114724d4e4c62ce935863fa9 + checksum: f8dceea46c32391861ecb23a4dbb0878048ca8aca2a8e617eb2a15266e77be4aaec795da223b6003b6bb61451fe66edbd5bb7665f9ada76e59e4e405331c5d1a languageName: node linkType: hard -"@smithy/hash-stream-node@npm:^2.0.2": - version: 2.0.2 - resolution: "@smithy/hash-stream-node@npm:2.0.2" +"@smithy/hash-stream-node@npm:^2.0.3": + version: 2.0.4 + resolution: "@smithy/hash-stream-node@npm:2.0.4" dependencies: - "@smithy/types": ^2.1.0 + "@smithy/types": ^2.2.1 "@smithy/util-utf8": ^2.0.0 tslib: ^2.5.0 - checksum: b588608e200978a09633591e5f155bb63890d0f96776eaf94bfbf8df7223bf6a83e8f1a0b256fd7ee286b7b2ca53f1f7124e2d436d5e21ddf10aeb52e7ab528d + checksum: c674e2ba399dd30757e0c0a8e432d2ce024e9f4335a41f20f86dec7f1f1acc7a6389ce8f1aae094b8549b385a2210346e340124a23af8572adb9271b8f580a28 languageName: node linkType: hard -"@smithy/invalid-dependency@npm:^2.0.2": - version: 2.0.2 - resolution: "@smithy/invalid-dependency@npm:2.0.2" +"@smithy/invalid-dependency@npm:^2.0.3": + version: 2.0.4 + resolution: "@smithy/invalid-dependency@npm:2.0.4" dependencies: - "@smithy/types": ^2.1.0 + "@smithy/types": ^2.2.1 tslib: ^2.5.0 - checksum: c31f5d8555729ac34a0e56f350061ee127a6869c6fbe5e30c303e8b273aa52370d7e3a9ec603448cf2e986740a4c67e5285a350d738896e2ad4f7312cb3ed943 + checksum: 947cc13ec2d949f42449492b8b10942676c99d82cec5a62b99e66098c71fed79528e0f2c058ca6e855192ecdb07e7be1e6a38f6fa98305b673fcea3e57152304 languageName: node linkType: hard @@ -14770,63 +14800,63 @@ __metadata: languageName: node linkType: hard -"@smithy/md5-js@npm:^2.0.2": - version: 2.0.2 - resolution: "@smithy/md5-js@npm:2.0.2" +"@smithy/md5-js@npm:^2.0.3": + version: 2.0.4 + resolution: "@smithy/md5-js@npm:2.0.4" dependencies: - "@smithy/types": ^2.1.0 + "@smithy/types": ^2.2.1 "@smithy/util-utf8": ^2.0.0 tslib: ^2.5.0 - checksum: 889056925d17f424f23540b25c237c7ad4e9b7b8a7817a0172cf0a648da5ab9c709593790629955365c93504787c534b2156aa8d056ea27fe81a88106126268b + checksum: f57f61bfb8cb353b86eabd3e0761744c6f3ee5597a6c54587cbffb59092ab1540a415cdbc6558d86d151c84432794303efce5c4fc5424a59ab8d4a5904e21597 languageName: node linkType: hard -"@smithy/middleware-content-length@npm:^2.0.2": - version: 2.0.2 - resolution: "@smithy/middleware-content-length@npm:2.0.2" +"@smithy/middleware-content-length@npm:^2.0.3": + version: 2.0.4 + resolution: "@smithy/middleware-content-length@npm:2.0.4" dependencies: - "@smithy/protocol-http": ^2.0.2 - "@smithy/types": ^2.1.0 + "@smithy/protocol-http": ^2.0.4 + "@smithy/types": ^2.2.1 tslib: ^2.5.0 - checksum: d4a28b967629eab3ee2265ad34e6f45b8006e247e51fdce53604431de58a7840a304ff530475b160d50dc9fb47b1c4c91e51e340003c57b9aaa8483686540336 + checksum: ef7fa3ff95a388e72f3847836bf663397c1ce436f0c27285d8db5c14f8c12c57b59a8928752f445b192658bd86977e6aa16faf1c2e5ea5ff51fabefc0667a5cc languageName: node linkType: hard -"@smithy/middleware-endpoint@npm:^2.0.2": - version: 2.0.2 - resolution: "@smithy/middleware-endpoint@npm:2.0.2" +"@smithy/middleware-endpoint@npm:^2.0.3": + version: 2.0.4 + resolution: "@smithy/middleware-endpoint@npm:2.0.4" dependencies: - "@smithy/middleware-serde": ^2.0.2 - "@smithy/types": ^2.1.0 - "@smithy/url-parser": ^2.0.2 + "@smithy/middleware-serde": ^2.0.4 + "@smithy/types": ^2.2.1 + "@smithy/url-parser": ^2.0.4 "@smithy/util-middleware": ^2.0.0 tslib: ^2.5.0 - checksum: 2a1ba8fa8fe0aef2bdd87c6fc7d3567b4b03e63ad8b46531130042c226b627d438f163caad81295b7dcb506536fd0700fb0ddc20bfc894c7be589b8c891fa799 + checksum: 0868e8a0c123c50f2fb93a9d58639306146a44c58ee48f7d208d21039e3c5b7c01c4697b9254d549e31494696abac95270c893564598abdac95f4bf5d47764d3 languageName: node linkType: hard -"@smithy/middleware-retry@npm:^2.0.2": - version: 2.0.2 - resolution: "@smithy/middleware-retry@npm:2.0.2" +"@smithy/middleware-retry@npm:^2.0.3": + version: 2.0.4 + resolution: "@smithy/middleware-retry@npm:2.0.4" dependencies: - "@smithy/protocol-http": ^2.0.2 + "@smithy/protocol-http": ^2.0.4 "@smithy/service-error-classification": ^2.0.0 - "@smithy/types": ^2.1.0 + "@smithy/types": ^2.2.1 "@smithy/util-middleware": ^2.0.0 "@smithy/util-retry": ^2.0.0 tslib: ^2.5.0 uuid: ^8.3.2 - checksum: c88134fe739b9b038117b388b10e29e53407af3bd6f61fbfdc2600b45b6415bb2e75ee4ce9b0423376d11472d0fb96ba6300c23a1c0ddf8a5d3806f8b7d3c088 + checksum: f5b637a3add7177b1109f7c2c28d35ef64112aed9191ea83bee666c6f0fd031afc37f23d8de1ad9449a6c610cdbc0174120871bbaeeb66b50e80f617b84bfcd0 languageName: node linkType: hard -"@smithy/middleware-serde@npm:^2.0.2": - version: 2.0.2 - resolution: "@smithy/middleware-serde@npm:2.0.2" +"@smithy/middleware-serde@npm:^2.0.3, @smithy/middleware-serde@npm:^2.0.4": + version: 2.0.4 + resolution: "@smithy/middleware-serde@npm:2.0.4" dependencies: - "@smithy/types": ^2.1.0 + "@smithy/types": ^2.2.1 tslib: ^2.5.0 - checksum: 6d343eceeff45c08142ff0567885b910f6d77e7ec95396f8fc4b0fc259284c8d430bd8412ef36c5c45905ee631c660524e38450bda86400b06f3272f4504b08f + checksum: 4b712a13f89a02ae4f912bac7a6c175474588b242cd834716ed7ec66e566fbea512b1b4af2c51841ea8cd980604c87e67497335bfc81e07f612386dff5d2f5e0 languageName: node linkType: hard @@ -14839,69 +14869,69 @@ __metadata: languageName: node linkType: hard -"@smithy/node-config-provider@npm:^2.0.2": - version: 2.0.2 - resolution: "@smithy/node-config-provider@npm:2.0.2" +"@smithy/node-config-provider@npm:^2.0.3, @smithy/node-config-provider@npm:^2.0.4": + version: 2.0.4 + resolution: "@smithy/node-config-provider@npm:2.0.4" dependencies: - "@smithy/property-provider": ^2.0.2 - "@smithy/shared-ini-file-loader": ^2.0.2 - "@smithy/types": ^2.1.0 + "@smithy/property-provider": ^2.0.4 + "@smithy/shared-ini-file-loader": ^2.0.4 + "@smithy/types": ^2.2.1 tslib: ^2.5.0 - checksum: 6cf3953dfd08f337b5ef41fa6808b083ceb06624e2de4996bfbb7d4326a8deefe73e47d6bb00ca81a2d2dc9b662d3eaaa3d1698262f2256d1a7c71290663ca12 + checksum: 0fdc571b996d472b5bb714fd79a4d253835ee711881bcb430194c1f62510db06d13f196bfd9b925cc3459a06d315e9096f6f91af2d92d4a0fafeebfa3a543516 languageName: node linkType: hard -"@smithy/node-http-handler@npm:^2.0.2": - version: 2.0.2 - resolution: "@smithy/node-http-handler@npm:2.0.2" +"@smithy/node-http-handler@npm:^2.0.3, @smithy/node-http-handler@npm:^2.0.4": + version: 2.0.4 + resolution: "@smithy/node-http-handler@npm:2.0.4" dependencies: - "@smithy/abort-controller": ^2.0.2 - "@smithy/protocol-http": ^2.0.2 - "@smithy/querystring-builder": ^2.0.2 - "@smithy/types": ^2.1.0 + "@smithy/abort-controller": ^2.0.4 + "@smithy/protocol-http": ^2.0.4 + "@smithy/querystring-builder": ^2.0.4 + "@smithy/types": ^2.2.1 tslib: ^2.5.0 - checksum: 1c5e0189d2f68bfc4c50c107182eb34b34024de3213a552cab2088c01bea8707c51c7cbbd7cf61290cf8b71e13ec2d715e51b7647edc9f5d27ab8779011e2a4d + checksum: 35622e82eec7ebc33a463c69da679127ccc76e84d628b752dcfde0a02a5e9a4c6a75076b01ca842e8bdf95e02f78fb45aaab77e0d7d474d9cc64c44a525b19ea languageName: node linkType: hard -"@smithy/property-provider@npm:^2.0.0, @smithy/property-provider@npm:^2.0.2": - version: 2.0.2 - resolution: "@smithy/property-provider@npm:2.0.2" +"@smithy/property-provider@npm:^2.0.0, @smithy/property-provider@npm:^2.0.4": + version: 2.0.4 + resolution: "@smithy/property-provider@npm:2.0.4" dependencies: - "@smithy/types": ^2.1.0 + "@smithy/types": ^2.2.1 tslib: ^2.5.0 - checksum: e18df64d5ec92b2c7876dc1e7a596dc80066e13d49fcad6d8caac50394e8b3f3b15aa1f517429a85cdfefc218ee3d72028613454c706638352732ab1ae0f7418 + checksum: 80d6eb6a87138c8752103ee5c541a1f8c867dc2baef5cf6eaa88e4cd920ea3d7d0b80aca7e8ff90b360ed976da688e26c3c20402cacbba32b807c7b612a2cc5a languageName: node linkType: hard -"@smithy/protocol-http@npm:^2.0.2": - version: 2.0.2 - resolution: "@smithy/protocol-http@npm:2.0.2" +"@smithy/protocol-http@npm:^2.0.3, @smithy/protocol-http@npm:^2.0.4": + version: 2.0.4 + resolution: "@smithy/protocol-http@npm:2.0.4" dependencies: - "@smithy/types": ^2.1.0 + "@smithy/types": ^2.2.1 tslib: ^2.5.0 - checksum: 61202d08d4433a4406a56e1e77863b89a60431a39984b38fec04a18276973857524b18d60c394236f3b664a08ec1996d837c295798e44f02ba93aca5336e9432 + checksum: 2e92a9a6ee52c5e94bfd21a510af3b5f2d4f56f849e5cb8a91eb0c28204051e51bf3801295acb5f4adb588c2bd0a3259c55019f9cca94d2056f838878cc0d9a3 languageName: node linkType: hard -"@smithy/querystring-builder@npm:^2.0.2": - version: 2.0.2 - resolution: "@smithy/querystring-builder@npm:2.0.2" +"@smithy/querystring-builder@npm:^2.0.4": + version: 2.0.4 + resolution: "@smithy/querystring-builder@npm:2.0.4" dependencies: - "@smithy/types": ^2.1.0 + "@smithy/types": ^2.2.1 "@smithy/util-uri-escape": ^2.0.0 tslib: ^2.5.0 - checksum: cdda228f0ac049aed302dcd19c47309a81eeb4d4c360189a399bc70bd6283ba218c87cfdee43e33c406cbe452d7979a389de9150b06de5221dfe4a6f69e53c1b + checksum: f26d8a9596f3f6c5ed8f42d4546c703c7dadc4e6156b2338b5383848a891aab684d84d80d8f775a0007a559e1f20f71707a999891423ac9f857acb06023e4216 languageName: node linkType: hard -"@smithy/querystring-parser@npm:^2.0.2": - version: 2.0.2 - resolution: "@smithy/querystring-parser@npm:2.0.2" +"@smithy/querystring-parser@npm:^2.0.4": + version: 2.0.4 + resolution: "@smithy/querystring-parser@npm:2.0.4" dependencies: - "@smithy/types": ^2.1.0 + "@smithy/types": ^2.2.1 tslib: ^2.5.0 - checksum: 0a571dbf7876096823071583e4b8506d9ce4fc1ff2af9fac07987bdf9a6e0dfee1598280cf411a6709cf535e2904eeab385bb2186bb6fe3aa987bae84620256c + checksum: cd7ba10925fe4e4cac9b90dd308270b32d9a12c89a75ede93fbb6b25e662135084d6c29034a27678df53d1386a16c6012f6a2f873c264b2d6c6ed70cc10676aa languageName: node linkType: hard @@ -14912,13 +14942,13 @@ __metadata: languageName: node linkType: hard -"@smithy/shared-ini-file-loader@npm:^2.0.0, @smithy/shared-ini-file-loader@npm:^2.0.2": - version: 2.0.2 - resolution: "@smithy/shared-ini-file-loader@npm:2.0.2" +"@smithy/shared-ini-file-loader@npm:^2.0.0, @smithy/shared-ini-file-loader@npm:^2.0.4": + version: 2.0.4 + resolution: "@smithy/shared-ini-file-loader@npm:2.0.4" dependencies: - "@smithy/types": ^2.1.0 + "@smithy/types": ^2.2.1 tslib: ^2.5.0 - checksum: 5a7100b1db34d0a479dcbc2d649840dcf37fb2be4d5798ba7bef58186b636d867c3c555796f1372bcfc5554705a3f267e13008705451f44cd03a2c5a87c5c89e + checksum: b0cb86f52d13a290705f2ef28ecdc6a8d6b817737a5dbb2ac8c3b8b45c77a0cc9d33b03a8e709bca963feb4415c50d37a5508fa0cd20e667a7ff7b8dafac5624 languageName: node linkType: hard @@ -14938,15 +14968,15 @@ __metadata: languageName: node linkType: hard -"@smithy/smithy-client@npm:^2.0.2": - version: 2.0.2 - resolution: "@smithy/smithy-client@npm:2.0.2" +"@smithy/smithy-client@npm:^2.0.3": + version: 2.0.4 + resolution: "@smithy/smithy-client@npm:2.0.4" dependencies: "@smithy/middleware-stack": ^2.0.0 - "@smithy/types": ^2.1.0 - "@smithy/util-stream": ^2.0.2 + "@smithy/types": ^2.2.1 + "@smithy/util-stream": ^2.0.4 tslib: ^2.5.0 - checksum: 999b814ece054dfcc4808e5e3bdf6d24f5bc1a16b375bccad95ba9f0ff709a68f4c6437d1378b8b1ef870ce75e4cd2e55df4143394890e9759cec69fd078062d + checksum: 11ba0e9c135ce4ca7a8a042679b9ae1a78405971699501b2ba065ab458a85113ddbadd55b793f15bdb448a2c80aee285028f5760ea9d9db0300c1231080f8826 languageName: node linkType: hard @@ -14959,23 +14989,23 @@ __metadata: languageName: node linkType: hard -"@smithy/types@npm:^2.0.2, @smithy/types@npm:^2.1.0": - version: 2.1.0 - resolution: "@smithy/types@npm:2.1.0" +"@smithy/types@npm:^2.0.2, @smithy/types@npm:^2.2.0, @smithy/types@npm:^2.2.1": + version: 2.2.1 + resolution: "@smithy/types@npm:2.2.1" dependencies: tslib: ^2.5.0 - checksum: 15c61c1b6520ef21257b64e4be7c8334c1206db8f21c9fb301838b5e09699996060c4361e51d2c63ee972f8678df68a8a60e2dd18216ae70751393d9d4188c5a + checksum: cd06347fce5ccf31464fef57a7943a3b5858aad6efc0169a9871c4e8dd11c542936f35ebac92c9d82e3cdd9668f23001400f5a1a015fff3f59e021a27fec32cb languageName: node linkType: hard -"@smithy/url-parser@npm:^2.0.2": - version: 2.0.2 - resolution: "@smithy/url-parser@npm:2.0.2" +"@smithy/url-parser@npm:^2.0.3, @smithy/url-parser@npm:^2.0.4": + version: 2.0.4 + resolution: "@smithy/url-parser@npm:2.0.4" dependencies: - "@smithy/querystring-parser": ^2.0.2 - "@smithy/types": ^2.1.0 + "@smithy/querystring-parser": ^2.0.4 + "@smithy/types": ^2.2.1 tslib: ^2.5.0 - checksum: 3a977e6a2c8d6d01e29d8925ef351d2cbc0951029d774490e3362d681fd18d97622afd2e99cea158f3e851cf423dc8dde5f6aee639cdf77f31e80150a732478b + checksum: 2fb1729ed6e822f65d9c22f9caa1dfd8008d9fd9c7bd3a4ea6c385741a65eec5d47a5f39ba50690f704923cbeb1edb6b6355bfecda41e15057167f5709aeee5b languageName: node linkType: hard @@ -15026,29 +15056,29 @@ __metadata: languageName: node linkType: hard -"@smithy/util-defaults-mode-browser@npm:^2.0.2": - version: 2.0.2 - resolution: "@smithy/util-defaults-mode-browser@npm:2.0.2" +"@smithy/util-defaults-mode-browser@npm:^2.0.3": + version: 2.0.4 + resolution: "@smithy/util-defaults-mode-browser@npm:2.0.4" dependencies: - "@smithy/property-provider": ^2.0.2 - "@smithy/types": ^2.1.0 + "@smithy/property-provider": ^2.0.4 + "@smithy/types": ^2.2.1 bowser: ^2.11.0 tslib: ^2.5.0 - checksum: 0e4d70040268757120aec9b6207256d091772075e21dc1778c29d33d002c12e4825a192a2424ca3099d79ceb9ce8e6e77a627b680e12a657a171ca9ed84818e7 + checksum: 3758310f855bb7127e732f778fda1c2ce1badc945fe79d9b56e1419ad8049043e645e07a572e667d804a61d29141ccfaded053b9e1854cc6c139c3dfbff06c04 languageName: node linkType: hard -"@smithy/util-defaults-mode-node@npm:^2.0.2": - version: 2.0.2 - resolution: "@smithy/util-defaults-mode-node@npm:2.0.2" +"@smithy/util-defaults-mode-node@npm:^2.0.3": + version: 2.0.4 + resolution: "@smithy/util-defaults-mode-node@npm:2.0.4" dependencies: - "@smithy/config-resolver": ^2.0.2 - "@smithy/credential-provider-imds": ^2.0.2 - "@smithy/node-config-provider": ^2.0.2 - "@smithy/property-provider": ^2.0.2 - "@smithy/types": ^2.1.0 + "@smithy/config-resolver": ^2.0.4 + "@smithy/credential-provider-imds": ^2.0.4 + "@smithy/node-config-provider": ^2.0.4 + "@smithy/property-provider": ^2.0.4 + "@smithy/types": ^2.2.1 tslib: ^2.5.0 - checksum: 25b8988bad21b7fb45c715e303b57bee4e865644f3c3282aa36f81ce71000e94289c84bccdd820556a8625d5d6bfa4ce70eb0f02bd74e9bb117ed713fabeba5d + checksum: b558c47ec61bafc8b69c84931e5c97aecc00d45b0dee1db56298d5fb205453a4be742899083a57cb282ae109b2bce9f70261d7a3ed0949dd5678daded4043567 languageName: node linkType: hard @@ -15080,19 +15110,19 @@ __metadata: languageName: node linkType: hard -"@smithy/util-stream@npm:^2.0.2": - version: 2.0.2 - resolution: "@smithy/util-stream@npm:2.0.2" +"@smithy/util-stream@npm:^2.0.3, @smithy/util-stream@npm:^2.0.4": + version: 2.0.4 + resolution: "@smithy/util-stream@npm:2.0.4" dependencies: - "@smithy/fetch-http-handler": ^2.0.2 - "@smithy/node-http-handler": ^2.0.2 - "@smithy/types": ^2.1.0 + "@smithy/fetch-http-handler": ^2.0.4 + "@smithy/node-http-handler": ^2.0.4 + "@smithy/types": ^2.2.1 "@smithy/util-base64": ^2.0.0 "@smithy/util-buffer-from": ^2.0.0 "@smithy/util-hex-encoding": ^2.0.0 "@smithy/util-utf8": ^2.0.0 tslib: ^2.5.0 - checksum: 32115fa35437370671dcedf14714ab32b94ceb598baffe1d8afa7c574084b4cf0826f15fd3a76bc1450010512d2d067cbe62fe8c6ce4ee640fb0270768a8d87c + checksum: 0d7b6b7b3ca01cdd24edccd9f411ae2fd6ef627c6b37b97b8be96d632cd43b49a0b4e20b180281ffcb5264237b0175594f3974c3278d859e9e988ab4eb109e1b languageName: node linkType: hard @@ -15115,14 +15145,14 @@ __metadata: languageName: node linkType: hard -"@smithy/util-waiter@npm:^2.0.2": - version: 2.0.2 - resolution: "@smithy/util-waiter@npm:2.0.2" +"@smithy/util-waiter@npm:^2.0.3": + version: 2.0.4 + resolution: "@smithy/util-waiter@npm:2.0.4" dependencies: - "@smithy/abort-controller": ^2.0.2 - "@smithy/types": ^2.1.0 + "@smithy/abort-controller": ^2.0.4 + "@smithy/types": ^2.2.1 tslib: ^2.5.0 - checksum: a0d23641fb724684b299d5131d82578f1c11cdcde9d55af309e00a0f75b19792016207eb1effb58da21eeafcac6cd5ed7ea4632c2c2e2e5eb423aa40f2e50fdf + checksum: d00ba1e2a066f069725d5e5394adea7b656f3be44565677bd59fda406272931b1414239f85c928e2edd9c9404e940a754e977cf86291d60c491632155dca9ce6 languageName: node linkType: hard From 42bde12f046202a1cb3f1a1af23c2b8b8d727d45 Mon Sep 17 00:00:00 2001 From: Adam Harvey Date: Wed, 16 Aug 2023 12:21:24 -0400 Subject: [PATCH 13/73] chore: Add backend logging if posts fail Signed-off-by: Adam Harvey --- plugins/entity-feedback-backend/src/service/router.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plugins/entity-feedback-backend/src/service/router.ts b/plugins/entity-feedback-backend/src/service/router.ts index ea759c1639..4953c531b8 100644 --- a/plugins/entity-feedback-backend/src/service/router.ts +++ b/plugins/entity-feedback-backend/src/service/router.ts @@ -134,6 +134,9 @@ export async function createRouter( const user = await identity.getIdentity({ request: req }); const rating = req.body.rating; if (!user || !rating) { + logger.warn( + `Can't save rating because there is not enough info: user=${user}, rating=${rating}`, + ); res.status(400).end(); return; } @@ -188,6 +191,7 @@ export async function createRouter( const { response, comments, consent } = req.body; if (!user) { + logger.warn(`Could not identify user to save responses, user=${user}`); res.status(400).end(); return; } From 740155e8e976dd424b4b80f56436e0a33af46212 Mon Sep 17 00:00:00 2001 From: Adam Harvey Date: Wed, 16 Aug 2023 12:22:03 -0400 Subject: [PATCH 14/73] chor: Add changeset Signed-off-by: Adam Harvey --- .changeset/poor-years-appear.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/poor-years-appear.md diff --git a/.changeset/poor-years-appear.md b/.changeset/poor-years-appear.md new file mode 100644 index 0000000000..d5b53a7051 --- /dev/null +++ b/.changeset/poor-years-appear.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-entity-feedback-backend': patch +--- + +Improve backend logging if method calls fail From 4e0e9b2a488e14b68b2dcd71645e1557f96572b5 Mon Sep 17 00:00:00 2001 From: Adam Harvey Date: Wed, 16 Aug 2023 12:29:51 -0400 Subject: [PATCH 15/73] chore: Clarify identify requirement Signed-off-by: Adam Harvey --- plugins/entity-feedback-backend/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plugins/entity-feedback-backend/README.md b/plugins/entity-feedback-backend/README.md index 99489e28b2..49a8ce20e0 100644 --- a/plugins/entity-feedback-backend/README.md +++ b/plugins/entity-feedback-backend/README.md @@ -4,6 +4,10 @@ Welcome to the entity-feedback backend plugin! ## Installation +Note: this plugin requires authentication and identity configured so Backstage can identify +which user has rated the entity. If you are using the guest identity provider which comes +out of the box, this plugin will not work when you test it. + ### Install the package ```bash From 5e2e06db747aa6865c724adfaaf79063c957874a Mon Sep 17 00:00:00 2001 From: Adam Harvey Date: Wed, 16 Aug 2023 12:30:36 -0400 Subject: [PATCH 16/73] chore: Add changeset Signed-off-by: Adam Harvey --- .changeset/few-nails-smile.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/few-nails-smile.md diff --git a/.changeset/few-nails-smile.md b/.changeset/few-nails-smile.md new file mode 100644 index 0000000000..6b5a08c97d --- /dev/null +++ b/.changeset/few-nails-smile.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-entity-feedback': patch +--- + +Improve README to identify that Backstage identity is required to be configured From 6093d001cf6c47f58e30bcf1e9dabdc37fdc9edc Mon Sep 17 00:00:00 2001 From: Adam Harvey Date: Wed, 16 Aug 2023 12:32:38 -0400 Subject: [PATCH 17/73] chore: Clarify identity requirement Signed-off-by: Adam Harvey --- plugins/entity-feedback/README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/plugins/entity-feedback/README.md b/plugins/entity-feedback/README.md index fdfa4761d6..c405bd4083 100644 --- a/plugins/entity-feedback/README.md +++ b/plugins/entity-feedback/README.md @@ -36,7 +36,11 @@ This plugin allows you give and view feedback on entities available in the Backs ## Setup -The following sections will help you get the Entity Feedback plugin setup and running +The following sections will help you get the Entity Feedback plugin setup and running. + +Note: this plugin requires authentication and identity configured so Backstage can identify +which user has rated the entity. If you are using the guest identity provider which comes +out of the box, this plugin will not work when you test it. ### Backend @@ -133,4 +137,4 @@ const groupPage = ( ); ``` -Note: For a full example of this you can look at [this EntityPage](../../packages/app/src/components/catalog/EntityPage.tsx) +Note: For a full example of this you can look at [this EntityPage](../../packages/app/src/components/catalog/EntityPage.tsx). From 828f5a67af457d6bd62e2f23f62a94311e525544 Mon Sep 17 00:00:00 2001 From: Adam Harvey Date: Wed, 16 Aug 2023 12:33:40 -0400 Subject: [PATCH 18/73] chore: Simplify wording Signed-off-by: Adam Harvey --- .changeset/few-nails-smile.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/few-nails-smile.md b/.changeset/few-nails-smile.md index 6b5a08c97d..2fad9a0b40 100644 --- a/.changeset/few-nails-smile.md +++ b/.changeset/few-nails-smile.md @@ -2,4 +2,4 @@ '@backstage/plugin-entity-feedback': patch --- -Improve README to identify that Backstage identity is required to be configured +Improve README to note that Backstage identity is required to be configured From 8be3659e68cfb96449255354f3184c4692457284 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 16 Aug 2023 22:43:24 +0000 Subject: [PATCH 19/73] Update dependency @newrelic/browser-agent to v1.238.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 27aab37fad..1dcb7ec252 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13106,14 +13106,14 @@ __metadata: linkType: hard "@newrelic/browser-agent@npm:^1.236.0": - version: 1.236.0 - resolution: "@newrelic/browser-agent@npm:1.236.0" + version: 1.238.0 + resolution: "@newrelic/browser-agent@npm:1.238.0" dependencies: core-js: ^3.26.0 fflate: ^0.7.4 rrweb: ^2.0.0-alpha.8 web-vitals: ^3.1.0 - checksum: 79a96c8f8421bed13e0e9eaf08c9bb8ac2785da3199e2304366c5cf98eb976713e393bd26a7efe998837eba5facfe7a54a6d58ba5c948c7ecc8de49e477b5836 + checksum: 180d2bc1d419e9b32fbadd6bfcbbea4d3300aa8fa9e8d848f25fe3f256d98a855c84ea5562d33b60e8ad24b5c0a7379f7e35cbeb7db271f454c64a793870efd2 languageName: node linkType: hard From 22581f2b6cb4c5bf8e02bd48ef54724ed7ebfb3f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 16 Aug 2023 23:25:58 +0000 Subject: [PATCH 20/73] Update dependency @codemirror/language to v6.9.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 1dcb7ec252..5a394646d8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9907,8 +9907,8 @@ __metadata: linkType: hard "@codemirror/language@npm:^6.0.0": - version: 6.8.0 - resolution: "@codemirror/language@npm:6.8.0" + version: 6.9.0 + resolution: "@codemirror/language@npm:6.9.0" dependencies: "@codemirror/state": ^6.0.0 "@codemirror/view": ^6.0.0 @@ -9916,7 +9916,7 @@ __metadata: "@lezer/highlight": ^1.0.0 "@lezer/lr": ^1.0.0 style-mod: ^4.0.0 - checksum: 64408d996641931fa4c6b892e17ee1fdaee0f63d3d84c019a6ea7b1e6d1c774f92357b95c2ebaed60545062b795b72d0a058c03578b2bf4023c87726e97b5d2f + checksum: 9a897fb0f569159eeafb7dce83061b425af7244bbeae2649e0e677488548b2a02eaf0c13c0c5b4d59da55e8866e6f4dc7abe3dfaa09c13749a2fa2c0dbc0c565 languageName: node linkType: hard From 0599e630cf432fa28518fc19153f4ba759863ea4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 17 Aug 2023 00:28:51 +0000 Subject: [PATCH 21/73] Update dependency pg to v8.11.3 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 5a394646d8..77ba3254dc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -34871,8 +34871,8 @@ __metadata: linkType: hard "pg@npm:^8.3.0, pg@npm:^8.9.0": - version: 8.11.2 - resolution: "pg@npm:8.11.2" + version: 8.11.3 + resolution: "pg@npm:8.11.3" dependencies: buffer-writer: 2.0.0 packet-reader: 1.0.0 @@ -34890,7 +34890,7 @@ __metadata: peerDependenciesMeta: pg-native: optional: true - checksum: dfea8a2269d500dee8c17291207e5a25897163480037beb7a59be35f51e33b519c297c943ea6898b285d6a74a0d661901dc9cff2e587cc4be0bbf09b833a71a5 + checksum: 8af9468b8969fa0d73a6b349216c8cbc953d938fcae5594f2d24043060e9226a072c8085fc4230172b5576fcab4c39c8563c655f271dc2a9209b6ad5370cafe5 languageName: node linkType: hard From b34e58c09362e561be2ff7056dc1ae5b9dba3047 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 17 Aug 2023 02:37:40 +0000 Subject: [PATCH 22/73] Update dependency @stoplight/types to v13.19.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 77ba3254dc..ec0379375a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15426,12 +15426,12 @@ __metadata: linkType: hard "@stoplight/types@npm:^12.3.0 || ^13.0.0, @stoplight/types@npm:^13.0.0, @stoplight/types@npm:^13.14.0, @stoplight/types@npm:^13.15.0, @stoplight/types@npm:^13.6.0": - version: 13.18.0 - resolution: "@stoplight/types@npm:13.18.0" + version: 13.19.0 + resolution: "@stoplight/types@npm:13.19.0" dependencies: "@types/json-schema": ^7.0.4 utility-types: ^3.10.0 - checksum: 17f464b6986fcb07719584cbb55c59e1c8d72d6d000ed64b13cae92acbdc069e5a725b4d14c4a2998eb701a0289e6ce3aee151e4200698df906ba058747e210f + checksum: 30ad1f7b8f7594e520cf5e0c1e1e9df8a2761cda1dff0a9ca22483e7b6c6310a0120fd1d599ddcaf9a1a622b064aeb5c5b8d84bdc6d8db8ce3f1bffe847d1f79 languageName: node linkType: hard From 0198aa596fd996f008d1e24efc457e3473029f4e Mon Sep 17 00:00:00 2001 From: Fevrin <5051062+fevrin@users.noreply.github.com> Date: Fri, 11 Aug 2023 22:11:11 -0400 Subject: [PATCH 23/73] add changeset Signed-off-by: Fevrin <5051062+fevrin@users.noreply.github.com> --- .changeset/late-cows-turn.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/late-cows-turn.md diff --git a/.changeset/late-cows-turn.md b/.changeset/late-cows-turn.md new file mode 100644 index 0000000000..7fa775ce22 --- /dev/null +++ b/.changeset/late-cows-turn.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend': patch +--- + +Fixed a link to the frontend Backstage plugin that had pointed to itself. From 4b8008c4d3919f05a7ba644e541b3423c7f9710a Mon Sep 17 00:00:00 2001 From: Fevrin <5051062+fevrin@users.noreply.github.com> Date: Thu, 17 Aug 2023 01:09:20 -0400 Subject: [PATCH 24/73] docs: minor grammatical fixes Signed-off-by: Fevrin <5051062+fevrin@users.noreply.github.com> --- docs/features/software-catalog/references.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/features/software-catalog/references.md b/docs/features/software-catalog/references.md index 6e0304b2e8..2240d376ce 100644 --- a/docs/features/software-catalog/references.md +++ b/docs/features/software-catalog/references.md @@ -23,9 +23,9 @@ compound reference structure. ## String References -This is the most common alternative, that is used in almost all circumstances. +This is the most common alternative and is used in almost all circumstances. -The string is on the form `[:][/]`, that is, it is +The string is of the form `[:][/]`. That is, it is composed of between one and three parts in this specific order, without any additional encoding: From f9657b891b0084f033faf69292351aface1cb89a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Thu, 17 Aug 2023 11:55:26 +0200 Subject: [PATCH 25/73] avoid unnecessary config notifications MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/warm-llamas-bake.md | 5 ++ .../src/sources/ObservableConfigProxy.test.ts | 65 +++++++++++++------ .../src/sources/ObservableConfigProxy.ts | 21 ++++-- 3 files changed, 67 insertions(+), 24 deletions(-) create mode 100644 .changeset/warm-llamas-bake.md diff --git a/.changeset/warm-llamas-bake.md b/.changeset/warm-llamas-bake.md new file mode 100644 index 0000000000..3da4a9b94d --- /dev/null +++ b/.changeset/warm-llamas-bake.md @@ -0,0 +1,5 @@ +--- +'@backstage/config-loader': patch +--- + +Do not unnecessarily notify subscribers when no-op updates to config happen diff --git a/packages/config-loader/src/sources/ObservableConfigProxy.test.ts b/packages/config-loader/src/sources/ObservableConfigProxy.test.ts index d1fccf3e80..f072536489 100644 --- a/packages/config-loader/src/sources/ObservableConfigProxy.test.ts +++ b/packages/config-loader/src/sources/ObservableConfigProxy.test.ts @@ -25,21 +25,17 @@ describe('ObservableConfigProxy', () => { const sub = config.subscribe(fn); expect(config.getOptionalNumber('x')).toBe(undefined); - config.setConfig(new ConfigReader({})); - expect(fn).toHaveBeenCalledTimes(1); - expect(config.getOptionalNumber('x')).toBe(undefined); - config.setConfig(new ConfigReader({ x: 1 })); - expect(fn).toHaveBeenCalledTimes(2); + expect(fn).toHaveBeenCalledTimes(1); expect(config.getOptionalNumber('x')).toBe(1); config.setConfig(new ConfigReader({ x: 3 })); - expect(fn).toHaveBeenCalledTimes(3); + expect(fn).toHaveBeenCalledTimes(2); sub.unsubscribe(); expect(config.getOptionalNumber('x')).toBe(3); config.setConfig(new ConfigReader({ x: 5 })); - expect(fn).toHaveBeenCalledTimes(3); + expect(fn).toHaveBeenCalledTimes(2); expect(config.getOptionalNumber('x')).toBe(5); }); @@ -58,18 +54,10 @@ describe('ObservableConfigProxy', () => { expect(config2.getOptionalNumber('x')).toBe(undefined); expect(config3.getOptionalNumber('x')).toBe(undefined); - config1.setConfig(new ConfigReader({})); + config1.setConfig(new ConfigReader({ x: 1, a: { x: 2, b: { x: 3 } } })); expect(fn1).toHaveBeenCalledTimes(1); expect(fn2).toHaveBeenCalledTimes(1); expect(fn3).toHaveBeenCalledTimes(1); - expect(config1.getOptionalNumber('x')).toBe(undefined); - expect(config2.getOptionalNumber('x')).toBe(undefined); - expect(config3.getOptionalNumber('x')).toBe(undefined); - - config1.setConfig(new ConfigReader({ x: 1, a: { x: 2, b: { x: 3 } } })); - expect(fn1).toHaveBeenCalledTimes(2); - expect(fn2).toHaveBeenCalledTimes(2); - expect(fn3).toHaveBeenCalledTimes(2); expect(config1.getNumber('x')).toBe(1); expect(config2.getNumber('x')).toBe(2); expect(config3.getNumber('x')).toBe(3); @@ -79,9 +67,9 @@ describe('ObservableConfigProxy', () => { sub3.unsubscribe(); config1.setConfig(new ConfigReader({ x: 4, a: { x: 5, b: { x: 6 } } })); - expect(fn1).toHaveBeenCalledTimes(2); - expect(fn2).toHaveBeenCalledTimes(2); - expect(fn3).toHaveBeenCalledTimes(2); + expect(fn1).toHaveBeenCalledTimes(1); + expect(fn2).toHaveBeenCalledTimes(1); + expect(fn3).toHaveBeenCalledTimes(1); expect(config1.getNumber('x')).toBe(4); expect(config2.getNumber('x')).toBe(5); expect(config3.getNumber('x')).toBe(6); @@ -140,4 +128,43 @@ describe('ObservableConfigProxy', () => { 'Only the root config can be closed', ); }); + + it('should only notify subscribers when the config data actually changes (ignoring key order)', () => { + const config = ObservableConfigProxy.create(new AbortController()); + const fn = jest.fn(); + config.subscribe(fn); + + expect(config.getOptionalNumber('a')).toBe(undefined); + + config.setConfig(new ConfigReader({})); + expect(fn).toHaveBeenCalledTimes(0); + expect(config.getOptionalNumber('a')).toBe(undefined); + + config.setConfig( + new ConfigReader({ + a: 1, + b: 1, + }), + ); + expect(fn).toHaveBeenCalledTimes(1); + expect(config.getOptionalNumber('a')).toBe(1); + + config.setConfig( + new ConfigReader({ + b: 1, + a: 1, + }), + ); + expect(fn).toHaveBeenCalledTimes(1); + expect(config.getOptionalNumber('a')).toBe(1); + + config.setConfig( + new ConfigReader({ + b: 1, + a: 2, + }), + ); + expect(fn).toHaveBeenCalledTimes(2); + expect(config.getOptionalNumber('a')).toBe(2); + }); }); diff --git a/packages/config-loader/src/sources/ObservableConfigProxy.ts b/packages/config-loader/src/sources/ObservableConfigProxy.ts index 59be836160..3d2084beac 100644 --- a/packages/config-loader/src/sources/ObservableConfigProxy.ts +++ b/packages/config-loader/src/sources/ObservableConfigProxy.ts @@ -16,6 +16,7 @@ import { Config, ConfigReader } from '@backstage/config'; import { JsonValue } from '@backstage/types'; +import isEqual from 'lodash/isEqual'; export class ObservableConfigProxy implements Config { private config: Config = new ConfigReader({}); @@ -40,12 +41,22 @@ export class ObservableConfigProxy implements Config { if (this.parent) { throw new Error('immutable'); } + + // We only notify subscribers if the data contents of the config actually + // changed. If they didn't, there's no point in callers trying to re-read + // them. However we still want to replace the local config object, since its + // runtime implementation could be entirely different. + const changed = !isEqual(this.config.get(), config.get()); + this.config = config; - for (const subscriber of this.subscribers) { - try { - subscriber(); - } catch (error) { - console.error(`Config subscriber threw error, ${error}`); + + if (changed) { + for (const subscriber of this.subscribers) { + try { + subscriber(); + } catch (error) { + console.error(`Config subscriber threw error, ${error}`); + } } } } From 044b4f2fb1e38083cdc0c51cf8ce82dbc0e8f419 Mon Sep 17 00:00:00 2001 From: Brian Fletcher Date: Thu, 17 Aug 2023 11:29:29 +0100 Subject: [PATCH 26/73] deduplicate search results from azure Signed-off-by: Brian Fletcher --- .changeset/mean-carpets-provide.md | 5 +++++ .../src/providers/AzureDevOpsEntityProvider.ts | 9 +++++---- 2 files changed, 10 insertions(+), 4 deletions(-) create mode 100644 .changeset/mean-carpets-provide.md diff --git a/.changeset/mean-carpets-provide.md b/.changeset/mean-carpets-provide.md new file mode 100644 index 0000000000..0d33816228 --- /dev/null +++ b/.changeset/mean-carpets-provide.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend-module-azure': patch +--- + +Remove duplications from Azure search before commiting the new locations to the catalog. diff --git a/plugins/catalog-backend-module-azure/src/providers/AzureDevOpsEntityProvider.ts b/plugins/catalog-backend-module-azure/src/providers/AzureDevOpsEntityProvider.ts index 5abd23ce00..4a9ad2f250 100644 --- a/plugins/catalog-backend-module-azure/src/providers/AzureDevOpsEntityProvider.ts +++ b/plugins/catalog-backend-module-azure/src/providers/AzureDevOpsEntityProvider.ts @@ -148,7 +148,10 @@ export class AzureDevOpsEntityProvider implements EntityProvider { logger.info(`Discovered ${files.length} catalog files`); - const locations = files.map(key => this.createLocationSpec(key)); + const targets = files.map(key => this.createObjectUrl(key)); + const locations = Array.from(new Set(targets)).map(key => + this.createLocationSpec(key), + ); await this.connection.applyMutation({ type: 'full', @@ -165,9 +168,7 @@ export class AzureDevOpsEntityProvider implements EntityProvider { ); } - private createLocationSpec(file: CodeSearchResultItem): LocationSpec { - const target = this.createObjectUrl(file); - + private createLocationSpec(target: string): LocationSpec { return { type: 'url', target: target, From c0a2e6e8c26aebd7ff365434af3b86ba696ba9f4 Mon Sep 17 00:00:00 2001 From: Brian Fletcher Date: Thu, 17 Aug 2023 11:32:49 +0100 Subject: [PATCH 27/73] fix typo Signed-off-by: Brian Fletcher --- .changeset/mean-carpets-provide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/mean-carpets-provide.md b/.changeset/mean-carpets-provide.md index 0d33816228..b5e9f551d4 100644 --- a/.changeset/mean-carpets-provide.md +++ b/.changeset/mean-carpets-provide.md @@ -2,4 +2,4 @@ '@backstage/plugin-catalog-backend-module-azure': patch --- -Remove duplications from Azure search before commiting the new locations to the catalog. +Remove duplications from Azure search before committing the new locations to the catalog. From cb2e19d82d95ac242fbc4781e7f168a698965377 Mon Sep 17 00:00:00 2001 From: Gustaf Lundh Date: Thu, 17 Aug 2023 12:56:02 +0200 Subject: [PATCH 28/73] Gitiles: Fix issue where the auth prefix was misplaced Bug: #19428 Signed-off-by: Gustaf Lundh --- .changeset/orange-houses-fly.md | 5 +++ packages/integration/src/gerrit/core.test.ts | 32 ++++++++++++++++++++ packages/integration/src/gerrit/core.ts | 10 ++++-- 3 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 .changeset/orange-houses-fly.md diff --git a/.changeset/orange-houses-fly.md b/.changeset/orange-houses-fly.md new file mode 100644 index 0000000000..546484304c --- /dev/null +++ b/.changeset/orange-houses-fly.md @@ -0,0 +1,5 @@ +--- +'@backstage/integration': patch +--- + +Gitiles: Fixed auth prefix issue diff --git a/packages/integration/src/gerrit/core.test.ts b/packages/integration/src/gerrit/core.test.ts index c00bae384f..6f6a8ed58f 100644 --- a/packages/integration/src/gerrit/core.test.ts +++ b/packages/integration/src/gerrit/core.test.ts @@ -39,6 +39,14 @@ describe('gerrit core', () => { host: 'gerrit.com', gitilesBaseUrl: 'https://gerrit.com/gitiles', }; + const configWithPath: GerritIntegrationConfig = { + host: 'gerrit.com', + gitilesBaseUrl: 'https://gerrit.com/path/gitiles', + }; + const configWithPathSlash: GerritIntegrationConfig = { + host: 'gerrit.com', + gitilesBaseUrl: 'https://gerrit.com/path1/path2/gitiles/', + }; it('can create an archive url for a branch', () => { expect(buildGerritGitilesArchiveUrl(config, 'repo', 'dev', '')).toEqual( 'https://gerrit.com/gitiles/repo/+archive/refs/heads/dev.tar.gz', @@ -67,6 +75,30 @@ describe('gerrit core', () => { 'https://gerrit.com/a/gitiles/repo/+archive/refs/heads/dev/docs.tar.gz', ); }); + it('can create an authenticated url when auth is enabled and an url-path is used', () => { + const authConfig = { + ...configWithPath, + username: 'username', + password: 'password', + }; + expect( + buildGerritGitilesArchiveUrl(authConfig, 'repo', 'dev', 'docs'), + ).toEqual( + 'https://gerrit.com/path/a/gitiles/repo/+archive/refs/heads/dev/docs.tar.gz', + ); + }); + it('can create an authenticated url when auth is enabled and an url-path + slash is used', () => { + const authConfig = { + ...configWithPathSlash, + username: 'username', + password: 'password', + }; + expect( + buildGerritGitilesArchiveUrl(authConfig, 'repo', 'dev', 'docs'), + ).toEqual( + 'https://gerrit.com/path1/path2/a/gitiles/repo/+archive/refs/heads/dev/docs.tar.gz', + ); + }); }); describe('buildGerritGitilesUrl', () => { diff --git a/packages/integration/src/gerrit/core.ts b/packages/integration/src/gerrit/core.ts index 107d5a4469..e104ffc7fb 100644 --- a/packages/integration/src/gerrit/core.ts +++ b/packages/integration/src/gerrit/core.ts @@ -157,9 +157,13 @@ export function getGitilesAuthenticationUrl( config: GerritIntegrationConfig, ): string { const parsedUrl = new URL(config.gitilesBaseUrl!); - return `${parsedUrl.protocol}//${parsedUrl.host}${getAuthenticationPrefix( - config, - )}${parsedUrl.pathname.substring(1)}`; + parsedUrl.pathname = parsedUrl.pathname.replace(/\/?$/, ''); + parsedUrl.pathname = parsedUrl.pathname.replace( + /\/([^\/]*)$/, + `${getAuthenticationPrefix(config)}$1`, + ); + + return parsedUrl.toString(); } /** From 9fb3b5373c453a257817c71cce5df68e1f064ab9 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 17 Aug 2023 14:40:29 +0200 Subject: [PATCH 29/73] backend-test-utils: add service mock helpers Signed-off-by: Patrik Oldsberg --- .changeset/old-geese-drive.md | 5 + packages/backend-test-utils/api-report.md | 253 ++++++++++++++++++ packages/backend-test-utils/package.json | 3 + .../src/next/services/mockServices.ts | 85 ++++++ yarn.lock | 2 + 5 files changed, 348 insertions(+) create mode 100644 .changeset/old-geese-drive.md diff --git a/.changeset/old-geese-drive.md b/.changeset/old-geese-drive.md new file mode 100644 index 0000000000..ddaa7ad30a --- /dev/null +++ b/.changeset/old-geese-drive.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-test-utils': patch +--- + +Extended `mockService` to also include mocked variants, for example `mockServices.lifecycle.mock()`. The returned mocked implementation will have a `factory` property which is a service factory for itself. You can also pass a partial implementation of the service to the mock function to use a mock implementation of specific methods. diff --git a/packages/backend-test-utils/api-report.md b/packages/backend-test-utils/api-report.md index d086b1d2ae..f87181f635 100644 --- a/packages/backend-test-utils/api-report.md +++ b/packages/backend-test-utils/api-report.md @@ -3,24 +3,52 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts +/// + +import { AuthorizePermissionRequest } from '@backstage/plugin-permission-common'; import { Backend } from '@backstage/backend-app-api'; import { BackendFeature } from '@backstage/backend-plugin-api'; +import { BackstageIdentityResponse } from '@backstage/plugin-auth-node'; import { CacheService } from '@backstage/backend-plugin-api'; +import { CacheServiceOptions } from '@backstage/backend-plugin-api'; +import { CacheServiceSetOptions } from '@backstage/backend-plugin-api'; import { DatabaseService } from '@backstage/backend-plugin-api'; +import { DefinitivePolicyDecision } from '@backstage/plugin-permission-common'; +import { EvaluatorRequestOptions } from '@backstage/plugin-permission-common'; import { ExtendedHttpServer } from '@backstage/backend-app-api'; import { ExtensionPoint } from '@backstage/backend-plugin-api'; +import { Handler } from 'express'; import { HttpRouterFactoryOptions } from '@backstage/backend-app-api'; import { HttpRouterService } from '@backstage/backend-plugin-api'; +import { IdentityApiGetIdentityRequest } from '@backstage/plugin-auth-node'; import { IdentityService } from '@backstage/backend-plugin-api'; import { JsonObject } from '@backstage/types'; +import { JsonValue } from '@backstage/types'; import { Knex } from 'knex'; import { LifecycleService } from '@backstage/backend-plugin-api'; +import { LifecycleServiceShutdownHook } from '@backstage/backend-plugin-api'; +import { LifecycleServiceShutdownOptions } from '@backstage/backend-plugin-api'; +import { LifecycleServiceStartupHook } from '@backstage/backend-plugin-api'; +import { LifecycleServiceStartupOptions } from '@backstage/backend-plugin-api'; import { LoggerService } from '@backstage/backend-plugin-api'; import { PermissionsService } from '@backstage/backend-plugin-api'; +import { PolicyDecision } from '@backstage/plugin-permission-common'; +import { QueryPermissionRequest } from '@backstage/plugin-permission-common'; +import { ReadTreeOptions } from '@backstage/backend-plugin-api'; +import { ReadTreeResponse } from '@backstage/backend-plugin-api'; +import { ReadUrlOptions } from '@backstage/backend-plugin-api'; +import { ReadUrlResponse } from '@backstage/backend-plugin-api'; import { RootConfigService } from '@backstage/backend-plugin-api'; import { RootLifecycleService } from '@backstage/backend-plugin-api'; +import { RootLoggerService } from '@backstage/backend-plugin-api'; import { SchedulerService } from '@backstage/backend-plugin-api'; +import { SearchOptions } from '@backstage/backend-plugin-api'; +import { SearchResponse } from '@backstage/backend-plugin-api'; import { ServiceFactory } from '@backstage/backend-plugin-api'; +import { TaskDescriptor } from '@backstage/backend-tasks'; +import { TaskInvocationDefinition } from '@backstage/backend-tasks'; +import { TaskRunner } from '@backstage/backend-tasks'; +import { TaskScheduleDefinition } from '@backstage/backend-tasks'; import { TokenManagerService } from '@backstage/backend-plugin-api'; import { UrlReaderService } from '@backstage/backend-plugin-api'; @@ -33,11 +61,47 @@ export namespace mockServices { export namespace cache { const // (undocumented) factory: () => ServiceFactory; + const // (undocumented) + mock: (partialImpl?: Partial | undefined) => { + factory: ServiceFactory; + } & { + get: jest.MockInstance< + Promise, + [key: string], + unknown + >; + set: jest.MockInstance< + Promise, + [ + key: string, + value: JsonValue, + options?: CacheServiceSetOptions | undefined, + ], + unknown + >; + delete: jest.MockInstance, [key: string], unknown>; + withOptions: jest.MockInstance< + CacheService, + [options: CacheServiceOptions], + unknown + >; + } & CacheService; } // (undocumented) export namespace database { const // (undocumented) factory: () => ServiceFactory; + const // (undocumented) + mock: (partialImpl?: Partial | undefined) => { + factory: ServiceFactory; + } & { + getClient: jest.MockInstance>, [], unknown>; + migrations?: + | { + skip?: boolean | undefined; + } + | undefined; + } & DatabaseService; } // (undocumented) export namespace httpRouter { @@ -45,6 +109,12 @@ export namespace mockServices { factory: ( options?: HttpRouterFactoryOptions | undefined, ) => ServiceFactory; + const // (undocumented) + mock: (partialImpl?: Partial | undefined) => { + factory: ServiceFactory; + } & { + use: jest.MockInstance; + } & HttpRouterService; } // (undocumented) export function identity(): IdentityService; @@ -52,21 +122,99 @@ export namespace mockServices { export namespace identity { const // (undocumented) factory: () => ServiceFactory; + const // (undocumented) + mock: (partialImpl?: Partial | undefined) => { + factory: ServiceFactory; + } & { + getIdentity: jest.MockInstance< + Promise, + [options: IdentityApiGetIdentityRequest], + unknown + >; + } & IdentityService; } // (undocumented) export namespace lifecycle { const // (undocumented) factory: () => ServiceFactory; + const // (undocumented) + mock: (partialImpl?: Partial | undefined) => { + factory: ServiceFactory; + } & { + addStartupHook: jest.MockInstance< + void, + [ + hook: LifecycleServiceStartupHook, + options?: LifecycleServiceStartupOptions | undefined, + ], + unknown + >; + addShutdownHook: jest.MockInstance< + void, + [ + hook: LifecycleServiceShutdownHook, + options?: LifecycleServiceShutdownOptions | undefined, + ], + unknown + >; + } & LifecycleService; } // (undocumented) export namespace logger { const // (undocumented) factory: () => ServiceFactory; + const // (undocumented) + mock: (partialImpl?: Partial | undefined) => { + factory: ServiceFactory; + } & { + error: jest.MockInstance< + void, + [message: string, meta?: Error | JsonObject | undefined], + unknown + >; + warn: jest.MockInstance< + void, + [message: string, meta?: Error | JsonObject | undefined], + unknown + >; + info: jest.MockInstance< + void, + [message: string, meta?: Error | JsonObject | undefined], + unknown + >; + debug: jest.MockInstance< + void, + [message: string, meta?: Error | JsonObject | undefined], + unknown + >; + child: jest.MockInstance; + } & LoggerService; } // (undocumented) export namespace permissions { const // (undocumented) factory: () => ServiceFactory; + const // (undocumented) + mock: (partialImpl?: Partial | undefined) => { + factory: ServiceFactory; + } & { + authorize: jest.MockInstance< + Promise, + [ + requests: AuthorizePermissionRequest[], + options?: EvaluatorRequestOptions | undefined, + ], + unknown + >; + authorizeConditional: jest.MockInstance< + Promise, + [ + requests: QueryPermissionRequest[], + options?: EvaluatorRequestOptions | undefined, + ], + unknown + >; + } & PermissionsService; } // (undocumented) export function rootConfig(options?: rootConfig.Options): RootConfigService; @@ -85,6 +233,27 @@ export namespace mockServices { export namespace rootLifecycle { const // (undocumented) factory: () => ServiceFactory; + const // (undocumented) + mock: (partialImpl?: Partial | undefined) => { + factory: ServiceFactory; + } & { + addStartupHook: jest.MockInstance< + void, + [ + hook: LifecycleServiceStartupHook, + options?: LifecycleServiceStartupOptions | undefined, + ], + unknown + >; + addShutdownHook: jest.MockInstance< + void, + [ + hook: LifecycleServiceShutdownHook, + options?: LifecycleServiceShutdownOptions | undefined, + ], + unknown + >; + } & RootLifecycleService; } // (undocumented) export function rootLogger(options?: rootLogger.Options): LoggerService; @@ -98,11 +267,58 @@ export namespace mockServices { factory: ( options?: Options | undefined, ) => ServiceFactory; + const // (undocumented) + mock: (partialImpl?: Partial | undefined) => { + factory: ServiceFactory; + } & { + error: jest.MockInstance< + void, + [message: string, meta?: Error | JsonObject | undefined], + unknown + >; + warn: jest.MockInstance< + void, + [message: string, meta?: Error | JsonObject | undefined], + unknown + >; + info: jest.MockInstance< + void, + [message: string, meta?: Error | JsonObject | undefined], + unknown + >; + debug: jest.MockInstance< + void, + [message: string, meta?: Error | JsonObject | undefined], + unknown + >; + child: jest.MockInstance; + } & RootLoggerService; } // (undocumented) export namespace scheduler { const // (undocumented) factory: () => ServiceFactory; + const // (undocumented) + mock: (partialImpl?: Partial | undefined) => { + factory: ServiceFactory; + } & { + triggerTask: jest.MockInstance, [id: string], unknown>; + scheduleTask: jest.MockInstance< + Promise, + [task: TaskScheduleDefinition & TaskInvocationDefinition], + unknown + >; + createScheduledTaskRunner: jest.MockInstance< + TaskRunner, + [schedule: TaskScheduleDefinition], + unknown + >; + getScheduledTasks: jest.MockInstance< + Promise, + [], + unknown + >; + } & SchedulerService; } // (undocumented) export function tokenManager(): TokenManagerService; @@ -110,11 +326,48 @@ export namespace mockServices { export namespace tokenManager { const // (undocumented) factory: () => ServiceFactory; + const // (undocumented) + mock: (partialImpl?: Partial | undefined) => { + factory: ServiceFactory; + } & { + getToken: jest.MockInstance< + Promise<{ + token: string; + }>, + [], + unknown + >; + authenticate: jest.MockInstance< + Promise, + [token: string], + unknown + >; + } & TokenManagerService; } // (undocumented) export namespace urlReader { const // (undocumented) factory: () => ServiceFactory; + const // (undocumented) + mock: (partialImpl?: Partial | undefined) => { + factory: ServiceFactory; + } & { + readUrl: jest.MockInstance< + Promise, + [url: string, options?: ReadUrlOptions | undefined], + unknown + >; + readTree: jest.MockInstance< + Promise, + [url: string, options?: ReadTreeOptions | undefined], + unknown + >; + search: jest.MockInstance< + Promise, + [url: string, options?: SearchOptions | undefined], + unknown + >; + } & UrlReaderService; } } diff --git a/packages/backend-test-utils/package.json b/packages/backend-test-utils/package.json index 02cb1d5cf9..21946be36c 100644 --- a/packages/backend-test-utils/package.json +++ b/packages/backend-test-utils/package.json @@ -57,6 +57,9 @@ "testcontainers": "^8.1.2", "uuid": "^8.0.0" }, + "peerDependencies": { + "@types/jest": "*" + }, "devDependencies": { "@backstage/cli": "workspace:^", "@types/supertest": "^2.0.8", diff --git a/packages/backend-test-utils/src/next/services/mockServices.ts b/packages/backend-test-utils/src/next/services/mockServices.ts index 0455b9f1ae..d0bb79dd2e 100644 --- a/packages/backend-test-utils/src/next/services/mockServices.ts +++ b/packages/backend-test-utils/src/next/services/mockServices.ts @@ -40,6 +40,7 @@ import { JsonObject } from '@backstage/types'; import { MockIdentityService } from './MockIdentityService'; import { MockRootLoggerService } from './MockRootLoggerService'; +/** @internal */ function simpleFactory< TService, TScope extends 'root' | 'plugin', @@ -57,6 +58,34 @@ function simpleFactory< })) as (...options: TOptions) => ServiceFactory; } +/** @internal */ +function simpleMock( + ref: ServiceRef, + mockFactory: () => jest.Mocked, +): ( + partialImpl?: Partial, +) => { factory: ServiceFactory } & jest.Mocked { + return partialImpl => { + const mock = mockFactory(); + if (partialImpl) { + for (const [key, impl] of Object.entries(partialImpl)) { + if (typeof impl === 'function') { + (mock as any)[key].mockImplementation(impl); + } else { + (mock as any)[key] = impl; + } + } + } + return Object.assign(mock, { + factory: createServiceFactory({ + service: ref, + deps: {}, + factory: () => mock, + })(), + }); + }; +} + /** * @public */ @@ -79,6 +108,13 @@ export namespace mockServices { }; export const factory = simpleFactory(coreServices.rootLogger, rootLogger); + export const mock = simpleMock(coreServices.rootLogger, () => ({ + child: jest.fn(), + debug: jest.fn(), + error: jest.fn(), + info: jest.fn(), + warn: jest.fn(), + })); } export function tokenManager(): TokenManagerService { @@ -98,6 +134,10 @@ export namespace mockServices { coreServices.tokenManager, tokenManager, ); + export const mock = simpleMock(coreServices.tokenManager, () => ({ + authenticate: jest.fn(), + getToken: jest.fn(), + })); } export function identity(): IdentityService { @@ -105,6 +145,9 @@ export namespace mockServices { } export namespace identity { export const factory = simpleFactory(coreServices.identity, identity); + export const mock = simpleMock(coreServices.identity, () => ({ + getIdentity: jest.fn(), + })); } // TODO(Rugvip): Not all core services have implementations available here yet. @@ -112,29 +155,71 @@ export namespace mockServices { // re-implement functioning mock versions here. export namespace cache { export const factory = cacheServiceFactory; + export const mock = simpleMock(coreServices.cache, () => ({ + delete: jest.fn(), + get: jest.fn(), + set: jest.fn(), + withOptions: jest.fn(), + })); } export namespace database { export const factory = databaseServiceFactory; + export const mock = simpleMock(coreServices.database, () => ({ + getClient: jest.fn(), + })); } export namespace httpRouter { export const factory = httpRouterServiceFactory; + export const mock = simpleMock(coreServices.httpRouter, () => ({ + use: jest.fn(), + })); } export namespace lifecycle { export const factory = lifecycleServiceFactory; + export const mock = simpleMock(coreServices.lifecycle, () => ({ + addShutdownHook: jest.fn(), + addStartupHook: jest.fn(), + })); } export namespace logger { export const factory = loggerServiceFactory; + export const mock = simpleMock(coreServices.logger, () => ({ + child: jest.fn(), + debug: jest.fn(), + error: jest.fn(), + info: jest.fn(), + warn: jest.fn(), + })); } export namespace permissions { export const factory = permissionsServiceFactory; + export const mock = simpleMock(coreServices.permissions, () => ({ + authorize: jest.fn(), + authorizeConditional: jest.fn(), + })); } export namespace rootLifecycle { export const factory = rootLifecycleServiceFactory; + export const mock = simpleMock(coreServices.rootLifecycle, () => ({ + addShutdownHook: jest.fn(), + addStartupHook: jest.fn(), + })); } export namespace scheduler { export const factory = schedulerServiceFactory; + export const mock = simpleMock(coreServices.scheduler, () => ({ + createScheduledTaskRunner: jest.fn(), + getScheduledTasks: jest.fn(), + scheduleTask: jest.fn(), + triggerTask: jest.fn(), + })); } export namespace urlReader { export const factory = urlReaderServiceFactory; + export const mock = simpleMock(coreServices.urlReader, () => ({ + readTree: jest.fn(), + readUrl: jest.fn(), + search: jest.fn(), + })); } } diff --git a/yarn.lock b/yarn.lock index ec0379375a..fd3d589b8a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3514,6 +3514,8 @@ __metadata: supertest: ^6.1.3 testcontainers: ^8.1.2 uuid: ^8.0.0 + peerDependencies: + "@types/jest": "*" languageName: unknown linkType: soft From 9df5afff8ebfb6f2ec812dae694c1410c113639d Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 17 Aug 2023 14:40:57 +0200 Subject: [PATCH 30/73] refactor plugin tests to use mocks from mockServices Signed-off-by: Patrik Oldsberg --- .../catalogModuleAwsS3EntityProvider.test.ts | 29 ++++--------------- ...logModuleAzureDevOpsEntityProvider.test.ts | 23 ++++----------- ...ModuleBitbucketCloudEntityProvider.test.ts | 23 ++++----------- ...oduleBitbucketServerEntityProvider.test.ts | 23 ++++----------- .../catalogModuleGerritEntityProvider.test.ts | 23 ++++----------- .../catalogModuleGithubEntityProvider.test.ts | 23 ++++----------- ...oduleGitlabDiscoveryEntityProvider.test.ts | 23 ++++----------- ...IncrementalIngestionEntityProvider.test.ts | 19 ++++-------- ...uleMicrosoftGraphOrgEntityProvider.test.ts | 23 ++++----------- ...atalogModulePuppetDbEntityProvider.test.ts | 23 ++++----------- ...oduleAwsSqsConsumingEventPublisher.test.ts | 15 ++-------- 11 files changed, 62 insertions(+), 185 deletions(-) diff --git a/plugins/catalog-backend-module-aws/src/module/catalogModuleAwsS3EntityProvider.test.ts b/plugins/catalog-backend-module-aws/src/module/catalogModuleAwsS3EntityProvider.test.ts index c9fea8aa28..ad1e94cad6 100644 --- a/plugins/catalog-backend-module-aws/src/module/catalogModuleAwsS3EntityProvider.test.ts +++ b/plugins/catalog-backend-module-aws/src/module/catalogModuleAwsS3EntityProvider.test.ts @@ -14,15 +14,7 @@ * limitations under the License. */ -import { getVoidLogger } from '@backstage/backend-common'; -import { - coreServices, - createServiceFactory, -} from '@backstage/backend-plugin-api'; -import { - PluginTaskScheduler, - TaskScheduleDefinition, -} from '@backstage/backend-tasks'; +import { TaskScheduleDefinition } from '@backstage/backend-tasks'; import { mockServices, startTestBackend } from '@backstage/backend-test-utils'; import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha'; import { Duration } from 'luxon'; @@ -40,12 +32,12 @@ describe('catalogModuleAwsS3EntityProvider', () => { }, }; const runner = jest.fn(); - const scheduler = { - createScheduledTaskRunner: (schedule: TaskScheduleDefinition) => { + const scheduler = mockServices.scheduler.mock({ + createScheduledTaskRunner(schedule) { usedSchedule = schedule; - return runner; + return { run: runner }; }, - } as unknown as PluginTaskScheduler; + }); const config = { catalog: { @@ -66,16 +58,7 @@ describe('catalogModuleAwsS3EntityProvider', () => { features: [ catalogModuleAwsS3EntityProvider(), mockServices.rootConfig.factory({ data: config }), - createServiceFactory(() => ({ - service: coreServices.logger, - deps: {}, - factory: getVoidLogger, - }))(), - createServiceFactory(() => ({ - service: coreServices.scheduler, - deps: {}, - factory: () => scheduler, - }))(), + scheduler.factory, ], }); diff --git a/plugins/catalog-backend-module-azure/src/module/catalogModuleAzureDevOpsEntityProvider.test.ts b/plugins/catalog-backend-module-azure/src/module/catalogModuleAzureDevOpsEntityProvider.test.ts index 3147a0871b..a20921fa3f 100644 --- a/plugins/catalog-backend-module-azure/src/module/catalogModuleAzureDevOpsEntityProvider.test.ts +++ b/plugins/catalog-backend-module-azure/src/module/catalogModuleAzureDevOpsEntityProvider.test.ts @@ -14,14 +14,7 @@ * limitations under the License. */ -import { - coreServices, - createServiceFactory, -} from '@backstage/backend-plugin-api'; -import { - PluginTaskScheduler, - TaskScheduleDefinition, -} from '@backstage/backend-tasks'; +import { TaskScheduleDefinition } from '@backstage/backend-tasks'; import { mockServices, startTestBackend } from '@backstage/backend-test-utils'; import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha'; import { Duration } from 'luxon'; @@ -39,12 +32,12 @@ describe('catalogModuleAzureDevOpsEntityProvider', () => { }, }; const runner = jest.fn(); - const scheduler = { - createScheduledTaskRunner: (schedule: TaskScheduleDefinition) => { + const scheduler = mockServices.scheduler.mock({ + createScheduledTaskRunner(schedule) { usedSchedule = schedule; - return runner; + return { run: runner }; }, - } as unknown as PluginTaskScheduler; + }); const config = { catalog: { @@ -69,11 +62,7 @@ describe('catalogModuleAzureDevOpsEntityProvider', () => { catalogModuleAzureDevOpsEntityProvider(), mockServices.rootConfig.factory({ data: config }), mockServices.logger.factory(), - createServiceFactory(() => ({ - deps: {}, - service: coreServices.scheduler, - factory: async () => scheduler, - })), + scheduler.factory, ], }); diff --git a/plugins/catalog-backend-module-bitbucket-cloud/src/module/catalogModuleBitbucketCloudEntityProvider.test.ts b/plugins/catalog-backend-module-bitbucket-cloud/src/module/catalogModuleBitbucketCloudEntityProvider.test.ts index 83769fc3f5..c771a40acc 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/src/module/catalogModuleBitbucketCloudEntityProvider.test.ts +++ b/plugins/catalog-backend-module-bitbucket-cloud/src/module/catalogModuleBitbucketCloudEntityProvider.test.ts @@ -14,14 +14,7 @@ * limitations under the License. */ -import { - coreServices, - createServiceFactory, -} from '@backstage/backend-plugin-api'; -import { - PluginTaskScheduler, - TaskScheduleDefinition, -} from '@backstage/backend-tasks'; +import { TaskScheduleDefinition } from '@backstage/backend-tasks'; import { startTestBackend, mockServices } from '@backstage/backend-test-utils'; import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha'; import { eventsExtensionPoint } from '@backstage/plugin-events-node/alpha'; @@ -46,12 +39,12 @@ describe('catalogModuleBitbucketCloudEntityProvider', () => { }, }; const runner = jest.fn(); - const scheduler = { - createScheduledTaskRunner: (schedule: TaskScheduleDefinition) => { + const scheduler = mockServices.scheduler.mock({ + createScheduledTaskRunner(schedule) { usedSchedule = schedule; - return runner; + return { run: runner }; }, - } as unknown as PluginTaskScheduler; + }); await startTestBackend({ extensionPoints: [ @@ -75,11 +68,7 @@ describe('catalogModuleBitbucketCloudEntityProvider', () => { }, }, }), - createServiceFactory({ - service: coreServices.scheduler, - deps: {}, - factory: async () => scheduler, - }), + scheduler.factory, ], }); diff --git a/plugins/catalog-backend-module-bitbucket-server/src/module/catalogModuleBitbucketServerEntityProvider.test.ts b/plugins/catalog-backend-module-bitbucket-server/src/module/catalogModuleBitbucketServerEntityProvider.test.ts index ae4a636008..ab92e24fd7 100644 --- a/plugins/catalog-backend-module-bitbucket-server/src/module/catalogModuleBitbucketServerEntityProvider.test.ts +++ b/plugins/catalog-backend-module-bitbucket-server/src/module/catalogModuleBitbucketServerEntityProvider.test.ts @@ -14,14 +14,7 @@ * limitations under the License. */ -import { - coreServices, - createServiceFactory, -} from '@backstage/backend-plugin-api'; -import { - PluginTaskScheduler, - TaskScheduleDefinition, -} from '@backstage/backend-tasks'; +import { TaskScheduleDefinition } from '@backstage/backend-tasks'; import { mockServices, startTestBackend } from '@backstage/backend-test-utils'; import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha'; import { catalogModuleBitbucketServerEntityProvider } from './catalogModuleBitbucketServerEntityProvider'; @@ -39,12 +32,12 @@ describe('catalogModuleBitbucketServerEntityProvider', () => { }, }; const runner = jest.fn(); - const scheduler = { - createScheduledTaskRunner: (schedule: TaskScheduleDefinition) => { + const scheduler = mockServices.scheduler.mock({ + createScheduledTaskRunner(schedule) { usedSchedule = schedule; - return runner; + return { run: runner }; }, - } as unknown as PluginTaskScheduler; + }); const config = { catalog: { @@ -73,11 +66,7 @@ describe('catalogModuleBitbucketServerEntityProvider', () => { catalogModuleBitbucketServerEntityProvider(), mockServices.rootConfig.factory({ data: config }), mockServices.logger.factory(), - createServiceFactory({ - service: coreServices.scheduler, - deps: {}, - factory: async () => scheduler, - }), + scheduler.factory, ], }); diff --git a/plugins/catalog-backend-module-gerrit/src/module/catalogModuleGerritEntityProvider.test.ts b/plugins/catalog-backend-module-gerrit/src/module/catalogModuleGerritEntityProvider.test.ts index 9807814f61..4afcd8e2d4 100644 --- a/plugins/catalog-backend-module-gerrit/src/module/catalogModuleGerritEntityProvider.test.ts +++ b/plugins/catalog-backend-module-gerrit/src/module/catalogModuleGerritEntityProvider.test.ts @@ -14,14 +14,7 @@ * limitations under the License. */ -import { - coreServices, - createServiceFactory, -} from '@backstage/backend-plugin-api'; -import { - PluginTaskScheduler, - TaskScheduleDefinition, -} from '@backstage/backend-tasks'; +import { TaskScheduleDefinition } from '@backstage/backend-tasks'; import { mockServices, startTestBackend } from '@backstage/backend-test-utils'; import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha'; import { Duration } from 'luxon'; @@ -39,12 +32,12 @@ describe('catalogModuleGerritEntityProvider', () => { }, }; const runner = jest.fn(); - const scheduler = { - createScheduledTaskRunner: (schedule: TaskScheduleDefinition) => { + const scheduler = mockServices.scheduler.mock({ + createScheduledTaskRunner(schedule) { usedSchedule = schedule; - return runner; + return { run: runner }; }, - } as unknown as PluginTaskScheduler; + }); const config = { catalog: { @@ -79,11 +72,7 @@ describe('catalogModuleGerritEntityProvider', () => { catalogModuleGerritEntityProvider(), mockServices.rootConfig.factory({ data: config }), mockServices.logger.factory(), - createServiceFactory({ - service: coreServices.scheduler, - deps: {}, - factory: async () => scheduler, - }), + scheduler.factory, ], }); diff --git a/plugins/catalog-backend-module-github/src/module/catalogModuleGithubEntityProvider.test.ts b/plugins/catalog-backend-module-github/src/module/catalogModuleGithubEntityProvider.test.ts index 9e36966eec..171a641fc7 100644 --- a/plugins/catalog-backend-module-github/src/module/catalogModuleGithubEntityProvider.test.ts +++ b/plugins/catalog-backend-module-github/src/module/catalogModuleGithubEntityProvider.test.ts @@ -14,19 +14,12 @@ * limitations under the License. */ -import { - PluginTaskScheduler, - TaskScheduleDefinition, -} from '@backstage/backend-tasks'; +import { TaskScheduleDefinition } from '@backstage/backend-tasks'; import { mockServices, startTestBackend } from '@backstage/backend-test-utils'; import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha'; import { Duration } from 'luxon'; import { catalogModuleGithubEntityProvider } from './catalogModuleGithubEntityProvider'; import { GithubEntityProvider } from '../providers/GithubEntityProvider'; -import { - coreServices, - createServiceFactory, -} from '@backstage/backend-plugin-api'; describe('catalogModuleGithubEntityProvider', () => { it('should register provider at the catalog extension point', async () => { @@ -39,12 +32,12 @@ describe('catalogModuleGithubEntityProvider', () => { }, }; const runner = jest.fn(); - const scheduler = { - createScheduledTaskRunner: (schedule: TaskScheduleDefinition) => { + const scheduler = mockServices.scheduler.mock({ + createScheduledTaskRunner(schedule) { usedSchedule = schedule; - return runner; + return { run: runner }; }, - } as unknown as PluginTaskScheduler; + }); const config = { catalog: { @@ -65,11 +58,7 @@ describe('catalogModuleGithubEntityProvider', () => { features: [ catalogModuleGithubEntityProvider(), mockServices.rootConfig.factory({ data: config }), - createServiceFactory({ - service: coreServices.scheduler, - deps: {}, - factory: async () => scheduler, - }), + scheduler.factory, ], }); diff --git a/plugins/catalog-backend-module-gitlab/src/module/catalogModuleGitlabDiscoveryEntityProvider.test.ts b/plugins/catalog-backend-module-gitlab/src/module/catalogModuleGitlabDiscoveryEntityProvider.test.ts index 22759cafa0..46cfe403e8 100644 --- a/plugins/catalog-backend-module-gitlab/src/module/catalogModuleGitlabDiscoveryEntityProvider.test.ts +++ b/plugins/catalog-backend-module-gitlab/src/module/catalogModuleGitlabDiscoveryEntityProvider.test.ts @@ -14,14 +14,7 @@ * limitations under the License. */ -import { - coreServices, - createServiceFactory, -} from '@backstage/backend-plugin-api'; -import { - PluginTaskScheduler, - TaskScheduleDefinition, -} from '@backstage/backend-tasks'; +import { TaskScheduleDefinition } from '@backstage/backend-tasks'; import { mockServices, startTestBackend } from '@backstage/backend-test-utils'; import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha'; import { Duration } from 'luxon'; @@ -39,12 +32,12 @@ describe('catalogModuleGitlabDiscoveryEntityProvider', () => { }, }; const runner = jest.fn(); - const scheduler = { - createScheduledTaskRunner: (schedule: TaskScheduleDefinition) => { + const scheduler = mockServices.scheduler.mock({ + createScheduledTaskRunner(schedule) { usedSchedule = schedule; - return runner; + return { run: runner }; }, - } as unknown as PluginTaskScheduler; + }); const config = { integrations: { @@ -78,11 +71,7 @@ describe('catalogModuleGitlabDiscoveryEntityProvider', () => { catalogModuleGitlabDiscoveryEntityProvider(), mockServices.rootConfig.factory({ data: config }), mockServices.logger.factory(), - createServiceFactory({ - deps: {}, - service: coreServices.scheduler, - factory: async () => scheduler, - }), + scheduler.factory, ], }); diff --git a/plugins/catalog-backend-module-incremental-ingestion/src/module/catalogModuleIncrementalIngestionEntityProvider.test.ts b/plugins/catalog-backend-module-incremental-ingestion/src/module/catalogModuleIncrementalIngestionEntityProvider.test.ts index ed0c776fa8..7d76ddf480 100644 --- a/plugins/catalog-backend-module-incremental-ingestion/src/module/catalogModuleIncrementalIngestionEntityProvider.test.ts +++ b/plugins/catalog-backend-module-incremental-ingestion/src/module/catalogModuleIncrementalIngestionEntityProvider.test.ts @@ -14,12 +14,8 @@ * limitations under the License. */ -import { - coreServices, - createBackendModule, - createServiceFactory, -} from '@backstage/backend-plugin-api'; -import { startTestBackend } from '@backstage/backend-test-utils'; +import { createBackendModule } from '@backstage/backend-plugin-api'; +import { mockServices, startTestBackend } from '@backstage/backend-test-utils'; import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha'; import { IncrementalEntityProvider } from '../types'; import { @@ -40,18 +36,15 @@ describe('catalogModuleIncrementalIngestionEntityProvider', () => { }; const addEntityProvider = jest.fn(); - const httpRouterUse = jest.fn(); + + const httpRouterMock = mockServices.httpRouter.mock(); await startTestBackend({ extensionPoints: [ [catalogProcessingExtensionPoint, { addEntityProvider }], ], features: [ - createServiceFactory({ - service: coreServices.httpRouter, - deps: {}, - factory: () => ({ use: httpRouterUse }), - }), + httpRouterMock.factory, catalogModuleIncrementalIngestionEntityProvider(), createBackendModule({ pluginId: 'catalog', @@ -79,6 +72,6 @@ describe('catalogModuleIncrementalIngestionEntityProvider', () => { expect(addEntityProvider.mock.calls[0][0].getProviderName()).toBe( 'provider1', ); - expect(httpRouterUse).toHaveBeenCalledTimes(1); + expect(httpRouterMock.use).toHaveBeenCalledTimes(1); }); }); diff --git a/plugins/catalog-backend-module-msgraph/src/module/catalogModuleMicrosoftGraphOrgEntityProvider.test.ts b/plugins/catalog-backend-module-msgraph/src/module/catalogModuleMicrosoftGraphOrgEntityProvider.test.ts index 96fec41cbe..d36995b1c8 100644 --- a/plugins/catalog-backend-module-msgraph/src/module/catalogModuleMicrosoftGraphOrgEntityProvider.test.ts +++ b/plugins/catalog-backend-module-msgraph/src/module/catalogModuleMicrosoftGraphOrgEntityProvider.test.ts @@ -14,14 +14,7 @@ * limitations under the License. */ -import { - coreServices, - createServiceFactory, -} from '@backstage/backend-plugin-api'; -import { - PluginTaskScheduler, - TaskScheduleDefinition, -} from '@backstage/backend-tasks'; +import { TaskScheduleDefinition } from '@backstage/backend-tasks'; import { mockServices, startTestBackend } from '@backstage/backend-test-utils'; import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha'; import { Duration } from 'luxon'; @@ -39,12 +32,12 @@ describe('catalogModuleMicrosoftGraphOrgEntityProvider', () => { }, }; const runner = jest.fn(); - const scheduler = { - createScheduledTaskRunner: (schedule: TaskScheduleDefinition) => { + const scheduler = mockServices.scheduler.mock({ + createScheduledTaskRunner(schedule) { usedSchedule = schedule; - return runner; + return { run: runner }; }, - } as unknown as PluginTaskScheduler; + }); const config = { catalog: { @@ -70,11 +63,7 @@ describe('catalogModuleMicrosoftGraphOrgEntityProvider', () => { features: [ catalogModuleMicrosoftGraphOrgEntityProvider(), mockServices.rootConfig.factory({ data: config }), - createServiceFactory(() => ({ - deps: {}, - service: coreServices.scheduler, - factory: async () => scheduler, - })), + scheduler.factory, ], }); diff --git a/plugins/catalog-backend-module-puppetdb/src/module/catalogModulePuppetDbEntityProvider.test.ts b/plugins/catalog-backend-module-puppetdb/src/module/catalogModulePuppetDbEntityProvider.test.ts index 3ea54d8c8f..f931b2c741 100644 --- a/plugins/catalog-backend-module-puppetdb/src/module/catalogModulePuppetDbEntityProvider.test.ts +++ b/plugins/catalog-backend-module-puppetdb/src/module/catalogModulePuppetDbEntityProvider.test.ts @@ -14,14 +14,7 @@ * limitations under the License. */ -import { - coreServices, - createServiceFactory, -} from '@backstage/backend-plugin-api'; -import { - PluginTaskScheduler, - TaskScheduleDefinition, -} from '@backstage/backend-tasks'; +import { TaskScheduleDefinition } from '@backstage/backend-tasks'; import { mockServices, startTestBackend } from '@backstage/backend-test-utils'; import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha'; import { catalogModulePuppetDbEntityProvider } from './catalogModulePuppetDbEntityProvider'; @@ -38,12 +31,12 @@ describe('catalogModulePuppetDbEntityProvider', () => { }, }; const runner = jest.fn(); - const scheduler = { - createScheduledTaskRunner: (schedule: TaskScheduleDefinition) => { + const scheduler = mockServices.scheduler.mock({ + createScheduledTaskRunner(schedule) { usedSchedule = schedule; - return runner; + return { run: runner }; }, - } as unknown as PluginTaskScheduler; + }); const config = { catalog: { @@ -64,11 +57,7 @@ describe('catalogModulePuppetDbEntityProvider', () => { features: [ catalogModulePuppetDbEntityProvider(), mockServices.rootConfig.factory({ data: config }), - createServiceFactory(() => ({ - deps: {}, - service: coreServices.scheduler, - factory: async () => scheduler, - })), + scheduler.factory, ], }); diff --git a/plugins/events-backend-module-aws-sqs/src/service/eventsModuleAwsSqsConsumingEventPublisher.test.ts b/plugins/events-backend-module-aws-sqs/src/service/eventsModuleAwsSqsConsumingEventPublisher.test.ts index a76817c3c0..57e1831667 100644 --- a/plugins/events-backend-module-aws-sqs/src/service/eventsModuleAwsSqsConsumingEventPublisher.test.ts +++ b/plugins/events-backend-module-aws-sqs/src/service/eventsModuleAwsSqsConsumingEventPublisher.test.ts @@ -14,11 +14,6 @@ * limitations under the License. */ -import { - coreServices, - createServiceFactory, - SchedulerService, -} from '@backstage/backend-plugin-api'; import { mockServices, startTestBackend } from '@backstage/backend-test-utils'; import { eventsExtensionPoint } from '@backstage/plugin-events-node/alpha'; import { TestEventBroker } from '@backstage/plugin-events-backend-test-utils'; @@ -34,9 +29,7 @@ describe('eventsModuleAwsSqsConsumingEventPublisher', () => { }, }; - const scheduler = { - scheduleTask: jest.fn(), - } as unknown as SchedulerService; + const scheduler = mockServices.scheduler.mock(); await startTestBackend({ extensionPoints: [[eventsExtensionPoint, extensionPoint]], @@ -68,11 +61,7 @@ describe('eventsModuleAwsSqsConsumingEventPublisher', () => { }, }, }), - createServiceFactory({ - service: coreServices.scheduler, - deps: {}, - factory: () => scheduler, - }), + scheduler.factory, ], }); From 47782f4bfa5b2cb79f582542b3dff195880dbdbb Mon Sep 17 00:00:00 2001 From: Matthew Clarke Date: Thu, 17 Aug 2023 09:46:03 -0400 Subject: [PATCH 31/73] feat: Table initial loading (#19343) * feat: add initial loading state for Table Signed-off-by: Matthew Clarke * Please answer yes or no. feat: add loading state for Table component Signed-off-by: Matthew Clarke * chore: changeset Signed-off-by: Matthew Clarke * test: add test Signed-off-by: Matthew Clarke * docs: api reports Signed-off-by: Matthew Clarke --------- Signed-off-by: Matthew Clarke --- .changeset/strange-frogs-count.md | 5 +++ packages/core-components/api-report.md | 2 + .../src/components/Table/Table.stories.tsx | 37 +++++++++++++++++++ .../src/components/Table/Table.test.tsx | 5 +++ .../src/components/Table/Table.tsx | 27 +++++++++++++- 5 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 .changeset/strange-frogs-count.md diff --git a/.changeset/strange-frogs-count.md b/.changeset/strange-frogs-count.md new file mode 100644 index 0000000000..94fa6b9fb6 --- /dev/null +++ b/.changeset/strange-frogs-count.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-components': patch +--- + +Add loading indicator to Table diff --git a/packages/core-components/api-report.md b/packages/core-components/api-report.md index df34abdd03..cc9246c752 100644 --- a/packages/core-components/api-report.md +++ b/packages/core-components/api-report.md @@ -1356,6 +1356,8 @@ export interface TableProps // (undocumented) initialState?: TableState; // (undocumented) + isLoading?: boolean; + // (undocumented) onStateChange?: (state: TableState) => any; // (undocumented) subtitle?: string; diff --git a/packages/core-components/src/components/Table/Table.stories.tsx b/packages/core-components/src/components/Table/Table.stories.tsx index 807d58057d..b38941012c 100644 --- a/packages/core-components/src/components/Table/Table.stories.tsx +++ b/packages/core-components/src/components/Table/Table.stories.tsx @@ -89,6 +89,43 @@ export const DefaultTable = () => { ); }; +export const LoadingTable = () => { + const classes = useStyles(); + const columns: TableColumn[] = [ + { + title: 'Column 1', + field: 'col1', + highlight: true, + }, + { + title: 'Column 2', + field: 'col2', + }, + { + title: 'Numeric value', + field: 'number', + type: 'numeric', + }, + { + title: 'A Date', + field: 'date', + type: 'date', + }, + ]; + + return ( +
+ + + ); +}; + export const EmptyTable = () => { const classes = useStyles(); const columns: TableColumn[] = [ diff --git a/packages/core-components/src/components/Table/Table.test.tsx b/packages/core-components/src/components/Table/Table.test.tsx index ffdca26d98..43c8cfe41d 100644 --- a/packages/core-components/src/components/Table/Table.test.tsx +++ b/packages/core-components/src/components/Table/Table.test.tsx @@ -48,6 +48,11 @@ describe('
', () => { expect(rendered.getByText('second value, second row')).toBeInTheDocument(); }); + it('renders loading without exploding', async () => { + const rendered = await renderInTestApp(
); + expect(rendered.getByTestId('loading-indicator')).toBeInTheDocument(); + }); + describe('with style rows', () => { describe('with CSS Properties object', () => { const styledColumn2 = { diff --git a/packages/core-components/src/components/Table/Table.tsx b/packages/core-components/src/components/Table/Table.tsx index 5cea3dd6b6..9f2b04c214 100644 --- a/packages/core-components/src/components/Table/Table.tsx +++ b/packages/core-components/src/components/Table/Table.tsx @@ -53,6 +53,7 @@ import React, { import { SelectProps } from '../Select/Select'; import { Filter, Filters, SelectedFilters, Without } from './Filters'; +import CircularProgress from '@material-ui/core/CircularProgress'; // Material-table is not using the standard icons available in in material-ui. https://github.com/mbrn/material-table/issues/51 const tableIcons: Icons = { @@ -236,6 +237,7 @@ export interface TableProps filters?: TableFilter[]; initialState?: TableState; emptyContent?: ReactNode; + isLoading?: boolean; onStateChange?: (state: TableState) => any; } @@ -309,6 +311,7 @@ export function Table(props: TableProps) { emptyContent, onStateChange, components, + isLoading: isLoading, ...restProps } = props; const tableClasses = useTableStyles(); @@ -470,6 +473,28 @@ export function Table(props: TableProps) { const columnCount = columns.length; const Body = useCallback( bodyProps => { + if (isLoading) { + return ( + + + + + + ); + } + if (emptyContent && hasNoRows) { return ( @@ -482,7 +507,7 @@ export function Table(props: TableProps) { return ; }, - [hasNoRows, emptyContent, columnCount], + [hasNoRows, emptyContent, columnCount, isLoading], ); return ( From 1fbad39b2deeb156085052c7b675fc991b0a31ab Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 17 Aug 2023 16:50:45 +0200 Subject: [PATCH 32/73] backend-test-utils: introduce ServiceMock type to clean up external API Signed-off-by: Patrik Oldsberg --- packages/backend-test-utils/api-report.md | 286 +++--------------- .../src/next/services/index.ts | 2 +- .../src/next/services/mockServices.ts | 18 +- 3 files changed, 63 insertions(+), 243 deletions(-) diff --git a/packages/backend-test-utils/api-report.md b/packages/backend-test-utils/api-report.md index f87181f635..95f67da35f 100644 --- a/packages/backend-test-utils/api-report.md +++ b/packages/backend-test-utils/api-report.md @@ -5,50 +5,25 @@ ```ts /// -import { AuthorizePermissionRequest } from '@backstage/plugin-permission-common'; import { Backend } from '@backstage/backend-app-api'; import { BackendFeature } from '@backstage/backend-plugin-api'; -import { BackstageIdentityResponse } from '@backstage/plugin-auth-node'; import { CacheService } from '@backstage/backend-plugin-api'; -import { CacheServiceOptions } from '@backstage/backend-plugin-api'; -import { CacheServiceSetOptions } from '@backstage/backend-plugin-api'; import { DatabaseService } from '@backstage/backend-plugin-api'; -import { DefinitivePolicyDecision } from '@backstage/plugin-permission-common'; -import { EvaluatorRequestOptions } from '@backstage/plugin-permission-common'; import { ExtendedHttpServer } from '@backstage/backend-app-api'; import { ExtensionPoint } from '@backstage/backend-plugin-api'; -import { Handler } from 'express'; import { HttpRouterFactoryOptions } from '@backstage/backend-app-api'; import { HttpRouterService } from '@backstage/backend-plugin-api'; -import { IdentityApiGetIdentityRequest } from '@backstage/plugin-auth-node'; import { IdentityService } from '@backstage/backend-plugin-api'; import { JsonObject } from '@backstage/types'; -import { JsonValue } from '@backstage/types'; import { Knex } from 'knex'; import { LifecycleService } from '@backstage/backend-plugin-api'; -import { LifecycleServiceShutdownHook } from '@backstage/backend-plugin-api'; -import { LifecycleServiceShutdownOptions } from '@backstage/backend-plugin-api'; -import { LifecycleServiceStartupHook } from '@backstage/backend-plugin-api'; -import { LifecycleServiceStartupOptions } from '@backstage/backend-plugin-api'; import { LoggerService } from '@backstage/backend-plugin-api'; import { PermissionsService } from '@backstage/backend-plugin-api'; -import { PolicyDecision } from '@backstage/plugin-permission-common'; -import { QueryPermissionRequest } from '@backstage/plugin-permission-common'; -import { ReadTreeOptions } from '@backstage/backend-plugin-api'; -import { ReadTreeResponse } from '@backstage/backend-plugin-api'; -import { ReadUrlOptions } from '@backstage/backend-plugin-api'; -import { ReadUrlResponse } from '@backstage/backend-plugin-api'; import { RootConfigService } from '@backstage/backend-plugin-api'; import { RootLifecycleService } from '@backstage/backend-plugin-api'; import { RootLoggerService } from '@backstage/backend-plugin-api'; import { SchedulerService } from '@backstage/backend-plugin-api'; -import { SearchOptions } from '@backstage/backend-plugin-api'; -import { SearchResponse } from '@backstage/backend-plugin-api'; import { ServiceFactory } from '@backstage/backend-plugin-api'; -import { TaskDescriptor } from '@backstage/backend-tasks'; -import { TaskInvocationDefinition } from '@backstage/backend-tasks'; -import { TaskRunner } from '@backstage/backend-tasks'; -import { TaskScheduleDefinition } from '@backstage/backend-tasks'; import { TokenManagerService } from '@backstage/backend-plugin-api'; import { UrlReaderService } from '@backstage/backend-plugin-api'; @@ -62,46 +37,18 @@ export namespace mockServices { const // (undocumented) factory: () => ServiceFactory; const // (undocumented) - mock: (partialImpl?: Partial | undefined) => { - factory: ServiceFactory; - } & { - get: jest.MockInstance< - Promise, - [key: string], - unknown - >; - set: jest.MockInstance< - Promise, - [ - key: string, - value: JsonValue, - options?: CacheServiceSetOptions | undefined, - ], - unknown - >; - delete: jest.MockInstance, [key: string], unknown>; - withOptions: jest.MockInstance< - CacheService, - [options: CacheServiceOptions], - unknown - >; - } & CacheService; + mock: ( + partialImpl?: Partial | undefined, + ) => ServiceMock; } // (undocumented) export namespace database { const // (undocumented) factory: () => ServiceFactory; const // (undocumented) - mock: (partialImpl?: Partial | undefined) => { - factory: ServiceFactory; - } & { - getClient: jest.MockInstance>, [], unknown>; - migrations?: - | { - skip?: boolean | undefined; - } - | undefined; - } & DatabaseService; + mock: ( + partialImpl?: Partial | undefined, + ) => ServiceMock; } // (undocumented) export namespace httpRouter { @@ -110,11 +57,9 @@ export namespace mockServices { options?: HttpRouterFactoryOptions | undefined, ) => ServiceFactory; const // (undocumented) - mock: (partialImpl?: Partial | undefined) => { - factory: ServiceFactory; - } & { - use: jest.MockInstance; - } & HttpRouterService; + mock: ( + partialImpl?: Partial | undefined, + ) => ServiceMock; } // (undocumented) export function identity(): IdentityService; @@ -123,98 +68,36 @@ export namespace mockServices { const // (undocumented) factory: () => ServiceFactory; const // (undocumented) - mock: (partialImpl?: Partial | undefined) => { - factory: ServiceFactory; - } & { - getIdentity: jest.MockInstance< - Promise, - [options: IdentityApiGetIdentityRequest], - unknown - >; - } & IdentityService; + mock: ( + partialImpl?: Partial | undefined, + ) => ServiceMock; } // (undocumented) export namespace lifecycle { const // (undocumented) factory: () => ServiceFactory; const // (undocumented) - mock: (partialImpl?: Partial | undefined) => { - factory: ServiceFactory; - } & { - addStartupHook: jest.MockInstance< - void, - [ - hook: LifecycleServiceStartupHook, - options?: LifecycleServiceStartupOptions | undefined, - ], - unknown - >; - addShutdownHook: jest.MockInstance< - void, - [ - hook: LifecycleServiceShutdownHook, - options?: LifecycleServiceShutdownOptions | undefined, - ], - unknown - >; - } & LifecycleService; + mock: ( + partialImpl?: Partial | undefined, + ) => ServiceMock; } // (undocumented) export namespace logger { const // (undocumented) factory: () => ServiceFactory; const // (undocumented) - mock: (partialImpl?: Partial | undefined) => { - factory: ServiceFactory; - } & { - error: jest.MockInstance< - void, - [message: string, meta?: Error | JsonObject | undefined], - unknown - >; - warn: jest.MockInstance< - void, - [message: string, meta?: Error | JsonObject | undefined], - unknown - >; - info: jest.MockInstance< - void, - [message: string, meta?: Error | JsonObject | undefined], - unknown - >; - debug: jest.MockInstance< - void, - [message: string, meta?: Error | JsonObject | undefined], - unknown - >; - child: jest.MockInstance; - } & LoggerService; + mock: ( + partialImpl?: Partial | undefined, + ) => ServiceMock; } // (undocumented) export namespace permissions { const // (undocumented) factory: () => ServiceFactory; const // (undocumented) - mock: (partialImpl?: Partial | undefined) => { - factory: ServiceFactory; - } & { - authorize: jest.MockInstance< - Promise, - [ - requests: AuthorizePermissionRequest[], - options?: EvaluatorRequestOptions | undefined, - ], - unknown - >; - authorizeConditional: jest.MockInstance< - Promise, - [ - requests: QueryPermissionRequest[], - options?: EvaluatorRequestOptions | undefined, - ], - unknown - >; - } & PermissionsService; + mock: ( + partialImpl?: Partial | undefined, + ) => ServiceMock; } // (undocumented) export function rootConfig(options?: rootConfig.Options): RootConfigService; @@ -234,26 +117,9 @@ export namespace mockServices { const // (undocumented) factory: () => ServiceFactory; const // (undocumented) - mock: (partialImpl?: Partial | undefined) => { - factory: ServiceFactory; - } & { - addStartupHook: jest.MockInstance< - void, - [ - hook: LifecycleServiceStartupHook, - options?: LifecycleServiceStartupOptions | undefined, - ], - unknown - >; - addShutdownHook: jest.MockInstance< - void, - [ - hook: LifecycleServiceShutdownHook, - options?: LifecycleServiceShutdownOptions | undefined, - ], - unknown - >; - } & RootLifecycleService; + mock: ( + partialImpl?: Partial | undefined, + ) => ServiceMock; } // (undocumented) export function rootLogger(options?: rootLogger.Options): LoggerService; @@ -268,57 +134,18 @@ export namespace mockServices { options?: Options | undefined, ) => ServiceFactory; const // (undocumented) - mock: (partialImpl?: Partial | undefined) => { - factory: ServiceFactory; - } & { - error: jest.MockInstance< - void, - [message: string, meta?: Error | JsonObject | undefined], - unknown - >; - warn: jest.MockInstance< - void, - [message: string, meta?: Error | JsonObject | undefined], - unknown - >; - info: jest.MockInstance< - void, - [message: string, meta?: Error | JsonObject | undefined], - unknown - >; - debug: jest.MockInstance< - void, - [message: string, meta?: Error | JsonObject | undefined], - unknown - >; - child: jest.MockInstance; - } & RootLoggerService; + mock: ( + partialImpl?: Partial | undefined, + ) => ServiceMock; } // (undocumented) export namespace scheduler { const // (undocumented) factory: () => ServiceFactory; const // (undocumented) - mock: (partialImpl?: Partial | undefined) => { - factory: ServiceFactory; - } & { - triggerTask: jest.MockInstance, [id: string], unknown>; - scheduleTask: jest.MockInstance< - Promise, - [task: TaskScheduleDefinition & TaskInvocationDefinition], - unknown - >; - createScheduledTaskRunner: jest.MockInstance< - TaskRunner, - [schedule: TaskScheduleDefinition], - unknown - >; - getScheduledTasks: jest.MockInstance< - Promise, - [], - unknown - >; - } & SchedulerService; + mock: ( + partialImpl?: Partial | undefined, + ) => ServiceMock; } // (undocumented) export function tokenManager(): TokenManagerService; @@ -327,50 +154,33 @@ export namespace mockServices { const // (undocumented) factory: () => ServiceFactory; const // (undocumented) - mock: (partialImpl?: Partial | undefined) => { - factory: ServiceFactory; - } & { - getToken: jest.MockInstance< - Promise<{ - token: string; - }>, - [], - unknown - >; - authenticate: jest.MockInstance< - Promise, - [token: string], - unknown - >; - } & TokenManagerService; + mock: ( + partialImpl?: Partial | undefined, + ) => ServiceMock; } // (undocumented) export namespace urlReader { const // (undocumented) factory: () => ServiceFactory; const // (undocumented) - mock: (partialImpl?: Partial | undefined) => { - factory: ServiceFactory; - } & { - readUrl: jest.MockInstance< - Promise, - [url: string, options?: ReadUrlOptions | undefined], - unknown - >; - readTree: jest.MockInstance< - Promise, - [url: string, options?: ReadTreeOptions | undefined], - unknown - >; - search: jest.MockInstance< - Promise, - [url: string, options?: SearchOptions | undefined], - unknown - >; - } & UrlReaderService; + mock: ( + partialImpl?: Partial | undefined, + ) => ServiceMock; } } +// @public (undocumented) +export type ServiceMock = { + factory: ServiceFactory; +} & { + [Key in keyof TService]: TService[Key] extends ( + this: infer This, + ...args: infer Args + ) => infer Return + ? TService[Key] & jest.MockInstance + : TService[Key]; +}; + // @public export function setupRequestMockHandlers(worker: { listen: (t: any) => void; diff --git a/packages/backend-test-utils/src/next/services/index.ts b/packages/backend-test-utils/src/next/services/index.ts index f562150efa..97a22567fd 100644 --- a/packages/backend-test-utils/src/next/services/index.ts +++ b/packages/backend-test-utils/src/next/services/index.ts @@ -13,4 +13,4 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export { mockServices } from './mockServices'; +export { mockServices, type ServiceMock } from './mockServices'; diff --git a/packages/backend-test-utils/src/next/services/mockServices.ts b/packages/backend-test-utils/src/next/services/mockServices.ts index d0bb79dd2e..3edc3e0894 100644 --- a/packages/backend-test-utils/src/next/services/mockServices.ts +++ b/packages/backend-test-utils/src/next/services/mockServices.ts @@ -58,13 +58,23 @@ function simpleFactory< })) as (...options: TOptions) => ServiceFactory; } +/** @public */ +export type ServiceMock = { + factory: ServiceFactory; +} & { + [Key in keyof TService]: TService[Key] extends ( + this: infer This, + ...args: infer Args + ) => infer Return + ? TService[Key] & jest.MockInstance + : TService[Key]; +}; + /** @internal */ function simpleMock( ref: ServiceRef, mockFactory: () => jest.Mocked, -): ( - partialImpl?: Partial, -) => { factory: ServiceFactory } & jest.Mocked { +): (partialImpl?: Partial) => ServiceMock { return partialImpl => { const mock = mockFactory(); if (partialImpl) { @@ -82,7 +92,7 @@ function simpleMock( deps: {}, factory: () => mock, })(), - }); + }) as ServiceMock; }; } From fb57a4694fc6f2efbba4baff22bc11690fdad738 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 17 Aug 2023 17:37:21 +0200 Subject: [PATCH 33/73] scaffolder-backend: fixed alpha module plugin and module ID Signed-off-by: Patrik Oldsberg --- .changeset/lazy-rice-rule.md | 5 +++++ .../src/modules/catalogModuleTemplateKind.ts | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 .changeset/lazy-rice-rule.md diff --git a/.changeset/lazy-rice-rule.md b/.changeset/lazy-rice-rule.md new file mode 100644 index 0000000000..1c3a3c3250 --- /dev/null +++ b/.changeset/lazy-rice-rule.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend': patch +--- + +Fixed the plugin and module ID of the alpha `catalogModuleTemplateKind` export. diff --git a/plugins/scaffolder-backend/src/modules/catalogModuleTemplateKind.ts b/plugins/scaffolder-backend/src/modules/catalogModuleTemplateKind.ts index 3359bd1dba..81d3dc3e93 100644 --- a/plugins/scaffolder-backend/src/modules/catalogModuleTemplateKind.ts +++ b/plugins/scaffolder-backend/src/modules/catalogModuleTemplateKind.ts @@ -24,8 +24,8 @@ import { ScaffolderEntitiesProcessor } from '../processor'; * @alpha */ export const catalogModuleTemplateKind = createBackendModule({ - moduleId: 'scaffolder', - pluginId: 'templateKind', + moduleId: 'templateKind', + pluginId: 'catalog', register(env) { env.registerInit({ deps: { From b2de501bda312d65c055976562d877bcf3921a45 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 17 Aug 2023 17:54:26 +0200 Subject: [PATCH 34/73] linguist-backend: fix config value being required Signed-off-by: Patrik Oldsberg --- .changeset/new-sheep-cover.md | 5 +++++ plugins/linguist-backend/src/service/router.ts | 5 ++--- 2 files changed, 7 insertions(+), 3 deletions(-) create mode 100644 .changeset/new-sheep-cover.md diff --git a/.changeset/new-sheep-cover.md b/.changeset/new-sheep-cover.md new file mode 100644 index 0000000000..390de1a9b3 --- /dev/null +++ b/.changeset/new-sheep-cover.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-linguist-backend': patch +--- + +When creating the router using `createRouterFromConfig` or using the plugin for the new backend system the `linguist.useSourceLocation` configuration is now optional. diff --git a/plugins/linguist-backend/src/service/router.ts b/plugins/linguist-backend/src/service/router.ts index 02ff05f398..d29943c38b 100644 --- a/plugins/linguist-backend/src/service/router.ts +++ b/plugins/linguist-backend/src/service/router.ts @@ -150,9 +150,8 @@ export async function createRouterFromConfig(routerOptions: RouterOptions) { ); } pluginOptions.batchSize = config.getOptionalNumber('linguist.batchSize'); - pluginOptions.useSourceLocation = config.getBoolean( - 'linguist.useSourceLocation', - ); + pluginOptions.useSourceLocation = + config.getOptionalBoolean('linguist.useSourceLocation') ?? false; pluginOptions.age = config.getOptionalConfig('linguist.age') as | HumanDuration | undefined; From 35bba616b7f4be8aeb7822c2dd36136cd7f0eb8d Mon Sep 17 00:00:00 2001 From: Vincenzo Scamporlino Date: Thu, 17 Aug 2023 15:37:08 +0200 Subject: [PATCH 35/73] catalog: EntitySwitch render children when entity is not found Signed-off-by: Vincenzo Scamporlino --- .../EntitySwitch/EntitySwitch.test.tsx | 46 ++++++++++++++++++- .../components/EntitySwitch/EntitySwitch.tsx | 15 ++++-- 2 files changed, 56 insertions(+), 5 deletions(-) diff --git a/plugins/catalog/src/components/EntitySwitch/EntitySwitch.test.tsx b/plugins/catalog/src/components/EntitySwitch/EntitySwitch.test.tsx index c93922e938..d9998b0ca5 100644 --- a/plugins/catalog/src/components/EntitySwitch/EntitySwitch.test.tsx +++ b/plugins/catalog/src/components/EntitySwitch/EntitySwitch.test.tsx @@ -59,6 +59,50 @@ describe('EntitySwitch', () => { expect(screen.queryByText('C')).not.toBeInTheDocument(); }); + it('should render the default case if entity is not found', () => { + const content = ( + + + + + + ); + + render( + + + {content} + + , + ); + + expect(screen.queryByText('A')).not.toBeInTheDocument(); + expect(screen.queryByText('B')).not.toBeInTheDocument(); + expect(screen.queryByText('C')).toBeInTheDocument(); + }); + + it(`shouldn't render any children if entity is loading and no entity exists in the context`, () => { + const content = ( + + + + + + ); + + render( + + + {content} + + , + ); + + expect(screen.queryByText('A')).not.toBeInTheDocument(); + expect(screen.queryByText('B')).not.toBeInTheDocument(); + expect(screen.queryByText('C')).not.toBeInTheDocument(); + }); + it('should render the fallback if no cases are matching', () => { const content = ( @@ -170,7 +214,7 @@ describe('EntitySwitch', () => { expect(screen.queryByText('A')).not.toBeInTheDocument(); expect(screen.queryByText('B')).not.toBeInTheDocument(); - expect(screen.queryByText('C')).not.toBeInTheDocument(); + expect(screen.queryByText('C')).toBeInTheDocument(); }); it('should switch child when filters switch', () => { diff --git a/plugins/catalog/src/components/EntitySwitch/EntitySwitch.tsx b/plugins/catalog/src/components/EntitySwitch/EntitySwitch.tsx index b12495052e..9eab743308 100644 --- a/plugins/catalog/src/components/EntitySwitch/EntitySwitch.tsx +++ b/plugins/catalog/src/components/EntitySwitch/EntitySwitch.tsx @@ -64,7 +64,7 @@ export interface EntitySwitchProps { /** @public */ export const EntitySwitch = (props: EntitySwitchProps) => { - const { entity } = useAsyncEntity(); + const { entity, loading } = useAsyncEntity(); const apis = useApiHolder(); const results = useElementFilter( @@ -77,14 +77,21 @@ export const EntitySwitch = (props: EntitySwitchProps) => { }) .getElements() .flatMap((element: ReactElement) => { - // If the entity is missing or there is an error, render nothing - if (!entity) { + if (loading && !entity) { return []; } const { if: condition, children: elementsChildren } = element.props as EntitySwitchCase; + if (!entity) { + return [ + { + if: condition === undefined, + children: elementsChildren, + }, + ]; + } return [ { if: condition?.(entity, { apis }), @@ -92,7 +99,7 @@ export const EntitySwitch = (props: EntitySwitchProps) => { }, ]; }), - [apis, entity], + [apis, entity, loading], ); const hasAsyncCases = results.some( From 163a41035e429282bed6fa645cb213d2102133d3 Mon Sep 17 00:00:00 2001 From: Vincenzo Scamporlino Date: Thu, 17 Aug 2023 21:26:30 +0200 Subject: [PATCH 36/73] add changeset Signed-off-by: Vincenzo Scamporlino --- .changeset/dull-tables-joke.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/dull-tables-joke.md diff --git a/.changeset/dull-tables-joke.md b/.changeset/dull-tables-joke.md new file mode 100644 index 0000000000..e987377023 --- /dev/null +++ b/.changeset/dull-tables-joke.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog': patch +--- + +Fixed an issue where `EntitySwitch` was preventing the display of entity errors. From 79efb2be1d82218f343ed4dd484b4139956979f1 Mon Sep 17 00:00:00 2001 From: Anton Ganhammar Date: Thu, 17 Aug 2023 21:31:54 +0200 Subject: [PATCH 37/73] feat: include authorization token if set in code-coverage plugin Signed-off-by: Anton Ganhammar --- plugins/code-coverage/src/api.ts | 28 +++++++++++++++++++++------- plugins/code-coverage/src/plugin.ts | 6 ++++-- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/plugins/code-coverage/src/api.ts b/plugins/code-coverage/src/api.ts index 081f1c7999..34e55b5cba 100644 --- a/plugins/code-coverage/src/api.ts +++ b/plugins/code-coverage/src/api.ts @@ -20,10 +20,13 @@ import { } from '@backstage/catalog-model'; import { ResponseError } from '@backstage/errors'; import { JsonCodeCoverage, JsonCoverageHistory } from './types'; -import { createApiRef, DiscoveryApi } from '@backstage/core-plugin-api'; +import { + createApiRef, + DiscoveryApi, + IdentityApi, +} from '@backstage/core-plugin-api'; export type CodeCoverageApi = { - discovery: DiscoveryApi; getCoverageForEntity: ( entity: CompoundEntityRef, ) => Promise; @@ -42,18 +45,29 @@ export const codeCoverageApiRef = createApiRef({ }); export class CodeCoverageRestApi implements CodeCoverageApi { - url: string = ''; + private readonly discoveryApi: DiscoveryApi; + private readonly identityApi: IdentityApi; - constructor(public discovery: DiscoveryApi) {} + private url: string = ''; + + public constructor(options: { + discoveryApi: DiscoveryApi; + identityApi: IdentityApi; + }) { + this.discoveryApi = options.discoveryApi; + this.identityApi = options.identityApi; + } private async fetch( path: string, - init?: RequestInit, ): Promise { if (!this.url) { - this.url = await this.discovery.getBaseUrl('code-coverage'); + this.url = await this.discoveryApi.getBaseUrl('code-coverage'); } - const resp = await fetch(`${this.url}${path}`, init); + const { token } = await this.identityApi.getCredentials(); + const resp = await fetch(`${this.url}${path}`, { + headers: token ? { Authorization: `Bearer ${token}` } : {}, + }); if (!resp.ok) { throw await ResponseError.fromResponse(resp); } diff --git a/plugins/code-coverage/src/plugin.ts b/plugins/code-coverage/src/plugin.ts index f137e9d488..22b59fd50a 100644 --- a/plugins/code-coverage/src/plugin.ts +++ b/plugins/code-coverage/src/plugin.ts @@ -21,6 +21,7 @@ import { createPlugin, createRoutableExtension, discoveryApiRef, + identityApiRef, } from '@backstage/core-plugin-api'; /** @@ -34,8 +35,9 @@ export const codeCoveragePlugin = createPlugin({ apis: [ createApiFactory({ api: codeCoverageApiRef, - deps: { discoveryApi: discoveryApiRef }, - factory: ({ discoveryApi }) => new CodeCoverageRestApi(discoveryApi), + deps: { discoveryApi: discoveryApiRef, identityApi: identityApiRef }, + factory: ({ discoveryApi, identityApi }) => + new CodeCoverageRestApi({ discoveryApi, identityApi }), }), ], }); From 1d8f4f0a7486872ec56d2e40a12631b1943417f4 Mon Sep 17 00:00:00 2001 From: Anton Ganhammar Date: Thu, 17 Aug 2023 21:45:58 +0200 Subject: [PATCH 38/73] feat: add changeset Signed-off-by: Anton Ganhammar --- .changeset/nice-forks-remain.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/nice-forks-remain.md diff --git a/.changeset/nice-forks-remain.md b/.changeset/nice-forks-remain.md new file mode 100644 index 0000000000..1545c88745 --- /dev/null +++ b/.changeset/nice-forks-remain.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-code-coverage': patch +--- + +Include authorization token (if one exists) when fetching code-coverage data From 850ca8eb106b24a834f73fab5073ab3d65506395 Mon Sep 17 00:00:00 2001 From: Anton Ganhammar Date: Fri, 18 Aug 2023 07:07:39 +0200 Subject: [PATCH 39/73] fix: use fetchapi to automatically handle authentication Signed-off-by: Anton Ganhammar --- .changeset/nice-forks-remain.md | 2 +- plugins/code-coverage/src/api.ts | 13 +++++-------- plugins/code-coverage/src/plugin.ts | 8 ++++---- 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/.changeset/nice-forks-remain.md b/.changeset/nice-forks-remain.md index 1545c88745..6d833ff283 100644 --- a/.changeset/nice-forks-remain.md +++ b/.changeset/nice-forks-remain.md @@ -2,4 +2,4 @@ '@backstage/plugin-code-coverage': patch --- -Include authorization token (if one exists) when fetching code-coverage data +Use fetchApi to ensure authorization is used when fetching code-coverage data diff --git a/plugins/code-coverage/src/api.ts b/plugins/code-coverage/src/api.ts index 34e55b5cba..9947891006 100644 --- a/plugins/code-coverage/src/api.ts +++ b/plugins/code-coverage/src/api.ts @@ -23,7 +23,7 @@ import { JsonCodeCoverage, JsonCoverageHistory } from './types'; import { createApiRef, DiscoveryApi, - IdentityApi, + FetchApi, } from '@backstage/core-plugin-api'; export type CodeCoverageApi = { @@ -46,16 +46,16 @@ export const codeCoverageApiRef = createApiRef({ export class CodeCoverageRestApi implements CodeCoverageApi { private readonly discoveryApi: DiscoveryApi; - private readonly identityApi: IdentityApi; + private readonly fetchApi: FetchApi; private url: string = ''; public constructor(options: { discoveryApi: DiscoveryApi; - identityApi: IdentityApi; + fetchApi: FetchApi; }) { this.discoveryApi = options.discoveryApi; - this.identityApi = options.identityApi; + this.fetchApi = options.fetchApi; } private async fetch( @@ -64,10 +64,7 @@ export class CodeCoverageRestApi implements CodeCoverageApi { if (!this.url) { this.url = await this.discoveryApi.getBaseUrl('code-coverage'); } - const { token } = await this.identityApi.getCredentials(); - const resp = await fetch(`${this.url}${path}`, { - headers: token ? { Authorization: `Bearer ${token}` } : {}, - }); + const resp = await this.fetchApi.fetch(`${this.url}${path}`); if (!resp.ok) { throw await ResponseError.fromResponse(resp); } diff --git a/plugins/code-coverage/src/plugin.ts b/plugins/code-coverage/src/plugin.ts index 22b59fd50a..391595f142 100644 --- a/plugins/code-coverage/src/plugin.ts +++ b/plugins/code-coverage/src/plugin.ts @@ -21,7 +21,7 @@ import { createPlugin, createRoutableExtension, discoveryApiRef, - identityApiRef, + fetchApiRef, } from '@backstage/core-plugin-api'; /** @@ -35,9 +35,9 @@ export const codeCoveragePlugin = createPlugin({ apis: [ createApiFactory({ api: codeCoverageApiRef, - deps: { discoveryApi: discoveryApiRef, identityApi: identityApiRef }, - factory: ({ discoveryApi, identityApi }) => - new CodeCoverageRestApi({ discoveryApi, identityApi }), + deps: { discoveryApi: discoveryApiRef, fetchApi: fetchApiRef }, + factory: ({ discoveryApi, fetchApi }) => + new CodeCoverageRestApi({ discoveryApi, fetchApi }), }), ], }); From 089786786840b6b8196b09c5fae3c28045351258 Mon Sep 17 00:00:00 2001 From: Morgan Bentell Date: Fri, 18 Aug 2023 11:19:47 +0200 Subject: [PATCH 40/73] add protean team members to techdocs-maintainers and organization Signed-off-by: Morgan Bentell --- OWNERS.md | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/OWNERS.md b/OWNERS.md index 66575e8e35..193c4f000f 100644 --- a/OWNERS.md +++ b/OWNERS.md @@ -90,10 +90,15 @@ Team: @backstage/techdocs-maintainers Scope: The TechDocs plugin and related tooling -| Name | Organization | Team | GitHub | Discord | -| ------------------------ | ------------ | ------------ | ------------------------------------------------ | ------------------ | -| Morgan Bentell | Spotify | Pulp Fiction | [agentbellnorm](http://github.com/agentbellnorm) | morganbentell#9030 | -| Raghunandan Balachandran | Spotify | Pulp Fiction | [soapraj](http://github.com/soapraj) | raghunandanb#1114 | +| Name | Organization | Team | GitHub | Discord | +| ------------------------ | ------------ | ------- | ------------------------------------------------- | ------------------- | +| Alex Lorenzi | Spotify | ProTean | [AlexLorenzi](https://github.com/AlexLorenzi) | `alexlorenzi` | +| Bond Yan | Spotify | ProTean | [byan1197](https://github.com/byan1197) | `bondify` | +| Jackson Chen | Spotify | ProTean | [PeaWarrior](https://github.com/PeaWarrior) | `jacksonc#3322` | +| John Philip | Spotify | ProTean | [johnphilip283](https://github.com/johnphilip283) | - | +| Morgan Bentell | Spotify | ProTean | [agentbellnorm](http://github.com/agentbellnorm) | `morganbentell` | +| Raghunandan Balachandran | Spotify | BUX | [soapraj](http://github.com/soapraj) | `raghunandanb#1114` | +| Squidney | Spotify | ProTean | [squid-ney](https://github.com/squid-ney) | - | ## Incubating Project Areas @@ -128,6 +133,7 @@ Scope: Tooling for frontend and backend schema-first OpenAPI development. | Aramis Sennyey | | [sennyeya](https://github.com/sennyeya) | `Aramis#7984` | | Brian Fletcher | Roadie.io | [punkle](https://github.com/punkle) | `Brian Fletcher#7051` | | Carlos Esteban Lopez Jaramillo | VMWare | [luchillo17](https://github.com/luchillo17) | `luchillo17#8777` | +| Daniel Lochrie | Spotify | [dlochrie](https://github.com/dlochrie) | - | | David Tuite | Roadie.io | [dtuite](https://github.com/dtuite) | `David Tuite (roadie.io)#1010` | | Himanshu Mishra | Harness.io | [OrkoHunter](https://github.com/OrkoHunter) | `OrkoHunter#1520` | | Irma Solakovic | Roadie.io | [Irma12](https://github.com/Irma12) | `Irma#7629` | @@ -139,6 +145,7 @@ Scope: Tooling for frontend and backend schema-first OpenAPI development. | Patrick Jungermann | Bonial International GmbH | [pjungermann](https://github.com/pjungermann) | `pjungermann#6933` | | Phil Kuang | FactSet Research Systems | [kuangp](https://github.com/kuangp) | `pkuang#3202` | | Taras Mankovski | Frontside | [taras](https://github.com/taras) | `tarasm#1256` | +| Vojta Burian | Spotify | [sankaritan](https://github.com/sankaritan) | `vojtabu` | ## Emeritus Core Maintainers From 78105bc7349cdad2a9ba21ac80adddb5902b6f98 Mon Sep 17 00:00:00 2001 From: blam Date: Fri, 18 Aug 2023 11:39:11 +0200 Subject: [PATCH 41/73] feat: added expedia part 2 blog Signed-off-by: blam --- ...08-17-expedia-proof-of-value-metrics-2.mdx | 206 ++++++++++++++++++ microsite/blog/assets/2023-08-17/header.png | Bin 0 -> 147502 bytes microsite/blog/assets/2023-08-17/table.png | Bin 0 -> 105318 bytes 3 files changed, 206 insertions(+) create mode 100644 microsite/blog/2023-08-17-expedia-proof-of-value-metrics-2.mdx create mode 100644 microsite/blog/assets/2023-08-17/header.png create mode 100644 microsite/blog/assets/2023-08-17/table.png diff --git a/microsite/blog/2023-08-17-expedia-proof-of-value-metrics-2.mdx b/microsite/blog/2023-08-17-expedia-proof-of-value-metrics-2.mdx new file mode 100644 index 0000000000..8534225953 --- /dev/null +++ b/microsite/blog/2023-08-17-expedia-proof-of-value-metrics-2.mdx @@ -0,0 +1,206 @@ +--- +# prettier-ignore +title: "Expedia Group shares Backstage proof of value metrics 2.0" +author: Guillermo Manzo, Expedia Group +authorURL: https://www.linkedin.com/in/guillermomanzo +--- + +![backstage header](assets/2023-08-17/header.png) + +_Editor's Note: In this post, Expedia Group provides a follow-up to their initial Q4 2021 [post on how they measure Backstage proof of value ](https://backstage.spotify.com/blog/measuring-backstage-proof-of-value-at-expedia/). +We're grateful to the Expedia Group team for sharing their processes, revised proof of value metrics, and adaptations to their approach over time in hopes of providing a successful framework for the rest of the Backstage community._ + +[Expedia Group's](https://expediagroup.com/home/default.aspx) mission is to power global travel for everyone, everywhere. +This vision is made possible through Expedia Group's massive platform, which connects 168 million loyalty members, 50 thousand B2B partners, 3 million properties and 500 airlines, car rentals and cruise lines across the globe. In short, the scale of our platform is enormous, which means that we need to scale our engineering capabilities as well so we can continue to provide seamless experiences to our travelers and partners. + +{/* truncate */} + +In August 2020, we adopted Backstage to enhance our foundational platform capabilities and reduce developer friction in the process. Its framework proved scalable for us and as EG's platform evolved, so did our application of Backstage. Since our [initial share about our Backstage deployment](https://backstage.spotify.com/blog/measuring-backstage-proof-of-value-at-expedia/), we've continued to follow our process of: + +- Syncing Expedia Group's internal Developer Journey phases by key DevOps processes and Software Delivery Life Cycle (SDLC) milestones (POC, Alpha, Beta, etc). +- Identifying Developer Jobs to be Done (JTBD) by our Internal Developer Journey phases +- Aligning developer JTBD's to proof of value (PoV) metrics. + +In the diagram below, you can see how we distilled these processes into Backstage PoV metrics. + +![backstage pov metrics](assets/2023-08-17/table.png) + +To ground ourselves in the evolving developer and Backstage landscape at Expedia Group, we constantly ask ourselves how we can continue to show the value of Backstage to our customers and the Developer Community? To fully answer this question, we adapted our initial proof of value metrics to reinforce our alignment to the current landscape of the Expedia Group developer journey. + +## Expedia Group proof of value metrics 2.0 + +We are excited to share our PoV metrics because it affirms our investment in Backstage for Expedia Group's Backstage users and provides a compelling metrics-based answer on why more organizations should consider adopting it. + +As our Backstage application matured, we updated our PoV metrics and aligned our 2023 roadmap to reflect these changes. Below, we highlight key wins from 2022 and outline our long-term vision for each metric. + +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PoV MetricDescription2022 Key Win(s)Long-Term Vision
"Ship on Day One" / onboarding metrics +

+ A metric used to determine an engineer's readiness to develop at EG + during their onboarding process. +

+

+ It measures the time from first commit to deploying code in + production, using a "Hello World Template" +

+
+
    +
  • + 850+ engineers went through the “Ship on Day One” Bootcamp when + first joining Expedia Group +
  • +
  • + We had a success rate of ~95% of engineers completing bootcamp on + first try +
  • +
  • 7,000+ components created or onboarded
  • +
  • 4-min average per app creation/onboarding
  • +
+
+
    +
  • + Develop full onboarding curriculum coverage for all critical + capabilities offered within EG - Example: performance and quality + management, pipeline management, etc. +
  • +
  • + Create an end-to-end guided tour of the EG Developer Journey w/ + functional training +
  • +
+
+ Reduce context switching through integration with core EG capabilities + + Through plugins, tool integration, reduces context-switching as + engineers will not need to toggle between multiple tools + +
    +
  • + 15%+ of internal developer tools are integrated within Backstage, + reducing the amount of context-switching needed +
  • +
  • + 4000+ unique users using Backstage for ~20 min on average a day. +
  • +
+
+
    +
  • + End-to-end integration with EG paved road tools and Backstage to + support increased developer productivity +
  • +
  • + Drive broader adoption to have all EG employees using Backstage to + manage their SDLC and to build internal UIs using plugins +
  • +
+
Improve search results relevance + Intuitive search capabilities to surface relevant Backstage content like + TechDocs, entities, tools, etc. + +
    +
  • Enabled global search functionality throughout Backstage
  • +
  • +

    Contributed to the open source Backstage Search platform

    +
  • +
+
+
    +
  • Engine optimization/ranking improvement
  • +
  • Visualize key search metrics to support improvements
  • +
  • Chat + AI integration with chat-based interfaces
  • +
+
Technical documentation reach + Number of developers leveraging TechDocs for all services within EG + +
    +
  • 500+ services tied with TechDocs
  • +
  • 50,000+ average monthly TechDoc views
  • +
+
+
    +
  • + All Backstage entities leveraging TechDocs to enable a centralized + documentation portal integrated with the Software Catalog +
  • +
  • + Quality/governance and gamification to support users and + contributors +
  • +
  • + More TechDocs and mkdocs add-ons to compliment the core capabilities + and drive usability of documentation on Backstage +
  • +
+
Developer Experience community engagementEnhance Backstage through community engagement +
    +
  • + Diverse contributions to Backstage open source focused on search and + discovery - 10+ +
  • +
  • Community engagement through internal case studies, and blogs
  • +
+
+
    +
  • + Continuous contributions to open-source Backstage, focused on plugin + administration, driving documentation adoption, and improved UX + around core capabilities +
  • +
  • + Strategic community engagements to enhance the platform's usability + and long-term confidence in adopting Backstage +
  • +
  • + Event participation and storytelling around EG's Backstage journey +
  • +
+
+ +## YMMV: Your Metrics May Vary! + +Measuring the value of Backstage will vary depending on your organization's needs and priorities. As an early adopter of Backstage, we hope the Expedia Group PoV metrics provide a helpful framework for understanding how Backstage can be used to improve developer productivity, collaboration, and knowledge sharing. + +We look forward to sharing future updates with the community as we continue to embrace a continuous improvement approach to Backstage. If you missed it, you can read about where we started in our [initial proof of value metrics](https://backstage.spotify.com/blog/measuring-backstage-proof-of-value-at-expedia/) back in 2021. + +_Read more about Expedia's tech journey on [their Medium Blog](https://medium.com/expedia-group-tech)_ diff --git a/microsite/blog/assets/2023-08-17/header.png b/microsite/blog/assets/2023-08-17/header.png new file mode 100644 index 0000000000000000000000000000000000000000..bd75529f72aee8e585a24af0b4c4430a3a217745 GIT binary patch literal 147502 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