From 0f645a7947e42437349b35981c1f0d5636b2a485 Mon Sep 17 00:00:00 2001 From: mufaddal motiwala Date: Fri, 10 Dec 2021 02:47:21 +0530 Subject: [PATCH 01/39] add OwnedEntityPicker field Signed-off-by: mufaddal motiwala --- .changeset/perfect-buses-collect.md | 5 + .../OwnedEntityPicker.test.tsx | 137 ++++++++++++++++++ .../OwnedEntityPicker/OwnedEntityPicker.tsx | 86 +++++++++++ .../fields/OwnedEntityPicker/index.ts | 16 ++ .../scaffolder/src/components/fields/index.ts | 1 + plugins/scaffolder/src/extensions/default.ts | 5 + plugins/scaffolder/src/index.ts | 2 + plugins/scaffolder/src/plugin.ts | 8 + 8 files changed, 260 insertions(+) create mode 100644 .changeset/perfect-buses-collect.md create mode 100644 plugins/scaffolder/src/components/fields/OwnedEntityPicker/OwnedEntityPicker.test.tsx create mode 100644 plugins/scaffolder/src/components/fields/OwnedEntityPicker/OwnedEntityPicker.tsx create mode 100644 plugins/scaffolder/src/components/fields/OwnedEntityPicker/index.ts diff --git a/.changeset/perfect-buses-collect.md b/.changeset/perfect-buses-collect.md new file mode 100644 index 0000000000..cd7b8164cf --- /dev/null +++ b/.changeset/perfect-buses-collect.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': minor +--- + +Added OwnedEntityPicker field which displays Owned Entities in options diff --git a/plugins/scaffolder/src/components/fields/OwnedEntityPicker/OwnedEntityPicker.test.tsx b/plugins/scaffolder/src/components/fields/OwnedEntityPicker/OwnedEntityPicker.test.tsx new file mode 100644 index 0000000000..ef6fc1b648 --- /dev/null +++ b/plugins/scaffolder/src/components/fields/OwnedEntityPicker/OwnedEntityPicker.test.tsx @@ -0,0 +1,137 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { Entity } from '@backstage/catalog-model'; +import { CatalogApi, catalogApiRef } from '@backstage/plugin-catalog-react'; +import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; +import { FieldProps } from '@rjsf/core'; +import userEvent from '@testing-library/user-event'; +import React from 'react'; +import { OwnedEntityPicker } from './OwnedEntityPicker'; + +const makeEntity = (kind: string, namespace: string, name: string): Entity => ({ + apiVersion: 'backstage.io/v1beta1', + kind, + metadata: { namespace, name }, +}); + +describe('', () => { + let entities: Entity[]; + const onChange = jest.fn(); + const schema = {}; + const required = false; + let uiSchema: { + 'ui:options': { allowedKinds?: string[]; defaultKind?: string }; + }; + const rawErrors: string[] = []; + const formData = undefined; + + let props: FieldProps; + + const catalogApi: jest.Mocked = { + getLocationById: jest.fn(), + getEntityByName: jest.fn(), + getEntities: jest.fn(async () => ({ items: entities })), + addLocation: jest.fn(), + getLocationByEntity: jest.fn(), + removeEntityByUid: jest.fn(), + } as any; + let Wrapper: React.ComponentType; + + beforeEach(() => { + entities = [ + makeEntity('Group', 'default', 'team-a'), + makeEntity('Group', 'default', 'squad-b'), + ]; + + Wrapper = ({ children }: { children?: React.ReactNode }) => ( + + {children} + + ); + }); + + afterEach(() => jest.resetAllMocks()); + + describe('without allowedKinds', () => { + beforeEach(() => { + uiSchema = { 'ui:options': {} }; + props = { + onChange, + schema, + required, + uiSchema, + rawErrors, + formData, + } as unknown as FieldProps; + + catalogApi.getEntities.mockResolvedValue({ items: entities }); + }); + + it('searches for all entities', async () => { + await renderInTestApp( + + + , + ); + + expect(catalogApi.getEntities).toHaveBeenCalledWith(undefined); + }); + + it('updates even if there is not an exact match', async () => { + const { getByLabelText } = await renderInTestApp( + + + , + ); + const input = getByLabelText('Entity'); + + userEvent.type(input, 'squ'); + input.blur(); + + expect(onChange).toHaveBeenCalledWith('squ'); + }); + }); + + describe('with allowedKinds', () => { + beforeEach(() => { + uiSchema = { 'ui:options': { allowedKinds: ['User'] } }; + props = { + onChange, + schema, + required, + uiSchema, + rawErrors, + formData, + } as unknown as FieldProps; + + catalogApi.getEntities.mockResolvedValue({ items: entities }); + }); + + it('searches for users and groups', async () => { + await renderInTestApp( + + + , + ); + + expect(catalogApi.getEntities).toHaveBeenCalledWith({ + filter: { + kind: ['User'], + }, + }); + }); + }); +}); diff --git a/plugins/scaffolder/src/components/fields/OwnedEntityPicker/OwnedEntityPicker.tsx b/plugins/scaffolder/src/components/fields/OwnedEntityPicker/OwnedEntityPicker.tsx new file mode 100644 index 0000000000..b73158ac60 --- /dev/null +++ b/plugins/scaffolder/src/components/fields/OwnedEntityPicker/OwnedEntityPicker.tsx @@ -0,0 +1,86 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { useApi } from '@backstage/core-plugin-api'; +import { + catalogApiRef, + formatEntityRefTitle, + useEntityOwnership, +} from '@backstage/plugin-catalog-react'; +import { TextField } from '@material-ui/core'; +import FormControl from '@material-ui/core/FormControl'; +import Autocomplete from '@material-ui/lab/Autocomplete'; +import { FieldProps } from '@rjsf/core'; +import React from 'react'; +import { useAsync } from 'react-use'; + +export const OwnedEntityPicker = ({ + onChange, + schema: { title = 'Entity', description = 'An entity from the catalog' }, + required, + uiSchema, + rawErrors, + formData, + idSchema, +}: FieldProps) => { + const allowedKinds = uiSchema['ui:options']?.allowedKinds as string[]; + const defaultKind = uiSchema['ui:options']?.defaultKind as string | undefined; + const catalogApi = useApi(catalogApiRef); + const { isOwnedEntity } = useEntityOwnership(); + + const { value: entities, loading } = useAsync(() => + catalogApi.getEntities( + allowedKinds ? { filter: { kind: allowedKinds } } : undefined, + ), + ); + + const entityRefs = entities?.items + .map(e => + isOwnedEntity(e) ? formatEntityRefTitle(e, { defaultKind }) : null, + ) + .filter(n => n); + + const onSelect = (_: any, value: string | null) => { + onChange(value || ''); + }; + return ( + 0 && !formData} + > + ( + + )} + /> + + ); +}; diff --git a/plugins/scaffolder/src/components/fields/OwnedEntityPicker/index.ts b/plugins/scaffolder/src/components/fields/OwnedEntityPicker/index.ts new file mode 100644 index 0000000000..7cf5add6eb --- /dev/null +++ b/plugins/scaffolder/src/components/fields/OwnedEntityPicker/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export { OwnedEntityPicker } from './OwnedEntityPicker'; diff --git a/plugins/scaffolder/src/components/fields/index.ts b/plugins/scaffolder/src/components/fields/index.ts index 5adc3d3141..299470e220 100644 --- a/plugins/scaffolder/src/components/fields/index.ts +++ b/plugins/scaffolder/src/components/fields/index.ts @@ -18,3 +18,4 @@ export * from './EntityPicker'; export * from './OwnerPicker'; export * from './RepoUrlPicker'; export * from './TextValuePicker'; +export * from './OwnedEntityPicker'; diff --git a/plugins/scaffolder/src/extensions/default.ts b/plugins/scaffolder/src/extensions/default.ts index be934546b3..12a29809e0 100644 --- a/plugins/scaffolder/src/extensions/default.ts +++ b/plugins/scaffolder/src/extensions/default.ts @@ -24,6 +24,7 @@ import { RepoUrlPicker, } from '../components/fields/RepoUrlPicker'; import { FieldExtensionOptions } from './types'; +import { OwnedEntityPicker } from '../components/fields/OwnedEntityPicker'; export const DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS: FieldExtensionOptions[] = [ { @@ -44,4 +45,8 @@ export const DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS: FieldExtensionOptions[] = [ component: OwnerPicker, name: 'OwnerPicker', }, + { + component: OwnedEntityPicker, + name: 'OwnedEntityPicker', + }, ]; diff --git a/plugins/scaffolder/src/index.ts b/plugins/scaffolder/src/index.ts index 0180c24b90..dfbd2af296 100644 --- a/plugins/scaffolder/src/index.ts +++ b/plugins/scaffolder/src/index.ts @@ -31,6 +31,7 @@ export { EntityPickerFieldExtension, EntityNamePickerFieldExtension, OwnerPickerFieldExtension, + OwnedEntityPickerFieldExtension, RepoUrlPickerFieldExtension, ScaffolderPage, scaffolderPlugin as plugin, @@ -42,6 +43,7 @@ export { OwnerPicker, RepoUrlPicker, TextValuePicker, + OwnedEntityPicker, } from './components/fields'; export { FavouriteTemplate } from './components/FavouriteTemplate'; export { TemplateList } from './components/TemplateList'; diff --git a/plugins/scaffolder/src/plugin.ts b/plugins/scaffolder/src/plugin.ts index b6ef0ebe17..95cad50eba 100644 --- a/plugins/scaffolder/src/plugin.ts +++ b/plugins/scaffolder/src/plugin.ts @@ -35,6 +35,7 @@ import { discoveryApiRef, identityApiRef, } from '@backstage/core-plugin-api'; +import { OwnedEntityPicker } from './components/fields/OwnedEntityPicker'; export const scaffolderPlugin = createPlugin({ id: 'scaffolder', @@ -95,3 +96,10 @@ export const ScaffolderPage = scaffolderPlugin.provide( mountPoint: rootRouteRef, }), ); + +export const OwnedEntityPickerFieldExtension = scaffolderPlugin.provide( + createScaffolderFieldExtension({ + component: OwnedEntityPicker, + name: 'OwnedEntityPicker', + }), +); From 121787e87ebd37d6ed218bf129399cb6c7573366 Mon Sep 17 00:00:00 2001 From: mufaddal motiwala Date: Fri, 10 Dec 2021 15:47:07 +0530 Subject: [PATCH 02/39] added api report Signed-off-by: mufaddal motiwala --- plugins/scaffolder/api-report.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/plugins/scaffolder/api-report.md b/plugins/scaffolder/api-report.md index 73fd8fae72..45419e82eb 100644 --- a/plugins/scaffolder/api-report.md +++ b/plugins/scaffolder/api-report.md @@ -96,6 +96,24 @@ export type FieldExtensionOptions = { validation?: CustomFieldValidator; }; +// Warning: (ae-missing-release-tag) "OwnedEntityPicker" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const OwnedEntityPicker: ({ + onChange, + schema: { title, description }, + required, + uiSchema, + rawErrors, + formData, + idSchema, +}: FieldProps) => JSX.Element; + +// Warning: (ae-missing-release-tag) "OwnedEntityPickerFieldExtension" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const OwnedEntityPickerFieldExtension: () => null; + // Warning: (ae-missing-release-tag) "OwnerPicker" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) From 90fbd943deb1560bb9acff3c99aa217eecc0ef3c Mon Sep 17 00:00:00 2001 From: lukzerom Date: Sat, 11 Dec 2021 00:35:19 +0100 Subject: [PATCH 03/39] Basic select api changes and adjustments ready Signed-off-by: lukzerom --- .../src/components/Select/Select.tsx | 55 +++++++---- .../src/components/Select/index.tsx | 7 +- .../fields/RepoUrlPicker/RepoUrlPicker.tsx | 93 ++++++++++--------- 3 files changed, 96 insertions(+), 59 deletions(-) diff --git a/packages/core-components/src/components/Select/Select.tsx b/packages/core-components/src/components/Select/Select.tsx index a0e3aba94b..53a9a4800a 100644 --- a/packages/core-components/src/components/Select/Select.tsx +++ b/packages/core-components/src/components/Select/Select.tsx @@ -21,13 +21,13 @@ import FormControl from '@material-ui/core/FormControl'; import InputBase from '@material-ui/core/InputBase'; import MenuItem from '@material-ui/core/MenuItem'; import Select from '@material-ui/core/Select'; -import Typography from '@material-ui/core/Typography'; import { createStyles, makeStyles, Theme, withStyles, } from '@material-ui/core/styles'; +import Typography from '@material-ui/core/Typography'; import React, { useEffect, useState } from 'react'; import ClosedDropdown from './static/ClosedDropdown'; import OpenedDropdown from './static/OpenedDropdown'; @@ -92,7 +92,14 @@ const useStyles = makeStyles( chip: { margin: 2, }, + checkbox: {}, + select: { + '&:hover': { + cursor: 'not-allowed', + }, + }, + root: { display: 'flex', flexDirection: 'column', @@ -101,12 +108,12 @@ const useStyles = makeStyles( { name: 'BackstageSelect' }, ); -type Item = { +export type Item = { label: string; value: string | number; }; -type Selection = string | string[] | number | number[]; +export type Selection = string | string[] | number | number[]; export type SelectProps = { multiple?: boolean; @@ -116,6 +123,8 @@ export type SelectProps = { selected?: Selection; onChange: (arg: Selection) => void; triggerReset?: boolean; + native?: boolean; + disabled?: boolean; }; export function SelectComponent(props: SelectProps) { @@ -127,6 +136,8 @@ export function SelectComponent(props: SelectProps) { selected, onChange, triggerReset, + native = false, + disabled = false, } = props; const classes = useStyles(); const [value, setValue] = useState( @@ -150,6 +161,9 @@ export function SelectComponent(props: SelectProps) { }; const handleClick = (event: React.ChangeEvent) => { + // if (disabled) { + // return event.preventDefault(); + // } setOpen(previous => { if (multiple && !(event.target instanceof HTMLElement)) { return true; @@ -175,6 +189,8 @@ export function SelectComponent(props: SelectProps) { diff --git a/packages/core-components/src/components/Select/index.tsx b/packages/core-components/src/components/Select/index.tsx index 0f149f05b5..8c9ae28ac8 100644 --- a/packages/core-components/src/components/Select/index.tsx +++ b/packages/core-components/src/components/Select/index.tsx @@ -15,6 +15,11 @@ */ export { SelectComponent as Select } from './Select'; -export type { SelectClassKey, SelectInputBaseClassKey } from './Select'; +export type { + Item, + SelectClassKey, + SelectInputBaseClassKey, + Selection, +} from './Select'; export type { ClosedDropdownClassKey } from './static/ClosedDropdown'; export type { OpenedDropdownClassKey } from './static/OpenedDropdown'; diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx b/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx index c4b1e79262..42e24cc998 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx @@ -13,19 +13,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React, { useCallback, useEffect } from 'react'; -import { FieldProps } from '@rjsf/core'; -import { scaffolderApiRef } from '../../../api'; +import { Item, Progress, Select, Selection } from '@backstage/core-components'; +import { useApi } from '@backstage/core-plugin-api'; import { scmIntegrationsApiRef } from '@backstage/integration-react'; -import { useAsync } from 'react-use'; -import Select from '@material-ui/core/Select'; -import InputLabel from '@material-ui/core/InputLabel'; -import Input from '@material-ui/core/Input'; import FormControl from '@material-ui/core/FormControl'; import FormHelperText from '@material-ui/core/FormHelperText'; - -import { useApi } from '@backstage/core-plugin-api'; -import { Progress } from '@backstage/core-components'; +import Input from '@material-ui/core/Input'; +import InputLabel from '@material-ui/core/InputLabel'; +import { FieldProps } from '@rjsf/core'; +import React, { useCallback, useEffect } from 'react'; +import { useAsync } from 'react-use'; +import { scaffolderApiRef } from '../../../api'; function splitFormData(url: string | undefined, allowedOwners?: string[]) { let host = undefined; @@ -106,10 +104,10 @@ export const RepoUrlPicker = ({ allowedOwners, ); const updateHost = useCallback( - (evt: React.ChangeEvent<{ name?: string; value: unknown }>) => { + (value: Selection) => { onChange( serializeFormData({ - host: evt.target.value as string, + host: value as string, owner, repo, organization, @@ -121,6 +119,21 @@ export const RepoUrlPicker = ({ [onChange, owner, repo, organization, workspace, project], ); + const updateOwnerSelect = useCallback( + (value: Selection) => + onChange( + serializeFormData({ + host, + owner: value as string, + repo, + organization, + workspace, + project, + }), + ), + [onChange, host, repo, organization, workspace, project], + ); + const updateOwner = useCallback( (evt: React.ChangeEvent<{ name?: string; value: unknown }>) => onChange( @@ -224,6 +237,16 @@ export const RepoUrlPicker = ({ return ; } + const hostsOptions: Item[] = integrations + ? integrations + .filter(i => allowedHosts?.includes(i.host)) + .map(i => ({ label: i.title, value: i.host })) + : [{ label: 'Loading...', value: 'loading' }]; + + const ownersOptions: Item[] = allowedOwners + ? allowedOwners.map(i => ({ label: i, value: i })) + : [{ label: 'Loading...', value: 'loading' }]; + return ( <> 0 && !host} > - Host - + - {allowedOwners ? ( - allowedOwners.map(i => ( - - )) - ) : ( -

loading

- )} - ; - + label="Owner Available" + onChange={updateOwnerSelect} + disabled={ownersOptions.length === 1} + selected={owner} + items={ownersOptions} + /> + The organization, user or project that this repo will belong to From 919ffa9b539b7f295ccea4a1217027a2e9e9f1a8 Mon Sep 17 00:00:00 2001 From: lukzerom Date: Sat, 11 Dec 2021 00:36:46 +0100 Subject: [PATCH 04/39] click handler adjustment Signed-off-by: lukzerom --- packages/core-components/src/components/Select/Select.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/core-components/src/components/Select/Select.tsx b/packages/core-components/src/components/Select/Select.tsx index 53a9a4800a..02e45c8334 100644 --- a/packages/core-components/src/components/Select/Select.tsx +++ b/packages/core-components/src/components/Select/Select.tsx @@ -161,9 +161,10 @@ export function SelectComponent(props: SelectProps) { }; const handleClick = (event: React.ChangeEvent) => { - // if (disabled) { - // return event.preventDefault(); - // } + if (disabled) { + event.preventDefault(); + return; + } setOpen(previous => { if (multiple && !(event.target instanceof HTMLElement)) { return true; From 56a5466790e3b8d4cbe21e5ae861a23bcfa51d93 Mon Sep 17 00:00:00 2001 From: lukzerom Date: Sat, 11 Dec 2021 00:51:26 +0100 Subject: [PATCH 05/39] eslint adjustments Signed-off-by: lukzerom --- .../fields/EntityPicker/EntityPicker.tsx | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/plugins/scaffolder/src/components/fields/EntityPicker/EntityPicker.tsx b/plugins/scaffolder/src/components/fields/EntityPicker/EntityPicker.tsx index a8ef524a13..d491af1da4 100644 --- a/plugins/scaffolder/src/components/fields/EntityPicker/EntityPicker.tsx +++ b/plugins/scaffolder/src/components/fields/EntityPicker/EntityPicker.tsx @@ -22,7 +22,7 @@ import { TextField } from '@material-ui/core'; import FormControl from '@material-ui/core/FormControl'; import Autocomplete from '@material-ui/lab/Autocomplete'; import { FieldProps } from '@rjsf/core'; -import React from 'react'; +import React, { useCallback, useEffect } from 'react'; import { useAsync } from 'react-use'; export const EntityPicker = ({ @@ -48,9 +48,18 @@ export const EntityPicker = ({ formatEntityRefTitle(e, { defaultKind }), ); - const onSelect = (_: any, value: string | null) => { - onChange(value || ''); - }; + const onSelect = useCallback( + (_: any, value: string | null) => { + onChange(value || ''); + }, + [onChange], + ); + + useEffect(() => { + if (entityRefs?.length === 1) { + onSelect('', entityRefs[0]); + } + }, [entityRefs, onSelect]); return ( 0 && !formData} > Date: Sat, 11 Dec 2021 01:07:35 +0100 Subject: [PATCH 06/39] Select changeset Signed-off-by: lukzerom --- .changeset/curvy-walls-itch.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/curvy-walls-itch.md diff --git a/.changeset/curvy-walls-itch.md b/.changeset/curvy-walls-itch.md new file mode 100644 index 0000000000..18f35a6e24 --- /dev/null +++ b/.changeset/curvy-walls-itch.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-components': minor +--- + +Select component has extended API with few more props From 7b5d40c2410556378abddf20e1cae0f367174e82 Mon Sep 17 00:00:00 2001 From: lukzerom Date: Sat, 11 Dec 2021 01:12:24 +0100 Subject: [PATCH 07/39] changeset scaffolder Signed-off-by: lukzerom --- .changeset/beige-balloons-grin.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/beige-balloons-grin.md diff --git a/.changeset/beige-balloons-grin.md b/.changeset/beige-balloons-grin.md new file mode 100644 index 0000000000..9ce1e0b6b5 --- /dev/null +++ b/.changeset/beige-balloons-grin.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': minor +--- + +When user will have one option available in hostUrl or owner - autoselect and select component should be readonly From 625240c4baa57eea9e82f3b147139edad0a9712c Mon Sep 17 00:00:00 2001 From: lukzerom Date: Sat, 11 Dec 2021 01:14:13 +0100 Subject: [PATCH 08/39] clean Signed-off-by: lukzerom --- packages/core-components/src/components/Select/Select.tsx | 6 ------ 1 file changed, 6 deletions(-) diff --git a/packages/core-components/src/components/Select/Select.tsx b/packages/core-components/src/components/Select/Select.tsx index 02e45c8334..3b6582865c 100644 --- a/packages/core-components/src/components/Select/Select.tsx +++ b/packages/core-components/src/components/Select/Select.tsx @@ -92,13 +92,7 @@ const useStyles = makeStyles( chip: { margin: 2, }, - checkbox: {}, - select: { - '&:hover': { - cursor: 'not-allowed', - }, - }, root: { display: 'flex', From 846773cf453aaf3e4c947f7b9dd6d03792f6b807 Mon Sep 17 00:00:00 2001 From: lukzerom Date: Sun, 12 Dec 2021 13:13:55 +0100 Subject: [PATCH 09/39] added docs Signed-off-by: lukzerom --- packages/core-components/api-report.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/packages/core-components/api-report.md b/packages/core-components/api-report.md index d098403113..72d47b494c 100644 --- a/packages/core-components/api-report.md +++ b/packages/core-components/api-report.md @@ -528,6 +528,14 @@ export type InfoCardVariants = 'flex' | 'fullHeight' | 'gridItem'; // @public (undocumented) export function IntroCard(props: IntroCardProps): JSX.Element; +// Warning: (ae-missing-release-tag) "Item" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type Item = { + label: string; + value: string | number; +}; + // Warning: (tsdoc-malformed-html-name) Invalid HTML element: Expecting an HTML name // Warning: (tsdoc-escape-greater-than) The ">" character should be escaped using a backslash to avoid confusion with an HTML tag // Warning: (ae-forgotten-export) The symbol "ItemCardProps" needs to be exported by the entry point index.d.ts @@ -835,6 +843,12 @@ export type SelectClassKey = // @public (undocumented) export type SelectInputBaseClassKey = 'root' | 'input'; +// Warning: (ae-missing-release-tag) "Selection" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +type Selection_2 = string | string[] | number | number[]; +export { Selection_2 as Selection }; + // Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "Sidebar" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // From 45ddfa099b1d5c18ce20860eceda09116d3b14e0 Mon Sep 17 00:00:00 2001 From: lukzerom Date: Sun, 12 Dec 2021 13:16:13 +0100 Subject: [PATCH 10/39] added autoselect to vocab txt Signed-off-by: lukzerom --- .github/styles/vocab.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/styles/vocab.txt b/.github/styles/vocab.txt index 4ec62923d8..a1bc30d73a 100644 --- a/.github/styles/vocab.txt +++ b/.github/styles/vocab.txt @@ -12,6 +12,7 @@ Atlassian automations autoscaling Autoscaling +autoselect Avro backrub Bigtable From 88bd7ef966ede89bffde162343a886499b759f85 Mon Sep 17 00:00:00 2001 From: mufaddal motiwala Date: Mon, 13 Dec 2021 11:30:57 +0530 Subject: [PATCH 11/39] add a function for fetching user owned entities Signed-off-by: mufaddal motiwala --- .../OwnedEntityPicker/useOwnedEntities.ts | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 plugins/scaffolder/src/components/fields/OwnedEntityPicker/useOwnedEntities.ts diff --git a/plugins/scaffolder/src/components/fields/OwnedEntityPicker/useOwnedEntities.ts b/plugins/scaffolder/src/components/fields/OwnedEntityPicker/useOwnedEntities.ts new file mode 100644 index 0000000000..ecdfc5c90f --- /dev/null +++ b/plugins/scaffolder/src/components/fields/OwnedEntityPicker/useOwnedEntities.ts @@ -0,0 +1,60 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { + catalogApiRef, + loadCatalogOwnerRefs, + loadIdentityOwnerRefs, +} from '@backstage/plugin-catalog-react'; +import { identityApiRef, useApi } from '@backstage/core-plugin-api'; +import { Entity, RELATION_OWNED_BY } from '@backstage/catalog-model'; +import { CatalogListResponse } from '@backstage/catalog-client'; +import { useAsync } from 'react-use'; +import { useMemo } from 'react'; + +export function useOwnedEntities(allowedKinds?: string[]): { + loading: boolean; + ownedEntities: CatalogListResponse | undefined; +} { + const identityApi = useApi(identityApiRef); + const catalogApi = useApi(catalogApiRef); + + const { loading, value: refs } = useAsync(async () => { + const identityRefs = await loadIdentityOwnerRefs(identityApi); + const catalogRefs = await loadCatalogOwnerRefs(catalogApi, identityRefs); + const catalogs = await catalogApi.getEntities( + allowedKinds + ? { + filter: { + kind: allowedKinds, + [`relations.${RELATION_OWNED_BY}`]: + [...identityRefs, ...catalogRefs] || [], + }, + } + : { + filter: { + [`relations.${RELATION_OWNED_BY}`]: + [...identityRefs, ...catalogRefs] || [], + }, + }, + ); + return catalogs; + }, []); + const ownedEntities = useMemo(() => { + return refs; + }, [refs]); + + return useMemo(() => ({ loading, ownedEntities }), [loading, ownedEntities]); +} From c0154e444b1bd27ebe46e20d367101d5655aec57 Mon Sep 17 00:00:00 2001 From: mufaddal motiwala Date: Mon, 13 Dec 2021 11:31:23 +0530 Subject: [PATCH 12/39] change API for fetching user owned entities Signed-off-by: mufaddal motiwala --- .../OwnedEntityPicker/OwnedEntityPicker.tsx | 25 +++++-------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/plugins/scaffolder/src/components/fields/OwnedEntityPicker/OwnedEntityPicker.tsx b/plugins/scaffolder/src/components/fields/OwnedEntityPicker/OwnedEntityPicker.tsx index b73158ac60..06b637a79c 100644 --- a/plugins/scaffolder/src/components/fields/OwnedEntityPicker/OwnedEntityPicker.tsx +++ b/plugins/scaffolder/src/components/fields/OwnedEntityPicker/OwnedEntityPicker.tsx @@ -13,18 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { useApi } from '@backstage/core-plugin-api'; -import { - catalogApiRef, - formatEntityRefTitle, - useEntityOwnership, -} from '@backstage/plugin-catalog-react'; +import { formatEntityRefTitle } from '@backstage/plugin-catalog-react'; import { TextField } from '@material-ui/core'; import FormControl from '@material-ui/core/FormControl'; import Autocomplete from '@material-ui/lab/Autocomplete'; import { FieldProps } from '@rjsf/core'; import React from 'react'; -import { useAsync } from 'react-use'; +import { useOwnedEntities } from './useOwnedEntities'; export const OwnedEntityPicker = ({ onChange, @@ -37,24 +32,16 @@ export const OwnedEntityPicker = ({ }: FieldProps) => { const allowedKinds = uiSchema['ui:options']?.allowedKinds as string[]; const defaultKind = uiSchema['ui:options']?.defaultKind as string | undefined; - const catalogApi = useApi(catalogApiRef); - const { isOwnedEntity } = useEntityOwnership(); + const { ownedEntities, loading } = useOwnedEntities(allowedKinds); - const { value: entities, loading } = useAsync(() => - catalogApi.getEntities( - allowedKinds ? { filter: { kind: allowedKinds } } : undefined, - ), - ); - - const entityRefs = entities?.items - .map(e => - isOwnedEntity(e) ? formatEntityRefTitle(e, { defaultKind }) : null, - ) + const entityRefs = ownedEntities?.items + .map(e => formatEntityRefTitle(e, { defaultKind })) .filter(n => n); const onSelect = (_: any, value: string | null) => { onChange(value || ''); }; + return ( Date: Tue, 14 Dec 2021 11:43:03 +0000 Subject: [PATCH 13/39] add cronjobs to list of required permissions Signed-off-by: Brian Fletcher --- docs/features/kubernetes/configuration.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/features/kubernetes/configuration.md b/docs/features/kubernetes/configuration.md index 07a12f54a0..2c5aefe7c3 100644 --- a/docs/features/kubernetes/configuration.md +++ b/docs/features/kubernetes/configuration.md @@ -263,6 +263,7 @@ following objects: - replicasets - horizontalpodautoscalers - ingresses +- cronjobs ## Surfacing your Kubernetes components as part of an entity From faaa7f009cb0645a793452710972441e3811faf1 Mon Sep 17 00:00:00 2001 From: lukzerom Date: Tue, 14 Dec 2021 17:49:16 +0100 Subject: [PATCH 14/39] changed type name to select item Signed-off-by: lukzerom --- .../core-components/src/components/Select/Select.tsx | 4 ++-- .../core-components/src/components/Select/index.tsx | 2 +- .../components/fields/RepoUrlPicker/RepoUrlPicker.tsx | 11 ++++++++--- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/packages/core-components/src/components/Select/Select.tsx b/packages/core-components/src/components/Select/Select.tsx index 3b6582865c..b5a641acd4 100644 --- a/packages/core-components/src/components/Select/Select.tsx +++ b/packages/core-components/src/components/Select/Select.tsx @@ -102,7 +102,7 @@ const useStyles = makeStyles( { name: 'BackstageSelect' }, ); -export type Item = { +export type SelectItem = { label: string; value: string | number; }; @@ -111,7 +111,7 @@ export type Selection = string | string[] | number | number[]; export type SelectProps = { multiple?: boolean; - items: Item[]; + items: SelectItem[]; label: string; placeholder?: string; selected?: Selection; diff --git a/packages/core-components/src/components/Select/index.tsx b/packages/core-components/src/components/Select/index.tsx index 8c9ae28ac8..293d626ee6 100644 --- a/packages/core-components/src/components/Select/index.tsx +++ b/packages/core-components/src/components/Select/index.tsx @@ -16,10 +16,10 @@ export { SelectComponent as Select } from './Select'; export type { - Item, SelectClassKey, SelectInputBaseClassKey, Selection, + SelectItem, } from './Select'; export type { ClosedDropdownClassKey } from './static/ClosedDropdown'; export type { OpenedDropdownClassKey } from './static/OpenedDropdown'; diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx b/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx index 42e24cc998..e4d6f280f4 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx @@ -13,7 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { Item, Progress, Select, Selection } from '@backstage/core-components'; +import { + Progress, + Select, + Selection, + SelectItem, +} from '@backstage/core-components'; import { useApi } from '@backstage/core-plugin-api'; import { scmIntegrationsApiRef } from '@backstage/integration-react'; import FormControl from '@material-ui/core/FormControl'; @@ -237,13 +242,13 @@ export const RepoUrlPicker = ({ return ; } - const hostsOptions: Item[] = integrations + const hostsOptions: SelectItem[] = integrations ? integrations .filter(i => allowedHosts?.includes(i.host)) .map(i => ({ label: i.title, value: i.host })) : [{ label: 'Loading...', value: 'loading' }]; - const ownersOptions: Item[] = allowedOwners + const ownersOptions: SelectItem[] = allowedOwners ? allowedOwners.map(i => ({ label: i, value: i })) : [{ label: 'Loading...', value: 'loading' }]; From 31c0106a4e991f367637fba883897ce11168e902 Mon Sep 17 00:00:00 2001 From: lukzerom Date: Tue, 14 Dec 2021 17:51:02 +0100 Subject: [PATCH 15/39] on change instead of on select in entitypicker Signed-off-by: lukzerom --- .../src/components/fields/EntityPicker/EntityPicker.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/scaffolder/src/components/fields/EntityPicker/EntityPicker.tsx b/plugins/scaffolder/src/components/fields/EntityPicker/EntityPicker.tsx index d491af1da4..452a5d97b1 100644 --- a/plugins/scaffolder/src/components/fields/EntityPicker/EntityPicker.tsx +++ b/plugins/scaffolder/src/components/fields/EntityPicker/EntityPicker.tsx @@ -57,9 +57,9 @@ export const EntityPicker = ({ useEffect(() => { if (entityRefs?.length === 1) { - onSelect('', entityRefs[0]); + onChange(entityRefs[0]); } - }, [entityRefs, onSelect]); + }, [entityRefs, onChange]); return ( Date: Tue, 14 Dec 2021 18:09:02 +0100 Subject: [PATCH 16/39] Delete old changeset Signed-off-by: lukzerom --- .changeset/beige-balloons-grin.md | 5 ----- .changeset/curvy-walls-itch.md | 5 ----- 2 files changed, 10 deletions(-) delete mode 100644 .changeset/beige-balloons-grin.md delete mode 100644 .changeset/curvy-walls-itch.md diff --git a/.changeset/beige-balloons-grin.md b/.changeset/beige-balloons-grin.md deleted file mode 100644 index 9ce1e0b6b5..0000000000 --- a/.changeset/beige-balloons-grin.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder': minor ---- - -When user will have one option available in hostUrl or owner - autoselect and select component should be readonly diff --git a/.changeset/curvy-walls-itch.md b/.changeset/curvy-walls-itch.md deleted file mode 100644 index 18f35a6e24..0000000000 --- a/.changeset/curvy-walls-itch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-components': minor ---- - -Select component has extended API with few more props From 14d0bc908104c7a9396859257102dbe585731643 Mon Sep 17 00:00:00 2001 From: lukzerom Date: Tue, 14 Dec 2021 18:14:11 +0100 Subject: [PATCH 17/39] updated docs Signed-off-by: lukzerom --- packages/core-components/api-report.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/core-components/api-report.md b/packages/core-components/api-report.md index 72d47b494c..3a19dcba0d 100644 --- a/packages/core-components/api-report.md +++ b/packages/core-components/api-report.md @@ -528,14 +528,6 @@ export type InfoCardVariants = 'flex' | 'fullHeight' | 'gridItem'; // @public (undocumented) export function IntroCard(props: IntroCardProps): JSX.Element; -// Warning: (ae-missing-release-tag) "Item" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export type Item = { - label: string; - value: string | number; -}; - // Warning: (tsdoc-malformed-html-name) Invalid HTML element: Expecting an HTML name // Warning: (tsdoc-escape-greater-than) The ">" character should be escaped using a backslash to avoid confusion with an HTML tag // Warning: (ae-forgotten-export) The symbol "ItemCardProps" needs to be exported by the entry point index.d.ts @@ -849,6 +841,14 @@ export type SelectInputBaseClassKey = 'root' | 'input'; type Selection_2 = string | string[] | number | number[]; export { Selection_2 as Selection }; +// Warning: (ae-missing-release-tag) "SelectItem" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type SelectItem = { + label: string; + value: string | number; +}; + // Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "Sidebar" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // From b646a73fe048e81e21aa73c9d73ea96efa8b9032 Mon Sep 17 00:00:00 2001 From: lukzerom Date: Tue, 14 Dec 2021 18:22:52 +0100 Subject: [PATCH 18/39] changeset fix Signed-off-by: lukzerom --- .changeset/ten-candles-call.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .changeset/ten-candles-call.md diff --git a/.changeset/ten-candles-call.md b/.changeset/ten-candles-call.md new file mode 100644 index 0000000000..d14020b9c8 --- /dev/null +++ b/.changeset/ten-candles-call.md @@ -0,0 +1,9 @@ +--- +'@backstage/core-components': minor +'@backstage/plugin-scaffolder': minor +--- + +In @backstage/plugin-scaffolder - When user will have one option available in hostUrl or owner - autoselect and select component should be readonly. + +in @backstage/core-components - Select component has extended API with few more props: native : boolean, disabled: boolean. native - if set to true - Select component will use native browser select picker (not rendered by Material UI lib ). +disabled - if set to true - action on component will not be possible. From 3491a36ab9bf2248e60cf10ed2436bd003ae2c5a Mon Sep 17 00:00:00 2001 From: mufaddal motiwala Date: Tue, 14 Dec 2021 23:45:33 +0530 Subject: [PATCH 19/39] add useOwnedEntites to catalog-react Signed-off-by: mufaddal motiwala --- .changeset/eleven-baboons-sparkle.md | 5 +++++ plugins/catalog-react/api-report.md | 7 +++++++ plugins/catalog-react/src/hooks/index.ts | 1 + .../src/hooks}/useOwnedEntities.ts | 15 +++++++++++++-- .../OwnedEntityPicker/OwnedEntityPicker.tsx | 6 ++++-- 5 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 .changeset/eleven-baboons-sparkle.md rename plugins/{scaffolder/src/components/fields/OwnedEntityPicker => catalog-react/src/hooks}/useOwnedEntities.ts (82%) diff --git a/.changeset/eleven-baboons-sparkle.md b/.changeset/eleven-baboons-sparkle.md new file mode 100644 index 0000000000..7dba4792bc --- /dev/null +++ b/.changeset/eleven-baboons-sparkle.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-react': minor +--- + +added useOwnedEntities hook to get the list of entities of the logged-in user diff --git a/plugins/catalog-react/api-report.md b/plugins/catalog-react/api-report.md index c4aa254226..ef469e3b02 100644 --- a/plugins/catalog-react/api-report.md +++ b/plugins/catalog-react/api-report.md @@ -9,6 +9,7 @@ import { ApiRef } from '@backstage/core-plugin-api'; import { AsyncState } from 'react-use/lib/useAsync'; import { CATALOG_FILTER_EXISTS } from '@backstage/catalog-client'; import { CatalogApi } from '@backstage/catalog-client'; +import { CatalogListResponse } from '@backstage/catalog-client'; import { ComponentEntity } from '@backstage/catalog-model'; import { ComponentProps } from 'react'; import { Context } from 'react'; @@ -847,6 +848,12 @@ export function useEntityOwnership(): { // @public export function useEntityTypeFilter(): EntityTypeReturn; +// @public +export function useOwnedEntities(allowedKinds?: string[]): { + loading: boolean; + ownedEntities: CatalogListResponse | undefined; +}; + // Warning: (ae-missing-release-tag) "useOwnUser" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public diff --git a/plugins/catalog-react/src/hooks/index.ts b/plugins/catalog-react/src/hooks/index.ts index bbbca3a501..a6684732ce 100644 --- a/plugins/catalog-react/src/hooks/index.ts +++ b/plugins/catalog-react/src/hooks/index.ts @@ -42,3 +42,4 @@ export { useEntityOwnership, loadIdentityOwnerRefs, } from './useEntityOwnership'; +export { useOwnedEntities } from './useOwnedEntities'; diff --git a/plugins/scaffolder/src/components/fields/OwnedEntityPicker/useOwnedEntities.ts b/plugins/catalog-react/src/hooks/useOwnedEntities.ts similarity index 82% rename from plugins/scaffolder/src/components/fields/OwnedEntityPicker/useOwnedEntities.ts rename to plugins/catalog-react/src/hooks/useOwnedEntities.ts index ecdfc5c90f..f9191364cb 100644 --- a/plugins/scaffolder/src/components/fields/OwnedEntityPicker/useOwnedEntities.ts +++ b/plugins/catalog-react/src/hooks/useOwnedEntities.ts @@ -13,17 +13,27 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import { catalogApiRef } from './../api'; import { - catalogApiRef, loadCatalogOwnerRefs, loadIdentityOwnerRefs, -} from '@backstage/plugin-catalog-react'; +} from './useEntityOwnership'; import { identityApiRef, useApi } from '@backstage/core-plugin-api'; import { Entity, RELATION_OWNED_BY } from '@backstage/catalog-model'; import { CatalogListResponse } from '@backstage/catalog-client'; import { useAsync } from 'react-use'; import { useMemo } from 'react'; +/** + * Takes the relevant parts of the Backstage identity, and translates them into + * a list of entities which are owned by the user. Takes an optional parameter + * to filter the entities based on allowedKinds + * + * @public + * + * @param allowedKinds - Array of allowed kinds to filter the entities + * @returns CatalogListResponse + */ export function useOwnedEntities(allowedKinds?: string[]): { loading: boolean; ownedEntities: CatalogListResponse | undefined; @@ -52,6 +62,7 @@ export function useOwnedEntities(allowedKinds?: string[]): { ); return catalogs; }, []); + const ownedEntities = useMemo(() => { return refs; }, [refs]); diff --git a/plugins/scaffolder/src/components/fields/OwnedEntityPicker/OwnedEntityPicker.tsx b/plugins/scaffolder/src/components/fields/OwnedEntityPicker/OwnedEntityPicker.tsx index 06b637a79c..3c2fc2b495 100644 --- a/plugins/scaffolder/src/components/fields/OwnedEntityPicker/OwnedEntityPicker.tsx +++ b/plugins/scaffolder/src/components/fields/OwnedEntityPicker/OwnedEntityPicker.tsx @@ -13,13 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { formatEntityRefTitle } from '@backstage/plugin-catalog-react'; +import { + formatEntityRefTitle, + useOwnedEntities, +} from '@backstage/plugin-catalog-react'; import { TextField } from '@material-ui/core'; import FormControl from '@material-ui/core/FormControl'; import Autocomplete from '@material-ui/lab/Autocomplete'; import { FieldProps } from '@rjsf/core'; import React from 'react'; -import { useOwnedEntities } from './useOwnedEntities'; export const OwnedEntityPicker = ({ onChange, From 8ecfac35fda4aa9bec329230cf06bd056cf05ede Mon Sep 17 00:00:00 2001 From: lukzerom Date: Tue, 14 Dec 2021 23:37:16 +0100 Subject: [PATCH 20/39] patch instead of minor Signed-off-by: lukzerom --- .changeset/ten-candles-call.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.changeset/ten-candles-call.md b/.changeset/ten-candles-call.md index d14020b9c8..8907da06bd 100644 --- a/.changeset/ten-candles-call.md +++ b/.changeset/ten-candles-call.md @@ -1,6 +1,6 @@ --- -'@backstage/core-components': minor -'@backstage/plugin-scaffolder': minor +'@backstage/core-components': patch +'@backstage/plugin-scaffolder': patch --- In @backstage/plugin-scaffolder - When user will have one option available in hostUrl or owner - autoselect and select component should be readonly. From aec8c678c8b111955af200d5d4ba584101b7fbab Mon Sep 17 00:00:00 2001 From: lukzerom Date: Tue, 14 Dec 2021 23:40:30 +0100 Subject: [PATCH 21/39] selected items instead of selection Signed-off-by: lukzerom --- .../core-components/src/components/Select/Select.tsx | 12 ++++++------ .../core-components/src/components/Select/index.tsx | 2 +- .../fields/RepoUrlPicker/RepoUrlPicker.tsx | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/core-components/src/components/Select/Select.tsx b/packages/core-components/src/components/Select/Select.tsx index b5a641acd4..82be078cd0 100644 --- a/packages/core-components/src/components/Select/Select.tsx +++ b/packages/core-components/src/components/Select/Select.tsx @@ -107,15 +107,15 @@ export type SelectItem = { value: string | number; }; -export type Selection = string | string[] | number | number[]; +export type SelectedItems = string | string[] | number | number[]; export type SelectProps = { multiple?: boolean; items: SelectItem[]; label: string; placeholder?: string; - selected?: Selection; - onChange: (arg: Selection) => void; + selected?: SelectedItems; + onChange: (arg: SelectedItems) => void; triggerReset?: boolean; native?: boolean; disabled?: boolean; @@ -134,7 +134,7 @@ export function SelectComponent(props: SelectProps) { disabled = false, } = props; const classes = useStyles(); - const [value, setValue] = useState( + const [value, setValue] = useState( selected || (multiple ? [] : ''), ); const [isOpen, setOpen] = useState(false); @@ -150,8 +150,8 @@ export function SelectComponent(props: SelectProps) { }, [selected]); const handleChange = (event: React.ChangeEvent<{ value: unknown }>) => { - setValue(event.target.value as Selection); - onChange(event.target.value as Selection); + setValue(event.target.value as SelectedItems); + onChange(event.target.value as SelectedItems); }; const handleClick = (event: React.ChangeEvent) => { diff --git a/packages/core-components/src/components/Select/index.tsx b/packages/core-components/src/components/Select/index.tsx index 293d626ee6..870c2a0899 100644 --- a/packages/core-components/src/components/Select/index.tsx +++ b/packages/core-components/src/components/Select/index.tsx @@ -17,8 +17,8 @@ export { SelectComponent as Select } from './Select'; export type { SelectClassKey, + SelectedItems, SelectInputBaseClassKey, - Selection, SelectItem, } from './Select'; export type { ClosedDropdownClassKey } from './static/ClosedDropdown'; diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx b/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx index e4d6f280f4..92261b6cac 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx @@ -16,7 +16,7 @@ import { Progress, Select, - Selection, + SelectedItems, SelectItem, } from '@backstage/core-components'; import { useApi } from '@backstage/core-plugin-api'; @@ -109,7 +109,7 @@ export const RepoUrlPicker = ({ allowedOwners, ); const updateHost = useCallback( - (value: Selection) => { + (value: SelectedItems) => { onChange( serializeFormData({ host: value as string, @@ -125,7 +125,7 @@ export const RepoUrlPicker = ({ ); const updateOwnerSelect = useCallback( - (value: Selection) => + (value: SelectedItems) => onChange( serializeFormData({ host, From 2d244da5c49903c50b91a5e49bb168daf21c4fc9 Mon Sep 17 00:00:00 2001 From: lukzerom Date: Tue, 14 Dec 2021 23:59:22 +0100 Subject: [PATCH 22/39] public adnotation Signed-off-by: lukzerom --- packages/core-components/src/components/Select/Select.tsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/core-components/src/components/Select/Select.tsx b/packages/core-components/src/components/Select/Select.tsx index 82be078cd0..022df0a7ad 100644 --- a/packages/core-components/src/components/Select/Select.tsx +++ b/packages/core-components/src/components/Select/Select.tsx @@ -32,6 +32,7 @@ import React, { useEffect, useState } from 'react'; import ClosedDropdown from './static/ClosedDropdown'; import OpenedDropdown from './static/OpenedDropdown'; +/** @public */ export type SelectInputBaseClassKey = 'root' | 'input'; const BootstrapInput = withStyles( @@ -60,6 +61,7 @@ const BootstrapInput = withStyles( { name: 'BackstageSelectInputBase' }, )(InputBase); +/** @public */ export type SelectClassKey = | 'formControl' | 'label' @@ -102,11 +104,13 @@ const useStyles = makeStyles( { name: 'BackstageSelect' }, ); +/** @public */ export type SelectItem = { label: string; value: string | number; }; +/** @public */ export type SelectedItems = string | string[] | number | number[]; export type SelectProps = { @@ -121,6 +125,7 @@ export type SelectProps = { disabled?: boolean; }; +/** @public */ export function SelectComponent(props: SelectProps) { const { multiple, From b040d62e8e2b5bb8efe2634fe1c1bb42a4f928e0 Mon Sep 17 00:00:00 2001 From: lukzerom Date: Wed, 15 Dec 2021 00:03:42 +0100 Subject: [PATCH 23/39] docs update Signed-off-by: lukzerom --- packages/core-components/api-report.md | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/packages/core-components/api-report.md b/packages/core-components/api-report.md index 3a19dcba0d..086a0bc632 100644 --- a/packages/core-components/api-report.md +++ b/packages/core-components/api-report.md @@ -814,13 +814,10 @@ export type ResponseErrorPanelClassKey = 'text' | 'divider'; export function RoutedTabs(props: { routes: SubRoute_2[] }): JSX.Element; // Warning: (ae-forgotten-export) The symbol "SelectProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "SelectComponent" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export function Select(props: SelectProps): JSX.Element; -// Warning: (ae-missing-release-tag) "SelectClassKey" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type SelectClassKey = | 'formControl' @@ -830,19 +827,12 @@ export type SelectClassKey = | 'checkbox' | 'root'; -// Warning: (ae-missing-release-tag) "SelectInputBaseClassKey" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// +// @public (undocumented) +export type SelectedItems = string | string[] | number | number[]; + // @public (undocumented) export type SelectInputBaseClassKey = 'root' | 'input'; -// Warning: (ae-missing-release-tag) "Selection" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -type Selection_2 = string | string[] | number | number[]; -export { Selection_2 as Selection }; - -// Warning: (ae-missing-release-tag) "SelectItem" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type SelectItem = { label: string; From a6c72b0d2ce6b5a9964712d468ae40313db03670 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Wed, 15 Dec 2021 10:40:26 +0100 Subject: [PATCH 24/39] Label PRs Signed-off-by: Johan Haals --- .github/labeler.yml | 9 +++++++++ .github/workflows/label.yml | 12 ++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 .github/labeler.yml create mode 100644 .github/workflows/label.yml diff --git a/.github/labeler.yml b/.github/labeler.yml new file mode 100644 index 0000000000..c16064c841 --- /dev/null +++ b/.github/labeler.yml @@ -0,0 +1,9 @@ +catalog: + - plugins/catalog/**/* + - plugins/catalog-*/**/* +scaffolder: + - plugins/scaffolder/**/* + - plugins/scaffolder-*/**/* +search: + - plugins/search/**/* + - plugins/search-*/**/* diff --git a/.github/workflows/label.yml b/.github/workflows/label.yml new file mode 100644 index 0000000000..0e112f97ac --- /dev/null +++ b/.github/workflows/label.yml @@ -0,0 +1,12 @@ +name: "Pull Request Labeler" +on: +- pull_request_target + +jobs: + triage: + runs-on: ubuntu-latest + steps: + - uses: actions/labeler@v3 + with: + repo-token: "${{ secrets.GITHUB_TOKEN }}" + sync-labels: true From cb65389b4804e0b6402876c93308f350e0c30f84 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Wed, 15 Dec 2021 10:54:38 +0100 Subject: [PATCH 25/39] format Signed-off-by: Johan Haals --- .github/workflows/label.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/label.yml b/.github/workflows/label.yml index 0e112f97ac..dc7127ab0d 100644 --- a/.github/workflows/label.yml +++ b/.github/workflows/label.yml @@ -1,12 +1,12 @@ -name: "Pull Request Labeler" +name: 'Pull Request Labeler' on: -- pull_request_target + - pull_request_target jobs: triage: runs-on: ubuntu-latest steps: - - uses: actions/labeler@v3 - with: - repo-token: "${{ secrets.GITHUB_TOKEN }}" - sync-labels: true + - uses: actions/labeler@v3 + with: + repo-token: '${{ secrets.GITHUB_TOKEN }}' + sync-labels: true From cafdecfc2fb54889e105254884572af40eaf2ca0 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Wed, 15 Dec 2021 10:58:15 +0100 Subject: [PATCH 26/39] add packages/catalog Signed-off-by: Johan Haals --- .github/labeler.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/labeler.yml b/.github/labeler.yml index c16064c841..112f77e078 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -1,6 +1,7 @@ catalog: - plugins/catalog/**/* - plugins/catalog-*/**/* + - packages/catalog-*/**/* scaffolder: - plugins/scaffolder/**/* - plugins/scaffolder-*/**/* From 5ad82708fd1dd7b38ae8bc4b18a7792bc3d524df Mon Sep 17 00:00:00 2001 From: mufaddal motiwala Date: Wed, 15 Dec 2021 16:28:26 +0530 Subject: [PATCH 27/39] changed minor to patch Signed-off-by: mufaddal motiwala --- .changeset/eleven-baboons-sparkle.md | 2 +- .changeset/perfect-buses-collect.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.changeset/eleven-baboons-sparkle.md b/.changeset/eleven-baboons-sparkle.md index 7dba4792bc..e8c28af482 100644 --- a/.changeset/eleven-baboons-sparkle.md +++ b/.changeset/eleven-baboons-sparkle.md @@ -1,5 +1,5 @@ --- -'@backstage/plugin-catalog-react': minor +'@backstage/plugin-catalog-react': patch --- added useOwnedEntities hook to get the list of entities of the logged-in user diff --git a/.changeset/perfect-buses-collect.md b/.changeset/perfect-buses-collect.md index cd7b8164cf..e0df504087 100644 --- a/.changeset/perfect-buses-collect.md +++ b/.changeset/perfect-buses-collect.md @@ -1,5 +1,5 @@ --- -'@backstage/plugin-scaffolder': minor +'@backstage/plugin-scaffolder': patch --- Added OwnedEntityPicker field which displays Owned Entities in options From 8b3f624aa50ba01f61aa61ffa8a0bb4a2746ebab Mon Sep 17 00:00:00 2001 From: Brian Fletcher Date: Tue, 14 Dec 2021 11:59:02 +0000 Subject: [PATCH 28/39] adds cronjobs to vocab list Signed-off-by: Brian Fletcher --- .github/styles/vocab.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/styles/vocab.txt b/.github/styles/vocab.txt index 4ec62923d8..f4393b591b 100644 --- a/.github/styles/vocab.txt +++ b/.github/styles/vocab.txt @@ -53,6 +53,7 @@ configs const cookiecutter cron +cronjobs css Datadog dataflow From 62915c368856695a46cb2166ee3a79c7191be861 Mon Sep 17 00:00:00 2001 From: Brian Fletcher Date: Wed, 15 Dec 2021 13:25:12 +0000 Subject: [PATCH 29/39] add batch api group explanation Signed-off-by: Brian Fletcher --- docs/features/kubernetes/configuration.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/features/kubernetes/configuration.md b/docs/features/kubernetes/configuration.md index 2c5aefe7c3..32ab830322 100644 --- a/docs/features/kubernetes/configuration.md +++ b/docs/features/kubernetes/configuration.md @@ -263,6 +263,11 @@ following objects: - replicasets - horizontalpodautoscalers - ingresses + +The following RBAC permissions are required on the batch API group for the +following objects: + +- jobs - cronjobs ## Surfacing your Kubernetes components as part of an entity From 8d9ab4d7c1da0a8ea123fbdc92fe8fc74340cc57 Mon Sep 17 00:00:00 2001 From: mufaddal motiwala Date: Wed, 15 Dec 2021 20:44:53 +0530 Subject: [PATCH 30/39] removed test case Signed-off-by: mufaddal motiwala --- .../OwnedEntityPicker.test.tsx | 137 ------------------ 1 file changed, 137 deletions(-) delete mode 100644 plugins/scaffolder/src/components/fields/OwnedEntityPicker/OwnedEntityPicker.test.tsx diff --git a/plugins/scaffolder/src/components/fields/OwnedEntityPicker/OwnedEntityPicker.test.tsx b/plugins/scaffolder/src/components/fields/OwnedEntityPicker/OwnedEntityPicker.test.tsx deleted file mode 100644 index ef6fc1b648..0000000000 --- a/plugins/scaffolder/src/components/fields/OwnedEntityPicker/OwnedEntityPicker.test.tsx +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright 2021 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { Entity } from '@backstage/catalog-model'; -import { CatalogApi, catalogApiRef } from '@backstage/plugin-catalog-react'; -import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; -import { FieldProps } from '@rjsf/core'; -import userEvent from '@testing-library/user-event'; -import React from 'react'; -import { OwnedEntityPicker } from './OwnedEntityPicker'; - -const makeEntity = (kind: string, namespace: string, name: string): Entity => ({ - apiVersion: 'backstage.io/v1beta1', - kind, - metadata: { namespace, name }, -}); - -describe('', () => { - let entities: Entity[]; - const onChange = jest.fn(); - const schema = {}; - const required = false; - let uiSchema: { - 'ui:options': { allowedKinds?: string[]; defaultKind?: string }; - }; - const rawErrors: string[] = []; - const formData = undefined; - - let props: FieldProps; - - const catalogApi: jest.Mocked = { - getLocationById: jest.fn(), - getEntityByName: jest.fn(), - getEntities: jest.fn(async () => ({ items: entities })), - addLocation: jest.fn(), - getLocationByEntity: jest.fn(), - removeEntityByUid: jest.fn(), - } as any; - let Wrapper: React.ComponentType; - - beforeEach(() => { - entities = [ - makeEntity('Group', 'default', 'team-a'), - makeEntity('Group', 'default', 'squad-b'), - ]; - - Wrapper = ({ children }: { children?: React.ReactNode }) => ( - - {children} - - ); - }); - - afterEach(() => jest.resetAllMocks()); - - describe('without allowedKinds', () => { - beforeEach(() => { - uiSchema = { 'ui:options': {} }; - props = { - onChange, - schema, - required, - uiSchema, - rawErrors, - formData, - } as unknown as FieldProps; - - catalogApi.getEntities.mockResolvedValue({ items: entities }); - }); - - it('searches for all entities', async () => { - await renderInTestApp( - - - , - ); - - expect(catalogApi.getEntities).toHaveBeenCalledWith(undefined); - }); - - it('updates even if there is not an exact match', async () => { - const { getByLabelText } = await renderInTestApp( - - - , - ); - const input = getByLabelText('Entity'); - - userEvent.type(input, 'squ'); - input.blur(); - - expect(onChange).toHaveBeenCalledWith('squ'); - }); - }); - - describe('with allowedKinds', () => { - beforeEach(() => { - uiSchema = { 'ui:options': { allowedKinds: ['User'] } }; - props = { - onChange, - schema, - required, - uiSchema, - rawErrors, - formData, - } as unknown as FieldProps; - - catalogApi.getEntities.mockResolvedValue({ items: entities }); - }); - - it('searches for users and groups', async () => { - await renderInTestApp( - - - , - ); - - expect(catalogApi.getEntities).toHaveBeenCalledWith({ - filter: { - kind: ['User'], - }, - }); - }); - }); -}); From 18d4f500afdf49c39afb62bfc0e3b038894c5253 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 15 Dec 2021 14:25:44 +0100 Subject: [PATCH 31/39] core-plugin-api: mark AnalyticsApi as experimental MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Signed-off-by: Patrik Oldsberg --- .changeset/cool-cows-report.md | 5 ++++ packages/core-plugin-api/api-report.md | 25 ++++++++++--------- .../src/analytics/AnalyticsContext.tsx | 2 +- .../core-plugin-api/src/analytics/types.ts | 10 +++++--- .../src/analytics/useAnalytics.tsx | 2 +- .../src/apis/definitions/AnalyticsApi.ts | 14 +++++++---- 6 files changed, 35 insertions(+), 23 deletions(-) create mode 100644 .changeset/cool-cows-report.md diff --git a/.changeset/cool-cows-report.md b/.changeset/cool-cows-report.md new file mode 100644 index 0000000000..2b183e39c2 --- /dev/null +++ b/.changeset/cool-cows-report.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-plugin-api': patch +--- + +Deprecated the `AnyAnalyticsContext` type and mark the `AnalyticsApi` experimental. diff --git a/packages/core-plugin-api/api-report.md b/packages/core-plugin-api/api-report.md index 9fd4f57ae9..8403a06b6f 100644 --- a/packages/core-plugin-api/api-report.md +++ b/packages/core-plugin-api/api-report.md @@ -35,25 +35,26 @@ export type AlertMessage = { severity?: 'success' | 'info' | 'warning' | 'error'; }; -// @public +// @alpha export type AnalyticsApi = { captureEvent(event: AnalyticsEvent): void; }; -// @public +// @alpha export const analyticsApiRef: ApiRef; -// @public +// @alpha export const AnalyticsContext: (options: { attributes: Partial; children: ReactNode; }) => JSX.Element; -// @public -export type AnalyticsContextValue = CommonAnalyticsContext & - AnyAnalyticsContext; +// @alpha +export type AnalyticsContextValue = CommonAnalyticsContext & { + [param in string]: string | boolean | number | undefined; +}; -// @public +// @alpha export type AnalyticsEvent = { action: string; subject: string; @@ -62,12 +63,12 @@ export type AnalyticsEvent = { context: AnalyticsContextValue; }; -// @public +// @alpha export type AnalyticsEventAttributes = { [attribute in string]: string | boolean | number; }; -// @public +// @alpha export type AnalyticsTracker = { captureEvent: ( action: string, @@ -79,7 +80,7 @@ export type AnalyticsTracker = { ) => void; }; -// @public +// @public @deprecated export type AnyAnalyticsContext = { [param in string]: string | boolean | number | undefined; }; @@ -282,7 +283,7 @@ export type BootErrorPageProps = { error: Error; }; -// @public +// @alpha export type CommonAnalyticsContext = { pluginId: string; routeRef: string; @@ -820,7 +821,7 @@ export type TypesToApiRefs = { [key in keyof T]: ApiRef; }; -// @public +// @alpha export function useAnalytics(): AnalyticsTracker; // @public diff --git a/packages/core-plugin-api/src/analytics/AnalyticsContext.tsx b/packages/core-plugin-api/src/analytics/AnalyticsContext.tsx index 075cdff3ff..af362cd921 100644 --- a/packages/core-plugin-api/src/analytics/AnalyticsContext.tsx +++ b/packages/core-plugin-api/src/analytics/AnalyticsContext.tsx @@ -60,7 +60,7 @@ export const useAnalyticsContext = (): AnalyticsContextValue => { * Analytics contexts are additive, meaning the context ultimately emitted with * an event is the combination of all contexts in the parent tree. * - * @public + * @alpha */ export const AnalyticsContext = (options: { attributes: Partial; diff --git a/packages/core-plugin-api/src/analytics/types.ts b/packages/core-plugin-api/src/analytics/types.ts index d001c38d3e..431e453a61 100644 --- a/packages/core-plugin-api/src/analytics/types.ts +++ b/packages/core-plugin-api/src/analytics/types.ts @@ -17,7 +17,7 @@ /** * Common analytics context attributes. * - * @public + * @alpha */ export type CommonAnalyticsContext = { /** @@ -40,6 +40,7 @@ export type CommonAnalyticsContext = { * Allows arbitrary scalar values as context attributes too. * * @public + * @deprecated Will be removed, use `AnalyticsContextValue` instead */ export type AnyAnalyticsContext = { [param in string]: string | boolean | number | undefined; @@ -48,7 +49,8 @@ export type AnyAnalyticsContext = { /** * Analytics context envelope. * - * @public + * @alpha */ -export type AnalyticsContextValue = CommonAnalyticsContext & - AnyAnalyticsContext; +export type AnalyticsContextValue = CommonAnalyticsContext & { + [param in string]: string | boolean | number | undefined; +}; diff --git a/packages/core-plugin-api/src/analytics/useAnalytics.tsx b/packages/core-plugin-api/src/analytics/useAnalytics.tsx index 5a047e5a63..f1297c5e4e 100644 --- a/packages/core-plugin-api/src/analytics/useAnalytics.tsx +++ b/packages/core-plugin-api/src/analytics/useAnalytics.tsx @@ -35,7 +35,7 @@ function useAnalyticsApi(): AnalyticsApi { /** * Gets a pre-configured analytics tracker. * - * @public + * @alpha */ export function useAnalytics(): AnalyticsTracker { const trackerRef = useRef(null); diff --git a/packages/core-plugin-api/src/apis/definitions/AnalyticsApi.ts b/packages/core-plugin-api/src/apis/definitions/AnalyticsApi.ts index ef190d6c21..dc38d7a250 100644 --- a/packages/core-plugin-api/src/apis/definitions/AnalyticsApi.ts +++ b/packages/core-plugin-api/src/apis/definitions/AnalyticsApi.ts @@ -21,7 +21,7 @@ import { AnalyticsContextValue } from '../../analytics/types'; * Represents an event worth tracking in an analytics system that could inform * how users of a Backstage instance are using its features. * - * @public + * @alpha */ export type AnalyticsEvent = { /** @@ -79,7 +79,7 @@ export type AnalyticsEvent = { * A structure allowing other arbitrary metadata to be provided by analytics * event emitters. * - * @public + * @alpha */ export type AnalyticsEventAttributes = { [attribute in string]: string | boolean | number; @@ -89,7 +89,7 @@ export type AnalyticsEventAttributes = { * Represents a tracker with methods that can be called to track events in a * configured analytics service. * - * @public + * @alpha */ export type AnalyticsTracker = { captureEvent: ( @@ -103,6 +103,8 @@ export type AnalyticsTracker = { }; /** + * **EXPERIMENTAL** + * * The Analytics API is used to track user behavior in a Backstage instance. * * @remarks @@ -111,7 +113,7 @@ export type AnalyticsTracker = { * useAnalytics() hook. This will return a pre-configured AnalyticsTracker * with relevant methods for instrumentation. * - * @public + * @alpha */ export type AnalyticsApi = { /** @@ -122,9 +124,11 @@ export type AnalyticsApi = { }; /** + * **EXPERIMENTAL** + * * The {@link ApiRef} of {@link AnalyticsApi}. * - * @public + * @alpha */ export const analyticsApiRef: ApiRef = createApiRef({ id: 'core.analytics', From 68b2a31a0531f11c43e4db8a2de28bebd4ae399d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlio=20Zynger?= Date: Wed, 15 Dec 2021 17:12:26 +0100 Subject: [PATCH 32/39] Update Airflow plugin README Airflow v1 exposed an experimental API [that got dropped](https://airflow.apache.org/docs/apache-airflow/stable/deprecated-rest-api-ref.html) later on. Let's add a note to the README making explicit users of Airflow v1 won't be able to integrate with this plugin unless they update. Signed-off-by: Julio Zynger --- plugins/apache-airflow/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/apache-airflow/README.md b/plugins/apache-airflow/README.md index c57ab9da43..bdbb1b981f 100644 --- a/plugins/apache-airflow/README.md +++ b/plugins/apache-airflow/README.md @@ -2,6 +2,9 @@ Welcome to the apache-airflow plugin! +This plugin serves as frontend to the REST API exposed by Apache Airflow. +Note only [Airflow v2 (and later)](https://airflow.apache.org/docs/apache-airflow/stable/deprecated-rest-api-ref.html) integrate with the plugin. + ## Feature Requests & Ideas - [ ] Add support for running multiple instances of Airflow for monitoring From 7927005152203ac15b48645a9ca84536fe20ad58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Wed, 7 Jul 2021 17:10:36 +0200 Subject: [PATCH 33/39] Add `fetchApiRef` which implements fetch, plus Backstage token header when available. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This intends to be the basis for other plugins' data fetching needs, so that they can transparently interact with the catalog and other parts of the Backstage ecosystem without explicitly having to deal with authenticating themselves. Signed-off-by: Fredrik Adelöw --- .changeset/blue-queens-sniff.md | 7 ++ .changeset/lovely-drinks-kiss.md | 5 ++ packages/app-defaults/src/defaults/apis.ts | 23 +++++ packages/catalog-client/api-report.md | 8 +- packages/catalog-client/src/CatalogClient.ts | 17 ++-- .../catalog-client/src/types/discovery.ts | 2 +- packages/catalog-client/src/types/fetch.ts | 26 ++++++ packages/catalog-client/src/types/index.ts | 1 + packages/core-app-api/api-report.md | 35 ++++++++ packages/core-app-api/package.json | 1 + ...ageProtocolResolverFetchMiddleware.test.ts | 86 +++++++++++++++++++ ...ackstageProtocolResolverFetchMiddleware.ts | 64 ++++++++++++++ .../FetchApi/FetchApiBuilder.ts | 55 ++++++++++++ .../IdentityAwareFetchMiddleware.test.ts | 43 ++++++++++ .../FetchApi/IdentityAwareFetchMiddleware.ts | 59 +++++++++++++ .../apis/implementations/FetchApi/index.ts | 20 +++++ .../apis/implementations/FetchApi/types.ts | 39 +++++++++ .../src/apis/implementations/index.ts | 1 + packages/core-plugin-api/api-report.md | 9 ++ packages/core-plugin-api/package.json | 2 +- .../src/apis/definitions/FetchApi.ts | 38 ++++++++ .../src/apis/definitions/index.ts | 1 + 22 files changed, 532 insertions(+), 10 deletions(-) create mode 100644 .changeset/blue-queens-sniff.md create mode 100644 .changeset/lovely-drinks-kiss.md create mode 100644 packages/catalog-client/src/types/fetch.ts create mode 100644 packages/core-app-api/src/apis/implementations/FetchApi/BackstageProtocolResolverFetchMiddleware.test.ts create mode 100644 packages/core-app-api/src/apis/implementations/FetchApi/BackstageProtocolResolverFetchMiddleware.ts create mode 100644 packages/core-app-api/src/apis/implementations/FetchApi/FetchApiBuilder.ts create mode 100644 packages/core-app-api/src/apis/implementations/FetchApi/IdentityAwareFetchMiddleware.test.ts create mode 100644 packages/core-app-api/src/apis/implementations/FetchApi/IdentityAwareFetchMiddleware.ts create mode 100644 packages/core-app-api/src/apis/implementations/FetchApi/index.ts create mode 100644 packages/core-app-api/src/apis/implementations/FetchApi/types.ts create mode 100644 packages/core-plugin-api/src/apis/definitions/FetchApi.ts diff --git a/.changeset/blue-queens-sniff.md b/.changeset/blue-queens-sniff.md new file mode 100644 index 0000000000..9a26507f92 --- /dev/null +++ b/.changeset/blue-queens-sniff.md @@ -0,0 +1,7 @@ +--- +'@backstage/app-defaults': patch +'@backstage/core-app-api': patch +'@backstage/core-plugin-api': patch +--- + +Add `FetchApi` and related `fetchApiRef` which implement fetch, with an added Backstage token header when available. diff --git a/.changeset/lovely-drinks-kiss.md b/.changeset/lovely-drinks-kiss.md new file mode 100644 index 0000000000..f343888920 --- /dev/null +++ b/.changeset/lovely-drinks-kiss.md @@ -0,0 +1,5 @@ +--- +'@backstage/catalog-client': patch +--- + +Add the ability to supply a custom `fetchApi`. In the default frontend app setup, this will use the `fetchApiRef` implementation. diff --git a/packages/app-defaults/src/defaults/apis.ts b/packages/app-defaults/src/defaults/apis.ts index d3c76d52bd..06562caaef 100644 --- a/packages/app-defaults/src/defaults/apis.ts +++ b/packages/app-defaults/src/defaults/apis.ts @@ -34,6 +34,9 @@ import { OneLoginAuth, UnhandledErrorForwarder, AtlassianAuth, + FetchApiBuilder, + IdentityAwareFetchMiddleware, + BackstageProtocolResolverFetchMiddleware, } from '@backstage/core-app-api'; import { @@ -42,6 +45,8 @@ import { analyticsApiRef, errorApiRef, discoveryApiRef, + fetchApiRef, + identityApiRef, oauthRequestApiRef, googleAuthApiRef, githubAuthApiRef, @@ -92,6 +97,24 @@ export const apis = [ deps: { errorApi: errorApiRef }, factory: ({ errorApi }) => WebStorage.create({ errorApi }), }), + createApiFactory({ + api: fetchApiRef, + deps: { identityApi: identityApiRef, discoveryApi: discoveryApiRef }, + factory: ({ identityApi, discoveryApi }) => { + return FetchApiBuilder.create() + .with( + new IdentityAwareFetchMiddleware(() => { + return identityApi.getCredentials().then(r => r.token); + }), + ) + .with( + new BackstageProtocolResolverFetchMiddleware(plugin => { + return discoveryApi.getBaseUrl(plugin); + }), + ) + .build(); + }, + }), createApiFactory({ api: oauthRequestApiRef, deps: {}, diff --git a/packages/catalog-client/api-report.md b/packages/catalog-client/api-report.md index e16ca740f6..41aea63716 100644 --- a/packages/catalog-client/api-report.md +++ b/packages/catalog-client/api-report.md @@ -5,6 +5,7 @@ ```ts import { Entity } from '@backstage/catalog-model'; import { EntityName } from '@backstage/catalog-model'; +import { default as fetch_2 } from 'cross-fetch'; import { Location as Location_2 } from '@backstage/catalog-model'; // @public @@ -71,7 +72,7 @@ export interface CatalogApi { // @public export class CatalogClient implements CatalogApi { - constructor(options: { discoveryApi: DiscoveryApi }); + constructor(options: { discoveryApi: DiscoveryApi; fetchApi?: FetchApi }); addLocation( { type, target, dryRun, presence }: AddLocationRequest, options?: CatalogRequestOptions, @@ -155,4 +156,9 @@ export type DiscoveryApi = { // @public export const ENTITY_STATUS_CATALOG_PROCESSING_TYPE = 'backstage.io/catalog-processing'; + +// @public +export type FetchApi = { + fetch: typeof fetch_2; +}; ``` diff --git a/packages/catalog-client/src/CatalogClient.ts b/packages/catalog-client/src/CatalogClient.ts index 29d01fbe5c..047a8c7cce 100644 --- a/packages/catalog-client/src/CatalogClient.ts +++ b/packages/catalog-client/src/CatalogClient.ts @@ -25,7 +25,7 @@ import { stringifyLocationReference, } from '@backstage/catalog-model'; import { ResponseError } from '@backstage/errors'; -import fetch from 'cross-fetch'; +import crossFetch from 'cross-fetch'; import { CATALOG_FILTER_EXISTS, AddLocationRequest, @@ -38,6 +38,7 @@ import { CatalogEntityAncestorsResponse, } from './types/api'; import { DiscoveryApi } from './types/discovery'; +import { FetchApi } from './types/fetch'; /** * A frontend and backend compatible client for communicating with the Backstage Catalog. @@ -46,9 +47,11 @@ import { DiscoveryApi } from './types/discovery'; * */ export class CatalogClient implements CatalogApi { private readonly discoveryApi: DiscoveryApi; + private readonly fetchApi: FetchApi; - constructor(options: { discoveryApi: DiscoveryApi }) { + constructor(options: { discoveryApi: DiscoveryApi; fetchApi?: FetchApi }) { this.discoveryApi = options.discoveryApi; + this.fetchApi = options.fetchApi || { fetch: crossFetch }; } /** @@ -206,7 +209,7 @@ export class CatalogClient implements CatalogApi { * @public */ async refreshEntity(entityRef: string, options?: CatalogRequestOptions) { - const response = await fetch( + const response = await this.fetchApi.fetch( `${await this.discoveryApi.getBaseUrl('catalog')}/refresh`, { headers: { @@ -237,7 +240,7 @@ export class CatalogClient implements CatalogApi { { type = 'url', target, dryRun, presence }: AddLocationRequest, options?: CatalogRequestOptions, ): Promise { - const response = await fetch( + const response = await this.fetchApi.fetch( `${await this.discoveryApi.getBaseUrl('catalog')}/locations${ dryRun ? '?dryRun=true' : '' }`, @@ -376,7 +379,7 @@ export class CatalogClient implements CatalogApi { const headers: Record = options?.token ? { Authorization: `Bearer ${options.token}` } : {}; - const response = await fetch(url, { method, headers }); + const response = await this.fetchApi.fetch(url, { method, headers }); if (!response.ok) { throw await ResponseError.fromResponse(response); @@ -392,7 +395,7 @@ export class CatalogClient implements CatalogApi { const headers: Record = options?.token ? { Authorization: `Bearer ${options.token}` } : {}; - const response = await fetch(url, { method, headers }); + const response = await this.fetchApi.fetch(url, { method, headers }); if (!response.ok) { throw await ResponseError.fromResponse(response); @@ -410,7 +413,7 @@ export class CatalogClient implements CatalogApi { const headers: Record = options?.token ? { Authorization: `Bearer ${options.token}` } : {}; - const response = await fetch(url, { method, headers }); + const response = await this.fetchApi.fetch(url, { method, headers }); if (!response.ok) { if (response.status === 404) { diff --git a/packages/catalog-client/src/types/discovery.ts b/packages/catalog-client/src/types/discovery.ts index 19ee5ed19c..5fa14372e3 100644 --- a/packages/catalog-client/src/types/discovery.ts +++ b/packages/catalog-client/src/types/discovery.ts @@ -15,7 +15,7 @@ */ /** - * This is a copy of the core DiscoveryApi, to avoid importing core. + * This is a copy of the DiscoveryApi, to avoid importing core-plugin-api. * * @public */ diff --git a/packages/catalog-client/src/types/fetch.ts b/packages/catalog-client/src/types/fetch.ts new file mode 100644 index 0000000000..cdddd31810 --- /dev/null +++ b/packages/catalog-client/src/types/fetch.ts @@ -0,0 +1,26 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import fetch from 'cross-fetch'; + +/** + * This is a copy of FetchApi, to avoid importing core-plugin-api. + * + * @public + */ +export type FetchApi = { + fetch: typeof fetch; +}; diff --git a/packages/catalog-client/src/types/index.ts b/packages/catalog-client/src/types/index.ts index 3552a72e3c..f3c6fab4e9 100644 --- a/packages/catalog-client/src/types/index.ts +++ b/packages/catalog-client/src/types/index.ts @@ -25,5 +25,6 @@ export type { CatalogEntityAncestorsResponse, } from './api'; export type { DiscoveryApi } from './discovery'; +export type { FetchApi } from './fetch'; export { CATALOG_FILTER_EXISTS } from './api'; export { ENTITY_STATUS_CATALOG_PROCESSING_TYPE } from './status'; diff --git a/packages/core-app-api/api-report.md b/packages/core-app-api/api-report.md index 8a3f0edf14..3277be7841 100644 --- a/packages/core-app-api/api-report.md +++ b/packages/core-app-api/api-report.md @@ -26,6 +26,7 @@ import { bitbucketAuthApiRef } from '@backstage/core-plugin-api'; import { ComponentType } from 'react'; import { ConfigReader } from '@backstage/config'; import { createApp as createApp_2 } from '@backstage/app-defaults'; +import crossFetch from 'cross-fetch'; import { DiscoveryApi } from '@backstage/core-plugin-api'; import { ErrorApi } from '@backstage/core-plugin-api'; import { ErrorApiError } from '@backstage/core-plugin-api'; @@ -34,6 +35,7 @@ import { ExternalRouteRef } from '@backstage/core-plugin-api'; import { FeatureFlag } from '@backstage/core-plugin-api'; import { FeatureFlagsApi } from '@backstage/core-plugin-api'; import { FeatureFlagsSaveOptions } from '@backstage/core-plugin-api'; +import { FetchApi } from '@backstage/core-plugin-api'; import { gitlabAuthApiRef } from '@backstage/core-plugin-api'; import { googleAuthApiRef } from '@backstage/core-plugin-api'; import { IconComponent } from '@backstage/core-plugin-api'; @@ -288,6 +290,14 @@ export type BackstagePluginWithAnyOutput = Omit< )[]; }; +// @public +export class BackstageProtocolResolverFetchMiddleware + implements FetchMiddleware +{ + constructor(discovery: (pluginId: string) => Promise); + apply(next: FetchFunction): FetchFunction; +} + // @public export class BitbucketAuth { // (undocumented) @@ -369,6 +379,24 @@ export type FeatureFlaggedProps = { } ); +// @public +export class FetchApiBuilder { + // (undocumented) + build(): FetchApi; + // (undocumented) + static create(): FetchApiBuilder; + // (undocumented) + with(middleware: FetchMiddleware): FetchApiBuilder; +} + +// @public +export type FetchFunction = typeof crossFetch; + +// @public +export interface FetchMiddleware { + apply(next: FetchFunction): FetchFunction; +} + // @public export const FlatRoutes: (props: FlatRoutesProps) => JSX.Element | null; @@ -426,6 +454,13 @@ export class GoogleAuth { static create(options: OAuthApiCreateOptions): typeof googleAuthApiRef.T; } +// @public +export class IdentityAwareFetchMiddleware implements FetchMiddleware { + constructor(tokenFunction: () => Promise); + apply(next: FetchFunction): FetchFunction; + setHeaderName(name: string): IdentityAwareFetchMiddleware; +} + // @public export class LocalStorageFeatureFlags implements FeatureFlagsApi { // (undocumented) diff --git a/packages/core-app-api/package.json b/packages/core-app-api/package.json index 23079d7ba0..d138417143 100644 --- a/packages/core-app-api/package.json +++ b/packages/core-app-api/package.json @@ -39,6 +39,7 @@ "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@types/prop-types": "^15.7.3", + "cross-fetch": "^3.0.6", "prop-types": "^15.7.2", "react-router-dom": "6.0.0-beta.0", "react-use": "^17.2.4", diff --git a/packages/core-app-api/src/apis/implementations/FetchApi/BackstageProtocolResolverFetchMiddleware.test.ts b/packages/core-app-api/src/apis/implementations/FetchApi/BackstageProtocolResolverFetchMiddleware.test.ts new file mode 100644 index 0000000000..7dcb90573b --- /dev/null +++ b/packages/core-app-api/src/apis/implementations/FetchApi/BackstageProtocolResolverFetchMiddleware.test.ts @@ -0,0 +1,86 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { BackstageProtocolResolverFetchMiddleware } from './BackstageProtocolResolverFetchMiddleware'; + +describe('BackstageProtocolResolverFetchMiddleware', () => { + it.each([['https://passthrough.com/a']])( + 'passes through regular URLs, %p', + async (url: string) => { + const resolve = jest.fn(); + const middleware = new BackstageProtocolResolverFetchMiddleware(resolve); + const inner = jest.fn(); + const outer = middleware.apply(inner); + + await outer(url); + expect(inner.mock.calls[0][0]).toBe(url); + expect(resolve).not.toBeCalled(); + }, + ); + + it.each([ + [ + 'backstage://my-plugin/sub/path', + 'my-plugin', + 'https://real.com/base', + 'https://real.com/base/sub/path', + ], + [ + 'backstage://my-plugin/sub/path/', + 'my-plugin', + 'https://real.com/base/', + 'https://real.com/base/sub/path/', + ], + ['backstage://x', 'x', 'http://real.com:8080', 'http://real.com:8080'], + [ + 'backstage://x/a/b?c=d&e=f#g', + 'x', + 'https://real.com/base', + 'https://real.com/base/a/b?c=d&e=f#g', + ], + [ + 'backstage://x?c=d&e=f#g', + 'x', + 'https://real.com:8080/base', + 'https://real.com:8080/base?c=d&e=f#g', + ], + [ + 'backstage://username:password@x?c=d&e=f#g', + 'x', + 'https://real.com:8080/base', + 'https://username:password@real.com:8080/base?c=d&e=f#g', + ], + [ + 'backstage://x?c=d&e=f#g', + 'x', + 'https://username:password@real.com:8080/base', + 'https://username:password@real.com:8080/base?c=d&e=f#g', + ], + ])( + 'resolves backstage URLs, %p', + async (original, host, resolved, result) => { + const resolve = jest.fn(); + const middleware = new BackstageProtocolResolverFetchMiddleware(resolve); + const inner = jest.fn(); + const outer = middleware.apply(inner); + + resolve.mockResolvedValueOnce(resolved); + await outer(original); + expect(inner.mock.calls[0][0]).toBe(result); + expect(resolve).toHaveBeenLastCalledWith(host); + }, + ); +}); diff --git a/packages/core-app-api/src/apis/implementations/FetchApi/BackstageProtocolResolverFetchMiddleware.ts b/packages/core-app-api/src/apis/implementations/FetchApi/BackstageProtocolResolverFetchMiddleware.ts new file mode 100644 index 0000000000..03d08c3096 --- /dev/null +++ b/packages/core-app-api/src/apis/implementations/FetchApi/BackstageProtocolResolverFetchMiddleware.ts @@ -0,0 +1,64 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { FetchFunction, FetchMiddleware } from './types'; + +function join(left: string, right: string): string { + if (!right || right === '/') { + return left; + } + + return `${left.replace(/\/$/, '')}/${right.replace(/^\//, '')}`; +} + +/** + * Handles translation from backstage://some-plugin-id/ to concrete + * http(s) URLs. + * + * @public + */ +export class BackstageProtocolResolverFetchMiddleware + implements FetchMiddleware +{ + constructor( + private readonly discovery: (pluginId: string) => Promise, + ) {} + + /** + * {@inheritdoc FetchMiddleware.apply} + */ + apply(next: FetchFunction): FetchFunction { + return async (input, init) => { + const request = new Request(input, init); + const { protocol, hostname, pathname, search, hash, username, password } = + new URL(request.url); + + if (protocol !== 'backstage:') { + return next(input, init); + } + + let base = await this.discovery(hostname); + if (username || password) { + const baseUrl = new URL(base); + const authority = `${username}${password ? `:${password}` : ''}@`; + base = `${baseUrl.protocol}//${authority}${baseUrl.host}${baseUrl.pathname}`; + } + + const target = `${join(base, pathname)}${search}${hash}`; + return next(target, request); + }; + } +} diff --git a/packages/core-app-api/src/apis/implementations/FetchApi/FetchApiBuilder.ts b/packages/core-app-api/src/apis/implementations/FetchApi/FetchApiBuilder.ts new file mode 100644 index 0000000000..1c96eb1ad6 --- /dev/null +++ b/packages/core-app-api/src/apis/implementations/FetchApi/FetchApiBuilder.ts @@ -0,0 +1,55 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { FetchApi } from '@backstage/core-plugin-api'; +import crossFetch from 'cross-fetch'; +import { FetchFunction, FetchMiddleware } from './types'; + +/** + * Builds a fetch API, based on the builtin fetch wrapped by a set of optional + * middleware implementations that add behaviors. + * + * @public + */ +export class FetchApiBuilder { + static create(): FetchApiBuilder { + return new FetchApiBuilder(crossFetch, []); + } + + private constructor( + private readonly implementation: FetchFunction, + private readonly middleware: FetchMiddleware[], + ) {} + + with(middleware: FetchMiddleware): FetchApiBuilder { + return new FetchApiBuilder(this.implementation, [ + ...this.middleware, + middleware, + ]); + } + + build(): FetchApi { + let result = this.implementation; + + for (const m of this.middleware) { + result = m.apply(result); + } + + return { + fetch: result, + }; + } +} diff --git a/packages/core-app-api/src/apis/implementations/FetchApi/IdentityAwareFetchMiddleware.test.ts b/packages/core-app-api/src/apis/implementations/FetchApi/IdentityAwareFetchMiddleware.test.ts new file mode 100644 index 0000000000..381ebd62a9 --- /dev/null +++ b/packages/core-app-api/src/apis/implementations/FetchApi/IdentityAwareFetchMiddleware.test.ts @@ -0,0 +1,43 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { IdentityAwareFetchMiddleware } from './IdentityAwareFetchMiddleware'; + +describe('IdentityAwareFetchMiddleware', () => { + it('injects the header only when a token is available', async () => { + const tokenFunction = jest.fn(); + const middleware = new IdentityAwareFetchMiddleware(tokenFunction); + const inner = jest.fn(); + const outer = middleware.apply(inner); + + // No token available + tokenFunction.mockResolvedValueOnce(undefined); + await outer(new Request('https://example.com')); + expect([...inner.mock.calls[0][0].headers.entries()]).toEqual([]); + + // Supply a token, header gets added + tokenFunction.mockResolvedValueOnce('token'); + await outer(new Request('https://example.com')); + expect([...inner.mock.calls[1][0].headers.entries()]).toEqual([ + ['backstage-token', 'token'], + ]); + + // Token no longer available + tokenFunction.mockResolvedValueOnce(undefined); + await outer(new Request('https://example.com')); + expect([...inner.mock.calls[2][0].headers.entries()]).toEqual([]); + }); +}); diff --git a/packages/core-app-api/src/apis/implementations/FetchApi/IdentityAwareFetchMiddleware.ts b/packages/core-app-api/src/apis/implementations/FetchApi/IdentityAwareFetchMiddleware.ts new file mode 100644 index 0000000000..474ca83894 --- /dev/null +++ b/packages/core-app-api/src/apis/implementations/FetchApi/IdentityAwareFetchMiddleware.ts @@ -0,0 +1,59 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { FetchFunction, FetchMiddleware } from './types'; + +const DEFAULT_HEADER_NAME = 'backstage-token'; + +/** + * A fetch middleware, which injects a Backstage token header when the user is + * signed in. + * + * @public + */ +export class IdentityAwareFetchMiddleware implements FetchMiddleware { + private headerName: string; + private tokenFunction: () => Promise; + + constructor(tokenFunction: () => Promise) { + this.headerName = DEFAULT_HEADER_NAME; + this.tokenFunction = tokenFunction; + } + + /** + * {@inheritdoc FetchMiddleware.apply} + */ + apply(next: FetchFunction): FetchFunction { + return async (input, init) => { + const token = await this.tokenFunction(); + if (typeof token !== 'string') { + return next(input, init); + } + + const request = new Request(input, init); + request.headers.set(this.headerName, token); + return next(request); + }; + } + + /** + * Changes the header name from the default value to a custom one. + */ + setHeaderName(name: string): IdentityAwareFetchMiddleware { + this.headerName = name; + return this; + } +} diff --git a/packages/core-app-api/src/apis/implementations/FetchApi/index.ts b/packages/core-app-api/src/apis/implementations/FetchApi/index.ts new file mode 100644 index 0000000000..7544bd8bf2 --- /dev/null +++ b/packages/core-app-api/src/apis/implementations/FetchApi/index.ts @@ -0,0 +1,20 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { BackstageProtocolResolverFetchMiddleware } from './BackstageProtocolResolverFetchMiddleware'; +export { FetchApiBuilder } from './FetchApiBuilder'; +export { IdentityAwareFetchMiddleware } from './IdentityAwareFetchMiddleware'; +export type { FetchFunction, FetchMiddleware } from './types'; diff --git a/packages/core-app-api/src/apis/implementations/FetchApi/types.ts b/packages/core-app-api/src/apis/implementations/FetchApi/types.ts new file mode 100644 index 0000000000..4cf0bf47f4 --- /dev/null +++ b/packages/core-app-api/src/apis/implementations/FetchApi/types.ts @@ -0,0 +1,39 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import crossFetch from 'cross-fetch'; + +/** + * The type of a fetch call. + * + * @public + */ +export type FetchFunction = typeof crossFetch; + +/** + * A middleware that modifies the behavior of an ongoing fetch. + * + * @public + */ +export interface FetchMiddleware { + /** + * Applies this middleware to an inner implementation. + * + * @param next - The next, inner, implementation, that this middleware shall + * call out to as part of the request cycle. + */ + apply(next: FetchFunction): FetchFunction; +} diff --git a/packages/core-app-api/src/apis/implementations/index.ts b/packages/core-app-api/src/apis/implementations/index.ts index c494f966f2..1c79d3d164 100644 --- a/packages/core-app-api/src/apis/implementations/index.ts +++ b/packages/core-app-api/src/apis/implementations/index.ts @@ -27,5 +27,6 @@ export * from './ConfigApi'; export * from './DiscoveryApi'; export * from './ErrorApi'; export * from './FeatureFlagsApi'; +export * from './FetchApi'; export * from './OAuthRequestApi'; export * from './StorageApi'; diff --git a/packages/core-plugin-api/api-report.md b/packages/core-plugin-api/api-report.md index 9fd4f57ae9..148115fd69 100644 --- a/packages/core-plugin-api/api-report.md +++ b/packages/core-plugin-api/api-report.md @@ -9,6 +9,7 @@ import { BackstagePlugin as BackstagePlugin_2 } from '@backstage/core-plugin-api import { BackstageTheme } from '@backstage/theme'; import { ComponentType } from 'react'; import { Config } from '@backstage/config'; +import { default as fetch_2 } from 'cross-fetch'; import { IconComponent as IconComponent_2 } from '@backstage/core-plugin-api'; import { IdentityApi as IdentityApi_2 } from '@backstage/core-plugin-api'; import { Observable as Observable_2 } from '@backstage/types'; @@ -505,6 +506,14 @@ export enum FeatureFlagState { None = 0, } +// @public +export type FetchApi = { + fetch: typeof fetch_2; +}; + +// @public +export const fetchApiRef: ApiRef; + // @public export function getComponentData( node: ReactNode, diff --git a/packages/core-plugin-api/package.json b/packages/core-plugin-api/package.json index 72827bde73..365cec3134 100644 --- a/packages/core-plugin-api/package.json +++ b/packages/core-plugin-api/package.json @@ -34,6 +34,7 @@ "@backstage/types": "^0.1.1", "@backstage/version-bridge": "^0.1.1", "@material-ui/core": "^4.12.2", + "cross-fetch": "^3.0.6", "history": "^5.0.0", "prop-types": "^15.7.2", "react-router-dom": "6.0.0-beta.0", @@ -56,7 +57,6 @@ "@types/node": "^14.14.32", "@types/prop-types": "^15.7.3", "@types/zen-observable": "^0.8.0", - "cross-fetch": "^3.0.6", "msw": "^0.35.0" }, "files": [ diff --git a/packages/core-plugin-api/src/apis/definitions/FetchApi.ts b/packages/core-plugin-api/src/apis/definitions/FetchApi.ts new file mode 100644 index 0000000000..30eb950634 --- /dev/null +++ b/packages/core-plugin-api/src/apis/definitions/FetchApi.ts @@ -0,0 +1,38 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import fetch from 'cross-fetch'; +import { ApiRef, createApiRef } from '../system'; + +/** + * A wrapper for the fetch API, that has additional behaviors such as the + * ability to automatically inject auth information where necessary. + * + * @public + */ +export type FetchApi = { + fetch: typeof fetch; +}; + +/** + * A wrapper for the fetch API, that has additional behaviors such as the + * ability to automatically inject auth information where necessary. + * + * @public + */ +export const fetchApiRef: ApiRef = createApiRef({ + id: 'core.fetch', +}); diff --git a/packages/core-plugin-api/src/apis/definitions/index.ts b/packages/core-plugin-api/src/apis/definitions/index.ts index b7666bcb54..67d442587d 100644 --- a/packages/core-plugin-api/src/apis/definitions/index.ts +++ b/packages/core-plugin-api/src/apis/definitions/index.ts @@ -29,6 +29,7 @@ export * from './ConfigApi'; export * from './DiscoveryApi'; export * from './ErrorApi'; export * from './FeatureFlagsApi'; +export * from './FetchApi'; export * from './IdentityApi'; export * from './OAuthRequestApi'; export * from './StorageApi'; From afb7f31840d506c270035d1b53e5f4ede553e1bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Thu, 9 Dec 2021 15:10:20 +0100 Subject: [PATCH 34/39] fixed the browser behavior for BackstageProtocolResolverFetchMiddleware MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .../BackstageProtocolResolverFetchMiddleware.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/core-app-api/src/apis/implementations/FetchApi/BackstageProtocolResolverFetchMiddleware.ts b/packages/core-app-api/src/apis/implementations/FetchApi/BackstageProtocolResolverFetchMiddleware.ts index 03d08c3096..2144d0058d 100644 --- a/packages/core-app-api/src/apis/implementations/FetchApi/BackstageProtocolResolverFetchMiddleware.ts +++ b/packages/core-app-api/src/apis/implementations/FetchApi/BackstageProtocolResolverFetchMiddleware.ts @@ -43,13 +43,18 @@ export class BackstageProtocolResolverFetchMiddleware apply(next: FetchFunction): FetchFunction { return async (input, init) => { const request = new Request(input, init); - const { protocol, hostname, pathname, search, hash, username, password } = - new URL(request.url); + const prefix = 'backstage://'; - if (protocol !== 'backstage:') { + if (!request.url.startsWith(prefix)) { return next(input, init); } + // Switch to a known protocol, since browser URL parsing misbehaves wildly + // on foreign protocols + const { hostname, pathname, search, hash, username, password } = new URL( + `http://${request.url.substring(prefix.length)}`, + ); + let base = await this.discovery(hostname); if (username || password) { const baseUrl = new URL(base); From 3fa31ec84a4b564397d410228df25a9c75dac2d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Tue, 14 Dec 2021 14:11:30 +0100 Subject: [PATCH 35/39] address comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/itchy-grapes-think.md | 25 +++ packages/app-defaults/src/defaults/apis.ts | 32 ++-- packages/catalog-client/api-report.md | 3 +- packages/catalog-client/src/types/fetch.ts | 2 - packages/core-app-api/api-report.md | 50 +++--- packages/core-app-api/package.json | 1 - .../FetchApi/FetchMiddlewares.ts | 76 +++++++++ ...dentityAuthInjectorFetchMiddleware.test.ts | 153 ++++++++++++++++++ .../IdentityAuthInjectorFetchMiddleware.ts | 82 ++++++++++ .../IdentityAwareFetchMiddleware.test.ts | 43 ----- .../FetchApi/IdentityAwareFetchMiddleware.ts | 59 ------- ...inProtocolResolverFetchMiddleware.test.ts} | 31 ++-- ... PluginProtocolResolverFetchMiddleware.ts} | 26 ++- .../{FetchApiBuilder.ts => createFetchApi.ts} | 47 +++--- .../apis/implementations/FetchApi/index.ts | 7 +- .../apis/implementations/FetchApi/types.ts | 11 +- packages/core-plugin-api/api-report.md | 3 +- packages/core-plugin-api/package.json | 2 +- .../src/apis/definitions/FetchApi.ts | 1 - plugins/catalog/api-report.md | 2 +- plugins/catalog/src/CatalogClientWrapper.ts | 7 + plugins/catalog/src/plugin.ts | 16 +- 22 files changed, 444 insertions(+), 235 deletions(-) create mode 100644 .changeset/itchy-grapes-think.md create mode 100644 packages/core-app-api/src/apis/implementations/FetchApi/FetchMiddlewares.ts create mode 100644 packages/core-app-api/src/apis/implementations/FetchApi/IdentityAuthInjectorFetchMiddleware.test.ts create mode 100644 packages/core-app-api/src/apis/implementations/FetchApi/IdentityAuthInjectorFetchMiddleware.ts delete mode 100644 packages/core-app-api/src/apis/implementations/FetchApi/IdentityAwareFetchMiddleware.test.ts delete mode 100644 packages/core-app-api/src/apis/implementations/FetchApi/IdentityAwareFetchMiddleware.ts rename packages/core-app-api/src/apis/implementations/FetchApi/{BackstageProtocolResolverFetchMiddleware.test.ts => PluginProtocolResolverFetchMiddleware.test.ts} (69%) rename packages/core-app-api/src/apis/implementations/FetchApi/{BackstageProtocolResolverFetchMiddleware.ts => PluginProtocolResolverFetchMiddleware.ts} (75%) rename packages/core-app-api/src/apis/implementations/FetchApi/{FetchApiBuilder.ts => createFetchApi.ts} (54%) diff --git a/.changeset/itchy-grapes-think.md b/.changeset/itchy-grapes-think.md new file mode 100644 index 0000000000..c453b24922 --- /dev/null +++ b/.changeset/itchy-grapes-think.md @@ -0,0 +1,25 @@ +--- +'@backstage/plugin-catalog': patch +--- + +Deprecated the `CatalogClientWrapper` class. + +The default implementation of `catalogApiRef` that this plugin exposes, is now powered by the new `fetchApiRef`. The default implementation of _that_ API, in turn, has the ability to inject the user's Backstage token in requests in a similar manner to what the deprecated `CatalogClientWrapper` used to do. The latter has therefore been taken out of the default catalog API implementation. + +If you use a custom `fetchApiRef` implementation that does NOT issue tokens, or use a custom `catalogApiRef` implementation which does NOT use the default `fetchApiRef`, you can still for some time wrap your catalog API in this class to get back the old behavior: + +```ts +// Add this to your packages/app/src/plugins.ts if you want to get back the old +// catalog client behavior: +createApiFactory({ + api: catalogApiRef, + deps: { discoveryApi: discoveryApiRef, identityApi: identityApiRef }, + factory: ({ discoveryApi, identityApi }) => + new CatalogClientWrapper({ + client: new CatalogClient({ discoveryApi }), + identityApi, + }), +}), +``` + +But do consider migrating to making use of the `fetchApiRef` as soon as convenient, since the wrapper class will be removed in a future release. diff --git a/packages/app-defaults/src/defaults/apis.ts b/packages/app-defaults/src/defaults/apis.ts index 06562caaef..29aa62bdab 100644 --- a/packages/app-defaults/src/defaults/apis.ts +++ b/packages/app-defaults/src/defaults/apis.ts @@ -34,9 +34,8 @@ import { OneLoginAuth, UnhandledErrorForwarder, AtlassianAuth, - FetchApiBuilder, - IdentityAwareFetchMiddleware, - BackstageProtocolResolverFetchMiddleware, + createFetchApi, + FetchMiddlewares, } from '@backstage/core-app-api'; import { @@ -99,20 +98,23 @@ export const apis = [ }), createApiFactory({ api: fetchApiRef, - deps: { identityApi: identityApiRef, discoveryApi: discoveryApiRef }, - factory: ({ identityApi, discoveryApi }) => { - return FetchApiBuilder.create() - .with( - new IdentityAwareFetchMiddleware(() => { - return identityApi.getCredentials().then(r => r.token); + deps: { + configApi: configApiRef, + identityApi: identityApiRef, + discoveryApi: discoveryApiRef, + }, + factory: ({ configApi, identityApi, discoveryApi }) => { + return createFetchApi({ + middleware: [ + FetchMiddlewares.resolvePluginProtocol({ + discoveryApi, }), - ) - .with( - new BackstageProtocolResolverFetchMiddleware(plugin => { - return discoveryApi.getBaseUrl(plugin); + FetchMiddlewares.injectIdentityAuth({ + identityApi, + config: configApi, }), - ) - .build(); + ], + }); }, }), createApiFactory({ diff --git a/packages/catalog-client/api-report.md b/packages/catalog-client/api-report.md index 41aea63716..495c98a104 100644 --- a/packages/catalog-client/api-report.md +++ b/packages/catalog-client/api-report.md @@ -5,7 +5,6 @@ ```ts import { Entity } from '@backstage/catalog-model'; import { EntityName } from '@backstage/catalog-model'; -import { default as fetch_2 } from 'cross-fetch'; import { Location as Location_2 } from '@backstage/catalog-model'; // @public @@ -159,6 +158,6 @@ export const ENTITY_STATUS_CATALOG_PROCESSING_TYPE = // @public export type FetchApi = { - fetch: typeof fetch_2; + fetch: typeof fetch; }; ``` diff --git a/packages/catalog-client/src/types/fetch.ts b/packages/catalog-client/src/types/fetch.ts index cdddd31810..59de6a68f1 100644 --- a/packages/catalog-client/src/types/fetch.ts +++ b/packages/catalog-client/src/types/fetch.ts @@ -14,8 +14,6 @@ * limitations under the License. */ -import fetch from 'cross-fetch'; - /** * This is a copy of FetchApi, to avoid importing core-plugin-api. * diff --git a/packages/core-app-api/api-report.md b/packages/core-app-api/api-report.md index 3277be7841..78bfd83251 100644 --- a/packages/core-app-api/api-report.md +++ b/packages/core-app-api/api-report.md @@ -24,9 +24,9 @@ import { BackstageIdentityApi } from '@backstage/core-plugin-api'; import { BackstagePlugin } from '@backstage/core-plugin-api'; import { bitbucketAuthApiRef } from '@backstage/core-plugin-api'; import { ComponentType } from 'react'; +import { Config } from '@backstage/config'; import { ConfigReader } from '@backstage/config'; import { createApp as createApp_2 } from '@backstage/app-defaults'; -import crossFetch from 'cross-fetch'; import { DiscoveryApi } from '@backstage/core-plugin-api'; import { ErrorApi } from '@backstage/core-plugin-api'; import { ErrorApiError } from '@backstage/core-plugin-api'; @@ -290,14 +290,6 @@ export type BackstagePluginWithAnyOutput = Omit< )[]; }; -// @public -export class BackstageProtocolResolverFetchMiddleware - implements FetchMiddleware -{ - constructor(discovery: (pluginId: string) => Promise); - apply(next: FetchFunction): FetchFunction; -} - // @public export class BitbucketAuth { // (undocumented) @@ -328,6 +320,12 @@ export function createApp( options?: Parameters[0], ): BackstageApp & AppContext; +// @public +export function createFetchApi(options: { + baseImplementation?: typeof fetch | undefined; + middleware?: FetchMiddleware | FetchMiddleware[] | undefined; +}): FetchApi; + // @public export function createSpecializedApp(options: AppOptions): BackstageApp; @@ -380,21 +378,24 @@ export type FeatureFlaggedProps = { ); // @public -export class FetchApiBuilder { - // (undocumented) - build(): FetchApi; - // (undocumented) - static create(): FetchApiBuilder; - // (undocumented) - with(middleware: FetchMiddleware): FetchApiBuilder; +export interface FetchMiddleware { + apply(next: typeof fetch): typeof fetch; } // @public -export type FetchFunction = typeof crossFetch; - -// @public -export interface FetchMiddleware { - apply(next: FetchFunction): FetchFunction; +export class FetchMiddlewares { + static injectIdentityAuth(options: { + identityApi: IdentityApi; + config?: Config; + urlPrefixAllowlist?: string[]; + header?: { + name: string; + value: (backstageToken: string) => string; + }; + }): FetchMiddleware; + static resolvePluginProtocol(options: { + discoveryApi: DiscoveryApi; + }): FetchMiddleware; } // @public @@ -454,13 +455,6 @@ export class GoogleAuth { static create(options: OAuthApiCreateOptions): typeof googleAuthApiRef.T; } -// @public -export class IdentityAwareFetchMiddleware implements FetchMiddleware { - constructor(tokenFunction: () => Promise); - apply(next: FetchFunction): FetchFunction; - setHeaderName(name: string): IdentityAwareFetchMiddleware; -} - // @public export class LocalStorageFeatureFlags implements FeatureFlagsApi { // (undocumented) diff --git a/packages/core-app-api/package.json b/packages/core-app-api/package.json index d138417143..23079d7ba0 100644 --- a/packages/core-app-api/package.json +++ b/packages/core-app-api/package.json @@ -39,7 +39,6 @@ "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@types/prop-types": "^15.7.3", - "cross-fetch": "^3.0.6", "prop-types": "^15.7.2", "react-router-dom": "6.0.0-beta.0", "react-use": "^17.2.4", diff --git a/packages/core-app-api/src/apis/implementations/FetchApi/FetchMiddlewares.ts b/packages/core-app-api/src/apis/implementations/FetchApi/FetchMiddlewares.ts new file mode 100644 index 0000000000..1cf09ff20d --- /dev/null +++ b/packages/core-app-api/src/apis/implementations/FetchApi/FetchMiddlewares.ts @@ -0,0 +1,76 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Config } from '@backstage/config'; +import { DiscoveryApi, IdentityApi } from '@backstage/core-plugin-api'; +import { IdentityAuthInjectorFetchMiddleware } from './IdentityAuthInjectorFetchMiddleware'; +import { PluginProtocolResolverFetchMiddleware } from './PluginProtocolResolverFetchMiddleware'; +import { FetchMiddleware } from './types'; + +/** + * A collection of common middlewares for the FetchApi. + * + * @public + */ +export class FetchMiddlewares { + /** + * Handles translation from `plugin://` URLs to concrete http(s) URLs based on + * the discovery API. + * + * @remarks + * + * If the request is for `plugin://catalog/entities?filter=x=y`, the discovery + * API will be queried for `'catalog'`. If it returned + * `https://backstage.example.net/api/catalog`, the resulting query would be + * `https://backstage.example.net/api/catalog/entities?filter=x=y`. + * + * If the incoming URL protocol was not `plugin`, the request is just passed + * through verbatim to the underlying implementation. + */ + static resolvePluginProtocol(options: { + discoveryApi: DiscoveryApi; + }): FetchMiddleware { + return new PluginProtocolResolverFetchMiddleware(options.discoveryApi); + } + + /** + * Injects a Backstage token header when the user is signed in. + * + * @remarks + * + * Per default, an `Authorization: Bearer ` is generated. This can be + * customized using the `header` option. + * + * The header injection only happens on allowlisted URLs. Per default, if the + * `config` option is passed in, the `backend.baseUrl` is allowlisted, unless + * the `urlPrefixAllowlist` option is passed in, in which case it takes + * precedence. If you pass in neither config nor an allowlist, the middleware + * will have no effect. + */ + static injectIdentityAuth(options: { + identityApi: IdentityApi; + config?: Config; + urlPrefixAllowlist?: string[]; + header?: { + name: string; + value: (backstageToken: string) => string; + }; + }): FetchMiddleware { + return IdentityAuthInjectorFetchMiddleware.create(options); + } + + private constructor() {} +} diff --git a/packages/core-app-api/src/apis/implementations/FetchApi/IdentityAuthInjectorFetchMiddleware.test.ts b/packages/core-app-api/src/apis/implementations/FetchApi/IdentityAuthInjectorFetchMiddleware.test.ts new file mode 100644 index 0000000000..b69a4b9f7a --- /dev/null +++ b/packages/core-app-api/src/apis/implementations/FetchApi/IdentityAuthInjectorFetchMiddleware.test.ts @@ -0,0 +1,153 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ConfigReader } from '@backstage/config'; +import { IdentityApi } from '@backstage/core-plugin-api'; +import { IdentityAuthInjectorFetchMiddleware } from './IdentityAuthInjectorFetchMiddleware'; + +describe('IdentityAuthInjectorFetchMiddleware', () => { + it('creates using defaults', async () => { + const middleware = IdentityAuthInjectorFetchMiddleware.create({ + identityApi: undefined as any, + }); + expect(middleware.urlPrefixAllowlist).toEqual([]); + expect(middleware.headerName).toEqual('authorization'); + expect(middleware.headerValue('t')).toEqual('Bearer t'); + }); + + it('creates using config', async () => { + const middleware = IdentityAuthInjectorFetchMiddleware.create({ + identityApi: undefined as any, + config: new ConfigReader({ + backend: { baseUrl: 'https://example.com/api' }, + }), + header: { name: 'auth', value: t => `${t}!` }, + }); + expect(middleware.urlPrefixAllowlist).toEqual(['https://example.com/api']); + expect(middleware.headerName).toEqual('auth'); + expect(middleware.headerValue('t')).toEqual('t!'); + }); + + it('creates using explicit allowlist', async () => { + const middleware = IdentityAuthInjectorFetchMiddleware.create({ + identityApi: undefined as any, + config: new ConfigReader({ + backend: { baseUrl: 'https://example.com/api' }, + }), + urlPrefixAllowlist: ['https://a.com', 'http://b.com:8080/'], + }); + expect(middleware.urlPrefixAllowlist).toEqual([ + 'https://a.com', + 'http://b.com:8080', + ]); + }); + + it('injects the header only when a token is available', async () => { + const tokenFunction = jest.fn(); + const identityApi = { + getCredentials: tokenFunction, + } as unknown as IdentityApi; + + const middleware = new IdentityAuthInjectorFetchMiddleware( + identityApi, + ['https://example.com'], + 'Authorization', + token => `Bearer ${token}`, + ); + const inner = jest.fn(); + const outer = middleware.apply(inner); + + // No token available + tokenFunction.mockResolvedValueOnce({ token: undefined }); + await outer(new Request('https://example.com')); + expect([...inner.mock.calls[0][0].headers.entries()]).toEqual([]); + + // Supply a token, header gets added + tokenFunction.mockResolvedValueOnce({ token: 'token' }); + await outer(new Request('https://example.com')); + expect([...inner.mock.calls[1][0].headers.entries()]).toEqual([ + ['authorization', 'Bearer token'], + ]); + + // Token no longer available + tokenFunction.mockResolvedValueOnce({ token: undefined }); + await outer(new Request('https://example.com')); + expect([...inner.mock.calls[2][0].headers.entries()]).toEqual([]); + }); + + it('does not overwrite an existing header with the same name', async () => { + const identityApi = { + getCredentials: () => ({ token: 'token' }), + } as unknown as IdentityApi; + + const middleware = new IdentityAuthInjectorFetchMiddleware( + identityApi, + ['https://example.com'], + 'Authorization', + token => `Bearer ${token}`, + ); + const inner = jest.fn(); + const outer = middleware.apply(inner); + + // No token available + await outer(new Request('https://example.com')); + expect([...inner.mock.calls[0][0].headers.entries()]).toEqual([ + ['authorization', 'Bearer token'], + ]); + + // Supply a token, header gets added + await outer( + new Request('https://example.com', { + headers: { authorization: 'do-not-clobber' }, + }), + ); + expect([...inner.mock.calls[1][0].headers.entries()]).toEqual([ + ['authorization', 'do-not-clobber'], + ]); + }); + + it('does not affect requests outside the allowlist', async () => { + const identityApi = { + getCredentials: () => ({ token: 'token' }), + } as unknown as IdentityApi; + + const middleware = new IdentityAuthInjectorFetchMiddleware( + identityApi, + ['https://example.com:8080/root'], + 'Authorization', + token => `Bearer ${token}`, + ); + + const inner = jest.fn(); + const outer = middleware.apply(inner); + + await outer(new Request('https://example.com:8080/root')); + await outer(new Request('https://example.com:8080/root/sub')); + await outer(new Request('https://example.com:8080/root2')); + await outer(new Request('https://example.com/root')); + await outer(new Request('http://example.com:8080/root')); + await outer(new Request('https://example.com/root')); + + const no: string[][] = []; + const yes: string[][] = [['authorization', 'Bearer token']]; + expect([...inner.mock.calls[0][0].headers.entries()]).toEqual(yes); + expect([...inner.mock.calls[1][0].headers.entries()]).toEqual(yes); + expect([...inner.mock.calls[2][0].headers.entries()]).toEqual(no); + expect([...inner.mock.calls[3][0].headers.entries()]).toEqual(no); + expect([...inner.mock.calls[4][0].headers.entries()]).toEqual(no); + expect([...inner.mock.calls[5][0].headers.entries()]).toEqual(no); + }); +}); diff --git a/packages/core-app-api/src/apis/implementations/FetchApi/IdentityAuthInjectorFetchMiddleware.ts b/packages/core-app-api/src/apis/implementations/FetchApi/IdentityAuthInjectorFetchMiddleware.ts new file mode 100644 index 0000000000..46ada0a505 --- /dev/null +++ b/packages/core-app-api/src/apis/implementations/FetchApi/IdentityAuthInjectorFetchMiddleware.ts @@ -0,0 +1,82 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Config } from '@backstage/config'; +import { IdentityApi } from '@backstage/core-plugin-api'; +import { FetchMiddleware } from './types'; + +/** + * A fetch middleware, which injects a Backstage token header when the user is + * signed in. + */ +export class IdentityAuthInjectorFetchMiddleware implements FetchMiddleware { + static create(options: { + identityApi: IdentityApi; + config?: Config; + urlPrefixAllowlist?: string[]; + header?: { + name: string; + value: (backstageToken: string) => string; + }; + }): IdentityAuthInjectorFetchMiddleware { + const allowlist: string[] = []; + if (options.urlPrefixAllowlist) { + allowlist.push(...options.urlPrefixAllowlist); + } else if (options.config) { + allowlist.push(options.config.getString('backend.baseUrl')); + } + + const headerName = options.header?.name || 'authorization'; + const headerValue = options.header?.value || (token => `Bearer ${token}`); + + return new IdentityAuthInjectorFetchMiddleware( + options.identityApi, + allowlist.map(prefix => prefix.replace(/\/$/, '')), + headerName, + headerValue, + ); + } + + constructor( + public readonly identityApi: IdentityApi, + public readonly urlPrefixAllowlist: string[], + public readonly headerName: string, + public readonly headerValue: (pluginId: string) => string, + ) {} + + apply(next: typeof fetch): typeof fetch { + return async (input, init) => { + // Skip this middleware if the header already exists, or if the URL + // doesn't match any of the allowlist items, or if there was no token + const request = new Request(input, init); + const { token } = await this.identityApi.getCredentials(); + if ( + request.headers.get(this.headerName) || + !this.urlPrefixAllowlist.some( + prefix => + request.url === prefix || request.url.startsWith(`${prefix}/`), + ) || + typeof token !== 'string' || + !token + ) { + return next(input, init); + } + + request.headers.set(this.headerName, this.headerValue(token)); + return next(request); + }; + } +} diff --git a/packages/core-app-api/src/apis/implementations/FetchApi/IdentityAwareFetchMiddleware.test.ts b/packages/core-app-api/src/apis/implementations/FetchApi/IdentityAwareFetchMiddleware.test.ts deleted file mode 100644 index 381ebd62a9..0000000000 --- a/packages/core-app-api/src/apis/implementations/FetchApi/IdentityAwareFetchMiddleware.test.ts +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2021 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { IdentityAwareFetchMiddleware } from './IdentityAwareFetchMiddleware'; - -describe('IdentityAwareFetchMiddleware', () => { - it('injects the header only when a token is available', async () => { - const tokenFunction = jest.fn(); - const middleware = new IdentityAwareFetchMiddleware(tokenFunction); - const inner = jest.fn(); - const outer = middleware.apply(inner); - - // No token available - tokenFunction.mockResolvedValueOnce(undefined); - await outer(new Request('https://example.com')); - expect([...inner.mock.calls[0][0].headers.entries()]).toEqual([]); - - // Supply a token, header gets added - tokenFunction.mockResolvedValueOnce('token'); - await outer(new Request('https://example.com')); - expect([...inner.mock.calls[1][0].headers.entries()]).toEqual([ - ['backstage-token', 'token'], - ]); - - // Token no longer available - tokenFunction.mockResolvedValueOnce(undefined); - await outer(new Request('https://example.com')); - expect([...inner.mock.calls[2][0].headers.entries()]).toEqual([]); - }); -}); diff --git a/packages/core-app-api/src/apis/implementations/FetchApi/IdentityAwareFetchMiddleware.ts b/packages/core-app-api/src/apis/implementations/FetchApi/IdentityAwareFetchMiddleware.ts deleted file mode 100644 index 474ca83894..0000000000 --- a/packages/core-app-api/src/apis/implementations/FetchApi/IdentityAwareFetchMiddleware.ts +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2021 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { FetchFunction, FetchMiddleware } from './types'; - -const DEFAULT_HEADER_NAME = 'backstage-token'; - -/** - * A fetch middleware, which injects a Backstage token header when the user is - * signed in. - * - * @public - */ -export class IdentityAwareFetchMiddleware implements FetchMiddleware { - private headerName: string; - private tokenFunction: () => Promise; - - constructor(tokenFunction: () => Promise) { - this.headerName = DEFAULT_HEADER_NAME; - this.tokenFunction = tokenFunction; - } - - /** - * {@inheritdoc FetchMiddleware.apply} - */ - apply(next: FetchFunction): FetchFunction { - return async (input, init) => { - const token = await this.tokenFunction(); - if (typeof token !== 'string') { - return next(input, init); - } - - const request = new Request(input, init); - request.headers.set(this.headerName, token); - return next(request); - }; - } - - /** - * Changes the header name from the default value to a custom one. - */ - setHeaderName(name: string): IdentityAwareFetchMiddleware { - this.headerName = name; - return this; - } -} diff --git a/packages/core-app-api/src/apis/implementations/FetchApi/BackstageProtocolResolverFetchMiddleware.test.ts b/packages/core-app-api/src/apis/implementations/FetchApi/PluginProtocolResolverFetchMiddleware.test.ts similarity index 69% rename from packages/core-app-api/src/apis/implementations/FetchApi/BackstageProtocolResolverFetchMiddleware.test.ts rename to packages/core-app-api/src/apis/implementations/FetchApi/PluginProtocolResolverFetchMiddleware.test.ts index 7dcb90573b..2f4ec6b536 100644 --- a/packages/core-app-api/src/apis/implementations/FetchApi/BackstageProtocolResolverFetchMiddleware.test.ts +++ b/packages/core-app-api/src/apis/implementations/FetchApi/PluginProtocolResolverFetchMiddleware.test.ts @@ -14,14 +14,18 @@ * limitations under the License. */ -import { BackstageProtocolResolverFetchMiddleware } from './BackstageProtocolResolverFetchMiddleware'; +import { DiscoveryApi } from '@backstage/core-plugin-api'; +import { PluginProtocolResolverFetchMiddleware } from './PluginProtocolResolverFetchMiddleware'; -describe('BackstageProtocolResolverFetchMiddleware', () => { +describe('PluginProtocolResolverFetchMiddleware', () => { it.each([['https://passthrough.com/a']])( 'passes through regular URLs, %p', - async (url: string) => { + async url => { const resolve = jest.fn(); - const middleware = new BackstageProtocolResolverFetchMiddleware(resolve); + const discoveryApi = { getBaseUrl: resolve } as unknown as DiscoveryApi; + const middleware = new PluginProtocolResolverFetchMiddleware( + discoveryApi, + ); const inner = jest.fn(); const outer = middleware.apply(inner); @@ -33,38 +37,38 @@ describe('BackstageProtocolResolverFetchMiddleware', () => { it.each([ [ - 'backstage://my-plugin/sub/path', + 'plugin://my-plugin/sub/path', 'my-plugin', 'https://real.com/base', 'https://real.com/base/sub/path', ], [ - 'backstage://my-plugin/sub/path/', + 'plugin://my-plugin/sub/path/', 'my-plugin', 'https://real.com/base/', 'https://real.com/base/sub/path/', ], - ['backstage://x', 'x', 'http://real.com:8080', 'http://real.com:8080'], + ['plugin://x', 'x', 'http://real.com:8080', 'http://real.com:8080'], [ - 'backstage://x/a/b?c=d&e=f#g', + 'plugin://x/a/b?c=d&e=f#g', 'x', 'https://real.com/base', 'https://real.com/base/a/b?c=d&e=f#g', ], [ - 'backstage://x?c=d&e=f#g', + 'plugin://x?c=d&e=f#g', 'x', 'https://real.com:8080/base', 'https://real.com:8080/base?c=d&e=f#g', ], [ - 'backstage://username:password@x?c=d&e=f#g', + 'plugin://username:password@x?c=d&e=f#g', 'x', 'https://real.com:8080/base', 'https://username:password@real.com:8080/base?c=d&e=f#g', ], [ - 'backstage://x?c=d&e=f#g', + 'plugin://x?c=d&e=f#g', 'x', 'https://username:password@real.com:8080/base', 'https://username:password@real.com:8080/base?c=d&e=f#g', @@ -73,7 +77,10 @@ describe('BackstageProtocolResolverFetchMiddleware', () => { 'resolves backstage URLs, %p', async (original, host, resolved, result) => { const resolve = jest.fn(); - const middleware = new BackstageProtocolResolverFetchMiddleware(resolve); + const discoveryApi = { getBaseUrl: resolve } as unknown as DiscoveryApi; + const middleware = new PluginProtocolResolverFetchMiddleware( + discoveryApi, + ); const inner = jest.fn(); const outer = middleware.apply(inner); diff --git a/packages/core-app-api/src/apis/implementations/FetchApi/BackstageProtocolResolverFetchMiddleware.ts b/packages/core-app-api/src/apis/implementations/FetchApi/PluginProtocolResolverFetchMiddleware.ts similarity index 75% rename from packages/core-app-api/src/apis/implementations/FetchApi/BackstageProtocolResolverFetchMiddleware.ts rename to packages/core-app-api/src/apis/implementations/FetchApi/PluginProtocolResolverFetchMiddleware.ts index 2144d0058d..72834731fe 100644 --- a/packages/core-app-api/src/apis/implementations/FetchApi/BackstageProtocolResolverFetchMiddleware.ts +++ b/packages/core-app-api/src/apis/implementations/FetchApi/PluginProtocolResolverFetchMiddleware.ts @@ -14,7 +14,8 @@ * limitations under the License. */ -import { FetchFunction, FetchMiddleware } from './types'; +import { DiscoveryApi } from '@backstage/core-plugin-api'; +import { FetchMiddleware } from './types'; function join(left: string, right: string): string { if (!right || right === '/') { @@ -25,25 +26,16 @@ function join(left: string, right: string): string { } /** - * Handles translation from backstage://some-plugin-id/ to concrete - * http(s) URLs. - * - * @public + * Handles translation from plugin://some-plugin-id/ to concrete http(s) + * URLs. */ -export class BackstageProtocolResolverFetchMiddleware - implements FetchMiddleware -{ - constructor( - private readonly discovery: (pluginId: string) => Promise, - ) {} +export class PluginProtocolResolverFetchMiddleware implements FetchMiddleware { + constructor(private readonly discoveryApi: DiscoveryApi) {} - /** - * {@inheritdoc FetchMiddleware.apply} - */ - apply(next: FetchFunction): FetchFunction { + apply(next: typeof fetch): typeof fetch { return async (input, init) => { const request = new Request(input, init); - const prefix = 'backstage://'; + const prefix = 'plugin://'; if (!request.url.startsWith(prefix)) { return next(input, init); @@ -55,7 +47,7 @@ export class BackstageProtocolResolverFetchMiddleware `http://${request.url.substring(prefix.length)}`, ); - let base = await this.discovery(hostname); + let base = await this.discoveryApi.getBaseUrl(hostname); if (username || password) { const baseUrl = new URL(base); const authority = `${username}${password ? `:${password}` : ''}@`; diff --git a/packages/core-app-api/src/apis/implementations/FetchApi/FetchApiBuilder.ts b/packages/core-app-api/src/apis/implementations/FetchApi/createFetchApi.ts similarity index 54% rename from packages/core-app-api/src/apis/implementations/FetchApi/FetchApiBuilder.ts rename to packages/core-app-api/src/apis/implementations/FetchApi/createFetchApi.ts index 1c96eb1ad6..1b85695daa 100644 --- a/packages/core-app-api/src/apis/implementations/FetchApi/FetchApiBuilder.ts +++ b/packages/core-app-api/src/apis/implementations/FetchApi/createFetchApi.ts @@ -15,41 +15,32 @@ */ import { FetchApi } from '@backstage/core-plugin-api'; -import crossFetch from 'cross-fetch'; -import { FetchFunction, FetchMiddleware } from './types'; +import { FetchMiddleware } from './types'; /** * Builds a fetch API, based on the builtin fetch wrapped by a set of optional * middleware implementations that add behaviors. * + * @remarks + * + * The middleware are applied in reverse order, i.e. the last one will be + * "closest" to the base implementation. Passing in `[M1, M2, M3]` effectively + * leads to `M1(M2(M3(baseImplementation)))`. + * * @public */ -export class FetchApiBuilder { - static create(): FetchApiBuilder { - return new FetchApiBuilder(crossFetch, []); +export function createFetchApi(options: { + baseImplementation?: typeof fetch | undefined; + middleware?: FetchMiddleware | FetchMiddleware[] | undefined; +}): FetchApi { + let result = options.baseImplementation || global.fetch; + + const middleware = [options.middleware ?? []].flat().reverse(); + for (const m of middleware) { + result = m.apply(result); } - private constructor( - private readonly implementation: FetchFunction, - private readonly middleware: FetchMiddleware[], - ) {} - - with(middleware: FetchMiddleware): FetchApiBuilder { - return new FetchApiBuilder(this.implementation, [ - ...this.middleware, - middleware, - ]); - } - - build(): FetchApi { - let result = this.implementation; - - for (const m of this.middleware) { - result = m.apply(result); - } - - return { - fetch: result, - }; - } + return { + fetch: result, + }; } diff --git a/packages/core-app-api/src/apis/implementations/FetchApi/index.ts b/packages/core-app-api/src/apis/implementations/FetchApi/index.ts index 7544bd8bf2..0f82a9020b 100644 --- a/packages/core-app-api/src/apis/implementations/FetchApi/index.ts +++ b/packages/core-app-api/src/apis/implementations/FetchApi/index.ts @@ -14,7 +14,6 @@ * limitations under the License. */ -export { BackstageProtocolResolverFetchMiddleware } from './BackstageProtocolResolverFetchMiddleware'; -export { FetchApiBuilder } from './FetchApiBuilder'; -export { IdentityAwareFetchMiddleware } from './IdentityAwareFetchMiddleware'; -export type { FetchFunction, FetchMiddleware } from './types'; +export { createFetchApi } from './createFetchApi'; +export { FetchMiddlewares } from './FetchMiddlewares'; +export type { FetchMiddleware } from './types'; diff --git a/packages/core-app-api/src/apis/implementations/FetchApi/types.ts b/packages/core-app-api/src/apis/implementations/FetchApi/types.ts index 4cf0bf47f4..5bf029cbf0 100644 --- a/packages/core-app-api/src/apis/implementations/FetchApi/types.ts +++ b/packages/core-app-api/src/apis/implementations/FetchApi/types.ts @@ -14,15 +14,6 @@ * limitations under the License. */ -import crossFetch from 'cross-fetch'; - -/** - * The type of a fetch call. - * - * @public - */ -export type FetchFunction = typeof crossFetch; - /** * A middleware that modifies the behavior of an ongoing fetch. * @@ -35,5 +26,5 @@ export interface FetchMiddleware { * @param next - The next, inner, implementation, that this middleware shall * call out to as part of the request cycle. */ - apply(next: FetchFunction): FetchFunction; + apply(next: typeof fetch): typeof fetch; } diff --git a/packages/core-plugin-api/api-report.md b/packages/core-plugin-api/api-report.md index 148115fd69..67c10837ac 100644 --- a/packages/core-plugin-api/api-report.md +++ b/packages/core-plugin-api/api-report.md @@ -9,7 +9,6 @@ import { BackstagePlugin as BackstagePlugin_2 } from '@backstage/core-plugin-api import { BackstageTheme } from '@backstage/theme'; import { ComponentType } from 'react'; import { Config } from '@backstage/config'; -import { default as fetch_2 } from 'cross-fetch'; import { IconComponent as IconComponent_2 } from '@backstage/core-plugin-api'; import { IdentityApi as IdentityApi_2 } from '@backstage/core-plugin-api'; import { Observable as Observable_2 } from '@backstage/types'; @@ -508,7 +507,7 @@ export enum FeatureFlagState { // @public export type FetchApi = { - fetch: typeof fetch_2; + fetch: typeof fetch; }; // @public diff --git a/packages/core-plugin-api/package.json b/packages/core-plugin-api/package.json index 365cec3134..72827bde73 100644 --- a/packages/core-plugin-api/package.json +++ b/packages/core-plugin-api/package.json @@ -34,7 +34,6 @@ "@backstage/types": "^0.1.1", "@backstage/version-bridge": "^0.1.1", "@material-ui/core": "^4.12.2", - "cross-fetch": "^3.0.6", "history": "^5.0.0", "prop-types": "^15.7.2", "react-router-dom": "6.0.0-beta.0", @@ -57,6 +56,7 @@ "@types/node": "^14.14.32", "@types/prop-types": "^15.7.3", "@types/zen-observable": "^0.8.0", + "cross-fetch": "^3.0.6", "msw": "^0.35.0" }, "files": [ diff --git a/packages/core-plugin-api/src/apis/definitions/FetchApi.ts b/packages/core-plugin-api/src/apis/definitions/FetchApi.ts index 30eb950634..ba304157ea 100644 --- a/packages/core-plugin-api/src/apis/definitions/FetchApi.ts +++ b/packages/core-plugin-api/src/apis/definitions/FetchApi.ts @@ -14,7 +14,6 @@ * limitations under the License. */ -import fetch from 'cross-fetch'; import { ApiRef, createApiRef } from '../system'; /** diff --git a/plugins/catalog/api-report.md b/plugins/catalog/api-report.md index 2be7fc8575..80271c89af 100644 --- a/plugins/catalog/api-report.md +++ b/plugins/catalog/api-report.md @@ -66,7 +66,7 @@ export type BackstageOverrides = Overrides & { // Warning: (ae-missing-release-tag) "CatalogClientWrapper" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // -// @public +// @public @deprecated export class CatalogClientWrapper implements CatalogApi { constructor(options: { client: CatalogClient; identityApi: IdentityApi }); // (undocumented) diff --git a/plugins/catalog/src/CatalogClientWrapper.ts b/plugins/catalog/src/CatalogClientWrapper.ts index 0463cbf30e..c5f072e96c 100644 --- a/plugins/catalog/src/CatalogClientWrapper.ts +++ b/plugins/catalog/src/CatalogClientWrapper.ts @@ -30,6 +30,13 @@ import { IdentityApi } from '@backstage/core-plugin-api'; /** * CatalogClient wrapper that injects identity token for all requests + * + * @deprecated The default catalog client now uses the `fetchApiRef` + * implementation, which in turn by default issues tokens just the same as this + * class used to assist in doing. If you use a custom `fetchApiRef` + * implementation that does NOT issue tokens, or use a custom `catalogApiRef` + * implementation which does not use the default `fetchApiRef`, you can wrap + * your catalog API in this class to get back the old behavior. */ export class CatalogClientWrapper implements CatalogApi { private readonly identityApi: IdentityApi; diff --git a/plugins/catalog/src/plugin.ts b/plugins/catalog/src/plugin.ts index 20f937b2e7..66fdf4638f 100644 --- a/plugins/catalog/src/plugin.ts +++ b/plugins/catalog/src/plugin.ts @@ -22,7 +22,6 @@ import { entityRouteRef, starredEntitiesApiRef, } from '@backstage/plugin-catalog-react'; -import { CatalogClientWrapper } from './CatalogClientWrapper'; import { createComponentRouteRef, viewTechDocRouteRef } from './routes'; import { createApiFactory, @@ -30,7 +29,7 @@ import { createPlugin, createRoutableExtension, discoveryApiRef, - identityApiRef, + fetchApiRef, storageApiRef, } from '@backstage/core-plugin-api'; @@ -39,14 +38,13 @@ export const catalogPlugin = createPlugin({ apis: [ createApiFactory({ api: catalogApiRef, - deps: { discoveryApi: discoveryApiRef, identityApi: identityApiRef }, - factory: ({ discoveryApi, identityApi }) => - new CatalogClientWrapper({ - client: new CatalogClient({ discoveryApi }), - identityApi, - }), + deps: { + discoveryApi: discoveryApiRef, + fetchApi: fetchApiRef, + }, + factory: ({ discoveryApi, fetchApi }) => + new CatalogClient({ discoveryApi, fetchApi }), }), - createApiFactory({ api: starredEntitiesApiRef, deps: { storageApi: storageApiRef }, From 6e5f6621876f4c20c040f73aeba702ea16cdcaa9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Dec 2021 04:20:04 +0000 Subject: [PATCH 36/39] build(deps): bump mock-fs from 5.1.0 to 5.1.2 Bumps [mock-fs](https://github.com/tschaub/mock-fs) from 5.1.0 to 5.1.2. - [Release notes](https://github.com/tschaub/mock-fs/releases) - [Changelog](https://github.com/tschaub/mock-fs/blob/main/changelog.md) - [Commits](https://github.com/tschaub/mock-fs/compare/v5.1.0...v5.1.2) --- updated-dependencies: - dependency-name: mock-fs dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- yarn.lock | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/yarn.lock b/yarn.lock index d6b47335ef..cca08863df 100644 --- a/yarn.lock +++ b/yarn.lock @@ -21282,12 +21282,7 @@ mkdirp@^1.0.3, mkdirp@^1.0.4: resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== -mock-fs@^5.1.0: - version "5.1.0" - resolved "https://registry.npmjs.org/mock-fs/-/mock-fs-5.1.0.tgz#a9aebd4e6d74a626f84b86eae8a372bd061754e8" - integrity sha512-wXdQ2nIk81TYIGLphUnbXl8akQpjb9ItfZefMcTxZcoe+djMkd5POU8fQdSEErxVAeT4CgDHWveYquys4H6Cmw== - -mock-fs@^5.1.1: +mock-fs@^5.1.0, mock-fs@^5.1.1: version "5.1.2" resolved "https://registry.npmjs.org/mock-fs/-/mock-fs-5.1.2.tgz#6fa486e06d00f8793a8d2228de980eff93ce6db7" integrity sha512-YkjQkdLulFrz0vD4BfNQdQRVmgycXTV7ykuHMlyv+C8WCHazpkiQRDthwa02kSyo8wKnY9wRptHfQLgmf0eR+A== From ef6a039e074f656f9671dbd50100f644f6dcae2e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 16 Dec 2021 08:56:38 +0000 Subject: [PATCH 37/39] Version Packages --- ...w-client-method-to-elastic-search-egine.md | 6 -- .changeset/beige-mangos-knock.md | 5 -- .changeset/beige-news-cover.md | 5 -- .changeset/cold-dolls-beam.md | 5 -- .changeset/cool-cows-report.md | 5 -- .changeset/eight-insects-kiss.md | 5 -- .changeset/five-cats-hunt.md | 5 -- .changeset/mighty-llamas-hope.md | 5 -- .changeset/nervous-hounds-attend.md | 5 -- .changeset/nice-seahorses-look.md | 5 -- .changeset/org-ownershipcard-filteradded.md | 5 -- .changeset/pink-ladybugs-share.md | 6 -- .changeset/shaggy-bears-remember.md | 6 -- .changeset/silly-dryers-smile.md | 58 ----------------- .changeset/spicy-parents-fold.md | 13 ---- .changeset/strong-doors-destroy.md | 5 -- .changeset/strong-paws-laugh.md | 5 -- .changeset/stupid-mice-dream.md | 5 -- .changeset/sweet-camels-learn.md | 5 -- .changeset/techdocs-forty-pumas-compete.md | 5 -- .changeset/thirty-ways-attend.md | 5 -- .changeset/weak-berries-heal.md | 14 ---- .changeset/young-students-applaud.md | 11 ---- packages/app/CHANGELOG.md | 18 ++++++ packages/app/package.json | 26 ++++---- packages/backend-common/CHANGELOG.md | 7 ++ packages/backend-common/package.json | 4 +- packages/backend/CHANGELOG.md | 14 ++++ packages/backend/package.json | 20 +++--- packages/catalog-model/CHANGELOG.md | 6 ++ packages/catalog-model/package.json | 4 +- packages/cli/CHANGELOG.md | 6 ++ packages/cli/package.json | 10 +-- packages/codemods/CHANGELOG.md | 9 +++ packages/codemods/package.json | 2 +- packages/core-app-api/CHANGELOG.md | 10 +++ packages/core-app-api/package.json | 8 +-- packages/core-components/CHANGELOG.md | 10 +++ packages/core-components/package.json | 8 +-- packages/core-plugin-api/CHANGELOG.md | 14 ++++ packages/core-plugin-api/package.json | 6 +- packages/create-app/CHANGELOG.md | 14 ++++ packages/create-app/package.json | 2 +- plugins/allure/package.json | 8 +-- plugins/analytics-module-ga/package.json | 8 +-- plugins/apache-airflow/CHANGELOG.md | 22 +++++++ plugins/apache-airflow/package.json | 10 +-- plugins/api-docs/package.json | 8 +-- plugins/auth-backend/CHANGELOG.md | 9 +++ plugins/auth-backend/package.json | 8 +-- plugins/azure-devops-backend/CHANGELOG.md | 61 ++++++++++++++++++ plugins/azure-devops-backend/package.json | 8 +-- plugins/azure-devops-common/CHANGELOG.md | 57 +++++++++++++++++ plugins/azure-devops-common/package.json | 4 +- plugins/azure-devops/CHANGELOG.md | 64 +++++++++++++++++++ plugins/azure-devops/package.json | 16 ++--- plugins/badges/package.json | 8 +-- plugins/bazaar/package.json | 6 +- plugins/bitrise/package.json | 8 +-- plugins/catalog-backend/CHANGELOG.md | 9 +++ plugins/catalog-backend/package.json | 8 +-- plugins/catalog-graph/package.json | 8 +-- plugins/catalog-import/package.json | 8 +-- plugins/catalog-react/CHANGELOG.md | 10 +++ plugins/catalog-react/package.json | 12 ++-- plugins/catalog/package.json | 8 +-- plugins/circleci/package.json | 8 +-- plugins/cloudbuild/package.json | 8 +-- plugins/code-coverage/package.json | 8 +-- plugins/config-schema/package.json | 8 +-- plugins/cost-insights/package.json | 8 +-- plugins/explore/package.json | 8 +-- plugins/firehydrant/package.json | 8 +-- plugins/fossa/package.json | 8 +-- plugins/gcp-projects/package.json | 8 +-- plugins/git-release-manager/package.json | 8 +-- plugins/github-actions/CHANGELOG.md | 11 ++++ plugins/github-actions/package.json | 14 ++-- plugins/github-deployments/package.json | 8 +-- plugins/gitops-profiles/package.json | 8 +-- plugins/graphiql/package.json | 8 +-- plugins/home/package.json | 8 +-- plugins/ilert/package.json | 8 +-- plugins/jenkins/package.json | 8 +-- plugins/kafka/package.json | 8 +-- plugins/kubernetes/CHANGELOG.md | 11 ++++ plugins/kubernetes/package.json | 14 ++-- plugins/lighthouse/package.json | 8 +-- plugins/newrelic/package.json | 8 +-- plugins/org/CHANGELOG.md | 11 ++++ plugins/org/package.json | 14 ++-- plugins/pagerduty/package.json | 8 +-- plugins/rollbar/package.json | 8 +-- plugins/scaffolder-backend/CHANGELOG.md | 11 ++++ plugins/scaffolder-backend/package.json | 10 +-- plugins/scaffolder/package.json | 10 +-- .../CHANGELOG.md | 7 ++ .../package.json | 6 +- plugins/search/package.json | 8 +-- plugins/sentry/package.json | 8 +-- plugins/shortcuts/package.json | 8 +-- plugins/sonarqube/package.json | 8 +-- plugins/splunk-on-call/package.json | 8 +-- plugins/tech-insights/package.json | 24 +++---- plugins/tech-radar/package.json | 8 +-- plugins/techdocs/CHANGELOG.md | 11 ++++ plugins/techdocs/package.json | 14 ++-- plugins/todo/package.json | 8 +-- plugins/user-settings/package.json | 8 +-- plugins/xcmetrics/package.json | 8 +-- 110 files changed, 688 insertions(+), 480 deletions(-) delete mode 100644 .changeset/add-new-client-method-to-elastic-search-egine.md delete mode 100644 .changeset/beige-mangos-knock.md delete mode 100644 .changeset/beige-news-cover.md delete mode 100644 .changeset/cold-dolls-beam.md delete mode 100644 .changeset/cool-cows-report.md delete mode 100644 .changeset/eight-insects-kiss.md delete mode 100644 .changeset/five-cats-hunt.md delete mode 100644 .changeset/mighty-llamas-hope.md delete mode 100644 .changeset/nervous-hounds-attend.md delete mode 100644 .changeset/nice-seahorses-look.md delete mode 100644 .changeset/org-ownershipcard-filteradded.md delete mode 100644 .changeset/pink-ladybugs-share.md delete mode 100644 .changeset/shaggy-bears-remember.md delete mode 100644 .changeset/silly-dryers-smile.md delete mode 100644 .changeset/spicy-parents-fold.md delete mode 100644 .changeset/strong-doors-destroy.md delete mode 100644 .changeset/strong-paws-laugh.md delete mode 100644 .changeset/stupid-mice-dream.md delete mode 100644 .changeset/sweet-camels-learn.md delete mode 100644 .changeset/techdocs-forty-pumas-compete.md delete mode 100644 .changeset/thirty-ways-attend.md delete mode 100644 .changeset/weak-berries-heal.md delete mode 100644 .changeset/young-students-applaud.md create mode 100644 plugins/apache-airflow/CHANGELOG.md diff --git a/.changeset/add-new-client-method-to-elastic-search-egine.md b/.changeset/add-new-client-method-to-elastic-search-egine.md deleted file mode 100644 index 9e5c363522..0000000000 --- a/.changeset/add-new-client-method-to-elastic-search-egine.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-search-backend-module-elasticsearch': patch ---- - -Add `newClient()` method to re-use the configuration of the elastic search -engine with custom clients diff --git a/.changeset/beige-mangos-knock.md b/.changeset/beige-mangos-knock.md deleted file mode 100644 index d8723c3f87..0000000000 --- a/.changeset/beige-mangos-knock.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-github-actions': patch ---- - -Show empty state only when workflow API call has completed diff --git a/.changeset/beige-news-cover.md b/.changeset/beige-news-cover.md deleted file mode 100644 index 70cebcd76f..0000000000 --- a/.changeset/beige-news-cover.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-app-api': patch ---- - -Deprecated `Auth0Auth`, pointing to using `OAuth2` directly instead. diff --git a/.changeset/cold-dolls-beam.md b/.changeset/cold-dolls-beam.md deleted file mode 100644 index 5257cd5553..0000000000 --- a/.changeset/cold-dolls-beam.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-kubernetes': patch ---- - -Fixed styling bug for the CronJobsAccordions and updated Completed pods to display a green dot. diff --git a/.changeset/cool-cows-report.md b/.changeset/cool-cows-report.md deleted file mode 100644 index 2b183e39c2..0000000000 --- a/.changeset/cool-cows-report.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-plugin-api': patch ---- - -Deprecated the `AnyAnalyticsContext` type and mark the `AnalyticsApi` experimental. diff --git a/.changeset/eight-insects-kiss.md b/.changeset/eight-insects-kiss.md deleted file mode 100644 index 4b09829bf3..0000000000 --- a/.changeset/eight-insects-kiss.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-components': patch ---- - -Items in `` are now only active when their full path is active (including search parameters). diff --git a/.changeset/five-cats-hunt.md b/.changeset/five-cats-hunt.md deleted file mode 100644 index cf3364a23a..0000000000 --- a/.changeset/five-cats-hunt.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend': patch ---- - -Fixed the handling of optional locations so that the catalog no longer logs `NotFoundError`s for missing optional locations. diff --git a/.changeset/mighty-llamas-hope.md b/.changeset/mighty-llamas-hope.md deleted file mode 100644 index 7ea87e50d0..0000000000 --- a/.changeset/mighty-llamas-hope.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': patch ---- - -Makes cookiecutter a default, but optional action based on if a containerRunner argument is passed in to createRouter or createBuiltinActions diff --git a/.changeset/nervous-hounds-attend.md b/.changeset/nervous-hounds-attend.md deleted file mode 100644 index b54eb5a688..0000000000 --- a/.changeset/nervous-hounds-attend.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': patch ---- - -Adding changes to create GitLab Merge Request using custom action diff --git a/.changeset/nice-seahorses-look.md b/.changeset/nice-seahorses-look.md deleted file mode 100644 index 9652898c54..0000000000 --- a/.changeset/nice-seahorses-look.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-plugin-api': patch ---- - -Deprecated `auth0AuthApiRef`, `oauth2ApiRef`, `oidcAuthApiRef`, `samlAuthApiRef`, and marked the rest of the auth `ApiRef`s as experimental. For more information on how to address the deprecations, see https://backstage.io/docs/api/deprecations#generic-auth-api-refs. diff --git a/.changeset/org-ownershipcard-filteradded.md b/.changeset/org-ownershipcard-filteradded.md deleted file mode 100644 index cbd1475bb1..0000000000 --- a/.changeset/org-ownershipcard-filteradded.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-org': patch ---- - -Added `entityFilterKind` property for `EntityOwnershipCard` diff --git a/.changeset/pink-ladybugs-share.md b/.changeset/pink-ladybugs-share.md deleted file mode 100644 index 83f5b8b78a..0000000000 --- a/.changeset/pink-ladybugs-share.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/backend-common': patch ---- - -Each plugin now saves to a separate sqlite database file when `connection.filename` is provided in the sqlite config. -Any existing sqlite database files will be ignored. diff --git a/.changeset/shaggy-bears-remember.md b/.changeset/shaggy-bears-remember.md deleted file mode 100644 index d041abb3d1..0000000000 --- a/.changeset/shaggy-bears-remember.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/core-app-api': patch -'@backstage/core-components': patch ---- - -Switched out usage of deprecated `OAuthRequestApi` types from `@backstage/core-plugin-api`. diff --git a/.changeset/silly-dryers-smile.md b/.changeset/silly-dryers-smile.md deleted file mode 100644 index 7337651532..0000000000 --- a/.changeset/silly-dryers-smile.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -'@backstage/plugin-azure-devops': patch -'@backstage/plugin-azure-devops-backend': patch -'@backstage/plugin-azure-devops-common': patch ---- - -Created some initial filters that can be used to create pull request columns: - -- All -- AssignedToUser -- AssignedToCurrentUser -- AssignedToTeam -- AssignedToTeams -- AssignedToCurrentUsersTeams -- CreatedByUser -- CreatedByCurrentUser -- CreatedByTeam -- CreatedByTeams -- CreatedByCurrentUsersTeams - -Example custom column creation: - -```tsx -const COLUMN_CONFIGS: PullRequestColumnConfig[] = [ - { - title: 'Created by me', - filters: [{ type: FilterType.CreatedByCurrentUser }], - }, - { - title: 'Created by Backstage Core', - filters: [ - { - type: FilterType.CreatedByTeam, - teamName: 'Backstage Core', - }, - ], - }, - { - title: 'Assigned to my teams', - filters: [{ type: FilterType.AssignedToCurrentUsersTeams }], - }, - { - title: 'Other PRs', - filters: [{ type: FilterType.All }], - simplified: true, - }, -]; - - - } -/>; -``` diff --git a/.changeset/spicy-parents-fold.md b/.changeset/spicy-parents-fold.md deleted file mode 100644 index 1ba056c7c8..0000000000 --- a/.changeset/spicy-parents-fold.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -'@backstage/create-app': patch ---- - -Updated the root `package.json` to include files with `.cjs` and `.mjs` extensions in the `"lint-staged"` configuration. - -To make this change to an existing app, apply the following changes to the `package.json` file: - -```diff - "lint-staged": { -- "*.{js,jsx,ts,tsx}": [ -+ "*.{js,jsx,ts,tsx,mjs,cjs}": [ -``` diff --git a/.changeset/strong-doors-destroy.md b/.changeset/strong-doors-destroy.md deleted file mode 100644 index d568ed4e07..0000000000 --- a/.changeset/strong-doors-destroy.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Add support for `.cjs` and `.mjs` extensions in local and dependency modules. diff --git a/.changeset/strong-paws-laugh.md b/.changeset/strong-paws-laugh.md deleted file mode 100644 index de39440e34..0000000000 --- a/.changeset/strong-paws-laugh.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-auth-backend': patch ---- - -export minimal typescript types for OIDC provider diff --git a/.changeset/stupid-mice-dream.md b/.changeset/stupid-mice-dream.md deleted file mode 100644 index 2cd2b4e067..0000000000 --- a/.changeset/stupid-mice-dream.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-components': patch ---- - -Add Missing Override Components Type for SidebarSpace, SidebarSpacer, and SidebarDivider Components. diff --git a/.changeset/sweet-camels-learn.md b/.changeset/sweet-camels-learn.md deleted file mode 100644 index 60481b9363..0000000000 --- a/.changeset/sweet-camels-learn.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/catalog-model': patch ---- - -Added an optional `presence` field to Location spec, which describes whether the target of a location is required to exist or not. It defaults to `'required'`, which is the current behaviour of the catalog. diff --git a/.changeset/techdocs-forty-pumas-compete.md b/.changeset/techdocs-forty-pumas-compete.md deleted file mode 100644 index 929ce3e2c9..0000000000 --- a/.changeset/techdocs-forty-pumas-compete.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-techdocs': patch ---- - -Fix issue where assets weren't being fetched from the correct URL path for doc URLs without trailing slashes diff --git a/.changeset/thirty-ways-attend.md b/.changeset/thirty-ways-attend.md deleted file mode 100644 index b294b4bfb0..0000000000 --- a/.changeset/thirty-ways-attend.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-react': patch ---- - -`useEntityTypeFilter`: Skip updating selected types if a kind filter change did not change them. diff --git a/.changeset/weak-berries-heal.md b/.changeset/weak-berries-heal.md deleted file mode 100644 index 4160d078fc..0000000000 --- a/.changeset/weak-berries-heal.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -'@backstage/plugin-apache-airflow': minor ---- - -Introduces a new plugin for the Apache Airflow workflow management platform. -This implementation has been tested with the Apache Airflow v2 API, -authenticating with basic authentication through the Backstage proxy plugin. - -Supported functionality includes: - -- Information card of version information of the Airflow instance -- Information card of instance health for the meta-database and scheduler -- Table of DAGs with meta information and status, along with a link to view - details in the Airflow UI diff --git a/.changeset/young-students-applaud.md b/.changeset/young-students-applaud.md deleted file mode 100644 index bbd825cf00..0000000000 --- a/.changeset/young-students-applaud.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -'@backstage/core-plugin-api': patch ---- - -Renamed `AuthProvider` to `AuthProviderInfo` and add a required 'id' property to match the majority of usage. The `AuthProvider` type without the `id` property still exists but is deprecated, and all usage of it without an `id` is deprecated as well. For example, calling `createAuthRequest` without a `provider.id` is deprecated and it will be required in the future. - -The following types have been renamed. The old names are still exported but deprecated, and are scheduled for removal in a future release. - -- Renamed `AuthRequesterOptions` to `OAuthRequesterOptions` -- Renamed `AuthRequester` to `OAuthRequester` -- Renamed `PendingAuthRequest` to `PendingOAuthRequest` diff --git a/packages/app/CHANGELOG.md b/packages/app/CHANGELOG.md index 3f3ac75853..d1055a54bf 100644 --- a/packages/app/CHANGELOG.md +++ b/packages/app/CHANGELOG.md @@ -1,5 +1,23 @@ # example-app +## 0.2.57 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-github-actions@0.4.27 + - @backstage/core-app-api@0.2.1 + - @backstage/plugin-kubernetes@0.5.1 + - @backstage/core-plugin-api@0.3.1 + - @backstage/core-components@0.8.1 + - @backstage/plugin-org@0.3.31 + - @backstage/plugin-azure-devops@0.1.7 + - @backstage/cli@0.10.2 + - @backstage/catalog-model@0.9.8 + - @backstage/plugin-techdocs@0.12.10 + - @backstage/plugin-catalog-react@0.6.7 + - @backstage/plugin-apache-airflow@0.1.0 + ## 0.2.56 ### Patch Changes diff --git a/packages/app/package.json b/packages/app/package.json index 99b90952e3..a9e8e8ddc8 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,39 +1,39 @@ { "name": "example-app", - "version": "0.2.56", + "version": "0.2.57", "private": true, "bundled": true, "dependencies": { "@backstage/app-defaults": "^0.1.2", - "@backstage/catalog-model": "^0.9.7", - "@backstage/cli": "^0.10.1", - "@backstage/core-app-api": "^0.2.0", - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/catalog-model": "^0.9.8", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/integration-react": "^0.1.15", "@backstage/plugin-api-docs": "^0.6.18", - "@backstage/plugin-azure-devops": "^0.1.6", - "@backstage/plugin-apache-airflow": "^0.0.0", + "@backstage/plugin-azure-devops": "^0.1.7", + "@backstage/plugin-apache-airflow": "^0.1.0", "@backstage/plugin-badges": "^0.2.16", "@backstage/plugin-catalog": "^0.7.4", "@backstage/plugin-catalog-graph": "^0.2.3", "@backstage/plugin-catalog-import": "^0.7.5", - "@backstage/plugin-catalog-react": "^0.6.5", + "@backstage/plugin-catalog-react": "^0.6.7", "@backstage/plugin-circleci": "^0.2.31", "@backstage/plugin-cloudbuild": "^0.2.29", "@backstage/plugin-code-coverage": "^0.1.19", "@backstage/plugin-cost-insights": "^0.11.13", "@backstage/plugin-explore": "^0.3.22", "@backstage/plugin-gcp-projects": "^0.3.10", - "@backstage/plugin-github-actions": "^0.4.26", + "@backstage/plugin-github-actions": "^0.4.27", "@backstage/plugin-graphiql": "^0.2.24", "@backstage/plugin-home": "^0.4.7", "@backstage/plugin-jenkins": "^0.5.14", "@backstage/plugin-kafka": "^0.2.22", - "@backstage/plugin-kubernetes": "^0.5.0", + "@backstage/plugin-kubernetes": "^0.5.1", "@backstage/plugin-lighthouse": "^0.2.31", "@backstage/plugin-newrelic": "^0.3.10", - "@backstage/plugin-org": "^0.3.30", + "@backstage/plugin-org": "^0.3.31", "@backstage/plugin-pagerduty": "0.3.19", "@backstage/plugin-rollbar": "^0.3.20", "@backstage/plugin-scaffolder": "^0.11.14", @@ -41,7 +41,7 @@ "@backstage/plugin-sentry": "^0.3.30", "@backstage/plugin-shortcuts": "^0.1.15", "@backstage/plugin-tech-radar": "^0.4.13", - "@backstage/plugin-techdocs": "^0.12.9", + "@backstage/plugin-techdocs": "^0.12.10", "@backstage/plugin-todo": "^0.1.16", "@backstage/plugin-user-settings": "^0.3.13", "@backstage/search-common": "^0.2.0", diff --git a/packages/backend-common/CHANGELOG.md b/packages/backend-common/CHANGELOG.md index ad3fb33365..4bd21df721 100644 --- a/packages/backend-common/CHANGELOG.md +++ b/packages/backend-common/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/backend-common +## 0.9.14 + +### Patch Changes + +- fe24bc9a32: Each plugin now saves to a separate sqlite database file when `connection.filename` is provided in the sqlite config. + Any existing sqlite database files will be ignored. + ## 0.9.13 ### Patch Changes diff --git a/packages/backend-common/package.json b/packages/backend-common/package.json index 824b676c82..91b8f46255 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.9.13", + "version": "0.9.14", "main": "src/index.ts", "types": "src/index.ts", "private": false, @@ -81,7 +81,7 @@ } }, "devDependencies": { - "@backstage/cli": "^0.10.1", + "@backstage/cli": "^0.10.2", "@backstage/test-utils": "^0.1.24", "@types/archiver": "^5.1.0", "@types/compression": "^1.7.0", diff --git a/packages/backend/CHANGELOG.md b/packages/backend/CHANGELOG.md index fa8632e2ef..9c7b00b61f 100644 --- a/packages/backend/CHANGELOG.md +++ b/packages/backend/CHANGELOG.md @@ -1,5 +1,19 @@ # example-backend +## 0.2.57 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-module-elasticsearch@0.0.7 + - @backstage/plugin-catalog-backend@0.19.2 + - @backstage/plugin-scaffolder-backend@0.15.17 + - @backstage/backend-common@0.9.14 + - @backstage/plugin-azure-devops-backend@0.2.5 + - @backstage/plugin-auth-backend@0.5.1 + - @backstage/catalog-model@0.9.8 + - example-app@0.2.57 + ## 0.2.56 ### Patch Changes diff --git a/packages/backend/package.json b/packages/backend/package.json index ae61bc7a45..80ae3b0998 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -1,6 +1,6 @@ { "name": "example-backend", - "version": "0.2.56", + "version": "0.2.57", "main": "dist/index.cjs.js", "types": "src/index.ts", "license": "Apache-2.0", @@ -24,16 +24,16 @@ "migrate:create": "knex migrate:make -x ts" }, "dependencies": { - "@backstage/backend-common": "^0.9.13", + "@backstage/backend-common": "^0.9.14", "@backstage/catalog-client": "^0.5.2", - "@backstage/catalog-model": "^0.9.7", + "@backstage/catalog-model": "^0.9.8", "@backstage/config": "^0.1.10", "@backstage/integration": "^0.6.10", "@backstage/plugin-app-backend": "^0.3.19", - "@backstage/plugin-auth-backend": "^0.5.0", - "@backstage/plugin-azure-devops-backend": "^0.2.4", + "@backstage/plugin-auth-backend": "^0.5.1", + "@backstage/plugin-azure-devops-backend": "^0.2.5", "@backstage/plugin-badges-backend": "^0.1.13", - "@backstage/plugin-catalog-backend": "^0.19.1", + "@backstage/plugin-catalog-backend": "^0.19.2", "@backstage/plugin-code-coverage-backend": "^0.1.16", "@backstage/plugin-graphql-backend": "^0.1.9", "@backstage/plugin-jenkins-backend": "^0.1.9", @@ -41,11 +41,11 @@ "@backstage/plugin-kafka-backend": "^0.2.12", "@backstage/plugin-proxy-backend": "^0.2.14", "@backstage/plugin-rollbar-backend": "^0.1.16", - "@backstage/plugin-scaffolder-backend": "^0.15.16", + "@backstage/plugin-scaffolder-backend": "^0.15.17", "@backstage/plugin-scaffolder-backend-module-rails": "^0.2.0", "@backstage/plugin-search-backend": "^0.2.8", "@backstage/plugin-search-backend-node": "^0.4.2", - "@backstage/plugin-search-backend-module-elasticsearch": "^0.0.6", + "@backstage/plugin-search-backend-module-elasticsearch": "^0.0.7", "@backstage/plugin-search-backend-module-pg": "^0.2.2", "@backstage/plugin-techdocs-backend": "^0.12.0", "@backstage/plugin-tech-insights-backend": "^0.1.3", @@ -56,7 +56,7 @@ "@octokit/rest": "^18.5.3", "azure-devops-node-api": "^11.0.1", "dockerode": "^3.3.1", - "example-app": "^0.2.56", + "example-app": "^0.2.57", "express": "^4.17.1", "express-promise-router": "^4.1.0", "express-prom-bundle": "^6.3.6", @@ -68,7 +68,7 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/cli": "^0.10.1", + "@backstage/cli": "^0.10.2", "@types/dockerode": "^3.3.0", "@types/express": "^4.17.6", "@types/express-serve-static-core": "^4.17.5" diff --git a/packages/catalog-model/CHANGELOG.md b/packages/catalog-model/CHANGELOG.md index efd6513cdd..8c0a65c20a 100644 --- a/packages/catalog-model/CHANGELOG.md +++ b/packages/catalog-model/CHANGELOG.md @@ -1,5 +1,11 @@ # @backstage/catalog-model +## 0.9.8 + +### Patch Changes + +- ad7338bb48: Added an optional `presence` field to Location spec, which describes whether the target of a location is required to exist or not. It defaults to `'required'`, which is the current behaviour of the catalog. + ## 0.9.7 ### Patch Changes diff --git a/packages/catalog-model/package.json b/packages/catalog-model/package.json index 60331d9dc8..6fdc89bdfb 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": "0.9.7", + "version": "0.9.8", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -42,7 +42,7 @@ "yup": "^0.32.9" }, "devDependencies": { - "@backstage/cli": "^0.10.0", + "@backstage/cli": "^0.10.2", "@types/jest": "^26.0.7", "@types/lodash": "^4.14.151", "yaml": "^1.9.2" diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index 0c30e8b251..5d51ea890b 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,11 @@ # @backstage/cli +## 0.10.2 + +### Patch Changes + +- 25dfc2d483: Add support for `.cjs` and `.mjs` extensions in local and dependency modules. + ## 0.10.1 ### Patch Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index 4208662f76..4b59d46827 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.10.1", + "version": "0.10.2", "private": false, "publishConfig": { "access": "public" @@ -116,11 +116,11 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/backend-common": "^0.9.13", + "@backstage/backend-common": "^0.9.14", "@backstage/config": "^0.1.11", - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", - "@backstage/core-app-api": "^0.2.0", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", + "@backstage/core-app-api": "^0.2.1", "@backstage/dev-utils": "^0.2.14", "@backstage/test-utils": "^0.1.24", "@backstage/theme": "^0.2.14", diff --git a/packages/codemods/CHANGELOG.md b/packages/codemods/CHANGELOG.md index d7e402270a..803579a963 100644 --- a/packages/codemods/CHANGELOG.md +++ b/packages/codemods/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/codemods +## 0.1.26 + +### Patch Changes + +- Updated dependencies + - @backstage/core-app-api@0.2.1 + - @backstage/core-plugin-api@0.3.1 + - @backstage/core-components@0.8.1 + ## 0.1.25 ### Patch Changes diff --git a/packages/codemods/package.json b/packages/codemods/package.json index 32bf6be518..8261e30547 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.25", + "version": "0.1.26", "private": false, "publishConfig": { "access": "public", diff --git a/packages/core-app-api/CHANGELOG.md b/packages/core-app-api/CHANGELOG.md index ff15f45898..66e0c7d6ed 100644 --- a/packages/core-app-api/CHANGELOG.md +++ b/packages/core-app-api/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/core-app-api +## 0.2.1 + +### Patch Changes + +- c11ce4f552: Deprecated `Auth0Auth`, pointing to using `OAuth2` directly instead. +- 9d6503e86c: Switched out usage of deprecated `OAuthRequestApi` types from `@backstage/core-plugin-api`. +- Updated dependencies + - @backstage/core-plugin-api@0.3.1 + - @backstage/core-components@0.8.1 + ## 0.2.0 ### Minor Changes diff --git a/packages/core-app-api/package.json b/packages/core-app-api/package.json index 23079d7ba0..166f39a484 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": "0.2.0", + "version": "0.2.1", "private": false, "publishConfig": { "access": "public", @@ -30,9 +30,9 @@ }, "dependencies": { "@backstage/app-defaults": "^0.1.2", - "@backstage/core-components": "^0.8.0", + "@backstage/core-components": "^0.8.1", "@backstage/config": "^0.1.11", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/theme": "^0.2.14", "@backstage/types": "^0.1.1", "@backstage/version-bridge": "^0.1.1", @@ -49,7 +49,7 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", + "@backstage/cli": "^0.10.2", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/packages/core-components/CHANGELOG.md b/packages/core-components/CHANGELOG.md index 4eab9cea54..2171a72ccb 100644 --- a/packages/core-components/CHANGELOG.md +++ b/packages/core-components/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/core-components +## 0.8.1 + +### Patch Changes + +- 2c17e5b073: Items in `` are now only active when their full path is active (including search parameters). +- 9d6503e86c: Switched out usage of deprecated `OAuthRequestApi` types from `@backstage/core-plugin-api`. +- 1680a1c5ac: Add Missing Override Components Type for SidebarSpace, SidebarSpacer, and SidebarDivider Components. +- Updated dependencies + - @backstage/core-plugin-api@0.3.1 + ## 0.8.0 ### Minor Changes diff --git a/packages/core-components/package.json b/packages/core-components/package.json index f47335fce8..b47a221227 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.8.0", + "version": "0.8.1", "private": false, "publishConfig": { "access": "public", @@ -30,7 +30,7 @@ }, "dependencies": { "@backstage/config": "^0.1.11", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/errors": "^0.1.5", "@backstage/theme": "^0.2.14", "@material-table/core": "^3.1.0", @@ -72,8 +72,8 @@ "react-dom": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/core-app-api": "^0.2.0", - "@backstage/cli": "^0.10.1", + "@backstage/core-app-api": "^0.2.1", + "@backstage/cli": "^0.10.2", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/packages/core-plugin-api/CHANGELOG.md b/packages/core-plugin-api/CHANGELOG.md index fdf64779fb..06d36ef486 100644 --- a/packages/core-plugin-api/CHANGELOG.md +++ b/packages/core-plugin-api/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/core-plugin-api +## 0.3.1 + +### Patch Changes + +- 18d4f500af: Deprecated the `AnyAnalyticsContext` type and mark the `AnalyticsApi` experimental. +- 8a7372cfd5: Deprecated `auth0AuthApiRef`, `oauth2ApiRef`, `oidcAuthApiRef`, `samlAuthApiRef`, and marked the rest of the auth `ApiRef`s as experimental. For more information on how to address the deprecations, see https://backstage.io/docs/api/deprecations#generic-auth-api-refs. +- 760791a642: Renamed `AuthProvider` to `AuthProviderInfo` and add a required 'id' property to match the majority of usage. The `AuthProvider` type without the `id` property still exists but is deprecated, and all usage of it without an `id` is deprecated as well. For example, calling `createAuthRequest` without a `provider.id` is deprecated and it will be required in the future. + + The following types have been renamed. The old names are still exported but deprecated, and are scheduled for removal in a future release. + + - Renamed `AuthRequesterOptions` to `OAuthRequesterOptions` + - Renamed `AuthRequester` to `OAuthRequester` + - Renamed `PendingAuthRequest` to `PendingOAuthRequest` + ## 0.3.0 ### Minor Changes diff --git a/packages/core-plugin-api/package.json b/packages/core-plugin-api/package.json index 72827bde73..20479acfeb 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": "0.3.0", + "version": "0.3.1", "private": false, "publishConfig": { "access": "public", @@ -45,8 +45,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/packages/create-app/CHANGELOG.md b/packages/create-app/CHANGELOG.md index cdcf7f4952..60d8a55635 100644 --- a/packages/create-app/CHANGELOG.md +++ b/packages/create-app/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/create-app +## 0.4.8 + +### Patch Changes + +- 25dfc2d483: Updated the root `package.json` to include files with `.cjs` and `.mjs` extensions in the `"lint-staged"` configuration. + + To make this change to an existing app, apply the following changes to the `package.json` file: + + ```diff + "lint-staged": { + - "*.{js,jsx,ts,tsx}": [ + + "*.{js,jsx,ts,tsx,mjs,cjs}": [ + ``` + ## 0.4.7 ### Patch Changes diff --git a/packages/create-app/package.json b/packages/create-app/package.json index e5108f540b..7a6c7ad551 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.7", + "version": "0.4.8", "private": false, "publishConfig": { "access": "public" diff --git a/plugins/allure/package.json b/plugins/allure/package.json index 8b3ee3b882..261c5e1879 100644 --- a/plugins/allure/package.json +++ b/plugins/allure/package.json @@ -23,8 +23,8 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.7", - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/plugin-catalog-react": "^0.6.5", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", @@ -37,8 +37,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/dev-utils": "^0.2.14", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/analytics-module-ga/package.json b/plugins/analytics-module-ga/package.json index 15055b2a4f..5f48d4404e 100644 --- a/plugins/analytics-module-ga/package.json +++ b/plugins/analytics-module-ga/package.json @@ -22,8 +22,8 @@ }, "dependencies": { "@backstage/config": "^0.1.5", - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -35,8 +35,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/dev-utils": "^0.2.14", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/apache-airflow/CHANGELOG.md b/plugins/apache-airflow/CHANGELOG.md new file mode 100644 index 0000000000..64abdb929a --- /dev/null +++ b/plugins/apache-airflow/CHANGELOG.md @@ -0,0 +1,22 @@ +# @backstage/plugin-apache-airflow + +## 0.1.0 + +### Minor Changes + +- 9aea335911: Introduces a new plugin for the Apache Airflow workflow management platform. + This implementation has been tested with the Apache Airflow v2 API, + authenticating with basic authentication through the Backstage proxy plugin. + + Supported functionality includes: + + - Information card of version information of the Airflow instance + - Information card of instance health for the meta-database and scheduler + - Table of DAGs with meta information and status, along with a link to view + details in the Airflow UI + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@0.3.1 + - @backstage/core-components@0.8.1 diff --git a/plugins/apache-airflow/package.json b/plugins/apache-airflow/package.json index a361961d12..58c5dceb77 100644 --- a/plugins/apache-airflow/package.json +++ b/plugins/apache-airflow/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-apache-airflow", - "version": "0.0.0", + "version": "0.1.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -20,8 +20,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", @@ -33,8 +33,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/dev-utils": "^0.2.14", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/api-docs/package.json b/plugins/api-docs/package.json index 93df7e68aa..fd057cf358 100644 --- a/plugins/api-docs/package.json +++ b/plugins/api-docs/package.json @@ -32,8 +32,8 @@ "dependencies": { "@asyncapi/react-component": "^1.0.0-next.25", "@backstage/catalog-model": "^0.9.7", - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/plugin-catalog": "^0.7.4", "@backstage/plugin-catalog-react": "^0.6.5", "@backstage/theme": "^0.2.14", @@ -54,8 +54,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/dev-utils": "^0.2.14", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/auth-backend/CHANGELOG.md b/plugins/auth-backend/CHANGELOG.md index dc45804449..cfdae9f4ef 100644 --- a/plugins/auth-backend/CHANGELOG.md +++ b/plugins/auth-backend/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-auth-backend +## 0.5.1 + +### Patch Changes + +- 699c2e9ddc: export minimal typescript types for OIDC provider +- Updated dependencies + - @backstage/backend-common@0.9.14 + - @backstage/catalog-model@0.9.8 + ## 0.5.0 ### Minor Changes diff --git a/plugins/auth-backend/package.json b/plugins/auth-backend/package.json index b2822c4f33..c7d208eef2 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.5.0", + "version": "0.5.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -30,9 +30,9 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.9.13", + "@backstage/backend-common": "^0.9.14", "@backstage/catalog-client": "^0.5.2", - "@backstage/catalog-model": "^0.9.7", + "@backstage/catalog-model": "^0.9.8", "@backstage/config": "^0.1.11", "@backstage/errors": "^0.1.5", "@backstage/test-utils": "^0.1.24", @@ -73,7 +73,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", + "@backstage/cli": "^0.10.2", "@types/body-parser": "^1.19.0", "@types/cookie-parser": "^1.4.2", "@types/express-session": "^1.17.2", diff --git a/plugins/azure-devops-backend/CHANGELOG.md b/plugins/azure-devops-backend/CHANGELOG.md index e0e74a9bc6..ff802a30e1 100644 --- a/plugins/azure-devops-backend/CHANGELOG.md +++ b/plugins/azure-devops-backend/CHANGELOG.md @@ -1,5 +1,66 @@ # @backstage/plugin-azure-devops-backend +## 0.2.5 + +### Patch Changes + +- daf32e2c9b: Created some initial filters that can be used to create pull request columns: + + - All + - AssignedToUser + - AssignedToCurrentUser + - AssignedToTeam + - AssignedToTeams + - AssignedToCurrentUsersTeams + - CreatedByUser + - CreatedByCurrentUser + - CreatedByTeam + - CreatedByTeams + - CreatedByCurrentUsersTeams + + Example custom column creation: + + ```tsx + const COLUMN_CONFIGS: PullRequestColumnConfig[] = [ + { + title: 'Created by me', + filters: [{ type: FilterType.CreatedByCurrentUser }], + }, + { + title: 'Created by Backstage Core', + filters: [ + { + type: FilterType.CreatedByTeam, + teamName: 'Backstage Core', + }, + ], + }, + { + title: 'Assigned to my teams', + filters: [{ type: FilterType.AssignedToCurrentUsersTeams }], + }, + { + title: 'Other PRs', + filters: [{ type: FilterType.All }], + simplified: true, + }, + ]; + + + } + />; + ``` + +- Updated dependencies + - @backstage/backend-common@0.9.14 + - @backstage/plugin-azure-devops-common@0.1.3 + ## 0.2.4 ### Patch Changes diff --git a/plugins/azure-devops-backend/package.json b/plugins/azure-devops-backend/package.json index 9741380fb1..a7aec3f2d6 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.2.4", + "version": "0.2.5", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -20,9 +20,9 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.9.13", + "@backstage/backend-common": "^0.9.14", "@backstage/config": "^0.1.11", - "@backstage/plugin-azure-devops-common": "^0.1.2", + "@backstage/plugin-azure-devops-common": "^0.1.3", "@types/express": "^4.17.6", "azure-devops-node-api": "^11.0.1", "express": "^4.17.1", @@ -31,7 +31,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", + "@backstage/cli": "^0.10.2", "@types/supertest": "^2.0.8", "supertest": "^4.0.2", "msw": "^0.35.0" diff --git a/plugins/azure-devops-common/CHANGELOG.md b/plugins/azure-devops-common/CHANGELOG.md index b2c8645e94..84c2cae9a5 100644 --- a/plugins/azure-devops-common/CHANGELOG.md +++ b/plugins/azure-devops-common/CHANGELOG.md @@ -1,5 +1,62 @@ # @backstage/plugin-azure-devops-common +## 0.1.3 + +### Patch Changes + +- daf32e2c9b: Created some initial filters that can be used to create pull request columns: + + - All + - AssignedToUser + - AssignedToCurrentUser + - AssignedToTeam + - AssignedToTeams + - AssignedToCurrentUsersTeams + - CreatedByUser + - CreatedByCurrentUser + - CreatedByTeam + - CreatedByTeams + - CreatedByCurrentUsersTeams + + Example custom column creation: + + ```tsx + const COLUMN_CONFIGS: PullRequestColumnConfig[] = [ + { + title: 'Created by me', + filters: [{ type: FilterType.CreatedByCurrentUser }], + }, + { + title: 'Created by Backstage Core', + filters: [ + { + type: FilterType.CreatedByTeam, + teamName: 'Backstage Core', + }, + ], + }, + { + title: 'Assigned to my teams', + filters: [{ type: FilterType.AssignedToCurrentUsersTeams }], + }, + { + title: 'Other PRs', + filters: [{ type: FilterType.All }], + simplified: true, + }, + ]; + + + } + />; + ``` + ## 0.1.2 ### Patch Changes diff --git a/plugins/azure-devops-common/package.json b/plugins/azure-devops-common/package.json index 7b82296c40..f8a9622bff 100644 --- a/plugins/azure-devops-common/package.json +++ b/plugins/azure-devops-common/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-azure-devops-common", - "version": "0.1.2", + "version": "0.1.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -29,7 +29,7 @@ "clean": "backstage-cli clean" }, "devDependencies": { - "@backstage/cli": "^0.10.1" + "@backstage/cli": "^0.10.2" }, "files": [ "dist" diff --git a/plugins/azure-devops/CHANGELOG.md b/plugins/azure-devops/CHANGELOG.md index 57f80f508b..c79c3abdbc 100644 --- a/plugins/azure-devops/CHANGELOG.md +++ b/plugins/azure-devops/CHANGELOG.md @@ -1,5 +1,69 @@ # @backstage/plugin-azure-devops +## 0.1.7 + +### Patch Changes + +- daf32e2c9b: Created some initial filters that can be used to create pull request columns: + + - All + - AssignedToUser + - AssignedToCurrentUser + - AssignedToTeam + - AssignedToTeams + - AssignedToCurrentUsersTeams + - CreatedByUser + - CreatedByCurrentUser + - CreatedByTeam + - CreatedByTeams + - CreatedByCurrentUsersTeams + + Example custom column creation: + + ```tsx + const COLUMN_CONFIGS: PullRequestColumnConfig[] = [ + { + title: 'Created by me', + filters: [{ type: FilterType.CreatedByCurrentUser }], + }, + { + title: 'Created by Backstage Core', + filters: [ + { + type: FilterType.CreatedByTeam, + teamName: 'Backstage Core', + }, + ], + }, + { + title: 'Assigned to my teams', + filters: [{ type: FilterType.AssignedToCurrentUsersTeams }], + }, + { + title: 'Other PRs', + filters: [{ type: FilterType.All }], + simplified: true, + }, + ]; + + + } + />; + ``` + +- Updated dependencies + - @backstage/core-plugin-api@0.3.1 + - @backstage/core-components@0.8.1 + - @backstage/plugin-azure-devops-common@0.1.3 + - @backstage/catalog-model@0.9.8 + - @backstage/plugin-catalog-react@0.6.7 + ## 0.1.6 ### Patch Changes diff --git a/plugins/azure-devops/package.json b/plugins/azure-devops/package.json index a37259739f..5d048c6471 100644 --- a/plugins/azure-devops/package.json +++ b/plugins/azure-devops/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-azure-devops", - "version": "0.1.6", + "version": "0.1.7", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -27,12 +27,12 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/catalog-model": "^0.9.7", - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/catalog-model": "^0.9.8", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/errors": "^0.1.4", - "@backstage/plugin-azure-devops-common": "^0.1.2", - "@backstage/plugin-catalog-react": "^0.6.5", + "@backstage/plugin-azure-devops-common": "^0.1.3", + "@backstage/plugin-catalog-react": "^0.6.7", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -46,8 +46,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/dev-utils": "^0.2.14", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/badges/package.json b/plugins/badges/package.json index 441f72c550..9d35a3b9e2 100644 --- a/plugins/badges/package.json +++ b/plugins/badges/package.json @@ -28,8 +28,8 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.7", - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/errors": "^0.1.5", "@backstage/plugin-catalog-react": "^0.6.5", "@backstage/theme": "^0.2.14", @@ -43,8 +43,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/dev-utils": "^0.2.14", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/bazaar/package.json b/plugins/bazaar/package.json index 3db79b9cdf..88da003778 100644 --- a/plugins/bazaar/package.json +++ b/plugins/bazaar/package.json @@ -23,8 +23,8 @@ "dependencies": { "@backstage/catalog-model": "^0.9.7", "@backstage/cli": "^0.10.1", - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/plugin-catalog": "^0.7.4", "@backstage/plugin-catalog-react": "^0.6.5", "@date-io/luxon": "1.x", @@ -42,7 +42,7 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", + "@backstage/cli": "^0.10.2", "@backstage/dev-utils": "^0.2.14", "@testing-library/jest-dom": "^5.10.1", "cross-fetch": "^3.0.6" diff --git a/plugins/bitrise/package.json b/plugins/bitrise/package.json index 35a0a9e079..c4a02c7403 100644 --- a/plugins/bitrise/package.json +++ b/plugins/bitrise/package.json @@ -22,8 +22,8 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.7", - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/plugin-catalog-react": "^0.6.5", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", @@ -40,8 +40,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/dev-utils": "^0.2.14", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/catalog-backend/CHANGELOG.md b/plugins/catalog-backend/CHANGELOG.md index dc7fc50f76..ce502f8f46 100644 --- a/plugins/catalog-backend/CHANGELOG.md +++ b/plugins/catalog-backend/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-catalog-backend +## 0.19.2 + +### Patch Changes + +- 3368f27aef: Fixed the handling of optional locations so that the catalog no longer logs `NotFoundError`s for missing optional locations. +- Updated dependencies + - @backstage/backend-common@0.9.14 + - @backstage/catalog-model@0.9.8 + ## 0.19.1 ### Patch Changes diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json index 6cfb73a3d1..d49723b7d2 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": "0.19.1", + "version": "0.19.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -30,9 +30,9 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.9.13", + "@backstage/backend-common": "^0.9.14", "@backstage/catalog-client": "^0.5.2", - "@backstage/catalog-model": "^0.9.7", + "@backstage/catalog-model": "^0.9.8", "@backstage/config": "^0.1.11", "@backstage/errors": "^0.1.5", "@backstage/integration": "^0.6.10", @@ -63,7 +63,7 @@ }, "devDependencies": { "@backstage/backend-test-utils": "^0.1.10", - "@backstage/cli": "^0.10.1", + "@backstage/cli": "^0.10.2", "@backstage/test-utils": "^0.1.24", "@types/core-js": "^2.5.4", "@types/git-url-parse": "^9.0.0", diff --git a/plugins/catalog-graph/package.json b/plugins/catalog-graph/package.json index b421a15265..59afadc62e 100644 --- a/plugins/catalog-graph/package.json +++ b/plugins/catalog-graph/package.json @@ -23,8 +23,8 @@ "dependencies": { "@backstage/catalog-client": "^0.5.2", "@backstage/catalog-model": "^0.9.7", - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/plugin-catalog-react": "^0.6.5", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", @@ -42,8 +42,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/dev-utils": "^0.2.14", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/catalog-import/package.json b/plugins/catalog-import/package.json index d417a337df..e017c45d09 100644 --- a/plugins/catalog-import/package.json +++ b/plugins/catalog-import/package.json @@ -33,8 +33,8 @@ "dependencies": { "@backstage/catalog-client": "^0.5.2", "@backstage/catalog-model": "^0.9.7", - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/errors": "^0.1.3", "@backstage/integration": "^0.6.10", "@backstage/integration-react": "^0.1.15", @@ -56,8 +56,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/dev-utils": "^0.2.14", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/catalog-react/CHANGELOG.md b/plugins/catalog-react/CHANGELOG.md index 5ebe626fad..0f7e08ead2 100644 --- a/plugins/catalog-react/CHANGELOG.md +++ b/plugins/catalog-react/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-catalog-react +## 0.6.7 + +### Patch Changes + +- 6156fb8730: `useEntityTypeFilter`: Skip updating selected types if a kind filter change did not change them. +- Updated dependencies + - @backstage/core-plugin-api@0.3.1 + - @backstage/core-components@0.8.1 + - @backstage/catalog-model@0.9.8 + ## 0.6.6 ### Patch Changes diff --git a/plugins/catalog-react/package.json b/plugins/catalog-react/package.json index da8300ae49..0bdffc0724 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": "0.6.6", + "version": "0.6.7", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -30,9 +30,9 @@ }, "dependencies": { "@backstage/catalog-client": "^0.5.2", - "@backstage/catalog-model": "^0.9.7", - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/catalog-model": "^0.9.8", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/errors": "^0.1.4", "@backstage/integration": "^0.6.10", "@backstage/types": "^0.1.1", @@ -52,8 +52,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/catalog/package.json b/plugins/catalog/package.json index 57e14b5475..00504d7777 100644 --- a/plugins/catalog/package.json +++ b/plugins/catalog/package.json @@ -33,8 +33,8 @@ "dependencies": { "@backstage/catalog-client": "^0.5.2", "@backstage/catalog-model": "^0.9.7", - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/errors": "^0.1.3", "@backstage/integration-react": "^0.1.15", "@backstage/plugin-catalog-react": "^0.6.5", @@ -53,8 +53,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/dev-utils": "^0.2.14", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/circleci/package.json b/plugins/circleci/package.json index e2aa415043..f449e5556c 100644 --- a/plugins/circleci/package.json +++ b/plugins/circleci/package.json @@ -33,8 +33,8 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.7", - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/plugin-catalog-react": "^0.6.5", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", @@ -52,8 +52,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/dev-utils": "^0.2.14", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/cloudbuild/package.json b/plugins/cloudbuild/package.json index 6e91b22fcb..44dafc8245 100644 --- a/plugins/cloudbuild/package.json +++ b/plugins/cloudbuild/package.json @@ -32,8 +32,8 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.7", - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/plugin-catalog-react": "^0.6.5", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", @@ -49,8 +49,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/dev-utils": "^0.2.14", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/code-coverage/package.json b/plugins/code-coverage/package.json index 951a93110a..c5cb3e3acb 100644 --- a/plugins/code-coverage/package.json +++ b/plugins/code-coverage/package.json @@ -23,8 +23,8 @@ "dependencies": { "@backstage/catalog-model": "^0.9.7", "@backstage/config": "^0.1.11", - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/errors": "^0.1.4", "@backstage/plugin-catalog-react": "^0.6.5", "@backstage/theme": "^0.2.14", @@ -43,8 +43,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/dev-utils": "^0.2.14", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/config-schema/package.json b/plugins/config-schema/package.json index 59d34cc00d..accf5e2d01 100644 --- a/plugins/config-schema/package.json +++ b/plugins/config-schema/package.json @@ -22,8 +22,8 @@ }, "dependencies": { "@backstage/config": "^0.1.11", - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/errors": "^0.1.5", "@backstage/theme": "^0.2.14", "@backstage/types": "^0.1.1", @@ -38,8 +38,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/dev-utils": "^0.2.14", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/cost-insights/package.json b/plugins/cost-insights/package.json index 45975163e4..94ec2bb5fe 100644 --- a/plugins/cost-insights/package.json +++ b/plugins/cost-insights/package.json @@ -32,8 +32,8 @@ }, "dependencies": { "@backstage/config": "^0.1.10", - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -56,8 +56,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/dev-utils": "^0.2.14", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/explore/package.json b/plugins/explore/package.json index 9975992ea5..4db5aa31e2 100644 --- a/plugins/explore/package.json +++ b/plugins/explore/package.json @@ -32,8 +32,8 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.7", - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/plugin-catalog-react": "^0.6.5", "@backstage/plugin-explore-react": "^0.0.8", "@backstage/theme": "^0.2.14", @@ -50,8 +50,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/dev-utils": "^0.2.14", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/firehydrant/package.json b/plugins/firehydrant/package.json index 68ee004605..784346e07c 100644 --- a/plugins/firehydrant/package.json +++ b/plugins/firehydrant/package.json @@ -22,8 +22,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/plugin-catalog-react": "^0.6.5", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", @@ -36,8 +36,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/dev-utils": "^0.2.14", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/fossa/package.json b/plugins/fossa/package.json index b28c8bd89f..6542721b61 100644 --- a/plugins/fossa/package.json +++ b/plugins/fossa/package.json @@ -33,8 +33,8 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.7", - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/errors": "^0.1.3", "@backstage/plugin-catalog-react": "^0.6.5", "@backstage/theme": "^0.2.14", @@ -50,8 +50,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/dev-utils": "^0.2.14", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/gcp-projects/package.json b/plugins/gcp-projects/package.json index e73dc7736a..5580595dc8 100644 --- a/plugins/gcp-projects/package.json +++ b/plugins/gcp-projects/package.json @@ -31,8 +31,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/theme": "^0.2.14", "@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.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/dev-utils": "^0.2.14", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/git-release-manager/package.json b/plugins/git-release-manager/package.json index ab11255e08..720f624fdd 100644 --- a/plugins/git-release-manager/package.json +++ b/plugins/git-release-manager/package.json @@ -21,8 +21,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/integration": "^0.6.10", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", @@ -40,8 +40,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/dev-utils": "^0.2.14", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/github-actions/CHANGELOG.md b/plugins/github-actions/CHANGELOG.md index 4c4a339415..15c8f61978 100644 --- a/plugins/github-actions/CHANGELOG.md +++ b/plugins/github-actions/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-github-actions +## 0.4.27 + +### Patch Changes + +- 89bd772b00: Show empty state only when workflow API call has completed +- Updated dependencies + - @backstage/core-plugin-api@0.3.1 + - @backstage/core-components@0.8.1 + - @backstage/catalog-model@0.9.8 + - @backstage/plugin-catalog-react@0.6.7 + ## 0.4.26 ### Patch Changes diff --git a/plugins/github-actions/package.json b/plugins/github-actions/package.json index 434a0b6224..22cd220e9c 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.4.26", + "version": "0.4.27", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,11 +33,11 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/catalog-model": "^0.9.7", - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/catalog-model": "^0.9.8", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/integration": "^0.6.10", - "@backstage/plugin-catalog-react": "^0.6.5", + "@backstage/plugin-catalog-react": "^0.6.7", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -52,8 +52,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/dev-utils": "^0.2.14", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/github-deployments/package.json b/plugins/github-deployments/package.json index 1965f98ef1..d593ae7ac0 100644 --- a/plugins/github-deployments/package.json +++ b/plugins/github-deployments/package.json @@ -22,8 +22,8 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.7", - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/errors": "^0.1.3", "@backstage/integration": "^0.6.10", "@backstage/integration-react": "^0.1.15", @@ -40,8 +40,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/dev-utils": "^0.2.14", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/gitops-profiles/package.json b/plugins/gitops-profiles/package.json index 834fd2f7cf..b6d3f2f569 100644 --- a/plugins/gitops-profiles/package.json +++ b/plugins/gitops-profiles/package.json @@ -32,8 +32,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -45,8 +45,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/dev-utils": "^0.2.14", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/graphiql/package.json b/plugins/graphiql/package.json index ec5a37bf36..7f165cbef5 100644 --- a/plugins/graphiql/package.json +++ b/plugins/graphiql/package.json @@ -31,8 +31,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -45,8 +45,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/dev-utils": "^0.2.14", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/home/package.json b/plugins/home/package.json index b04e4a787d..4d14388d09 100644 --- a/plugins/home/package.json +++ b/plugins/home/package.json @@ -21,8 +21,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -36,8 +36,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/dev-utils": "^0.2.14", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/ilert/package.json b/plugins/ilert/package.json index 5c07bc9d21..a476abebd8 100644 --- a/plugins/ilert/package.json +++ b/plugins/ilert/package.json @@ -22,8 +22,8 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.7", - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/errors": "^0.1.3", "@backstage/plugin-catalog-react": "^0.6.5", "@backstage/theme": "^0.2.14", @@ -40,8 +40,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/dev-utils": "^0.2.14", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/jenkins/package.json b/plugins/jenkins/package.json index 2211bf54de..5822a262b5 100644 --- a/plugins/jenkins/package.json +++ b/plugins/jenkins/package.json @@ -33,8 +33,8 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.7", - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/plugin-catalog-react": "^0.6.5", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", @@ -49,8 +49,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/dev-utils": "^0.2.14", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/kafka/package.json b/plugins/kafka/package.json index 309e239a68..d3353a1f0d 100644 --- a/plugins/kafka/package.json +++ b/plugins/kafka/package.json @@ -22,8 +22,8 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.7", - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/plugin-catalog-react": "^0.6.5", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", @@ -36,8 +36,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/dev-utils": "^0.2.14", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/kubernetes/CHANGELOG.md b/plugins/kubernetes/CHANGELOG.md index 0329a9bc5b..94826738b3 100644 --- a/plugins/kubernetes/CHANGELOG.md +++ b/plugins/kubernetes/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-kubernetes +## 0.5.1 + +### Patch Changes + +- 6f0c850a86: Fixed styling bug for the CronJobsAccordions and updated Completed pods to display a green dot. +- Updated dependencies + - @backstage/core-plugin-api@0.3.1 + - @backstage/core-components@0.8.1 + - @backstage/catalog-model@0.9.8 + - @backstage/plugin-catalog-react@0.6.7 + ## 0.5.0 ### Minor Changes diff --git a/plugins/kubernetes/package.json b/plugins/kubernetes/package.json index 3a2ea6a9a9..02b8e85855 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.5.0", + "version": "0.5.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -31,11 +31,11 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/catalog-model": "^0.9.7", + "@backstage/catalog-model": "^0.9.8", "@backstage/config": "^0.1.11", - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", - "@backstage/plugin-catalog-react": "^0.6.5", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", + "@backstage/plugin-catalog-react": "^0.6.7", "@backstage/plugin-kubernetes-common": "^0.2.0", "@kubernetes/client-node": "^0.16.0", "@backstage/theme": "^0.2.14", @@ -53,8 +53,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/dev-utils": "^0.2.14", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/lighthouse/package.json b/plugins/lighthouse/package.json index 43aabc3e3f..3820e85fdd 100644 --- a/plugins/lighthouse/package.json +++ b/plugins/lighthouse/package.json @@ -34,8 +34,8 @@ "dependencies": { "@backstage/catalog-model": "^0.9.7", "@backstage/config": "^0.1.10", - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/plugin-catalog-react": "^0.6.5", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", @@ -48,8 +48,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/dev-utils": "^0.2.14", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/newrelic/package.json b/plugins/newrelic/package.json index b7be235b9e..9a32e23e18 100644 --- a/plugins/newrelic/package.json +++ b/plugins/newrelic/package.json @@ -32,8 +32,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/theme": "^0.2.14", "@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.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/dev-utils": "^0.2.14", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/org/CHANGELOG.md b/plugins/org/CHANGELOG.md index 0576d644da..eb2599237c 100644 --- a/plugins/org/CHANGELOG.md +++ b/plugins/org/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-org +## 0.3.31 + +### Patch Changes + +- fe86adbcd2: Added `entityFilterKind` property for `EntityOwnershipCard` +- Updated dependencies + - @backstage/core-plugin-api@0.3.1 + - @backstage/core-components@0.8.1 + - @backstage/catalog-model@0.9.8 + - @backstage/plugin-catalog-react@0.6.7 + ## 0.3.30 ### Patch Changes diff --git a/plugins/org/package.json b/plugins/org/package.json index 8df865f386..8733c1c322 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.3.30", + "version": "0.3.31", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -21,10 +21,10 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/catalog-model": "^0.9.7", - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", - "@backstage/plugin-catalog-react": "^0.6.5", + "@backstage/catalog-model": "^0.9.8", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", + "@backstage/plugin-catalog-react": "^0.6.7", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -38,8 +38,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/catalog-client": "^0.5.2", "@backstage/dev-utils": "^0.2.14", "@backstage/test-utils": "^0.1.24", diff --git a/plugins/pagerduty/package.json b/plugins/pagerduty/package.json index 59e76878b5..1b6c38465f 100644 --- a/plugins/pagerduty/package.json +++ b/plugins/pagerduty/package.json @@ -32,8 +32,8 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.7", - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/plugin-catalog-react": "^0.6.5", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", @@ -49,8 +49,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/dev-utils": "^0.2.14", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/rollbar/package.json b/plugins/rollbar/package.json index d6a14a5b2a..012cb24490 100644 --- a/plugins/rollbar/package.json +++ b/plugins/rollbar/package.json @@ -33,8 +33,8 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.7", - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/plugin-catalog-react": "^0.6.5", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", @@ -50,8 +50,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/dev-utils": "^0.2.14", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/scaffolder-backend/CHANGELOG.md b/plugins/scaffolder-backend/CHANGELOG.md index 3986961f16..50d10b564c 100644 --- a/plugins/scaffolder-backend/CHANGELOG.md +++ b/plugins/scaffolder-backend/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-scaffolder-backend +## 0.15.17 + +### Patch Changes + +- eec0750d8d: Makes cookiecutter a default, but optional action based on if a containerRunner argument is passed in to createRouter or createBuiltinActions +- ed52f74ab3: Adding changes to create GitLab Merge Request using custom action +- Updated dependencies + - @backstage/plugin-catalog-backend@0.19.2 + - @backstage/backend-common@0.9.14 + - @backstage/catalog-model@0.9.8 + ## 0.15.16 ### Patch Changes diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index 2dae658d74..3686c33c40 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": "0.15.16", + "version": "0.15.17", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -31,13 +31,13 @@ "build:assets": "node scripts/build-nunjucks.js" }, "dependencies": { - "@backstage/backend-common": "^0.9.13", + "@backstage/backend-common": "^0.9.14", "@backstage/catalog-client": "^0.5.2", - "@backstage/catalog-model": "^0.9.7", + "@backstage/catalog-model": "^0.9.8", "@backstage/config": "^0.1.11", "@backstage/errors": "^0.1.5", "@backstage/integration": "^0.6.10", - "@backstage/plugin-catalog-backend": "^0.19.1", + "@backstage/plugin-catalog-backend": "^0.19.2", "@backstage/plugin-scaffolder-common": "^0.1.1", "@backstage/plugin-scaffolder-backend-module-cookiecutter": "^0.1.5", "@backstage/types": "^0.1.1", @@ -73,7 +73,7 @@ "vm2": "^3.9.5" }, "devDependencies": { - "@backstage/cli": "^0.10.1", + "@backstage/cli": "^0.10.2", "@backstage/test-utils": "^0.1.24", "@types/command-exists": "^1.2.0", "@types/fs-extra": "^9.0.1", diff --git a/plugins/scaffolder/package.json b/plugins/scaffolder/package.json index e3aaa722b0..3d42126624 100644 --- a/plugins/scaffolder/package.json +++ b/plugins/scaffolder/package.json @@ -34,8 +34,8 @@ "@backstage/catalog-client": "^0.5.2", "@backstage/catalog-model": "^0.9.7", "@backstage/config": "^0.1.11", - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/errors": "^0.1.5", "@backstage/integration": "^0.6.10", "@backstage/integration-react": "^0.1.15", @@ -66,10 +66,10 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/plugin-catalog": "^0.7.4", - "@backstage/cli": "^0.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/dev-utils": "^0.2.14", + "@backstage/plugin-catalog": "^0.7.4", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/search-backend-module-elasticsearch/CHANGELOG.md b/plugins/search-backend-module-elasticsearch/CHANGELOG.md index f36078c503..52ca5efaff 100644 --- a/plugins/search-backend-module-elasticsearch/CHANGELOG.md +++ b/plugins/search-backend-module-elasticsearch/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-search-backend-module-elasticsearch +## 0.0.7 + +### Patch Changes + +- 68512f5178: Add `newClient()` method to re-use the configuration of the elastic search + engine with custom clients + ## 0.0.6 ### Patch Changes diff --git a/plugins/search-backend-module-elasticsearch/package.json b/plugins/search-backend-module-elasticsearch/package.json index 633af83ca6..0873fb24ac 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": "0.0.6", + "version": "0.0.7", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -30,8 +30,8 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/backend-common": "^0.9.13", - "@backstage/cli": "^0.10.1", + "@backstage/backend-common": "^0.9.14", + "@backstage/cli": "^0.10.2", "@elastic/elasticsearch-mock": "^0.3.0" }, "files": [ diff --git a/plugins/search/package.json b/plugins/search/package.json index dbef8e5608..85996d65c3 100644 --- a/plugins/search/package.json +++ b/plugins/search/package.json @@ -32,8 +32,8 @@ "dependencies": { "@backstage/catalog-model": "^0.9.7", "@backstage/config": "^0.1.11", - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/errors": "^0.1.4", "@backstage/plugin-catalog-react": "^0.6.5", "@backstage/search-common": "^0.2.1", @@ -52,8 +52,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/dev-utils": "^0.2.14", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/sentry/package.json b/plugins/sentry/package.json index 41dc522e77..0f41bfaf16 100644 --- a/plugins/sentry/package.json +++ b/plugins/sentry/package.json @@ -33,8 +33,8 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.7", - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/plugin-catalog-react": "^0.6.5", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", @@ -49,8 +49,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/dev-utils": "^0.2.14", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/shortcuts/package.json b/plugins/shortcuts/package.json index a706d43e0e..a03dde616b 100644 --- a/plugins/shortcuts/package.json +++ b/plugins/shortcuts/package.json @@ -21,8 +21,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/theme": "^0.2.14", "@backstage/types": "^0.1.1", "@material-ui/core": "^4.12.2", @@ -39,8 +39,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/dev-utils": "^0.2.14", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/sonarqube/package.json b/plugins/sonarqube/package.json index 451ec86659..d1daf47b67 100644 --- a/plugins/sonarqube/package.json +++ b/plugins/sonarqube/package.json @@ -34,8 +34,8 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.7", - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/plugin-catalog-react": "^0.6.5", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", @@ -50,8 +50,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/dev-utils": "^0.2.14", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/splunk-on-call/package.json b/plugins/splunk-on-call/package.json index e5b55836a4..faa49a962e 100644 --- a/plugins/splunk-on-call/package.json +++ b/plugins/splunk-on-call/package.json @@ -32,8 +32,8 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.7", - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/plugin-catalog-react": "^0.6.5", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", @@ -48,8 +48,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/dev-utils": "^0.2.14", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/tech-insights/package.json b/plugins/tech-insights/package.json index 16e1ec6784..9466433b8e 100644 --- a/plugins/tech-insights/package.json +++ b/plugins/tech-insights/package.json @@ -20,26 +20,26 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/catalog-model": "^0.9.7", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", + "@backstage/errors": "^0.1.4", + "@backstage/plugin-catalog-react": "^0.6.5", + "@backstage/plugin-tech-insights-common": "^0.2.0", "@backstage/theme": "^0.2.14", + "@backstage/types": "^0.1.1", "@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", "react-router-dom": "6.0.0-beta.0", - "@backstage/plugin-catalog-react": "^0.6.5", - "@backstage/plugin-tech-insights-common": "^0.2.0", - "@backstage/catalog-model": "^0.9.7", - "@backstage/errors": "^0.1.4", - "@backstage/types": "^0.1.1" + "react-use": "^17.2.4" }, "peerDependencies": { "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/dev-utils": "^0.2.14", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", @@ -47,8 +47,8 @@ "@testing-library/user-event": "^13.1.8", "@types/jest": "^26.0.7", "@types/node": "^14.14.32", - "msw": "^0.35.0", - "cross-fetch": "^3.0.6" + "cross-fetch": "^3.0.6", + "msw": "^0.35.0" }, "files": [ "dist" diff --git a/plugins/tech-radar/package.json b/plugins/tech-radar/package.json index 7d6fdb4afe..b68a05c546 100644 --- a/plugins/tech-radar/package.json +++ b/plugins/tech-radar/package.json @@ -31,8 +31,8 @@ "start": "backstage-cli plugin:serve" }, "dependencies": { - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -46,8 +46,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/dev-utils": "^0.2.14", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/techdocs/CHANGELOG.md b/plugins/techdocs/CHANGELOG.md index 5cab32a73f..d12e2df366 100644 --- a/plugins/techdocs/CHANGELOG.md +++ b/plugins/techdocs/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-techdocs +## 0.12.10 + +### Patch Changes + +- e7cce2b603: Fix issue where assets weren't being fetched from the correct URL path for doc URLs without trailing slashes +- Updated dependencies + - @backstage/core-plugin-api@0.3.1 + - @backstage/core-components@0.8.1 + - @backstage/catalog-model@0.9.8 + - @backstage/plugin-catalog-react@0.6.7 + ## 0.12.9 ### Patch Changes diff --git a/plugins/techdocs/package.json b/plugins/techdocs/package.json index 4ac62a2b56..f9e3db913b 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": "0.12.9", + "version": "0.12.10", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,15 +32,15 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/catalog-model": "^0.9.7", + "@backstage/catalog-model": "^0.9.8", "@backstage/config": "^0.1.11", - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/errors": "^0.1.5", "@backstage/integration": "^0.6.10", "@backstage/integration-react": "^0.1.15", "@backstage/plugin-catalog": "^0.7.4", - "@backstage/plugin-catalog-react": "^0.6.5", + "@backstage/plugin-catalog-react": "^0.6.7", "@backstage/plugin-search": "^0.5.1", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", @@ -62,8 +62,8 @@ "react-dom": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/dev-utils": "^0.2.14", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/todo/package.json b/plugins/todo/package.json index 10f2b311ca..deef4ac7f2 100644 --- a/plugins/todo/package.json +++ b/plugins/todo/package.json @@ -28,8 +28,8 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.7", - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/errors": "^0.1.3", "@backstage/plugin-catalog-react": "^0.6.5", "@backstage/theme": "^0.2.14", @@ -42,8 +42,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/dev-utils": "^0.2.14", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/user-settings/package.json b/plugins/user-settings/package.json index aaef5eb0a3..6d9f4bac21 100644 --- a/plugins/user-settings/package.json +++ b/plugins/user-settings/package.json @@ -31,8 +31,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/theme": "^0.2.14", "@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.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/dev-utils": "^0.2.14", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/xcmetrics/package.json b/plugins/xcmetrics/package.json index 55488aa8f4..26fcc28f9f 100644 --- a/plugins/xcmetrics/package.json +++ b/plugins/xcmetrics/package.json @@ -21,8 +21,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core-components": "^0.8.0", - "@backstage/core-plugin-api": "^0.3.0", + "@backstage/core-components": "^0.8.1", + "@backstage/core-plugin-api": "^0.3.1", "@backstage/errors": "^0.1.3", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", @@ -37,8 +37,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.10.1", - "@backstage/core-app-api": "^0.2.0", + "@backstage/cli": "^0.10.2", + "@backstage/core-app-api": "^0.2.1", "@backstage/dev-utils": "^0.2.14", "@backstage/test-utils": "^0.1.24", "@testing-library/jest-dom": "^5.10.1", From b80e25bf1d3b31bdb6ebe56cd627bd2c6d20b8c6 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Thu, 16 Dec 2021 10:03:27 +0100 Subject: [PATCH 38/39] add search packages to matching Signed-off-by: Johan Haals --- .github/labeler.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/labeler.yml b/.github/labeler.yml index 112f77e078..5f513b3db8 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -8,3 +8,4 @@ scaffolder: search: - plugins/search/**/* - plugins/search-*/**/* + - packages/search-*/**/* From 5463c03b35cc815cb619ae92a79203ce6030290e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Wed, 15 Dec 2021 22:47:52 +0100 Subject: [PATCH 39/39] Add support for passing paging parameters to the getEntities call of the catalog client MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/silver-books-clean.md | 5 ++ packages/catalog-client/api-report.md | 3 + .../catalog-client/src/CatalogClient.test.ts | 18 +++++ packages/catalog-client/src/CatalogClient.ts | 12 +++- packages/catalog-client/src/types/api.ts | 70 +++++++++++++++++++ 5 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 .changeset/silver-books-clean.md diff --git a/.changeset/silver-books-clean.md b/.changeset/silver-books-clean.md new file mode 100644 index 0000000000..9685cc2119 --- /dev/null +++ b/.changeset/silver-books-clean.md @@ -0,0 +1,5 @@ +--- +'@backstage/catalog-client': patch +--- + +Add support for passing paging parameters to the getEntities call of the catalog client diff --git a/packages/catalog-client/api-report.md b/packages/catalog-client/api-report.md index e16ca740f6..88c5ad6c27 100644 --- a/packages/catalog-client/api-report.md +++ b/packages/catalog-client/api-report.md @@ -121,6 +121,9 @@ export type CatalogEntitiesRequest = { | Record | undefined; fields?: string[] | undefined; + offset?: number; + limit?: number; + after?: string; }; // @public diff --git a/packages/catalog-client/src/CatalogClient.test.ts b/packages/catalog-client/src/CatalogClient.test.ts index d2db98bb25..1331f8e874 100644 --- a/packages/catalog-client/src/CatalogClient.test.ts +++ b/packages/catalog-client/src/CatalogClient.test.ts @@ -175,6 +175,24 @@ describe('CatalogClient', () => { { apiVersion: '2' }, ]); }); + + it('builds paging parameters properly', async () => { + expect.assertions(2); + + server.use( + rest.get(`${mockBaseUrl}/entities`, (req, res, ctx) => { + expect(req.url.search).toBe('?offset=1&limit=2&after=%3D'); + return res(ctx.json([])); + }), + ); + + const response = await client.getEntities( + { offset: 1, limit: 2, after: '=' }, + { token }, + ); + + expect(response.items).toEqual([]); + }); }); describe('getLocationById', () => { diff --git a/packages/catalog-client/src/CatalogClient.ts b/packages/catalog-client/src/CatalogClient.ts index 29d01fbe5c..0e5e2600bb 100644 --- a/packages/catalog-client/src/CatalogClient.ts +++ b/packages/catalog-client/src/CatalogClient.ts @@ -110,7 +110,7 @@ export class CatalogClient implements CatalogApi { request?: CatalogEntitiesRequest, options?: CatalogRequestOptions, ): Promise> { - const { filter = [], fields = [] } = request ?? {}; + const { filter = [], fields = [], offset, limit, after } = request ?? {}; const filterItems = [filter].flat(); const params: string[] = []; @@ -141,6 +141,16 @@ export class CatalogClient implements CatalogApi { params.push(`fields=${fields.map(encodeURIComponent).join(',')}`); } + if (offset !== undefined) { + params.push(`offset=${offset}`); + } + if (limit !== undefined) { + params.push(`limit=${limit}`); + } + if (after !== undefined) { + params.push(`after=${encodeURIComponent(after)}`); + } + const query = params.length ? `?${params.join('&')}` : ''; const entities: Entity[] = await this.requestRequired( 'GET', diff --git a/packages/catalog-client/src/types/api.ts b/packages/catalog-client/src/types/api.ts index 6344caff7c..3a09e14d71 100644 --- a/packages/catalog-client/src/types/api.ts +++ b/packages/catalog-client/src/types/api.ts @@ -29,11 +29,81 @@ export const CATALOG_FILTER_EXISTS = Symbol('CATALOG_FILTER_EXISTS'); * @public */ export type CatalogEntitiesRequest = { + /** + * If given, return only entities that match the given patterns. + * + * @remarks + * + * 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. + * + * Example: For an input of + * + * ``` + * [ + * { kind: ['API', 'Component'] }, + * { 'metadata.name': 'a', 'metadata.namespace': 'b' } + * ] + * ``` + * + * This effectively means + * + * ``` + * (kind = EITHER 'API' OR 'Component') + * OR + * (metadata.name = 'a' AND metadata.namespace = 'b' ) + * ``` + * + * Each key is a dot separated path in each object. + * + * As a value you can also pass in the symbol `CATALOG_FILTER_EXISTS` + * (exported from this package), which means that you assert on the existence + * of that key, no matter what its value is. + */ filter?: | Record[] | Record | undefined; + /** + * If given, return only the parts of each entity that match those dot + * separated paths in each object. + * + * @remarks + * + * Example: For an input of `['kind', 'metadata.annotations']`, then response + * objects will be shaped like + * + * ``` + * { + * "kind": "Component", + * "metadata": { + * "annotations": { + * "foo": "bar" + * } + * } + * } + * ``` + */ fields?: string[] | undefined; + /** + * If given, skips over the first N items in the result set. + */ + offset?: number; + /** + * If given, returns at most N items from the result set. + */ + limit?: number; + /** + * If given, skips over all items before that cursor as returned by a previous + * request. + */ + after?: string; }; /**