diff --git a/.changeset/brave-peaches-brush.md b/.changeset/brave-peaches-brush.md new file mode 100644 index 0000000000..f0661ba818 --- /dev/null +++ b/.changeset/brave-peaches-brush.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +Making the description of the GitLab repoUrl owner field more clearer by focusing it refers to the GitLab namespace. diff --git a/.changeset/loud-dots-sit.md b/.changeset/loud-dots-sit.md new file mode 100644 index 0000000000..fa6175358e --- /dev/null +++ b/.changeset/loud-dots-sit.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-user-settings': patch +--- + +Update installation instructions diff --git a/.changeset/lovely-peaches-fold.md b/.changeset/lovely-peaches-fold.md new file mode 100644 index 0000000000..dcff35f4d7 --- /dev/null +++ b/.changeset/lovely-peaches-fold.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-tech-insights': patch +--- + +making available the search for the last FACTS executed diff --git a/.changeset/mean-spiders-design.md b/.changeset/mean-spiders-design.md new file mode 100644 index 0000000000..3704c9fca9 --- /dev/null +++ b/.changeset/mean-spiders-design.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-search-backend': minor +--- + +Be less restrictive with unknown keys on query endpoint diff --git a/.changeset/old-needles-brake.md b/.changeset/old-needles-brake.md new file mode 100644 index 0000000000..eea2bf6539 --- /dev/null +++ b/.changeset/old-needles-brake.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-github-issues': patch +'@backstage/plugin-github-pull-requests-board': patch +--- + +Properly filter on relations instead of the spec, when finding by owner diff --git a/.changeset/plenty-kids-fetch.md b/.changeset/plenty-kids-fetch.md new file mode 100644 index 0000000000..6a31b4db20 --- /dev/null +++ b/.changeset/plenty-kids-fetch.md @@ -0,0 +1,5 @@ +--- +'@backstage/catalog-client': patch +--- + +Renamed argument in `validateEntity` from `location` to `locationRef` diff --git a/.changeset/twelve-melons-notice.md b/.changeset/twelve-melons-notice.md new file mode 100644 index 0000000000..4a91642426 --- /dev/null +++ b/.changeset/twelve-melons-notice.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-tech-insights-backend': patch +--- + +Modify router endpoint to handle singular and collections of request parameters similarly. diff --git a/packages/catalog-client/api-report.md b/packages/catalog-client/api-report.md index 0ad77ce39c..85fc389af7 100644 --- a/packages/catalog-client/api-report.md +++ b/packages/catalog-client/api-report.md @@ -68,7 +68,7 @@ export interface CatalogApi { ): Promise; validateEntity( entity: Entity, - location: string, + locationRef: string, options?: CatalogRequestOptions, ): Promise; } @@ -130,7 +130,7 @@ export class CatalogClient implements CatalogApi { ): Promise; validateEntity( entity: Entity, - location: string, + locationRef: string, options?: CatalogRequestOptions, ): Promise; } diff --git a/packages/catalog-client/src/CatalogClient.test.ts b/packages/catalog-client/src/CatalogClient.test.ts index 6c9c68efa2..5a344f49a3 100644 --- a/packages/catalog-client/src/CatalogClient.test.ts +++ b/packages/catalog-client/src/CatalogClient.test.ts @@ -322,7 +322,7 @@ describe('CatalogClient', () => { name: '', }, }, - 'http://example.com', + 'url:http://example.com', ), ).toMatchObject({ valid: false, @@ -350,7 +350,7 @@ describe('CatalogClient', () => { name: 'good', }, }, - 'http://example.com', + 'url:http://example.com', ), ).toMatchObject({ valid: true, @@ -373,7 +373,7 @@ describe('CatalogClient', () => { name: 'good', }, }, - 'http://example.com', + 'url:http://example.com', ), ).rejects.toThrow(/Request failed with 500 Error/); }); diff --git a/packages/catalog-client/src/CatalogClient.ts b/packages/catalog-client/src/CatalogClient.ts index f2b4186bfb..d67392d80d 100644 --- a/packages/catalog-client/src/CatalogClient.ts +++ b/packages/catalog-client/src/CatalogClient.ts @@ -359,7 +359,7 @@ export class CatalogClient implements CatalogApi { */ async validateEntity( entity: Entity, - location: string, + locationRef: string, options?: CatalogRequestOptions, ): Promise { const response = await this.fetchApi.fetch( @@ -370,7 +370,7 @@ export class CatalogClient implements CatalogApi { ...(options?.token && { Authorization: `Bearer ${options?.token}` }), }, method: 'POST', - body: JSON.stringify({ entity, location }), + body: JSON.stringify({ entity, location: locationRef }), }, ); diff --git a/packages/catalog-client/src/types/api.ts b/packages/catalog-client/src/types/api.ts index f483c3454c..d3d02022f3 100644 --- a/packages/catalog-client/src/types/api.ts +++ b/packages/catalog-client/src/types/api.ts @@ -405,11 +405,11 @@ export interface CatalogApi { * Validate entity and its location. * * @param entity - Entity to validate - * @param location - URL location of the entity + * @param locationRef - Location ref in format `url:http://example.com/file` */ validateEntity( entity: Entity, - location: string, + locationRef: string, options?: CatalogRequestOptions, ): Promise; } diff --git a/plugins/github-issues/src/hooks/useEntityGitHubRepositories.ts b/plugins/github-issues/src/hooks/useEntityGitHubRepositories.ts index 242de514ca..d7b60575ad 100644 --- a/plugins/github-issues/src/hooks/useEntityGitHubRepositories.ts +++ b/plugins/github-issues/src/hooks/useEntityGitHubRepositories.ts @@ -13,13 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { Entity } from '@backstage/catalog-model'; + +import { Entity, stringifyEntityRef } from '@backstage/catalog-model'; import { useApi } from '@backstage/core-plugin-api'; -import { - catalogApiRef, - humanizeEntityRef, - useEntity, -} from '@backstage/plugin-catalog-react'; +import { catalogApiRef, useEntity } from '@backstage/plugin-catalog-react'; import { useCallback, useEffect, useState } from 'react'; const GITHUB_PROJECT_SLUG_ANNOTATION = 'github.com/project-slug'; @@ -48,7 +45,7 @@ export function useEntityGitHubRepositories() { const entitiesList = await catalogApi.getEntities({ filter: { kind: ['Component', 'API'], - 'spec.owner': humanizeEntityRef(entity, { defaultKind: 'group' }), + 'relations.ownedBy': stringifyEntityRef(entity), }, }); diff --git a/plugins/github-pull-requests-board/src/hooks/useUserRepositories.tsx b/plugins/github-pull-requests-board/src/hooks/useUserRepositories.tsx index b905811aea..ed0d3580f0 100644 --- a/plugins/github-pull-requests-board/src/hooks/useUserRepositories.tsx +++ b/plugins/github-pull-requests-board/src/hooks/useUserRepositories.tsx @@ -13,12 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +import { stringifyEntityRef } from '@backstage/catalog-model'; import { useApi } from '@backstage/core-plugin-api'; -import { - catalogApiRef, - humanizeEntityRef, - useEntity, -} from '@backstage/plugin-catalog-react'; +import { catalogApiRef, useEntity } from '@backstage/plugin-catalog-react'; import { useCallback, useEffect, useState } from 'react'; import { getProjectNameFromEntity } from '../utils/functions'; @@ -29,9 +27,7 @@ export function useUserRepositories() { const getRepositoriesNames = useCallback(async () => { const entitiesList = await catalogApi.getEntities({ - filter: { - 'spec.owner': humanizeEntityRef(teamEntity, { defaultKind: 'group' }), - }, + filter: { 'relations.ownedBy': stringifyEntityRef(teamEntity) }, }); const entitiesNames: string[] = entitiesList.items.map(componentEntity => diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/GitlabRepoPicker.tsx b/plugins/scaffolder/src/components/fields/RepoUrlPicker/GitlabRepoPicker.tsx index c628b364b9..fbcc13c846 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/GitlabRepoPicker.tsx +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/GitlabRepoPicker.tsx @@ -66,8 +66,8 @@ export const GitlabRepoPicker = (props: { )} - The organization, groups, subgroups, user, project (also known as - namespaces in gitlab), that this repo will belong to + GitLab namespace where this repository will belong to. It can be the + name of organization, group, subgroup, user, or the project. diff --git a/plugins/search-backend/src/service/router.test.ts b/plugins/search-backend/src/service/router.test.ts index 1437e65b84..f26f191ecd 100644 --- a/plugins/search-backend/src/service/router.test.ts +++ b/plugins/search-backend/src/service/router.test.ts @@ -148,6 +148,25 @@ describe('createRouter', () => { }); }); + it('is less restrictive with unknown keys on query endpoint', async () => { + const queryString = + 'term=test&%5BdocType%5D%5B0%5D=Service&filters%5BdocType%5D%5B0%5D=filter1&unknownKey1%5B2%5D=unknownValue1&unknownKey1%5B3%5D=unknownValue2&unknownKey2=unknownValue1&pageCursor'; + const response = await request(app).get(`/query?${queryString}`); + const firstArg: Object = { + docType: ['Service'], + filters: { docType: ['filter1'] }, + pageCursor: '', + term: 'test', + unknownKey1: ['unknownValue1', 'unknownValue2'], + unknownKey2: 'unknownValue1', + }; + const secondArg = { + token: undefined, + }; + expect(response.status).toEqual(200); + expect(mockSearchEngine.query).toHaveBeenCalledWith(firstArg, secondArg); + }); + describe('search result filtering', () => { beforeAll(async () => { const logger = getVoidLogger(); diff --git a/plugins/search-backend/src/service/router.ts b/plugins/search-backend/src/service/router.ts index cf9abff675..87da80d8f5 100644 --- a/plugins/search-backend/src/service/router.ts +++ b/plugins/search-backend/src/service/router.ts @@ -133,7 +133,7 @@ export async function createRouter( req: express.Request, res: express.Response, ) => { - const parseResult = requestSchema.safeParse(req.query); + const parseResult = requestSchema.passthrough().safeParse(req.query); if (!parseResult.success) { throw new InputError(`Invalid query string: ${parseResult.error}`); diff --git a/plugins/tech-insights-backend/src/service/router.test.ts b/plugins/tech-insights-backend/src/service/router.test.ts index 8513973598..6935338a56 100644 --- a/plugins/tech-insights-backend/src/service/router.test.ts +++ b/plugins/tech-insights-backend/src/service/router.test.ts @@ -87,59 +87,94 @@ describe('Tech Insights router tests', () => { app = express().use(router); }); - - it('should be able to retrieve latest schemas', async () => { - await request(app).get('/fact-schemas').expect(200); - expect(latestSchemasMock).toHaveBeenCalled(); + describe('/fact-schemas', () => { + it('should be able to retrieve latest schemas', async () => { + await request(app).get('/fact-schemas').expect(200); + expect(latestSchemasMock).toHaveBeenCalled(); + }); }); - it('should not contain check endpoints when checker not present', async () => { - await request(app).get('/checks').expect(404); - await request(app).post('/checks/a/a/a').expect(404); + describe('/checks', () => { + it('should not contain check endpoints when checker not present', async () => { + await request(app).get('/checks').expect(404); + await request(app).post('/checks/a/a/a').expect(404); + }); }); - it('should be able to parse id request params for fact retrieval', async () => { - await request(app) - .get('/facts/latest') - .query({ - entity: 'a:a/a', - ids: ['firstId', 'secondId'], - }) - .expect(200); - expect(latestFactsByIdsMock).toHaveBeenCalledWith( - ['firstId', 'secondId'], - 'a:a/a', - ); + describe('/facts/latest', () => { + it('should be able to parse id request params for fact retrieval', async () => { + await request(app) + .get('/facts/latest') + .query({ + entity: 'a:a/a', + ids: ['firstId', 'secondId'], + }) + .expect(200); + expect(latestFactsByIdsMock).toHaveBeenCalledWith( + ['firstId', 'secondId'], + 'a:a/a', + ); + }); + it('should handle singular ids in query params correctly', async () => { + await request(app) + .get('/facts/latest') + .query({ + entity: 'a:a/a', + ids: ['secondId'], + }) + .expect(200); + expect(latestFactsByIdsMock).toHaveBeenCalledWith(['secondId'], 'a:a/a'); + }); }); - it('should be able to parse datetime request params for fact retrieval', async () => { - await request(app) - .get('/facts/range') - .query({ - entity: 'a:a/a', - ids: ['firstId', 'secondId'], - startDatetime: '2021-12-12T12:12:12', - endDatetime: '2022-11-11T11:11:11', - }) - .expect(200); - expect(factsBetweenTimestampsByIdsMock).toHaveBeenCalledWith( - ['firstId', 'secondId'], - 'a:a/a', - DateTime.fromISO('2021-12-12T12:12:12.000+00:00'), - DateTime.fromISO('2022-11-11T11:11:11.000+00:00'), - ); - }); + describe('/facts/range', () => { + it('should be able to parse datetime request params for fact retrieval', async () => { + await request(app) + .get('/facts/range') + .query({ + entity: 'a:a/a', + ids: ['firstId', 'secondId'], + startDatetime: '2021-12-12T12:12:12', + endDatetime: '2022-11-11T11:11:11', + }) + .expect(200); + expect(factsBetweenTimestampsByIdsMock).toHaveBeenCalledWith( + ['firstId', 'secondId'], + 'a:a/a', + DateTime.fromISO('2021-12-12T12:12:12.000+00:00'), + DateTime.fromISO('2022-11-11T11:11:11.000+00:00'), + ); + }); - it('should respond gracefully on parsing errors', async () => { - await request(app) - .get('/facts/range') - .query({ - entity: 'a:a/a', - ids: ['firstId', 'secondId'], - startDatetime: '2021-12-1222T12:12:12', - endDatetime: '2022-1122-11T11:11:11', - }) - .expect(422); - expect(latestFactsByIdsMock).toHaveBeenCalledTimes(0); + it('should respond gracefully on parsing errors', async () => { + await request(app) + .get('/facts/range') + .query({ + entity: 'a:a/a', + ids: ['firstId', 'secondId'], + startDatetime: '2021-12-1222T12:12:12', + endDatetime: '2022-1122-11T11:11:11', + }) + .expect(422); + expect(latestFactsByIdsMock).toHaveBeenCalledTimes(0); + }); + + it('should handle singular ids in query params correctly', async () => { + await request(app) + .get('/facts/range') + .query({ + entity: 'a:a/a', + ids: ['firstId'], + startDatetime: '2021-12-12T12:12:12', + endDatetime: '2022-11-11T11:11:11', + }) + .expect(200); + expect(factsBetweenTimestampsByIdsMock).toHaveBeenCalledWith( + ['firstId'], + 'a:a/a', + DateTime.fromISO('2021-12-12T12:12:12.000+00:00'), + DateTime.fromISO('2022-11-11T11:11:11.000+00:00'), + ); + }); }); }); diff --git a/plugins/tech-insights-backend/src/service/router.ts b/plugins/tech-insights-backend/src/service/router.ts index 4b93bf4d60..0df7080db5 100644 --- a/plugins/tech-insights-backend/src/service/router.ts +++ b/plugins/tech-insights-backend/src/service/router.ts @@ -132,7 +132,13 @@ export async function createRouter< router.get('/facts/latest', async (req, res) => { const { entity } = req.query; const { namespace, kind, name } = parseEntityRef(entity as string); - const ids = req.query.ids as string[]; + + if (!req.query.ids) { + return res + .status(422) + .send({ error: 'Failed to parse ids from request' }); + } + const ids = [req.query.ids].flat() as string[]; return res.send( await techInsightsStore.getLatestFactsByIds( ids, @@ -148,7 +154,12 @@ export async function createRouter< const { entity } = req.query; const { namespace, kind, name } = parseEntityRef(entity as string); - const ids = req.query.ids as string[]; + if (!req.query.ids) { + return res + .status(422) + .send({ error: 'Failed to parse ids from request' }); + } + const ids = [req.query.ids].flat() as string[]; const startDatetime = DateTime.fromISO(req.query.startDatetime as string); const endDatetime = DateTime.fromISO(req.query.endDatetime as string); if (!startDatetime.isValid || !endDatetime.isValid) { diff --git a/plugins/tech-insights/api-report.md b/plugins/tech-insights/api-report.md index 03155a5958..2d25d6d39d 100644 --- a/plugins/tech-insights/api-report.md +++ b/plugins/tech-insights/api-report.md @@ -12,6 +12,7 @@ import { CheckResult } from '@backstage/plugin-tech-insights-common'; import { CompoundEntityRef } from '@backstage/catalog-model'; import { DiscoveryApi } from '@backstage/core-plugin-api'; import { IdentityApi } from '@backstage/core-plugin-api'; +import { JsonValue } from '@backstage/types'; import { default as React_2 } from 'react'; import { RouteRef } from '@backstage/core-plugin-api'; @@ -51,6 +52,16 @@ export const EntityTechInsightsScorecardContent: (props: { checksId?: string[] | undefined; }) => JSX.Element; +// @public +export interface InsightFacts { + // (undocumented) + [factId: string]: { + timestamp: string; + version: string; + facts: Record; + }; +} + // @public export const jsonRulesEngineCheckResultRenderer: CheckResultRenderer; @@ -61,6 +72,8 @@ export interface TechInsightsApi { // (undocumented) getCheckResultRenderers: (types: string[]) => CheckResultRenderer[]; // (undocumented) + getFacts(entity: CompoundEntityRef, facts: string[]): Promise; + // (undocumented) runBulkChecks( entities: CompoundEntityRef[], checks?: Check[], @@ -87,6 +100,8 @@ export class TechInsightsClient implements TechInsightsApi { // (undocumented) getCheckResultRenderers(types: string[]): CheckResultRenderer[]; // (undocumented) + getFacts(entity: CompoundEntityRef, facts: string[]): Promise; + // (undocumented) runBulkChecks( entities: CompoundEntityRef[], checks?: Check[], diff --git a/plugins/tech-insights/package.json b/plugins/tech-insights/package.json index f308017fa0..9c940d4d55 100644 --- a/plugins/tech-insights/package.json +++ b/plugins/tech-insights/package.json @@ -38,6 +38,7 @@ "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", + "qs": "^6.9.4", "react-use": "^17.2.4" }, "peerDependencies": { diff --git a/plugins/tech-insights/src/api/TechInsightsApi.ts b/plugins/tech-insights/src/api/TechInsightsApi.ts index 8ab1090304..166f1d2782 100644 --- a/plugins/tech-insights/src/api/TechInsightsApi.ts +++ b/plugins/tech-insights/src/api/TechInsightsApi.ts @@ -19,7 +19,7 @@ import { CheckResult, BulkCheckResponse, } from '@backstage/plugin-tech-insights-common'; -import { Check } from './types'; +import { Check, InsightFacts } from './types'; import { CheckResultRenderer } from '../components/CheckResultRenderer'; import { CompoundEntityRef } from '@backstage/catalog-model'; @@ -48,4 +48,5 @@ export interface TechInsightsApi { entities: CompoundEntityRef[], checks?: Check[], ): Promise; + getFacts(entity: CompoundEntityRef, facts: string[]): Promise; } diff --git a/plugins/tech-insights/src/api/TechInsightsClient.ts b/plugins/tech-insights/src/api/TechInsightsClient.ts index 8db5de3945..9bdeb119f9 100644 --- a/plugins/tech-insights/src/api/TechInsightsClient.ts +++ b/plugins/tech-insights/src/api/TechInsightsClient.ts @@ -19,15 +19,19 @@ import { BulkCheckResponse, CheckResult, } from '@backstage/plugin-tech-insights-common'; -import { Check } from './types'; +import { Check, InsightFacts } from './types'; import { DiscoveryApi, IdentityApi } from '@backstage/core-plugin-api'; import { ResponseError } from '@backstage/errors'; -import { CompoundEntityRef } from '@backstage/catalog-model'; +import { + CompoundEntityRef, + stringifyEntityRef, +} from '@backstage/catalog-model'; import { CheckResultRenderer, jsonRulesEngineCheckResultRenderer, } from '../components/CheckResultRenderer'; +import qs from 'qs'; /** @public */ export class TechInsightsClient implements TechInsightsApi { @@ -45,76 +49,75 @@ export class TechInsightsClient implements TechInsightsApi { this.renderers = options.renderers; } + async getFacts( + entity: CompoundEntityRef, + facts: string[], + ): Promise { + const query = qs.stringify({ + entity: stringifyEntityRef(entity), + ids: facts, + }); + return await this.api(`/facts/latest?${query}`); + } + getCheckResultRenderers(types: string[]): CheckResultRenderer[] { const renderers = this.renderers ?? [jsonRulesEngineCheckResultRenderer]; return renderers.filter(d => types.includes(d.type)); } async getAllChecks(): Promise { - const url = await this.discoveryApi.getBaseUrl('tech-insights'); - const { token } = await this.identityApi.getCredentials(); - const response = await fetch(`${url}/checks`, { - headers: token - ? { - Authorization: `Bearer ${token}`, - } - : undefined, - }); - if (!response.ok) { - throw await ResponseError.fromResponse(response); - } - return await response.json(); + return this.api('/checks'); } async runChecks( entityParams: CompoundEntityRef, checks?: string[], ): Promise { - const url = await this.discoveryApi.getBaseUrl('tech-insights'); - const { token } = await this.identityApi.getCredentials(); const { namespace, kind, name } = entityParams; const requestBody = { checks }; - const response = await fetch( - `${url}/checks/run/${encodeURIComponent(namespace)}/${encodeURIComponent( + return this.api( + `/checks/run/${encodeURIComponent(namespace)}/${encodeURIComponent( kind, )}/${encodeURIComponent(name)}`, { method: 'POST', body: JSON.stringify(requestBody), - headers: { - 'Content-Type': 'application/json', - ...(token && { Authorization: `Bearer ${token}` }), - }, }, ); - if (!response.ok) { - throw await ResponseError.fromResponse(response); - } - return await response.json(); } async runBulkChecks( entities: CompoundEntityRef[], checks?: Check[], ): Promise { - const url = await this.discoveryApi.getBaseUrl('tech-insights'); - const { token } = await this.identityApi.getCredentials(); const checkIds = checks ? checks.map(check => check.id) : []; const requestBody = { entities, checks: checkIds.length > 0 ? checkIds : undefined, }; - const response = await fetch(`${url}/checks/run`, { + return this.api('/checks/run', { method: 'POST', body: JSON.stringify(requestBody), - headers: { - 'Content-Type': 'application/json', - ...(token && { Authorization: `Bearer ${token}` }), - }, }); - if (!response.ok) { - throw await ResponseError.fromResponse(response); + } + + private async api(path: string, init?: RequestInit): Promise { + const url = await this.discoveryApi.getBaseUrl('tech-insights'); + const { token } = await this.identityApi.getCredentials(); + + const request = new Request(`${url}${path}`, init); + if (!request.headers.has('content-type')) { + request.headers.set('content-type', 'application/json'); } - return await response.json(); + if (token && !request.headers.has('authorization')) { + request.headers.set('authorization', `Bearer ${token}`); + } + + return fetch(request).then(async response => { + if (!response.ok) { + throw await ResponseError.fromResponse(response); + } + return response.json() as Promise; + }); } } diff --git a/plugins/tech-insights/src/api/types.ts b/plugins/tech-insights/src/api/types.ts index 10dfa06420..ac1f2e44ee 100644 --- a/plugins/tech-insights/src/api/types.ts +++ b/plugins/tech-insights/src/api/types.ts @@ -14,6 +14,8 @@ * limitations under the License. */ +import { JsonValue } from '@backstage/types'; + /** * Represents a single check defined on the TechInsights backend. * @@ -26,3 +28,16 @@ export type Check = { description: string; factIds: string[]; }; + +/** + * Represents a Fact defined on the TechInsights backend. + * + * @public + */ +export interface InsightFacts { + [factId: string]: { + timestamp: string; + version: string; + facts: Record; + }; +} diff --git a/plugins/tech-insights/src/index.ts b/plugins/tech-insights/src/index.ts index f3dd05c3aa..9e075df038 100644 --- a/plugins/tech-insights/src/index.ts +++ b/plugins/tech-insights/src/index.ts @@ -20,7 +20,7 @@ export { } from './plugin'; export { techInsightsApiRef, TechInsightsClient } from './api'; -export type { TechInsightsApi, Check } from './api'; +export type { TechInsightsApi, Check, InsightFacts } from './api'; export { BooleanCheck } from './components/BooleanCheck'; export { jsonRulesEngineCheckResultRenderer } from './components/CheckResultRenderer'; export type { CheckResultRenderer } from './components/CheckResultRenderer'; diff --git a/plugins/user-settings/README.md b/plugins/user-settings/README.md index abe66120fe..ce07d76257 100644 --- a/plugins/user-settings/README.md +++ b/plugins/user-settings/README.md @@ -29,11 +29,11 @@ import { Settings as SidebarSettings } from '@backstage/plugin-user-settings'; Add the page to the App routing: ```ts -import { Router as SettingsRouter } from '@backstage/plugin-user-settings'; +import { UserSettingsPage } from '@backstage/plugin-user-settings'; const AppRoutes = () => ( - } /> + } /> ); ``` diff --git a/storybook/yarn.lock b/storybook/yarn.lock index 4a5d57c5b2..1597d0728c 100644 --- a/storybook/yarn.lock +++ b/storybook/yarn.lock @@ -2977,126 +2977,126 @@ __metadata: languageName: node linkType: hard -"@swc/core-android-arm-eabi@npm:1.3.2": - version: 1.3.2 - resolution: "@swc/core-android-arm-eabi@npm:1.3.2" +"@swc/core-android-arm-eabi@npm:1.3.3": + version: 1.3.3 + resolution: "@swc/core-android-arm-eabi@npm:1.3.3" dependencies: "@swc/wasm": 1.2.122 conditions: os=android & cpu=arm languageName: node linkType: hard -"@swc/core-android-arm64@npm:1.3.2": - version: 1.3.2 - resolution: "@swc/core-android-arm64@npm:1.3.2" +"@swc/core-android-arm64@npm:1.3.3": + version: 1.3.3 + resolution: "@swc/core-android-arm64@npm:1.3.3" dependencies: "@swc/wasm": 1.2.130 conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@swc/core-darwin-arm64@npm:1.3.2": - version: 1.3.2 - resolution: "@swc/core-darwin-arm64@npm:1.3.2" +"@swc/core-darwin-arm64@npm:1.3.3": + version: 1.3.3 + resolution: "@swc/core-darwin-arm64@npm:1.3.3" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@swc/core-darwin-x64@npm:1.3.2": - version: 1.3.2 - resolution: "@swc/core-darwin-x64@npm:1.3.2" +"@swc/core-darwin-x64@npm:1.3.3": + version: 1.3.3 + resolution: "@swc/core-darwin-x64@npm:1.3.3" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@swc/core-freebsd-x64@npm:1.3.2": - version: 1.3.2 - resolution: "@swc/core-freebsd-x64@npm:1.3.2" +"@swc/core-freebsd-x64@npm:1.3.3": + version: 1.3.3 + resolution: "@swc/core-freebsd-x64@npm:1.3.3" dependencies: "@swc/wasm": 1.2.130 conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@swc/core-linux-arm-gnueabihf@npm:1.3.2": - version: 1.3.2 - resolution: "@swc/core-linux-arm-gnueabihf@npm:1.3.2" +"@swc/core-linux-arm-gnueabihf@npm:1.3.3": + version: 1.3.3 + resolution: "@swc/core-linux-arm-gnueabihf@npm:1.3.3" dependencies: "@swc/wasm": 1.2.130 conditions: os=linux & cpu=arm languageName: node linkType: hard -"@swc/core-linux-arm64-gnu@npm:1.3.2": - version: 1.3.2 - resolution: "@swc/core-linux-arm64-gnu@npm:1.3.2" +"@swc/core-linux-arm64-gnu@npm:1.3.3": + version: 1.3.3 + resolution: "@swc/core-linux-arm64-gnu@npm:1.3.3" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-arm64-musl@npm:1.3.2": - version: 1.3.2 - resolution: "@swc/core-linux-arm64-musl@npm:1.3.2" +"@swc/core-linux-arm64-musl@npm:1.3.3": + version: 1.3.3 + resolution: "@swc/core-linux-arm64-musl@npm:1.3.3" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@swc/core-linux-x64-gnu@npm:1.3.2": - version: 1.3.2 - resolution: "@swc/core-linux-x64-gnu@npm:1.3.2" +"@swc/core-linux-x64-gnu@npm:1.3.3": + version: 1.3.3 + resolution: "@swc/core-linux-x64-gnu@npm:1.3.3" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-x64-musl@npm:1.3.2": - version: 1.3.2 - resolution: "@swc/core-linux-x64-musl@npm:1.3.2" +"@swc/core-linux-x64-musl@npm:1.3.3": + version: 1.3.3 + resolution: "@swc/core-linux-x64-musl@npm:1.3.3" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@swc/core-win32-arm64-msvc@npm:1.3.2": - version: 1.3.2 - resolution: "@swc/core-win32-arm64-msvc@npm:1.3.2" +"@swc/core-win32-arm64-msvc@npm:1.3.3": + version: 1.3.3 + resolution: "@swc/core-win32-arm64-msvc@npm:1.3.3" dependencies: "@swc/wasm": 1.2.130 conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@swc/core-win32-ia32-msvc@npm:1.3.2": - version: 1.3.2 - resolution: "@swc/core-win32-ia32-msvc@npm:1.3.2" +"@swc/core-win32-ia32-msvc@npm:1.3.3": + version: 1.3.3 + resolution: "@swc/core-win32-ia32-msvc@npm:1.3.3" dependencies: "@swc/wasm": 1.2.130 conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@swc/core-win32-x64-msvc@npm:1.3.2": - version: 1.3.2 - resolution: "@swc/core-win32-x64-msvc@npm:1.3.2" +"@swc/core-win32-x64-msvc@npm:1.3.3": + version: 1.3.3 + resolution: "@swc/core-win32-x64-msvc@npm:1.3.3" conditions: os=win32 & cpu=x64 languageName: node linkType: hard "@swc/core@npm:^1.2.239": - version: 1.3.2 - resolution: "@swc/core@npm:1.3.2" + version: 1.3.3 + resolution: "@swc/core@npm:1.3.3" dependencies: - "@swc/core-android-arm-eabi": 1.3.2 - "@swc/core-android-arm64": 1.3.2 - "@swc/core-darwin-arm64": 1.3.2 - "@swc/core-darwin-x64": 1.3.2 - "@swc/core-freebsd-x64": 1.3.2 - "@swc/core-linux-arm-gnueabihf": 1.3.2 - "@swc/core-linux-arm64-gnu": 1.3.2 - "@swc/core-linux-arm64-musl": 1.3.2 - "@swc/core-linux-x64-gnu": 1.3.2 - "@swc/core-linux-x64-musl": 1.3.2 - "@swc/core-win32-arm64-msvc": 1.3.2 - "@swc/core-win32-ia32-msvc": 1.3.2 - "@swc/core-win32-x64-msvc": 1.3.2 + "@swc/core-android-arm-eabi": 1.3.3 + "@swc/core-android-arm64": 1.3.3 + "@swc/core-darwin-arm64": 1.3.3 + "@swc/core-darwin-x64": 1.3.3 + "@swc/core-freebsd-x64": 1.3.3 + "@swc/core-linux-arm-gnueabihf": 1.3.3 + "@swc/core-linux-arm64-gnu": 1.3.3 + "@swc/core-linux-arm64-musl": 1.3.3 + "@swc/core-linux-x64-gnu": 1.3.3 + "@swc/core-linux-x64-musl": 1.3.3 + "@swc/core-win32-arm64-msvc": 1.3.3 + "@swc/core-win32-ia32-msvc": 1.3.3 + "@swc/core-win32-x64-msvc": 1.3.3 dependenciesMeta: "@swc/core-android-arm-eabi": optional: true @@ -3126,7 +3126,7 @@ __metadata: optional: true bin: swcx: run_swcx.js - checksum: c2c83d0e6b4c56d65fb3723aa0be5e777823a6efe5b12702d4d44827a6c6dd8fac3c5dec7ff45222c7b22b4084bffc846f8497d697e61a1706817977256a65dc + checksum: bead8463cd7c11e2cd87d3835045e4a245e755409e912a40c575026a0475cc0010fa6ef48936ea5f7e62c84cdc63c21a83d61755813f2ba9b565d397fad7c5f5 languageName: node linkType: hard diff --git a/yarn.lock b/yarn.lock index 7776d00e77..7e67c7174a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7229,6 +7229,7 @@ __metadata: "@types/node": ^16.11.26 cross-fetch: ^3.1.5 msw: ^0.47.0 + qs: ^6.9.4 react-use: ^17.2.4 peerDependencies: "@types/react": ^16.13.1 || ^17.0.0 @@ -12468,126 +12469,126 @@ __metadata: languageName: node linkType: hard -"@swc/core-android-arm-eabi@npm:1.3.2": - version: 1.3.2 - resolution: "@swc/core-android-arm-eabi@npm:1.3.2" +"@swc/core-android-arm-eabi@npm:1.3.3": + version: 1.3.3 + resolution: "@swc/core-android-arm-eabi@npm:1.3.3" dependencies: "@swc/wasm": 1.2.122 conditions: os=android & cpu=arm languageName: node linkType: hard -"@swc/core-android-arm64@npm:1.3.2": - version: 1.3.2 - resolution: "@swc/core-android-arm64@npm:1.3.2" +"@swc/core-android-arm64@npm:1.3.3": + version: 1.3.3 + resolution: "@swc/core-android-arm64@npm:1.3.3" dependencies: "@swc/wasm": 1.2.130 conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@swc/core-darwin-arm64@npm:1.3.2": - version: 1.3.2 - resolution: "@swc/core-darwin-arm64@npm:1.3.2" +"@swc/core-darwin-arm64@npm:1.3.3": + version: 1.3.3 + resolution: "@swc/core-darwin-arm64@npm:1.3.3" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@swc/core-darwin-x64@npm:1.3.2": - version: 1.3.2 - resolution: "@swc/core-darwin-x64@npm:1.3.2" +"@swc/core-darwin-x64@npm:1.3.3": + version: 1.3.3 + resolution: "@swc/core-darwin-x64@npm:1.3.3" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@swc/core-freebsd-x64@npm:1.3.2": - version: 1.3.2 - resolution: "@swc/core-freebsd-x64@npm:1.3.2" +"@swc/core-freebsd-x64@npm:1.3.3": + version: 1.3.3 + resolution: "@swc/core-freebsd-x64@npm:1.3.3" dependencies: "@swc/wasm": 1.2.130 conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@swc/core-linux-arm-gnueabihf@npm:1.3.2": - version: 1.3.2 - resolution: "@swc/core-linux-arm-gnueabihf@npm:1.3.2" +"@swc/core-linux-arm-gnueabihf@npm:1.3.3": + version: 1.3.3 + resolution: "@swc/core-linux-arm-gnueabihf@npm:1.3.3" dependencies: "@swc/wasm": 1.2.130 conditions: os=linux & cpu=arm languageName: node linkType: hard -"@swc/core-linux-arm64-gnu@npm:1.3.2": - version: 1.3.2 - resolution: "@swc/core-linux-arm64-gnu@npm:1.3.2" +"@swc/core-linux-arm64-gnu@npm:1.3.3": + version: 1.3.3 + resolution: "@swc/core-linux-arm64-gnu@npm:1.3.3" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-arm64-musl@npm:1.3.2": - version: 1.3.2 - resolution: "@swc/core-linux-arm64-musl@npm:1.3.2" +"@swc/core-linux-arm64-musl@npm:1.3.3": + version: 1.3.3 + resolution: "@swc/core-linux-arm64-musl@npm:1.3.3" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@swc/core-linux-x64-gnu@npm:1.3.2": - version: 1.3.2 - resolution: "@swc/core-linux-x64-gnu@npm:1.3.2" +"@swc/core-linux-x64-gnu@npm:1.3.3": + version: 1.3.3 + resolution: "@swc/core-linux-x64-gnu@npm:1.3.3" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-x64-musl@npm:1.3.2": - version: 1.3.2 - resolution: "@swc/core-linux-x64-musl@npm:1.3.2" +"@swc/core-linux-x64-musl@npm:1.3.3": + version: 1.3.3 + resolution: "@swc/core-linux-x64-musl@npm:1.3.3" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@swc/core-win32-arm64-msvc@npm:1.3.2": - version: 1.3.2 - resolution: "@swc/core-win32-arm64-msvc@npm:1.3.2" +"@swc/core-win32-arm64-msvc@npm:1.3.3": + version: 1.3.3 + resolution: "@swc/core-win32-arm64-msvc@npm:1.3.3" dependencies: "@swc/wasm": 1.2.130 conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@swc/core-win32-ia32-msvc@npm:1.3.2": - version: 1.3.2 - resolution: "@swc/core-win32-ia32-msvc@npm:1.3.2" +"@swc/core-win32-ia32-msvc@npm:1.3.3": + version: 1.3.3 + resolution: "@swc/core-win32-ia32-msvc@npm:1.3.3" dependencies: "@swc/wasm": 1.2.130 conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@swc/core-win32-x64-msvc@npm:1.3.2": - version: 1.3.2 - resolution: "@swc/core-win32-x64-msvc@npm:1.3.2" +"@swc/core-win32-x64-msvc@npm:1.3.3": + version: 1.3.3 + resolution: "@swc/core-win32-x64-msvc@npm:1.3.3" conditions: os=win32 & cpu=x64 languageName: node linkType: hard "@swc/core@npm:^1.2.239": - version: 1.3.2 - resolution: "@swc/core@npm:1.3.2" + version: 1.3.3 + resolution: "@swc/core@npm:1.3.3" dependencies: - "@swc/core-android-arm-eabi": 1.3.2 - "@swc/core-android-arm64": 1.3.2 - "@swc/core-darwin-arm64": 1.3.2 - "@swc/core-darwin-x64": 1.3.2 - "@swc/core-freebsd-x64": 1.3.2 - "@swc/core-linux-arm-gnueabihf": 1.3.2 - "@swc/core-linux-arm64-gnu": 1.3.2 - "@swc/core-linux-arm64-musl": 1.3.2 - "@swc/core-linux-x64-gnu": 1.3.2 - "@swc/core-linux-x64-musl": 1.3.2 - "@swc/core-win32-arm64-msvc": 1.3.2 - "@swc/core-win32-ia32-msvc": 1.3.2 - "@swc/core-win32-x64-msvc": 1.3.2 + "@swc/core-android-arm-eabi": 1.3.3 + "@swc/core-android-arm64": 1.3.3 + "@swc/core-darwin-arm64": 1.3.3 + "@swc/core-darwin-x64": 1.3.3 + "@swc/core-freebsd-x64": 1.3.3 + "@swc/core-linux-arm-gnueabihf": 1.3.3 + "@swc/core-linux-arm64-gnu": 1.3.3 + "@swc/core-linux-arm64-musl": 1.3.3 + "@swc/core-linux-x64-gnu": 1.3.3 + "@swc/core-linux-x64-musl": 1.3.3 + "@swc/core-win32-arm64-msvc": 1.3.3 + "@swc/core-win32-ia32-msvc": 1.3.3 + "@swc/core-win32-x64-msvc": 1.3.3 dependenciesMeta: "@swc/core-android-arm-eabi": optional: true @@ -12617,7 +12618,7 @@ __metadata: optional: true bin: swcx: run_swcx.js - checksum: c2c83d0e6b4c56d65fb3723aa0be5e777823a6efe5b12702d4d44827a6c6dd8fac3c5dec7ff45222c7b22b4084bffc846f8497d697e61a1706817977256a65dc + checksum: bead8463cd7c11e2cd87d3835045e4a245e755409e912a40c575026a0475cc0010fa6ef48936ea5f7e62c84cdc63c21a83d61755813f2ba9b565d397fad7c5f5 languageName: node linkType: hard @@ -14598,12 +14599,12 @@ __metadata: linkType: hard "@types/tar@npm:^6.1.1": - version: 6.1.2 - resolution: "@types/tar@npm:6.1.2" + version: 6.1.3 + resolution: "@types/tar@npm:6.1.3" dependencies: "@types/node": "*" minipass: ^3.3.5 - checksum: 57e625e2db29e3b9c6d8d06774758cf6e4caa2096f4144f7c0fdb2760e1150146d2a86f0eb80b4d2e1ba0ecf07f06303775054c4f4d22bea5d51e8b54cdd0fd8 + checksum: 3a221f74adfcef8555b9c4cc951907dfd567630744ffe5211da1b44caf2a4c3b02297b73c9fb02d171e93a7a7c74fb15c1826e3f0438f0e5e8f4c790db59ddcf languageName: node linkType: hard @@ -23969,11 +23970,11 @@ __metadata: linkType: hard "graphql-ws@npm:^5.4.1, graphql-ws@npm:^5.9.0": - version: 5.10.1 - resolution: "graphql-ws@npm:5.10.1" + version: 5.11.2 + resolution: "graphql-ws@npm:5.11.2" peerDependencies: graphql: ">=0.11 <=16" - checksum: ad8eb8a6823a32a7bd9bc6ec73a0b244f503e50318ef5db1312f1d09c5f0b0e4505ad75b08f06e4c40c6935cf5170444b19347b7b83222b4e1af01401418cb91 + checksum: 2c94b06c1919217dc15a0556474673de7aabcc7179a2982a87ded51856c105e4f4ee6d54a6c135a0a7f55d85a5997a6a15cff514959258885814adec6a61ff00 languageName: node linkType: hard