From 07dda0b746a9dd16ea5921fb72f1ef0312d0a999 Mon Sep 17 00:00:00 2001 From: Axel Hecht Date: Wed, 31 Aug 2022 14:06:00 +0200 Subject: [PATCH 001/185] Add optional value to hasAnnotation. Signed-off-by: Axel Hecht --- .changeset/famous-rats-heal.md | 5 ++ plugins/catalog-backend/api-report.md | 4 +- .../permissions/rules/hasAnnotation.test.ts | 62 +++++++++++++++++++ .../src/permissions/rules/hasAnnotation.ts | 21 +++++-- 4 files changed, 85 insertions(+), 7 deletions(-) create mode 100644 .changeset/famous-rats-heal.md diff --git a/.changeset/famous-rats-heal.md b/.changeset/famous-rats-heal.md new file mode 100644 index 0000000000..e233070849 --- /dev/null +++ b/.changeset/famous-rats-heal.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend': patch +--- + +Add optional value to hasAnnotation permission rule diff --git a/plugins/catalog-backend/api-report.md b/plugins/catalog-backend/api-report.md index 0460fbc5e9..8a2b0fc9cc 100644 --- a/plugins/catalog-backend/api-report.md +++ b/plugins/catalog-backend/api-report.md @@ -177,7 +177,7 @@ export const catalogConditions: Conditions<{ Entity, EntitiesSearchFilter, 'catalog-entity', - [annotation: string] + [annotation: string, value?: string | undefined] >; hasLabel: PermissionRule< Entity, @@ -448,7 +448,7 @@ export const permissionRules: { Entity, EntitiesSearchFilter, 'catalog-entity', - [annotation: string] + [annotation: string, value?: string | undefined] >; hasLabel: PermissionRule< Entity, diff --git a/plugins/catalog-backend/src/permissions/rules/hasAnnotation.test.ts b/plugins/catalog-backend/src/permissions/rules/hasAnnotation.test.ts index 1596270907..609114be3d 100644 --- a/plugins/catalog-backend/src/permissions/rules/hasAnnotation.test.ts +++ b/plugins/catalog-backend/src/permissions/rules/hasAnnotation.test.ts @@ -49,6 +49,19 @@ describe('hasAnnotation permission rule', () => { 'backstage.io/test-annotation', ), ).toEqual(false); + expect( + hasAnnotation.apply( + { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + name: 'test-component', + }, + }, + 'backstage.io/test-annotation', + 'some value', + ), + ).toEqual(false); }); it('returns true when specified annotation is present', () => { @@ -69,6 +82,46 @@ describe('hasAnnotation permission rule', () => { ), ).toEqual(true); }); + + it('returns false when specified annotation has different than expected value', () => { + expect( + hasAnnotation.apply( + { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + name: 'test-component', + annotations: { + 'other-annotation': 'foo', + 'backstage.io/test-annotation': 'bar', + }, + }, + }, + 'backstage.io/test-annotation', + 'baz', + ), + ).toEqual(false); + }); + + it('returns true when specified annotation has expected value', () => { + expect( + hasAnnotation.apply( + { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + name: 'test-component', + annotations: { + 'other-annotation': 'foo', + 'backstage.io/test-annotation': 'bar', + }, + }, + }, + 'backstage.io/test-annotation', + 'bar', + ), + ).toEqual(true); + }); }); describe('toQuery', () => { @@ -78,4 +131,13 @@ describe('hasAnnotation permission rule', () => { }); }); }); + + it('returns an appropriate catalog-backend filter with values', () => { + expect( + hasAnnotation.toQuery('backstage.io/test-annotation', 'foo'), + ).toEqual({ + key: 'metadata.annotations.backstage.io/test-annotation', + values: ['foo'], + }); + }); }); diff --git a/plugins/catalog-backend/src/permissions/rules/hasAnnotation.ts b/plugins/catalog-backend/src/permissions/rules/hasAnnotation.ts index 68ca65418d..22dbd307a6 100644 --- a/plugins/catalog-backend/src/permissions/rules/hasAnnotation.ts +++ b/plugins/catalog-backend/src/permissions/rules/hasAnnotation.ts @@ -22,6 +22,8 @@ import { createCatalogPermissionRule } from './util'; * A catalog {@link @backstage/plugin-permission-node#PermissionRule} which * filters for the presence of an annotation on a given entity. * + * If a value is given, it filters for the annotation value, too. + * * @alpha */ export const hasAnnotation = createCatalogPermissionRule({ @@ -29,9 +31,18 @@ export const hasAnnotation = createCatalogPermissionRule({ description: 'Allow entities which are annotated with the specified annotation', resourceType: RESOURCE_TYPE_CATALOG_ENTITY, - apply: (resource: Entity, annotation: string) => - !!resource.metadata.annotations?.hasOwnProperty(annotation), - toQuery: (annotation: string) => ({ - key: `metadata.annotations.${annotation}`, - }), + apply: (resource: Entity, annotation: string, value?: string) => + !!resource.metadata.annotations?.hasOwnProperty(annotation) && + (value === undefined + ? true + : resource.metadata.annotations?.[annotation] === value), + toQuery: (annotation: string, value?: string) => + value === undefined + ? { + key: `metadata.annotations.${annotation}`, + } + : { + key: `metadata.annotations.${annotation}`, + values: [value], + }, }); From 5fa831ce551eda0fb14ac4d05a372b8450048e07 Mon Sep 17 00:00:00 2001 From: Marcus Eide Date: Tue, 6 Sep 2022 13:12:50 +0200 Subject: [PATCH 002/185] Add optional SameSite attribute to CookieConfigurer and return from defaultCookieConfigurer for secure contexts. Signed-off-by: Marcus Eide --- .changeset/kind-penguins-report.md | 5 ++++ plugins/auth-backend/api-report.md | 5 ++-- .../src/lib/oauth/OAuthAdapter.test.ts | 15 ++++++++--- .../src/lib/oauth/OAuthAdapter.ts | 16 ++++-------- .../src/lib/oauth/helpers.test.ts | 25 +++++++++++++++++++ plugins/auth-backend/src/lib/oauth/helpers.ts | 3 ++- plugins/auth-backend/src/providers/types.ts | 7 +++++- 7 files changed, 57 insertions(+), 19 deletions(-) create mode 100644 .changeset/kind-penguins-report.md diff --git a/.changeset/kind-penguins-report.md b/.changeset/kind-penguins-report.md new file mode 100644 index 0000000000..6596f727d2 --- /dev/null +++ b/.changeset/kind-penguins-report.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-backend': patch +--- + +Allow CookieConfigurer to optionally return the SameSite cookie attribute. Return `SameSite=None` in `defaultCookieConfigurer` for secure contexts to allow cookies to be included in third-party requests. diff --git a/plugins/auth-backend/api-report.md b/plugins/auth-backend/api-report.md index d47abeee83..ed3561d37c 100644 --- a/plugins/auth-backend/api-report.md +++ b/plugins/auth-backend/api-report.md @@ -187,6 +187,7 @@ export type CookieConfigurer = (ctx: { domain: string; path: string; secure: boolean; + sameSite?: 'none' | 'lax' | 'strict'; }; // @public @@ -280,11 +281,9 @@ export class OAuthAdapter implements AuthProviderRouteHandlers { // @public (undocumented) export type OAuthAdapterOptions = { providerId: string; - secure: boolean; persistScopes?: boolean; - cookieDomain: string; - cookiePath: string; appOrigin: string; + cookieConfig: ReturnType; isOriginAllowed: (origin: string) => boolean; callbackUrl: string; }; diff --git a/plugins/auth-backend/src/lib/oauth/OAuthAdapter.test.ts b/plugins/auth-backend/src/lib/oauth/OAuthAdapter.test.ts index 9dcd76e92e..a61554b600 100644 --- a/plugins/auth-backend/src/lib/oauth/OAuthAdapter.test.ts +++ b/plugins/auth-backend/src/lib/oauth/OAuthAdapter.test.ts @@ -18,6 +18,7 @@ import express from 'express'; import { THOUSAND_DAYS_MS, TEN_MINUTES_MS, OAuthAdapter } from './OAuthAdapter'; import { encodeState } from './helpers'; import { OAuthHandlers, OAuthState } from './types'; +import { CookieConfigurer } from '../../providers/types'; const mockResponseData = { providerInfo: { @@ -57,12 +58,17 @@ describe('OAuthAdapter', () => { } } const providerInstance = new MyAuthProvider(); + const cookieConfig = { + domain: 'example.com', + path: '/auth/test-provider', + secure: false, + sameSite: 'lax', + } as ReturnType; + const oAuthProviderOptions = { providerId: 'test-provider', - secure: false, appOrigin: 'http://localhost:3000', - cookieDomain: 'example.com', - cookiePath: '/auth/test-provider', + cookieConfig, tokenIssuer: { issueToken: async () => 'my-id-token', listPublicKeys: async () => ({ keys: [] }), @@ -136,6 +142,8 @@ describe('OAuthAdapter', () => { expect.objectContaining({ path: '/auth/test-provider', maxAge: THOUSAND_DAYS_MS, + secure: false, + sameSite: 'lax', }), ); }); @@ -331,6 +339,7 @@ describe('OAuthAdapter', () => { domain: 'authdomain.org', path: '/auth/test-provider/handler', secure: true, + sameSite: 'none', }), ); }); diff --git a/plugins/auth-backend/src/lib/oauth/OAuthAdapter.ts b/plugins/auth-backend/src/lib/oauth/OAuthAdapter.ts index 6caa9fed12..c021104010 100644 --- a/plugins/auth-backend/src/lib/oauth/OAuthAdapter.ts +++ b/plugins/auth-backend/src/lib/oauth/OAuthAdapter.ts @@ -24,6 +24,7 @@ import { import { AuthProviderRouteHandlers, AuthProviderConfig, + CookieConfigurer, } from '../../providers/types'; import { AuthenticationError, @@ -47,11 +48,9 @@ export const TEN_MINUTES_MS = 600 * 1000; /** @public */ export type OAuthAdapterOptions = { providerId: string; - secure: boolean; persistScopes?: boolean; - cookieDomain: string; - cookiePath: string; appOrigin: string; + cookieConfig: ReturnType; isOriginAllowed: (origin: string) => boolean; callbackUrl: string; }; @@ -78,9 +77,7 @@ export class OAuthAdapter implements AuthProviderRouteHandlers { return new OAuthAdapter(handlers, { ...options, appOrigin, - cookieDomain: cookieConfig.domain, - cookiePath: cookieConfig.path, - secure: cookieConfig.secure, + cookieConfig, isOriginAllowed: config.isOriginAllowed, }); } @@ -93,10 +90,7 @@ export class OAuthAdapter implements AuthProviderRouteHandlers { ) { this.baseCookieOptions = { httpOnly: true, - sameSite: 'lax', - secure: this.options.secure, - path: this.options.cookiePath, - domain: this.options.cookieDomain, + ...this.options.cookieConfig, }; } @@ -265,7 +259,7 @@ export class OAuthAdapter implements AuthProviderRouteHandlers { res.cookie(`${this.options.providerId}-nonce`, nonce, { maxAge: TEN_MINUTES_MS, ...this.baseCookieOptions, - path: `${this.options.cookiePath}/handler`, + path: `${this.options.cookieConfig.path}/handler`, }); }; diff --git a/plugins/auth-backend/src/lib/oauth/helpers.test.ts b/plugins/auth-backend/src/lib/oauth/helpers.test.ts index b3052c93e1..2202fa60ea 100644 --- a/plugins/auth-backend/src/lib/oauth/helpers.test.ts +++ b/plugins/auth-backend/src/lib/oauth/helpers.test.ts @@ -150,5 +150,30 @@ describe('OAuthProvider Utils', () => { secure: true, }); }); + + it('should set sameSite to none for https', () => { + expect( + defaultCookieConfigurer({ + baseUrl: '', + providerId: 'test-provider', + callbackUrl: 'https://domain.org/auth', + }), + ).toMatchObject({ + sameSite: 'none', + secure: true, + }); + }); + it('should set sameSite to lax for http', () => { + expect( + defaultCookieConfigurer({ + baseUrl: '', + providerId: 'test-provider', + callbackUrl: 'http://domain.org/auth', + }), + ).toMatchObject({ + sameSite: 'lax', + secure: false, + }); + }); }); }); diff --git a/plugins/auth-backend/src/lib/oauth/helpers.ts b/plugins/auth-backend/src/lib/oauth/helpers.ts index 63d5d62ef9..b18db59ca7 100644 --- a/plugins/auth-backend/src/lib/oauth/helpers.ts +++ b/plugins/auth-backend/src/lib/oauth/helpers.ts @@ -68,6 +68,7 @@ export const defaultCookieConfigurer: CookieConfigurer = ({ }) => { const { hostname: domain, pathname, protocol } = new URL(callbackUrl); const secure = protocol === 'https:'; + const sameSite = secure ? 'none' : 'lax'; // If the provider supports callbackUrls, the pathname will // contain the complete path to the frame handler so we need @@ -76,5 +77,5 @@ export const defaultCookieConfigurer: CookieConfigurer = ({ ? pathname.slice(0, -'/handler/frame'.length) : `${pathname}/${providerId}`; - return { domain, path, secure }; + return { domain, path, secure, sameSite }; }; diff --git a/plugins/auth-backend/src/providers/types.ts b/plugins/auth-backend/src/providers/types.ts index 574afade79..f22e6b0492 100644 --- a/plugins/auth-backend/src/providers/types.ts +++ b/plugins/auth-backend/src/providers/types.ts @@ -100,7 +100,12 @@ export type CookieConfigurer = (ctx: { baseUrl: string; /** The configured callback URL of the auth provider */ callbackUrl: string; -}) => { domain: string; path: string; secure: boolean }; +}) => { + domain: string; + path: string; + secure: boolean; + sameSite?: 'none' | 'lax' | 'strict'; +}; /** @public */ export type AuthProviderConfig = { From 7531aef58b36c60255ebed1c9273cc6646971ac7 Mon Sep 17 00:00:00 2001 From: Vladimir Masarik Date: Thu, 1 Sep 2022 10:21:05 +0200 Subject: [PATCH 003/185] Fix settings page not displaying sing in properly Signed-off-by: Vladimir Masarik --- .../AuthProviders/ProviderSettingsItem.tsx | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/plugins/user-settings/src/components/AuthProviders/ProviderSettingsItem.tsx b/plugins/user-settings/src/components/AuthProviders/ProviderSettingsItem.tsx index e170aa2daa..6de5f9ad73 100644 --- a/plugins/user-settings/src/components/AuthProviders/ProviderSettingsItem.tsx +++ b/plugins/user-settings/src/components/AuthProviders/ProviderSettingsItem.tsx @@ -26,9 +26,10 @@ import { import { ApiRef, SessionApi, + ProfileInfoApi, + ProfileInfo, useApi, IconComponent, - SessionState, } from '@backstage/core-plugin-api'; /** @public */ @@ -36,23 +37,27 @@ export const ProviderSettingsItem = (props: { title: string; description: string; icon: IconComponent; - apiRef: ApiRef; + apiRef: ApiRef; }) => { const { title, description, icon: Icon, apiRef } = props; const api = useApi(apiRef); const [signedIn, setSignedIn] = useState(false); + const [profileEmail, setProfileEmail] = useState(''); useEffect(() => { let didCancel = false; - const subscription = api - .sessionState$() - .subscribe((sessionState: SessionState) => { - if (!didCancel) { - setSignedIn(sessionState === SessionState.SignedIn); - } - }); + const subscription = api.sessionState$().subscribe(() => { + if (!didCancel) { + api + .getProfile({ optional: false }) + .then((profile: ProfileInfo | undefined) => { + setSignedIn(profile !== undefined); + setProfileEmail(profile?.email ?? ''); + }); + } + }); return () => { didCancel = true; @@ -69,7 +74,9 @@ export const ProviderSettingsItem = (props: { primary={title} secondary={ - {description} + + {description}. Signed in as {profileEmail} + } secondaryTypographyProps={{ noWrap: true, style: { width: '80%' } }} From 4ce0c846cccae75c682643e0ba3f5f71d514a8fa Mon Sep 17 00:00:00 2001 From: Vladimir Masarik Date: Fri, 2 Sep 2022 14:00:12 +0200 Subject: [PATCH 004/185] fix optional to true Signed-off-by: Vladimir Masarik --- .../src/components/AuthProviders/ProviderSettingsItem.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/user-settings/src/components/AuthProviders/ProviderSettingsItem.tsx b/plugins/user-settings/src/components/AuthProviders/ProviderSettingsItem.tsx index 6de5f9ad73..7ff13a11d4 100644 --- a/plugins/user-settings/src/components/AuthProviders/ProviderSettingsItem.tsx +++ b/plugins/user-settings/src/components/AuthProviders/ProviderSettingsItem.tsx @@ -51,7 +51,7 @@ export const ProviderSettingsItem = (props: { const subscription = api.sessionState$().subscribe(() => { if (!didCancel) { api - .getProfile({ optional: false }) + .getProfile({ optional: true }) .then((profile: ProfileInfo | undefined) => { setSignedIn(profile !== undefined); setProfileEmail(profile?.email ?? ''); From 5e00eb69c5b79f686f27a248136d6f52e80d61bd Mon Sep 17 00:00:00 2001 From: Vladimir Masarik Date: Fri, 2 Sep 2022 14:00:38 +0200 Subject: [PATCH 005/185] check sessions state as well Signed-off-by: Vladimir Masarik --- .../AuthProviders/ProviderSettingsItem.tsx | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/plugins/user-settings/src/components/AuthProviders/ProviderSettingsItem.tsx b/plugins/user-settings/src/components/AuthProviders/ProviderSettingsItem.tsx index 7ff13a11d4..4a3b28b335 100644 --- a/plugins/user-settings/src/components/AuthProviders/ProviderSettingsItem.tsx +++ b/plugins/user-settings/src/components/AuthProviders/ProviderSettingsItem.tsx @@ -26,6 +26,7 @@ import { import { ApiRef, SessionApi, + SessionState, ProfileInfoApi, ProfileInfo, useApi, @@ -48,16 +49,22 @@ export const ProviderSettingsItem = (props: { useEffect(() => { let didCancel = false; - const subscription = api.sessionState$().subscribe(() => { - if (!didCancel) { - api - .getProfile({ optional: true }) - .then((profile: ProfileInfo | undefined) => { - setSignedIn(profile !== undefined); - setProfileEmail(profile?.email ?? ''); - }); - } - }); + const subscription = api + .sessionState$() + .subscribe((sessionState: SessionState) => { + if (!didCancel) { + api + .getProfile({ optional: true }) + .then((profile: ProfileInfo | undefined) => { + if (sessionState === SessionState.SignedIn) { + setSignedIn(true); + } else { + setSignedIn(profile !== undefined); + } + setProfileEmail(profile?.email ?? ''); + }); + } + }); return () => { didCancel = true; From 0d25d297a33841b8e8e0c24c0d48c60a37fa784a Mon Sep 17 00:00:00 2001 From: Vladimir Masarik Date: Mon, 5 Sep 2022 16:46:08 +0200 Subject: [PATCH 006/185] add more info into providers Signed-off-by: Vladimir Masarik --- .../AuthProviders/ProviderSettingsAvatar.tsx | 38 +++++++++++++++++++ .../AuthProviders/ProviderSettingsItem.tsx | 37 +++++++++++++++--- 2 files changed, 70 insertions(+), 5 deletions(-) create mode 100644 plugins/user-settings/src/components/AuthProviders/ProviderSettingsAvatar.tsx diff --git a/plugins/user-settings/src/components/AuthProviders/ProviderSettingsAvatar.tsx b/plugins/user-settings/src/components/AuthProviders/ProviderSettingsAvatar.tsx new file mode 100644 index 0000000000..e92b0efe15 --- /dev/null +++ b/plugins/user-settings/src/components/AuthProviders/ProviderSettingsAvatar.tsx @@ -0,0 +1,38 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import { BackstageTheme } from '@backstage/theme'; +import { makeStyles, Avatar } from '@material-ui/core'; +import { sidebarConfig } from '@backstage/core-components'; + +const useStyles = makeStyles(theme => ({ + avatar: { + width: ({ size }) => size, + height: ({ size }) => size, + fontSize: ({ size }) => size * 0.7, + border: `1px solid ${theme.palette.textSubtle}`, + }, +})); + +type Props = { size?: number; picture: string | undefined }; + +export const ProviderSettingsAvatar = ({ size, picture }: Props) => { + const { iconSize } = sidebarConfig; + const classes = useStyles(size ? { size } : { size: iconSize }); + + return ; +}; diff --git a/plugins/user-settings/src/components/AuthProviders/ProviderSettingsItem.tsx b/plugins/user-settings/src/components/AuthProviders/ProviderSettingsItem.tsx index 4a3b28b335..ef31e70d81 100644 --- a/plugins/user-settings/src/components/AuthProviders/ProviderSettingsItem.tsx +++ b/plugins/user-settings/src/components/AuthProviders/ProviderSettingsItem.tsx @@ -17,11 +17,13 @@ import React, { useEffect, useState } from 'react'; import { Button, + Grid, ListItem, ListItemIcon, ListItemSecondaryAction, ListItemText, Tooltip, + Typography, } from '@material-ui/core'; import { ApiRef, @@ -32,6 +34,7 @@ import { useApi, IconComponent, } from '@backstage/core-plugin-api'; +import { ProviderSettingsAvatar } from './ProviderSettingsAvatar'; /** @public */ export const ProviderSettingsItem = (props: { @@ -44,7 +47,8 @@ export const ProviderSettingsItem = (props: { const api = useApi(apiRef); const [signedIn, setSignedIn] = useState(false); - const [profileEmail, setProfileEmail] = useState(''); + const emptyProfile: ProfileInfo = {}; + const [profile, setProfile] = useState(emptyProfile); useEffect(() => { let didCancel = false; @@ -55,13 +59,13 @@ export const ProviderSettingsItem = (props: { if (!didCancel) { api .getProfile({ optional: true }) - .then((profile: ProfileInfo | undefined) => { + .then((profileResponse: ProfileInfo | undefined) => { if (sessionState === SessionState.SignedIn) { setSignedIn(true); } else { - setSignedIn(profile !== undefined); + setSignedIn(profileResponse !== undefined); } - setProfileEmail(profile?.email ?? ''); + setProfile(profileResponse ?? {}); }); } }); @@ -82,7 +86,30 @@ export const ProviderSettingsItem = (props: { secondary={ - {description}. Signed in as {profileEmail} + + + + + + + + + {profile.displayName} + + + {profile.email} + + + {description} + + + + + } From 5543e866602cd6fd67ee8cf04c2233b7b8d1a8e3 Mon Sep 17 00:00:00 2001 From: Vladimir Masarik Date: Tue, 6 Sep 2022 19:09:59 +0200 Subject: [PATCH 007/185] add change set Signed-off-by: Vladimir Masarik --- .changeset/soft-falcons-love.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/soft-falcons-love.md diff --git a/.changeset/soft-falcons-love.md b/.changeset/soft-falcons-love.md new file mode 100644 index 0000000000..5f2d282158 --- /dev/null +++ b/.changeset/soft-falcons-love.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-user-settings': patch +--- + +Fixed settings page showing providers as logged out when the user is using more than one provider, and displayed some additional login information. From 6253418cb3b6c7154b0d2ba51a1a62e89c7a528a Mon Sep 17 00:00:00 2001 From: bnechyporenko Date: Thu, 8 Sep 2022 08:52:04 +0200 Subject: [PATCH 008/185] Provide information about the user into scaffolder template action's context Signed-off-by: bnechyporenko --- .../lib/resolvers/CatalogAuthResolverContext.ts | 2 +- .../src/scaffolder/actions/types.ts | 17 ++++++++++++++++- .../scaffolder/tasks/NunjucksWorkflowRunner.ts | 1 + 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/plugins/auth-backend/src/lib/resolvers/CatalogAuthResolverContext.ts b/plugins/auth-backend/src/lib/resolvers/CatalogAuthResolverContext.ts index cbc2439563..c62c0737d8 100644 --- a/plugins/auth-backend/src/lib/resolvers/CatalogAuthResolverContext.ts +++ b/plugins/auth-backend/src/lib/resolvers/CatalogAuthResolverContext.ts @@ -27,7 +27,7 @@ import { ConflictError, InputError, NotFoundError } from '@backstage/errors'; import { Logger } from 'winston'; import { TokenIssuer, TokenParams } from '../../identity/types'; import { AuthResolverContext } from '../../providers'; -import { AuthResolverCatalogUserQuery } from '../../providers/types'; +import { AuthResolverCatalogUserQuery } from '../../providers'; import { CatalogIdentityClient } from '../catalog'; /** diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/types.ts b/plugins/scaffolder-backend/src/scaffolder/actions/types.ts index ff15300b4a..666f7a0d50 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/types.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/types.ts @@ -18,8 +18,9 @@ import { Logger } from 'winston'; import { Writable } from 'stream'; import { JsonValue, JsonObject } from '@backstage/types'; import { Schema } from 'jsonschema'; -import { TaskSecrets } from '../tasks/types'; +import { TaskSecrets } from '../tasks'; import { TemplateInfo } from '@backstage/plugin-scaffolder-common'; +import { UserEntity } from '@backstage/catalog-model'; /** * ActionContext is passed into scaffolder actions. @@ -45,6 +46,20 @@ export type ActionContext = { * This will only ever be true if the actions as marked as supporting dry-runs. */ isDryRun?: boolean; + + /** + * The user which triggered the action. + */ + user?: { + /** + * The decorated entity from the Catalog + */ + entity?: UserEntity; + /** + * An entity ref for the author of the task + */ + ref?: string; + }; }; /** @public */ diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.ts index 97e37fd3eb..6e35f7c69b 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.ts @@ -300,6 +300,7 @@ export class NunjucksWorkflowRunner implements WorkflowRunner { stepOutput[name] = value; }, templateInfo: task.spec.templateInfo, + user: task.spec.user, }); // Remove all temporary directories that were created when executing the action From de8ee4afe301b13da181aef2ae0acc04e140412d Mon Sep 17 00:00:00 2001 From: bnechyporenko Date: Thu, 8 Sep 2022 08:57:42 +0200 Subject: [PATCH 009/185] Provide information about the user into scaffolder template action's context Signed-off-by: bnechyporenko --- .changeset/hungry-llamas-tie.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/hungry-llamas-tie.md diff --git a/.changeset/hungry-llamas-tie.md b/.changeset/hungry-llamas-tie.md new file mode 100644 index 0000000000..c4848b50ef --- /dev/null +++ b/.changeset/hungry-llamas-tie.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-auth-backend': patch +'@backstage/plugin-scaffolder-backend': patch +--- + +Provide information about the user into scaffolder template action's context From 820628b17f844ec7dbda7c5919f28a900deb3585 Mon Sep 17 00:00:00 2001 From: bnechyporenko Date: Thu, 8 Sep 2022 09:21:25 +0200 Subject: [PATCH 010/185] Updated api-report.md Signed-off-by: bnechyporenko --- plugins/scaffolder-backend/api-report.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/plugins/scaffolder-backend/api-report.md b/plugins/scaffolder-backend/api-report.md index 44bf45061b..0d5fbcb31f 100644 --- a/plugins/scaffolder-backend/api-report.md +++ b/plugins/scaffolder-backend/api-report.md @@ -31,6 +31,7 @@ import { TaskSpec } from '@backstage/plugin-scaffolder-common'; import { TaskSpecV1beta3 } from '@backstage/plugin-scaffolder-common'; import { TemplateInfo } from '@backstage/plugin-scaffolder-common'; import { UrlReader } from '@backstage/backend-common'; +import { UserEntity } from '@backstage/catalog-model'; import { Writable } from 'stream'; // @public @@ -44,6 +45,10 @@ export type ActionContext = { createTemporaryDirectory(): Promise; templateInfo?: TemplateInfo; isDryRun?: boolean; + user?: { + entity?: UserEntity; + ref?: string; + }; }; // @public From 63b0626c9d3be0e33408a144b6eb27afea76580f Mon Sep 17 00:00:00 2001 From: bnechyporenko Date: Thu, 8 Sep 2022 11:00:55 +0200 Subject: [PATCH 011/185] Added a unit test Signed-off-by: bnechyporenko --- .../tasks/NunjucksWorkflowRunner.test.ts | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.test.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.test.ts index 3627d83aa7..5af26bfea3 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.test.ts @@ -66,7 +66,7 @@ describe('DefaultWorkflowRunner', () => { }); beforeEach(() => { - winston.format.simple(); // put logform the require cache before mocking fs + winston.format.simple(); // put logform the required cache before mocking fs mockFs({ '/tmp': mockFs.directory(), ...realFiles, @@ -169,6 +169,21 @@ describe('DefaultWorkflowRunner', () => { it('should pass metadata through', async () => { const entityRef = `template:default/templateName`; + + const userEntity: UserEntity = { + apiVersion: 'backstage.io/v1beta1', + kind: 'User', + metadata: { + name: 'user', + }, + spec: { + profile: { + displayName: 'Bogdan Nechyporenko', + email: 'bnechyporenko@company.com', + }, + }, + }; + const task = createMockTaskWithSpec({ apiVersion: 'scaffolder.backstage.io/v1beta3', parameters: {}, @@ -182,6 +197,9 @@ describe('DefaultWorkflowRunner', () => { }, ], templateInfo: { entityRef }, + user: { + entity: userEntity, + }, }); await runner.execute(task); @@ -189,6 +207,10 @@ describe('DefaultWorkflowRunner', () => { expect(fakeActionHandler.mock.calls[0][0].templateInfo).toEqual({ entityRef, }); + + expect(fakeActionHandler.mock.calls[0][0].user).toEqual({ + entity: userEntity, + }); }); it('should pass token through', async () => { From 19ac96e4c2987c31af0c97ecbe01cdca5c0288dc Mon Sep 17 00:00:00 2001 From: David Zemon Date: Thu, 8 Sep 2022 11:36:49 -0500 Subject: [PATCH 012/185] feat: Allow passing additional JWT claims to `TokenIssuer` Signed-off-by: David Zemon --- plugins/auth-backend/src/identity/TokenFactory.test.ts | 8 +++++++- plugins/auth-backend/src/identity/TokenFactory.ts | 5 ++--- plugins/auth-backend/src/identity/types.ts | 10 ++++++++-- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/plugins/auth-backend/src/identity/TokenFactory.test.ts b/plugins/auth-backend/src/identity/TokenFactory.test.ts index 9a163b3ff5..4f6df89210 100644 --- a/plugins/auth-backend/src/identity/TokenFactory.test.ts +++ b/plugins/auth-backend/src/identity/TokenFactory.test.ts @@ -48,7 +48,12 @@ describe('TokenFactory', () => { await expect(factory.listPublicKeys()).resolves.toEqual({ keys: [] }); const token = await factory.issueToken({ - claims: { sub: entityRef, ent: [entityRef] }, + claims: { + sub: entityRef, + ent: [entityRef], + 'x-fancy-claim': 'my special claim', + aud: 'this value will be overridden', + }, }); const { keys } = await factory.listPublicKeys(); @@ -60,6 +65,7 @@ describe('TokenFactory', () => { aud: 'backstage', sub: entityRef, ent: [entityRef], + 'x-fancy-claim': 'my special claim', iat: expect.any(Number), exp: expect.any(Number), }); diff --git a/plugins/auth-backend/src/identity/TokenFactory.ts b/plugins/auth-backend/src/identity/TokenFactory.ts index 44cfebfb71..f80b79b6bc 100644 --- a/plugins/auth-backend/src/identity/TokenFactory.ts +++ b/plugins/auth-backend/src/identity/TokenFactory.ts @@ -77,8 +77,7 @@ export class TokenFactory implements TokenIssuer { const key = await this.getKey(); const iss = this.issuer; - const sub = params.claims.sub; - const ent = params.claims.ent; + const { sub, ent, ...additionalClaims } = params.claims; const aud = 'backstage'; const iat = Math.floor(Date.now() / MS_IN_S); const exp = iat + this.keyDurationSeconds; @@ -98,7 +97,7 @@ export class TokenFactory implements TokenIssuer { throw new AuthenticationError('No algorithm was provided in the key'); } - return new SignJWT({ iss, sub, ent, aud, iat, exp }) + return new SignJWT({ ...additionalClaims, iss, sub, ent, aud, iat, exp }) .setProtectedHeader({ alg: key.alg, kid: key.kid }) .setIssuer(iss) .setAudience(aud) diff --git a/plugins/auth-backend/src/identity/types.ts b/plugins/auth-backend/src/identity/types.ts index 4765b50d7d..49d78b8472 100644 --- a/plugins/auth-backend/src/identity/types.ts +++ b/plugins/auth-backend/src/identity/types.ts @@ -28,13 +28,19 @@ export interface AnyJWK extends Record { * @public */ export type TokenParams = { - /** The claims that will be embedded within the token */ + /** + * The claims that will be embedded within the token. At a minimum, this should include + * the subject claim, `sub`. It is common to also list entity ownership relations in the + * `ent` list. Additional claims may also be added at the developer's discretion except + * for the following list, which will be overwritten by the TokenIssuer: `iss`, `aud`, + * `iat`, and `exp`. + */ claims: { /** The token subject, i.e. User ID */ sub: string; /** A list of entity references that the user claims ownership through */ ent?: string[]; - }; + } & Record; }; /** From 5b011fb2e6aa88964fe737531fe2296e7e3f8dbb Mon Sep 17 00:00:00 2001 From: David Zemon Date: Thu, 8 Sep 2022 11:48:36 -0500 Subject: [PATCH 013/185] chore: Add changeset Signed-off-by: David Zemon --- .changeset/cold-bananas-hang.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/cold-bananas-hang.md diff --git a/.changeset/cold-bananas-hang.md b/.changeset/cold-bananas-hang.md new file mode 100644 index 0000000000..8e535a5532 --- /dev/null +++ b/.changeset/cold-bananas-hang.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-backend': patch +--- + +Allow adding misc claims to JWT From dba3c15c96be917c99461158a16f6a9dfafab3b0 Mon Sep 17 00:00:00 2001 From: David Zemon Date: Thu, 8 Sep 2022 12:06:23 -0500 Subject: [PATCH 014/185] chore: Add API report Signed-off-by: David Zemon --- plugins/auth-backend/api-report.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/auth-backend/api-report.md b/plugins/auth-backend/api-report.md index d47abeee83..2420a79a79 100644 --- a/plugins/auth-backend/api-report.md +++ b/plugins/auth-backend/api-report.md @@ -706,7 +706,7 @@ export type TokenParams = { claims: { sub: string; ent?: string[]; - }; + } & Record; }; // @public (undocumented) From 4a77dec3951d7f1286ee8a4668c68e8cc6b05e52 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 9 Sep 2022 05:56:14 +0000 Subject: [PATCH 015/185] chore(deps): update dependency @types/marked to v4.0.7 Signed-off-by: Renovate Bot --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index e8c07a2c57..96b99aed3c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14427,9 +14427,9 @@ __metadata: linkType: hard "@types/marked@npm:^4.0.0": - version: 4.0.6 - resolution: "@types/marked@npm:4.0.6" - checksum: 223f7d8e9481287aa0274df573dd56df6cb11a1090649fabd63fd97f900ed318e730d9dfaff598aa75d8946a212c1d8959a421c5cb46d90c5a6f734a1e4a7d78 + version: 4.0.7 + resolution: "@types/marked@npm:4.0.7" + checksum: 4907b6a606578cd864bad429aca3c234591e6ed56bd141c575140487269b825a480ace9a85e4d003d1de1f007004c9d9b2fe600038ded5bba75aef59118e58d5 languageName: node linkType: hard From 12943d1ade5a7658a05148d7a8a676ce98a43c40 Mon Sep 17 00:00:00 2001 From: Marcus Eide Date: Fri, 9 Sep 2022 11:16:04 +0200 Subject: [PATCH 016/185] Calculate SameSite attribute more carefully, defaulting to lax in most cases Signed-off-by: Marcus Eide --- .changeset/kind-penguins-report.md | 7 +- plugins/auth-backend/api-report.md | 3 + .../src/lib/oauth/OAuthAdapter.test.ts | 121 +++++++++++++++++- .../src/lib/oauth/OAuthAdapter.ts | 25 +++- .../src/lib/oauth/helpers.test.ts | 40 +++++- plugins/auth-backend/src/lib/oauth/helpers.ts | 11 +- plugins/auth-backend/src/providers/types.ts | 2 + 7 files changed, 193 insertions(+), 16 deletions(-) diff --git a/.changeset/kind-penguins-report.md b/.changeset/kind-penguins-report.md index 6596f727d2..9f2401491e 100644 --- a/.changeset/kind-penguins-report.md +++ b/.changeset/kind-penguins-report.md @@ -1,5 +1,8 @@ --- -'@backstage/plugin-auth-backend': patch +'@backstage/plugin-auth-backend': minor --- -Allow CookieConfigurer to optionally return the SameSite cookie attribute. Return `SameSite=None` in `defaultCookieConfigurer` for secure contexts to allow cookies to be included in third-party requests. +CookieConfigurer can optionally return the `SameSite` cookie attribute. +CookieConfigurer now requires an additional argument `appOrigin` - the origin URL of the app - which is used to calculate the `SameSite` attribute. +defaultCookieConfigurer returns the `SameSite` attribute which defaults to `Lax`. In cases where an auth-backend is running on a different domain than the App, `SameSite=None` is used - but only for secure contexts. This is so that cookies can be included in third-party requests. +OAuthAdapterOptions has been modified to require additional arguments, `baseUrl`, `cookieConfigurer` and `cookieConfig`. diff --git a/plugins/auth-backend/api-report.md b/plugins/auth-backend/api-report.md index ed3561d37c..8cb7e35e9b 100644 --- a/plugins/auth-backend/api-report.md +++ b/plugins/auth-backend/api-report.md @@ -183,6 +183,7 @@ export type CookieConfigurer = (ctx: { providerId: string; baseUrl: string; callbackUrl: string; + appOrigin: string; }) => { domain: string; path: string; @@ -283,7 +284,9 @@ export type OAuthAdapterOptions = { providerId: string; persistScopes?: boolean; appOrigin: string; + baseUrl: string; cookieConfig: ReturnType; + cookieConfigurer: CookieConfigurer; isOriginAllowed: (origin: string) => boolean; callbackUrl: string; }; diff --git a/plugins/auth-backend/src/lib/oauth/OAuthAdapter.test.ts b/plugins/auth-backend/src/lib/oauth/OAuthAdapter.test.ts index a61554b600..d59a712205 100644 --- a/plugins/auth-backend/src/lib/oauth/OAuthAdapter.test.ts +++ b/plugins/auth-backend/src/lib/oauth/OAuthAdapter.test.ts @@ -37,6 +37,10 @@ const mockResponseData = { }; describe('OAuthAdapter', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + class MyAuthProvider implements OAuthHandlers { async start() { return { @@ -58,17 +62,19 @@ describe('OAuthAdapter', () => { } } const providerInstance = new MyAuthProvider(); - const cookieConfig = { + const mockCookieConfig: ReturnType = { domain: 'example.com', path: '/auth/test-provider', secure: false, - sameSite: 'lax', - } as ReturnType; + }; + const mockCookieConfigurer = jest.fn().mockReturnValue(mockCookieConfig); const oAuthProviderOptions = { providerId: 'test-provider', appOrigin: 'http://localhost:3000', - cookieConfig, + cookieConfig: mockCookieConfig, + cookieConfigurer: mockCookieConfigurer, + baseUrl: 'http://example.com:7007', tokenIssuer: { issueToken: async () => 'my-id-token', listPublicKeys: async () => ({ keys: [] }), @@ -135,11 +141,13 @@ describe('OAuthAdapter', () => { } as unknown as express.Response; await oauthProvider.frameHandler(mockRequest, mockResponse); + expect(mockCookieConfigurer).toHaveBeenCalledTimes(1); expect(mockResponse.cookie).toHaveBeenCalledTimes(1); expect(mockResponse.cookie).toHaveBeenCalledWith( expect.stringContaining('test-provider-refresh-token'), expect.stringContaining('token'), expect.objectContaining({ + httpOnly: true, path: '/auth/test-provider', maxAge: THOUSAND_DAYS_MS, secure: false, @@ -210,6 +218,7 @@ describe('OAuthAdapter', () => { } as unknown as express.Response; await oauthProvider.frameHandler(mockHandleReq, mockHandleRes); + expect(mockCookieConfigurer).toHaveBeenCalledTimes(1); expect(mockHandleRes.cookie).toHaveBeenCalledTimes(1); expect(mockHandleRes.cookie).toHaveBeenCalledWith( 'test-provider-granted-scope', @@ -303,7 +312,7 @@ describe('OAuthAdapter', () => { }); }); - it('sets the correct cookie configuration using a callbackUrl', async () => { + it('sets the correct cookie configuration using an unsecure callbackUrl', async () => { const config = { baseUrl: 'http://domain.org/auth', appUrl: 'http://domain.org', @@ -312,7 +321,7 @@ describe('OAuthAdapter', () => { const oauthProvider = OAuthAdapter.fromConfig(config, providerInstance, { ...oAuthProviderOptions, - callbackUrl: 'https://authdomain.org/auth/test-provider/handler/frame', + callbackUrl: 'http://authdomain.org/auth/test-provider/handler/frame', }); const mockRequest = { @@ -330,14 +339,112 @@ describe('OAuthAdapter', () => { } as unknown as express.Response; await oauthProvider.start(mockRequest, mockResponse); - + expect(mockCookieConfigurer).not.toHaveBeenCalled(); expect(mockResponse.cookie).toHaveBeenCalledTimes(1); expect(mockResponse.cookie).toHaveBeenCalledWith( `${oAuthProviderOptions.providerId}-nonce`, expect.any(String), expect.objectContaining({ + httpOnly: true, domain: 'authdomain.org', path: '/auth/test-provider/handler', + secure: false, + sameSite: 'lax', + }), + ); + }); + + it('sets the correct cookie configuration using an secure callbackUrl', async () => { + const config = { + baseUrl: 'https://domain.org/auth', + appUrl: 'http://domain.org', + isOriginAllowed: () => false, + }; + + const oauthProvider = OAuthAdapter.fromConfig(config, providerInstance, { + ...oAuthProviderOptions, + callbackUrl: 'https://authdomain.org/auth/test-provider/handler/frame', + }); + + const state = { + nonce: 'nonce', + env: 'development', + }; + + const mockRequest = { + cookies: { + 'test-provider-nonce': 'nonce', + }, + query: { + state: encodeState(state), + }, + } as unknown as express.Request; + + const mockResponse = { + cookie: jest.fn().mockReturnThis(), + setHeader: jest.fn().mockReturnThis(), + end: jest.fn().mockReturnThis(), + } as unknown as express.Response; + + await oauthProvider.frameHandler(mockRequest, mockResponse); + expect(mockCookieConfigurer).not.toHaveBeenCalled(); + expect(mockResponse.cookie).toHaveBeenCalledTimes(1); + expect(mockResponse.cookie).toHaveBeenCalledWith( + expect.stringContaining('test-provider-refresh-token'), + expect.stringContaining('token'), + expect.objectContaining({ + httpOnly: true, + domain: 'authdomain.org', + path: '/auth/test-provider', + secure: true, + sameSite: 'none', + }), + ); + }); + + it('sets the correct cookie configuration using state', async () => { + const config = { + baseUrl: 'https://domain.org/auth', + appUrl: 'http://domain.org', + isOriginAllowed: () => true, + }; + + const oauthProvider = OAuthAdapter.fromConfig(config, providerInstance, { + ...oAuthProviderOptions, + callbackUrl: 'https://domain.org/auth/test-provider/handler/frame', + }); + + const state = { + nonce: 'nonce', + env: 'development', + origin: 'http://other.domain', + }; + + const mockRequest = { + cookies: { + 'test-provider-nonce': 'nonce', + }, + query: { + state: encodeState(state), + }, + } as unknown as express.Request; + + const mockResponse = { + cookie: jest.fn().mockReturnThis(), + setHeader: jest.fn().mockReturnThis(), + end: jest.fn().mockReturnThis(), + } as unknown as express.Response; + + await oauthProvider.frameHandler(mockRequest, mockResponse); + expect(mockCookieConfigurer).not.toHaveBeenCalled(); + expect(mockResponse.cookie).toHaveBeenCalledTimes(1); + expect(mockResponse.cookie).toHaveBeenCalledWith( + expect.stringContaining('test-provider-refresh-token'), + expect.stringContaining('token'), + expect.objectContaining({ + httpOnly: true, + domain: 'domain.org', + path: '/auth/test-provider', secure: true, sameSite: 'none', }), diff --git a/plugins/auth-backend/src/lib/oauth/OAuthAdapter.ts b/plugins/auth-backend/src/lib/oauth/OAuthAdapter.ts index c021104010..64dc4f70e3 100644 --- a/plugins/auth-backend/src/lib/oauth/OAuthAdapter.ts +++ b/plugins/auth-backend/src/lib/oauth/OAuthAdapter.ts @@ -50,7 +50,9 @@ export type OAuthAdapterOptions = { providerId: string; persistScopes?: boolean; appOrigin: string; + baseUrl: string; cookieConfig: ReturnType; + cookieConfigurer: CookieConfigurer; isOriginAllowed: (origin: string) => boolean; callbackUrl: string; }; @@ -65,24 +67,28 @@ export class OAuthAdapter implements AuthProviderRouteHandlers { 'providerId' | 'persistScopes' | 'callbackUrl' >, ): OAuthAdapter { - const { origin: appOrigin } = new URL(config.appUrl); + const { appUrl, baseUrl, isOriginAllowed } = config; + const { origin: appOrigin } = new URL(appUrl); const cookieConfigurer = config.cookieConfigurer ?? defaultCookieConfigurer; const cookieConfig = cookieConfigurer({ providerId: options.providerId, baseUrl: config.baseUrl, callbackUrl: options.callbackUrl, + appOrigin, }); return new OAuthAdapter(handlers, { ...options, appOrigin, + baseUrl, cookieConfig, - isOriginAllowed: config.isOriginAllowed, + cookieConfigurer, + isOriginAllowed, }); } - private readonly baseCookieOptions: CookieOptions; + private baseCookieOptions: CookieOptions; constructor( private readonly handlers: OAuthHandlers, @@ -90,6 +96,7 @@ export class OAuthAdapter implements AuthProviderRouteHandlers { ) { this.baseCookieOptions = { httpOnly: true, + sameSite: 'lax', ...this.options.cookieConfig, }; } @@ -147,6 +154,18 @@ export class OAuthAdapter implements AuthProviderRouteHandlers { } } + // Update cookie options to reflect any changes for the appOrigin + const updatedCookieOptions = this.options.cookieConfigurer({ + providerId: this.options.providerId, + baseUrl: this.options.baseUrl, + callbackUrl: this.options.callbackUrl, + appOrigin, + }); + this.baseCookieOptions = { + ...this.baseCookieOptions, + ...updatedCookieOptions, + }; + // verify nonce cookie and state cookie on callback verifyNonce(req, this.options.providerId); diff --git a/plugins/auth-backend/src/lib/oauth/helpers.test.ts b/plugins/auth-backend/src/lib/oauth/helpers.test.ts index 2202fa60ea..58a3dcab05 100644 --- a/plugins/auth-backend/src/lib/oauth/helpers.test.ts +++ b/plugins/auth-backend/src/lib/oauth/helpers.test.ts @@ -117,6 +117,7 @@ describe('OAuthProvider Utils', () => { baseUrl: '', providerId: 'test-provider', callbackUrl: 'http://domain.org/auth', + appOrigin: 'http://domain.org', }), ).toMatchObject({ domain: 'domain.org', @@ -131,6 +132,7 @@ describe('OAuthProvider Utils', () => { baseUrl: '', providerId: 'test-provider', callbackUrl: 'http://domain.org/auth/test-provider/handler/frame', + appOrigin: 'http://domain.org', }), ).toMatchObject({ domain: 'domain.org', @@ -145,35 +147,67 @@ describe('OAuthProvider Utils', () => { baseUrl: '', providerId: 'test-provider', callbackUrl: 'https://domain.org/auth', + appOrigin: 'http://domain.org', }), ).toMatchObject({ secure: true, }); }); - it('should set sameSite to none for https', () => { + it('should set sameSite to lax for https on the same domain', () => { expect( defaultCookieConfigurer({ baseUrl: '', providerId: 'test-provider', callbackUrl: 'https://domain.org/auth', + appOrigin: 'http://domain.org', }), ).toMatchObject({ - sameSite: 'none', + sameSite: 'lax', secure: true, }); }); - it('should set sameSite to lax for http', () => { + + it('should set sameSite to lax for http on the same domain', () => { expect( defaultCookieConfigurer({ baseUrl: '', providerId: 'test-provider', callbackUrl: 'http://domain.org/auth', + appOrigin: 'http://domain.org', }), ).toMatchObject({ sameSite: 'lax', secure: false, }); }); + + it('should set sameSite to lax if not secure and on different domains', () => { + expect( + defaultCookieConfigurer({ + baseUrl: '', + providerId: 'test-provider', + callbackUrl: 'http://authdomain.org/auth', + appOrigin: 'http://domain.org', + }), + ).toMatchObject({ + sameSite: 'lax', + secure: false, + }); + }); + + it('should set sameSite to none if secure and on different domains', () => { + expect( + defaultCookieConfigurer({ + baseUrl: '', + providerId: 'test-provider', + callbackUrl: 'https://authdomain.org/auth', + appOrigin: 'http://domain.org', + }), + ).toMatchObject({ + sameSite: 'none', + secure: true, + }); + }); }); }); diff --git a/plugins/auth-backend/src/lib/oauth/helpers.ts b/plugins/auth-backend/src/lib/oauth/helpers.ts index b18db59ca7..2b4e50b477 100644 --- a/plugins/auth-backend/src/lib/oauth/helpers.ts +++ b/plugins/auth-backend/src/lib/oauth/helpers.ts @@ -65,10 +65,19 @@ export const verifyNonce = (req: express.Request, providerId: string) => { export const defaultCookieConfigurer: CookieConfigurer = ({ callbackUrl, providerId, + appOrigin, }) => { const { hostname: domain, pathname, protocol } = new URL(callbackUrl); const secure = protocol === 'https:'; - const sameSite = secure ? 'none' : 'lax'; + + // For situations where the auth-backend is running on a + // different domain than the app, we set the SameSite attribute + // to 'none' to allow third-party access to the cookie, but + // only if it's in a secure context (https). + let sameSite: ReturnType['sameSite'] = 'lax'; + if (new URL(appOrigin).hostname !== domain && secure) { + sameSite = 'none'; + } // If the provider supports callbackUrls, the pathname will // contain the complete path to the frame handler so we need diff --git a/plugins/auth-backend/src/providers/types.ts b/plugins/auth-backend/src/providers/types.ts index f22e6b0492..1459cff484 100644 --- a/plugins/auth-backend/src/providers/types.ts +++ b/plugins/auth-backend/src/providers/types.ts @@ -100,6 +100,8 @@ export type CookieConfigurer = (ctx: { baseUrl: string; /** The configured callback URL of the auth provider */ callbackUrl: string; + /** The origin URL of the app */ + appOrigin: string; }) => { domain: string; path: string; From 01345242dd8b47b93b883aee2a9367159ad89b82 Mon Sep 17 00:00:00 2001 From: Axel Hecht Date: Fri, 9 Sep 2022 14:41:47 +0200 Subject: [PATCH 017/185] Update .changeset/famous-rats-heal.md Co-authored-by: Ben Lambert Signed-off-by: Axel Hecht --- .changeset/famous-rats-heal.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/famous-rats-heal.md b/.changeset/famous-rats-heal.md index e233070849..4235a9fa44 100644 --- a/.changeset/famous-rats-heal.md +++ b/.changeset/famous-rats-heal.md @@ -2,4 +2,4 @@ '@backstage/plugin-catalog-backend': patch --- -Add optional value to hasAnnotation permission rule +Add optional value to `hasAnnotation` permission rule From b16ca8255b8f838f8525dd2d27fe402e44004064 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 9 Sep 2022 16:28:26 +0000 Subject: [PATCH 018/185] fix(deps): update dependency eslint-plugin-react to v7.31.8 Signed-off-by: Renovate Bot --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 701a3f3229..77008419ec 100644 --- a/yarn.lock +++ b/yarn.lock @@ -22076,8 +22076,8 @@ __metadata: linkType: hard "eslint-plugin-react@npm:^7.28.0": - version: 7.31.1 - resolution: "eslint-plugin-react@npm:7.31.1" + version: 7.31.8 + resolution: "eslint-plugin-react@npm:7.31.8" dependencies: array-includes: ^3.1.5 array.prototype.flatmap: ^1.3.0 @@ -22095,7 +22095,7 @@ __metadata: string.prototype.matchall: ^4.0.7 peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 - checksum: 6217d4c4e36c8fea24facd0cdcf22b2fd38a3603db94ec7c0a6f430046c8564b6c6884e0a9d4a4b8766201f66e8b18af594002210421bf9b6623b1fc32e15a3a + checksum: 0683e2a624a4df6f08264a3f6bc614a81e8f961c83173bdf2d8d3523f84ed5d234cddc976dbc6815913e007c5984df742ba61be0c0592b27c3daabe0f68165a3 languageName: node linkType: hard From 2270997d57f4f39f58bbfadee9dcaf7d101ee774 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Mota?= Date: Fri, 9 Sep 2022 22:44:55 +0200 Subject: [PATCH 019/185] Update docker guide for clarity MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As happened to a colleague of mine and might happen to others, one might see a "docker" section and skip straight to that since it looks on the surface to be a quick way to check out backstage yourself. In this case that resulted in trying to make all these builds from the main backstage/backstage repo, before even understanding the concept of a Backstage App, which obviously did not work out. Signed-off-by: Tomás Mota --- docs/deployment/docker.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/deployment/docker.md b/docs/deployment/docker.md index d46aff1b06..5455babc6f 100644 --- a/docs/deployment/docker.md +++ b/docs/deployment/docker.md @@ -16,7 +16,8 @@ are stateless, so for a production deployment you will want to set up and connect to an external PostgreSQL instance where the backend plugins can store their state, rather than using SQLite. -By default, in an app created with `@backstage/create-app`, the frontend is +It is in this section assumed that an [app](https://backstage.io/docs/getting-started/create-an-app) +has already been created with`@backstage/create-app`, in which the frontend is bundled and served from the backend. This is done using the `@backstage/plugin-app-backend` plugin, which also injects the frontend configuration into the app. This means that you only need to build and deploy a From 01e9214ab23cb64b1d62b9bee29b630a56f596b8 Mon Sep 17 00:00:00 2001 From: Vladimir Masarik Date: Sun, 11 Sep 2022 15:34:24 +0200 Subject: [PATCH 020/185] Chang changeset to minor Signed-off-by: Vladimir Masarik --- .changeset/soft-falcons-love.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.changeset/soft-falcons-love.md b/.changeset/soft-falcons-love.md index 5f2d282158..9fbc8f1419 100644 --- a/.changeset/soft-falcons-love.md +++ b/.changeset/soft-falcons-love.md @@ -1,5 +1,5 @@ --- -'@backstage/plugin-user-settings': patch +'@backstage/plugin-user-settings': minor --- -Fixed settings page showing providers as logged out when the user is using more than one provider, and displayed some additional login information. +**BREAKING** Fixed settings page showing providers as logged out when the user is using more than one provider, and displayed some additional login information. From 2282c9936ceed5b34efbd6a0993e1a8a38ca0b16 Mon Sep 17 00:00:00 2001 From: Vladimir Masarik Date: Sun, 11 Sep 2022 15:34:35 +0200 Subject: [PATCH 021/185] Generate API report Signed-off-by: Vladimir Masarik --- plugins/user-settings/api-report.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/user-settings/api-report.md b/plugins/user-settings/api-report.md index bc5c3a9c70..e2f3d46e24 100644 --- a/plugins/user-settings/api-report.md +++ b/plugins/user-settings/api-report.md @@ -10,6 +10,7 @@ import { BackstagePlugin } from '@backstage/core-plugin-api'; import { BackstageUserIdentity } from '@backstage/core-plugin-api'; import { IconComponent } from '@backstage/core-plugin-api'; import { ProfileInfo } from '@backstage/core-plugin-api'; +import { ProfileInfoApi } from '@backstage/core-plugin-api'; import { PropsWithChildren } from 'react'; import { RouteRef } from '@backstage/core-plugin-api'; import { SessionApi } from '@backstage/core-plugin-api'; @@ -24,7 +25,7 @@ export const ProviderSettingsItem: (props: { title: string; description: string; icon: IconComponent; - apiRef: ApiRef; + apiRef: ApiRef; }) => JSX.Element; // @public (undocumented) From cc538eccc20eca3102ad0332dda8ef97cafb117c Mon Sep 17 00:00:00 2001 From: Vladimir Masarik Date: Sun, 11 Sep 2022 15:34:56 +0200 Subject: [PATCH 022/185] Dont set to empty profile Signed-off-by: Vladimir Masarik --- .../src/components/AuthProviders/ProviderSettingsItem.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/user-settings/src/components/AuthProviders/ProviderSettingsItem.tsx b/plugins/user-settings/src/components/AuthProviders/ProviderSettingsItem.tsx index ef31e70d81..b5d056eed2 100644 --- a/plugins/user-settings/src/components/AuthProviders/ProviderSettingsItem.tsx +++ b/plugins/user-settings/src/components/AuthProviders/ProviderSettingsItem.tsx @@ -62,10 +62,10 @@ export const ProviderSettingsItem = (props: { .then((profileResponse: ProfileInfo | undefined) => { if (sessionState === SessionState.SignedIn) { setSignedIn(true); - } else { - setSignedIn(profileResponse !== undefined); } - setProfile(profileResponse ?? {}); + if (profileResponse) { + setProfile(profileResponse); + } }); } }); From 1bdb0bf24b3b8ef134e1a475492e24aee33d42c7 Mon Sep 17 00:00:00 2001 From: Jussi Hallila Date: Mon, 12 Sep 2022 09:49:19 +0200 Subject: [PATCH 023/185] Modify RecentWorkflowRunsCard use constructed routeRef instead of hardcoded route. Signed-off-by: Jussi Hallila --- .changeset/brown-kings-greet.md | 5 +++++ .../components/Cards/RecentWorkflowRunsCard.tsx | 17 ++++++++++------- 2 files changed, 15 insertions(+), 7 deletions(-) create mode 100644 .changeset/brown-kings-greet.md diff --git a/.changeset/brown-kings-greet.md b/.changeset/brown-kings-greet.md new file mode 100644 index 0000000000..00e82675ee --- /dev/null +++ b/.changeset/brown-kings-greet.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-github-actions': patch +--- + +Modify RecentWorkflowRunsCard use constructed routeRef instead of hardcoded route. diff --git a/plugins/github-actions/src/components/Cards/RecentWorkflowRunsCard.tsx b/plugins/github-actions/src/components/Cards/RecentWorkflowRunsCard.tsx index fcd0f194a3..931b5b676e 100644 --- a/plugins/github-actions/src/components/Cards/RecentWorkflowRunsCard.tsx +++ b/plugins/github-actions/src/components/Cards/RecentWorkflowRunsCard.tsx @@ -16,19 +16,25 @@ import { readGitHubIntegrationConfigs } from '@backstage/integration'; import { useEntity } from '@backstage/plugin-catalog-react'; import React, { useEffect } from 'react'; -import { generatePath, Link as RouterLink } from 'react-router-dom'; +import { Link as RouterLink } from 'react-router-dom'; import { GITHUB_ACTIONS_ANNOTATION } from '../getProjectNameFromEntity'; import { useWorkflowRuns, WorkflowRun } from '../useWorkflowRuns'; import { WorkflowRunStatus } from '../WorkflowRunStatus'; import { Typography } from '@material-ui/core'; -import { configApiRef, errorApiRef, useApi } from '@backstage/core-plugin-api'; +import { + configApiRef, + errorApiRef, + useApi, + useRouteRef, +} from '@backstage/core-plugin-api'; import { InfoCard, InfoCardVariants, Link, Table, } from '@backstage/core-components'; +import { buildRouteRef } from '../../routes'; const firstLine = (message: string): string => message.split('\n')[0]; @@ -69,7 +75,7 @@ export const RecentWorkflowRunsCard = (props: { }, [error, errorApi]); const githubHost = hostname || 'github.com'; - + const routeLink = useRouteRef(buildRouteRef); return ( ( - + {firstLine(data.message ?? '')} ), From 3d184f17130506397f300a57e2fe6e9a6653abc9 Mon Sep 17 00:00:00 2001 From: Jussi Hallila Date: Mon, 12 Sep 2022 09:56:52 +0200 Subject: [PATCH 024/185] Add routes to tests. Signed-off-by: Jussi Hallila --- .../Cards/RecentWorkflowRunsCard.test.tsx | 47 ++++++++++--------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/plugins/github-actions/src/components/Cards/RecentWorkflowRunsCard.test.tsx b/plugins/github-actions/src/components/Cards/RecentWorkflowRunsCard.test.tsx index 7a20501072..5e0a5f3e15 100644 --- a/plugins/github-actions/src/components/Cards/RecentWorkflowRunsCard.test.tsx +++ b/plugins/github-actions/src/components/Cards/RecentWorkflowRunsCard.test.tsx @@ -15,21 +15,19 @@ */ import { EntityProvider } from '@backstage/plugin-catalog-react'; -import { lightTheme } from '@backstage/theme'; -import { ThemeProvider } from '@material-ui/core'; -import { render } from '@testing-library/react'; import React from 'react'; -import { MemoryRouter } from 'react-router'; import { useWorkflowRuns } from '../useWorkflowRuns'; import { RecentWorkflowRunsCard } from './RecentWorkflowRunsCard'; import { ConfigReader } from '@backstage/core-app-api'; import { - errorApiRef, - configApiRef, ConfigApi, + configApiRef, + errorApiRef, } from '@backstage/core-plugin-api'; -import { TestApiProvider } from '@backstage/test-utils'; +import { TestApiProvider, wrapInTestApp } from '@backstage/test-utils'; +import { rootRouteRef } from '../../routes'; +import { render } from '@testing-library/react'; jest.mock('../useWorkflowRuns', () => ({ useWorkflowRuns: jest.fn(), @@ -76,24 +74,27 @@ describe('', () => { const renderSubject = (props: any = {}) => render( - - - - - - - - - , + wrapInTestApp( + + + + + , + { + mountedRoutes: { + '/ci-cd': rootRouteRef, + }, + }, + ), ); it('renders a table with a row for each workflow', async () => { - const subject = renderSubject(); + const subject = await renderSubject(); workflowRuns.forEach(run => { expect(subject.getByText(run.message)).toBeInTheDocument(); @@ -101,7 +102,7 @@ describe('', () => { }); it('renders a workflow row correctly', async () => { - const subject = renderSubject(); + const subject = await renderSubject(); const [run] = workflowRuns; expect(subject.getByText(run.message).closest('a')).toHaveAttribute( 'href', From 65c990705dfc3a8c396826e7d6cd2388cc955dd8 Mon Sep 17 00:00:00 2001 From: Jussi Hallila Date: Mon, 12 Sep 2022 10:01:54 +0200 Subject: [PATCH 025/185] Modify changeset wording to appease vale. Signed-off-by: Jussi Hallila --- .changeset/brown-kings-greet.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.changeset/brown-kings-greet.md b/.changeset/brown-kings-greet.md index 00e82675ee..918474baf7 100644 --- a/.changeset/brown-kings-greet.md +++ b/.changeset/brown-kings-greet.md @@ -1,5 +1,6 @@ ---- +4--- '@backstage/plugin-github-actions': patch + --- -Modify RecentWorkflowRunsCard use constructed routeRef instead of hardcoded route. +Modify RecentWorkflowRunsCard use constructed route instead of hardcoded route. From 83b1b5ee5b899507bf1d6808e56db565a7091410 Mon Sep 17 00:00:00 2001 From: Jussi Hallila Date: Mon, 12 Sep 2022 10:09:29 +0200 Subject: [PATCH 026/185] Remove extra character. Signed-off-by: Jussi Hallila --- .changeset/brown-kings-greet.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.changeset/brown-kings-greet.md b/.changeset/brown-kings-greet.md index 918474baf7..8271b40bb4 100644 --- a/.changeset/brown-kings-greet.md +++ b/.changeset/brown-kings-greet.md @@ -1,6 +1,5 @@ -4--- +--- '@backstage/plugin-github-actions': patch - --- Modify RecentWorkflowRunsCard use constructed route instead of hardcoded route. From f52dfc0c485f7c7cc0763bb89b978828895bc021 Mon Sep 17 00:00:00 2001 From: sblausten Date: Mon, 12 Sep 2022 11:56:23 +0100 Subject: [PATCH 027/185] Fix overflow issue for mic drop image Signed-off-by: sblausten --- packages/core-components/src/layout/ErrorPage/ErrorPage.tsx | 2 +- packages/core-components/src/layout/ErrorPage/MicDrop.tsx | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/core-components/src/layout/ErrorPage/ErrorPage.tsx b/packages/core-components/src/layout/ErrorPage/ErrorPage.tsx index 928a3eb0d4..658c06de2a 100644 --- a/packages/core-components/src/layout/ErrorPage/ErrorPage.tsx +++ b/packages/core-components/src/layout/ErrorPage/ErrorPage.tsx @@ -70,7 +70,6 @@ export function ErrorPage(props: IErrorPageProps) { return ( - + ); } diff --git a/packages/core-components/src/layout/ErrorPage/MicDrop.tsx b/packages/core-components/src/layout/ErrorPage/MicDrop.tsx index efa101b23b..aacb44079a 100644 --- a/packages/core-components/src/layout/ErrorPage/MicDrop.tsx +++ b/packages/core-components/src/layout/ErrorPage/MicDrop.tsx @@ -22,12 +22,10 @@ const useStyles = makeStyles( theme => ({ micDrop: { maxWidth: '60%', - position: 'absolute', bottom: theme.spacing(2), right: theme.spacing(2), [theme.breakpoints.down('xs')]: { maxWidth: '96%', - position: 'relative', bottom: 'unset', right: 'unset', margin: `${theme.spacing(10)}px auto ${theme.spacing(4)}px`, From 023d14c52b03d530de1dd257cd199e9caafd37d7 Mon Sep 17 00:00:00 2001 From: sblausten Date: Mon, 12 Sep 2022 13:03:50 +0100 Subject: [PATCH 028/185] changeset Signed-off-by: sblausten --- .changeset/three-dryers-confess.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/three-dryers-confess.md diff --git a/.changeset/three-dryers-confess.md b/.changeset/three-dryers-confess.md new file mode 100644 index 0000000000..e68bc36665 --- /dev/null +++ b/.changeset/three-dryers-confess.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-components': patch +--- + +Fix overflow bug on MicDrop image for 404 page by moving the image and making it relative rather than absolute From a983f2037b80366f5deeac2fb4ca391a79a93e49 Mon Sep 17 00:00:00 2001 From: Clemens Stefan Heithecker <48448358+clemensheithecker@users.noreply.github.com> Date: Mon, 12 Sep 2022 15:19:57 +0200 Subject: [PATCH 029/185] Add custom actions plugin for Azure pipelines Signed-off-by: Clemens Stefan Heithecker <48448358+clemensheithecker@users.noreply.github.com> --- .../writing-custom-actions.md | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/docs/features/software-templates/writing-custom-actions.md b/docs/features/software-templates/writing-custom-actions.md index a9e1d297f3..b35ceb907d 100644 --- a/docs/features/software-templates/writing-custom-actions.md +++ b/docs/features/software-templates/writing-custom-actions.md @@ -156,15 +156,16 @@ export default async function createPlugin( Here is a list of Open Source custom actions that you can add to your Backstage scaffolder backend: -| Name | Package | Owner | -| ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | -| Yeoman | [plugin-scaffolder-backend-module-yeoman](https://www.npmjs.com/package/@backstage/plugin-scaffolder-backend-module-yeoman) | [Backstage](https://backstage.io) | -| Cookiecutter | [plugin-scaffolder-backend-module-cookiecutter](https://www.npmjs.com/package/@backstage/plugin-scaffolder-backend-module-cookiecutter) | [Backstage](https://backstage.io) | -| Rails | [plugin-scaffolder-backend-module-rails](https://www.npmjs.com/package/@backstage/plugin-scaffolder-backend-module-rails) | [Backstage](https://backstage.io) | -| HTTP requests | [scaffolder-backend-module-http-request](https://www.npmjs.com/package/@roadiehq/scaffolder-backend-module-http-request) | [Roadie](https://roadie.io) | -| Utility actions | [scaffolder-backend-module-utils](https://www.npmjs.com/package/@roadiehq/scaffolder-backend-module-utils) | [Roadie](https://roadie.io) | -| AWS cli actions | [scaffolder-backend-module-aws](https://www.npmjs.com/package/@roadiehq/scaffolder-backend-module-aws) | [Roadie](https://roadie.io) | -| Scaffolder .NET Actions | [plugin-scaffolder-dotnet-backend](https://www.npmjs.com/package/@plusultra/plugin-scaffolder-dotnet-backend) | [Alef Carlos](https://github.com/alefcarlos) | -| Scaffolder Git Actions | [plugin-scaffolder-git-actions](https://www.npmjs.com/package/@mdude2314/backstage-plugin-scaffolder-git-actions) | [Drew Hill](https://github.com/arhill05) | +| Name | Package | Owner | +| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ | +| Yeoman | [plugin-scaffolder-backend-module-yeoman](https://www.npmjs.com/package/@backstage/plugin-scaffolder-backend-module-yeoman) | [Backstage](https://backstage.io) | +| Cookiecutter | [plugin-scaffolder-backend-module-cookiecutter](https://www.npmjs.com/package/@backstage/plugin-scaffolder-backend-module-cookiecutter) | [Backstage](https://backstage.io) | +| Rails | [plugin-scaffolder-backend-module-rails](https://www.npmjs.com/package/@backstage/plugin-scaffolder-backend-module-rails) | [Backstage](https://backstage.io) | +| HTTP requests | [scaffolder-backend-module-http-request](https://www.npmjs.com/package/@roadiehq/scaffolder-backend-module-http-request) | [Roadie](https://roadie.io) | +| Utility actions | [scaffolder-backend-module-utils](https://www.npmjs.com/package/@roadiehq/scaffolder-backend-module-utils) | [Roadie](https://roadie.io) | +| AWS cli actions | [scaffolder-backend-module-aws](https://www.npmjs.com/package/@roadiehq/scaffolder-backend-module-aws) | [Roadie](https://roadie.io) | +| Scaffolder .NET Actions | [plugin-scaffolder-dotnet-backend](https://www.npmjs.com/package/@plusultra/plugin-scaffolder-dotnet-backend) | [Alef Carlos](https://github.com/alefcarlos) | +| Scaffolder Git Actions | [plugin-scaffolder-git-actions](https://www.npmjs.com/package/@mdude2314/backstage-plugin-scaffolder-git-actions) | [Drew Hill](https://github.com/arhill05) | +| Azure Pipeline Actions | [scaffolder-backend-module-azure-pipelines](https://www.npmjs.com/package/@parfuemerie-douglas/scaffolder-backend-module-azure-pipelines) | [Parfümerie Douglas](https://github.com/Parfuemerie-Douglas) | Have fun! 🚀 From a57d29d572a9375fd1d6054b2313dae21c9ff452 Mon Sep 17 00:00:00 2001 From: Michael Stergianis Date: Mon, 12 Sep 2022 10:00:32 -0400 Subject: [PATCH 030/185] Adds skipMetricsLookup to kubernetes-backend schema Signed-off-by: Michael Stergianis --- .changeset/fuzzy-jars-compare.md | 5 +++++ plugins/kubernetes-backend/schema.d.ts | 4 ++++ 2 files changed, 9 insertions(+) create mode 100644 .changeset/fuzzy-jars-compare.md diff --git a/.changeset/fuzzy-jars-compare.md b/.changeset/fuzzy-jars-compare.md new file mode 100644 index 0000000000..b8c404c001 --- /dev/null +++ b/.changeset/fuzzy-jars-compare.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-kubernetes-backend': patch +--- + +Adds skipMetricsLookup to the kubernetes-backend schema diff --git a/plugins/kubernetes-backend/schema.d.ts b/plugins/kubernetes-backend/schema.d.ts index fed243ef17..59fa7a5d97 100644 --- a/plugins/kubernetes-backend/schema.d.ts +++ b/plugins/kubernetes-backend/schema.d.ts @@ -40,6 +40,8 @@ export interface Config { region?: string; /** @visibility frontend */ skipTLSVerify?: boolean; + /** @visibility frontend */ + skipMetricsLookup?: boolean; } | { /** @visibility frontend */ @@ -62,6 +64,8 @@ export interface Config { oidcTokenProvider?: string; /** @visibility frontend */ skipTLSVerify?: boolean; + /** @visibility frontend */ + skipMetricsLookup?: boolean; }>; } >; From da9547d2f34b14dfdbcf33958cf34466fa94f056 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 13 Sep 2022 08:56:36 +0000 Subject: [PATCH 031/185] Version Packages (next) --- .changeset/pre.json | 25 + docs/releases/v1.6.0-next.3-changelog.md | 1768 ++++++++++++ package.json | 2 +- packages/app-defaults/CHANGELOG.md | 12 + packages/app-defaults/package.json | 14 +- packages/app/CHANGELOG.md | 56 + packages/app/package.json | 104 +- packages/backend-app-api/CHANGELOG.md | 13 + packages/backend-app-api/package.json | 14 +- packages/backend-common/CHANGELOG.md | 12 + packages/backend-common/package.json | 16 +- packages/backend-defaults/CHANGELOG.md | 9 + packages/backend-defaults/package.json | 8 +- packages/backend-plugin-api/CHANGELOG.md | 12 + packages/backend-plugin-api/package.json | 12 +- packages/backend-tasks/CHANGELOG.md | 9 + packages/backend-tasks/package.json | 12 +- packages/backend-test-utils/CHANGELOG.md | 12 + packages/backend-test-utils/package.json | 14 +- packages/backend/CHANGELOG.md | 40 + packages/backend/package.json | 70 +- packages/catalog-client/CHANGELOG.md | 13 + packages/catalog-client/package.json | 8 +- packages/catalog-model/CHANGELOG.md | 9 + packages/catalog-model/package.json | 8 +- packages/cli-common/CHANGELOG.md | 6 + packages/cli-common/package.json | 4 +- packages/cli/CHANGELOG.md | 13 + packages/cli/package.json | 26 +- packages/codemods/CHANGELOG.md | 7 + packages/codemods/package.json | 6 +- packages/config-loader/CHANGELOG.md | 11 + packages/config-loader/package.json | 10 +- packages/config/CHANGELOG.md | 6 + packages/config/package.json | 6 +- packages/core-app-api/CHANGELOG.md | 9 + packages/core-app-api/package.json | 10 +- packages/core-components/CHANGELOG.md | 10 + packages/core-components/package.json | 14 +- packages/core-plugin-api/CHANGELOG.md | 8 + packages/core-plugin-api/package.json | 10 +- packages/create-app/CHANGELOG.md | 8 + packages/create-app/package.json | 6 +- packages/dev-utils/CHANGELOG.md | 16 + packages/dev-utils/package.json | 20 +- packages/e2e-test/package.json | 6 +- packages/errors/CHANGELOG.md | 6 + packages/errors/package.json | 4 +- packages/integration-react/CHANGELOG.md | 11 + packages/integration-react/package.json | 16 +- packages/integration/CHANGELOG.md | 13 + packages/integration/package.json | 12 +- packages/release-manifests/CHANGELOG.md | 6 + packages/release-manifests/package.json | 6 +- .../techdocs-cli-embedded-app/CHANGELOG.md | 18 + .../techdocs-cli-embedded-app/package.json | 28 +- packages/techdocs-cli/CHANGELOG.md | 12 + packages/techdocs-cli/package.json | 14 +- packages/test-utils/CHANGELOG.md | 13 + packages/test-utils/package.json | 14 +- plugins/adr-backend/CHANGELOG.md | 13 + plugins/adr-backend/package.json | 18 +- plugins/adr-common/CHANGELOG.md | 8 + plugins/adr-common/package.json | 8 +- plugins/adr/CHANGELOG.md | 13 + plugins/adr/package.json | 22 +- plugins/airbrake-backend/CHANGELOG.md | 8 + plugins/airbrake-backend/package.json | 8 +- plugins/airbrake/CHANGELOG.md | 13 + plugins/airbrake/package.json | 22 +- plugins/allure/CHANGELOG.md | 11 + plugins/allure/package.json | 18 +- plugins/analytics-module-ga/CHANGELOG.md | 10 + plugins/analytics-module-ga/package.json | 16 +- plugins/apache-airflow/CHANGELOG.md | 9 + plugins/apache-airflow/package.json | 14 +- plugins/api-docs/CHANGELOG.md | 12 + plugins/api-docs/package.json | 20 +- plugins/apollo-explorer/CHANGELOG.md | 9 + plugins/apollo-explorer/package.json | 14 +- plugins/app-backend/CHANGELOG.md | 9 + plugins/app-backend/package.json | 12 +- plugins/auth-backend/CHANGELOG.md | 18 + plugins/auth-backend/package.json | 18 +- plugins/auth-node/CHANGELOG.md | 9 + plugins/auth-node/package.json | 12 +- plugins/azure-devops-backend/CHANGELOG.md | 8 + plugins/azure-devops-backend/package.json | 8 +- plugins/azure-devops/CHANGELOG.md | 12 + plugins/azure-devops/package.json | 20 +- plugins/badges-backend/CHANGELOG.md | 11 + plugins/badges-backend/package.json | 14 +- plugins/badges/CHANGELOG.md | 12 + plugins/badges/package.json | 20 +- plugins/bazaar-backend/CHANGELOG.md | 9 + plugins/bazaar-backend/package.json | 10 +- plugins/bazaar/CHANGELOG.md | 14 + plugins/bazaar/package.json | 20 +- plugins/bitrise/CHANGELOG.md | 11 + plugins/bitrise/package.json | 18 +- .../catalog-backend-module-aws/CHANGELOG.md | 13 + .../catalog-backend-module-aws/package.json | 18 +- .../catalog-backend-module-azure/CHANGELOG.md | 13 + .../catalog-backend-module-azure/package.json | 20 +- .../CHANGELOG.md | 10 + .../package.json | 16 +- .../CHANGELOG.md | 13 + .../package.json | 20 +- .../CHANGELOG.md | 12 + .../package.json | 18 +- .../CHANGELOG.md | 13 + .../package.json | 20 +- .../CHANGELOG.md | 15 + .../package.json | 24 +- .../CHANGELOG.md | 13 + .../package.json | 20 +- .../catalog-backend-module-ldap/CHANGELOG.md | 11 + .../catalog-backend-module-ldap/package.json | 14 +- .../CHANGELOG.md | 11 + .../package.json | 16 +- .../CHANGELOG.md | 12 + .../package.json | 18 +- plugins/catalog-backend/CHANGELOG.md | 21 + plugins/catalog-backend/package.json | 32 +- plugins/catalog-graph/CHANGELOG.md | 12 + plugins/catalog-graph/package.json | 22 +- plugins/catalog-graphql/CHANGELOG.md | 8 + plugins/catalog-graphql/package.json | 10 +- plugins/catalog-import/CHANGELOG.md | 16 + plugins/catalog-import/package.json | 28 +- plugins/catalog-node/CHANGELOG.md | 15 + plugins/catalog-node/package.json | 16 +- plugins/catalog-react/CHANGELOG.md | 17 + plugins/catalog-react/package.json | 26 +- plugins/catalog/CHANGELOG.md | 14 + plugins/catalog/package.json | 26 +- .../CHANGELOG.md | 9 + .../package.json | 10 +- plugins/cicd-statistics/CHANGELOG.md | 9 + plugins/cicd-statistics/package.json | 10 +- plugins/circleci/CHANGELOG.md | 11 + plugins/circleci/package.json | 18 +- plugins/cloudbuild/CHANGELOG.md | 11 + plugins/cloudbuild/package.json | 18 +- plugins/code-climate/CHANGELOG.md | 11 + plugins/code-climate/package.json | 16 +- plugins/code-coverage-backend/CHANGELOG.md | 12 + plugins/code-coverage-backend/package.json | 16 +- plugins/code-coverage/CHANGELOG.md | 13 + plugins/code-coverage/package.json | 22 +- plugins/codescene/CHANGELOG.md | 11 + plugins/codescene/package.json | 18 +- plugins/config-schema/CHANGELOG.md | 11 + plugins/config-schema/package.json | 18 +- plugins/cost-insights/CHANGELOG.md | 11 + plugins/cost-insights/package.json | 18 +- plugins/dynatrace/CHANGELOG.md | 10 + plugins/dynatrace/package.json | 16 +- .../example-todo-list-backend/CHANGELOG.md | 10 + .../example-todo-list-backend/package.json | 12 +- plugins/explore-react/CHANGELOG.md | 8 + plugins/explore-react/package.json | 10 +- plugins/explore/CHANGELOG.md | 12 + plugins/explore/package.json | 20 +- plugins/firehydrant/CHANGELOG.md | 10 + plugins/firehydrant/package.json | 16 +- plugins/fossa/CHANGELOG.md | 12 + plugins/fossa/package.json | 20 +- plugins/gcalendar/CHANGELOG.md | 10 + plugins/gcalendar/package.json | 16 +- plugins/gcp-projects/CHANGELOG.md | 9 + plugins/gcp-projects/package.json | 14 +- plugins/git-release-manager/CHANGELOG.md | 10 + plugins/git-release-manager/package.json | 16 +- plugins/github-actions/CHANGELOG.md | 12 + plugins/github-actions/package.json | 20 +- plugins/github-deployments/CHANGELOG.md | 14 + plugins/github-deployments/package.json | 24 +- plugins/github-issues/CHANGELOG.md | 13 + plugins/github-issues/package.json | 22 +- .../github-pull-requests-board/CHANGELOG.md | 12 + .../github-pull-requests-board/package.json | 18 +- plugins/gitops-profiles/CHANGELOG.md | 9 + plugins/gitops-profiles/package.json | 14 +- plugins/gocd/CHANGELOG.md | 12 + plugins/gocd/package.json | 20 +- plugins/graphiql/CHANGELOG.md | 9 + plugins/graphiql/package.json | 14 +- plugins/graphql-backend/CHANGELOG.md | 9 + plugins/graphql-backend/package.json | 10 +- plugins/home/CHANGELOG.md | 13 + plugins/home/package.json | 22 +- plugins/ilert/CHANGELOG.md | 12 + plugins/ilert/package.json | 20 +- plugins/jenkins-backend/CHANGELOG.md | 13 + plugins/jenkins-backend/package.json | 18 +- plugins/jenkins/CHANGELOG.md | 12 + plugins/jenkins/package.json | 20 +- plugins/kafka-backend/CHANGELOG.md | 10 + plugins/kafka-backend/package.json | 12 +- plugins/kafka/CHANGELOG.md | 12 + plugins/kafka/package.json | 20 +- plugins/kubernetes-backend/CHANGELOG.md | 13 + plugins/kubernetes-backend/package.json | 18 +- plugins/kubernetes-common/CHANGELOG.md | 7 + plugins/kubernetes-common/package.json | 6 +- plugins/kubernetes/CHANGELOG.md | 14 + plugins/kubernetes/package.json | 22 +- plugins/lighthouse/CHANGELOG.md | 12 + plugins/lighthouse/package.json | 20 +- plugins/newrelic-dashboard/CHANGELOG.md | 11 + plugins/newrelic-dashboard/package.json | 16 +- plugins/newrelic/CHANGELOG.md | 9 + plugins/newrelic/package.json | 14 +- plugins/org/CHANGELOG.md | 11 + plugins/org/package.json | 20 +- plugins/pagerduty/CHANGELOG.md | 12 + plugins/pagerduty/package.json | 20 +- plugins/periskop-backend/CHANGELOG.md | 8 + plugins/periskop-backend/package.json | 8 +- plugins/periskop/CHANGELOG.md | 12 + plugins/periskop/package.json | 20 +- plugins/permission-backend/CHANGELOG.md | 12 + plugins/permission-backend/package.json | 16 +- plugins/permission-common/CHANGELOG.md | 9 + plugins/permission-common/package.json | 8 +- plugins/permission-node/CHANGELOG.md | 11 + plugins/permission-node/package.json | 16 +- plugins/permission-react/CHANGELOG.md | 10 + plugins/permission-react/package.json | 12 +- plugins/proxy-backend/CHANGELOG.md | 8 + plugins/proxy-backend/package.json | 8 +- plugins/rollbar-backend/CHANGELOG.md | 8 + plugins/rollbar-backend/package.json | 10 +- plugins/rollbar/CHANGELOG.md | 11 + plugins/rollbar/package.json | 18 +- .../CHANGELOG.md | 12 + .../package.json | 14 +- .../CHANGELOG.md | 12 + .../package.json | 14 +- .../CHANGELOG.md | 9 + .../package.json | 10 +- plugins/scaffolder-backend/CHANGELOG.md | 18 + plugins/scaffolder-backend/package.json | 28 +- plugins/scaffolder-common/CHANGELOG.md | 7 + plugins/scaffolder-common/package.json | 6 +- plugins/scaffolder/CHANGELOG.md | 20 + plugins/scaffolder/package.json | 34 +- .../CHANGELOG.md | 8 + .../package.json | 10 +- plugins/search-backend-module-pg/CHANGELOG.md | 9 + plugins/search-backend-module-pg/package.json | 12 +- plugins/search-backend-node/CHANGELOG.md | 11 + plugins/search-backend-node/package.json | 16 +- plugins/search-backend/CHANGELOG.md | 13 + plugins/search-backend/package.json | 18 +- plugins/search/CHANGELOG.md | 13 + plugins/search/package.json | 22 +- plugins/sentry/CHANGELOG.md | 11 + plugins/sentry/package.json | 18 +- plugins/shortcuts/CHANGELOG.md | 9 + plugins/shortcuts/package.json | 14 +- plugins/sonarqube-backend/CHANGELOG.md | 9 + plugins/sonarqube-backend/package.json | 12 +- plugins/sonarqube/CHANGELOG.md | 11 + plugins/sonarqube/package.json | 18 +- plugins/splunk-on-call/CHANGELOG.md | 11 + plugins/splunk-on-call/package.json | 18 +- plugins/stack-overflow-backend/CHANGELOG.md | 8 + plugins/stack-overflow-backend/package.json | 6 +- plugins/stack-overflow/CHANGELOG.md | 11 + plugins/stack-overflow/package.json | 18 +- .../CHANGELOG.md | 10 + .../package.json | 12 +- plugins/tech-insights-backend/CHANGELOG.md | 13 + plugins/tech-insights-backend/package.json | 20 +- plugins/tech-insights-node/CHANGELOG.md | 9 + plugins/tech-insights-node/package.json | 10 +- plugins/tech-insights/CHANGELOG.md | 12 + plugins/tech-insights/package.json | 20 +- plugins/tech-radar/CHANGELOG.md | 9 + plugins/tech-radar/package.json | 14 +- .../techdocs-addons-test-utils/CHANGELOG.md | 15 + .../techdocs-addons-test-utils/package.json | 22 +- plugins/techdocs-backend/CHANGELOG.md | 14 + plugins/techdocs-backend/package.json | 24 +- .../CHANGELOG.md | 12 + .../package.json | 22 +- plugins/techdocs-node/CHANGELOG.md | 11 + plugins/techdocs-node/package.json | 14 +- plugins/techdocs-react/CHANGELOG.md | 10 + plugins/techdocs-react/package.json | 14 +- plugins/techdocs/CHANGELOG.md | 16 + plugins/techdocs/package.json | 28 +- plugins/todo-backend/CHANGELOG.md | 12 + plugins/todo-backend/package.json | 16 +- plugins/todo/CHANGELOG.md | 12 + plugins/todo/package.json | 20 +- plugins/user-settings/CHANGELOG.md | 9 + plugins/user-settings/package.json | 14 +- plugins/vault-backend/CHANGELOG.md | 11 + plugins/vault-backend/package.json | 14 +- plugins/vault/CHANGELOG.md | 12 + plugins/vault/package.json | 20 +- plugins/xcmetrics/CHANGELOG.md | 10 + plugins/xcmetrics/package.json | 16 +- yarn.lock | 2484 +++++++++-------- 307 files changed, 6104 insertions(+), 2508 deletions(-) create mode 100644 docs/releases/v1.6.0-next.3-changelog.md diff --git a/.changeset/pre.json b/.changeset/pre.json index 96664632fd..028a1a665f 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -188,19 +188,24 @@ "clever-turtles-work", "cold-frogs-kiss", "cool-cameras-count", + "cuddly-clocks-dance", "cuddly-needles-marry", "curly-hounds-wait", "dry-games-end", "dry-tips-build", "dull-spoons-doubt", + "eight-shrimps-call", "eight-spies-protect", "eleven-bees-marry", + "empty-colts-whisper", "famous-cups-roll", "famous-hounds-sit", "famous-pianos-kick", "famous-wombats-happen", "fast-paws-press", "five-carrots-pay", + "flat-crabs-love", + "flat-humans-dance", "flat-plums-shout", "flat-walls-kiss", "fresh-rabbits-juggle", @@ -211,17 +216,21 @@ "gold-laws-attend", "good-avocados-grow", "good-papayas-dress", + "gorgeous-boats-prove", + "gorgeous-pillows-retire", "gorgeous-swans-kiss", "great-cats-sit", "great-rules-march", "grumpy-kiwis-juggle", "happy-kiwis-look", "heavy-ligers-laugh", + "hot-brooms-drive", "hot-files-begin", "hot-suits-glow", "hungry-dogs-agree", "itchy-brooms-end", "itchy-kiwis-warn", + "large-books-deny", "large-eagles-shop", "large-trainers-float", "late-turtles-listen", @@ -230,13 +239,17 @@ "light-donuts-obey", "loud-comics-search", "lovely-ants-invite", + "lucky-ads-worry", "lucky-points-wash", "many-rules-raise", "mean-tomatoes-visit", + "metal-candles-tease", "metal-crabs-wash", + "metal-weeks-kiss", "moody-berries-sneeze", "neat-kangaroos-turn", "nervous-rivers-sneeze", + "new-taxis-vanish", "old-lemons-switch", "old-readers-provide", "old-rockets-doubt", @@ -247,7 +260,9 @@ "purple-jeans-bathe", "purple-plums-travel", "purple-wolves-confess", + "quick-items-invite", "quick-lamps-talk", + "rare-tips-glow", "red-numbers-suffer", "renovate-16f36a0", "renovate-1a6cc1f", @@ -263,6 +278,7 @@ "rotten-books-crash", "rude-books-rush", "rude-tips-argue", + "rude-weeks-retire", "search-feet-flash", "search-planets-flash", "search-zebras-tap", @@ -273,11 +289,14 @@ "shiny-lobsters-fix", "shiny-ties-leave", "shiny-walls-kiss", + "short-mice-explode", "silent-kings-live", "slimy-stingrays-type", "slimy-zebras-reply", + "slow-phones-count", "small-lemons-brake", "small-walls-promise", + "smart-sloths-search", "smart-squids-change", "smooth-yaks-hug", "spicy-cherries-remember", @@ -286,10 +305,13 @@ "strong-planes-return", "stupid-pigs-appear", "sweet-fishes-taste", + "sweet-grapes-explain", "swift-readers-sin", "tall-trains-remain", "tame-papayas-protect", + "tame-socks-sniff", "tame-trainers-rule", + "tasty-clouds-cover", "techdocs-feet-dress", "techdocs-jeans-wait", "tender-ladybugs-relax", @@ -298,13 +320,16 @@ "tiny-oranges-thank", "tiny-rocks-flash", "tough-dolphins-smile", + "twenty-dolls-smoke", "two-planets-provide", "veka-fingrar-drar", "weak-camels-roll", + "weak-radios-sin", "weak-yaks-learn", "wild-sheep-roll", "witty-cats-wink", "witty-queens-happen", + "young-falcons-sleep", "young-trees-rescue" ] } diff --git a/docs/releases/v1.6.0-next.3-changelog.md b/docs/releases/v1.6.0-next.3-changelog.md new file mode 100644 index 0000000000..9cf02ac93f --- /dev/null +++ b/docs/releases/v1.6.0-next.3-changelog.md @@ -0,0 +1,1768 @@ +# Release v1.6.0-next.3 + +## @backstage/catalog-client@1.1.0-next.2 + +### Minor Changes + +- 65d1d4343f: Adding `validateEntity` method that calls `/validate-entity` endpoint. + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/errors@1.1.1-next.0 + +## @backstage/plugin-auth-backend@0.16.0-next.3 + +### Minor Changes + +- 8600855fbf: The auth0 integration is updated to use the `passport-auth0` library. The configuration under `auth.providers.auth0.\*` now supports an optional `audience` parameter; providing that allows you to connect to the correct API to get permissions, access tokens, and full profile information. + + [What is an Audience](https://community.auth0.com/t/what-is-the-audience/71414) + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.1.0-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/plugin-auth-node@0.2.5-next.3 + +## @backstage/plugin-catalog-backend@1.4.0-next.3 + +### Minor Changes + +- 6e63bc43f2: Added the `refresh` function to the Connection of the entity providers. + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.1.0-next.2 + - @backstage/backend-plugin-api@0.1.2-next.2 + - @backstage/catalog-client@1.1.0-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/plugin-permission-common@0.6.4-next.2 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/plugin-scaffolder-common@1.2.0-next.1 + - @backstage/plugin-permission-node@0.6.5-next.3 + +## @backstage/plugin-catalog-node@1.1.0-next.2 + +### Minor Changes + +- 9743bc788c: Added refresh function to the `EntityProviderConnection` to be able to schedule refreshes from entity providers. + +### Patch Changes + +- 409ed984e8: Updated usage of experimental backend service APIs. +- Updated dependencies + - @backstage/backend-plugin-api@0.1.2-next.2 + - @backstage/catalog-client@1.1.0-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/errors@1.1.1-next.0 + +## @backstage/app-defaults@1.0.6-next.2 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- d9e39544be: Add missing peer dependencies +- Updated dependencies + - @backstage/core-app-api@1.1.0-next.3 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/plugin-permission-react@0.4.5-next.2 + +## @backstage/backend-app-api@0.2.1-next.2 + +### Patch Changes + +- 854ba37357: Updated to support new `ServiceFactory` formats. +- 409ed984e8: Updated service implementations and backend wiring to support scoped service. +- Updated dependencies + - @backstage/backend-plugin-api@0.1.2-next.2 + - @backstage/errors@1.1.1-next.0 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/backend-tasks@0.3.5-next.1 + - @backstage/plugin-permission-node@0.6.5-next.3 + +## @backstage/backend-common@0.15.1-next.3 + +### Patch Changes + +- 96689fbdcb: Workaround for a rare race condition in tests. +- Updated dependencies + - @backstage/config-loader@1.1.4-next.2 + - @backstage/cli-common@0.1.10-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + +## @backstage/backend-defaults@0.1.1-next.1 + +### Patch Changes + +- 854ba37357: Updated to support new `ServiceFactory` formats. +- Updated dependencies + - @backstage/backend-plugin-api@0.1.2-next.2 + - @backstage/backend-app-api@0.2.1-next.2 + +## @backstage/backend-plugin-api@0.1.2-next.2 + +### Patch Changes + +- 409ed984e8: Service are now scoped to either `'plugin'` or `'root'` scope. Service factories have been updated to provide dependency instances directly rather than factory functions. +- 854ba37357: The `createServiceFactory` method has been updated to return a higher-order factory that can accept options. +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/plugin-permission-common@0.6.4-next.2 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/backend-tasks@0.3.5-next.1 + +## @backstage/backend-tasks@0.3.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/backend-common@0.15.1-next.3 + +## @backstage/backend-test-utils@0.1.28-next.3 + +### Patch Changes + +- 854ba37357: Updated to support new `ServiceFactory` formats. +- Updated dependencies + - @backstage/backend-plugin-api@0.1.2-next.2 + - @backstage/config@1.0.2-next.0 + - @backstage/backend-app-api@0.2.1-next.2 + - @backstage/cli@0.19.0-next.3 + - @backstage/backend-common@0.15.1-next.3 + +## @backstage/catalog-model@1.1.1-next.0 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + +## @backstage/cli@0.19.0-next.3 + +### Patch Changes + +- 7d47def9c4: Added dependency on `@types/jest` v27. The `@types/jest` dependency has also been removed from the plugin template and should be removed from any of your own internal packages. If you wish to override the version of `@types/jest` or `jest`, use Yarn resolutions. +- a7e82c9b01: Updated `versions:bump` command to be compatible with Yarn 3. +- Updated dependencies + - @backstage/config-loader@1.1.4-next.2 + - @backstage/cli-common@0.1.10-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/release-manifests@0.0.6-next.2 + +## @backstage/cli-common@0.1.10-next.0 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. + +## @backstage/codemods@0.1.39-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/cli-common@0.1.10-next.0 + +## @backstage/config@1.0.2-next.0 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. + +## @backstage/config-loader@1.1.4-next.2 + +### Patch Changes + +- 5ecca7e44b: No longer log when reloading remote config. +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/cli-common@0.1.10-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + +## @backstage/core-app-api@1.1.0-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/core-plugin-api@1.0.6-next.3 + +## @backstage/core-components@0.11.1-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + +## @backstage/core-plugin-api@1.0.6-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/config@1.0.2-next.0 + +## @backstage/create-app@0.4.31-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/cli-common@0.1.10-next.0 + +## @backstage/dev-utils@1.0.6-next.2 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- 329ed2b9c7: Fixed routing when using React Router v6 stable. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/app-defaults@1.0.6-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-app-api@1.1.0-next.3 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/integration-react@1.1.4-next.2 + - @backstage/test-utils@1.2.0-next.3 + +## @backstage/errors@1.1.1-next.0 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. + +## @backstage/integration@1.3.1-next.2 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- f76f22c649: Improved caching around github app tokens. + Tokens are now cached for 50 minutes, not 10. + Calls to get app installations are also included in this cache. + If you have more than one github app configured, consider adding `allowedInstallationOwners` to your apps configuration to gain the most benefit from these performance changes. +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + +## @backstage/integration-react@1.1.4-next.2 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/integration@1.3.1-next.2 + +## @backstage/release-manifests@0.0.6-next.2 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. + +## @techdocs/cli@1.2.1-next.2 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/cli-common@0.1.10-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/plugin-techdocs-node@1.4.0-next.2 + +## @backstage/test-utils@1.2.0-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- d9e39544be: Add missing peer dependencies +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/core-app-api@1.1.0-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/plugin-permission-common@0.6.4-next.2 + - @backstage/plugin-permission-react@0.4.5-next.2 + +## @backstage/plugin-adr@0.2.1-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/integration-react@1.1.4-next.2 + - @backstage/plugin-adr-common@0.2.1-next.1 + +## @backstage/plugin-adr-backend@0.2.1-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.1.0-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/plugin-adr-common@0.2.1-next.1 + +## @backstage/plugin-adr-common@0.2.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + +## @backstage/plugin-airbrake@0.3.9-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/dev-utils@1.0.6-next.2 + - @backstage/test-utils@1.2.0-next.3 + +## @backstage/plugin-airbrake-backend@0.2.9-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/backend-common@0.15.1-next.3 + +## @backstage/plugin-allure@0.1.25-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + +## @backstage/plugin-analytics-module-ga@0.1.20-next.2 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + +## @backstage/plugin-apache-airflow@0.2.2-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + +## @backstage/plugin-api-docs@0.8.9-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/plugin-catalog@1.5.1-next.3 + +## @backstage/plugin-apollo-explorer@0.1.2-next.2 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + +## @backstage/plugin-app-backend@0.3.36-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.1.4-next.2 + - @backstage/config@1.0.2-next.0 + - @backstage/backend-common@0.15.1-next.3 + +## @backstage/plugin-auth-node@0.2.5-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/backend-common@0.15.1-next.3 + +## @backstage/plugin-azure-devops@0.2.0-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + +## @backstage/plugin-azure-devops-backend@0.3.15-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/backend-common@0.15.1-next.3 + +## @backstage/plugin-badges@0.2.33-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + +## @backstage/plugin-badges-backend@0.1.30-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.1.0-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/backend-common@0.15.1-next.3 + +## @backstage/plugin-bazaar@0.1.24-next.2 + +### Patch Changes + +- 1dd12349d1: Fixed broken routing by removing the wrapping `Router` from the `RoutedTabs` children. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-client@1.1.0-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/plugin-catalog@1.5.1-next.3 + - @backstage/cli@0.19.0-next.3 + +## @backstage/plugin-bazaar-backend@0.1.20-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/backend-test-utils@0.1.28-next.3 + - @backstage/backend-common@0.15.1-next.3 + +## @backstage/plugin-bitrise@0.1.36-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + +## @backstage/plugin-catalog@1.5.1-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-client@1.1.0-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration-react@1.1.4-next.2 + +## @backstage/plugin-catalog-backend-module-aws@0.1.9-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/plugin-catalog-backend@1.4.0-next.3 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/backend-tasks@0.3.5-next.1 + +## @backstage/plugin-catalog-backend-module-azure@0.1.7-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/plugin-catalog-backend@1.4.0-next.3 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/backend-tasks@0.3.5-next.1 + +## @backstage/plugin-catalog-backend-module-bitbucket@0.2.3-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/plugin-catalog-backend@1.4.0-next.3 + - @backstage/backend-common@0.15.1-next.3 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.1.3-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/plugin-catalog-backend@1.4.0-next.3 + - @backstage/backend-tasks@0.3.5-next.1 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.1.1-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/plugin-catalog-backend@1.4.0-next.3 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/backend-tasks@0.3.5-next.1 + +## @backstage/plugin-catalog-backend-module-gerrit@0.1.4-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/plugin-catalog-backend@1.4.0-next.3 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/backend-tasks@0.3.5-next.1 + +## @backstage/plugin-catalog-backend-module-github@0.1.7-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.1.0-next.2 + - @backstage/backend-plugin-api@0.1.2-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/plugin-catalog-backend@1.4.0-next.3 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/backend-tasks@0.3.5-next.1 + +## @backstage/plugin-catalog-backend-module-gitlab@0.1.7-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/plugin-catalog-backend@1.4.0-next.3 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/backend-tasks@0.3.5-next.1 + +## @backstage/plugin-catalog-backend-module-ldap@0.5.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/plugin-catalog-backend@1.4.0-next.3 + - @backstage/backend-tasks@0.3.5-next.1 + +## @backstage/plugin-catalog-backend-module-msgraph@0.4.2-next.3 + +### Patch Changes + +- d80aab31ae: Added $select attribute to user query +- Updated dependencies + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/plugin-catalog-backend@1.4.0-next.3 + - @backstage/backend-tasks@0.3.5-next.1 + +## @backstage/plugin-catalog-backend-module-openapi@0.1.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.1.0-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/plugin-catalog-backend@1.4.0-next.3 + - @backstage/backend-common@0.15.1-next.3 + +## @backstage/plugin-catalog-graph@0.2.21-next.2 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-client@1.1.0-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + +## @backstage/plugin-catalog-graphql@0.3.13-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + +## @backstage/plugin-catalog-import@0.8.12-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-client@1.1.0-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/integration-react@1.1.4-next.2 + +## @backstage/plugin-catalog-react@1.1.4-next.2 + +### Patch Changes + +- f6033d1121: humanizeEntityRef function can now be forced to include default namespace +- c86741a052: Support showing counts in option labels of the `EntityTagPicker`. You can enable this by adding the `showCounts` property +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/catalog-client@1.1.0-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/plugin-permission-common@0.6.4-next.2 + - @backstage/plugin-permission-react@0.4.5-next.2 + +## @backstage/plugin-cicd-statistics@0.1.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-plugin-api@1.0.6-next.3 + +## @backstage/plugin-cicd-statistics-module-gitlab@0.1.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/plugin-cicd-statistics@0.1.11-next.2 + +## @backstage/plugin-circleci@0.3.9-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + +## @backstage/plugin-cloudbuild@0.3.9-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + +## @backstage/plugin-code-climate@0.1.9-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + +## @backstage/plugin-code-coverage@0.2.2-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + +## @backstage/plugin-code-coverage-backend@0.2.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.1.0-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/backend-common@0.15.1-next.3 + +## @backstage/plugin-codescene@0.1.4-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + +## @backstage/plugin-config-schema@0.1.32-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + +## @backstage/plugin-cost-insights@0.11.31-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + +## @backstage/plugin-dynatrace@0.2.0-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + +## @backstage/plugin-explore@0.3.40-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/plugin-explore-react@0.0.21-next.3 + +## @backstage/plugin-explore-react@0.0.21-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/core-plugin-api@1.0.6-next.3 + +## @backstage/plugin-firehydrant@0.1.26-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + +## @backstage/plugin-fossa@0.2.41-next.2 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + +## @backstage/plugin-gcalendar@0.3.5-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + +## @backstage/plugin-gcp-projects@0.3.28-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + +## @backstage/plugin-git-release-manager@0.3.22-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/integration@1.3.1-next.2 + +## @backstage/plugin-github-actions@0.5.9-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/integration@1.3.1-next.2 + +## @backstage/plugin-github-deployments@0.1.40-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/integration-react@1.1.4-next.2 + +## @backstage/plugin-github-issues@0.1.1-next.2 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + +## @backstage/plugin-github-pull-requests-board@0.1.3-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/integration@1.3.1-next.2 + +## @backstage/plugin-gitops-profiles@0.3.27-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + +## @backstage/plugin-gocd@0.1.15-next.2 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + +## @backstage/plugin-graphiql@0.2.41-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + +## @backstage/plugin-graphql-backend@0.1.26-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/plugin-catalog-graphql@0.3.13-next.3 + +## @backstage/plugin-home@0.4.25-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/plugin-stack-overflow@0.1.5-next.3 + +## @backstage/plugin-ilert@0.1.35-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + +## @backstage/plugin-jenkins@0.7.8-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + +## @backstage/plugin-jenkins-backend@0.1.26-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.1.0-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/plugin-permission-common@0.6.4-next.2 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/plugin-auth-node@0.2.5-next.3 + +## @backstage/plugin-kafka@0.3.9-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + +## @backstage/plugin-kafka-backend@0.2.29-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/backend-common@0.15.1-next.3 + +## @backstage/plugin-kubernetes@0.7.2-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- 19a27929fb: Reset error state on success +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/plugin-kubernetes-common@0.4.2-next.1 + +## @backstage/plugin-kubernetes-backend@0.7.2-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.1.0-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/plugin-kubernetes-common@0.4.2-next.1 + - @backstage/plugin-auth-node@0.2.5-next.3 + +## @backstage/plugin-kubernetes-common@0.4.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.1.1-next.0 + +## @backstage/plugin-lighthouse@0.3.9-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + +## @backstage/plugin-newrelic@0.3.27-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + +## @backstage/plugin-newrelic-dashboard@0.2.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + +## @backstage/plugin-org@0.5.9-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + +## @backstage/plugin-pagerduty@0.5.2-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + +## @backstage/plugin-periskop@0.1.7-next.2 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + +## @backstage/plugin-periskop-backend@0.1.7-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/backend-common@0.15.1-next.3 + +## @backstage/plugin-permission-backend@0.5.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/plugin-permission-common@0.6.4-next.2 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/plugin-auth-node@0.2.5-next.3 + - @backstage/plugin-permission-node@0.6.5-next.3 + +## @backstage/plugin-permission-common@0.6.4-next.2 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + +## @backstage/plugin-permission-node@0.6.5-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/plugin-permission-common@0.6.4-next.2 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/plugin-auth-node@0.2.5-next.3 + +## @backstage/plugin-permission-react@0.4.5-next.2 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/plugin-permission-common@0.6.4-next.2 + +## @backstage/plugin-proxy-backend@0.2.30-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/backend-common@0.15.1-next.3 + +## @backstage/plugin-rollbar@0.4.9-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + +## @backstage/plugin-rollbar-backend@0.1.33-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/backend-common@0.15.1-next.3 + +## @backstage/plugin-scaffolder@1.6.0-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- 6522e459aa: Support displaying and ordering by counts in `EntityTagPicker` field. Add the `showCounts` option to enable this. Also support configuring `helperText`. +- f0510a20b5: Addition of a dismissible Error Banner in Scaffolder page +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-client@1.1.0-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/integration-react@1.1.4-next.2 + - @backstage/plugin-permission-react@0.4.5-next.2 + - @backstage/plugin-scaffolder-common@1.2.0-next.1 + +## @backstage/plugin-scaffolder-backend@1.6.0-next.3 + +### Patch Changes + +- 50467bc15b: The number of task workers used to execute templates now default to 3, rather than 1. +- Updated dependencies + - @backstage/plugin-catalog-node@1.1.0-next.2 + - @backstage/backend-plugin-api@0.1.2-next.2 + - @backstage/catalog-client@1.1.0-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/plugin-catalog-backend@1.4.0-next.3 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/plugin-scaffolder-common@1.2.0-next.1 + - @backstage/plugin-auth-node@0.2.5-next.3 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.2.11-next.2 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/plugin-scaffolder-backend@1.6.0-next.3 + +## @backstage/plugin-scaffolder-backend-module-rails@0.4.4-next.1 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/plugin-scaffolder-backend@1.6.0-next.3 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.2.9-next.1 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/plugin-scaffolder-backend@1.6.0-next.3 + +## @backstage/plugin-scaffolder-common@1.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.1.1-next.0 + +## @backstage/plugin-search@1.0.2-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + +## @backstage/plugin-search-backend@1.0.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/plugin-permission-common@0.6.4-next.2 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/plugin-auth-node@0.2.5-next.3 + - @backstage/plugin-permission-node@0.6.5-next.3 + - @backstage/plugin-search-backend-node@1.0.2-next.2 + +## @backstage/plugin-search-backend-module-elasticsearch@1.0.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/plugin-search-backend-node@1.0.2-next.2 + +## @backstage/plugin-search-backend-module-pg@0.4.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/plugin-search-backend-node@1.0.2-next.2 + +## @backstage/plugin-search-backend-node@1.0.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/plugin-permission-common@0.6.4-next.2 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/backend-tasks@0.3.5-next.1 + +## @backstage/plugin-sentry@0.4.2-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + +## @backstage/plugin-shortcuts@0.3.1-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + +## @backstage/plugin-sonarqube@0.4.1-next.2 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + +## @backstage/plugin-sonarqube-backend@0.1.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/backend-common@0.15.1-next.3 + +## @backstage/plugin-splunk-on-call@0.3.33-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + +## @backstage/plugin-stack-overflow@0.1.5-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/plugin-home@0.4.25-next.3 + +## @backstage/plugin-stack-overflow-backend@0.1.5-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/cli@0.19.0-next.3 + +## @backstage/plugin-tech-insights@0.3.0-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + +## @backstage/plugin-tech-insights-backend@0.5.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.1.0-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/backend-tasks@0.3.5-next.1 + - @backstage/plugin-tech-insights-node@0.3.4-next.1 + +## @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.20-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/plugin-tech-insights-node@0.3.4-next.1 + +## @backstage/plugin-tech-insights-node@0.3.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/backend-tasks@0.3.5-next.1 + +## @backstage/plugin-tech-radar@0.5.16-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + +## @backstage/plugin-techdocs@1.3.2-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/integration-react@1.1.4-next.2 + - @backstage/plugin-techdocs-react@1.0.4-next.2 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.4-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/core-app-api@1.1.0-next.3 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/integration-react@1.1.4-next.2 + - @backstage/test-utils@1.2.0-next.3 + - @backstage/plugin-catalog@1.5.1-next.3 + - @backstage/plugin-techdocs@1.3.2-next.3 + - @backstage/plugin-techdocs-react@1.0.4-next.2 + +## @backstage/plugin-techdocs-backend@1.3.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.1.0-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/plugin-permission-common@0.6.4-next.2 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/plugin-techdocs-node@1.4.0-next.2 + +## @backstage/plugin-techdocs-module-addons-contrib@1.0.4-next.2 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/integration@1.3.1-next.2 + - @backstage/integration-react@1.1.4-next.2 + - @backstage/plugin-techdocs-react@1.0.4-next.2 + +## @backstage/plugin-techdocs-node@1.4.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/backend-common@0.15.1-next.3 + +## @backstage/plugin-techdocs-react@1.0.4-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + +## @backstage/plugin-todo@0.2.11-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + +## @backstage/plugin-todo-backend@0.1.33-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.1.0-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/backend-common@0.15.1-next.3 + +## @backstage/plugin-user-settings@0.4.8-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + +## @backstage/plugin-vault@0.1.3-next.2 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + +## @backstage/plugin-vault-backend@0.2.2-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/backend-test-utils@0.1.28-next.3 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/backend-tasks@0.3.5-next.1 + +## @backstage/plugin-xcmetrics@0.2.29-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + +## example-app@0.2.75-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/app-defaults@1.0.6-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/core-app-api@1.1.0-next.3 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/integration-react@1.1.4-next.2 + - @backstage/plugin-airbrake@0.3.9-next.3 + - @backstage/plugin-apache-airflow@0.2.2-next.3 + - @backstage/plugin-api-docs@0.8.9-next.3 + - @backstage/plugin-azure-devops@0.2.0-next.3 + - @backstage/plugin-badges@0.2.33-next.3 + - @backstage/plugin-catalog-graph@0.2.21-next.2 + - @backstage/plugin-catalog-import@0.8.12-next.3 + - @backstage/plugin-circleci@0.3.9-next.3 + - @backstage/plugin-cloudbuild@0.3.9-next.3 + - @backstage/plugin-code-coverage@0.2.2-next.3 + - @backstage/plugin-cost-insights@0.11.31-next.3 + - @backstage/plugin-dynatrace@0.2.0-next.3 + - @backstage/plugin-explore@0.3.40-next.3 + - @backstage/plugin-gcalendar@0.3.5-next.3 + - @backstage/plugin-gcp-projects@0.3.28-next.3 + - @backstage/plugin-github-actions@0.5.9-next.3 + - @backstage/plugin-gocd@0.1.15-next.2 + - @backstage/plugin-graphiql@0.2.41-next.3 + - @backstage/plugin-home@0.4.25-next.3 + - @backstage/plugin-jenkins@0.7.8-next.3 + - @backstage/plugin-kafka@0.3.9-next.3 + - @backstage/plugin-kubernetes@0.7.2-next.3 + - @backstage/plugin-lighthouse@0.3.9-next.3 + - @backstage/plugin-newrelic@0.3.27-next.3 + - @backstage/plugin-org@0.5.9-next.3 + - @backstage/plugin-pagerduty@0.5.2-next.3 + - @backstage/plugin-permission-react@0.4.5-next.2 + - @backstage/plugin-rollbar@0.4.9-next.3 + - @backstage/plugin-scaffolder@1.6.0-next.3 + - @backstage/plugin-search@1.0.2-next.3 + - @backstage/plugin-sentry@0.4.2-next.3 + - @backstage/plugin-shortcuts@0.3.1-next.3 + - @backstage/plugin-stack-overflow@0.1.5-next.3 + - @backstage/plugin-tech-insights@0.3.0-next.3 + - @backstage/plugin-tech-radar@0.5.16-next.3 + - @backstage/plugin-techdocs@1.3.2-next.3 + - @backstage/plugin-techdocs-module-addons-contrib@1.0.4-next.2 + - @backstage/plugin-todo@0.2.11-next.3 + - @backstage/plugin-user-settings@0.4.8-next.3 + - @backstage/cli@0.19.0-next.3 + - @backstage/plugin-newrelic-dashboard@0.2.2-next.2 + - @backstage/plugin-techdocs-react@1.0.4-next.2 + +## example-backend@0.2.75-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.1.0-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/plugin-permission-common@0.6.4-next.2 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.4-next.1 + - @backstage/plugin-catalog-backend@1.4.0-next.3 + - @backstage/plugin-auth-backend@0.16.0-next.3 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/plugin-scaffolder-backend@1.6.0-next.3 + - @backstage/plugin-badges-backend@0.1.30-next.1 + - @backstage/plugin-code-coverage-backend@0.2.2-next.2 + - @backstage/plugin-jenkins-backend@0.1.26-next.3 + - @backstage/plugin-kubernetes-backend@0.7.2-next.3 + - @backstage/plugin-tech-insights-backend@0.5.2-next.2 + - @backstage/plugin-techdocs-backend@1.3.0-next.2 + - @backstage/plugin-todo-backend@0.1.33-next.2 + - example-app@0.2.75-next.3 + - @backstage/plugin-kafka-backend@0.2.29-next.1 + - @backstage/backend-tasks@0.3.5-next.1 + - @backstage/plugin-app-backend@0.3.36-next.3 + - @backstage/plugin-auth-node@0.2.5-next.3 + - @backstage/plugin-azure-devops-backend@0.3.15-next.2 + - @backstage/plugin-graphql-backend@0.1.26-next.3 + - @backstage/plugin-permission-backend@0.5.11-next.2 + - @backstage/plugin-permission-node@0.6.5-next.3 + - @backstage/plugin-proxy-backend@0.2.30-next.2 + - @backstage/plugin-rollbar-backend@0.1.33-next.3 + - @backstage/plugin-search-backend@1.0.2-next.1 + - @backstage/plugin-search-backend-module-elasticsearch@1.0.2-next.2 + - @backstage/plugin-search-backend-module-pg@0.4.0-next.2 + - @backstage/plugin-search-backend-node@1.0.2-next.2 + - @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.20-next.1 + - @backstage/plugin-tech-insights-node@0.3.4-next.1 + +## techdocs-cli-embedded-app@0.2.74-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/app-defaults@1.0.6-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/core-app-api@1.1.0-next.3 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/integration-react@1.1.4-next.2 + - @backstage/test-utils@1.2.0-next.3 + - @backstage/plugin-catalog@1.5.1-next.3 + - @backstage/plugin-techdocs@1.3.2-next.3 + - @backstage/cli@0.19.0-next.3 + - @backstage/plugin-techdocs-react@1.0.4-next.2 + +## @internal/plugin-todo-list-backend@1.0.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/plugin-auth-node@0.2.5-next.3 diff --git a/package.json b/package.json index 3c9e2743cb..a0de99bfad 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "@types/react": "^17", "@types/react-dom": "^17" }, - "version": "1.6.0-next.2", + "version": "1.6.0-next.3", "dependencies": { "@manypkg/get-packages": "^1.1.3", "@microsoft/api-documenter": "^7.17.11", diff --git a/packages/app-defaults/CHANGELOG.md b/packages/app-defaults/CHANGELOG.md index 799c380dbc..c9216bf2a4 100644 --- a/packages/app-defaults/CHANGELOG.md +++ b/packages/app-defaults/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/app-defaults +## 1.0.6-next.2 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- d9e39544be: Add missing peer dependencies +- Updated dependencies + - @backstage/core-app-api@1.1.0-next.3 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/plugin-permission-react@0.4.5-next.2 + ## 1.0.6-next.1 ### Patch Changes diff --git a/packages/app-defaults/package.json b/packages/app-defaults/package.json index 355a7ee77e..c83e31b057 100644 --- a/packages/app-defaults/package.json +++ b/packages/app-defaults/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/app-defaults", "description": "Provides the default wiring of a Backstage App", - "version": "1.0.6-next.1", + "version": "1.0.6-next.2", "publishConfig": { "access": "public", "main": "dist/index.esm.js", @@ -32,10 +32,10 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/core-app-api": "^1.1.0-next.1", - "@backstage/core-components": "^0.11.1-next.1", - "@backstage/core-plugin-api": "^1.0.6-next.1", - "@backstage/plugin-permission-react": "^0.4.5-next.1", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/plugin-permission-react": "^0.4.5-next.2", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1" @@ -47,8 +47,8 @@ "react-router-dom": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.1", - "@backstage/test-utils": "^1.2.0-next.1", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@types/node": "^16.11.26", diff --git a/packages/app/CHANGELOG.md b/packages/app/CHANGELOG.md index ec851aa8d0..f763210b27 100644 --- a/packages/app/CHANGELOG.md +++ b/packages/app/CHANGELOG.md @@ -1,5 +1,61 @@ # example-app +## 0.2.75-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/app-defaults@1.0.6-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/core-app-api@1.1.0-next.3 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/integration-react@1.1.4-next.2 + - @backstage/plugin-airbrake@0.3.9-next.3 + - @backstage/plugin-apache-airflow@0.2.2-next.3 + - @backstage/plugin-api-docs@0.8.9-next.3 + - @backstage/plugin-azure-devops@0.2.0-next.3 + - @backstage/plugin-badges@0.2.33-next.3 + - @backstage/plugin-catalog-graph@0.2.21-next.2 + - @backstage/plugin-catalog-import@0.8.12-next.3 + - @backstage/plugin-circleci@0.3.9-next.3 + - @backstage/plugin-cloudbuild@0.3.9-next.3 + - @backstage/plugin-code-coverage@0.2.2-next.3 + - @backstage/plugin-cost-insights@0.11.31-next.3 + - @backstage/plugin-dynatrace@0.2.0-next.3 + - @backstage/plugin-explore@0.3.40-next.3 + - @backstage/plugin-gcalendar@0.3.5-next.3 + - @backstage/plugin-gcp-projects@0.3.28-next.3 + - @backstage/plugin-github-actions@0.5.9-next.3 + - @backstage/plugin-gocd@0.1.15-next.2 + - @backstage/plugin-graphiql@0.2.41-next.3 + - @backstage/plugin-home@0.4.25-next.3 + - @backstage/plugin-jenkins@0.7.8-next.3 + - @backstage/plugin-kafka@0.3.9-next.3 + - @backstage/plugin-kubernetes@0.7.2-next.3 + - @backstage/plugin-lighthouse@0.3.9-next.3 + - @backstage/plugin-newrelic@0.3.27-next.3 + - @backstage/plugin-org@0.5.9-next.3 + - @backstage/plugin-pagerduty@0.5.2-next.3 + - @backstage/plugin-permission-react@0.4.5-next.2 + - @backstage/plugin-rollbar@0.4.9-next.3 + - @backstage/plugin-scaffolder@1.6.0-next.3 + - @backstage/plugin-search@1.0.2-next.3 + - @backstage/plugin-sentry@0.4.2-next.3 + - @backstage/plugin-shortcuts@0.3.1-next.3 + - @backstage/plugin-stack-overflow@0.1.5-next.3 + - @backstage/plugin-tech-insights@0.3.0-next.3 + - @backstage/plugin-tech-radar@0.5.16-next.3 + - @backstage/plugin-techdocs@1.3.2-next.3 + - @backstage/plugin-techdocs-module-addons-contrib@1.0.4-next.2 + - @backstage/plugin-todo@0.2.11-next.3 + - @backstage/plugin-user-settings@0.4.8-next.3 + - @backstage/cli@0.19.0-next.3 + - @backstage/plugin-newrelic-dashboard@0.2.2-next.2 + - @backstage/plugin-techdocs-react@1.0.4-next.2 + ## 0.2.75-next.2 ### Patch Changes diff --git a/packages/app/package.json b/packages/app/package.json index e9c9632d81..df68e1032c 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,65 +1,65 @@ { "name": "example-app", - "version": "0.2.75-next.2", + "version": "0.2.75-next.3", "private": true, "backstage": { "role": "frontend" }, "bundled": true, "dependencies": { - "@backstage/app-defaults": "^1.0.6-next.1", - "@backstage/catalog-model": "^1.1.0", - "@backstage/cli": "^0.19.0-next.2", - "@backstage/config": "^1.0.1", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/integration-react": "^1.1.4-next.1", - "@backstage/plugin-airbrake": "^0.3.9-next.2", - "@backstage/plugin-apache-airflow": "^0.2.2-next.2", - "@backstage/plugin-api-docs": "^0.8.9-next.2", - "@backstage/plugin-azure-devops": "^0.2.0-next.2", - "@backstage/plugin-badges": "^0.2.33-next.2", + "@backstage/app-defaults": "^1.0.6-next.2", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/config": "^1.0.2-next.0", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/integration-react": "^1.1.4-next.2", + "@backstage/plugin-airbrake": "^0.3.9-next.3", + "@backstage/plugin-apache-airflow": "^0.2.2-next.3", + "@backstage/plugin-api-docs": "^0.8.9-next.3", + "@backstage/plugin-azure-devops": "^0.2.0-next.3", + "@backstage/plugin-badges": "^0.2.33-next.3", "@backstage/plugin-catalog-common": "^1.0.6-next.0", - "@backstage/plugin-catalog-graph": "^0.2.21-next.1", - "@backstage/plugin-catalog-import": "^0.8.12-next.2", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", - "@backstage/plugin-circleci": "^0.3.9-next.2", - "@backstage/plugin-cloudbuild": "^0.3.9-next.2", - "@backstage/plugin-code-coverage": "^0.2.2-next.2", - "@backstage/plugin-cost-insights": "^0.11.31-next.2", - "@backstage/plugin-dynatrace": "^0.2.0-next.2", - "@backstage/plugin-explore": "^0.3.40-next.2", - "@backstage/plugin-gcalendar": "^0.3.5-next.2", - "@backstage/plugin-gcp-projects": "^0.3.28-next.2", - "@backstage/plugin-github-actions": "^0.5.9-next.2", - "@backstage/plugin-gocd": "^0.1.15-next.1", - "@backstage/plugin-graphiql": "^0.2.41-next.2", - "@backstage/plugin-home": "^0.4.25-next.2", - "@backstage/plugin-jenkins": "^0.7.8-next.2", - "@backstage/plugin-kafka": "^0.3.9-next.2", - "@backstage/plugin-kubernetes": "^0.7.2-next.2", - "@backstage/plugin-lighthouse": "^0.3.9-next.2", - "@backstage/plugin-newrelic": "^0.3.27-next.2", - "@backstage/plugin-newrelic-dashboard": "^0.2.2-next.1", - "@backstage/plugin-org": "^0.5.9-next.2", - "@backstage/plugin-pagerduty": "0.5.2-next.2", - "@backstage/plugin-permission-react": "^0.4.5-next.1", - "@backstage/plugin-rollbar": "^0.4.9-next.2", - "@backstage/plugin-scaffolder": "^1.6.0-next.2", - "@backstage/plugin-search": "^1.0.2-next.2", + "@backstage/plugin-catalog-graph": "^0.2.21-next.2", + "@backstage/plugin-catalog-import": "^0.8.12-next.3", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", + "@backstage/plugin-circleci": "^0.3.9-next.3", + "@backstage/plugin-cloudbuild": "^0.3.9-next.3", + "@backstage/plugin-code-coverage": "^0.2.2-next.3", + "@backstage/plugin-cost-insights": "^0.11.31-next.3", + "@backstage/plugin-dynatrace": "^0.2.0-next.3", + "@backstage/plugin-explore": "^0.3.40-next.3", + "@backstage/plugin-gcalendar": "^0.3.5-next.3", + "@backstage/plugin-gcp-projects": "^0.3.28-next.3", + "@backstage/plugin-github-actions": "^0.5.9-next.3", + "@backstage/plugin-gocd": "^0.1.15-next.2", + "@backstage/plugin-graphiql": "^0.2.41-next.3", + "@backstage/plugin-home": "^0.4.25-next.3", + "@backstage/plugin-jenkins": "^0.7.8-next.3", + "@backstage/plugin-kafka": "^0.3.9-next.3", + "@backstage/plugin-kubernetes": "^0.7.2-next.3", + "@backstage/plugin-lighthouse": "^0.3.9-next.3", + "@backstage/plugin-newrelic": "^0.3.27-next.3", + "@backstage/plugin-newrelic-dashboard": "^0.2.2-next.2", + "@backstage/plugin-org": "^0.5.9-next.3", + "@backstage/plugin-pagerduty": "0.5.2-next.3", + "@backstage/plugin-permission-react": "^0.4.5-next.2", + "@backstage/plugin-rollbar": "^0.4.9-next.3", + "@backstage/plugin-scaffolder": "^1.6.0-next.3", + "@backstage/plugin-search": "^1.0.2-next.3", "@backstage/plugin-search-common": "^1.0.1-next.0", "@backstage/plugin-search-react": "^1.1.0-next.2", - "@backstage/plugin-sentry": "^0.4.2-next.2", - "@backstage/plugin-shortcuts": "^0.3.1-next.2", - "@backstage/plugin-stack-overflow": "^0.1.5-next.2", - "@backstage/plugin-tech-insights": "^0.3.0-next.2", - "@backstage/plugin-tech-radar": "^0.5.16-next.2", - "@backstage/plugin-techdocs": "^1.3.2-next.2", - "@backstage/plugin-techdocs-module-addons-contrib": "^1.0.4-next.1", - "@backstage/plugin-techdocs-react": "^1.0.4-next.1", - "@backstage/plugin-todo": "^0.2.11-next.2", - "@backstage/plugin-user-settings": "^0.4.8-next.2", + "@backstage/plugin-sentry": "^0.4.2-next.3", + "@backstage/plugin-shortcuts": "^0.3.1-next.3", + "@backstage/plugin-stack-overflow": "^0.1.5-next.3", + "@backstage/plugin-tech-insights": "^0.3.0-next.3", + "@backstage/plugin-tech-radar": "^0.5.16-next.3", + "@backstage/plugin-techdocs": "^1.3.2-next.3", + "@backstage/plugin-techdocs-module-addons-contrib": "^1.0.4-next.2", + "@backstage/plugin-techdocs-react": "^1.0.4-next.2", + "@backstage/plugin-todo": "^0.2.11-next.3", + "@backstage/plugin-user-settings": "^0.4.8-next.3", "@backstage/theme": "^0.2.16", "@internal/plugin-catalog-customized": "0.0.2-next.0", "@material-ui/core": "^4.12.2", @@ -80,7 +80,7 @@ "zen-observable": "^0.8.15" }, "devDependencies": { - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@rjsf/core": "^3.2.1", "@testing-library/cypress": "^8.0.2", "@testing-library/jest-dom": "^5.10.1", diff --git a/packages/backend-app-api/CHANGELOG.md b/packages/backend-app-api/CHANGELOG.md index 635dad30d0..a9ab990f92 100644 --- a/packages/backend-app-api/CHANGELOG.md +++ b/packages/backend-app-api/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/backend-app-api +## 0.2.1-next.2 + +### Patch Changes + +- 854ba37357: Updated to support new `ServiceFactory` formats. +- 409ed984e8: Updated service implementations and backend wiring to support scoped service. +- Updated dependencies + - @backstage/backend-plugin-api@0.1.2-next.2 + - @backstage/errors@1.1.1-next.0 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/backend-tasks@0.3.5-next.1 + - @backstage/plugin-permission-node@0.6.5-next.3 + ## 0.2.1-next.1 ### Patch Changes diff --git a/packages/backend-app-api/package.json b/packages/backend-app-api/package.json index d4379bcde6..a028af090f 100644 --- a/packages/backend-app-api/package.json +++ b/packages/backend-app-api/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-app-api", "description": "Core API used by Backstage backend apps", - "version": "0.2.1-next.1", + "version": "0.2.1-next.2", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { @@ -33,17 +33,17 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/backend-common": "^0.15.1-next.2", - "@backstage/backend-plugin-api": "^0.1.2-next.1", - "@backstage/backend-tasks": "^0.3.5-next.0", - "@backstage/errors": "^1.1.0", - "@backstage/plugin-permission-node": "^0.6.5-next.2", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/backend-plugin-api": "^0.1.2-next.2", + "@backstage/backend-tasks": "^0.3.5-next.1", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/plugin-permission-node": "^0.6.5-next.3", "express": "^4.17.1", "express-promise-router": "^4.1.0", "winston": "^3.2.1" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2" + "@backstage/cli": "^0.19.0-next.3" }, "files": [ "dist", diff --git a/packages/backend-common/CHANGELOG.md b/packages/backend-common/CHANGELOG.md index 87f95aa12a..aaa90ac704 100644 --- a/packages/backend-common/CHANGELOG.md +++ b/packages/backend-common/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/backend-common +## 0.15.1-next.3 + +### Patch Changes + +- 96689fbdcb: Workaround for a rare race condition in tests. +- Updated dependencies + - @backstage/config-loader@1.1.4-next.2 + - @backstage/cli-common@0.1.10-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + ## 0.15.1-next.2 ### Patch Changes diff --git a/packages/backend-common/package.json b/packages/backend-common/package.json index 5509adb752..81dc37caca 100644 --- a/packages/backend-common/package.json +++ b/packages/backend-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-common", "description": "Common functionality library for Backstage backends", - "version": "0.15.1-next.2", + "version": "0.15.1-next.3", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { @@ -34,11 +34,11 @@ "test:kubernetes": "backstage-cli package test -t KubernetesContainerRunner --no-watch" }, "dependencies": { - "@backstage/cli-common": "^0.1.9", - "@backstage/config": "^1.0.1", - "@backstage/config-loader": "^1.1.4-next.1", - "@backstage/errors": "^1.1.0", - "@backstage/integration": "^1.3.1-next.1", + "@backstage/cli-common": "^0.1.10-next.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/config-loader": "^1.1.4-next.2", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/integration": "^1.3.1-next.2", "@backstage/types": "^1.0.0", "@google-cloud/storage": "^6.0.0", "@keyv/redis": "^2.2.3", @@ -94,8 +94,8 @@ } }, "devDependencies": { - "@backstage/backend-test-utils": "^0.1.28-next.2", - "@backstage/cli": "^0.19.0-next.2", + "@backstage/backend-test-utils": "^0.1.28-next.3", + "@backstage/cli": "^0.19.0-next.3", "@types/archiver": "^5.1.0", "@types/base64-stream": "^1.0.2", "@types/compression": "^1.7.0", diff --git a/packages/backend-defaults/CHANGELOG.md b/packages/backend-defaults/CHANGELOG.md index e91d4880c6..9684395ce0 100644 --- a/packages/backend-defaults/CHANGELOG.md +++ b/packages/backend-defaults/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/backend-defaults +## 0.1.1-next.1 + +### Patch Changes + +- 854ba37357: Updated to support new `ServiceFactory` formats. +- Updated dependencies + - @backstage/backend-plugin-api@0.1.2-next.2 + - @backstage/backend-app-api@0.2.1-next.2 + ## 0.1.1-next.0 ### Patch Changes diff --git a/packages/backend-defaults/package.json b/packages/backend-defaults/package.json index 9485091f76..e754b74c4d 100644 --- a/packages/backend-defaults/package.json +++ b/packages/backend-defaults/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-defaults", "description": "Backend defaults used by Backstage backend apps", - "version": "0.1.1-next.0", + "version": "0.1.1-next.1", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { @@ -32,11 +32,11 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/backend-app-api": "^0.2.1-next.0", - "@backstage/backend-plugin-api": "^0.1.2-next.0" + "@backstage/backend-app-api": "^0.2.1-next.2", + "@backstage/backend-plugin-api": "^0.1.2-next.2" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.1" + "@backstage/cli": "^0.19.0-next.3" }, "files": [ "dist" diff --git a/packages/backend-plugin-api/CHANGELOG.md b/packages/backend-plugin-api/CHANGELOG.md index 9bb9cbcc49..b0dadbf61c 100644 --- a/packages/backend-plugin-api/CHANGELOG.md +++ b/packages/backend-plugin-api/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/backend-plugin-api +## 0.1.2-next.2 + +### Patch Changes + +- 409ed984e8: Service are now scoped to either `'plugin'` or `'root'` scope. Service factories have been updated to provide dependency instances directly rather than factory functions. +- 854ba37357: The `createServiceFactory` method has been updated to return a higher-order factory that can accept options. +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/plugin-permission-common@0.6.4-next.2 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/backend-tasks@0.3.5-next.1 + ## 0.1.2-next.1 ### Patch Changes diff --git a/packages/backend-plugin-api/package.json b/packages/backend-plugin-api/package.json index 8510f2eaa8..e9593dec3d 100644 --- a/packages/backend-plugin-api/package.json +++ b/packages/backend-plugin-api/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-plugin-api", "description": "Core API used by Backstage backend plugins", - "version": "0.1.2-next.1", + "version": "0.1.2-next.2", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { @@ -33,17 +33,17 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/backend-common": "^0.15.1-next.2", - "@backstage/backend-tasks": "^0.3.5-next.0", - "@backstage/config": "^1.0.1", - "@backstage/plugin-permission-common": "^0.6.4-next.1", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/backend-tasks": "^0.3.5-next.1", + "@backstage/config": "^1.0.2-next.0", + "@backstage/plugin-permission-common": "^0.6.4-next.2", "@types/express": "^4.17.6", "express": "^4.17.1", "winston": "^3.2.1", "winston-transport": "^4.5.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2" + "@backstage/cli": "^0.19.0-next.3" }, "files": [ "dist", diff --git a/packages/backend-tasks/CHANGELOG.md b/packages/backend-tasks/CHANGELOG.md index 28017cf3d5..2307fd5d57 100644 --- a/packages/backend-tasks/CHANGELOG.md +++ b/packages/backend-tasks/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/backend-tasks +## 0.3.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/backend-common@0.15.1-next.3 + ## 0.3.5-next.0 ### Patch Changes diff --git a/packages/backend-tasks/package.json b/packages/backend-tasks/package.json index 7d244a387c..444616660a 100644 --- a/packages/backend-tasks/package.json +++ b/packages/backend-tasks/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-tasks", "description": "Common distributed task management library for Backstage backends", - "version": "0.3.5-next.0", + "version": "0.3.5-next.1", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { @@ -32,9 +32,9 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/backend-common": "^0.15.1-next.1", - "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/config": "^1.0.2-next.0", + "@backstage/errors": "^1.1.1-next.0", "@backstage/types": "^1.0.0", "@types/luxon": "^3.0.0", "cron": "^2.0.0", @@ -47,8 +47,8 @@ "zod": "^3.9.5" }, "devDependencies": { - "@backstage/backend-test-utils": "^0.1.28-next.1", - "@backstage/cli": "^0.19.0-next.1", + "@backstage/backend-test-utils": "^0.1.28-next.3", + "@backstage/cli": "^0.19.0-next.3", "@types/cron": "^2.0.0", "wait-for-expect": "^3.0.2" }, diff --git a/packages/backend-test-utils/CHANGELOG.md b/packages/backend-test-utils/CHANGELOG.md index ef8fdeaeec..5ec06645b0 100644 --- a/packages/backend-test-utils/CHANGELOG.md +++ b/packages/backend-test-utils/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/backend-test-utils +## 0.1.28-next.3 + +### Patch Changes + +- 854ba37357: Updated to support new `ServiceFactory` formats. +- Updated dependencies + - @backstage/backend-plugin-api@0.1.2-next.2 + - @backstage/config@1.0.2-next.0 + - @backstage/backend-app-api@0.2.1-next.2 + - @backstage/cli@0.19.0-next.3 + - @backstage/backend-common@0.15.1-next.3 + ## 0.1.28-next.2 ### Patch Changes diff --git a/packages/backend-test-utils/package.json b/packages/backend-test-utils/package.json index 5e421b4b38..374860a387 100644 --- a/packages/backend-test-utils/package.json +++ b/packages/backend-test-utils/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-test-utils", "description": "Test helpers library for Backstage backends", - "version": "0.1.28-next.2", + "version": "0.1.28-next.3", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { @@ -34,11 +34,11 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/backend-app-api": "^0.2.1-next.1", - "@backstage/backend-common": "^0.15.1-next.2", - "@backstage/backend-plugin-api": "^0.1.2-next.1", - "@backstage/cli": "^0.19.0-next.2", - "@backstage/config": "^1.0.1", + "@backstage/backend-app-api": "^0.2.1-next.2", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/backend-plugin-api": "^0.1.2-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/config": "^1.0.2-next.0", "better-sqlite3": "^7.5.0", "knex": "^2.0.0", "msw": "^0.47.0", @@ -48,7 +48,7 @@ "uuid": "^8.0.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2" + "@backstage/cli": "^0.19.0-next.3" }, "files": [ "dist", diff --git a/packages/backend/CHANGELOG.md b/packages/backend/CHANGELOG.md index 43d4c1c7c2..7b20372856 100644 --- a/packages/backend/CHANGELOG.md +++ b/packages/backend/CHANGELOG.md @@ -1,5 +1,45 @@ # example-backend +## 0.2.75-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.1.0-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/plugin-permission-common@0.6.4-next.2 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.4-next.1 + - @backstage/plugin-catalog-backend@1.4.0-next.3 + - @backstage/plugin-auth-backend@0.16.0-next.3 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/plugin-scaffolder-backend@1.6.0-next.3 + - @backstage/plugin-badges-backend@0.1.30-next.1 + - @backstage/plugin-code-coverage-backend@0.2.2-next.2 + - @backstage/plugin-jenkins-backend@0.1.26-next.3 + - @backstage/plugin-kubernetes-backend@0.7.2-next.3 + - @backstage/plugin-tech-insights-backend@0.5.2-next.2 + - @backstage/plugin-techdocs-backend@1.3.0-next.2 + - @backstage/plugin-todo-backend@0.1.33-next.2 + - example-app@0.2.75-next.3 + - @backstage/plugin-kafka-backend@0.2.29-next.1 + - @backstage/backend-tasks@0.3.5-next.1 + - @backstage/plugin-app-backend@0.3.36-next.3 + - @backstage/plugin-auth-node@0.2.5-next.3 + - @backstage/plugin-azure-devops-backend@0.3.15-next.2 + - @backstage/plugin-graphql-backend@0.1.26-next.3 + - @backstage/plugin-permission-backend@0.5.11-next.2 + - @backstage/plugin-permission-node@0.6.5-next.3 + - @backstage/plugin-proxy-backend@0.2.30-next.2 + - @backstage/plugin-rollbar-backend@0.1.33-next.3 + - @backstage/plugin-search-backend@1.0.2-next.1 + - @backstage/plugin-search-backend-module-elasticsearch@1.0.2-next.2 + - @backstage/plugin-search-backend-module-pg@0.4.0-next.2 + - @backstage/plugin-search-backend-node@1.0.2-next.2 + - @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.20-next.1 + - @backstage/plugin-tech-insights-node@0.3.4-next.1 + ## 0.2.75-next.2 ### Patch Changes diff --git a/packages/backend/package.json b/packages/backend/package.json index 5518b9d586..a8ae29ee18 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -1,6 +1,6 @@ { "name": "example-backend", - "version": "0.2.75-next.2", + "version": "0.2.75-next.3", "main": "dist/index.cjs.js", "types": "src/index.ts", "license": "Apache-2.0", @@ -26,40 +26,40 @@ "build-image": "docker build ../.. -f Dockerfile --tag example-backend" }, "dependencies": { - "@backstage/backend-common": "^0.15.1-next.2", - "@backstage/backend-tasks": "^0.3.5-next.0", - "@backstage/catalog-client": "^1.0.5-next.1", - "@backstage/catalog-model": "^1.1.0", - "@backstage/config": "^1.0.1", - "@backstage/integration": "^1.3.1-next.1", - "@backstage/plugin-app-backend": "^0.3.36-next.2", - "@backstage/plugin-auth-backend": "^0.16.0-next.2", - "@backstage/plugin-auth-node": "^0.2.5-next.2", - "@backstage/plugin-azure-devops-backend": "^0.3.15-next.1", - "@backstage/plugin-badges-backend": "^0.1.30-next.0", - "@backstage/plugin-catalog-backend": "^1.4.0-next.2", - "@backstage/plugin-code-coverage-backend": "^0.2.2-next.1", - "@backstage/plugin-graphql-backend": "^0.1.26-next.2", - "@backstage/plugin-jenkins-backend": "^0.1.26-next.2", - "@backstage/plugin-kafka-backend": "^0.2.29-next.0", - "@backstage/plugin-kubernetes-backend": "^0.7.2-next.2", - "@backstage/plugin-permission-backend": "^0.5.11-next.1", - "@backstage/plugin-permission-common": "^0.6.4-next.1", - "@backstage/plugin-permission-node": "^0.6.5-next.2", - "@backstage/plugin-proxy-backend": "^0.2.30-next.1", - "@backstage/plugin-rollbar-backend": "^0.1.33-next.2", - "@backstage/plugin-scaffolder-backend": "^1.6.0-next.2", - "@backstage/plugin-scaffolder-backend-module-rails": "^0.4.4-next.0", - "@backstage/plugin-search-backend": "^1.0.2-next.0", - "@backstage/plugin-search-backend-module-elasticsearch": "^1.0.2-next.1", - "@backstage/plugin-search-backend-module-pg": "^0.4.0-next.1", - "@backstage/plugin-search-backend-node": "^1.0.2-next.1", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/backend-tasks": "^0.3.5-next.1", + "@backstage/catalog-client": "^1.1.0-next.2", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/integration": "^1.3.1-next.2", + "@backstage/plugin-app-backend": "^0.3.36-next.3", + "@backstage/plugin-auth-backend": "^0.16.0-next.3", + "@backstage/plugin-auth-node": "^0.2.5-next.3", + "@backstage/plugin-azure-devops-backend": "^0.3.15-next.2", + "@backstage/plugin-badges-backend": "^0.1.30-next.1", + "@backstage/plugin-catalog-backend": "^1.4.0-next.3", + "@backstage/plugin-code-coverage-backend": "^0.2.2-next.2", + "@backstage/plugin-graphql-backend": "^0.1.26-next.3", + "@backstage/plugin-jenkins-backend": "^0.1.26-next.3", + "@backstage/plugin-kafka-backend": "^0.2.29-next.1", + "@backstage/plugin-kubernetes-backend": "^0.7.2-next.3", + "@backstage/plugin-permission-backend": "^0.5.11-next.2", + "@backstage/plugin-permission-common": "^0.6.4-next.2", + "@backstage/plugin-permission-node": "^0.6.5-next.3", + "@backstage/plugin-proxy-backend": "^0.2.30-next.2", + "@backstage/plugin-rollbar-backend": "^0.1.33-next.3", + "@backstage/plugin-scaffolder-backend": "^1.6.0-next.3", + "@backstage/plugin-scaffolder-backend-module-rails": "^0.4.4-next.1", + "@backstage/plugin-search-backend": "^1.0.2-next.1", + "@backstage/plugin-search-backend-module-elasticsearch": "^1.0.2-next.2", + "@backstage/plugin-search-backend-module-pg": "^0.4.0-next.2", + "@backstage/plugin-search-backend-node": "^1.0.2-next.2", "@backstage/plugin-search-common": "^1.0.1-next.0", - "@backstage/plugin-tech-insights-backend": "^0.5.2-next.1", - "@backstage/plugin-tech-insights-backend-module-jsonfc": "^0.1.20-next.0", - "@backstage/plugin-tech-insights-node": "^0.3.4-next.0", - "@backstage/plugin-techdocs-backend": "^1.3.0-next.1", - "@backstage/plugin-todo-backend": "^0.1.33-next.1", + "@backstage/plugin-tech-insights-backend": "^0.5.2-next.2", + "@backstage/plugin-tech-insights-backend-module-jsonfc": "^0.1.20-next.1", + "@backstage/plugin-tech-insights-node": "^0.3.4-next.1", + "@backstage/plugin-techdocs-backend": "^1.3.0-next.2", + "@backstage/plugin-todo-backend": "^0.1.33-next.2", "@gitbeaker/node": "^35.1.0", "@octokit/rest": "^19.0.3", "azure-devops-node-api": "^11.0.1", @@ -76,7 +76,7 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", + "@backstage/cli": "^0.19.0-next.3", "@types/dockerode": "^3.3.0", "@types/express": "^4.17.6", "@types/express-serve-static-core": "^4.17.5", diff --git a/packages/catalog-client/CHANGELOG.md b/packages/catalog-client/CHANGELOG.md index 77e0b7ab48..6cbcab0a4e 100644 --- a/packages/catalog-client/CHANGELOG.md +++ b/packages/catalog-client/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/catalog-client +## 1.1.0-next.2 + +### Minor Changes + +- 65d1d4343f: Adding `validateEntity` method that calls `/validate-entity` endpoint. + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/errors@1.1.1-next.0 + ## 1.0.5-next.1 ### Patch Changes diff --git a/packages/catalog-client/package.json b/packages/catalog-client/package.json index 61d47aa65e..3a06074a4d 100644 --- a/packages/catalog-client/package.json +++ b/packages/catalog-client/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/catalog-client", "description": "An isomorphic client for the catalog backend", - "version": "1.0.5-next.1", + "version": "1.1.0-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,12 +32,12 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0", - "@backstage/errors": "^1.1.0", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/errors": "^1.1.1-next.0", "cross-fetch": "^3.1.5" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", + "@backstage/cli": "^0.19.0-next.3", "msw": "^0.47.0" }, "files": [ diff --git a/packages/catalog-model/CHANGELOG.md b/packages/catalog-model/CHANGELOG.md index 9554b94788..25d5866002 100644 --- a/packages/catalog-model/CHANGELOG.md +++ b/packages/catalog-model/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/catalog-model +## 1.1.1-next.0 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + ## 1.1.0 ### Minor Changes diff --git a/packages/catalog-model/package.json b/packages/catalog-model/package.json index be2cbb7664..28df6e58fc 100644 --- a/packages/catalog-model/package.json +++ b/packages/catalog-model/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/catalog-model", "description": "Types and validators that help describe the model of a Backstage Catalog", - "version": "1.1.0", + "version": "1.1.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,8 +33,8 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/errors": "^1.1.1-next.0", "@backstage/types": "^1.0.0", "ajv": "^8.10.0", "json-schema": "^0.4.0", @@ -42,7 +42,7 @@ "uuid": "^8.0.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.1", + "@backstage/cli": "^0.19.0-next.3", "@types/json-schema": "^7.0.5", "@types/lodash": "^4.14.151", "yaml": "^2.0.0" diff --git a/packages/cli-common/CHANGELOG.md b/packages/cli-common/CHANGELOG.md index b5b24d099e..05362b7a31 100644 --- a/packages/cli-common/CHANGELOG.md +++ b/packages/cli-common/CHANGELOG.md @@ -1,5 +1,11 @@ # @backstage/cli-common +## 0.1.10-next.0 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. + ## 0.1.9 ### Patch Changes diff --git a/packages/cli-common/package.json b/packages/cli-common/package.json index e95a07d401..965c62ce38 100644 --- a/packages/cli-common/package.json +++ b/packages/cli-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/cli-common", "description": "Common functionality used by cli, backend, and create-app", - "version": "0.1.9", + "version": "0.1.10-next.0", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { @@ -32,7 +32,7 @@ "start": "backstage-cli package start" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.1", + "@backstage/cli": "^0.19.0-next.3", "@types/node": "^16.0.0" }, "files": [ diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index 6d40a22cae..52ba0a24c6 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/cli +## 0.19.0-next.3 + +### Patch Changes + +- 7d47def9c4: Added dependency on `@types/jest` v27. The `@types/jest` dependency has also been removed from the plugin template and should be removed from any of your own internal packages. If you wish to override the version of `@types/jest` or `jest`, use Yarn resolutions. +- a7e82c9b01: Updated `versions:bump` command to be compatible with Yarn 3. +- Updated dependencies + - @backstage/config-loader@1.1.4-next.2 + - @backstage/cli-common@0.1.10-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/release-manifests@0.0.6-next.2 + ## 0.19.0-next.2 ### Patch Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index f267a0d9ad..9a412d401f 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/cli", "description": "CLI for developing Backstage plugins and apps", - "version": "0.19.0-next.2", + "version": "0.19.0-next.3", "publishConfig": { "access": "public" }, @@ -30,11 +30,11 @@ "backstage-cli": "bin/backstage-cli" }, "dependencies": { - "@backstage/cli-common": "^0.1.9", - "@backstage/config": "^1.0.1", - "@backstage/config-loader": "^1.1.4-next.1", - "@backstage/errors": "^1.1.0", - "@backstage/release-manifests": "^0.0.6-next.1", + "@backstage/cli-common": "^0.1.10-next.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/config-loader": "^1.1.4-next.2", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/release-manifests": "^0.0.6-next.2", "@backstage/types": "^1.0.0", "@manypkg/get-packages": "^1.1.3", "@octokit/request": "^6.0.0", @@ -129,13 +129,13 @@ "zod": "^3.11.6" }, "devDependencies": { - "@backstage/backend-common": "^0.15.1-next.2", - "@backstage/config": "^1.0.1", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/config": "^1.0.2-next.0", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@backstage/theme": "^0.2.16", "@types/diff": "^5.0.0", "@types/express": "^4.17.6", diff --git a/packages/codemods/CHANGELOG.md b/packages/codemods/CHANGELOG.md index ab9ddbc28c..43b2bb2d8a 100644 --- a/packages/codemods/CHANGELOG.md +++ b/packages/codemods/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/codemods +## 0.1.39-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/cli-common@0.1.10-next.0 + ## 0.1.38 ### Patch Changes diff --git a/packages/codemods/package.json b/packages/codemods/package.json index 69720ab0a2..c7630cae6f 100644 --- a/packages/codemods/package.json +++ b/packages/codemods/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/codemods", "description": "A collection of codemods for Backstage projects", - "version": "0.1.38", + "version": "0.1.39-next.0", "publishConfig": { "access": "public", "main": "dist/index.cjs.js" @@ -33,13 +33,13 @@ "backstage-codemods": "bin/backstage-codemods" }, "dependencies": { - "@backstage/cli-common": "^0.1.9", + "@backstage/cli-common": "^0.1.10-next.0", "chalk": "^4.0.0", "jscodeshift": "^0.13.0", "jscodeshift-add-imports": "^1.0.10" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.1", + "@backstage/cli": "^0.19.0-next.3", "@types/jscodeshift": "^0.11.0", "@types/node": "^16.11.26", "commander": "^9.1.0", diff --git a/packages/config-loader/CHANGELOG.md b/packages/config-loader/CHANGELOG.md index 8e49a132ce..c46763bccd 100644 --- a/packages/config-loader/CHANGELOG.md +++ b/packages/config-loader/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/config-loader +## 1.1.4-next.2 + +### Patch Changes + +- 5ecca7e44b: No longer log when reloading remote config. +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/cli-common@0.1.10-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + ## 1.1.4-next.1 ### Patch Changes diff --git a/packages/config-loader/package.json b/packages/config-loader/package.json index 95704de6f3..3f0644e3d6 100644 --- a/packages/config-loader/package.json +++ b/packages/config-loader/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/config-loader", "description": "Config loading functionality used by Backstage backend, and CLI", - "version": "1.1.4-next.1", + "version": "1.1.4-next.2", "publishConfig": { "access": "public", "main": "dist/index.cjs.js", @@ -33,9 +33,9 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/cli-common": "^0.1.9", - "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0", + "@backstage/cli-common": "^0.1.10-next.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/errors": "^1.1.1-next.0", "@backstage/types": "^1.0.0", "@types/json-schema": "^7.0.6", "ajv": "^8.10.0", @@ -50,7 +50,7 @@ "yup": "^0.32.9" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", + "@backstage/cli": "^0.19.0-next.3", "@types/json-schema-merge-allof": "^0.6.0", "@types/mock-fs": "^4.10.0", "@types/node": "^16.11.26", diff --git a/packages/config/CHANGELOG.md b/packages/config/CHANGELOG.md index 7858e99096..9b9ea96dd1 100644 --- a/packages/config/CHANGELOG.md +++ b/packages/config/CHANGELOG.md @@ -1,5 +1,11 @@ # @backstage/config +## 1.0.2-next.0 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. + ## 1.0.1 ### Patch Changes diff --git a/packages/config/package.json b/packages/config/package.json index ff759170bd..9610495455 100644 --- a/packages/config/package.json +++ b/packages/config/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/config", "description": "Config API used by Backstage core, backend, and CLI", - "version": "1.0.1", + "version": "1.0.2-next.0", "publishConfig": { "access": "public", "main": "dist/index.cjs.js", @@ -36,8 +36,8 @@ "lodash": "^4.17.21" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.1", - "@backstage/test-utils": "^1.2.0-next.1", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/test-utils": "^1.2.0-next.3", "@types/node": "^16.0.0" }, "files": [ diff --git a/packages/core-app-api/CHANGELOG.md b/packages/core-app-api/CHANGELOG.md index 6fe94bee7f..47740e9e7b 100644 --- a/packages/core-app-api/CHANGELOG.md +++ b/packages/core-app-api/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/core-app-api +## 1.1.0-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/core-plugin-api@1.0.6-next.3 + ## 1.1.0-next.2 ### Patch Changes diff --git a/packages/core-app-api/package.json b/packages/core-app-api/package.json index c5b8907b8f..8532997477 100644 --- a/packages/core-app-api/package.json +++ b/packages/core-app-api/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/core-app-api", "description": "Core app API used by Backstage apps", - "version": "1.1.0-next.2", + "version": "1.1.0-next.3", "publishConfig": { "access": "public", "main": "dist/index.esm.js", @@ -32,8 +32,8 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/config": "^1.0.1", - "@backstage/core-plugin-api": "^1.0.6-next.2", + "@backstage/config": "^1.0.2-next.0", + "@backstage/core-plugin-api": "^1.0.6-next.3", "@backstage/types": "^1.0.0", "@backstage/version-bridge": "^1.0.1", "@types/prop-types": "^15.7.3", @@ -48,8 +48,8 @@ "react-router-dom": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/react-hooks": "^8.0.0", diff --git a/packages/core-components/CHANGELOG.md b/packages/core-components/CHANGELOG.md index f0ecf302c9..64c5ddc502 100644 --- a/packages/core-components/CHANGELOG.md +++ b/packages/core-components/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/core-components +## 0.11.1-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + ## 0.11.1-next.2 ### Patch Changes diff --git a/packages/core-components/package.json b/packages/core-components/package.json index e316e7d6f4..a32961eece 100644 --- a/packages/core-components/package.json +++ b/packages/core-components/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/core-components", "description": "Core components used by Backstage plugins and apps", - "version": "0.11.1-next.2", + "version": "0.11.1-next.3", "publishConfig": { "access": "public", "main": "dist/index.esm.js", @@ -32,9 +32,9 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/config": "^1.0.1", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/errors": "^1.1.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/errors": "^1.1.1-next.0", "@backstage/theme": "^0.2.16", "@backstage/version-bridge": "^1.0.1", "@material-table/core": "^3.1.0", @@ -78,9 +78,9 @@ "react-router-dom": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/react-hooks": "^8.0.0", diff --git a/packages/core-plugin-api/CHANGELOG.md b/packages/core-plugin-api/CHANGELOG.md index a1da7291e9..0889d0d6e9 100644 --- a/packages/core-plugin-api/CHANGELOG.md +++ b/packages/core-plugin-api/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/core-plugin-api +## 1.0.6-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/config@1.0.2-next.0 + ## 1.0.6-next.2 ### Patch Changes diff --git a/packages/core-plugin-api/package.json b/packages/core-plugin-api/package.json index a40ffcf3bb..5d013f6e87 100644 --- a/packages/core-plugin-api/package.json +++ b/packages/core-plugin-api/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/core-plugin-api", "description": "Core API used by Backstage plugins", - "version": "1.0.6-next.2", + "version": "1.0.6-next.3", "publishConfig": { "access": "public", "main": "dist/index.esm.js", @@ -33,7 +33,7 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/config": "^1.0.1", + "@backstage/config": "^1.0.2-next.0", "@backstage/types": "^1.0.0", "@backstage/version-bridge": "^1.0.1", "history": "^5.0.0", @@ -46,9 +46,9 @@ "react-router-dom": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/react-hooks": "^8.0.0", diff --git a/packages/create-app/CHANGELOG.md b/packages/create-app/CHANGELOG.md index c30f0c9d75..e131c59b6c 100644 --- a/packages/create-app/CHANGELOG.md +++ b/packages/create-app/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/create-app +## 0.4.31-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/cli-common@0.1.10-next.0 + ## 0.4.31-next.2 ### Patch Changes diff --git a/packages/create-app/package.json b/packages/create-app/package.json index 6523e36bc0..d059446638 100644 --- a/packages/create-app/package.json +++ b/packages/create-app/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/create-app", "description": "A CLI that helps you create your own Backstage app", - "version": "0.4.31-next.2", + "version": "0.4.31-next.3", "publishConfig": { "access": "public" }, @@ -32,7 +32,7 @@ "start": "nodemon --" }, "dependencies": { - "@backstage/cli-common": "^0.1.9", + "@backstage/cli-common": "^0.1.10-next.0", "chalk": "^4.0.0", "commander": "^9.1.0", "fs-extra": "10.1.0", @@ -42,7 +42,7 @@ "recursive-readdir": "^2.2.2" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", + "@backstage/cli": "^0.19.0-next.3", "@types/fs-extra": "^9.0.1", "@types/inquirer": "^8.1.3", "@types/node": "^16.11.26", diff --git a/packages/dev-utils/CHANGELOG.md b/packages/dev-utils/CHANGELOG.md index 6115fc076e..e292fde14c 100644 --- a/packages/dev-utils/CHANGELOG.md +++ b/packages/dev-utils/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/dev-utils +## 1.0.6-next.2 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- 329ed2b9c7: Fixed routing when using React Router v6 stable. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/app-defaults@1.0.6-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-app-api@1.1.0-next.3 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/integration-react@1.1.4-next.2 + - @backstage/test-utils@1.2.0-next.3 + ## 1.0.6-next.1 ### Patch Changes diff --git a/packages/dev-utils/package.json b/packages/dev-utils/package.json index 671f264e79..dbbdce225a 100644 --- a/packages/dev-utils/package.json +++ b/packages/dev-utils/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/dev-utils", "description": "Utilities for developing Backstage plugins.", - "version": "1.0.6-next.1", + "version": "1.0.6-next.2", "publishConfig": { "access": "public", "main": "dist/index.esm.js", @@ -32,14 +32,14 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/app-defaults": "^1.0.6-next.1", - "@backstage/catalog-model": "^1.1.0", - "@backstage/core-app-api": "^1.1.0-next.1", - "@backstage/core-components": "^0.11.1-next.1", - "@backstage/core-plugin-api": "^1.0.6-next.1", - "@backstage/integration-react": "^1.1.4-next.0", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", - "@backstage/test-utils": "^1.2.0-next.1", + "@backstage/app-defaults": "^1.0.6-next.2", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/integration-react": "^1.1.4-next.2", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -57,7 +57,7 @@ "react-router-dom": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.1", + "@backstage/cli": "^0.19.0-next.3", "@types/node": "^16.0.0" }, "files": [ diff --git a/packages/e2e-test/package.json b/packages/e2e-test/package.json index b9660518a5..12f430cad2 100644 --- a/packages/e2e-test/package.json +++ b/packages/e2e-test/package.json @@ -27,9 +27,9 @@ }, "bin": "bin/e2e-test", "devDependencies": { - "@backstage/cli": "^0.19.0-next.1", - "@backstage/cli-common": "^0.1.9-next.0", - "@backstage/errors": "^1.1.0-next.0", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/cli-common": "^0.1.10-next.0", + "@backstage/errors": "^1.1.1-next.0", "@types/fs-extra": "^9.0.1", "@types/node": "^16.11.26", "@types/puppeteer": "^5.4.4", diff --git a/packages/errors/CHANGELOG.md b/packages/errors/CHANGELOG.md index bb3eba0249..cbb5292829 100644 --- a/packages/errors/CHANGELOG.md +++ b/packages/errors/CHANGELOG.md @@ -1,5 +1,11 @@ # @backstage/errors +## 1.1.1-next.0 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. + ## 1.1.0 ### Minor Changes diff --git a/packages/errors/package.json b/packages/errors/package.json index 3a84d4c7c5..ab315338bb 100644 --- a/packages/errors/package.json +++ b/packages/errors/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/errors", "description": "Common utilities for error handling within Backstage", - "version": "1.1.0", + "version": "1.1.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -37,7 +37,7 @@ "serialize-error": "^8.0.1" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.1" + "@backstage/cli": "^0.19.0-next.3" }, "files": [ "dist" diff --git a/packages/integration-react/CHANGELOG.md b/packages/integration-react/CHANGELOG.md index 41afc53fe8..f09758bffe 100644 --- a/packages/integration-react/CHANGELOG.md +++ b/packages/integration-react/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/integration-react +## 1.1.4-next.2 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/integration@1.3.1-next.2 + ## 1.1.4-next.1 ### Patch Changes diff --git a/packages/integration-react/package.json b/packages/integration-react/package.json index 34e50cf84b..80ea2f029b 100644 --- a/packages/integration-react/package.json +++ b/packages/integration-react/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/integration-react", "description": "Frontend package for managing integrations towards external systems", - "version": "1.1.4-next.1", + "version": "1.1.4-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -23,10 +23,10 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/config": "^1.0.1", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/integration": "^1.3.1-next.1", + "@backstage/config": "^1.0.2-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/integration": "^1.3.1-next.2", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -37,9 +37,9 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/packages/integration/CHANGELOG.md b/packages/integration/CHANGELOG.md index ac5ec94bc4..0ac5e9e5bd 100644 --- a/packages/integration/CHANGELOG.md +++ b/packages/integration/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/integration +## 1.3.1-next.2 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- f76f22c649: Improved caching around github app tokens. + Tokens are now cached for 50 minutes, not 10. + Calls to get app installations are also included in this cache. + If you have more than one github app configured, consider adding `allowedInstallationOwners` to your apps configuration to gain the most benefit from these performance changes. +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + ## 1.3.1-next.1 ### Patch Changes diff --git a/packages/integration/package.json b/packages/integration/package.json index ba6ef42fb2..c68bd3176c 100644 --- a/packages/integration/package.json +++ b/packages/integration/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/integration", "description": "Helpers for managing integrations towards external systems", - "version": "1.3.1-next.1", + "version": "1.3.1-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,8 +32,8 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/errors": "^1.1.1-next.0", "@octokit/auth-app": "^4.0.0", "@octokit/rest": "^19.0.3", "cross-fetch": "^3.1.5", @@ -42,9 +42,9 @@ "luxon": "^3.0.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/config-loader": "^1.1.4-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/config-loader": "^1.1.4-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@types/luxon": "^3.0.0", "msw": "^0.47.0" }, diff --git a/packages/release-manifests/CHANGELOG.md b/packages/release-manifests/CHANGELOG.md index 2445088982..b0e104511f 100644 --- a/packages/release-manifests/CHANGELOG.md +++ b/packages/release-manifests/CHANGELOG.md @@ -1,5 +1,11 @@ # @backstage/release-manifests +## 0.0.6-next.2 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. + ## 0.0.6-next.1 ### Patch Changes diff --git a/packages/release-manifests/package.json b/packages/release-manifests/package.json index 371745f43f..44c081581c 100644 --- a/packages/release-manifests/package.json +++ b/packages/release-manifests/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/release-manifests", "description": "Helper library for receiving release manifests", - "version": "0.0.6-next.1", + "version": "0.0.6-next.2", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { @@ -35,8 +35,8 @@ "cross-fetch": "^3.1.5" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/test-utils": "^1.2.0-next.3", "@types/node": "^16.0.0", "msw": "^0.47.0" }, diff --git a/packages/techdocs-cli-embedded-app/CHANGELOG.md b/packages/techdocs-cli-embedded-app/CHANGELOG.md index 55552f363e..ee1e3ea184 100644 --- a/packages/techdocs-cli-embedded-app/CHANGELOG.md +++ b/packages/techdocs-cli-embedded-app/CHANGELOG.md @@ -1,5 +1,23 @@ # techdocs-cli-embedded-app +## 0.2.74-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/app-defaults@1.0.6-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/core-app-api@1.1.0-next.3 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/integration-react@1.1.4-next.2 + - @backstage/test-utils@1.2.0-next.3 + - @backstage/plugin-catalog@1.5.1-next.3 + - @backstage/plugin-techdocs@1.3.2-next.3 + - @backstage/cli@0.19.0-next.3 + - @backstage/plugin-techdocs-react@1.0.4-next.2 + ## 0.2.74-next.1 ### Patch Changes diff --git a/packages/techdocs-cli-embedded-app/package.json b/packages/techdocs-cli-embedded-app/package.json index 295688eca8..a8d0e0cf4c 100644 --- a/packages/techdocs-cli-embedded-app/package.json +++ b/packages/techdocs-cli-embedded-app/package.json @@ -1,24 +1,24 @@ { "name": "techdocs-cli-embedded-app", - "version": "0.2.74-next.1", + "version": "0.2.74-next.2", "private": true, "backstage": { "role": "frontend" }, "bundled": true, "dependencies": { - "@backstage/app-defaults": "^1.0.6-next.1", - "@backstage/catalog-model": "^1.1.0", - "@backstage/cli": "^0.19.0-next.1", - "@backstage/config": "^1.0.1", - "@backstage/core-app-api": "^1.1.0-next.1", - "@backstage/core-components": "^0.11.1-next.1", - "@backstage/core-plugin-api": "^1.0.6-next.1", - "@backstage/integration-react": "^1.1.4-next.0", - "@backstage/plugin-catalog": "^1.5.1-next.1", - "@backstage/plugin-techdocs": "^1.3.2-next.1", - "@backstage/plugin-techdocs-react": "^1.0.4-next.1", - "@backstage/test-utils": "^1.2.0-next.1", + "@backstage/app-defaults": "^1.0.6-next.2", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/config": "^1.0.2-next.0", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/integration-react": "^1.1.4-next.2", + "@backstage/plugin-catalog": "^1.5.1-next.3", + "@backstage/plugin-techdocs": "^1.3.2-next.3", + "@backstage/plugin-techdocs-react": "^1.0.4-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", @@ -30,7 +30,7 @@ "react-use": "^17.2.4" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.1", + "@backstage/cli": "^0.19.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/packages/techdocs-cli/CHANGELOG.md b/packages/techdocs-cli/CHANGELOG.md index 17780a3887..56fdf6afd2 100644 --- a/packages/techdocs-cli/CHANGELOG.md +++ b/packages/techdocs-cli/CHANGELOG.md @@ -1,5 +1,17 @@ # @techdocs/cli +## 1.2.1-next.2 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/cli-common@0.1.10-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/plugin-techdocs-node@1.4.0-next.2 + ## 1.2.1-next.1 ### Patch Changes diff --git a/packages/techdocs-cli/package.json b/packages/techdocs-cli/package.json index 97d8a5e721..2ec384eb34 100644 --- a/packages/techdocs-cli/package.json +++ b/packages/techdocs-cli/package.json @@ -1,7 +1,7 @@ { "name": "@techdocs/cli", "description": "Utility CLI for managing TechDocs sites in Backstage.", - "version": "1.2.1-next.1", + "version": "1.2.1-next.2", "publishConfig": { "access": "public" }, @@ -36,7 +36,7 @@ "techdocs-cli": "bin/techdocs-cli" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", + "@backstage/cli": "^0.19.0-next.3", "@types/commander": "^2.12.2", "@types/fs-extra": "^9.0.6", "@types/http-proxy": "^1.17.4", @@ -60,11 +60,11 @@ "ext": "ts" }, "dependencies": { - "@backstage/backend-common": "^0.15.1-next.2", - "@backstage/catalog-model": "^1.1.0", - "@backstage/cli-common": "^0.1.9", - "@backstage/config": "^1.0.1", - "@backstage/plugin-techdocs-node": "^1.4.0-next.1", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/cli-common": "^0.1.10-next.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/plugin-techdocs-node": "^1.4.0-next.2", "@types/dockerode": "^3.3.0", "commander": "^9.1.0", "dockerode": "^3.3.1", diff --git a/packages/test-utils/CHANGELOG.md b/packages/test-utils/CHANGELOG.md index 2317386cf7..b4101d9514 100644 --- a/packages/test-utils/CHANGELOG.md +++ b/packages/test-utils/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/test-utils +## 1.2.0-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- d9e39544be: Add missing peer dependencies +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/core-app-api@1.1.0-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/plugin-permission-common@0.6.4-next.2 + - @backstage/plugin-permission-react@0.4.5-next.2 + ## 1.2.0-next.2 ### Patch Changes diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index 8399e09357..4d45519fa1 100644 --- a/packages/test-utils/package.json +++ b/packages/test-utils/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/test-utils", "description": "Utilities to test Backstage plugins and apps.", - "version": "1.2.0-next.2", + "version": "1.2.0-next.3", "publishConfig": { "access": "public", "main": "dist/index.esm.js", @@ -32,11 +32,11 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/config": "^1.0.1", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/plugin-permission-common": "^0.6.4-next.1", - "@backstage/plugin-permission-react": "^0.4.5-next.1", + "@backstage/config": "^1.0.2-next.0", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/plugin-permission-common": "^0.6.4-next.2", + "@backstage/plugin-permission-react": "^0.4.5-next.2", "@backstage/theme": "^0.2.16", "@backstage/types": "^1.0.0", "@material-ui/core": "^4.12.2", @@ -55,7 +55,7 @@ "react-router-dom": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", + "@backstage/cli": "^0.19.0-next.3", "@types/node": "^16.11.26", "msw": "^0.47.0" }, diff --git a/plugins/adr-backend/CHANGELOG.md b/plugins/adr-backend/CHANGELOG.md index 9b5bdf0ebd..b92a33a8f0 100644 --- a/plugins/adr-backend/CHANGELOG.md +++ b/plugins/adr-backend/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-adr-backend +## 0.2.1-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.1.0-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/plugin-adr-common@0.2.1-next.1 + ## 0.2.1-next.2 ### Patch Changes diff --git a/plugins/adr-backend/package.json b/plugins/adr-backend/package.json index 2ebdd9c78f..91ed8e002c 100644 --- a/plugins/adr-backend/package.json +++ b/plugins/adr-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-adr-backend", - "version": "0.2.1-next.2", + "version": "0.2.1-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -28,13 +28,13 @@ "postpack": "backstage-cli package postpack" }, "dependencies": { - "@backstage/backend-common": "^0.15.1-next.2", - "@backstage/catalog-client": "^1.0.5-next.1", - "@backstage/catalog-model": "^1.1.0", - "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0", - "@backstage/integration": "^1.3.1-next.1", - "@backstage/plugin-adr-common": "^0.2.1-next.0", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/catalog-client": "^1.1.0-next.2", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/integration": "^1.3.1-next.2", + "@backstage/plugin-adr-common": "^0.2.1-next.1", "@backstage/plugin-search-common": "^1.0.1-next.0", "luxon": "^3.0.0", "marked": "^4.0.14", @@ -43,7 +43,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", + "@backstage/cli": "^0.19.0-next.3", "@types/marked": "^4.0.0", "@types/supertest": "^2.0.8", "msw": "^0.47.0", diff --git a/plugins/adr-common/CHANGELOG.md b/plugins/adr-common/CHANGELOG.md index 63584b41b1..9269768185 100644 --- a/plugins/adr-common/CHANGELOG.md +++ b/plugins/adr-common/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-adr-common +## 0.2.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + ## 0.2.1-next.0 ### Patch Changes diff --git a/plugins/adr-common/package.json b/plugins/adr-common/package.json index c5a49f59fe..02631c3e6c 100644 --- a/plugins/adr-common/package.json +++ b/plugins/adr-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-adr-common", "description": "Common functionalities for the adr plugin", - "version": "0.2.1-next.0", + "version": "0.2.1-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -29,12 +29,12 @@ "postpack": "backstage-cli package postpack" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0", - "@backstage/integration": "^1.3.1-next.0", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/integration": "^1.3.1-next.2", "@backstage/plugin-search-common": "^1.0.1-next.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.1" + "@backstage/cli": "^0.19.0-next.3" }, "files": [ "dist" diff --git a/plugins/adr/CHANGELOG.md b/plugins/adr/CHANGELOG.md index 494a7f33fe..3fc5634bd1 100644 --- a/plugins/adr/CHANGELOG.md +++ b/plugins/adr/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-adr +## 0.2.1-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/integration-react@1.1.4-next.2 + - @backstage/plugin-adr-common@0.2.1-next.1 + ## 0.2.1-next.2 ### Patch Changes diff --git a/plugins/adr/package.json b/plugins/adr/package.json index db9ba4a11c..732cb4d67f 100644 --- a/plugins/adr/package.json +++ b/plugins/adr/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-adr", - "version": "0.2.1-next.2", + "version": "0.2.1-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -22,12 +22,12 @@ "postpack": "backstage-cli package postpack" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/integration-react": "^1.1.4-next.1", - "@backstage/plugin-adr-common": "^0.2.1-next.0", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/integration-react": "^1.1.4-next.2", + "@backstage/plugin-adr-common": "^0.2.1-next.1", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", "@backstage/plugin-search-common": "^1.0.1-next.0", "@backstage/plugin-search-react": "^1.1.0-next.2", "@backstage/theme": "^0.2.16", @@ -45,10 +45,10 @@ "react-router-dom": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/airbrake-backend/CHANGELOG.md b/plugins/airbrake-backend/CHANGELOG.md index d6c30dddcb..1868062e0b 100644 --- a/plugins/airbrake-backend/CHANGELOG.md +++ b/plugins/airbrake-backend/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-airbrake-backend +## 0.2.9-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/backend-common@0.15.1-next.3 + ## 0.2.9-next.2 ### Patch Changes diff --git a/plugins/airbrake-backend/package.json b/plugins/airbrake-backend/package.json index 3a658af4e3..1a04e5185d 100644 --- a/plugins/airbrake-backend/package.json +++ b/plugins/airbrake-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-airbrake-backend", - "version": "0.2.9-next.2", + "version": "0.2.9-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -22,8 +22,8 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/backend-common": "^0.15.1-next.2", - "@backstage/config": "^1.0.1", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/config": "^1.0.2-next.0", "@types/express": "*", "express": "^4.17.1", "express-promise-router": "^4.1.0", @@ -32,7 +32,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", + "@backstage/cli": "^0.19.0-next.3", "@types/http-proxy-middleware": "^0.19.3", "@types/supertest": "^2.0.8", "msw": "^0.47.0", diff --git a/plugins/airbrake/CHANGELOG.md b/plugins/airbrake/CHANGELOG.md index 6935373985..8262a89cb0 100644 --- a/plugins/airbrake/CHANGELOG.md +++ b/plugins/airbrake/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-airbrake +## 0.3.9-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/dev-utils@1.0.6-next.2 + - @backstage/test-utils@1.2.0-next.3 + ## 0.3.9-next.2 ### Patch Changes diff --git a/plugins/airbrake/package.json b/plugins/airbrake/package.json index 3d829c4bd0..c8ec322420 100644 --- a/plugins/airbrake/package.json +++ b/plugins/airbrake/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-airbrake", - "version": "0.3.9-next.2", + "version": "0.3.9-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -22,12 +22,12 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -40,10 +40,10 @@ "react-router": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/app-defaults": "^1.0.6-next.1", - "@backstage/cli": "^0.19.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/app-defaults": "^1.0.6-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/allure/CHANGELOG.md b/plugins/allure/CHANGELOG.md index f7db453135..64e114dda7 100644 --- a/plugins/allure/CHANGELOG.md +++ b/plugins/allure/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-allure +## 0.1.25-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + ## 0.1.25-next.2 ### Patch Changes diff --git a/plugins/allure/package.json b/plugins/allure/package.json index 511b3b02a5..12400806a7 100644 --- a/plugins/allure/package.json +++ b/plugins/allure/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-allure", "description": "A Backstage plugin that integrates with Allure", - "version": "0.1.25-next.2", + "version": "0.1.25-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -23,10 +23,10 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -38,10 +38,10 @@ "react-router-dom": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/analytics-module-ga/CHANGELOG.md b/plugins/analytics-module-ga/CHANGELOG.md index 0e666be80a..fb5051da23 100644 --- a/plugins/analytics-module-ga/CHANGELOG.md +++ b/plugins/analytics-module-ga/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-analytics-module-ga +## 0.1.20-next.2 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + ## 0.1.20-next.1 ### Patch Changes diff --git a/plugins/analytics-module-ga/package.json b/plugins/analytics-module-ga/package.json index a10056153b..e9b5044d92 100644 --- a/plugins/analytics-module-ga/package.json +++ b/plugins/analytics-module-ga/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-analytics-module-ga", - "version": "0.1.20-next.1", + "version": "0.1.20-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -22,9 +22,9 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/config": "^1.0.1", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", + "@backstage/config": "^1.0.2-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -36,10 +36,10 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/apache-airflow/CHANGELOG.md b/plugins/apache-airflow/CHANGELOG.md index 3f3f236b76..2396ca2b6f 100644 --- a/plugins/apache-airflow/CHANGELOG.md +++ b/plugins/apache-airflow/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-apache-airflow +## 0.2.2-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + ## 0.2.2-next.2 ### Patch Changes diff --git a/plugins/apache-airflow/package.json b/plugins/apache-airflow/package.json index 5cf15f7620..f132c46a78 100644 --- a/plugins/apache-airflow/package.json +++ b/plugins/apache-airflow/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-apache-airflow", - "version": "0.2.2-next.2", + "version": "0.2.2-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -22,8 +22,8 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", @@ -35,10 +35,10 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/api-docs/CHANGELOG.md b/plugins/api-docs/CHANGELOG.md index d71021782f..db0ffbeada 100644 --- a/plugins/api-docs/CHANGELOG.md +++ b/plugins/api-docs/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-api-docs +## 0.8.9-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/plugin-catalog@1.5.1-next.3 + ## 0.8.9-next.2 ### Patch Changes diff --git a/plugins/api-docs/package.json b/plugins/api-docs/package.json index 1ae1c8e00f..8281a1522d 100644 --- a/plugins/api-docs/package.json +++ b/plugins/api-docs/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-api-docs", "description": "A Backstage plugin that helps represent API entities in the frontend", - "version": "0.8.9-next.2", + "version": "0.8.9-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,11 +33,11 @@ }, "dependencies": { "@asyncapi/react-component": "1.0.0-next.40", - "@backstage/catalog-model": "^1.1.0", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/plugin-catalog": "^1.5.1-next.2", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/plugin-catalog": "^1.5.1-next.3", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -56,10 +56,10 @@ "react-router-dom": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/apollo-explorer/CHANGELOG.md b/plugins/apollo-explorer/CHANGELOG.md index 68983a1f07..40c9fa0c57 100644 --- a/plugins/apollo-explorer/CHANGELOG.md +++ b/plugins/apollo-explorer/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-apollo-explorer +## 0.1.2-next.2 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + ## 0.1.2-next.1 ### Patch Changes diff --git a/plugins/apollo-explorer/package.json b/plugins/apollo-explorer/package.json index b33901b96f..39143c3133 100644 --- a/plugins/apollo-explorer/package.json +++ b/plugins/apollo-explorer/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-apollo-explorer", - "version": "0.1.2-next.1", + "version": "0.1.2-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -23,8 +23,8 @@ }, "dependencies": { "@apollo/explorer": "^1.1.1", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.9.13", "@material-ui/icons": "^4.9.1", @@ -36,10 +36,10 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/app-backend/CHANGELOG.md b/plugins/app-backend/CHANGELOG.md index 33df9f7078..02188afefc 100644 --- a/plugins/app-backend/CHANGELOG.md +++ b/plugins/app-backend/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-app-backend +## 0.3.36-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.1.4-next.2 + - @backstage/config@1.0.2-next.0 + - @backstage/backend-common@0.15.1-next.3 + ## 0.3.36-next.2 ### Patch Changes diff --git a/plugins/app-backend/package.json b/plugins/app-backend/package.json index f37e9e5ab8..c06c41e6dd 100644 --- a/plugins/app-backend/package.json +++ b/plugins/app-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-app-backend", "description": "A Backstage backend plugin that serves the Backstage frontend app", - "version": "0.3.36-next.2", + "version": "0.3.36-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,9 +32,9 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/backend-common": "^0.15.1-next.2", - "@backstage/config": "^1.0.1", - "@backstage/config-loader": "^1.1.4-next.1", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/config": "^1.0.2-next.0", + "@backstage/config-loader": "^1.1.4-next.2", "@backstage/types": "^1.0.0", "@types/express": "^4.17.6", "express": "^4.17.1", @@ -49,8 +49,8 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/backend-test-utils": "^0.1.28-next.2", - "@backstage/cli": "^0.19.0-next.2", + "@backstage/backend-test-utils": "^0.1.28-next.3", + "@backstage/cli": "^0.19.0-next.3", "@backstage/types": "^1.0.0", "@types/supertest": "^2.0.8", "mock-fs": "^5.1.0", diff --git a/plugins/auth-backend/CHANGELOG.md b/plugins/auth-backend/CHANGELOG.md index 7b723756cf..7c5fff0dd0 100644 --- a/plugins/auth-backend/CHANGELOG.md +++ b/plugins/auth-backend/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-auth-backend +## 0.16.0-next.3 + +### Minor Changes + +- 8600855fbf: The auth0 integration is updated to use the `passport-auth0` library. The configuration under `auth.providers.auth0.\*` now supports an optional `audience` parameter; providing that allows you to connect to the correct API to get permissions, access tokens, and full profile information. + + [What is an Audience](https://community.auth0.com/t/what-is-the-audience/71414) + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.1.0-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/plugin-auth-node@0.2.5-next.3 + ## 0.16.0-next.2 ### Patch Changes diff --git a/plugins/auth-backend/package.json b/plugins/auth-backend/package.json index 35e6f86f2c..4f820f4829 100644 --- a/plugins/auth-backend/package.json +++ b/plugins/auth-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-auth-backend", "description": "A Backstage backend plugin that handles authentication", - "version": "0.16.0-next.2", + "version": "0.16.0-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,12 +32,12 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/backend-common": "^0.15.1-next.2", - "@backstage/catalog-client": "^1.0.5-next.1", - "@backstage/catalog-model": "^1.1.0", - "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0", - "@backstage/plugin-auth-node": "^0.2.5-next.2", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/catalog-client": "^1.1.0-next.2", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/plugin-auth-node": "^0.2.5-next.3", "@backstage/types": "^1.0.0", "@davidzemon/passport-okta-oauth": "^0.0.5", "@google-cloud/firestore": "^6.0.0", @@ -76,8 +76,8 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/backend-test-utils": "^0.1.28-next.2", - "@backstage/cli": "^0.19.0-next.2", + "@backstage/backend-test-utils": "^0.1.28-next.3", + "@backstage/cli": "^0.19.0-next.3", "@types/body-parser": "^1.19.0", "@types/cookie-parser": "^1.4.2", "@types/express-session": "^1.17.2", diff --git a/plugins/auth-node/CHANGELOG.md b/plugins/auth-node/CHANGELOG.md index 71413dc6ef..13fb0bbcce 100644 --- a/plugins/auth-node/CHANGELOG.md +++ b/plugins/auth-node/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-auth-node +## 0.2.5-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/backend-common@0.15.1-next.3 + ## 0.2.5-next.2 ### Patch Changes diff --git a/plugins/auth-node/package.json b/plugins/auth-node/package.json index ebf8c6974d..52115d6611 100644 --- a/plugins/auth-node/package.json +++ b/plugins/auth-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-node", - "version": "0.2.5-next.2", + "version": "0.2.5-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -22,9 +22,9 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/backend-common": "^0.15.1-next.2", - "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/config": "^1.0.2-next.0", + "@backstage/errors": "^1.1.1-next.0", "@types/express": "*", "express": "^4.17.1", "jose": "^4.6.0", @@ -32,8 +32,8 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/backend-test-utils": "^0.1.28-next.2", - "@backstage/cli": "^0.19.0-next.2", + "@backstage/backend-test-utils": "^0.1.28-next.3", + "@backstage/cli": "^0.19.0-next.3", "lodash": "^4.17.21", "msw": "^0.47.0", "uuid": "^8.0.0" diff --git a/plugins/azure-devops-backend/CHANGELOG.md b/plugins/azure-devops-backend/CHANGELOG.md index dba2ff571a..d6145f3308 100644 --- a/plugins/azure-devops-backend/CHANGELOG.md +++ b/plugins/azure-devops-backend/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-azure-devops-backend +## 0.3.15-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/backend-common@0.15.1-next.3 + ## 0.3.15-next.1 ### Patch Changes diff --git a/plugins/azure-devops-backend/package.json b/plugins/azure-devops-backend/package.json index debcf701e2..92bcf84c62 100644 --- a/plugins/azure-devops-backend/package.json +++ b/plugins/azure-devops-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-azure-devops-backend", - "version": "0.3.15-next.1", + "version": "0.3.15-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -22,8 +22,8 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/backend-common": "^0.15.1-next.2", - "@backstage/config": "^1.0.1", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/config": "^1.0.2-next.0", "@backstage/plugin-azure-devops-common": "^0.3.0-next.0", "@types/express": "^4.17.6", "azure-devops-node-api": "^11.0.1", @@ -35,7 +35,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", + "@backstage/cli": "^0.19.0-next.3", "@types/supertest": "^2.0.8", "msw": "^0.47.0", "supertest": "^6.1.6" diff --git a/plugins/azure-devops/CHANGELOG.md b/plugins/azure-devops/CHANGELOG.md index e4fa40551a..13ea5bbaa5 100644 --- a/plugins/azure-devops/CHANGELOG.md +++ b/plugins/azure-devops/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-azure-devops +## 0.2.0-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + ## 0.2.0-next.2 ### Patch Changes diff --git a/plugins/azure-devops/package.json b/plugins/azure-devops/package.json index 969103db00..0cdd048b1b 100644 --- a/plugins/azure-devops/package.json +++ b/plugins/azure-devops/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-azure-devops", - "version": "0.2.0-next.2", + "version": "0.2.0-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -28,12 +28,12 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/errors": "^1.1.0", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/errors": "^1.1.1-next.0", "@backstage/plugin-azure-devops-common": "^0.3.0-next.0", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -47,10 +47,10 @@ "react-router": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/badges-backend/CHANGELOG.md b/plugins/badges-backend/CHANGELOG.md index f26dab77f3..c54c09a08b 100644 --- a/plugins/badges-backend/CHANGELOG.md +++ b/plugins/badges-backend/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-badges-backend +## 0.1.30-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.1.0-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/backend-common@0.15.1-next.3 + ## 0.1.30-next.0 ### Patch Changes diff --git a/plugins/badges-backend/package.json b/plugins/badges-backend/package.json index 420bfbd86b..0002695cc8 100644 --- a/plugins/badges-backend/package.json +++ b/plugins/badges-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-badges-backend", "description": "A Backstage backend plugin that generates README badges for your entities", - "version": "0.1.30-next.0", + "version": "0.1.30-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,11 +33,11 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/backend-common": "^0.15.1-next.1", - "@backstage/catalog-client": "^1.0.5-next.0", - "@backstage/catalog-model": "^1.1.0", - "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/catalog-client": "^1.1.0-next.2", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/errors": "^1.1.1-next.0", "@types/express": "^4.17.6", "badge-maker": "^3.3.0", "cors": "^2.8.5", @@ -47,7 +47,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.1", + "@backstage/cli": "^0.19.0-next.3", "@types/supertest": "^2.0.8", "supertest": "^6.1.3" }, diff --git a/plugins/badges/CHANGELOG.md b/plugins/badges/CHANGELOG.md index 0533b306d1..50137c221b 100644 --- a/plugins/badges/CHANGELOG.md +++ b/plugins/badges/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-badges +## 0.2.33-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + ## 0.2.33-next.2 ### Patch Changes diff --git a/plugins/badges/package.json b/plugins/badges/package.json index 100f2a6102..8748a05077 100644 --- a/plugins/badges/package.json +++ b/plugins/badges/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-badges", "description": "A Backstage plugin that generates README badges for your entities", - "version": "0.2.33-next.2", + "version": "0.2.33-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -29,11 +29,11 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/errors": "^1.1.0", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -45,10 +45,10 @@ "react-router": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/bazaar-backend/CHANGELOG.md b/plugins/bazaar-backend/CHANGELOG.md index b6cec7bc0d..4494697278 100644 --- a/plugins/bazaar-backend/CHANGELOG.md +++ b/plugins/bazaar-backend/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-bazaar-backend +## 0.1.20-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/backend-test-utils@0.1.28-next.3 + - @backstage/backend-common@0.15.1-next.3 + ## 0.1.20-next.0 ### Patch Changes diff --git a/plugins/bazaar-backend/package.json b/plugins/bazaar-backend/package.json index 0c7c2c51ea..c1242acd7e 100644 --- a/plugins/bazaar-backend/package.json +++ b/plugins/bazaar-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-bazaar-backend", - "version": "0.1.20-next.0", + "version": "0.1.20-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -22,9 +22,9 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/backend-common": "^0.15.1-next.1", - "@backstage/backend-test-utils": "^0.1.28-next.1", - "@backstage/config": "^1.0.1", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/backend-test-utils": "^0.1.28-next.3", + "@backstage/config": "^1.0.2-next.0", "@types/express": "^4.17.6", "express": "^4.17.1", "express-promise-router": "^4.1.0", @@ -33,7 +33,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.1" + "@backstage/cli": "^0.19.0-next.3" }, "files": [ "dist", diff --git a/plugins/bazaar/CHANGELOG.md b/plugins/bazaar/CHANGELOG.md index c8fbcb961b..8d93b89e0f 100644 --- a/plugins/bazaar/CHANGELOG.md +++ b/plugins/bazaar/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-bazaar +## 0.1.24-next.2 + +### Patch Changes + +- 1dd12349d1: Fixed broken routing by removing the wrapping `Router` from the `RoutedTabs` children. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-client@1.1.0-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/plugin-catalog@1.5.1-next.3 + - @backstage/cli@0.19.0-next.3 + ## 0.1.24-next.1 ### Patch Changes diff --git a/plugins/bazaar/package.json b/plugins/bazaar/package.json index f78a4f08fe..21e2f3ce25 100644 --- a/plugins/bazaar/package.json +++ b/plugins/bazaar/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-bazaar", - "version": "0.1.24-next.1", + "version": "0.1.24-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -22,13 +22,13 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-client": "^1.0.5-next.0", - "@backstage/catalog-model": "^1.1.0", - "@backstage/cli": "^0.19.0-next.1", - "@backstage/core-components": "^0.11.1-next.1", - "@backstage/core-plugin-api": "^1.0.6-next.1", - "@backstage/plugin-catalog": "^1.5.1-next.1", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", + "@backstage/catalog-client": "^1.1.0-next.2", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/plugin-catalog": "^1.5.1-next.3", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", "@date-io/luxon": "1.x", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -44,8 +44,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.1", - "@backstage/dev-utils": "^1.0.6-next.1", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", "@testing-library/jest-dom": "^5.10.1", "cross-fetch": "^3.1.5" }, diff --git a/plugins/bitrise/CHANGELOG.md b/plugins/bitrise/CHANGELOG.md index f940cb40df..114ab5549e 100644 --- a/plugins/bitrise/CHANGELOG.md +++ b/plugins/bitrise/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-bitrise +## 0.1.36-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + ## 0.1.36-next.2 ### Patch Changes diff --git a/plugins/bitrise/package.json b/plugins/bitrise/package.json index a849fba8ef..b659cac03a 100644 --- a/plugins/bitrise/package.json +++ b/plugins/bitrise/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-bitrise", "description": "A Backstage plugin that integrates towards Bitrise", - "version": "0.1.36-next.2", + "version": "0.1.36-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -23,10 +23,10 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -42,10 +42,10 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/catalog-backend-module-aws/CHANGELOG.md b/plugins/catalog-backend-module-aws/CHANGELOG.md index 10196c0793..07b5446dcc 100644 --- a/plugins/catalog-backend-module-aws/CHANGELOG.md +++ b/plugins/catalog-backend-module-aws/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-catalog-backend-module-aws +## 0.1.9-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/plugin-catalog-backend@1.4.0-next.3 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/backend-tasks@0.3.5-next.1 + ## 0.1.9-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-aws/package.json b/plugins/catalog-backend-module-aws/package.json index 871f32773b..33158ac182 100644 --- a/plugins/catalog-backend-module-aws/package.json +++ b/plugins/catalog-backend-module-aws/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-aws", "description": "A Backstage catalog backend module that helps integrate towards AWS", - "version": "0.1.9-next.1", + "version": "0.1.9-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,13 +32,13 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/backend-common": "^0.15.1-next.1", - "@backstage/backend-tasks": "^0.3.5-next.0", - "@backstage/catalog-model": "^1.1.0", - "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0", - "@backstage/integration": "^1.3.1-next.0", - "@backstage/plugin-catalog-backend": "^1.4.0-next.1", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/backend-tasks": "^0.3.5-next.1", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/integration": "^1.3.1-next.2", + "@backstage/plugin-catalog-backend": "^1.4.0-next.3", "@backstage/types": "^1.0.0", "aws-sdk": "^2.840.0", "lodash": "^4.17.21", @@ -47,7 +47,7 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.1", + "@backstage/cli": "^0.19.0-next.3", "@types/lodash": "^4.14.151", "aws-sdk-mock": "^5.2.1", "yaml": "^2.0.0" diff --git a/plugins/catalog-backend-module-azure/CHANGELOG.md b/plugins/catalog-backend-module-azure/CHANGELOG.md index de79e9f47c..57d5315cf4 100644 --- a/plugins/catalog-backend-module-azure/CHANGELOG.md +++ b/plugins/catalog-backend-module-azure/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-catalog-backend-module-azure +## 0.1.7-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/plugin-catalog-backend@1.4.0-next.3 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/backend-tasks@0.3.5-next.1 + ## 0.1.7-next.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-azure/package.json b/plugins/catalog-backend-module-azure/package.json index 2c7ab06064..3dd90d1bb3 100644 --- a/plugins/catalog-backend-module-azure/package.json +++ b/plugins/catalog-backend-module-azure/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-azure", "description": "A Backstage catalog backend module that helps integrate towards Azure", - "version": "0.1.7-next.2", + "version": "0.1.7-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,13 +32,13 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/backend-common": "^0.15.1-next.2", - "@backstage/backend-tasks": "^0.3.5-next.0", - "@backstage/catalog-model": "^1.1.0", - "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0", - "@backstage/integration": "^1.3.1-next.1", - "@backstage/plugin-catalog-backend": "^1.4.0-next.2", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/backend-tasks": "^0.3.5-next.1", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/integration": "^1.3.1-next.2", + "@backstage/plugin-catalog-backend": "^1.4.0-next.3", "@backstage/types": "^1.0.0", "lodash": "^4.17.21", "msw": "^0.47.0", @@ -47,8 +47,8 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/backend-test-utils": "^0.1.28-next.2", - "@backstage/cli": "^0.19.0-next.2", + "@backstage/backend-test-utils": "^0.1.28-next.3", + "@backstage/cli": "^0.19.0-next.3", "@types/lodash": "^4.14.151" }, "files": [ diff --git a/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md b/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md index b75a810816..cd50519279 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md +++ b/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-catalog-backend-module-bitbucket-cloud +## 0.1.3-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/plugin-catalog-backend@1.4.0-next.3 + - @backstage/backend-tasks@0.3.5-next.1 + ## 0.1.3-next.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-bitbucket-cloud/package.json b/plugins/catalog-backend-module-bitbucket-cloud/package.json index 441e7c5ab2..e8ddff85b0 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/package.json +++ b/plugins/catalog-backend-module-bitbucket-cloud/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-bitbucket-cloud", "description": "A Backstage catalog backend module that helps integrate towards Bitbucket Cloud", - "version": "0.1.3-next.2", + "version": "0.1.3-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,18 +32,18 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/backend-tasks": "^0.3.5-next.0", - "@backstage/config": "^1.0.1", - "@backstage/integration": "^1.3.1-next.1", + "@backstage/backend-tasks": "^0.3.5-next.1", + "@backstage/config": "^1.0.2-next.0", + "@backstage/integration": "^1.3.1-next.2", "@backstage/plugin-bitbucket-cloud-common": "^0.1.3-next.1", - "@backstage/plugin-catalog-backend": "^1.4.0-next.2", + "@backstage/plugin-catalog-backend": "^1.4.0-next.3", "uuid": "^8.0.0", "winston": "^3.2.1" }, "devDependencies": { - "@backstage/backend-common": "^0.15.1-next.2", - "@backstage/backend-test-utils": "^0.1.28-next.2", - "@backstage/cli": "^0.19.0-next.2", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/backend-test-utils": "^0.1.28-next.3", + "@backstage/cli": "^0.19.0-next.3", "msw": "^0.47.0" }, "files": [ diff --git a/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md b/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md index 7a8b1c95bc..ae82dc8ad7 100644 --- a/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md +++ b/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-catalog-backend-module-bitbucket-server +## 0.1.1-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/plugin-catalog-backend@1.4.0-next.3 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/backend-tasks@0.3.5-next.1 + ## 0.1.1-next.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-bitbucket-server/package.json b/plugins/catalog-backend-module-bitbucket-server/package.json index 31b24687e8..4064732eca 100644 --- a/plugins/catalog-backend-module-bitbucket-server/package.json +++ b/plugins/catalog-backend-module-bitbucket-server/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-bitbucket-server", - "version": "0.1.1-next.2", + "version": "0.1.1-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -31,21 +31,21 @@ "postpack": "backstage-cli package postpack" }, "dependencies": { - "@backstage/backend-common": "^0.15.1-next.2", - "@backstage/backend-tasks": "^0.3.5-next.0", - "@backstage/catalog-model": "^1.0.1", - "@backstage/config": "^1.0.0", - "@backstage/errors": "^1.0.0", - "@backstage/integration": "^1.3.1-next.1", - "@backstage/plugin-catalog-backend": "^1.4.0-next.2", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/backend-tasks": "^0.3.5-next.1", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/integration": "^1.3.1-next.2", + "@backstage/plugin-catalog-backend": "^1.4.0-next.3", "@types/node-fetch": "^2.5.12", "node-fetch": "^2.6.7", "uuid": "^8.0.0", "winston": "^3.2.1" }, "devDependencies": { - "@backstage/backend-test-utils": "^0.1.28-next.2", - "@backstage/cli": "^0.19.0-next.2", + "@backstage/backend-test-utils": "^0.1.28-next.3", + "@backstage/cli": "^0.19.0-next.3", "msw": "^0.47.0" }, "files": [ diff --git a/plugins/catalog-backend-module-bitbucket/CHANGELOG.md b/plugins/catalog-backend-module-bitbucket/CHANGELOG.md index 65f5fb11f1..7533ebaa47 100644 --- a/plugins/catalog-backend-module-bitbucket/CHANGELOG.md +++ b/plugins/catalog-backend-module-bitbucket/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-catalog-backend-module-bitbucket +## 0.2.3-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/plugin-catalog-backend@1.4.0-next.3 + - @backstage/backend-common@0.15.1-next.3 + ## 0.2.3-next.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-bitbucket/package.json b/plugins/catalog-backend-module-bitbucket/package.json index 7881402dea..7d27598d1f 100644 --- a/plugins/catalog-backend-module-bitbucket/package.json +++ b/plugins/catalog-backend-module-bitbucket/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-bitbucket", "description": "A Backstage catalog backend module that helps integrate towards Bitbucket", - "version": "0.2.3-next.2", + "version": "0.2.3-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,13 +32,13 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/backend-common": "^0.15.1-next.2", - "@backstage/catalog-model": "^1.1.0", - "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0", - "@backstage/integration": "^1.3.1-next.1", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/integration": "^1.3.1-next.2", "@backstage/plugin-bitbucket-cloud-common": "^0.1.3-next.1", - "@backstage/plugin-catalog-backend": "^1.4.0-next.2", + "@backstage/plugin-catalog-backend": "^1.4.0-next.3", "@backstage/types": "^1.0.0", "lodash": "^4.17.21", "msw": "^0.47.0", @@ -46,8 +46,8 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/backend-test-utils": "^0.1.28-next.2", - "@backstage/cli": "^0.19.0-next.2", + "@backstage/backend-test-utils": "^0.1.28-next.3", + "@backstage/cli": "^0.19.0-next.3", "@types/lodash": "^4.14.151" }, "files": [ diff --git a/plugins/catalog-backend-module-gerrit/CHANGELOG.md b/plugins/catalog-backend-module-gerrit/CHANGELOG.md index 015804e6ea..d90cbfbe10 100644 --- a/plugins/catalog-backend-module-gerrit/CHANGELOG.md +++ b/plugins/catalog-backend-module-gerrit/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-catalog-backend-module-gerrit +## 0.1.4-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/plugin-catalog-backend@1.4.0-next.3 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/backend-tasks@0.3.5-next.1 + ## 0.1.4-next.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-gerrit/package.json b/plugins/catalog-backend-module-gerrit/package.json index af98288b4e..53d54afc06 100644 --- a/plugins/catalog-backend-module-gerrit/package.json +++ b/plugins/catalog-backend-module-gerrit/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-gerrit", - "version": "0.1.4-next.2", + "version": "0.1.4-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -28,13 +28,13 @@ "postpack": "backstage-cli package postpack" }, "dependencies": { - "@backstage/backend-common": "^0.15.1-next.2", - "@backstage/backend-tasks": "^0.3.5-next.0", - "@backstage/catalog-model": "^1.1.0", - "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0", - "@backstage/integration": "^1.3.1-next.1", - "@backstage/plugin-catalog-backend": "^1.4.0-next.2", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/backend-tasks": "^0.3.5-next.1", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/integration": "^1.3.1-next.2", + "@backstage/plugin-catalog-backend": "^1.4.0-next.3", "fs-extra": "10.1.0", "msw": "^0.47.0", "node-fetch": "^2.6.7", @@ -42,8 +42,8 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/backend-test-utils": "^0.1.28-next.2", - "@backstage/cli": "^0.19.0-next.2", + "@backstage/backend-test-utils": "^0.1.28-next.3", + "@backstage/cli": "^0.19.0-next.3", "@types/fs-extra": "^9.0.1" }, "files": [ diff --git a/plugins/catalog-backend-module-github/CHANGELOG.md b/plugins/catalog-backend-module-github/CHANGELOG.md index aa8db8962d..a1a11f1519 100644 --- a/plugins/catalog-backend-module-github/CHANGELOG.md +++ b/plugins/catalog-backend-module-github/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-catalog-backend-module-github +## 0.1.7-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.1.0-next.2 + - @backstage/backend-plugin-api@0.1.2-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/plugin-catalog-backend@1.4.0-next.3 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/backend-tasks@0.3.5-next.1 + ## 0.1.7-next.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-github/package.json b/plugins/catalog-backend-module-github/package.json index 04a4d3c01f..c27d3d4c60 100644 --- a/plugins/catalog-backend-module-github/package.json +++ b/plugins/catalog-backend-module-github/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-github", "description": "A Backstage catalog backend module that helps integrate towards GitHub", - "version": "0.1.7-next.2", + "version": "0.1.7-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,15 +33,15 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/backend-common": "^0.15.1-next.2", - "@backstage/backend-plugin-api": "^0.1.2-next.1", - "@backstage/backend-tasks": "^0.3.5-next.0", - "@backstage/catalog-model": "^1.1.0", - "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0", - "@backstage/integration": "^1.3.1-next.1", - "@backstage/plugin-catalog-backend": "^1.4.0-next.2", - "@backstage/plugin-catalog-node": "^1.0.2-next.1", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/backend-plugin-api": "^0.1.2-next.2", + "@backstage/backend-tasks": "^0.3.5-next.1", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/integration": "^1.3.1-next.2", + "@backstage/plugin-catalog-backend": "^1.4.0-next.3", + "@backstage/plugin-catalog-node": "^1.1.0-next.2", "@backstage/types": "^1.0.0", "@octokit/graphql": "^5.0.0", "lodash": "^4.17.21", @@ -51,8 +51,8 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/backend-test-utils": "^0.1.28-next.2", - "@backstage/cli": "^0.19.0-next.2", + "@backstage/backend-test-utils": "^0.1.28-next.3", + "@backstage/cli": "^0.19.0-next.3", "@types/lodash": "^4.14.151" }, "files": [ diff --git a/plugins/catalog-backend-module-gitlab/CHANGELOG.md b/plugins/catalog-backend-module-gitlab/CHANGELOG.md index 958fce089d..ba2016b713 100644 --- a/plugins/catalog-backend-module-gitlab/CHANGELOG.md +++ b/plugins/catalog-backend-module-gitlab/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-catalog-backend-module-gitlab +## 0.1.7-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/plugin-catalog-backend@1.4.0-next.3 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/backend-tasks@0.3.5-next.1 + ## 0.1.7-next.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-gitlab/package.json b/plugins/catalog-backend-module-gitlab/package.json index 9933f8c5a8..56d6fd73e8 100644 --- a/plugins/catalog-backend-module-gitlab/package.json +++ b/plugins/catalog-backend-module-gitlab/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-gitlab", "description": "A Backstage catalog backend module that helps integrate towards GitLab", - "version": "0.1.7-next.2", + "version": "0.1.7-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,13 +32,13 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/backend-common": "^0.15.1-next.2", - "@backstage/backend-tasks": "^0.3.5-next.0", - "@backstage/catalog-model": "^1.1.0", - "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0", - "@backstage/integration": "^1.3.1-next.1", - "@backstage/plugin-catalog-backend": "^1.4.0-next.2", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/backend-tasks": "^0.3.5-next.1", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/integration": "^1.3.1-next.2", + "@backstage/plugin-catalog-backend": "^1.4.0-next.3", "@backstage/types": "^1.0.0", "lodash": "^4.17.21", "msw": "^0.47.0", @@ -47,8 +47,8 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/backend-test-utils": "^0.1.28-next.2", - "@backstage/cli": "^0.19.0-next.2", + "@backstage/backend-test-utils": "^0.1.28-next.3", + "@backstage/cli": "^0.19.0-next.3", "@types/lodash": "^4.14.151", "@types/uuid": "^8.0.0" }, diff --git a/plugins/catalog-backend-module-ldap/CHANGELOG.md b/plugins/catalog-backend-module-ldap/CHANGELOG.md index addb85f704..6429576b05 100644 --- a/plugins/catalog-backend-module-ldap/CHANGELOG.md +++ b/plugins/catalog-backend-module-ldap/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-catalog-backend-module-ldap +## 0.5.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/plugin-catalog-backend@1.4.0-next.3 + - @backstage/backend-tasks@0.3.5-next.1 + ## 0.5.3-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-ldap/package.json b/plugins/catalog-backend-module-ldap/package.json index 35924aaf67..4d9de73a77 100644 --- a/plugins/catalog-backend-module-ldap/package.json +++ b/plugins/catalog-backend-module-ldap/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-ldap", "description": "A Backstage catalog backend module that helps integrate towards LDAP", - "version": "0.5.3-next.1", + "version": "0.5.3-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,11 +32,11 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/backend-tasks": "^0.3.5-next.0", - "@backstage/catalog-model": "^1.1.0", - "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0", - "@backstage/plugin-catalog-backend": "^1.4.0-next.1", + "@backstage/backend-tasks": "^0.3.5-next.1", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/plugin-catalog-backend": "^1.4.0-next.3", "@backstage/types": "^1.0.0", "@types/ldapjs": "^2.2.0", "ldapjs": "^2.2.0", @@ -45,7 +45,7 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.1", + "@backstage/cli": "^0.19.0-next.3", "@types/lodash": "^4.14.151" }, "files": [ diff --git a/plugins/catalog-backend-module-msgraph/CHANGELOG.md b/plugins/catalog-backend-module-msgraph/CHANGELOG.md index e69fa287c9..25ac8c2716 100644 --- a/plugins/catalog-backend-module-msgraph/CHANGELOG.md +++ b/plugins/catalog-backend-module-msgraph/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-catalog-backend-module-msgraph +## 0.4.2-next.3 + +### Patch Changes + +- d80aab31ae: Added $select attribute to user query +- Updated dependencies + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/plugin-catalog-backend@1.4.0-next.3 + - @backstage/backend-tasks@0.3.5-next.1 + ## 0.4.2-next.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-msgraph/package.json b/plugins/catalog-backend-module-msgraph/package.json index 3bddab4130..93270570fb 100644 --- a/plugins/catalog-backend-module-msgraph/package.json +++ b/plugins/catalog-backend-module-msgraph/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-msgraph", "description": "A Backstage catalog backend module that helps integrate towards Microsoft Graph", - "version": "0.4.2-next.2", + "version": "0.4.2-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,10 +33,10 @@ }, "dependencies": { "@azure/identity": "^2.1.0", - "@backstage/backend-tasks": "^0.3.5-next.0", - "@backstage/catalog-model": "^1.1.0", - "@backstage/config": "^1.0.1", - "@backstage/plugin-catalog-backend": "^1.4.0-next.2", + "@backstage/backend-tasks": "^0.3.5-next.1", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/plugin-catalog-backend": "^1.4.0-next.3", "@microsoft/microsoft-graph-types": "^2.6.0", "@types/node-fetch": "^2.5.12", "lodash": "^4.17.21", @@ -47,9 +47,9 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/backend-common": "^0.15.1-next.2", - "@backstage/backend-test-utils": "^0.1.28-next.2", - "@backstage/cli": "^0.19.0-next.2", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/backend-test-utils": "^0.1.28-next.3", + "@backstage/cli": "^0.19.0-next.3", "@types/lodash": "^4.14.151", "msw": "^0.47.0" }, diff --git a/plugins/catalog-backend-module-openapi/CHANGELOG.md b/plugins/catalog-backend-module-openapi/CHANGELOG.md index e93151d472..f9a1ad9ed9 100644 --- a/plugins/catalog-backend-module-openapi/CHANGELOG.md +++ b/plugins/catalog-backend-module-openapi/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-catalog-backend-module-openapi +## 0.1.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.1.0-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/plugin-catalog-backend@1.4.0-next.3 + - @backstage/backend-common@0.15.1-next.3 + ## 0.1.2-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-openapi/package.json b/plugins/catalog-backend-module-openapi/package.json index 55ffe05fc7..420a9d547e 100644 --- a/plugins/catalog-backend-module-openapi/package.json +++ b/plugins/catalog-backend-module-openapi/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-openapi", "description": "A Backstage catalog backend module that helps with OpenAPI specifications", - "version": "0.1.2-next.1", + "version": "0.1.2-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,19 +33,19 @@ }, "dependencies": { "@apidevtools/swagger-parser": "^10.1.0", - "@backstage/backend-common": "^0.15.1-next.1", - "@backstage/catalog-model": "^1.1.0", - "@backstage/config": "^1.0.1", - "@backstage/integration": "^1.3.1-next.0", - "@backstage/plugin-catalog-backend": "^1.4.0-next.1", - "@backstage/plugin-catalog-node": "^1.0.2-next.0", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/integration": "^1.3.1-next.2", + "@backstage/plugin-catalog-backend": "^1.4.0-next.3", + "@backstage/plugin-catalog-node": "^1.1.0-next.2", "@backstage/types": "^1.0.0", "winston": "^3.2.1", "yaml": "^2.1.1" }, "devDependencies": { - "@backstage/backend-test-utils": "^0.1.28-next.1", - "@backstage/cli": "^0.19.0-next.1", + "@backstage/backend-test-utils": "^0.1.28-next.3", + "@backstage/cli": "^0.19.0-next.3", "openapi-types": "^12.0.0" }, "files": [ diff --git a/plugins/catalog-backend/CHANGELOG.md b/plugins/catalog-backend/CHANGELOG.md index 7fb1cf7cab..07d434b7b2 100644 --- a/plugins/catalog-backend/CHANGELOG.md +++ b/plugins/catalog-backend/CHANGELOG.md @@ -1,5 +1,26 @@ # @backstage/plugin-catalog-backend +## 1.4.0-next.3 + +### Minor Changes + +- 6e63bc43f2: Added the `refresh` function to the Connection of the entity providers. + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.1.0-next.2 + - @backstage/backend-plugin-api@0.1.2-next.2 + - @backstage/catalog-client@1.1.0-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/plugin-permission-common@0.6.4-next.2 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/plugin-scaffolder-common@1.2.0-next.1 + - @backstage/plugin-permission-node@0.6.5-next.3 + ## 1.4.0-next.2 ### Patch Changes diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json index fe0478e115..0b9d363b3a 100644 --- a/plugins/catalog-backend/package.json +++ b/plugins/catalog-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend", "description": "The Backstage backend plugin that provides the Backstage catalog", - "version": "1.4.0-next.2", + "version": "1.4.0-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,18 +33,18 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/backend-common": "^0.15.1-next.2", - "@backstage/backend-plugin-api": "^0.1.2-next.1", - "@backstage/catalog-client": "^1.0.5-next.1", - "@backstage/catalog-model": "^1.1.0", - "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0", - "@backstage/integration": "^1.3.1-next.1", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/backend-plugin-api": "^0.1.2-next.2", + "@backstage/catalog-client": "^1.1.0-next.2", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/integration": "^1.3.1-next.2", "@backstage/plugin-catalog-common": "^1.0.6-next.0", - "@backstage/plugin-catalog-node": "^1.0.2-next.1", - "@backstage/plugin-permission-common": "^0.6.4-next.1", - "@backstage/plugin-permission-node": "^0.6.5-next.2", - "@backstage/plugin-scaffolder-common": "^1.2.0-next.0", + "@backstage/plugin-catalog-node": "^1.1.0-next.2", + "@backstage/plugin-permission-common": "^0.6.4-next.2", + "@backstage/plugin-permission-node": "^0.6.5-next.3", + "@backstage/plugin-scaffolder-common": "^1.2.0-next.1", "@backstage/plugin-search-common": "^1.0.1-next.0", "@backstage/types": "^1.0.0", "@types/express": "^4.17.6", @@ -69,10 +69,10 @@ "zod": "^3.11.6" }, "devDependencies": { - "@backstage/backend-test-utils": "^0.1.28-next.2", - "@backstage/cli": "^0.19.0-next.2", - "@backstage/plugin-permission-common": "^0.6.4-next.1", - "@backstage/plugin-search-backend-node": "1.0.2-next.1", + "@backstage/backend-test-utils": "^0.1.28-next.3", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/plugin-permission-common": "^0.6.4-next.2", + "@backstage/plugin-search-backend-node": "1.0.2-next.2", "@types/core-js": "^2.5.4", "@types/git-url-parse": "^9.0.0", "@types/lodash": "^4.14.151", diff --git a/plugins/catalog-graph/CHANGELOG.md b/plugins/catalog-graph/CHANGELOG.md index 7d11622796..5fbaa9ecca 100644 --- a/plugins/catalog-graph/CHANGELOG.md +++ b/plugins/catalog-graph/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-catalog-graph +## 0.2.21-next.2 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-client@1.1.0-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + ## 0.2.21-next.1 ### Patch Changes diff --git a/plugins/catalog-graph/package.json b/plugins/catalog-graph/package.json index 3f9a79ee9a..995ed3eebe 100644 --- a/plugins/catalog-graph/package.json +++ b/plugins/catalog-graph/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-graph", - "version": "0.2.21-next.1", + "version": "0.2.21-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -22,11 +22,11 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-client": "^1.0.5-next.0", - "@backstage/catalog-model": "^1.1.0", - "@backstage/core-components": "^0.11.1-next.1", - "@backstage/core-plugin-api": "^1.0.6-next.1", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", + "@backstage/catalog-client": "^1.1.0-next.2", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -43,11 +43,11 @@ "react-router": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.1", - "@backstage/core-app-api": "^1.1.0-next.1", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/plugin-catalog": "^1.5.1-next.1", - "@backstage/test-utils": "^1.2.0-next.1", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/plugin-catalog": "^1.5.1-next.3", + "@backstage/test-utils": "^1.2.0-next.3", "@backstage/types": "^1.0.0", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", diff --git a/plugins/catalog-graphql/CHANGELOG.md b/plugins/catalog-graphql/CHANGELOG.md index 53e66ef2c7..28eafef43b 100644 --- a/plugins/catalog-graphql/CHANGELOG.md +++ b/plugins/catalog-graphql/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-catalog-graphql +## 0.3.13-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + ## 0.3.13-next.2 ### Patch Changes diff --git a/plugins/catalog-graphql/package.json b/plugins/catalog-graphql/package.json index d4268ea270..b8c65b2784 100644 --- a/plugins/catalog-graphql/package.json +++ b/plugins/catalog-graphql/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-graphql", "description": "An experimental Backstage catalog GraphQL module", - "version": "0.3.13-next.2", + "version": "0.3.13-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -34,8 +34,8 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0", - "@backstage/config": "^1.0.1", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/config": "^1.0.2-next.0", "@backstage/types": "^1.0.0", "apollo-server": "^3.0.0", "graphql": "^16.0.0", @@ -46,8 +46,8 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/test-utils": "^1.2.0-next.3", "@graphql-codegen/cli": "^2.3.1", "@graphql-codegen/graphql-modules-preset": "^2.3.2", "@graphql-codegen/typescript": "^2.4.2", diff --git a/plugins/catalog-import/CHANGELOG.md b/plugins/catalog-import/CHANGELOG.md index c817f09e8d..35633dca6a 100644 --- a/plugins/catalog-import/CHANGELOG.md +++ b/plugins/catalog-import/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-catalog-import +## 0.8.12-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-client@1.1.0-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/integration-react@1.1.4-next.2 + ## 0.8.12-next.2 ### Patch Changes diff --git a/plugins/catalog-import/package.json b/plugins/catalog-import/package.json index 9d6a6945e0..895973f1ca 100644 --- a/plugins/catalog-import/package.json +++ b/plugins/catalog-import/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-import", "description": "A Backstage plugin the helps you import entities into your catalog", - "version": "0.8.12-next.2", + "version": "0.8.12-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,15 +32,15 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-client": "^1.0.5-next.1", - "@backstage/catalog-model": "^1.1.0", - "@backstage/config": "^1.0.1", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/errors": "^1.1.0", - "@backstage/integration": "^1.3.1-next.1", - "@backstage/integration-react": "^1.1.4-next.1", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", + "@backstage/catalog-client": "^1.1.0-next.2", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/integration": "^1.3.1-next.2", + "@backstage/integration-react": "^1.1.4-next.2", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", @@ -58,10 +58,10 @@ "react-router": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/react-hooks": "^8.0.0", diff --git a/plugins/catalog-node/CHANGELOG.md b/plugins/catalog-node/CHANGELOG.md index 24006068f6..0c88527b97 100644 --- a/plugins/catalog-node/CHANGELOG.md +++ b/plugins/catalog-node/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-catalog-node +## 1.1.0-next.2 + +### Minor Changes + +- 9743bc788c: Added refresh function to the `EntityProviderConnection` to be able to schedule refreshes from entity providers. + +### Patch Changes + +- 409ed984e8: Updated usage of experimental backend service APIs. +- Updated dependencies + - @backstage/backend-plugin-api@0.1.2-next.2 + - @backstage/catalog-client@1.1.0-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/errors@1.1.1-next.0 + ## 1.0.2-next.1 ### Patch Changes diff --git a/plugins/catalog-node/package.json b/plugins/catalog-node/package.json index 991aa67b68..2ef9a738fc 100644 --- a/plugins/catalog-node/package.json +++ b/plugins/catalog-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-node", "description": "The plugin-catalog-node module for @backstage/plugin-catalog-backend", - "version": "1.0.2-next.1", + "version": "1.1.0-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -24,16 +24,16 @@ "postpack": "backstage-cli package postpack" }, "dependencies": { - "@backstage/backend-plugin-api": "^0.1.2-next.1", - "@backstage/catalog-client": "^1.0.5-next.1", - "@backstage/catalog-model": "^1.1.0", - "@backstage/errors": "1.1.0", + "@backstage/backend-plugin-api": "^0.1.2-next.2", + "@backstage/catalog-client": "^1.1.0-next.2", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/errors": "1.1.1-next.0", "@backstage/types": "^1.0.0" }, "devDependencies": { - "@backstage/backend-common": "^0.15.1-next.2", - "@backstage/backend-test-utils": "^0.1.28-next.2", - "@backstage/cli": "^0.19.0-next.2" + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/backend-test-utils": "^0.1.28-next.3", + "@backstage/cli": "^0.19.0-next.3" }, "files": [ "dist", diff --git a/plugins/catalog-react/CHANGELOG.md b/plugins/catalog-react/CHANGELOG.md index 59a178de9e..a0e7bfcae5 100644 --- a/plugins/catalog-react/CHANGELOG.md +++ b/plugins/catalog-react/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-catalog-react +## 1.1.4-next.2 + +### Patch Changes + +- f6033d1121: humanizeEntityRef function can now be forced to include default namespace +- c86741a052: Support showing counts in option labels of the `EntityTagPicker`. You can enable this by adding the `showCounts` property +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/catalog-client@1.1.0-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/plugin-permission-common@0.6.4-next.2 + - @backstage/plugin-permission-react@0.4.5-next.2 + ## 1.1.4-next.1 ### Patch Changes diff --git a/plugins/catalog-react/package.json b/plugins/catalog-react/package.json index c7c17f9b2f..962c859c62 100644 --- a/plugins/catalog-react/package.json +++ b/plugins/catalog-react/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-react", "description": "A frontend library that helps other Backstage plugins interact with the catalog", - "version": "1.1.4-next.1", + "version": "1.1.4-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,15 +33,15 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/catalog-client": "^1.0.5-next.0", - "@backstage/catalog-model": "^1.1.0", - "@backstage/core-components": "^0.11.1-next.1", - "@backstage/core-plugin-api": "^1.0.6-next.1", - "@backstage/errors": "^1.1.0", - "@backstage/integration": "^1.3.1-next.0", + "@backstage/catalog-client": "^1.1.0-next.2", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/integration": "^1.3.1-next.2", "@backstage/plugin-catalog-common": "^1.0.6-next.0", - "@backstage/plugin-permission-common": "^0.6.4-next.0", - "@backstage/plugin-permission-react": "^0.4.5-next.1", + "@backstage/plugin-permission-common": "^0.6.4-next.2", + "@backstage/plugin-permission-react": "^0.4.5-next.2", "@backstage/theme": "^0.2.16", "@backstage/types": "^1.0.0", "@backstage/version-bridge": "^1.0.1", @@ -62,11 +62,11 @@ "react-router": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.1", - "@backstage/core-app-api": "^1.1.0-next.1", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", "@backstage/plugin-catalog-common": "^1.0.6-next.0", - "@backstage/plugin-scaffolder-common": "^1.2.0-next.0", - "@backstage/test-utils": "^1.2.0-next.1", + "@backstage/plugin-scaffolder-common": "^1.2.0-next.1", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/react-hooks": "^8.0.0", diff --git a/plugins/catalog/CHANGELOG.md b/plugins/catalog/CHANGELOG.md index 814f75e80c..51507389cf 100644 --- a/plugins/catalog/CHANGELOG.md +++ b/plugins/catalog/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-catalog +## 1.5.1-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-client@1.1.0-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration-react@1.1.4-next.2 + ## 1.5.1-next.2 ### Patch Changes diff --git a/plugins/catalog/package.json b/plugins/catalog/package.json index ed0198b799..2610c9db93 100644 --- a/plugins/catalog/package.json +++ b/plugins/catalog/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog", "description": "The Backstage plugin for browsing the Backstage catalog", - "version": "1.5.1-next.2", + "version": "1.5.1-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,14 +32,14 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-client": "^1.0.5-next.1", - "@backstage/catalog-model": "^1.1.0", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/errors": "^1.1.0", - "@backstage/integration-react": "^1.1.4-next.1", + "@backstage/catalog-client": "^1.1.0-next.2", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/integration-react": "^1.1.4-next.2", "@backstage/plugin-catalog-common": "^1.0.6-next.0", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", "@backstage/plugin-search-common": "^1.0.1-next.0", "@backstage/plugin-search-react": "^1.1.0-next.2", "@backstage/theme": "^0.2.16", @@ -59,11 +59,11 @@ "react-router": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/plugin-permission-react": "^0.4.5-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/plugin-permission-react": "^0.4.5-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/cicd-statistics-module-gitlab/CHANGELOG.md b/plugins/cicd-statistics-module-gitlab/CHANGELOG.md index 4846df3e12..32ababf2d9 100644 --- a/plugins/cicd-statistics-module-gitlab/CHANGELOG.md +++ b/plugins/cicd-statistics-module-gitlab/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-cicd-statistics-module-gitlab +## 0.1.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/plugin-cicd-statistics@0.1.11-next.2 + ## 0.1.5-next.0 ### Patch Changes diff --git a/plugins/cicd-statistics-module-gitlab/package.json b/plugins/cicd-statistics-module-gitlab/package.json index 15d3f5d6b3..ee8eaed465 100644 --- a/plugins/cicd-statistics-module-gitlab/package.json +++ b/plugins/cicd-statistics-module-gitlab/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-cicd-statistics-module-gitlab", "description": "CI/CD Statistics plugin module; Gitlab CICD", - "version": "0.1.5-next.0", + "version": "0.1.5-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -28,16 +28,16 @@ "postpack": "backstage-cli package postpack" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0", - "@backstage/core-plugin-api": "^1.0.6-next.1", - "@backstage/plugin-cicd-statistics": "^0.1.11-next.1", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/plugin-cicd-statistics": "^0.1.11-next.2", "@gitbeaker/browser": "^35.6.0", "@gitbeaker/core": "^35.6.0", "luxon": "^3.0.0", "p-limit": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.1" + "@backstage/cli": "^0.19.0-next.3" }, "files": [ "dist" diff --git a/plugins/cicd-statistics/CHANGELOG.md b/plugins/cicd-statistics/CHANGELOG.md index 1ad30f818b..ac1cd23660 100644 --- a/plugins/cicd-statistics/CHANGELOG.md +++ b/plugins/cicd-statistics/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-cicd-statistics +## 0.1.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-plugin-api@1.0.6-next.3 + ## 0.1.11-next.1 ### Patch Changes diff --git a/plugins/cicd-statistics/package.json b/plugins/cicd-statistics/package.json index 2964a0b6f1..6394baaf94 100644 --- a/plugins/cicd-statistics/package.json +++ b/plugins/cicd-statistics/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-cicd-statistics", "description": "A frontend plugin visualizing CI/CD pipeline statistics (build time)", - "version": "0.1.11-next.1", + "version": "0.1.11-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,14 +32,14 @@ "start": "backstage-cli package start" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.1", + "@backstage/cli": "^0.19.0-next.3", "@types/luxon": "^3.0.0", "@types/react": "^16.13.1 || ^17.0.0" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0", - "@backstage/core-plugin-api": "^1.0.6-next.1", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", "@date-io/luxon": "^1.3.13", "@material-ui/core": "^4.9.13", "@material-ui/icons": "^4.11.2", diff --git a/plugins/circleci/CHANGELOG.md b/plugins/circleci/CHANGELOG.md index 82c0ffdba6..44ccf89c42 100644 --- a/plugins/circleci/CHANGELOG.md +++ b/plugins/circleci/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-circleci +## 0.3.9-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + ## 0.3.9-next.2 ### Patch Changes diff --git a/plugins/circleci/package.json b/plugins/circleci/package.json index 29a4144db4..229ff9fb11 100644 --- a/plugins/circleci/package.json +++ b/plugins/circleci/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-circleci", "description": "A Backstage plugin that integrates towards Circle CI", - "version": "0.3.9-next.2", + "version": "0.3.9-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,10 +33,10 @@ "postpack": "backstage-cli package postpack" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -53,10 +53,10 @@ "react-router-dom": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/cloudbuild/CHANGELOG.md b/plugins/cloudbuild/CHANGELOG.md index 2f9cd9b608..35a8a675e0 100644 --- a/plugins/cloudbuild/CHANGELOG.md +++ b/plugins/cloudbuild/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-cloudbuild +## 0.3.9-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + ## 0.3.9-next.2 ### Patch Changes diff --git a/plugins/cloudbuild/package.json b/plugins/cloudbuild/package.json index 1994c6c3fd..6215547041 100644 --- a/plugins/cloudbuild/package.json +++ b/plugins/cloudbuild/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-cloudbuild", "description": "A Backstage plugin that integrates towards Google Cloud Build", - "version": "0.3.9-next.2", + "version": "0.3.9-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,10 +33,10 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -51,10 +51,10 @@ "react-router-dom": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/code-climate/CHANGELOG.md b/plugins/code-climate/CHANGELOG.md index 3bc35b9466..3d45e5c3a2 100644 --- a/plugins/code-climate/CHANGELOG.md +++ b/plugins/code-climate/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-code-climate +## 0.1.9-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + ## 0.1.9-next.2 ### Patch Changes diff --git a/plugins/code-climate/package.json b/plugins/code-climate/package.json index 83a1787c43..464142f680 100644 --- a/plugins/code-climate/package.json +++ b/plugins/code-climate/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-code-climate", - "version": "0.1.9-next.2", + "version": "0.1.9-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -22,10 +22,10 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -39,9 +39,9 @@ "react-router": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/code-coverage-backend/CHANGELOG.md b/plugins/code-coverage-backend/CHANGELOG.md index 8f788c4614..2d440fd31b 100644 --- a/plugins/code-coverage-backend/CHANGELOG.md +++ b/plugins/code-coverage-backend/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-code-coverage-backend +## 0.2.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.1.0-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/backend-common@0.15.1-next.3 + ## 0.2.2-next.1 ### Patch Changes diff --git a/plugins/code-coverage-backend/package.json b/plugins/code-coverage-backend/package.json index b74209374f..bbc5714fb8 100644 --- a/plugins/code-coverage-backend/package.json +++ b/plugins/code-coverage-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-code-coverage-backend", "description": "A Backstage backend plugin that helps you keep track of your code coverage", - "version": "0.2.2-next.1", + "version": "0.2.2-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -23,12 +23,12 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/backend-common": "^0.15.1-next.2", - "@backstage/catalog-client": "^1.0.5-next.1", - "@backstage/catalog-model": "^1.1.0", - "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0", - "@backstage/integration": "^1.3.1-next.1", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/catalog-client": "^1.1.0-next.2", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/integration": "^1.3.1-next.2", "@types/express": "^4.17.6", "express": "^4.17.1", "express-promise-router": "^4.1.0", @@ -39,7 +39,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", + "@backstage/cli": "^0.19.0-next.3", "@types/express-xml-bodyparser": "^0.3.2", "@types/supertest": "^2.0.8", "msw": "^0.47.0", diff --git a/plugins/code-coverage/CHANGELOG.md b/plugins/code-coverage/CHANGELOG.md index 3b235f5926..9e120afd38 100644 --- a/plugins/code-coverage/CHANGELOG.md +++ b/plugins/code-coverage/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-code-coverage +## 0.2.2-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + ## 0.2.2-next.2 ### Patch Changes diff --git a/plugins/code-coverage/package.json b/plugins/code-coverage/package.json index 88fb957420..c3f992a428 100644 --- a/plugins/code-coverage/package.json +++ b/plugins/code-coverage/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-code-coverage", "description": "A Backstage plugin that helps you keep track of your code coverage", - "version": "0.2.2-next.2", + "version": "0.2.2-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -23,12 +23,12 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0", - "@backstage/config": "^1.0.1", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/errors": "^1.1.0", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -45,10 +45,10 @@ "react-router-dom": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/codescene/CHANGELOG.md b/plugins/codescene/CHANGELOG.md index b42a2ec80c..aa43d5edd3 100644 --- a/plugins/codescene/CHANGELOG.md +++ b/plugins/codescene/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-codescene +## 0.1.4-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + ## 0.1.4-next.2 ### Patch Changes diff --git a/plugins/codescene/package.json b/plugins/codescene/package.json index 303046610a..bc709a215c 100644 --- a/plugins/codescene/package.json +++ b/plugins/codescene/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-codescene", - "version": "0.1.4-next.2", + "version": "0.1.4-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -22,10 +22,10 @@ "postpack": "backstage-cli package postpack" }, "dependencies": { - "@backstage/config": "^1.0.1", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/errors": "^1.1.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/errors": "^1.1.1-next.0", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.9.10", "@material-ui/icons": "^4.9.1", @@ -38,10 +38,10 @@ "react-router-dom": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/config-schema/CHANGELOG.md b/plugins/config-schema/CHANGELOG.md index d65e0a1cdc..3e7483e879 100644 --- a/plugins/config-schema/CHANGELOG.md +++ b/plugins/config-schema/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-config-schema +## 0.1.32-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + ## 0.1.32-next.2 ### Patch Changes diff --git a/plugins/config-schema/package.json b/plugins/config-schema/package.json index f8d3d3e5cf..7f650fb4bc 100644 --- a/plugins/config-schema/package.json +++ b/plugins/config-schema/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-config-schema", "description": "A Backstage plugin that lets you browse the configuration schema of your app", - "version": "0.1.32-next.2", + "version": "0.1.32-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -23,10 +23,10 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/config": "^1.0.1", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/errors": "^1.1.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/errors": "^1.1.1-next.0", "@backstage/theme": "^0.2.16", "@backstage/types": "^1.0.0", "@material-ui/core": "^4.12.2", @@ -40,10 +40,10 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/cost-insights/CHANGELOG.md b/plugins/cost-insights/CHANGELOG.md index d0d1b2c76f..fec45acdd1 100644 --- a/plugins/cost-insights/CHANGELOG.md +++ b/plugins/cost-insights/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-cost-insights +## 0.11.31-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + ## 0.11.31-next.2 ### Patch Changes diff --git a/plugins/cost-insights/package.json b/plugins/cost-insights/package.json index 666e4bdbae..8034195d62 100644 --- a/plugins/cost-insights/package.json +++ b/plugins/cost-insights/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-cost-insights", "description": "A Backstage plugin that helps you keep track of your cloud spend", - "version": "0.11.31-next.2", + "version": "0.11.31-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,10 +32,10 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0", - "@backstage/config": "^1.0.1", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", "@backstage/plugin-cost-insights-common": "^0.1.1", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", @@ -59,10 +59,10 @@ "react-router-dom": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/dynatrace/CHANGELOG.md b/plugins/dynatrace/CHANGELOG.md index 4ca38cc5b7..33e547a2bf 100644 --- a/plugins/dynatrace/CHANGELOG.md +++ b/plugins/dynatrace/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-dynatrace +## 0.2.0-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + ## 0.2.0-next.2 ### Patch Changes diff --git a/plugins/dynatrace/package.json b/plugins/dynatrace/package.json index 008e6f116f..3df69ca25f 100644 --- a/plugins/dynatrace/package.json +++ b/plugins/dynatrace/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-dynatrace", - "version": "0.2.0-next.2", + "version": "0.2.0-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -22,9 +22,9 @@ "postpack": "backstage-cli package postpack" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.9.13", "@material-ui/icons": "^4.9.1", @@ -36,10 +36,10 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/example-todo-list-backend/CHANGELOG.md b/plugins/example-todo-list-backend/CHANGELOG.md index ba33b2f29d..f3bdba1397 100644 --- a/plugins/example-todo-list-backend/CHANGELOG.md +++ b/plugins/example-todo-list-backend/CHANGELOG.md @@ -1,5 +1,15 @@ # @internal/plugin-todo-list-backend +## 1.0.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/plugin-auth-node@0.2.5-next.3 + ## 1.0.5-next.0 ### Patch Changes diff --git a/plugins/example-todo-list-backend/package.json b/plugins/example-todo-list-backend/package.json index 876afd4ea8..5623c22f58 100644 --- a/plugins/example-todo-list-backend/package.json +++ b/plugins/example-todo-list-backend/package.json @@ -1,6 +1,6 @@ { "name": "@internal/plugin-todo-list-backend", - "version": "1.0.5-next.0", + "version": "1.0.5-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -23,10 +23,10 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/backend-common": "^0.15.1-next.1", - "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0", - "@backstage/plugin-auth-node": "^0.2.5-next.1", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/config": "^1.0.2-next.0", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/plugin-auth-node": "^0.2.5-next.3", "@types/express": "^4.17.6", "express": "^4.17.1", "express-promise-router": "^4.1.0", @@ -35,7 +35,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.1", + "@backstage/cli": "^0.19.0-next.3", "@types/supertest": "^2.0.8", "@types/uuid": "^8.0.0", "msw": "^0.47.0", diff --git a/plugins/explore-react/CHANGELOG.md b/plugins/explore-react/CHANGELOG.md index c61f7049a3..0a1d2c795d 100644 --- a/plugins/explore-react/CHANGELOG.md +++ b/plugins/explore-react/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-explore-react +## 0.0.21-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/core-plugin-api@1.0.6-next.3 + ## 0.0.21-next.2 ### Patch Changes diff --git a/plugins/explore-react/package.json b/plugins/explore-react/package.json index 404832050a..1e715965a8 100644 --- a/plugins/explore-react/package.json +++ b/plugins/explore-react/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-explore-react", "description": "A frontend library for Backstage plugins that want to interact with the explore plugin", - "version": "0.0.21-next.2", + "version": "0.0.21-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,12 +32,12 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/core-plugin-api": "^1.0.6-next.2" + "@backstage/core-plugin-api": "^1.0.6-next.3" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/explore/CHANGELOG.md b/plugins/explore/CHANGELOG.md index 84f1f77494..c558be8b63 100644 --- a/plugins/explore/CHANGELOG.md +++ b/plugins/explore/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-explore +## 0.3.40-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/plugin-explore-react@0.0.21-next.3 + ## 0.3.40-next.2 ### Patch Changes diff --git a/plugins/explore/package.json b/plugins/explore/package.json index c06fcfc709..c0a5453c02 100644 --- a/plugins/explore/package.json +++ b/plugins/explore/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-explore", "description": "A Backstage plugin for building an exploration page of your software ecosystem", - "version": "0.3.40-next.2", + "version": "0.3.40-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,11 +32,11 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", - "@backstage/plugin-explore-react": "^0.0.21-next.2", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", + "@backstage/plugin-explore-react": "^0.0.21-next.3", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -51,10 +51,10 @@ "react-router-dom": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/firehydrant/CHANGELOG.md b/plugins/firehydrant/CHANGELOG.md index e1bea4bf11..1e55a1fdfa 100644 --- a/plugins/firehydrant/CHANGELOG.md +++ b/plugins/firehydrant/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-firehydrant +## 0.1.26-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + ## 0.1.26-next.2 ### Patch Changes diff --git a/plugins/firehydrant/package.json b/plugins/firehydrant/package.json index 695f0c60ee..bc10c957c6 100644 --- a/plugins/firehydrant/package.json +++ b/plugins/firehydrant/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-firehydrant", "description": "A Backstage plugin that integrates towards FireHydrant", - "version": "0.1.26-next.2", + "version": "0.1.26-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -23,9 +23,9 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -37,10 +37,10 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/fossa/CHANGELOG.md b/plugins/fossa/CHANGELOG.md index 68e6ec5a6e..05ec48b992 100644 --- a/plugins/fossa/CHANGELOG.md +++ b/plugins/fossa/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-fossa +## 0.2.41-next.2 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + ## 0.2.41-next.1 ### Patch Changes diff --git a/plugins/fossa/package.json b/plugins/fossa/package.json index f84604135b..c96353f3d6 100644 --- a/plugins/fossa/package.json +++ b/plugins/fossa/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-fossa", "description": "A Backstage plugin that integrates towards FOSSA", - "version": "0.2.41-next.1", + "version": "0.2.41-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,11 +33,11 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/errors": "^1.1.0", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -51,10 +51,10 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/gcalendar/CHANGELOG.md b/plugins/gcalendar/CHANGELOG.md index 7f522a6f9f..f87f087880 100644 --- a/plugins/gcalendar/CHANGELOG.md +++ b/plugins/gcalendar/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-gcalendar +## 0.3.5-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + ## 0.3.5-next.2 ### Patch Changes diff --git a/plugins/gcalendar/package.json b/plugins/gcalendar/package.json index d5a5125fd3..fbcc9b0c33 100644 --- a/plugins/gcalendar/package.json +++ b/plugins/gcalendar/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-gcalendar", - "version": "0.3.5-next.2", + "version": "0.3.5-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -22,9 +22,9 @@ "postpack": "backstage-cli package postpack" }, "dependencies": { - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/errors": "^1.1.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/errors": "^1.1.1-next.0", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -43,10 +43,10 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/gcp-projects/CHANGELOG.md b/plugins/gcp-projects/CHANGELOG.md index 95d1360c7e..cbd55e8414 100644 --- a/plugins/gcp-projects/CHANGELOG.md +++ b/plugins/gcp-projects/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-gcp-projects +## 0.3.28-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + ## 0.3.28-next.2 ### Patch Changes diff --git a/plugins/gcp-projects/package.json b/plugins/gcp-projects/package.json index 88f8c2c99f..601d491184 100644 --- a/plugins/gcp-projects/package.json +++ b/plugins/gcp-projects/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-gcp-projects", "description": "A Backstage plugin that helps you manage projects in GCP", - "version": "0.3.28-next.2", + "version": "0.3.28-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,8 +33,8 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -46,10 +46,10 @@ "react-router-dom": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/git-release-manager/CHANGELOG.md b/plugins/git-release-manager/CHANGELOG.md index 9ca3416e82..1dc0bd72bd 100644 --- a/plugins/git-release-manager/CHANGELOG.md +++ b/plugins/git-release-manager/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-git-release-manager +## 0.3.22-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/integration@1.3.1-next.2 + ## 0.3.22-next.2 ### Patch Changes diff --git a/plugins/git-release-manager/package.json b/plugins/git-release-manager/package.json index 3b90a363e3..fb56a6d0e1 100644 --- a/plugins/git-release-manager/package.json +++ b/plugins/git-release-manager/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-git-release-manager", "description": "A Backstage plugin that helps you manage releases in git", - "version": "0.3.22-next.2", + "version": "0.3.22-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -23,9 +23,9 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/integration": "^1.3.1-next.1", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/integration": "^1.3.1-next.2", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -42,10 +42,10 @@ "react-router": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/react-hooks": "^8.0.0", diff --git a/plugins/github-actions/CHANGELOG.md b/plugins/github-actions/CHANGELOG.md index 91fdab23d7..b261cef2ba 100644 --- a/plugins/github-actions/CHANGELOG.md +++ b/plugins/github-actions/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-github-actions +## 0.5.9-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/integration@1.3.1-next.2 + ## 0.5.9-next.2 ### Patch Changes diff --git a/plugins/github-actions/package.json b/plugins/github-actions/package.json index 646c599663..7866ded70e 100644 --- a/plugins/github-actions/package.json +++ b/plugins/github-actions/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-github-actions", "description": "A Backstage plugin that integrates towards GitHub Actions", - "version": "0.5.9-next.2", + "version": "0.5.9-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -34,11 +34,11 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/integration": "^1.3.1-next.1", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/integration": "^1.3.1-next.2", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -53,10 +53,10 @@ "react-router-dom": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/github-deployments/CHANGELOG.md b/plugins/github-deployments/CHANGELOG.md index e429e1f325..655d640357 100644 --- a/plugins/github-deployments/CHANGELOG.md +++ b/plugins/github-deployments/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-github-deployments +## 0.1.40-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/integration-react@1.1.4-next.2 + ## 0.1.40-next.2 ### Patch Changes diff --git a/plugins/github-deployments/package.json b/plugins/github-deployments/package.json index 04085204a8..8e32c3c0ff 100644 --- a/plugins/github-deployments/package.json +++ b/plugins/github-deployments/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-github-deployments", "description": "A Backstage plugin that integrates towards GitHub Deployments", - "version": "0.1.40-next.2", + "version": "0.1.40-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -23,13 +23,13 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/errors": "^1.1.0", - "@backstage/integration": "^1.3.1-next.1", - "@backstage/integration-react": "^1.1.4-next.1", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/integration": "^1.3.1-next.2", + "@backstage/integration-react": "^1.1.4-next.2", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -42,10 +42,10 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/github-issues/CHANGELOG.md b/plugins/github-issues/CHANGELOG.md index e36a2f2af8..758146689a 100644 --- a/plugins/github-issues/CHANGELOG.md +++ b/plugins/github-issues/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-github-issues +## 0.1.1-next.2 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + ## 0.1.1-next.1 ### Patch Changes diff --git a/plugins/github-issues/package.json b/plugins/github-issues/package.json index 3cbcb54bca..b98197505c 100644 --- a/plugins/github-issues/package.json +++ b/plugins/github-issues/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-github-issues", - "version": "0.1.1-next.1", + "version": "0.1.1-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -22,12 +22,12 @@ "postpack": "backstage-cli package postpack" }, "dependencies": { - "@backstage/catalog-model": "^1.0.3", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/errors": "^1.1.0", - "@backstage/integration": "^1.3.1-next.1", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/integration": "^1.3.1-next.2", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", "@backstage/theme": "^0.2.15", "@material-ui/core": "^4.12.4", "@material-ui/icons": "^4.9.1", @@ -40,10 +40,10 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@spotify/prettier-config": "^14.0.0", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", diff --git a/plugins/github-pull-requests-board/CHANGELOG.md b/plugins/github-pull-requests-board/CHANGELOG.md index 8455285ce0..37d3fdc257 100644 --- a/plugins/github-pull-requests-board/CHANGELOG.md +++ b/plugins/github-pull-requests-board/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-github-pull-requests-board +## 0.1.3-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/integration@1.3.1-next.2 + ## 0.1.3-next.2 ### Patch Changes diff --git a/plugins/github-pull-requests-board/package.json b/plugins/github-pull-requests-board/package.json index 03a1bd081e..d667acb5a3 100644 --- a/plugins/github-pull-requests-board/package.json +++ b/plugins/github-pull-requests-board/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-github-pull-requests-board", "description": "A Backstage plugin that allows you to see all open Pull Requests for all the repositories owned by your team", - "version": "0.1.3-next.2", + "version": "0.1.3-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -34,11 +34,11 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/integration": "^1.3.1-next.1", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/integration": "^1.3.1-next.2", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -48,9 +48,9 @@ "react-use": "^17.2.4" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/gitops-profiles/CHANGELOG.md b/plugins/gitops-profiles/CHANGELOG.md index 88cd223f38..93975d7184 100644 --- a/plugins/gitops-profiles/CHANGELOG.md +++ b/plugins/gitops-profiles/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-gitops-profiles +## 0.3.27-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + ## 0.3.27-next.2 ### Patch Changes diff --git a/plugins/gitops-profiles/package.json b/plugins/gitops-profiles/package.json index 9b850e5dc3..6e54ed98e9 100644 --- a/plugins/gitops-profiles/package.json +++ b/plugins/gitops-profiles/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-gitops-profiles", "description": "A Backstage plugin that helps you manage GitOps profiles", - "version": "0.3.27-next.2", + "version": "0.3.27-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,8 +33,8 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -46,10 +46,10 @@ "react-router-dom": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/gocd/CHANGELOG.md b/plugins/gocd/CHANGELOG.md index 2a9f31f68b..3673cc4163 100644 --- a/plugins/gocd/CHANGELOG.md +++ b/plugins/gocd/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-gocd +## 0.1.15-next.2 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + ## 0.1.15-next.1 ### Patch Changes diff --git a/plugins/gocd/package.json b/plugins/gocd/package.json index cee6976b5b..0ab50a90e5 100644 --- a/plugins/gocd/package.json +++ b/plugins/gocd/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-gocd", "description": "A Backstage plugin that integrates towards GoCD", - "version": "0.1.15-next.1", + "version": "0.1.15-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -29,11 +29,11 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/errors": "^1.1.0", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -47,10 +47,10 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/graphiql/CHANGELOG.md b/plugins/graphiql/CHANGELOG.md index 34c80287a7..a9f2f743ec 100644 --- a/plugins/graphiql/CHANGELOG.md +++ b/plugins/graphiql/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-graphiql +## 0.2.41-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + ## 0.2.41-next.2 ### Patch Changes diff --git a/plugins/graphiql/package.json b/plugins/graphiql/package.json index e19e1d4036..d6a16708b9 100644 --- a/plugins/graphiql/package.json +++ b/plugins/graphiql/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-graphiql", "description": "Backstage plugin for browsing GraphQL APIs", - "version": "0.2.41-next.2", + "version": "0.2.41-next.3", "publishConfig": { "access": "public", "main": "dist/index.esm.js", @@ -32,8 +32,8 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -48,10 +48,10 @@ "react-router-dom": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/graphql-backend/CHANGELOG.md b/plugins/graphql-backend/CHANGELOG.md index 86b91c9329..c94a7619b5 100644 --- a/plugins/graphql-backend/CHANGELOG.md +++ b/plugins/graphql-backend/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-graphql-backend +## 0.1.26-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/plugin-catalog-graphql@0.3.13-next.3 + ## 0.1.26-next.2 ### Patch Changes diff --git a/plugins/graphql-backend/package.json b/plugins/graphql-backend/package.json index 1f896d9128..96fe0c1fe8 100644 --- a/plugins/graphql-backend/package.json +++ b/plugins/graphql-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-graphql-backend", "description": "An experimental Backstage backend plugin for GraphQL", - "version": "0.1.26-next.2", + "version": "0.1.26-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,9 +33,9 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/backend-common": "^0.15.1-next.2", - "@backstage/config": "^1.0.1", - "@backstage/plugin-catalog-graphql": "^0.3.13-next.2", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/config": "^1.0.2-next.0", + "@backstage/plugin-catalog-graphql": "^0.3.13-next.3", "@graphql-tools/schema": "^9.0.0", "@types/express": "^4.17.6", "apollo-server": "^3.0.0", @@ -50,7 +50,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", + "@backstage/cli": "^0.19.0-next.3", "@types/supertest": "^2.0.8", "msw": "^0.47.0", "supertest": "^6.1.3" diff --git a/plugins/home/CHANGELOG.md b/plugins/home/CHANGELOG.md index 4c5c71d262..55da92f23f 100644 --- a/plugins/home/CHANGELOG.md +++ b/plugins/home/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-home +## 0.4.25-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/plugin-stack-overflow@0.1.5-next.3 + ## 0.4.25-next.2 ### Patch Changes diff --git a/plugins/home/package.json b/plugins/home/package.json index c53de70940..df285bad43 100644 --- a/plugins/home/package.json +++ b/plugins/home/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-home", "description": "A Backstage plugin that helps you build a home page", - "version": "0.4.25-next.2", + "version": "0.4.25-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,12 +33,12 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0", - "@backstage/config": "^1.0.1", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", - "@backstage/plugin-stack-overflow": "^0.1.5-next.2", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", + "@backstage/plugin-stack-overflow": "^0.1.5-next.3", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -52,10 +52,10 @@ "react-router": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/ilert/CHANGELOG.md b/plugins/ilert/CHANGELOG.md index 75da9167fe..bfb3ada100 100644 --- a/plugins/ilert/CHANGELOG.md +++ b/plugins/ilert/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-ilert +## 0.1.35-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + ## 0.1.35-next.2 ### Patch Changes diff --git a/plugins/ilert/package.json b/plugins/ilert/package.json index bdf7bdd430..7aa79fb143 100644 --- a/plugins/ilert/package.json +++ b/plugins/ilert/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-ilert", "description": "A Backstage plugin that integrates towards iLert", - "version": "0.1.35-next.2", + "version": "0.1.35-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -23,11 +23,11 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/errors": "^1.1.0", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", "@backstage/theme": "^0.2.16", "@date-io/luxon": "1.x", "@material-ui/core": "^4.12.2", @@ -42,10 +42,10 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/jenkins-backend/CHANGELOG.md b/plugins/jenkins-backend/CHANGELOG.md index 90756caa1c..9aa3e20d79 100644 --- a/plugins/jenkins-backend/CHANGELOG.md +++ b/plugins/jenkins-backend/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-jenkins-backend +## 0.1.26-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.1.0-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/plugin-permission-common@0.6.4-next.2 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/plugin-auth-node@0.2.5-next.3 + ## 0.1.26-next.2 ### Patch Changes diff --git a/plugins/jenkins-backend/package.json b/plugins/jenkins-backend/package.json index d910c9e682..55f856003e 100644 --- a/plugins/jenkins-backend/package.json +++ b/plugins/jenkins-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-jenkins-backend", "description": "A Backstage backend plugin that integrates towards Jenkins", - "version": "0.1.26-next.2", + "version": "0.1.26-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -24,14 +24,14 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/backend-common": "^0.15.1-next.2", - "@backstage/catalog-client": "^1.0.5-next.1", - "@backstage/catalog-model": "^1.1.0", - "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0", - "@backstage/plugin-auth-node": "^0.2.5-next.2", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/catalog-client": "^1.1.0-next.2", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/plugin-auth-node": "^0.2.5-next.3", "@backstage/plugin-jenkins-common": "^0.1.8-next.0", - "@backstage/plugin-permission-common": "^0.6.4-next.1", + "@backstage/plugin-permission-common": "^0.6.4-next.2", "@types/express": "^4.17.6", "express": "^4.17.1", "express-promise-router": "^4.1.0", @@ -41,7 +41,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", + "@backstage/cli": "^0.19.0-next.3", "@types/jenkins": "^0.23.1", "@types/supertest": "^2.0.8", "msw": "^0.47.0", diff --git a/plugins/jenkins/CHANGELOG.md b/plugins/jenkins/CHANGELOG.md index 5fc8526590..c6cc5ed432 100644 --- a/plugins/jenkins/CHANGELOG.md +++ b/plugins/jenkins/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-jenkins +## 0.7.8-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + ## 0.7.8-next.2 ### Patch Changes diff --git a/plugins/jenkins/package.json b/plugins/jenkins/package.json index 3243bd6411..f415770809 100644 --- a/plugins/jenkins/package.json +++ b/plugins/jenkins/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-jenkins", "description": "A Backstage plugin that integrates towards Jenkins", - "version": "0.7.8-next.2", + "version": "0.7.8-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,11 +33,11 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/errors": "^1.1.0", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", "@backstage/plugin-jenkins-common": "^0.1.8-next.0", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", @@ -52,10 +52,10 @@ "react-router-dom": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/kafka-backend/CHANGELOG.md b/plugins/kafka-backend/CHANGELOG.md index 6dd2737b9a..6bd87b05b7 100644 --- a/plugins/kafka-backend/CHANGELOG.md +++ b/plugins/kafka-backend/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-kafka-backend +## 0.2.29-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/backend-common@0.15.1-next.3 + ## 0.2.29-next.0 ### Patch Changes diff --git a/plugins/kafka-backend/package.json b/plugins/kafka-backend/package.json index 424c5db9fc..0d65283a53 100644 --- a/plugins/kafka-backend/package.json +++ b/plugins/kafka-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-kafka-backend", "description": "A Backstage backend plugin that integrates towards Kafka", - "version": "0.2.29-next.0", + "version": "0.2.29-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -34,10 +34,10 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/backend-common": "^0.15.1-next.1", - "@backstage/catalog-model": "^1.1.0", - "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/errors": "^1.1.1-next.0", "@types/express": "^4.17.6", "express": "^4.17.1", "express-promise-router": "^4.1.0", @@ -46,7 +46,7 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.1", + "@backstage/cli": "^0.19.0-next.3", "@types/jest-when": "^3.5.0", "@types/lodash": "^4.14.151", "jest-when": "^3.1.0", diff --git a/plugins/kafka/CHANGELOG.md b/plugins/kafka/CHANGELOG.md index 415c7603cd..3a9e86b62e 100644 --- a/plugins/kafka/CHANGELOG.md +++ b/plugins/kafka/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-kafka +## 0.3.9-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + ## 0.3.9-next.2 ### Patch Changes diff --git a/plugins/kafka/package.json b/plugins/kafka/package.json index 026d26de62..291f1dcea6 100644 --- a/plugins/kafka/package.json +++ b/plugins/kafka/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-kafka", "description": "A Backstage plugin that integrates towards Kafka", - "version": "0.3.9-next.2", + "version": "0.3.9-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -24,11 +24,11 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0", - "@backstage/config": "^1.0.1", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -40,10 +40,10 @@ "react-router": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/react-hooks": "^8.0.0", diff --git a/plugins/kubernetes-backend/CHANGELOG.md b/plugins/kubernetes-backend/CHANGELOG.md index f023e16e7d..626003f241 100644 --- a/plugins/kubernetes-backend/CHANGELOG.md +++ b/plugins/kubernetes-backend/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-kubernetes-backend +## 0.7.2-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.1.0-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/plugin-kubernetes-common@0.4.2-next.1 + - @backstage/plugin-auth-node@0.2.5-next.3 + ## 0.7.2-next.2 ### Patch Changes diff --git a/plugins/kubernetes-backend/package.json b/plugins/kubernetes-backend/package.json index 8af7439255..f40492e1b7 100644 --- a/plugins/kubernetes-backend/package.json +++ b/plugins/kubernetes-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-kubernetes-backend", "description": "A Backstage backend plugin that integrates towards Kubernetes", - "version": "0.7.2-next.2", + "version": "0.7.2-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -35,13 +35,13 @@ }, "dependencies": { "@azure/identity": "^2.0.4", - "@backstage/backend-common": "^0.15.1-next.2", - "@backstage/catalog-client": "^1.0.5-next.1", - "@backstage/catalog-model": "^1.1.0", - "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0", - "@backstage/plugin-auth-node": "^0.2.5-next.2", - "@backstage/plugin-kubernetes-common": "^0.4.2-next.0", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/catalog-client": "^1.1.0-next.2", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/plugin-auth-node": "^0.2.5-next.3", + "@backstage/plugin-kubernetes-common": "^0.4.2-next.1", "@google-cloud/container": "^4.0.0", "@kubernetes/client-node": "^0.17.0", "@types/express": "^4.17.6", @@ -62,7 +62,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", + "@backstage/cli": "^0.19.0-next.3", "@types/aws4": "^1.5.1", "aws-sdk-mock": "^5.2.1", "supertest": "^6.1.3" diff --git a/plugins/kubernetes-common/CHANGELOG.md b/plugins/kubernetes-common/CHANGELOG.md index 3046aab5d2..08ba0764dc 100644 --- a/plugins/kubernetes-common/CHANGELOG.md +++ b/plugins/kubernetes-common/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-kubernetes-common +## 0.4.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.1.1-next.0 + ## 0.4.2-next.0 ### Patch Changes diff --git a/plugins/kubernetes-common/package.json b/plugins/kubernetes-common/package.json index af5342db3f..3095ac68d4 100644 --- a/plugins/kubernetes-common/package.json +++ b/plugins/kubernetes-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-kubernetes-common", "description": "Common functionalities for kubernetes, to be shared between kubernetes and kubernetes-backend plugin", - "version": "0.4.2-next.0", + "version": "0.4.2-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -38,11 +38,11 @@ "url": "https://github.com/backstage/backstage/issues" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0", + "@backstage/catalog-model": "^1.1.1-next.0", "@kubernetes/client-node": "^0.17.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.1" + "@backstage/cli": "^0.19.0-next.3" }, "jest": { "roots": [ diff --git a/plugins/kubernetes/CHANGELOG.md b/plugins/kubernetes/CHANGELOG.md index 29f502d17a..264e550c5c 100644 --- a/plugins/kubernetes/CHANGELOG.md +++ b/plugins/kubernetes/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-kubernetes +## 0.7.2-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- 19a27929fb: Reset error state on success +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/plugin-kubernetes-common@0.4.2-next.1 + ## 0.7.2-next.2 ### Patch Changes diff --git a/plugins/kubernetes/package.json b/plugins/kubernetes/package.json index 574e1aa9fa..27b91b7c79 100644 --- a/plugins/kubernetes/package.json +++ b/plugins/kubernetes/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-kubernetes", "description": "A Backstage plugin that integrates towards Kubernetes", - "version": "0.7.2-next.2", + "version": "0.7.2-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,12 +33,12 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0", - "@backstage/config": "^1.0.1", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", - "@backstage/plugin-kubernetes-common": "^0.4.2-next.0", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", + "@backstage/plugin-kubernetes-common": "^0.4.2-next.1", "@backstage/theme": "^0.2.16", "@kubernetes/client-node": "^0.17.0", "@material-ui/core": "^4.12.2", @@ -56,10 +56,10 @@ "react-router-dom": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/react-hooks": "^8.0.0", diff --git a/plugins/lighthouse/CHANGELOG.md b/plugins/lighthouse/CHANGELOG.md index 4c2bf73400..7cb872e30f 100644 --- a/plugins/lighthouse/CHANGELOG.md +++ b/plugins/lighthouse/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-lighthouse +## 0.3.9-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + ## 0.3.9-next.2 ### Patch Changes diff --git a/plugins/lighthouse/package.json b/plugins/lighthouse/package.json index d209f4660f..cfe7be9b16 100644 --- a/plugins/lighthouse/package.json +++ b/plugins/lighthouse/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-lighthouse", "description": "A Backstage plugin that integrates towards Lighthouse", - "version": "0.3.9-next.2", + "version": "0.3.9-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,11 +33,11 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0", - "@backstage/config": "^1.0.1", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -49,10 +49,10 @@ "react-router-dom": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/react-hooks": "^8.0.0", diff --git a/plugins/newrelic-dashboard/CHANGELOG.md b/plugins/newrelic-dashboard/CHANGELOG.md index 0939b53154..8668e588fa 100644 --- a/plugins/newrelic-dashboard/CHANGELOG.md +++ b/plugins/newrelic-dashboard/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-newrelic-dashboard +## 0.2.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + ## 0.2.2-next.1 ### Patch Changes diff --git a/plugins/newrelic-dashboard/package.json b/plugins/newrelic-dashboard/package.json index 7673ba697b..d08ce75ef3 100644 --- a/plugins/newrelic-dashboard/package.json +++ b/plugins/newrelic-dashboard/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-newrelic-dashboard", - "version": "0.2.2-next.1", + "version": "0.2.2-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -22,19 +22,19 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0", - "@backstage/core-components": "^0.11.1-next.1", - "@backstage/core-plugin-api": "^1.0.6-next.1", - "@backstage/errors": "^1.1.0", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", "react-use": "^17.2.4" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.1", - "@backstage/dev-utils": "^1.0.6-next.1", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", "@testing-library/jest-dom": "^5.10.1", "@types/react": "^16.13.1 || ^17.0.0", "cross-fetch": "^3.1.5" diff --git a/plugins/newrelic/CHANGELOG.md b/plugins/newrelic/CHANGELOG.md index 0c56ba254d..3748b744de 100644 --- a/plugins/newrelic/CHANGELOG.md +++ b/plugins/newrelic/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-newrelic +## 0.3.27-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + ## 0.3.27-next.2 ### Patch Changes diff --git a/plugins/newrelic/package.json b/plugins/newrelic/package.json index 0d858cdc93..978b0abddd 100644 --- a/plugins/newrelic/package.json +++ b/plugins/newrelic/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-newrelic", "description": "A Backstage plugin that integrates towards New Relic", - "version": "0.3.27-next.2", + "version": "0.3.27-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,8 +33,8 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -45,10 +45,10 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/org/CHANGELOG.md b/plugins/org/CHANGELOG.md index 883a613b88..568bba4890 100644 --- a/plugins/org/CHANGELOG.md +++ b/plugins/org/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-org +## 0.5.9-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + ## 0.5.9-next.2 ### Patch Changes diff --git a/plugins/org/package.json b/plugins/org/package.json index a6701a3c1d..f62d938486 100644 --- a/plugins/org/package.json +++ b/plugins/org/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-org", "description": "A Backstage plugin that helps you create entity pages for your organization", - "version": "0.5.9-next.2", + "version": "0.5.9-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -28,10 +28,10 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -47,11 +47,11 @@ "react-router-dom": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/catalog-client": "^1.0.5-next.1", - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/catalog-client": "^1.1.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/pagerduty/CHANGELOG.md b/plugins/pagerduty/CHANGELOG.md index 42b61b3643..98485e3836 100644 --- a/plugins/pagerduty/CHANGELOG.md +++ b/plugins/pagerduty/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-pagerduty +## 0.5.2-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + ## 0.5.2-next.2 ### Patch Changes diff --git a/plugins/pagerduty/package.json b/plugins/pagerduty/package.json index df5971497d..dda460bbb6 100644 --- a/plugins/pagerduty/package.json +++ b/plugins/pagerduty/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-pagerduty", "description": "A Backstage plugin that integrates towards PagerDuty", - "version": "0.5.2-next.2", + "version": "0.5.2-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,11 +33,11 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/errors": "^1.1.0", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -52,10 +52,10 @@ "react-router-dom": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/periskop-backend/CHANGELOG.md b/plugins/periskop-backend/CHANGELOG.md index 5e01c50257..adf1520cf9 100644 --- a/plugins/periskop-backend/CHANGELOG.md +++ b/plugins/periskop-backend/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-periskop-backend +## 0.1.7-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/backend-common@0.15.1-next.3 + ## 0.1.7-next.2 ### Patch Changes diff --git a/plugins/periskop-backend/package.json b/plugins/periskop-backend/package.json index 088fe43d9c..c49d71028e 100644 --- a/plugins/periskop-backend/package.json +++ b/plugins/periskop-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-periskop-backend", - "version": "0.1.7-next.2", + "version": "0.1.7-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -23,8 +23,8 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/backend-common": "^0.15.1-next.2", - "@backstage/config": "^1.0.1", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/config": "^1.0.2-next.0", "@types/express": "*", "express": "^4.17.1", "express-promise-router": "^4.1.0", @@ -33,7 +33,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", + "@backstage/cli": "^0.19.0-next.3", "@types/supertest": "^2.0.8", "msw": "^0.47.0", "supertest": "^6.1.6" diff --git a/plugins/periskop/CHANGELOG.md b/plugins/periskop/CHANGELOG.md index 1e18571dc0..7b5cccc8d4 100644 --- a/plugins/periskop/CHANGELOG.md +++ b/plugins/periskop/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-periskop +## 0.1.7-next.2 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + ## 0.1.7-next.1 ### Patch Changes diff --git a/plugins/periskop/package.json b/plugins/periskop/package.json index 03a15b2b4a..b4494bc934 100644 --- a/plugins/periskop/package.json +++ b/plugins/periskop/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-periskop", - "version": "0.1.7-next.1", + "version": "0.1.7-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -23,11 +23,11 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/errors": "^1.1.0", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -40,10 +40,10 @@ "react-dom": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/permission-backend/CHANGELOG.md b/plugins/permission-backend/CHANGELOG.md index c8d4957c8a..615104ee9b 100644 --- a/plugins/permission-backend/CHANGELOG.md +++ b/plugins/permission-backend/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-permission-backend +## 0.5.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/plugin-permission-common@0.6.4-next.2 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/plugin-auth-node@0.2.5-next.3 + - @backstage/plugin-permission-node@0.6.5-next.3 + ## 0.5.11-next.1 ### Patch Changes diff --git a/plugins/permission-backend/package.json b/plugins/permission-backend/package.json index 1b47c84061..42dd4fcd1c 100644 --- a/plugins/permission-backend/package.json +++ b/plugins/permission-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-permission-backend", - "version": "0.5.11-next.1", + "version": "0.5.11-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -22,12 +22,12 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/backend-common": "^0.15.1-next.2", - "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0", - "@backstage/plugin-auth-node": "^0.2.5-next.2", - "@backstage/plugin-permission-common": "^0.6.4-next.1", - "@backstage/plugin-permission-node": "^0.6.5-next.2", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/config": "^1.0.2-next.0", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/plugin-auth-node": "^0.2.5-next.3", + "@backstage/plugin-permission-common": "^0.6.4-next.2", + "@backstage/plugin-permission-node": "^0.6.5-next.3", "@types/express": "*", "dataloader": "^2.0.0", "express": "^4.17.1", @@ -39,7 +39,7 @@ "zod": "^3.11.6" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", + "@backstage/cli": "^0.19.0-next.3", "@types/lodash": "^4.14.151", "@types/supertest": "^2.0.8", "msw": "^0.47.0", diff --git a/plugins/permission-common/CHANGELOG.md b/plugins/permission-common/CHANGELOG.md index 592f6b4fdb..0a64a7faf8 100644 --- a/plugins/permission-common/CHANGELOG.md +++ b/plugins/permission-common/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-permission-common +## 0.6.4-next.2 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + ## 0.6.4-next.1 ### Patch Changes diff --git a/plugins/permission-common/package.json b/plugins/permission-common/package.json index 6c3c9d2d29..5a6d98aba5 100644 --- a/plugins/permission-common/package.json +++ b/plugins/permission-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-permission-common", "description": "Isomorphic types and client for Backstage permissions and authorization", - "version": "0.6.4-next.1", + "version": "0.6.4-next.2", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { @@ -41,14 +41,14 @@ "url": "https://github.com/backstage/backstage/issues" }, "dependencies": { - "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/errors": "^1.1.1-next.0", "cross-fetch": "^3.1.5", "uuid": "^8.0.0", "zod": "^3.11.6" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", + "@backstage/cli": "^0.19.0-next.3", "msw": "^0.47.0" } } diff --git a/plugins/permission-node/CHANGELOG.md b/plugins/permission-node/CHANGELOG.md index 887061acbf..6ac474d76d 100644 --- a/plugins/permission-node/CHANGELOG.md +++ b/plugins/permission-node/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-permission-node +## 0.6.5-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/plugin-permission-common@0.6.4-next.2 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/plugin-auth-node@0.2.5-next.3 + ## 0.6.5-next.2 ### Patch Changes diff --git a/plugins/permission-node/package.json b/plugins/permission-node/package.json index ef8c932b68..6cb3f771d5 100644 --- a/plugins/permission-node/package.json +++ b/plugins/permission-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-permission-node", "description": "Common permission and authorization utilities for backend plugins", - "version": "0.6.5-next.2", + "version": "0.6.5-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,19 +33,19 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/backend-common": "^0.15.1-next.2", - "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0", - "@backstage/plugin-auth-node": "^0.2.5-next.2", - "@backstage/plugin-permission-common": "^0.6.4-next.1", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/config": "^1.0.2-next.0", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/plugin-auth-node": "^0.2.5-next.3", + "@backstage/plugin-permission-common": "^0.6.4-next.2", "@types/express": "^4.17.6", "express": "^4.17.1", "express-promise-router": "^4.1.0", "zod": "^3.11.6" }, "devDependencies": { - "@backstage/backend-test-utils": "^0.1.28-next.2", - "@backstage/cli": "^0.19.0-next.2", + "@backstage/backend-test-utils": "^0.1.28-next.3", + "@backstage/cli": "^0.19.0-next.3", "@types/supertest": "^2.0.8", "msw": "^0.47.0", "supertest": "^6.1.3" diff --git a/plugins/permission-react/CHANGELOG.md b/plugins/permission-react/CHANGELOG.md index e4414a7daa..8cc4c02424 100644 --- a/plugins/permission-react/CHANGELOG.md +++ b/plugins/permission-react/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-permission-react +## 0.4.5-next.2 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/plugin-permission-common@0.6.4-next.2 + ## 0.4.5-next.1 ### Patch Changes diff --git a/plugins/permission-react/package.json b/plugins/permission-react/package.json index 621379544c..82c5140f86 100644 --- a/plugins/permission-react/package.json +++ b/plugins/permission-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-permission-react", - "version": "0.4.5-next.1", + "version": "0.4.5-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -31,9 +31,9 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/config": "^1.0.1", - "@backstage/core-plugin-api": "^1.0.6-next.1", - "@backstage/plugin-permission-common": "^0.6.4-next.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/plugin-permission-common": "^0.6.4-next.2", "cross-fetch": "^3.1.5", "react-use": "^17.2.4", "swr": "^1.1.2" @@ -44,8 +44,8 @@ "react-router": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.1", - "@backstage/test-utils": "^1.2.0-next.1", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3" }, diff --git a/plugins/proxy-backend/CHANGELOG.md b/plugins/proxy-backend/CHANGELOG.md index d76c3511f9..08e89d6910 100644 --- a/plugins/proxy-backend/CHANGELOG.md +++ b/plugins/proxy-backend/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-proxy-backend +## 0.2.30-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/backend-common@0.15.1-next.3 + ## 0.2.30-next.1 ### Patch Changes diff --git a/plugins/proxy-backend/package.json b/plugins/proxy-backend/package.json index 1e7f7dc96e..1870c1ec7d 100644 --- a/plugins/proxy-backend/package.json +++ b/plugins/proxy-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-proxy-backend", "description": "A Backstage backend plugin that helps you set up proxy endpoints in the backend", - "version": "0.2.30-next.1", + "version": "0.2.30-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,8 +32,8 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/backend-common": "^0.15.1-next.2", - "@backstage/config": "^1.0.1", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/config": "^1.0.2-next.0", "@types/express": "^4.17.6", "express": "^4.17.1", "express-promise-router": "^4.1.0", @@ -46,7 +46,7 @@ "yup": "^0.32.9" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", + "@backstage/cli": "^0.19.0-next.3", "@types/http-proxy-middleware": "^0.19.3", "@types/supertest": "^2.0.8", "@types/uuid": "^8.0.0", diff --git a/plugins/rollbar-backend/CHANGELOG.md b/plugins/rollbar-backend/CHANGELOG.md index aaca8497da..8f821f6e8f 100644 --- a/plugins/rollbar-backend/CHANGELOG.md +++ b/plugins/rollbar-backend/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-rollbar-backend +## 0.1.33-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/backend-common@0.15.1-next.3 + ## 0.1.33-next.2 ### Patch Changes diff --git a/plugins/rollbar-backend/package.json b/plugins/rollbar-backend/package.json index c0777e9950..eb3b74e69a 100644 --- a/plugins/rollbar-backend/package.json +++ b/plugins/rollbar-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-rollbar-backend", "description": "A Backstage backend plugin that integrates towards Rollbar", - "version": "0.1.33-next.2", + "version": "0.1.33-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,8 +33,8 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/backend-common": "^0.15.1-next.2", - "@backstage/config": "^1.0.1", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/config": "^1.0.2-next.0", "@types/express": "^4.17.6", "camelcase-keys": "^7.0.1", "compression": "^1.7.4", @@ -49,8 +49,8 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/backend-test-utils": "^0.1.28-next.2", - "@backstage/cli": "^0.19.0-next.2", + "@backstage/backend-test-utils": "^0.1.28-next.3", + "@backstage/cli": "^0.19.0-next.3", "@types/supertest": "^2.0.8", "msw": "^0.47.0", "supertest": "^6.1.3" diff --git a/plugins/rollbar/CHANGELOG.md b/plugins/rollbar/CHANGELOG.md index 55926c9611..6d1464aa02 100644 --- a/plugins/rollbar/CHANGELOG.md +++ b/plugins/rollbar/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-rollbar +## 0.4.9-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + ## 0.4.9-next.2 ### Patch Changes diff --git a/plugins/rollbar/package.json b/plugins/rollbar/package.json index 769e002539..9cf5aa4964 100644 --- a/plugins/rollbar/package.json +++ b/plugins/rollbar/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-rollbar", "description": "A Backstage plugin that integrates towards Rollbar", - "version": "0.4.9-next.2", + "version": "0.4.9-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,10 +33,10 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -51,10 +51,10 @@ "react-router-dom": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/react-hooks": "^8.0.0", diff --git a/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md b/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md index 495712b802..77c0282940 100644 --- a/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-scaffolder-backend-module-cookiecutter +## 0.2.11-next.2 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/plugin-scaffolder-backend@1.6.0-next.3 + ## 0.2.11-next.1 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-cookiecutter/package.json b/plugins/scaffolder-backend-module-cookiecutter/package.json index a9c95cacb8..5c19a3d4cf 100644 --- a/plugins/scaffolder-backend-module-cookiecutter/package.json +++ b/plugins/scaffolder-backend-module-cookiecutter/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder-backend-module-cookiecutter", "description": "A module for the scaffolder backend that lets you template projects using cookiecutter", - "version": "0.2.11-next.1", + "version": "0.2.11-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -23,11 +23,11 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/backend-common": "^0.15.1-next.2", - "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0", - "@backstage/integration": "^1.3.1-next.1", - "@backstage/plugin-scaffolder-backend": "^1.6.0-next.2", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/config": "^1.0.2-next.0", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/integration": "^1.3.1-next.2", + "@backstage/plugin-scaffolder-backend": "^1.6.0-next.3", "@backstage/types": "^1.0.0", "command-exists": "^1.2.9", "fs-extra": "10.1.0", @@ -35,7 +35,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", + "@backstage/cli": "^0.19.0-next.3", "@types/command-exists": "^1.2.0", "@types/fs-extra": "^9.0.1", "@types/mock-fs": "^4.13.0", diff --git a/plugins/scaffolder-backend-module-rails/CHANGELOG.md b/plugins/scaffolder-backend-module-rails/CHANGELOG.md index 15930b6b1d..ceb954110b 100644 --- a/plugins/scaffolder-backend-module-rails/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-rails/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-scaffolder-backend-module-rails +## 0.4.4-next.1 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/plugin-scaffolder-backend@1.6.0-next.3 + ## 0.4.4-next.0 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-rails/package.json b/plugins/scaffolder-backend-module-rails/package.json index 3c47c435df..e60e643880 100644 --- a/plugins/scaffolder-backend-module-rails/package.json +++ b/plugins/scaffolder-backend-module-rails/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder-backend-module-rails", "description": "A module for the scaffolder backend that lets you template projects using Rails", - "version": "0.4.4-next.0", + "version": "0.4.4-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -23,17 +23,17 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/backend-common": "^0.15.1-next.1", - "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0", - "@backstage/integration": "^1.3.1-next.0", - "@backstage/plugin-scaffolder-backend": "^1.6.0-next.1", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/config": "^1.0.2-next.0", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/integration": "^1.3.1-next.2", + "@backstage/plugin-scaffolder-backend": "^1.6.0-next.3", "@backstage/types": "^1.0.0", "command-exists": "^1.2.9", "fs-extra": "^10.0.1" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.1", + "@backstage/cli": "^0.19.0-next.3", "@types/command-exists": "^1.2.0", "@types/fs-extra": "^9.0.1", "@types/mock-fs": "^4.13.0", diff --git a/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md b/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md index 117dd2e7d0..1769ad172e 100644 --- a/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-scaffolder-backend-module-yeoman +## 0.2.9-next.1 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/plugin-scaffolder-backend@1.6.0-next.3 + ## 0.2.9-next.0 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-yeoman/package.json b/plugins/scaffolder-backend-module-yeoman/package.json index 0a8648134f..eac08016f8 100644 --- a/plugins/scaffolder-backend-module-yeoman/package.json +++ b/plugins/scaffolder-backend-module-yeoman/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-yeoman", - "version": "0.2.9-next.0", + "version": "0.2.9-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -22,15 +22,15 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/config": "^1.0.1", - "@backstage/plugin-scaffolder-backend": "^1.6.0-next.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/plugin-scaffolder-backend": "^1.6.0-next.3", "@backstage/types": "^1.0.0", "winston": "^3.2.1", "yeoman-environment": "^3.9.1" }, "devDependencies": { - "@backstage/backend-common": "^0.15.1-next.0", - "@backstage/cli": "^0.19.0-next.1" + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/cli": "^0.19.0-next.3" }, "files": [ "dist" diff --git a/plugins/scaffolder-backend/CHANGELOG.md b/plugins/scaffolder-backend/CHANGELOG.md index b612234d50..bf0b46c509 100644 --- a/plugins/scaffolder-backend/CHANGELOG.md +++ b/plugins/scaffolder-backend/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-scaffolder-backend +## 1.6.0-next.3 + +### Patch Changes + +- 50467bc15b: The number of task workers used to execute templates now default to 3, rather than 1. +- Updated dependencies + - @backstage/plugin-catalog-node@1.1.0-next.2 + - @backstage/backend-plugin-api@0.1.2-next.2 + - @backstage/catalog-client@1.1.0-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/plugin-catalog-backend@1.4.0-next.3 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/plugin-scaffolder-common@1.2.0-next.1 + - @backstage/plugin-auth-node@0.2.5-next.3 + ## 1.6.0-next.2 ### Minor Changes diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index 7f8d7e1f67..5b72ab2f07 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder-backend", "description": "The Backstage backend plugin that helps you create new things", - "version": "1.6.0-next.2", + "version": "1.6.0-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -34,17 +34,17 @@ "build:assets": "node scripts/build-nunjucks.js" }, "dependencies": { - "@backstage/backend-common": "^0.15.1-next.2", - "@backstage/backend-plugin-api": "^0.1.2-next.1", - "@backstage/catalog-client": "^1.0.5-next.1", - "@backstage/catalog-model": "^1.1.0", - "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0", - "@backstage/integration": "^1.3.1-next.1", - "@backstage/plugin-auth-node": "^0.2.5-next.2", - "@backstage/plugin-catalog-backend": "^1.4.0-next.2", - "@backstage/plugin-catalog-node": "^1.0.2-next.1", - "@backstage/plugin-scaffolder-common": "^1.2.0-next.0", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/backend-plugin-api": "^0.1.2-next.2", + "@backstage/catalog-client": "^1.1.0-next.2", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/integration": "^1.3.1-next.2", + "@backstage/plugin-auth-node": "^0.2.5-next.3", + "@backstage/plugin-catalog-backend": "^1.4.0-next.3", + "@backstage/plugin-catalog-node": "^1.1.0-next.2", + "@backstage/plugin-scaffolder-common": "^1.2.0-next.1", "@backstage/types": "^1.0.0", "@gitbeaker/core": "^35.6.0", "@gitbeaker/node": "^35.1.0", @@ -79,8 +79,8 @@ "zod": "^3.11.6" }, "devDependencies": { - "@backstage/backend-test-utils": "^0.1.28-next.2", - "@backstage/cli": "^0.19.0-next.2", + "@backstage/backend-test-utils": "^0.1.28-next.3", + "@backstage/cli": "^0.19.0-next.3", "@types/command-exists": "^1.2.0", "@types/fs-extra": "^9.0.1", "@types/git-url-parse": "^9.0.0", diff --git a/plugins/scaffolder-common/CHANGELOG.md b/plugins/scaffolder-common/CHANGELOG.md index 95a5c9061b..f7cdcfe3b0 100644 --- a/plugins/scaffolder-common/CHANGELOG.md +++ b/plugins/scaffolder-common/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-scaffolder-common +## 1.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.1.1-next.0 + ## 1.2.0-next.0 ### Minor Changes diff --git a/plugins/scaffolder-common/package.json b/plugins/scaffolder-common/package.json index 834e3e266a..40ef29a3ae 100644 --- a/plugins/scaffolder-common/package.json +++ b/plugins/scaffolder-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder-common", "description": "Common functionalities for the scaffolder, to be shared between scaffolder and scaffolder-backend plugin", - "version": "1.2.0-next.0", + "version": "1.2.0-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -38,10 +38,10 @@ "url": "https://github.com/backstage/backstage/issues" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0", + "@backstage/catalog-model": "^1.1.1-next.0", "@backstage/types": "^1.0.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.1" + "@backstage/cli": "^0.19.0-next.3" } } diff --git a/plugins/scaffolder/CHANGELOG.md b/plugins/scaffolder/CHANGELOG.md index eccaecc152..d30be1c8fc 100644 --- a/plugins/scaffolder/CHANGELOG.md +++ b/plugins/scaffolder/CHANGELOG.md @@ -1,5 +1,25 @@ # @backstage/plugin-scaffolder +## 1.6.0-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- 6522e459aa: Support displaying and ordering by counts in `EntityTagPicker` field. Add the `showCounts` option to enable this. Also support configuring `helperText`. +- f0510a20b5: Addition of a dismissible Error Banner in Scaffolder page +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-client@1.1.0-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/integration-react@1.1.4-next.2 + - @backstage/plugin-permission-react@0.4.5-next.2 + - @backstage/plugin-scaffolder-common@1.2.0-next.1 + ## 1.6.0-next.2 ### Patch Changes diff --git a/plugins/scaffolder/package.json b/plugins/scaffolder/package.json index 5416c0bb2c..d0387ef4fe 100644 --- a/plugins/scaffolder/package.json +++ b/plugins/scaffolder/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder", "description": "The Backstage plugin that helps you create new things", - "version": "1.6.0-next.2", + "version": "1.6.0-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,18 +33,18 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-client": "^1.0.5-next.1", - "@backstage/catalog-model": "^1.1.0", - "@backstage/config": "^1.0.1", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/errors": "^1.1.0", - "@backstage/integration": "^1.3.1-next.1", - "@backstage/integration-react": "^1.1.4-next.1", + "@backstage/catalog-client": "^1.1.0-next.2", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/integration": "^1.3.1-next.2", + "@backstage/integration-react": "^1.1.4-next.2", "@backstage/plugin-catalog-common": "^1.0.6-next.0", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", - "@backstage/plugin-permission-react": "^0.4.5-next.1", - "@backstage/plugin-scaffolder-common": "^1.2.0-next.0", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", + "@backstage/plugin-permission-react": "^0.4.5-next.2", + "@backstage/plugin-scaffolder-common": "^1.2.0-next.1", "@backstage/theme": "^0.2.16", "@backstage/types": "^1.0.0", "@codemirror/language": "^6.0.0", @@ -79,11 +79,11 @@ "react-router-dom": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/plugin-catalog": "^1.5.1-next.2", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/plugin-catalog": "^1.5.1-next.3", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/react-hooks": "^8.0.0", diff --git a/plugins/search-backend-module-elasticsearch/CHANGELOG.md b/plugins/search-backend-module-elasticsearch/CHANGELOG.md index 83f4cdab3e..01b3be70b1 100644 --- a/plugins/search-backend-module-elasticsearch/CHANGELOG.md +++ b/plugins/search-backend-module-elasticsearch/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-search-backend-module-elasticsearch +## 1.0.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/plugin-search-backend-node@1.0.2-next.2 + ## 1.0.2-next.1 ### Patch Changes diff --git a/plugins/search-backend-module-elasticsearch/package.json b/plugins/search-backend-module-elasticsearch/package.json index 7b66d0c179..6ba1fe73d5 100644 --- a/plugins/search-backend-module-elasticsearch/package.json +++ b/plugins/search-backend-module-elasticsearch/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search-backend-module-elasticsearch", "description": "A module for the search backend that implements search using ElasticSearch", - "version": "1.0.2-next.1", + "version": "1.0.2-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -23,8 +23,8 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/config": "^1.0.1", - "@backstage/plugin-search-backend-node": "^1.0.2-next.1", + "@backstage/config": "^1.0.2-next.0", + "@backstage/plugin-search-backend-node": "^1.0.2-next.2", "@backstage/plugin-search-common": "^1.0.1-next.0", "@elastic/elasticsearch": "^7.13.0", "@opensearch-project/opensearch": "^2.0.0", @@ -36,8 +36,8 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/backend-common": "^0.15.1-next.2", - "@backstage/cli": "^0.19.0-next.2", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/cli": "^0.19.0-next.3", "@elastic/elasticsearch-mock": "^1.0.0", "@short.io/opensearch-mock": "^0.3.1" }, diff --git a/plugins/search-backend-module-pg/CHANGELOG.md b/plugins/search-backend-module-pg/CHANGELOG.md index 93d0abe0be..2610be5997 100644 --- a/plugins/search-backend-module-pg/CHANGELOG.md +++ b/plugins/search-backend-module-pg/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-search-backend-module-pg +## 0.4.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/plugin-search-backend-node@1.0.2-next.2 + ## 0.4.0-next.1 ### Patch Changes diff --git a/plugins/search-backend-module-pg/package.json b/plugins/search-backend-module-pg/package.json index f98e440972..cc04e46be1 100644 --- a/plugins/search-backend-module-pg/package.json +++ b/plugins/search-backend-module-pg/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search-backend-module-pg", "description": "A module for the search backend that implements search using PostgreSQL", - "version": "0.4.0-next.1", + "version": "0.4.0-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -23,17 +23,17 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/backend-common": "^0.15.1-next.1", - "@backstage/config": "^1.0.1", - "@backstage/plugin-search-backend-node": "^1.0.2-next.1", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/config": "^1.0.2-next.0", + "@backstage/plugin-search-backend-node": "^1.0.2-next.2", "@backstage/plugin-search-common": "^1.0.1-next.0", "knex": "^2.0.0", "lodash": "^4.17.21", "uuid": "^8.3.2" }, "devDependencies": { - "@backstage/backend-test-utils": "^0.1.28-next.1", - "@backstage/cli": "^0.19.0-next.1" + "@backstage/backend-test-utils": "^0.1.28-next.3", + "@backstage/cli": "^0.19.0-next.3" }, "files": [ "dist", diff --git a/plugins/search-backend-node/CHANGELOG.md b/plugins/search-backend-node/CHANGELOG.md index d5895611ab..dc16b57c18 100644 --- a/plugins/search-backend-node/CHANGELOG.md +++ b/plugins/search-backend-node/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-search-backend-node +## 1.0.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/plugin-permission-common@0.6.4-next.2 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/backend-tasks@0.3.5-next.1 + ## 1.0.2-next.1 ### Patch Changes diff --git a/plugins/search-backend-node/package.json b/plugins/search-backend-node/package.json index 6899afb192..096deeab9e 100644 --- a/plugins/search-backend-node/package.json +++ b/plugins/search-backend-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search-backend-node", "description": "A library for Backstage backend plugins that want to interact with the search backend plugin", - "version": "1.0.2-next.1", + "version": "1.0.2-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -23,11 +23,11 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/backend-common": "^0.15.1-next.1", - "@backstage/backend-tasks": "^0.3.5-next.0", - "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0", - "@backstage/plugin-permission-common": "^0.6.4-next.0", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/backend-tasks": "^0.3.5-next.1", + "@backstage/config": "^1.0.2-next.0", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/plugin-permission-common": "^0.6.4-next.2", "@backstage/plugin-search-common": "^1.0.1-next.0", "@types/lunr": "^2.3.3", "lodash": "^4.17.21", @@ -38,8 +38,8 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/backend-common": "^0.15.1-next.1", - "@backstage/cli": "^0.19.0-next.1", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/cli": "^0.19.0-next.3", "@types/ndjson": "^2.0.1" }, "files": [ diff --git a/plugins/search-backend/CHANGELOG.md b/plugins/search-backend/CHANGELOG.md index 6179dbff4f..0707bdd5d6 100644 --- a/plugins/search-backend/CHANGELOG.md +++ b/plugins/search-backend/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-search-backend +## 1.0.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/plugin-permission-common@0.6.4-next.2 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/plugin-auth-node@0.2.5-next.3 + - @backstage/plugin-permission-node@0.6.5-next.3 + - @backstage/plugin-search-backend-node@1.0.2-next.2 + ## 1.0.2-next.0 ### Patch Changes diff --git a/plugins/search-backend/package.json b/plugins/search-backend/package.json index c6a104b14e..56070040fd 100644 --- a/plugins/search-backend/package.json +++ b/plugins/search-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search-backend", "description": "The Backstage backend plugin that provides your backstage app with search", - "version": "1.0.2-next.0", + "version": "1.0.2-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -23,13 +23,13 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/backend-common": "^0.15.1-next.1", - "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0", - "@backstage/plugin-auth-node": "^0.2.5-next.1", - "@backstage/plugin-permission-common": "^0.6.4-next.0", - "@backstage/plugin-permission-node": "^0.6.5-next.1", - "@backstage/plugin-search-backend-node": "^1.0.2-next.1", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/config": "^1.0.2-next.0", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/plugin-auth-node": "^0.2.5-next.3", + "@backstage/plugin-permission-common": "^0.6.4-next.2", + "@backstage/plugin-permission-node": "^0.6.5-next.3", + "@backstage/plugin-search-backend-node": "^1.0.2-next.2", "@backstage/plugin-search-common": "^1.0.1-next.0", "@backstage/types": "^1.0.0", "@types/express": "^4.17.6", @@ -43,7 +43,7 @@ "zod": "^3.11.6" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.1", + "@backstage/cli": "^0.19.0-next.3", "@types/supertest": "^2.0.8", "supertest": "^6.1.3" }, diff --git a/plugins/search/CHANGELOG.md b/plugins/search/CHANGELOG.md index 6358e0495f..b02bccd5ed 100644 --- a/plugins/search/CHANGELOG.md +++ b/plugins/search/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-search +## 1.0.2-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + ## 1.0.2-next.2 ### Patch Changes diff --git a/plugins/search/package.json b/plugins/search/package.json index 89401a8189..ad9d95e81f 100644 --- a/plugins/search/package.json +++ b/plugins/search/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search", "description": "The Backstage plugin that provides your backstage app with search", - "version": "1.0.2-next.2", + "version": "1.0.2-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,12 +32,12 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0", - "@backstage/config": "^1.0.1", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/errors": "^1.1.0", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", "@backstage/plugin-search-common": "^1.0.1-next.0", "@backstage/plugin-search-react": "^1.1.0-next.2", "@backstage/theme": "^0.2.16", @@ -56,10 +56,10 @@ "react-router-dom": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/react-hooks": "^8.0.0", diff --git a/plugins/sentry/CHANGELOG.md b/plugins/sentry/CHANGELOG.md index ea399442f6..049627446c 100644 --- a/plugins/sentry/CHANGELOG.md +++ b/plugins/sentry/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-sentry +## 0.4.2-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + ## 0.4.2-next.2 ### Patch Changes diff --git a/plugins/sentry/package.json b/plugins/sentry/package.json index d23bd17cdb..b48f5b7489 100644 --- a/plugins/sentry/package.json +++ b/plugins/sentry/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-sentry", "description": "A Backstage plugin that integrates towards Sentry", - "version": "0.4.2-next.2", + "version": "0.4.2-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,10 +33,10 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", "@backstage/theme": "^0.2.16", "@material-table/core": "^3.1.0", "@material-ui/core": "^4.12.2", @@ -51,10 +51,10 @@ "react-router": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/shortcuts/CHANGELOG.md b/plugins/shortcuts/CHANGELOG.md index eed53a0314..8bf4e62b3a 100644 --- a/plugins/shortcuts/CHANGELOG.md +++ b/plugins/shortcuts/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-shortcuts +## 0.3.1-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + ## 0.3.1-next.2 ### Patch Changes diff --git a/plugins/shortcuts/package.json b/plugins/shortcuts/package.json index 80e0c75488..cf2038ffe3 100644 --- a/plugins/shortcuts/package.json +++ b/plugins/shortcuts/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-shortcuts", "description": "A Backstage plugin that provides a shortcuts feature to the sidebar", - "version": "0.3.1-next.2", + "version": "0.3.1-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -23,8 +23,8 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", "@backstage/theme": "^0.2.16", "@backstage/types": "^1.0.0", "@material-ui/core": "^4.12.2", @@ -41,10 +41,10 @@ "react-router": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/sonarqube-backend/CHANGELOG.md b/plugins/sonarqube-backend/CHANGELOG.md index ddb7eb49b4..dae521af5f 100644 --- a/plugins/sonarqube-backend/CHANGELOG.md +++ b/plugins/sonarqube-backend/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-sonarqube-backend +## 0.1.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/backend-common@0.15.1-next.3 + ## 0.1.1-next.1 ### Patch Changes diff --git a/plugins/sonarqube-backend/package.json b/plugins/sonarqube-backend/package.json index 928c21f939..2ecc0e5d10 100644 --- a/plugins/sonarqube-backend/package.json +++ b/plugins/sonarqube-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-sonarqube-backend", - "version": "0.1.1-next.1", + "version": "0.1.1-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -22,9 +22,9 @@ "postpack": "backstage-cli package postpack" }, "dependencies": { - "@backstage/backend-common": "^0.15.1-next.2", - "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/config": "^1.0.2-next.0", + "@backstage/errors": "^1.1.1-next.0", "@types/express": "*", "express": "^4.18.1", "express-promise-router": "^4.1.0", @@ -33,8 +33,8 @@ "yn": "^5.0.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/test-utils": "^1.2.0-next.3", "@types/supertest": "^2.0.12", "msw": "^0.47.0", "supertest": "^6.2.4" diff --git a/plugins/sonarqube/CHANGELOG.md b/plugins/sonarqube/CHANGELOG.md index a0c70158ce..9a33a45ebb 100644 --- a/plugins/sonarqube/CHANGELOG.md +++ b/plugins/sonarqube/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-sonarqube +## 0.4.1-next.2 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + ## 0.4.1-next.1 ### Patch Changes diff --git a/plugins/sonarqube/package.json b/plugins/sonarqube/package.json index d4a36da284..422fcebcdf 100644 --- a/plugins/sonarqube/package.json +++ b/plugins/sonarqube/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-sonarqube", "description": "", - "version": "0.4.1-next.1", + "version": "0.4.1-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -34,10 +34,10 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -51,10 +51,10 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/splunk-on-call/CHANGELOG.md b/plugins/splunk-on-call/CHANGELOG.md index 7f9ee71ca2..a3c4536f17 100644 --- a/plugins/splunk-on-call/CHANGELOG.md +++ b/plugins/splunk-on-call/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-splunk-on-call +## 0.3.33-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + ## 0.3.33-next.2 ### Patch Changes diff --git a/plugins/splunk-on-call/package.json b/plugins/splunk-on-call/package.json index f9e464819f..2ea4cbd62d 100644 --- a/plugins/splunk-on-call/package.json +++ b/plugins/splunk-on-call/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-splunk-on-call", "description": "A Backstage plugin that integrates towards Splunk On-Call", - "version": "0.3.33-next.2", + "version": "0.3.33-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,10 +33,10 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -50,10 +50,10 @@ "react-router-dom": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/stack-overflow-backend/CHANGELOG.md b/plugins/stack-overflow-backend/CHANGELOG.md index 0d47f9362e..f844a3de68 100644 --- a/plugins/stack-overflow-backend/CHANGELOG.md +++ b/plugins/stack-overflow-backend/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-stack-overflow-backend +## 0.1.5-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/cli@0.19.0-next.3 + ## 0.1.5-next.1 ### Patch Changes diff --git a/plugins/stack-overflow-backend/package.json b/plugins/stack-overflow-backend/package.json index 2c4c18d9e8..9f12767ef1 100644 --- a/plugins/stack-overflow-backend/package.json +++ b/plugins/stack-overflow-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-stack-overflow-backend", - "version": "0.1.5-next.1", + "version": "0.1.5-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,8 +32,8 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/cli": "^0.19.0-next.1", - "@backstage/config": "^1.0.1", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/config": "^1.0.2-next.0", "@backstage/plugin-search-common": "^1.0.1-next.0", "node-fetch": "^2.6.7", "qs": "^6.9.4", diff --git a/plugins/stack-overflow/CHANGELOG.md b/plugins/stack-overflow/CHANGELOG.md index 815d381673..25c55415b3 100644 --- a/plugins/stack-overflow/CHANGELOG.md +++ b/plugins/stack-overflow/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-stack-overflow +## 0.1.5-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/plugin-home@0.4.25-next.3 + ## 0.1.5-next.2 ### Patch Changes diff --git a/plugins/stack-overflow/package.json b/plugins/stack-overflow/package.json index 156f7b1a26..e3b514fca1 100644 --- a/plugins/stack-overflow/package.json +++ b/plugins/stack-overflow/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-stack-overflow", - "version": "0.1.5-next.2", + "version": "0.1.5-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -22,10 +22,10 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/config": "^1.0.1", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/plugin-home": "^0.4.25-next.2", + "@backstage/config": "^1.0.2-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/plugin-home": "^0.4.25-next.3", "@backstage/plugin-search-common": "^1.0.1-next.0", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", @@ -41,10 +41,10 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", diff --git a/plugins/tech-insights-backend-module-jsonfc/CHANGELOG.md b/plugins/tech-insights-backend-module-jsonfc/CHANGELOG.md index 6951f1d4ef..27782333f2 100644 --- a/plugins/tech-insights-backend-module-jsonfc/CHANGELOG.md +++ b/plugins/tech-insights-backend-module-jsonfc/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-tech-insights-backend-module-jsonfc +## 0.1.20-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/plugin-tech-insights-node@0.3.4-next.1 + ## 0.1.20-next.0 ### Patch Changes diff --git a/plugins/tech-insights-backend-module-jsonfc/package.json b/plugins/tech-insights-backend-module-jsonfc/package.json index e2a46b05bd..7716a426ab 100644 --- a/plugins/tech-insights-backend-module-jsonfc/package.json +++ b/plugins/tech-insights-backend-module-jsonfc/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-tech-insights-backend-module-jsonfc", - "version": "0.1.20-next.0", + "version": "0.1.20-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,11 +33,11 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/backend-common": "^0.15.1-next.1", - "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/config": "^1.0.2-next.0", + "@backstage/errors": "^1.1.1-next.0", "@backstage/plugin-tech-insights-common": "^0.2.6", - "@backstage/plugin-tech-insights-node": "^0.3.4-next.0", + "@backstage/plugin-tech-insights-node": "^0.3.4-next.1", "ajv": "^8.10.0", "json-rules-engine": "^6.1.2", "lodash": "^4.17.21", @@ -45,7 +45,7 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.1" + "@backstage/cli": "^0.19.0-next.3" }, "files": [ "dist" diff --git a/plugins/tech-insights-backend/CHANGELOG.md b/plugins/tech-insights-backend/CHANGELOG.md index 61a334770c..3daf38e0ef 100644 --- a/plugins/tech-insights-backend/CHANGELOG.md +++ b/plugins/tech-insights-backend/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-tech-insights-backend +## 0.5.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.1.0-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/backend-tasks@0.3.5-next.1 + - @backstage/plugin-tech-insights-node@0.3.4-next.1 + ## 0.5.2-next.1 ### Patch Changes diff --git a/plugins/tech-insights-backend/package.json b/plugins/tech-insights-backend/package.json index 556ad5163c..cd4db90942 100644 --- a/plugins/tech-insights-backend/package.json +++ b/plugins/tech-insights-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-tech-insights-backend", - "version": "0.5.2-next.1", + "version": "0.5.2-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,14 +33,14 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/backend-common": "^0.15.1-next.1", - "@backstage/backend-tasks": "^0.3.5-next.0", - "@backstage/catalog-client": "^1.0.5-next.0", - "@backstage/catalog-model": "^1.1.0", - "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/backend-tasks": "^0.3.5-next.1", + "@backstage/catalog-client": "^1.1.0-next.2", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/errors": "^1.1.1-next.0", "@backstage/plugin-tech-insights-common": "^0.2.6", - "@backstage/plugin-tech-insights-node": "^0.3.4-next.0", + "@backstage/plugin-tech-insights-node": "^0.3.4-next.1", "@types/express": "^4.17.6", "@types/luxon": "^3.0.0", "express": "^4.17.1", @@ -54,8 +54,8 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/backend-test-utils": "^0.1.28-next.1", - "@backstage/cli": "^0.19.0-next.1", + "@backstage/backend-test-utils": "^0.1.28-next.3", + "@backstage/cli": "^0.19.0-next.3", "@types/semver": "^7.3.8", "@types/supertest": "^2.0.8", "supertest": "^6.1.3", diff --git a/plugins/tech-insights-node/CHANGELOG.md b/plugins/tech-insights-node/CHANGELOG.md index 53e8b06716..0411c2fe2a 100644 --- a/plugins/tech-insights-node/CHANGELOG.md +++ b/plugins/tech-insights-node/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-tech-insights-node +## 0.3.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/backend-tasks@0.3.5-next.1 + ## 0.3.4-next.0 ### Patch Changes diff --git a/plugins/tech-insights-node/package.json b/plugins/tech-insights-node/package.json index e74b9df57f..41d4bebc62 100644 --- a/plugins/tech-insights-node/package.json +++ b/plugins/tech-insights-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-tech-insights-node", - "version": "0.3.4-next.0", + "version": "0.3.4-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,9 +32,9 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/backend-common": "^0.15.1-next.1", - "@backstage/backend-tasks": "^0.3.5-next.0", - "@backstage/config": "^1.0.1", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/backend-tasks": "^0.3.5-next.1", + "@backstage/config": "^1.0.2-next.0", "@backstage/plugin-tech-insights-common": "^0.2.6", "@backstage/types": "^1.0.0", "@types/luxon": "^3.0.0", @@ -42,7 +42,7 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.1" + "@backstage/cli": "^0.19.0-next.3" }, "files": [ "dist" diff --git a/plugins/tech-insights/CHANGELOG.md b/plugins/tech-insights/CHANGELOG.md index 5f2c9347a5..44b9d666d8 100644 --- a/plugins/tech-insights/CHANGELOG.md +++ b/plugins/tech-insights/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-tech-insights +## 0.3.0-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + ## 0.3.0-next.2 ### Patch Changes diff --git a/plugins/tech-insights/package.json b/plugins/tech-insights/package.json index 836181aea6..4e521c6436 100644 --- a/plugins/tech-insights/package.json +++ b/plugins/tech-insights/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-tech-insights", - "version": "0.3.0-next.2", + "version": "0.3.0-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -27,11 +27,11 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/errors": "^1.1.0", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", "@backstage/plugin-tech-insights-common": "^0.2.6", "@backstage/theme": "^0.2.16", "@backstage/types": "^1.0.0", @@ -46,10 +46,10 @@ "react-router-dom": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/tech-radar/CHANGELOG.md b/plugins/tech-radar/CHANGELOG.md index ef29d8e037..af98588824 100644 --- a/plugins/tech-radar/CHANGELOG.md +++ b/plugins/tech-radar/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-tech-radar +## 0.5.16-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + ## 0.5.16-next.2 ### Patch Changes diff --git a/plugins/tech-radar/package.json b/plugins/tech-radar/package.json index f2d4fd5ee2..e2cdbae22b 100644 --- a/plugins/tech-radar/package.json +++ b/plugins/tech-radar/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-tech-radar", "description": "A Backstage plugin that lets you display a Tech Radar for your organization", - "version": "0.5.16-next.2", + "version": "0.5.16-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,8 +32,8 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -47,10 +47,10 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/techdocs-addons-test-utils/CHANGELOG.md b/plugins/techdocs-addons-test-utils/CHANGELOG.md index 288c24b4b9..ceb99b546b 100644 --- a/plugins/techdocs-addons-test-utils/CHANGELOG.md +++ b/plugins/techdocs-addons-test-utils/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-techdocs-addons-test-utils +## 1.0.4-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/core-app-api@1.1.0-next.3 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/integration-react@1.1.4-next.2 + - @backstage/test-utils@1.2.0-next.3 + - @backstage/plugin-catalog@1.5.1-next.3 + - @backstage/plugin-techdocs@1.3.2-next.3 + - @backstage/plugin-techdocs-react@1.0.4-next.2 + ## 1.0.4-next.2 ### Patch Changes diff --git a/plugins/techdocs-addons-test-utils/package.json b/plugins/techdocs-addons-test-utils/package.json index 54548fb080..574503a9d8 100644 --- a/plugins/techdocs-addons-test-utils/package.json +++ b/plugins/techdocs-addons-test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs-addons-test-utils", - "version": "1.0.4-next.2", + "version": "1.0.4-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,15 +32,15 @@ "postpack": "backstage-cli package postpack" }, "dependencies": { - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/integration-react": "^1.1.4-next.1", - "@backstage/plugin-catalog": "^1.5.1-next.2", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/integration-react": "^1.1.4-next.2", + "@backstage/plugin-catalog": "^1.5.1-next.3", "@backstage/plugin-search-react": "^1.1.0-next.2", - "@backstage/plugin-techdocs": "^1.3.2-next.2", - "@backstage/plugin-techdocs-react": "^1.0.4-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/plugin-techdocs": "^1.3.2-next.3", + "@backstage/plugin-techdocs-react": "^1.0.4-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.9.13", "@material-ui/icons": "^4.9.1", @@ -56,8 +56,8 @@ "react-router-dom": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/techdocs-backend/CHANGELOG.md b/plugins/techdocs-backend/CHANGELOG.md index 6b4d76b393..8e695b9426 100644 --- a/plugins/techdocs-backend/CHANGELOG.md +++ b/plugins/techdocs-backend/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-techdocs-backend +## 1.3.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.1.0-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/plugin-permission-common@0.6.4-next.2 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/plugin-techdocs-node@1.4.0-next.2 + ## 1.3.0-next.1 ### Minor Changes diff --git a/plugins/techdocs-backend/package.json b/plugins/techdocs-backend/package.json index 9bed0743bd..6915d9b0b5 100644 --- a/plugins/techdocs-backend/package.json +++ b/plugins/techdocs-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-techdocs-backend", "description": "The Backstage backend plugin that renders technical documentation for your components", - "version": "1.3.0-next.1", + "version": "1.3.0-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,16 +33,16 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/backend-common": "^0.15.1-next.2", - "@backstage/catalog-client": "^1.0.5-next.1", - "@backstage/catalog-model": "^1.1.0", - "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0", - "@backstage/integration": "^1.3.1-next.1", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/catalog-client": "^1.1.0-next.2", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/integration": "^1.3.1-next.2", "@backstage/plugin-catalog-common": "^1.0.6-next.0", - "@backstage/plugin-permission-common": "^0.6.4-next.1", + "@backstage/plugin-permission-common": "^0.6.4-next.2", "@backstage/plugin-search-common": "^1.0.1-next.0", - "@backstage/plugin-techdocs-node": "^1.4.0-next.1", + "@backstage/plugin-techdocs-node": "^1.4.0-next.2", "@types/express": "^4.17.6", "dockerode": "^3.3.1", "express": "^4.17.1", @@ -55,9 +55,9 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/backend-test-utils": "^0.1.28-next.2", - "@backstage/cli": "^0.19.0-next.2", - "@backstage/plugin-search-backend-node": "1.0.2-next.1", + "@backstage/backend-test-utils": "^0.1.28-next.3", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/plugin-search-backend-node": "1.0.2-next.2", "@types/dockerode": "^3.3.0", "msw": "^0.47.0", "supertest": "^6.1.3" diff --git a/plugins/techdocs-module-addons-contrib/CHANGELOG.md b/plugins/techdocs-module-addons-contrib/CHANGELOG.md index b683b09e89..ea008bb121 100644 --- a/plugins/techdocs-module-addons-contrib/CHANGELOG.md +++ b/plugins/techdocs-module-addons-contrib/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-techdocs-module-addons-contrib +## 1.0.4-next.2 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/integration@1.3.1-next.2 + - @backstage/integration-react@1.1.4-next.2 + - @backstage/plugin-techdocs-react@1.0.4-next.2 + ## 1.0.4-next.1 ### Patch Changes diff --git a/plugins/techdocs-module-addons-contrib/package.json b/plugins/techdocs-module-addons-contrib/package.json index 35db982035..250394603c 100644 --- a/plugins/techdocs-module-addons-contrib/package.json +++ b/plugins/techdocs-module-addons-contrib/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-techdocs-module-addons-contrib", "description": "Plugin module for contributed TechDocs Addons", - "version": "1.0.4-next.1", + "version": "1.0.4-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,11 +33,11 @@ "postpack": "backstage-cli package postpack" }, "dependencies": { - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/integration": "^1.3.1-next.1", - "@backstage/integration-react": "^1.1.4-next.1", - "@backstage/plugin-techdocs-react": "^1.0.4-next.1", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/integration": "^1.3.1-next.2", + "@backstage/integration-react": "^1.1.4-next.2", + "@backstage/plugin-techdocs-react": "^1.0.4-next.2", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.9.13", "@material-ui/icons": "^4.9.1", @@ -50,11 +50,11 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/plugin-techdocs-addons-test-utils": "^1.0.4-next.2", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/plugin-techdocs-addons-test-utils": "^1.0.4-next.3", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/techdocs-node/CHANGELOG.md b/plugins/techdocs-node/CHANGELOG.md index f17a69ce4d..1dabca3005 100644 --- a/plugins/techdocs-node/CHANGELOG.md +++ b/plugins/techdocs-node/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-techdocs-node +## 1.4.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/backend-common@0.15.1-next.3 + ## 1.4.0-next.1 ### Minor Changes diff --git a/plugins/techdocs-node/package.json b/plugins/techdocs-node/package.json index f6d9042359..8bd6971528 100644 --- a/plugins/techdocs-node/package.json +++ b/plugins/techdocs-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-techdocs-node", "description": "Common node.js functionalities for TechDocs, to be shared between techdocs-backend plugin and techdocs-cli", - "version": "1.4.0-next.1", + "version": "1.4.0-next.2", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { @@ -41,11 +41,11 @@ "dependencies": { "@azure/identity": "^2.0.1", "@azure/storage-blob": "^12.5.0", - "@backstage/backend-common": "^0.15.1-next.2", - "@backstage/catalog-model": "^1.1.0", - "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0", - "@backstage/integration": "^1.3.1-next.1", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/integration": "^1.3.1-next.2", "@backstage/plugin-search-common": "^1.0.1-next.0", "@google-cloud/storage": "^6.0.0", "@trendyol-js/openstack-swift-sdk": "^0.0.5", @@ -63,7 +63,7 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", + "@backstage/cli": "^0.19.0-next.3", "@types/fs-extra": "^9.0.5", "@types/js-yaml": "^4.0.0", "@types/mime-types": "^2.1.0", diff --git a/plugins/techdocs-react/CHANGELOG.md b/plugins/techdocs-react/CHANGELOG.md index 07599edc75..b7223d3ba4 100644 --- a/plugins/techdocs-react/CHANGELOG.md +++ b/plugins/techdocs-react/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-techdocs-react +## 1.0.4-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + ## 1.0.4-next.1 ### Patch Changes diff --git a/plugins/techdocs-react/package.json b/plugins/techdocs-react/package.json index f86ff600d8..d54de784aa 100644 --- a/plugins/techdocs-react/package.json +++ b/plugins/techdocs-react/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-techdocs-react", "description": "Shared frontend utilities for TechDocs and Addons", - "version": "1.0.4-next.1", + "version": "1.0.4-next.2", "publishConfig": { "access": "public", "alphaTypes": "dist/index.alpha.d.ts", @@ -34,10 +34,10 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0", - "@backstage/config": "^1.0.1", - "@backstage/core-components": "^0.11.1-next.1", - "@backstage/core-plugin-api": "^1.0.6-next.1", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", "@backstage/version-bridge": "^1.0.1", "@material-ui/core": "^4.12.2", "@material-ui/lab": "4.0.0-alpha.57", @@ -53,8 +53,8 @@ "react-router-dom": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.1", - "@backstage/test-utils": "^1.2.0-next.1", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/test-utils": "^1.2.0-next.3", "@backstage/theme": "^0.2.16", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", diff --git a/plugins/techdocs/CHANGELOG.md b/plugins/techdocs/CHANGELOG.md index b40aed750d..a89b1361ca 100644 --- a/plugins/techdocs/CHANGELOG.md +++ b/plugins/techdocs/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-techdocs +## 1.3.2-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/integration-react@1.1.4-next.2 + - @backstage/plugin-techdocs-react@1.0.4-next.2 + ## 1.3.2-next.2 ### Patch Changes diff --git a/plugins/techdocs/package.json b/plugins/techdocs/package.json index 4ea6307408..e484b6ba07 100644 --- a/plugins/techdocs/package.json +++ b/plugins/techdocs/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-techdocs", "description": "The Backstage plugin that renders technical documentation for your components", - "version": "1.3.2-next.2", + "version": "1.3.2-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,17 +33,17 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0", - "@backstage/config": "^1.0.1", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/errors": "^1.1.0", - "@backstage/integration": "^1.3.1-next.1", - "@backstage/integration-react": "^1.1.4-next.1", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/integration": "^1.3.1-next.2", + "@backstage/integration-react": "^1.1.4-next.2", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", "@backstage/plugin-search-common": "^1.0.1-next.0", "@backstage/plugin-search-react": "^1.1.0-next.2", - "@backstage/plugin-techdocs-react": "^1.0.4-next.1", + "@backstage/plugin-techdocs-react": "^1.0.4-next.2", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -65,10 +65,10 @@ "react-router-dom": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/react-hooks": "^8.0.0", diff --git a/plugins/todo-backend/CHANGELOG.md b/plugins/todo-backend/CHANGELOG.md index aca3dfb965..b77960123a 100644 --- a/plugins/todo-backend/CHANGELOG.md +++ b/plugins/todo-backend/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-todo-backend +## 0.1.33-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.1.0-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/backend-common@0.15.1-next.3 + ## 0.1.33-next.1 ### Patch Changes diff --git a/plugins/todo-backend/package.json b/plugins/todo-backend/package.json index 1ecce23282..55bf606f4e 100644 --- a/plugins/todo-backend/package.json +++ b/plugins/todo-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-todo-backend", "description": "A Backstage backend plugin that lets you browse TODO comments in your source code", - "version": "0.1.33-next.1", + "version": "0.1.33-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -29,12 +29,12 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/backend-common": "^0.15.1-next.2", - "@backstage/catalog-client": "^1.0.5-next.1", - "@backstage/catalog-model": "^1.1.0", - "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0", - "@backstage/integration": "^1.3.1-next.1", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/catalog-client": "^1.1.0-next.2", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/integration": "^1.3.1-next.2", "@types/express": "^4.17.6", "express": "^4.17.1", "express-promise-router": "^4.1.0", @@ -43,7 +43,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", + "@backstage/cli": "^0.19.0-next.3", "@types/supertest": "^2.0.8", "msw": "^0.47.0", "supertest": "^6.1.3" diff --git a/plugins/todo/CHANGELOG.md b/plugins/todo/CHANGELOG.md index 88d4812a28..da47468aa2 100644 --- a/plugins/todo/CHANGELOG.md +++ b/plugins/todo/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-todo +## 0.2.11-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + ## 0.2.11-next.2 ### Patch Changes diff --git a/plugins/todo/package.json b/plugins/todo/package.json index 880209654b..9ee1e06b98 100644 --- a/plugins/todo/package.json +++ b/plugins/todo/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-todo", "description": "A Backstage plugin that lets you browse TODO comments in your source code", - "version": "0.2.11-next.2", + "version": "0.2.11-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -29,11 +29,11 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/errors": "^1.1.0", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -45,10 +45,10 @@ "react-router": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/user-settings/CHANGELOG.md b/plugins/user-settings/CHANGELOG.md index e720e3255d..e249499aa4 100644 --- a/plugins/user-settings/CHANGELOG.md +++ b/plugins/user-settings/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-user-settings +## 0.4.8-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + ## 0.4.8-next.2 ### Patch Changes diff --git a/plugins/user-settings/package.json b/plugins/user-settings/package.json index 0f6ab5161b..f99c0d206e 100644 --- a/plugins/user-settings/package.json +++ b/plugins/user-settings/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-user-settings", "description": "A Backstage plugin that provides a settings page", - "version": "0.4.8-next.2", + "version": "0.4.8-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,8 +32,8 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -46,10 +46,10 @@ "react-router": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/vault-backend/CHANGELOG.md b/plugins/vault-backend/CHANGELOG.md index 7d839d2f31..8ef29cf44a 100644 --- a/plugins/vault-backend/CHANGELOG.md +++ b/plugins/vault-backend/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-vault-backend +## 0.2.2-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + - @backstage/backend-test-utils@0.1.28-next.3 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/backend-tasks@0.3.5-next.1 + ## 0.2.2-next.2 ### Patch Changes diff --git a/plugins/vault-backend/package.json b/plugins/vault-backend/package.json index b6b59892e0..b90118bb66 100644 --- a/plugins/vault-backend/package.json +++ b/plugins/vault-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-vault-backend", "description": "A Backstage backend plugin that integrates towards Vault", - "version": "0.2.2-next.2", + "version": "0.2.2-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,11 +33,11 @@ "postpack": "backstage-cli package postpack" }, "dependencies": { - "@backstage/backend-common": "^0.15.1-next.2", - "@backstage/backend-tasks": "^0.3.5-next.0", - "@backstage/backend-test-utils": "^0.1.28-next.2", - "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/backend-tasks": "^0.3.5-next.1", + "@backstage/backend-test-utils": "^0.1.28-next.3", + "@backstage/config": "^1.0.2-next.0", + "@backstage/errors": "^1.1.1-next.0", "@types/express": "*", "compression": "^1.7.4", "cors": "^2.8.5", @@ -50,7 +50,7 @@ "yn": "^5.0.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", + "@backstage/cli": "^0.19.0-next.3", "@types/compression": "^1.7.2", "@types/supertest": "^2.0.8", "msw": "^0.47.0", diff --git a/plugins/vault/CHANGELOG.md b/plugins/vault/CHANGELOG.md index e551781a71..852be0d87e 100644 --- a/plugins/vault/CHANGELOG.md +++ b/plugins/vault/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-vault +## 0.1.3-next.2 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + ## 0.1.3-next.1 ### Patch Changes diff --git a/plugins/vault/package.json b/plugins/vault/package.json index 00d4d4bf47..762a5328ea 100644 --- a/plugins/vault/package.json +++ b/plugins/vault/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-vault", "description": "A Backstage plugin that integrates towards Vault", - "version": "0.1.3-next.1", + "version": "0.1.3-next.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,11 +33,11 @@ "postpack": "backstage-cli package postpack" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/errors": "^1.1.0", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -48,10 +48,10 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/xcmetrics/CHANGELOG.md b/plugins/xcmetrics/CHANGELOG.md index 8d64162dbe..b998a9955e 100644 --- a/plugins/xcmetrics/CHANGELOG.md +++ b/plugins/xcmetrics/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-xcmetrics +## 0.2.29-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + ## 0.2.29-next.2 ### Patch Changes diff --git a/plugins/xcmetrics/package.json b/plugins/xcmetrics/package.json index 94cd0e8066..0b4099b691 100644 --- a/plugins/xcmetrics/package.json +++ b/plugins/xcmetrics/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-xcmetrics", "description": "A Backstage plugin that shows XCode build metrics for your components", - "version": "0.2.29-next.2", + "version": "0.2.29-next.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -23,9 +23,9 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/errors": "^1.1.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/errors": "^1.1.1-next.0", "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -39,10 +39,10 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/yarn.lock b/yarn.lock index c772e1a835..8c36d1da02 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2814,16 +2814,16 @@ __metadata: languageName: node linkType: hard -"@backstage/app-defaults@^1.0.6-next.1, @backstage/app-defaults@workspace:packages/app-defaults": +"@backstage/app-defaults@^1.0.6-next.2, @backstage/app-defaults@workspace:packages/app-defaults": version: 0.0.0-use.local resolution: "@backstage/app-defaults@workspace:packages/app-defaults" dependencies: - "@backstage/cli": ^0.19.0-next.1 - "@backstage/core-app-api": ^1.1.0-next.1 - "@backstage/core-components": ^0.11.1-next.1 - "@backstage/core-plugin-api": ^1.0.6-next.1 - "@backstage/plugin-permission-react": ^0.4.5-next.1 - "@backstage/test-utils": ^1.2.0-next.1 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/plugin-permission-react": ^0.4.5-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -2839,33 +2839,33 @@ __metadata: languageName: unknown linkType: soft -"@backstage/backend-app-api@^0.2.1-next.0, @backstage/backend-app-api@^0.2.1-next.1, @backstage/backend-app-api@workspace:packages/backend-app-api": +"@backstage/backend-app-api@^0.2.1-next.2, @backstage/backend-app-api@workspace:packages/backend-app-api": version: 0.0.0-use.local resolution: "@backstage/backend-app-api@workspace:packages/backend-app-api" dependencies: - "@backstage/backend-common": ^0.15.1-next.2 - "@backstage/backend-plugin-api": ^0.1.2-next.1 - "@backstage/backend-tasks": ^0.3.5-next.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/errors": ^1.1.0 - "@backstage/plugin-permission-node": ^0.6.5-next.2 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/backend-plugin-api": ^0.1.2-next.2 + "@backstage/backend-tasks": ^0.3.5-next.1 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/plugin-permission-node": ^0.6.5-next.3 express: ^4.17.1 express-promise-router: ^4.1.0 winston: ^3.2.1 languageName: unknown linkType: soft -"@backstage/backend-common@^0.15.1-next.0, @backstage/backend-common@^0.15.1-next.1, @backstage/backend-common@^0.15.1-next.2, @backstage/backend-common@workspace:packages/backend-common": +"@backstage/backend-common@^0.15.1-next.3, @backstage/backend-common@workspace:packages/backend-common": version: 0.0.0-use.local resolution: "@backstage/backend-common@workspace:packages/backend-common" dependencies: - "@backstage/backend-test-utils": ^0.1.28-next.2 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/cli-common": ^0.1.9 - "@backstage/config": ^1.0.1 - "@backstage/config-loader": ^1.1.4-next.1 - "@backstage/errors": ^1.1.0 - "@backstage/integration": ^1.3.1-next.1 + "@backstage/backend-test-utils": ^0.1.28-next.3 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/cli-common": ^0.1.10-next.0 + "@backstage/config": ^1.0.2-next.0 + "@backstage/config-loader": ^1.1.4-next.2 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/integration": ^1.3.1-next.2 "@backstage/types": ^1.0.0 "@google-cloud/storage": ^6.0.0 "@keyv/redis": ^2.2.3 @@ -2945,21 +2945,21 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/backend-defaults@workspace:packages/backend-defaults" dependencies: - "@backstage/backend-app-api": ^0.2.1-next.0 - "@backstage/backend-plugin-api": ^0.1.2-next.0 - "@backstage/cli": ^0.19.0-next.1 + "@backstage/backend-app-api": ^0.2.1-next.2 + "@backstage/backend-plugin-api": ^0.1.2-next.2 + "@backstage/cli": ^0.19.0-next.3 languageName: unknown linkType: soft -"@backstage/backend-plugin-api@^0.1.2-next.0, @backstage/backend-plugin-api@^0.1.2-next.1, @backstage/backend-plugin-api@workspace:packages/backend-plugin-api": +"@backstage/backend-plugin-api@^0.1.2-next.2, @backstage/backend-plugin-api@workspace:packages/backend-plugin-api": version: 0.0.0-use.local resolution: "@backstage/backend-plugin-api@workspace:packages/backend-plugin-api" dependencies: - "@backstage/backend-common": ^0.15.1-next.2 - "@backstage/backend-tasks": ^0.3.5-next.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/plugin-permission-common": ^0.6.4-next.1 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/backend-tasks": ^0.3.5-next.1 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/plugin-permission-common": ^0.6.4-next.2 "@types/express": ^4.17.6 express: ^4.17.1 winston: ^3.2.1 @@ -2967,15 +2967,15 @@ __metadata: languageName: unknown linkType: soft -"@backstage/backend-tasks@^0.3.5-next.0, @backstage/backend-tasks@workspace:packages/backend-tasks": +"@backstage/backend-tasks@^0.3.5-next.1, @backstage/backend-tasks@workspace:packages/backend-tasks": version: 0.0.0-use.local resolution: "@backstage/backend-tasks@workspace:packages/backend-tasks" dependencies: - "@backstage/backend-common": ^0.15.1-next.1 - "@backstage/backend-test-utils": ^0.1.28-next.1 - "@backstage/cli": ^0.19.0-next.1 - "@backstage/config": ^1.0.1 - "@backstage/errors": ^1.1.0 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/backend-test-utils": ^0.1.28-next.3 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/errors": ^1.1.1-next.0 "@backstage/types": ^1.0.0 "@types/cron": ^2.0.0 "@types/luxon": ^3.0.0 @@ -2991,15 +2991,15 @@ __metadata: languageName: unknown linkType: soft -"@backstage/backend-test-utils@^0.1.28-next.1, @backstage/backend-test-utils@^0.1.28-next.2, @backstage/backend-test-utils@workspace:packages/backend-test-utils": +"@backstage/backend-test-utils@^0.1.28-next.3, @backstage/backend-test-utils@workspace:packages/backend-test-utils": version: 0.0.0-use.local resolution: "@backstage/backend-test-utils@workspace:packages/backend-test-utils" dependencies: - "@backstage/backend-app-api": ^0.2.1-next.1 - "@backstage/backend-common": ^0.15.1-next.2 - "@backstage/backend-plugin-api": ^0.1.2-next.1 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 + "@backstage/backend-app-api": ^0.2.1-next.2 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/backend-plugin-api": ^0.1.2-next.2 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 better-sqlite3: ^7.5.0 knex: ^2.0.0 msw: ^0.47.0 @@ -3010,13 +3010,13 @@ __metadata: languageName: unknown linkType: soft -"@backstage/catalog-client@^1.0.5-next.0, @backstage/catalog-client@^1.0.5-next.1, @backstage/catalog-client@workspace:packages/catalog-client": +"@backstage/catalog-client@^1.1.0-next.2, @backstage/catalog-client@workspace:packages/catalog-client": version: 0.0.0-use.local resolution: "@backstage/catalog-client@workspace:packages/catalog-client" dependencies: - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/errors": ^1.1.0 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/errors": ^1.1.1-next.0 cross-fetch: ^3.1.5 msw: ^0.47.0 languageName: unknown @@ -3033,13 +3033,13 @@ __metadata: languageName: node linkType: hard -"@backstage/catalog-model@^1.0.0, @backstage/catalog-model@^1.0.1, @backstage/catalog-model@^1.0.3, @backstage/catalog-model@^1.1.0, @backstage/catalog-model@workspace:packages/catalog-model": +"@backstage/catalog-model@^1.1.1-next.0, @backstage/catalog-model@workspace:packages/catalog-model": version: 0.0.0-use.local resolution: "@backstage/catalog-model@workspace:packages/catalog-model" dependencies: - "@backstage/cli": ^0.19.0-next.1 - "@backstage/config": ^1.0.1 - "@backstage/errors": ^1.1.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/errors": ^1.1.1-next.0 "@backstage/types": ^1.0.0 "@types/json-schema": ^7.0.5 "@types/lodash": ^4.14.151 @@ -3051,30 +3051,45 @@ __metadata: languageName: unknown linkType: soft -"@backstage/cli-common@^0.1.9, @backstage/cli-common@^0.1.9-next.0, @backstage/cli-common@workspace:packages/cli-common": +"@backstage/catalog-model@npm:^1.0.0, @backstage/catalog-model@npm:^1.1.0": + version: 1.1.0 + resolution: "@backstage/catalog-model@npm:1.1.0" + dependencies: + "@backstage/config": ^1.0.1 + "@backstage/errors": ^1.1.0 + "@backstage/types": ^1.0.0 + ajv: ^8.10.0 + json-schema: ^0.4.0 + lodash: ^4.17.21 + uuid: ^8.0.0 + checksum: 81db2da7f960e6207f2eeab3944d5bc54d739b6172575cf4cb9096a2058835af75534fd5232c450efddc8d656952ebbf130501ac0bba43690a3d742c3e11143d + languageName: node + linkType: hard + +"@backstage/cli-common@^0.1.10-next.0, @backstage/cli-common@workspace:packages/cli-common": version: 0.0.0-use.local resolution: "@backstage/cli-common@workspace:packages/cli-common" dependencies: - "@backstage/cli": ^0.19.0-next.1 + "@backstage/cli": ^0.19.0-next.3 "@types/node": ^16.0.0 languageName: unknown linkType: soft -"@backstage/cli@^0.19.0-next.1, @backstage/cli@^0.19.0-next.2, @backstage/cli@workspace:*, @backstage/cli@workspace:packages/cli": +"@backstage/cli@^0.19.0-next.1, @backstage/cli@^0.19.0-next.2, @backstage/cli@^0.19.0-next.3, @backstage/cli@workspace:*, @backstage/cli@workspace:packages/cli": version: 0.0.0-use.local resolution: "@backstage/cli@workspace:packages/cli" dependencies: - "@backstage/backend-common": ^0.15.1-next.2 - "@backstage/cli-common": ^0.1.9 - "@backstage/config": ^1.0.1 - "@backstage/config-loader": ^1.1.4-next.1 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/errors": ^1.1.0 - "@backstage/release-manifests": ^0.0.6-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/cli-common": ^0.1.10-next.0 + "@backstage/config": ^1.0.2-next.0 + "@backstage/config-loader": ^1.1.4-next.2 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/release-manifests": ^0.0.6-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@backstage/types": ^1.0.0 "@manypkg/get-packages": ^1.1.3 @@ -3204,8 +3219,8 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/codemods@workspace:packages/codemods" dependencies: - "@backstage/cli": ^0.19.0-next.1 - "@backstage/cli-common": ^0.1.9 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/cli-common": ^0.1.10-next.0 "@types/jscodeshift": ^0.11.0 "@types/node": ^16.11.26 chalk: ^4.0.0 @@ -3218,14 +3233,14 @@ __metadata: languageName: unknown linkType: soft -"@backstage/config-loader@^1.1.4-next.1, @backstage/config-loader@workspace:packages/config-loader": +"@backstage/config-loader@^1.1.4-next.2, @backstage/config-loader@workspace:packages/config-loader": version: 0.0.0-use.local resolution: "@backstage/config-loader@workspace:packages/config-loader" dependencies: - "@backstage/cli": ^0.19.0-next.2 - "@backstage/cli-common": ^0.1.9 - "@backstage/config": ^1.0.1 - "@backstage/errors": ^1.1.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/cli-common": ^0.1.10-next.0 + "@backstage/config": ^1.0.2-next.0 + "@backstage/errors": ^1.1.1-next.0 "@backstage/types": ^1.0.0 "@types/json-schema": ^7.0.6 "@types/json-schema-merge-allof": ^0.6.0 @@ -3247,26 +3262,36 @@ __metadata: languageName: unknown linkType: soft -"@backstage/config@^1.0.0, @backstage/config@^1.0.1, @backstage/config@workspace:packages/config": +"@backstage/config@^1.0.2-next.0, @backstage/config@workspace:packages/config": version: 0.0.0-use.local resolution: "@backstage/config@workspace:packages/config" dependencies: - "@backstage/cli": ^0.19.0-next.1 - "@backstage/test-utils": ^1.2.0-next.1 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/types": ^1.0.0 "@types/node": ^16.0.0 lodash: ^4.17.21 languageName: unknown linkType: soft -"@backstage/core-app-api@^1.1.0-next.1, @backstage/core-app-api@^1.1.0-next.2, @backstage/core-app-api@workspace:packages/core-app-api": +"@backstage/config@npm:^1.0.1": + version: 1.0.1 + resolution: "@backstage/config@npm:1.0.1" + dependencies: + "@backstage/types": ^1.0.0 + lodash: ^4.17.21 + checksum: 08ec95a9ddbfc8410c949314c464c63c0723a0681e21607463495454d7b06a9e7884110874efe7a9f7a8c9c864eb20a528a7a407dba7da84516d47d929e7ebc3 + languageName: node + linkType: hard + +"@backstage/core-app-api@^1.1.0-next.1, @backstage/core-app-api@^1.1.0-next.2, @backstage/core-app-api@^1.1.0-next.3, @backstage/core-app-api@workspace:packages/core-app-api": version: 0.0.0-use.local resolution: "@backstage/core-app-api@workspace:packages/core-app-api" dependencies: - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/types": ^1.0.0 "@backstage/version-bridge": ^1.0.1 "@testing-library/jest-dom": ^5.10.1 @@ -3293,16 +3318,16 @@ __metadata: languageName: unknown linkType: soft -"@backstage/core-components@^0.11.1-next.1, @backstage/core-components@^0.11.1-next.2, @backstage/core-components@workspace:packages/core-components": +"@backstage/core-components@^0.11.1-next.1, @backstage/core-components@^0.11.1-next.2, @backstage/core-components@^0.11.1-next.3, @backstage/core-components@workspace:packages/core-components": version: 0.0.0-use.local resolution: "@backstage/core-components@workspace:packages/core-components" dependencies: - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/errors": ^1.1.0 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@backstage/version-bridge": ^1.0.1 "@material-table/core": ^3.1.0 @@ -3416,14 +3441,14 @@ __metadata: languageName: node linkType: hard -"@backstage/core-plugin-api@^1.0.6-next.1, @backstage/core-plugin-api@^1.0.6-next.2, @backstage/core-plugin-api@workspace:packages/core-plugin-api": +"@backstage/core-plugin-api@^1.0.6-next.1, @backstage/core-plugin-api@^1.0.6-next.2, @backstage/core-plugin-api@^1.0.6-next.3, @backstage/core-plugin-api@workspace:packages/core-plugin-api": version: 0.0.0-use.local resolution: "@backstage/core-plugin-api@workspace:packages/core-plugin-api" dependencies: - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/types": ^1.0.0 "@backstage/version-bridge": ^1.0.1 "@testing-library/jest-dom": ^5.10.1 @@ -3467,8 +3492,8 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/create-app@workspace:packages/create-app" dependencies: - "@backstage/cli": ^0.19.0-next.2 - "@backstage/cli-common": ^0.1.9 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/cli-common": ^0.1.10-next.0 "@types/fs-extra": ^9.0.1 "@types/inquirer": ^8.1.3 "@types/node": ^16.11.26 @@ -3487,19 +3512,19 @@ __metadata: languageName: unknown linkType: soft -"@backstage/dev-utils@^1.0.6-next.1, @backstage/dev-utils@workspace:packages/dev-utils": +"@backstage/dev-utils@^1.0.6-next.1, @backstage/dev-utils@^1.0.6-next.2, @backstage/dev-utils@workspace:packages/dev-utils": version: 0.0.0-use.local resolution: "@backstage/dev-utils@workspace:packages/dev-utils" dependencies: - "@backstage/app-defaults": ^1.0.6-next.1 - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.1 - "@backstage/core-app-api": ^1.1.0-next.1 - "@backstage/core-components": ^0.11.1-next.1 - "@backstage/core-plugin-api": ^1.0.6-next.1 - "@backstage/integration-react": ^1.1.4-next.0 - "@backstage/plugin-catalog-react": ^1.1.4-next.1 - "@backstage/test-utils": ^1.2.0-next.1 + "@backstage/app-defaults": ^1.0.6-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/integration-react": ^1.1.4-next.2 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -3518,28 +3543,39 @@ __metadata: languageName: unknown linkType: soft -"@backstage/errors@1.1.0, @backstage/errors@^1.0.0, @backstage/errors@^1.1.0, @backstage/errors@^1.1.0-next.0, @backstage/errors@workspace:packages/errors": +"@backstage/errors@1.1.1-next.0, @backstage/errors@^1.1.1-next.0, @backstage/errors@workspace:packages/errors": version: 0.0.0-use.local resolution: "@backstage/errors@workspace:packages/errors" dependencies: - "@backstage/cli": ^0.19.0-next.1 + "@backstage/cli": ^0.19.0-next.3 "@backstage/types": ^1.0.0 cross-fetch: ^3.1.5 serialize-error: ^8.0.1 languageName: unknown linkType: soft -"@backstage/integration-react@^1.1.4-next.0, @backstage/integration-react@^1.1.4-next.1, @backstage/integration-react@workspace:packages/integration-react": +"@backstage/errors@npm:^1.1.0": + version: 1.1.0 + resolution: "@backstage/errors@npm:1.1.0" + dependencies: + "@backstage/types": ^1.0.0 + cross-fetch: ^3.1.5 + serialize-error: ^8.0.1 + checksum: b21d35803ce1adf7c7d7219e02636340780dc7f007bdaa966f62120f3607548a5e7a557b364abf54da29081f30efe3df72c5bfefebde335c305034961c6ae620 + languageName: node + linkType: hard + +"@backstage/integration-react@^1.1.4-next.2, @backstage/integration-react@workspace:packages/integration-react": version: 0.0.0-use.local resolution: "@backstage/integration-react@workspace:packages/integration-react" dependencies: - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/integration": ^1.3.1-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/integration": ^1.3.1-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -3575,15 +3611,15 @@ __metadata: languageName: node linkType: hard -"@backstage/integration@^1.3.1-next.0, @backstage/integration@^1.3.1-next.1, @backstage/integration@workspace:packages/integration": +"@backstage/integration@^1.3.1-next.1, @backstage/integration@^1.3.1-next.2, @backstage/integration@workspace:packages/integration": version: 0.0.0-use.local resolution: "@backstage/integration@workspace:packages/integration" dependencies: - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/config-loader": ^1.1.4-next.1 - "@backstage/errors": ^1.1.0 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/config-loader": ^1.1.4-next.2 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/test-utils": ^1.2.0-next.3 "@octokit/auth-app": ^4.0.0 "@octokit/rest": ^19.0.3 "@types/luxon": ^3.0.0 @@ -3615,14 +3651,14 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-adr-backend@workspace:plugins/adr-backend" dependencies: - "@backstage/backend-common": ^0.15.1-next.2 - "@backstage/catalog-client": ^1.0.5-next.1 - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/errors": ^1.1.0 - "@backstage/integration": ^1.3.1-next.1 - "@backstage/plugin-adr-common": ^0.2.1-next.0 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/catalog-client": ^1.1.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/integration": ^1.3.1-next.2 + "@backstage/plugin-adr-common": ^0.2.1-next.1 "@backstage/plugin-search-common": ^1.0.1-next.0 "@types/marked": ^4.0.0 "@types/supertest": ^2.0.8 @@ -3636,13 +3672,13 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-adr-common@^0.2.1-next.0, @backstage/plugin-adr-common@workspace:plugins/adr-common": +"@backstage/plugin-adr-common@^0.2.1-next.1, @backstage/plugin-adr-common@workspace:plugins/adr-common": version: 0.0.0-use.local resolution: "@backstage/plugin-adr-common@workspace:plugins/adr-common" dependencies: - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.1 - "@backstage/integration": ^1.3.1-next.0 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/integration": ^1.3.1-next.2 "@backstage/plugin-search-common": ^1.0.1-next.0 languageName: unknown linkType: soft @@ -3651,18 +3687,18 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-adr@workspace:plugins/adr" dependencies: - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/integration-react": ^1.1.4-next.1 - "@backstage/plugin-adr-common": ^0.2.1-next.0 - "@backstage/plugin-catalog-react": ^1.1.4-next.1 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/integration-react": ^1.1.4-next.2 + "@backstage/plugin-adr-common": ^0.2.1-next.1 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 "@backstage/plugin-search-common": ^1.0.1-next.0 "@backstage/plugin-search-react": ^1.1.0-next.2 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -3689,9 +3725,9 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-airbrake-backend@workspace:plugins/airbrake-backend" dependencies: - "@backstage/backend-common": ^0.15.1-next.2 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 "@types/express": "*" "@types/http-proxy-middleware": ^0.19.3 "@types/supertest": ^2.0.8 @@ -3705,18 +3741,18 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-airbrake@^0.3.9-next.2, @backstage/plugin-airbrake@workspace:plugins/airbrake": +"@backstage/plugin-airbrake@^0.3.9-next.3, @backstage/plugin-airbrake@workspace:plugins/airbrake": version: 0.0.0-use.local resolution: "@backstage/plugin-airbrake@workspace:plugins/airbrake" dependencies: - "@backstage/app-defaults": ^1.0.6-next.1 - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/plugin-catalog-react": ^1.1.4-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/app-defaults": ^1.0.6-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -3740,14 +3776,14 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-allure@workspace:plugins/allure" dependencies: - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/plugin-catalog-react": ^1.1.4-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -3769,13 +3805,13 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-analytics-module-ga@workspace:plugins/analytics-module-ga" dependencies: - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -3793,16 +3829,16 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-apache-airflow@^0.2.2-next.2, @backstage/plugin-apache-airflow@workspace:plugins/apache-airflow": +"@backstage/plugin-apache-airflow@^0.2.2-next.3, @backstage/plugin-apache-airflow@workspace:plugins/apache-airflow": version: 0.0.0-use.local resolution: "@backstage/plugin-apache-airflow@workspace:plugins/apache-airflow" dependencies: - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.57 @@ -3832,20 +3868,20 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-api-docs@^0.8.9-next.2, @backstage/plugin-api-docs@workspace:plugins/api-docs": +"@backstage/plugin-api-docs@^0.8.9-next.3, @backstage/plugin-api-docs@workspace:plugins/api-docs": version: 0.0.0-use.local resolution: "@backstage/plugin-api-docs@workspace:plugins/api-docs" dependencies: "@asyncapi/react-component": 1.0.0-next.40 - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/plugin-catalog": ^1.5.1-next.2 - "@backstage/plugin-catalog-react": ^1.1.4-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/plugin-catalog": ^1.5.1-next.3 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -3876,12 +3912,12 @@ __metadata: resolution: "@backstage/plugin-apollo-explorer@workspace:plugins/apollo-explorer" dependencies: "@apollo/explorer": ^1.1.1 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.9.13 "@material-ui/icons": ^4.9.1 @@ -3899,15 +3935,15 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-app-backend@^0.3.36-next.2, @backstage/plugin-app-backend@workspace:plugins/app-backend": +"@backstage/plugin-app-backend@^0.3.36-next.3, @backstage/plugin-app-backend@workspace:plugins/app-backend": version: 0.0.0-use.local resolution: "@backstage/plugin-app-backend@workspace:plugins/app-backend" dependencies: - "@backstage/backend-common": ^0.15.1-next.2 - "@backstage/backend-test-utils": ^0.1.28-next.2 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/config-loader": ^1.1.4-next.1 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/backend-test-utils": ^0.1.28-next.3 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/config-loader": ^1.1.4-next.2 "@backstage/types": ^1.0.0 "@types/express": ^4.17.6 "@types/supertest": ^2.0.8 @@ -3927,18 +3963,18 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-auth-backend@^0.16.0-next.2, @backstage/plugin-auth-backend@workspace:plugins/auth-backend": +"@backstage/plugin-auth-backend@^0.16.0-next.3, @backstage/plugin-auth-backend@workspace:plugins/auth-backend": version: 0.0.0-use.local resolution: "@backstage/plugin-auth-backend@workspace:plugins/auth-backend" dependencies: - "@backstage/backend-common": ^0.15.1-next.2 - "@backstage/backend-test-utils": ^0.1.28-next.2 - "@backstage/catalog-client": ^1.0.5-next.1 - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/errors": ^1.1.0 - "@backstage/plugin-auth-node": ^0.2.5-next.2 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/backend-test-utils": ^0.1.28-next.3 + "@backstage/catalog-client": ^1.1.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/plugin-auth-node": ^0.2.5-next.3 "@backstage/types": ^1.0.0 "@davidzemon/passport-okta-oauth": ^0.0.5 "@google-cloud/firestore": ^6.0.0 @@ -3991,15 +4027,15 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-auth-node@^0.2.5-next.1, @backstage/plugin-auth-node@^0.2.5-next.2, @backstage/plugin-auth-node@workspace:plugins/auth-node": +"@backstage/plugin-auth-node@^0.2.5-next.3, @backstage/plugin-auth-node@workspace:plugins/auth-node": version: 0.0.0-use.local resolution: "@backstage/plugin-auth-node@workspace:plugins/auth-node" dependencies: - "@backstage/backend-common": ^0.15.1-next.2 - "@backstage/backend-test-utils": ^0.1.28-next.2 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/errors": ^1.1.0 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/backend-test-utils": ^0.1.28-next.3 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/errors": ^1.1.1-next.0 "@types/express": "*" express: ^4.17.1 jose: ^4.6.0 @@ -4011,13 +4047,13 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-azure-devops-backend@^0.3.15-next.1, @backstage/plugin-azure-devops-backend@workspace:plugins/azure-devops-backend": +"@backstage/plugin-azure-devops-backend@^0.3.15-next.2, @backstage/plugin-azure-devops-backend@workspace:plugins/azure-devops-backend": version: 0.0.0-use.local resolution: "@backstage/plugin-azure-devops-backend@workspace:plugins/azure-devops-backend" dependencies: - "@backstage/backend-common": ^0.15.1-next.2 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 "@backstage/plugin-azure-devops-common": ^0.3.0-next.0 "@types/express": ^4.17.6 "@types/supertest": ^2.0.8 @@ -4041,20 +4077,20 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-azure-devops@^0.2.0-next.2, @backstage/plugin-azure-devops@workspace:plugins/azure-devops": +"@backstage/plugin-azure-devops@^0.2.0-next.3, @backstage/plugin-azure-devops@workspace:plugins/azure-devops": version: 0.0.0-use.local resolution: "@backstage/plugin-azure-devops@workspace:plugins/azure-devops" dependencies: - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/errors": ^1.1.0 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/errors": ^1.1.1-next.0 "@backstage/plugin-azure-devops-common": ^0.3.0-next.0 - "@backstage/plugin-catalog-react": ^1.1.4-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -4074,16 +4110,16 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-badges-backend@^0.1.30-next.0, @backstage/plugin-badges-backend@workspace:plugins/badges-backend": +"@backstage/plugin-badges-backend@^0.1.30-next.1, @backstage/plugin-badges-backend@workspace:plugins/badges-backend": version: 0.0.0-use.local resolution: "@backstage/plugin-badges-backend@workspace:plugins/badges-backend" dependencies: - "@backstage/backend-common": ^0.15.1-next.1 - "@backstage/catalog-client": ^1.0.5-next.0 - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.1 - "@backstage/config": ^1.0.1 - "@backstage/errors": ^1.1.0 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/catalog-client": ^1.1.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/errors": ^1.1.1-next.0 "@types/express": ^4.17.6 "@types/supertest": ^2.0.8 badge-maker: ^3.3.0 @@ -4096,19 +4132,19 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-badges@^0.2.33-next.2, @backstage/plugin-badges@workspace:plugins/badges": +"@backstage/plugin-badges@^0.2.33-next.3, @backstage/plugin-badges@workspace:plugins/badges": version: 0.0.0-use.local resolution: "@backstage/plugin-badges@workspace:plugins/badges" dependencies: - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/errors": ^1.1.0 - "@backstage/plugin-catalog-react": ^1.1.4-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -4130,10 +4166,10 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-bazaar-backend@workspace:plugins/bazaar-backend" dependencies: - "@backstage/backend-common": ^0.15.1-next.1 - "@backstage/backend-test-utils": ^0.1.28-next.1 - "@backstage/cli": ^0.19.0-next.1 - "@backstage/config": ^1.0.1 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/backend-test-utils": ^0.1.28-next.3 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 "@types/express": ^4.17.6 express: ^4.17.1 express-promise-router: ^4.1.0 @@ -4147,14 +4183,14 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-bazaar@workspace:plugins/bazaar" dependencies: - "@backstage/catalog-client": ^1.0.5-next.0 - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.1 - "@backstage/core-components": ^0.11.1-next.1 - "@backstage/core-plugin-api": ^1.0.6-next.1 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/plugin-catalog": ^1.5.1-next.1 - "@backstage/plugin-catalog-react": ^1.1.4-next.1 + "@backstage/catalog-client": ^1.1.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/plugin-catalog": ^1.5.1-next.3 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 "@date-io/luxon": 1.x "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -4188,14 +4224,14 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-bitrise@workspace:plugins/bitrise" dependencies: - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/plugin-catalog-react": ^1.1.4-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -4221,14 +4257,14 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-backend-module-aws@workspace:plugins/catalog-backend-module-aws" dependencies: - "@backstage/backend-common": ^0.15.1-next.1 - "@backstage/backend-tasks": ^0.3.5-next.0 - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.1 - "@backstage/config": ^1.0.1 - "@backstage/errors": ^1.1.0 - "@backstage/integration": ^1.3.1-next.0 - "@backstage/plugin-catalog-backend": ^1.4.0-next.1 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/backend-tasks": ^0.3.5-next.1 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/integration": ^1.3.1-next.2 + "@backstage/plugin-catalog-backend": ^1.4.0-next.3 "@backstage/types": ^1.0.0 "@types/lodash": ^4.14.151 aws-sdk: ^2.840.0 @@ -4245,15 +4281,15 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-backend-module-azure@workspace:plugins/catalog-backend-module-azure" dependencies: - "@backstage/backend-common": ^0.15.1-next.2 - "@backstage/backend-tasks": ^0.3.5-next.0 - "@backstage/backend-test-utils": ^0.1.28-next.2 - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/errors": ^1.1.0 - "@backstage/integration": ^1.3.1-next.1 - "@backstage/plugin-catalog-backend": ^1.4.0-next.2 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/backend-tasks": ^0.3.5-next.1 + "@backstage/backend-test-utils": ^0.1.28-next.3 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/integration": ^1.3.1-next.2 + "@backstage/plugin-catalog-backend": ^1.4.0-next.3 "@backstage/types": ^1.0.0 "@types/lodash": ^4.14.151 lodash: ^4.17.21 @@ -4268,14 +4304,14 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-backend-module-bitbucket-cloud@workspace:plugins/catalog-backend-module-bitbucket-cloud" dependencies: - "@backstage/backend-common": ^0.15.1-next.2 - "@backstage/backend-tasks": ^0.3.5-next.0 - "@backstage/backend-test-utils": ^0.1.28-next.2 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/integration": ^1.3.1-next.1 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/backend-tasks": ^0.3.5-next.1 + "@backstage/backend-test-utils": ^0.1.28-next.3 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/integration": ^1.3.1-next.2 "@backstage/plugin-bitbucket-cloud-common": ^0.1.3-next.1 - "@backstage/plugin-catalog-backend": ^1.4.0-next.2 + "@backstage/plugin-catalog-backend": ^1.4.0-next.3 msw: ^0.47.0 uuid: ^8.0.0 winston: ^3.2.1 @@ -4286,15 +4322,15 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-backend-module-bitbucket-server@workspace:plugins/catalog-backend-module-bitbucket-server" dependencies: - "@backstage/backend-common": ^0.15.1-next.2 - "@backstage/backend-tasks": ^0.3.5-next.0 - "@backstage/backend-test-utils": ^0.1.28-next.2 - "@backstage/catalog-model": ^1.0.1 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.0 - "@backstage/errors": ^1.0.0 - "@backstage/integration": ^1.3.1-next.1 - "@backstage/plugin-catalog-backend": ^1.4.0-next.2 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/backend-tasks": ^0.3.5-next.1 + "@backstage/backend-test-utils": ^0.1.28-next.3 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/integration": ^1.3.1-next.2 + "@backstage/plugin-catalog-backend": ^1.4.0-next.3 "@types/node-fetch": ^2.5.12 msw: ^0.47.0 node-fetch: ^2.6.7 @@ -4307,15 +4343,15 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-backend-module-bitbucket@workspace:plugins/catalog-backend-module-bitbucket" dependencies: - "@backstage/backend-common": ^0.15.1-next.2 - "@backstage/backend-test-utils": ^0.1.28-next.2 - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/errors": ^1.1.0 - "@backstage/integration": ^1.3.1-next.1 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/backend-test-utils": ^0.1.28-next.3 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/integration": ^1.3.1-next.2 "@backstage/plugin-bitbucket-cloud-common": ^0.1.3-next.1 - "@backstage/plugin-catalog-backend": ^1.4.0-next.2 + "@backstage/plugin-catalog-backend": ^1.4.0-next.3 "@backstage/types": ^1.0.0 "@types/lodash": ^4.14.151 lodash: ^4.17.21 @@ -4329,15 +4365,15 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-backend-module-gerrit@workspace:plugins/catalog-backend-module-gerrit" dependencies: - "@backstage/backend-common": ^0.15.1-next.2 - "@backstage/backend-tasks": ^0.3.5-next.0 - "@backstage/backend-test-utils": ^0.1.28-next.2 - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/errors": ^1.1.0 - "@backstage/integration": ^1.3.1-next.1 - "@backstage/plugin-catalog-backend": ^1.4.0-next.2 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/backend-tasks": ^0.3.5-next.1 + "@backstage/backend-test-utils": ^0.1.28-next.3 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/integration": ^1.3.1-next.2 + "@backstage/plugin-catalog-backend": ^1.4.0-next.3 "@types/fs-extra": ^9.0.1 fs-extra: 10.1.0 msw: ^0.47.0 @@ -4351,17 +4387,17 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-backend-module-github@workspace:plugins/catalog-backend-module-github" dependencies: - "@backstage/backend-common": ^0.15.1-next.2 - "@backstage/backend-plugin-api": ^0.1.2-next.1 - "@backstage/backend-tasks": ^0.3.5-next.0 - "@backstage/backend-test-utils": ^0.1.28-next.2 - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/errors": ^1.1.0 - "@backstage/integration": ^1.3.1-next.1 - "@backstage/plugin-catalog-backend": ^1.4.0-next.2 - "@backstage/plugin-catalog-node": ^1.0.2-next.1 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/backend-plugin-api": ^0.1.2-next.2 + "@backstage/backend-tasks": ^0.3.5-next.1 + "@backstage/backend-test-utils": ^0.1.28-next.3 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/integration": ^1.3.1-next.2 + "@backstage/plugin-catalog-backend": ^1.4.0-next.3 + "@backstage/plugin-catalog-node": ^1.1.0-next.2 "@backstage/types": ^1.0.0 "@octokit/graphql": ^5.0.0 "@types/lodash": ^4.14.151 @@ -4377,15 +4413,15 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-backend-module-gitlab@workspace:plugins/catalog-backend-module-gitlab" dependencies: - "@backstage/backend-common": ^0.15.1-next.2 - "@backstage/backend-tasks": ^0.3.5-next.0 - "@backstage/backend-test-utils": ^0.1.28-next.2 - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/errors": ^1.1.0 - "@backstage/integration": ^1.3.1-next.1 - "@backstage/plugin-catalog-backend": ^1.4.0-next.2 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/backend-tasks": ^0.3.5-next.1 + "@backstage/backend-test-utils": ^0.1.28-next.3 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/integration": ^1.3.1-next.2 + "@backstage/plugin-catalog-backend": ^1.4.0-next.3 "@backstage/types": ^1.0.0 "@types/lodash": ^4.14.151 "@types/uuid": ^8.0.0 @@ -4401,12 +4437,12 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-backend-module-ldap@workspace:plugins/catalog-backend-module-ldap" dependencies: - "@backstage/backend-tasks": ^0.3.5-next.0 - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.1 - "@backstage/config": ^1.0.1 - "@backstage/errors": ^1.1.0 - "@backstage/plugin-catalog-backend": ^1.4.0-next.1 + "@backstage/backend-tasks": ^0.3.5-next.1 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/plugin-catalog-backend": ^1.4.0-next.3 "@backstage/types": ^1.0.0 "@types/ldapjs": ^2.2.0 "@types/lodash": ^4.14.151 @@ -4422,13 +4458,13 @@ __metadata: resolution: "@backstage/plugin-catalog-backend-module-msgraph@workspace:plugins/catalog-backend-module-msgraph" dependencies: "@azure/identity": ^2.1.0 - "@backstage/backend-common": ^0.15.1-next.2 - "@backstage/backend-tasks": ^0.3.5-next.0 - "@backstage/backend-test-utils": ^0.1.28-next.2 - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/plugin-catalog-backend": ^1.4.0-next.2 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/backend-tasks": ^0.3.5-next.1 + "@backstage/backend-test-utils": ^0.1.28-next.3 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/plugin-catalog-backend": ^1.4.0-next.3 "@microsoft/microsoft-graph-types": ^2.6.0 "@types/lodash": ^4.14.151 "@types/node-fetch": ^2.5.12 @@ -4447,14 +4483,14 @@ __metadata: resolution: "@backstage/plugin-catalog-backend-module-openapi@workspace:plugins/catalog-backend-module-openapi" dependencies: "@apidevtools/swagger-parser": ^10.1.0 - "@backstage/backend-common": ^0.15.1-next.1 - "@backstage/backend-test-utils": ^0.1.28-next.1 - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.1 - "@backstage/config": ^1.0.1 - "@backstage/integration": ^1.3.1-next.0 - "@backstage/plugin-catalog-backend": ^1.4.0-next.1 - "@backstage/plugin-catalog-node": ^1.0.2-next.0 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/backend-test-utils": ^0.1.28-next.3 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/integration": ^1.3.1-next.2 + "@backstage/plugin-catalog-backend": ^1.4.0-next.3 + "@backstage/plugin-catalog-node": ^1.1.0-next.2 "@backstage/types": ^1.0.0 openapi-types: ^12.0.0 winston: ^3.2.1 @@ -4462,25 +4498,25 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-catalog-backend@^1.4.0-next.1, @backstage/plugin-catalog-backend@^1.4.0-next.2, @backstage/plugin-catalog-backend@workspace:plugins/catalog-backend": +"@backstage/plugin-catalog-backend@^1.4.0-next.1, @backstage/plugin-catalog-backend@^1.4.0-next.3, @backstage/plugin-catalog-backend@workspace:plugins/catalog-backend": version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-backend@workspace:plugins/catalog-backend" dependencies: - "@backstage/backend-common": ^0.15.1-next.2 - "@backstage/backend-plugin-api": ^0.1.2-next.1 - "@backstage/backend-test-utils": ^0.1.28-next.2 - "@backstage/catalog-client": ^1.0.5-next.1 - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/errors": ^1.1.0 - "@backstage/integration": ^1.3.1-next.1 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/backend-plugin-api": ^0.1.2-next.2 + "@backstage/backend-test-utils": ^0.1.28-next.3 + "@backstage/catalog-client": ^1.1.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/integration": ^1.3.1-next.2 "@backstage/plugin-catalog-common": ^1.0.6-next.0 - "@backstage/plugin-catalog-node": ^1.0.2-next.1 - "@backstage/plugin-permission-common": ^0.6.4-next.1 - "@backstage/plugin-permission-node": ^0.6.5-next.2 - "@backstage/plugin-scaffolder-common": ^1.2.0-next.0 - "@backstage/plugin-search-backend-node": 1.0.2-next.1 + "@backstage/plugin-catalog-node": ^1.1.0-next.2 + "@backstage/plugin-permission-common": ^0.6.4-next.2 + "@backstage/plugin-permission-node": ^0.6.5-next.3 + "@backstage/plugin-scaffolder-common": ^1.2.0-next.1 + "@backstage/plugin-search-backend-node": 1.0.2-next.2 "@backstage/plugin-search-common": ^1.0.1-next.0 "@backstage/types": ^1.0.0 "@types/core-js": ^2.5.4 @@ -4535,20 +4571,20 @@ __metadata: languageName: node linkType: hard -"@backstage/plugin-catalog-graph@^0.2.21-next.1, @backstage/plugin-catalog-graph@workspace:plugins/catalog-graph": +"@backstage/plugin-catalog-graph@^0.2.21-next.2, @backstage/plugin-catalog-graph@workspace:plugins/catalog-graph": version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-graph@workspace:plugins/catalog-graph" dependencies: - "@backstage/catalog-client": ^1.0.5-next.0 - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.1 - "@backstage/core-app-api": ^1.1.0-next.1 - "@backstage/core-components": ^0.11.1-next.1 - "@backstage/core-plugin-api": ^1.0.6-next.1 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/plugin-catalog": ^1.5.1-next.1 - "@backstage/plugin-catalog-react": ^1.1.4-next.1 - "@backstage/test-utils": ^1.2.0-next.1 + "@backstage/catalog-client": ^1.1.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/plugin-catalog": ^1.5.1-next.3 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@backstage/types": ^1.0.0 "@material-ui/core": ^4.12.2 @@ -4570,14 +4606,14 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-catalog-graphql@^0.3.13-next.2, @backstage/plugin-catalog-graphql@workspace:plugins/catalog-graphql": +"@backstage/plugin-catalog-graphql@^0.3.13-next.3, @backstage/plugin-catalog-graphql@workspace:plugins/catalog-graphql": version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-graphql@workspace:plugins/catalog-graphql" dependencies: - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/types": ^1.0.0 "@graphql-codegen/cli": ^2.3.1 "@graphql-codegen/graphql-modules-preset": ^2.3.2 @@ -4595,23 +4631,23 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-catalog-import@^0.8.12-next.2, @backstage/plugin-catalog-import@workspace:plugins/catalog-import": +"@backstage/plugin-catalog-import@^0.8.12-next.3, @backstage/plugin-catalog-import@workspace:plugins/catalog-import": version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-import@workspace:plugins/catalog-import" dependencies: - "@backstage/catalog-client": ^1.0.5-next.1 - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/errors": ^1.1.0 - "@backstage/integration": ^1.3.1-next.1 - "@backstage/integration-react": ^1.1.4-next.1 - "@backstage/plugin-catalog-react": ^1.1.4-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/catalog-client": ^1.1.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/integration": ^1.3.1-next.2 + "@backstage/integration-react": ^1.1.4-next.2 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.57 @@ -4635,38 +4671,38 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-catalog-node@^1.0.2-next.0, @backstage/plugin-catalog-node@^1.0.2-next.1, @backstage/plugin-catalog-node@workspace:plugins/catalog-node": +"@backstage/plugin-catalog-node@^1.1.0-next.2, @backstage/plugin-catalog-node@workspace:plugins/catalog-node": version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-node@workspace:plugins/catalog-node" dependencies: - "@backstage/backend-common": ^0.15.1-next.2 - "@backstage/backend-plugin-api": ^0.1.2-next.1 - "@backstage/backend-test-utils": ^0.1.28-next.2 - "@backstage/catalog-client": ^1.0.5-next.1 - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/errors": 1.1.0 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/backend-plugin-api": ^0.1.2-next.2 + "@backstage/backend-test-utils": ^0.1.28-next.3 + "@backstage/catalog-client": ^1.1.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/errors": 1.1.1-next.0 "@backstage/types": ^1.0.0 languageName: unknown linkType: soft -"@backstage/plugin-catalog-react@^1.1.4-next.0, @backstage/plugin-catalog-react@^1.1.4-next.1, @backstage/plugin-catalog-react@workspace:plugins/catalog-react": +"@backstage/plugin-catalog-react@^1.1.4-next.0, @backstage/plugin-catalog-react@^1.1.4-next.2, @backstage/plugin-catalog-react@workspace:plugins/catalog-react": version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-react@workspace:plugins/catalog-react" dependencies: - "@backstage/catalog-client": ^1.0.5-next.0 - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.1 - "@backstage/core-app-api": ^1.1.0-next.1 - "@backstage/core-components": ^0.11.1-next.1 - "@backstage/core-plugin-api": ^1.0.6-next.1 - "@backstage/errors": ^1.1.0 - "@backstage/integration": ^1.3.1-next.0 + "@backstage/catalog-client": ^1.1.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/integration": ^1.3.1-next.2 "@backstage/plugin-catalog-common": ^1.0.6-next.0 - "@backstage/plugin-permission-common": ^0.6.4-next.0 - "@backstage/plugin-permission-react": ^0.4.5-next.1 - "@backstage/plugin-scaffolder-common": ^1.2.0-next.0 - "@backstage/test-utils": ^1.2.0-next.1 + "@backstage/plugin-permission-common": ^0.6.4-next.2 + "@backstage/plugin-permission-react": ^0.4.5-next.2 + "@backstage/plugin-scaffolder-common": ^1.2.0-next.1 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@backstage/types": ^1.0.0 "@backstage/version-bridge": ^1.0.1 @@ -4729,25 +4765,25 @@ __metadata: languageName: node linkType: hard -"@backstage/plugin-catalog@^1.5.1-next.0, @backstage/plugin-catalog@^1.5.1-next.1, @backstage/plugin-catalog@^1.5.1-next.2, @backstage/plugin-catalog@workspace:plugins/catalog": +"@backstage/plugin-catalog@^1.5.1-next.0, @backstage/plugin-catalog@^1.5.1-next.3, @backstage/plugin-catalog@workspace:plugins/catalog": version: 0.0.0-use.local resolution: "@backstage/plugin-catalog@workspace:plugins/catalog" dependencies: - "@backstage/catalog-client": ^1.0.5-next.1 - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/errors": ^1.1.0 - "@backstage/integration-react": ^1.1.4-next.1 + "@backstage/catalog-client": ^1.1.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/integration-react": ^1.1.4-next.2 "@backstage/plugin-catalog-common": ^1.0.6-next.0 - "@backstage/plugin-catalog-react": ^1.1.4-next.1 - "@backstage/plugin-permission-react": ^0.4.5-next.1 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 + "@backstage/plugin-permission-react": ^0.4.5-next.2 "@backstage/plugin-search-common": ^1.0.1-next.0 "@backstage/plugin-search-react": ^1.1.0-next.2 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@backstage/types": ^1.0.0 "@material-ui/core": ^4.12.2 @@ -4773,10 +4809,10 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-cicd-statistics-module-gitlab@workspace:plugins/cicd-statistics-module-gitlab" dependencies: - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.1 - "@backstage/core-plugin-api": ^1.0.6-next.1 - "@backstage/plugin-cicd-statistics": ^0.1.11-next.1 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/plugin-cicd-statistics": ^0.1.11-next.2 "@gitbeaker/browser": ^35.6.0 "@gitbeaker/core": ^35.6.0 luxon: ^3.0.0 @@ -4784,14 +4820,14 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-cicd-statistics@^0.1.11-next.1, @backstage/plugin-cicd-statistics@workspace:plugins/cicd-statistics": +"@backstage/plugin-cicd-statistics@^0.1.11-next.2, @backstage/plugin-cicd-statistics@workspace:plugins/cicd-statistics": version: 0.0.0-use.local resolution: "@backstage/plugin-cicd-statistics@workspace:plugins/cicd-statistics" dependencies: - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.1 - "@backstage/core-plugin-api": ^1.0.6-next.1 - "@backstage/plugin-catalog-react": ^1.1.4-next.1 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 "@date-io/luxon": ^1.3.13 "@material-ui/core": ^4.9.13 "@material-ui/icons": ^4.11.2 @@ -4810,18 +4846,18 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-circleci@^0.3.9-next.2, @backstage/plugin-circleci@workspace:plugins/circleci": +"@backstage/plugin-circleci@^0.3.9-next.3, @backstage/plugin-circleci@workspace:plugins/circleci": version: 0.0.0-use.local resolution: "@backstage/plugin-circleci@workspace:plugins/circleci" dependencies: - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/plugin-catalog-react": ^1.1.4-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -4845,18 +4881,18 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-cloudbuild@^0.3.9-next.2, @backstage/plugin-cloudbuild@workspace:plugins/cloudbuild": +"@backstage/plugin-cloudbuild@^0.3.9-next.3, @backstage/plugin-cloudbuild@workspace:plugins/cloudbuild": version: 0.0.0-use.local resolution: "@backstage/plugin-cloudbuild@workspace:plugins/cloudbuild" dependencies: - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/plugin-catalog-react": ^1.1.4-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -4881,13 +4917,13 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-code-climate@workspace:plugins/code-climate" dependencies: - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/plugin-catalog-react": ^1.1.4-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -4909,17 +4945,17 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-code-coverage-backend@^0.2.2-next.1, @backstage/plugin-code-coverage-backend@workspace:plugins/code-coverage-backend": +"@backstage/plugin-code-coverage-backend@^0.2.2-next.2, @backstage/plugin-code-coverage-backend@workspace:plugins/code-coverage-backend": version: 0.0.0-use.local resolution: "@backstage/plugin-code-coverage-backend@workspace:plugins/code-coverage-backend" dependencies: - "@backstage/backend-common": ^0.15.1-next.2 - "@backstage/catalog-client": ^1.0.5-next.1 - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/errors": ^1.1.0 - "@backstage/integration": ^1.3.1-next.1 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/catalog-client": ^1.1.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/integration": ^1.3.1-next.2 "@types/express": ^4.17.6 "@types/express-xml-bodyparser": ^0.3.2 "@types/supertest": ^2.0.8 @@ -4936,20 +4972,20 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-code-coverage@^0.2.2-next.2, @backstage/plugin-code-coverage@workspace:plugins/code-coverage": +"@backstage/plugin-code-coverage@^0.2.2-next.3, @backstage/plugin-code-coverage@workspace:plugins/code-coverage": version: 0.0.0-use.local resolution: "@backstage/plugin-code-coverage@workspace:plugins/code-coverage" dependencies: - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/errors": ^1.1.0 - "@backstage/plugin-catalog-react": ^1.1.4-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -4978,14 +5014,14 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-codescene@workspace:plugins/codescene" dependencies: - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/errors": ^1.1.0 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.9.10 "@material-ui/icons": ^4.9.1 @@ -5008,14 +5044,14 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-config-schema@workspace:plugins/config-schema" dependencies: - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/errors": ^1.1.0 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@backstage/types": ^1.0.0 "@material-ui/core": ^4.12.2 @@ -5043,19 +5079,19 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-cost-insights@^0.11.31-next.2, @backstage/plugin-cost-insights@workspace:plugins/cost-insights": +"@backstage/plugin-cost-insights@^0.11.31-next.3, @backstage/plugin-cost-insights@workspace:plugins/cost-insights": version: 0.0.0-use.local resolution: "@backstage/plugin-cost-insights@workspace:plugins/cost-insights" dependencies: - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 "@backstage/plugin-cost-insights-common": ^0.1.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -5088,17 +5124,17 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-dynatrace@^0.2.0-next.2, @backstage/plugin-dynatrace@workspace:plugins/dynatrace": +"@backstage/plugin-dynatrace@^0.2.0-next.3, @backstage/plugin-dynatrace@workspace:plugins/dynatrace": version: 0.0.0-use.local resolution: "@backstage/plugin-dynatrace@workspace:plugins/dynatrace" dependencies: - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.9.13 "@material-ui/icons": ^4.9.1 @@ -5116,14 +5152,14 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-explore-react@^0.0.21-next.2, @backstage/plugin-explore-react@workspace:plugins/explore-react": +"@backstage/plugin-explore-react@^0.0.21-next.3, @backstage/plugin-explore-react@workspace:plugins/explore-react": version: 0.0.0-use.local resolution: "@backstage/plugin-explore-react@workspace:plugins/explore-react" dependencies: - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 @@ -5133,19 +5169,19 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-explore@^0.3.40-next.2, @backstage/plugin-explore@workspace:plugins/explore": +"@backstage/plugin-explore@^0.3.40-next.3, @backstage/plugin-explore@workspace:plugins/explore": version: 0.0.0-use.local resolution: "@backstage/plugin-explore@workspace:plugins/explore" dependencies: - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/plugin-catalog-react": ^1.1.4-next.1 - "@backstage/plugin-explore-react": ^0.0.21-next.2 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 + "@backstage/plugin-explore-react": ^0.0.21-next.3 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -5170,13 +5206,13 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-firehydrant@workspace:plugins/firehydrant" dependencies: - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/plugin-catalog-react": ^1.1.4-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -5198,15 +5234,15 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-fossa@workspace:plugins/fossa" dependencies: - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/errors": ^1.1.0 - "@backstage/plugin-catalog-react": ^1.1.4-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -5225,17 +5261,17 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-gcalendar@^0.3.5-next.2, @backstage/plugin-gcalendar@workspace:plugins/gcalendar": +"@backstage/plugin-gcalendar@^0.3.5-next.3, @backstage/plugin-gcalendar@workspace:plugins/gcalendar": version: 0.0.0-use.local resolution: "@backstage/plugin-gcalendar@workspace:plugins/gcalendar" dependencies: - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/errors": ^1.1.0 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -5261,16 +5297,16 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-gcp-projects@^0.3.28-next.2, @backstage/plugin-gcp-projects@workspace:plugins/gcp-projects": +"@backstage/plugin-gcp-projects@^0.3.28-next.3, @backstage/plugin-gcp-projects@workspace:plugins/gcp-projects": version: 0.0.0-use.local resolution: "@backstage/plugin-gcp-projects@workspace:plugins/gcp-projects" dependencies: - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -5292,13 +5328,13 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-git-release-manager@workspace:plugins/git-release-manager" dependencies: - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/integration": ^1.3.1-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/integration": ^1.3.1-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -5323,19 +5359,19 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-github-actions@^0.5.9-next.2, @backstage/plugin-github-actions@workspace:plugins/github-actions": +"@backstage/plugin-github-actions@^0.5.9-next.3, @backstage/plugin-github-actions@workspace:plugins/github-actions": version: 0.0.0-use.local resolution: "@backstage/plugin-github-actions@workspace:plugins/github-actions" dependencies: - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/integration": ^1.3.1-next.1 - "@backstage/plugin-catalog-react": ^1.1.4-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/integration": ^1.3.1-next.2 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -5360,17 +5396,17 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-github-deployments@workspace:plugins/github-deployments" dependencies: - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/errors": ^1.1.0 - "@backstage/integration": ^1.3.1-next.1 - "@backstage/integration-react": ^1.1.4-next.1 - "@backstage/plugin-catalog-react": ^1.1.4-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/integration": ^1.3.1-next.2 + "@backstage/integration-react": ^1.1.4-next.2 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -5393,16 +5429,16 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-github-issues@workspace:plugins/github-issues" dependencies: - "@backstage/catalog-model": ^1.0.3 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/errors": ^1.1.0 - "@backstage/integration": ^1.3.1-next.1 - "@backstage/plugin-catalog-react": ^1.1.4-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/integration": ^1.3.1-next.2 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.15 "@material-ui/core": ^4.12.4 "@material-ui/icons": ^4.9.1 @@ -5427,14 +5463,14 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-github-pull-requests-board@workspace:plugins/github-pull-requests-board" dependencies: - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/integration": ^1.3.1-next.1 - "@backstage/plugin-catalog-react": ^1.1.4-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/integration": ^1.3.1-next.2 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -5459,12 +5495,12 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-gitops-profiles@workspace:plugins/gitops-profiles" dependencies: - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -5482,19 +5518,19 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-gocd@^0.1.15-next.1, @backstage/plugin-gocd@workspace:plugins/gocd": +"@backstage/plugin-gocd@^0.1.15-next.2, @backstage/plugin-gocd@workspace:plugins/gocd": version: 0.0.0-use.local resolution: "@backstage/plugin-gocd@workspace:plugins/gocd" dependencies: - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/errors": ^1.1.0 - "@backstage/plugin-catalog-react": ^1.1.4-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -5516,16 +5552,16 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-graphiql@^0.2.41-next.2, @backstage/plugin-graphiql@workspace:plugins/graphiql": +"@backstage/plugin-graphiql@^0.2.41-next.3, @backstage/plugin-graphiql@workspace:plugins/graphiql": version: 0.0.0-use.local resolution: "@backstage/plugin-graphiql@workspace:plugins/graphiql" dependencies: - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -5547,14 +5583,14 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-graphql-backend@^0.1.26-next.2, @backstage/plugin-graphql-backend@workspace:plugins/graphql-backend": +"@backstage/plugin-graphql-backend@^0.1.26-next.3, @backstage/plugin-graphql-backend@workspace:plugins/graphql-backend": version: 0.0.0-use.local resolution: "@backstage/plugin-graphql-backend@workspace:plugins/graphql-backend" dependencies: - "@backstage/backend-common": ^0.15.1-next.2 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/plugin-catalog-graphql": ^0.3.13-next.2 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/plugin-catalog-graphql": ^0.3.13-next.3 "@graphql-tools/schema": ^9.0.0 "@types/express": ^4.17.6 "@types/supertest": ^2.0.8 @@ -5573,20 +5609,20 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-home@^0.4.25-next.2, @backstage/plugin-home@workspace:plugins/home": +"@backstage/plugin-home@^0.4.25-next.3, @backstage/plugin-home@workspace:plugins/home": version: 0.0.0-use.local resolution: "@backstage/plugin-home@workspace:plugins/home" dependencies: - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/plugin-catalog-react": ^1.1.4-next.1 - "@backstage/plugin-stack-overflow": ^0.1.5-next.2 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 + "@backstage/plugin-stack-overflow": ^0.1.5-next.3 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -5634,15 +5670,15 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-ilert@workspace:plugins/ilert" dependencies: - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/errors": ^1.1.0 - "@backstage/plugin-catalog-react": ^1.1.4-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@date-io/luxon": 1.x "@material-ui/core": ^4.12.2 @@ -5663,19 +5699,19 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-jenkins-backend@^0.1.26-next.2, @backstage/plugin-jenkins-backend@workspace:plugins/jenkins-backend": +"@backstage/plugin-jenkins-backend@^0.1.26-next.3, @backstage/plugin-jenkins-backend@workspace:plugins/jenkins-backend": version: 0.0.0-use.local resolution: "@backstage/plugin-jenkins-backend@workspace:plugins/jenkins-backend" dependencies: - "@backstage/backend-common": ^0.15.1-next.2 - "@backstage/catalog-client": ^1.0.5-next.1 - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/errors": ^1.1.0 - "@backstage/plugin-auth-node": ^0.2.5-next.2 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/catalog-client": ^1.1.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/plugin-auth-node": ^0.2.5-next.3 "@backstage/plugin-jenkins-common": ^0.1.8-next.0 - "@backstage/plugin-permission-common": ^0.6.4-next.1 + "@backstage/plugin-permission-common": ^0.6.4-next.2 "@types/express": ^4.17.6 "@types/jenkins": ^0.23.1 "@types/supertest": ^2.0.8 @@ -5700,20 +5736,20 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-jenkins@^0.7.8-next.2, @backstage/plugin-jenkins@workspace:plugins/jenkins": +"@backstage/plugin-jenkins@^0.7.8-next.3, @backstage/plugin-jenkins@workspace:plugins/jenkins": version: 0.0.0-use.local resolution: "@backstage/plugin-jenkins@workspace:plugins/jenkins" dependencies: - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/errors": ^1.1.0 - "@backstage/plugin-catalog-react": ^1.1.4-next.1 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 "@backstage/plugin-jenkins-common": ^0.1.8-next.0 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -5734,15 +5770,15 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-kafka-backend@^0.2.29-next.0, @backstage/plugin-kafka-backend@workspace:plugins/kafka-backend": +"@backstage/plugin-kafka-backend@^0.2.29-next.1, @backstage/plugin-kafka-backend@workspace:plugins/kafka-backend": version: 0.0.0-use.local resolution: "@backstage/plugin-kafka-backend@workspace:plugins/kafka-backend" dependencies: - "@backstage/backend-common": ^0.15.1-next.1 - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.1 - "@backstage/config": ^1.0.1 - "@backstage/errors": ^1.1.0 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/errors": ^1.1.1-next.0 "@types/express": ^4.17.6 "@types/jest-when": ^3.5.0 "@types/lodash": ^4.14.151 @@ -5756,19 +5792,19 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-kafka@^0.3.9-next.2, @backstage/plugin-kafka@workspace:plugins/kafka": +"@backstage/plugin-kafka@^0.3.9-next.3, @backstage/plugin-kafka@workspace:plugins/kafka": version: 0.0.0-use.local resolution: "@backstage/plugin-kafka@workspace:plugins/kafka" dependencies: - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/plugin-catalog-react": ^1.1.4-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -5788,19 +5824,19 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-kubernetes-backend@^0.7.2-next.2, @backstage/plugin-kubernetes-backend@workspace:plugins/kubernetes-backend": +"@backstage/plugin-kubernetes-backend@^0.7.2-next.3, @backstage/plugin-kubernetes-backend@workspace:plugins/kubernetes-backend": version: 0.0.0-use.local resolution: "@backstage/plugin-kubernetes-backend@workspace:plugins/kubernetes-backend" dependencies: "@azure/identity": ^2.0.4 - "@backstage/backend-common": ^0.15.1-next.2 - "@backstage/catalog-client": ^1.0.5-next.1 - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/errors": ^1.1.0 - "@backstage/plugin-auth-node": ^0.2.5-next.2 - "@backstage/plugin-kubernetes-common": ^0.4.2-next.0 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/catalog-client": ^1.1.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/plugin-auth-node": ^0.2.5-next.3 + "@backstage/plugin-kubernetes-common": ^0.4.2-next.1 "@google-cloud/container": ^4.0.0 "@kubernetes/client-node": ^0.17.0 "@types/aws4": ^1.5.1 @@ -5825,30 +5861,30 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-kubernetes-common@^0.4.2-next.0, @backstage/plugin-kubernetes-common@workspace:plugins/kubernetes-common": +"@backstage/plugin-kubernetes-common@^0.4.2-next.1, @backstage/plugin-kubernetes-common@workspace:plugins/kubernetes-common": version: 0.0.0-use.local resolution: "@backstage/plugin-kubernetes-common@workspace:plugins/kubernetes-common" dependencies: - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.1 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 "@kubernetes/client-node": ^0.17.0 languageName: unknown linkType: soft -"@backstage/plugin-kubernetes@^0.7.2-next.2, @backstage/plugin-kubernetes@workspace:plugins/kubernetes": +"@backstage/plugin-kubernetes@^0.7.2-next.3, @backstage/plugin-kubernetes@workspace:plugins/kubernetes": version: 0.0.0-use.local resolution: "@backstage/plugin-kubernetes@workspace:plugins/kubernetes" dependencies: - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/plugin-catalog-react": ^1.1.4-next.1 - "@backstage/plugin-kubernetes-common": ^0.4.2-next.0 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 + "@backstage/plugin-kubernetes-common": ^0.4.2-next.1 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@kubernetes/client-node": ^0.17.0 "@material-ui/core": ^4.12.2 @@ -5873,19 +5909,19 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-lighthouse@^0.3.9-next.2, @backstage/plugin-lighthouse@workspace:plugins/lighthouse": +"@backstage/plugin-lighthouse@^0.3.9-next.3, @backstage/plugin-lighthouse@workspace:plugins/lighthouse": version: 0.0.0-use.local resolution: "@backstage/plugin-lighthouse@workspace:plugins/lighthouse" dependencies: - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/plugin-catalog-react": ^1.1.4-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -5905,17 +5941,17 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-newrelic-dashboard@^0.2.2-next.1, @backstage/plugin-newrelic-dashboard@workspace:plugins/newrelic-dashboard": +"@backstage/plugin-newrelic-dashboard@^0.2.2-next.2, @backstage/plugin-newrelic-dashboard@workspace:plugins/newrelic-dashboard": version: 0.0.0-use.local resolution: "@backstage/plugin-newrelic-dashboard@workspace:plugins/newrelic-dashboard" dependencies: - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.1 - "@backstage/core-components": ^0.11.1-next.1 - "@backstage/core-plugin-api": ^1.0.6-next.1 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/errors": ^1.1.0 - "@backstage/plugin-catalog-react": ^1.1.4-next.1 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.57 @@ -5928,16 +5964,16 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-newrelic@^0.3.27-next.2, @backstage/plugin-newrelic@workspace:plugins/newrelic": +"@backstage/plugin-newrelic@^0.3.27-next.3, @backstage/plugin-newrelic@workspace:plugins/newrelic": version: 0.0.0-use.local resolution: "@backstage/plugin-newrelic@workspace:plugins/newrelic" dependencies: - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -5954,19 +5990,19 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-org@^0.5.9-next.2, @backstage/plugin-org@workspace:plugins/org": +"@backstage/plugin-org@^0.5.9-next.3, @backstage/plugin-org@workspace:plugins/org": version: 0.0.0-use.local resolution: "@backstage/plugin-org@workspace:plugins/org" dependencies: - "@backstage/catalog-client": ^1.0.5-next.1 - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/plugin-catalog-react": ^1.1.4-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/catalog-client": ^1.1.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -5988,19 +6024,19 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-pagerduty@0.5.2-next.2, @backstage/plugin-pagerduty@workspace:plugins/pagerduty": +"@backstage/plugin-pagerduty@0.5.2-next.3, @backstage/plugin-pagerduty@workspace:plugins/pagerduty": version: 0.0.0-use.local resolution: "@backstage/plugin-pagerduty@workspace:plugins/pagerduty" dependencies: - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/errors": ^1.1.0 - "@backstage/plugin-catalog-react": ^1.1.4-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -6025,9 +6061,9 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-periskop-backend@workspace:plugins/periskop-backend" dependencies: - "@backstage/backend-common": ^0.15.1-next.2 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 "@types/express": "*" "@types/supertest": ^2.0.8 express: ^4.17.1 @@ -6044,15 +6080,15 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-periskop@workspace:plugins/periskop" dependencies: - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/errors": ^1.1.0 - "@backstage/plugin-catalog-react": ^1.1.4-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -6072,17 +6108,17 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-permission-backend@^0.5.11-next.1, @backstage/plugin-permission-backend@workspace:plugins/permission-backend": +"@backstage/plugin-permission-backend@^0.5.11-next.2, @backstage/plugin-permission-backend@workspace:plugins/permission-backend": version: 0.0.0-use.local resolution: "@backstage/plugin-permission-backend@workspace:plugins/permission-backend" dependencies: - "@backstage/backend-common": ^0.15.1-next.2 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/errors": ^1.1.0 - "@backstage/plugin-auth-node": ^0.2.5-next.2 - "@backstage/plugin-permission-common": ^0.6.4-next.1 - "@backstage/plugin-permission-node": ^0.6.5-next.2 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/plugin-auth-node": ^0.2.5-next.3 + "@backstage/plugin-permission-common": ^0.6.4-next.2 + "@backstage/plugin-permission-node": ^0.6.5-next.3 "@types/express": "*" "@types/lodash": ^4.14.151 "@types/supertest": ^2.0.8 @@ -6099,13 +6135,13 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-permission-common@^0.6.4-next.0, @backstage/plugin-permission-common@^0.6.4-next.1, @backstage/plugin-permission-common@workspace:plugins/permission-common": +"@backstage/plugin-permission-common@^0.6.4-next.0, @backstage/plugin-permission-common@^0.6.4-next.2, @backstage/plugin-permission-common@workspace:plugins/permission-common": version: 0.0.0-use.local resolution: "@backstage/plugin-permission-common@workspace:plugins/permission-common" dependencies: - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/errors": ^1.1.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/errors": ^1.1.1-next.0 cross-fetch: ^3.1.5 msw: ^0.47.0 uuid: ^8.0.0 @@ -6126,17 +6162,17 @@ __metadata: languageName: node linkType: hard -"@backstage/plugin-permission-node@^0.6.5-next.1, @backstage/plugin-permission-node@^0.6.5-next.2, @backstage/plugin-permission-node@workspace:plugins/permission-node": +"@backstage/plugin-permission-node@^0.6.5-next.3, @backstage/plugin-permission-node@workspace:plugins/permission-node": version: 0.0.0-use.local resolution: "@backstage/plugin-permission-node@workspace:plugins/permission-node" dependencies: - "@backstage/backend-common": ^0.15.1-next.2 - "@backstage/backend-test-utils": ^0.1.28-next.2 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/errors": ^1.1.0 - "@backstage/plugin-auth-node": ^0.2.5-next.2 - "@backstage/plugin-permission-common": ^0.6.4-next.1 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/backend-test-utils": ^0.1.28-next.3 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/plugin-auth-node": ^0.2.5-next.3 + "@backstage/plugin-permission-common": ^0.6.4-next.2 "@types/express": ^4.17.6 "@types/supertest": ^2.0.8 express: ^4.17.1 @@ -6147,15 +6183,15 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-permission-react@^0.4.5-next.1, @backstage/plugin-permission-react@workspace:plugins/permission-react": +"@backstage/plugin-permission-react@^0.4.5-next.2, @backstage/plugin-permission-react@workspace:plugins/permission-react": version: 0.0.0-use.local resolution: "@backstage/plugin-permission-react@workspace:plugins/permission-react" dependencies: - "@backstage/cli": ^0.19.0-next.1 - "@backstage/config": ^1.0.1 - "@backstage/core-plugin-api": ^1.0.6-next.1 - "@backstage/plugin-permission-common": ^0.6.4-next.0 - "@backstage/test-utils": ^1.2.0-next.1 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/plugin-permission-common": ^0.6.4-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 cross-fetch: ^3.1.5 @@ -6186,13 +6222,13 @@ __metadata: languageName: node linkType: hard -"@backstage/plugin-proxy-backend@^0.2.30-next.1, @backstage/plugin-proxy-backend@workspace:plugins/proxy-backend": +"@backstage/plugin-proxy-backend@^0.2.30-next.2, @backstage/plugin-proxy-backend@workspace:plugins/proxy-backend": version: 0.0.0-use.local resolution: "@backstage/plugin-proxy-backend@workspace:plugins/proxy-backend" dependencies: - "@backstage/backend-common": ^0.15.1-next.2 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 "@types/express": ^4.17.6 "@types/http-proxy-middleware": ^0.19.3 "@types/supertest": ^2.0.8 @@ -6212,14 +6248,14 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-rollbar-backend@^0.1.33-next.2, @backstage/plugin-rollbar-backend@workspace:plugins/rollbar-backend": +"@backstage/plugin-rollbar-backend@^0.1.33-next.3, @backstage/plugin-rollbar-backend@workspace:plugins/rollbar-backend": version: 0.0.0-use.local resolution: "@backstage/plugin-rollbar-backend@workspace:plugins/rollbar-backend" dependencies: - "@backstage/backend-common": ^0.15.1-next.2 - "@backstage/backend-test-utils": ^0.1.28-next.2 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/backend-test-utils": ^0.1.28-next.3 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 "@types/express": ^4.17.6 "@types/supertest": ^2.0.8 camelcase-keys: ^7.0.1 @@ -6238,18 +6274,18 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-rollbar@^0.4.9-next.2, @backstage/plugin-rollbar@workspace:plugins/rollbar": +"@backstage/plugin-rollbar@^0.4.9-next.3, @backstage/plugin-rollbar@workspace:plugins/rollbar": version: 0.0.0-use.local resolution: "@backstage/plugin-rollbar@workspace:plugins/rollbar" dependencies: - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/plugin-catalog-react": ^1.1.4-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -6276,12 +6312,12 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-scaffolder-backend-module-cookiecutter@workspace:plugins/scaffolder-backend-module-cookiecutter" dependencies: - "@backstage/backend-common": ^0.15.1-next.2 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/errors": ^1.1.0 - "@backstage/integration": ^1.3.1-next.1 - "@backstage/plugin-scaffolder-backend": ^1.6.0-next.2 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/integration": ^1.3.1-next.2 + "@backstage/plugin-scaffolder-backend": ^1.6.0-next.3 "@backstage/types": ^1.0.0 "@types/command-exists": ^1.2.0 "@types/fs-extra": ^9.0.1 @@ -6295,16 +6331,16 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-scaffolder-backend-module-rails@^0.4.4-next.0, @backstage/plugin-scaffolder-backend-module-rails@workspace:plugins/scaffolder-backend-module-rails": +"@backstage/plugin-scaffolder-backend-module-rails@^0.4.4-next.1, @backstage/plugin-scaffolder-backend-module-rails@workspace:plugins/scaffolder-backend-module-rails": version: 0.0.0-use.local resolution: "@backstage/plugin-scaffolder-backend-module-rails@workspace:plugins/scaffolder-backend-module-rails" dependencies: - "@backstage/backend-common": ^0.15.1-next.1 - "@backstage/cli": ^0.19.0-next.1 - "@backstage/config": ^1.0.1 - "@backstage/errors": ^1.1.0 - "@backstage/integration": ^1.3.1-next.0 - "@backstage/plugin-scaffolder-backend": ^1.6.0-next.1 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/integration": ^1.3.1-next.2 + "@backstage/plugin-scaffolder-backend": ^1.6.0-next.3 "@backstage/types": ^1.0.0 "@types/command-exists": ^1.2.0 "@types/fs-extra": ^9.0.1 @@ -6321,33 +6357,33 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-scaffolder-backend-module-yeoman@workspace:plugins/scaffolder-backend-module-yeoman" dependencies: - "@backstage/backend-common": ^0.15.1-next.0 - "@backstage/cli": ^0.19.0-next.1 - "@backstage/config": ^1.0.1 - "@backstage/plugin-scaffolder-backend": ^1.6.0-next.0 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/plugin-scaffolder-backend": ^1.6.0-next.3 "@backstage/types": ^1.0.0 winston: ^3.2.1 yeoman-environment: ^3.9.1 languageName: unknown linkType: soft -"@backstage/plugin-scaffolder-backend@^1.6.0-next.0, @backstage/plugin-scaffolder-backend@^1.6.0-next.1, @backstage/plugin-scaffolder-backend@^1.6.0-next.2, @backstage/plugin-scaffolder-backend@workspace:plugins/scaffolder-backend": +"@backstage/plugin-scaffolder-backend@^1.6.0-next.1, @backstage/plugin-scaffolder-backend@^1.6.0-next.3, @backstage/plugin-scaffolder-backend@workspace:plugins/scaffolder-backend": version: 0.0.0-use.local resolution: "@backstage/plugin-scaffolder-backend@workspace:plugins/scaffolder-backend" dependencies: - "@backstage/backend-common": ^0.15.1-next.2 - "@backstage/backend-plugin-api": ^0.1.2-next.1 - "@backstage/backend-test-utils": ^0.1.28-next.2 - "@backstage/catalog-client": ^1.0.5-next.1 - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/errors": ^1.1.0 - "@backstage/integration": ^1.3.1-next.1 - "@backstage/plugin-auth-node": ^0.2.5-next.2 - "@backstage/plugin-catalog-backend": ^1.4.0-next.2 - "@backstage/plugin-catalog-node": ^1.0.2-next.1 - "@backstage/plugin-scaffolder-common": ^1.2.0-next.0 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/backend-plugin-api": ^0.1.2-next.2 + "@backstage/backend-test-utils": ^0.1.28-next.3 + "@backstage/catalog-client": ^1.1.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/integration": ^1.3.1-next.2 + "@backstage/plugin-auth-node": ^0.2.5-next.3 + "@backstage/plugin-catalog-backend": ^1.4.0-next.3 + "@backstage/plugin-catalog-node": ^1.1.0-next.2 + "@backstage/plugin-scaffolder-common": ^1.2.0-next.1 "@backstage/types": ^1.0.0 "@gitbeaker/core": ^35.6.0 "@gitbeaker/node": ^35.1.0 @@ -6395,37 +6431,37 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-scaffolder-common@^1.2.0-next.0, @backstage/plugin-scaffolder-common@workspace:plugins/scaffolder-common": +"@backstage/plugin-scaffolder-common@^1.2.0-next.1, @backstage/plugin-scaffolder-common@workspace:plugins/scaffolder-common": version: 0.0.0-use.local resolution: "@backstage/plugin-scaffolder-common@workspace:plugins/scaffolder-common" dependencies: - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.1 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 "@backstage/types": ^1.0.0 languageName: unknown linkType: soft -"@backstage/plugin-scaffolder@^1.6.0-next.2, @backstage/plugin-scaffolder@workspace:plugins/scaffolder": +"@backstage/plugin-scaffolder@^1.6.0-next.3, @backstage/plugin-scaffolder@workspace:plugins/scaffolder": version: 0.0.0-use.local resolution: "@backstage/plugin-scaffolder@workspace:plugins/scaffolder" dependencies: - "@backstage/catalog-client": ^1.0.5-next.1 - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/errors": ^1.1.0 - "@backstage/integration": ^1.3.1-next.1 - "@backstage/integration-react": ^1.1.4-next.1 - "@backstage/plugin-catalog": ^1.5.1-next.2 + "@backstage/catalog-client": ^1.1.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/integration": ^1.3.1-next.2 + "@backstage/integration-react": ^1.1.4-next.2 + "@backstage/plugin-catalog": ^1.5.1-next.3 "@backstage/plugin-catalog-common": ^1.0.6-next.0 - "@backstage/plugin-catalog-react": ^1.1.4-next.1 - "@backstage/plugin-permission-react": ^0.4.5-next.1 - "@backstage/plugin-scaffolder-common": ^1.2.0-next.0 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 + "@backstage/plugin-permission-react": ^0.4.5-next.2 + "@backstage/plugin-scaffolder-common": ^1.2.0-next.1 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@backstage/types": ^1.0.0 "@codemirror/language": ^6.0.0 @@ -6469,14 +6505,14 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-search-backend-module-elasticsearch@^1.0.2-next.1, @backstage/plugin-search-backend-module-elasticsearch@workspace:plugins/search-backend-module-elasticsearch": +"@backstage/plugin-search-backend-module-elasticsearch@^1.0.2-next.2, @backstage/plugin-search-backend-module-elasticsearch@workspace:plugins/search-backend-module-elasticsearch": version: 0.0.0-use.local resolution: "@backstage/plugin-search-backend-module-elasticsearch@workspace:plugins/search-backend-module-elasticsearch" dependencies: - "@backstage/backend-common": ^0.15.1-next.2 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/plugin-search-backend-node": ^1.0.2-next.1 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/plugin-search-backend-node": ^1.0.2-next.2 "@backstage/plugin-search-common": ^1.0.1-next.0 "@elastic/elasticsearch": ^7.13.0 "@elastic/elasticsearch-mock": ^1.0.0 @@ -6491,15 +6527,15 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-search-backend-module-pg@^0.4.0-next.1, @backstage/plugin-search-backend-module-pg@workspace:plugins/search-backend-module-pg": +"@backstage/plugin-search-backend-module-pg@^0.4.0-next.2, @backstage/plugin-search-backend-module-pg@workspace:plugins/search-backend-module-pg": version: 0.0.0-use.local resolution: "@backstage/plugin-search-backend-module-pg@workspace:plugins/search-backend-module-pg" dependencies: - "@backstage/backend-common": ^0.15.1-next.1 - "@backstage/backend-test-utils": ^0.1.28-next.1 - "@backstage/cli": ^0.19.0-next.1 - "@backstage/config": ^1.0.1 - "@backstage/plugin-search-backend-node": ^1.0.2-next.1 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/backend-test-utils": ^0.1.28-next.3 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/plugin-search-backend-node": ^1.0.2-next.2 "@backstage/plugin-search-common": ^1.0.1-next.0 knex: ^2.0.0 lodash: ^4.17.21 @@ -6507,16 +6543,16 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-search-backend-node@1.0.2-next.1, @backstage/plugin-search-backend-node@^1.0.2-next.1, @backstage/plugin-search-backend-node@workspace:plugins/search-backend-node": +"@backstage/plugin-search-backend-node@1.0.2-next.2, @backstage/plugin-search-backend-node@^1.0.2-next.2, @backstage/plugin-search-backend-node@workspace:plugins/search-backend-node": version: 0.0.0-use.local resolution: "@backstage/plugin-search-backend-node@workspace:plugins/search-backend-node" dependencies: - "@backstage/backend-common": ^0.15.1-next.1 - "@backstage/backend-tasks": ^0.3.5-next.0 - "@backstage/cli": ^0.19.0-next.1 - "@backstage/config": ^1.0.1 - "@backstage/errors": ^1.1.0 - "@backstage/plugin-permission-common": ^0.6.4-next.0 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/backend-tasks": ^0.3.5-next.1 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/plugin-permission-common": ^0.6.4-next.2 "@backstage/plugin-search-common": ^1.0.1-next.0 "@types/lunr": ^2.3.3 "@types/ndjson": ^2.0.1 @@ -6529,18 +6565,18 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-search-backend@^1.0.2-next.0, @backstage/plugin-search-backend@workspace:plugins/search-backend": +"@backstage/plugin-search-backend@^1.0.2-next.1, @backstage/plugin-search-backend@workspace:plugins/search-backend": version: 0.0.0-use.local resolution: "@backstage/plugin-search-backend@workspace:plugins/search-backend" dependencies: - "@backstage/backend-common": ^0.15.1-next.1 - "@backstage/cli": ^0.19.0-next.1 - "@backstage/config": ^1.0.1 - "@backstage/errors": ^1.1.0 - "@backstage/plugin-auth-node": ^0.2.5-next.1 - "@backstage/plugin-permission-common": ^0.6.4-next.0 - "@backstage/plugin-permission-node": ^0.6.5-next.1 - "@backstage/plugin-search-backend-node": ^1.0.2-next.1 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/plugin-auth-node": ^0.2.5-next.3 + "@backstage/plugin-permission-common": ^0.6.4-next.2 + "@backstage/plugin-permission-node": ^0.6.5-next.3 + "@backstage/plugin-search-backend-node": ^1.0.2-next.2 "@backstage/plugin-search-common": ^1.0.1-next.0 "@backstage/types": ^1.0.0 "@types/express": ^4.17.6 @@ -6605,22 +6641,22 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-search@^1.0.2-next.2, @backstage/plugin-search@workspace:plugins/search": +"@backstage/plugin-search@^1.0.2-next.3, @backstage/plugin-search@workspace:plugins/search": version: 0.0.0-use.local resolution: "@backstage/plugin-search@workspace:plugins/search" dependencies: - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/errors": ^1.1.0 - "@backstage/plugin-catalog-react": ^1.1.4-next.1 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 "@backstage/plugin-search-common": ^1.0.1-next.0 "@backstage/plugin-search-react": ^1.1.0-next.2 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@backstage/types": ^1.0.0 "@backstage/version-bridge": ^1.0.1 @@ -6644,18 +6680,18 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-sentry@^0.4.2-next.2, @backstage/plugin-sentry@workspace:plugins/sentry": +"@backstage/plugin-sentry@^0.4.2-next.3, @backstage/plugin-sentry@workspace:plugins/sentry": version: 0.0.0-use.local resolution: "@backstage/plugin-sentry@workspace:plugins/sentry" dependencies: - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/plugin-catalog-react": ^1.1.4-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-table/core": ^3.1.0 "@material-ui/core": ^4.12.2 @@ -6678,16 +6714,16 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-shortcuts@^0.3.1-next.2, @backstage/plugin-shortcuts@workspace:plugins/shortcuts": +"@backstage/plugin-shortcuts@^0.3.1-next.3, @backstage/plugin-shortcuts@workspace:plugins/shortcuts": version: 0.0.0-use.local resolution: "@backstage/plugin-shortcuts@workspace:plugins/shortcuts" dependencies: - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@backstage/types": ^1.0.0 "@material-ui/core": ^4.12.2 @@ -6714,11 +6750,11 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-sonarqube-backend@workspace:plugins/sonarqube-backend" dependencies: - "@backstage/backend-common": ^0.15.1-next.2 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/errors": ^1.1.0 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/test-utils": ^1.2.0-next.3 "@types/express": "*" "@types/supertest": ^2.0.12 express: ^4.18.1 @@ -6735,14 +6771,14 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-sonarqube@workspace:plugins/sonarqube" dependencies: - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/plugin-catalog-react": ^1.1.4-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -6765,14 +6801,14 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-splunk-on-call@workspace:plugins/splunk-on-call" dependencies: - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/plugin-catalog-react": ^1.1.4-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -6797,8 +6833,8 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-stack-overflow-backend@workspace:plugins/stack-overflow-backend" dependencies: - "@backstage/cli": ^0.19.0-next.1 - "@backstage/config": ^1.0.1 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 "@backstage/plugin-search-common": ^1.0.1-next.0 node-fetch: ^2.6.7 qs: ^6.9.4 @@ -6806,19 +6842,19 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-stack-overflow@^0.1.5-next.2, @backstage/plugin-stack-overflow@workspace:plugins/stack-overflow": +"@backstage/plugin-stack-overflow@^0.1.5-next.3, @backstage/plugin-stack-overflow@workspace:plugins/stack-overflow": version: 0.0.0-use.local resolution: "@backstage/plugin-stack-overflow@workspace:plugins/stack-overflow" dependencies: - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/plugin-home": ^0.4.25-next.2 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/plugin-home": ^0.4.25-next.3 "@backstage/plugin-search-common": ^1.0.1-next.0 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -6861,16 +6897,16 @@ __metadata: languageName: node linkType: hard -"@backstage/plugin-tech-insights-backend-module-jsonfc@^0.1.20-next.0, @backstage/plugin-tech-insights-backend-module-jsonfc@workspace:plugins/tech-insights-backend-module-jsonfc": +"@backstage/plugin-tech-insights-backend-module-jsonfc@^0.1.20-next.1, @backstage/plugin-tech-insights-backend-module-jsonfc@workspace:plugins/tech-insights-backend-module-jsonfc": version: 0.0.0-use.local resolution: "@backstage/plugin-tech-insights-backend-module-jsonfc@workspace:plugins/tech-insights-backend-module-jsonfc" dependencies: - "@backstage/backend-common": ^0.15.1-next.1 - "@backstage/cli": ^0.19.0-next.1 - "@backstage/config": ^1.0.1 - "@backstage/errors": ^1.1.0 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/errors": ^1.1.1-next.0 "@backstage/plugin-tech-insights-common": ^0.2.6 - "@backstage/plugin-tech-insights-node": ^0.3.4-next.0 + "@backstage/plugin-tech-insights-node": ^0.3.4-next.1 ajv: ^8.10.0 json-rules-engine: ^6.1.2 lodash: ^4.17.21 @@ -6879,20 +6915,20 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-tech-insights-backend@^0.5.2-next.1, @backstage/plugin-tech-insights-backend@workspace:plugins/tech-insights-backend": +"@backstage/plugin-tech-insights-backend@^0.5.2-next.2, @backstage/plugin-tech-insights-backend@workspace:plugins/tech-insights-backend": version: 0.0.0-use.local resolution: "@backstage/plugin-tech-insights-backend@workspace:plugins/tech-insights-backend" dependencies: - "@backstage/backend-common": ^0.15.1-next.1 - "@backstage/backend-tasks": ^0.3.5-next.0 - "@backstage/backend-test-utils": ^0.1.28-next.1 - "@backstage/catalog-client": ^1.0.5-next.0 - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.1 - "@backstage/config": ^1.0.1 - "@backstage/errors": ^1.1.0 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/backend-tasks": ^0.3.5-next.1 + "@backstage/backend-test-utils": ^0.1.28-next.3 + "@backstage/catalog-client": ^1.1.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/errors": ^1.1.1-next.0 "@backstage/plugin-tech-insights-common": ^0.2.6 - "@backstage/plugin-tech-insights-node": ^0.3.4-next.0 + "@backstage/plugin-tech-insights-node": ^0.3.4-next.1 "@types/express": ^4.17.6 "@types/luxon": ^3.0.0 "@types/semver": ^7.3.8 @@ -6922,14 +6958,14 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-tech-insights-node@^0.3.4-next.0, @backstage/plugin-tech-insights-node@workspace:plugins/tech-insights-node": +"@backstage/plugin-tech-insights-node@^0.3.4-next.1, @backstage/plugin-tech-insights-node@workspace:plugins/tech-insights-node": version: 0.0.0-use.local resolution: "@backstage/plugin-tech-insights-node@workspace:plugins/tech-insights-node" dependencies: - "@backstage/backend-common": ^0.15.1-next.1 - "@backstage/backend-tasks": ^0.3.5-next.0 - "@backstage/cli": ^0.19.0-next.1 - "@backstage/config": ^1.0.1 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/backend-tasks": ^0.3.5-next.1 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 "@backstage/plugin-tech-insights-common": ^0.2.6 "@backstage/types": ^1.0.0 "@types/luxon": ^3.0.0 @@ -6938,20 +6974,20 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-tech-insights@^0.3.0-next.2, @backstage/plugin-tech-insights@workspace:plugins/tech-insights": +"@backstage/plugin-tech-insights@^0.3.0-next.3, @backstage/plugin-tech-insights@workspace:plugins/tech-insights": version: 0.0.0-use.local resolution: "@backstage/plugin-tech-insights@workspace:plugins/tech-insights" dependencies: - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/errors": ^1.1.0 - "@backstage/plugin-catalog-react": ^1.1.4-next.1 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 "@backstage/plugin-tech-insights-common": ^0.2.6 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@backstage/types": ^1.0.0 "@material-ui/core": ^4.12.2 @@ -6971,16 +7007,16 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-tech-radar@^0.5.16-next.2, @backstage/plugin-tech-radar@workspace:plugins/tech-radar": +"@backstage/plugin-tech-radar@^0.5.16-next.3, @backstage/plugin-tech-radar@workspace:plugins/tech-radar": version: 0.0.0-use.local resolution: "@backstage/plugin-tech-radar@workspace:plugins/tech-radar" dependencies: - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -7003,21 +7039,21 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-techdocs-addons-test-utils@^1.0.4-next.2, @backstage/plugin-techdocs-addons-test-utils@workspace:plugins/techdocs-addons-test-utils": +"@backstage/plugin-techdocs-addons-test-utils@^1.0.4-next.3, @backstage/plugin-techdocs-addons-test-utils@workspace:plugins/techdocs-addons-test-utils": version: 0.0.0-use.local resolution: "@backstage/plugin-techdocs-addons-test-utils@workspace:plugins/techdocs-addons-test-utils" dependencies: - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/integration-react": ^1.1.4-next.1 - "@backstage/plugin-catalog": ^1.5.1-next.2 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/integration-react": ^1.1.4-next.2 + "@backstage/plugin-catalog": ^1.5.1-next.3 "@backstage/plugin-search-react": ^1.1.0-next.2 - "@backstage/plugin-techdocs": ^1.3.2-next.2 - "@backstage/plugin-techdocs-react": ^1.0.4-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/plugin-techdocs": ^1.3.2-next.3 + "@backstage/plugin-techdocs-react": ^1.0.4-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.9.13 "@material-ui/icons": ^4.9.1 @@ -7038,23 +7074,23 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-techdocs-backend@^1.3.0-next.1, @backstage/plugin-techdocs-backend@workspace:plugins/techdocs-backend": +"@backstage/plugin-techdocs-backend@^1.3.0-next.2, @backstage/plugin-techdocs-backend@workspace:plugins/techdocs-backend": version: 0.0.0-use.local resolution: "@backstage/plugin-techdocs-backend@workspace:plugins/techdocs-backend" dependencies: - "@backstage/backend-common": ^0.15.1-next.2 - "@backstage/backend-test-utils": ^0.1.28-next.2 - "@backstage/catalog-client": ^1.0.5-next.1 - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/errors": ^1.1.0 - "@backstage/integration": ^1.3.1-next.1 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/backend-test-utils": ^0.1.28-next.3 + "@backstage/catalog-client": ^1.1.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/integration": ^1.3.1-next.2 "@backstage/plugin-catalog-common": ^1.0.6-next.0 - "@backstage/plugin-permission-common": ^0.6.4-next.1 - "@backstage/plugin-search-backend-node": 1.0.2-next.1 + "@backstage/plugin-permission-common": ^0.6.4-next.2 + "@backstage/plugin-search-backend-node": 1.0.2-next.2 "@backstage/plugin-search-common": ^1.0.1-next.0 - "@backstage/plugin-techdocs-node": ^1.4.0-next.1 + "@backstage/plugin-techdocs-node": ^1.4.0-next.2 "@types/dockerode": ^3.3.0 "@types/express": ^4.17.6 dockerode: ^3.3.1 @@ -7071,20 +7107,20 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-techdocs-module-addons-contrib@^1.0.4-next.1, @backstage/plugin-techdocs-module-addons-contrib@workspace:plugins/techdocs-module-addons-contrib": +"@backstage/plugin-techdocs-module-addons-contrib@^1.0.4-next.2, @backstage/plugin-techdocs-module-addons-contrib@workspace:plugins/techdocs-module-addons-contrib": version: 0.0.0-use.local resolution: "@backstage/plugin-techdocs-module-addons-contrib@workspace:plugins/techdocs-module-addons-contrib" dependencies: - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/integration": ^1.3.1-next.1 - "@backstage/integration-react": ^1.1.4-next.1 - "@backstage/plugin-techdocs-addons-test-utils": ^1.0.4-next.2 - "@backstage/plugin-techdocs-react": ^1.0.4-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/integration": ^1.3.1-next.2 + "@backstage/integration-react": ^1.1.4-next.2 + "@backstage/plugin-techdocs-addons-test-utils": ^1.0.4-next.3 + "@backstage/plugin-techdocs-react": ^1.0.4-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.9.13 "@material-ui/icons": ^4.9.1 @@ -7104,18 +7140,18 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-techdocs-node@^1.4.0-next.1, @backstage/plugin-techdocs-node@workspace:plugins/techdocs-node": +"@backstage/plugin-techdocs-node@^1.4.0-next.2, @backstage/plugin-techdocs-node@workspace:plugins/techdocs-node": version: 0.0.0-use.local resolution: "@backstage/plugin-techdocs-node@workspace:plugins/techdocs-node" dependencies: "@azure/identity": ^2.0.1 "@azure/storage-blob": ^12.5.0 - "@backstage/backend-common": ^0.15.1-next.2 - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/errors": ^1.1.0 - "@backstage/integration": ^1.3.1-next.1 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/integration": ^1.3.1-next.2 "@backstage/plugin-search-common": ^1.0.1-next.0 "@google-cloud/storage": ^6.0.0 "@trendyol-js/openstack-swift-sdk": ^0.0.5 @@ -7141,16 +7177,16 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-techdocs-react@^1.0.4-next.1, @backstage/plugin-techdocs-react@workspace:plugins/techdocs-react": +"@backstage/plugin-techdocs-react@^1.0.4-next.2, @backstage/plugin-techdocs-react@workspace:plugins/techdocs-react": version: 0.0.0-use.local resolution: "@backstage/plugin-techdocs-react@workspace:plugins/techdocs-react" dependencies: - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.1 - "@backstage/config": ^1.0.1 - "@backstage/core-components": ^0.11.1-next.1 - "@backstage/core-plugin-api": ^1.0.6-next.1 - "@backstage/test-utils": ^1.2.0-next.1 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@backstage/version-bridge": ^1.0.1 "@material-ui/core": ^4.12.2 @@ -7170,25 +7206,25 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-techdocs@^1.3.2-next.1, @backstage/plugin-techdocs@^1.3.2-next.2, @backstage/plugin-techdocs@workspace:plugins/techdocs": +"@backstage/plugin-techdocs@^1.3.2-next.3, @backstage/plugin-techdocs@workspace:plugins/techdocs": version: 0.0.0-use.local resolution: "@backstage/plugin-techdocs@workspace:plugins/techdocs" dependencies: - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/errors": ^1.1.0 - "@backstage/integration": ^1.3.1-next.1 - "@backstage/integration-react": ^1.1.4-next.1 - "@backstage/plugin-catalog-react": ^1.1.4-next.1 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/integration": ^1.3.1-next.2 + "@backstage/integration-react": ^1.1.4-next.2 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 "@backstage/plugin-search-common": ^1.0.1-next.0 "@backstage/plugin-search-react": ^1.1.0-next.2 - "@backstage/plugin-techdocs-react": ^1.0.4-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/plugin-techdocs-react": ^1.0.4-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -7220,17 +7256,17 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-todo-backend@^0.1.33-next.1, @backstage/plugin-todo-backend@workspace:plugins/todo-backend": +"@backstage/plugin-todo-backend@^0.1.33-next.2, @backstage/plugin-todo-backend@workspace:plugins/todo-backend": version: 0.0.0-use.local resolution: "@backstage/plugin-todo-backend@workspace:plugins/todo-backend" dependencies: - "@backstage/backend-common": ^0.15.1-next.2 - "@backstage/catalog-client": ^1.0.5-next.1 - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/errors": ^1.1.0 - "@backstage/integration": ^1.3.1-next.1 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/catalog-client": ^1.1.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/integration": ^1.3.1-next.2 "@types/express": ^4.17.6 "@types/supertest": ^2.0.8 express: ^4.17.1 @@ -7243,19 +7279,19 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-todo@^0.2.11-next.2, @backstage/plugin-todo@workspace:plugins/todo": +"@backstage/plugin-todo@^0.2.11-next.3, @backstage/plugin-todo@workspace:plugins/todo": version: 0.0.0-use.local resolution: "@backstage/plugin-todo@workspace:plugins/todo" dependencies: - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/errors": ^1.1.0 - "@backstage/plugin-catalog-react": ^1.1.4-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -7273,16 +7309,16 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-user-settings@^0.4.8-next.2, @backstage/plugin-user-settings@workspace:plugins/user-settings": +"@backstage/plugin-user-settings@^0.4.8-next.3, @backstage/plugin-user-settings@workspace:plugins/user-settings": version: 0.0.0-use.local resolution: "@backstage/plugin-user-settings@workspace:plugins/user-settings" dependencies: - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -7305,12 +7341,12 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-vault-backend@workspace:plugins/vault-backend" dependencies: - "@backstage/backend-common": ^0.15.1-next.2 - "@backstage/backend-tasks": ^0.3.5-next.0 - "@backstage/backend-test-utils": ^0.1.28-next.2 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/errors": ^1.1.0 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/backend-tasks": ^0.3.5-next.1 + "@backstage/backend-test-utils": ^0.1.28-next.3 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/errors": ^1.1.1-next.0 "@types/compression": ^1.7.2 "@types/express": "*" "@types/supertest": ^2.0.8 @@ -7332,15 +7368,15 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-vault@workspace:plugins/vault" dependencies: - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/errors": ^1.1.0 - "@backstage/plugin-catalog-react": ^1.1.4-next.1 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -7361,13 +7397,13 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-xcmetrics@workspace:plugins/xcmetrics" dependencies: - "@backstage/cli": ^0.19.0-next.2 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/dev-utils": ^1.0.6-next.1 - "@backstage/errors": ^1.1.0 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -7388,28 +7424,28 @@ __metadata: languageName: unknown linkType: soft -"@backstage/release-manifests@^0.0.6-next.1, @backstage/release-manifests@workspace:packages/release-manifests": +"@backstage/release-manifests@^0.0.6-next.2, @backstage/release-manifests@workspace:packages/release-manifests": version: 0.0.0-use.local resolution: "@backstage/release-manifests@workspace:packages/release-manifests" dependencies: - "@backstage/cli": ^0.19.0-next.2 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/test-utils": ^1.2.0-next.3 "@types/node": ^16.0.0 cross-fetch: ^3.1.5 msw: ^0.47.0 languageName: unknown linkType: soft -"@backstage/test-utils@^1.2.0-next.1, @backstage/test-utils@^1.2.0-next.2, @backstage/test-utils@workspace:packages/test-utils": +"@backstage/test-utils@^1.2.0-next.1, @backstage/test-utils@^1.2.0-next.2, @backstage/test-utils@^1.2.0-next.3, @backstage/test-utils@workspace:packages/test-utils": version: 0.0.0-use.local resolution: "@backstage/test-utils@workspace:packages/test-utils" dependencies: - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/plugin-permission-common": ^0.6.4-next.1 - "@backstage/plugin-permission-react": ^0.4.5-next.1 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/plugin-permission-common": ^0.6.4-next.2 + "@backstage/plugin-permission-react": ^0.4.5-next.2 "@backstage/theme": ^0.2.16 "@backstage/types": ^1.0.0 "@material-ui/core": ^4.12.2 @@ -9105,11 +9141,11 @@ __metadata: version: 0.0.0-use.local resolution: "@internal/plugin-todo-list-backend@workspace:plugins/example-todo-list-backend" dependencies: - "@backstage/backend-common": ^0.15.1-next.1 - "@backstage/cli": ^0.19.0-next.1 - "@backstage/config": ^1.0.1 - "@backstage/errors": ^1.1.0 - "@backstage/plugin-auth-node": ^0.2.5-next.1 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/plugin-auth-node": ^0.2.5-next.3 "@types/express": ^4.17.6 "@types/supertest": ^2.0.8 "@types/uuid": ^8.0.0 @@ -13274,12 +13310,12 @@ __metadata: version: 0.0.0-use.local resolution: "@techdocs/cli@workspace:packages/techdocs-cli" dependencies: - "@backstage/backend-common": ^0.15.1-next.2 - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/cli-common": ^0.1.9 - "@backstage/config": ^1.0.1 - "@backstage/plugin-techdocs-node": ^1.4.0-next.1 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/cli-common": ^0.1.10-next.0 + "@backstage/config": ^1.0.2-next.0 + "@backstage/plugin-techdocs-node": ^1.4.0-next.2 "@types/commander": ^2.12.2 "@types/dockerode": ^3.3.0 "@types/fs-extra": ^9.0.6 @@ -21170,9 +21206,9 @@ __metadata: version: 0.0.0-use.local resolution: "e2e-test@workspace:packages/e2e-test" dependencies: - "@backstage/cli": ^0.19.0-next.1 - "@backstage/cli-common": ^0.1.9-next.0 - "@backstage/errors": ^1.1.0-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/cli-common": ^0.1.10-next.0 + "@backstage/errors": ^1.1.1-next.0 "@types/fs-extra": ^9.0.1 "@types/node": ^16.11.26 "@types/puppeteer": ^5.4.4 @@ -22395,60 +22431,60 @@ __metadata: version: 0.0.0-use.local resolution: "example-app@workspace:packages/app" dependencies: - "@backstage/app-defaults": ^1.0.6-next.1 - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/core-app-api": ^1.1.0-next.2 - "@backstage/core-components": ^0.11.1-next.2 - "@backstage/core-plugin-api": ^1.0.6-next.2 - "@backstage/integration-react": ^1.1.4-next.1 - "@backstage/plugin-airbrake": ^0.3.9-next.2 - "@backstage/plugin-apache-airflow": ^0.2.2-next.2 - "@backstage/plugin-api-docs": ^0.8.9-next.2 - "@backstage/plugin-azure-devops": ^0.2.0-next.2 - "@backstage/plugin-badges": ^0.2.33-next.2 + "@backstage/app-defaults": ^1.0.6-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/integration-react": ^1.1.4-next.2 + "@backstage/plugin-airbrake": ^0.3.9-next.3 + "@backstage/plugin-apache-airflow": ^0.2.2-next.3 + "@backstage/plugin-api-docs": ^0.8.9-next.3 + "@backstage/plugin-azure-devops": ^0.2.0-next.3 + "@backstage/plugin-badges": ^0.2.33-next.3 "@backstage/plugin-catalog-common": ^1.0.6-next.0 - "@backstage/plugin-catalog-graph": ^0.2.21-next.1 - "@backstage/plugin-catalog-import": ^0.8.12-next.2 - "@backstage/plugin-catalog-react": ^1.1.4-next.1 - "@backstage/plugin-circleci": ^0.3.9-next.2 - "@backstage/plugin-cloudbuild": ^0.3.9-next.2 - "@backstage/plugin-code-coverage": ^0.2.2-next.2 - "@backstage/plugin-cost-insights": ^0.11.31-next.2 - "@backstage/plugin-dynatrace": ^0.2.0-next.2 - "@backstage/plugin-explore": ^0.3.40-next.2 - "@backstage/plugin-gcalendar": ^0.3.5-next.2 - "@backstage/plugin-gcp-projects": ^0.3.28-next.2 - "@backstage/plugin-github-actions": ^0.5.9-next.2 - "@backstage/plugin-gocd": ^0.1.15-next.1 - "@backstage/plugin-graphiql": ^0.2.41-next.2 - "@backstage/plugin-home": ^0.4.25-next.2 - "@backstage/plugin-jenkins": ^0.7.8-next.2 - "@backstage/plugin-kafka": ^0.3.9-next.2 - "@backstage/plugin-kubernetes": ^0.7.2-next.2 - "@backstage/plugin-lighthouse": ^0.3.9-next.2 - "@backstage/plugin-newrelic": ^0.3.27-next.2 - "@backstage/plugin-newrelic-dashboard": ^0.2.2-next.1 - "@backstage/plugin-org": ^0.5.9-next.2 - "@backstage/plugin-pagerduty": 0.5.2-next.2 - "@backstage/plugin-permission-react": ^0.4.5-next.1 - "@backstage/plugin-rollbar": ^0.4.9-next.2 - "@backstage/plugin-scaffolder": ^1.6.0-next.2 - "@backstage/plugin-search": ^1.0.2-next.2 + "@backstage/plugin-catalog-graph": ^0.2.21-next.2 + "@backstage/plugin-catalog-import": ^0.8.12-next.3 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 + "@backstage/plugin-circleci": ^0.3.9-next.3 + "@backstage/plugin-cloudbuild": ^0.3.9-next.3 + "@backstage/plugin-code-coverage": ^0.2.2-next.3 + "@backstage/plugin-cost-insights": ^0.11.31-next.3 + "@backstage/plugin-dynatrace": ^0.2.0-next.3 + "@backstage/plugin-explore": ^0.3.40-next.3 + "@backstage/plugin-gcalendar": ^0.3.5-next.3 + "@backstage/plugin-gcp-projects": ^0.3.28-next.3 + "@backstage/plugin-github-actions": ^0.5.9-next.3 + "@backstage/plugin-gocd": ^0.1.15-next.2 + "@backstage/plugin-graphiql": ^0.2.41-next.3 + "@backstage/plugin-home": ^0.4.25-next.3 + "@backstage/plugin-jenkins": ^0.7.8-next.3 + "@backstage/plugin-kafka": ^0.3.9-next.3 + "@backstage/plugin-kubernetes": ^0.7.2-next.3 + "@backstage/plugin-lighthouse": ^0.3.9-next.3 + "@backstage/plugin-newrelic": ^0.3.27-next.3 + "@backstage/plugin-newrelic-dashboard": ^0.2.2-next.2 + "@backstage/plugin-org": ^0.5.9-next.3 + "@backstage/plugin-pagerduty": 0.5.2-next.3 + "@backstage/plugin-permission-react": ^0.4.5-next.2 + "@backstage/plugin-rollbar": ^0.4.9-next.3 + "@backstage/plugin-scaffolder": ^1.6.0-next.3 + "@backstage/plugin-search": ^1.0.2-next.3 "@backstage/plugin-search-common": ^1.0.1-next.0 "@backstage/plugin-search-react": ^1.1.0-next.2 - "@backstage/plugin-sentry": ^0.4.2-next.2 - "@backstage/plugin-shortcuts": ^0.3.1-next.2 - "@backstage/plugin-stack-overflow": ^0.1.5-next.2 - "@backstage/plugin-tech-insights": ^0.3.0-next.2 - "@backstage/plugin-tech-radar": ^0.5.16-next.2 - "@backstage/plugin-techdocs": ^1.3.2-next.2 - "@backstage/plugin-techdocs-module-addons-contrib": ^1.0.4-next.1 - "@backstage/plugin-techdocs-react": ^1.0.4-next.1 - "@backstage/plugin-todo": ^0.2.11-next.2 - "@backstage/plugin-user-settings": ^0.4.8-next.2 - "@backstage/test-utils": ^1.2.0-next.2 + "@backstage/plugin-sentry": ^0.4.2-next.3 + "@backstage/plugin-shortcuts": ^0.3.1-next.3 + "@backstage/plugin-stack-overflow": ^0.1.5-next.3 + "@backstage/plugin-tech-insights": ^0.3.0-next.3 + "@backstage/plugin-tech-radar": ^0.5.16-next.3 + "@backstage/plugin-techdocs": ^1.3.2-next.3 + "@backstage/plugin-techdocs-module-addons-contrib": ^1.0.4-next.2 + "@backstage/plugin-techdocs-react": ^1.0.4-next.2 + "@backstage/plugin-todo": ^0.2.11-next.3 + "@backstage/plugin-user-settings": ^0.4.8-next.3 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@internal/plugin-catalog-customized": 0.0.2-next.0 "@material-ui/core": ^4.12.2 @@ -22499,41 +22535,41 @@ __metadata: version: 0.0.0-use.local resolution: "example-backend@workspace:packages/backend" dependencies: - "@backstage/backend-common": ^0.15.1-next.2 - "@backstage/backend-tasks": ^0.3.5-next.0 - "@backstage/catalog-client": ^1.0.5-next.1 - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.2 - "@backstage/config": ^1.0.1 - "@backstage/integration": ^1.3.1-next.1 - "@backstage/plugin-app-backend": ^0.3.36-next.2 - "@backstage/plugin-auth-backend": ^0.16.0-next.2 - "@backstage/plugin-auth-node": ^0.2.5-next.2 - "@backstage/plugin-azure-devops-backend": ^0.3.15-next.1 - "@backstage/plugin-badges-backend": ^0.1.30-next.0 - "@backstage/plugin-catalog-backend": ^1.4.0-next.2 - "@backstage/plugin-code-coverage-backend": ^0.2.2-next.1 - "@backstage/plugin-graphql-backend": ^0.1.26-next.2 - "@backstage/plugin-jenkins-backend": ^0.1.26-next.2 - "@backstage/plugin-kafka-backend": ^0.2.29-next.0 - "@backstage/plugin-kubernetes-backend": ^0.7.2-next.2 - "@backstage/plugin-permission-backend": ^0.5.11-next.1 - "@backstage/plugin-permission-common": ^0.6.4-next.1 - "@backstage/plugin-permission-node": ^0.6.5-next.2 - "@backstage/plugin-proxy-backend": ^0.2.30-next.1 - "@backstage/plugin-rollbar-backend": ^0.1.33-next.2 - "@backstage/plugin-scaffolder-backend": ^1.6.0-next.2 - "@backstage/plugin-scaffolder-backend-module-rails": ^0.4.4-next.0 - "@backstage/plugin-search-backend": ^1.0.2-next.0 - "@backstage/plugin-search-backend-module-elasticsearch": ^1.0.2-next.1 - "@backstage/plugin-search-backend-module-pg": ^0.4.0-next.1 - "@backstage/plugin-search-backend-node": ^1.0.2-next.1 + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/backend-tasks": ^0.3.5-next.1 + "@backstage/catalog-client": ^1.1.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/integration": ^1.3.1-next.2 + "@backstage/plugin-app-backend": ^0.3.36-next.3 + "@backstage/plugin-auth-backend": ^0.16.0-next.3 + "@backstage/plugin-auth-node": ^0.2.5-next.3 + "@backstage/plugin-azure-devops-backend": ^0.3.15-next.2 + "@backstage/plugin-badges-backend": ^0.1.30-next.1 + "@backstage/plugin-catalog-backend": ^1.4.0-next.3 + "@backstage/plugin-code-coverage-backend": ^0.2.2-next.2 + "@backstage/plugin-graphql-backend": ^0.1.26-next.3 + "@backstage/plugin-jenkins-backend": ^0.1.26-next.3 + "@backstage/plugin-kafka-backend": ^0.2.29-next.1 + "@backstage/plugin-kubernetes-backend": ^0.7.2-next.3 + "@backstage/plugin-permission-backend": ^0.5.11-next.2 + "@backstage/plugin-permission-common": ^0.6.4-next.2 + "@backstage/plugin-permission-node": ^0.6.5-next.3 + "@backstage/plugin-proxy-backend": ^0.2.30-next.2 + "@backstage/plugin-rollbar-backend": ^0.1.33-next.3 + "@backstage/plugin-scaffolder-backend": ^1.6.0-next.3 + "@backstage/plugin-scaffolder-backend-module-rails": ^0.4.4-next.1 + "@backstage/plugin-search-backend": ^1.0.2-next.1 + "@backstage/plugin-search-backend-module-elasticsearch": ^1.0.2-next.2 + "@backstage/plugin-search-backend-module-pg": ^0.4.0-next.2 + "@backstage/plugin-search-backend-node": ^1.0.2-next.2 "@backstage/plugin-search-common": ^1.0.1-next.0 - "@backstage/plugin-tech-insights-backend": ^0.5.2-next.1 - "@backstage/plugin-tech-insights-backend-module-jsonfc": ^0.1.20-next.0 - "@backstage/plugin-tech-insights-node": ^0.3.4-next.0 - "@backstage/plugin-techdocs-backend": ^1.3.0-next.1 - "@backstage/plugin-todo-backend": ^0.1.33-next.1 + "@backstage/plugin-tech-insights-backend": ^0.5.2-next.2 + "@backstage/plugin-tech-insights-backend-module-jsonfc": ^0.1.20-next.1 + "@backstage/plugin-tech-insights-node": ^0.3.4-next.1 + "@backstage/plugin-techdocs-backend": ^1.3.0-next.2 + "@backstage/plugin-todo-backend": ^0.1.33-next.2 "@gitbeaker/node": ^35.1.0 "@octokit/rest": ^19.0.3 "@types/dockerode": ^3.3.0 @@ -38179,18 +38215,18 @@ __metadata: version: 0.0.0-use.local resolution: "techdocs-cli-embedded-app@workspace:packages/techdocs-cli-embedded-app" dependencies: - "@backstage/app-defaults": ^1.0.6-next.1 - "@backstage/catalog-model": ^1.1.0 - "@backstage/cli": ^0.19.0-next.1 - "@backstage/config": ^1.0.1 - "@backstage/core-app-api": ^1.1.0-next.1 - "@backstage/core-components": ^0.11.1-next.1 - "@backstage/core-plugin-api": ^1.0.6-next.1 - "@backstage/integration-react": ^1.1.4-next.0 - "@backstage/plugin-catalog": ^1.5.1-next.1 - "@backstage/plugin-techdocs": ^1.3.2-next.1 - "@backstage/plugin-techdocs-react": ^1.0.4-next.1 - "@backstage/test-utils": ^1.2.0-next.1 + "@backstage/app-defaults": ^1.0.6-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/integration-react": ^1.1.4-next.2 + "@backstage/plugin-catalog": ^1.5.1-next.3 + "@backstage/plugin-techdocs": ^1.3.2-next.3 + "@backstage/plugin-techdocs-react": ^1.0.4-next.2 + "@backstage/test-utils": ^1.2.0-next.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.11.0 "@material-ui/icons": ^4.9.1 From 709f4683301be50e66024f81698f6404b8d08b87 Mon Sep 17 00:00:00 2001 From: Magnus Persson Date: Tue, 13 Sep 2022 10:21:50 +0200 Subject: [PATCH 032/185] backend-common: wrap branch command Signed-off-by: Magnus Persson --- .changeset/smooth-camels-melt.md | 5 +++++ packages/backend-common/api-report.md | 2 ++ packages/backend-common/src/scm/git.test.ts | 16 ++++++++++++++++ packages/backend-common/src/scm/git.ts | 7 +++++++ 4 files changed, 30 insertions(+) create mode 100644 .changeset/smooth-camels-melt.md diff --git a/.changeset/smooth-camels-melt.md b/.changeset/smooth-camels-melt.md new file mode 100644 index 0000000000..bd816827a4 --- /dev/null +++ b/.changeset/smooth-camels-melt.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-common': patch +--- + +The `branch` command has been added to the `Git` isomorphic-git wrapper. diff --git a/packages/backend-common/api-report.md b/packages/backend-common/api-report.md index 40bd885fe8..600e3edef8 100644 --- a/packages/backend-common/api-report.md +++ b/packages/backend-common/api-report.md @@ -342,6 +342,8 @@ export class Git { force?: boolean; }): Promise; // (undocumented) + branch(options: { dir: string; ref: string }): Promise; + // (undocumented) checkout(options: { dir: string; ref: string }): Promise; clone(options: { url: string; diff --git a/packages/backend-common/src/scm/git.test.ts b/packages/backend-common/src/scm/git.test.ts index e9c66a896e..fdd3c7dbc8 100644 --- a/packages/backend-common/src/scm/git.test.ts +++ b/packages/backend-common/src/scm/git.test.ts @@ -95,6 +95,22 @@ describe('Git', () => { }); }); + describe('branch', () => { + it('should call isomorphic-git with the correct arguments', async () => { + const git = Git.fromAuth({}); + const dir = 'mockdirectory'; + const ref = 'master'; + + await git.branch({ dir, ref }); + + expect(isomorphic.branch).toHaveBeenCalledWith({ + fs, + dir, + ref, + }); + }); + }); + describe('commit', () => { it('should call isomorphic-git with the correct arguments', async () => { const git = Git.fromAuth({}); diff --git a/packages/backend-common/src/scm/git.ts b/packages/backend-common/src/scm/git.ts index 8a72c7af89..0c9252cb64 100644 --- a/packages/backend-common/src/scm/git.ts +++ b/packages/backend-common/src/scm/git.ts @@ -94,6 +94,13 @@ export class Git { return git.checkout({ fs, dir, ref }); } + async branch(options: { dir: string; ref: string }): Promise { + const { dir, ref } = options; + this.config.logger?.info(`Creating branch {dir=${dir},ref=${ref}`); + + return git.branch({ fs, dir, ref }); + } + async commit(options: { dir: string; message: string; From ed6375119a604603455c204f23dc99802cc8f1f5 Mon Sep 17 00:00:00 2001 From: Marcus Crane Date: Tue, 13 Sep 2022 21:22:15 +1200 Subject: [PATCH 033/185] Add a note about the Python interpreter during Yarn migration Signed-off-by: Marcus Crane --- docs/tutorials/yarn-migration.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/docs/tutorials/yarn-migration.md b/docs/tutorials/yarn-migration.md index 3bba18f945..7f898c7b98 100644 --- a/docs/tutorials/yarn-migration.md +++ b/docs/tutorials/yarn-migration.md @@ -73,4 +73,23 @@ The `--production` flag to `yarn install` has been removed in Yarn 3, instead yo RUN yarn workspaces focus --all --production && rm -rf "$(yarn cache clean)" ``` +Additionally, `yarn config` has been reworked from being able to store any arbitrary key-value pairs to only supporting a handful of predefined pairs. Previously, we would set our preferred `python3` interpreter to work around [any issues related to node-gyp](https://github.com/backstage/backstage/issues/11583) so we need to provide an appropriate substitute. + +```diff +FROM node:16-bullseye-slim + ++# Set Python interpreter for `node-gyp` to use ++ENV PYTHON /usr/bin/python3 + +# Install sqlite3 dependencies. You can skip this if you don't use sqlite3 in the image, +# in which case you should also move better-sqlite3 to "devDependencies" in package.json. +RUN apt-get update && \ + apt-get install -y --no-install-recommends libsqlite3-dev python3 build-essential && \ +- rm -rf /var/lib/apt/lists/* && \ +- yarn config set python /usr/bin/python3 ++ rm -rf /var/lib/apt/lists/* +``` + +You'll want to make sure that the `PYTHON` environment variable is declared relatively early, before any instances of `Yarn` are invoked as `node-gyp` is indirectly triggered by some modules during installation. + If you have any internal CLI tools in your project that are exposed through `"bin"` entries in `package.json`, then you'll need to add these packages as dependencies in your project root `package.json`. This is to make sure Yarn picks up the executables and makes them available through `yarn `. From 3924292cf3eea19e765fffb5bd767dc9e9da0967 Mon Sep 17 00:00:00 2001 From: bnechyporenko Date: Tue, 13 Sep 2022 12:29:29 +0200 Subject: [PATCH 034/185] Incorporated the feedback Signed-off-by: bnechyporenko --- .changeset/hungry-llamas-tie.md | 1 - .../src/lib/resolvers/CatalogAuthResolverContext.ts | 2 +- .../src/scaffolder/tasks/NunjucksWorkflowRunner.test.ts | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.changeset/hungry-llamas-tie.md b/.changeset/hungry-llamas-tie.md index c4848b50ef..0f3be39c3f 100644 --- a/.changeset/hungry-llamas-tie.md +++ b/.changeset/hungry-llamas-tie.md @@ -1,5 +1,4 @@ --- -'@backstage/plugin-auth-backend': patch '@backstage/plugin-scaffolder-backend': patch --- diff --git a/plugins/auth-backend/src/lib/resolvers/CatalogAuthResolverContext.ts b/plugins/auth-backend/src/lib/resolvers/CatalogAuthResolverContext.ts index c62c0737d8..cbc2439563 100644 --- a/plugins/auth-backend/src/lib/resolvers/CatalogAuthResolverContext.ts +++ b/plugins/auth-backend/src/lib/resolvers/CatalogAuthResolverContext.ts @@ -27,7 +27,7 @@ import { ConflictError, InputError, NotFoundError } from '@backstage/errors'; import { Logger } from 'winston'; import { TokenIssuer, TokenParams } from '../../identity/types'; import { AuthResolverContext } from '../../providers'; -import { AuthResolverCatalogUserQuery } from '../../providers'; +import { AuthResolverCatalogUserQuery } from '../../providers/types'; import { CatalogIdentityClient } from '../catalog'; /** diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.test.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.test.ts index 5af26bfea3..8745b7afdf 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.test.ts @@ -66,7 +66,7 @@ describe('DefaultWorkflowRunner', () => { }); beforeEach(() => { - winston.format.simple(); // put logform the required cache before mocking fs + winston.format.simple(); // put logform in the require.cache before mocking fs mockFs({ '/tmp': mockFs.directory(), ...realFiles, From 3bced8687cfcedf048bafb49d519186b82d66eb4 Mon Sep 17 00:00:00 2001 From: Samba siva Tiyyagura <40207674+stiyyagura0901@users.noreply.github.com> Date: Wed, 14 Sep 2022 14:47:32 -0400 Subject: [PATCH 035/185] Update index.md Fix a small typo Signed-off-by: Samba siva Tiyyagura <40207674+stiyyagura0901@users.noreply.github.com> --- docs/auth/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/auth/index.md b/docs/auth/index.md index 8d303c776d..ab04d3ed87 100644 --- a/docs/auth/index.md +++ b/docs/auth/index.md @@ -65,7 +65,7 @@ the local `auth.environment` setting will be selected. > and access to a Backstage Identity Token, which can be passed to backend > plugins. -Using an authentication provide for sign-in is something you need to configure +Using an authentication provider for sign-in is something you need to configure both in the frontend app, as well as the `auth` backend plugin. For information on how to configure the backend app, see [Sign-in Identities and Resolvers](./identity-resolver.md). The rest of this section will focus on how to configure sign-in for the frontend app. From 633b090d88914e36ff701eec236e8b869b3c9f2d Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Tue, 13 Sep 2022 11:23:35 +0200 Subject: [PATCH 036/185] refactor(search-react): sort context import and states definitions Signed-off-by: Camila Belo --- .../src/context/SearchContext.tsx | 25 +++++++++++-------- plugins/search-react/src/context/index.tsx | 1 + 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/plugins/search-react/src/context/SearchContext.tsx b/plugins/search-react/src/context/SearchContext.tsx index b4b5f00919..7faa743c9d 100644 --- a/plugins/search-react/src/context/SearchContext.tsx +++ b/plugins/search-react/src/context/SearchContext.tsx @@ -14,13 +14,6 @@ * limitations under the License. */ -import { JsonObject } from '@backstage/types'; -import { useApi, AnalyticsContext } from '@backstage/core-plugin-api'; -import { SearchResultSet } from '@backstage/plugin-search-common'; -import { - createVersionedContext, - createVersionedValueMap, -} from '@backstage/version-bridge'; import React, { PropsWithChildren, useCallback, @@ -30,6 +23,15 @@ import React, { } from 'react'; import useAsync, { AsyncState } from 'react-use/lib/useAsync'; import usePrevious from 'react-use/lib/usePrevious'; + +import { + createVersionedContext, + createVersionedValueMap, +} from '@backstage/version-bridge'; +import { JsonObject } from '@backstage/types'; +import { AnalyticsContext, useApi } from '@backstage/core-plugin-api'; +import { SearchResultSet } from '@backstage/plugin-search-common'; + import { searchApiRef } from '../api'; /** @@ -104,12 +106,13 @@ const useSearchContextValue = ( initialValue: SearchContextState = searchInitialState, ) => { const searchApi = useApi(searchApiRef); + + const [term, setTerm] = useState(initialValue.term); + const [types, setTypes] = useState(initialValue.types); + const [filters, setFilters] = useState(initialValue.filters); const [pageCursor, setPageCursor] = useState( initialValue.pageCursor, ); - const [filters, setFilters] = useState(initialValue.filters); - const [term, setTerm] = useState(initialValue.term); - const [types, setTypes] = useState(initialValue.types); const prevTerm = usePrevious(term); @@ -121,7 +124,7 @@ const useSearchContextValue = ( pageCursor, types, }), - [term, filters, types, pageCursor], + [term, types, filters, pageCursor], ); const hasNextPage = diff --git a/plugins/search-react/src/context/index.tsx b/plugins/search-react/src/context/index.tsx index 304f762943..720af8a949 100644 --- a/plugins/search-react/src/context/index.tsx +++ b/plugins/search-react/src/context/index.tsx @@ -19,6 +19,7 @@ export { useSearch, useSearchContextCheck, } from './SearchContext'; + export type { SearchContextProviderProps, SearchContextState, From acb8804a7704bd12e42355b184063369486af54f Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Tue, 13 Sep 2022 13:41:45 +0200 Subject: [PATCH 037/185] feat(search-react): add search result query prop Signed-off-by: Camila Belo --- .../SearchResult/SearchResult.stories.tsx | 67 ++++- .../components/SearchResult/SearchResult.tsx | 228 ++++++++++++++---- .../src/components/SearchResult/index.tsx | 16 +- 3 files changed, 258 insertions(+), 53 deletions(-) diff --git a/plugins/search-react/src/components/SearchResult/SearchResult.stories.tsx b/plugins/search-react/src/components/SearchResult/SearchResult.stories.tsx index 32f9a19a07..2fde91a1f8 100644 --- a/plugins/search-react/src/components/SearchResult/SearchResult.stories.tsx +++ b/plugins/search-react/src/components/SearchResult/SearchResult.stories.tsx @@ -15,15 +15,19 @@ */ import React, { ComponentType } from 'react'; -import { List, ListItem } from '@material-ui/core'; import { MemoryRouter } from 'react-router'; +import { List, ListItem } from '@material-ui/core'; + import { Link } from '@backstage/core-components'; import { TestApiProvider } from '@backstage/test-utils'; +import { SearchDocument } from '@backstage/plugin-search-common'; import { searchApiRef, MockSearchApi } from '../../api'; import { SearchContextProvider } from '../../context'; + import { DefaultResultListItem } from '../DefaultResultListItem'; + import { SearchResult } from './SearchResult'; const mockResults = { @@ -55,15 +59,15 @@ const mockResults = { ], }; +const searchApiMock = new MockSearchApi(mockResults); + export default { title: 'Plugins/Search/SearchResult', component: SearchResult, decorators: [ (Story: ComponentType<{}>) => ( - + @@ -73,6 +77,17 @@ export default { ], }; +const CustomResultListItem = (props: { result: SearchDocument }) => { + const { result } = props; + return ( + + + {result.title} - {result.text} + + + ); +}; + export const Default = () => { return ( @@ -82,18 +97,50 @@ export const Default = () => { switch (type) { case 'custom-result-item': return ( - ); default: return ( - - - {document.title} - {document.text} - - + + ); + } + })} + + )} + + ); +}; + +export const WithQuery = () => { + const query = { + term: 'documentation', + }; + + return ( + + {({ results }) => ( + + {results.map(({ type, document }) => { + switch (type) { + case 'custom-result-item': + return ( + + ); + default: + return ( + ); } })} diff --git a/plugins/search-react/src/components/SearchResult/SearchResult.tsx b/plugins/search-react/src/components/SearchResult/SearchResult.tsx index 46a2dde305..a3e4c0e1f0 100644 --- a/plugins/search-react/src/components/SearchResult/SearchResult.tsx +++ b/plugins/search-react/src/components/SearchResult/SearchResult.tsx @@ -15,69 +15,215 @@ */ import React from 'react'; +import useAsync, { AsyncState } from 'react-use/lib/useAsync'; import { EmptyState, Progress, ResponseErrorPanel, } from '@backstage/core-components'; -import { AnalyticsContext } from '@backstage/core-plugin-api'; -import { SearchResult } from '@backstage/plugin-search-common'; +import { AnalyticsContext, useApi } from '@backstage/core-plugin-api'; +import { SearchQuery, SearchResultSet } from '@backstage/plugin-search-common'; import { useSearch } from '../../context'; +import { searchApiRef } from '../../api'; /** - * Props for {@link SearchResultComponent} - * + * Props for {@link SearchResultContext} * @public */ -export type SearchResultProps = { - children: (results: { results: SearchResult[] }) => JSX.Element; +export type SearchResultContextProps = { + /** + * A child function that receives an asynchronous result set and returns a react element. + */ + children: (state: AsyncState) => JSX.Element; }; /** - * A component returning the search result. - * + * Provides context-based results to a child function. + * @param props - see {@link SearchResultContextProps}. + * @example + * ``` + * + * {({ loading, error, value }) => ( + * + * {value?.map(({ document }) => ( + * + * ))} + * + * )} + * + * ``` * @public */ -export const SearchResultComponent = ({ children }: SearchResultProps) => { - const { - result: { loading, error, value }, - } = useSearch(); - - if (loading) { - return ; - } - if (error) { - return ( - - ); - } - - if (!value?.results.length) { - return ; - } - - return <>{children({ results: value.results })}; +export const SearchResultContext = (props: SearchResultContextProps) => { + const { children } = props; + const context = useSearch(); + const state = context.result; + return children(state); }; /** + * Props for {@link SearchResultApi} * @public */ -const HigherOrderSearchResult = (props: SearchResultProps) => { - return ( - - - +export type SearchResultApiProps = SearchResultContextProps & { + query: Partial; +}; + +/** + * Request results through the search api and provide them to a child function. + * @param props - see {@link SearchResultApiProps}. + * @example + * ``` + * + * {({ loading, error, value }) => ( + * + * {value?.map(({ document }) => ( + * + * ))} + * + * )} + * + * ``` + * @public + */ +export const SearchResultApi = (props: SearchResultApiProps) => { + const { query, children } = props; + const searchApi = useApi(searchApiRef); + + const state = useAsync( + () => + searchApi.query({ + term: query.term ?? '', + types: query.types ?? [], + filters: query.filters ?? {}, + pageCursor: query.pageCursor, + }), + [query], + ); + + return children(state); +}; + +/** + * Props for {@link SearchResultState} + * @public + */ +export type SearchResultStateProps = SearchResultContextProps & + Partial; + +/** + * Call a child render function passing a search state as an argument. + * @remarks By default, results are taken from context, but when a "query" prop is set, results are requested from the search api. + * @param props - see {@link SearchResultStateProps}. + * @example + * Consuming results from context: + * ``` + * + * {({ loading, error, value }) => ( + * + * {value?.map(({ document }) => ( + * + * ))} + * + * )} + * + * ``` + * @example + * Requesting results using the search api: + * ``` + * + * {({ loading, error, value }) => ( + * + * {value?.map(({ document }) => ( + * + * ))} + * + * )} + * + * ``` + * @public + */ +export const SearchResultState = (props: SearchResultStateProps) => { + const { query, children } = props; + + return query ? ( + {children} + ) : ( + {children} ); }; -export { HigherOrderSearchResult as SearchResult }; +/** + * Props for {@link SearchResult} + * @public + */ +export type SearchResultProps = Pick & { + children: (resultSet: SearchResultSet) => JSX.Element; +}; + +/** + * Renders results from a parent search context or api. + * @remarks default components for loading, error and empty variants are returned. + * @param props - see {@link SearchResultProps}. + * @public + */ +export const SearchResultComponent = (props: SearchResultProps) => { + const { query, children } = props; + + return ( + + {({ loading, error, value }) => { + if (loading) { + return ; + } + + if (error) { + return ( + + ); + } + + if (!value?.results.length) { + return ( + + ); + } + + return children(value); + }} + + ); +}; + +/** + * A component returning the search result from a parent search context or api. + * @param props - see {@link SearchResultProps}. + * @public + */ +export const SearchResult = (props: SearchResultProps) => ( + + + +); diff --git a/plugins/search-react/src/components/SearchResult/index.tsx b/plugins/search-react/src/components/SearchResult/index.tsx index 503ac47bbd..eab599883b 100644 --- a/plugins/search-react/src/components/SearchResult/index.tsx +++ b/plugins/search-react/src/components/SearchResult/index.tsx @@ -14,5 +14,17 @@ * limitations under the License. */ -export { SearchResult, SearchResultComponent } from './SearchResult'; -export type { SearchResultProps } from './SearchResult'; +export { + SearchResult, + SearchResultApi, + SearchResultContext, + SearchResultState, + SearchResultComponent, +} from './SearchResult'; + +export type { + SearchResultProps, + SearchResultApiProps, + SearchResultContextProps, + SearchResultStateProps, +} from './SearchResult'; From 589e6a4fbab29e968243461d1d35ab11adf781b7 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Tue, 13 Sep 2022 11:25:18 +0200 Subject: [PATCH 038/185] feat(search-react): create search result list component Signed-off-by: Camila Belo --- .../SearchResult/SearchResult.stories.tsx | 31 +++ .../SearchResultList.stories.tsx | 182 ++++++++++++++++++ .../SearchResultList.test.tsx | 146 ++++++++++++++ .../SearchResultList/SearchResultList.tsx | 130 +++++++++++++ .../src/components/SearchResultList/index.tsx | 22 +++ plugins/search-react/src/components/index.ts | 1 + 6 files changed, 512 insertions(+) create mode 100644 plugins/search-react/src/components/SearchResultList/SearchResultList.stories.tsx create mode 100644 plugins/search-react/src/components/SearchResultList/SearchResultList.test.tsx create mode 100644 plugins/search-react/src/components/SearchResultList/SearchResultList.tsx create mode 100644 plugins/search-react/src/components/SearchResultList/index.tsx diff --git a/plugins/search-react/src/components/SearchResult/SearchResult.stories.tsx b/plugins/search-react/src/components/SearchResult/SearchResult.stories.tsx index 2fde91a1f8..8ac8aace0f 100644 --- a/plugins/search-react/src/components/SearchResult/SearchResult.stories.tsx +++ b/plugins/search-react/src/components/SearchResult/SearchResult.stories.tsx @@ -27,6 +27,7 @@ import { searchApiRef, MockSearchApi } from '../../api'; import { SearchContextProvider } from '../../context'; import { DefaultResultListItem } from '../DefaultResultListItem'; +import { SearchResultListLayout } from '../SearchResultList'; import { SearchResult } from './SearchResult'; @@ -149,3 +150,33 @@ export const WithQuery = () => { ); }; + +export const ListLayout = () => { + return ( + + {({ results }) => ( + { + switch (type) { + case 'custom-result-item': + return ( + + ); + default: + return ( + + ); + } + }} + /> + )} + + ); +}; diff --git a/plugins/search-react/src/components/SearchResultList/SearchResultList.stories.tsx b/plugins/search-react/src/components/SearchResultList/SearchResultList.stories.tsx new file mode 100644 index 0000000000..5762aba2d8 --- /dev/null +++ b/plugins/search-react/src/components/SearchResultList/SearchResultList.stories.tsx @@ -0,0 +1,182 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React, { ComponentType, useState } from 'react'; + +import { Grid, ListItem, ListItemIcon, ListItemText } from '@material-ui/core'; + +import { createRouteRef } from '@backstage/core-plugin-api'; +import { CatalogIcon, Link } from '@backstage/core-components'; +import { SearchQuery, SearchResultSet } from '@backstage/plugin-search-common'; +import { TestApiProvider, wrapInTestApp } from '@backstage/test-utils'; + +import { searchApiRef, MockSearchApi } from '../../api'; + +import { SearchResultList } from './SearchResultList'; +import { DefaultResultListItem } from '../DefaultResultListItem'; + +const routeRef = createRouteRef({ + id: 'storybook.search.results.list.route', +}); + +const searchApiMock = new MockSearchApi({ + results: [ + { + type: 'techdocs', + document: { + location: 'search/search-result1', + title: 'Search Result 1', + text: 'Some text from the search result 1', + }, + }, + { + type: 'custom', + document: { + location: 'search/search-result2', + title: 'Search Result 2', + text: 'Some text from the search result 2', + }, + }, + ], +}); + +export default { + title: 'Plugins/Search/SearchResultList', + component: SearchResultList, + decorators: [ + (Story: ComponentType<{}>) => + wrapInTestApp( + + + + + + + , + { mountedRoutes: { '/': routeRef } }, + ), + ], +}; + +export const Default = () => { + const [query] = useState>({ + types: ['techdocs'], + }); + + return ; +}; + +export const Loading = () => { + const [query] = useState>({ + types: ['techdocs'], + }); + + return ( + new Promise(() => {}) }], + ]} + > + + + ); +}; + +export const WithError = () => { + const [query] = useState>({ + types: ['techdocs'], + }); + + return ( + + new Promise(() => { + throw new Error(); + }), + }, + ], + ]} + > + + + ); +}; + +export const WithNoResults = () => { + const [query] = useState>({ + types: ['techdocs'], + }); + + return ( + + + + ); +}; + +const CustomResultListItem = (props: any) => { + const { icon, result } = props; + + return ( + + + {icon && {icon}} + + + + ); +}; + +export const WithCustomResultItem = () => { + const [query] = useState>({ + types: ['custom'], + }); + + return ( + { + switch (type) { + case 'custom': + return ( + } + result={document} + highlight={highlight} + rank={rank} + /> + ); + default: + return ( + + ); + } + }} + /> + ); +}; diff --git a/plugins/search-react/src/components/SearchResultList/SearchResultList.test.tsx b/plugins/search-react/src/components/SearchResultList/SearchResultList.test.tsx new file mode 100644 index 0000000000..20e5a1cba1 --- /dev/null +++ b/plugins/search-react/src/components/SearchResultList/SearchResultList.test.tsx @@ -0,0 +1,146 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import { screen, waitFor } from '@testing-library/react'; + +import { + TestApiProvider, + renderWithEffects, + wrapInTestApp, +} from '@backstage/test-utils'; + +import { searchApiRef } from '../../api'; +import { SearchResultList } from './SearchResultList'; + +const query = jest.fn().mockResolvedValue({ results: [] }); +const searchApiMock = { query }; + +describe('SearchResultList', () => { + const results = [ + { + type: 'techdocs', + document: { + location: 'search/search-result1', + title: 'Search Result 1', + text: 'Some text from the search result 1', + }, + }, + { + type: 'techdocs', + document: { + location: 'search/search-result2', + title: 'Search Result 2', + text: 'Some text from the search result 2', + }, + }, + ]; + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('Renders without exploding', async () => { + await renderWithEffects( + wrapInTestApp( + + + , + ), + ); + + expect(query).toHaveBeenCalledWith({ + filters: {}, + pageCursor: undefined, + term: '', + types: ['techdocs'], + }); + }); + + it('Defines a default render result item', async () => { + query.mockResolvedValueOnce({ + results, + }); + + await renderWithEffects( + wrapInTestApp( + + + , + ), + ); + + expect(screen.getByText('Search Result 1')).toBeInTheDocument(); + expect( + screen.getByText('Some text from the search result 1'), + ).toBeInTheDocument(); + + expect(screen.getByText('Search Result 2')).toBeInTheDocument(); + expect( + screen.getByText('Some text from the search result 2'), + ).toBeInTheDocument(); + }); + + it('Shows a progress bar when loading results', async () => { + query.mockReturnValueOnce(new Promise(() => {})); + await renderWithEffects( + wrapInTestApp( + + + , + ), + ); + + await waitFor(() => { + expect(screen.getByRole('progressbar')).toBeInTheDocument(); + }); + }); + + it('Shows an error panel when results rendering fails', async () => { + query.mockRejectedValueOnce(new Error()); + await renderWithEffects( + wrapInTestApp( + + + , + ), + ); + + await waitFor(() => { + expect( + screen.getByText( + 'Error: Error encountered while fetching search results', + ), + ).toBeInTheDocument(); + }); + }); +}); diff --git a/plugins/search-react/src/components/SearchResultList/SearchResultList.tsx b/plugins/search-react/src/components/SearchResultList/SearchResultList.tsx new file mode 100644 index 0000000000..8f184f7080 --- /dev/null +++ b/plugins/search-react/src/components/SearchResultList/SearchResultList.tsx @@ -0,0 +1,130 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; + +import { List, ListProps } from '@material-ui/core'; + +import { + EmptyState, + Progress, + ResponseErrorPanel, +} from '@backstage/core-components'; +import { AnalyticsContext } from '@backstage/core-plugin-api'; +import { SearchQuery, SearchResult } from '@backstage/plugin-search-common'; + +import { DefaultResultListItem } from '../DefaultResultListItem'; +import { SearchResultState } from '../SearchResult'; + +/** + * Props for {@link SearchResultListLayout} + * @public + */ +export type SearchResultListLayoutProps = ListProps & { + /** + * Search results to be rendered as a list. + */ + resultItems?: SearchResult[]; + /** + * Function to customize how result items are rendered. + */ + renderResultItem?: (resultItem: SearchResult) => JSX.Element; + /** + * If defined, will render a default error panel. + */ + error?: Error; + /** + * If defined, will render a default loading progress. + */ + loading?: boolean; +}; + +/** + * Default layout for rendering search results in a list. + * @param props - See {@link SearchResultListLayoutProps}. + * @public + */ +export const SearchResultListLayout = (props: SearchResultListLayoutProps) => { + const { loading, error, resultItems, renderResultItem, ...rest } = props; + + return ( + + {loading ? : null} + {!loading && error ? ( + + ) : null} + {!loading && !error && resultItems?.length + ? resultItems.map(resultItem => renderResultItem?.(resultItem) ?? null) + : null} + {!loading && !error && !resultItems?.length ? ( + + ) : null} + + ); +}; + +/** + * Props for {@link SearchResultList}. + * @public + */ +export type SearchResultListProps = Omit< + SearchResultListLayoutProps, + 'loading' | 'error' | 'resultItems' +> & { + /** + * A search query used for requesting the results to be listed. + */ + query: Partial; +}; + +/** + * Given a query, search for results and render them as a list. + * @param props - See {@link SearchResultListProps}. + * @public + */ +export const SearchResultList = (props: SearchResultListProps) => { + const { + query, + renderResultItem = ({ document }) => ( + + ), + ...rest + } = props; + + return ( + + + {({ loading, error, value }) => ( + + )} + + + ); +}; diff --git a/plugins/search-react/src/components/SearchResultList/index.tsx b/plugins/search-react/src/components/SearchResultList/index.tsx new file mode 100644 index 0000000000..64dee0dd2c --- /dev/null +++ b/plugins/search-react/src/components/SearchResultList/index.tsx @@ -0,0 +1,22 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { SearchResultList, SearchResultListLayout } from './SearchResultList'; + +export type { + SearchResultListProps, + SearchResultListLayoutProps, +} from './SearchResultList'; diff --git a/plugins/search-react/src/components/index.ts b/plugins/search-react/src/components/index.ts index e254c36dd9..6cf7a22a7d 100644 --- a/plugins/search-react/src/components/index.ts +++ b/plugins/search-react/src/components/index.ts @@ -20,4 +20,5 @@ export * from './SearchAutocomplete'; export * from './SearchFilter'; export * from './SearchResult'; export * from './SearchResultPager'; +export * from './SearchResultList'; export * from './DefaultResultListItem'; From 69ce53d58885ebde0fb688c4558ba1959e637388 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Tue, 13 Sep 2022 11:25:50 +0200 Subject: [PATCH 039/185] feat(search-react): create search result group component Signed-off-by: Camila Belo --- .../SearchResult/SearchResult.stories.tsx | 38 ++ .../SearchResultGroup.stories.tsx | 326 +++++++++++ .../SearchResultGroup.test.tsx | 316 +++++++++++ .../SearchResultGroup/SearchResultGroup.tsx | 512 ++++++++++++++++++ .../components/SearchResultGroup/index.tsx | 32 ++ plugins/search-react/src/components/index.ts | 1 + 6 files changed, 1225 insertions(+) create mode 100644 plugins/search-react/src/components/SearchResultGroup/SearchResultGroup.stories.tsx create mode 100644 plugins/search-react/src/components/SearchResultGroup/SearchResultGroup.test.tsx create mode 100644 plugins/search-react/src/components/SearchResultGroup/SearchResultGroup.tsx create mode 100644 plugins/search-react/src/components/SearchResultGroup/index.tsx diff --git a/plugins/search-react/src/components/SearchResult/SearchResult.stories.tsx b/plugins/search-react/src/components/SearchResult/SearchResult.stories.tsx index 8ac8aace0f..4b8d9bbdd4 100644 --- a/plugins/search-react/src/components/SearchResult/SearchResult.stories.tsx +++ b/plugins/search-react/src/components/SearchResult/SearchResult.stories.tsx @@ -18,6 +18,8 @@ import React, { ComponentType } from 'react'; import { MemoryRouter } from 'react-router'; import { List, ListItem } from '@material-ui/core'; +import DefaultIcon from '@material-ui/icons/InsertDriveFile'; +import CustomIcon from '@material-ui/icons/NoteAdd'; import { Link } from '@backstage/core-components'; import { TestApiProvider } from '@backstage/test-utils'; @@ -30,6 +32,7 @@ import { DefaultResultListItem } from '../DefaultResultListItem'; import { SearchResultListLayout } from '../SearchResultList'; import { SearchResult } from './SearchResult'; +import { SearchResultGroupLayout } from '../SearchResultGroup'; const mockResults = { results: [ @@ -180,3 +183,38 @@ export const ListLayout = () => { ); }; + +export const GroupLayout = () => { + return ( + + {({ results }) => ( + <> + } + title="Custom" + link="See all custom results" + resultItems={results.filter( + ({ type }) => type === 'custom-result-item', + )} + renderResultItem={({ document }) => ( + + )} + /> + } + title="Default" + resultItems={results.filter( + ({ type }) => type !== 'custom-result-item', + )} + renderResultItem={({ document }) => ( + + )} + /> + + )} + + ); +}; diff --git a/plugins/search-react/src/components/SearchResultGroup/SearchResultGroup.stories.tsx b/plugins/search-react/src/components/SearchResultGroup/SearchResultGroup.stories.tsx new file mode 100644 index 0000000000..3a20dec36d --- /dev/null +++ b/plugins/search-react/src/components/SearchResultGroup/SearchResultGroup.stories.tsx @@ -0,0 +1,326 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React, { ComponentType, useCallback, useState } from 'react'; + +import { + Grid, + ListItem, + ListItemIcon, + ListItemText, + MenuItem, +} from '@material-ui/core'; +import DocsIcon from '@material-ui/icons/InsertDriveFile'; + +import { JsonValue } from '@backstage/types'; +import { Link } from '@backstage/core-components'; +import { createRouteRef } from '@backstage/core-plugin-api'; +import { SearchQuery, SearchResultSet } from '@backstage/plugin-search-common'; +import { TestApiProvider, wrapInTestApp } from '@backstage/test-utils'; + +import { searchApiRef, MockSearchApi } from '../../api'; + +import { + SearchResultGroup, + SearchResultGroupTextFilterField, + SearchResultGroupSelectFilterField, +} from './SearchResultGroup'; + +const routeRef = createRouteRef({ + id: 'storybook.search.results.group.route', +}); + +const searchApiMock = new MockSearchApi({ + results: [ + { + type: 'techdocs', + document: { + location: 'search/search-result1', + title: 'Search Result 1', + text: 'Some text from the search result 1', + }, + }, + { + type: 'custom', + document: { + location: 'search/search-result2', + title: 'Search Result 2', + text: 'Some text from the search result 2', + }, + }, + ], +}); + +export default { + title: 'Plugins/Search/SearchResultGroup', + component: SearchResultGroup, + decorators: [ + (Story: ComponentType<{}>) => + wrapInTestApp( + + + + + + + , + { mountedRoutes: { '/': routeRef } }, + ), + ], +}; + +export const Default = () => { + const [query] = useState>({ + types: ['techdocs'], + }); + + return ( + } + title="Documentation" + /> + ); +}; + +export const Loading = () => { + const [query] = useState>({ + types: ['techdocs'], + }); + + return ( + new Promise(() => {}) }], + ]} + > + } + title="Documentation" + /> + + ); +}; + +export const WithError = () => { + const [query] = useState>({ + types: ['techdocs'], + }); + + return ( + + new Promise(() => { + throw new Error(); + }), + }, + ], + ]} + > + } + title="Documentation" + /> + + ); +}; + +export const WithCustomTitle = () => { + const [query] = useState>({ + types: ['custom'], + }); + + return ( + } + title="Custom" + titleProps={{ color: 'secondary' }} + /> + ); +}; + +export const WithCustomLink = () => { + const [query] = useState>({ + types: ['custom'], + }); + + return ( + } + title="Custom" + link="See all custom results" + linkProps={{ to: '/custom' }} + /> + ); +}; + +export const WithFilters = () => { + const [query, setQuery] = useState>({ + types: ['software-catalog'], + }); + + const filterOptions = [ + { + label: 'Lifecycle', + value: 'lifecycle', + }, + { + label: 'Owner', + value: 'owner', + }, + ]; + + const handleFilterAdd = useCallback( + (key: string) => () => { + setQuery(prevQuery => { + const { filters: prevFilters, ...rest } = prevQuery; + const newFilters = { ...prevFilters, [key]: undefined }; + return { ...rest, filters: newFilters }; + }); + }, + [], + ); + + const handleFilterChange = useCallback( + (key: string) => (value: JsonValue) => { + setQuery(prevQuery => { + const { filters: prevFilters, ...rest } = prevQuery; + const newFilters = { ...prevFilters, [key]: value }; + return { ...rest, filters: newFilters }; + }); + }, + [], + ); + + const handleFilterDelete = useCallback( + (key: string) => () => { + setQuery(prevQuery => { + const { filters: prevFilters, ...rest } = prevQuery; + const newFilters = { ...prevFilters }; + delete newFilters[key]; + return { ...rest, filters: newFilters }; + }); + }, + [], + ); + + return ( + } + title="Documentation" + filterOptions={filterOptions} + renderFilterOption={option => ( + + {option.label} + + )} + renderFilterField={(key: string) => { + switch (key) { + case 'lifecycle': + return ( + + Production + Experimental + + ); + case 'owner': + return ( + + ); + default: + return null; + } + }} + /> + ); +}; + +export const WithNoResults = () => { + const [query] = useState>({ + types: ['techdocs'], + }); + + return ( + + } + title="Documentation" + /> + + ); +}; + +const CustomResultListItem = (props: any) => { + const { icon, result } = props; + + return ( + + + {icon && {icon}} + + + + ); +}; + +export const WithCustomResultItem = () => { + const [query] = useState>({ + types: ['custom'], + }); + + return ( + } + title="Custom" + link="See all custom results" + renderResultItem={({ document, highlight, rank }) => ( + + )} + /> + ); +}; diff --git a/plugins/search-react/src/components/SearchResultGroup/SearchResultGroup.test.tsx b/plugins/search-react/src/components/SearchResultGroup/SearchResultGroup.test.tsx new file mode 100644 index 0000000000..c1b45cc433 --- /dev/null +++ b/plugins/search-react/src/components/SearchResultGroup/SearchResultGroup.test.tsx @@ -0,0 +1,316 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import { screen, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; + +import { MenuItem } from '@material-ui/core'; +import DocsIcon from '@material-ui/icons/InsertDriveFile'; + +import { + TestApiProvider, + renderWithEffects, + wrapInTestApp, +} from '@backstage/test-utils'; + +import { searchApiRef } from '../../api'; +import { + SearchResultGroup, + SearchResultGroupSelectFilterField, + SearchResultGroupTextFilterField, +} from './SearchResultGroup'; + +const query = jest.fn().mockResolvedValue({ results: [] }); +const searchApiMock = { query }; + +describe('SearchResultGroup', () => { + const results = [ + { + type: 'techdocs', + document: { + location: 'search/search-result1', + title: 'Search Result 1', + text: 'Some text from the search result 1', + }, + }, + { + type: 'techdocs', + document: { + location: 'search/search-result2', + title: 'Search Result 2', + text: 'Some text from the search result 2', + }, + }, + ]; + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('Renders without exploding', async () => { + await renderWithEffects( + wrapInTestApp( + + } + title="Documentation" + /> + , + ), + ); + + expect(screen.getByTitle('Docs icon')).toBeInTheDocument(); + expect(screen.getByText('Documentation')).toBeInTheDocument(); + expect(query).toHaveBeenCalledWith({ + filters: {}, + pageCursor: undefined, + term: '', + types: ['techdocs'], + }); + }); + + it('Defines a default link', async () => { + await renderWithEffects( + wrapInTestApp( + + } + title="Documentation" + /> + , + ), + ); + + const link = screen.getByText('See all', { exact: false }); + expect(link).toHaveAttribute('href', encodeURI('/search?types[]=techdocs')); + }); + + it('Defines a default render result item', async () => { + query.mockResolvedValueOnce({ + results, + }); + + await renderWithEffects( + wrapInTestApp( + + } + title="Documentation" + /> + , + ), + ); + + expect(screen.getByText('Search Result 1')).toBeInTheDocument(); + expect( + screen.getByText('Some text from the search result 1'), + ).toBeInTheDocument(); + + expect(screen.getByText('Search Result 2')).toBeInTheDocument(); + expect( + screen.getByText('Some text from the search result 2'), + ).toBeInTheDocument(); + }); + + it('Could be customized with no results text', async () => { + await renderWithEffects( + wrapInTestApp( + + } + title="Documentation" + /> + , + ), + ); + + expect( + screen.getByText('Sorry, no results were found'), + ).toBeInTheDocument(); + }); + + it('Could be customized with filters', async () => { + query.mockResolvedValueOnce({ + results, + }); + + await renderWithEffects( + wrapInTestApp( + + } + title="Documentation" + filterOptions={['lifecycle', 'owner']} + /> + , + ), + ); + + await userEvent.click(screen.getByText('Add filter', { exact: false })); + + await waitFor(() => { + expect(screen.getByText('lifecycle')).toBeInTheDocument(); + }); + + expect(screen.getByText('owner')).toBeInTheDocument(); + }); + + it('Could have a text search filter field', async () => { + query.mockResolvedValueOnce({ + results, + }); + + const handleFilterChange = jest.fn(); + const handleFilterDelete = jest.fn(); + + await renderWithEffects( + wrapInTestApp( + + } + title="Documentation" + filterOptions={['owner']} + renderFilterField={(key: string) => + key === 'owner' ? ( + + ) : null + } + /> + , + ), + ); + + await userEvent.click(screen.getByText('Add filter', { exact: false })); + + await userEvent.click(screen.getByText('owner')); + + await userEvent.type( + screen.getByRole('textbox'), + '{backspace}{backspace}{backspace}{backspace}techdocs-core', + ); + + await waitFor(() => { + expect(screen.getByText('techdocs-core')).toBeInTheDocument(); + }); + }); + + it('Could have a select search filter field', async () => { + query.mockResolvedValueOnce({ + results, + }); + + const handleFilterChange = jest.fn(); + const handleFilterDelete = jest.fn(); + + await renderWithEffects( + wrapInTestApp( + + } + title="Documentation" + filterOptions={['lifecycle']} + renderFilterField={(key: string) => + key === 'lifecycle' ? ( + + Production + Experimental + + ) : null + } + /> + , + ), + ); + + await userEvent.click(screen.getByText('Add filter', { exact: false })); + + await userEvent.click(screen.getByText('lifecycle')); + + await userEvent.click(screen.getByText('None')); + + await userEvent.click(screen.getByText('Experimental')); + + await waitFor(() => { + expect(handleFilterChange).toHaveBeenCalledWith('experimental'); + }); + }); + + it('Shows a progress bar when loading results', async () => { + query.mockReturnValueOnce(new Promise(() => {})); + await renderWithEffects( + wrapInTestApp( + + } + title="Documentation" + /> + , + ), + ); + + await waitFor(() => { + expect(screen.getByRole('progressbar')).toBeInTheDocument(); + }); + }); + + it('Shows an error panel when results rendering fails', async () => { + query.mockRejectedValueOnce(new Error()); + await renderWithEffects( + wrapInTestApp( + + } + title="Documentation" + /> + , + ), + ); + + await waitFor(() => { + expect( + screen.getByText( + 'Error: Error encountered while fetching search results', + ), + ).toBeInTheDocument(); + }); + }); +}); diff --git a/plugins/search-react/src/components/SearchResultGroup/SearchResultGroup.tsx b/plugins/search-react/src/components/SearchResultGroup/SearchResultGroup.tsx new file mode 100644 index 0000000000..9c55996ca7 --- /dev/null +++ b/plugins/search-react/src/components/SearchResultGroup/SearchResultGroup.tsx @@ -0,0 +1,512 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React, { + ChangeEvent, + PropsWithChildren, + ReactNode, + useCallback, + useState, +} from 'react'; +import qs from 'qs'; + +import { + makeStyles, + Theme, + List, + ListSubheader, + ListItem, + ListProps, + Menu, + MenuItem, + InputBase, + Select, + Chip, + Typography, + TypographyProps, +} from '@material-ui/core'; +import AddIcon from '@material-ui/icons/Add'; +import ArrowRightIcon from '@material-ui/icons/ArrowForwardIos'; + +import { JsonValue } from '@backstage/types'; +import { + EmptyState, + Link, + LinkProps, + Progress, + ResponseErrorPanel, +} from '@backstage/core-components'; +import { AnalyticsContext } from '@backstage/core-plugin-api'; +import { SearchQuery, SearchResult } from '@backstage/plugin-search-common'; + +import { DefaultResultListItem } from '../DefaultResultListItem'; +import { SearchResultState } from '../SearchResult'; + +const useStyles = makeStyles((theme: Theme) => ({ + listSubheader: { + display: 'flex', + alignItems: 'center', + }, + listSubheaderName: { + marginLeft: theme.spacing(1), + textTransform: 'uppercase', + }, + listSubheaderChip: { + color: theme.palette.text.secondary, + margin: theme.spacing(0, 0, 0, 1.5), + }, + listSubheaderFilter: { + display: 'flex', + color: theme.palette.text.secondary, + margin: theme.spacing(0, 0, 0, 1.5), + }, + listSubheaderLink: { + marginLeft: 'auto', + display: 'flex', + alignItems: 'center', + }, + listSubheaderLinkIcon: { + fontSize: 'inherit', + marginLeft: theme.spacing(0.5), + }, +})); + +/** + * Props for {@link SearchResultGroupFilterFieldLayout} + * @public + */ +export type SearchResultGroupFilterFieldLayoutProps = PropsWithChildren<{ + label: string; + value?: JsonValue; + onDelete: () => void; +}>; + +/** + * Default layout for a search group filter field. + * @param props - See {@link SearchResultGroupFilterFieldLayoutProps}. + * @public + */ +export const SearchResultGroupFilterFieldLayout = ( + props: SearchResultGroupFilterFieldLayoutProps, +) => { + const classes = useStyles(); + const { label, children, ...rest } = props; + + return ( + + {label}: {children} + + } + /> + ); +}; + +const NullIcon = () => null; + +/** + * Common props for a result group filter field. + * @public + */ +export type SearchResultGroupFilterFieldPropsWith = T & + SearchResultGroupFilterFieldLayoutProps & { + onChange: (value: JsonValue) => void; + }; + +const useSearchResultGroupTextFilterStyles = makeStyles((theme: Theme) => ({ + root: { + fontSize: 'inherit', + '&:focus': { + outline: 'none', + background: theme.palette.common.white, + }, + '&:not(:focus)': { + cursor: 'pointer', + color: theme.palette.primary.main, + '&:hover': { + textDecoration: 'underline', + }, + }, + }, +})); + +/** + * Props for {@link SearchResultGroupTextFilterField}. + * @public + */ +export type SearchResultGroupTextFilterFieldProps = + SearchResultGroupFilterFieldPropsWith<{}>; + +/** + * A text field that can be used as filter on search result groups. + * @param props - See {@link SearchResultGroupTextFilterFieldProps}. + * @example + * ``` + * + * ``` + * @public + */ +export const SearchResultGroupTextFilterField = ( + props: SearchResultGroupTextFilterFieldProps, +) => { + const classes = useSearchResultGroupTextFilterStyles(); + const { label, value = 'None', onChange, onDelete } = props; + + const handleChange = useCallback( + (e: ChangeEvent) => { + onChange(e.target.value); + }, + [onChange], + ); + + return ( + + + {value} + + + ); +}; + +const useSearchResultGroupSelectFilterStyles = makeStyles((theme: Theme) => ({ + root: { + fontSize: 'inherit', + '&:not(:focus)': { + cursor: 'pointer', + color: theme.palette.primary.main, + '&:hover': { + textDecoration: 'underline', + }, + }, + '&:focus': { + outline: 'none', + }, + '&>div:first-child': { + padding: 0, + }, + }, +})); + +/** + * Props for {@link SearchResultGroupTextFilterField}. + * @public + */ +export type SearchResultGroupSelectFilterFieldProps = + SearchResultGroupFilterFieldPropsWith<{ + children: ReactNode; + }>; + +/** + * A select field that can be used as filter on search result groups. + * @param props - See {@link SearchResultGroupSelectFilterFieldProps}. + * @example + * ``` + * + * Experimental + * Production + * + * ``` + * @public + */ +export const SearchResultGroupSelectFilterField = ( + props: SearchResultGroupSelectFilterFieldProps, +) => { + const classes = useSearchResultGroupSelectFilterStyles(); + const { label, value = 'none', onChange, onDelete, children } = props; + + const handleChange = useCallback( + (e: ChangeEvent<{ value: unknown }>) => { + onChange(e.target.value as JsonValue); + }, + [onChange], + ); + + return ( + + + + ); +}; + +/** + * Props for {@link SearchResultGroupLayout} + * @public + */ +export type SearchResultGroupLayoutProps = ListProps & { + /** + * Icon that representing a result group. + */ + icon: JSX.Element; + /** + * The results group title content, it could be a text or an element. + */ + title: ReactNode; + /** + * Props for the results group title. + */ + titleProps?: Partial; + /** + * The results group link content, it could be a text or an element. + */ + link?: ReactNode; + /** + * Props for the results group link, the "to" prop defaults to "/search". + */ + linkProps?: Partial; + /** + * A generic filter options that is rendered on the "Add filter" dropdown. + */ + filterOptions?: FilterOption[]; + /** + * Function to customize how filter options are rendered. + * @remarks Defaults to a menu item where its value and label bounds to the option string. + */ + renderFilterOption?: (filterOption: FilterOption) => JSX.Element; + /** + * A list of search filter keys, also known as filter field names. + */ + filterFields?: string[]; + /** + * Function to customize how filter chips are rendered. + */ + renderFilterField?: (key: string) => JSX.Element | null; + /** + * Search results to be rendered as a group. + */ + resultItems?: SearchResult[]; + /** + * Function to customize how result items are rendered. + */ + renderResultItem?: (resultItem: SearchResult) => JSX.Element; + /** + * If defined, will render a default error panel. + */ + error?: Error; + /** + * If defined, will render a default loading progress. + */ + loading?: boolean; +}; + +/** + * Default layout for rendering search results in a group. + * @param props - See {@link SearchResultGroupLayoutProps}. + * @public + */ +export function SearchResultGroupLayout( + props: SearchResultGroupLayoutProps, +) { + const classes = useStyles(); + const [anchorEl, setAnchorEl] = useState(null); + + const { + loading, + error, + icon, + title, + titleProps = {}, + link, + linkProps = {}, + filterOptions, + renderFilterOption, + filterFields, + renderFilterField, + resultItems, + renderResultItem, + ...rest + } = props; + + const handleClick = useCallback((e: React.MouseEvent) => { + setAnchorEl(e.currentTarget); + }, []); + + const handleClose = useCallback(() => { + setAnchorEl(null); + }, []); + + return ( + + + {icon} + + {title} + + {filterOptions ? ( + } + variant="outlined" + label="Add filter" + aria-controls="filters-menu" + aria-haspopup="true" + onClick={handleClick} + /> + ) : null} + {filterOptions ? ( + + {filterOptions.map(filterOption => + renderFilterOption ? ( + renderFilterOption(filterOption) + ) : ( + + {filterOption} + + ), + )} + + ) : null} + {filterFields?.map( + filterField => renderFilterField?.(filterField) ?? null, + )} + + {link ?? ( + <> + See all + + + )} + + + {loading ? : null} + {!loading && error ? ( + + ) : null} + {!loading && !error && resultItems?.length + ? resultItems.map(resultItem => renderResultItem?.(resultItem) ?? null) + : null} + {!loading && !error && !resultItems?.length ? ( + + + + ) : null} + + ); +} + +/** + * Props for {@link SearchResultGroup}. + * @public + */ +export type SearchResultGroupProps = Omit< + SearchResultGroupLayoutProps, + 'loading' | 'error' | 'resultItems' | 'filterFields' +> & { + /** + * A search query used for requesting the results to be grouped. + */ + query: Partial; +}; + +/** + * Given a query, search for results and render them as a group. + * @param props - See {@link SearchResultGroupProps}. + * @public + */ +export function SearchResultGroup( + props: SearchResultGroupProps, +) { + const { + query, + linkProps = {}, + renderResultItem = ({ document }) => ( + + ), + ...rest + } = props; + + const to = `/search?${qs.stringify( + { + query: query.term, + types: query.types, + filters: query.filters, + pageCursor: query.pageCursor, + }, + { arrayFormat: 'brackets' }, + )}`; + + return ( + + + {({ loading, error, value }) => ( + + )} + + + ); +} diff --git a/plugins/search-react/src/components/SearchResultGroup/index.tsx b/plugins/search-react/src/components/SearchResultGroup/index.tsx new file mode 100644 index 0000000000..5cab1320be --- /dev/null +++ b/plugins/search-react/src/components/SearchResultGroup/index.tsx @@ -0,0 +1,32 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { + SearchResultGroup, + SearchResultGroupLayout, + SearchResultGroupTextFilterField, + SearchResultGroupSelectFilterField, + SearchResultGroupFilterFieldLayout, +} from './SearchResultGroup'; + +export type { + SearchResultGroupProps, + SearchResultGroupLayoutProps, + SearchResultGroupFilterFieldPropsWith, + SearchResultGroupFilterFieldLayoutProps, + SearchResultGroupTextFilterFieldProps, + SearchResultGroupSelectFilterFieldProps, +} from './SearchResultGroup'; diff --git a/plugins/search-react/src/components/index.ts b/plugins/search-react/src/components/index.ts index 6cf7a22a7d..62d8b611a4 100644 --- a/plugins/search-react/src/components/index.ts +++ b/plugins/search-react/src/components/index.ts @@ -21,4 +21,5 @@ export * from './SearchFilter'; export * from './SearchResult'; export * from './SearchResultPager'; export * from './SearchResultList'; +export * from './SearchResultGroup'; export * from './DefaultResultListItem'; From cdec578a5f1800ff4f9c559915a63fd3f728fe67 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Tue, 13 Sep 2022 11:26:39 +0200 Subject: [PATCH 040/185] feat(search-react): update yarn lock Signed-off-by: Camila Belo --- plugins/search-react/package.json | 1 + yarn.lock | 1 + 2 files changed, 2 insertions(+) diff --git a/plugins/search-react/package.json b/plugins/search-react/package.json index 1afdc3c406..826d751353 100644 --- a/plugins/search-react/package.json +++ b/plugins/search-react/package.json @@ -40,6 +40,7 @@ "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", + "qs": "^6.9.4", "react-use": "^17.3.2" }, "peerDependencies": { diff --git a/yarn.lock b/yarn.lock index 8c36d1da02..d55434a22a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6633,6 +6633,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/react-hooks": ^8.0.0 "@testing-library/user-event": ^14.0.0 + qs: ^6.9.4 react-use: ^17.3.2 peerDependencies: "@types/react": ^16.13.1 || ^17.0.0 From c94bab21a8e95ae9aed49784d9e370d09ea3ba34 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Tue, 13 Sep 2022 11:28:39 +0200 Subject: [PATCH 041/185] docs(search-react): update api reports Signed-off-by: Camila Belo --- plugins/search-react/api-report.md | 136 +++++++++++++++++++++++++++-- 1 file changed, 130 insertions(+), 6 deletions(-) diff --git a/plugins/search-react/api-report.md b/plugins/search-react/api-report.md index 7d5e64757b..5ec4124fcc 100644 --- a/plugins/search-react/api-report.md +++ b/plugins/search-react/api-report.md @@ -11,7 +11,10 @@ import { AutocompleteProps } from '@material-ui/lab'; import { ForwardRefExoticComponent } from 'react'; import { InputBaseProps } from '@material-ui/core'; import { JsonObject } from '@backstage/types'; +import { JsonValue } from '@backstage/types'; +import { LinkProps } from '@backstage/core-components'; import { ListItemTextProps } from '@material-ui/core'; +import { ListProps } from '@material-ui/core'; import { PropsWithChildren } from 'react'; import { default as React_2 } from 'react'; import { ReactElement } from 'react'; @@ -21,6 +24,7 @@ import { SearchDocument } from '@backstage/plugin-search-common'; import { SearchQuery } from '@backstage/plugin-search-common'; import { SearchResult as SearchResult_2 } from '@backstage/plugin-search-common'; import { SearchResultSet } from '@backstage/plugin-search-common'; +import { TypographyProps } from '@material-ui/core'; // @public (undocumented) export const AutocompleteFilter: ( @@ -205,22 +209,142 @@ export type SearchFilterWrapperProps = SearchFilterComponentProps & { debug?: boolean; }; -// @public (undocumented) +// @public export const SearchResult: (props: SearchResultProps) => JSX.Element; // @public -export const SearchResultComponent: ({ - children, -}: SearchResultProps) => JSX.Element; +export const SearchResultApi: (props: SearchResultApiProps) => JSX.Element; + +// @public +export type SearchResultApiProps = SearchResultContextProps & { + query: Partial; +}; + +// @public +export const SearchResultComponent: (props: SearchResultProps) => JSX.Element; + +// @public +export const SearchResultContext: ( + props: SearchResultContextProps, +) => JSX.Element; + +// @public +export type SearchResultContextProps = { + children: (state: AsyncState) => JSX.Element; +}; + +// @public +export function SearchResultGroup( + props: SearchResultGroupProps, +): JSX.Element; + +// @public +export const SearchResultGroupFilterFieldLayout: ( + props: SearchResultGroupFilterFieldLayoutProps, +) => JSX.Element; + +// @public +export type SearchResultGroupFilterFieldLayoutProps = PropsWithChildren<{ + label: string; + value?: JsonValue; + onDelete: () => void; +}>; + +// @public +export type SearchResultGroupFilterFieldPropsWith = T & + SearchResultGroupFilterFieldLayoutProps & { + onChange: (value: JsonValue) => void; + }; + +// @public +export function SearchResultGroupLayout( + props: SearchResultGroupLayoutProps, +): JSX.Element; + +// @public +export type SearchResultGroupLayoutProps = ListProps & { + icon: JSX.Element; + title: ReactNode; + titleProps?: Partial; + link?: ReactNode; + linkProps?: Partial; + filterOptions?: FilterOption[]; + renderFilterOption?: (filterOption: FilterOption) => JSX.Element; + filterFields?: string[]; + renderFilterField?: (key: string) => JSX.Element | null; + resultItems?: SearchResult_2[]; + renderResultItem?: (resultItem: SearchResult_2) => JSX.Element; + error?: Error; + loading?: boolean; +}; + +// @public +export type SearchResultGroupProps = Omit< + SearchResultGroupLayoutProps, + 'loading' | 'error' | 'resultItems' | 'filterFields' +> & { + query: Partial; +}; + +// @public +export const SearchResultGroupSelectFilterField: ( + props: SearchResultGroupSelectFilterFieldProps, +) => JSX.Element; + +// @public +export type SearchResultGroupSelectFilterFieldProps = + SearchResultGroupFilterFieldPropsWith<{ + children: ReactNode; + }>; + +// @public +export const SearchResultGroupTextFilterField: ( + props: SearchResultGroupTextFilterFieldProps, +) => JSX.Element; + +// @public +export type SearchResultGroupTextFilterFieldProps = + SearchResultGroupFilterFieldPropsWith<{}>; + +// @public +export const SearchResultList: (props: SearchResultListProps) => JSX.Element; + +// @public +export const SearchResultListLayout: ( + props: SearchResultListLayoutProps, +) => JSX.Element; + +// @public +export type SearchResultListLayoutProps = ListProps & { + resultItems?: SearchResult_2[]; + renderResultItem?: (resultItem: SearchResult_2) => JSX.Element; + error?: Error; + loading?: boolean; +}; + +// @public +export type SearchResultListProps = Omit< + SearchResultListLayoutProps, + 'loading' | 'error' | 'resultItems' +> & { + query: Partial; +}; // @public (undocumented) export const SearchResultPager: () => JSX.Element; // @public -export type SearchResultProps = { - children: (results: { results: SearchResult_2[] }) => JSX.Element; +export type SearchResultProps = Pick & { + children: (resultSet: SearchResultSet) => JSX.Element; }; +// @public +export const SearchResultState: (props: SearchResultStateProps) => JSX.Element; + +// @public +export type SearchResultStateProps = SearchResultContextProps & + Partial; + // @public (undocumented) export const SelectFilter: (props: SearchFilterComponentProps) => JSX.Element; From 97f2b8f3fd2db7c5c4fdcbce7157150eb60dbf4a Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Wed, 14 Sep 2022 13:50:37 +0200 Subject: [PATCH 042/185] chore: add changeset file Signed-off-by: Camila Belo --- .changeset/search-countries-exercise.md | 283 ++++++++++++++++++++++++ 1 file changed, 283 insertions(+) create mode 100644 .changeset/search-countries-exercise.md diff --git a/.changeset/search-countries-exercise.md b/.changeset/search-countries-exercise.md new file mode 100644 index 0000000000..390813444f --- /dev/null +++ b/.changeset/search-countries-exercise.md @@ -0,0 +1,283 @@ +--- +'@backstage/plugin-search-react': minor +--- + +The `` component now accepts a optional `query` prop to request results from the search api: + +> Note: If a query prop is not defined, the results will by default be consumed from the context. + +Example: + +```jsx +import React, { useState, useCallback } from 'react'; + +import { Grid, List, Paper } from '@material-ui/core'; + +import { Page, Header, Content, Lifecycle } from '@backstage/core-components'; +import { + DefaultResultListItem, + SearchBarBase, + SearchResult, +} from '@backstage/plugin-search-react'; + +const SearchPage = () => { + const [query, setQuery] = useState({ + term: '', + types: [], + filters: {}, + }); + + const handleChange = useCallback( + (term: string) => { + setQuery(prevQuery => ({ ...prevQuery, term })); + }, + [setQuery], + ); + + return ( + +
} /> + + + + + + + + + + {({ results }) => ( + + {results.map(({ document }) => ( + + ))} + + )} + + + + + + ); +}; +``` + +Additionally, a search page can also be composed using these two new results layout components: + +```jsx +// Example rendering results as list + + {({ results }) => ( + { + switch (type) { + case 'custom-result-item': + return ( + + ); + default: + return ( + + ); + } + }} + /> + )} + +``` + +```jsx +// Example rendering results as groups + + {({ results }) => ( + <> + } + title="Custom" + link="See all custom results" + resultItems={results.filter( + ({ type }) => type === 'custom-result-item', + )} + renderResultItem={({ document }) => ( + + )} + /> + } + title="Default" + resultItems={results.filter( + ({ type }) => type !== 'custom-result-item', + )} + renderResultItem={({ document }) => ( + + )} + /> + + )} + +``` + +A `SearchResultList` and `SearchResultGroup` components were also created for users who have search pages with multiple queries, both are specializations of `SearchResult` and also accept a `query` as a prop as well: + +```jsx +// Example using the +const SearchPage = () => { + const query = { + term: 'example', + }; + + return ( + { + switch (type) { + case 'custom': + return ( + } + result={document} + highlight={highlight} + rank={rank} + /> + ); + default: + return ( + + ); + } + }} + /> + ); +}; +``` + +```jsx +// Example using the for creating a component that search and group software catalog results +import React, { useState, useCallback } from 'react'; + +import { MenuItem } from '@material-ui/core'; + +import { JsonValue } from '@backstage/types'; +import { CatalogIcon } from '@backstage/core-components'; +import { CatalogSearchResultListItem } from '@backstage/plugin-catalog'; +import { + SearchResultGroup, + SearchResultGroupTextFilterField, + SearchResultGroupSelectFilterField, +} from @backstage/plugin-search-react; +import { SearchQuery } from '@backstage/plugin-search-common'; + +const CatalogResultsGroup = () => { + const [query, setQuery] = useState>({ + types: ['software-catalog'], + }); + + const filterOptions = [ + { + label: 'Lifecycle', + value: 'lifecycle', + }, + { + label: 'Owner', + value: 'owner', + }, + ]; + + const handleFilterAdd = useCallback( + (key: string) => () => { + setQuery(prevQuery => { + const { filters: prevFilters, ...rest } = prevQuery; + const newFilters = { ...prevFilters, [key]: undefined }; + return { ...rest, filters: newFilters }; + }); + }, + [], + ); + + const handleFilterChange = useCallback( + (key: string) => (value: JsonValue) => { + setQuery(prevQuery => { + const { filters: prevFilters, ...rest } = prevQuery; + const newFilters = { ...prevFilters, [key]: value }; + return { ...rest, filters: newFilters }; + }); + }, + [], + ); + + const handleFilterDelete = useCallback( + (key: string) => () => { + setQuery(prevQuery => { + const { filters: prevFilters, ...rest } = prevQuery; + const newFilters = { ...prevFilters }; + delete newFilters[key]; + return { ...rest, filters: newFilters }; + }); + }, + [], + ); + + return ( + } + title="Software Catalog" + link="See all software catalog results" + filterOptions={filterOptions} + renderFilterOption={({ label, value }) => ( + + {label} + + )} + renderFilterField={(key: string) => { + switch (key) { + case 'lifecycle': + return ( + + Production + Experimental + + ); + case 'owner': + return ( + + ); + default: + return null; + } + } + renderResultItem={({ document, highlight, rank }) => ( + + )} + /> + ); +}; +``` From b6de0abf85cfc7c1c75626466f1242e665f12cd7 Mon Sep 17 00:00:00 2001 From: Taras Date: Thu, 15 Sep 2022 09:15:57 -0400 Subject: [PATCH 043/185] Add failing test Signed-off-by: Taras --- .../modules/core/PlaceholderProcessor.test.ts | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/plugins/catalog-backend/src/modules/core/PlaceholderProcessor.test.ts b/plugins/catalog-backend/src/modules/core/PlaceholderProcessor.test.ts index 8fd8114760..e0f7d81968 100644 --- a/plugins/catalog-backend/src/modules/core/PlaceholderProcessor.test.ts +++ b/plugins/catalog-backend/src/modules/core/PlaceholderProcessor.test.ts @@ -387,6 +387,44 @@ describe('PlaceholderProcessor', () => { key: 'url:http://example.com/path-to-file.json', }); }); + + it('accepts arbitrary object as value', async () => { + read.mockResolvedValue( + Buffer.from(JSON.stringify({ a: ['b', 7] }), 'utf-8'), + ); + + const processor = new PlaceholderProcessor({ + resolvers: { + merge: async ({ value }) => { + console.log({ value }); + if (value instanceof Object) { + return { merged: 'value', ...value }; + } + return value; + }, + }, + reader, + integrations, + }); + + const result = await processor.preProcessEntity( + { + apiVersion: 'a', + kind: 'k', + metadata: { name: 'n' }, + spec: { a: { $merge: { passed: 'value' } } }, + }, + { type: 'fake', target: 'http://example.com' }, + () => {}, + ); + + expect(result).toMatchObject({ + apiVersion: 'a', + kind: 'k', + metadata: { name: 'n' }, + spec: { a: { passed: 'value', merged: 'value' } }, + }); + }); }); describe('yamlPlaceholderResolver', () => { From f2f2df9a731491a55bdf530244f21e706af88866 Mon Sep 17 00:00:00 2001 From: Taras Date: Thu, 15 Sep 2022 09:23:07 -0400 Subject: [PATCH 044/185] Allow value to be non-string Signed-off-by: Taras --- .../modules/core/PlaceholderProcessor.test.ts | 1 - .../src/modules/core/PlaceholderProcessor.ts | 16 ++++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/plugins/catalog-backend/src/modules/core/PlaceholderProcessor.test.ts b/plugins/catalog-backend/src/modules/core/PlaceholderProcessor.test.ts index e0f7d81968..aa0d6c4766 100644 --- a/plugins/catalog-backend/src/modules/core/PlaceholderProcessor.test.ts +++ b/plugins/catalog-backend/src/modules/core/PlaceholderProcessor.test.ts @@ -396,7 +396,6 @@ describe('PlaceholderProcessor', () => { const processor = new PlaceholderProcessor({ resolvers: { merge: async ({ value }) => { - console.log({ value }); if (value instanceof Object) { return { merged: 'value', ...value }; } diff --git a/plugins/catalog-backend/src/modules/core/PlaceholderProcessor.ts b/plugins/catalog-backend/src/modules/core/PlaceholderProcessor.ts index 39c9dc59ec..cf5679058d 100644 --- a/plugins/catalog-backend/src/modules/core/PlaceholderProcessor.ts +++ b/plugins/catalog-backend/src/modules/core/PlaceholderProcessor.ts @@ -111,15 +111,19 @@ export class PlaceholderProcessor implements CatalogProcessor { const resolverValue = data[keys[0]]; const resolver = this.options.resolvers[resolverKey]; - if (!resolver || typeof resolverValue !== 'string') { - // If there was no such placeholder resolver or if the value was not a - // string, we err on the side of safety and assume that this is - // something that's best left alone. For example, if the input contains - // JSONSchema, there may be "$ref": "#/definitions/node" nodes in the - // document. + if (!resolver) { + // If there was no such placeholder resolver, we err on the side of safety + // and assume that this is something that's best left alone. For example, if + // the input contains JSONSchema, there may be "$ref": "#/definitions/node" + // nodes in the document. return [data, false]; } + // if (typeof resolverValue !== 'string') { + // treat it as an argument to resolver function + // TODO: make this recursive, but it should resolve from bottom up + // } + const read = async (url: string): Promise => { if (this.options.reader.readUrl) { const response = await this.options.reader.readUrl(url); From 63296ebcd4191c58d11fb168c953440c1871bfd5 Mon Sep 17 00:00:00 2001 From: Taras Date: Thu, 15 Sep 2022 09:44:14 -0400 Subject: [PATCH 045/185] Added changeset Signed-off-by: Taras --- .changeset/rude-bulldogs-sleep.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/rude-bulldogs-sleep.md diff --git a/.changeset/rude-bulldogs-sleep.md b/.changeset/rude-bulldogs-sleep.md new file mode 100644 index 0000000000..8a2a0590b3 --- /dev/null +++ b/.changeset/rude-bulldogs-sleep.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend': patch +--- + +Allow Placeholder value to be any value, not only string. From a98f5d4c212283eae991dd287569241e8b9675a5 Mon Sep 17 00:00:00 2001 From: Jake Crews Date: Thu, 15 Sep 2022 08:51:02 -0500 Subject: [PATCH 046/185] Add the ability to pass custom defaults to createGitlabApi constructor Signed-off-by: Jake Crews --- .changeset/wicked-spies-draw.md | 5 +++++ plugins/cicd-statistics-module-gitlab/src/api/gitlab.ts | 9 ++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 .changeset/wicked-spies-draw.md diff --git a/.changeset/wicked-spies-draw.md b/.changeset/wicked-spies-draw.md new file mode 100644 index 0000000000..3b92e394d0 --- /dev/null +++ b/.changeset/wicked-spies-draw.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-cicd-statistics-module-gitlab': patch +--- + +add the ability to add cicd default options to createGitlabApi constructor diff --git a/plugins/cicd-statistics-module-gitlab/src/api/gitlab.ts b/plugins/cicd-statistics-module-gitlab/src/api/gitlab.ts index 7439d1800c..5e4384fe88 100644 --- a/plugins/cicd-statistics-module-gitlab/src/api/gitlab.ts +++ b/plugins/cicd-statistics-module-gitlab/src/api/gitlab.ts @@ -18,6 +18,7 @@ import { CicdStatisticsApi, CicdState, CicdConfiguration, + CicdDefaults, Build, FetchBuildsOptions, Stage, @@ -47,9 +48,14 @@ export type GitlabClient = { */ export class CicdStatisticsApiGitlab implements CicdStatisticsApi { readonly #gitLabAuthApi: OAuthApi; + readonly #cicdDefaults: Partial; - constructor(gitLabAuthApi: OAuthApi) { + constructor( + gitLabAuthApi: OAuthApi, + cicdDefaults: Partial = {}, + ) { this.#gitLabAuthApi = gitLabAuthApi; + this.#cicdDefaults = cicdDefaults; } public async createGitlabApi( @@ -154,6 +160,7 @@ export class CicdStatisticsApiGitlab implements CicdStatisticsApi { 'expired', 'unknown', ] as const, + defaults: this.#cicdDefaults, }; } } From f493a9efcc639107a313db2f74cc5f62cded4a88 Mon Sep 17 00:00:00 2001 From: Jake Crews Date: Thu, 15 Sep 2022 09:47:05 -0500 Subject: [PATCH 047/185] Fix documentation errors Signed-off-by: Jake Crews --- .changeset/wicked-spies-draw.md | 2 +- plugins/cicd-statistics-module-gitlab/README.md | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.changeset/wicked-spies-draw.md b/.changeset/wicked-spies-draw.md index 3b92e394d0..399f70e062 100644 --- a/.changeset/wicked-spies-draw.md +++ b/.changeset/wicked-spies-draw.md @@ -2,4 +2,4 @@ '@backstage/plugin-cicd-statistics-module-gitlab': patch --- -add the ability to add cicd default options to createGitlabApi constructor +add the ability to add CICD default options to createGitlabApi constructor diff --git a/plugins/cicd-statistics-module-gitlab/README.md b/plugins/cicd-statistics-module-gitlab/README.md index 0b11f6950a..392bd0e937 100644 --- a/plugins/cicd-statistics-module-gitlab/README.md +++ b/plugins/cicd-statistics-module-gitlab/README.md @@ -7,6 +7,7 @@ This is an extension module to the `cicd-statistics` plugin, providing a `CicdSt 1. Install the `cicd-statistics` and `cicd-statistics-module-gitlab` plugins in the `app` package. 2. Configure your ApiFactory: + - You can optionally pass in a second argument to `CicdStatisticsApiGitlab` of type [CicdDefaults](https://github.com/backstage/backstage/blob/2881c53cb383bf127c150f837f37fe535d8cf97b/plugins/cicd-statistics/src/apis/types.ts#L179) to alter the default CICD UI configuration ```tsx // packages/app/src/apis.ts From b31ffb0067319258697c6668679979116791e21e Mon Sep 17 00:00:00 2001 From: Jake Crews Date: Thu, 15 Sep 2022 09:58:12 -0500 Subject: [PATCH 048/185] api report generation Signed-off-by: Jake Crews --- plugins/cicd-statistics-module-gitlab/api-report.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/cicd-statistics-module-gitlab/api-report.md b/plugins/cicd-statistics-module-gitlab/api-report.md index 5e07255f54..a0364afa31 100644 --- a/plugins/cicd-statistics-module-gitlab/api-report.md +++ b/plugins/cicd-statistics-module-gitlab/api-report.md @@ -4,6 +4,7 @@ ```ts import { CicdConfiguration } from '@backstage/plugin-cicd-statistics'; +import { CicdDefaults } from '@backstage/plugin-cicd-statistics'; import { CicdState } from '@backstage/plugin-cicd-statistics'; import { CicdStatisticsApi } from '@backstage/plugin-cicd-statistics'; import { Entity } from '@backstage/catalog-model'; @@ -13,7 +14,7 @@ import { OAuthApi } from '@backstage/core-plugin-api'; // @public export class CicdStatisticsApiGitlab implements CicdStatisticsApi { - constructor(gitLabAuthApi: OAuthApi); + constructor(gitLabAuthApi: OAuthApi, cicdDefaults?: Partial); // (undocumented) createGitlabApi(entity: Entity, scopes: string[]): Promise; // (undocumented) From 0fbd20aa7efab51412e0619af82c3dbc62e634a3 Mon Sep 17 00:00:00 2001 From: Tim Jacomb <21194782+timja@users.noreply.github.com> Date: Thu, 15 Sep 2022 16:35:34 +0100 Subject: [PATCH 049/185] Update Dockerfile Signed-off-by: Tim Jacomb <21194782+timja@users.noreply.github.com> --- packages/backend/Dockerfile | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/backend/Dockerfile b/packages/backend/Dockerfile index 7ed0121467..21ff07deb4 100644 --- a/packages/backend/Dockerfile +++ b/packages/backend/Dockerfile @@ -19,15 +19,17 @@ RUN apt-get update && \ yarn config set python /usr/bin/python3 # From here on we use the least-privileged `node` user to run the backend. -USER node WORKDIR /app +RUN chown node:node /app +USER node + # This switches many Node.js dependencies to production mode. ENV NODE_ENV production # Copy over Yarn 3 configuration, release, and plugins -COPY .yarn ./.yarn -COPY .yarnrc.yml ./ +COPY --chown=node:node .yarn ./.yarn +COPY --chown=node:node .yarnrc.yml ./ # Copy repo skeleton first, to avoid unnecessary docker cache invalidation. # The skeleton contains the package.json of each package in the monorepo, From 95376dd679e66df3c2b464e8b62cb018a8d859a5 Mon Sep 17 00:00:00 2001 From: Taras Date: Thu, 15 Sep 2022 14:50:43 -0400 Subject: [PATCH 050/185] Remove unnecessary mock Signed-off-by: Taras --- .../src/modules/core/PlaceholderProcessor.test.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/plugins/catalog-backend/src/modules/core/PlaceholderProcessor.test.ts b/plugins/catalog-backend/src/modules/core/PlaceholderProcessor.test.ts index aa0d6c4766..105ab03d90 100644 --- a/plugins/catalog-backend/src/modules/core/PlaceholderProcessor.test.ts +++ b/plugins/catalog-backend/src/modules/core/PlaceholderProcessor.test.ts @@ -389,10 +389,6 @@ describe('PlaceholderProcessor', () => { }); it('accepts arbitrary object as value', async () => { - read.mockResolvedValue( - Buffer.from(JSON.stringify({ a: ['b', 7] }), 'utf-8'), - ); - const processor = new PlaceholderProcessor({ resolvers: { merge: async ({ value }) => { From 06bd9581778ad435e9f39c20ed54af9d9be4a8ec Mon Sep 17 00:00:00 2001 From: Taras Date: Thu, 15 Sep 2022 15:08:56 -0400 Subject: [PATCH 051/185] Add some minimal documentation on how to use the PlaceholderProcessor Signed-off-by: Taras --- .../software-templates/writing-templates.md | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/docs/features/software-templates/writing-templates.md b/docs/features/software-templates/writing-templates.md index a1cd50f271..2ce7c27bc1 100644 --- a/docs/features/software-templates/writing-templates.md +++ b/docs/features/software-templates/writing-templates.md @@ -581,3 +581,96 @@ output things. You can grab that output using `steps.$stepId.output.$property`. You can read more about all the `inputs` and `outputs` defined in the actions in code part of the `JSONSchema`, or you can read more about our [built in actions](./builtin-actions.md). + +## Creating reusable templates + +We can use the PlaceholderProcessor to create reusable portions of a template. A placeholder is a property on an entity object that starts with `$`. Backstage has some built in placeholders including `$text`, `$json` and `$yaml`. Each placeholder has a resolver. A resolver is an asyncronous function that receives the value assigned to the placeholder. A resolver is expected to return a promise that resolves to a value. The resolved value will replace the object where the placeholder was defined. + +Let's say we want to reuse a portion of the template that asks user to specify a host name and we want to be able to add other fields to that form step. + +```yaml +apiVersion: scaffolder.backstage.io/v1beta3 +kind: Template +metadata: + name: v1beta3-demo + title: Microservice example + description: scaffolder v1beta3 template demo +spec: + owner: backstage/techdocs-core + type: service + parameters: + - title: Specify a host + parameters: + name: + title: Hostname + type: string + description: Specify host name +``` + +Our placeholder is going to be called `$specifyHostname`. We'd use it like this, + +```yaml +apiVersion: scaffolder.backstage.io/v1beta3 +kind: Template +metadata: + name: v1beta3-demo + title: Microservice example + description: scaffolder v1beta3 template demo +spec: + owner: backstage/techdocs-core + type: service + parameters: + - $specifyHostname: + domainExt: + name: Domain extension + type: string + description: Specify domain extension like .com, .ca, .co.uk or something else. +``` + +The result after the placeholder is applied will look like this, + +```yaml +apiVersion: scaffolder.backstage.io/v1beta3 +kind: Template +metadata: + name: v1beta3-demo + title: Microservice example + description: scaffolder v1beta3 template demo +spec: + owner: backstage/techdocs-core + type: service + parameters: + - title: Specify a host + parameters: + name: + title: Hostname + type: string + description: Specify host name + domainExt: + name: Domain extension + type: string + description: Specify domain extension like .com, .ca, .co.uk or something else. +``` + +To implement this, you have to modify the catalog plugin to create a `specifyHostname` resolver. In `/packages/backend/src/plugins/catalog.ts`. Add the following code, + +```ts +const builder = await CatalogBuilder.create(env); + +builder.setPlaceholderResolver( + 'specifyHostname', + async specifyHostnameResolver({ value }) => { + return { + "title": "Specify a host", + "parameters": { + "name": { + "title": "Hostname", + "type": "string", + "description": "Specify host name" + }, + ...value + } + } + }, + );` +``` From b87a88776d168dc039957ca32adda8ecd9f54b80 Mon Sep 17 00:00:00 2001 From: Matthew Clarke Date: Thu, 15 Sep 2022 21:59:57 -0400 Subject: [PATCH 052/185] (feat): kubernetes add new backend endpoints to api interface Signed-off-by: Matthew Clarke --- .../src/service/KubernetesFanOutHandler.ts | 2 +- plugins/kubernetes-backend/src/types/types.ts | 7 +---- plugins/kubernetes-common/src/types.ts | 7 +++++ .../src/api/KubernetesBackendClient.ts | 30 ++++++++++++++++--- plugins/kubernetes/src/api/types.ts | 12 ++++++++ 5 files changed, 47 insertions(+), 11 deletions(-) diff --git a/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.ts b/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.ts index 7fcc9836a3..23163d1004 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.ts @@ -25,7 +25,6 @@ import { FetchResponseWrapper, ObjectToFetch, CustomResource, - CustomResourceMatcher, CustomResourcesByEntity, KubernetesObjectsByEntity, } from '../types/types'; @@ -40,6 +39,7 @@ import { ObjectsByEntityResponse, PodFetchResponse, KubernetesRequestAuth, + CustomResourceMatcher, } from '@backstage/plugin-kubernetes-common'; import { ContainerStatus, diff --git a/plugins/kubernetes-backend/src/types/types.ts b/plugins/kubernetes-backend/src/types/types.ts index 33fde70b24..5ddfe7367d 100644 --- a/plugins/kubernetes-backend/src/types/types.ts +++ b/plugins/kubernetes-backend/src/types/types.ts @@ -18,6 +18,7 @@ import { Entity } from '@backstage/catalog-model'; import { Logger } from 'winston'; import type { JsonObject } from '@backstage/types'; import type { + CustomResourceMatcher, FetchResponse, KubernetesFetchError, KubernetesRequestAuth, @@ -86,12 +87,6 @@ export interface CustomResource extends ObjectToFetch { objectType: 'customresources'; } -/** - * - * @alpha - */ -export type CustomResourceMatcher = Omit; - /** * * @alpha diff --git a/plugins/kubernetes-common/src/types.ts b/plugins/kubernetes-common/src/types.ts index 830c32c32c..07378ae688 100644 --- a/plugins/kubernetes-common/src/types.ts +++ b/plugins/kubernetes-common/src/types.ts @@ -39,6 +39,13 @@ export interface KubernetesRequestAuth { }; } +/** @public */ +export interface CustomResourceMatcher { + group: string; + apiVersion: string; + plural: string; +} + /** @public */ export interface KubernetesRequestBody { auth?: KubernetesRequestAuth; diff --git a/plugins/kubernetes/src/api/KubernetesBackendClient.ts b/plugins/kubernetes/src/api/KubernetesBackendClient.ts index 209f5f950d..04f4624b24 100644 --- a/plugins/kubernetes/src/api/KubernetesBackendClient.ts +++ b/plugins/kubernetes/src/api/KubernetesBackendClient.ts @@ -16,10 +16,13 @@ import { KubernetesApi } from './types'; import { + KubernetesRequestAuth, KubernetesRequestBody, ObjectsByEntityResponse, + CustomResourceMatcher, } from '@backstage/plugin-kubernetes-common'; import { DiscoveryApi, IdentityApi } from '@backstage/core-plugin-api'; +import { Entity, stringifyEntityRef } from '@backstage/catalog-model'; export class KubernetesBackendClient implements KubernetesApi { private readonly discoveryApi: DiscoveryApi; @@ -51,10 +54,7 @@ export class KubernetesBackendClient implements KubernetesApi { return await response.json(); } - private async postRequired( - path: string, - requestBody: KubernetesRequestBody, - ): Promise { + private async postRequired(path: string, requestBody: any): Promise { const url = `${await this.discoveryApi.getBaseUrl('kubernetes')}${path}`; const { token: idToken } = await this.identityApi.getCredentials(); const response = await fetch(url, { @@ -78,6 +78,28 @@ export class KubernetesBackendClient implements KubernetesApi { ); } + async getWorkloadsByEntity( + auth: KubernetesRequestAuth, + entity: Entity, + ): Promise { + return await this.postRequired('/resources/workloads/query', { + auth, + entityRef: stringifyEntityRef(entity), + }); + } + + async getCustomObjectsByEntity( + auth: KubernetesRequestAuth, + customResources: CustomResourceMatcher[], + entity: Entity, + ): Promise { + return await this.postRequired(`/resources/custom/query`, { + entityRef: stringifyEntityRef(entity), + auth, + customResources, + }); + } + async getClusters(): Promise<{ name: string; authProvider: string }[]> { const { token: idToken } = await this.identityApi.getCredentials(); const url = `${await this.discoveryApi.getBaseUrl('kubernetes')}/clusters`; diff --git a/plugins/kubernetes/src/api/types.ts b/plugins/kubernetes/src/api/types.ts index 7c5943a6eb..b7e3f9fd49 100644 --- a/plugins/kubernetes/src/api/types.ts +++ b/plugins/kubernetes/src/api/types.ts @@ -15,10 +15,13 @@ */ import { + KubernetesRequestAuth, KubernetesRequestBody, ObjectsByEntityResponse, + CustomResourceMatcher, } from '@backstage/plugin-kubernetes-common'; import { createApiRef } from '@backstage/core-plugin-api'; +import { Entity } from '@backstage/catalog-model'; export const kubernetesApiRef = createApiRef({ id: 'plugin.kubernetes.service', @@ -35,4 +38,13 @@ export interface KubernetesApi { oidcTokenProvider?: string | undefined; }[] >; + getWorkloadsByEntity( + auth: KubernetesRequestAuth, + entity: Entity, + ): Promise; + getCustomObjectsByEntity( + auth: KubernetesRequestAuth, + customResources: CustomResourceMatcher[], + entity: Entity, + ): Promise; } From 29dd35cdcb9d504f7c744804e7be5e777e7f1424 Mon Sep 17 00:00:00 2001 From: Matthew Clarke Date: Thu, 15 Sep 2022 22:03:09 -0400 Subject: [PATCH 053/185] update api report Signed-off-by: Matthew Clarke --- plugins/kubernetes-backend/api-report.md | 4 +--- plugins/kubernetes-common/api-report.md | 10 ++++++++++ plugins/kubernetes/api-report.md | 24 ++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/plugins/kubernetes-backend/api-report.md b/plugins/kubernetes-backend/api-report.md index f97a0fd032..4219387819 100644 --- a/plugins/kubernetes-backend/api-report.md +++ b/plugins/kubernetes-backend/api-report.md @@ -8,6 +8,7 @@ import { Config } from '@backstage/config'; import { CoreV1Api } from '@kubernetes/client-node'; import { Credentials } from 'aws-sdk'; import { CustomObjectsApi } from '@kubernetes/client-node'; +import type { CustomResourceMatcher } from '@backstage/plugin-kubernetes-common'; import { Duration } from 'luxon'; import { Entity } from '@backstage/catalog-model'; import express from 'express'; @@ -101,9 +102,6 @@ export interface CustomResource extends ObjectToFetch { objectType: 'customresources'; } -// @alpha (undocumented) -export type CustomResourceMatcher = Omit; - // @alpha (undocumented) export interface CustomResourcesByEntity extends KubernetesObjectsByEntity { // (undocumented) diff --git a/plugins/kubernetes-common/api-report.md b/plugins/kubernetes-common/api-report.md index ef36d5ce28..9485bd0294 100644 --- a/plugins/kubernetes-common/api-report.md +++ b/plugins/kubernetes-common/api-report.md @@ -97,6 +97,16 @@ export interface CustomResourceFetchResponse { type: 'customresources'; } +// @public (undocumented) +export interface CustomResourceMatcher { + // (undocumented) + apiVersion: string; + // (undocumented) + group: string; + // (undocumented) + plural: string; +} + // @public (undocumented) export interface DaemonSetsFetchResponse { // (undocumented) diff --git a/plugins/kubernetes/api-report.md b/plugins/kubernetes/api-report.md index 81ce386200..98ca4e4725 100644 --- a/plugins/kubernetes/api-report.md +++ b/plugins/kubernetes/api-report.md @@ -10,10 +10,12 @@ import { BackstagePlugin } from '@backstage/core-plugin-api'; import { ClientPodStatus } from '@backstage/plugin-kubernetes-common'; import { ClusterAttributes } from '@backstage/plugin-kubernetes-common'; import { ClusterObjects } from '@backstage/plugin-kubernetes-common'; +import { CustomResourceMatcher } from '@backstage/plugin-kubernetes-common'; import { DiscoveryApi } from '@backstage/core-plugin-api'; import { Entity } from '@backstage/catalog-model'; import { IdentityApi } from '@backstage/core-plugin-api'; import type { JsonObject } from '@backstage/types'; +import { KubernetesRequestAuth } from '@backstage/plugin-kubernetes-common'; import { KubernetesRequestBody } from '@backstage/plugin-kubernetes-common'; import { OAuthApi } from '@backstage/core-plugin-api'; import { ObjectsByEntityResponse } from '@backstage/plugin-kubernetes-common'; @@ -245,9 +247,20 @@ export interface KubernetesApi { }[] >; // (undocumented) + getCustomObjectsByEntity( + auth: KubernetesRequestAuth, + customResources: CustomResourceMatcher[], + entity: Entity, + ): Promise; + // (undocumented) getObjectsByEntity( requestBody: KubernetesRequestBody, ): Promise; + // (undocumented) + getWorkloadsByEntity( + auth: KubernetesRequestAuth, + entity: Entity, + ): Promise; } // Warning: (ae-missing-release-tag) "kubernetesApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -304,9 +317,20 @@ export class KubernetesBackendClient implements KubernetesApi { }[] >; // (undocumented) + getCustomObjectsByEntity( + auth: KubernetesRequestAuth, + customResources: CustomResourceMatcher[], + entity: Entity, + ): Promise; + // (undocumented) getObjectsByEntity( requestBody: KubernetesRequestBody, ): Promise; + // (undocumented) + getWorkloadsByEntity( + auth: KubernetesRequestAuth, + entity: Entity, + ): Promise; } // Warning: (ae-forgotten-export) The symbol "KubernetesContentProps" needs to be exported by the entry point index.d.ts From 0768d6dece0706b37218a2e08058bf7dd0a8f693 Mon Sep 17 00:00:00 2001 From: Matthew Clarke Date: Thu, 15 Sep 2022 22:04:31 -0400 Subject: [PATCH 054/185] changeset Signed-off-by: Matthew Clarke --- .changeset/poor-lobsters-wonder.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changeset/poor-lobsters-wonder.md diff --git a/.changeset/poor-lobsters-wonder.md b/.changeset/poor-lobsters-wonder.md new file mode 100644 index 0000000000..c0adea235f --- /dev/null +++ b/.changeset/poor-lobsters-wonder.md @@ -0,0 +1,7 @@ +--- +'@backstage/plugin-kubernetes': patch +'@backstage/plugin-kubernetes-backend': patch +'@backstage/plugin-kubernetes-common': patch +--- + +add new kubernetes backend endpoints to kubernetes backend client From 3da0c9a1812a92e6d0948a88e8c2306097561574 Mon Sep 17 00:00:00 2001 From: Matthew Clarke Date: Thu, 15 Sep 2022 22:10:42 -0400 Subject: [PATCH 055/185] update mock Signed-off-by: Matthew Clarke --- plugins/kubernetes/dev/index.tsx | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/plugins/kubernetes/dev/index.tsx b/plugins/kubernetes/dev/index.tsx index 068f26b7f5..6a02540604 100644 --- a/plugins/kubernetes/dev/index.tsx +++ b/plugins/kubernetes/dev/index.tsx @@ -24,7 +24,9 @@ import { KubernetesApi, } from '../src'; import { + CustomResourceMatcher, FetchResponse, + KubernetesRequestAuth, ObjectsByEntityResponse, } from '@backstage/plugin-kubernetes-common'; import fixture1 from '../src/__fixtures__/1-deployments.json'; @@ -59,6 +61,19 @@ class MockKubernetesClient implements KubernetesApi { ({ type: type.toLocaleLowerCase('en-US'), resources } as FetchResponse), ); } + async getWorkloadsByEntity( + _auth: KubernetesRequestAuth, + _entity: Entity, + ): Promise { + throw new Error('Method not implemented.'); + } + async getCustomObjectsByEntity( + _auth: KubernetesRequestAuth, + _customResources: CustomResourceMatcher[], + entity: Entity, + ): Promise { + throw new Error('Method not implemented.'); + } async getObjectsByEntity(): Promise { return { From 5eb54be2ac56af8765e18def149cefe09f0f920e Mon Sep 17 00:00:00 2001 From: Matthew Clarke Date: Thu, 15 Sep 2022 22:15:26 -0400 Subject: [PATCH 056/185] typo Signed-off-by: Matthew Clarke --- plugins/kubernetes/dev/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/kubernetes/dev/index.tsx b/plugins/kubernetes/dev/index.tsx index 6a02540604..3dd0557ae1 100644 --- a/plugins/kubernetes/dev/index.tsx +++ b/plugins/kubernetes/dev/index.tsx @@ -70,7 +70,7 @@ class MockKubernetesClient implements KubernetesApi { async getCustomObjectsByEntity( _auth: KubernetesRequestAuth, _customResources: CustomResourceMatcher[], - entity: Entity, + _entity: Entity, ): Promise { throw new Error('Method not implemented.'); } From 04c50e297d8a0e4fb0ad78fe9f5912ce1794f543 Mon Sep 17 00:00:00 2001 From: Marcus Eide Date: Fri, 16 Sep 2022 09:57:44 +0200 Subject: [PATCH 057/185] Resolve cookie configuration per request Signed-off-by: Marcus Eide --- .changeset/kind-penguins-report.md | 4 +- plugins/auth-backend/api-report.md | 1 - .../src/lib/oauth/OAuthAdapter.test.ts | 164 ++++++++++++++++-- .../src/lib/oauth/OAuthAdapter.ts | 74 ++++---- 4 files changed, 200 insertions(+), 43 deletions(-) diff --git a/.changeset/kind-penguins-report.md b/.changeset/kind-penguins-report.md index 9f2401491e..4023ea5976 100644 --- a/.changeset/kind-penguins-report.md +++ b/.changeset/kind-penguins-report.md @@ -5,4 +5,6 @@ CookieConfigurer can optionally return the `SameSite` cookie attribute. CookieConfigurer now requires an additional argument `appOrigin` - the origin URL of the app - which is used to calculate the `SameSite` attribute. defaultCookieConfigurer returns the `SameSite` attribute which defaults to `Lax`. In cases where an auth-backend is running on a different domain than the App, `SameSite=None` is used - but only for secure contexts. This is so that cookies can be included in third-party requests. -OAuthAdapterOptions has been modified to require additional arguments, `baseUrl`, `cookieConfigurer` and `cookieConfig`. + +OAuthAdapterOptions has been modified to require additional arguments, `baseUrl`, and `cookieConfigurer`. +OAuthAdapter now resolves cookie configuration using its supplied CookieConfigurer for each request to make sure that the proper attributes always are set. diff --git a/plugins/auth-backend/api-report.md b/plugins/auth-backend/api-report.md index 8cb7e35e9b..f4e8415266 100644 --- a/plugins/auth-backend/api-report.md +++ b/plugins/auth-backend/api-report.md @@ -285,7 +285,6 @@ export type OAuthAdapterOptions = { persistScopes?: boolean; appOrigin: string; baseUrl: string; - cookieConfig: ReturnType; cookieConfigurer: CookieConfigurer; isOriginAllowed: (origin: string) => boolean; callbackUrl: string; diff --git a/plugins/auth-backend/src/lib/oauth/OAuthAdapter.test.ts b/plugins/auth-backend/src/lib/oauth/OAuthAdapter.test.ts index d59a712205..6521519808 100644 --- a/plugins/auth-backend/src/lib/oauth/OAuthAdapter.test.ts +++ b/plugins/auth-backend/src/lib/oauth/OAuthAdapter.test.ts @@ -63,7 +63,7 @@ describe('OAuthAdapter', () => { } const providerInstance = new MyAuthProvider(); const mockCookieConfig: ReturnType = { - domain: 'example.com', + domain: 'domain.org', path: '/auth/test-provider', secure: false, }; @@ -72,15 +72,14 @@ describe('OAuthAdapter', () => { const oAuthProviderOptions = { providerId: 'test-provider', appOrigin: 'http://localhost:3000', - cookieConfig: mockCookieConfig, + baseUrl: 'http://domain.org/auth', cookieConfigurer: mockCookieConfigurer, - baseUrl: 'http://example.com:7007', tokenIssuer: { issueToken: async () => 'my-id-token', listPublicKeys: async () => ({ keys: [] }), }, isOriginAllowed: () => false, - callbackUrl: 'http://example.com:7007/auth/test-provider/frame/handler', + callbackUrl: 'http://domain.org/auth/test-provider/handler/frame', }; it('sets the correct headers in start', async () => { @@ -108,7 +107,14 @@ describe('OAuthAdapter', () => { expect(mockResponse.cookie).toHaveBeenCalledWith( `${oAuthProviderOptions.providerId}-nonce`, expect.any(String), - expect.objectContaining({ maxAge: TEN_MINUTES_MS }), + expect.objectContaining({ + httpOnly: true, + path: '/auth/test-provider/handler', + maxAge: TEN_MINUTES_MS, + domain: 'domain.org', + sameSite: 'lax', + secure: false, + }), ); // redirect checks expect(mockResponse.setHeader).toHaveBeenCalledTimes(2); @@ -150,6 +156,7 @@ describe('OAuthAdapter', () => { httpOnly: true, path: '/auth/test-provider', maxAge: THOUSAND_DAYS_MS, + domain: 'domain.org', secure: false, sameSite: 'lax', }), @@ -218,14 +225,17 @@ describe('OAuthAdapter', () => { } as unknown as express.Response; await oauthProvider.frameHandler(mockHandleReq, mockHandleRes); - expect(mockCookieConfigurer).toHaveBeenCalledTimes(1); expect(mockHandleRes.cookie).toHaveBeenCalledTimes(1); expect(mockHandleRes.cookie).toHaveBeenCalledWith( 'test-provider-granted-scope', 'user', expect.objectContaining({ + httpOnly: true, path: '/auth/test-provider', maxAge: THOUSAND_DAYS_MS, + domain: 'domain.org', + secure: false, + sameSite: 'lax', }), ); @@ -260,6 +270,7 @@ describe('OAuthAdapter', () => { const mockRequest = { header: () => 'XMLHttpRequest', + get: jest.fn(), } as unknown as express.Request; const mockResponse = { @@ -269,6 +280,7 @@ describe('OAuthAdapter', () => { } as unknown as express.Response; await oauthProvider.logout(mockRequest, mockResponse); + expect(mockRequest.get).toHaveBeenCalledTimes(1); expect(mockResponse.cookie).toHaveBeenCalledTimes(1); expect(mockResponse.cookie).toHaveBeenCalledWith( expect.stringContaining('test-provider-refresh-token'), @@ -312,7 +324,46 @@ describe('OAuthAdapter', () => { }); }); - it('sets the correct cookie configuration using an unsecure callbackUrl', async () => { + it('sets new access-token when old cookie exists', async () => { + const oauthProvider = new OAuthAdapter(providerInstance, { + ...oAuthProviderOptions, + isOriginAllowed: () => false, + }); + + const mockRequest = { + header: () => 'XMLHttpRequest', + cookies: { + 'test-provider-refresh-token': 'old-token', + }, + query: {}, + get: jest.fn(), + } as unknown as express.Request; + + const mockResponse = { + json: jest.fn().mockReturnThis(), + status: jest.fn().mockReturnThis(), + cookie: jest.fn().mockReturnThis(), + } as unknown as express.Response; + + await oauthProvider.refresh(mockRequest, mockResponse); + expect(mockRequest.get).toHaveBeenCalledTimes(1); + expect(mockCookieConfigurer).toHaveBeenCalledTimes(1); + expect(mockResponse.cookie).toHaveBeenCalledTimes(1); + expect(mockResponse.cookie).toHaveBeenCalledWith( + 'test-provider-refresh-token', + 'token', + expect.objectContaining({ + httpOnly: true, + path: '/auth/test-provider', + maxAge: THOUSAND_DAYS_MS, + domain: 'domain.org', + secure: false, + sameSite: 'lax', + }), + ); + }); + + it('sets the correct nonce cookie configuration', async () => { const config = { baseUrl: 'http://domain.org/auth', appUrl: 'http://domain.org', @@ -321,7 +372,6 @@ describe('OAuthAdapter', () => { const oauthProvider = OAuthAdapter.fromConfig(config, providerInstance, { ...oAuthProviderOptions, - callbackUrl: 'http://authdomain.org/auth/test-provider/handler/frame', }); const mockRequest = { @@ -346,7 +396,8 @@ describe('OAuthAdapter', () => { expect.any(String), expect.objectContaining({ httpOnly: true, - domain: 'authdomain.org', + domain: 'domain.org', + maxAge: TEN_MINUTES_MS, path: '/auth/test-provider/handler', secure: false, sameSite: 'lax', @@ -361,6 +412,54 @@ describe('OAuthAdapter', () => { isOriginAllowed: () => false, }; + const oauthProvider = OAuthAdapter.fromConfig(config, providerInstance, { + ...oAuthProviderOptions, + callbackUrl: 'https://domain.org/auth/test-provider/handler/frame', + }); + + const state = { + nonce: 'nonce', + env: 'development', + }; + + const mockRequest = { + cookies: { + 'test-provider-nonce': 'nonce', + }, + query: { + state: encodeState(state), + }, + } as unknown as express.Request; + + const mockResponse = { + cookie: jest.fn().mockReturnThis(), + setHeader: jest.fn().mockReturnThis(), + end: jest.fn().mockReturnThis(), + } as unknown as express.Response; + + await oauthProvider.frameHandler(mockRequest, mockResponse); + expect(mockCookieConfigurer).not.toHaveBeenCalled(); + expect(mockResponse.cookie).toHaveBeenCalledTimes(1); + expect(mockResponse.cookie).toHaveBeenCalledWith( + expect.stringContaining('test-provider-refresh-token'), + expect.stringContaining('token'), + expect.objectContaining({ + httpOnly: true, + domain: 'domain.org', + path: '/auth/test-provider', + secure: true, + sameSite: 'lax', + }), + ); + }); + + it('sets the correct cookie configuration when on different domains and secure', async () => { + const config = { + baseUrl: 'https://domain.org/auth', + appUrl: 'http://domain.org', + isOriginAllowed: () => false, + }; + const oauthProvider = OAuthAdapter.fromConfig(config, providerInstance, { ...oAuthProviderOptions, callbackUrl: 'https://authdomain.org/auth/test-provider/handler/frame', @@ -402,7 +501,7 @@ describe('OAuthAdapter', () => { ); }); - it('sets the correct cookie configuration using state', async () => { + it('sets the correct cookie configuration using origin from state', async () => { const config = { baseUrl: 'https://domain.org/auth', appUrl: 'http://domain.org', @@ -450,4 +549,49 @@ describe('OAuthAdapter', () => { }), ); }); + + it('sets the correct cookie configuration using origin from header', async () => { + const config = { + baseUrl: 'https://domain.org/auth', + appUrl: 'http://domain.org', + isOriginAllowed: () => false, + }; + + const oauthProvider = OAuthAdapter.fromConfig(config, providerInstance, { + ...oAuthProviderOptions, + callbackUrl: 'https://domain.org/auth/test-provider/handler/frame', + }); + + const mockRequest = { + header: () => 'XMLHttpRequest', + cookies: { + 'test-provider-refresh-token': 'old-token', + }, + query: {}, + get: jest.fn().mockReturnValue('http://other.domain'), + } as unknown as express.Request; + + const mockResponse = { + json: jest.fn().mockReturnThis(), + status: jest.fn().mockReturnThis(), + cookie: jest.fn().mockReturnThis(), + } as unknown as express.Response; + + await oauthProvider.refresh(mockRequest, mockResponse); + expect(mockRequest.get).toHaveBeenCalledTimes(1); + expect(mockCookieConfigurer).not.toHaveBeenCalled(); + expect(mockResponse.cookie).toHaveBeenCalledTimes(1); + expect(mockResponse.cookie).toHaveBeenCalledWith( + 'test-provider-refresh-token', + 'token', + expect.objectContaining({ + httpOnly: true, + path: '/auth/test-provider', + maxAge: THOUSAND_DAYS_MS, + domain: 'domain.org', + secure: true, + sameSite: 'none', + }), + ); + }); }); diff --git a/plugins/auth-backend/src/lib/oauth/OAuthAdapter.ts b/plugins/auth-backend/src/lib/oauth/OAuthAdapter.ts index 64dc4f70e3..43fcc5e20b 100644 --- a/plugins/auth-backend/src/lib/oauth/OAuthAdapter.ts +++ b/plugins/auth-backend/src/lib/oauth/OAuthAdapter.ts @@ -51,7 +51,6 @@ export type OAuthAdapterOptions = { persistScopes?: boolean; appOrigin: string; baseUrl: string; - cookieConfig: ReturnType; cookieConfigurer: CookieConfigurer; isOriginAllowed: (origin: string) => boolean; callbackUrl: string; @@ -71,24 +70,17 @@ export class OAuthAdapter implements AuthProviderRouteHandlers { const { origin: appOrigin } = new URL(appUrl); const cookieConfigurer = config.cookieConfigurer ?? defaultCookieConfigurer; - const cookieConfig = cookieConfigurer({ - providerId: options.providerId, - baseUrl: config.baseUrl, - callbackUrl: options.callbackUrl, - appOrigin, - }); return new OAuthAdapter(handlers, { ...options, appOrigin, baseUrl, - cookieConfig, cookieConfigurer, isOriginAllowed, }); } - private baseCookieOptions: CookieOptions; + private readonly baseCookieOptions: CookieOptions; constructor( private readonly handlers: OAuthHandlers, @@ -97,7 +89,6 @@ export class OAuthAdapter implements AuthProviderRouteHandlers { this.baseCookieOptions = { httpOnly: true, sameSite: 'lax', - ...this.options.cookieConfig, }; } @@ -111,9 +102,11 @@ export class OAuthAdapter implements AuthProviderRouteHandlers { throw new InputError('No env provided in request query parameters'); } + const cookieConfig = this.getCookieConfig(); + const nonce = crypto.randomBytes(16).toString('base64'); // set a nonce cookie before redirecting to oauth provider - this.setNonceCookie(res, nonce); + this.setNonceCookie(res, nonce, cookieConfig); const state: OAuthState = { nonce, env, origin }; @@ -154,33 +147,23 @@ export class OAuthAdapter implements AuthProviderRouteHandlers { } } - // Update cookie options to reflect any changes for the appOrigin - const updatedCookieOptions = this.options.cookieConfigurer({ - providerId: this.options.providerId, - baseUrl: this.options.baseUrl, - callbackUrl: this.options.callbackUrl, - appOrigin, - }); - this.baseCookieOptions = { - ...this.baseCookieOptions, - ...updatedCookieOptions, - }; - // verify nonce cookie and state cookie on callback verifyNonce(req, this.options.providerId); const { response, refreshToken } = await this.handlers.handler(req); + const cookieConfig = this.getCookieConfig(appOrigin); + // Store the scope that we have been granted for this session. This is useful if // the provider does not return granted scopes on refresh or if they are normalized. if (this.options.persistScopes && state.scope) { - this.setGrantedScopeCookie(res, state.scope); + this.setGrantedScopeCookie(res, state.scope, cookieConfig); response.providerInfo.scope = state.scope; } if (refreshToken) { // set new refresh token - this.setRefreshTokenCookie(res, refreshToken); + this.setRefreshTokenCookie(res, refreshToken, cookieConfig); } const identity = await this.populateIdentity(response.backstageIdentity); @@ -208,7 +191,9 @@ export class OAuthAdapter implements AuthProviderRouteHandlers { } // remove refresh token cookie if it is set - this.removeRefreshTokenCookie(res); + const origin = req.get('origin'); + const cookieConfig = this.getCookieConfig(origin); + this.removeRefreshTokenCookie(res, cookieConfig); res.status(200).end(); } @@ -248,7 +233,9 @@ export class OAuthAdapter implements AuthProviderRouteHandlers { ); if (newRefreshToken && newRefreshToken !== refreshToken) { - this.setRefreshTokenCookie(res, newRefreshToken); + const origin = req.get('origin'); + const cookieConfig = this.getCookieConfig(origin); + this.setRefreshTokenCookie(res, newRefreshToken, cookieConfig); } res.status(200).json({ ...response, backstageIdentity }); @@ -274,18 +261,28 @@ export class OAuthAdapter implements AuthProviderRouteHandlers { return prepareBackstageIdentityResponse(identity); } - private setNonceCookie = (res: express.Response, nonce: string) => { + private setNonceCookie = ( + res: express.Response, + nonce: string, + cookieConfig: ReturnType, + ) => { res.cookie(`${this.options.providerId}-nonce`, nonce, { maxAge: TEN_MINUTES_MS, ...this.baseCookieOptions, - path: `${this.options.cookieConfig.path}/handler`, + ...cookieConfig, + path: `${cookieConfig.path}/handler`, }); }; - private setGrantedScopeCookie = (res: express.Response, scope: string) => { + private setGrantedScopeCookie = ( + res: express.Response, + scope: string, + cookieConfig: ReturnType, + ) => { res.cookie(`${this.options.providerId}-granted-scope`, scope, { maxAge: THOUSAND_DAYS_MS, ...this.baseCookieOptions, + ...cookieConfig, }); }; @@ -296,17 +293,32 @@ export class OAuthAdapter implements AuthProviderRouteHandlers { private setRefreshTokenCookie = ( res: express.Response, refreshToken: string, + cookieConfig: ReturnType, ) => { res.cookie(`${this.options.providerId}-refresh-token`, refreshToken, { maxAge: THOUSAND_DAYS_MS, ...this.baseCookieOptions, + ...cookieConfig, }); }; - private removeRefreshTokenCookie = (res: express.Response) => { + private removeRefreshTokenCookie = ( + res: express.Response, + cookieConfig: ReturnType, + ) => { res.cookie(`${this.options.providerId}-refresh-token`, '', { maxAge: 0, ...this.baseCookieOptions, + ...cookieConfig, + }); + }; + + private getCookieConfig = (origin?: string) => { + return this.options.cookieConfigurer({ + providerId: this.options.providerId, + baseUrl: this.options.baseUrl, + callbackUrl: this.options.callbackUrl, + appOrigin: origin ?? this.options.appOrigin, }); }; } From e55d855a6ba1e754e7c99e8bd405428696c2c06d Mon Sep 17 00:00:00 2001 From: Tim Jacomb Date: Fri, 16 Sep 2022 09:40:25 +0100 Subject: [PATCH 058/185] Fix Jenkins plugin not working at all Signed-off-by: Tim Jacomb --- .changeset/stale-paws-dance.md | 5 +++++ plugins/jenkins-backend/src/service/jenkinsApi.ts | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 .changeset/stale-paws-dance.md diff --git a/.changeset/stale-paws-dance.md b/.changeset/stale-paws-dance.md new file mode 100644 index 0000000000..2745faea1c --- /dev/null +++ b/.changeset/stale-paws-dance.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-jenkins-backend': patch +--- + +Jenkins plugin works again diff --git a/plugins/jenkins-backend/src/service/jenkinsApi.ts b/plugins/jenkins-backend/src/service/jenkinsApi.ts index ae2fa0f7b5..18a79a2ffe 100644 --- a/plugins/jenkins-backend/src/service/jenkinsApi.ts +++ b/plugins/jenkins-backend/src/service/jenkinsApi.ts @@ -15,7 +15,7 @@ */ import type { JenkinsInfo } from './jenkinsInfoProvider'; -import jenkins from 'jenkins'; +import Jenkins from 'jenkins'; import type { BackstageBuild, BackstageProject, @@ -177,12 +177,12 @@ export class JenkinsApiImpl { private static async getClient(jenkinsInfo: JenkinsInfo) { // The typings for the jenkins library are out of date so just cast to any - return jenkins({ + return new (Jenkins as any)({ baseUrl: jenkinsInfo.baseUrl, headers: jenkinsInfo.headers, promisify: true, crumbIssuer: jenkinsInfo.crumbIssuer, - }) as any; + }); } private augmentProject(project: JenkinsProject): BackstageProject { From a966ed8385324dde95de2a17041bee046ebb7e6e Mon Sep 17 00:00:00 2001 From: Tim Jacomb Date: Fri, 16 Sep 2022 10:47:29 +0100 Subject: [PATCH 059/185] Unwrap error message when getting projects in Jenkins plugin Signed-off-by: Tim Jacomb --- .changeset/ninety-knives-knock.md | 5 +++++ .../jenkins-backend/src/service/jenkinsApi.ts | 2 +- plugins/jenkins-backend/src/service/router.ts | 20 +++++++++++++++---- 3 files changed, 22 insertions(+), 5 deletions(-) create mode 100644 .changeset/ninety-knives-knock.md diff --git a/.changeset/ninety-knives-knock.md b/.changeset/ninety-knives-knock.md new file mode 100644 index 0000000000..19797e472c --- /dev/null +++ b/.changeset/ninety-knives-knock.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-jenkins-backend': patch +--- + +Unwrap error message when getting projects diff --git a/plugins/jenkins-backend/src/service/jenkinsApi.ts b/plugins/jenkins-backend/src/service/jenkinsApi.ts index ae2fa0f7b5..37aaf0ac3b 100644 --- a/plugins/jenkins-backend/src/service/jenkinsApi.ts +++ b/plugins/jenkins-backend/src/service/jenkinsApi.ts @@ -100,7 +100,7 @@ export class JenkinsApiImpl { // Filter only be the information we need, instead of loading all fields. // Limit to only show the latest build for each job and only load 50 jobs // at all. - // Whitespaces are only included for readablity here and stripped out + // Whitespaces are only included for readability here and stripped out // before sending to Jenkins tree: JenkinsApiImpl.jobsTreeSpec.replace(/\s/g, ''), }); diff --git a/plugins/jenkins-backend/src/service/router.ts b/plugins/jenkins-backend/src/service/router.ts index bc0e978396..395efffb9c 100644 --- a/plugins/jenkins-backend/src/service/router.ts +++ b/plugins/jenkins-backend/src/service/router.ts @@ -27,6 +27,7 @@ import { } from '@backstage/plugin-permission-common'; import { getBearerTokenFromAuthorizationHeader } from '@backstage/plugin-auth-node'; import { stringifyEntityRef } from '@backstage/catalog-model'; +import { stringifyError } from "@backstage/errors"; /** @public */ export interface RouterOptions { @@ -90,11 +91,22 @@ export async function createRouter( }, backstageToken: token, }); - const projects = await jenkinsApi.getProjects(jenkinsInfo, branches); - response.json({ - projects: projects, - }); + + try { + const projects = await jenkinsApi.getProjects(jenkinsInfo, branches); + + response.json({ + projects: projects, + }); + } catch (err) { + // Promise.any, used in the getProjects call returns an Aggregate error message with a useless error message 'AggregateError: All promises were rejected' + // extract useful information ourselves + if (err.errors) { + throw new Error(`Unable to fetch projects, for ${jenkinsInfo.jobFullName}: ${stringifyError(err.errors)}`) + } + throw err + } }, ); From d3737da3377da376b0b82c9d884cc656f5455292 Mon Sep 17 00:00:00 2001 From: Phil Kuang Date: Sat, 2 Jul 2022 00:00:52 -0400 Subject: [PATCH 060/185] feat(playlists): implement playlist plugin Signed-off-by: Phil Kuang --- .changeset/calm-snakes-tap.md | 5 + .changeset/nice-ducks-smile.md | 7 + .changeset/purple-chicken-kneel.md | 5 + app-config.yaml | 3 + microsite/data/plugins/playlist.yaml | 9 + microsite/static/img/playlist-logo.png | Bin 0 -> 14734 bytes packages/app/package.json | 1 + packages/app/src/App.tsx | 2 + packages/app/src/components/Root/Root.tsx | 2 + .../app/src/components/catalog/EntityPage.tsx | 12 + packages/backend/package.json | 1 + packages/backend/src/index.ts | 3 + packages/backend/src/plugins/permission.ts | 25 +- packages/backend/src/plugins/playlist.ts | 37 ++ packages/backend/src/types.ts | 7 +- packages/core-components/api-report.md | 27 + .../src/components/Table/Table.tsx | 5 + .../HeaderActionMenu/HeaderActionMenu.tsx | 15 +- .../src/layout/HeaderActionMenu/index.ts | 4 + packages/core-components/src/layout/index.ts | 1 + plugins/playlist-backend/.eslintrc.js | 1 + plugins/playlist-backend/README.md | 93 ++++ plugins/playlist-backend/api-report.md | 93 ++++ .../migrations/20220701011329_init.js | 60 ++ plugins/playlist-backend/package.json | 52 ++ plugins/playlist-backend/src/index.ts | 28 + .../DefaultPlaylistPermissionPolicy.test.ts | 135 +++++ .../DefaultPlaylistPermissionPolicy.ts | 90 +++ .../src/permissions/conditions.ts | 44 ++ .../playlist-backend/src/permissions/index.ts | 19 + .../playlist-backend/src/permissions/rules.ts | 54 ++ plugins/playlist-backend/src/run.ts | 33 ++ .../src/service/DatabaseHandler.test.ts | 349 ++++++++++++ .../src/service/DatabaseHandler.ts | 278 ++++++++++ .../src/service/ListPlaylistsFilter.test.ts | 95 ++++ .../src/service/ListPlaylistsFilter.ts | 101 ++++ plugins/playlist-backend/src/service/index.ts | 21 + .../src/service/router.test.ts | 511 ++++++++++++++++++ .../playlist-backend/src/service/router.ts | 232 ++++++++ .../src/service/standaloneServer.ts | 90 +++ plugins/playlist-backend/src/setupTests.ts | 17 + plugins/playlist-common/.eslintrc.js | 1 + plugins/playlist-common/README.md | 3 + plugins/playlist-common/api-report.md | 36 ++ plugins/playlist-common/package.json | 34 ++ plugins/playlist-common/src/index.ts | 24 + plugins/playlist-common/src/permissions.ts | 62 +++ plugins/playlist-common/src/setupTests.ts | 16 + plugins/playlist-common/src/types.ts | 35 ++ plugins/playlist/.eslintrc.js | 1 + plugins/playlist/README.md | 128 +++++ plugins/playlist/api-report.md | 106 ++++ .../playlist/dev/index.tsx | 20 +- plugins/playlist/package.json | 67 +++ plugins/playlist/src/api/PlaylistApi.ts | 75 +++ .../playlist/src/api/PlaylistClient.test.ts | 272 ++++++++++ plugins/playlist/src/api/PlaylistClient.ts | 198 +++++++ plugins/playlist/src/api/index.ts | 18 + .../CreatePlaylistButton.test.tsx | 142 +++++ .../CreatePlaylistButton.tsx | 87 +++ .../components/CreatePlaylistButton/index.ts | 17 + .../EntityPlaylistDialog.test.tsx | 200 +++++++ .../EntityPlaylistDialog.tsx | 256 +++++++++ .../components/EntityPlaylistDialog/index.ts | 17 + .../PersonalListPicker.test.tsx | 286 ++++++++++ .../PersonalListPicker/PersonalListPicker.tsx | 293 ++++++++++ .../components/PersonalListPicker/index.ts | 17 + .../PlaylistCard/PlaylistCard.test.tsx | 57 ++ .../components/PlaylistCard/PlaylistCard.tsx | 131 +++++ .../src/components/PlaylistCard/index.ts | 17 + .../PlaylistEditDialog.test.tsx | 86 +++ .../PlaylistEditDialog/PlaylistEditDialog.tsx | 217 ++++++++ .../components/PlaylistEditDialog/index.ts | 17 + .../PlaylistIndexPage.test.tsx | 52 ++ .../PlaylistIndexPage/PlaylistIndexPage.tsx | 56 ++ .../src/components/PlaylistIndexPage/index.ts | 16 + .../PlaylistList/PlaylistList.test.tsx | 86 +++ .../components/PlaylistList/PlaylistList.tsx | 58 ++ .../src/components/PlaylistList/index.ts | 17 + .../PlaylistOwnerPicker.test.tsx | 215 ++++++++ .../PlaylistOwnerPicker.tsx | 134 +++++ .../components/PlaylistOwnerPicker/index.ts | 17 + .../PlaylistPage/AddEntitiesDrawer.test.tsx | 159 ++++++ .../PlaylistPage/AddEntitiesDrawer.tsx | 239 ++++++++ .../PlaylistEntitiesTable.test.tsx | 211 ++++++++ .../PlaylistPage/PlaylistEntitiesTable.tsx | 218 ++++++++ .../PlaylistPage/PlaylistHeader.test.tsx | 242 +++++++++ .../PlaylistPage/PlaylistHeader.tsx | 197 +++++++ .../PlaylistPage/PlaylistPage.test.tsx | 141 +++++ .../components/PlaylistPage/PlaylistPage.tsx | 133 +++++ .../src/components/PlaylistPage/index.ts | 17 + .../PlaylistSearchBar.test.tsx | 52 ++ .../PlaylistSearchBar/PlaylistSearchBar.tsx | 102 ++++ .../src/components/PlaylistSearchBar/index.ts | 17 + .../PlaylistSortPicker.test.tsx | 68 +++ .../PlaylistSortPicker/PlaylistSortPicker.tsx | 115 ++++ .../components/PlaylistSortPicker/index.ts | 17 + .../src/components/Router/Router.test.tsx | 51 ++ .../playlist/src/components/Router/Router.tsx | 29 + .../playlist/src/components/Router/index.ts | 17 + plugins/playlist/src/components/index.ts | 27 + plugins/playlist/src/hooks/index.ts | 17 + .../src/hooks/usePlaylistList.test.tsx | 225 ++++++++ .../playlist/src/hooks/usePlaylistList.tsx | 284 ++++++++++ plugins/playlist/src/index.ts | 28 + plugins/playlist/src/plugin.test.ts | 22 + plugins/playlist/src/plugin.ts | 74 +++ plugins/playlist/src/routes.ts | 26 + plugins/playlist/src/setupTests.ts | 17 + .../testUtils/MockPlaylistListProvider.tsx | 102 ++++ plugins/playlist/src/testUtils/index.ts | 17 + plugins/playlist/src/types.ts | 27 + .../SearchFilter.Autocomplete.tsx | 3 +- .../SearchFilter/SearchFilter.test.tsx | 16 +- .../components/SearchFilter/SearchFilter.tsx | 6 +- 115 files changed, 9042 insertions(+), 28 deletions(-) create mode 100644 .changeset/calm-snakes-tap.md create mode 100644 .changeset/nice-ducks-smile.md create mode 100644 .changeset/purple-chicken-kneel.md create mode 100644 microsite/data/plugins/playlist.yaml create mode 100644 microsite/static/img/playlist-logo.png create mode 100644 packages/backend/src/plugins/playlist.ts create mode 100644 plugins/playlist-backend/.eslintrc.js create mode 100644 plugins/playlist-backend/README.md create mode 100644 plugins/playlist-backend/api-report.md create mode 100644 plugins/playlist-backend/migrations/20220701011329_init.js create mode 100644 plugins/playlist-backend/package.json create mode 100644 plugins/playlist-backend/src/index.ts create mode 100644 plugins/playlist-backend/src/permissions/DefaultPlaylistPermissionPolicy.test.ts create mode 100644 plugins/playlist-backend/src/permissions/DefaultPlaylistPermissionPolicy.ts create mode 100644 plugins/playlist-backend/src/permissions/conditions.ts create mode 100644 plugins/playlist-backend/src/permissions/index.ts create mode 100644 plugins/playlist-backend/src/permissions/rules.ts create mode 100644 plugins/playlist-backend/src/run.ts create mode 100644 plugins/playlist-backend/src/service/DatabaseHandler.test.ts create mode 100644 plugins/playlist-backend/src/service/DatabaseHandler.ts create mode 100644 plugins/playlist-backend/src/service/ListPlaylistsFilter.test.ts create mode 100644 plugins/playlist-backend/src/service/ListPlaylistsFilter.ts create mode 100644 plugins/playlist-backend/src/service/index.ts create mode 100644 plugins/playlist-backend/src/service/router.test.ts create mode 100644 plugins/playlist-backend/src/service/router.ts create mode 100644 plugins/playlist-backend/src/service/standaloneServer.ts create mode 100644 plugins/playlist-backend/src/setupTests.ts create mode 100644 plugins/playlist-common/.eslintrc.js create mode 100644 plugins/playlist-common/README.md create mode 100644 plugins/playlist-common/api-report.md create mode 100644 plugins/playlist-common/package.json create mode 100644 plugins/playlist-common/src/index.ts create mode 100644 plugins/playlist-common/src/permissions.ts create mode 100644 plugins/playlist-common/src/setupTests.ts create mode 100644 plugins/playlist-common/src/types.ts create mode 100644 plugins/playlist/.eslintrc.js create mode 100644 plugins/playlist/README.md create mode 100644 plugins/playlist/api-report.md rename packages/core-components/src/layout/HeaderActionMenu/VerticalMenuIcon.tsx => plugins/playlist/dev/index.tsx (58%) create mode 100644 plugins/playlist/package.json create mode 100644 plugins/playlist/src/api/PlaylistApi.ts create mode 100644 plugins/playlist/src/api/PlaylistClient.test.ts create mode 100644 plugins/playlist/src/api/PlaylistClient.ts create mode 100644 plugins/playlist/src/api/index.ts create mode 100644 plugins/playlist/src/components/CreatePlaylistButton/CreatePlaylistButton.test.tsx create mode 100644 plugins/playlist/src/components/CreatePlaylistButton/CreatePlaylistButton.tsx create mode 100644 plugins/playlist/src/components/CreatePlaylistButton/index.ts create mode 100644 plugins/playlist/src/components/EntityPlaylistDialog/EntityPlaylistDialog.test.tsx create mode 100644 plugins/playlist/src/components/EntityPlaylistDialog/EntityPlaylistDialog.tsx create mode 100644 plugins/playlist/src/components/EntityPlaylistDialog/index.ts create mode 100644 plugins/playlist/src/components/PersonalListPicker/PersonalListPicker.test.tsx create mode 100644 plugins/playlist/src/components/PersonalListPicker/PersonalListPicker.tsx create mode 100644 plugins/playlist/src/components/PersonalListPicker/index.ts create mode 100644 plugins/playlist/src/components/PlaylistCard/PlaylistCard.test.tsx create mode 100644 plugins/playlist/src/components/PlaylistCard/PlaylistCard.tsx create mode 100644 plugins/playlist/src/components/PlaylistCard/index.ts create mode 100644 plugins/playlist/src/components/PlaylistEditDialog/PlaylistEditDialog.test.tsx create mode 100644 plugins/playlist/src/components/PlaylistEditDialog/PlaylistEditDialog.tsx create mode 100644 plugins/playlist/src/components/PlaylistEditDialog/index.ts create mode 100644 plugins/playlist/src/components/PlaylistIndexPage/PlaylistIndexPage.test.tsx create mode 100644 plugins/playlist/src/components/PlaylistIndexPage/PlaylistIndexPage.tsx create mode 100644 plugins/playlist/src/components/PlaylistIndexPage/index.ts create mode 100644 plugins/playlist/src/components/PlaylistList/PlaylistList.test.tsx create mode 100644 plugins/playlist/src/components/PlaylistList/PlaylistList.tsx create mode 100644 plugins/playlist/src/components/PlaylistList/index.ts create mode 100644 plugins/playlist/src/components/PlaylistOwnerPicker/PlaylistOwnerPicker.test.tsx create mode 100644 plugins/playlist/src/components/PlaylistOwnerPicker/PlaylistOwnerPicker.tsx create mode 100644 plugins/playlist/src/components/PlaylistOwnerPicker/index.ts create mode 100644 plugins/playlist/src/components/PlaylistPage/AddEntitiesDrawer.test.tsx create mode 100644 plugins/playlist/src/components/PlaylistPage/AddEntitiesDrawer.tsx create mode 100644 plugins/playlist/src/components/PlaylistPage/PlaylistEntitiesTable.test.tsx create mode 100644 plugins/playlist/src/components/PlaylistPage/PlaylistEntitiesTable.tsx create mode 100644 plugins/playlist/src/components/PlaylistPage/PlaylistHeader.test.tsx create mode 100644 plugins/playlist/src/components/PlaylistPage/PlaylistHeader.tsx create mode 100644 plugins/playlist/src/components/PlaylistPage/PlaylistPage.test.tsx create mode 100644 plugins/playlist/src/components/PlaylistPage/PlaylistPage.tsx create mode 100644 plugins/playlist/src/components/PlaylistPage/index.ts create mode 100644 plugins/playlist/src/components/PlaylistSearchBar/PlaylistSearchBar.test.tsx create mode 100644 plugins/playlist/src/components/PlaylistSearchBar/PlaylistSearchBar.tsx create mode 100644 plugins/playlist/src/components/PlaylistSearchBar/index.ts create mode 100644 plugins/playlist/src/components/PlaylistSortPicker/PlaylistSortPicker.test.tsx create mode 100644 plugins/playlist/src/components/PlaylistSortPicker/PlaylistSortPicker.tsx create mode 100644 plugins/playlist/src/components/PlaylistSortPicker/index.ts create mode 100644 plugins/playlist/src/components/Router/Router.test.tsx create mode 100644 plugins/playlist/src/components/Router/Router.tsx create mode 100644 plugins/playlist/src/components/Router/index.ts create mode 100644 plugins/playlist/src/components/index.ts create mode 100644 plugins/playlist/src/hooks/index.ts create mode 100644 plugins/playlist/src/hooks/usePlaylistList.test.tsx create mode 100644 plugins/playlist/src/hooks/usePlaylistList.tsx create mode 100644 plugins/playlist/src/index.ts create mode 100644 plugins/playlist/src/plugin.test.ts create mode 100644 plugins/playlist/src/plugin.ts create mode 100644 plugins/playlist/src/routes.ts create mode 100644 plugins/playlist/src/setupTests.ts create mode 100644 plugins/playlist/src/testUtils/MockPlaylistListProvider.tsx create mode 100644 plugins/playlist/src/testUtils/index.ts create mode 100644 plugins/playlist/src/types.ts diff --git a/.changeset/calm-snakes-tap.md b/.changeset/calm-snakes-tap.md new file mode 100644 index 0000000000..6b853da53d --- /dev/null +++ b/.changeset/calm-snakes-tap.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-components': patch +--- + +Export `HeaderActionMenu` and expose default `Table` icons via `Table.tableIcons` diff --git a/.changeset/nice-ducks-smile.md b/.changeset/nice-ducks-smile.md new file mode 100644 index 0000000000..14153c6350 --- /dev/null +++ b/.changeset/nice-ducks-smile.md @@ -0,0 +1,7 @@ +--- +'@backstage/plugin-playlist': minor +'@backstage/plugin-playlist-backend': minor +'@backstage/plugin-playlist-common': minor +--- + +Implement playlist plugin, check out the `README.md` for more details! diff --git a/.changeset/purple-chicken-kneel.md b/.changeset/purple-chicken-kneel.md new file mode 100644 index 0000000000..d6a81c7f17 --- /dev/null +++ b/.changeset/purple-chicken-kneel.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-search-react': patch +--- + +Reset page cursor on search filter change diff --git a/app-config.yaml b/app-config.yaml index 7c93d9cbd2..22ca1fcaff 100644 --- a/app-config.yaml +++ b/app-config.yaml @@ -444,3 +444,6 @@ apacheAirflow: gocd: baseUrl: https://your.gocd.instance.com + +permission: + enabled: true diff --git a/microsite/data/plugins/playlist.yaml b/microsite/data/plugins/playlist.yaml new file mode 100644 index 0000000000..3d69103d69 --- /dev/null +++ b/microsite/data/plugins/playlist.yaml @@ -0,0 +1,9 @@ +--- +title: Playlist +author: Phil Kuang +authorUrl: https://github.com/kuangp +category: Discovery +description: Create, share, and follow custom collections of entities available in the Backstage catalog. +documentation: https://github.com/backstage/backstage/tree/master/plugins/playlist +iconUrl: img/playlist-logo.png +npmPackageName: '@backstage/plugin-playlist' diff --git a/microsite/static/img/playlist-logo.png b/microsite/static/img/playlist-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..b5c8d9940175d6221c1bf1cdf9ab473e5793a5fb GIT binary patch literal 14734 zcmd_RWmH_zwkAq|1PBhn2`<6i-QBHlcc*X(?(PnO;O-LK-Jx)I3ob!l<(zZRmDfG` ze|L?ly=SfcO<8lvUN*xO#KfIyUz6jcV_&%nQ3*iYbVNbqA1`1S#)EFlb0 zHHm)={$pVZkTR2#gP;b}un^E6K0!eJg+M@pFKGXwKY;0P|Ct_Y2?6~N3s`{~&asDIPDe}UHo^)X<$gQY6K86YRiZESB#Z)jp~WJ>RD>+lxVpD~pQ%iyi!rkHo^+*@2sZ!OhK$-i?Lc-pQPSiHnPifsvVknVAlZpaXi?IUBmu z*#SxaDda!oh?)Y8oh%)kE$!`y{>n8pvUhRjBO&>#=-;1z+Uaa*_Me*Ufd9%CID-s- zpD-}dGcx?I*ua@pwlueJ2L9X1|HkWX=cxg3()j$(m%3kV`9bt z*6>g5|8UPgt>*n}6Ss)Ht%H*(5D3m4KNIgi?EG(O|C!5w;+0K-_BJkmouOuD>CDgk zFP8t2{6D!AoGeYj-u=t=Z!P~d?SJAGE$p4`!6ofvX)I;uZ0ZCy@n78kq40l?_%E{l z?O1LNQzI3y1XEkE8T@~%0`OmT!Pw9a=xlFn?eJG4{okUpu{1Wd1DY~$F|ji-ae?ax z?_c-*vw;4)od2TfueZ5n|G{bRq^2zUf6!s;0<<)ybFeY=u(1R>)47@&JKHaaZ>H~)MGoLE-ofJ#sc%Wev3S|0F#^JA<$2S+d>^=2;^+M|8vR`dh zww$dlQ+$2g?;G!$*3}*ND=~7J?E86QsEW{0g58!uNz?@-KVSi{-wYdxzd?Q?{t?7h zQm3jaCJ0wYdD7i478d4fy3l-rf1O_6O(PF5fD)w68DMBL%3&L3|nwFMC z_@Sw<`jHr*fPsP3GGc1bNi{2dl(;M^Iz@^c0S$;4pP2I!-aVR52FM>gx90 zqtfxikKTRJG`cyl8_vUTEt;Y*k$-qMBhg$toBcFBzjJt`QD`FHiO1_JMn*5bKw079 z)}EG9);yGk*8U=a@#T*+8H5WRgCVd|;#EjEl+=0Skx7{PZJS(EANk(i(Kfa}*jdHT ziCNhbD)69&u)t25>|!v1b7=gYZod25_Z98rD^-Qwe8AfV|KqD3JdIMF`ny|>mG)Oq zdUI0xI?R+g^YF)B&i51RX_ZEl>hsfqQ<$eqVRQU9MEk+EuInzxlDdy=UNB0UI86;@ zl4nKfXWM38>E;hqW^ccxm(qv4H#U`Ub?HT78QH8Ru3b3O9EkQ2dI+rqdvOL&`K0zz zvqECMk5{oP?0RKjR^we-q(G3)Mrc!u`9ay$Yyx9b*$U=y3h^yegmspL*Ow%Tu0%K! zJ?Ec)HVTCIM2NMVMQ#e)oiB6FFCce~1+wBhJigw5J`@IJ?}zYQ*ymzB#6!t958(zP z{P_br>rng6|$}6hmzq4td1qJhVsHKZKZ}b)gWjCt{v?0q|V|!4B+GeTN z$I#Zbet~@B75cm-pd4LYUaM&3M{T})5MDDP>>HT>%p8)?vA+PsqFa7t< zn*;luL;W@!9)0gG#q?H!`m~moM&_Ux9#=p{rhjxO-&o-us|)@jpqHCmIK(75q`~Le z6#)@3xh$3Gfy!_wsAvxvZIQ+>@b2!eq_mW4o1vX{U4Bvr_roWd$7{zkkLwR>iSj$W zr*^`Ik@E3&1RYU8LnHV<#|>VKj)znxYd9UlwX+S(pN#RBa^GI&Ic zo-~Vvis7v>>AK4mc*Bab?AmuTPOofyk(e|fVA{M;Y|46J-jCZ_UJ0uuhVpCydg#JY z=fq>Fk2)8txH15b-G{q7!+{8lme>1L;)5%b2sBq_iy0I0_!oS6uERB;!*(#1e0WXD zZhwz% z_R6C0v1(_=gHO5-v7&-c70h?GyMxhyHdi{M+NEKrqDQ%L+fww$|df)R)29v{=wDEFFW z^2A^ZL&r+6LOR;k1iFSUQSO?2QpOdASeoQd=z31gtO+S{lyf0R3x{6qMXke(G(ulg?Cb^ferCeM#l2iI zj@<@n+YhK|=$fLcAE=F*B{sFxMZ6Qljt>kSZ+?W{+h1B)iO96?Tz0ybgP|wor1*el zc_L!9QN!V<;v@8OywSFOv$!4b;Da#bhCp%-zr9dJoaNFZwsiTM&i(G8OL%xn391uf z$63!br1${Cgs(!oSmYL`tq5Eyz2PIPYim*V-)}M>C*3-Y(^XwlAc@c2MUcx3DHjK! z7bVF83>YmuA}HPN_hOMkdnLuuh80&wdB1Xq;AntUcS`kNu;n5#f9_YvEn&!A!VtbS zR3rMn^>m5z1XADgK9hxdVb<7w`Avn(HrBGwYrBVv{z;lU6S4T>?ZB1P+E>2LWt96VSkUhD$k7l@Kmo`Ps-C@z~ z?W6C5eX((THQIV90$LV!P4rB}#p7P|I+?d>E=Wes%WDMc7*@{t&MWmzQ`^kDQk111I84TWt;q7=* z8J+7=NH8Ad4$GAGy$YR=mO=IMs#i>e4z%GYF-V%nLlW<8FN!NzGz)W5xj zyPJ}-$f{($tM3m`th_L~o}Lgbsd8Vxzc z)K=rw<{P+D{mWchdJ%o5#)}Wirl?_IEyd=3t<%e+I2g$RF+RE4_9VK!!lVShN+LP+ z3cBzi4Q6rPoTnNO;BAC`&Grc!Oq47{{|MZ`J!8UCAg@@yuUME8^*@)LE`(?lqdH6w?1)tBn+-@B5`9!m0nzJ zmm3ua;!1>f1TijRzumgA00Q3eWxn+L^O8Fgl*s#^sm3kYInwRh9U6vMjTMx#%yUfS z9R_oeXrNo%tk7#7@+}e(NT;l(7$J-*3p|4N?dBTV&7s?pD5`rH2MZKV+quFLO&46( z+gswkFJ+jPg~-+t7T96gXrOLsmG}?2L)O6z6e>y;+Kt%R416Jcv74d6&dg#z9S?0CP1`qo{I%o^bw&aqVE1dIAkM>@K;p7MQ zBXsbwJThn$>9%XO(aTjf2s>{)zOZiIDA5R+w+_E_tshWM6u6<}tf%@FeF;yzS;K)& zKIeUtg-r!hM$nL4WB&bQ3gaqgq9Udry^pa8+MWew&URV(Vg@K%yQa2>P7n`C(V|H( z@Qmia?4|(mi#b@+0BjYg(JH~bxF47t)1O#R58bU%vif4oKD{;bzcLE*c`2a|lb*X8 z_zhKf^--8<-D>6~>(RsS6he(kQvq+q#=gg*HJz19exwcerhlqsw^-`G8BSC*d(gUERp4262Gfx< z4fsGIVsNexhU!3XNXFip>yni4zCzI>H6L9wtBqE|KjsAF>Ntd66VR1>1U zrh}y&W>G9a_eT5Oj*H@SM;2eRFR;LcWmo_k_D6j^x~=UwXgW5|J#6llI<-Qus*HdM z>8v3AOs>k(h$*GUH7z6jN9H$R>o%Q9a;3qFQ&KXED;d@o%De7?DM<~OvZVo+_~8V9 zlA0el%Lc)X^AaJi02O$`k#Ul_!?P?ov@d#gh@-NqGBUPP{>fSW$|eML9o4rul;1DH zMh^Q@Q}b}N6+RoL*FzAPMj4hTngB!`gx&0F#d9N8h zqHFSt%v5HE;|wXZC5)8?;NbbyN0r;Zh>~ce~dg(sYd}(IK5y@)PCzLqRosNzU(3sM-g&d8h1YbxRc&P3? zKLygzCXl&F+zJOIp~`8};2B3)Uz)T!`3Ybfg?vuPwUt22%UDWeOQ~t%0xc{AGx+`) zbANx{w7;_q9-eJ(Y!ogXUGPbi5QL=}%kzG_$sGzr<_}9rNg2^MVK$dE2x1%L21ylq z<#{Bq3^IyZLd}Yk@kJT8K+$g2FC)xN4C4tp@uq7;kyi+=&&>EYcbwaTn7?}6pVdlg z*;Fmt>)wQwAj8cNTgzo;zH=f}VLqezV$WRE%Y{u*BxA(E=Jo&XsV zHXS)Uvy$?IU-7hf#LFL381(H>)j(eHZxwQYi41q6)m((=un@l8D3%!O#%^>PxoxX_ z&dScp!stkrSC&WpItnKW+h5by=;4KV+I2>mO`lVXMe2_KzB3!M<&k+W zA?(_(#BDgOp`NLN$##q|%cZ=H@S@xC%gf7aT~5`**jUafu0#h2*|RI9j-6FoD{D2; zSOI+lwUGF!(LI#U%j~lWLh(g4B4IWqt0REkh)>C;$g8WXjw9r$TPNk!ITjeFjzj)_ z00uOn+d#sXZj#@QIz|b_igZZU@?5n5!Wf;^y~bycCBZ(^ATF*4;RUrwJvf?@av&!FeFE&LOanp(8u zAcX5Mm9cgsGQ)jD>P%K#;!4&6^bWmJ4>hh1H26W`m7boSK7ys=4&&qU!|Z%(a$2Q2 zr8wt4iW)MU)bL|I*+f9stw~TBHP<^^2m)Q8!E|U~Y*!eB20AP|h$NfCYc!F06(608YdYH`xSzoj!NRFClu_V0vib zE<;`bKK+-O)hg?d{*48ZkXy$kZ%2O?%jrQFZFVw6*H$$78ColRx<`|dRbI%b-R3sTtg=`XM;8X ziF>fcW+(uckf7uB&_Y}Q5+NT&WohirXh6=?is?bkn0kl$0ZtG+ydP&Irm$m=)wplo zUK^_p30z@IaOxfNsFjoL1$EwWoq7K@Wc`FwH|nSrYGHctof>JF^F#0W5qVM#%jf0| zn_gJJiW=+LOeSaM8h)%x4a+J{q~Y?iefO_s{Se)7+D~;-Aw*5a=^O#(7p+i#9w9_f zOI2`Ww`&q&So#6<1{O-axLS@kx;Bq>Y z&f@w8gwmtY@w)k%eX(SuHazLss73}&`M%1VH(#Tj)=cWy^FDc-1`FoAF7nn#@1@}m zqu&Ch3loj2a8#N0YW)4*d>@z3FB$Dx5?Fv)XkaTetD}oiNNR^mf z0Yj1vYDefH-QCkfWt@{MzfN7e-{Et6r0hLuesNiszita`%^z@E>B=LG9B?Mf8|8Rt zBdv@EeMrBwtC<=Z-+D(^KlRLG7Wea6B$4AJfy=}Y85heQX-^rYmd`%zW7&MB-wg@0 z*b_w&P^*?zuc=dFtfVTHuDhNiImI?^GmR3hwJ0-;oSE*L5cCtJ|0Y+3D#OezwKj)) zl75w|M~Sp88K0NcF3QFP$X7g@+O7`y4qgPTnB`DF}Aw{e79qnlB=@3W?Duk;{X zI&-7j#YU?#rRg7hW-RqOPt~x8))nxY2PntRtnCjYQD;dtKLRE_%nLH{axMEa@Gd zT8El97x(F5c|LkqwMHOKn(PUWKD93cqc2hKM5l# zY|Szuh9nayN6xieQjJQ8BEt{ZaePSd!d;)%g|jefn#~*?d*C0pnYbA^4C@RAGaEwJ zvX-To;!-_{sa$&KK@M$r>;4#t6{7&8F$=F4MDlXpfp+pUXEv4&I~-C2MkQO-AuqAz zp`&8(s&^6`STb`dEQSbb8Z4w0ngTRApIHhDwoGo)QSM|y5R1=hElRp2*X{QRKN7|d z(5ij%5M+ENO(-UvYz6?93W6!Hdj^GiIJXxK#K`Yh%#J(la&0}O?PIhDa)BD^W!d) z2o#mZOyvHzarkios|TIUyrAqpHd?I-ki$>HIjP<-^(12*dJb>Bgz=sRp7Es3DHAi@ zuRad$KEqBkrGxv$2FJ6>4w4CW^o$q|UfXUhD1`XJ_7@OFBB*C8tx)0qA6kHp^C5L5 z)m46rSUYub{A5N-3CU%FM(f z2K@AZ!3m1#6+$tFmKE)F;VjREeL%x+)*xKW9u>{NFR7UcYFmOg%Ofvc1XUk3de*w+ zs(!FdIPytx&98@i)z0bb#Ci`4thN;*#VWD7#C~%D-rK>M5@vnSF%A7Waq+Lh;lsA57+4;1)jI98)R5Zp<2^YGb2@+fI88k+5_{26Iy{)VBy2!1p0 zDREM;ojHg-qrc4o*j=GN=Y{8yu6FNdIng962qk2X)XUy`#N5#)Y=|lMjTR^RD9u#hbYkn-UWhv^ctDIDMuFDsyKRQ)6T24bR@_d9y?@VS+Dydd>L%Qls{n(Kh|GMV_$;naz*(v?Y zS9y~Zlw7jJRCt_EFwdp0IyzjVg>tKd1Ttt+lx1aBimQr|g1UV2{O=PbRsaN6IuY{~ z|G*jAk)u8$0b~;$3(jXFowYj5hmEJHrM7pMs+iyVk?JY)KMoFMgd^G&3sx&V7Xp6n z{dIGW__*Q7RbBO;bLDK1Cw5&(+^7 zu3(Qw=R$MUli3-f?|X`Q=Ig?;Grwl%neQ_{UE9Z%Ur?_6eLXqd4%v8ps@8I@$nd9S zg~%wdD=jub()(&>pygr1Yq>gs!v(}lX`AT8J3?tK9NP&}9bcGPOt?s>Qyb;kxI#Kx zZAOO2q)jstXqr9(_KUUG87A0zT@WFGD!V1#j`6}iX4X_&hs|H+M`SdnZ>;^gg=kuT z0P+Gib+@`{sRQ)pgZp5A;isg_W-cX+crMpgQ$;E+_n=CBCzLLnL6T8DO}&h?gt}N)D)$lvehmNkA&BKgGHqY!6-K6^3Xmf*s9)NQrYz=C{-oR^$(24nvyar?+ zb{hbIBZ}T=Zt{%zawhQ}u{U|>aJ|D#HWxrDcO*M|jU-c@@nV9C+~j>tSgWtuzlSuN zgXpeX;`SUDg4{;XinXfe{mIvHVsp0vp1#*V23yBp+IavcY5QjPd{HkJi+ktD?47NF zD9YUk1<5nsbT_{`_!mBV3=l1RK-o?`o_rqR-I&&J06(RWdI z@>O9jB{L-Xt>ueH&Xpc3x-DV8esG1J)d2L6f;Nl1_a%$I;13USS62jLGQCZ21Q}f_ zeD4=j-rGKVLqnp_UoPdSIA?{WC#KUPc^sDL18=nCfiDycOg)=@dHE`-)j}{D;=b1) z29l;5)2y4kt|8)4!DnnfA5{Db+io6#J2BA?w)p~KaV-h_=44+@AimQMg?-XC^G3(H z@j+kl-=%amcJ`gO=Zm4(@3*8nK6eYD6NZjk_~o){BJ#P*MP z-+4YlWxFY3otTdzciN!&*rjqdiiD*8~hSZDgyuuJmNeXv$Okvx{i`eMT2$is)s z;2s9k;BwOLiICwQqM%!j<}ycFjytq#;O|f7=QWpt77HL~cLTxeB?i>EstMY@cjfv6 zw$1CV*k+cT_pa`TB?3h&5JjGE-yADUj*Je*WF+-CReXrUQe2f+5v6ly_5I=BPoUgA zhynpI#vM`U{B4CFwBI(f-5-ZG2XP{;E&7W}mZ{X3qZzZMJq)KD(ueC;3ix-{53uQX z!*0B5n^@Tm9(Es$fSi87_XD%`d0dfc6){BWe%TqwgUEp82qzGBMJ}j4)gI0=L&Aj9 z##fse%lyf zbr^V_Zu9j^zacUOVHXkbw=8%JkElfrvfEN-aV1Sv@WLw}ERt?1&C#b#)se|Ey+%uz z_#U%kOmWi;eHV&-$kTtN`0$Gbh4%)seGOC0kHuc63Odw$_Hp9t<{-5%E@E<{B-t#2 zk%0?yQF!8W*zp<8=7`H&IW(LpC)p;iQ~H%LLt`mV~Ahd57Z$*Byc^lNGq zq$c0SQ0v{O0r(FrNyp)X=<2MA7y}}Hw)rc7$OByK`dF$^g?R0!%BFMywe%%T!3P7h z?LkahoeqL*d~T^(ZG6Emjq7c-`@i4215R+sj-s6ATFG1;Hl*?$Xi&tCtj}|5zL7d$ z0zn(JDvPEQc`h|wzZ&vT+j6`Jpm<#KQ!?24P^3KUJVu7i(r1N1`4gS$SDkS1>_bSb zDK)@9l{5@Q#NAgZw1MQGu;R%UuVe`0G`|MUBf=5M*CIn&pPWh4x)1&x8GFM%EHu(sebfvQ0cS%endAbim^IVpKDqdf3W@EwX?U!J`)DY~JXf&FTA&OE?HK+sK3|UZZO1$2Rm<8~ zAqzTHZZF<(B|vA6baOt}!K~^>P&Q7M`7OO>0@Om|Js^AcEm)}X#xY(7DraANXetKmuGS=Qj8 zERZNiQ!2P6VX6nC1N|}Y@@y?%Qq{{O=&o7&;kqBc7daezLMEd5VciB_zC_& z19RFZ$&d{Zm@VTLgV7Pqp0Hv{81C|?T)7xtftWZzR*05af zD~I|(DvHp-HC`<^9<0;kR{{H)fQ&Kw^iBfDPP5&k3+uo|g=X4`-DP?L2IH)sB9cIY z3bs!)MRlfliZ@d=_qn#T6hL2N(rk*GxH-qOnT>_xma!{cmEO-CS%OHDz`J_=qhhzE z9t1Rc4)oI2qf*l-$Cc4yGN{~Ok`)gMnVg3)r<|(u*W^6%m2reOb4D?xcP$6{Tl3gq zt+*Qi#p_vDQW4Zt>mSuQ|0Ki3D2g3cFH1dTYyX%c-sdR07%ww2HBp=|Jd*tbFA5&% z0Ez2}DXAj4Um^Mg#)*vx1O_RhioKI)mvbK4;p8zAo~5OdT1Dt72(p(BXUQ=oHd*}> zk|=%7(u{A7m0raxm$S?LTo;lm<;>23^?=dGFU%cukz~&mI0p(&Ei@IfZ}Nj*ro;zU*I^yq$+^4}%@OK3N0cqix(k9c%_4F+ zpBoXfYx48Yb`K3OzCMsnh3eqFU+YOikTwG+m*&XIND>%JPcDwpk=M6Y{)BRFw^(oLKXnh};RA-eI zgUE|*w|JMKZ{%AQh5kIPYR$~GVhJ6ji<9o+7p22u;=@NEF>GUru*gGxJi!V?cy{591Sn{~fdID<|5F{U23p#TI4C#KSplQLS?EBR z6{EV(?|Z6AssTte-1_&)$zb6{X9nD`h$IZ~vcS0H!Q}Fi6nR#Oq9+_J)wD}=(DTjs zl^^6`cEOQSBP?z?4}*l?eYdC|i|lhGlG0Q|86X2iZ`Z%CCzp^aT_^DU^;ExEk|v!p zrg>QO^67;7Y&)_7xXR92-36gb#j)b~NpZCS-~4_5`SLpZJ)|C!gGescDFUuLn;^&e z@s&a~o13^|8*eOYKL~1a`ihD0%KF*Wct8Enc=_0TdwG&orN+rcrfN6QYBSiMPrEkY zSb>GCrXC@`HU{hcn0E@$D@|Yg`uq?`gSDlS`;=5@DkhUI4H$WO5AS-02Jdc!KmTr< z(wfHkpG@O>ro{j;sYTBJpL=*ohEoOEn! zGJG1rzF~e8s7jqZ3=US+J1hHoz)*~poGETHe+;izU+)UlnTb?91~b8gM6a%fVD;h= z&U+n3v9%~z27vjS|Lwf!O&I6>Y5z|-cr1L56FE@hdaebpscAgK9=^}fCZLg1Lr9lQ zd(h~(D_)`BwV~y?cSK528!AFvYJvoBeNwx>aOmi8BLbW2M36eYh06g4ldas?@>u;2 z^R`RFVW8QV*_!eq87FJhJId+^GnKl`jMl=~*em-+R-S|p?mbp~QGD;?Pq(!@kzjtc zW|8-irn0ILFLz>1tv~Qol)wWq9{5`<@{x1d8&{`#>Z5hFB_x-@Tbc(4X1tGEf$Ea0 zCMU&fPtDi7`KAmVx5_eOpvA>lcl<`e|7OC`_~ zIlXT4qMVIdas!RiG0rl@Lw;TD*uS9{>v&__D+Zf&Brk0&#@^Yt;^+17^FG!44vmbZ zYSo+8olQvtwp1_UQzcTA)HMfb2e{C;8$n34#W-)E*f&1cf_C*;2TIZ!EvsJ6+aZ{m z_fnXetkW0iI<|Ca4wngj+}PHebpRrbkJ>8f8u;we+uNJe!l)|lUV$BJPvHJXvKUIu zI*}~PpZheRABFT>*KQekWaT=fQ%sXzO5H7pqG{|NKkry`Y$yNbgq$x?dqcon+^c=f zYrDEd?urhMVzja;sXzEpbj-)U0U>@O5fnh*0Hk#{*M}VA=s?GMTQ{$Do9=P(G65|3 zuMnkHjXUpRap*^80I;aj7e`2y6ueze%-=N97Oe%!t(G9s#L?8L)rP5aR2iV4_Ux&4 zoHHzNB&1NDI9bL8wMQpf|7){!yN^&G_YgS(Q-sg zTKj3eC`f%@3kYRZTot^qNH&Njy%wKqudb1I|Gcq2CE9rgiRf%20ltiGHQ@=wJpKO4 zS;`*d4`^ph5(DxJ*nGx9MqPg3A(?o28I$atoGQb8FO7twkvQNSq#h7DjPKv|To$lB zB^0FA3G8~!-Ry(^^XUwG&jH@p-RBRqmK9V9aPYEwsw))hq62=SRH#AKfsk+Fn)!;+ zmnoSZtrtIL``57Y2=!<}lwd4O$LW5Li~fzU}On?ah= z@aJZv$|+>aJ5Tdg_kqAxL6PSqQ3OE5;b(4-C&a5cG)gkTK)Y+KOR%qC*R<<86 z+s>k=&F&BXuRi#zr#Av<>yxxb#=eo?a9PSzYLF`rTgz?VBlxEHqDAcqg`Ek4kEL80 z>A5ZnVRC|!{V>YA#$JZb=t+ecfN?V4t9XHYpsWY>AoUK^z)qt3Tk%pRE{CK&c)yH> z^s%6q-Y;(#0NkpII6E&ib6~fz(IFCBfE@fMF;A=XI2?+B393!g}<~RI!$p@xsh94xQZ{TzX6X4LAPg3k6%VaPr)QMz5b6K4dvsa$X(F|ir z40`mB&;~Mn{UyHe_^UW zG*;@JjMpNpt{o$dnQpOp-C1aa#9ns8n0VB3!yTJ!gDuwe#=+I7+`S+`5KRQBa;EE& z;sn+UQ*)=2DdD#CW@Y+l5!N%-Mal>y-Nx6$PM4}mT^D&h)&6t-LpCro@8a)eTzZ*#Ac$@So5(s z=RuuT#|yVCwNfxdMh&T;Rh~PwGD$4$n37~0JFN#*4>?;>DCWNkHN>CcR)od4AaP-VXi)(nTMM+%p>5^$z#|72#=dm8A78fBcO~(nHGvFhcNqr zElkoEYc{ID%InT_&x;%N00re$1{Ma}O6o9qY=ECBkRwZnkvnJ0Nu!~-BMM_udEoHK zf?FM2_M(z(XOg^8udcMc1g{3{niklJ18A6lqxFdU!cThz52}+RY$nSRrUFgoaeXYT zk>^Lny|Val8F5Le7e1D zzMtXR(>3=j`1}<|vBJI`7DHK&b4!37F8{X*{{Hw+x%|?D){MtthH&2+F@W_@D!kYc$mLAg;{2iqn8oe1>z`1YDD3eGx zN#T1b_Y_@&%!cHbLc@AQC#;`~Qj4O0ilKh<7mO*YO6=nl1_h|orq$o)4S;O?OUjsR zZHjJG;CQl+aJ_A@>Mvw!8xPzuD+>LO@4i-l%N`Oj-|3<Nc;=c*GFe0GHQN4zCk z=D7u8qH^wdq=^yVg8pvtG5y`*Ln!{^r5az{>@A3G&spqUkcA|bR5Ry)LaQ_P+gkn= z)O2j^o6?!jC#&+b2zQokLhEqMfBC|Ka=3}E@PqD{I6|-$9P2{2n4#4A#UBkE)gt4U z-}c4d2^> } /> } /> + } /> ); diff --git a/packages/app/src/components/Root/Root.tsx b/packages/app/src/components/Root/Root.tsx index 30da01841c..8b5f0932fb 100644 --- a/packages/app/src/components/Root/Root.tsx +++ b/packages/app/src/components/Root/Root.tsx @@ -22,6 +22,7 @@ import RuleIcon from '@material-ui/icons/AssignmentTurnedIn'; import MapIcon from '@material-ui/icons/MyLocation'; import LayersIcon from '@material-ui/icons/Layers'; import LibraryBooks from '@material-ui/icons/LibraryBooks'; +import PlaylistPlayIcon from '@material-ui/icons/PlaylistPlay'; import CreateComponentIcon from '@material-ui/icons/AddCircleOutline'; import SearchIcon from '@material-ui/icons/Search'; import MenuIcon from '@material-ui/icons/Menu'; @@ -105,6 +106,7 @@ export const Root = ({ children }: PropsWithChildren<{}>) => ( /> + {/* End global nav */} diff --git a/packages/app/src/components/catalog/EntityPage.tsx b/packages/app/src/components/catalog/EntityPage.tsx index e15df4bc6c..c2f297a2d7 100644 --- a/packages/app/src/components/catalog/EntityPage.tsx +++ b/packages/app/src/components/catalog/EntityPage.tsx @@ -104,6 +104,7 @@ import { EntityPagerDutyCard, isPagerDutyAvailable, } from '@backstage/plugin-pagerduty'; +import { EntityPlaylistDialog } from '@backstage/plugin-playlist'; import { EntityRollbarContent, isRollbarAvailable, @@ -114,6 +115,7 @@ import { EntityTechInsightsScorecardCard } from '@backstage/plugin-tech-insights import { EntityTodoContent } from '@backstage/plugin-todo'; import { Button, Grid } from '@material-ui/core'; import BadgeIcon from '@material-ui/icons/CallToAction'; +import PlaylistAddIcon from '@material-ui/icons/PlaylistAdd'; import { EntityGithubInsightsContent, @@ -155,6 +157,7 @@ const customEntityFilterKind = ['Component', 'API', 'System']; const EntityLayoutWrapper = (props: { children?: ReactNode }) => { const [badgesDialogOpen, setBadgesDialogOpen] = useState(false); + const [playlistDialogOpen, setPlaylistDialogOpen] = useState(false); const extraMenuItems = useMemo(() => { return [ @@ -163,6 +166,11 @@ const EntityLayoutWrapper = (props: { children?: ReactNode }) => { Icon: BadgeIcon, onClick: () => setBadgesDialogOpen(true), }, + { + title: 'Add to playlist', + Icon: PlaylistAddIcon, + onClick: () => setPlaylistDialogOpen(true), + }, ]; }, []); @@ -180,6 +188,10 @@ const EntityLayoutWrapper = (props: { children?: ReactNode }) => { open={badgesDialogOpen} onClose={() => setBadgesDialogOpen(false)} /> + setPlaylistDialogOpen(false)} + /> ); }; diff --git a/packages/backend/package.json b/packages/backend/package.json index a8ae29ee18..eb0e0d58e5 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -46,6 +46,7 @@ "@backstage/plugin-permission-backend": "^0.5.11-next.2", "@backstage/plugin-permission-common": "^0.6.4-next.2", "@backstage/plugin-permission-node": "^0.6.5-next.3", + "@backstage/plugin-playlist-backend": "^0.0.0", "@backstage/plugin-proxy-backend": "^0.2.30-next.2", "@backstage/plugin-rollbar-backend": "^0.1.33-next.3", "@backstage/plugin-scaffolder-backend": "^1.6.0-next.3", diff --git a/packages/backend/src/index.ts b/packages/backend/src/index.ts index de3f435508..cb9c9bf580 100644 --- a/packages/backend/src/index.ts +++ b/packages/backend/src/index.ts @@ -57,6 +57,7 @@ import app from './plugins/app'; import badges from './plugins/badges'; import jenkins from './plugins/jenkins'; import permission from './plugins/permission'; +import playlist from './plugins/playlist'; import { PluginEnvironment } from './types'; import { ServerPermissionClient } from '@backstage/plugin-permission-node'; import { DefaultIdentityClient } from '@backstage/plugin-auth-node'; @@ -139,6 +140,7 @@ async function main() { createEnv('tech-insights'), ); const permissionEnv = useHotMemoize(module, () => createEnv('permission')); + const playlistEnv = useHotMemoize(module, () => createEnv('playlist')); const apiRouter = Router(); apiRouter.use('/catalog', await catalog(catalogEnv)); @@ -158,6 +160,7 @@ async function main() { apiRouter.use('/badges', await badges(badgesEnv)); apiRouter.use('/jenkins', await jenkins(jenkinsEnv)); apiRouter.use('/permission', await permission(permissionEnv)); + apiRouter.use('/playlist', await playlist(playlistEnv)); apiRouter.use(notFoundHandler()); const service = createServiceBuilder(module) diff --git a/packages/backend/src/plugins/permission.ts b/packages/backend/src/plugins/permission.ts index 0d3dcc588d..7192a1ddec 100644 --- a/packages/backend/src/plugins/permission.ts +++ b/packages/backend/src/plugins/permission.ts @@ -14,17 +14,34 @@ * limitations under the License. */ +import { BackstageIdentityResponse } from '@backstage/plugin-auth-node'; import { createRouter } from '@backstage/plugin-permission-backend'; import { AuthorizeResult, PolicyDecision, } from '@backstage/plugin-permission-common'; -import { PermissionPolicy } from '@backstage/plugin-permission-node'; +import { + PermissionPolicy, + PolicyQuery, +} from '@backstage/plugin-permission-node'; +import { + DefaultPlaylistPermissionPolicy, + isPlaylistPermission, +} from '@backstage/plugin-playlist-backend'; import { Router } from 'express'; import { PluginEnvironment } from '../types'; -class AllowAllPermissionPolicy implements PermissionPolicy { - async handle(): Promise { +class ExamplePermissionPolicy implements PermissionPolicy { + private playlistPermissionPolicy = new DefaultPlaylistPermissionPolicy(); + + async handle( + request: PolicyQuery, + user?: BackstageIdentityResponse, + ): Promise { + if (isPlaylistPermission(request.permission)) { + return this.playlistPermissionPolicy.handle(request, user); + } + return { result: AuthorizeResult.ALLOW, }; @@ -38,7 +55,7 @@ export default async function createPlugin( config: env.config, logger: env.logger, discovery: env.discovery, - policy: new AllowAllPermissionPolicy(), + policy: new ExamplePermissionPolicy(), identity: env.identity, }); } diff --git a/packages/backend/src/plugins/playlist.ts b/packages/backend/src/plugins/playlist.ts new file mode 100644 index 0000000000..0d31158842 --- /dev/null +++ b/packages/backend/src/plugins/playlist.ts @@ -0,0 +1,37 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { IdentityClient } from '@backstage/plugin-auth-node'; +import { createRouter } from '@backstage/plugin-playlist-backend'; +import { Router } from 'express'; +import { PluginEnvironment } from '../types'; + +export default async function createPlugin({ + database, + discovery, + logger, + permissions, +}: PluginEnvironment): Promise { + return await createRouter({ + database, + identity: IdentityClient.create({ + discovery, + issuer: await discovery.getExternalBaseUrl('auth'), + }), + logger, + permissions, + }); +} diff --git a/packages/backend/src/types.ts b/packages/backend/src/types.ts index 831eaebb66..895581c702 100644 --- a/packages/backend/src/types.ts +++ b/packages/backend/src/types.ts @@ -24,11 +24,8 @@ import { UrlReader, } from '@backstage/backend-common'; import { PluginTaskScheduler } from '@backstage/backend-tasks'; -import { - PermissionAuthorizer, - PermissionEvaluator, -} from '@backstage/plugin-permission-common'; import { IdentityApi } from '@backstage/plugin-auth-node'; +import { PermissionEvaluator } from '@backstage/plugin-permission-common'; export type PluginEnvironment = { logger: Logger; @@ -38,7 +35,7 @@ export type PluginEnvironment = { reader: UrlReader; discovery: PluginEndpointDiscovery; tokenManager: TokenManager; - permissions: PermissionEvaluator | PermissionAuthorizer; + permissions: PermissionEvaluator; scheduler: PluginTaskScheduler; identity: IdentityApi; }; diff --git a/packages/core-components/api-report.md b/packages/core-components/api-report.md index 3dc4e2848e..20e14312bb 100644 --- a/packages/core-components/api-report.md +++ b/packages/core-components/api-report.md @@ -16,15 +16,18 @@ import { CardHeaderProps } from '@material-ui/core/CardHeader'; import { Column } from '@material-table/core'; import { ComponentClass } from 'react'; import { ComponentProps } from 'react'; +import { ComponentType } from 'react'; import { default as CSS_2 } from 'csstype'; import { CSSProperties } from 'react'; import { ElementType } from 'react'; import { ErrorInfo } from 'react'; import { IconComponent } from '@backstage/core-plugin-api'; +import { Icons } from '@material-table/core'; import { IdentityApi } from '@backstage/core-plugin-api'; import { LinearProgressProps } from '@material-ui/core/LinearProgress'; import { LinkProps as LinkProps_2 } from '@material-ui/core/Link'; import { LinkProps as LinkProps_3 } from 'react-router-dom'; +import { ListItemTextProps } from '@material-ui/core/ListItemText'; import MaterialBreadcrumbs from '@material-ui/core/Breadcrumbs'; import { MaterialTableProps } from '@material-table/core'; import { NavLinkProps } from 'react-router-dom'; @@ -50,6 +53,16 @@ import { Theme } from '@material-ui/core/styles'; import { TooltipProps } from '@material-ui/core/Tooltip'; import { WithStyles } from '@material-ui/core/styles'; +// @public (undocumented) +export type ActionItemProps = { + label?: ListItemTextProps['primary']; + secondaryLabel?: ListItemTextProps['secondary']; + icon?: ReactElement; + disabled?: boolean; + onClick?: (event: React_2.MouseEvent) => void; + WrapperComponent?: ComponentType; +}; + // @public (undocumented) export function AlertDisplay(props: AlertDisplayProps): JSX.Element | null; @@ -432,6 +445,14 @@ export function GroupIcon(props: IconComponentProps): JSX.Element; // @public export function Header(props: PropsWithChildren): JSX.Element; +// @public (undocumented) +export function HeaderActionMenu(props: HeaderActionMenuProps): JSX.Element; + +// @public (undocumented) +export type HeaderActionMenuProps = { + actionItems: ActionItemProps[]; +}; + // @public (undocumented) export type HeaderClassKey = | 'header' @@ -1333,6 +1354,12 @@ export type TabIconClassKey = 'root'; // @public (undocumented) export function Table(props: TableProps): JSX.Element; +// @public (undocumented) +export namespace Table { + var // (undocumented) + tableIcons: Readonly; +} + // Warning: (ae-missing-release-tag) "TableClassKey" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) diff --git a/packages/core-components/src/components/Table/Table.tsx b/packages/core-components/src/components/Table/Table.tsx index 65edb5b69b..b04c247b2f 100644 --- a/packages/core-components/src/components/Table/Table.tsx +++ b/packages/core-components/src/components/Table/Table.tsx @@ -292,6 +292,9 @@ export function TableToolbar(toolbarProps: { ); } +/** + * @public + */ export function Table(props: TableProps) { const { data, @@ -519,3 +522,5 @@ export function Table(props: TableProps) { ); } + +Table.tableIcons = Object.freeze(tableIcons); diff --git a/packages/core-components/src/layout/HeaderActionMenu/HeaderActionMenu.tsx b/packages/core-components/src/layout/HeaderActionMenu/HeaderActionMenu.tsx index d8dc398ce3..125363fe0a 100644 --- a/packages/core-components/src/layout/HeaderActionMenu/HeaderActionMenu.tsx +++ b/packages/core-components/src/layout/HeaderActionMenu/HeaderActionMenu.tsx @@ -23,9 +23,12 @@ import ListItemText, { ListItemTextProps, } from '@material-ui/core/ListItemText'; import Popover from '@material-ui/core/Popover'; -import { VerticalMenuIcon } from './VerticalMenuIcon'; +import MoreVert from '@material-ui/icons/MoreVert'; -type ActionItemProps = { +/** + * @public + */ +export type ActionItemProps = { label?: ListItemTextProps['primary']; secondaryLabel?: ListItemTextProps['secondary']; icon?: ReactElement; @@ -61,10 +64,16 @@ const ActionItem = ({ ); }; +/** + * @public + */ export type HeaderActionMenuProps = { actionItems: ActionItemProps[]; }; +/** + * @public + */ export function HeaderActionMenu(props: HeaderActionMenuProps) { const { actionItems } = props; const [open, setOpen] = React.useState(false); @@ -84,7 +93,7 @@ export function HeaderActionMenu(props: HeaderActionMenuProps) { padding: 0, }} > - + { + return await createRouter({ + database, + identity: IdentityClient.create({ + discovery, + issuer: await discovery.getExternalBaseUrl('auth'), + }), + logger, + permissions, + }); +} +``` + +With the `playlist.ts` router setup in place, add the router to `packages/backend/src/index.ts`: + +```diff ++import playlist from './plugins/playlist'; + +async function main() { + ... + const createEnv = makeCreateEnv(config); + + const catalogEnv = useHotMemoize(module, () => createEnv('catalog')); ++ const playlistEnv = useHotMemoize(module, () => createEnv('playlist')); + + const apiRouter = Router(); ++ apiRouter.use('/playlist', await playlist(playlistEnv)); + ... + apiRouter.use(notFoundHandler()); + +``` + +## Setting up plugin permissions + +You configure permissions for specific playlist actions by importing the supported set of permissions from the [playlist-common](../playlist-common/README.md) package along with the custom rules/conditions provided here to incorporate into your [permission policy](https://backstage.io/docs/permissions/writing-a-policy). + +This package also exports a `DefaultPlaylistPermissionPolicy` which contains a recommended default permissions policy you can apply as a "sub-policy" in your app: + +```diff +# packages/backend/src/plugins/permission.ts + ++import { DefaultPlaylistPermissionPolicy, isPlaylistPermission } from '@backstage/plugin-playlist-backend'; +... +class BackstagePermissionPolicy implements PermissionPolicy { ++ private playlistPermissionPolicy = new DefaultPlaylistPermissionPolicy(); + + async handle( + request: PolicyQuery, + user?: BackstageIdentityResponse, + ): Promise { ++ if (isPlaylistPermission(request.permission)) { ++ return this.playlistPermissionPolicy.handle(request, user); ++ } + ... + } +} + +export default async function createPlugin(env: PluginEnvironment): Promise { + return await createRouter({ + config: env.config, + logger: env.logger, + discovery: env.discovery, + policy: new BackstagePermissionPolicy(), + ... +``` diff --git a/plugins/playlist-backend/api-report.md b/plugins/playlist-backend/api-report.md new file mode 100644 index 0000000000..5c86b6ae45 --- /dev/null +++ b/plugins/playlist-backend/api-report.md @@ -0,0 +1,93 @@ +## API Report File for "@backstage/plugin-playlist-backend" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BackstageIdentityResponse } from '@backstage/plugin-auth-node'; +import { ConditionalPolicyDecision } from '@backstage/plugin-permission-common'; +import { Conditions } from '@backstage/plugin-permission-node'; +import express from 'express'; +import { IdentityClient } from '@backstage/plugin-auth-node'; +import { Logger } from 'winston'; +import { Permission } from '@backstage/plugin-permission-common'; +import { PermissionCondition } from '@backstage/plugin-permission-common'; +import { PermissionCriteria } from '@backstage/plugin-permission-common'; +import { PermissionEvaluator } from '@backstage/plugin-permission-common'; +import { PermissionPolicy } from '@backstage/plugin-permission-node'; +import { PermissionRule } from '@backstage/plugin-permission-node'; +import { PlaylistMetadata } from '@backstage/plugin-playlist-common'; +import { PluginDatabaseManager } from '@backstage/backend-common'; +import { PolicyDecision } from '@backstage/plugin-permission-common'; +import { PolicyQuery } from '@backstage/plugin-permission-node'; +import { ResourcePermission } from '@backstage/plugin-permission-common'; + +// @public (undocumented) +export const createPlaylistConditionalDecision: ( + permission: ResourcePermission<'playlist-list'>, + conditions: PermissionCriteria< + PermissionCondition<'playlist-list', unknown[]> + >, +) => ConditionalPolicyDecision; + +// @public (undocumented) +export function createRouter(options: RouterOptions): Promise; + +// @public +export class DefaultPlaylistPermissionPolicy implements PermissionPolicy { + // (undocumented) + handle( + request: PolicyQuery, + user?: BackstageIdentityResponse, + ): Promise; +} + +// @public (undocumented) +export const isPlaylistPermission: (permission: Permission) => boolean; + +// @public (undocumented) +export type ListPlaylistsFilter = + | { + allOf: ListPlaylistsFilter[]; + } + | { + anyOf: ListPlaylistsFilter[]; + } + | { + not: ListPlaylistsFilter; + } + | ListPlaylistsMatchFilter; + +// @public (undocumented) +export type ListPlaylistsMatchFilter = { + key: string; + values: any[]; +}; + +// @public (undocumented) +export const playlistConditions: Conditions<{ + isOwner: PermissionRule< + PlaylistMetadata, + ListPlaylistsFilter, + 'playlist-list', + [userOwnershipRefs: string[]] + >; + isPublic: PermissionRule< + PlaylistMetadata, + ListPlaylistsFilter, + 'playlist-list', + [] + >; +}>; + +// @public (undocumented) +export interface RouterOptions { + // (undocumented) + database: PluginDatabaseManager; + // (undocumented) + identity: IdentityClient; + // (undocumented) + logger: Logger; + // (undocumented) + permissions: PermissionEvaluator; +} +``` diff --git a/plugins/playlist-backend/migrations/20220701011329_init.js b/plugins/playlist-backend/migrations/20220701011329_init.js new file mode 100644 index 0000000000..17a71e8438 --- /dev/null +++ b/plugins/playlist-backend/migrations/20220701011329_init.js @@ -0,0 +1,60 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +exports.up = async function up(knex) { + await knex.schema.createTable('playlists', table => { + table.comment('Playlists table'); + table.uuid('id').primary().comment('Automatically generated unique ID'); + table.text('name').notNullable().comment('The name of the playlist'); + table.text('description').comment('The description of the playlist'); + table.string('owner').notNullable().comment('The owner entity ref'); + table + .boolean('public') + .defaultTo(false) + .notNullable() + .comment('Whether the playlist is public'); + }); + + await knex.schema.createTable('entities', table => { + table.comment('The table of playlist entities'); + table + .uuid('playlist_id') + .notNullable() + .references('playlists.id') + .onDelete('CASCADE') + .comment('The id of the playlist this entity belongs to'); + table.string('entity_ref').notNullable().comment('A entity ref'); + table.unique(['playlist_id', 'entity_ref']); + }); + + await knex.schema.createTable('followers', table => { + table.comment('The table of playlist followers'); + table + .uuid('playlist_id') + .notNullable() + .references('playlists.id') + .onDelete('CASCADE') + .comment('The id of the playlist being followed'); + table.string('user_ref').notNullable().comment('A user entity ref'); + table.unique(['playlist_id', 'user_ref']); + }); +}; + +exports.down = async function down(knex) { + await knex.schema.dropTable('playlists'); + await knex.schema.dropTable('entities'); + await knex.schema.dropTable('followers'); +}; diff --git a/plugins/playlist-backend/package.json b/plugins/playlist-backend/package.json new file mode 100644 index 0000000000..bbea8163fb --- /dev/null +++ b/plugins/playlist-backend/package.json @@ -0,0 +1,52 @@ +{ + "name": "@backstage/plugin-playlist-backend", + "version": "0.0.0", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "publishConfig": { + "access": "public", + "main": "dist/index.cjs.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "backend-plugin" + }, + "scripts": { + "start": "backstage-cli package start", + "build": "backstage-cli package build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "dependencies": { + "@backstage/backend-common": "^0.15.1-next.2", + "@backstage/backend-test-utils": "^0.1.28-next.2", + "@backstage/config": "^1.0.1", + "@backstage/errors": "^1.1.0", + "@backstage/plugin-auth-node": "^0.2.5-next.2", + "@backstage/plugin-permission-common": "^0.6.4-next.1", + "@backstage/plugin-permission-node": "^0.6.5-next.2", + "@backstage/plugin-playlist-common": "^0.0.0", + "@types/express": "*", + "express": "^4.17.1", + "express-promise-router": "^4.1.0", + "knex": "^2.0.0", + "node-fetch": "^2.6.7", + "uuid": "^8.2.0", + "winston": "^3.2.1", + "yn": "^4.0.0" + }, + "devDependencies": { + "@backstage/cli": "^0.19.0-next.2", + "@types/supertest": "^2.0.8", + "msw": "^0.47.0", + "supertest": "^6.1.3" + }, + "files": [ + "dist", + "migrations/**/*.{js,d.ts}" + ] +} diff --git a/plugins/playlist-backend/src/index.ts b/plugins/playlist-backend/src/index.ts new file mode 100644 index 0000000000..eeccd8913f --- /dev/null +++ b/plugins/playlist-backend/src/index.ts @@ -0,0 +1,28 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Playlist backend plugin + * + * @packageDocumentation + */ +export * from './service'; +export { + createPlaylistConditionalDecision, + DefaultPlaylistPermissionPolicy, + isPlaylistPermission, + playlistConditions, +} from './permissions'; diff --git a/plugins/playlist-backend/src/permissions/DefaultPlaylistPermissionPolicy.test.ts b/plugins/playlist-backend/src/permissions/DefaultPlaylistPermissionPolicy.test.ts new file mode 100644 index 0000000000..179b0d7f9b --- /dev/null +++ b/plugins/playlist-backend/src/permissions/DefaultPlaylistPermissionPolicy.test.ts @@ -0,0 +1,135 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { BackstageIdentityResponse } from '@backstage/plugin-auth-node'; +import { + AuthorizeResult, + createPermission, +} from '@backstage/plugin-permission-common'; +import { + permissions, + PLAYLIST_LIST_RESOURCE_TYPE, +} from '@backstage/plugin-playlist-common'; + +import { playlistConditions } from './conditions'; +import { DefaultPlaylistPermissionPolicy } from './DefaultPlaylistPermissionPolicy'; + +describe('DefaultPlaylistPermissionPolicy', () => { + const policy = new DefaultPlaylistPermissionPolicy(); + const mockUser: BackstageIdentityResponse = { + token: 'token', + identity: { + type: 'user', + ownershipEntityRefs: ['user:default/me', 'group:default/owner'], + userEntityRef: 'user:default/me', + }, + }; + + it('should deny non-playlist permissions', async () => { + const mockPermission = createPermission({ + name: 'test.permission', + attributes: { action: 'read' }, + }); + + expect(await policy.handle({ permission: mockPermission })).toEqual({ + result: AuthorizeResult.DENY, + }); + }); + + it('should allow create permissions', async () => { + expect( + await policy.handle({ permission: permissions.playlistListCreate }), + ).toEqual({ result: AuthorizeResult.ALLOW }); + }); + + it('should return a conditional decision for read permissions', async () => { + expect( + await policy.handle( + { permission: permissions.playlistListRead }, + mockUser, + ), + ).toEqual({ + result: AuthorizeResult.CONDITIONAL, + pluginId: 'playlist', + resourceType: PLAYLIST_LIST_RESOURCE_TYPE, + conditions: { + anyOf: [ + playlistConditions.isOwner([ + 'user:default/me', + 'group:default/owner', + ]), + playlistConditions.isPublic(), + ], + }, + }); + }); + + it('should return a conditional decision for followers update permissions', async () => { + expect( + await policy.handle( + { permission: permissions.playlistFollowersUpdate }, + mockUser, + ), + ).toEqual({ + result: AuthorizeResult.CONDITIONAL, + pluginId: 'playlist', + resourceType: PLAYLIST_LIST_RESOURCE_TYPE, + conditions: { + anyOf: [ + playlistConditions.isOwner([ + 'user:default/me', + 'group:default/owner', + ]), + playlistConditions.isPublic(), + ], + }, + }); + }); + + it('should return a conditional decision for update permissions', async () => { + expect( + await policy.handle( + { permission: permissions.playlistListUpdate }, + mockUser, + ), + ).toEqual({ + result: AuthorizeResult.CONDITIONAL, + pluginId: 'playlist', + resourceType: PLAYLIST_LIST_RESOURCE_TYPE, + conditions: playlistConditions.isOwner([ + 'user:default/me', + 'group:default/owner', + ]), + }); + }); + + it('should return a conditional decision for delete permissions', async () => { + expect( + await policy.handle( + { permission: permissions.playlistListDelete }, + mockUser, + ), + ).toEqual({ + result: AuthorizeResult.CONDITIONAL, + pluginId: 'playlist', + resourceType: PLAYLIST_LIST_RESOURCE_TYPE, + conditions: playlistConditions.isOwner([ + 'user:default/me', + 'group:default/owner', + ]), + }); + }); +}); diff --git a/plugins/playlist-backend/src/permissions/DefaultPlaylistPermissionPolicy.ts b/plugins/playlist-backend/src/permissions/DefaultPlaylistPermissionPolicy.ts new file mode 100644 index 0000000000..86d103e789 --- /dev/null +++ b/plugins/playlist-backend/src/permissions/DefaultPlaylistPermissionPolicy.ts @@ -0,0 +1,90 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { BackstageIdentityResponse } from '@backstage/plugin-auth-node'; +import { + AuthorizeResult, + isPermission, + Permission, + PolicyDecision, +} from '@backstage/plugin-permission-common'; +import { + PermissionPolicy, + PolicyQuery, +} from '@backstage/plugin-permission-node'; +import { permissions } from '@backstage/plugin-playlist-common'; + +import { + createPlaylistConditionalDecision, + playlistConditions, +} from './conditions'; + +/** + * @public + */ +export const isPlaylistPermission = (permission: Permission) => + Object.values(permissions).some(playlistPermission => + isPermission(permission, playlistPermission), + ); + +/** + * Default policy for the Playlist plugin. This should be applied as a "sub-policy" + * of your master permission policy for Playlist permission requests only. + * + * @public + */ +export class DefaultPlaylistPermissionPolicy implements PermissionPolicy { + async handle( + request: PolicyQuery, + user?: BackstageIdentityResponse, + ): Promise { + // Reject permissions we don't know how to evaluate in case this policy was incorrectly applied + if (!isPlaylistPermission(request.permission)) { + return { result: AuthorizeResult.DENY }; + } + + // Anyone should be allowed to create a new playlist + if (isPermission(request.permission, permissions.playlistListCreate)) { + return { result: AuthorizeResult.ALLOW }; + } + + // Reading and following/unfollowing playlists is allowed if it is public or owned + if ( + isPermission(request.permission, permissions.playlistListRead) || + isPermission(request.permission, permissions.playlistFollowersUpdate) + ) { + return createPlaylistConditionalDecision(request.permission, { + anyOf: [ + playlistConditions.isOwner(user?.identity.ownershipEntityRefs ?? []), + playlistConditions.isPublic(), + ], + }); + } + + // Updating or deleting playlists is only allowed for owners + if ( + isPermission(request.permission, permissions.playlistListUpdate) || + isPermission(request.permission, permissions.playlistListDelete) + ) { + return createPlaylistConditionalDecision( + request.permission, + playlistConditions.isOwner(user?.identity.ownershipEntityRefs ?? []), + ); + } + + return { result: AuthorizeResult.ALLOW }; + } +} diff --git a/plugins/playlist-backend/src/permissions/conditions.ts b/plugins/playlist-backend/src/permissions/conditions.ts new file mode 100644 index 0000000000..8162c1046f --- /dev/null +++ b/plugins/playlist-backend/src/permissions/conditions.ts @@ -0,0 +1,44 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { PLAYLIST_LIST_RESOURCE_TYPE } from '@backstage/plugin-playlist-common'; +import { + ConditionTransformer, + createConditionExports, + createConditionTransformer, +} from '@backstage/plugin-permission-node'; + +import { ListPlaylistsFilter } from '../service'; +import { rules } from './rules'; + +const { conditions, createConditionalDecision } = createConditionExports({ + pluginId: 'playlist', + resourceType: PLAYLIST_LIST_RESOURCE_TYPE, + rules, +}); + +/** + * @public + */ +export const playlistConditions = conditions; + +/** + * @public + */ +export const createPlaylistConditionalDecision = createConditionalDecision; + +export const transformConditions: ConditionTransformer = + createConditionTransformer(Object.values(rules)); diff --git a/plugins/playlist-backend/src/permissions/index.ts b/plugins/playlist-backend/src/permissions/index.ts new file mode 100644 index 0000000000..a6bb633a1e --- /dev/null +++ b/plugins/playlist-backend/src/permissions/index.ts @@ -0,0 +1,19 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './conditions'; +export * from './rules'; +export * from './DefaultPlaylistPermissionPolicy'; diff --git a/plugins/playlist-backend/src/permissions/rules.ts b/plugins/playlist-backend/src/permissions/rules.ts new file mode 100644 index 0000000000..cbf81bee65 --- /dev/null +++ b/plugins/playlist-backend/src/permissions/rules.ts @@ -0,0 +1,54 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { makeCreatePermissionRule } from '@backstage/plugin-permission-node'; +import { + PLAYLIST_LIST_RESOURCE_TYPE, + PlaylistMetadata, +} from '@backstage/plugin-playlist-common'; + +import { ListPlaylistsFilter } from '../service'; + +const createPlaylistPermissionRule = makeCreatePermissionRule< + PlaylistMetadata, + ListPlaylistsFilter, + typeof PLAYLIST_LIST_RESOURCE_TYPE +>(); + +const isOwner = createPlaylistPermissionRule({ + name: 'IS_OWNER', + description: 'Should allow only if the playlist belongs to the user', + resourceType: PLAYLIST_LIST_RESOURCE_TYPE, + apply: (list: PlaylistMetadata, userOwnershipRefs: string[]) => + userOwnershipRefs.includes(list.owner), + toQuery: (userOwnershipRefs: string[]) => ({ + key: 'owner', + values: userOwnershipRefs, + }), +}); + +const isPublic = createPlaylistPermissionRule({ + name: 'IS_PUBLIC', + description: 'Should allow only if the playlist is public', + resourceType: PLAYLIST_LIST_RESOURCE_TYPE, + apply: (list: PlaylistMetadata) => list.public, + toQuery: () => ({ key: 'public', values: [true] }), +}); + +/** + * @public + */ +export const rules = { isOwner, isPublic }; diff --git a/plugins/playlist-backend/src/run.ts b/plugins/playlist-backend/src/run.ts new file mode 100644 index 0000000000..d945aa13f0 --- /dev/null +++ b/plugins/playlist-backend/src/run.ts @@ -0,0 +1,33 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { getRootLogger } from '@backstage/backend-common'; +import yn from 'yn'; +import { startStandaloneServer } from './service/standaloneServer'; + +const port = process.env.PLUGIN_PORT ? Number(process.env.PLUGIN_PORT) : 7007; +const enableCors = yn(process.env.PLUGIN_CORS, { default: false }); +const logger = getRootLogger(); + +startStandaloneServer({ port, enableCors, logger }).catch(err => { + logger.error(err); + process.exit(1); +}); + +process.on('SIGINT', () => { + logger.info('CTRL+C pressed; exiting.'); + process.exit(0); +}); diff --git a/plugins/playlist-backend/src/service/DatabaseHandler.test.ts b/plugins/playlist-backend/src/service/DatabaseHandler.test.ts new file mode 100644 index 0000000000..5d6b4aa0ca --- /dev/null +++ b/plugins/playlist-backend/src/service/DatabaseHandler.test.ts @@ -0,0 +1,349 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { DatabaseHandler } from './DatabaseHandler'; +import { TestDatabaseId, TestDatabases } from '@backstage/backend-test-utils'; +import { BackstageUserIdentity } from '@backstage/plugin-auth-node'; +import { Knex } from 'knex'; +import { v4 as uuid } from 'uuid'; + +describe('DatabaseHandler', () => { + const databases = TestDatabases.create(); + + async function createDatabaseHandler(databaseId: TestDatabaseId) { + const knex = await databases.init(databaseId); + return { + knex, + dbHandler: await DatabaseHandler.create({ database: knex }), + }; + } + + describe.each(databases.eachSupportedId())( + '%p', + databaseId => { + let knex: Knex; + let dbHandler: DatabaseHandler; + const playlist1Id = uuid(); + const playlist2Id = uuid(); + const playlist3Id = uuid(); + const user: BackstageUserIdentity = { + type: 'user', + userEntityRef: 'user:default/foo', + ownershipEntityRefs: ['user:default/foo', 'group:default/foo-group'], + }; + + beforeEach(async () => { + ({ knex, dbHandler } = await createDatabaseHandler(databaseId)); + await knex('playlists').insert([ + { + id: playlist1Id, + name: 'test', + description: 'test description', + owner: 'user:default/foo', + public: true, + }, + { + id: playlist2Id, + name: 'test 2', + description: 'test description 2', + owner: 'group:default/foo-group', + public: false, + }, + { + id: playlist3Id, + name: 'test 3', + description: 'test description 3', + owner: 'user:default/bar', + public: false, + }, + ]); + + await knex('entities').insert([ + { + playlist_id: playlist1Id, + entity_ref: 'component:default/ent0', + }, + { + playlist_id: playlist1Id, + entity_ref: 'component:default/ent1', + }, + { + playlist_id: playlist1Id, + entity_ref: 'component:default/ent2', + }, + { + playlist_id: playlist2Id, + entity_ref: 'component:default/ent1', + }, + ]); + + await knex('followers').insert([ + { + playlist_id: playlist2Id, + user_ref: 'user:default/some-user', + }, + { + playlist_id: playlist2Id, + user_ref: 'user:default/bar', + }, + { + playlist_id: playlist2Id, + user_ref: 'user:default/foo', + }, + { + playlist_id: playlist3Id, + user_ref: 'user:default/foo', + }, + ]); + }, 30000); + + it('listPlaylists', async () => { + const allPlaylists = [ + { + id: playlist1Id, + name: 'test', + description: 'test description', + owner: 'user:default/foo', + public: true, + entities: 3, + followers: 0, + isFollowing: false, + }, + { + id: playlist2Id, + name: 'test 2', + description: 'test description 2', + owner: 'group:default/foo-group', + public: false, + entities: 1, + followers: 3, + isFollowing: true, + }, + { + id: playlist3Id, + name: 'test 3', + description: 'test description 3', + owner: 'user:default/bar', + public: false, + entities: 0, + followers: 1, + isFollowing: true, + }, + ]; + + const playlists = await dbHandler.listPlaylists(user); + expect(playlists.length).toEqual(3); + expect(playlists).toEqual(expect.arrayContaining(allPlaylists)); + + const followedPlaylists = await dbHandler.listPlaylists(user, { + key: 'public', + values: [true], + }); + expect(followedPlaylists).toEqual([allPlaylists[0]]); + + const ownedPlaylists = await dbHandler.listPlaylists(user, { + key: 'owner', + values: user.ownershipEntityRefs, + }); + expect(ownedPlaylists.length).toEqual(2); + expect(ownedPlaylists).toEqual( + expect.arrayContaining([allPlaylists[0], allPlaylists[1]]), + ); + }); + + it('createPlaylist', async () => { + const newList = { + name: 'new list', + description: 'new description', + owner: 'user:default/new', + public: true, + }; + + const newPlaylistId = await dbHandler.createPlaylist(newList); + + const newPlaylist = await knex('playlists').where('id', newPlaylistId); + expect( + newPlaylist.map(list => ({ ...list, public: Boolean(list.public) })), + ).toEqual([ + { + ...newList, + id: newPlaylistId, + }, + ]); + }); + + it('getPlaylist', async () => { + const playlist = await dbHandler.getPlaylist(playlist1Id, user); + expect(playlist).toEqual({ + id: playlist1Id, + name: 'test', + description: 'test description', + owner: 'user:default/foo', + public: true, + entities: 3, + followers: 0, + isFollowing: false, + }); + }); + + it('updatePlaylist', async () => { + const update = { + id: playlist1Id, + name: 'test rename', + description: 'test new description', + owner: 'user:default/new-foo', + public: false, + }; + await dbHandler.updatePlaylist(update); + + const updatedPlaylist = await knex('playlists').where( + 'id', + playlist1Id, + ); + expect( + updatedPlaylist.map(list => ({ + ...list, + public: Boolean(list.public), + })), + ).toEqual([update]); + }); + + it('deletePlaylist', async () => { + await dbHandler.deletePlaylist(playlist1Id); + const deleted = await knex('playlists').where('id', playlist1Id); + expect(deleted.length).toEqual(0); + }); + + it('addPlaylistEntities', async () => { + await dbHandler.addPlaylistEntities(playlist1Id, [ + 'component:default/ent1', + 'component:default/ent3', + 'component:default/ent4', + ]); + + const entities = await knex('entities').where( + 'playlist_id', + playlist1Id, + ); + expect(entities.length).toEqual(5); + expect(entities).toEqual( + expect.arrayContaining([ + { + playlist_id: playlist1Id, + entity_ref: 'component:default/ent0', + }, + { + playlist_id: playlist1Id, + entity_ref: 'component:default/ent1', + }, + { + playlist_id: playlist1Id, + entity_ref: 'component:default/ent2', + }, + { + playlist_id: playlist1Id, + entity_ref: 'component:default/ent3', + }, + { + playlist_id: playlist1Id, + entity_ref: 'component:default/ent4', + }, + ]), + ); + }); + + it('getPlaylistEntities', async () => { + const entities = await dbHandler.getPlaylistEntities(playlist1Id); + expect(entities.length).toEqual(3); + expect(entities).toEqual( + expect.arrayContaining([ + 'component:default/ent0', + 'component:default/ent1', + 'component:default/ent2', + ]), + ); + }); + + it('removePlaylistEntities', async () => { + await dbHandler.removePlaylistEntities(playlist1Id, [ + 'component:default/ent1', + 'component:default/ent2', + ]); + + const entities = await knex('entities').where( + 'playlist_id', + playlist1Id, + ); + expect(entities).toEqual([ + { + playlist_id: playlist1Id, + entity_ref: 'component:default/ent0', + }, + ]); + }); + + it('followPlaylist', async () => { + await dbHandler.followPlaylist(playlist1Id, user); + + const playlist1Followers = await knex('followers').where( + 'playlist_id', + playlist1Id, + ); + expect(playlist1Followers).toEqual([ + { + playlist_id: playlist1Id, + user_ref: 'user:default/foo', + }, + ]); + + await dbHandler.followPlaylist(playlist3Id, user); + + const playlist3Followers = await knex('followers').where( + 'playlist_id', + playlist3Id, + ); + expect(playlist3Followers).toEqual([ + { + playlist_id: playlist3Id, + user_ref: 'user:default/foo', + }, + ]); + }); + + it('unfollowPlaylist', async () => { + await dbHandler.unfollowPlaylist(playlist2Id, user); + + const followers = await knex('followers').where( + 'playlist_id', + playlist2Id, + ); + expect(followers).toEqual( + expect.arrayContaining([ + { + playlist_id: playlist2Id, + user_ref: 'user:default/some-user', + }, + { + playlist_id: playlist2Id, + user_ref: 'user:default/bar', + }, + ]), + ); + }); + }, + 60000, + ); +}); diff --git a/plugins/playlist-backend/src/service/DatabaseHandler.ts b/plugins/playlist-backend/src/service/DatabaseHandler.ts new file mode 100644 index 0000000000..6118f22ff9 --- /dev/null +++ b/plugins/playlist-backend/src/service/DatabaseHandler.ts @@ -0,0 +1,278 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { resolvePackagePath } from '@backstage/backend-common'; +import { BackstageUserIdentity } from '@backstage/plugin-auth-node'; +import { Playlist, PlaylistMetadata } from '@backstage/plugin-playlist-common'; +import { Knex } from 'knex'; +import { v4 as uuid } from 'uuid'; + +import { + ListPlaylistsFilter, + ListPlaylistsMatchFilter, +} from './ListPlaylistsFilter'; + +const migrationsDir = resolvePackagePath( + '@backstage/plugin-playlist-backend', + 'migrations', +); + +function isMatchFilter( + filter: ListPlaylistsMatchFilter | ListPlaylistsFilter, +): filter is ListPlaylistsMatchFilter { + return filter.hasOwnProperty('key'); +} + +function isOrFilter( + filter: { anyOf: ListPlaylistsFilter[] } | ListPlaylistsFilter, +): filter is { anyOf: ListPlaylistsFilter[] } { + return filter.hasOwnProperty('anyOf'); +} + +function isNegationFilter( + filter: { not: ListPlaylistsFilter } | ListPlaylistsFilter, +): filter is { not: ListPlaylistsFilter } { + return filter.hasOwnProperty('not'); +} + +function parseFilter( + filter: ListPlaylistsFilter, + query: Knex.QueryBuilder, + db: Knex, + negate: boolean = false, +): Knex.QueryBuilder { + if (isMatchFilter(filter)) { + return query.andWhere(function filterFunction() { + if (filter.values.length === 1) { + this.where(filter.key, negate ? '!=' : '=', filter.values[0]); + } else { + this.andWhere(filter.key, negate ? 'not in' : 'in', filter.values); + } + }); + } + + if (isNegationFilter(filter)) { + return parseFilter(filter.not, query, db, !negate); + } + + return query[negate ? 'andWhereNot' : 'andWhere'](function filterFunction() { + if (isOrFilter(filter)) { + for (const subFilter of filter.anyOf ?? []) { + this.orWhere(subQuery => parseFilter(subFilter, subQuery, db)); + } + } else { + for (const subFilter of filter.allOf ?? []) { + this.andWhere(subQuery => parseFilter(subFilter, subQuery, db)); + } + } + }); +} + +type Options = { + database: Knex; +}; + +/** + * @public + */ +export class DatabaseHandler { + static async create(options: Options): Promise { + const { database } = options; + + await database.migrate.latest({ + directory: migrationsDir, + }); + + return new DatabaseHandler(options); + } + + private readonly database: Knex; + + private constructor(options: Options) { + this.database = options.database; + } + + private playlistColumns = ['id', 'name', 'description', 'owner', 'public']; + + async listPlaylists( + user: BackstageUserIdentity, + filter?: ListPlaylistsFilter, + ): Promise { + let playlistQuery = this.database>( + 'playlists', + ) + .select( + ...this.playlistColumns, + this.database.raw('COALESCE(entities, 0) AS entities'), + this.database.raw('COALESCE(followers, 0) AS followers'), + ) + .leftOuterJoin( + this.database('entities') + .as('e') + .select('playlist_id') + .count('entity_ref', { as: 'entities' }) + .groupBy('playlist_id'), + 'playlists.id', + 'e.playlist_id', + ) + .leftOuterJoin( + this.database('followers') + .as('f') + .select('playlist_id') + .count('user_ref', { as: 'followers' }) + .groupBy('playlist_id'), + 'playlists.id', + 'f.playlist_id', + ); + + if (filter) { + playlistQuery = parseFilter(filter, playlistQuery, this.database); + } + + const playlists = await playlistQuery; + + const followedPlaylists = ( + await this.database('followers') + .select('playlist_id') + .where('user_ref', user.userEntityRef) + ).map(follows => follows.playlist_id); + + return playlists.map(list => ({ + ...list, + entities: Number(list.entities), + followers: Number(list.followers), + public: Boolean(list.public), + isFollowing: followedPlaylists.includes(list.id), + })); + } + + async createPlaylist( + playlist: Omit, + ): Promise { + const id = uuid(); + const newPlaylist = await this.database('playlists').insert( + { + ...playlist, + id, + }, + ['id'], + ); + + // MySQL does not support returning from inserts so return generated uuid if undefined + return newPlaylist[0].id ?? id; + } + + async getPlaylist( + id: string, + user?: BackstageUserIdentity, + ): Promise { + const playlist = await this.database>( + 'playlists', + ) + .select( + ...this.playlistColumns, + this.database.raw('COALESCE(entities, 0) AS entities'), + this.database.raw('COALESCE(followers, 0) AS followers'), + ) + .where('id', id) + .leftOuterJoin( + this.database('entities') + .as('e') + .select('playlist_id') + .count('entity_ref', { as: 'entities' }) + .groupBy('playlist_id'), + 'playlists.id', + 'e.playlist_id', + ) + .leftOuterJoin( + this.database('followers') + .as('f') + .select('playlist_id') + .count('user_ref', { as: 'followers' }) + .groupBy('playlist_id'), + 'playlists.id', + 'f.playlist_id', + ); + + if (!playlist.length) { + return undefined; + } + + const followedPlaylists = user + ? ( + await this.database('followers') + .select('playlist_id') + .where('user_ref', user.userEntityRef) + ).map(follows => follows.playlist_id) + : []; + + return { + ...playlist[0], + entities: Number(playlist[0].entities), + followers: Number(playlist[0].followers), + public: Boolean(playlist[0].public), + isFollowing: followedPlaylists.includes(playlist[0].id), + }; + } + + async updatePlaylist(playlist: PlaylistMetadata) { + await this.database('playlists').where('id', playlist.id).update(playlist); + } + + async deletePlaylist(id: string) { + await this.database('playlists').where('id', id).del(); + } + + async addPlaylistEntities(playlistId: string, entityRefs: string[]) { + await this.database('entities') + .insert( + entityRefs.map(ref => ({ playlist_id: playlistId, entity_ref: ref })), + ) + .onConflict(['playlist_id', 'entity_ref']) + .ignore(); + } + + async getPlaylistEntities(playlistId: string): Promise { + return ( + await this.database('entities') + .select('entity_ref') + .where('playlist_id', playlistId) + ).map(entity => entity.entity_ref); + } + + async removePlaylistEntities(playlistId: string, entityRefs: string[]) { + await this.database('entities') + .where(builder => + entityRefs.forEach(ref => + builder.orWhere({ playlist_id: playlistId, entity_ref: ref }), + ), + ) + .del(); + } + + async followPlaylist(playlistId: string, user: BackstageUserIdentity) { + await this.database('followers') + .insert({ playlist_id: playlistId, user_ref: user.userEntityRef }) + .onConflict(['playlist_id', 'user_ref']) + .ignore(); + } + + async unfollowPlaylist(playlistId: string, user: BackstageUserIdentity) { + await this.database('followers') + .where({ playlist_id: playlistId, user_ref: user.userEntityRef }) + .del(); + } +} diff --git a/plugins/playlist-backend/src/service/ListPlaylistsFilter.test.ts b/plugins/playlist-backend/src/service/ListPlaylistsFilter.test.ts new file mode 100644 index 0000000000..64405fa6d0 --- /dev/null +++ b/plugins/playlist-backend/src/service/ListPlaylistsFilter.test.ts @@ -0,0 +1,95 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + parseListPlaylistsFilterParams, + parseListPlaylistsFilterString, +} from './ListPlaylistsFilter'; + +describe('parseListPlaylistsFilterParams', () => { + it('translates empty query to empty list', () => { + const result = parseListPlaylistsFilterParams({}); + expect(result).toEqual(undefined); + }); + + it('supports single-string format', () => { + const result = parseListPlaylistsFilterParams({ filter: 'a=1' })!; + expect(result).toEqual({ + anyOf: [{ allOf: [{ key: 'a', values: ['1'] }] }], + }); + }); + + it('supports array-of-strings format', () => { + const result = parseListPlaylistsFilterParams({ + filter: ['a=1', 'b=2'], + }); + expect(result).toEqual({ + anyOf: [ + { allOf: [{ key: 'a', values: ['1'] }] }, + { allOf: [{ key: 'b', values: ['2'] }] }, + ], + }); + }); + + it('merges values within each filter', () => { + const result = parseListPlaylistsFilterParams({ + filter: ['a=1', 'b=2,b=3,c=4'], + }); + expect(result).toEqual({ + anyOf: [ + { allOf: [{ key: 'a', values: ['1'] }] }, + { + allOf: [ + { key: 'b', values: ['2', '3'] }, + { key: 'c', values: ['4'] }, + ], + }, + ], + }); + }); + + it('throws for non-strings', () => { + expect(() => parseListPlaylistsFilterParams({ filter: [3] })).toThrow( + 'Invalid filter', + ); + }); +}); + +describe('parseListPlaylistsFilterString', () => { + it('works for the happy path', () => { + expect(parseListPlaylistsFilterString('')).toBeUndefined(); + expect(parseListPlaylistsFilterString('a=1,b=2,a=3')).toEqual([ + { key: 'a', values: ['1', '3'] }, + { key: 'b', values: ['2'] }, + ]); + }); + + it('trims values', () => { + expect(parseListPlaylistsFilterString(' a = 1 , b = 2 , a = 3 ')).toEqual([ + { key: 'a', values: ['1', '3'] }, + { key: 'b', values: ['2'] }, + ]); + }); + + it('rejects malformed strings', () => { + expect(() => parseListPlaylistsFilterString('x=2,=a')).toThrow( + "Invalid filter, '=a' is not a valid statement (expected a string of the form a=b)", + ); + expect(() => parseListPlaylistsFilterString('x=2,a=')).toThrow( + "Invalid filter, 'a=' is not a valid statement (expected a string of the form a=b)", + ); + }); +}); diff --git a/plugins/playlist-backend/src/service/ListPlaylistsFilter.ts b/plugins/playlist-backend/src/service/ListPlaylistsFilter.ts new file mode 100644 index 0000000000..bff14b2a58 --- /dev/null +++ b/plugins/playlist-backend/src/service/ListPlaylistsFilter.ts @@ -0,0 +1,101 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { InputError } from '@backstage/errors'; + +// TODO(kuangp): this filter shape was basically plagiarized from catalog-backend, +// it should probably be abstracted into a common plugin module to allow others to reuse the same pattern + +/** + * @public + */ +export type ListPlaylistsMatchFilter = { + key: string; + values: any[]; +}; + +/** + * @public + */ +export type ListPlaylistsFilter = + | { allOf: ListPlaylistsFilter[] } + | { anyOf: ListPlaylistsFilter[] } + | { not: ListPlaylistsFilter } + | ListPlaylistsMatchFilter; + +export function parseListPlaylistsFilterParams( + params: Record, +): ListPlaylistsFilter | undefined { + if (!params.filter) { + return undefined; + } + + // Each filter string is on the form a=b,c=d + const filterStrings = [params.filter].flat(); + if (filterStrings.some(p => typeof p !== 'string')) { + throw new InputError('Invalid filter'); + } + + // Outer array: "any of the inner ones" + // Inner arrays: "all of these must match" + const filters = (filterStrings as string[]) + .map(parseListPlaylistsFilterString) + .filter(Boolean); + if (!filters.length) { + return undefined; + } + + return { anyOf: filters.map(f => ({ allOf: f! })) }; +} + +export function parseListPlaylistsFilterString( + filterString: string, +): ListPlaylistsMatchFilter[] | undefined { + const statements = filterString + .split(',') + .map(s => s.trim()) + .filter(Boolean); + + if (!statements.length) { + return undefined; + } + + const filtersByKey: Record = {}; + + for (const statement of statements) { + const equalsIndex = statement.indexOf('='); + + const key = + equalsIndex === -1 ? statement : statement.substr(0, equalsIndex).trim(); + const value = + equalsIndex === -1 ? undefined : statement.substr(equalsIndex + 1).trim(); + + if (!key || !value) { + throw new InputError( + `Invalid filter, '${statement}' is not a valid statement (expected a string of the form a=b)`, + ); + } + + const f = + key in filtersByKey + ? filtersByKey[key] + : (filtersByKey[key] = { key, values: [] }); + + f.values.push(value); + } + + return Object.values(filtersByKey); +} diff --git a/plugins/playlist-backend/src/service/index.ts b/plugins/playlist-backend/src/service/index.ts new file mode 100644 index 0000000000..3a1499f495 --- /dev/null +++ b/plugins/playlist-backend/src/service/index.ts @@ -0,0 +1,21 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './router'; +export type { + ListPlaylistsFilter, + ListPlaylistsMatchFilter, +} from './ListPlaylistsFilter'; diff --git a/plugins/playlist-backend/src/service/router.test.ts b/plugins/playlist-backend/src/service/router.test.ts new file mode 100644 index 0000000000..06185acae8 --- /dev/null +++ b/plugins/playlist-backend/src/service/router.test.ts @@ -0,0 +1,511 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { DatabaseManager, getVoidLogger } from '@backstage/backend-common'; +import { ConfigReader } from '@backstage/config'; +import { IdentityClient } from '@backstage/plugin-auth-node'; +import { AuthorizeResult } from '@backstage/plugin-permission-common'; +import { permissions } from '@backstage/plugin-playlist-common'; +import express from 'express'; +import request from 'supertest'; + +import { createRouter } from './router'; + +jest.mock('@backstage/plugin-auth-node', () => ({ + ...jest.requireActual('@backstage/plugin-auth-node'), + getBearerTokenFromAuthorizationHeader: () => 'token', +})); + +const mockConditionFilter = { key: 'test', values: ['test-val'] }; +jest.mock('../permissions', () => ({ + ...jest.requireActual('../permissions'), + transformConditions: () => mockConditionFilter, +})); + +const mockPlaylist = { + id: 'playlist-id', + name: 'test-playlist', + owner: 'group:default/owner', + public: true, + entities: 2, + followers: 4, + isFollowing: false, +}; + +const mockEntities = [ + 'component:default/test-ent', + 'system:default/test-ent-system', +]; + +const mockDbHandler = { + listPlaylists: jest.fn().mockImplementation(async () => [mockPlaylist]), + createPlaylist: jest.fn().mockImplementation(async () => 'playlist-id'), + getPlaylist: jest.fn().mockImplementation(async () => mockPlaylist), + updatePlaylist: jest.fn().mockImplementation(async () => {}), + deletePlaylist: jest.fn().mockImplementation(async () => {}), + addPlaylistEntities: jest.fn().mockImplementation(async () => {}), + getPlaylistEntities: jest.fn().mockImplementation(async () => mockEntities), + removePlaylistEntities: jest.fn().mockImplementation(async () => {}), + followPlaylist: jest.fn().mockImplementation(async () => {}), + unfollowPlaylist: jest.fn().mockImplementation(async () => {}), +}; + +jest.mock('./DatabaseHandler', () => ({ + DatabaseHandler: { create: async () => mockDbHandler }, +})); + +describe('createRouter', () => { + let app: express.Express; + + const createDatabase = () => + DatabaseManager.fromConfig( + new ConfigReader({ + backend: { + database: { + client: 'better-sqlite3', + connection: ':memory:', + }, + }, + }), + ).forPlugin('playlist'); + + const mockedAuthorize = jest + .fn() + .mockImplementation(async () => [{ result: AuthorizeResult.ALLOW }]); + const mockedAuthorizeConditional = jest + .fn() + .mockImplementation(async () => [{ result: AuthorizeResult.ALLOW }]); + const mockPermissionEvaluator = { + authorize: mockedAuthorize, + authorizeConditional: mockedAuthorizeConditional, + }; + + const mockUser = { + type: 'user', + ownershipEntityRefs: ['user:default/me', 'group:default/owner'], + userEntityRef: 'user:default/me', + }; + const mockIdentityClient = { + authenticate: jest + .fn() + .mockImplementation(async () => ({ identity: mockUser })), + } as unknown as IdentityClient; + + beforeEach(async () => { + const router = await createRouter({ + database: createDatabase(), + identity: mockIdentityClient, + logger: getVoidLogger(), + permissions: mockPermissionEvaluator, + }); + + app = express().use(router); + jest.clearAllMocks(); + }); + + describe('GET /', () => { + const mockRequestFilter = { + anyOf: [ + { allOf: [{ key: 'mock', values: ['test'] }] }, + { allOf: [{ key: 'foo', values: ['bar'] }] }, + ], + }; + + it('should respond correctly if unauthorized', async () => { + mockedAuthorizeConditional.mockImplementationOnce(async () => [ + { result: AuthorizeResult.DENY }, + ]); + const response = await request(app).get('/').send(); + + expect(mockedAuthorizeConditional).toHaveBeenCalledWith( + [{ permission: permissions.playlistListRead }], + { token: 'token' }, + ); + expect(mockDbHandler.listPlaylists).not.toHaveBeenCalled(); + expect(response.status).toEqual(403); + }); + + it('should get playlists correctly', async () => { + let response = await request(app).get('/').send(); + expect(mockDbHandler.listPlaylists).toHaveBeenLastCalledWith( + mockUser, + undefined, + ); + expect(response.status).toEqual(200); + expect(response.body).toEqual([mockPlaylist]); + + mockedAuthorizeConditional.mockImplementationOnce(async () => [ + { result: AuthorizeResult.CONDITIONAL }, + ]); + response = await request(app).get('/').send(); + expect(mockDbHandler.listPlaylists).toHaveBeenLastCalledWith( + mockUser, + mockConditionFilter, + ); + expect(response.status).toEqual(200); + expect(response.body).toEqual([mockPlaylist]); + }); + + it('should get filtered playlists correctly', async () => { + let response = await request(app) + .get('/?filter=mock=test&filter=foo=bar') + .send(); + expect(mockDbHandler.listPlaylists).toHaveBeenLastCalledWith( + mockUser, + mockRequestFilter, + ); + expect(response.status).toEqual(200); + expect(response.body).toEqual([mockPlaylist]); + + mockedAuthorizeConditional.mockImplementationOnce(async () => [ + { result: AuthorizeResult.CONDITIONAL }, + ]); + response = await request(app) + .get('/?filter=mock=test&filter=foo=bar') + .send(); + expect(mockDbHandler.listPlaylists).toHaveBeenLastCalledWith(mockUser, { + allOf: [mockRequestFilter, mockConditionFilter], + }); + expect(response.status).toEqual(200); + expect(response.body).toEqual([mockPlaylist]); + }); + + it('should get editable playlists correctly', async () => { + let response = await request(app).get('/?editable=true').send(); + expect(mockedAuthorizeConditional).toHaveBeenCalledWith( + [{ permission: permissions.playlistListUpdate }], + { token: 'token' }, + ); + expect(mockDbHandler.listPlaylists).toHaveBeenLastCalledWith( + mockUser, + undefined, + ); + expect(response.status).toEqual(200); + expect(response.body).toEqual([mockPlaylist]); + + response = await request(app) + .get('/?editable=true&filter=mock=test&filter=foo=bar') + .send(); + expect(mockDbHandler.listPlaylists).toHaveBeenLastCalledWith( + mockUser, + mockRequestFilter, + ); + expect(response.status).toEqual(200); + expect(response.body).toEqual([mockPlaylist]); + + mockedAuthorizeConditional.mockImplementation(async () => [ + { result: AuthorizeResult.CONDITIONAL }, + ]); + response = await request(app).get('/?editable=true').send(); + expect(mockDbHandler.listPlaylists).toHaveBeenLastCalledWith(mockUser, { + allOf: [mockConditionFilter, mockConditionFilter], + }); + expect(response.status).toEqual(200); + expect(response.body).toEqual([mockPlaylist]); + + mockedAuthorizeConditional.mockImplementation(async () => [ + { result: AuthorizeResult.CONDITIONAL }, + ]); + response = await request(app) + .get('/?editable=true&filter=mock=test&filter=foo=bar') + .send(); + expect(mockDbHandler.listPlaylists).toHaveBeenLastCalledWith(mockUser, { + allOf: [ + { allOf: [mockRequestFilter, mockConditionFilter] }, + mockConditionFilter, + ], + }); + expect(response.status).toEqual(200); + expect(response.body).toEqual([mockPlaylist]); + }); + }); + + describe('POST /', () => { + const body = { name: 'new-playlist' }; + + it('should respond correctly if unauthorized', async () => { + mockedAuthorize.mockImplementationOnce(async () => [ + { result: AuthorizeResult.DENY }, + ]); + const response = await request(app).post('/').send(body); + + expect(mockedAuthorize).toHaveBeenCalledWith( + [{ permission: permissions.playlistListCreate }], + { token: 'token' }, + ); + expect(mockDbHandler.createPlaylist).not.toHaveBeenCalled(); + expect(response.status).toEqual(403); + }); + + it('should create a playlist correctly', async () => { + const response = await request(app).post('/').send(body); + expect(mockDbHandler.createPlaylist).toHaveBeenCalledWith(body); + expect(response.status).toEqual(201); + expect(response.body).toEqual('playlist-id'); + }); + }); + + describe('GET /:playlistId', () => { + it('should respond correctly if unauthorized', async () => { + mockedAuthorize.mockImplementationOnce(async () => [ + { result: AuthorizeResult.DENY }, + ]); + const response = await request(app).get('/playlist-id').send(); + + expect(mockedAuthorize).toHaveBeenCalledWith( + [ + { + permission: permissions.playlistListRead, + resourceRef: 'playlist-id', + }, + ], + { token: 'token' }, + ); + expect(mockDbHandler.getPlaylist).not.toHaveBeenCalled(); + expect(response.status).toEqual(403); + }); + + it('should get a playlist correctly', async () => { + const response = await request(app).get('/playlist-id').send(); + expect(mockDbHandler.getPlaylist).toHaveBeenCalledWith( + 'playlist-id', + mockUser, + ); + expect(response.status).toEqual(200); + expect(response.body).toEqual(mockPlaylist); + }); + }); + + describe('PUT /:playlistId', () => { + it('should respond correctly if unauthorized', async () => { + mockedAuthorize.mockImplementationOnce(async () => [ + { result: AuthorizeResult.DENY }, + ]); + const response = await request(app) + .put('/playlist-id') + .send(mockPlaylist); + + expect(mockedAuthorize).toHaveBeenCalledWith( + [ + { + permission: permissions.playlistListUpdate, + resourceRef: 'playlist-id', + }, + ], + { token: 'token' }, + ); + expect(mockDbHandler.updatePlaylist).not.toHaveBeenCalled(); + expect(response.status).toEqual(403); + }); + + it('should update a playlist correctly', async () => { + const response = await request(app) + .put('/playlist-id') + .send(mockPlaylist); + expect(mockDbHandler.updatePlaylist).toHaveBeenCalledWith(mockPlaylist); + expect(response.status).toEqual(200); + }); + }); + + describe('DELETE /:playlistId', () => { + it('should respond correctly if unauthorized', async () => { + mockedAuthorize.mockImplementationOnce(async () => [ + { result: AuthorizeResult.DENY }, + ]); + const response = await request(app).delete('/playlist-id').send(); + + expect(mockedAuthorize).toHaveBeenCalledWith( + [ + { + permission: permissions.playlistListDelete, + resourceRef: 'playlist-id', + }, + ], + { token: 'token' }, + ); + expect(mockDbHandler.deletePlaylist).not.toHaveBeenCalled(); + expect(response.status).toEqual(403); + }); + + it('should delete a playlist correctly', async () => { + const response = await request(app).delete('/playlist-id').send(); + expect(mockDbHandler.deletePlaylist).toHaveBeenCalledWith('playlist-id'); + expect(response.status).toEqual(200); + }); + }); + + describe('POST /:playlistId/entities', () => { + it('should respond correctly if unauthorized', async () => { + mockedAuthorize.mockImplementationOnce(async () => [ + { result: AuthorizeResult.DENY }, + ]); + const response = await request(app) + .post('/playlist-id/entities') + .send(['component:default/test-ent']); + + expect(mockedAuthorize).toHaveBeenCalledWith( + [ + { + permission: permissions.playlistListUpdate, + resourceRef: 'playlist-id', + }, + ], + { token: 'token' }, + ); + expect(mockDbHandler.addPlaylistEntities).not.toHaveBeenCalled(); + expect(response.status).toEqual(403); + }); + + it('should add entities to a playlist correctly', async () => { + const response = await request(app) + .post('/playlist-id/entities') + .send(mockEntities); + expect(mockDbHandler.addPlaylistEntities).toHaveBeenCalledWith( + 'playlist-id', + mockEntities, + ); + expect(response.status).toEqual(200); + }); + }); + + describe('GET /:playlistId/entities', () => { + it('should respond correctly if unauthorized', async () => { + mockedAuthorize.mockImplementationOnce(async () => [ + { result: AuthorizeResult.DENY }, + ]); + const response = await request(app).get('/playlist-id/entities').send(); + + expect(mockedAuthorize).toHaveBeenCalledWith( + [ + { + permission: permissions.playlistListRead, + resourceRef: 'playlist-id', + }, + ], + { token: 'token' }, + ); + expect(mockDbHandler.getPlaylistEntities).not.toHaveBeenCalled(); + expect(response.status).toEqual(403); + }); + + it('should get entities from a playlist correctly', async () => { + const response = await request(app).get('/playlist-id/entities').send(); + expect(mockDbHandler.getPlaylistEntities).toHaveBeenCalledWith( + 'playlist-id', + ); + expect(response.status).toEqual(200); + expect(response.body).toEqual(mockEntities); + }); + }); + + describe('DELETE /:playlistId/entities', () => { + it('should respond correctly if unauthorized', async () => { + mockedAuthorize.mockImplementationOnce(async () => [ + { result: AuthorizeResult.DENY }, + ]); + const response = await request(app) + .delete('/playlist-id/entities') + .send(mockEntities); + + expect(mockedAuthorize).toHaveBeenCalledWith( + [ + { + permission: permissions.playlistListUpdate, + resourceRef: 'playlist-id', + }, + ], + { token: 'token' }, + ); + expect(mockDbHandler.removePlaylistEntities).not.toHaveBeenCalled(); + expect(response.status).toEqual(403); + }); + + it('should delete entities from a playlist correctly', async () => { + const response = await request(app) + .delete('/playlist-id/entities') + .send(mockEntities); + expect(mockDbHandler.removePlaylistEntities).toHaveBeenCalledWith( + 'playlist-id', + mockEntities, + ); + expect(response.status).toEqual(200); + }); + }); + + describe('POST /:playlistId/followers', () => { + it('should respond correctly if unauthorized', async () => { + mockedAuthorize.mockImplementationOnce(async () => [ + { result: AuthorizeResult.DENY }, + ]); + const response = await request(app).post('/playlist-id/followers').send(); + + expect(mockedAuthorize).toHaveBeenCalledWith( + [ + { + permission: permissions.playlistFollowersUpdate, + resourceRef: 'playlist-id', + }, + ], + { token: 'token' }, + ); + expect(mockDbHandler.followPlaylist).not.toHaveBeenCalled(); + expect(response.status).toEqual(403); + }); + + it('should follow a playlist correctly', async () => { + const response = await request(app).post('/playlist-id/followers').send(); + expect(mockDbHandler.followPlaylist).toHaveBeenCalledWith( + 'playlist-id', + mockUser, + ); + expect(response.status).toEqual(200); + }); + }); + + describe('DELETE /:playlistId/followers', () => { + it('should respond correctly if unauthorized', async () => { + mockedAuthorize.mockImplementationOnce(async () => [ + { result: AuthorizeResult.DENY }, + ]); + const response = await request(app) + .delete('/playlist-id/followers') + .send(); + + expect(mockedAuthorize).toHaveBeenCalledWith( + [ + { + permission: permissions.playlistFollowersUpdate, + resourceRef: 'playlist-id', + }, + ], + { token: 'token' }, + ); + expect(mockDbHandler.unfollowPlaylist).not.toHaveBeenCalled(); + expect(response.status).toEqual(403); + }); + + it('should unfollow a playlist correctly', async () => { + const response = await request(app) + .delete('/playlist-id/followers') + .send(); + expect(mockDbHandler.unfollowPlaylist).toHaveBeenCalledWith( + 'playlist-id', + mockUser, + ); + expect(response.status).toEqual(200); + }); + }); +}); diff --git a/plugins/playlist-backend/src/service/router.ts b/plugins/playlist-backend/src/service/router.ts new file mode 100644 index 0000000000..7ca41c0ac1 --- /dev/null +++ b/plugins/playlist-backend/src/service/router.ts @@ -0,0 +1,232 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { errorHandler, PluginDatabaseManager } from '@backstage/backend-common'; +import { NotAllowedError } from '@backstage/errors'; +import { + getBearerTokenFromAuthorizationHeader, + IdentityClient, +} from '@backstage/plugin-auth-node'; +import { + AuthorizePermissionRequest, + AuthorizeResult, + PermissionEvaluator, + QueryPermissionRequest, +} from '@backstage/plugin-permission-common'; +import { createPermissionIntegrationRouter } from '@backstage/plugin-permission-node'; +import { + PLAYLIST_LIST_RESOURCE_TYPE, + permissions, +} from '@backstage/plugin-playlist-common'; +import express from 'express'; +import Router from 'express-promise-router'; +import { Logger } from 'winston'; + +import { rules, transformConditions } from '../permissions'; +import { DatabaseHandler } from './DatabaseHandler'; +import { parseListPlaylistsFilterParams } from './ListPlaylistsFilter'; + +/** + * @public + */ +export interface RouterOptions { + database: PluginDatabaseManager; + identity: IdentityClient; + logger: Logger; + permissions: PermissionEvaluator; +} + +/** + * @public + */ +export async function createRouter( + options: RouterOptions, +): Promise { + const { + database, + identity, + logger, + permissions: permissionEvaluator, + } = options; + + logger.info('Initializing Playlist backend'); + + const db = await database.getClient(); + const dbHandler = await DatabaseHandler.create({ database: db }); + + const evaluateRequestPermission = async ( + req: express.Request, + permission: AuthorizePermissionRequest | QueryPermissionRequest, + conditional: boolean = false, + ) => { + const token = getBearerTokenFromAuthorizationHeader( + req.header('authorization'), + ); + + const user = await identity.authenticate(token); + + const decision = conditional + ? ( + await permissionEvaluator.authorizeConditional( + [permission as QueryPermissionRequest], + { token }, + ) + )[0] + : ( + await permissionEvaluator.authorize( + [permission as AuthorizePermissionRequest], + { token }, + ) + )[0]; + + if (decision.result === AuthorizeResult.DENY) { + throw new NotAllowedError('Unauthorized'); + } + + return { decision, user: user.identity }; + }; + + const permissionIntegrationRouter = createPermissionIntegrationRouter({ + getResources: resourceRefs => + Promise.all(resourceRefs.map(ref => dbHandler.getPlaylist(ref))), + resourceType: PLAYLIST_LIST_RESOURCE_TYPE, + rules: Object.values(rules), + }); + + const router = Router(); + router.use(express.json()); + router.use(permissionIntegrationRouter); + + router.get('/', async (req, res) => { + const { decision, user } = await evaluateRequestPermission( + req, + { permission: permissions.playlistListRead }, + true, + ); + + let filter = parseListPlaylistsFilterParams(req.query); + if (decision.result === AuthorizeResult.CONDITIONAL) { + const conditionsFilter = transformConditions(decision.conditions); + filter = filter + ? { allOf: [filter, conditionsFilter] } + : conditionsFilter; + } + + if (req.query.editable) { + const { decision: updatePermissionDecision } = + await evaluateRequestPermission( + req, + { permission: permissions.playlistListUpdate }, + true, + ); + + if (updatePermissionDecision.result === AuthorizeResult.CONDITIONAL) { + const updateConditionsFilter = transformConditions( + updatePermissionDecision.conditions, + ); + filter = filter + ? { allOf: [filter, updateConditionsFilter] } + : updateConditionsFilter; + } + } + + const playlists = await dbHandler.listPlaylists(user, filter); + res.json(playlists); + }); + + router.post('/', async (req, res) => { + await evaluateRequestPermission(req, { + permission: permissions.playlistListCreate, + }); + const playlistId = await dbHandler.createPlaylist(req.body); + res.status(201).json(playlistId); + }); + + router.get('/:playlistId', async (req, res) => { + const { user } = await evaluateRequestPermission(req, { + permission: permissions.playlistListRead, + resourceRef: req.params.playlistId, + }); + const playlist = await dbHandler.getPlaylist(req.params.playlistId, user); + res.json(playlist); + }); + + router.put('/:playlistId', async (req, res) => { + await evaluateRequestPermission(req, { + permission: permissions.playlistListUpdate, + resourceRef: req.params.playlistId, + }); + await dbHandler.updatePlaylist({ ...req.body, id: req.params.playlistId }); + res.status(200).end(); + }); + + router.delete('/:playlistId', async (req, res) => { + await evaluateRequestPermission(req, { + permission: permissions.playlistListDelete, + resourceRef: req.params.playlistId, + }); + await dbHandler.deletePlaylist(req.params.playlistId); + res.status(200).end(); + }); + + router.post('/:playlistId/entities', async (req, res) => { + await evaluateRequestPermission(req, { + permission: permissions.playlistListUpdate, + resourceRef: req.params.playlistId, + }); + await dbHandler.addPlaylistEntities(req.params.playlistId, req.body); + res.status(200).end(); + }); + + router.get('/:playlistId/entities', async (req, res) => { + await evaluateRequestPermission(req, { + permission: permissions.playlistListRead, + resourceRef: req.params.playlistId, + }); + const entities = await dbHandler.getPlaylistEntities(req.params.playlistId); + res.json(entities); + }); + + router.delete('/:playlistId/entities', async (req, res) => { + await evaluateRequestPermission(req, { + permission: permissions.playlistListUpdate, + resourceRef: req.params.playlistId, + }); + await dbHandler.removePlaylistEntities(req.params.playlistId, req.body); + res.status(200).end(); + }); + + router.post('/:playlistId/followers', async (req, res) => { + const { user } = await evaluateRequestPermission(req, { + permission: permissions.playlistFollowersUpdate, + resourceRef: req.params.playlistId, + }); + await dbHandler.followPlaylist(req.params.playlistId, user); + res.status(200).end(); + }); + + router.delete('/:playlistId/followers', async (req, res) => { + const { user } = await evaluateRequestPermission(req, { + permission: permissions.playlistFollowersUpdate, + resourceRef: req.params.playlistId, + }); + await dbHandler.unfollowPlaylist(req.params.playlistId, user); + res.status(200).end(); + }); + + router.use(errorHandler()); + return router; +} diff --git a/plugins/playlist-backend/src/service/standaloneServer.ts b/plugins/playlist-backend/src/service/standaloneServer.ts new file mode 100644 index 0000000000..46d6f7ad8d --- /dev/null +++ b/plugins/playlist-backend/src/service/standaloneServer.ts @@ -0,0 +1,90 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + createServiceBuilder, + DatabaseManager, + loadBackendConfig, + ServerTokenManager, + SingleHostDiscovery, + useHotMemoize, +} from '@backstage/backend-common'; +import { ConfigReader } from '@backstage/config'; +import { IdentityClient } from '@backstage/plugin-auth-node'; +import { ServerPermissionClient } from '@backstage/plugin-permission-node'; +import { Server } from 'http'; +import { Logger } from 'winston'; +import { createRouter } from './router'; + +export interface ServerOptions { + port: number; + enableCors: boolean; + logger: Logger; +} + +export async function startStandaloneServer( + options: ServerOptions, +): Promise { + const logger = options.logger.child({ service: 'playlist-backend' }); + const config = await loadBackendConfig({ logger, argv: process.argv }); + const discovery = SingleHostDiscovery.fromConfig(config); + + const database = useHotMemoize(module, () => { + const manager = DatabaseManager.fromConfig( + new ConfigReader({ + backend: { + database: { client: 'better-sqlite3', connection: ':memory:' }, + }, + }), + ); + return manager.forPlugin('playlist'); + }); + + const identity = IdentityClient.create({ + discovery, + issuer: await discovery.getExternalBaseUrl('auth'), + }); + + const tokenManager = ServerTokenManager.fromConfig(config, { + logger, + }); + const permissions = ServerPermissionClient.fromConfig(config, { + discovery, + tokenManager, + }); + + logger.debug('Starting application server...'); + const router = await createRouter({ + database, + identity, + logger, + permissions, + }); + + let service = createServiceBuilder(module) + .setPort(options.port) + .addRouter('/playlist', router); + if (options.enableCors) { + service = service.enableCors({ origin: 'http://localhost:3000' }); + } + + return await service.start().catch(err => { + logger.error(err); + process.exit(1); + }); +} + +module.hot?.accept(); diff --git a/plugins/playlist-backend/src/setupTests.ts b/plugins/playlist-backend/src/setupTests.ts new file mode 100644 index 0000000000..813cdeaae3 --- /dev/null +++ b/plugins/playlist-backend/src/setupTests.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export {}; diff --git a/plugins/playlist-common/.eslintrc.js b/plugins/playlist-common/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/playlist-common/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/playlist-common/README.md b/plugins/playlist-common/README.md new file mode 100644 index 0000000000..72f502386c --- /dev/null +++ b/plugins/playlist-common/README.md @@ -0,0 +1,3 @@ +# Playlist Common + +Common functionalities, types, and permissions for the playlist plugin. diff --git a/plugins/playlist-common/api-report.md b/plugins/playlist-common/api-report.md new file mode 100644 index 0000000000..e97cb3dc64 --- /dev/null +++ b/plugins/playlist-common/api-report.md @@ -0,0 +1,36 @@ +## API Report File for "@backstage/plugin-playlist-common" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BasicPermission } from '@backstage/plugin-permission-common'; +import { ResourcePermission } from '@backstage/plugin-permission-common'; + +// @public (undocumented) +export const permissions: { + playlistListCreate: BasicPermission; + playlistListRead: ResourcePermission<'playlist-list'>; + playlistListUpdate: ResourcePermission<'playlist-list'>; + playlistListDelete: ResourcePermission<'playlist-list'>; + playlistFollowersUpdate: ResourcePermission<'playlist-list'>; +}; + +// @public (undocumented) +export type Playlist = PlaylistMetadata & { + entities: number; + followers: number; + isFollowing: boolean; +}; + +// @public (undocumented) +export const PLAYLIST_LIST_RESOURCE_TYPE = 'playlist-list'; + +// @public (undocumented) +export type PlaylistMetadata = { + id: string; + name: string; + description?: string; + owner: string; + public: boolean; +}; +``` diff --git a/plugins/playlist-common/package.json b/plugins/playlist-common/package.json new file mode 100644 index 0000000000..67a97b1237 --- /dev/null +++ b/plugins/playlist-common/package.json @@ -0,0 +1,34 @@ +{ + "name": "@backstage/plugin-playlist-common", + "description": "Common functionalities for the playlist plugin", + "version": "0.0.0", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "publishConfig": { + "access": "public", + "main": "dist/index.cjs.js", + "module": "dist/index.esm.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "common-library" + }, + "scripts": { + "build": "backstage-cli package build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "dependencies": { + "@backstage/plugin-permission-common": "^0.6.4-next.1" + }, + "devDependencies": { + "@backstage/cli": "^0.19.0-next.2" + }, + "files": [ + "dist" + ] +} diff --git a/plugins/playlist-common/src/index.ts b/plugins/playlist-common/src/index.ts new file mode 100644 index 0000000000..92cf1eb461 --- /dev/null +++ b/plugins/playlist-common/src/index.ts @@ -0,0 +1,24 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Common functionalities for the playlist plugin. + * + * @packageDocumentation + */ + +export * from './types'; +export * from './permissions'; diff --git a/plugins/playlist-common/src/permissions.ts b/plugins/playlist-common/src/permissions.ts new file mode 100644 index 0000000000..89d526127e --- /dev/null +++ b/plugins/playlist-common/src/permissions.ts @@ -0,0 +1,62 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createPermission } from '@backstage/plugin-permission-common'; + +/** + * @public + */ +export const PLAYLIST_LIST_RESOURCE_TYPE = 'playlist-list'; + +const playlistListCreate = createPermission({ + name: 'playlist.list.create', + attributes: { action: 'create' }, +}); + +const playlistListRead = createPermission({ + name: 'playlist.list.read', + attributes: { action: 'read' }, + resourceType: PLAYLIST_LIST_RESOURCE_TYPE, +}); + +const playlistListUpdate = createPermission({ + name: 'playlist.list.update', + attributes: { action: 'update' }, + resourceType: PLAYLIST_LIST_RESOURCE_TYPE, +}); + +const playlistListDelete = createPermission({ + name: 'playlist.list.delete', + attributes: { action: 'delete' }, + resourceType: PLAYLIST_LIST_RESOURCE_TYPE, +}); + +const playlistFollowersUpdate = createPermission({ + name: 'playlist.followers.update', + attributes: { action: 'update' }, + resourceType: PLAYLIST_LIST_RESOURCE_TYPE, +}); + +/** + * @public + */ +export const permissions = { + playlistListCreate, + playlistListRead, + playlistListUpdate, + playlistListDelete, + playlistFollowersUpdate, +}; diff --git a/plugins/playlist-common/src/setupTests.ts b/plugins/playlist-common/src/setupTests.ts new file mode 100644 index 0000000000..8b9b6bd586 --- /dev/null +++ b/plugins/playlist-common/src/setupTests.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export {}; diff --git a/plugins/playlist-common/src/types.ts b/plugins/playlist-common/src/types.ts new file mode 100644 index 0000000000..667cd35ece --- /dev/null +++ b/plugins/playlist-common/src/types.ts @@ -0,0 +1,35 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @public + */ +export type PlaylistMetadata = { + id: string; + name: string; + description?: string; + owner: string; + public: boolean; +}; + +/** + * @public + */ +export type Playlist = PlaylistMetadata & { + entities: number; + followers: number; + isFollowing: boolean; +}; diff --git a/plugins/playlist/.eslintrc.js b/plugins/playlist/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/playlist/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/playlist/README.md b/plugins/playlist/README.md new file mode 100644 index 0000000000..7c814d302b --- /dev/null +++ b/plugins/playlist/README.md @@ -0,0 +1,128 @@ +# Playlist Plugin + +Welcome to the playlist plugin! + +This plugin allows you to create, share, and follow custom collections of entities available in the Backstage catalog. + +## Setup + +Install this plugin: + +```bash +# From your Backstage root directory +yarn --cwd packages/app add @backstage/plugin-playlist +``` + +### Add the plugin to your `packages/app` + +Add the root page that the playlist plugin provides to your app. You can +choose any path for the route, but we recommend the following: + +```diff +// packages/app/src/App.tsx ++import { PlaylistIndexPage } from '@backstage/plugin-playlist'; + + + + } /> + }> + {entityPage} + ++ } /> + ... + +``` + +You may also want to add a link to the playlist page to your application sidebar: + +```diff +// packages/app/src/components/Root/Root.tsx ++import PlaylistPlayIcon from '@material-ui/icons/PlaylistPlay'; + +export const Root = ({ children }: PropsWithChildren<{}>) => ( + + ++ + ... + +``` + +### Entity Pages + +You can also make the following changes to add the playlist context menu to your `EntityPage.tsx` +to be able to add entities to playlists directly from your entity pages: + +First we need to add the following imports: + +```ts +import { EntityPlaylistDialog } from '@backstage/plugin-playlist'; +import PlaylistAddIcon from '@material-ui/icons/PlaylistAdd'; +``` + +Next we'll update the React import that looks like this: + +```ts +import React from 'react'; +``` + +To look like this: + +```ts +import React, { ReactNode, useMemo, useState } from 'react'; +``` + +Then we have to add this chunk of code after all the imports but before any of the other code: + +```ts +const EntityLayoutWrapper = (props: { children?: ReactNode }) => { + const [playlistDialogOpen, setPlaylistDialogOpen] = useState(false); + + const extraMenuItems = useMemo(() => { + return [ + { + title: 'Add to playlist', + Icon: PlaylistAddIcon, + onClick: () => setPlaylistDialogOpen(true), + }, + ]; + }, []); + + return ( + <> + + {props.children} + + setPlaylistDialogOpen(false)} + /> + + ); +}; +``` + +The last step is to wrap all the entity pages in the `EntityLayoutWrapper` like this: + +```diff +const defaultEntityPage = ( ++ + + {overviewContent} + + + + + + + + + ++ +); +``` + +Note: the above only shows an example for the `defaultEntityPage` for a full example of this you can look at [this EntityPage](../../packages/app/src/components/catalog/EntityPage.tsx) + +## Links + +- [playlist-backend](../playlist-backend) provides the backend API for this frontend. diff --git a/plugins/playlist/api-report.md b/plugins/playlist/api-report.md new file mode 100644 index 0000000000..ddfec2948d --- /dev/null +++ b/plugins/playlist/api-report.md @@ -0,0 +1,106 @@ +## API Report File for "@backstage/plugin-playlist" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +/// + +import { ApiRef } from '@backstage/core-plugin-api'; +import { BackstagePlugin } from '@backstage/core-plugin-api'; +import { DiscoveryApi } from '@backstage/core-plugin-api'; +import { FetchApi } from '@backstage/core-plugin-api'; +import { Playlist } from '@backstage/plugin-playlist-common'; +import { PlaylistMetadata } from '@backstage/plugin-playlist-common'; +import { RouteRef } from '@backstage/core-plugin-api'; + +// @public (undocumented) +export const EntityPlaylistDialog: ({ + open, + onClose, +}: EntityPlaylistDialogProps) => JSX.Element; + +// @public (undocumented) +export type EntityPlaylistDialogProps = { + open: boolean; + onClose: () => void; +}; + +// @public (undocumented) +export interface GetAllPlaylistsRequest { + // (undocumented) + editable?: boolean; + filter?: + | Record[] + | Record; +} + +// @public (undocumented) +export interface PlaylistApi { + // (undocumented) + addPlaylistEntities(playlistId: string, entityRefs: string[]): Promise; + // (undocumented) + createPlaylist(playlist: Omit): Promise; + // (undocumented) + deletePlaylist(playlistId: string): Promise; + // (undocumented) + followPlaylist(playlistId: string): Promise; + // (undocumented) + getAllPlaylists(req: GetAllPlaylistsRequest): Promise; + // (undocumented) + getPlaylist(playlistId: string): Promise; + // (undocumented) + getPlaylistEntities(playlistId: string): Promise; + // (undocumented) + removePlaylistEntities( + playlistId: string, + entityRefs: string[], + ): Promise; + // (undocumented) + unfollowPlaylist(playlistId: string): Promise; + // (undocumented) + updatePlaylist(playlist: PlaylistMetadata): Promise; +} + +// @public (undocumented) +export const playlistApiRef: ApiRef; + +// @public (undocumented) +export class PlaylistClient implements PlaylistApi { + constructor(options: { discoveryApi: DiscoveryApi; fetchApi: FetchApi }); + // (undocumented) + addPlaylistEntities(playlistId: string, entityRefs: string[]): Promise; + // (undocumented) + createPlaylist(playlist: Omit): Promise; + // (undocumented) + deletePlaylist(playlistId: string): Promise; + // (undocumented) + followPlaylist(playlistId: string): Promise; + // (undocumented) + getAllPlaylists(req?: GetAllPlaylistsRequest): Promise; + // (undocumented) + getPlaylist(playlistId: string): Promise; + // (undocumented) + getPlaylistEntities(playlistId: string): Promise; + // (undocumented) + removePlaylistEntities( + playlistId: string, + entityRefs: string[], + ): Promise; + // (undocumented) + unfollowPlaylist(playlistId: string): Promise; + // (undocumented) + updatePlaylist(playlist: PlaylistMetadata): Promise; +} + +// @public (undocumented) +export const PlaylistIndexPage: () => JSX.Element; + +// @public (undocumented) +export const playlistPlugin: BackstagePlugin< + { + root: RouteRef; + }, + {}, + {} +>; +``` diff --git a/packages/core-components/src/layout/HeaderActionMenu/VerticalMenuIcon.tsx b/plugins/playlist/dev/index.tsx similarity index 58% rename from packages/core-components/src/layout/HeaderActionMenu/VerticalMenuIcon.tsx rename to plugins/playlist/dev/index.tsx index a6a1d3a3d7..c9c626ab38 100644 --- a/packages/core-components/src/layout/HeaderActionMenu/VerticalMenuIcon.tsx +++ b/plugins/playlist/dev/index.tsx @@ -1,5 +1,5 @@ /* - * Copyright 2020 The Backstage Authors + * Copyright 2022 The Backstage Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,13 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - import React from 'react'; -import SvgIcon, { SvgIconProps } from '@material-ui/core/SvgIcon'; +import { createDevApp } from '@backstage/dev-utils'; +import { playlistPlugin, PlaylistIndexPage } from '../src/plugin'; -export const VerticalMenuIcon = (props: SvgIconProps) => - React.createElement( - SvgIcon, - props, - , - ); +createDevApp() + .registerPlugin(playlistPlugin) + .addPage({ + element: , + title: 'Root Page', + path: '/playlist', + }) + .render(); diff --git a/plugins/playlist/package.json b/plugins/playlist/package.json new file mode 100644 index 0000000000..51cffcca9f --- /dev/null +++ b/plugins/playlist/package.json @@ -0,0 +1,67 @@ +{ + "name": "@backstage/plugin-playlist", + "version": "0.0.0", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "publishConfig": { + "access": "public", + "main": "dist/index.esm.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "frontend-plugin" + }, + "scripts": { + "start": "backstage-cli package start", + "build": "backstage-cli package build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "dependencies": { + "@backstage/catalog-model": "^1.1.0", + "@backstage/core-components": "^0.11.1-next.2", + "@backstage/core-plugin-api": "^1.0.6-next.2", + "@backstage/errors": "^1.1.0", + "@backstage/plugin-catalog-common": "^1.0.6-next.0", + "@backstage/plugin-catalog-react": "^1.1.4-next.1", + "@backstage/plugin-permission-common": "^0.6.4-next.1", + "@backstage/plugin-permission-react": "^0.4.5-next.1", + "@backstage/plugin-playlist-common": "^0.0.0", + "@backstage/plugin-search-react": "^1.1.0-next.2", + "@backstage/theme": "^0.2.16", + "@material-ui/core": "^4.9.13", + "@material-ui/icons": "^4.9.1", + "@material-ui/lab": "^4.0.0-alpha.57", + "lodash": "^4.17.21", + "qs": "^6.9.4", + "react-hook-form": "^7.13.0", + "react-use": "^17.2.4" + }, + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0", + "react-router": "6.0.0-beta.0 || ^6.3.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, + "devDependencies": { + "@backstage/cli": "^0.19.0-next.2", + "@backstage/core-app-api": "^1.1.0-next.2", + "@backstage/dev-utils": "^1.0.6-next.1", + "@backstage/test-utils": "^1.2.0-next.2", + "@testing-library/jest-dom": "^5.10.1", + "@testing-library/react": "^12.1.3", + "@testing-library/react-hooks": "^8.0.0", + "@testing-library/user-event": "^14.0.0", + "@types/jest": "*", + "@types/node": "*", + "cross-fetch": "^3.1.5", + "msw": "^0.47.0", + "swr": "^1.1.2" + }, + "files": [ + "dist" + ] +} diff --git a/plugins/playlist/src/api/PlaylistApi.ts b/plugins/playlist/src/api/PlaylistApi.ts new file mode 100644 index 0000000000..d0b87ec28a --- /dev/null +++ b/plugins/playlist/src/api/PlaylistApi.ts @@ -0,0 +1,75 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createApiRef } from '@backstage/core-plugin-api'; +import { Playlist, PlaylistMetadata } from '@backstage/plugin-playlist-common'; + +/** + * @public + */ +export const playlistApiRef = createApiRef({ + id: 'plugin.playlist.service', +}); + +/** + * @public + */ +export interface GetAllPlaylistsRequest { + /** + * If multiple filter sets are given as an array, then there is effectively an + * OR between each filter set. + * + * Within one filter set, there is effectively an AND between the various + * keys. + * + * Within one key, if there are more than one value, then there is effectively + * an OR between them. + */ + filter?: + | Record[] + | Record; + + // If true, will filter results that satisfies the playlist.list.update permission + editable?: boolean; +} + +/** + * @public + */ +export interface PlaylistApi { + getAllPlaylists(req: GetAllPlaylistsRequest): Promise; + + createPlaylist(playlist: Omit): Promise; + + getPlaylist(playlistId: string): Promise; + + updatePlaylist(playlist: PlaylistMetadata): Promise; + + deletePlaylist(playlistId: string): Promise; + + addPlaylistEntities(playlistId: string, entityRefs: string[]): Promise; + + getPlaylistEntities(playlistId: string): Promise; + + removePlaylistEntities( + playlistId: string, + entityRefs: string[], + ): Promise; + + followPlaylist(playlistId: string): Promise; + + unfollowPlaylist(playlistId: string): Promise; +} diff --git a/plugins/playlist/src/api/PlaylistClient.test.ts b/plugins/playlist/src/api/PlaylistClient.test.ts new file mode 100644 index 0000000000..f3b62c19ac --- /dev/null +++ b/plugins/playlist/src/api/PlaylistClient.test.ts @@ -0,0 +1,272 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { MockFetchApi, setupRequestMockHandlers } from '@backstage/test-utils'; +import { rest } from 'msw'; +import { setupServer } from 'msw/node'; + +import { PlaylistClient } from './PlaylistClient'; + +const server = setupServer(); + +describe('PlaylistClient', () => { + setupRequestMockHandlers(server); + const mockBaseUrl = 'http://backstage/api/playlist'; + const discoveryApi = { getBaseUrl: async () => mockBaseUrl }; + const fetchApi = new MockFetchApi(); + + let client: PlaylistClient; + beforeEach(() => { + client = new PlaylistClient({ discoveryApi, fetchApi }); + }); + + describe('getAllPlaylists', () => { + const expectedResp = [ + { + id: 'id', + name: 'name', + description: 'description', + owner: 'owner', + public: true, + entities: 1, + followers: 2, + isFollowing: true, + }, + ]; + + it('should fetch playlists from correct endpoint', async () => { + server.use( + rest.get(`${mockBaseUrl}/`, (_, res, ctx) => + res(ctx.json(expectedResp)), + ), + ); + const response = await client.getAllPlaylists(); + expect(response).toEqual(expectedResp); + }); + + it('should fetch editable playlists correctly', async () => { + expect.assertions(2); + + server.use( + rest.get(`${mockBaseUrl}/`, (req, res, ctx) => { + expect(req.url.search).toBe('?editable=true'); + return res(ctx.json(expectedResp)); + }), + ); + + const response = await client.getAllPlaylists({ editable: true }); + expect(response).toEqual(expectedResp); + }); + + it('builds multiple search filters properly', async () => { + expect.assertions(2); + + server.use( + rest.get(`${mockBaseUrl}/`, (req, res, ctx) => { + expect(req.url.search).toBe( + '?filter=a=1,b=2,b=3,%C3%B6=%3D&filter=a=2&editable=true', + ); + return res(ctx.json(expectedResp)); + }), + ); + + const response = await client.getAllPlaylists({ + editable: true, + filter: [ + { + a: '1', + b: ['2', '3'], + ö: '=', + }, + { + a: '2', + }, + ], + }); + + expect(response).toEqual(expectedResp); + }); + + it('builds single search filter properly', async () => { + expect.assertions(2); + + server.use( + rest.get(`${mockBaseUrl}/`, (req, res, ctx) => { + expect(req.url.search).toBe('?filter=a=1,b=2,b=3,%C3%B6=%3D'); + return res(ctx.json(expectedResp)); + }), + ); + + const response = await client.getAllPlaylists({ + filter: { + a: '1', + b: ['2', '3'], + ö: '=', + }, + }); + + expect(response).toEqual(expectedResp); + }); + }); + + it('createPlaylist', async () => { + expect.assertions(2); + + const newPlaylist = { + name: 'name', + description: 'description', + owner: 'owner', + public: true, + }; + + server.use( + rest.post(`${mockBaseUrl}/`, (req, res, ctx) => { + expect(req.body).toEqual(newPlaylist); + return res(ctx.json('123')); + }), + ); + + const response = await client.createPlaylist(newPlaylist); + + expect(response).toEqual('123'); + }); + + it('getPlaylist', async () => { + const playlist = { + id: '123', + name: 'name', + description: 'description', + owner: 'owner', + public: true, + entities: 1, + followers: 2, + isFollowing: true, + }; + + server.use( + rest.get(`${mockBaseUrl}/123`, (_, res, ctx) => res(ctx.json(playlist))), + ); + + const response = await client.getPlaylist('123'); + expect(response).toEqual(playlist); + }); + + it('updatePlaylist', async () => { + expect.assertions(1); + + const playlist = { + id: 'id', + name: 'name', + description: 'description', + owner: 'owner', + public: true, + }; + + server.use( + rest.put(`${mockBaseUrl}/id`, (req, res) => { + expect(req.body).toEqual(playlist); + return res(); + }), + ); + + await client.updatePlaylist(playlist); + }); + + it('deletePlaylist', async () => { + expect.assertions(1); + + server.use( + rest.delete(`${mockBaseUrl}/id`, (_, res) => { + // eslint requires at least 1 assertion so this is here is verify this handler is called + expect(true).toBe(true); + return res(); + }), + ); + + await client.deletePlaylist('id'); + }); + + it('addPlaylistEntities', async () => { + expect.assertions(1); + + const entities = ['component:default/ent1', 'component:default/ent2']; + + server.use( + rest.post(`${mockBaseUrl}/id/entities`, (req, res) => { + expect(req.body).toEqual(entities); + return res(); + }), + ); + + await client.addPlaylistEntities('id', entities); + }); + + it('getPlaylistEntities', async () => { + const entities = ['component:default/ent1', 'component:default/ent2']; + + server.use( + rest.get(`${mockBaseUrl}/id/entities`, (_, res, ctx) => + res(ctx.json(entities)), + ), + ); + + const response = await client.getPlaylistEntities('id'); + expect(response).toEqual(entities); + }); + + it('removePlaylistEntities', async () => { + expect.assertions(1); + + const entities = ['component:default/ent1', 'component:default/ent2']; + + server.use( + rest.delete(`${mockBaseUrl}/id/entities`, (req, res) => { + expect(req.body).toEqual(entities); + return res(); + }), + ); + + await client.removePlaylistEntities('id', entities); + }); + + it('followPlaylist', async () => { + expect.assertions(1); + + server.use( + rest.post(`${mockBaseUrl}/id/followers`, (_, res) => { + // eslint requires at least 1 assertion so this is here is verify this handler is called + expect(true).toBe(true); + return res(); + }), + ); + + await client.followPlaylist('id'); + }); + + it('unfollowPlaylist', async () => { + expect.assertions(1); + + server.use( + rest.delete(`${mockBaseUrl}/id/followers`, (_, res) => { + // eslint requires at least 1 assertion so this is here is verify this handler is called + expect(true).toBe(true); + return res(); + }), + ); + + await client.unfollowPlaylist('id'); + }); +}); diff --git a/plugins/playlist/src/api/PlaylistClient.ts b/plugins/playlist/src/api/PlaylistClient.ts new file mode 100644 index 0000000000..b77aa79733 --- /dev/null +++ b/plugins/playlist/src/api/PlaylistClient.ts @@ -0,0 +1,198 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { DiscoveryApi, FetchApi } from '@backstage/core-plugin-api'; +import { ResponseError } from '@backstage/errors'; +import { Playlist, PlaylistMetadata } from '@backstage/plugin-playlist-common'; + +import { GetAllPlaylistsRequest, PlaylistApi } from './PlaylistApi'; + +/** + * @public + */ +export class PlaylistClient implements PlaylistApi { + private readonly discoveryApi: DiscoveryApi; + private readonly fetchApi: FetchApi; + + constructor(options: { discoveryApi: DiscoveryApi; fetchApi: FetchApi }) { + this.discoveryApi = options.discoveryApi; + this.fetchApi = options.fetchApi; + } + + async getAllPlaylists(req: GetAllPlaylistsRequest = {}): Promise { + const { filter = [], editable } = req; + const params: string[] = []; + + // the "outer array" defined by `filter` occurrences corresponds to "anyOf" filters + // the "inner array" defined within a `filter` param corresponds to "allOf" filters + for (const filterItem of [filter].flat()) { + const filterParts: string[] = []; + for (const [key, value] of Object.entries(filterItem)) { + for (const v of [value].flat()) { + if (typeof v === 'string') { + filterParts.push( + `${encodeURIComponent(key)}=${encodeURIComponent(v)}`, + ); + } + } + } + + if (filterParts.length) { + params.push(`filter=${filterParts.join(',')}`); + } + } + + if (editable) { + params.push('editable=true'); + } + + const query = params.length ? `?${params.join('&')}` : ''; + const baseUrl = await this.discoveryApi.getBaseUrl('playlist'); + const resp = await this.fetchApi.fetch(`${baseUrl}/${query}`, { + method: 'GET', + }); + + if (!resp.ok) { + throw await ResponseError.fromResponse(resp); + } + + return await resp.json(); + } + + async createPlaylist( + playlist: Omit, + ): Promise { + const baseUrl = await this.discoveryApi.getBaseUrl('playlist'); + const resp = await this.fetchApi.fetch(`${baseUrl}/`, { + headers: { 'Content-Type': 'application/json' }, + method: 'POST', + body: JSON.stringify(playlist), + }); + + if (!resp.ok) { + throw await ResponseError.fromResponse(resp); + } + + return await resp.json(); + } + + async getPlaylist(playlistId: string): Promise { + const baseUrl = await this.discoveryApi.getBaseUrl('playlist'); + const resp = await this.fetchApi.fetch(`${baseUrl}/${playlistId}`, { + method: 'GET', + }); + + if (!resp.ok) { + throw await ResponseError.fromResponse(resp); + } + + return await resp.json(); + } + + async updatePlaylist(playlist: PlaylistMetadata) { + const baseUrl = await this.discoveryApi.getBaseUrl('playlist'); + const resp = await this.fetchApi.fetch(`${baseUrl}/${playlist.id}`, { + headers: { 'Content-Type': 'application/json' }, + method: 'PUT', + body: JSON.stringify(playlist), + }); + + if (!resp.ok) { + throw await ResponseError.fromResponse(resp); + } + } + + async deletePlaylist(playlistId: string) { + const baseUrl = await this.discoveryApi.getBaseUrl('playlist'); + const resp = await this.fetchApi.fetch(`${baseUrl}/${playlistId}`, { + method: 'DELETE', + }); + + if (!resp.ok) { + throw await ResponseError.fromResponse(resp); + } + } + + async addPlaylistEntities(playlistId: string, entityRefs: string[]) { + const baseUrl = await this.discoveryApi.getBaseUrl('playlist'); + const resp = await this.fetchApi.fetch( + `${baseUrl}/${playlistId}/entities`, + { + headers: { 'Content-Type': 'application/json' }, + method: 'POST', + body: JSON.stringify(entityRefs), + }, + ); + + if (!resp.ok) { + throw await ResponseError.fromResponse(resp); + } + } + + async getPlaylistEntities(playlistId: string): Promise { + const baseUrl = await this.discoveryApi.getBaseUrl('playlist'); + const resp = await this.fetchApi.fetch( + `${baseUrl}/${playlistId}/entities`, + { method: 'GET' }, + ); + + if (!resp.ok) { + throw await ResponseError.fromResponse(resp); + } + + return await resp.json(); + } + + async removePlaylistEntities(playlistId: string, entityRefs: string[]) { + const baseUrl = await this.discoveryApi.getBaseUrl('playlist'); + const resp = await this.fetchApi.fetch( + `${baseUrl}/${playlistId}/entities`, + { + headers: { 'Content-Type': 'application/json' }, + method: 'DELETE', + body: JSON.stringify(entityRefs), + }, + ); + + if (!resp.ok) { + throw await ResponseError.fromResponse(resp); + } + } + + async followPlaylist(playlistId: string) { + const baseUrl = await this.discoveryApi.getBaseUrl('playlist'); + const resp = await this.fetchApi.fetch( + `${baseUrl}/${playlistId}/followers`, + { method: 'POST' }, + ); + + if (!resp.ok) { + throw await ResponseError.fromResponse(resp); + } + } + + async unfollowPlaylist(playlistId: string) { + const baseUrl = await this.discoveryApi.getBaseUrl('playlist'); + const resp = await this.fetchApi.fetch( + `${baseUrl}/${playlistId}/followers`, + { method: 'DELETE' }, + ); + + if (!resp.ok) { + throw await ResponseError.fromResponse(resp); + } + } +} diff --git a/plugins/playlist/src/api/index.ts b/plugins/playlist/src/api/index.ts new file mode 100644 index 0000000000..b53cbd99ef --- /dev/null +++ b/plugins/playlist/src/api/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './PlaylistClient'; +export * from './PlaylistApi'; diff --git a/plugins/playlist/src/components/CreatePlaylistButton/CreatePlaylistButton.test.tsx b/plugins/playlist/src/components/CreatePlaylistButton/CreatePlaylistButton.test.tsx new file mode 100644 index 0000000000..e00f7dc582 --- /dev/null +++ b/plugins/playlist/src/components/CreatePlaylistButton/CreatePlaylistButton.test.tsx @@ -0,0 +1,142 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ErrorApi, errorApiRef } from '@backstage/core-plugin-api'; +import { AuthorizeResult } from '@backstage/plugin-permission-common'; +import { + PermissionApi, + permissionApiRef, +} from '@backstage/plugin-permission-react'; +import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; +import { Button } from '@material-ui/core'; +import { fireEvent, waitFor } from '@testing-library/react'; +import { act } from '@testing-library/react-hooks'; +import React from 'react'; +import { SWRConfig } from 'swr'; + +import { PlaylistApi, playlistApiRef } from '../../api'; +import { rootRouteRef } from '../../routes'; +import { CreatePlaylistButton } from './CreatePlaylistButton'; + +jest.mock('../PlaylistEditDialog', () => ({ + PlaylistEditDialog: ({ onSave, open }: { onSave: Function; open: boolean }) => + open ? ( + + )} + setOpenDialog(false)} + onSave={savePlaylist} + /> + + ); +}; diff --git a/plugins/playlist/src/components/CreatePlaylistButton/index.ts b/plugins/playlist/src/components/CreatePlaylistButton/index.ts new file mode 100644 index 0000000000..ac28bbc509 --- /dev/null +++ b/plugins/playlist/src/components/CreatePlaylistButton/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './CreatePlaylistButton'; diff --git a/plugins/playlist/src/components/EntityPlaylistDialog/EntityPlaylistDialog.test.tsx b/plugins/playlist/src/components/EntityPlaylistDialog/EntityPlaylistDialog.test.tsx new file mode 100644 index 0000000000..9c61105ef9 --- /dev/null +++ b/plugins/playlist/src/components/EntityPlaylistDialog/EntityPlaylistDialog.test.tsx @@ -0,0 +1,200 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entity } from '@backstage/catalog-model'; +import { AlertApi, alertApiRef } from '@backstage/core-plugin-api'; +import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; +import { EntityProvider } from '@backstage/plugin-catalog-react'; +import { AuthorizeResult } from '@backstage/plugin-permission-common'; +import { + PermissionApi, + permissionApiRef, +} from '@backstage/plugin-permission-react'; +import { Button } from '@material-ui/core'; +import { fireEvent, getByRole, waitFor } from '@testing-library/react'; +import { act } from '@testing-library/react-hooks'; +import React from 'react'; +import { SWRConfig } from 'swr'; + +import { PlaylistApi, playlistApiRef } from '../../api'; +import { rootRouteRef } from '../../routes'; +import { EntityPlaylistDialog } from './EntityPlaylistDialog'; + +const navigateMock = jest.fn(); +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), + useNavigate: () => navigateMock, +})); + +jest.mock('../PlaylistEditDialog', () => ({ + PlaylistEditDialog: ({ onSave, open }: { onSave: Function; open: boolean }) => + open ? ( + + + + setOpenEditDialog(false)} + onSave={createNewPlaylist} + /> + + ); +}; diff --git a/plugins/playlist/src/components/EntityPlaylistDialog/index.ts b/plugins/playlist/src/components/EntityPlaylistDialog/index.ts new file mode 100644 index 0000000000..77d7e73ae0 --- /dev/null +++ b/plugins/playlist/src/components/EntityPlaylistDialog/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './EntityPlaylistDialog'; diff --git a/plugins/playlist/src/components/PersonalListPicker/PersonalListPicker.test.tsx b/plugins/playlist/src/components/PersonalListPicker/PersonalListPicker.test.tsx new file mode 100644 index 0000000000..9255ee1bdb --- /dev/null +++ b/plugins/playlist/src/components/PersonalListPicker/PersonalListPicker.test.tsx @@ -0,0 +1,286 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ApiProvider } from '@backstage/core-app-api'; +import { + ConfigApi, + configApiRef, + IdentityApi, + identityApiRef, + storageApiRef, +} from '@backstage/core-plugin-api'; +import { Playlist } from '@backstage/plugin-playlist-common'; +import { MockStorageApi, TestApiRegistry } from '@backstage/test-utils'; +import { fireEvent, render, waitFor } from '@testing-library/react'; +import React from 'react'; + +import { MockPlaylistListProvider } from '../../testUtils'; +import { PlaylistOwnerFilter } from '../PlaylistOwnerPicker'; +import { PersonalListPicker } from './PersonalListPicker'; + +const mockConfigApi = { + getOptionalString: () => 'Test Company', +} as Partial; + +const mockIdentityApi = { + getBackstageIdentity: async () => ({ + ownershipEntityRefs: ['user:default/owner', 'group:default/some-owner'], + }), +} as Partial; + +const apis = TestApiRegistry.from( + [configApiRef, mockConfigApi], + [identityApiRef, mockIdentityApi], + [storageApiRef, MockStorageApi.create()], +); + +const backendPlaylists: Playlist[] = [ + { + id: 'id1', + name: 'playlist-1', + owner: 'group:default/some-owner', + public: true, + entities: 1, + followers: 2, + isFollowing: false, + }, + { + id: 'id2', + name: 'playlist-2', + owner: 'group:default/another-owner', + public: true, + entities: 2, + followers: 1, + isFollowing: true, + }, + { + id: 'id3', + name: 'playlist-3', + owner: 'group:default/another-owner', + public: true, + entities: 2, + followers: 1, + isFollowing: true, + }, + { + id: 'id4', + name: 'playlist-4', + owner: 'user:default/owner', + public: true, + entities: 2, + followers: 1, + isFollowing: true, + }, +]; + +describe('', () => { + const updateFilters = jest.fn() as any; + + beforeEach(() => { + updateFilters.mockClear(); + }); + + it('renders filter groups', async () => { + const { queryByText } = render( + + + + + , + ); + + await waitFor(() => { + expect(queryByText('Personal')).toBeInTheDocument(); + expect(queryByText('Test Company')).toBeInTheDocument(); + }); + }); + + it('renders filters', async () => { + const { getAllByRole } = render( + + + + + , + ); + + await waitFor(() => { + expect( + getAllByRole('menuitem').map(({ textContent }) => textContent), + ).toEqual(['Owned 2', 'Following 3', 'All 4']); + }); + }); + + it('respects other frontend filters in counts', async () => { + const { getAllByRole } = render( + + + + + , + ); + + await waitFor(() => { + expect( + getAllByRole('menuitem').map(({ textContent }) => textContent), + ).toEqual(['Owned -', 'Following 2', 'All 2']); + }); + }); + + it('respects the query parameter filter value', async () => { + const queryParameters = { personal: 'owned' }; + render( + + + + + , + ); + + await waitFor(() => { + expect(updateFilters.mock.lastCall[0].personal.value).toBe('owned'); + }); + }); + + it('updates personal filter when a menuitem is selected', async () => { + const { getByText } = render( + + + + + , + ); + + fireEvent.click(getByText('Following')); + + await waitFor(() => { + expect(updateFilters.mock.lastCall[0].personal.value).toBe('following'); + }); + }); + + it('responds to external queryParameters changes', async () => { + const rendered = render( + + + + + , + ); + + await waitFor(() => { + expect(updateFilters.mock.lastCall[0].personal.value).toBe('all'); + }); + + rendered.rerender( + + + + + , + ); + + await waitFor(() => { + expect(updateFilters.mock.lastCall[0].personal.value).toBe('owned'); + }); + }); + + describe.each(['owned', 'following'])( + 'filter resetting for %s playlists', + type => { + const picker = (props: { loading: boolean; mockData: any }) => ( + + ({ + ...p, + ...props.mockData, + })), + queryParameters: { personal: type }, + updateFilters, + loading: props.loading, + }} + > + + + + ); + + describe(`when there are no ${type} playlists`, () => { + const mockData = + type === 'owned' + ? { owner: 'group:default/no-owner' } + : { isFollowing: false }; + + it('does not reset the filter while playlists are loading', async () => { + render(picker({ loading: true, mockData })); + await waitFor(() => { + expect(updateFilters.mock.lastCall[0].personal.value).not.toBe( + 'all', + ); + }); + }); + + it('resets the filter to "all" when playlists are loaded', async () => { + render(picker({ loading: false, mockData })); + await waitFor(() => { + expect(updateFilters.mock.lastCall[0].personal.value).toBe('all'); + }); + }); + }); + + describe(`when there are some ${type} playlists present`, () => { + const mockData = {}; + + it('does not reset the filter while playlists are loading', async () => { + render(picker({ loading: true, mockData })); + await waitFor(() => { + expect(updateFilters.mock.lastCall[0].personal.value).not.toBe( + 'all', + ); + }); + }); + + it('does not reset the filter when playlists are loaded', async () => { + render(picker({ loading: false, mockData })); + await waitFor(() => { + expect(updateFilters.mock.lastCall[0].personal.value).toBe(type); + }); + }); + }); + }, + ); +}); diff --git a/plugins/playlist/src/components/PersonalListPicker/PersonalListPicker.tsx b/plugins/playlist/src/components/PersonalListPicker/PersonalListPicker.tsx new file mode 100644 index 0000000000..1172f2f6fa --- /dev/null +++ b/plugins/playlist/src/components/PersonalListPicker/PersonalListPicker.tsx @@ -0,0 +1,293 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + configApiRef, + IconComponent, + identityApiRef, + useApi, +} from '@backstage/core-plugin-api'; +import { Playlist } from '@backstage/plugin-playlist-common'; +import { + Card, + List, + ListItemIcon, + ListItemSecondaryAction, + ListItemText, + makeStyles, + MenuItem, + Theme, + Typography, +} from '@material-ui/core'; +import PlaylistPlayIcon from '@material-ui/icons/PlaylistPlay'; +import SettingsIcon from '@material-ui/icons/Settings'; +import { compact } from 'lodash'; +import React, { Fragment, useEffect, useMemo, useState } from 'react'; +import useAsync from 'react-use/lib/useAsync'; + +import { usePlaylistList } from '../../hooks'; +import { PlaylistFilter } from '../../types'; + +export const enum PersonalListFilterValue { + owned = 'owned', + following = 'following', + all = 'all', +} + +export class PersonalListFilter implements PlaylistFilter { + constructor( + readonly value: PersonalListFilterValue, + readonly isOwnedPlaylist: (playlist: Playlist) => boolean, + ) {} + + filterPlaylist(playlist: Playlist): boolean { + switch (this.value) { + case PersonalListFilterValue.owned: + return this.isOwnedPlaylist(playlist); + case PersonalListFilterValue.following: + return playlist.isFollowing; + default: + return true; + } + } + + toQueryValue(): string { + return this.value; + } +} + +const useStyles = makeStyles(theme => ({ + root: { + backgroundColor: 'rgba(0, 0, 0, .11)', + boxShadow: 'none', + margin: theme.spacing(1, 0, 1, 0), + }, + title: { + margin: theme.spacing(1, 0, 0, 1), + textTransform: 'uppercase', + fontSize: 12, + fontWeight: 'bold', + }, + listIcon: { + minWidth: 30, + color: theme.palette.text.primary, + }, + menuItem: { + minHeight: theme.spacing(6), + }, + groupWrapper: { + margin: theme.spacing(1, 1, 2, 1), + }, +})); + +type ButtonGroup = { + name: string; + items: { + id: PersonalListFilterValue; + label: string; + icon?: IconComponent; + }[]; +}; + +function getFilterGroups(orgName: string | undefined): ButtonGroup[] { + return [ + { + name: 'Personal', + items: [ + { + id: PersonalListFilterValue.owned, + label: 'Owned', + icon: SettingsIcon, + }, + { + id: PersonalListFilterValue.following, + label: 'Following', + icon: PlaylistPlayIcon, + }, + ], + }, + { + name: orgName ?? 'Company', + items: [ + { + id: PersonalListFilterValue.all, + label: 'All', + }, + ], + }, + ]; +} + +export const PersonalListPicker = () => { + const classes = useStyles(); + const configApi = useApi(configApiRef); + const identityApi = useApi(identityApiRef); + const orgName = configApi.getOptionalString('organization.name') ?? 'Company'; + const filterGroups = getFilterGroups(orgName); + + const { loading: loadingOwnership, value: ownershipRefs } = + useAsync(async () => { + const { ownershipEntityRefs } = await identityApi.getBackstageIdentity(); + return ownershipEntityRefs; + }, []); + + const isOwnedPlaylist = useMemo(() => { + const myOwnerRefs = new Set(ownershipRefs ?? []); + return (playlist: Playlist) => myOwnerRefs.has(playlist.owner); + }, [ownershipRefs]); + + const { + filters, + updateFilters, + backendPlaylists, + queryParameters: { personal: personalParameter }, + loading: loadingBackendPlaylists, + } = usePlaylistList(); + + const loading = loadingBackendPlaylists || loadingOwnership; + + // Static filters; used for generating counts of potentially unselected options + const ownedFilter = useMemo( + () => + new PersonalListFilter(PersonalListFilterValue.owned, isOwnedPlaylist), + [isOwnedPlaylist], + ); + const followingFilter = useMemo( + () => + new PersonalListFilter( + PersonalListFilterValue.following, + isOwnedPlaylist, + ), + [isOwnedPlaylist], + ); + + const queryParamPersonalFilter = useMemo( + () => [personalParameter].flat()[0], + [personalParameter], + ); + + const [selectedPersonalFilter, setSelectedPersonalFilter] = useState( + queryParamPersonalFilter ?? PersonalListFilterValue.all, + ); + + // To show proper counts for each section, apply all other frontend filters _except_ the personal + // filter that's controlled by this picker. + const playlistsWithoutPersonalFilter = useMemo( + () => + backendPlaylists.filter(playlist => + compact(Object.values({ ...filters, personal: undefined })).every( + (filter: PlaylistFilter) => + !filter.filterPlaylist || filter.filterPlaylist(playlist), + ), + ), + [filters, backendPlaylists], + ); + + const filterCounts = useMemo>( + () => ({ + all: playlistsWithoutPersonalFilter.length, + following: playlistsWithoutPersonalFilter.filter(playlist => + followingFilter.filterPlaylist(playlist), + ).length, + owned: playlistsWithoutPersonalFilter.filter(playlist => + ownedFilter.filterPlaylist(playlist), + ).length, + }), + [playlistsWithoutPersonalFilter, followingFilter, ownedFilter], + ); + + // Set selected personal filter on query parameter updates; this happens at initial page load and from + // external updates to the page location. + useEffect(() => { + if (queryParamPersonalFilter) { + setSelectedPersonalFilter(queryParamPersonalFilter); + } + }, [queryParamPersonalFilter]); + + useEffect(() => { + if ( + !loading && + !!selectedPersonalFilter && + selectedPersonalFilter !== PersonalListFilterValue.all && + filterCounts[selectedPersonalFilter] === 0 + ) { + setSelectedPersonalFilter(PersonalListFilterValue.all); + } + }, [ + loading, + filterCounts, + selectedPersonalFilter, + setSelectedPersonalFilter, + ]); + + useEffect(() => { + updateFilters({ + personal: selectedPersonalFilter + ? new PersonalListFilter( + selectedPersonalFilter as PersonalListFilterValue, + isOwnedPlaylist, + ) + : undefined, + }); + }, [selectedPersonalFilter, isOwnedPlaylist, updateFilters]); + + return ( + + {filterGroups.map(group => ( + + + {group.name} + + + + {group.items.map(item => ( + setSelectedPersonalFilter(item.id)} + selected={item.id === selectedPersonalFilter} + className={classes.menuItem} + disabled={filterCounts[item.id] === 0} + data-testid={`personal-picker-${item.id}`} + tabIndex={0} + ContainerProps={{ role: 'menuitem' }} + > + {item.icon && ( + + + + )} + + {item.label} + + + {filterCounts[item.id] || '-'} + + + ))} + + + + ))} + + ); +}; diff --git a/plugins/playlist/src/components/PersonalListPicker/index.ts b/plugins/playlist/src/components/PersonalListPicker/index.ts new file mode 100644 index 0000000000..f67f18ab39 --- /dev/null +++ b/plugins/playlist/src/components/PersonalListPicker/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './PersonalListPicker'; diff --git a/plugins/playlist/src/components/PlaylistCard/PlaylistCard.test.tsx b/plugins/playlist/src/components/PlaylistCard/PlaylistCard.test.tsx new file mode 100644 index 0000000000..177cc23b81 --- /dev/null +++ b/plugins/playlist/src/components/PlaylistCard/PlaylistCard.test.tsx @@ -0,0 +1,57 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { entityRouteRef } from '@backstage/plugin-catalog-react'; +import { renderInTestApp } from '@backstage/test-utils'; +import { lightTheme } from '@backstage/theme'; +import { ThemeProvider } from '@material-ui/core'; +import React from 'react'; + +import { rootRouteRef } from '../../routes'; +import { PlaylistCard } from './PlaylistCard'; + +describe('', () => { + it('renders playlist info', async () => { + const rendered = await renderInTestApp( + + + , + { + mountedRoutes: { + '/playlists': rootRouteRef, + '/catalog/:namespace/:kind/:name': entityRouteRef, + }, + }, + ); + + expect(rendered.getByText('playlist-1')).toBeInTheDocument(); + expect(rendered.getByText('test description')).toBeInTheDocument(); + expect(rendered.getByText('some-owner')).toBeInTheDocument(); + expect(rendered.getByText('3 entities')).toBeInTheDocument(); + expect(rendered.getByText('2 followers')).toBeInTheDocument(); + }); +}); diff --git a/plugins/playlist/src/components/PlaylistCard/PlaylistCard.tsx b/plugins/playlist/src/components/PlaylistCard/PlaylistCard.tsx new file mode 100644 index 0000000000..2db7e85f7e --- /dev/null +++ b/plugins/playlist/src/components/PlaylistCard/PlaylistCard.tsx @@ -0,0 +1,131 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + Button, + ItemCardHeader, + MarkdownContent, +} from '@backstage/core-components'; +import { useRouteRef } from '@backstage/core-plugin-api'; +import { EntityRefLinks } from '@backstage/plugin-catalog-react'; +import { Playlist } from '@backstage/plugin-playlist-common'; +import { BackstageTheme } from '@backstage/theme'; +import { + Box, + Card, + CardActions, + CardContent, + CardMedia, + Chip, + makeStyles, + Tooltip, + Typography, +} from '@material-ui/core'; +import LockIcon from '@material-ui/icons/Lock'; +import React from 'react'; + +import { playlistRouteRef } from '../../routes'; + +const useStyles = makeStyles((theme: BackstageTheme) => ({ + cardHeader: { + position: 'relative', + }, + title: { + backgroundImage: theme.getPageTheme({ themeId: 'home' }).backgroundImage, + }, + box: { + overflow: 'hidden', + textOverflow: 'ellipsis', + display: '-webkit-box', + '-webkit-line-clamp': 10, + '-webkit-box-orient': 'vertical', + paddingBottom: '0.8em', + }, + label: { + color: theme.palette.text.secondary, + textTransform: 'uppercase', + fontSize: '0.65rem', + fontWeight: 'bold', + letterSpacing: 0.5, + lineHeight: 1, + paddingBottom: '0.2rem', + }, + chip: { + marginRight: 'auto', + }, + privateIcon: { + position: 'absolute', + top: theme.spacing(0.5), + right: theme.spacing(0.5), + padding: '0.25rem', + }, +})); + +export type PlaylistCardProps = { + playlist: Playlist; +}; + +export const PlaylistCard = ({ playlist }: PlaylistCardProps) => { + const classes = useStyles(); + const playlistRoute = useRouteRef(playlistRouteRef); + + return ( + + + {!playlist.public && ( + + + + )} + + + + + + + + + Description + + + + + + Owner + + + + + + + + + ); +}; diff --git a/plugins/playlist/src/components/PlaylistCard/index.ts b/plugins/playlist/src/components/PlaylistCard/index.ts new file mode 100644 index 0000000000..d043c8b6d0 --- /dev/null +++ b/plugins/playlist/src/components/PlaylistCard/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './PlaylistCard'; diff --git a/plugins/playlist/src/components/PlaylistEditDialog/PlaylistEditDialog.test.tsx b/plugins/playlist/src/components/PlaylistEditDialog/PlaylistEditDialog.test.tsx new file mode 100644 index 0000000000..9f30d7608c --- /dev/null +++ b/plugins/playlist/src/components/PlaylistEditDialog/PlaylistEditDialog.test.tsx @@ -0,0 +1,86 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { IdentityApi, identityApiRef } from '@backstage/core-plugin-api'; +import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; +import { fireEvent, getByRole, waitFor } from '@testing-library/react'; +import { act } from '@testing-library/react-hooks'; +import React from 'react'; + +import { PlaylistEditDialog } from './PlaylistEditDialog'; + +describe('', () => { + it('handle saving with an edited playlist', async () => { + const identityApi: Partial = { + getBackstageIdentity: async () => ({ + type: 'user', + userEntityRef: 'user:default/me', + ownershipEntityRefs: ['group:default/test-owner', 'user:default/me'], + }), + }; + + const mockOnSave = jest.fn().mockImplementation(async () => {}); + const rendered = await renderInTestApp( + + + , + ); + + act(() => { + fireEvent.input( + getByRole(rendered.getByTestId('edit-dialog-name-input'), 'textbox'), + { + target: { + value: 'test playlist', + }, + }, + ); + + fireEvent.input( + getByRole( + rendered.getByTestId('edit-dialog-description-input'), + 'textbox', + ), + { + target: { + value: 'test description', + }, + }, + ); + + fireEvent.mouseDown( + getByRole(rendered.getByTestId('edit-dialog-owner-select'), 'button'), + ); + + fireEvent.click(rendered.getByText('test-owner')); + + fireEvent.click( + getByRole(rendered.getByTestId('edit-dialog-public-option'), 'radio'), + ); + + fireEvent.click(rendered.getByTestId('edit-dialog-save-button')); + }); + + await waitFor(() => { + expect(mockOnSave).toHaveBeenCalledWith({ + name: 'test playlist', + description: 'test description', + owner: 'group:default/test-owner', + public: true, + }); + }); + }); +}); diff --git a/plugins/playlist/src/components/PlaylistEditDialog/PlaylistEditDialog.tsx b/plugins/playlist/src/components/PlaylistEditDialog/PlaylistEditDialog.tsx new file mode 100644 index 0000000000..27cc13fede --- /dev/null +++ b/plugins/playlist/src/components/PlaylistEditDialog/PlaylistEditDialog.tsx @@ -0,0 +1,217 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { parseEntityRef } from '@backstage/catalog-model'; +import { identityApiRef, useApi } from '@backstage/core-plugin-api'; +import { humanizeEntityRef } from '@backstage/plugin-catalog-react'; +import { PlaylistMetadata } from '@backstage/plugin-playlist-common'; +import { + Button, + CircularProgress, + Dialog, + DialogActions, + DialogContent, + FormControl, + FormControlLabel, + InputLabel, + makeStyles, + MenuItem, + LinearProgress, + Radio, + RadioGroup, + Select, + TextField, +} from '@material-ui/core'; +import React from 'react'; +import { useForm, Controller } from 'react-hook-form'; +import useAsync from 'react-use/lib/useAsync'; +import useAsyncFn from 'react-use/lib/useAsyncFn'; + +const useStyles = makeStyles({ + buttonWrapper: { + position: 'relative', + }, + buttonProgress: { + position: 'absolute', + top: '50%', + left: '50%', + marginTop: -12, + marginLeft: -12, + }, +}); + +export type PlaylistEditDialogProps = { + open: boolean; + onClose: () => void; + onSave: (playlist: Omit) => Promise; + playlist?: Omit; +}; + +export const PlaylistEditDialog = ({ + open, + onClose, + onSave, + playlist = { + name: '', + description: '', + owner: '', + public: false, + }, +}: PlaylistEditDialogProps) => { + const classes = useStyles(); + const identityApi = useApi(identityApiRef); + + const { loading: loadingOwnership, value: ownershipRefs } = + useAsync(async () => { + const { ownershipEntityRefs } = await identityApi.getBackstageIdentity(); + return ownershipEntityRefs; + }, []); + + const defaultValues = { + ...playlist, + public: playlist.public.toString(), + }; + + const { + control, + formState: { errors }, + handleSubmit, + reset, + } = useForm({ defaultValues }); + + const [saving, savePlaylist] = useAsyncFn( + formValues => + onSave({ ...formValues, public: JSON.parse(formValues.public) }), + [onSave], + ); + + const closeDialog = () => { + if (!saving.loading) { + onClose(); + reset(defaultValues); + } + }; + + return ( + + + ( + + )} + /> + ( + + )} + /> + {loadingOwnership ? ( + + ) : ( + ( + + Owner + + + )} + /> + )} + ( + + + } + /> + } + /> + + + )} + /> + + + +
+ + {saving.loading && ( + + )} +
+
+
+ ); +}; diff --git a/plugins/playlist/src/components/PlaylistEditDialog/index.ts b/plugins/playlist/src/components/PlaylistEditDialog/index.ts new file mode 100644 index 0000000000..3355443b82 --- /dev/null +++ b/plugins/playlist/src/components/PlaylistEditDialog/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './PlaylistEditDialog'; diff --git a/plugins/playlist/src/components/PlaylistIndexPage/PlaylistIndexPage.test.tsx b/plugins/playlist/src/components/PlaylistIndexPage/PlaylistIndexPage.test.tsx new file mode 100644 index 0000000000..6dae17d3bc --- /dev/null +++ b/plugins/playlist/src/components/PlaylistIndexPage/PlaylistIndexPage.test.tsx @@ -0,0 +1,52 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; +import { AuthorizeResult } from '@backstage/plugin-permission-common'; +import { + PermissionApi, + permissionApiRef, +} from '@backstage/plugin-permission-react'; +import React from 'react'; + +import { PlaylistApi, playlistApiRef } from '../../api'; +import { rootRouteRef } from '../../routes'; +import { PlaylistIndexPage } from './PlaylistIndexPage'; + +const playlistApi: Partial = { + getAllPlaylists: async () => [], +}; + +const permissionApi: Partial = { + authorize: async () => ({ result: AuthorizeResult.ALLOW }), +}; + +describe('PlaylistIndexPage', () => { + it('should render', async () => { + const rendered = await renderInTestApp( + + + , + { mountedRoutes: { '/playlists': rootRouteRef } }, + ); + expect(rendered.getByText('Playlists')).toBeInTheDocument(); + }); +}); diff --git a/plugins/playlist/src/components/PlaylistIndexPage/PlaylistIndexPage.tsx b/plugins/playlist/src/components/PlaylistIndexPage/PlaylistIndexPage.tsx new file mode 100644 index 0000000000..0ee829018a --- /dev/null +++ b/plugins/playlist/src/components/PlaylistIndexPage/PlaylistIndexPage.tsx @@ -0,0 +1,56 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import { + PageWithHeader, + Content, + ContentHeader, + SupportButton, +} from '@backstage/core-components'; +import { CatalogFilterLayout } from '@backstage/plugin-catalog-react'; + +import { PlaylistListProvider } from '../../hooks'; +import { CreatePlaylistButton } from '../CreatePlaylistButton'; +import { PersonalListPicker } from '../PersonalListPicker'; +import { PlaylistList } from '../PlaylistList'; +import { PlaylistOwnerPicker } from '../PlaylistOwnerPicker'; +import { PlaylistSearchBar } from '../PlaylistSearchBar'; +import { PlaylistSortPicker } from '../PlaylistSortPicker'; + +export const PlaylistIndexPage = () => ( + + + + + + + + + + + + + + + + + + + + + +); diff --git a/plugins/playlist/src/components/PlaylistIndexPage/index.ts b/plugins/playlist/src/components/PlaylistIndexPage/index.ts new file mode 100644 index 0000000000..06858a8262 --- /dev/null +++ b/plugins/playlist/src/components/PlaylistIndexPage/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export { PlaylistIndexPage } from './PlaylistIndexPage'; diff --git a/plugins/playlist/src/components/PlaylistList/PlaylistList.test.tsx b/plugins/playlist/src/components/PlaylistList/PlaylistList.test.tsx new file mode 100644 index 0000000000..27030ec1c7 --- /dev/null +++ b/plugins/playlist/src/components/PlaylistList/PlaylistList.test.tsx @@ -0,0 +1,86 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Playlist } from '@backstage/plugin-playlist-common'; +import { render } from '@testing-library/react'; +import React from 'react'; + +import { MockPlaylistListProvider } from '../../testUtils'; +import { PlaylistList } from './PlaylistList'; + +jest.mock('../PlaylistCard', () => ({ + PlaylistCard: ({ playlist }: { playlist: Playlist }) => ( +
{playlist.name}
+ ), +})); + +describe('', () => { + it('renders error on error', () => { + const rendered = render( + + + , + ); + + expect(rendered.getByText('Test Error')).toBeInTheDocument(); + }); + + it('handles no playlists', () => { + const rendered = render( + + + , + ); + + expect( + rendered.getByText('No playlists found that match your filter.'), + ).toBeInTheDocument(); + }); + + it('renders playlists', () => { + const rendered = render( + + + , + ); + + expect(rendered.getByText('playlist-1')).toBeInTheDocument(); + expect(rendered.getByText('playlist-2')).toBeInTheDocument(); + }); +}); diff --git a/plugins/playlist/src/components/PlaylistList/PlaylistList.tsx b/plugins/playlist/src/components/PlaylistList/PlaylistList.tsx new file mode 100644 index 0000000000..fcc3971542 --- /dev/null +++ b/plugins/playlist/src/components/PlaylistList/PlaylistList.tsx @@ -0,0 +1,58 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import { + Content, + ItemCardGrid, + Progress, + WarningPanel, +} from '@backstage/core-components'; +import { Typography } from '@material-ui/core'; + +import { usePlaylistList } from '../../hooks'; +import { PlaylistCard } from '../PlaylistCard'; + +export const PlaylistList = () => { + const { loading, error, playlists } = usePlaylistList(); + + return ( + <> + {loading && } + + {error && ( + + {error.message} + + )} + + {!error && !loading && !playlists.length && ( + + No playlists found that match your filter. + + )} + + + + {playlists?.length > 0 && + playlists.map(playlist => ( + + ))} + + + + ); +}; diff --git a/plugins/playlist/src/components/PlaylistList/index.ts b/plugins/playlist/src/components/PlaylistList/index.ts new file mode 100644 index 0000000000..59fa5cf0fb --- /dev/null +++ b/plugins/playlist/src/components/PlaylistList/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './PlaylistList'; diff --git a/plugins/playlist/src/components/PlaylistOwnerPicker/PlaylistOwnerPicker.test.tsx b/plugins/playlist/src/components/PlaylistOwnerPicker/PlaylistOwnerPicker.test.tsx new file mode 100644 index 0000000000..c74e6f6853 --- /dev/null +++ b/plugins/playlist/src/components/PlaylistOwnerPicker/PlaylistOwnerPicker.test.tsx @@ -0,0 +1,215 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { parseEntityRef } from '@backstage/catalog-model'; +import { humanizeEntityRef } from '@backstage/plugin-catalog-react'; +import { Playlist } from '@backstage/plugin-playlist-common'; +import { fireEvent, render } from '@testing-library/react'; +import React from 'react'; +import { MockPlaylistListProvider } from '../../testUtils'; +import { + PlaylistOwnerFilter, + PlaylistOwnerPicker, +} from './PlaylistOwnerPicker'; + +const samplePlaylists: Playlist[] = [ + { + id: 'id1', + name: 'playlist-1', + owner: 'group:default/some-owner', + public: true, + entities: 1, + followers: 2, + isFollowing: false, + }, + { + id: 'id2', + name: 'playlist-2', + owner: 'group:default/another-owner', + public: true, + entities: 2, + followers: 1, + isFollowing: true, + }, + { + id: 'id3', + name: 'playlist-3', + owner: 'group:default/another-owner', + public: true, + entities: 2, + followers: 1, + isFollowing: true, + }, + { + id: 'id4', + name: 'playlist-4', + owner: 'user:default/owner', + public: true, + entities: 2, + followers: 1, + isFollowing: true, + }, +]; + +describe('', () => { + it('renders all owners', () => { + const rendered = render( + + + , + ); + expect(rendered.getByText('Owner')).toBeInTheDocument(); + + fireEvent.click(rendered.getByTestId('owner-picker-expand')); + samplePlaylists + .map(p => + humanizeEntityRef(parseEntityRef(p.owner), { defaultKind: 'group' }), + ) + .forEach(owner => { + expect(rendered.getByText(owner as string)).toBeInTheDocument(); + }); + }); + + it('renders unique owners in alphabetical order', () => { + const rendered = render( + + + , + ); + expect(rendered.getByText('Owner')).toBeInTheDocument(); + + fireEvent.click(rendered.getByTestId('owner-picker-expand')); + + expect(rendered.getAllByRole('option').map(o => o.textContent)).toEqual([ + 'another-owner', + 'some-owner', + 'user:owner', + ]); + }); + + it('respects the query parameter filter value', () => { + const updateFilters = jest.fn(); + const queryParameters = { owners: ['group:default/another-owner'] }; + render( + + + , + ); + + expect(updateFilters).toHaveBeenLastCalledWith({ + owners: new PlaylistOwnerFilter(['group:default/another-owner']), + }); + }); + + it('adds owners to filters', () => { + const updateFilters = jest.fn(); + const rendered = render( + + + , + ); + expect(updateFilters).toHaveBeenLastCalledWith({ + owners: undefined, + }); + + fireEvent.click(rendered.getByTestId('owner-picker-expand')); + fireEvent.click(rendered.getByText('some-owner')); + expect(updateFilters).toHaveBeenLastCalledWith({ + owners: new PlaylistOwnerFilter(['group:default/some-owner']), + }); + }); + + it('removes owners from filters', () => { + const updateFilters = jest.fn(); + const rendered = render( + + + , + ); + expect(updateFilters).toHaveBeenLastCalledWith({ + owners: new PlaylistOwnerFilter(['group:default/some-owner']), + }); + fireEvent.click(rendered.getByTestId('owner-picker-expand')); + expect(rendered.getByLabelText('some-owner')).toBeChecked(); + + fireEvent.click(rendered.getByLabelText('some-owner')); + expect(updateFilters).toHaveBeenLastCalledWith({ + owner: undefined, + }); + }); + + it('responds to external queryParameters changes', () => { + const updateFilters = jest.fn(); + const rendered = render( + + + , + ); + expect(updateFilters).toHaveBeenLastCalledWith({ + owners: new PlaylistOwnerFilter(['group:default/team-a']), + }); + rendered.rerender( + + + , + ); + expect(updateFilters).toHaveBeenLastCalledWith({ + owners: new PlaylistOwnerFilter(['group:default/team-b']), + }); + }); +}); diff --git a/plugins/playlist/src/components/PlaylistOwnerPicker/PlaylistOwnerPicker.tsx b/plugins/playlist/src/components/PlaylistOwnerPicker/PlaylistOwnerPicker.tsx new file mode 100644 index 0000000000..7def794c6b --- /dev/null +++ b/plugins/playlist/src/components/PlaylistOwnerPicker/PlaylistOwnerPicker.tsx @@ -0,0 +1,134 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { parseEntityRef } from '@backstage/catalog-model'; +import { humanizeEntityRef } from '@backstage/plugin-catalog-react'; +import { Playlist } from '@backstage/plugin-playlist-common'; +import { + Box, + Checkbox, + Chip, + FormControlLabel, + TextField, + Typography, +} from '@material-ui/core'; +import CheckBoxIcon from '@material-ui/icons/CheckBox'; +import CheckBoxOutlineBlankIcon from '@material-ui/icons/CheckBoxOutlineBlank'; +import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; +import { Autocomplete } from '@material-ui/lab'; +import React, { useEffect, useMemo, useState } from 'react'; + +import { usePlaylistList } from '../../hooks'; +import { PlaylistFilter } from '../../types'; + +export class PlaylistOwnerFilter implements PlaylistFilter { + constructor(readonly values: string[]) {} + + filterPlaylist(playlist: Playlist): boolean { + return this.values.some(v => playlist.owner === v); + } + + toQueryValue(): string[] { + return this.values; + } +} + +const icon = ; +const checkedIcon = ; + +export const PlaylistOwnerPicker = () => { + const { + updateFilters, + backendPlaylists, + filters, + queryParameters: { owners: ownersParameter }, + } = usePlaylistList(); + + const queryParamOwners = useMemo( + () => [ownersParameter].flat().filter(Boolean) as string[], + [ownersParameter], + ); + + const [selectedOwners, setSelectedOwners] = useState( + queryParamOwners.length ? queryParamOwners : filters.owners?.values ?? [], + ); + + // Set selected owners on query parameter updates; this happens at initial page load and from + // external updates to the page location. + useEffect(() => { + if (queryParamOwners.length) { + setSelectedOwners(queryParamOwners); + } + }, [queryParamOwners]); + + useEffect(() => { + updateFilters({ + owners: selectedOwners.length + ? new PlaylistOwnerFilter(selectedOwners) + : undefined, + }); + }, [selectedOwners, updateFilters]); + + const availableOwners = useMemo( + () => [...new Set(backendPlaylists.map(p => p.owner))].sort(), + [backendPlaylists], + ); + + if (!availableOwners.length) return null; + + return ( + + + Owner + setSelectedOwners(value)} + renderTags={(values: string[], getTagProps: Function) => + values.map((val, index) => ( + + )) + } + renderOption={(option, { selected }) => ( + + } + label={humanizeEntityRef(parseEntityRef(option), { + defaultKind: 'group', + })} + /> + )} + size="small" + popupIcon={} + renderInput={params => } + /> + + + ); +}; diff --git a/plugins/playlist/src/components/PlaylistOwnerPicker/index.ts b/plugins/playlist/src/components/PlaylistOwnerPicker/index.ts new file mode 100644 index 0000000000..fcde27e956 --- /dev/null +++ b/plugins/playlist/src/components/PlaylistOwnerPicker/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './PlaylistOwnerPicker'; diff --git a/plugins/playlist/src/components/PlaylistPage/AddEntitiesDrawer.test.tsx b/plugins/playlist/src/components/PlaylistPage/AddEntitiesDrawer.test.tsx new file mode 100644 index 0000000000..d1bdf1d46a --- /dev/null +++ b/plugins/playlist/src/components/PlaylistPage/AddEntitiesDrawer.test.tsx @@ -0,0 +1,159 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + CatalogApi, + catalogApiRef, + entityRouteRef, +} from '@backstage/plugin-catalog-react'; +import { SearchApi, searchApiRef } from '@backstage/plugin-search-react'; +import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; +import { fireEvent, getByText } from '@testing-library/react'; +import { act } from '@testing-library/react-hooks'; +import React from 'react'; + +import { AddEntitiesDrawer } from './AddEntitiesDrawer'; + +describe('AddEntitiesDrawer', () => { + const catalogApi: Partial = { + getEntityFacets: jest.fn().mockImplementation(async () => ({ + facets: { + kind: [{ value: 'component' }], + }, + })), + }; + + const mockOnAdd = jest.fn(); + const sampleCurrentEntities = [ + { + apiVersion: 'backstage.io/v1alpha1', + kind: 'system', + metadata: { namespace: 'default', name: 'test-ent' }, + }, + ]; + + const mockSearchResults = [ + { + type: 'software-catalog', + document: { + title: 'Test Ent', + text: 'This is test ent', + location: '/catalog/default/system/test-ent', + kind: 'system', + }, + }, + { + type: 'software-catalog', + document: { + title: 'Test Ent 2', + text: 'This is test ent 2', + location: '/catalog/foo/component/test-ent2', + kind: 'component', + type: 'library', + }, + }, + { + type: 'software-catalog', + document: { + title: 'Test Ent 3', + text: 'This is test ent 3', + location: '/catalog/bar/api/test-ent3', + kind: 'api', + type: 'openapi', + }, + }, + ]; + + const searchApi: Partial = { + query: jest + .fn() + .mockImplementation(async () => ({ results: mockSearchResults })), + }; + + const element = ( + + + + ); + + const render = async () => + renderInTestApp(element, { + mountedRoutes: { '/catalog/:namespace/:kind/:name': entityRouteRef }, + }); + + beforeEach(() => { + mockOnAdd.mockClear(); + }); + + it('should render available entities correctly', async () => { + const rendered = await render(); + expect(searchApi.query).toHaveBeenLastCalledWith({ + filters: {}, + term: '', + types: ['software-catalog'], + }); + + expect(rendered.getByText('Test Ent')).toBeInTheDocument(); + expect(rendered.getByText('This is test ent')).toBeInTheDocument(); + expect(rendered.getByText('Kind: system')).toBeInTheDocument(); + + expect(rendered.getByText('Test Ent 2')).toBeInTheDocument(); + expect(rendered.getByText('This is test ent 2')).toBeInTheDocument(); + expect(rendered.getByText('Kind: component')).toBeInTheDocument(); + expect(rendered.getByText('Type: library')).toBeInTheDocument(); + + expect(rendered.getByText('Test Ent 3')).toBeInTheDocument(); + expect(rendered.getByText('This is test ent 3')).toBeInTheDocument(); + expect(rendered.getByText('Kind: api')).toBeInTheDocument(); + expect(rendered.getByText('Type: openapi')).toBeInTheDocument(); + }); + + it('should disable options that are already added', async () => { + const rendered = await render(); + + const addButtons = rendered.getAllByTestId('entity-drawer-add-button'); + expect(addButtons.length).toEqual(3); + + expect(getByText(addButtons[0], 'Added')).toBeInTheDocument(); + expect(addButtons[0]).toBeDisabled(); + + expect(getByText(addButtons[1], 'Add')).toBeInTheDocument(); + expect(addButtons[1]).not.toBeDisabled(); + + expect(getByText(addButtons[2], 'Add')).toBeInTheDocument(); + expect(addButtons[2]).not.toBeDisabled(); + }); + + it('should add entities correctly', async () => { + const rendered = await render(); + + act(() => { + fireEvent.click(rendered.getAllByTestId('entity-drawer-add-button')[1]); + }); + + expect(mockOnAdd).toHaveBeenCalledWith('component:foo/test-ent2'); + }); +}); diff --git a/plugins/playlist/src/components/PlaylistPage/AddEntitiesDrawer.tsx b/plugins/playlist/src/components/PlaylistPage/AddEntitiesDrawer.tsx new file mode 100644 index 0000000000..05dd4da231 --- /dev/null +++ b/plugins/playlist/src/components/PlaylistPage/AddEntitiesDrawer.tsx @@ -0,0 +1,239 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + Entity, + getCompoundEntityRef, + stringifyEntityRef, +} from '@backstage/catalog-model'; +import { useApi, useRouteRef } from '@backstage/core-plugin-api'; +import { CatalogEntityDocument } from '@backstage/plugin-catalog-common'; +import { catalogApiRef, entityRouteRef } from '@backstage/plugin-catalog-react'; +import { + SearchBar, + SearchContextProvider, + SearchFilter, + SearchResult, + SearchResultPager, + useSearch, +} from '@backstage/plugin-search-react'; +import { + Box, + Button, + Chip, + createStyles, + Divider, + Drawer, + Grid, + List, + ListItem, + ListItemSecondaryAction, + ListItemText, + makeStyles, + Paper, + Theme, + Typography, +} from '@material-ui/core'; +import React, { useCallback, useEffect, useMemo } from 'react'; + +const useStyles = makeStyles((theme: Theme) => + createStyles({ + paper: { + width: '50%', + padding: theme.spacing(2.5), + }, + searchBarContainer: { + borderRadius: 30, + display: 'flex', + height: '2.4em', + }, + gridContainer: { + height: '100%', + }, + searchResults: { + overflow: 'auto', + }, + itemContainer: { + flexWrap: 'wrap', + paddingRight: '75px', + }, + itemText: { + width: '100%', + wordBreak: 'break-word', + marginBottom: '1rem', + }, + }), +); + +const RestrictCatalogIndexResults = () => { + const { setTypes } = useSearch(); + useEffect(() => setTypes(['software-catalog']), [setTypes]); + return null; +}; + +export type AddEntitiesDrawerProps = { + currentEntities: Entity[]; + open: boolean; + onAdd: (entityRef: string) => void; + onClose: () => void; +}; + +export const AddEntitiesDrawer = ({ + currentEntities, + open, + onAdd, + onClose, +}: AddEntitiesDrawerProps) => { + const classes = useStyles(); + const catalogApi = useApi(catalogApiRef); + const entityRoute = useRouteRef(entityRouteRef); + const entityLocationRegex = useMemo(() => { + const forwardSlashRegex = new RegExp('/', 'g'); + const locationRegex = entityRoute({ + namespace: '(?.+?)', + kind: '(?.+?)', + name: '(?.+?)', + }).replace(forwardSlashRegex, '\\/'); + + return new RegExp(`${locationRegex}$`); + }, [entityRoute]); + + const currentEntityLocations = useMemo( + () => + currentEntities.map(entity => + entityRoute(getCompoundEntityRef(entity)).toLocaleLowerCase('en-US'), + ), + [currentEntities, entityRoute], + ); + + const getEntityKinds = async () => { + return ( + await catalogApi.getEntityFacets({ facets: ['kind'] }) + ).facets.kind.map(f => f.value); + }; + + const addEntity = useCallback( + entityResult => { + // TODO (kuangp): this parsing of the location is not great. Ideally `CatalogEntityDocument` + // contains the `metadata.name` field so we can derive the full ref and we only fall back to + // parsing location if it's missing (ie. for older versions) + const { groups } = entityResult.location.match(entityLocationRegex); + if (groups) { + onAdd(stringifyEntityRef(groups)); + } else { + // eslint-disable-next-line no-console + console.error( + `Failed to parse entity ref from entity location: ${entityResult.location}`, + ); + } + }, + [entityLocationRegex, onAdd], + ); + + return ( + + + + + + + Let's find something for your playlist + + + + + + + + + + + + + {({ results }) => ( + + {results.map(({ document }) => ( + + +
+ + + + + + {(document as CatalogEntityDocument).kind && ( + + )} + {(document as CatalogEntityDocument).type && ( + + )} + +
+
+ +
+ ))} +
+ )} +
+ +
+
+
+
+ ); +}; diff --git a/plugins/playlist/src/components/PlaylistPage/PlaylistEntitiesTable.test.tsx b/plugins/playlist/src/components/PlaylistPage/PlaylistEntitiesTable.test.tsx new file mode 100644 index 0000000000..3dfd89fda9 --- /dev/null +++ b/plugins/playlist/src/components/PlaylistPage/PlaylistEntitiesTable.test.tsx @@ -0,0 +1,211 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ErrorApi, errorApiRef } from '@backstage/core-plugin-api'; +import { + CatalogApi, + catalogApiRef, + entityRouteRef, +} from '@backstage/plugin-catalog-react'; +import { AuthorizeResult } from '@backstage/plugin-permission-common'; +import { + PermissionApi, + permissionApiRef, +} from '@backstage/plugin-permission-react'; +import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; +import { Button } from '@material-ui/core'; +import { fireEvent, waitFor } from '@testing-library/react'; +import { act } from '@testing-library/react-hooks'; +import React from 'react'; +import { SWRConfig } from 'swr'; + +import { PlaylistApi, playlistApiRef } from '../../api'; +import { PlaylistEntitiesTable } from './PlaylistEntitiesTable'; + +jest.mock('./AddEntitiesDrawer', () => ({ + AddEntitiesDrawer: ({ onAdd, open }: { onAdd: Function; open: boolean }) => + open ? ( + +
+ + {deleting.loading && ( + + )} +
+ + +
+ ); +}; diff --git a/plugins/playlist/src/components/PlaylistPage/PlaylistPage.test.tsx b/plugins/playlist/src/components/PlaylistPage/PlaylistPage.test.tsx new file mode 100644 index 0000000000..65d3d79be6 --- /dev/null +++ b/plugins/playlist/src/components/PlaylistPage/PlaylistPage.test.tsx @@ -0,0 +1,141 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ErrorApi, errorApiRef } from '@backstage/core-plugin-api'; +import { AuthorizeResult } from '@backstage/plugin-permission-common'; +import { + PermissionApi, + permissionApiRef, +} from '@backstage/plugin-permission-react'; +import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; +import { fireEvent, getByText, waitFor } from '@testing-library/react'; +import { act } from '@testing-library/react-hooks'; +import React from 'react'; +import { SWRConfig } from 'swr'; + +import { PlaylistApi, playlistApiRef } from '../../api'; +import { PlaylistPage } from './PlaylistPage'; + +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), + useParams: () => ({ playlistId: 'id1' }), +})); + +// Mock out nested components to simplify tests +jest.mock('./PlaylistEntitiesTable', () => ({ + PlaylistEntitiesTable: () => null, +})); + +jest.mock('./PlaylistHeader', () => ({ + PlaylistHeader: () => null, +})); + +describe('PlaylistPage', () => { + const testPlaylist = { + id: 'id1', + name: 'playlist-1', + description: 'test description', + owner: 'group:default/some-owner', + public: true, + entities: 1, + followers: 2, + isFollowing: false, + }; + + const errorApi: Partial = { post: jest.fn() }; + const playlistApi: Partial = { + getPlaylist: jest.fn().mockImplementation(async () => testPlaylist), + followPlaylist: jest.fn().mockImplementation(async () => {}), + unfollowPlaylist: jest.fn().mockImplementation(async () => {}), + }; + const mockAuthorize = jest + .fn() + .mockImplementation(async () => ({ result: AuthorizeResult.ALLOW })); + const permissionApi: Partial = { authorize: mockAuthorize }; + + // SWR used by the usePermission hook needs cache to be reset for each test + const element = ( + new Map() }}> + + + + + ); + + beforeEach(() => { + mockAuthorize.mockClear(); + }); + + it('show render the playlist info', async () => { + const rendered = await renderInTestApp(element); + expect(playlistApi.getPlaylist).toHaveBeenCalledWith('id1'); + expect(rendered.getByText('test description')).toBeInTheDocument(); + expect( + rendered.getByTestId('playlist-page-follow-button'), + ).toBeInTheDocument(); + expect( + getByText(rendered.getByTestId('playlist-page-follow-button'), 'Follow'), + ).toBeInTheDocument(); + }); + + it('should not render the follow button if unauthorized', async () => { + mockAuthorize.mockImplementationOnce(async () => ({ + result: AuthorizeResult.DENY, + })); + const rendered = await renderInTestApp(element); + expect(rendered.queryByTestId('playlist-page-follow-button')).toBeNull(); + }); + + it('should reflect and toggle the following state of the playlist', async () => { + const rendered = await renderInTestApp(element); + + act(() => { + fireEvent.click(rendered.getByTestId('playlist-page-follow-button')); + testPlaylist.isFollowing = true; + }); + + await waitFor(() => { + expect(playlistApi.followPlaylist).toHaveBeenCalledWith('id1'); + expect( + getByText( + rendered.getByTestId('playlist-page-follow-button'), + 'Following', + ), + ).toBeInTheDocument(); + }); + + act(() => { + fireEvent.click(rendered.getByTestId('playlist-page-follow-button')); + testPlaylist.isFollowing = false; + }); + + await waitFor(() => { + expect(playlistApi.unfollowPlaylist).toHaveBeenCalledWith('id1'); + expect( + getByText( + rendered.getByTestId('playlist-page-follow-button'), + 'Follow', + ), + ).toBeInTheDocument(); + }); + }); +}); diff --git a/plugins/playlist/src/components/PlaylistPage/PlaylistPage.tsx b/plugins/playlist/src/components/PlaylistPage/PlaylistPage.tsx new file mode 100644 index 0000000000..4c9a0edbb7 --- /dev/null +++ b/plugins/playlist/src/components/PlaylistPage/PlaylistPage.tsx @@ -0,0 +1,133 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Content, ErrorPage, Page } from '@backstage/core-components'; +import { errorApiRef, useApi } from '@backstage/core-plugin-api'; +import { ResponseError } from '@backstage/errors'; +import { usePermission } from '@backstage/plugin-permission-react'; +import { permissions } from '@backstage/plugin-playlist-common'; +import { + Button, + Card, + CardContent, + CardHeader, + Divider, + LinearProgress, + makeStyles, + Typography, +} from '@material-ui/core'; +import React, { useEffect } from 'react'; +import { useParams } from 'react-router-dom'; +import useAsyncFn from 'react-use/lib/useAsyncFn'; + +import { playlistApiRef } from '../../api'; +import { PlaylistEntitiesTable } from './PlaylistEntitiesTable'; +import { PlaylistHeader } from './PlaylistHeader'; + +const useStyles = makeStyles({ + followButton: { + top: '6px', + right: '8px', + }, +}); + +export const PlaylistPage = () => { + const classes = useStyles(); + const errorApi = useApi(errorApiRef); + const playlistApi = useApi(playlistApiRef); + const { playlistId } = useParams(); + + const [{ value: playlist, loading, error }, loadPlaylist] = useAsyncFn( + () => playlistApi.getPlaylist(playlistId!), + [playlistApi], + ); + + useEffect(() => { + loadPlaylist(); + }, [loadPlaylist]); + + const { allowed: followAllowed } = usePermission({ + permission: permissions.playlistFollowersUpdate, + resourceRef: playlist?.id, + }); + + const [{ loading: loadingFollowRequest }, followPlaylist] = + useAsyncFn(async () => { + try { + if (playlist!.isFollowing) { + await playlistApi.unfollowPlaylist(playlist!.id); + } else { + await playlistApi.followPlaylist(playlist!.id); + } + + loadPlaylist(); + } catch (e) { + errorApi.post(e); + } + }, [errorApi, loadPlaylist, playlist, playlistApi]); + + if (error) { + return ( + + ); + } + + return ( + <> + {loading && } + + {playlist && ( + <> + + + + + {playlist.isFollowing ? 'Following' : 'Follow'} + + ) + } + /> + + + + {playlist.description} + + + +
+ +
+ + )} +
+ + ); +}; diff --git a/plugins/playlist/src/components/PlaylistPage/index.ts b/plugins/playlist/src/components/PlaylistPage/index.ts new file mode 100644 index 0000000000..695b243cd0 --- /dev/null +++ b/plugins/playlist/src/components/PlaylistPage/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './PlaylistPage'; diff --git a/plugins/playlist/src/components/PlaylistSearchBar/PlaylistSearchBar.test.tsx b/plugins/playlist/src/components/PlaylistSearchBar/PlaylistSearchBar.test.tsx new file mode 100644 index 0000000000..84650e4f41 --- /dev/null +++ b/plugins/playlist/src/components/PlaylistSearchBar/PlaylistSearchBar.test.tsx @@ -0,0 +1,52 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import { fireEvent, render, waitFor } from '@testing-library/react'; +import { DefaultPlaylistFilters } from '../../hooks'; +import { MockPlaylistListProvider } from '../../testUtils'; +import { PlaylistSearchBar, PlaylistTextFilter } from './PlaylistSearchBar'; + +describe('PlaylistSearchBar', () => { + it('should display search value and execute set callback', async () => { + const updateFilters = jest.fn(); + + const filters: DefaultPlaylistFilters = { + text: new PlaylistTextFilter('hello'), + }; + + const { getByDisplayValue } = render( + + + , + ); + + const searchInput = getByDisplayValue('hello'); + expect(searchInput).toBeInTheDocument(); + + fireEvent.change(searchInput, { target: { value: 'world' } }); + await waitFor(() => expect(updateFilters.mock.calls.length).toBe(1)); + expect(updateFilters).toHaveBeenCalledWith({ + text: new PlaylistTextFilter('world'), + }); + + fireEvent.change(searchInput, { target: { value: '' } }); + await waitFor(() => expect(updateFilters.mock.calls.length).toBe(2)); + expect(updateFilters).toHaveBeenCalledWith({ + text: undefined, + }); + }); +}); diff --git a/plugins/playlist/src/components/PlaylistSearchBar/PlaylistSearchBar.tsx b/plugins/playlist/src/components/PlaylistSearchBar/PlaylistSearchBar.tsx new file mode 100644 index 0000000000..94a22a23f5 --- /dev/null +++ b/plugins/playlist/src/components/PlaylistSearchBar/PlaylistSearchBar.tsx @@ -0,0 +1,102 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Playlist } from '@backstage/plugin-playlist-common'; +import { + FormControl, + IconButton, + Input, + InputAdornment, + makeStyles, + Toolbar, +} from '@material-ui/core'; +import Clear from '@material-ui/icons/Clear'; +import Search from '@material-ui/icons/Search'; +import React, { useState } from 'react'; +import useDebounce from 'react-use/lib/useDebounce'; + +import { usePlaylistList } from '../../hooks'; +import { PlaylistFilter } from '../../types'; + +export class PlaylistTextFilter implements PlaylistFilter { + constructor(readonly value: string) {} + + filterPlaylist(playlist: Playlist): boolean { + const upperCaseValue = this.value.toLocaleUpperCase('en-US'); + return ( + playlist.name.toLocaleUpperCase('en-US').includes(upperCaseValue) || + !!playlist.description + ?.toLocaleUpperCase('en-US') + .includes(upperCaseValue) + ); + } +} + +const useStyles = makeStyles(_theme => ({ + searchToolbar: { + paddingLeft: 0, + paddingRight: 0, + }, +})); + +export const PlaylistSearchBar = () => { + const classes = useStyles(); + + const { filters, updateFilters } = usePlaylistList(); + const [search, setSearch] = useState(filters.text?.value ?? ''); + + useDebounce( + () => { + updateFilters({ + text: search.length ? new PlaylistTextFilter(search) : undefined, + }); + }, + 250, + [search, updateFilters], + ); + + return ( + + + setSearch(event.target.value)} + value={search} + startAdornment={ + + + + } + endAdornment={ + + setSearch('')} + edge="end" + disabled={search.length === 0} + > + + + + } + /> + + + ); +}; diff --git a/plugins/playlist/src/components/PlaylistSearchBar/index.ts b/plugins/playlist/src/components/PlaylistSearchBar/index.ts new file mode 100644 index 0000000000..65b7e181cf --- /dev/null +++ b/plugins/playlist/src/components/PlaylistSearchBar/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './PlaylistSearchBar'; diff --git a/plugins/playlist/src/components/PlaylistSortPicker/PlaylistSortPicker.test.tsx b/plugins/playlist/src/components/PlaylistSortPicker/PlaylistSortPicker.test.tsx new file mode 100644 index 0000000000..9317bfd4c1 --- /dev/null +++ b/plugins/playlist/src/components/PlaylistSortPicker/PlaylistSortPicker.test.tsx @@ -0,0 +1,68 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { fireEvent, getByRole, render, waitFor } from '@testing-library/react'; +import { act } from '@testing-library/react-hooks'; +import React from 'react'; + +import { MockPlaylistListProvider } from '../../testUtils'; +import { + DefaultPlaylistSortTypes, + DefaultSortCompareFunctions, + PlaylistSortPicker, +} from './PlaylistSortPicker'; + +describe('PlaylistSortPicker', () => { + it('should update sort based on selection', async () => { + const updateSort = jest.fn(); + + const { getByText, getByTestId } = render( + + + , + ); + + act(() => { + fireEvent.mouseDown( + getByRole(getByTestId('sort-picker-select'), 'button'), + ); + }); + const abcSort = getByText('Alphabetical'); + expect(abcSort).toBeInTheDocument(); + + fireEvent.click(abcSort); + await waitFor(() => { + expect(updateSort).toHaveBeenLastCalledWith( + DefaultSortCompareFunctions[DefaultPlaylistSortTypes.alphabetical], + ); + }); + + act(() => { + fireEvent.mouseDown( + getByRole(getByTestId('sort-picker-select'), 'button'), + ); + }); + const entitiesSort = getByText('# Entities'); + expect(entitiesSort).toBeInTheDocument(); + + fireEvent.click(entitiesSort); + await waitFor(() => { + expect(updateSort).toHaveBeenLastCalledWith( + DefaultSortCompareFunctions[DefaultPlaylistSortTypes.numEntities], + ); + }); + }); +}); diff --git a/plugins/playlist/src/components/PlaylistSortPicker/PlaylistSortPicker.tsx b/plugins/playlist/src/components/PlaylistSortPicker/PlaylistSortPicker.tsx new file mode 100644 index 0000000000..21c961eb91 --- /dev/null +++ b/plugins/playlist/src/components/PlaylistSortPicker/PlaylistSortPicker.tsx @@ -0,0 +1,115 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Playlist } from '@backstage/plugin-playlist-common'; +import { + ListSubheader, + makeStyles, + MenuItem, + Select, + Typography, +} from '@material-ui/core'; +import SwapVertIcon from '@material-ui/icons/SwapVert'; +import React from 'react'; +import useEffectOnce from 'react-use/lib/useEffectOnce'; + +import { usePlaylistList } from '../../hooks'; +import { PlaylistSortCompareFunction } from '../../types'; + +export const enum DefaultPlaylistSortTypes { + popular = 'popular', + alphabetical = 'alphabetical', + numEntities = 'numEntities', +} + +export const DefaultSortCompareFunctions: { + [type in DefaultPlaylistSortTypes]: PlaylistSortCompareFunction; +} = { + [DefaultPlaylistSortTypes.popular]: (a: Playlist, b: Playlist) => { + if (a.followers < b.followers) { + return 1; + } else if (a.followers > b.followers) { + return -1; + } + return 0; + }, + [DefaultPlaylistSortTypes.alphabetical]: (a: Playlist, b: Playlist) => + a.name.localeCompare(b.name), + [DefaultPlaylistSortTypes.numEntities]: (a: Playlist, b: Playlist) => { + if (a.entities < b.entities) { + return 1; + } else if (a.entities > b.entities) { + return -1; + } + return 0; + }, +}; + +const sortTypeLabels = { + [DefaultPlaylistSortTypes.popular]: 'Popular', + [DefaultPlaylistSortTypes.alphabetical]: 'Alphabetical', + [DefaultPlaylistSortTypes.numEntities]: '# Entities', +}; + +const useStyles = makeStyles({ + select: { + width: '10rem', + marginRight: '1rem', + }, + icon: { + verticalAlign: 'bottom', + }, +}); + +export const PlaylistSortPicker = () => { + const classes = useStyles(); + const { updateSort } = usePlaylistList(); + + useEffectOnce(() => + updateSort(DefaultSortCompareFunctions[DefaultPlaylistSortTypes.popular]), + ); + + return ( + + ); +}; diff --git a/plugins/playlist/src/components/PlaylistSortPicker/index.ts b/plugins/playlist/src/components/PlaylistSortPicker/index.ts new file mode 100644 index 0000000000..04ea5268ef --- /dev/null +++ b/plugins/playlist/src/components/PlaylistSortPicker/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './PlaylistSortPicker'; diff --git a/plugins/playlist/src/components/Router/Router.test.tsx b/plugins/playlist/src/components/Router/Router.test.tsx new file mode 100644 index 0000000000..ea8620ec42 --- /dev/null +++ b/plugins/playlist/src/components/Router/Router.test.tsx @@ -0,0 +1,51 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import { PlaylistIndexPage } from '../PlaylistIndexPage'; +import { PlaylistPage } from '../PlaylistPage'; +import { Router } from './Router'; +import { renderInTestApp } from '@backstage/test-utils'; + +jest.mock('../PlaylistIndexPage', () => ({ + PlaylistIndexPage: jest.fn(() => null), +})); + +jest.mock('../PlaylistPage', () => ({ + PlaylistPage: jest.fn(() => null), +})); + +describe('Router', () => { + beforeEach(() => { + (PlaylistPage as jest.Mock).mockClear(); + (PlaylistIndexPage as jest.Mock).mockClear(); + }); + describe('/', () => { + it('should render the PlaylistIndexPage', async () => { + await renderInTestApp(); + expect(PlaylistIndexPage).toHaveBeenCalled(); + }); + }); + + describe('/:playlistId', () => { + it('should render the PlaylistPage page', async () => { + await renderInTestApp(, { + routeEntries: ['/my-playlist'], + }); + expect(PlaylistPage).toHaveBeenCalled(); + }); + }); +}); diff --git a/plugins/playlist/src/components/Router/Router.tsx b/plugins/playlist/src/components/Router/Router.tsx new file mode 100644 index 0000000000..5791a0817c --- /dev/null +++ b/plugins/playlist/src/components/Router/Router.tsx @@ -0,0 +1,29 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import { Routes, Route } from 'react-router'; + +import { playlistRouteRef } from '../../routes'; +import { PlaylistIndexPage } from '../PlaylistIndexPage'; +import { PlaylistPage } from '../PlaylistPage'; + +export const Router = () => ( + + } /> + } /> + +); diff --git a/plugins/playlist/src/components/Router/index.ts b/plugins/playlist/src/components/Router/index.ts new file mode 100644 index 0000000000..6606629fee --- /dev/null +++ b/plugins/playlist/src/components/Router/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './Router'; diff --git a/plugins/playlist/src/components/index.ts b/plugins/playlist/src/components/index.ts new file mode 100644 index 0000000000..2be300ac51 --- /dev/null +++ b/plugins/playlist/src/components/index.ts @@ -0,0 +1,27 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './CreatePlaylistButton'; +export * from './EntityPlaylistDialog'; +export * from './PersonalListPicker'; +export * from './PlaylistCard'; +export * from './PlaylistEditDialog'; +export * from './PlaylistIndexPage'; +export * from './PlaylistList'; +export * from './PlaylistOwnerPicker'; +export * from './PlaylistPage'; +export * from './PlaylistSearchBar'; +export * from './PlaylistSortPicker'; diff --git a/plugins/playlist/src/hooks/index.ts b/plugins/playlist/src/hooks/index.ts new file mode 100644 index 0000000000..316121b515 --- /dev/null +++ b/plugins/playlist/src/hooks/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './usePlaylistList'; diff --git a/plugins/playlist/src/hooks/usePlaylistList.test.tsx b/plugins/playlist/src/hooks/usePlaylistList.test.tsx new file mode 100644 index 0000000000..d04996513e --- /dev/null +++ b/plugins/playlist/src/hooks/usePlaylistList.test.tsx @@ -0,0 +1,225 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + ConfigApi, + configApiRef, + IdentityApi, + identityApiRef, +} from '@backstage/core-plugin-api'; +import { Playlist } from '@backstage/plugin-playlist-common'; +import { TestApiProvider } from '@backstage/test-utils'; +import { act, renderHook } from '@testing-library/react-hooks'; +import qs from 'qs'; +import React, { PropsWithChildren } from 'react'; +import { MemoryRouter } from 'react-router'; +import { PlaylistApi, playlistApiRef } from '../api'; +import { + DefaultSortCompareFunctions, + DefaultPlaylistSortTypes, + PersonalListFilter, + PersonalListFilterValue, + PersonalListPicker, + PlaylistOwnerPicker, +} from '../components'; +import { PlaylistListProvider, usePlaylistList } from './usePlaylistList'; + +const playlists: Playlist[] = [ + { + id: 'id1', + name: 'list-1', + owner: 'user:default/guest', + public: true, + entities: 2, + followers: 5, + isFollowing: false, + }, + { + id: 'id2', + name: 'list-2', + owner: 'group:default/foo', + public: true, + entities: 3, + followers: 2, + isFollowing: true, + }, +]; + +const mockConfigApi = { + getOptionalString: () => '', +} as Partial; + +const mockIdentityApi: Partial = { + getBackstageIdentity: async () => ({ + type: 'user', + userEntityRef: 'user:default/guest', + ownershipEntityRefs: [], + }), +}; + +const mockPlaylistApi: Partial = { + getAllPlaylists: jest.fn().mockImplementation(async () => playlists), +}; + +const wrapper = ({ + location, + children, +}: PropsWithChildren<{ + location?: string; +}>) => { + return ( + + + + + + {children} + + + + ); +}; + +describe('', () => { + const origReplaceState = window.history.replaceState; + beforeEach(() => { + window.history.replaceState = jest.fn(); + }); + afterEach(() => { + window.history.replaceState = origReplaceState; + }); + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('resolves backend filters', async () => { + const { result, waitForValueToChange } = renderHook( + () => usePlaylistList(), + { + wrapper, + }, + ); + await waitForValueToChange(() => result.current.backendPlaylists); + expect(result.current.backendPlaylists.length).toBe(2); + expect(mockPlaylistApi.getAllPlaylists).toHaveBeenCalled(); + }); + + it('resolves frontend filters', async () => { + const { result, waitFor } = renderHook(() => usePlaylistList(), { + wrapper, + }); + await waitFor(() => !!result.current.playlists.length); + expect(result.current.backendPlaylists.length).toBe(2); + + act(() => + result.current.updateFilters({ + personal: new PersonalListFilter( + PersonalListFilterValue.owned, + playlist => playlist.name === 'list-1', + ), + }), + ); + + await waitFor(() => { + expect(result.current.backendPlaylists.length).toBe(2); + expect(result.current.playlists.length).toBe(1); + expect(mockPlaylistApi.getAllPlaylists).toHaveBeenCalledTimes(1); + }); + }); + + it('resolves query param filter values', async () => { + const query = qs.stringify({ + filters: { personal: 'all', owners: ['user:default/guest'] }, + }); + const { result, waitFor } = renderHook(() => usePlaylistList(), { + wrapper, + initialProps: { + location: `/playlist?${query}`, + }, + }); + await waitFor(() => !!result.current.queryParameters); + expect(result.current.queryParameters).toEqual({ + personal: 'all', + owners: ['user:default/guest'], + }); + }); + + it('does not fetch when only frontend filters change', async () => { + const { result, waitFor } = renderHook(() => usePlaylistList(), { + wrapper, + }); + + await waitFor(() => { + expect(result.current.playlists.length).toBe(2); + expect(mockPlaylistApi.getAllPlaylists).toHaveBeenCalledTimes(1); + }); + + act(() => + result.current.updateFilters({ + personal: new PersonalListFilter( + PersonalListFilterValue.owned, + playlist => playlist.name === 'list-1', + ), + }), + ); + + await waitFor(() => { + expect(result.current.playlists.length).toBe(1); + expect(mockPlaylistApi.getAllPlaylists).toHaveBeenCalledTimes(1); + }); + }); + + it('applies custom sorting', async () => { + const { result, waitFor } = renderHook(() => usePlaylistList(), { + wrapper, + }); + + await waitFor(() => { + expect(result.current.playlists.length).toBe(2); + expect(result.current.playlists[0].name).toEqual('list-1'); + expect(result.current.playlists[1].name).toEqual('list-2'); + }); + + act(() => + result.current.updateSort( + DefaultSortCompareFunctions[DefaultPlaylistSortTypes.numEntities], + ), + ); + + await waitFor(() => { + expect(result.current.playlists.length).toBe(2); + expect(result.current.playlists[0].name).toEqual('list-2'); + expect(result.current.playlists[1].name).toEqual('list-1'); + }); + }); + + it('returns an error on playlistApi failure', async () => { + mockPlaylistApi.getAllPlaylists = jest.fn().mockRejectedValue('error'); + const { result, waitFor } = renderHook(() => usePlaylistList(), { + wrapper, + }); + await waitFor(() => { + expect(result.current.error).toBeDefined(); + }); + }); +}); diff --git a/plugins/playlist/src/hooks/usePlaylistList.tsx b/plugins/playlist/src/hooks/usePlaylistList.tsx new file mode 100644 index 0000000000..93c0becbfd --- /dev/null +++ b/plugins/playlist/src/hooks/usePlaylistList.tsx @@ -0,0 +1,284 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { useApi } from '@backstage/core-plugin-api'; +import { Playlist } from '@backstage/plugin-playlist-common'; +import { compact, isEqual } from 'lodash'; +import qs from 'qs'; +import React, { + createContext, + PropsWithChildren, + useCallback, + useContext, + useMemo, + useState, +} from 'react'; +import { useLocation } from 'react-router'; +import useAsyncFn from 'react-use/lib/useAsyncFn'; +import useDebounce from 'react-use/lib/useDebounce'; +import useMountedState from 'react-use/lib/useMountedState'; + +import { playlistApiRef } from '../api'; +import { PersonalListFilter } from '../components/PersonalListPicker'; +import { PlaylistOwnerFilter } from '../components/PlaylistOwnerPicker'; +import { PlaylistTextFilter } from '../components/PlaylistSearchBar'; +import { + DefaultPlaylistSortTypes, + DefaultSortCompareFunctions, +} from '../components/PlaylistSortPicker'; +import { PlaylistFilter, PlaylistSortCompareFunction } from '../types'; + +class NoopFilter implements PlaylistFilter { + getBackendFilters() { + return { '': null }; + } +} + +export type DefaultPlaylistFilters = { + noop?: NoopFilter; + owners?: PlaylistOwnerFilter; + personal?: PersonalListFilter; + text?: PlaylistTextFilter; +}; + +export type PlaylistListContextProps< + PlaylistFilters extends DefaultPlaylistFilters = DefaultPlaylistFilters, +> = { + /** + * The currently registered filters, adhering to the shape of DefaultPlaylistFilters + */ + filters: PlaylistFilters; + + /** + * The resolved list of playlists, after all filters are applied. + */ + playlists: Playlist[]; + + /** + * The resolved list of playlists, after _only playlist-backend_ filters are applied. + */ + backendPlaylists: Playlist[]; + + /** + * Update one or more of the registered filters. Optional filters can be set to `undefined` to + * reset the filter. + */ + updateFilters: ( + filters: + | Partial + | ((prevFilters: PlaylistFilters) => Partial), + ) => void; + + /** + * Update the compare function used to sort playlists. + */ + updateSort: (compareFn: PlaylistSortCompareFunction) => void; + + /** + * Filter values from query parameters. + */ + queryParameters: Partial>; + + loading: boolean; + error?: Error; +}; + +export const PlaylistListContext = createContext< + PlaylistListContextProps | undefined +>(undefined); + +const reduceBackendFilters = ( + filters: PlaylistFilter[], +): Record => { + return filters.reduce((compoundFilter, filter) => { + return { + ...compoundFilter, + ...(filter.getBackendFilters ? filter.getBackendFilters() : {}), + }; + }, {} as Record); +}; + +type OutputState = { + appliedFilters: PlaylistFilters; + playlists: Playlist[]; + backendPlaylists: Playlist[]; +}; + +export const PlaylistListProvider = < + PlaylistFilters extends DefaultPlaylistFilters, +>({ + children, +}: PropsWithChildren<{}>) => { + const isMounted = useMountedState(); + const playlistApi = useApi(playlistApiRef); + const [sortCompareFn, setSortCompareFn] = + useState( + () => DefaultSortCompareFunctions[DefaultPlaylistSortTypes.popular], + ); + const [requestedFilters, setRequestedFilters] = useState( + {} as PlaylistFilters, + ); + + // We use react-router's useLocation hook so updates from external sources trigger an update to + // the queryParameters in outputState. Updates from this hook use replaceState below and won't + // trigger a useLocation change; this would instead come from an external source, such as a manual + // update of the URL or two sidebar links with different filters. + const location = useLocation(); + const queryParameters = useMemo( + () => + (qs.parse(location.search, { + ignoreQueryPrefix: true, + }).filters ?? {}) as Record, + [location], + ); + + const [outputState, setOutputState] = useState>({ + appliedFilters: { + noop: new NoopFilter(), // Init with a noop filter to trigger intial request + } as PlaylistFilters, + playlists: [], + backendPlaylists: [], + }); + + // The main async filter worker. Note that while it has a lot of dependencies + // in terms of its implementation, the triggering only happens (debounced) + // based on the requested filters/sortCompareFn changing. + const [{ loading, error }, refresh] = useAsyncFn( + async () => { + const compacted: PlaylistFilter[] = compact( + Object.values(requestedFilters), + ); + const playlistFilter = (p: Playlist) => + compacted.every( + filter => !filter.filterPlaylist || filter.filterPlaylist(p), + ); + const backendFilter = reduceBackendFilters(compacted); + const previousBackendFilter = reduceBackendFilters( + compact(Object.values(outputState.appliedFilters)), + ); + + const queryParams = Object.keys(requestedFilters).reduce( + (params, key) => { + const filter: PlaylistFilter | undefined = + requestedFilters[key as keyof PlaylistFilters]; + if (filter?.toQueryValue) { + params[key] = filter.toQueryValue(); + } + return params; + }, + {} as Record, + ); + + if (!isEqual(previousBackendFilter, backendFilter)) { + const response = await playlistApi.getAllPlaylists({ + filter: backendFilter, + }); + setOutputState({ + appliedFilters: requestedFilters, + backendPlaylists: response, + playlists: response.filter(playlistFilter).sort(sortCompareFn), + }); + } else { + setOutputState({ + appliedFilters: requestedFilters, + backendPlaylists: outputState.backendPlaylists, + playlists: outputState.backendPlaylists + .filter(playlistFilter) + .sort(sortCompareFn), + }); + } + + if (isMounted()) { + const oldParams = qs.parse(location.search, { + ignoreQueryPrefix: true, + }); + const newParams = qs.stringify( + { ...oldParams, filters: queryParams }, + { addQueryPrefix: true, arrayFormat: 'repeat' }, + ); + const newUrl = `${window.location.pathname}${newParams}`; + // We use direct history manipulation since useSearchParams and + // useNavigate in react-router-dom cause unnecessary extra rerenders. + // Also make sure to replace the state rather than pushing, since we + // don't want there to be back/forward slots for every single filter + // change. + window.history?.replaceState(null, document.title, newUrl); + } + }, + [ + playlistApi, + queryParameters, + requestedFilters, + sortCompareFn, + outputState, + ], + { loading: true }, + ); + + // Slight debounce on the refresh, since (especially on page load) several + // filters will be calling this in rapid succession. + useDebounce(refresh, 10, [requestedFilters, sortCompareFn]); + + const updateFilters = useCallback( + ( + update: + | Partial + | ((prevFilters: PlaylistFilters) => Partial), + ) => { + setRequestedFilters(prevFilters => { + const newFilters = + typeof update === 'function' ? update(prevFilters) : update; + return { ...prevFilters, ...newFilters }; + }); + }, + [], + ); + + const updateSort = useCallback( + (compareFn: PlaylistSortCompareFunction) => + setSortCompareFn(() => compareFn), + [], + ); + + const value = useMemo( + () => ({ + filters: outputState.appliedFilters, + playlists: outputState.playlists, + backendPlaylists: outputState.backendPlaylists, + updateFilters, + updateSort, + queryParameters, + loading, + error, + }), + [outputState, updateFilters, updateSort, queryParameters, loading, error], + ); + + return ( + + {children} + + ); +}; + +export function usePlaylistList< + PlaylistFilters extends DefaultPlaylistFilters = DefaultPlaylistFilters, +>(): PlaylistListContextProps { + const context = useContext(PlaylistListContext); + if (!context) + throw new Error('usePlaylistList must be used within PlaylistListProvider'); + return context; +} diff --git a/plugins/playlist/src/index.ts b/plugins/playlist/src/index.ts new file mode 100644 index 0000000000..3b7004ce22 --- /dev/null +++ b/plugins/playlist/src/index.ts @@ -0,0 +1,28 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Playlist frontend plugin + * + * @packageDocumentation + */ +export type { EntityPlaylistDialogProps } from './components'; +export { + EntityPlaylistDialog, + playlistPlugin, + PlaylistIndexPage, +} from './plugin'; +export * from './api'; diff --git a/plugins/playlist/src/plugin.test.ts b/plugins/playlist/src/plugin.test.ts new file mode 100644 index 0000000000..a2dfc7fcd7 --- /dev/null +++ b/plugins/playlist/src/plugin.test.ts @@ -0,0 +1,22 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { playlistPlugin } from './plugin'; + +describe('playlist', () => { + it('should export plugin', () => { + expect(playlistPlugin).toBeDefined(); + }); +}); diff --git a/plugins/playlist/src/plugin.ts b/plugins/playlist/src/plugin.ts new file mode 100644 index 0000000000..8e73fffe37 --- /dev/null +++ b/plugins/playlist/src/plugin.ts @@ -0,0 +1,74 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + createApiFactory, + createComponentExtension, + createPlugin, + createRoutableExtension, + discoveryApiRef, + fetchApiRef, +} from '@backstage/core-plugin-api'; + +import { playlistApiRef, PlaylistClient } from './api'; +import { rootRouteRef } from './routes'; + +/** + * @public + */ +export const playlistPlugin = createPlugin({ + id: 'playlist', + routes: { + root: rootRouteRef, + }, + apis: [ + createApiFactory({ + api: playlistApiRef, + deps: { + discoveryApi: discoveryApiRef, + fetchApi: fetchApiRef, + }, + factory: ({ discoveryApi, fetchApi }) => + new PlaylistClient({ discoveryApi, fetchApi }), + }), + ], +}); + +/** + * @public + */ +export const PlaylistIndexPage = playlistPlugin.provide( + createRoutableExtension({ + name: 'PlaylistIndexPage', + component: () => import('./components/Router').then(m => m.Router), + mountPoint: rootRouteRef, + }), +); + +/** + * @public + */ +export const EntityPlaylistDialog = playlistPlugin.provide( + createComponentExtension({ + name: 'EntityPlaylistDialog', + component: { + lazy: () => + import('./components/EntityPlaylistDialog').then( + m => m.EntityPlaylistDialog, + ), + }, + }), +); diff --git a/plugins/playlist/src/routes.ts b/plugins/playlist/src/routes.ts new file mode 100644 index 0000000000..632dc06439 --- /dev/null +++ b/plugins/playlist/src/routes.ts @@ -0,0 +1,26 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { createRouteRef, createSubRouteRef } from '@backstage/core-plugin-api'; + +export const rootRouteRef = createRouteRef({ + id: 'playlist:index-page', +}); + +export const playlistRouteRef = createSubRouteRef({ + id: 'playlist:playlist-page', + parent: rootRouteRef, + path: '/:playlistId', +}); diff --git a/plugins/playlist/src/setupTests.ts b/plugins/playlist/src/setupTests.ts new file mode 100644 index 0000000000..9bb3e72355 --- /dev/null +++ b/plugins/playlist/src/setupTests.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import '@testing-library/jest-dom'; +import 'cross-fetch/polyfill'; diff --git a/plugins/playlist/src/testUtils/MockPlaylistListProvider.tsx b/plugins/playlist/src/testUtils/MockPlaylistListProvider.tsx new file mode 100644 index 0000000000..2acef15e14 --- /dev/null +++ b/plugins/playlist/src/testUtils/MockPlaylistListProvider.tsx @@ -0,0 +1,102 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React, { + PropsWithChildren, + useCallback, + useMemo, + useState, +} from 'react'; +import { + DefaultPlaylistSortTypes, + DefaultSortCompareFunctions, +} from '../components'; +import { + DefaultPlaylistFilters, + PlaylistListContext, + PlaylistListContextProps, +} from '../hooks'; +import { PlaylistSortCompareFunction } from '../types'; + +export const MockPlaylistListProvider = ({ + children, + value, +}: PropsWithChildren<{ + value?: Partial; +}>) => { + const [filters, setFilters] = useState( + value?.filters ?? {}, + ); + + const [_, setSortCompareFn] = useState( + () => DefaultSortCompareFunctions[DefaultPlaylistSortTypes.popular], + ); + + const updateFilters = useCallback( + ( + update: + | Partial + | (( + prevFilters: DefaultPlaylistFilters, + ) => Partial), + ) => { + setFilters(prevFilters => { + const newFilters = + typeof update === 'function' ? update(prevFilters) : update; + return { ...prevFilters, ...newFilters }; + }); + }, + [], + ); + + const updateSort = useCallback( + (compareFn: PlaylistSortCompareFunction) => + setSortCompareFn(() => compareFn), + [], + ); + + // Memoize the default values since pickers have useEffect triggers on these; naively defaulting + // below with `?? ` breaks referential equality on subsequent updates. + const defaultValues = useMemo( + () => ({ + playlists: [], + backendPlaylists: [], + queryParameters: {}, + }), + [], + ); + + const resolvedValue: PlaylistListContextProps = useMemo( + () => ({ + playlists: value?.playlists ?? defaultValues.playlists, + backendPlaylists: + value?.backendPlaylists ?? defaultValues.backendPlaylists, + updateFilters: value?.updateFilters ?? updateFilters, + filters, + updateSort: value?.updateSort ?? updateSort, + loading: value?.loading ?? false, + queryParameters: value?.queryParameters ?? defaultValues.queryParameters, + error: value?.error, + }), + [value, defaultValues, filters, updateFilters, updateSort], + ); + + return ( + + {children} + + ); +}; diff --git a/plugins/playlist/src/testUtils/index.ts b/plugins/playlist/src/testUtils/index.ts new file mode 100644 index 0000000000..9b6f333a59 --- /dev/null +++ b/plugins/playlist/src/testUtils/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './MockPlaylistListProvider'; diff --git a/plugins/playlist/src/types.ts b/plugins/playlist/src/types.ts new file mode 100644 index 0000000000..fbd348f98a --- /dev/null +++ b/plugins/playlist/src/types.ts @@ -0,0 +1,27 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Playlist } from '@backstage/plugin-playlist-common'; + +export type PlaylistFilter = { + getBackendFilters?: () => Record; + + filterPlaylist?: (playlist: Playlist) => boolean; + + toQueryValue?: () => string | string[]; +}; + +export type PlaylistSortCompareFunction = (a: Playlist, b: Playlist) => number; diff --git a/plugins/search-react/src/components/SearchFilter/SearchFilter.Autocomplete.tsx b/plugins/search-react/src/components/SearchFilter/SearchFilter.Autocomplete.tsx index 35d1f376e5..c14dfdfa7e 100644 --- a/plugins/search-react/src/components/SearchFilter/SearchFilter.Autocomplete.tsx +++ b/plugins/search-react/src/components/SearchFilter/SearchFilter.Autocomplete.tsx @@ -62,7 +62,7 @@ export const AutocompleteFilter = (props: SearchAutocompleteFilterProps) => { defaultValues, valuesDebounceMs, ); - const { filters, setFilters } = useSearch(); + const { filters, setFilters, setPageCursor } = useSearch(); const filterValue = (filters[name] as string | string[] | undefined) || (multiple ? [] : null); @@ -79,6 +79,7 @@ export const AutocompleteFilter = (props: SearchAutocompleteFilterProps) => { } return { ...others }; }); + setPageCursor(undefined); }; // Provide the input field. diff --git a/plugins/search-react/src/components/SearchFilter/SearchFilter.test.tsx b/plugins/search-react/src/components/SearchFilter/SearchFilter.test.tsx index 89a1818e8d..27fbae237c 100644 --- a/plugins/search-react/src/components/SearchFilter/SearchFilter.test.tsx +++ b/plugins/search-react/src/components/SearchFilter/SearchFilter.test.tsx @@ -33,6 +33,7 @@ describe('SearchFilter', () => { term: '', filters: {}, types: [], + pageCursor: 'abc123', }; const label = 'Field'; @@ -138,7 +139,10 @@ describe('SearchFilter', () => { await userEvent.click(checkBox); await waitFor(() => { expect(query).toHaveBeenLastCalledWith( - expect.objectContaining({ filters: { field: [values[0]] } }), + expect.objectContaining({ + filters: { field: [values[0]] }, + pageCursor: undefined, + }), ); }); @@ -146,7 +150,7 @@ describe('SearchFilter', () => { await userEvent.click(checkBox); await waitFor(() => { expect(query).toHaveBeenLastCalledWith( - expect.objectContaining({ filters: {} }), + expect.objectContaining({ filters: {}, pageCursor: undefined }), ); }); }); @@ -170,6 +174,7 @@ describe('SearchFilter', () => { expect(query).toHaveBeenLastCalledWith( expect.objectContaining({ filters: { ...filters, field: [values[0]] }, + pageCursor: undefined, }), ); }); @@ -178,7 +183,7 @@ describe('SearchFilter', () => { await userEvent.click(checkBox); await waitFor(() => { expect(query).toHaveBeenLastCalledWith( - expect.objectContaining({ filters }), + expect.objectContaining({ filters, pageCursor: undefined }), ); }); }); @@ -337,6 +342,7 @@ describe('SearchFilter', () => { expect(query).toHaveBeenLastCalledWith( expect.objectContaining({ filters: { [name]: values[0] }, + pageCursor: undefined, }), ); }); @@ -353,6 +359,7 @@ describe('SearchFilter', () => { expect(query).toHaveBeenLastCalledWith( expect.objectContaining({ filters: {}, + pageCursor: undefined, }), ); }); @@ -388,6 +395,7 @@ describe('SearchFilter', () => { expect(query).toHaveBeenLastCalledWith( expect.objectContaining({ filters: { ...filters, [name]: values[0] }, + pageCursor: undefined, }), ); }); @@ -402,7 +410,7 @@ describe('SearchFilter', () => { await waitFor(() => { expect(query).toHaveBeenLastCalledWith( - expect.objectContaining({ filters }), + expect.objectContaining({ filters, pageCursor: undefined }), ); }); }); diff --git a/plugins/search-react/src/components/SearchFilter/SearchFilter.tsx b/plugins/search-react/src/components/SearchFilter/SearchFilter.tsx index 2a6d7baafa..958caf0927 100644 --- a/plugins/search-react/src/components/SearchFilter/SearchFilter.tsx +++ b/plugins/search-react/src/components/SearchFilter/SearchFilter.tsx @@ -82,7 +82,7 @@ export const CheckboxFilter = (props: SearchFilterComponentProps) => { valuesDebounceMs, } = props; const classes = useStyles(); - const { filters, setFilters } = useSearch(); + const { filters, setFilters, setPageCursor } = useSearch(); useDefaultFilterValue(name, defaultValue); const asyncValues = typeof givenValues === 'function' ? givenValues : undefined; @@ -106,6 +106,7 @@ export const CheckboxFilter = (props: SearchFilterComponentProps) => { const items = checked ? [...rest, value] : rest; return items.length ? { ...others, [name]: items } : others; }); + setPageCursor(undefined); }; return ( @@ -161,7 +162,7 @@ export const SelectFilter = (props: SearchFilterComponentProps) => { defaultValues, valuesDebounceMs, ); - const { filters, setFilters } = useSearch(); + const { filters, setFilters, setPageCursor } = useSearch(); const handleChange = (e: ChangeEvent<{ value: unknown }>) => { const { @@ -172,6 +173,7 @@ export const SelectFilter = (props: SearchFilterComponentProps) => { const { [name]: filter, ...others } = prevFilters; return value ? { ...others, [name]: value as string } : others; }); + setPageCursor(undefined); }; return ( From 2028a73c9661b1589e2e4f15faab6427200791f9 Mon Sep 17 00:00:00 2001 From: Phil Kuang Date: Tue, 6 Sep 2022 17:36:17 -0400 Subject: [PATCH 061/185] refactor(playlists): address review comments Signed-off-by: Phil Kuang --- .changeset/calm-snakes-tap.md | 2 +- .github/CODEOWNERS | 4 + microsite/static/img/playlist-logo.png | Bin 14734 -> 14844 bytes packages/backend/src/plugins/playlist.ts | 22 ++--- packages/core-components/api-report.md | 24 +++-- .../src/components/Table/Table.tsx | 2 +- .../HeaderActionMenu.test.tsx | 6 +- .../HeaderActionMenu/HeaderActionMenu.tsx | 16 ++-- .../src/layout/HeaderActionMenu/index.ts | 2 +- plugins/playlist-backend/README.md | 21 ++--- plugins/playlist-backend/api-report.md | 7 +- .../migrations/20220701011329_init.js | 8 +- plugins/playlist-backend/package.json | 18 ++-- .../src/service/ListPlaylistsFilter.ts | 13 ++- .../src/service/router.test.ts | 71 +++++++++++++-- .../playlist-backend/src/service/router.ts | 55 ++++++++++-- .../src/service/standaloneServer.ts | 5 +- plugins/playlist-common/package.json | 4 +- plugins/playlist/api-report.md | 12 +-- plugins/playlist/package.json | 23 +++-- plugins/playlist/src/api/PlaylistApi.ts | 3 +- .../playlist/src/api/PlaylistClient.test.ts | 24 ++++- plugins/playlist/src/api/PlaylistClient.ts | 3 +- .../EntityPlaylistDialog.tsx | 7 +- .../PlaylistEntitiesTable.test.tsx | 48 ++-------- .../PlaylistPage/PlaylistEntitiesTable.tsx | 48 ++-------- yarn.lock | 83 +++++++++++++++++- 27 files changed, 330 insertions(+), 201 deletions(-) diff --git a/.changeset/calm-snakes-tap.md b/.changeset/calm-snakes-tap.md index 6b853da53d..6fdf092ede 100644 --- a/.changeset/calm-snakes-tap.md +++ b/.changeset/calm-snakes-tap.md @@ -2,4 +2,4 @@ '@backstage/core-components': patch --- -Export `HeaderActionMenu` and expose default `Table` icons via `Table.tableIcons` +Export `HeaderActionMenu` and expose default `Table` icons via `Table.icons` diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index f00771d29d..b0f1e828cd 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -16,6 +16,8 @@ yarn.lock @backstage/reviewers @backst /docs/plugins/integrating-search-into-plugins.md @backstage/reviewers @backstage/techdocs-core /packages/techdocs-cli @backstage/reviewers @backstage/techdocs-core /packages/techdocs-cli-embedded-app @backstage/reviewers @backstage/techdocs-core +/plugins/adr @backstage/reviewers @kuangp +/plugins/adr-* @backstage/reviewers @kuangp /plugins/allure @backstage/reviewers @deepak-bhardwaj-ps /plugins/apache-airflow @backstage/reviewers @cmpadden /plugins/api-docs @backstage/reviewers @backstage/sda-se-reviewers @@ -47,6 +49,8 @@ yarn.lock @backstage/reviewers @backst /plugins/kubernetes @backstage/reviewers @backstage/warpspeed /plugins/kubernetes-* @backstage/reviewers @backstage/warpspeed /plugins/newrelic-dashboard @backstage/reviewers @mufaddal7 +/plugins/playlist @backstage/reviewers @kuangp +/plugins/playlist-* @backstage/reviewers @kuangp /plugins/scaffolder-backend-module-rails @backstage/reviewers @angeliski /plugins/scaffolder-backend-module-yeoman @backstage/reviewers @pawelmitka /plugins/search @backstage/reviewers @backstage/techdocs-core diff --git a/microsite/static/img/playlist-logo.png b/microsite/static/img/playlist-logo.png index b5c8d9940175d6221c1bf1cdf9ab473e5793a5fb..333a9f832a48f430f415c94cc9e1346d5a04ce20 100644 GIT binary patch literal 14844 zcmeHudpuNY`?nb*L&dDxItj~6B}o)fIn0uYP_%iTgdEyQwR1j%oMyJlv~!pqHrYaL zp_4;|ipEs-CPar_D5q^3D#sbyDPz3Xa(JHi^V{#=@B4W_k3ag%$Gz@#-S>T6-|KrF z?$xD3*5=D)*U3sqNG!M5&#;w{Aad}3-^i_eA^D9Aze}(Q_U6(qcp6acYXp8n?;+NgGLN&;1+-{y;X7Y=fuH?aQt1V>? z+S--BVmq$PIZxUoD_J9Ba`(!%oHZNWPo$`4dwySgDb;l(W?VaMWpCTixv_H@C!LMM zdg@IgGDh!>PHK)CO!XHB%h1Ub6k|#dh$Qkq$Voq*G_sug14dEOO{@7w6!g$W6utY< z@W8@T6m7%bnSGhHg+Orlm49sEZvx@7+<&CXkZZPVlV7>83VDCvGnylE{i5S0)xGu$*Mi9- z6N&!k)m#3whF`Vj)5!{)x3O0$u&rhdx8O^ zRq1ZI4u>&o9ZP9d?D~Bs({tJPkFJnN-TU9}IbJ{%E(_||fVq)i#b-(Verg25qm})- zb+R?5%|4?fvhFGhC(cAu|6fez`qPdl`~Qh$+!#zFkz-L<@#?>f24UskAJRP>2)kcy zRyr@i`VI22?YH=5kb2P$_QgJtt#Hh5}Xe2;m}BS~&A6FW{Iw5<8vp9ZS9k`wfs z%c2n$jj-qm|4%(ZPsf%1^4R+Gz?#dYEY*YckLIUk?-v+5TuV%%`fb1l7 z&AR4*`(d*Mqi;N~o3MMJ@mhL-Q_s{L<~5%jYX)8-N(0qNaw2|l0yiHx% z0iGh629oe;yIe3#*=O+bG%OYAaZC*_HnlmxPp6KQemDyJrB;ICb>uxDMftyzB6YWp1U>GPBHdKnJ6o;m!6}!Ya!EDA=Hm@aqrtQ*AGq(* zn9P1J>X<1$(G=#X{^p)I7oIe&@UZ~k^+&yZflW)v`}J{TkjS1u>58u^cEmB~xg18# zWyv+Pl8C$dVD68M{uq4XMVMzA`(o1^^*bixV?AKgfX1fJ`Ku`$Z-|s&vt}@l{`Jrk z>p-ou!3sv>0Tt%oPaXDwuvK=cSstIbOch0A)+8RBi)|%a@v(YM6z$C@c(x;-;rFq;c4#2@th}#+Ph7JX!{oMaN}CJbXB_act40C=XjH0FOT@buQ5@ZfS^+a?2WdH*10Cza>!dG+oXsXNv#C?^fj zlV;i0^XP9`8`1yHnJ?Nu5$(iULD?pW)l%*&%`StsZ-BP_Zw05=4zBg@)r(+5{#3OU zRWxzDD8c#+rsB{PIHvIf4-YP_F?&xeLT;V_>so`wciR$ncQ?m>e8BW{*IayIQA>-^ zSoDYgzgfeu;X}%7sG_p!D>SGs^w(FsjecZa3oOiw--tR{IL=1nWGKL_;yxZ5f~3M( zW-(Oa8e7cK7IU=!)*Q_}OVNKcYX7=CkF`Y7pw0CpfBEzvsU0KJv@ZR9RnpGW)7+U! zA$_J}e6nxmsJPFzmS5S?AH(!CJAH!y{jIDUCp`2VYj=>yt(80@$ma+zHGLH>Wv)Ro z14o4YC8sXISxuonUB<^Yzs;QIeh@U+p z+=CJB&oCUmd7P_G-4->S#h%E`PKpX>GbVLg*a=&BMJ5 zaO-ZR@twD(l{=~J;R;Cwn%Ncn_Ytx+*0~-|F;LQ&)z7U(u2CPtJX|8r3hpC(`}eFn?1lvhc#`L3m-WU`1R?W#o*mblA8_yq~v zlUb3Pm`iTG!Hl}pBS#oNXQUH#l3_UTrJ&<}Q}Dg8t5AZ*o~xIasWA&!$%#WXO?i!& zT#)pR5uwvSt75#0-tRqLV|$?Rj6A9VO-W}8p@sZr2VMpSqdF>Qt#*lfRQ0?PcS7A{ zcIN3xDKHacz_aQq=SrqdUT23i{L|1y{QGKp57bxz4J9qNN$xbuc`@!~Af|FFHA4}J zj5}Ut_kHPhLQAZF!v)a$BiRK(!3b#ZiSd7>gh=F6+LnGtl1O~^`ZG? z`7tAah}(h{-h$bThqfr&bX;D34a#YoER{c>gOqCvQgWf+8y>-v zSOh+n2PxVMQtZH%V!_=I(JMQ>&aAoG?M+K0oQ$=ADETLFGN*!P0%7ip36oA2(DSzc zq32_8uBc#!=q3B1s7;<&CQIHwZh|SN+}(mnNUXhse+%FzP3lH!xhCkKdUor}KN`TP zgg*8&>FkLK1J{?bE1}qtiTNPhAGxIHO3oZ=BA57&18g#t5ufI1Q)BHSC~rc~N%uQr zdV5#R;s83#=Ku!9w62}ykyTwffYY@(5C2>XDmc1;0dLqF_@7qGfaIzSXv8+?zEobEEoI;&Ucd9<#g7e^%ou3$J*Qv!v{b?^V=X6O)60mURu~6IfUhF^9^=oF)Ji1 zoLm*=x1fjX=L8~XJGi=}Sr)KQ@cr zjlKm?`>xJcfPVEhb|!1qN8sQul!mqHb&nklMF@|CfBE>HC4@@eOf#gSKEHIYB?fQp zJc;^XS5q?)guV_@36HKe+S?f+1G;|Jh$$~9n3u^2C^g%>0Iw-?h0?;9J z)mu&M=#*up0a)+sZuQlxbW za~md1+~lES7W0L126poNn|VC6kAY^FQoCBpB3?<7N}*LWaMr3q9aW5T!1R82unan2 zdEmNRsFAh%R15JI-rA7A_&`cB3yAbt%_(5Bs~>JAodwS~kWAoK0E?I`AbMKXy{Ff_ zDxrJ>NeoTHB@%ti#Hl=D0Sw8td6uh3Od#e+8Ui%%MZ>%B$f03yrdh{{qEWfO|BuJD_2ug{Pe8=aM>c1-784J7 zL>^&?zGH|=6&m_t+n}K}X!fS*BFWu#q)-uxgbFKEN2}7SkzY0>h~`0f6D}KNan(`j zb;)@v(874kgKJ1tE^oM${y+!9dJA^$WBhzWktZakPHsm8Ln$#5zB#Z(yC|m5(i*}= z_sh_e-N;F`iDjqU3;I5H-~fi5)#J36(&ihbg%y}bWEdlyFQiB`K$JT9MSj?eu$#y6 zyduFW0j&znSG$PGrgZW(_^_$*UnLV$ z4?@Fp3V)K%Py?(dn*8;6IiaP`z5lWVYa?Lf0wRdrC_nVd2+p68^ZE}Ll6#El{f$J@ zdxe_%vVB$61sa{*=|H*GOJ4Wsk=zRs?`siB$t!E>=VnC$(MkqrjN0XArS#!g7!c|c>zu?08Q9Y? zMd&ux)MqBJV>sw57VN~0Y~*8tjTtJ1(J(i4R=uba5s3ef@7>d!CC{Ado99 z&#KNN*C^+HXG0=yRfCwMfE3K05PI_cK|9j>t>7%=kI)&#PZ-V+)qIe(?zjREPpvWX z-iM9tQV64BZo3JU(%t^Fp=lnmXj~?}f=&n(N`z-X4|p|f#|{xF>5>DfC~B~lQScEz z%WqsV<%lJKdOKCzZyR&AIRlc+#>YEr|iU?@&(dv(%4#DGH-#CGajX?iqj0)c;i3WbTM3rwXCrhly zJ)D#Pr*aqFmd;{A&Adwf3i|32&qqC5)cE%eWGW&Bjzitnt+#p7Nw)1RpW8j}N`fQ* zTXV126RS6n1JU6#*+~hX+*C?m!CiHK$gWZ|CT|aDmW2ou`>r)x7_6H3Y+Fk+XwS?G zf{;3|!cHnD)hB^1{R;Ih;*F=+a=W{YCc=BcLL-D0WdgB}?B2s~!dxOXZ>o?QzM1%7 zTU&PR5uszy6^ucr8Nd}d0&uBA1pLeEo3>9WgoLZ}heped4EmtWKc+1ehWFIVXOJ;| z!j1~jm5Y&-U3NT`;~_a>v||+~dReWW4CSgTq@o5?7o8c4^g_r`F4*)+emNFKEQ(QY zmIPR}PwQ}06p~tw}Kf}G5LOux&4Pa`PoU; zK@YW@zRc1V<>S1sTQCg$z}M;Dc4}CucZ7D0N1UU;jYiFNPq=2^3D{kW2%hb_BMzJ)Gpn}PG9_4(B+;IlNsm3eOOf}J{3l1t zA}J5St1FPi7=W_xJ@ByYROQfq`v|XNtf9@>qR$r^hd%uTrd(0~Ctz*YUhv&5RB;#5 zAzV&`YEGT6!a;rQAhg-3HzLq%!N8JL?1^95A(fK!KD#rrqUW}?xp|?1x$Rp}w5&EX z0esb9DNb_FR5Z$pi}`<^0aZR@VQ|xQ@3j!W@sazcrd}(at+H!4(YPds7j31Uk~uII z&4Vv4y5nve?gs`v4uoz>?Q%7%GFP5D;p()%b121Dx%gG6QVE=AHUTA(`&BuqDfHD- z!rtRkklV0wQ*2!xR6l!vZTe}#{|7l zkkrXP5y7N3e3CKIV_U1Q>+;tBGI-#=B?DLCdkhT-b8L1>d>GMS=uoE;A{e%<)e3&7 z@3aowTuys~(+1qlx!b792YR@Sv=ct;N@w%%i@a;tw!+Az;-cc8DOvpzKdM zDRI-gMq_Tt^CvBDP{_aMf*ybivRCp7(%_-aa!YkrznC*25q^-bO-T8M6G^`zHTAh> zRpW8R#|;J!b*9_XrzQfF245yG0lt@9UUwL7H94vDFd2yzBt6-R!X#mR+|ao=UKk|G zb$Co-!2*}5UDDDYit@&2zLOCu^sFSI)wJgeYcq&LS=J3)8Oo8vz?ZwI84tEHqkR-Y z4y*ISO1b?;a}^TK!qE`EU>khbTa(PErQYSeG8IKhLg~h-3av&c>Q1KJ8iCup^AP{E zs2Sx|$CQNDQrl*_>iH_pGxh1)x+93=P;3R`q9h?Lj5#{JwL4n6m8+?uG29C{3F%jh z@Hz`FH+4QeL4tK!N>pn6HolbqR4f3UiOuTvRRJLVT zeAi)fBw`=vtn2smRCpVXOh5!**c0bZ%kj}Xl6bE=zt2(AL+O7z5J2@f^;zSN<;K;& zeT+J&&X>onPin_ItVFS8(#j( z>`bBG{w<+ID#O7t^p6iD>q=-!wK_F_#ocN@kk^+lO{T_wUAOsqAd0B9CEM^xrB};q zPmof2X%F0uTERy6O;4P~+3V=@)tO;1MDNn+ z$0xa@c4Z_%EBh!;1?7;ow_S?BFMF#&&p?mDNFT~4&7FHBHl$Yy&8dE z|Kd|F)4J5FqgqzWuX-rj-9!%>){pT158QfI0m~dQ{C?1GTg2l!pQe!y*;4Dp-vAHD zmM7q6-UW_Th6wzsBVMP-tq8FNMpynzGgEaK^z!BcPUu8pYU#yM z=o#amApjB#(J4L-Gg_}eT#aCazg5!g;_Hwy94#kVI>!BJq(P9;hIhudZsw#m{>UD3 z9R5U8o@}CZSxqn1p~ZW*8!fE~J=y0D>U;=juiQly#UAb$@6Lnt(Y99cYkN*x9w6C1 z?coT1&Q+|tbb~3aeO0DU1J#CqWQUwp=X8AX;p;mSfv5 zStC&a>U_mL9}@B?AzDx!?w!3dE(a_=LIj5Eb7e)A48z@Myd>e{Hm=(-q5*(F>5!%c5P}2j z2q;#lb3CQe*ey9A$Tz;O(jj8fp}MmDsf#BID}iM-kdq|RPo_uYoQOgVd+M~u5 z37J-g;@%z&C(c|=b}AFU5ne`24V}!3%uqt)GygD@&iuo?K41KSxGfp23P@(?=y+Xbc)(Z!RPkpD#4BP?+B_dGhjPj}{?{CsT9^Y< zJsIJ)jHBZF&^yu7=& zM4zDlwUsa3(bz%XOpTmQt`wUyMB`JU@yJJzJrv)XhPhA^wUT>xf=A7s_zn=(yB7xf ya3*|U@$sTs7U8hy28-;l$cq2hqrr^4=*S(lcUyh(;J#KfIyUz6jcV_&%nQ3*iYbVNbqA1`1S#)EFlb0 zHHm)={$pVZkTR2#gP;b}un^E6K0!eJg+M@pFKGXwKY;0P|Ct_Y2?6~N3s`{~&asDIPDe}UHo^)X<$gQY6K86YRiZESB#Z)jp~WJ>RD>+lxVpD~pQ%iyi!rkHo^+*@2sZ!OhK$-i?Lc-pQPSiHnPifsvVknVAlZpaXi?IUBmu z*#SxaDda!oh?)Y8oh%)kE$!`y{>n8pvUhRjBO&>#=-;1z+Uaa*_Me*Ufd9%CID-s- zpD-}dGcx?I*ua@pwlueJ2L9X1|HkWX=cxg3()j$(m%3kV`9bt z*6>g5|8UPgt>*n}6Ss)Ht%H*(5D3m4KNIgi?EG(O|C!5w;+0K-_BJkmouOuD>CDgk zFP8t2{6D!AoGeYj-u=t=Z!P~d?SJAGE$p4`!6ofvX)I;uZ0ZCy@n78kq40l?_%E{l z?O1LNQzI3y1XEkE8T@~%0`OmT!Pw9a=xlFn?eJG4{okUpu{1Wd1DY~$F|ji-ae?ax z?_c-*vw;4)od2TfueZ5n|G{bRq^2zUf6!s;0<<)ybFeY=u(1R>)47@&JKHaaZ>H~)MGoLE-ofJ#sc%Wev3S|0F#^JA<$2S+d>^=2;^+M|8vR`dh zww$dlQ+$2g?;G!$*3}*ND=~7J?E86QsEW{0g58!uNz?@-KVSi{-wYdxzd?Q?{t?7h zQm3jaCJ0wYdD7i478d4fy3l-rf1O_6O(PF5fD)w68DMBL%3&L3|nwFMC z_@Sw<`jHr*fPsP3GGc1bNi{2dl(;M^Iz@^c0S$;4pP2I!-aVR52FM>gx90 zqtfxikKTRJG`cyl8_vUTEt;Y*k$-qMBhg$toBcFBzjJt`QD`FHiO1_JMn*5bKw079 z)}EG9);yGk*8U=a@#T*+8H5WRgCVd|;#EjEl+=0Skx7{PZJS(EANk(i(Kfa}*jdHT ziCNhbD)69&u)t25>|!v1b7=gYZod25_Z98rD^-Qwe8AfV|KqD3JdIMF`ny|>mG)Oq zdUI0xI?R+g^YF)B&i51RX_ZEl>hsfqQ<$eqVRQU9MEk+EuInzxlDdy=UNB0UI86;@ zl4nKfXWM38>E;hqW^ccxm(qv4H#U`Ub?HT78QH8Ru3b3O9EkQ2dI+rqdvOL&`K0zz zvqECMk5{oP?0RKjR^we-q(G3)Mrc!u`9ay$Yyx9b*$U=y3h^yegmspL*Ow%Tu0%K! zJ?Ec)HVTCIM2NMVMQ#e)oiB6FFCce~1+wBhJigw5J`@IJ?}zYQ*ymzB#6!t958(zP z{P_br>rng6|$}6hmzq4td1qJhVsHKZKZ}b)gWjCt{v?0q|V|!4B+GeTN z$I#Zbet~@B75cm-pd4LYUaM&3M{T})5MDDP>>HT>%p8)?vA+PsqFa7t< zn*;luL;W@!9)0gG#q?H!`m~moM&_Ux9#=p{rhjxO-&o-us|)@jpqHCmIK(75q`~Le z6#)@3xh$3Gfy!_wsAvxvZIQ+>@b2!eq_mW4o1vX{U4Bvr_roWd$7{zkkLwR>iSj$W zr*^`Ik@E3&1RYU8LnHV<#|>VKj)znxYd9UlwX+S(pN#RBa^GI&Ic zo-~Vvis7v>>AK4mc*Bab?AmuTPOofyk(e|fVA{M;Y|46J-jCZ_UJ0uuhVpCydg#JY z=fq>Fk2)8txH15b-G{q7!+{8lme>1L;)5%b2sBq_iy0I0_!oS6uERB;!*(#1e0WXD zZhwz% z_R6C0v1(_=gHO5-v7&-c70h?GyMxhyHdi{M+NEKrqDQ%L+fww$|df)R)29v{=wDEFFW z^2A^ZL&r+6LOR;k1iFSUQSO?2QpOdASeoQd=z31gtO+S{lyf0R3x{6qMXke(G(ulg?Cb^ferCeM#l2iI zj@<@n+YhK|=$fLcAE=F*B{sFxMZ6Qljt>kSZ+?W{+h1B)iO96?Tz0ybgP|wor1*el zc_L!9QN!V<;v@8OywSFOv$!4b;Da#bhCp%-zr9dJoaNFZwsiTM&i(G8OL%xn391uf z$63!br1${Cgs(!oSmYL`tq5Eyz2PIPYim*V-)}M>C*3-Y(^XwlAc@c2MUcx3DHjK! z7bVF83>YmuA}HPN_hOMkdnLuuh80&wdB1Xq;AntUcS`kNu;n5#f9_YvEn&!A!VtbS zR3rMn^>m5z1XADgK9hxdVb<7w`Avn(HrBGwYrBVv{z;lU6S4T>?ZB1P+E>2LWt96VSkUhD$k7l@Kmo`Ps-C@z~ z?W6C5eX((THQIV90$LV!P4rB}#p7P|I+?d>E=Wes%WDMc7*@{t&MWmzQ`^kDQk111I84TWt;q7=* z8J+7=NH8Ad4$GAGy$YR=mO=IMs#i>e4z%GYF-V%nLlW<8FN!NzGz)W5xj zyPJ}-$f{($tM3m`th_L~o}Lgbsd8Vxzc z)K=rw<{P+D{mWchdJ%o5#)}Wirl?_IEyd=3t<%e+I2g$RF+RE4_9VK!!lVShN+LP+ z3cBzi4Q6rPoTnNO;BAC`&Grc!Oq47{{|MZ`J!8UCAg@@yuUME8^*@)LE`(?lqdH6w?1)tBn+-@B5`9!m0nzJ zmm3ua;!1>f1TijRzumgA00Q3eWxn+L^O8Fgl*s#^sm3kYInwRh9U6vMjTMx#%yUfS z9R_oeXrNo%tk7#7@+}e(NT;l(7$J-*3p|4N?dBTV&7s?pD5`rH2MZKV+quFLO&46( z+gswkFJ+jPg~-+t7T96gXrOLsmG}?2L)O6z6e>y;+Kt%R416Jcv74d6&dg#z9S?0CP1`qo{I%o^bw&aqVE1dIAkM>@K;p7MQ zBXsbwJThn$>9%XO(aTjf2s>{)zOZiIDA5R+w+_E_tshWM6u6<}tf%@FeF;yzS;K)& zKIeUtg-r!hM$nL4WB&bQ3gaqgq9Udry^pa8+MWew&URV(Vg@K%yQa2>P7n`C(V|H( z@Qmia?4|(mi#b@+0BjYg(JH~bxF47t)1O#R58bU%vif4oKD{;bzcLE*c`2a|lb*X8 z_zhKf^--8<-D>6~>(RsS6he(kQvq+q#=gg*HJz19exwcerhlqsw^-`G8BSC*d(gUERp4262Gfx< z4fsGIVsNexhU!3XNXFip>yni4zCzI>H6L9wtBqE|KjsAF>Ntd66VR1>1U zrh}y&W>G9a_eT5Oj*H@SM;2eRFR;LcWmo_k_D6j^x~=UwXgW5|J#6llI<-Qus*HdM z>8v3AOs>k(h$*GUH7z6jN9H$R>o%Q9a;3qFQ&KXED;d@o%De7?DM<~OvZVo+_~8V9 zlA0el%Lc)X^AaJi02O$`k#Ul_!?P?ov@d#gh@-NqGBUPP{>fSW$|eML9o4rul;1DH zMh^Q@Q}b}N6+RoL*FzAPMj4hTngB!`gx&0F#d9N8h zqHFSt%v5HE;|wXZC5)8?;NbbyN0r;Zh>~ce~dg(sYd}(IK5y@)PCzLqRosNzU(3sM-g&d8h1YbxRc&P3? zKLygzCXl&F+zJOIp~`8};2B3)Uz)T!`3Ybfg?vuPwUt22%UDWeOQ~t%0xc{AGx+`) zbANx{w7;_q9-eJ(Y!ogXUGPbi5QL=}%kzG_$sGzr<_}9rNg2^MVK$dE2x1%L21ylq z<#{Bq3^IyZLd}Yk@kJT8K+$g2FC)xN4C4tp@uq7;kyi+=&&>EYcbwaTn7?}6pVdlg z*;Fmt>)wQwAj8cNTgzo;zH=f}VLqezV$WRE%Y{u*BxA(E=Jo&XsV zHXS)Uvy$?IU-7hf#LFL381(H>)j(eHZxwQYi41q6)m((=un@l8D3%!O#%^>PxoxX_ z&dScp!stkrSC&WpItnKW+h5by=;4KV+I2>mO`lVXMe2_KzB3!M<&k+W zA?(_(#BDgOp`NLN$##q|%cZ=H@S@xC%gf7aT~5`**jUafu0#h2*|RI9j-6FoD{D2; zSOI+lwUGF!(LI#U%j~lWLh(g4B4IWqt0REkh)>C;$g8WXjw9r$TPNk!ITjeFjzj)_ z00uOn+d#sXZj#@QIz|b_igZZU@?5n5!Wf;^y~bycCBZ(^ATF*4;RUrwJvf?@av&!FeFE&LOanp(8u zAcX5Mm9cgsGQ)jD>P%K#;!4&6^bWmJ4>hh1H26W`m7boSK7ys=4&&qU!|Z%(a$2Q2 zr8wt4iW)MU)bL|I*+f9stw~TBHP<^^2m)Q8!E|U~Y*!eB20AP|h$NfCYc!F06(608YdYH`xSzoj!NRFClu_V0vib zE<;`bKK+-O)hg?d{*48ZkXy$kZ%2O?%jrQFZFVw6*H$$78ColRx<`|dRbI%b-R3sTtg=`XM;8X ziF>fcW+(uckf7uB&_Y}Q5+NT&WohirXh6=?is?bkn0kl$0ZtG+ydP&Irm$m=)wplo zUK^_p30z@IaOxfNsFjoL1$EwWoq7K@Wc`FwH|nSrYGHctof>JF^F#0W5qVM#%jf0| zn_gJJiW=+LOeSaM8h)%x4a+J{q~Y?iefO_s{Se)7+D~;-Aw*5a=^O#(7p+i#9w9_f zOI2`Ww`&q&So#6<1{O-axLS@kx;Bq>Y z&f@w8gwmtY@w)k%eX(SuHazLss73}&`M%1VH(#Tj)=cWy^FDc-1`FoAF7nn#@1@}m zqu&Ch3loj2a8#N0YW)4*d>@z3FB$Dx5?Fv)XkaTetD}oiNNR^mf z0Yj1vYDefH-QCkfWt@{MzfN7e-{Et6r0hLuesNiszita`%^z@E>B=LG9B?Mf8|8Rt zBdv@EeMrBwtC<=Z-+D(^KlRLG7Wea6B$4AJfy=}Y85heQX-^rYmd`%zW7&MB-wg@0 z*b_w&P^*?zuc=dFtfVTHuDhNiImI?^GmR3hwJ0-;oSE*L5cCtJ|0Y+3D#OezwKj)) zl75w|M~Sp88K0NcF3QFP$X7g@+O7`y4qgPTnB`DF}Aw{e79qnlB=@3W?Duk;{X zI&-7j#YU?#rRg7hW-RqOPt~x8))nxY2PntRtnCjYQD;dtKLRE_%nLH{axMEa@Gd zT8El97x(F5c|LkqwMHOKn(PUWKD93cqc2hKM5l# zY|Szuh9nayN6xieQjJQ8BEt{ZaePSd!d;)%g|jefn#~*?d*C0pnYbA^4C@RAGaEwJ zvX-To;!-_{sa$&KK@M$r>;4#t6{7&8F$=F4MDlXpfp+pUXEv4&I~-C2MkQO-AuqAz zp`&8(s&^6`STb`dEQSbb8Z4w0ngTRApIHhDwoGo)QSM|y5R1=hElRp2*X{QRKN7|d z(5ij%5M+ENO(-UvYz6?93W6!Hdj^GiIJXxK#K`Yh%#J(la&0}O?PIhDa)BD^W!d) z2o#mZOyvHzarkios|TIUyrAqpHd?I-ki$>HIjP<-^(12*dJb>Bgz=sRp7Es3DHAi@ zuRad$KEqBkrGxv$2FJ6>4w4CW^o$q|UfXUhD1`XJ_7@OFBB*C8tx)0qA6kHp^C5L5 z)m46rSUYub{A5N-3CU%FM(f z2K@AZ!3m1#6+$tFmKE)F;VjREeL%x+)*xKW9u>{NFR7UcYFmOg%Ofvc1XUk3de*w+ zs(!FdIPytx&98@i)z0bb#Ci`4thN;*#VWD7#C~%D-rK>M5@vnSF%A7Waq+Lh;lsA57+4;1)jI98)R5Zp<2^YGb2@+fI88k+5_{26Iy{)VBy2!1p0 zDREM;ojHg-qrc4o*j=GN=Y{8yu6FNdIng962qk2X)XUy`#N5#)Y=|lMjTR^RD9u#hbYkn-UWhv^ctDIDMuFDsyKRQ)6T24bR@_d9y?@VS+Dydd>L%Qls{n(Kh|GMV_$;naz*(v?Y zS9y~Zlw7jJRCt_EFwdp0IyzjVg>tKd1Ttt+lx1aBimQr|g1UV2{O=PbRsaN6IuY{~ z|G*jAk)u8$0b~;$3(jXFowYj5hmEJHrM7pMs+iyVk?JY)KMoFMgd^G&3sx&V7Xp6n z{dIGW__*Q7RbBO;bLDK1Cw5&(+^7 zu3(Qw=R$MUli3-f?|X`Q=Ig?;Grwl%neQ_{UE9Z%Ur?_6eLXqd4%v8ps@8I@$nd9S zg~%wdD=jub()(&>pygr1Yq>gs!v(}lX`AT8J3?tK9NP&}9bcGPOt?s>Qyb;kxI#Kx zZAOO2q)jstXqr9(_KUUG87A0zT@WFGD!V1#j`6}iX4X_&hs|H+M`SdnZ>;^gg=kuT z0P+Gib+@`{sRQ)pgZp5A;isg_W-cX+crMpgQ$;E+_n=CBCzLLnL6T8DO}&h?gt}N)D)$lvehmNkA&BKgGHqY!6-K6^3Xmf*s9)NQrYz=C{-oR^$(24nvyar?+ zb{hbIBZ}T=Zt{%zawhQ}u{U|>aJ|D#HWxrDcO*M|jU-c@@nV9C+~j>tSgWtuzlSuN zgXpeX;`SUDg4{;XinXfe{mIvHVsp0vp1#*V23yBp+IavcY5QjPd{HkJi+ktD?47NF zD9YUk1<5nsbT_{`_!mBV3=l1RK-o?`o_rqR-I&&J06(RWdI z@>O9jB{L-Xt>ueH&Xpc3x-DV8esG1J)d2L6f;Nl1_a%$I;13USS62jLGQCZ21Q}f_ zeD4=j-rGKVLqnp_UoPdSIA?{WC#KUPc^sDL18=nCfiDycOg)=@dHE`-)j}{D;=b1) z29l;5)2y4kt|8)4!DnnfA5{Db+io6#J2BA?w)p~KaV-h_=44+@AimQMg?-XC^G3(H z@j+kl-=%amcJ`gO=Zm4(@3*8nK6eYD6NZjk_~o){BJ#P*MP z-+4YlWxFY3otTdzciN!&*rjqdiiD*8~hSZDgyuuJmNeXv$Okvx{i`eMT2$is)s z;2s9k;BwOLiICwQqM%!j<}ycFjytq#;O|f7=QWpt77HL~cLTxeB?i>EstMY@cjfv6 zw$1CV*k+cT_pa`TB?3h&5JjGE-yADUj*Je*WF+-CReXrUQe2f+5v6ly_5I=BPoUgA zhynpI#vM`U{B4CFwBI(f-5-ZG2XP{;E&7W}mZ{X3qZzZMJq)KD(ueC;3ix-{53uQX z!*0B5n^@Tm9(Es$fSi87_XD%`d0dfc6){BWe%TqwgUEp82qzGBMJ}j4)gI0=L&Aj9 z##fse%lyf zbr^V_Zu9j^zacUOVHXkbw=8%JkElfrvfEN-aV1Sv@WLw}ERt?1&C#b#)se|Ey+%uz z_#U%kOmWi;eHV&-$kTtN`0$Gbh4%)seGOC0kHuc63Odw$_Hp9t<{-5%E@E<{B-t#2 zk%0?yQF!8W*zp<8=7`H&IW(LpC)p;iQ~H%LLt`mV~Ahd57Z$*Byc^lNGq zq$c0SQ0v{O0r(FrNyp)X=<2MA7y}}Hw)rc7$OByK`dF$^g?R0!%BFMywe%%T!3P7h z?LkahoeqL*d~T^(ZG6Emjq7c-`@i4215R+sj-s6ATFG1;Hl*?$Xi&tCtj}|5zL7d$ z0zn(JDvPEQc`h|wzZ&vT+j6`Jpm<#KQ!?24P^3KUJVu7i(r1N1`4gS$SDkS1>_bSb zDK)@9l{5@Q#NAgZw1MQGu;R%UuVe`0G`|MUBf=5M*CIn&pPWh4x)1&x8GFM%EHu(sebfvQ0cS%endAbim^IVpKDqdf3W@EwX?U!J`)DY~JXf&FTA&OE?HK+sK3|UZZO1$2Rm<8~ zAqzTHZZF<(B|vA6baOt}!K~^>P&Q7M`7OO>0@Om|Js^AcEm)}X#xY(7DraANXetKmuGS=Qj8 zERZNiQ!2P6VX6nC1N|}Y@@y?%Qq{{O=&o7&;kqBc7daezLMEd5VciB_zC_& z19RFZ$&d{Zm@VTLgV7Pqp0Hv{81C|?T)7xtftWZzR*05af zD~I|(DvHp-HC`<^9<0;kR{{H)fQ&Kw^iBfDPP5&k3+uo|g=X4`-DP?L2IH)sB9cIY z3bs!)MRlfliZ@d=_qn#T6hL2N(rk*GxH-qOnT>_xma!{cmEO-CS%OHDz`J_=qhhzE z9t1Rc4)oI2qf*l-$Cc4yGN{~Ok`)gMnVg3)r<|(u*W^6%m2reOb4D?xcP$6{Tl3gq zt+*Qi#p_vDQW4Zt>mSuQ|0Ki3D2g3cFH1dTYyX%c-sdR07%ww2HBp=|Jd*tbFA5&% z0Ez2}DXAj4Um^Mg#)*vx1O_RhioKI)mvbK4;p8zAo~5OdT1Dt72(p(BXUQ=oHd*}> zk|=%7(u{A7m0raxm$S?LTo;lm<;>23^?=dGFU%cukz~&mI0p(&Ei@IfZ}Nj*ro;zU*I^yq$+^4}%@OK3N0cqix(k9c%_4F+ zpBoXfYx48Yb`K3OzCMsnh3eqFU+YOikTwG+m*&XIND>%JPcDwpk=M6Y{)BRFw^(oLKXnh};RA-eI zgUE|*w|JMKZ{%AQh5kIPYR$~GVhJ6ji<9o+7p22u;=@NEF>GUru*gGxJi!V?cy{591Sn{~fdID<|5F{U23p#TI4C#KSplQLS?EBR z6{EV(?|Z6AssTte-1_&)$zb6{X9nD`h$IZ~vcS0H!Q}Fi6nR#Oq9+_J)wD}=(DTjs zl^^6`cEOQSBP?z?4}*l?eYdC|i|lhGlG0Q|86X2iZ`Z%CCzp^aT_^DU^;ExEk|v!p zrg>QO^67;7Y&)_7xXR92-36gb#j)b~NpZCS-~4_5`SLpZJ)|C!gGescDFUuLn;^&e z@s&a~o13^|8*eOYKL~1a`ihD0%KF*Wct8Enc=_0TdwG&orN+rcrfN6QYBSiMPrEkY zSb>GCrXC@`HU{hcn0E@$D@|Yg`uq?`gSDlS`;=5@DkhUI4H$WO5AS-02Jdc!KmTr< z(wfHkpG@O>ro{j;sYTBJpL=*ohEoOEn! zGJG1rzF~e8s7jqZ3=US+J1hHoz)*~poGETHe+;izU+)UlnTb?91~b8gM6a%fVD;h= z&U+n3v9%~z27vjS|Lwf!O&I6>Y5z|-cr1L56FE@hdaebpscAgK9=^}fCZLg1Lr9lQ zd(h~(D_)`BwV~y?cSK528!AFvYJvoBeNwx>aOmi8BLbW2M36eYh06g4ldas?@>u;2 z^R`RFVW8QV*_!eq87FJhJId+^GnKl`jMl=~*em-+R-S|p?mbp~QGD;?Pq(!@kzjtc zW|8-irn0ILFLz>1tv~Qol)wWq9{5`<@{x1d8&{`#>Z5hFB_x-@Tbc(4X1tGEf$Ea0 zCMU&fPtDi7`KAmVx5_eOpvA>lcl<`e|7OC`_~ zIlXT4qMVIdas!RiG0rl@Lw;TD*uS9{>v&__D+Zf&Brk0&#@^Yt;^+17^FG!44vmbZ zYSo+8olQvtwp1_UQzcTA)HMfb2e{C;8$n34#W-)E*f&1cf_C*;2TIZ!EvsJ6+aZ{m z_fnXetkW0iI<|Ca4wngj+}PHebpRrbkJ>8f8u;we+uNJe!l)|lUV$BJPvHJXvKUIu zI*}~PpZheRABFT>*KQekWaT=fQ%sXzO5H7pqG{|NKkry`Y$yNbgq$x?dqcon+^c=f zYrDEd?urhMVzja;sXzEpbj-)U0U>@O5fnh*0Hk#{*M}VA=s?GMTQ{$Do9=P(G65|3 zuMnkHjXUpRap*^80I;aj7e`2y6ueze%-=N97Oe%!t(G9s#L?8L)rP5aR2iV4_Ux&4 zoHHzNB&1NDI9bL8wMQpf|7){!yN^&G_YgS(Q-sg zTKj3eC`f%@3kYRZTot^qNH&Njy%wKqudb1I|Gcq2CE9rgiRf%20ltiGHQ@=wJpKO4 zS;`*d4`^ph5(DxJ*nGx9MqPg3A(?o28I$atoGQb8FO7twkvQNSq#h7DjPKv|To$lB zB^0FA3G8~!-Ry(^^XUwG&jH@p-RBRqmK9V9aPYEwsw))hq62=SRH#AKfsk+Fn)!;+ zmnoSZtrtIL``57Y2=!<}lwd4O$LW5Li~fzU}On?ah= z@aJZv$|+>aJ5Tdg_kqAxL6PSqQ3OE5;b(4-C&a5cG)gkTK)Y+KOR%qC*R<<86 z+s>k=&F&BXuRi#zr#Av<>yxxb#=eo?a9PSzYLF`rTgz?VBlxEHqDAcqg`Ek4kEL80 z>A5ZnVRC|!{V>YA#$JZb=t+ecfN?V4t9XHYpsWY>AoUK^z)qt3Tk%pRE{CK&c)yH> z^s%6q-Y;(#0NkpII6E&ib6~fz(IFCBfE@fMF;A=XI2?+B393!g}<~RI!$p@xsh94xQZ{TzX6X4LAPg3k6%VaPr)QMz5b6K4dvsa$X(F|ir z40`mB&;~Mn{UyHe_^UW zG*;@JjMpNpt{o$dnQpOp-C1aa#9ns8n0VB3!yTJ!gDuwe#=+I7+`S+`5KRQBa;EE& z;sn+UQ*)=2DdD#CW@Y+l5!N%-Mal>y-Nx6$PM4}mT^D&h)&6t-LpCro@8a)eTzZ*#Ac$@So5(s z=RuuT#|yVCwNfxdMh&T;Rh~PwGD$4$n37~0JFN#*4>?;>DCWNkHN>CcR)od4AaP-VXi)(nTMM+%p>5^$z#|72#=dm8A78fBcO~(nHGvFhcNqr zElkoEYc{ID%InT_&x;%N00re$1{Ma}O6o9qY=ECBkRwZnkvnJ0Nu!~-BMM_udEoHK zf?FM2_M(z(XOg^8udcMc1g{3{niklJ18A6lqxFdU!cThz52}+RY$nSRrUFgoaeXYT zk>^Lny|Val8F5Le7e1D zzMtXR(>3=j`1}<|vBJI`7DHK&b4!37F8{X*{{Hw+x%|?D){MtthH&2+F@W_@D!kYc$mLAg;{2iqn8oe1>z`1YDD3eGx zN#T1b_Y_@&%!cHbLc@AQC#;`~Qj4O0ilKh<7mO*YO6=nl1_h|orq$o)4S;O?OUjsR zZHjJG;CQl+aJ_A@>Mvw!8xPzuD+>LO@4i-l%N`Oj-|3<Nc;=c*GFe0GHQN4zCk z=D7u8qH^wdq=^yVg8pvtG5y`*Ln!{^r5az{>@A3G&spqUkcA|bR5Ry)LaQ_P+gkn= z)O2j^o6?!jC#&+b2zQokLhEqMfBC|Ka=3}E@PqD{I6|-$9P2{2n4#4A#UBkE)gt4U z-}c4d2^> { +export default async function createPlugin( + env: PluginEnvironment, +): Promise { return await createRouter({ - database, - identity: IdentityClient.create({ - discovery, - issuer: await discovery.getExternalBaseUrl('auth'), - }), - logger, - permissions, + database: env.database, + discovery: env.discovery, + identity: env.identity, + logger: env.logger, + permissions: env.permissions, }); } diff --git a/packages/core-components/api-report.md b/packages/core-components/api-report.md index 20e14312bb..99d18b9b12 100644 --- a/packages/core-components/api-report.md +++ b/packages/core-components/api-report.md @@ -16,7 +16,6 @@ import { CardHeaderProps } from '@material-ui/core/CardHeader'; import { Column } from '@material-table/core'; import { ComponentClass } from 'react'; import { ComponentProps } from 'react'; -import { ComponentType } from 'react'; import { default as CSS_2 } from 'csstype'; import { CSSProperties } from 'react'; import { ElementType } from 'react'; @@ -53,16 +52,6 @@ import { Theme } from '@material-ui/core/styles'; import { TooltipProps } from '@material-ui/core/Tooltip'; import { WithStyles } from '@material-ui/core/styles'; -// @public (undocumented) -export type ActionItemProps = { - label?: ListItemTextProps['primary']; - secondaryLabel?: ListItemTextProps['secondary']; - icon?: ReactElement; - disabled?: boolean; - onClick?: (event: React_2.MouseEvent) => void; - WrapperComponent?: ComponentType; -}; - // @public (undocumented) export function AlertDisplay(props: AlertDisplayProps): JSX.Element | null; @@ -448,9 +437,18 @@ export function Header(props: PropsWithChildren): JSX.Element; // @public (undocumented) export function HeaderActionMenu(props: HeaderActionMenuProps): JSX.Element; +// @public (undocumented) +export type HeaderActionMenuItem = { + label?: ListItemTextProps['primary']; + secondaryLabel?: ListItemTextProps['secondary']; + icon?: ReactElement; + disabled?: boolean; + onClick?: (event: React_2.MouseEvent) => void; +}; + // @public (undocumented) export type HeaderActionMenuProps = { - actionItems: ActionItemProps[]; + actionItems: HeaderActionMenuItem[]; }; // @public (undocumented) @@ -1357,7 +1355,7 @@ export function Table(props: TableProps): JSX.Element; // @public (undocumented) export namespace Table { var // (undocumented) - tableIcons: Readonly; + icons: Readonly; } // Warning: (ae-missing-release-tag) "TableClassKey" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) diff --git a/packages/core-components/src/components/Table/Table.tsx b/packages/core-components/src/components/Table/Table.tsx index b04c247b2f..49538b680a 100644 --- a/packages/core-components/src/components/Table/Table.tsx +++ b/packages/core-components/src/components/Table/Table.tsx @@ -523,4 +523,4 @@ export function Table(props: TableProps) { ); } -Table.tableIcons = Object.freeze(tableIcons); +Table.icons = Object.freeze(tableIcons); diff --git a/packages/core-components/src/layout/HeaderActionMenu/HeaderActionMenu.test.tsx b/packages/core-components/src/layout/HeaderActionMenu/HeaderActionMenu.test.tsx index 3337571d4e..92ce241aa8 100644 --- a/packages/core-components/src/layout/HeaderActionMenu/HeaderActionMenu.test.tsx +++ b/packages/core-components/src/layout/HeaderActionMenu/HeaderActionMenu.test.tsx @@ -60,7 +60,7 @@ describe('', () => { ); }); - it('Test wrapper, and secondary label', async () => { + it('Secondary label', async () => { const onClickFunction = jest.fn(); const rendered = await renderInTestApp( ', () => { { label: 'Some label', secondaryLabel: 'Secondary label', - WrapperComponent: ({ children }) => ( - - ), + onClick: onClickFunction, }, ]} />, diff --git a/packages/core-components/src/layout/HeaderActionMenu/HeaderActionMenu.tsx b/packages/core-components/src/layout/HeaderActionMenu/HeaderActionMenu.tsx index 125363fe0a..e164244ea7 100644 --- a/packages/core-components/src/layout/HeaderActionMenu/HeaderActionMenu.tsx +++ b/packages/core-components/src/layout/HeaderActionMenu/HeaderActionMenu.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import React, { Fragment, ReactElement, ComponentType } from 'react'; +import React, { Fragment, ReactElement } from 'react'; import IconButton from '@material-ui/core/IconButton'; import List from '@material-ui/core/List'; import ListItem from '@material-ui/core/ListItem'; @@ -28,13 +28,12 @@ import MoreVert from '@material-ui/icons/MoreVert'; /** * @public */ -export type ActionItemProps = { +export type HeaderActionMenuItem = { label?: ListItemTextProps['primary']; secondaryLabel?: ListItemTextProps['secondary']; icon?: ReactElement; disabled?: boolean; - onClick?: (event: React.MouseEvent) => void; - WrapperComponent?: ComponentType; + onClick?: (event: React.MouseEvent) => void; }; const ActionItem = ({ @@ -43,10 +42,9 @@ const ActionItem = ({ icon, disabled = false, onClick, - WrapperComponent = React.Fragment, -}: ActionItemProps) => { +}: HeaderActionMenuItem) => { return ( - + {icon}} - + ); }; @@ -68,7 +66,7 @@ const ActionItem = ({ * @public */ export type HeaderActionMenuProps = { - actionItems: ActionItemProps[]; + actionItems: HeaderActionMenuItem[]; }; /** diff --git a/packages/core-components/src/layout/HeaderActionMenu/index.ts b/packages/core-components/src/layout/HeaderActionMenu/index.ts index 6fa74d9d09..4fd9552fa7 100644 --- a/packages/core-components/src/layout/HeaderActionMenu/index.ts +++ b/packages/core-components/src/layout/HeaderActionMenu/index.ts @@ -16,6 +16,6 @@ export { HeaderActionMenu } from './HeaderActionMenu'; export type { - ActionItemProps, + HeaderActionMenuItem, HeaderActionMenuProps, } from './HeaderActionMenu'; diff --git a/plugins/playlist-backend/README.md b/plugins/playlist-backend/README.md index 75e0281a08..14a39ca741 100644 --- a/plugins/playlist-backend/README.md +++ b/plugins/playlist-backend/README.md @@ -21,20 +21,15 @@ import { createRouter } from '@backstage/plugin-playlist-backend'; import { Router } from 'express'; import { PluginEnvironment } from '../types'; -export default async function createPlugin({ - database, - discovery, - logger, - permissions, -}: PluginEnvironment): Promise { +export default async function createPlugin( + env: PluginEnvironment, +): Promise { return await createRouter({ - database, - identity: IdentityClient.create({ - discovery, - issuer: await discovery.getExternalBaseUrl('auth'), - }), - logger, - permissions, + database: env.database, + discovery: env.discovery, + identity: env.identity, + logger: env.logger, + permissions: env.permissions, }); } ``` diff --git a/plugins/playlist-backend/api-report.md b/plugins/playlist-backend/api-report.md index 5c86b6ae45..c7109efbfb 100644 --- a/plugins/playlist-backend/api-report.md +++ b/plugins/playlist-backend/api-report.md @@ -7,7 +7,7 @@ import { BackstageIdentityResponse } from '@backstage/plugin-auth-node'; import { ConditionalPolicyDecision } from '@backstage/plugin-permission-common'; import { Conditions } from '@backstage/plugin-permission-node'; import express from 'express'; -import { IdentityClient } from '@backstage/plugin-auth-node'; +import { IdentityApi } from '@backstage/plugin-auth-node'; import { Logger } from 'winston'; import { Permission } from '@backstage/plugin-permission-common'; import { PermissionCondition } from '@backstage/plugin-permission-common'; @@ -17,6 +17,7 @@ import { PermissionPolicy } from '@backstage/plugin-permission-node'; import { PermissionRule } from '@backstage/plugin-permission-node'; import { PlaylistMetadata } from '@backstage/plugin-playlist-common'; import { PluginDatabaseManager } from '@backstage/backend-common'; +import { PluginEndpointDiscovery } from '@backstage/backend-common'; import { PolicyDecision } from '@backstage/plugin-permission-common'; import { PolicyQuery } from '@backstage/plugin-permission-node'; import { ResourcePermission } from '@backstage/plugin-permission-common'; @@ -84,7 +85,9 @@ export interface RouterOptions { // (undocumented) database: PluginDatabaseManager; // (undocumented) - identity: IdentityClient; + discovery: PluginEndpointDiscovery; + // (undocumented) + identity: IdentityApi; // (undocumented) logger: Logger; // (undocumented) diff --git a/plugins/playlist-backend/migrations/20220701011329_init.js b/plugins/playlist-backend/migrations/20220701011329_init.js index 17a71e8438..be08363dec 100644 --- a/plugins/playlist-backend/migrations/20220701011329_init.js +++ b/plugins/playlist-backend/migrations/20220701011329_init.js @@ -37,7 +37,9 @@ exports.up = async function up(knex) { .onDelete('CASCADE') .comment('The id of the playlist this entity belongs to'); table.string('entity_ref').notNullable().comment('A entity ref'); - table.unique(['playlist_id', 'entity_ref']); + table.unique(['playlist_id', 'entity_ref'], { + indexName: 'playlist_entity_composite_index', + }); }); await knex.schema.createTable('followers', table => { @@ -49,7 +51,9 @@ exports.up = async function up(knex) { .onDelete('CASCADE') .comment('The id of the playlist being followed'); table.string('user_ref').notNullable().comment('A user entity ref'); - table.unique(['playlist_id', 'user_ref']); + table.unique(['playlist_id', 'user_ref'], { + indexName: 'playlist_follower_composite_index', + }); }); }; diff --git a/plugins/playlist-backend/package.json b/plugins/playlist-backend/package.json index bbea8163fb..b760611548 100644 --- a/plugins/playlist-backend/package.json +++ b/plugins/playlist-backend/package.json @@ -22,13 +22,15 @@ "postpack": "backstage-cli package postpack" }, "dependencies": { - "@backstage/backend-common": "^0.15.1-next.2", - "@backstage/backend-test-utils": "^0.1.28-next.2", - "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0", - "@backstage/plugin-auth-node": "^0.2.5-next.2", - "@backstage/plugin-permission-common": "^0.6.4-next.1", - "@backstage/plugin-permission-node": "^0.6.5-next.2", + "@backstage/backend-common": "^0.15.1-next.3", + "@backstage/backend-test-utils": "^0.1.28-next.3", + "@backstage/catalog-client": "1.1.0-next.2", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/config": "^1.0.2-next.0", + "@backstage/errors": "^1.1.1-next.0", + "@backstage/plugin-auth-node": "^0.2.5-next.3", + "@backstage/plugin-permission-common": "^0.6.4-next.2", + "@backstage/plugin-permission-node": "^0.6.5-next.3", "@backstage/plugin-playlist-common": "^0.0.0", "@types/express": "*", "express": "^4.17.1", @@ -40,7 +42,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", + "@backstage/cli": "^0.19.0-next.3", "@types/supertest": "^2.0.8", "msw": "^0.47.0", "supertest": "^6.1.3" diff --git a/plugins/playlist-backend/src/service/ListPlaylistsFilter.ts b/plugins/playlist-backend/src/service/ListPlaylistsFilter.ts index bff14b2a58..a746286136 100644 --- a/plugins/playlist-backend/src/service/ListPlaylistsFilter.ts +++ b/plugins/playlist-backend/src/service/ListPlaylistsFilter.ts @@ -73,7 +73,7 @@ export function parseListPlaylistsFilterString( return undefined; } - const filtersByKey: Record = {}; + const filtersByKey = new Map(); for (const statement of statements) { const equalsIndex = statement.indexOf('='); @@ -89,13 +89,12 @@ export function parseListPlaylistsFilterString( ); } - const f = - key in filtersByKey - ? filtersByKey[key] - : (filtersByKey[key] = { key, values: [] }); + const f = filtersByKey.has(key) + ? filtersByKey.get(key) + : filtersByKey.set(key, { key, values: [] }).get(key); - f.values.push(value); + f!.values.push(value); } - return Object.values(filtersByKey); + return [...filtersByKey.values()]; } diff --git a/plugins/playlist-backend/src/service/router.test.ts b/plugins/playlist-backend/src/service/router.test.ts index 06185acae8..3f90a8b8af 100644 --- a/plugins/playlist-backend/src/service/router.test.ts +++ b/plugins/playlist-backend/src/service/router.test.ts @@ -14,9 +14,13 @@ * limitations under the License. */ -import { DatabaseManager, getVoidLogger } from '@backstage/backend-common'; +import { + DatabaseManager, + getVoidLogger, + PluginEndpointDiscovery, +} from '@backstage/backend-common'; import { ConfigReader } from '@backstage/config'; -import { IdentityClient } from '@backstage/plugin-auth-node'; +import { IdentityApi } from '@backstage/plugin-auth-node'; import { AuthorizeResult } from '@backstage/plugin-permission-common'; import { permissions } from '@backstage/plugin-playlist-common'; import express from 'express'; @@ -24,8 +28,39 @@ import request from 'supertest'; import { createRouter } from './router'; +const sampleEntities = [ + { + kind: 'system', + metadata: { + namespace: 'default', + name: 'test-ent-system', + title: 'Test Ent', + description: 'test ent description', + }, + }, + { + kind: 'component', + metadata: { + namespace: 'default', + name: 'test-ent', + title: 'Test Ent 2', + description: 'test ent description 2', + }, + spec: { + type: 'library', + }, + }, +]; +const mockGetEntties = jest + .fn() + .mockImplementation(async () => ({ items: sampleEntities })); +jest.mock('@backstage/catalog-client', () => ({ + CatalogClient: jest + .fn() + .mockImplementation(() => ({ getEntities: mockGetEntties })), +})); + jest.mock('@backstage/plugin-auth-node', () => ({ - ...jest.requireActual('@backstage/plugin-auth-node'), getBearerTokenFromAuthorizationHeader: () => 'token', })); @@ -99,14 +134,20 @@ describe('createRouter', () => { userEntityRef: 'user:default/me', }; const mockIdentityClient = { - authenticate: jest + getIdentity: jest .fn() .mockImplementation(async () => ({ identity: mockUser })), - } as unknown as IdentityClient; + } as unknown as IdentityApi; + + const discovery: jest.Mocked = { + getBaseUrl: jest.fn(), + getExternalBaseUrl: jest.fn(), + }; beforeEach(async () => { const router = await createRouter({ database: createDatabase(), + discovery, identity: mockIdentityClient, logger: getVoidLogger(), permissions: mockPermissionEvaluator, @@ -398,6 +439,7 @@ describe('createRouter', () => { { token: 'token' }, ); expect(mockDbHandler.getPlaylistEntities).not.toHaveBeenCalled(); + expect(mockGetEntties).not.toHaveBeenCalled(); expect(response.status).toEqual(403); }); @@ -406,8 +448,25 @@ describe('createRouter', () => { expect(mockDbHandler.getPlaylistEntities).toHaveBeenCalledWith( 'playlist-id', ); + expect(mockGetEntties).toHaveBeenCalledWith( + { + filter: [ + { + kind: 'component', + 'metadata.namespace': 'default', + 'metadata.name': 'test-ent', + }, + { + kind: 'system', + 'metadata.namespace': 'default', + 'metadata.name': 'test-ent-system', + }, + ], + }, + { token: 'token' }, + ); expect(response.status).toEqual(200); - expect(response.body).toEqual(mockEntities); + expect(response.body).toEqual(sampleEntities); }); }); diff --git a/plugins/playlist-backend/src/service/router.ts b/plugins/playlist-backend/src/service/router.ts index 7ca41c0ac1..bf0b789b7a 100644 --- a/plugins/playlist-backend/src/service/router.ts +++ b/plugins/playlist-backend/src/service/router.ts @@ -14,11 +14,17 @@ * limitations under the License. */ -import { errorHandler, PluginDatabaseManager } from '@backstage/backend-common'; +import { + errorHandler, + PluginDatabaseManager, + PluginEndpointDiscovery, +} from '@backstage/backend-common'; +import { CatalogClient } from '@backstage/catalog-client'; +import { parseEntityRef } from '@backstage/catalog-model'; import { NotAllowedError } from '@backstage/errors'; import { getBearerTokenFromAuthorizationHeader, - IdentityClient, + IdentityApi, } from '@backstage/plugin-auth-node'; import { AuthorizePermissionRequest, @@ -44,7 +50,8 @@ import { parseListPlaylistsFilterParams } from './ListPlaylistsFilter'; */ export interface RouterOptions { database: PluginDatabaseManager; - identity: IdentityClient; + discovery: PluginEndpointDiscovery; + identity: IdentityApi; logger: Logger; permissions: PermissionEvaluator; } @@ -57,6 +64,7 @@ export async function createRouter( ): Promise { const { database, + discovery, identity, logger, permissions: permissionEvaluator, @@ -64,19 +72,23 @@ export async function createRouter( logger.info('Initializing Playlist backend'); + const catalogClient = new CatalogClient({ discoveryApi: discovery }); const db = await database.getClient(); const dbHandler = await DatabaseHandler.create({ database: db }); const evaluateRequestPermission = async ( - req: express.Request, + request: express.Request, permission: AuthorizePermissionRequest | QueryPermissionRequest, conditional: boolean = false, ) => { const token = getBearerTokenFromAuthorizationHeader( - req.header('authorization'), + request.header('authorization'), ); - const user = await identity.authenticate(token); + const user = await identity.getIdentity({ request }); + if (!user) { + throw new NotAllowedError('Unauthorized'); + } const decision = conditional ? ( @@ -196,7 +208,36 @@ export async function createRouter( permission: permissions.playlistListRead, resourceRef: req.params.playlistId, }); - const entities = await dbHandler.getPlaylistEntities(req.params.playlistId); + + const entityRefs = await dbHandler.getPlaylistEntities( + req.params.playlistId, + ); + if (!entityRefs.length) { + res.json([]); + return; + } + + const filter = entityRefs.map(ref => { + const compoundRef = parseEntityRef(ref); + return { + kind: compoundRef.kind, + 'metadata.namespace': compoundRef.namespace, + 'metadata.name': compoundRef.name, + }; + }); + + const token = getBearerTokenFromAuthorizationHeader( + req.header('authorization'), + ); + + // TODO(kuanpg): entities in this playlist that no longer exist in the catalog will be + // excluded from this response, we need a way to clean up these orphaned refs potentially + // via catalog events (https://github.com/backstage/backstage/issues/8219) + // + // Note: This will also enforce catalog permissions and will only return entities for which the current user has access to + const entities = (await catalogClient.getEntities({ filter }, { token })) + .items; + res.json(entities); }); diff --git a/plugins/playlist-backend/src/service/standaloneServer.ts b/plugins/playlist-backend/src/service/standaloneServer.ts index 46d6f7ad8d..3b6acfd09b 100644 --- a/plugins/playlist-backend/src/service/standaloneServer.ts +++ b/plugins/playlist-backend/src/service/standaloneServer.ts @@ -23,7 +23,7 @@ import { useHotMemoize, } from '@backstage/backend-common'; import { ConfigReader } from '@backstage/config'; -import { IdentityClient } from '@backstage/plugin-auth-node'; +import { DefaultIdentityClient } from '@backstage/plugin-auth-node'; import { ServerPermissionClient } from '@backstage/plugin-permission-node'; import { Server } from 'http'; import { Logger } from 'winston'; @@ -53,7 +53,7 @@ export async function startStandaloneServer( return manager.forPlugin('playlist'); }); - const identity = IdentityClient.create({ + const identity = DefaultIdentityClient.create({ discovery, issuer: await discovery.getExternalBaseUrl('auth'), }); @@ -69,6 +69,7 @@ export async function startStandaloneServer( logger.debug('Starting application server...'); const router = await createRouter({ database, + discovery, identity, logger, permissions, diff --git a/plugins/playlist-common/package.json b/plugins/playlist-common/package.json index 67a97b1237..b9e8637f17 100644 --- a/plugins/playlist-common/package.json +++ b/plugins/playlist-common/package.json @@ -23,10 +23,10 @@ "postpack": "backstage-cli package postpack" }, "dependencies": { - "@backstage/plugin-permission-common": "^0.6.4-next.1" + "@backstage/plugin-permission-common": "^0.6.4-next.2" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2" + "@backstage/cli": "^0.19.0-next.3" }, "files": [ "dist" diff --git a/plugins/playlist/api-report.md b/plugins/playlist/api-report.md index ddfec2948d..7a732a4a53 100644 --- a/plugins/playlist/api-report.md +++ b/plugins/playlist/api-report.md @@ -8,16 +8,16 @@ import { ApiRef } from '@backstage/core-plugin-api'; import { BackstagePlugin } from '@backstage/core-plugin-api'; import { DiscoveryApi } from '@backstage/core-plugin-api'; +import { Entity } from '@backstage/catalog-model'; import { FetchApi } from '@backstage/core-plugin-api'; import { Playlist } from '@backstage/plugin-playlist-common'; import { PlaylistMetadata } from '@backstage/plugin-playlist-common'; import { RouteRef } from '@backstage/core-plugin-api'; // @public (undocumented) -export const EntityPlaylistDialog: ({ - open, - onClose, -}: EntityPlaylistDialogProps) => JSX.Element; +export const EntityPlaylistDialog: ( + props: EntityPlaylistDialogProps, +) => JSX.Element; // @public (undocumented) export type EntityPlaylistDialogProps = { @@ -49,7 +49,7 @@ export interface PlaylistApi { // (undocumented) getPlaylist(playlistId: string): Promise; // (undocumented) - getPlaylistEntities(playlistId: string): Promise; + getPlaylistEntities(playlistId: string): Promise; // (undocumented) removePlaylistEntities( playlistId: string, @@ -80,7 +80,7 @@ export class PlaylistClient implements PlaylistApi { // (undocumented) getPlaylist(playlistId: string): Promise; // (undocumented) - getPlaylistEntities(playlistId: string): Promise; + getPlaylistEntities(playlistId: string): Promise; // (undocumented) removePlaylistEntities( playlistId: string, diff --git a/plugins/playlist/package.json b/plugins/playlist/package.json index 51cffcca9f..f59fce18db 100644 --- a/plugins/playlist/package.json +++ b/plugins/playlist/package.json @@ -22,14 +22,14 @@ "postpack": "backstage-cli package postpack" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0", - "@backstage/core-components": "^0.11.1-next.2", - "@backstage/core-plugin-api": "^1.0.6-next.2", - "@backstage/errors": "^1.1.0", + "@backstage/catalog-model": "^1.1.1-next.0", + "@backstage/core-components": "^0.11.1-next.3", + "@backstage/core-plugin-api": "^1.0.6-next.3", + "@backstage/errors": "^1.1.1-next.0", "@backstage/plugin-catalog-common": "^1.0.6-next.0", - "@backstage/plugin-catalog-react": "^1.1.4-next.1", - "@backstage/plugin-permission-common": "^0.6.4-next.1", - "@backstage/plugin-permission-react": "^0.4.5-next.1", + "@backstage/plugin-catalog-react": "^1.1.4-next.2", + "@backstage/plugin-permission-common": "^0.6.4-next.2", + "@backstage/plugin-permission-react": "^0.4.5-next.2", "@backstage/plugin-playlist-common": "^0.0.0", "@backstage/plugin-search-react": "^1.1.0-next.2", "@backstage/theme": "^0.2.16", @@ -47,15 +47,14 @@ "react-router-dom": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { - "@backstage/cli": "^0.19.0-next.2", - "@backstage/core-app-api": "^1.1.0-next.2", - "@backstage/dev-utils": "^1.0.6-next.1", - "@backstage/test-utils": "^1.2.0-next.2", + "@backstage/cli": "^0.19.0-next.3", + "@backstage/core-app-api": "^1.1.0-next.3", + "@backstage/dev-utils": "^1.0.6-next.2", + "@backstage/test-utils": "^1.2.0-next.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/react-hooks": "^8.0.0", "@testing-library/user-event": "^14.0.0", - "@types/jest": "*", "@types/node": "*", "cross-fetch": "^3.1.5", "msw": "^0.47.0", diff --git a/plugins/playlist/src/api/PlaylistApi.ts b/plugins/playlist/src/api/PlaylistApi.ts index d0b87ec28a..9a9da1badb 100644 --- a/plugins/playlist/src/api/PlaylistApi.ts +++ b/plugins/playlist/src/api/PlaylistApi.ts @@ -14,6 +14,7 @@ * limitations under the License. */ +import { Entity } from '@backstage/catalog-model'; import { createApiRef } from '@backstage/core-plugin-api'; import { Playlist, PlaylistMetadata } from '@backstage/plugin-playlist-common'; @@ -62,7 +63,7 @@ export interface PlaylistApi { addPlaylistEntities(playlistId: string, entityRefs: string[]): Promise; - getPlaylistEntities(playlistId: string): Promise; + getPlaylistEntities(playlistId: string): Promise; removePlaylistEntities( playlistId: string, diff --git a/plugins/playlist/src/api/PlaylistClient.test.ts b/plugins/playlist/src/api/PlaylistClient.test.ts index f3b62c19ac..20d4a0bcc8 100644 --- a/plugins/playlist/src/api/PlaylistClient.test.ts +++ b/plugins/playlist/src/api/PlaylistClient.test.ts @@ -215,7 +215,29 @@ describe('PlaylistClient', () => { }); it('getPlaylistEntities', async () => { - const entities = ['component:default/ent1', 'component:default/ent2']; + const entities = [ + { + kind: 'system', + metadata: { + namespace: 'default', + name: 'test-ent', + title: 'Test Ent', + description: 'test ent description', + }, + }, + { + kind: 'component', + metadata: { + namespace: 'foo', + name: 'test-ent2', + title: 'Test Ent 2', + description: 'test ent description 2', + }, + spec: { + type: 'library', + }, + }, + ]; server.use( rest.get(`${mockBaseUrl}/id/entities`, (_, res, ctx) => diff --git a/plugins/playlist/src/api/PlaylistClient.ts b/plugins/playlist/src/api/PlaylistClient.ts index b77aa79733..425b185de8 100644 --- a/plugins/playlist/src/api/PlaylistClient.ts +++ b/plugins/playlist/src/api/PlaylistClient.ts @@ -14,6 +14,7 @@ * limitations under the License. */ +import { Entity } from '@backstage/catalog-model'; import { DiscoveryApi, FetchApi } from '@backstage/core-plugin-api'; import { ResponseError } from '@backstage/errors'; import { Playlist, PlaylistMetadata } from '@backstage/plugin-playlist-common'; @@ -142,7 +143,7 @@ export class PlaylistClient implements PlaylistApi { } } - async getPlaylistEntities(playlistId: string): Promise { + async getPlaylistEntities(playlistId: string): Promise { const baseUrl = await this.discoveryApi.getBaseUrl('playlist'); const resp = await this.fetchApi.fetch( `${baseUrl}/${playlistId}/entities`, diff --git a/plugins/playlist/src/components/EntityPlaylistDialog/EntityPlaylistDialog.tsx b/plugins/playlist/src/components/EntityPlaylistDialog/EntityPlaylistDialog.tsx index 474a9abb1f..247f737f3f 100644 --- a/plugins/playlist/src/components/EntityPlaylistDialog/EntityPlaylistDialog.tsx +++ b/plugins/playlist/src/components/EntityPlaylistDialog/EntityPlaylistDialog.tsx @@ -78,10 +78,9 @@ export type EntityPlaylistDialogProps = { onClose: () => void; }; -export const EntityPlaylistDialog = ({ - open, - onClose, -}: EntityPlaylistDialogProps) => { +export const EntityPlaylistDialog = (props: EntityPlaylistDialogProps) => { + const { open, onClose } = props; + const classes = useStyles(); const navigate = useNavigate(); const { entity } = useAsyncEntity(); diff --git a/plugins/playlist/src/components/PlaylistPage/PlaylistEntitiesTable.test.tsx b/plugins/playlist/src/components/PlaylistPage/PlaylistEntitiesTable.test.tsx index 3dfd89fda9..f7720b25c1 100644 --- a/plugins/playlist/src/components/PlaylistPage/PlaylistEntitiesTable.test.tsx +++ b/plugins/playlist/src/components/PlaylistPage/PlaylistEntitiesTable.test.tsx @@ -15,11 +15,7 @@ */ import { ErrorApi, errorApiRef } from '@backstage/core-plugin-api'; -import { - CatalogApi, - catalogApiRef, - entityRouteRef, -} from '@backstage/plugin-catalog-react'; +import { entityRouteRef } from '@backstage/plugin-catalog-react'; import { AuthorizeResult } from '@backstage/plugin-permission-common'; import { PermissionApi, @@ -47,17 +43,6 @@ jest.mock('./AddEntitiesDrawer', () => ({ describe('PlaylistEntitiesTable', () => { const errorApi: Partial = { post: jest.fn() }; - const playlistApi: Partial = { - getPlaylistEntities: jest - .fn() - .mockImplementation(async () => [ - 'system:default/test-ent', - 'component:foo/test-ent2', - ]), - addPlaylistEntities: jest.fn().mockImplementation(async () => {}), - removePlaylistEntities: jest.fn().mockImplementation(async () => {}), - }; - const sampleEntities = [ { kind: 'system', @@ -81,10 +66,12 @@ describe('PlaylistEntitiesTable', () => { }, }, ]; - const catalogApi: Partial = { - getEntities: jest + const playlistApi: Partial = { + getPlaylistEntities: jest .fn() - .mockImplementation(async () => ({ items: sampleEntities })), + .mockImplementation(async () => sampleEntities), + addPlaylistEntities: jest.fn().mockImplementation(async () => {}), + removePlaylistEntities: jest.fn().mockImplementation(async () => {}), }; const mockAuthorize = jest @@ -97,7 +84,6 @@ describe('PlaylistEntitiesTable', () => { new Map() }}> { const rendered = await render(); expect(playlistApi.getPlaylistEntities).toHaveBeenCalledWith('playlist-id'); - expect(catalogApi.getEntities).toHaveBeenCalledWith({ - filter: [ - { - kind: 'system', - 'metadata.namespace': 'default', - 'metadata.name': 'test-ent', - }, - { - kind: 'component', - 'metadata.namespace': 'foo', - 'metadata.name': 'test-ent2', - }, - ], - fields: [ - 'kind', - 'metadata.namespace', - 'metadata.name', - 'metadata.title', - 'metadata.description', - 'spec.type', - ], - }); expect(rendered.getByText('Test Ent')).toBeInTheDocument(); expect(rendered.getByText('system')).toBeInTheDocument(); diff --git a/plugins/playlist/src/components/PlaylistPage/PlaylistEntitiesTable.tsx b/plugins/playlist/src/components/PlaylistPage/PlaylistEntitiesTable.tsx index 0fa78b19bd..f499f59a61 100644 --- a/plugins/playlist/src/components/PlaylistPage/PlaylistEntitiesTable.tsx +++ b/plugins/playlist/src/components/PlaylistPage/PlaylistEntitiesTable.tsx @@ -14,11 +14,7 @@ * limitations under the License. */ -import { - Entity, - parseEntityRef, - stringifyEntityRef, -} from '@backstage/catalog-model'; +import { Entity, stringifyEntityRef } from '@backstage/catalog-model'; import { ErrorPanel, SubvalueCell, @@ -26,7 +22,7 @@ import { TableFilter, } from '@backstage/core-components'; import { errorApiRef, useApi } from '@backstage/core-plugin-api'; -import { catalogApiRef, EntityRefLink } from '@backstage/plugin-catalog-react'; +import { EntityRefLink } from '@backstage/plugin-catalog-react'; import { usePermission } from '@backstage/plugin-permission-react'; import { permissions } from '@backstage/plugin-playlist-common'; import AddBoxIcon from '@material-ui/icons/AddBox'; @@ -43,7 +39,6 @@ export const PlaylistEntitiesTable = ({ }: { playlistId: string; }) => { - const catalogApi = useApi(catalogApiRef); const errorApi = useApi(errorApiRef); const playlistApi = useApi(playlistApiRef); const [openAddEntitiesDrawer, setOpenAddEntitiesDrawer] = useState(false); @@ -53,39 +48,10 @@ export const PlaylistEntitiesTable = ({ resourceRef: playlistId, }); - const [{ value: entities, loading, error }, loadEntities] = - useAsyncFn(async () => { - const entityRefs = await playlistApi.getPlaylistEntities(playlistId); - if (!entityRefs.length) { - return []; - } - - const filter = entityRefs.map(ref => { - const compoundRef = parseEntityRef(ref); - return { - kind: compoundRef.kind, - 'metadata.namespace': compoundRef.namespace, - 'metadata.name': compoundRef.name, - }; - }); - - // TODO(kuanpg): entities in this playlist that no longer exist in the catalog will be - // excluded from this response, we need a way to clean up these orphaned refs potentially - // via catalog events (https://github.com/backstage/backstage/issues/8219) - return ( - await catalogApi.getEntities({ - filter, - fields: [ - 'kind', - 'metadata.namespace', - 'metadata.name', - 'metadata.title', - 'metadata.description', - 'spec.type', - ], - }) - ).items; - }, [catalogApi, playlistApi]); + const [{ value: entities, loading, error }, loadEntities] = useAsyncFn( + () => playlistApi.getPlaylistEntities(playlistId), + [playlistApi], + ); useEffect(() => { loadEntities(); @@ -190,7 +156,7 @@ export const PlaylistEntitiesTable = ({ data={entities ?? []} filters={filters} icons={{ - ...Table.tableIcons, + ...Table.icons, Search: forwardRef((props, ref) => ( )), diff --git a/yarn.lock b/yarn.lock index d55434a22a..02659263e8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3010,7 +3010,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/catalog-client@^1.1.0-next.2, @backstage/catalog-client@workspace:packages/catalog-client": +"@backstage/catalog-client@1.1.0-next.2, @backstage/catalog-client@^1.1.0-next.2, @backstage/catalog-client@workspace:packages/catalog-client": version: 0.0.0-use.local resolution: "@backstage/catalog-client@workspace:packages/catalog-client" dependencies: @@ -6222,6 +6222,85 @@ __metadata: languageName: node linkType: hard +"@backstage/plugin-playlist-backend@^0.0.0, @backstage/plugin-playlist-backend@workspace:plugins/playlist-backend": + version: 0.0.0-use.local + resolution: "@backstage/plugin-playlist-backend@workspace:plugins/playlist-backend" + dependencies: + "@backstage/backend-common": ^0.15.1-next.3 + "@backstage/backend-test-utils": ^0.1.28-next.3 + "@backstage/catalog-client": 1.1.0-next.2 + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/config": ^1.0.2-next.0 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/plugin-auth-node": ^0.2.5-next.3 + "@backstage/plugin-permission-common": ^0.6.4-next.2 + "@backstage/plugin-permission-node": ^0.6.5-next.3 + "@backstage/plugin-playlist-common": ^0.0.0 + "@types/express": "*" + "@types/supertest": ^2.0.8 + express: ^4.17.1 + express-promise-router: ^4.1.0 + knex: ^2.0.0 + msw: ^0.47.0 + node-fetch: ^2.6.7 + supertest: ^6.1.3 + uuid: ^8.2.0 + winston: ^3.2.1 + yn: ^4.0.0 + languageName: unknown + linkType: soft + +"@backstage/plugin-playlist-common@^0.0.0, @backstage/plugin-playlist-common@workspace:plugins/playlist-common": + version: 0.0.0-use.local + resolution: "@backstage/plugin-playlist-common@workspace:plugins/playlist-common" + dependencies: + "@backstage/cli": ^0.19.0-next.3 + "@backstage/plugin-permission-common": ^0.6.4-next.2 + languageName: unknown + linkType: soft + +"@backstage/plugin-playlist@^0.0.0, @backstage/plugin-playlist@workspace:plugins/playlist": + version: 0.0.0-use.local + resolution: "@backstage/plugin-playlist@workspace:plugins/playlist" + dependencies: + "@backstage/catalog-model": ^1.1.1-next.0 + "@backstage/cli": ^0.19.0-next.3 + "@backstage/core-app-api": ^1.1.0-next.3 + "@backstage/core-components": ^0.11.1-next.3 + "@backstage/core-plugin-api": ^1.0.6-next.3 + "@backstage/dev-utils": ^1.0.6-next.2 + "@backstage/errors": ^1.1.1-next.0 + "@backstage/plugin-catalog-common": ^1.0.6-next.0 + "@backstage/plugin-catalog-react": ^1.1.4-next.2 + "@backstage/plugin-permission-common": ^0.6.4-next.2 + "@backstage/plugin-permission-react": ^0.4.5-next.2 + "@backstage/plugin-playlist-common": ^0.0.0 + "@backstage/plugin-search-react": ^1.1.0-next.2 + "@backstage/test-utils": ^1.2.0-next.3 + "@backstage/theme": ^0.2.16 + "@material-ui/core": ^4.9.13 + "@material-ui/icons": ^4.9.1 + "@material-ui/lab": ^4.0.0-alpha.57 + "@testing-library/jest-dom": ^5.10.1 + "@testing-library/react": ^12.1.3 + "@testing-library/react-hooks": ^8.0.0 + "@testing-library/user-event": ^14.0.0 + "@types/node": "*" + cross-fetch: ^3.1.5 + lodash: ^4.17.21 + msw: ^0.47.0 + qs: ^6.9.4 + react-hook-form: ^7.13.0 + react-use: ^17.2.4 + swr: ^1.1.2 + peerDependencies: + react: ^16.13.1 || ^17.0.0 + react-router: 6.0.0-beta.0 || ^6.3.0 + react-router-dom: 6.0.0-beta.0 || ^6.3.0 + languageName: unknown + linkType: soft + "@backstage/plugin-proxy-backend@^0.2.30-next.2, @backstage/plugin-proxy-backend@workspace:plugins/proxy-backend": version: 0.0.0-use.local resolution: "@backstage/plugin-proxy-backend@workspace:plugins/proxy-backend" @@ -22470,6 +22549,7 @@ __metadata: "@backstage/plugin-org": ^0.5.9-next.3 "@backstage/plugin-pagerduty": 0.5.2-next.3 "@backstage/plugin-permission-react": ^0.4.5-next.2 + "@backstage/plugin-playlist": ^0.0.0 "@backstage/plugin-rollbar": ^0.4.9-next.3 "@backstage/plugin-scaffolder": ^1.6.0-next.3 "@backstage/plugin-search": ^1.0.2-next.3 @@ -22557,6 +22637,7 @@ __metadata: "@backstage/plugin-permission-backend": ^0.5.11-next.2 "@backstage/plugin-permission-common": ^0.6.4-next.2 "@backstage/plugin-permission-node": ^0.6.5-next.3 + "@backstage/plugin-playlist-backend": ^0.0.0 "@backstage/plugin-proxy-backend": ^0.2.30-next.2 "@backstage/plugin-rollbar-backend": ^0.1.33-next.3 "@backstage/plugin-scaffolder-backend": ^1.6.0-next.3 From 02a5296f859aa605a53b32d4b4c5a922740867a7 Mon Sep 17 00:00:00 2001 From: Phil Kuang Date: Fri, 16 Sep 2022 14:34:33 -0400 Subject: [PATCH 062/185] refactor(search-react): address review comment Signed-off-by: Phil Kuang --- plugins/search-react/package.json | 1 + .../SearchFilter.Autocomplete.tsx | 3 +- .../SearchFilter/SearchFilter.test.tsx | 16 ++---- .../components/SearchFilter/SearchFilter.tsx | 6 +-- .../src/context/SearchContext.test.tsx | 54 +++++++++++++++++++ .../src/context/SearchContext.tsx | 10 ++++ yarn.lock | 1 + 7 files changed, 73 insertions(+), 18 deletions(-) diff --git a/plugins/search-react/package.json b/plugins/search-react/package.json index 826d751353..8de637d46c 100644 --- a/plugins/search-react/package.json +++ b/plugins/search-react/package.json @@ -40,6 +40,7 @@ "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", + "lodash": "^4.17.21", "qs": "^6.9.4", "react-use": "^17.3.2" }, diff --git a/plugins/search-react/src/components/SearchFilter/SearchFilter.Autocomplete.tsx b/plugins/search-react/src/components/SearchFilter/SearchFilter.Autocomplete.tsx index c14dfdfa7e..35d1f376e5 100644 --- a/plugins/search-react/src/components/SearchFilter/SearchFilter.Autocomplete.tsx +++ b/plugins/search-react/src/components/SearchFilter/SearchFilter.Autocomplete.tsx @@ -62,7 +62,7 @@ export const AutocompleteFilter = (props: SearchAutocompleteFilterProps) => { defaultValues, valuesDebounceMs, ); - const { filters, setFilters, setPageCursor } = useSearch(); + const { filters, setFilters } = useSearch(); const filterValue = (filters[name] as string | string[] | undefined) || (multiple ? [] : null); @@ -79,7 +79,6 @@ export const AutocompleteFilter = (props: SearchAutocompleteFilterProps) => { } return { ...others }; }); - setPageCursor(undefined); }; // Provide the input field. diff --git a/plugins/search-react/src/components/SearchFilter/SearchFilter.test.tsx b/plugins/search-react/src/components/SearchFilter/SearchFilter.test.tsx index 27fbae237c..89a1818e8d 100644 --- a/plugins/search-react/src/components/SearchFilter/SearchFilter.test.tsx +++ b/plugins/search-react/src/components/SearchFilter/SearchFilter.test.tsx @@ -33,7 +33,6 @@ describe('SearchFilter', () => { term: '', filters: {}, types: [], - pageCursor: 'abc123', }; const label = 'Field'; @@ -139,10 +138,7 @@ describe('SearchFilter', () => { await userEvent.click(checkBox); await waitFor(() => { expect(query).toHaveBeenLastCalledWith( - expect.objectContaining({ - filters: { field: [values[0]] }, - pageCursor: undefined, - }), + expect.objectContaining({ filters: { field: [values[0]] } }), ); }); @@ -150,7 +146,7 @@ describe('SearchFilter', () => { await userEvent.click(checkBox); await waitFor(() => { expect(query).toHaveBeenLastCalledWith( - expect.objectContaining({ filters: {}, pageCursor: undefined }), + expect.objectContaining({ filters: {} }), ); }); }); @@ -174,7 +170,6 @@ describe('SearchFilter', () => { expect(query).toHaveBeenLastCalledWith( expect.objectContaining({ filters: { ...filters, field: [values[0]] }, - pageCursor: undefined, }), ); }); @@ -183,7 +178,7 @@ describe('SearchFilter', () => { await userEvent.click(checkBox); await waitFor(() => { expect(query).toHaveBeenLastCalledWith( - expect.objectContaining({ filters, pageCursor: undefined }), + expect.objectContaining({ filters }), ); }); }); @@ -342,7 +337,6 @@ describe('SearchFilter', () => { expect(query).toHaveBeenLastCalledWith( expect.objectContaining({ filters: { [name]: values[0] }, - pageCursor: undefined, }), ); }); @@ -359,7 +353,6 @@ describe('SearchFilter', () => { expect(query).toHaveBeenLastCalledWith( expect.objectContaining({ filters: {}, - pageCursor: undefined, }), ); }); @@ -395,7 +388,6 @@ describe('SearchFilter', () => { expect(query).toHaveBeenLastCalledWith( expect.objectContaining({ filters: { ...filters, [name]: values[0] }, - pageCursor: undefined, }), ); }); @@ -410,7 +402,7 @@ describe('SearchFilter', () => { await waitFor(() => { expect(query).toHaveBeenLastCalledWith( - expect.objectContaining({ filters, pageCursor: undefined }), + expect.objectContaining({ filters }), ); }); }); diff --git a/plugins/search-react/src/components/SearchFilter/SearchFilter.tsx b/plugins/search-react/src/components/SearchFilter/SearchFilter.tsx index 958caf0927..2a6d7baafa 100644 --- a/plugins/search-react/src/components/SearchFilter/SearchFilter.tsx +++ b/plugins/search-react/src/components/SearchFilter/SearchFilter.tsx @@ -82,7 +82,7 @@ export const CheckboxFilter = (props: SearchFilterComponentProps) => { valuesDebounceMs, } = props; const classes = useStyles(); - const { filters, setFilters, setPageCursor } = useSearch(); + const { filters, setFilters } = useSearch(); useDefaultFilterValue(name, defaultValue); const asyncValues = typeof givenValues === 'function' ? givenValues : undefined; @@ -106,7 +106,6 @@ export const CheckboxFilter = (props: SearchFilterComponentProps) => { const items = checked ? [...rest, value] : rest; return items.length ? { ...others, [name]: items } : others; }); - setPageCursor(undefined); }; return ( @@ -162,7 +161,7 @@ export const SelectFilter = (props: SearchFilterComponentProps) => { defaultValues, valuesDebounceMs, ); - const { filters, setFilters, setPageCursor } = useSearch(); + const { filters, setFilters } = useSearch(); const handleChange = (e: ChangeEvent<{ value: unknown }>) => { const { @@ -173,7 +172,6 @@ export const SelectFilter = (props: SearchFilterComponentProps) => { const { [name]: filter, ...others } = prevFilters; return value ? { ...others, [name]: value as string } : others; }); - setPageCursor(undefined); }; return ( diff --git a/plugins/search-react/src/context/SearchContext.test.tsx b/plugins/search-react/src/context/SearchContext.test.tsx index 68c79d3a5e..b5888fa8a9 100644 --- a/plugins/search-react/src/context/SearchContext.test.tsx +++ b/plugins/search-react/src/context/SearchContext.test.tsx @@ -160,6 +160,60 @@ describe('SearchContext', () => { expect(result.current.pageCursor).toBeUndefined(); }); + + it('When filters are cleared', async () => { + const { result, waitForNextUpdate } = renderHook(() => useSearch(), { + wrapper, + initialProps: { + initialState: { + ...initialState, + filters: { foo: 'bar' }, + term: 'first term', + pageCursor: 'SOMEPAGE', + }, + }, + }); + + await waitForNextUpdate(); + + expect(result.current.filters).toEqual({ foo: 'bar' }); + expect(result.current.pageCursor).toEqual('SOMEPAGE'); + + act(() => { + result.current.setFilters({}); + }); + + await waitForNextUpdate(); + + expect(result.current.pageCursor).toBeUndefined(); + }); + + it('When filters are set (and different from previous)', async () => { + const { result, waitForNextUpdate } = renderHook(() => useSearch(), { + wrapper, + initialProps: { + initialState: { + ...initialState, + filters: { foo: 'bar' }, + term: 'first term', + pageCursor: 'SOMEPAGE', + }, + }, + }); + + await waitForNextUpdate(); + + expect(result.current.filters).toEqual({ foo: 'bar' }); + expect(result.current.pageCursor).toEqual('SOMEPAGE'); + + act(() => { + result.current.setFilters({ foo: 'test' }); + }); + + await waitForNextUpdate(); + + expect(result.current.pageCursor).toBeUndefined(); + }); }); describe('Performs search (and sets results)', () => { diff --git a/plugins/search-react/src/context/SearchContext.tsx b/plugins/search-react/src/context/SearchContext.tsx index 7faa743c9d..6557f04c15 100644 --- a/plugins/search-react/src/context/SearchContext.tsx +++ b/plugins/search-react/src/context/SearchContext.tsx @@ -14,6 +14,7 @@ * limitations under the License. */ +import { isEqual } from 'lodash'; import React, { PropsWithChildren, useCallback, @@ -115,6 +116,7 @@ const useSearchContextValue = ( ); const prevTerm = usePrevious(term); + const prevFilters = usePrevious(filters); const result = useAsync( () => @@ -146,6 +148,14 @@ const useSearchContextValue = ( } }, [term, prevTerm, setPageCursor]); + useEffect(() => { + // Any time filters is reset, we want to start from page 0. + // Only reset the page if it has been modified by the user at least once, the initial state must not reset the page. + if (prevFilters !== undefined && !isEqual(filters, prevFilters)) { + setPageCursor(undefined); + } + }, [filters, prevFilters, setPageCursor]); + const value: SearchContextValue = { result, filters, diff --git a/yarn.lock b/yarn.lock index 02659263e8..659cc76d23 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6712,6 +6712,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/react-hooks": ^8.0.0 "@testing-library/user-event": ^14.0.0 + lodash: ^4.17.21 qs: ^6.9.4 react-use: ^17.3.2 peerDependencies: From 7c09eb1bb74d90513734c9757e0781aa38d590f4 Mon Sep 17 00:00:00 2001 From: blam Date: Fri, 16 Sep 2022 16:52:11 -0400 Subject: [PATCH 063/185] chore: what da font Signed-off-by: blam --- .../src/components/SearchResultPager/SearchResultPager.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/search-react/src/components/SearchResultPager/SearchResultPager.tsx b/plugins/search-react/src/components/SearchResultPager/SearchResultPager.tsx index 68f8223ca0..b4c834a678 100644 --- a/plugins/search-react/src/components/SearchResultPager/SearchResultPager.tsx +++ b/plugins/search-react/src/components/SearchResultPager/SearchResultPager.tsx @@ -43,7 +43,7 @@ export const SearchResultPager = () => { } return ( -