diff --git a/.changeset/brave-brooms-tie.md b/.changeset/brave-brooms-tie.md new file mode 100644 index 0000000000..a4b986c9d5 --- /dev/null +++ b/.changeset/brave-brooms-tie.md @@ -0,0 +1,33 @@ +--- +'@backstage/create-app': patch +--- + +Builtin support for cookiecutter based templates has been removed from `@backstage/plugin-scaffolder-backend`. Due to this, the `containerRunner` argument to its `createRouter` has also been removed. + +If you do not use cookiecutter templates and are fine with removing support from it in your own installation, update your `packages/backend/src/plugins/scaffolder.ts` file as follows: + +```diff +-import { DockerContainerRunner } from '@backstage/backend-common'; + import { CatalogClient } from '@backstage/catalog-client'; + import { createRouter } from '@backstage/plugin-scaffolder-backend'; +-import Docker from 'dockerode'; + import { Router } from 'express'; + import type { PluginEnvironment } from '../types'; + + export default async function createPlugin({ + reader, + discovery, + }: PluginEnvironment): Promise { +- const dockerClient = new Docker(); +- const containerRunner = new DockerContainerRunner({ dockerClient }); +- + const catalogClient = new CatalogClient({ discoveryApi: discovery }); +- + return await createRouter({ +- containerRunner, + logger, + config, + // ... +``` + +If you want to retain cookiecutter support, please use the `@backstage/plugin-scaffolder-backend-module-cookiecutter` package explicitly (see [its README](https://github.com/backstage/backstage/tree/master/plugins/scaffolder-backend-module-cookiecutter) for installation instructions). diff --git a/.changeset/late-pianos-attend.md b/.changeset/late-pianos-attend.md new file mode 100644 index 0000000000..e1e0aac392 --- /dev/null +++ b/.changeset/late-pianos-attend.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-react': minor +--- + +**BREAKING**: Removed `useEntityFromUrl`. diff --git a/.changeset/many-coins-drive.md b/.changeset/many-coins-drive.md new file mode 100644 index 0000000000..b28a0b0519 --- /dev/null +++ b/.changeset/many-coins-drive.md @@ -0,0 +1,8 @@ +--- +'@backstage/plugin-scaffolder-backend': minor +--- + +**BREAKING**: + +- Removed the `createFetchCookiecutterAction` export, please use the `@backstage/plugin-scaffolder-backend-module-cookiecutter` package explicitly (see [its README](https://github.com/backstage/backstage/tree/master/plugins/scaffolder-backend-module-cookiecutter) for installation instructions). +- Removed the `containerRunner` argument from the types `RouterOptions` (as used by `createRouter`) and `CreateBuiltInActionsOptions` (as used by `createBuiltinActions`). diff --git a/.changeset/modern-windows-brush.md b/.changeset/modern-windows-brush.md new file mode 100644 index 0000000000..49c45eb41e --- /dev/null +++ b/.changeset/modern-windows-brush.md @@ -0,0 +1,9 @@ +--- +'@backstage/catalog-model': minor +--- + +**BREAKING**: + +- Removed the previously deprecated type `EntityRef`. Please use `string` for stringified entity refs, `CompoundEntityRef` for compound kind-namespace-name triplet objects, or custom objects like `{ kind?: string; namespace?: string; name: string }` and similar if you have need for partial types. +- Removed the previously deprecated type `LocationSpec` type, which has been moved to `@backstage/plugin-catalog-backend`. +- Removed the previously deprecated function `parseEntityName`. Please use `parseEntityRef` instead. diff --git a/.changeset/polite-apples-relax.md b/.changeset/polite-apples-relax.md new file mode 100644 index 0000000000..f6d10aaabf --- /dev/null +++ b/.changeset/polite-apples-relax.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend': patch +--- + +Fixed display of the location in the log message that is printed when entity envelope validation fails. diff --git a/.changeset/red-kiwis-divide.md b/.changeset/red-kiwis-divide.md new file mode 100644 index 0000000000..0bfb247093 --- /dev/null +++ b/.changeset/red-kiwis-divide.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend': minor +--- + +**BREAKING**: Removed the previously deprecated `OctokitProvider` class. diff --git a/.changeset/search-talking-in-code.md b/.changeset/search-talking-in-code.md new file mode 100644 index 0000000000..46de5f8343 --- /dev/null +++ b/.changeset/search-talking-in-code.md @@ -0,0 +1,7 @@ +--- +'@backstage/create-app': patch +--- + +Postgres-based search is now installed when PG is chosen as the desired database for Backstage. + +There is no need to make this change in an existing Backstage backend. See [supported search engines](https://backstage.io/docs/features/search/search-engines) for details about production-ready search engines. diff --git a/.changeset/spotty-seals-press.md b/.changeset/spotty-seals-press.md new file mode 100644 index 0000000000..a0a69b2efc --- /dev/null +++ b/.changeset/spotty-seals-press.md @@ -0,0 +1,7 @@ +--- +'@backstage/plugin-catalog-react': minor +--- + +**BREAKING**: Removed `useOwnedEntities` and moved its usage internally to the scaffolder-backend where it's used. + +**BREAKING**: Removed `EntityTypeReturn` type which is now inlined. diff --git a/.changeset/tender-berries-lie.md b/.changeset/tender-berries-lie.md new file mode 100644 index 0000000000..74a3eb4707 --- /dev/null +++ b/.changeset/tender-berries-lie.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Changed the logic for how modules are marked as external in the Rollup build of packages. Rather than only marking dependencies and build-in Node.js modules as external, all non-relative imports are now considered external. diff --git a/.changeset/young-feet-flow.md b/.changeset/young-feet-flow.md new file mode 100644 index 0000000000..91e55da1d8 --- /dev/null +++ b/.changeset/young-feet-flow.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-react': patch +--- + +Internalized usage of `useOwnedEntities` hook. diff --git a/.github/workflows/sync_release-manifest.yml b/.github/workflows/sync_release-manifest.yml index f4d9afc0df..328c64fb58 100644 --- a/.github/workflows/sync_release-manifest.yml +++ b/.github/workflows/sync_release-manifest.yml @@ -56,18 +56,7 @@ jobs: github-token: ${{ secrets.GH_SERVICE_ACCOUNT_TOKEN }} # TODO(Rugvip): Remove the create-app dispatch once we've been on the release version for a while script: | - console.log('Dispatching upgrade helper sync - release version'); - await github.rest.actions.createWorkflowDispatch({ - owner: 'backstage', - repo: 'upgrade-helper-diff', - workflow_id: 'release.yml', - ref: 'master', - inputs: { - version: require('./backstage/package.json').version, - }, - }); - - console.log('Dispatching upgrade helper sync - create-app version'); + console.log('Dispatching upgrade helper sync'); await github.rest.actions.createWorkflowDispatch({ owner: 'backstage', repo: 'upgrade-helper-diff', @@ -75,5 +64,6 @@ jobs: ref: 'master', inputs: { version: require('./backstage/packages/create-app/package.json').version, + releaseVersion: require('./backstage/package.json').version }, }); diff --git a/docs/features/search/README.md b/docs/features/search/README.md index 0856451882..f25087d59b 100644 --- a/docs/features/search/README.md +++ b/docs/features/search/README.md @@ -24,12 +24,12 @@ Backstage ecosystem. ## Project roadmap -| Version | Description | -| -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Backstage Search Pre-Alpha ✅ | Search Frontend letting you search through the entities of the software catalog. [See Pre-Alpha Use Cases.](#backstage-search-pre-alpha) | -| Backstage Search Alpha ✅ | Basic “out-of-the-box” in-memory indexing process of entities, and their metadata, registered to the Software Catalog. [See Alpha Use Cases](#backstage-search-alpha). | -| [Backstage Search Beta ⌛][beta] | At least one production-ready search engine that supports the same use-cases as in the alpha. [See Beta Use Cases](#backstage-search-beta). | -| [Backstage Search GA ⌛][ga] | A stable Search API for plugin developers to add search to their plugins, and app integrators to expose that to their users. [See GA Use Cases](#backstage-search-ga). | +| Version | Description | +| ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Backstage Search Pre-Alpha ✅ | Search Frontend letting you search through the entities of the software catalog. [See Pre-Alpha Use Cases.](#backstage-search-pre-alpha) | +| Backstage Search Alpha ✅ | Basic “out-of-the-box” in-memory indexing process of entities, and their metadata, registered to the Software Catalog. [See Alpha Use Cases](#backstage-search-alpha). | +| Backstage Search Beta ✅ | At least one production-ready search engine that supports the same use-cases as in the alpha. [See Beta Use Cases](#backstage-search-beta). | +| [Backstage Search GA ⌛][ga] | A stable Search API for plugin developers to add search to their plugins, and app integrators to expose that to their users. [See GA Use Cases](#backstage-search-ga). | [beta]: https://github.com/backstage/backstage/milestone/27 [ga]: https://github.com/backstage/backstage/milestone/28 diff --git a/docs/features/search/how-to-guides.md b/docs/features/search/how-to-guides.md index 0a5f53d2f2..16596c6e92 100644 --- a/docs/features/search/how-to-guides.md +++ b/docs/features/search/how-to-guides.md @@ -137,9 +137,10 @@ entities are indexed by the search engine. For the purposes of this guide, Search Beta version is defined as: -- **Search Plugin**: At least `v0.x.y` -- **Search Backend Plugin**: At least `v0.x.y` -- **Search Backend Node**: At least `v0.x.y` +- **Search Plugin**: At least `v0.7.2` +- **Search Backend Plugin**: At least `v0.4.6` +- **Search Backend Node**: At least `v0.5.0` +- **Search Common**: At least `v0.3.0` In the Beta version, the Search Platform's indexing process has been rewritten as a stream pipeline in order to improve efficiency and performance on large @@ -149,11 +150,14 @@ If you've not yet extended the Search Platform with custom code, and have instead taken advantage of default collators, decorators, and search engines provided by existing plugins, the migration process is fairly straightforward: -1. Upgrade to at least version `0.x.y` of +1. Upgrade to at least version `0.5.0` of `@backstage/plugin-search-backend-node`, as well as any backend plugins whose - collators you are using (e.g. at least version `0.x.y` of - `@backstage/plugin-catalog-backend` and/or version `0.x.y` of - `@backstage/plugin-techdocs-backend`). + collators you are using (e.g. at least version `0.23.0` of + `@backstage/plugin-catalog-backend` and/or version `0.14.1` of + `@backstage/plugin-techdocs-backend`), as well as any search-engine specific + plugin you are using (e.g. at least version `0.3.0` of + `@backstage/plugin-search-backend-module-pg` or version `0.1.0` of + `@backstage/plugin-search-backend-module-elasticsearch`). 2. Then, make the following changes to your `/packages/backend/src/plugins/search.ts` file: diff --git a/docs/local-dev/cli-build-system.md b/docs/local-dev/cli-build-system.md index f57efc1255..aed3ba70bc 100644 --- a/docs/local-dev/cli-build-system.md +++ b/docs/local-dev/cli-build-system.md @@ -181,12 +181,10 @@ files like stylesheets or images. For more details on what syntax and file formats are supported by the build process, see the [loaders section](#loaders). When building CommonJS or ESM output, the build commands will always use -`src/index.ts` as the entrypoint. All dependencies of the package will be marked -as external, meaning that in general it is only the contents of the `src` folder -that ends up being compiled and output to `dist`. All import statements of -external dependencies, even within the same monorepo, will stay intact. The -externalized dependencies are based on dependency information in `package.json`, -which means it's important to keep it up to date. +`src/index.ts` as the entrypoint. All non-relative modules imports are considered +external, meaning the Rollup build will only compile the source code of the package +itself. All import statements of external dependencies, even within the same +monorepo, will stay intact. The build of the type definitions works quite differently. The entrypoint of the type definition build is the relative location of the package within the diff --git a/packages/backend/src/plugins/scaffolder.ts b/packages/backend/src/plugins/scaffolder.ts index 619134a990..e0f3a4b1ca 100644 --- a/packages/backend/src/plugins/scaffolder.ts +++ b/packages/backend/src/plugins/scaffolder.ts @@ -14,10 +14,8 @@ * limitations under the License. */ -import { DockerContainerRunner } from '@backstage/backend-common'; import { CatalogClient } from '@backstage/catalog-client'; import { createRouter } from '@backstage/plugin-scaffolder-backend'; -import Docker from 'dockerode'; import { Router } from 'express'; import type { PluginEnvironment } from '../types'; @@ -28,13 +26,8 @@ export default async function createPlugin({ reader, discovery, }: PluginEnvironment): Promise { - const dockerClient = new Docker(); - const containerRunner = new DockerContainerRunner({ dockerClient }); - const catalogClient = new CatalogClient({ discoveryApi: discovery }); - return await createRouter({ - containerRunner, logger, config, database, diff --git a/packages/catalog-model/api-report.md b/packages/catalog-model/api-report.md index 9a65401d55..90242f9293 100644 --- a/packages/catalog-model/api-report.md +++ b/packages/catalog-model/api-report.md @@ -190,15 +190,6 @@ export type EntityPolicy = { enforce(entity: Entity): Promise; }; -// @public @deprecated -export type EntityRef = - | string - | { - kind?: string; - namespace?: string; - name: string; - }; - // @public export type EntityRelation = { type: string; @@ -316,13 +307,6 @@ export { LocationEntityV1alpha1 }; // @public export const locationEntityV1alpha1Validator: KindValidator; -// @public @deprecated -export type LocationSpec = { - type: string; - target: string; - presence?: 'optional' | 'required'; -}; - // @public export function makeValidator(overrides?: Partial): Validators; @@ -333,21 +317,6 @@ export class NoForeignRootFieldsEntityPolicy implements EntityPolicy { enforce(entity: Entity): Promise; } -// @public @deprecated -export function parseEntityName( - ref: - | string - | { - kind?: string; - namespace?: string; - name: string; - }, - context?: { - defaultKind?: string; - defaultNamespace?: string; - }, -): CompoundEntityRef; - // @public export function parseEntityRef( ref: diff --git a/packages/catalog-model/src/entity/index.ts b/packages/catalog-model/src/entity/index.ts index fb9eee0353..f46f53945f 100644 --- a/packages/catalog-model/src/entity/index.ts +++ b/packages/catalog-model/src/entity/index.ts @@ -36,7 +36,6 @@ export * from './policies'; export { getCompoundEntityRef, getEntityName, - parseEntityName, parseEntityRef, stringifyEntityRef, } from './ref'; diff --git a/packages/catalog-model/src/entity/ref.test.ts b/packages/catalog-model/src/entity/ref.test.ts index 045c4710dc..6cb7612439 100644 --- a/packages/catalog-model/src/entity/ref.test.ts +++ b/packages/catalog-model/src/entity/ref.test.ts @@ -14,171 +14,9 @@ * limitations under the License. */ -import { DEFAULT_NAMESPACE } from './constants'; -import { parseEntityName, parseEntityRef } from './ref'; +import { parseEntityRef } from './ref'; describe('ref', () => { - describe('parseEntityName', () => { - it('handles some omissions', () => { - expect(parseEntityName('a:b/c')).toEqual({ - kind: 'a', - namespace: 'b', - name: 'c', - }); - expect(() => parseEntityName('b/c')).toThrow(/kind/); - expect(parseEntityName('a:c')).toEqual({ - kind: 'a', - namespace: DEFAULT_NAMESPACE, - name: 'c', - }); - expect(() => parseEntityName('c')).toThrow(/kind/); - }); - - it('rejects bad inputs', () => { - expect(() => parseEntityName(null as any)).toThrow(); - expect(() => parseEntityName(7 as any)).toThrow(); - expect(() => parseEntityName('a:b:c')).toThrow(); - expect(() => parseEntityName('a/b/c')).toThrow(); - expect(() => parseEntityName('a/b:c')).toThrow(); - expect(() => parseEntityName('a:b/c/d')).toThrow(); - expect(() => parseEntityName('a:b/c:d')).toThrow(); - }); - - it('rejects empty parts in strings', () => { - // one is empty - expect(() => parseEntityName(':b/c')).toThrow(); - expect(() => parseEntityName('a:/c')).toThrow(); - expect(() => parseEntityName('a:b/')).toThrow(); - // two are empty - expect(() => parseEntityName('a:/')).toThrow(); - expect(() => parseEntityName(':b/')).toThrow(); - expect(() => parseEntityName(':/c')).toThrow(); - // three are empty - expect(() => parseEntityName(':/')).toThrow(); - // one is left out, one empty - expect(() => parseEntityName('/c')).toThrow(); - expect(() => parseEntityName('b/')).toThrow(); - expect(() => parseEntityName(':c')).toThrow(); - expect(() => parseEntityName('a:')).toThrow(); - // nothing at all - expect(() => parseEntityName('')).toThrow(); - }); - - it('rejects empty parts in compounds', () => { - // one is empty - expect(() => - parseEntityName({ kind: '', namespace: 'b', name: 'c' }), - ).toThrow(); - expect(() => parseEntityName({ namespace: 'b', name: 'c' })).toThrow(); - expect(() => - parseEntityName({ kind: 'a', namespace: '', name: 'c' }), - ).toThrow(); - expect(() => parseEntityName({ kind: 'a', name: 'c' })).not.toThrow(); - expect(() => - parseEntityName({ kind: 'a', namespace: 'b', name: '' }), - ).toThrow(); - expect(() => - parseEntityName({ kind: 'a', namespace: 'b' } as any), - ).toThrow(); - // two are empty - expect(() => - parseEntityName({ kind: '', namespace: '', name: 'c' }), - ).toThrow(); - expect(() => parseEntityName({ name: 'c' })).toThrow(); - expect(() => - parseEntityName({ kind: '', namespace: 'b', name: '' }), - ).toThrow(); - expect(() => parseEntityName({ namespace: 'b' } as any)).toThrow(); - expect(() => - parseEntityName({ kind: 'a', namespace: '', name: '' }), - ).toThrow(); - expect(() => parseEntityName({ kind: 'a' } as any)).toThrow(); - // three are empty - expect(() => - parseEntityName({ kind: '', namespace: '', name: '' }), - ).toThrow(); - expect(() => parseEntityName({} as any)).toThrow(); - // one is left out, one empty - expect(() => parseEntityName({ namespace: '', name: 'c' })).toThrow(); - expect(() => parseEntityName({ namespace: 'b', name: '' })).toThrow(); - expect(() => parseEntityName({ kind: '', name: 'c' })).toThrow(); - expect(() => parseEntityName({ kind: 'a', name: '' })).toThrow(); - }); - - it('adds defaults where necessary to strings', () => { - expect( - parseEntityName('a:b/c', { defaultKind: 'x', defaultNamespace: 'y' }), - ).toEqual({ kind: 'a', namespace: 'b', name: 'c' }); - expect( - parseEntityName('b/c', { defaultKind: 'x', defaultNamespace: 'y' }), - ).toEqual({ kind: 'x', namespace: 'b', name: 'c' }); - expect( - parseEntityName('a:c', { defaultKind: 'x', defaultNamespace: 'y' }), - ).toEqual({ kind: 'a', namespace: 'y', name: 'c' }); - expect(parseEntityName('a:c', { defaultKind: 'x' })).toEqual({ - kind: 'a', - namespace: DEFAULT_NAMESPACE, - name: 'c', - }); - expect( - parseEntityName('c', { defaultKind: 'x', defaultNamespace: 'y' }), - ).toEqual({ kind: 'x', namespace: 'y', name: 'c' }); - expect(parseEntityName('c', { defaultKind: 'x' })).toEqual({ - kind: 'x', - namespace: DEFAULT_NAMESPACE, - name: 'c', - }); - }); - - it('adds defaults where necessary to compounds', () => { - expect( - parseEntityName( - { kind: 'a', namespace: 'b', name: 'c' }, - { defaultKind: 'x', defaultNamespace: 'y' }, - ), - ).toEqual({ kind: 'a', namespace: 'b', name: 'c' }); - expect( - parseEntityName( - { namespace: 'b', name: 'c' }, - { defaultKind: 'x', defaultNamespace: 'y' }, - ), - ).toEqual({ kind: 'x', namespace: 'b', name: 'c' }); - expect( - parseEntityName( - { kind: 'a', name: 'c' }, - { defaultKind: 'x', defaultNamespace: 'y' }, - ), - ).toEqual({ kind: 'a', namespace: 'y', name: 'c' }); - expect( - parseEntityName({ kind: 'a', name: 'c' }, { defaultKind: 'x' }), - ).toEqual({ kind: 'a', namespace: DEFAULT_NAMESPACE, name: 'c' }); - expect( - parseEntityName( - { name: 'c' }, - { defaultKind: 'x', defaultNamespace: 'y' }, - ), - ).toEqual({ kind: 'x', namespace: 'y', name: 'c' }); - expect(parseEntityName({ name: 'c' }, { defaultKind: 'x' })).toEqual({ - kind: 'x', - namespace: DEFAULT_NAMESPACE, - name: 'c', - }); - // empty strings are errors, not defaults - expect(() => - parseEntityName( - { kind: '', namespace: 'b', name: 'c' }, - { defaultKind: 'x', defaultNamespace: 'y' }, - ), - ).toThrow(/kind/); - expect(() => - parseEntityName( - { kind: 'a', namespace: '', name: 'c' }, - { defaultKind: 'x', defaultNamespace: 'y' }, - ), - ).toThrow(/namespace/); - }); - }); - describe('parseEntityRef', () => { it('handles some omissions', () => { expect(parseEntityRef('a:b/c')).toEqual({ diff --git a/packages/catalog-model/src/entity/ref.ts b/packages/catalog-model/src/entity/ref.ts index 4529b1174c..acede5a56b 100644 --- a/packages/catalog-model/src/entity/ref.ts +++ b/packages/catalog-model/src/entity/ref.ts @@ -64,45 +64,6 @@ export function getCompoundEntityRef(entity: Entity): CompoundEntityRef { }; } -/** - * Parses an entity reference, either on string or compound form, and always - * returns a complete entity name including kind, namespace and name. - * - * @remarks - * - * This function automatically assumes the default namespace "default" unless - * otherwise specified as part of the options, and will throw an error if no - * kind was specified in the input reference and no default kind was given. - * - * @deprecated Please use parseEntityRef instead - * @public - * @param ref - The reference to parse - * @param context - The context of defaults that the parsing happens within - * @returns A complete entity name - */ -export function parseEntityName( - ref: string | { kind?: string; namespace?: string; name: string }, - context: { - /** The default kind, if none is given in the reference */ - defaultKind?: string; - /** The default namespace, if none is given in the reference */ - defaultNamespace?: string; - } = {}, -): CompoundEntityRef { - const { kind, namespace, name } = parseEntityRef(ref, { - defaultNamespace: DEFAULT_NAMESPACE, - ...context, - }); - - if (!kind) { - throw new Error( - `Entity reference ${namespace}/${name} did not contain a kind`, - ); - } - - return { kind, namespace, name }; -} - /** * Parses an entity reference, either on string or compound form, and returns * a structure with a name, and optional kind and namespace. diff --git a/packages/catalog-model/src/index.ts b/packages/catalog-model/src/index.ts index 19eacd4925..b5ccfed149 100644 --- a/packages/catalog-model/src/index.ts +++ b/packages/catalog-model/src/index.ts @@ -24,5 +24,5 @@ export * from './entity'; export { EntityPolicies } from './EntityPolicies'; export * from './kinds'; export * from './location'; -export type { EntityName, EntityRef, CompoundEntityRef } from './types'; +export type { EntityName, CompoundEntityRef } from './types'; export * from './validation'; diff --git a/packages/catalog-model/src/location/annotation.ts b/packages/catalog-model/src/location/annotation.ts index 61dbc0b305..bd282e2871 100644 --- a/packages/catalog-model/src/location/annotation.ts +++ b/packages/catalog-model/src/location/annotation.ts @@ -15,19 +15,25 @@ */ /** - * Constant storing location annotation. + * Entity annotation containing the location from which the entity is sourced. * - * @public */ + * @public + */ export const ANNOTATION_LOCATION = 'backstage.io/managed-by-location'; + /** - * Constant storing origin location annotation + * Entity annotation containing the originally sourced location which ultimately + * led to this entity being ingested. * - * @public */ + * @public + */ export const ANNOTATION_ORIGIN_LOCATION = 'backstage.io/managed-by-origin-location'; /** - * Contant storing source location annotation + * Entity annotation pointing to the source (e.g. source code repository root or + * similar) for this entity. * - * @public */ + * @public + */ export const ANNOTATION_SOURCE_LOCATION = 'backstage.io/source-location'; diff --git a/packages/catalog-model/src/location/index.ts b/packages/catalog-model/src/location/index.ts index dc709144b2..c53a1d2c83 100644 --- a/packages/catalog-model/src/location/index.ts +++ b/packages/catalog-model/src/location/index.ts @@ -24,4 +24,3 @@ export { parseLocationRef, stringifyLocationRef, } from './helpers'; -export type { LocationSpec } from './types'; diff --git a/packages/catalog-model/src/location/types.ts b/packages/catalog-model/src/location/types.ts deleted file mode 100644 index 9e2c9339e6..0000000000 --- a/packages/catalog-model/src/location/types.ts +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Holds the entity location information. - * - * @remarks - * - * `presence` flag: when using repo importer plugin, location is being created before the component yaml file is merged to the main branch. - * This flag is then set to indicate that the file can be not present. - * default value: 'required'. - * - * @public - * @deprecated Import from `@backstage/plugin-catalog-backend` instead. - */ -export type LocationSpec = { - type: string; - target: string; - presence?: 'optional' | 'required'; -}; diff --git a/packages/catalog-model/src/types.ts b/packages/catalog-model/src/types.ts index e7d819ace9..7b3f23c64f 100644 --- a/packages/catalog-model/src/types.ts +++ b/packages/catalog-model/src/types.ts @@ -33,25 +33,3 @@ export type CompoundEntityRef = { * @public */ export type EntityName = CompoundEntityRef; - -/** - * A reference by name to an entity, either as a compact string representation, - * or as a compound reference structure. - * - * @deprecated Please use string directly, or EntityName (depending on what you actually need) - * @remarks - * - * The string representation is on the form `[:][/]`. - * - * Left-out parts of the reference need to be handled by the application, - * either by rejecting the reference or by falling back to default values. - * - * @public - */ -export type EntityRef = - | string - | { - kind?: string; - namespace?: string; - name: string; - }; diff --git a/packages/cli/package.json b/packages/cli/package.json index af2c3afb2d..ec158fa5c1 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -103,7 +103,6 @@ "rollup": "^2.60.2", "rollup-plugin-dts": "^4.0.1", "rollup-plugin-esbuild": "^4.7.2", - "rollup-plugin-peer-deps-external": "^2.2.2", "rollup-plugin-postcss": "^4.0.0", "rollup-pluginutils": "^2.8.2", "run-script-webpack-plugin": "^0.0.11", diff --git a/packages/cli/src/lib/builder/config.test.ts b/packages/cli/src/lib/builder/config.test.ts new file mode 100644 index 0000000000..a2e99da73b --- /dev/null +++ b/packages/cli/src/lib/builder/config.test.ts @@ -0,0 +1,59 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ExternalOption } from 'rollup'; +import { makeRollupConfigs } from './config'; +import { Output } from './types'; + +describe('makeRollupConfigs', () => { + it('should mark external modules correctly', async () => { + const importerPath = '/some/path.ts'; // when specified we don't care about the path + + const [config] = await makeRollupConfigs({ + outputs: new Set([Output.cjs]), + }); + const external = config.external as Exclude< + ExternalOption, + string | RegExp | (string | RegExp)[] + >; + + expect(external('foo', importerPath, false)).toBe(true); + expect(external('./foo', importerPath, false)).toBe(false); + expect(external('/foo', importerPath, false)).toBe(false); + expect(external('.\\foo', importerPath, false)).toBe(false); + expect(external('c:\\foo', importerPath, false)).toBe(false); + expect(external('@foo/bar', importerPath, false)).toBe(true); + expect(external('../foo', importerPath, false)).toBe(false); + + // Modules without an importer are entry points, i.e. not external + expect(external('foo', undefined, false)).toBe(false); + expect(external('./foo', undefined, false)).toBe(false); + expect(external('/foo', undefined, false)).toBe(false); + expect(external('.\\foo', undefined, false)).toBe(false); + expect(external('c:\\foo', undefined, false)).toBe(false); + expect(external('@foo/bar', undefined, false)).toBe(false); + expect(external('../foo', undefined, false)).toBe(false); + + // After modules have been resolved they're never marked as external + expect(external('foo', importerPath, true)).toBe(false); + expect(external('./foo', importerPath, true)).toBe(false); + expect(external('/foo', importerPath, true)).toBe(false); + expect(external('.\\foo', importerPath, true)).toBe(false); + expect(external('c:\\foo', importerPath, true)).toBe(false); + expect(external('@foo/bar', importerPath, true)).toBe(false); + expect(external('../foo', importerPath, true)).toBe(false); + }); +}); diff --git a/packages/cli/src/lib/builder/config.ts b/packages/cli/src/lib/builder/config.ts index 0a214f1a7a..fe91cedbb0 100644 --- a/packages/cli/src/lib/builder/config.ts +++ b/packages/cli/src/lib/builder/config.ts @@ -17,7 +17,6 @@ import chalk from 'chalk'; import fs from 'fs-extra'; import { relative as relativePath, resolve as resolvePath } from 'path'; -import peerDepsExternal from 'rollup-plugin-peer-deps-external'; import commonjs from '@rollup/plugin-commonjs'; import resolve from '@rollup/plugin-node-resolve'; import postcss from 'rollup-plugin-postcss'; @@ -33,6 +32,19 @@ import { BuildOptions, Output } from './types'; import { paths } from '../paths'; import { svgrTemplate } from '../svgrTemplate'; +function isFileImport(source: string) { + if (source.startsWith('.')) { + return true; + } + if (source.startsWith('/')) { + return true; + } + if (source.match(/[a-z]:/i)) { + return true; + } + return false; +} + export async function makeRollupConfigs( options: BuildOptions, ): Promise { @@ -81,12 +93,10 @@ export async function makeRollupConfigs( output, onwarn, preserveEntrySignatures: 'strict', - external: require('module').builtinModules, + // All module imports are always marked as external + external: (source, importer, isResolved) => + Boolean(importer && !isResolved && !isFileImport(source)), plugins: [ - peerDepsExternal({ - packageJsonPath: resolvePath(targetDir, 'package.json'), - includeDependencies: true, - }), resolve({ mainFields }), commonjs({ include: /node_modules/, diff --git a/packages/core-components/src/components/DependencyGraph/DependencyGraph.tsx b/packages/core-components/src/components/DependencyGraph/DependencyGraph.tsx index 49f209d04e..6db8e2dd02 100644 --- a/packages/core-components/src/components/DependencyGraph/DependencyGraph.tsx +++ b/packages/core-components/src/components/DependencyGraph/DependencyGraph.tsx @@ -99,7 +99,7 @@ export interface DependencyGraphProps /** * Margin on top and bottom of whole graph * - * @remarks + * @remarks * * Default: 0 */ diff --git a/packages/create-app/package.json b/packages/create-app/package.json index 975d2cee7e..9fd8c33837 100644 --- a/packages/create-app/package.json +++ b/packages/create-app/package.json @@ -86,6 +86,7 @@ "@backstage/plugin-scaffolder-backend": "", "@backstage/plugin-search": "", "@backstage/plugin-search-backend": "", + "@backstage/plugin-search-backend-module-pg": "", "@backstage/plugin-search-backend-node": "", "@backstage/plugin-tech-radar": "", "@backstage/plugin-techdocs": "", diff --git a/packages/create-app/src/lib/versions.ts b/packages/create-app/src/lib/versions.ts index 3c898f1e02..963c04afdf 100644 --- a/packages/create-app/src/lib/versions.ts +++ b/packages/create-app/src/lib/versions.ts @@ -70,6 +70,7 @@ import { version as pluginScaffolder } from '../../../../plugins/scaffolder/pack import { version as pluginScaffolderBackend } from '../../../../plugins/scaffolder-backend/package.json'; import { version as pluginSearch } from '../../../../plugins/search/package.json'; import { version as pluginSearchBackend } from '../../../../plugins/search-backend/package.json'; +import { version as pluginSearchBackendModulePg } from '../../../../plugins/search-backend-module-pg/package.json'; import { version as pluginSearchBackendNode } from '../../../../plugins/search-backend-node/package.json'; import { version as pluginTechRadar } from '../../../../plugins/tech-radar/package.json'; import { version as pluginTechdocs } from '../../../../plugins/techdocs/package.json'; @@ -113,6 +114,7 @@ export const packageVersions = { '@backstage/plugin-scaffolder-backend': pluginScaffolderBackend, '@backstage/plugin-search': pluginSearch, '@backstage/plugin-search-backend': pluginSearchBackend, + '@backstage/plugin-search-backend-module-pg': pluginSearchBackendModulePg, '@backstage/plugin-search-backend-node': pluginSearchBackendNode, '@backstage/plugin-tech-radar': pluginTechRadar, '@backstage/plugin-techdocs': pluginTechdocs, diff --git a/packages/create-app/templates/default-app/packages/backend/package.json.hbs b/packages/create-app/templates/default-app/packages/backend/package.json.hbs index 5dd70286bc..feba5169ba 100644 --- a/packages/create-app/templates/default-app/packages/backend/package.json.hbs +++ b/packages/create-app/templates/default-app/packages/backend/package.json.hbs @@ -28,6 +28,9 @@ "@backstage/plugin-proxy-backend": "^{{version '@backstage/plugin-proxy-backend'}}", "@backstage/plugin-scaffolder-backend": "^{{version '@backstage/plugin-scaffolder-backend'}}", "@backstage/plugin-search-backend": "^{{version '@backstage/plugin-search-backend'}}", + {{#if dbTypePG}} + "@backstage/plugin-search-backend-module-pg": "^{{version '@backstage/plugin-search-backend-module-pg'}}", + {{/if}} "@backstage/plugin-search-backend-node": "^{{version '@backstage/plugin-search-backend-node'}}", "@backstage/plugin-techdocs-backend": "^{{version '@backstage/plugin-techdocs-backend'}}", "@gitbeaker/node": "^34.6.0", diff --git a/packages/create-app/templates/default-app/packages/backend/src/plugins/scaffolder.ts b/packages/create-app/templates/default-app/packages/backend/src/plugins/scaffolder.ts index 6be2e9712d..a460fd8a6d 100644 --- a/packages/create-app/templates/default-app/packages/backend/src/plugins/scaffolder.ts +++ b/packages/create-app/templates/default-app/packages/backend/src/plugins/scaffolder.ts @@ -1,7 +1,5 @@ -import { DockerContainerRunner } from '@backstage/backend-common'; import { CatalogClient } from '@backstage/catalog-client'; import { createRouter } from '@backstage/plugin-scaffolder-backend'; -import Docker from 'dockerode'; import { Router } from 'express'; import type { PluginEnvironment } from '../types'; @@ -12,12 +10,8 @@ export default async function createPlugin({ reader, discovery, }: PluginEnvironment): Promise { - const dockerClient = new Docker(); - const containerRunner = new DockerContainerRunner({ dockerClient }); const catalogClient = new CatalogClient({ discoveryApi: discovery }); - return await createRouter({ - containerRunner, logger, config, database, diff --git a/packages/create-app/templates/default-app/packages/backend/src/plugins/search.ts b/packages/create-app/templates/default-app/packages/backend/src/plugins/search.ts.hbs similarity index 85% rename from packages/create-app/templates/default-app/packages/backend/src/plugins/search.ts rename to packages/create-app/templates/default-app/packages/backend/src/plugins/search.ts.hbs index c359cb4986..d8ad991e8a 100644 --- a/packages/create-app/templates/default-app/packages/backend/src/plugins/search.ts +++ b/packages/create-app/templates/default-app/packages/backend/src/plugins/search.ts.hbs @@ -4,6 +4,9 @@ import { IndexBuilder, LunrSearchEngine, } from '@backstage/plugin-search-backend-node'; +{{#if dbTypePG}} +import { PgSearchEngine } from '@backstage/plugin-search-backend-module-pg'; +{{/if}} import { PluginEnvironment } from '../types'; import { DefaultCatalogCollatorFactory } from '@backstage/plugin-catalog-backend'; import { DefaultTechDocsCollatorFactory } from '@backstage/plugin-techdocs-backend'; @@ -16,7 +19,14 @@ export default async function createPlugin({ tokenManager, }: PluginEnvironment) { // Initialize a connection to a search engine. + {{#if dbTypeSqlite}} const searchEngine = new LunrSearchEngine({ logger }); + {{/if}} + {{#if dbTypePG}} + const searchEngine = (await PgSearchEngine.supported(database)) + ? await PgSearchEngine.from({ database }) + : new LunrSearchEngine({ logger }); + {{/if}} const indexBuilder = new IndexBuilder({ logger, searchEngine }); // Collators are responsible for gathering documents known to plugins. This diff --git a/packages/e2e-test/src/commands/run.ts b/packages/e2e-test/src/commands/run.ts index a7456f91dd..1ec9499b92 100644 --- a/packages/e2e-test/src/commands/run.ts +++ b/packages/e2e-test/src/commands/run.ts @@ -420,9 +420,15 @@ async function testBackendStart(appDir: string, isPostgres: boolean) { if (isPostgres) { print('Dropping old DBs'); await Promise.all( - ['catalog', 'scaffolder', 'auth', 'identity', 'proxy', 'techdocs'].map( - name => dropDB(`backstage_plugin_${name}`), - ), + [ + 'catalog', + 'scaffolder', + 'auth', + 'identity', + 'proxy', + 'techdocs', + 'search', + ].map(name => dropDB(`backstage_plugin_${name}`)), ); print('Created DBs'); } diff --git a/packages/test-utils/src/testUtils/logCollector.ts b/packages/test-utils/src/testUtils/logCollector.ts index b9fa6220ed..7529a00e7a 100644 --- a/packages/test-utils/src/testUtils/logCollector.ts +++ b/packages/test-utils/src/testUtils/logCollector.ts @@ -18,37 +18,44 @@ /** * Severity levels of {@link CollectedLogs} - * @public */ + * @public + */ export type LogFuncs = 'log' | 'warn' | 'error'; /** * AsyncLogCollector type used in {@link (withLogCollector:1)} callback function. - * @public */ + * @public + */ export type AsyncLogCollector = () => Promise; /** * SyncLogCollector type used in {@link (withLogCollector:2)} callback function. - * @public */ + * @public + */ export type SyncLogCollector = () => void; /** * Union type used in {@link (withLogCollector:3)} callback function. - * @public */ + * @public + */ export type LogCollector = AsyncLogCollector | SyncLogCollector; /** * Map of severity level and corresponding log lines. - * @public */ + * @public + */ export type CollectedLogs = { [key in T]: string[] }; const allCategories = ['log', 'warn', 'error']; /** * Asynchronous log collector with that collects all categories - * @public */ + * @public + */ export function withLogCollector( callback: AsyncLogCollector, ): Promise>; /** * Synchronous log collector with that collects all categories - * @public */ + * @public + */ export function withLogCollector( callback: SyncLogCollector, ): CollectedLogs; @@ -64,7 +71,8 @@ export function withLogCollector( /** * Synchronous log collector with that only collects selected categories - * @public */ + * @public + */ export function withLogCollector( logsToCollect: T[], callback: SyncLogCollector, @@ -73,7 +81,7 @@ export function withLogCollector( /** * Log collector that collect logs either from a sync or async collector. * @public - * */ + */ export function withLogCollector( logsToCollect: LogFuncs[] | LogCollector, callback?: LogCollector, diff --git a/plugins/catalog-backend/src/ingestion/types.ts b/plugins/catalog-backend/src/ingestion/types.ts index 37d12d12b1..6d1e9a3927 100644 --- a/plugins/catalog-backend/src/ingestion/types.ts +++ b/plugins/catalog-backend/src/ingestion/types.ts @@ -62,7 +62,7 @@ export type AnalyzeLocationExistingEntity = { * enough info for the frontend to know what form data to show to the user * for overriding/completing the info. * @public - * */ + */ export type AnalyzeLocationGenerateEntity = { // Some form of partial representation of the entity entity: RecursivePartial; diff --git a/plugins/catalog-backend/src/processing/ProcessorOutputCollector.ts b/plugins/catalog-backend/src/processing/ProcessorOutputCollector.ts index ff12f2f3db..cc3e1401bd 100644 --- a/plugins/catalog-backend/src/processing/ProcessorOutputCollector.ts +++ b/plugins/catalog-backend/src/processing/ProcessorOutputCollector.ts @@ -72,17 +72,17 @@ export class ProcessorOutputCollector { if (i.type === 'entity') { let entity: Entity; + const location = stringifyLocationRef(i.location); + try { entity = validateEntityEnvelope(i.entity); } catch (e) { assertError(e); - this.logger.debug(`Envelope validation failed at ${i.location}, ${e}`); + this.logger.debug(`Envelope validation failed at ${location}, ${e}`); this.errors.push(e); return; } - const location = stringifyLocationRef(i.location); - // Note that at this point, we have only validated the envelope part of // the entity data. Annotations are not part of that, so we have to be // defensive. If the annotations were malformed (e.g. were not a valid diff --git a/plugins/catalog-backend/src/processing/types.ts b/plugins/catalog-backend/src/processing/types.ts index 484cd73939..b178522c14 100644 --- a/plugins/catalog-backend/src/processing/types.ts +++ b/plugins/catalog-backend/src/processing/types.ts @@ -48,7 +48,7 @@ export type EntityProcessingResult = /** * Responsible for executing the individual processing steps in order to fully process an entity. * @public - * */ + */ export interface CatalogProcessingOrchestrator { process(request: EntityProcessingRequest): Promise; } @@ -56,7 +56,7 @@ export interface CatalogProcessingOrchestrator { /** * Entities that are not yet processed. * @public - * */ + */ export type DeferredEntity = { entity: Entity; locationKey?: string; diff --git a/plugins/catalog-backend/src/service/types.ts b/plugins/catalog-backend/src/service/types.ts index 02268ab63c..fc315b9d89 100644 --- a/plugins/catalog-backend/src/service/types.ts +++ b/plugins/catalog-backend/src/service/types.ts @@ -77,7 +77,8 @@ export interface RefreshService { /** * Interacts with the database to manage locations. - * @public */ + * @public + */ export interface LocationStore { createLocation(location: LocationInput): Promise; listLocations(): Promise; diff --git a/plugins/catalog-react/api-report.md b/plugins/catalog-react/api-report.md index 85bbc51328..c42bfdf8aa 100644 --- a/plugins/catalog-react/api-report.md +++ b/plugins/catalog-react/api-report.md @@ -12,7 +12,6 @@ import { ComponentEntity } from '@backstage/catalog-model'; import { ComponentProps } from 'react'; import { CompoundEntityRef } from '@backstage/catalog-model'; import { Entity } from '@backstage/catalog-model'; -import { GetEntitiesResponse } from '@backstage/catalog-client'; import { IconButton } from '@material-ui/core'; import { LinkProps } from '@backstage/core-components'; import { Observable } from '@backstage/types'; @@ -386,15 +385,6 @@ export interface EntityTypePickerProps { initialFilter?: string; } -// @public @deprecated (undocumented) -export type EntityTypeReturn = { - loading: boolean; - error?: Error; - availableTypes: string[]; - selectedTypes: string[]; - setSelectedTypes: (types: string[]) => void; -}; - // @public export const FavoriteEntity: (props: FavoriteEntityProps) => JSX.Element; @@ -510,9 +500,6 @@ export function useEntity(): { refresh?: VoidFunction; }; -// @public @deprecated (undocumented) -export const useEntityFromUrl: () => EntityLoadingStatus; - // @public @deprecated export function useEntityKinds(): { error: Error | undefined; @@ -547,12 +534,6 @@ export function useEntityTypeFilter(): { setSelectedTypes: (types: string[]) => void; }; -// @public @deprecated -export function useOwnedEntities(allowedKinds?: string[]): { - loading: boolean; - ownedEntities: GetEntitiesResponse | undefined; -}; - // @public (undocumented) export function useRelatedEntities( entity: Entity, diff --git a/plugins/catalog-react/src/hooks/index.ts b/plugins/catalog-react/src/hooks/index.ts index 322f1cf31f..445ed8c5af 100644 --- a/plugins/catalog-react/src/hooks/index.ts +++ b/plugins/catalog-react/src/hooks/index.ts @@ -15,7 +15,6 @@ */ export { useEntity, - useEntityFromUrl, EntityProvider, AsyncEntityProvider, useAsyncEntity, @@ -35,11 +34,9 @@ export type { EntityListContextProps, } from './useEntityListProvider'; export { useEntityTypeFilter } from './useEntityTypeFilter'; -export type { EntityTypeReturn } from './useEntityTypeFilter'; export { useEntityKinds } from './useEntityKinds'; export { useRelatedEntities } from './useRelatedEntities'; export { useStarredEntities } from './useStarredEntities'; export { useStarredEntity } from './useStarredEntity'; export { loadCatalogOwnerRefs, useEntityOwnership } from './useEntityOwnership'; -export { useOwnedEntities } from './useOwnedEntities'; export { useEntityPermission } from './useEntityPermission'; diff --git a/plugins/catalog-react/src/hooks/useEntity.tsx b/plugins/catalog-react/src/hooks/useEntity.tsx index 152c1ebe61..75a623aaed 100644 --- a/plugins/catalog-react/src/hooks/useEntity.tsx +++ b/plugins/catalog-react/src/hooks/useEntity.tsx @@ -14,21 +14,12 @@ * limitations under the License. */ import { Entity } from '@backstage/catalog-model'; -import { - errorApiRef, - useApi, - useRouteRefParams, -} from '@backstage/core-plugin-api'; import { createVersionedContext, createVersionedValueMap, useVersionedContext, } from '@backstage/version-bridge'; -import React, { ReactNode, useEffect } from 'react'; -import { useNavigate } from 'react-router'; -import useAsyncRetry from 'react-use/lib/useAsyncRetry'; -import { catalogApiRef } from '../api'; -import { entityRouteRef } from '../routes'; +import React, { ReactNode } from 'react'; /** @public */ export type EntityLoadingStatus = { @@ -104,35 +95,6 @@ export const EntityProvider = ({ entity, children }: EntityProviderProps) => ( /> ); -/** @public - * @deprecated will be deleted shortly due to low external usage, re-implement if needed. - */ -export const useEntityFromUrl = (): EntityLoadingStatus => { - const { kind, namespace, name } = useRouteRefParams(entityRouteRef); - const navigate = useNavigate(); - const errorApi = useApi(errorApiRef); - const catalogApi = useApi(catalogApiRef); - - const { - value: entity, - error, - loading, - retry: refresh, - } = useAsyncRetry( - () => catalogApi.getEntityByRef({ kind, namespace, name }), - [catalogApi, kind, namespace, name], - ); - - useEffect(() => { - if (!name) { - errorApi.post(new Error('No name provided!')); - navigate('/'); - } - }, [errorApi, navigate, error, loading, entity, name]); - - return { entity, loading, error, refresh }; -}; - /** * Grab the current entity from the context, throws if the entity has not yet been loaded * or is not available. diff --git a/plugins/catalog-react/src/hooks/useEntityTypeFilter.tsx b/plugins/catalog-react/src/hooks/useEntityTypeFilter.tsx index 2159c30edc..9971536138 100644 --- a/plugins/catalog-react/src/hooks/useEntityTypeFilter.tsx +++ b/plugins/catalog-react/src/hooks/useEntityTypeFilter.tsx @@ -23,17 +23,6 @@ import { catalogApiRef } from '../api'; import { useEntityList } from './useEntityListProvider'; import { EntityTypeFilter } from '../filters'; -/** @public - * @deprecated type inlined with {@link useEntityTypeFilter}. - */ -export type EntityTypeReturn = { - loading: boolean; - error?: Error; - availableTypes: string[]; - selectedTypes: string[]; - setSelectedTypes: (types: string[]) => void; -}; - /** * A hook built on top of `useEntityList` for enabling selection of valid `spec.type` values * based on the selected EntityKindFilter. diff --git a/plugins/catalog-react/src/hooks/useOwnedEntities.ts b/plugins/catalog-react/src/hooks/useOwnedEntities.ts deleted file mode 100644 index a2258cf138..0000000000 --- a/plugins/catalog-react/src/hooks/useOwnedEntities.ts +++ /dev/null @@ -1,69 +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 { catalogApiRef } from './../api'; -import { loadCatalogOwnerRefs } from './useEntityOwnership'; -import { identityApiRef, useApi } from '@backstage/core-plugin-api'; -import { RELATION_OWNED_BY } from '@backstage/catalog-model'; -import { GetEntitiesResponse } from '@backstage/catalog-client'; -import useAsync from 'react-use/lib/useAsync'; -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 - * @deprecated Use `ownershipEntityRefs` from `identityApi.getBackstageIdentity()` instead. - */ -export function useOwnedEntities(allowedKinds?: string[]): { - loading: boolean; - ownedEntities: GetEntitiesResponse | undefined; -} { - const identityApi = useApi(identityApiRef); - const catalogApi = useApi(catalogApiRef); - - const { loading, value: refs } = useAsync(async () => { - const identity = await identityApi.getBackstageIdentity(); - const identityRefs = identity.ownershipEntityRefs; - 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]); -} diff --git a/plugins/scaffolder-backend/api-report.md b/plugins/scaffolder-backend/api-report.md index b18e199f40..612ddedecc 100644 --- a/plugins/scaffolder-backend/api-report.md +++ b/plugins/scaffolder-backend/api-report.md @@ -9,8 +9,6 @@ import { CatalogApi } from '@backstage/catalog-client'; import { CatalogProcessor } from '@backstage/plugin-catalog-backend'; import { CatalogProcessorEmit } from '@backstage/plugin-catalog-backend'; import { Config } from '@backstage/config'; -import { ContainerRunner } from '@backstage/backend-common'; -import { createFetchCookiecutterAction } from '@backstage/plugin-scaffolder-backend-module-cookiecutter'; import { createPullRequest } from 'octokit-plugin-create-pull-request'; import { Entity } from '@backstage/catalog-model'; import express from 'express'; @@ -21,7 +19,6 @@ import { Knex } from 'knex'; import { LocationSpec } from '@backstage/plugin-catalog-backend'; import { Logger as Logger_2 } from 'winston'; import { Observable } from '@backstage/types'; -import { Octokit } from 'octokit'; import { PluginDatabaseManager } from '@backstage/backend-common'; import { Schema } from 'jsonschema'; import { ScmIntegrationRegistry } from '@backstage/integration'; @@ -63,8 +60,6 @@ export interface CreateBuiltInActionsOptions { catalogClient: CatalogApi; // (undocumented) config: Config; - // @deprecated (undocumented) - containerRunner?: ContainerRunner; // (undocumented) integrations: ScmIntegrations; // (undocumented) @@ -99,8 +94,6 @@ export function createDebugLogAction(): TemplateAction<{ listWorkspace?: boolean | undefined; }>; -export { createFetchCookiecutterAction }; - // @public export function createFetchPlainAction(options: { reader: UrlReader; @@ -388,25 +381,6 @@ export function fetchContents({ outputPath: string; }): Promise; -// Warning: (ae-missing-release-tag) "OctokitProvider" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public @deprecated -export class OctokitProvider { - constructor( - integrations: ScmIntegrationRegistry, - githubCredentialsProvider?: GithubCredentialsProvider, - ); - // Warning: (ae-forgotten-export) The symbol "OctokitIntegration" needs to be exported by the entry point index.d.ts - // - // @deprecated - getOctokit( - repoUrl: string, - options?: { - token?: string; - }, - ): Promise; -} - // @public (undocumented) export interface OctokitWithPullRequestPluginClient { // (undocumented) @@ -428,8 +402,6 @@ export interface RouterOptions { // (undocumented) config: Config; // (undocumented) - containerRunner?: ContainerRunner; - // (undocumented) database: PluginDatabaseManager; // (undocumented) logger: Logger_2; diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index 09df1818b4..f0822c27bb 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -42,7 +42,6 @@ "@backstage/integration": "^0.8.0", "@backstage/plugin-catalog-backend": "^0.23.0", "@backstage/plugin-scaffolder-common": "^0.2.3", - "@backstage/plugin-scaffolder-backend-module-cookiecutter": "^0.2.3", "@backstage/types": "^0.1.3", "@gitbeaker/core": "^34.6.0", "@gitbeaker/node": "^35.1.0", diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts index c03ba150c2..7405dc4de8 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { ContainerRunner, UrlReader } from '@backstage/backend-common'; +import { UrlReader } from '@backstage/backend-common'; import { JsonObject } from '@backstage/types'; import { CatalogApi } from '@backstage/catalog-client'; import { @@ -30,7 +30,6 @@ import { import { createDebugLogAction } from './debug'; import { createFetchPlainAction, createFetchTemplateAction } from './fetch'; -import { createFetchCookiecutterAction } from '@backstage/plugin-scaffolder-backend-module-cookiecutter'; import { createFilesystemDeleteAction, createFilesystemRenameAction, @@ -49,7 +48,6 @@ import { } from './github'; import { TemplateFilter } from '../../../lib'; import { TemplateAction } from '../types'; -import { getRootLogger } from '@backstage/backend-common'; /** * The options passed to {@link createBuiltinActions} @@ -59,8 +57,6 @@ export interface CreateBuiltInActionsOptions { reader: UrlReader; integrations: ScmIntegrations; catalogClient: CatalogApi; - /** @deprecated when the cookiecutter action is removed this won't be necessary */ - containerRunner?: ContainerRunner; config: Config; additionalTemplateFilters?: Record; } @@ -78,7 +74,6 @@ export const createBuiltinActions = ( const { reader, integrations, - containerRunner, catalogClient, config, additionalTemplateFilters, @@ -135,20 +130,5 @@ export const createBuiltinActions = ( }), ]; - if (containerRunner) { - getRootLogger().warn( - `[DEPRECATED] The fetch:cookiecutter action will be removed part of the default scaffolder actions in later versions. -You can install the package seperately and remove the containerRunner from the createBuiltInActions to remove this warning, -or you can migrate to using fetch:template https://backstage.io/docs/features/software-templates/builtin-actions#migrating-from-fetchcookiecutter-to-fetchtemplate`, - ); - actions.push( - createFetchCookiecutterAction({ - reader, - integrations, - containerRunner, - }), - ); - } - return actions as TemplateAction[]; }; diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/OctokitProvider.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/OctokitProvider.test.ts deleted file mode 100644 index e2449917ab..0000000000 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/OctokitProvider.test.ts +++ /dev/null @@ -1,88 +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 { OctokitProvider } from './OctokitProvider'; -import { - ScmIntegrations, - DefaultGithubCredentialsProvider, -} from '@backstage/integration'; -import { ConfigReader } from '@backstage/config'; - -describe('getOctokit', () => { - const config = new ConfigReader({ - integrations: { - github: [ - { host: 'github.com', token: 'tokenlols' }, - { host: 'ghe.github.com' }, - ], - }, - }); - - const integrations = ScmIntegrations.fromConfig(config); - const githubCredentialsProvider = - DefaultGithubCredentialsProvider.fromIntegrations(integrations); - const octokitProvider = new OctokitProvider( - integrations, - githubCredentialsProvider, - ); - - beforeEach(() => { - jest.resetAllMocks(); - }); - - it('should throw an error when the repoUrl is not well formed', async () => { - await expect( - octokitProvider.getOctokit('github.com?repo=bob'), - ).rejects.toThrow(/missing owner/); - - await expect( - octokitProvider.getOctokit('github.com?owner=owner'), - ).rejects.toThrow(/missing repo/); - }); - - it('should throw if there is no integration config provided', async () => { - await expect( - octokitProvider.getOctokit('missing.com?repo=bob&owner=owner'), - ).rejects.toThrow(/No matching integration configuration/); - }); - - it('should throw if there is no token in the integration config that is returned', async () => { - await expect( - octokitProvider.getOctokit('ghe.github.com?repo=bob&owner=owner'), - ).rejects.toThrow(/No token available for host/); - }); - - it('should return proper Octokit', async () => { - const { client, token, owner, repo } = await octokitProvider.getOctokit( - 'github.com?repo=bob&owner=owner', - ); - expect(client).toBeDefined(); - expect(token).toBe('tokenlols'); - expect(owner).toBe('owner'); - expect(repo).toBe('bob'); - }); - - it('should return an octokit client with the passed in token if it is provided', async () => { - const { client, token, owner, repo } = await octokitProvider.getOctokit( - 'github.com?repo=bob&owner=owner', - { token: 'tokenlols2' }, - ); - expect(client).toBeDefined(); - expect(token).toBe('tokenlols2'); - expect(owner).toBe('owner'); - expect(repo).toBe('bob'); - }); -}); diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/OctokitProvider.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/OctokitProvider.ts deleted file mode 100644 index 2f3c43a6b8..0000000000 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/OctokitProvider.ts +++ /dev/null @@ -1,111 +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 { InputError } from '@backstage/errors'; -import { - DefaultGithubCredentialsProvider, - GithubCredentialsProvider, - ScmIntegrationRegistry, -} from '@backstage/integration'; -import { Octokit } from 'octokit'; -import { parseRepoUrl } from '../publish/util'; - -export type OctokitIntegration = { - client: Octokit; - token: string; - owner: string; - repo: string; -}; -/** - * OctokitProvider provides Octokit client based on ScmIntegrationsRegistry configuration. - * OctokitProvider supports GitHub credentials caching out of the box. - * - * @deprecated we are no longer providing a way from the scaffolder to generate octokit instances. - * Implement your own if you're using this method from an external package, or use the internal `getOctokitOptions` function instead - */ -export class OctokitProvider { - private readonly integrations: ScmIntegrationRegistry; - private readonly githubCredentialsProvider: GithubCredentialsProvider; - - constructor( - integrations: ScmIntegrationRegistry, - githubCredentialsProvider?: GithubCredentialsProvider, - ) { - this.integrations = integrations; - this.githubCredentialsProvider = - githubCredentialsProvider || - DefaultGithubCredentialsProvider.fromIntegrations(this.integrations); - } - - /** - * gets standard Octokit client based on repository URL. - * - * @param repoUrl - Repository URL - * - * @deprecated we are no longer providing a way from the scaffolder to generate octokit instances. - * Implement your own if you're using this method from an external package, or use the internal `getOctokitOptions` function instead - */ - async getOctokit( - repoUrl: string, - options?: { token?: string }, - ): Promise { - const { owner, repo, host } = parseRepoUrl(repoUrl, this.integrations); - - if (!owner) { - throw new InputError(`No owner provided for repo ${repoUrl}`); - } - - const integrationConfig = this.integrations.github.byHost(host)?.config; - - if (!integrationConfig) { - throw new InputError(`No integration for host ${host}`); - } - - // Short circuit the internal Github Token provider the token provided - // by the action or the caller. - if (options?.token) { - const client = new Octokit({ - auth: options.token, - baseUrl: integrationConfig.apiBaseUrl, - previews: ['nebula-preview'], - }); - - return { client, token: options.token, owner, repo }; - } - - // TODO(blam): Consider changing this API to have owner, repoo interface instead of URL as the it's - // needless to create URL and then parse again the other side. - const { token } = await this.githubCredentialsProvider.getCredentials({ - url: `https://${host}/${encodeURIComponent(owner)}/${encodeURIComponent( - repo, - )}`, - }); - - if (!token) { - throw new InputError( - `No token available for host: ${host}, with owner ${owner}, and repo ${repo}`, - ); - } - - const client = new Octokit({ - auth: token, - baseUrl: integrationConfig.apiBaseUrl, - previews: ['nebula-preview'], - }); - - return { client, token, owner, repo }; - } -} diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/index.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/index.ts index 865c433c16..07614e8a03 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/index.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/index.ts @@ -16,4 +16,3 @@ export { createGithubActionsDispatchAction } from './githubActionsDispatch'; export { createGithubWebhookAction } from './githubWebhook'; -export { OctokitProvider } from './OctokitProvider'; diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/index.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/index.ts index 8be1b62eaa..553481ba40 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/index.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/index.ts @@ -22,8 +22,5 @@ export * from './filesystem'; export * from './publish'; export * from './github'; -/** @deprecated please add this package to your own installation manually */ -export { createFetchCookiecutterAction } from '@backstage/plugin-scaffolder-backend-module-cookiecutter'; - export { runCommand, executeShellCommand } from './helpers'; export type { RunCommandOptions } from './helpers'; diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/types.ts b/plugins/scaffolder-backend/src/scaffolder/actions/types.ts index 2a87f58fd8..55ef68423e 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/types.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/types.ts @@ -26,7 +26,8 @@ import { /** * ActionContext is passed into scaffolder actions. - * @public */ + * @public + */ export type ActionContext = { /** * Base URL for the location of the task spec, typically the url of the source entity file. diff --git a/plugins/scaffolder-backend/src/service/router.test.ts b/plugins/scaffolder-backend/src/service/router.test.ts index 4041e41cf8..1c57153fb0 100644 --- a/plugins/scaffolder-backend/src/service/router.test.ts +++ b/plugins/scaffolder-backend/src/service/router.test.ts @@ -30,7 +30,6 @@ jest.doMock('fs-extra', () => ({ import { DatabaseManager, - DockerContainerRunner, getVoidLogger, PluginDatabaseManager, UrlReaders, @@ -122,7 +121,6 @@ describe('createRouter', () => { config: new ConfigReader({}), database: createDatabase(), catalogClient: createCatalogClient(template), - containerRunner: new DockerContainerRunner({} as any), reader: mockUrlReader, taskBroker, }); diff --git a/plugins/scaffolder-backend/src/service/router.ts b/plugins/scaffolder-backend/src/service/router.ts index 8f793a34d8..f7e375b0b2 100644 --- a/plugins/scaffolder-backend/src/service/router.ts +++ b/plugins/scaffolder-backend/src/service/router.ts @@ -14,11 +14,7 @@ * limitations under the License. */ -import { - ContainerRunner, - PluginDatabaseManager, - UrlReader, -} from '@backstage/backend-common'; +import { PluginDatabaseManager, UrlReader } from '@backstage/backend-common'; import { CatalogApi } from '@backstage/catalog-client'; import { parseEntityRef, stringifyEntityRef } from '@backstage/catalog-model'; import { Entity } from '@backstage/catalog-model'; @@ -61,7 +57,6 @@ export interface RouterOptions { catalogClient: CatalogApi; actions?: TemplateAction[]; taskWorkers?: number; - containerRunner?: ContainerRunner; taskBroker?: TaskBroker; additionalTemplateFilters?: Record; } @@ -89,7 +84,6 @@ export async function createRouter( database, catalogClient, actions, - containerRunner, taskWorkers, additionalTemplateFilters, } = options; @@ -128,7 +122,6 @@ export async function createRouter( : createBuiltinActions({ integrations, catalogClient, - containerRunner, reader, config, additionalTemplateFilters, diff --git a/plugins/scaffolder/src/components/fields/OwnedEntityPicker/OwnedEntityPicker.tsx b/plugins/scaffolder/src/components/fields/OwnedEntityPicker/OwnedEntityPicker.tsx index aded9acffa..fb4a7a7234 100644 --- a/plugins/scaffolder/src/components/fields/OwnedEntityPicker/OwnedEntityPicker.tsx +++ b/plugins/scaffolder/src/components/fields/OwnedEntityPicker/OwnedEntityPicker.tsx @@ -13,14 +13,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import { GetEntitiesResponse } from '@backstage/catalog-client'; +import { RELATION_OWNED_BY } from '@backstage/catalog-model'; +import { identityApiRef, useApi } from '@backstage/core-plugin-api'; import { + catalogApiRef, humanizeEntityRef, - 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 React from 'react'; +import React, { useMemo } from 'react'; +import useAsync from 'react-use/lib/useAsync'; import { FieldExtensionComponentProps } from '../../../extensions'; @@ -86,3 +90,45 @@ export const OwnedEntityPicker = ( ); }; + +/** + * 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 + * + * + * @param allowedKinds - Array of allowed kinds to filter the entities + */ +function useOwnedEntities(allowedKinds?: string[]): { + loading: boolean; + ownedEntities: GetEntitiesResponse | undefined; +} { + const identityApi = useApi(identityApiRef); + const catalogApi = useApi(catalogApiRef); + + const { loading, value: refs } = useAsync(async () => { + const identity = await identityApi.getBackstageIdentity(); + const identityRefs = identity.ownershipEntityRefs; + const catalogs = await catalogApi.getEntities( + allowedKinds + ? { + filter: { + kind: allowedKinds, + [`relations.${RELATION_OWNED_BY}`]: identityRefs || [], + }, + } + : { + filter: { + [`relations.${RELATION_OWNED_BY}`]: identityRefs || [], + }, + }, + ); + return catalogs; + }, []); + + const ownedEntities = useMemo(() => { + return refs; + }, [refs]); + + return useMemo(() => ({ loading, ownedEntities }), [loading, ownedEntities]); +} diff --git a/plugins/tech-insights-node/src/facts.ts b/plugins/tech-insights-node/src/facts.ts index 7a70f92f92..24b6764ba4 100644 --- a/plugins/tech-insights-node/src/facts.ts +++ b/plugins/tech-insights-node/src/facts.ts @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { DateTime, DurationLike } from 'luxon'; import { Config } from '@backstage/config'; import { PluginEndpointDiscovery } from '@backstage/backend-common'; @@ -62,11 +63,10 @@ export type TechInsightFact = { }; /** - * Response type used when returning from database and API. * Adds a field for ref for easier usage * - * @public + * @public */ export type FlatTechInsightFact = TechInsightFact & { /** @@ -76,12 +76,12 @@ export type FlatTechInsightFact = TechInsightFact & { }; /** - * @public - * * A record type to specify individual fact shapes * * Used as part of a schema to validate, identify and generically construct usage implementations * of individual fact values in the system. + * + * @public */ export type FactSchema = { /** @@ -142,11 +142,9 @@ export type FactRetrieverContext = { }; /** - * @public - * * FactRetriever interface * - * A component specifying + * @public */ export interface FactRetriever { /** @@ -191,10 +189,9 @@ export interface FactRetriever { } /** - * @public - * * A Luxon duration like object for time to live value * + * @public * @example * \{ timeToLive: 1209600000 \} * \{ timeToLive: \{ weeks: 4 \} \} @@ -203,10 +200,9 @@ export interface FactRetriever { export type TTL = { timeToLive: DurationLike }; /** - * @public - * * A maximum number for items to be kept in the database for each fact retriever/entity pair * + * @public * @example * \{ maxItems: 10 \} * @@ -214,25 +210,25 @@ export type TTL = { timeToLive: DurationLike }; export type MaxItems = { maxItems: number }; /** - * @public - * * A fact lifecycle definition. Determines which strategy to use to purge expired facts from the database. + * + * @public */ export type FactLifecycle = TTL | MaxItems; /** - * @public - * * A flat serializable structure for Facts. * Containing information about fact schema, version, id, and entity filters + * + * @public */ export type FactSchemaDefinition = Omit; /** - * @public - * * Registration of a fact retriever * Used to add and schedule individual fact retrievers to the fact retriever engine. + * + * @public */ export type FactRetrieverRegistration = { /** diff --git a/plugins/techdocs-backend/src/service/router.ts b/plugins/techdocs-backend/src/service/router.ts index 73f212d049..9d240cb7fa 100644 --- a/plugins/techdocs-backend/src/service/router.ts +++ b/plugins/techdocs-backend/src/service/router.ts @@ -347,8 +347,8 @@ export function createEventStream( } /** - * @deprecated use event-stream implementation of the sync endpoint - * */ + * @deprecated use event-stream implementation of the sync endpoint + */ export function createHttpResponse( res: Response, ): DocsSynchronizerSyncOpts { diff --git a/yarn.lock b/yarn.lock index 5d8b1c24d7..02532c5286 100644 --- a/yarn.lock +++ b/yarn.lock @@ -22048,11 +22048,6 @@ rollup-plugin-esbuild@^4.7.2: joycon "^3.0.1" jsonc-parser "^3.0.0" -rollup-plugin-peer-deps-external@^2.2.2: - version "2.2.4" - resolved "https://registry.npmjs.org/rollup-plugin-peer-deps-external/-/rollup-plugin-peer-deps-external-2.2.4.tgz#8a420bbfd6dccc30aeb68c9bf57011f2f109570d" - integrity sha512-AWdukIM1+k5JDdAqV/Cxd+nejvno2FVLVeZ74NKggm3Q5s9cbbcOgUPGdbxPi4BXu7xGaZ8HG12F+thImYu/0g== - rollup-plugin-postcss@*, rollup-plugin-postcss@^4.0.0: version "4.0.2" resolved "https://registry.npmjs.org/rollup-plugin-postcss/-/rollup-plugin-postcss-4.0.2.tgz#15e9462f39475059b368ce0e49c800fa4b1f7050"