diff --git a/.changeset/bright-birds-jog.md b/.changeset/bright-birds-jog.md
new file mode 100644
index 0000000000..20954eca77
--- /dev/null
+++ b/.changeset/bright-birds-jog.md
@@ -0,0 +1,14 @@
+---
+'@backstage/core-components': patch
+---
+
+Fix warning produced by BottomLink component
+
+During development, we noticed warnings such as:
+
+```
+react_devtools_backend.js:2842 Warning: validateDOMNesting(...):
cannot appear as a descendant of
.
+```
+
+The BottomLink component renders a Box component within a Typography component which leads to a div tag within a p tag.
+This change inverts that ordering without changing the visual appearance.
diff --git a/.changeset/dull-trains-shout.md b/.changeset/dull-trains-shout.md
new file mode 100644
index 0000000000..bfd9a461d3
--- /dev/null
+++ b/.changeset/dull-trains-shout.md
@@ -0,0 +1,11 @@
+---
+'@backstage/backend-test-utils': patch
+'@backstage/catalog-client': patch
+'@backstage/catalog-model': patch
+'@backstage/cli-common': patch
+'@backstage/config-loader': patch
+'@backstage/dev-utils': patch
+'@backstage/errors': patch
+---
+
+Properly export all used types.
diff --git a/.changeset/forty-moons-boil.md b/.changeset/forty-moons-boil.md
new file mode 100644
index 0000000000..0000374546
--- /dev/null
+++ b/.changeset/forty-moons-boil.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-todo': patch
+---
+
+All types are now properly documented and exported.
diff --git a/.changeset/good-singers-flourish.md b/.changeset/good-singers-flourish.md
new file mode 100644
index 0000000000..d8b6e1a140
--- /dev/null
+++ b/.changeset/good-singers-flourish.md
@@ -0,0 +1,6 @@
+---
+'@backstage/plugin-home': minor
+---
+
+Rename RandomJokeHomePageComponent to HomePageRandomJoke to fit convention, and update example app accordingly.
+**NOTE**: If you're using the RandomJoke component in your instance, it now has to be renamed to `HomePageRandomJoke`
diff --git a/.changeset/great-balloons-walk.md b/.changeset/great-balloons-walk.md
new file mode 100644
index 0000000000..7675a2badd
--- /dev/null
+++ b/.changeset/great-balloons-walk.md
@@ -0,0 +1,5 @@
+---
+'@backstage/config': patch
+---
+
+Documented `Config` interface and mark types as public.
diff --git a/.changeset/long-walls-tie.md b/.changeset/long-walls-tie.md
new file mode 100644
index 0000000000..c23c34b4ce
--- /dev/null
+++ b/.changeset/long-walls-tie.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-scaffolder-backend': patch
+---
+
+GitHub Webhook action in Scaffolder Backend has been improved to validate event names against Octokit Webhook event names list.
diff --git a/.changeset/lucky-lies-count.md b/.changeset/lucky-lies-count.md
new file mode 100644
index 0000000000..79e7c09391
--- /dev/null
+++ b/.changeset/lucky-lies-count.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-org': patch
+---
+
+Make ownership card style customizable via custom `theme.getPageTheme()`.
diff --git a/.changeset/perfect-elephants-do.md b/.changeset/perfect-elephants-do.md
new file mode 100644
index 0000000000..d5e4c864d7
--- /dev/null
+++ b/.changeset/perfect-elephants-do.md
@@ -0,0 +1,21 @@
+---
+'@backstage/plugin-catalog-backend': patch
+---
+
+Use `ScmIntegrationRegistry#resolveUrl` in the placeholder processors instead of a custom implementation.
+
+If you manually instantiate the `PlaceholderProcessor` (you most probably don't), add the new required constructor parameter:
+
+```diff
++ import { ScmIntegrations } from '@backstage/integration';
+ // ...
++ const integrations = ScmIntegrations.fromConfig(config);
+ // ...
+ new PlaceholderProcessor({
+ resolvers: placeholderResolvers,
+ reader,
++ integrations,
+ });
+```
+
+All custom `PlaceholderResolver` can use the new `resolveUrl` parameter to resolve relative URLs.
diff --git a/.changeset/sour-bees-pretend.md b/.changeset/sour-bees-pretend.md
new file mode 100644
index 0000000000..748266132c
--- /dev/null
+++ b/.changeset/sour-bees-pretend.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-org': patch
+---
+
+Use correct `Link` in ownership card to avoid a full reload of the app while navigating.
diff --git a/.changeset/strong-pears-wink.md b/.changeset/strong-pears-wink.md
new file mode 100644
index 0000000000..811eb56519
--- /dev/null
+++ b/.changeset/strong-pears-wink.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-scaffolder': patch
+---
+
+Fix display error when it fails to load a template (/create) page
diff --git a/.changeset/twenty-ravens-fetch.md b/.changeset/twenty-ravens-fetch.md
new file mode 100644
index 0000000000..28393b7936
--- /dev/null
+++ b/.changeset/twenty-ravens-fetch.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-search': patch
+---
+
+Add Home Page Search Bar Component, to be included in composable Home Page.
diff --git a/.changeset/wise-monkeys-enjoy.md b/.changeset/wise-monkeys-enjoy.md
new file mode 100644
index 0000000000..446d5bbfad
--- /dev/null
+++ b/.changeset/wise-monkeys-enjoy.md
@@ -0,0 +1,5 @@
+---
+'@backstage/backend-common': patch
+---
+
+Properly export all used types.
diff --git a/.changeset/yellow-hats-sniff.md b/.changeset/yellow-hats-sniff.md
new file mode 100644
index 0000000000..b360cfef29
--- /dev/null
+++ b/.changeset/yellow-hats-sniff.md
@@ -0,0 +1,6 @@
+---
+'@backstage/cli': patch
+---
+
+Support importing font files in tests.
+This fixes remaining issues from [#7019](https://github.com/backstage/backstage/pull/7019).
diff --git a/.snyk b/.snyk
new file mode 100644
index 0000000000..732671517a
--- /dev/null
+++ b/.snyk
@@ -0,0 +1,10 @@
+# Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities.
+version: v1.22.1
+# ignores vulnerabilities until expiry date; change duration by modifying expiry date
+ignore:
+ SNYK-JS-ANSIHTML-1296849:
+ - '@backstage/cli > webpack-dev-server > ansi-html':
+ reason: Developer tools are not a valid target for ReDoS attacks
+ expires: 2022-03-06T17:18:55.019Z
+ created: 2021-09-06T17:18:55.027Z
+patch: {}
diff --git a/docs/assets/features/catalog/life-of-an-entity_processing.svg b/docs/assets/features/catalog/life-of-an-entity_processing.svg
new file mode 100644
index 0000000000..da3c4c7dba
--- /dev/null
+++ b/docs/assets/features/catalog/life-of-an-entity_processing.svg
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/docs/assets/features/catalog/life-of-an-entity_stitching.svg b/docs/assets/features/catalog/life-of-an-entity_stitching.svg
new file mode 100644
index 0000000000..3b232a361c
--- /dev/null
+++ b/docs/assets/features/catalog/life-of-an-entity_stitching.svg
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/docs/features/software-catalog/life-of-an-entity.md b/docs/features/software-catalog/life-of-an-entity.md
index 817529c0f2..9e8a3f0563 100644
--- a/docs/features/software-catalog/life-of-an-entity.md
+++ b/docs/features/software-catalog/life-of-an-entity.md
@@ -111,20 +111,136 @@ as possible.
Each catalog deployment has a number of processors installed. They are
responsible for receiving unprocessed entities that the catalog decided are due
for processing, and then running that data through a number of processing
-stages. mutating the entity and emitting auxiliary data about it. When all of
+stages, mutating the entity and emitting auxiliary data about it. When all of
that is done, the catalog takes all of that information and stores it as the
processed entity, and errors and relations to other entities separately. Then,
the catalog checks to see what entities are touched by that output, and triggers
the final assembly of those (see Stitching below).
-There are several stages involved in the processing.
+
-> TODO: More info here
+Entities are always processed one by one, but all of your catalog service hosts
+collaborate in doing so to distribute the load. Note how each processor can
+contribute to one or more of the fixed steps in the processing pipeline. First
+all of the processors' contributions to one step are run in the order that the
+processors were registered, then all of their contributions to the next step in
+the same order, and so on.
+
+Each step has the opportunity to optionally modify the entity, and to optionally
+emit other information. For example, the processor might look at information in
+the `spec` field of the entity, and emit relations that correspond to those
+declarations. If the processor emits an entity, then that entity gets stored
+verbatim with a timestamp saying that it, too, should be processed as soon as
+possible. If errors are emitted, then that signals that something is wrong with
+the entity and that it should not replace whatever previously error-free version
+we had among the final entities. If relations are emitted, then they are put in
+a dedicated relations table to be picked up by the stitching process below.
+
+> Optional low level detail note: When entities are emitted, the catalog keeps
+> track of the edges between the emitting entity and the ones emitted. This
+> happens behind the scenes, hidden from the outside, and is used to form a
+> graph. This is _not_ the same thing as relations! The purpose of these edges,
+> is to be able to detect when an entity becomes orphaned (see below), and to be
+> able to perform eager deletions throughout the graph when a root is explicitly
+> unregistered and nothing else is keeping lower nodes alive. We will talk more
+> about orphaning and deletions later on in this article.
+
+When the final step has completed, and no errors were encountered, the processed
+entity and all of the relations are finally persisted in the database. Then the
+catalog considers this entity, and all of the entities it had relations to,
+subject for stitching.
+
+It is worth noting here that the processing does not lead to deletion or
+unregistration of entities; it can only call new entities into existence or
+update entities that it has previously called into existence. More about that
+later.
## Stitching
+Stitching finalizes the entity, by gathering all of the output from the previous
+steps and merging them into the final object which is what is visible from the
+catalog API. As the final entity itself gets updated, the stitcher makes sure
+that the search table gets refreshed accordingly as well.
+
+> Note: The search table mentioned here is not related to the core Search
+> feature of Backstage. It's rather the table that backs the ability to filter
+> catalog API query results.
+
+
+
+The diagram shows how the stitcher reads from several sources:
+
+- The processed entity, as returned from the processing step
+- The errors, if any, that were emitted by the processing step
+- All relations that were emitted by the processing step, as well as any
+ relations emitted by _other_ entity processing steps that happen to point at
+ the current entity
+
+The last part is noteworthy: This is how the stitcher is able to collect all of
+the relation edges, both incoming and outgoing, no matter who produced them.
+
The stitching is currently a fixed process, that cannot be modified or extended.
This means that any modifications you want to make on the final result, has to
happen during ingestion or processing.
-> TODO: More info here
+## Errors
+
+> TODO: Describe how errors are exposed through entities
+
+## Orphaning
+
+As mentioned earlier, entities internally form a graph. The edges go from
+processed parent entities, to child entities emitted while processing the
+parent.
+
+The processing loop runs continuously, so these edges are reconsidered over
+time. If processing a parent entity no longer emits a given child entity, then
+that former edge is severed. If that child has no other edges pointing at it
+either, it becomes _orphaned_. The end result is as follows:
+
+- The stitching process injects a `backstage.io/orphan: 'true'` annotation on
+ the child entity.
+- The child entity is _not_ removed from the catalog, but stays around until
+ explicitly deleted via the catalog API, or "reclaimed" by the original parent
+ or another parent starting to reference it.
+- The catalog page in Backstage for the child entity detects the new annotation
+ and informs users about the orphan status.
+
+Orphaning can occur in several different scenarios. One common cause is that the
+end user edited a corresponding catalog catalog-info YAML file removing the
+entity's entry. In the case of a `Location` parent entity, orphaning can happen
+if removing the target line pointing to the file containing the child entity.
+Another common cause is large batch processors such as the ones that crawl
+through remote systems looking for entities, no longer finding something that it
+used to find before. Maybe the data was moved, or deleted, in the remote system.
+So for example when a person leaves the company an LDAP org discovery processor
+might leave an orphaned `User` entity behind. Note that this only applies to
+processors - ingestion that happens using entity providers work differently,
+described below.
+
+> Note that removing a file, or accidentally corrupting a file so that it cannot
+> be read successfully, does _not_ lead to orphaning. Hard errors, including the
+> inability to find or read a distinct remote, are marked as such on the entity
+> to inform the owner that something is wrong. But processing and other
+> behaviors continue as usual.
+
+The reason that the orphaning mechanism exists instead of having an eager
+deletion triggered, is safety. Scenarios like these can happen purely by
+accident, due to the asynchronous nature of the system and the fallible nature
+of humans. In particular when external systems start consuming and relying on
+the catalog, there could be substantial consequences to suddenly dropping
+entities without explicit owner consent. The catalog therefore takes the stance
+that entities that often were added by direct user action should also be deleted
+only by direct user action.
+
+It is possible to use the catalog API to build automated "reaper" systems that
+finally delete entities that are orphaned. This is however not something that's
+provided out of the box.
+
+## Implicit Deletion
+
+> TODO: Describe the process of entity providers eagerly deleting entities
+
+## Explicit Deletion
+
+> TODO: Describe direct deletion via the catalog API
diff --git a/packages/app/src/components/home/HomePage.tsx b/packages/app/src/components/home/HomePage.tsx
index e171e22ae9..5831b49d2c 100644
--- a/packages/app/src/components/home/HomePage.tsx
+++ b/packages/app/src/components/home/HomePage.tsx
@@ -17,27 +17,28 @@
import React from 'react';
import Grid from '@material-ui/core/Grid';
import {
- RandomJokeHomePageComponent,
+ HomePageRandomJoke,
ComponentAccordion,
ComponentTabs,
ComponentTab,
} from '@backstage/plugin-home';
+import { HomePageSearchBar } from '@backstage/plugin-search';
export const HomePage = () => (
-
-
+
+
-
-
+
+
+
+
- (
{
label: 'Programming',
Component: () => (
-
@@ -59,7 +60,7 @@ export const HomePage = () => (
{
label: 'Any',
Component: () => (
-
diff --git a/packages/backend-common/api-report.md b/packages/backend-common/api-report.md
index de8c1d4101..eb1f9ad31f 100644
--- a/packages/backend-common/api-report.md
+++ b/packages/backend-common/api-report.md
@@ -9,7 +9,6 @@
import { AzureIntegration } from '@backstage/integration';
import { BitbucketIntegration } from '@backstage/integration';
import { Config } from '@backstage/config';
-import { ConfigReader } from '@backstage/config';
import cors from 'cors';
import Docker from 'dockerode';
import { ErrorRequestHandler } from 'express';
@@ -17,7 +16,6 @@ import express from 'express';
import { GithubCredentialsProvider } from '@backstage/integration';
import { GitHubIntegration } from '@backstage/integration';
import { GitLabIntegration } from '@backstage/integration';
-import * as http from 'http';
import { isChildPath } from '@backstage/cli-common';
import { JsonValue } from '@backstage/config';
import { Knex } from 'knex';
@@ -32,8 +30,6 @@ import { Server } from 'http';
import * as winston from 'winston';
import { Writable } from 'stream';
-// Warning: (ae-missing-release-tag) "AzureUrlReader" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export class AzureUrlReader implements UrlReader {
constructor(
@@ -56,8 +52,6 @@ export class AzureUrlReader implements UrlReader {
toString(): string;
}
-// Warning: (ae-missing-release-tag) "BitbucketUrlReader" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export class BitbucketUrlReader implements UrlReader {
constructor(
@@ -80,92 +74,82 @@ export class BitbucketUrlReader implements UrlReader {
toString(): string;
}
-// Warning: (ae-missing-release-tag) "CacheClient" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export interface CacheClient {
delete(key: string): Promise;
get(key: string): Promise;
- // Warning: (ae-forgotten-export) The symbol "CacheSetOptions" needs to be exported by the entry point index.d.ts
- set(key: string, value: JsonValue, options?: CacheSetOptions): Promise;
+ set(
+ key: string,
+ value: JsonValue,
+ options?: CacheClientSetOptions,
+ ): Promise;
}
-// Warning: (ae-missing-release-tag) "CacheManager" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
+// @public (undocumented)
+export type CacheClientOptions = {
+ defaultTtl?: number;
+};
+
+// @public (undocumented)
+export type CacheClientSetOptions = {
+ ttl?: number;
+};
+
// @public
export class CacheManager {
- // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
forPlugin(pluginId: string): PluginCacheManager;
- // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
- // Warning: (ae-forgotten-export) The symbol "CacheManagerOptions" needs to be exported by the entry point index.d.ts
static fromConfig(
config: Config,
options?: CacheManagerOptions,
): CacheManager;
}
-// Warning: (ae-missing-release-tag) "coloredFormat" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
+// @public (undocumented)
+export type CacheManagerOptions = {
+ logger?: Logger_2;
+ onError?: (err: Error) => void;
+};
+
// @public (undocumented)
export const coloredFormat: winston.Logform.Format;
-// Warning: (ae-missing-release-tag) "ContainerRunner" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export interface ContainerRunner {
// (undocumented)
runContainer(opts: RunContainerOptions): Promise;
}
-// Warning: (ae-missing-release-tag) "createDatabase" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public @deprecated
export const createDatabase: typeof createDatabaseClient;
-// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
-// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
-// Warning: (ae-missing-release-tag) "createDatabaseClient" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export function createDatabaseClient(
dbConfig: Config,
overrides?: Partial,
): Knex;
-// Warning: (ae-missing-release-tag) "createRootLogger" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export function createRootLogger(
options?: winston.LoggerOptions,
env?: NodeJS.ProcessEnv,
): winston.Logger;
-// Warning: (ae-forgotten-export) The symbol "ServiceBuilderImpl" needs to be exported by the entry point index.d.ts
-// Warning: (ae-missing-release-tag) "createServiceBuilder" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
-export function createServiceBuilder(_module: NodeModule): ServiceBuilderImpl;
+export function createServiceBuilder(_module: NodeModule): ServiceBuilder;
-// Warning: (ae-forgotten-export) The symbol "StatusCheckRouterOptions" needs to be exported by the entry point index.d.ts
-// Warning: (ae-missing-release-tag) "createStatusCheckRouter" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
-export function createStatusCheckRouter(
- options: StatusCheckRouterOptions,
-): Promise;
+export function createStatusCheckRouter(options: {
+ logger: Logger_2;
+ path?: string;
+ statusCheck?: StatusCheck;
+}): Promise;
-// Warning: (ae-missing-release-tag) "DatabaseManager" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export class DatabaseManager {
- // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
forPlugin(pluginId: string): PluginDatabaseManager;
- // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
static fromConfig(config: Config): DatabaseManager;
}
-// Warning: (ae-missing-release-tag) "DockerContainerRunner" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export class DockerContainerRunner implements ContainerRunner {
constructor({ dockerClient }: { dockerClient: Docker });
@@ -182,23 +166,17 @@ export class DockerContainerRunner implements ContainerRunner {
}: RunContainerOptions): Promise;
}
-// Warning: (ae-missing-release-tag) "ensureDatabaseExists" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export function ensureDatabaseExists(
dbConfig: Config,
...databases: Array
): Promise;
-// Warning: (ae-missing-release-tag) "errorHandler" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export function errorHandler(
options?: ErrorHandlerOptions,
): ErrorRequestHandler;
-// Warning: (ae-missing-release-tag) "ErrorHandlerOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export type ErrorHandlerOptions = {
showStackTraces?: boolean;
@@ -206,18 +184,12 @@ export type ErrorHandlerOptions = {
logClientErrors?: boolean;
};
-// Warning: (ae-missing-release-tag) "getRootLogger" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export function getRootLogger(): winston.Logger;
-// Warning: (ae-missing-release-tag) "getVoidLogger" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export function getVoidLogger(): winston.Logger;
-// Warning: (ae-missing-release-tag) "Git" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export class Git {
// (undocumented)
@@ -322,8 +294,6 @@ export class Git {
resolveRef({ dir, ref }: { dir: string; ref: string }): Promise;
}
-// Warning: (ae-missing-release-tag) "GithubUrlReader" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export class GithubUrlReader implements UrlReader {
constructor(
@@ -347,8 +317,6 @@ export class GithubUrlReader implements UrlReader {
toString(): string;
}
-// Warning: (ae-missing-release-tag) "GitlabUrlReader" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export class GitlabUrlReader implements UrlReader {
constructor(
@@ -373,41 +341,31 @@ export class GitlabUrlReader implements UrlReader {
export { isChildPath };
-// Warning: (ae-forgotten-export) The symbol "Options" needs to be exported by the entry point index.d.ts
-// Warning: (ae-missing-release-tag) "loadBackendConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
-export function loadBackendConfig(options: Options): Promise;
+export function loadBackendConfig(options: {
+ logger: Logger_2;
+ argv: string[];
+}): Promise;
-// Warning: (ae-missing-release-tag) "notFoundHandler" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export function notFoundHandler(): RequestHandler;
-// Warning: (ae-missing-release-tag) "PluginCacheManager" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export type PluginCacheManager = {
- getClient: (options?: ClientOptions) => CacheClient;
+ getClient: (options?: CacheClientOptions) => CacheClient;
};
-// Warning: (ae-missing-release-tag) "PluginDatabaseManager" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export interface PluginDatabaseManager {
getClient(): Promise;
}
-// Warning: (ae-missing-release-tag) "PluginEndpointDiscovery" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export type PluginEndpointDiscovery = {
getBaseUrl(pluginId: string): Promise;
getExternalBaseUrl(pluginId: string): Promise;
};
-// Warning: (ae-missing-release-tag) "ReaderFactory" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export type ReaderFactory = (options: {
config: Config;
@@ -415,8 +373,6 @@ export type ReaderFactory = (options: {
treeResponseFactory: ReadTreeResponseFactory;
}) => UrlReaderPredicateTuple[];
-// Warning: (ae-missing-release-tag) "ReadTreeOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export type ReadTreeOptions = {
filter?(
@@ -428,8 +384,6 @@ export type ReadTreeOptions = {
etag?: string;
};
-// Warning: (ae-missing-release-tag) "ReadTreeResponse" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export type ReadTreeResponse = {
files(): Promise;
@@ -438,68 +392,67 @@ export type ReadTreeResponse = {
etag: string;
};
-// Warning: (ae-missing-release-tag) "ReadTreeResponseFactory" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
+// @public (undocumented)
+export type ReadTreeResponseDirOptions = {
+ targetDir?: string;
+};
+
// @public (undocumented)
export interface ReadTreeResponseFactory {
- // Warning: (ae-forgotten-export) The symbol "FromArchiveOptions" needs to be exported by the entry point index.d.ts
- //
// (undocumented)
- fromTarArchive(options: FromArchiveOptions): Promise;
+ fromTarArchive(
+ options: ReadTreeResponseFactoryOptions,
+ ): Promise;
// (undocumented)
- fromZipArchive(options: FromArchiveOptions): Promise;
+ fromZipArchive(
+ options: ReadTreeResponseFactoryOptions,
+ ): Promise;
}
-// Warning: (ae-missing-release-tag) "ReadTreeResponseFile" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
+// @public (undocumented)
+export type ReadTreeResponseFactoryOptions = {
+ stream: Readable;
+ subpath?: string;
+ etag: string;
+ filter?: (
+ path: string,
+ info?: {
+ size: number;
+ },
+ ) => boolean;
+};
+
// @public
export type ReadTreeResponseFile = {
path: string;
content(): Promise;
};
-// Warning: (ae-missing-release-tag) "ReadUrlOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export type ReadUrlOptions = {
etag?: string;
};
-// Warning: (ae-missing-release-tag) "ReadUrlResponse" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export type ReadUrlResponse = {
buffer(): Promise;
etag?: string;
};
-// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
-// Warning: (ae-missing-release-tag) "requestLoggingHandler" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export function requestLoggingHandler(logger?: Logger_2): RequestHandler;
-// Warning: (ae-missing-release-tag) "RequestLoggingHandlerFactory" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export type RequestLoggingHandlerFactory = (
logger?: Logger_2,
) => RequestHandler;
-// Warning: (ae-missing-release-tag) "resolvePackagePath" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export function resolvePackagePath(name: string, ...paths: string[]): string;
-// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
-// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
-// Warning: (ae-missing-release-tag) "resolveSafeChildPath" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export function resolveSafeChildPath(base: string, path: string): string;
-// Warning: (ae-missing-release-tag) "RunContainerOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export type RunContainerOptions = {
imageName: string;
@@ -512,39 +465,40 @@ export type RunContainerOptions = {
pullImage?: boolean;
};
-// Warning: (ae-missing-release-tag) "SearchOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export type SearchOptions = {
etag?: string;
};
-// Warning: (ae-missing-release-tag) "SearchResponse" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export type SearchResponse = {
files: SearchResponseFile[];
etag: string;
};
-// Warning: (ae-missing-release-tag) "SearchResponseFile" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export type SearchResponseFile = {
url: string;
content(): Promise;
};
-// Warning: (ae-missing-release-tag) "ServiceBuilder" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export type ServiceBuilder = {
- loadConfig(config: ConfigReader): ServiceBuilder;
+ loadConfig(config: Config): ServiceBuilder;
setPort(port: number): ServiceBuilder;
setHost(host: string): ServiceBuilder;
setLogger(logger: Logger_2): ServiceBuilder;
enableCors(options: cors.CorsOptions): ServiceBuilder;
- setHttpsSettings(settings: HttpsSettings): ServiceBuilder;
+ setHttpsSettings(settings: {
+ certificate:
+ | {
+ key: string;
+ cert: string;
+ }
+ | {
+ hostname: string;
+ };
+ }): ServiceBuilder;
addRouter(root: string, router: Router | RequestHandler): ServiceBuilder;
setRequestLoggingHandler(
requestLoggingHandler: RequestLoggingHandlerFactory,
@@ -552,18 +506,12 @@ export type ServiceBuilder = {
start(): Promise;
};
-// Warning: (ae-missing-release-tag) "setRootLogger" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export function setRootLogger(newLogger: winston.Logger): void;
-// Warning: (ae-missing-release-tag) "SingleConnectionDatabaseManager" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public @deprecated
export const SingleConnectionDatabaseManager: typeof DatabaseManager;
-// Warning: (ae-missing-release-tag) "SingleHostDiscovery" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export class SingleHostDiscovery implements PluginEndpointDiscovery {
static fromConfig(
@@ -578,28 +526,19 @@ export class SingleHostDiscovery implements PluginEndpointDiscovery {
getExternalBaseUrl(pluginId: string): Promise;
}
-// Warning: (ae-missing-release-tag) "StatusCheck" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export type StatusCheck = () => Promise;
-// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
-// Warning: (ae-missing-release-tag) "statusCheckHandler" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export function statusCheckHandler(
options?: StatusCheckHandlerOptions,
): Promise;
-// Warning: (ae-missing-release-tag) "StatusCheckHandlerOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export interface StatusCheckHandlerOptions {
statusCheck?: StatusCheck;
}
-// Warning: (ae-missing-release-tag) "UrlReader" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export type UrlReader = {
read(url: string): Promise;
@@ -608,56 +547,33 @@ export type UrlReader = {
search(url: string, options?: SearchOptions): Promise;
};
-// Warning: (ae-missing-release-tag) "UrlReaderPredicateTuple" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export type UrlReaderPredicateTuple = {
predicate: (url: URL) => boolean;
reader: UrlReader;
};
-// Warning: (ae-missing-release-tag) "UrlReaders" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export class UrlReaders {
- // Warning: (ae-forgotten-export) The symbol "CreateOptions" needs to be exported by the entry point index.d.ts
- static create({ logger, config, factories }: CreateOptions): UrlReader;
- static default({ logger, config, factories }: CreateOptions): UrlReader;
+ static create({ logger, config, factories }: UrlReadersOptions): UrlReader;
+ static default({ logger, config, factories }: UrlReadersOptions): UrlReader;
}
-// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
-// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
-// Warning: (ae-missing-release-tag) "useHotCleanup" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
+// @public (undocumented)
+export type UrlReadersOptions = {
+ config: Config;
+ logger: Logger_2;
+ factories?: ReaderFactory[];
+};
+
// @public
export function useHotCleanup(
_module: NodeModule,
cancelEffect: () => void,
): void;
-// Warning: (tsdoc-undefined-tag) The TSDoc tag "@warning" is not defined in this configuration
-// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
-// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
-// Warning: (ae-missing-release-tag) "useHotMemoize" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export function useHotMemoize(_module: NodeModule, valueFactory: () => T): T;
-// Warnings were encountered during analysis:
-//
-// src/cache/types.d.ts:34:5 - (ae-forgotten-export) The symbol "ClientOptions" needs to be exported by the entry point index.d.ts
-// src/middleware/errorHandler.d.ts:17:26 - (tsdoc-malformed-html-name) Invalid HTML element: A space is not allowed here
-// src/reading/types.d.ts:108:5 - (ae-forgotten-export) The symbol "ReadTreeResponseDirOptions" needs to be exported by the entry point index.d.ts
-// src/service/types.d.ts:12:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
-// src/service/types.d.ts:22:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
-// src/service/types.d.ts:30:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
-// src/service/types.d.ts:38:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
-// src/service/types.d.ts:47:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
-// src/service/types.d.ts:55:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
-// src/service/types.d.ts:57:5 - (ae-forgotten-export) The symbol "HttpsSettings" needs to be exported by the entry point index.d.ts
-// src/service/types.d.ts:61:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
-// src/service/types.d.ts:62:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
-// src/service/types.d.ts:70:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
-
// (No @packageDocumentation comment for this package)
```
diff --git a/packages/backend-common/src/cache/CacheClient.ts b/packages/backend-common/src/cache/CacheClient.ts
index 860754aae1..79f48a2757 100644
--- a/packages/backend-common/src/cache/CacheClient.ts
+++ b/packages/backend-common/src/cache/CacheClient.ts
@@ -22,7 +22,8 @@ type CacheClientArgs = {
client: Keyv;
};
-type CacheSetOptions = {
+/** @public */
+export type CacheClientSetOptions = {
/**
* Optional TTL in milliseconds. Defaults to the TTL provided when the client
* was set up (or no TTL if none are provided).
@@ -33,6 +34,8 @@ type CacheSetOptions = {
/**
* A pre-configured, storage agnostic cache client suitable for use by
* Backstage plugins.
+ *
+ * @public
*/
export interface CacheClient {
/**
@@ -46,7 +49,11 @@ export interface CacheClient {
* optional TTL may also be provided, otherwise it defaults to the TTL that
* was provided when the client was instantiated.
*/
- set(key: string, value: JsonValue, options?: CacheSetOptions): Promise;
+ set(
+ key: string,
+ value: JsonValue,
+ options?: CacheClientSetOptions,
+ ): Promise;
/**
* Removes the given key from the cache store.
@@ -73,7 +80,7 @@ export class DefaultCacheClient implements CacheClient {
async set(
key: string,
value: JsonValue,
- opts: CacheSetOptions = {},
+ opts: CacheClientSetOptions = {},
): Promise {
const k = this.getNormalizedKey(key);
await this.client.set(k, value, opts.ttl);
diff --git a/packages/backend-common/src/cache/CacheManager.ts b/packages/backend-common/src/cache/CacheManager.ts
index 9d1afdaaeb..d3a1504187 100644
--- a/packages/backend-common/src/cache/CacheManager.ts
+++ b/packages/backend-common/src/cache/CacheManager.ts
@@ -22,16 +22,14 @@ import { Logger } from 'winston';
import { getRootLogger } from '../logging';
import { DefaultCacheClient, CacheClient } from './CacheClient';
import { NoStore } from './NoStore';
-import {
- CacheManagerOptions,
- OptionalOnError,
- PluginCacheManager,
-} from './types';
+import { CacheManagerOptions, PluginCacheManager } from './types';
/**
* Implements a Cache Manager which will automatically create new cache clients
* for plugins when requested. All requested cache clients are created with the
* connection details provided.
+ *
+ * @public
*/
export class CacheManager {
/**
@@ -47,13 +45,13 @@ export class CacheManager {
private readonly logger: Logger;
private readonly store: keyof CacheManager['storeFactories'];
private readonly connection: string;
- private readonly errorHandler: OptionalOnError;
+ private readonly errorHandler: CacheManagerOptions['onError'];
/**
* Creates a new CacheManager instance by reading from the `backend` config
* section, specifically the `.cache` key.
*
- * @param config The loaded application configuration.
+ * @param config - The loaded application configuration.
*/
static fromConfig(
config: Config,
@@ -74,7 +72,7 @@ export class CacheManager {
store: string,
connectionString: string,
logger: Logger,
- errorHandler: OptionalOnError,
+ errorHandler: CacheManagerOptions['onError'],
) {
if (!this.storeFactories.hasOwnProperty(store)) {
throw new Error(`Unknown cache store: ${store}`);
@@ -88,7 +86,7 @@ export class CacheManager {
/**
* Generates a PluginCacheManager for consumption by plugins.
*
- * @param pluginId The plugin that the cache manager should be created for. Plugin names should be unique.
+ * @param pluginId - The plugin that the cache manager should be created for. Plugin names should be unique.
*/
forPlugin(pluginId: string): PluginCacheManager {
return {
diff --git a/packages/backend-common/src/cache/index.ts b/packages/backend-common/src/cache/index.ts
index 45eb431ed1..26e6c102d8 100644
--- a/packages/backend-common/src/cache/index.ts
+++ b/packages/backend-common/src/cache/index.ts
@@ -14,6 +14,10 @@
* limitations under the License.
*/
-export type { CacheClient } from './CacheClient';
+export type { CacheClient, CacheClientSetOptions } from './CacheClient';
export { CacheManager } from './CacheManager';
-export type { PluginCacheManager } from './types';
+export type {
+ PluginCacheManager,
+ CacheManagerOptions,
+ CacheClientOptions,
+} from './types';
diff --git a/packages/backend-common/src/cache/types.ts b/packages/backend-common/src/cache/types.ts
index ac5bb91b21..70c46770a8 100644
--- a/packages/backend-common/src/cache/types.ts
+++ b/packages/backend-common/src/cache/types.ts
@@ -17,7 +17,8 @@
import { Logger } from 'winston';
import { CacheClient } from './CacheClient';
-type ClientOptions = {
+/** @public */
+export type CacheClientOptions = {
/**
* An optional default TTL (in milliseconds) to be set when getting a client
* instance. If not provided, data will persist indefinitely by default (or
@@ -26,8 +27,7 @@ type ClientOptions = {
defaultTtl?: number;
};
-export type OptionalOnError = ((err: Error) => void) | undefined;
-
+/** @public */
export type CacheManagerOptions = {
/**
* An optional logger for use by the PluginCacheManager.
@@ -38,11 +38,13 @@ export type CacheManagerOptions = {
* An optional handler for connection errors emitted from the underlying data
* store.
*/
- onError?: OptionalOnError;
+ onError?: (err: Error) => void;
};
/**
* The PluginCacheManager manages access to cache stores that Plugins get.
+ *
+ * @public
*/
export type PluginCacheManager = {
/**
@@ -52,5 +54,5 @@ export type PluginCacheManager = {
* stores so that plugins are discouraged from cache-level integration
* and/or cache key collisions.
*/
- getClient: (options?: ClientOptions) => CacheClient;
+ getClient: (options?: CacheClientOptions) => CacheClient;
};
diff --git a/packages/backend-common/src/config.ts b/packages/backend-common/src/config.ts
index 7c660ee4e6..96907870cb 100644
--- a/packages/backend-common/src/config.ts
+++ b/packages/backend-common/src/config.ts
@@ -101,12 +101,6 @@ class ObservableConfigProxy implements Config {
}
}
-type Options = {
- logger: Logger;
- // process.argv or any other overrides
- argv: string[];
-};
-
// A global used to ensure that only a single file watcher is active at a time.
let currentCancelFunc: () => void;
@@ -114,8 +108,14 @@ let currentCancelFunc: () => void;
* Load configuration for a Backend.
*
* This function should only be called once, during the initialization of the backend.
+ *
+ * @public
*/
-export async function loadBackendConfig(options: Options): Promise {
+export async function loadBackendConfig(options: {
+ logger: Logger;
+ // process.argv or any other overrides
+ argv: string[];
+}): Promise {
const args = parseArgs(options.argv);
const configPaths: string[] = [args.config ?? []].flat();
diff --git a/packages/backend-common/src/database/DatabaseManager.ts b/packages/backend-common/src/database/DatabaseManager.ts
index 2d60104bcb..de39279a4f 100644
--- a/packages/backend-common/src/database/DatabaseManager.ts
+++ b/packages/backend-common/src/database/DatabaseManager.ts
@@ -31,6 +31,7 @@ function pluginPath(pluginId: string): string {
return `plugin.${pluginId}`;
}
+/** @public */
export class DatabaseManager {
/**
* Creates a DatabaseManager from `backend.database` config.
@@ -40,7 +41,7 @@ export class DatabaseManager {
* defaults. Optionally, a user may set `prefix` which is used to prefix generated database
* names if config is not provided.
*
- * @param config The loaded application configuration.
+ * @param config - The loaded application configuration.
*/
static fromConfig(config: Config): DatabaseManager {
const databaseConfig = config.getConfig('backend.database');
@@ -59,7 +60,7 @@ export class DatabaseManager {
/**
* Generates a PluginDatabaseManager for consumption by plugins.
*
- * @param pluginId The plugin that the database manager should be created for. Plugin names
+ * @param pluginId - The plugin that the database manager should be created for. Plugin names
* should be unique as they are used to look up database config overrides under
* `backend.database.plugin`.
*/
diff --git a/packages/backend-common/src/database/SingleConnection.ts b/packages/backend-common/src/database/SingleConnection.ts
index 153aea7f38..a81d60fe83 100644
--- a/packages/backend-common/src/database/SingleConnection.ts
+++ b/packages/backend-common/src/database/SingleConnection.ts
@@ -22,6 +22,7 @@ import { DatabaseManager } from './DatabaseManager';
* credentials provided; if the database already exists no attempt to create
* the database will be made.
*
+ * @public
* @deprecated Use `DatabaseManager` from `@backend-common` instead.
*/
export const SingleConnectionDatabaseManager = DatabaseManager;
diff --git a/packages/backend-common/src/database/config.ts b/packages/backend-common/src/database/config.ts
index b771811e8c..cf821087d7 100644
--- a/packages/backend-common/src/database/config.ts
+++ b/packages/backend-common/src/database/config.ts
@@ -19,6 +19,7 @@ import { merge } from 'lodash';
/**
* Merges database objects together
*
+ * @public
* @param config The base config. The input is not modified
* @param overrides Any additional overrides
*/
diff --git a/packages/backend-common/src/database/connection.ts b/packages/backend-common/src/database/connection.ts
index 6fdb5554bd..8ea46070eb 100644
--- a/packages/backend-common/src/database/connection.ts
+++ b/packages/backend-common/src/database/connection.ts
@@ -40,8 +40,9 @@ const ConnectorMapping: Record = {
/**
* Creates a knex database connection
*
- * @param dbConfig The database config
- * @param overrides Additional options to merge with the config
+ * @public
+ * @param dbConfig - The database config
+ * @param overrides - Additional options to merge with the config
*/
export function createDatabaseClient(
dbConfig: Config,
@@ -57,12 +58,16 @@ export function createDatabaseClient(
/**
* Alias for createDatabaseClient
+ *
+ * @public
* @deprecated Use createDatabaseClient instead
*/
export const createDatabase = createDatabaseClient;
/**
* Ensures that the given databases all exist, creating them if they do not.
+ *
+ * @public
*/
export async function ensureDatabaseExists(
dbConfig: Config,
diff --git a/packages/backend-common/src/database/types.ts b/packages/backend-common/src/database/types.ts
index c1647862af..edcba1e643 100644
--- a/packages/backend-common/src/database/types.ts
+++ b/packages/backend-common/src/database/types.ts
@@ -19,6 +19,8 @@ import { Knex } from 'knex';
/**
* The PluginDatabaseManager manages access to databases that Plugins get.
+ *
+ * @public
*/
export interface PluginDatabaseManager {
/**
diff --git a/packages/backend-common/src/discovery/SingleHostDiscovery.ts b/packages/backend-common/src/discovery/SingleHostDiscovery.ts
index 7d19284d9a..c1e092706b 100644
--- a/packages/backend-common/src/discovery/SingleHostDiscovery.ts
+++ b/packages/backend-common/src/discovery/SingleHostDiscovery.ts
@@ -26,6 +26,8 @@ import { DEFAULT_PORT } from '../service/lib/ServiceBuilderImpl';
* The deployment may be scaled horizontally, as long as the external URL
* is the same for all instances. However, internal URLs will always be
* resolved to the same host, so there won't be any balancing of internal traffic.
+ *
+ * @public
*/
export class SingleHostDiscovery implements PluginEndpointDiscovery {
/**
diff --git a/packages/backend-common/src/discovery/types.ts b/packages/backend-common/src/discovery/types.ts
index a5915be773..0b502bf88c 100644
--- a/packages/backend-common/src/discovery/types.ts
+++ b/packages/backend-common/src/discovery/types.ts
@@ -25,6 +25,8 @@
* Implementations of the discovery API can be as simple as a URL pattern
* using the pluginId, but could also have overrides for individual plugins,
* or query a separate discovery service.
+ *
+ * @public
*/
export type PluginEndpointDiscovery = {
/**
diff --git a/packages/backend-common/src/hot.ts b/packages/backend-common/src/hot.ts
index 951e29da6a..7148778b8c 100644
--- a/packages/backend-common/src/hot.ts
+++ b/packages/backend-common/src/hot.ts
@@ -46,13 +46,14 @@ function findAllAncestors(_module: NodeModule): NodeModule[] {
*
* Useful for cleaning intervals, timers, requests etc
*
+ * @public
* @example
* ```ts
* const intervalId = setInterval(doStuff, 1000);
* useHotCleanup(module, () => clearInterval(intervalId));
* ```
- * @param _module Reference to the current module where you invoke the fn
- * @param cancelEffect Fn that cleans up the ongoing effects
+ * @param _module - Reference to the current module where you invoke the fn
+ * @param cancelEffect - Fn that cleans up the ongoing effects
*/
export function useHotCleanup(_module: NodeModule, cancelEffect: () => void) {
if (_module.hot) {
@@ -78,16 +79,17 @@ const CURRENT_HOT_MEMOIZE_INDEX_KEY = 'backstage.io/hmr-memoize-key';
* Memoizes a generated value across hot-module reloads. This is useful for
* stateful parts of the backend, e.g. to retain a database.
*
+ * @public
* @example
* ```ts
* const db = useHotMemoize(module, () => createDB(dbParams));
* ```
*
- * @warning Don't use inside conditionals or loops,
+ * **NOTE:** Do not use inside conditionals or loops,
* same rules as for hooks apply (https://reactjs.org/docs/hooks-rules.html)
*
- * @param _module Reference to the current module where you invoke the fn
- * @param valueFactory Fn that returns the value you want to memoize
+ * @param _module - Reference to the current module where you invoke the fn
+ * @param valueFactory - Fn that returns the value you want to memoize
*/
export function useHotMemoize(
_module: NodeModule,
diff --git a/packages/backend-common/src/logging/formats.ts b/packages/backend-common/src/logging/formats.ts
index 870eeafa2a..0477136e63 100644
--- a/packages/backend-common/src/logging/formats.ts
+++ b/packages/backend-common/src/logging/formats.ts
@@ -31,6 +31,7 @@ const coloredTemplate = (info: TransformableInfo) => {
return `${timestampColor} ${prefixColor} ${level} ${message} ${extraFields}`;
};
+/** @public */
export const coloredFormat = winston.format.combine(
winston.format.timestamp(),
winston.format.colorize({
diff --git a/packages/backend-common/src/logging/rootLogger.ts b/packages/backend-common/src/logging/rootLogger.ts
index 58b675d9cf..d06037863c 100644
--- a/packages/backend-common/src/logging/rootLogger.ts
+++ b/packages/backend-common/src/logging/rootLogger.ts
@@ -21,14 +21,17 @@ import { coloredFormat } from './formats';
let rootLogger: winston.Logger;
+/** @public */
export function getRootLogger(): winston.Logger {
return rootLogger;
}
+/** @public */
export function setRootLogger(newLogger: winston.Logger) {
rootLogger = newLogger;
}
+/** @public */
export function createRootLogger(
options: winston.LoggerOptions = {},
env = process.env,
diff --git a/packages/backend-common/src/logging/voidLogger.ts b/packages/backend-common/src/logging/voidLogger.ts
index 0afc1fc8c7..eb9993fe7f 100644
--- a/packages/backend-common/src/logging/voidLogger.ts
+++ b/packages/backend-common/src/logging/voidLogger.ts
@@ -19,6 +19,8 @@ import * as winston from 'winston';
/**
* A logger that just throws away all messages.
+ *
+ * @public
*/
export function getVoidLogger(): winston.Logger {
return winston.createLogger({
diff --git a/packages/backend-common/src/middleware/errorHandler.ts b/packages/backend-common/src/middleware/errorHandler.ts
index ee7995f2c6..47c9285b18 100644
--- a/packages/backend-common/src/middleware/errorHandler.ts
+++ b/packages/backend-common/src/middleware/errorHandler.ts
@@ -28,6 +28,7 @@ import { ErrorRequestHandler, NextFunction, Request, Response } from 'express';
import { Logger } from 'winston';
import { getRootLogger } from '../logging';
+/** @public */
export type ErrorHandlerOptions = {
/**
* Whether error response bodies should show error stack traces or not.
@@ -44,9 +45,9 @@ export type ErrorHandlerOptions = {
logger?: Logger;
/**
- * Whether any error < 4XX should be logged or not.
+ * Whether any 4xx errors should be logged or not.
*
- * If not specified, by default log any 5xx errors.
+ * If not specified, default to only logging 5xx errors.
*/
logClientErrors?: boolean;
};
@@ -62,6 +63,7 @@ export type ErrorHandlerOptions = {
* error types (such as http-error exceptions) and returns the enclosed status
* code accordingly.
*
+ * @public
* @returns An Express error request handler
*/
export function errorHandler(
diff --git a/packages/backend-common/src/middleware/notFoundHandler.ts b/packages/backend-common/src/middleware/notFoundHandler.ts
index 59ca957cc1..53a548c0ad 100644
--- a/packages/backend-common/src/middleware/notFoundHandler.ts
+++ b/packages/backend-common/src/middleware/notFoundHandler.ts
@@ -22,6 +22,7 @@ import { NextFunction, Request, RequestHandler, Response } from 'express';
* Should be used as the very last handler in the chain, as it unconditionally
* returns a 404 status.
*
+ * @public
* @returns An Express request handler
*/
export function notFoundHandler(): RequestHandler {
diff --git a/packages/backend-common/src/middleware/requestLoggingHandler.ts b/packages/backend-common/src/middleware/requestLoggingHandler.ts
index f2f5cbda27..fa114411e1 100644
--- a/packages/backend-common/src/middleware/requestLoggingHandler.ts
+++ b/packages/backend-common/src/middleware/requestLoggingHandler.ts
@@ -22,7 +22,8 @@ import { getRootLogger } from '../logging';
/**
* Logs incoming requests.
*
- * @param logger An optional logger to use. If not specified, the root logger will be used.
+ * @public
+ * @param logger - An optional logger to use. If not specified, the root logger will be used.
* @returns An Express request handler
*/
export function requestLoggingHandler(logger?: Logger): RequestHandler {
diff --git a/packages/backend-common/src/middleware/statusCheckHandler.ts b/packages/backend-common/src/middleware/statusCheckHandler.ts
index 243d6533c8..a0ba59fac4 100644
--- a/packages/backend-common/src/middleware/statusCheckHandler.ts
+++ b/packages/backend-common/src/middleware/statusCheckHandler.ts
@@ -16,8 +16,10 @@
import { NextFunction, Request, Response, RequestHandler } from 'express';
+/** @public */
export type StatusCheck = () => Promise;
+/** @public */
export interface StatusCheckHandlerOptions {
/**
* Optional status function which returns a message.
@@ -30,7 +32,8 @@ export interface StatusCheckHandlerOptions {
*
* This is commonly used to implement healthcheck and readiness routes.
*
- * @param options An optional configuration object.
+ * @public
+ * @param options - An optional configuration object.
* @returns An Express error request handler
*/
export async function statusCheckHandler(
diff --git a/packages/backend-common/src/paths.ts b/packages/backend-common/src/paths.ts
index ffe99fe762..c8a8849d6c 100644
--- a/packages/backend-common/src/paths.ts
+++ b/packages/backend-common/src/paths.ts
@@ -25,6 +25,8 @@ import { resolve as resolvePath } from 'path';
* This is particularly useful when you want to access assets shipped with
* your backend plugin package. When doing so, do not forget to include the assets
* in your published package by adding them to `files` in your `package.json`.
+ *
+ * @public
*/
export function resolvePackagePath(name: string, ...paths: string[]) {
const req =
@@ -40,8 +42,9 @@ export function resolvePackagePath(name: string, ...paths: string[]) {
* a path that point to or within the base path. This is useful for resolving
* paths from user input, as it otherwise opens up for vulnerabilities.
*
- * @param base The base directory to resolve the path from.
- * @param path The target path, relative or absolute
+ * @public
+ * @param base - The base directory to resolve the path from.
+ * @param path - The target path, relative or absolute
* @returns A path that is guaranteed to point to or within the base path.
*/
export function resolveSafeChildPath(base: string, path: string): string {
diff --git a/packages/backend-common/src/reading/AzureUrlReader.ts b/packages/backend-common/src/reading/AzureUrlReader.ts
index 7b4b1e345e..910e8e04a5 100644
--- a/packages/backend-common/src/reading/AzureUrlReader.ts
+++ b/packages/backend-common/src/reading/AzureUrlReader.ts
@@ -40,6 +40,7 @@ import {
ReadUrlResponse,
} from './types';
+/** @public */
export class AzureUrlReader implements UrlReader {
static factory: ReaderFactory = ({ config, treeResponseFactory }) => {
const integrations = ScmIntegrations.fromConfig(config);
diff --git a/packages/backend-common/src/reading/BitbucketUrlReader.ts b/packages/backend-common/src/reading/BitbucketUrlReader.ts
index 7925212b20..4965d5a370 100644
--- a/packages/backend-common/src/reading/BitbucketUrlReader.ts
+++ b/packages/backend-common/src/reading/BitbucketUrlReader.ts
@@ -43,6 +43,8 @@ import {
/**
* A processor that adds the ability to read files from Bitbucket v1 and v2 APIs, such as
* the one exposed by Bitbucket Cloud itself.
+ *
+ * @public
*/
export class BitbucketUrlReader implements UrlReader {
static factory: ReaderFactory = ({ config, treeResponseFactory }) => {
diff --git a/packages/backend-common/src/reading/FetchUrlReader.ts b/packages/backend-common/src/reading/FetchUrlReader.ts
index 6b45d99cc3..732d3b9f59 100644
--- a/packages/backend-common/src/reading/FetchUrlReader.ts
+++ b/packages/backend-common/src/reading/FetchUrlReader.ts
@@ -27,6 +27,8 @@ import {
/**
* A UrlReader that does a plain fetch of the URL.
+ *
+ * @public
*/
export class FetchUrlReader implements UrlReader {
/**
diff --git a/packages/backend-common/src/reading/GithubUrlReader.ts b/packages/backend-common/src/reading/GithubUrlReader.ts
index 5dc1430ea8..1eed5764ef 100644
--- a/packages/backend-common/src/reading/GithubUrlReader.ts
+++ b/packages/backend-common/src/reading/GithubUrlReader.ts
@@ -51,6 +51,8 @@ export type GhBlobResponse =
/**
* A processor that adds the ability to read files from GitHub v3 APIs, such as
* the one exposed by GitHub itself.
+ *
+ * @public
*/
export class GithubUrlReader implements UrlReader {
static factory: ReaderFactory = ({ config, treeResponseFactory }) => {
diff --git a/packages/backend-common/src/reading/GitlabUrlReader.ts b/packages/backend-common/src/reading/GitlabUrlReader.ts
index baee64fab2..b78add6916 100644
--- a/packages/backend-common/src/reading/GitlabUrlReader.ts
+++ b/packages/backend-common/src/reading/GitlabUrlReader.ts
@@ -38,6 +38,7 @@ import {
ReadUrlOptions,
} from './types';
+/** @public */
export class GitlabUrlReader implements UrlReader {
static factory: ReaderFactory = ({ config, treeResponseFactory }) => {
const integrations = ScmIntegrations.fromConfig(config);
diff --git a/packages/backend-common/src/reading/GoogleGcsUrlReader.ts b/packages/backend-common/src/reading/GoogleGcsUrlReader.ts
index 9f3fbad302..f1684c2945 100644
--- a/packages/backend-common/src/reading/GoogleGcsUrlReader.ts
+++ b/packages/backend-common/src/reading/GoogleGcsUrlReader.ts
@@ -48,6 +48,7 @@ const parseURL = (
};
};
+/** @public */
export class GoogleGcsUrlReader implements UrlReader {
static factory: ReaderFactory = ({ config, logger }) => {
if (!config.has('integrations.googleGcs')) {
diff --git a/packages/backend-common/src/reading/UrlReaders.ts b/packages/backend-common/src/reading/UrlReaders.ts
index f9a4865717..7120a9570f 100644
--- a/packages/backend-common/src/reading/UrlReaders.ts
+++ b/packages/backend-common/src/reading/UrlReaders.ts
@@ -27,7 +27,8 @@ import { FetchUrlReader } from './FetchUrlReader';
import { GoogleGcsUrlReader } from './GoogleGcsUrlReader';
import { AwsS3UrlReader } from './AwsS3UrlReader';
-type CreateOptions = {
+/** @public */
+export type UrlReadersOptions = {
/** Root config object */
config: Config;
/** Logger used by all the readers */
@@ -38,12 +39,14 @@ type CreateOptions = {
/**
* UrlReaders provide various utilities related to the UrlReader interface.
+ *
+ * @public
*/
export class UrlReaders {
/**
* Creates a UrlReader without any known types.
*/
- static create({ logger, config, factories }: CreateOptions): UrlReader {
+ static create({ logger, config, factories }: UrlReadersOptions): UrlReader {
const mux = new UrlReaderPredicateMux(logger);
const treeResponseFactory = DefaultReadTreeResponseFactory.create({
config,
@@ -65,7 +68,7 @@ export class UrlReaders {
*
* Any additional factories passed will be loaded before the default ones.
*/
- static default({ logger, config, factories = [] }: CreateOptions) {
+ static default({ logger, config, factories = [] }: UrlReadersOptions) {
return UrlReaders.create({
logger,
config,
diff --git a/packages/backend-common/src/reading/index.ts b/packages/backend-common/src/reading/index.ts
index 207f01b37f..097f604987 100644
--- a/packages/backend-common/src/reading/index.ts
+++ b/packages/backend-common/src/reading/index.ts
@@ -24,6 +24,8 @@ export type {
ReadTreeResponse,
ReadTreeResponseFactory,
ReadTreeResponseFile,
+ ReadTreeResponseDirOptions,
+ ReadTreeResponseFactoryOptions,
ReadUrlOptions,
ReadUrlResponse,
SearchOptions,
@@ -33,3 +35,4 @@ export type {
UrlReaderPredicateTuple,
} from './types';
export { UrlReaders } from './UrlReaders';
+export type { UrlReadersOptions } from './UrlReaders';
diff --git a/packages/backend-common/src/reading/tree/ReadTreeResponseFactory.ts b/packages/backend-common/src/reading/tree/ReadTreeResponseFactory.ts
index 912fddf965..5fdd633102 100644
--- a/packages/backend-common/src/reading/tree/ReadTreeResponseFactory.ts
+++ b/packages/backend-common/src/reading/tree/ReadTreeResponseFactory.ts
@@ -18,7 +18,7 @@ import os from 'os';
import { Config } from '@backstage/config';
import {
ReadTreeResponse,
- FromArchiveOptions,
+ ReadTreeResponseFactoryOptions,
ReadTreeResponseFactory,
} from '../types';
import { TarArchiveResponse } from './TarArchiveResponse';
@@ -34,7 +34,9 @@ export class DefaultReadTreeResponseFactory implements ReadTreeResponseFactory {
constructor(private readonly workDir: string) {}
- async fromTarArchive(options: FromArchiveOptions): Promise {
+ async fromTarArchive(
+ options: ReadTreeResponseFactoryOptions,
+ ): Promise {
return new TarArchiveResponse(
options.stream,
options.subpath ?? '',
@@ -44,7 +46,9 @@ export class DefaultReadTreeResponseFactory implements ReadTreeResponseFactory {
);
}
- async fromZipArchive(options: FromArchiveOptions): Promise {
+ async fromZipArchive(
+ options: ReadTreeResponseFactoryOptions,
+ ): Promise {
return new ZipArchiveResponse(
options.stream,
options.subpath ?? '',
diff --git a/packages/backend-common/src/reading/types.ts b/packages/backend-common/src/reading/types.ts
index 93f287d4fe..b7e1ff823f 100644
--- a/packages/backend-common/src/reading/types.ts
+++ b/packages/backend-common/src/reading/types.ts
@@ -20,6 +20,8 @@ import { Config } from '@backstage/config';
/**
* A generic interface for fetching plain data from URLs.
+ *
+ * @public
*/
export type UrlReader = {
/* Used to read a single file and return its content. */
@@ -39,6 +41,7 @@ export type UrlReader = {
search(url: string, options?: SearchOptions): Promise;
};
+/** @public */
export type UrlReaderPredicateTuple = {
predicate: (url: URL) => boolean;
reader: UrlReader;
@@ -47,6 +50,8 @@ export type UrlReaderPredicateTuple = {
/**
* A factory function that can read config to construct zero or more
* UrlReaders along with a predicate for when it should be used.
+ *
+ * @public
*/
export type ReaderFactory = (options: {
config: Config;
@@ -56,6 +61,8 @@ export type ReaderFactory = (options: {
/**
* An options object for readUrl operations.
+ *
+ * @public
*/
export type ReadUrlOptions = {
/**
@@ -74,6 +81,8 @@ export type ReadUrlOptions = {
/**
* A response object for readUrl operations.
+ *
+ * @public
*/
export type ReadUrlResponse = {
/**
@@ -90,6 +99,8 @@ export type ReadUrlResponse = {
/**
* An options object for readTree operations.
+ *
+ * @public
*/
export type ReadTreeOptions = {
/**
@@ -120,8 +131,16 @@ export type ReadTreeOptions = {
etag?: string;
};
+/** @public */
+export type ReadTreeResponseDirOptions = {
+ /** The directory to write files to. Defaults to the OS tmpdir or `backend.workingDirectory` if set in config */
+ targetDir?: string;
+};
+
/**
* A response object for readTree operations.
+ *
+ * @public
*/
export type ReadTreeResponse = {
/**
@@ -142,20 +161,18 @@ export type ReadTreeResponse = {
etag: string;
};
-export type ReadTreeResponseDirOptions = {
- /** The directory to write files to. Defaults to the OS tmpdir or `backend.workingDirectory` if set in config */
- targetDir?: string;
-};
-
/**
* Represents a single file in a readTree response.
+ *
+ * @public
*/
export type ReadTreeResponseFile = {
path: string;
content(): Promise;
};
-export type FromArchiveOptions = {
+/** @public */
+export type ReadTreeResponseFactoryOptions = {
// A binary stream of a tar archive.
stream: Readable;
// If unset, the files at the root of the tree will be read.
@@ -167,13 +184,20 @@ export type FromArchiveOptions = {
filter?: (path: string, info?: { size: number }) => boolean;
};
+/** @public */
export interface ReadTreeResponseFactory {
- fromTarArchive(options: FromArchiveOptions): Promise;
- fromZipArchive(options: FromArchiveOptions): Promise;
+ fromTarArchive(
+ options: ReadTreeResponseFactoryOptions,
+ ): Promise;
+ fromZipArchive(
+ options: ReadTreeResponseFactoryOptions,
+ ): Promise;
}
/**
* An options object for search operations.
+ *
+ * @public
*/
export type SearchOptions = {
/**
@@ -192,6 +216,8 @@ export type SearchOptions = {
/**
* The output of a search operation.
+ *
+ * @public
*/
export type SearchResponse = {
/**
@@ -207,6 +233,8 @@ export type SearchResponse = {
/**
* Represents a single file in a search response.
+ *
+ * @public
*/
export type SearchResponseFile = {
/**
diff --git a/packages/backend-common/src/scm/git.ts b/packages/backend-common/src/scm/git.ts
index e786c279a1..00b103b240 100644
--- a/packages/backend-common/src/scm/git.ts
+++ b/packages/backend-common/src/scm/git.ts
@@ -31,6 +31,8 @@ From : https://isomorphic-git.org/docs/en/onAuth with fix for GitHub
Azure 'notempty' token
*/
+
+/** @public */
export class Git {
private constructor(
private readonly config: {
diff --git a/packages/backend-common/src/service/createServiceBuilder.ts b/packages/backend-common/src/service/createServiceBuilder.ts
index 17d69e7082..a6ca25415e 100644
--- a/packages/backend-common/src/service/createServiceBuilder.ts
+++ b/packages/backend-common/src/service/createServiceBuilder.ts
@@ -15,10 +15,13 @@
*/
import { ServiceBuilderImpl } from './lib/ServiceBuilderImpl';
+import { ServiceBuilder } from './types';
/**
* Creates a new service builder.
+ *
+ * @public
*/
-export function createServiceBuilder(_module: NodeModule) {
+export function createServiceBuilder(_module: NodeModule): ServiceBuilder {
return new ServiceBuilderImpl(_module);
}
diff --git a/packages/backend-common/src/service/createStatusCheckRouter.ts b/packages/backend-common/src/service/createStatusCheckRouter.ts
index fd794cc9c4..0d0f93f25c 100644
--- a/packages/backend-common/src/service/createStatusCheckRouter.ts
+++ b/packages/backend-common/src/service/createStatusCheckRouter.ts
@@ -19,7 +19,8 @@ import Router from 'express-promise-router';
import express from 'express';
import { errorHandler, statusCheckHandler, StatusCheck } from '../middleware';
-export interface StatusCheckRouterOptions {
+/** @public */
+export async function createStatusCheckRouter(options: {
logger: Logger;
path?: string;
/**
@@ -27,11 +28,7 @@ export interface StatusCheckRouterOptions {
* Override this to implement your own logic for a health check.
*/
statusCheck?: StatusCheck;
-}
-
-export async function createStatusCheckRouter(
- options: StatusCheckRouterOptions,
-): Promise {
+}): Promise {
const router = Router();
const { path = '/healthcheck', statusCheck } = options;
diff --git a/packages/backend-common/src/service/types.ts b/packages/backend-common/src/service/types.ts
index f845397ca2..3765cbcfdd 100644
--- a/packages/backend-common/src/service/types.ts
+++ b/packages/backend-common/src/service/types.ts
@@ -14,20 +14,20 @@
* limitations under the License.
*/
-import { ConfigReader } from '@backstage/config';
+import { Config } from '@backstage/config';
import cors from 'cors';
import { Router, RequestHandler } from 'express';
import { Server } from 'http';
import { Logger } from 'winston';
-import { HttpsSettings } from './lib/config';
+/** @public */
export type ServiceBuilder = {
/**
* Sets the service parameters based on configuration.
*
- * @param config The configuration to read
+ * @param config - The configuration to read
*/
- loadConfig(config: ConfigReader): ServiceBuilder;
+ loadConfig(config: Config): ServiceBuilder;
/**
* Sets the port to listen on.
@@ -36,7 +36,7 @@ export type ServiceBuilder = {
* variable named PORT and use that if present, otherwise it picks a default
* port (7000).
*
- * @param port The port to listen on
+ * @param port - The port to listen on
*/
setPort(port: number): ServiceBuilder;
@@ -45,7 +45,7 @@ export type ServiceBuilder = {
*
* '' is express default, which listens to all interfaces.
*
- * @param host The host to listen on
+ * @param host - The host to listen on
*/
setHost(host: string): ServiceBuilder;
@@ -54,7 +54,7 @@ export type ServiceBuilder = {
*
* If no logger is given, the default root logger is used.
*
- * @param logger A winston logger
+ * @param logger - A winston logger
*/
setLogger(logger: Logger): ServiceBuilder;
@@ -64,7 +64,7 @@ export type ServiceBuilder = {
* If this method is not called, the resulting service will not have any
* built in CORS handling.
*
- * @param options Standard CORS options
+ * @param options - Standard CORS options
*/
enableCors(options: cors.CorsOptions): ServiceBuilder;
@@ -73,15 +73,17 @@ export type ServiceBuilder = {
*
* If this method is not called, the resulting service will use sensible defaults
*
- * @param options Standard certificate options
+ * @param options - Standard certificate options
*/
- setHttpsSettings(settings: HttpsSettings): ServiceBuilder;
+ setHttpsSettings(settings: {
+ certificate: { key: string; cert: string } | { hostname: string };
+ }): ServiceBuilder;
/**
* Adds a router (similar to the express .use call) to the service.
*
- * @param root The root URL to bind to (e.g. "/api/function1")
- * @param router An express router
+ * @param root - The root URL to bind to (e.g. "/api/function1")
+ * @param router - An express router
*/
addRouter(root: string, router: Router | RequestHandler): ServiceBuilder;
@@ -90,7 +92,7 @@ export type ServiceBuilder = {
*
* If no handler is given the default one is used
*
- * @param requestLoggingHandler a factory function that given a logger returns an handler
+ * @param requestLoggingHandler - a factory function that given a logger returns an handler
*/
setRequestLoggingHandler(
requestLoggingHandler: RequestLoggingHandlerFactory,
@@ -102,4 +104,5 @@ export type ServiceBuilder = {
start(): Promise;
};
+/** @public */
export type RequestLoggingHandlerFactory = (logger?: Logger) => RequestHandler;
diff --git a/packages/backend-common/src/util/ContainerRunner.ts b/packages/backend-common/src/util/ContainerRunner.ts
index 8a73be42ba..be861501c3 100644
--- a/packages/backend-common/src/util/ContainerRunner.ts
+++ b/packages/backend-common/src/util/ContainerRunner.ts
@@ -16,6 +16,7 @@
import { Writable } from 'stream';
+/** @public */
export type RunContainerOptions = {
imageName: string;
command?: string | string[];
@@ -27,6 +28,7 @@ export type RunContainerOptions = {
pullImage?: boolean;
};
+/** @public */
export interface ContainerRunner {
runContainer(opts: RunContainerOptions): Promise;
}
diff --git a/packages/backend-common/src/util/DockerContainerRunner.ts b/packages/backend-common/src/util/DockerContainerRunner.ts
index 33a4874151..da3ce66ec2 100644
--- a/packages/backend-common/src/util/DockerContainerRunner.ts
+++ b/packages/backend-common/src/util/DockerContainerRunner.ts
@@ -23,6 +23,7 @@ export type UserOptions = {
User?: string;
};
+/** @public */
export class DockerContainerRunner implements ContainerRunner {
private readonly dockerClient: Docker;
diff --git a/packages/backend-test-utils/api-report.md b/packages/backend-test-utils/api-report.md
index 411ecc7ddf..184ed74978 100644
--- a/packages/backend-test-utils/api-report.md
+++ b/packages/backend-test-utils/api-report.md
@@ -5,13 +5,9 @@
```ts
import { Knex } from 'knex';
-// Warning: (ae-missing-release-tag) "isDockerDisabledForTests" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export function isDockerDisabledForTests(): boolean;
-// Warning: (ae-missing-release-tag) "TestDatabaseId" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export type TestDatabaseId =
| 'POSTGRES_13'
@@ -19,8 +15,6 @@ export type TestDatabaseId =
| 'MYSQL_8'
| 'SQLITE_3';
-// Warning: (ae-missing-release-tag) "TestDatabases" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export class TestDatabases {
static create(options?: {
@@ -29,7 +23,6 @@ export class TestDatabases {
}): TestDatabases;
// (undocumented)
eachSupportedId(): [TestDatabaseId][];
- // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
init(id: TestDatabaseId): Promise;
// (undocumented)
supports(id: TestDatabaseId): boolean;
diff --git a/packages/backend-test-utils/src/database/TestDatabases.ts b/packages/backend-test-utils/src/database/TestDatabases.ts
index 329aec5e8a..243c6bbe52 100644
--- a/packages/backend-test-utils/src/database/TestDatabases.ts
+++ b/packages/backend-test-utils/src/database/TestDatabases.ts
@@ -31,6 +31,8 @@ import {
/**
* Encapsulates the creation of ephemeral test database instances for use
* inside unit or integration tests.
+ *
+ * @public
*/
export class TestDatabases {
private readonly instanceById: Map;
@@ -113,7 +115,7 @@ export class TestDatabases {
* Returns a fresh, unique, empty logical database on an instance of the
* given database ID platform.
*
- * @param id The ID of the database platform to use, e.g. 'POSTGRES_13'
+ * @param id - The ID of the database platform to use, e.g. 'POSTGRES_13'
* @returns A `Knex` connection object
*/
async init(id: TestDatabaseId): Promise {
diff --git a/packages/backend-test-utils/src/database/types.ts b/packages/backend-test-utils/src/database/types.ts
index 514a3a85e8..d405f73738 100644
--- a/packages/backend-test-utils/src/database/types.ts
+++ b/packages/backend-test-utils/src/database/types.ts
@@ -19,6 +19,8 @@ import { Knex } from 'knex';
/**
* The possible databases to test against.
+ *
+ * @public
*/
export type TestDatabaseId =
| 'POSTGRES_13'
diff --git a/packages/backend-test-utils/src/util/isDockerDisabledForTests.ts b/packages/backend-test-utils/src/util/isDockerDisabledForTests.ts
index 617e9eb2a1..b411086728 100644
--- a/packages/backend-test-utils/src/util/isDockerDisabledForTests.ts
+++ b/packages/backend-test-utils/src/util/isDockerDisabledForTests.ts
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+/** @public */
export function isDockerDisabledForTests() {
// If we are not running in continuous integration, the default is to skip
// the (relatively heavy, long running) docker based tests. If you want to
diff --git a/packages/catalog-client/api-report.md b/packages/catalog-client/api-report.md
index 173af9aef3..f059174ba3 100644
--- a/packages/catalog-client/api-report.md
+++ b/packages/catalog-client/api-report.md
@@ -7,8 +7,6 @@ import { Entity } from '@backstage/catalog-model';
import { EntityName } from '@backstage/catalog-model';
import { Location as Location_2 } from '@backstage/catalog-model';
-// Warning: (ae-missing-release-tag) "AddLocationRequest" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export type AddLocationRequest = {
type?: string;
@@ -17,21 +15,15 @@ export type AddLocationRequest = {
presence?: 'optional' | 'required';
};
-// Warning: (ae-missing-release-tag) "AddLocationResponse" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export type AddLocationResponse = {
location: Location_2;
entities: Entity[];
};
-// Warning: (ae-missing-release-tag) "CATALOG_FILTER_EXISTS" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export const CATALOG_FILTER_EXISTS: unique symbol;
-// Warning: (ae-missing-release-tag) "CatalogApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export interface CatalogApi {
// (undocumented)
@@ -76,8 +68,6 @@ export interface CatalogApi {
): Promise;
}
-// Warning: (ae-missing-release-tag) "CatalogClient" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export class CatalogClient implements CatalogApi {
constructor(options: { discoveryApi: DiscoveryApi });
@@ -123,8 +113,6 @@ export class CatalogClient implements CatalogApi {
): Promise;
}
-// Warning: (ae-missing-release-tag) "CatalogEntitiesRequest" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export type CatalogEntitiesRequest = {
filter?:
@@ -134,29 +122,24 @@ export type CatalogEntitiesRequest = {
fields?: string[] | undefined;
};
-// Warning: (ae-missing-release-tag) "CatalogListResponse" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export type CatalogListResponse = {
items: T[];
};
-// Warning: (ae-missing-release-tag) "CatalogRequestOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export type CatalogRequestOptions = {
token?: string;
};
-// Warning: (ae-missing-release-tag) "ENTITY_STATUS_CATALOG_PROCESSING_TYPE" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
+// @public
+export type DiscoveryApi = {
+ getBaseUrl(pluginId: string): Promise;
+};
+
// @public
export const ENTITY_STATUS_CATALOG_PROCESSING_TYPE =
'backstage.io/catalog-processing';
-// Warnings were encountered during analysis:
-//
-// src/CatalogClient.d.ts:7:9 - (ae-forgotten-export) The symbol "DiscoveryApi" needs to be exported by the entry point index.d.ts
-
// (No @packageDocumentation comment for this package)
```
diff --git a/packages/catalog-client/src/CatalogClient.ts b/packages/catalog-client/src/CatalogClient.ts
index ef90287c37..410d921d3b 100644
--- a/packages/catalog-client/src/CatalogClient.ts
+++ b/packages/catalog-client/src/CatalogClient.ts
@@ -36,6 +36,7 @@ import {
} from './types/api';
import { DiscoveryApi } from './types/discovery';
+/** @public */
export class CatalogClient implements CatalogApi {
private readonly discoveryApi: DiscoveryApi;
diff --git a/packages/catalog-client/src/types/api.ts b/packages/catalog-client/src/types/api.ts
index d30caa50d6..e78bd9d713 100644
--- a/packages/catalog-client/src/types/api.ts
+++ b/packages/catalog-client/src/types/api.ts
@@ -16,8 +16,10 @@
import { Entity, EntityName, Location } from '@backstage/catalog-model';
+/** @public */
export const CATALOG_FILTER_EXISTS = Symbol('CATALOG_FILTER_EXISTS');
+/** @public */
export type CatalogEntitiesRequest = {
filter?:
| Record[]
@@ -26,14 +28,17 @@ export type CatalogEntitiesRequest = {
fields?: string[] | undefined;
};
+/** @public */
export type CatalogListResponse = {
items: T[];
};
+/** @public */
export type CatalogRequestOptions = {
token?: string;
};
+/** @public */
export interface CatalogApi {
// Entities
getEntities(
@@ -72,6 +77,7 @@ export interface CatalogApi {
): Promise;
}
+/** @public */
export type AddLocationRequest = {
type?: string;
target: string;
@@ -79,6 +85,7 @@ export type AddLocationRequest = {
presence?: 'optional' | 'required';
};
+/** @public */
export type AddLocationResponse = {
location: Location;
entities: Entity[];
diff --git a/packages/catalog-client/src/types/discovery.ts b/packages/catalog-client/src/types/discovery.ts
index 447998b3b8..19ee5ed19c 100644
--- a/packages/catalog-client/src/types/discovery.ts
+++ b/packages/catalog-client/src/types/discovery.ts
@@ -16,6 +16,8 @@
/**
* This is a copy of the core DiscoveryApi, to avoid importing core.
+ *
+ * @public
*/
export type DiscoveryApi = {
getBaseUrl(pluginId: string): Promise;
diff --git a/packages/catalog-client/src/types/index.ts b/packages/catalog-client/src/types/index.ts
index 3bfcdd7fba..7963891a4c 100644
--- a/packages/catalog-client/src/types/index.ts
+++ b/packages/catalog-client/src/types/index.ts
@@ -22,5 +22,6 @@ export type {
CatalogListResponse,
CatalogRequestOptions,
} from './api';
+export type { DiscoveryApi } from './discovery';
export { CATALOG_FILTER_EXISTS } from './api';
export { ENTITY_STATUS_CATALOG_PROCESSING_TYPE } from './status';
diff --git a/packages/catalog-client/src/types/status.ts b/packages/catalog-client/src/types/status.ts
index d2935b890e..38560a3791 100644
--- a/packages/catalog-client/src/types/status.ts
+++ b/packages/catalog-client/src/types/status.ts
@@ -17,6 +17,8 @@
/**
* The entity `status.items[].type` for the status of the processing engine in
* regards to an entity.
+ *
+ * @public
*/
export const ENTITY_STATUS_CATALOG_PROCESSING_TYPE =
'backstage.io/catalog-processing';
diff --git a/packages/catalog-model/api-report.md b/packages/catalog-model/api-report.md
index b9f46add6a..407e18a409 100644
--- a/packages/catalog-model/api-report.md
+++ b/packages/catalog-model/api-report.md
@@ -9,9 +9,6 @@ import { JsonValue } from '@backstage/config';
import { SerializedError } from '@backstage/errors';
import * as yup from 'yup';
-// Warning: (tsdoc-missing-deprecation-message) The @deprecated block must include a deprecation message, e.g. describing the recommended alternative
-// Warning: (ae-missing-release-tag) "analyzeLocationSchema" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public @deprecated (undocumented)
export const analyzeLocationSchema: yup.ObjectSchema<
{
@@ -20,8 +17,6 @@ export const analyzeLocationSchema: yup.ObjectSchema<
object
>;
-// Warning: (ae-missing-release-tag) "ApiEntityV1alpha1" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
interface ApiEntityV1alpha1 extends Entity {
// (undocumented)
@@ -40,43 +35,24 @@ interface ApiEntityV1alpha1 extends Entity {
export { ApiEntityV1alpha1 as ApiEntity };
export { ApiEntityV1alpha1 };
-// Warning: (ae-missing-release-tag) "apiEntityV1alpha1Validator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export const apiEntityV1alpha1Validator: KindValidator;
-// Warning: (ae-missing-release-tag) "CommonValidatorFunctions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export class CommonValidatorFunctions {
- // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
static isJsonSafe(value: unknown): boolean;
- // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
static isValidDnsLabel(value: unknown): boolean;
- // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
static isValidDnsSubdomain(value: unknown): boolean;
- // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
- // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
- // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
- // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
static isValidPrefixAndOrSuffix(
value: unknown,
separator: string,
isValidPrefix: (value: string) => boolean,
isValidSuffix: (value: string) => boolean,
): boolean;
- // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
static isValidString(value: unknown): boolean;
- // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
static isValidUrl(value: unknown): boolean;
}
-// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
-// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
-// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
-// Warning: (ae-forgotten-export) The symbol "EntityRefContext" needs to be exported by the entry point index.d.ts
-// Warning: (ae-missing-release-tag) "compareEntityToRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export function compareEntityToRef(
entity: Entity,
@@ -84,8 +60,6 @@ export function compareEntityToRef(
context?: EntityRefContext,
): boolean;
-// Warning: (ae-missing-release-tag) "ComponentEntityV1alpha1" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
interface ComponentEntityV1alpha1 extends Entity {
// (undocumented)
@@ -107,13 +81,9 @@ interface ComponentEntityV1alpha1 extends Entity {
export { ComponentEntityV1alpha1 as ComponentEntity };
export { ComponentEntityV1alpha1 };
-// Warning: (ae-missing-release-tag) "componentEntityV1alpha1Validator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export const componentEntityV1alpha1Validator: KindValidator;
-// Warning: (ae-missing-release-tag) "DefaultNamespaceEntityPolicy" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export class DefaultNamespaceEntityPolicy implements EntityPolicy {
constructor(namespace?: string);
@@ -121,8 +91,6 @@ export class DefaultNamespaceEntityPolicy implements EntityPolicy {
enforce(entity: Entity): Promise;
}
-// Warning: (ae-missing-release-tag) "DomainEntityV1alpha1" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
interface DomainEntityV1alpha1 extends Entity {
// (undocumented)
@@ -137,18 +105,12 @@ interface DomainEntityV1alpha1 extends Entity {
export { DomainEntityV1alpha1 as DomainEntity };
export { DomainEntityV1alpha1 };
-// Warning: (ae-missing-release-tag) "domainEntityV1alpha1Validator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export const domainEntityV1alpha1Validator: KindValidator;
-// Warning: (ae-missing-release-tag) "EDIT_URL_ANNOTATION" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export const EDIT_URL_ANNOTATION = 'backstage.io/edit-url';
-// Warning: (ae-missing-release-tag) "Entity" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export type Entity = {
apiVersion: string;
@@ -159,13 +121,9 @@ export type Entity = {
status?: UNSTABLE_EntityStatus;
};
-// Warning: (ae-missing-release-tag) "ENTITY_DEFAULT_NAMESPACE" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export const ENTITY_DEFAULT_NAMESPACE = 'default';
-// Warning: (ae-missing-release-tag) "ENTITY_META_GENERATED_FIELDS" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export const ENTITY_META_GENERATED_FIELDS: readonly [
'uid',
@@ -173,8 +131,6 @@ export const ENTITY_META_GENERATED_FIELDS: readonly [
'generation',
];
-// Warning: (ae-missing-release-tag) "EntityEnvelope" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export type EntityEnvelope = {
apiVersion: string;
@@ -185,35 +141,19 @@ export type EntityEnvelope = {
};
};
-// Warning: (ae-missing-release-tag) "entityEnvelopeSchemaValidator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@backstage/catalog-model" does not have an export "TypeError"
-//
// @public
export function entityEnvelopeSchemaValidator<
T extends EntityEnvelope = EntityEnvelope,
>(schema?: unknown): (data: unknown) => T;
-// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
-// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
-// Warning: (ae-missing-release-tag) "entityHasChanges" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export function entityHasChanges(previous: Entity, next: Entity): boolean;
-// Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@"
-// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag
-// Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@"
-// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag
-// Warning: (ae-missing-release-tag) "entityKindSchemaValidator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@backstage/catalog-model" does not have an export "TypeError"
-//
// @public
export function entityKindSchemaValidator(
schema: unknown,
): (data: unknown) => T | false;
-// Warning: (ae-missing-release-tag) "EntityLink" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export type EntityLink = {
url: string;
@@ -221,8 +161,6 @@ export type EntityLink = {
icon?: string;
};
-// Warning: (ae-missing-release-tag) "EntityMeta" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export type EntityMeta = JsonObject & {
uid?: string;
@@ -238,8 +176,6 @@ export type EntityMeta = JsonObject & {
links?: EntityLink[];
};
-// Warning: (ae-missing-release-tag) "EntityName" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export type EntityName = {
kind: string;
@@ -247,23 +183,17 @@ export type EntityName = {
name: string;
};
-// Warning: (ae-missing-release-tag) "EntityPolicies" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export const EntityPolicies: {
- allOf(policies: EntityPolicy[]): AllEntityPolicies;
- oneOf(policies: EntityPolicy[]): AnyEntityPolicy;
+ allOf(policies: EntityPolicy[]): EntityPolicy;
+ oneOf(policies: EntityPolicy[]): EntityPolicy;
};
-// Warning: (ae-missing-release-tag) "EntityPolicy" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export type EntityPolicy = {
enforce(entity: Entity): Promise;
};
-// Warning: (ae-missing-release-tag) "EntityRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export type EntityRef =
| string
@@ -273,16 +203,18 @@ export type EntityRef =
name: string;
};
-// Warning: (ae-missing-release-tag) "EntityRelation" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
+// @public
+export type EntityRefContext = {
+ defaultKind?: string;
+ defaultNamespace?: string;
+};
+
// @public
export type EntityRelation = {
type: string;
target: EntityName;
};
-// Warning: (ae-missing-release-tag) "EntityRelationSpec" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export type EntityRelationSpec = {
source: EntityName;
@@ -290,16 +222,11 @@ export type EntityRelationSpec = {
target: EntityName;
};
-// Warning: (ae-missing-release-tag) "entitySchemaValidator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@backstage/catalog-model" does not have an export "TypeError"
-//
// @public
export function entitySchemaValidator(
schema?: unknown,
): (data: unknown) => T;
-// Warning: (ae-missing-release-tag) "FieldFormatEntityPolicy" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export class FieldFormatEntityPolicy implements EntityPolicy {
constructor(validators?: Validators);
@@ -307,40 +234,24 @@ export class FieldFormatEntityPolicy implements EntityPolicy {
enforce(entity: Entity): Promise;
}
-// Warning: (ae-missing-release-tag) "generateEntityEtag" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export function generateEntityEtag(): string;
-// Warning: (ae-missing-release-tag) "generateEntityUid" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export function generateEntityUid(): string;
-// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
-// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
-// Warning: (ae-missing-release-tag) "generateUpdatedEntity" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export function generateUpdatedEntity(previous: Entity, next: Entity): Entity;
-// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
-// Warning: (ae-missing-release-tag) "getEntityName" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export function getEntityName(entity: Entity): EntityName;
-// Warning: (tsdoc-characters-after-block-tag) The token "@backstage" looks like a TSDoc tag but contains an invalid character "/"; if it is not a tag, use a backslash to escape the "@"
-// Warning: (ae-missing-release-tag) "getEntitySourceLocation" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export function getEntitySourceLocation(entity: Entity): {
type: string;
target: string;
};
-// Warning: (ae-missing-release-tag) "GroupEntityV1alpha1" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
interface GroupEntityV1alpha1 extends Entity {
// (undocumented)
@@ -363,28 +274,20 @@ interface GroupEntityV1alpha1 extends Entity {
export { GroupEntityV1alpha1 as GroupEntity };
export { GroupEntityV1alpha1 };
-// Warning: (ae-missing-release-tag) "groupEntityV1alpha1Validator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export const groupEntityV1alpha1Validator: KindValidator;
-// Warning: (ae-missing-release-tag) "JSONSchema" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export type JSONSchema = JSONSchema7 &
{
[key in string]?: JsonValue;
};
-// Warning: (ae-missing-release-tag) "KindValidator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export type KindValidator = {
check(entity: Entity): Promise;
};
-// Warning: (ae-missing-release-tag) "KubernetesValidatorFunctions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export class KubernetesValidatorFunctions {
// (undocumented)
@@ -405,21 +308,15 @@ export class KubernetesValidatorFunctions {
static isValidObjectName(value: unknown): boolean;
}
-// Warning: (ae-missing-release-tag) "Location" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
type Location_2 = {
id: string;
} & LocationSpec;
export { Location_2 as Location };
-// Warning: (ae-missing-release-tag) "LOCATION_ANNOTATION" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export const LOCATION_ANNOTATION = 'backstage.io/managed-by-location';
-// Warning: (ae-missing-release-tag) "LocationEntityV1alpha1" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
interface LocationEntityV1alpha1 extends Entity {
// (undocumented)
@@ -436,19 +333,12 @@ interface LocationEntityV1alpha1 extends Entity {
export { LocationEntityV1alpha1 as LocationEntity };
export { LocationEntityV1alpha1 };
-// Warning: (ae-missing-release-tag) "locationEntityV1alpha1Validator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export const locationEntityV1alpha1Validator: KindValidator;
-// Warning: (tsdoc-missing-deprecation-message) The @deprecated block must include a deprecation message, e.g. describing the recommended alternative
-// Warning: (ae-missing-release-tag) "locationSchema" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public @deprecated (undocumented)
export const locationSchema: yup.ObjectSchema;
-// Warning: (ae-missing-release-tag) "LocationSpec" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export type LocationSpec = {
type: string;
@@ -456,19 +346,12 @@ export type LocationSpec = {
presence?: 'optional' | 'required';
};
-// Warning: (tsdoc-missing-deprecation-message) The @deprecated block must include a deprecation message, e.g. describing the recommended alternative
-// Warning: (ae-missing-release-tag) "locationSpecSchema" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public @deprecated (undocumented)
export const locationSpecSchema: yup.ObjectSchema;
-// Warning: (ae-missing-release-tag) "makeValidator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export function makeValidator(overrides?: Partial): Validators;
-// Warning: (ae-missing-release-tag) "NoForeignRootFieldsEntityPolicy" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export class NoForeignRootFieldsEntityPolicy implements EntityPolicy {
constructor(knownFields?: string[]);
@@ -476,28 +359,16 @@ export class NoForeignRootFieldsEntityPolicy implements EntityPolicy {
enforce(entity: Entity): Promise;
}
-// Warning: (ae-missing-release-tag) "ORIGIN_LOCATION_ANNOTATION" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export const ORIGIN_LOCATION_ANNOTATION =
'backstage.io/managed-by-origin-location';
-// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
-// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
-// Warning: (ae-missing-release-tag) "parseEntityName" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export function parseEntityName(
ref: EntityRef,
context?: EntityRefContext,
): EntityName;
-// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
-// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
-// Warning: (ae-missing-release-tag) "parseEntityRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-// Warning: (ae-missing-release-tag) "parseEntityRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-// Warning: (ae-missing-release-tag) "parseEntityRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export function parseEntityRef(
ref: EntityRef,
@@ -535,89 +406,54 @@ export function parseEntityRef(
name: string;
};
-// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
-// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag
-// Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@"
-// Warning: (ae-missing-release-tag) "parseLocationReference" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export function parseLocationReference(ref: string): {
type: string;
target: string;
};
-// Warning: (ae-missing-release-tag) "RELATION_API_CONSUMED_BY" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export const RELATION_API_CONSUMED_BY = 'apiConsumedBy';
-// Warning: (ae-missing-release-tag) "RELATION_API_PROVIDED_BY" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export const RELATION_API_PROVIDED_BY = 'apiProvidedBy';
-// Warning: (ae-missing-release-tag) "RELATION_CHILD_OF" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export const RELATION_CHILD_OF = 'childOf';
-// Warning: (ae-missing-release-tag) "RELATION_CONSUMES_API" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export const RELATION_CONSUMES_API = 'consumesApi';
-// Warning: (ae-missing-release-tag) "RELATION_DEPENDENCY_OF" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export const RELATION_DEPENDENCY_OF = 'dependencyOf';
-// Warning: (ae-missing-release-tag) "RELATION_DEPENDS_ON" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export const RELATION_DEPENDS_ON = 'dependsOn';
-// Warning: (ae-missing-release-tag) "RELATION_HAS_MEMBER" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export const RELATION_HAS_MEMBER = 'hasMember';
-// Warning: (ae-missing-release-tag) "RELATION_HAS_PART" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export const RELATION_HAS_PART = 'hasPart';
-// Warning: (ae-missing-release-tag) "RELATION_MEMBER_OF" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export const RELATION_MEMBER_OF = 'memberOf';
-// Warning: (ae-missing-release-tag) "RELATION_OWNED_BY" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export const RELATION_OWNED_BY = 'ownedBy';
-// Warning: (ae-missing-release-tag) "RELATION_OWNER_OF" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export const RELATION_OWNER_OF = 'ownerOf';
-// Warning: (ae-missing-release-tag) "RELATION_PARENT_OF" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export const RELATION_PARENT_OF = 'parentOf';
-// Warning: (ae-missing-release-tag) "RELATION_PART_OF" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export const RELATION_PART_OF = 'partOf';
-// Warning: (ae-missing-release-tag) "RELATION_PROVIDES_API" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export const RELATION_PROVIDES_API = 'providesApi';
-// Warning: (ae-missing-release-tag) "ResourceEntityV1alpha1" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
interface ResourceEntityV1alpha1 extends Entity {
// (undocumented)
@@ -635,22 +471,15 @@ interface ResourceEntityV1alpha1 extends Entity {
export { ResourceEntityV1alpha1 as ResourceEntity };
export { ResourceEntityV1alpha1 };
-// Warning: (ae-missing-release-tag) "resourceEntityV1alpha1Validator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export const resourceEntityV1alpha1Validator: KindValidator;
-// Warning: (ae-missing-release-tag) "SchemaValidEntityPolicy" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export class SchemaValidEntityPolicy implements EntityPolicy {
// (undocumented)
enforce(entity: Entity): Promise;
}
-// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
-// Warning: (ae-missing-release-tag) "serializeEntityRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public @deprecated
export function serializeEntityRef(
ref:
@@ -662,14 +491,9 @@ export function serializeEntityRef(
},
): EntityRef;
-// Warning: (ae-missing-release-tag) "SOURCE_LOCATION_ANNOTATION" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export const SOURCE_LOCATION_ANNOTATION = 'backstage.io/source-location';
-// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
-// Warning: (ae-missing-release-tag) "stringifyEntityRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export function stringifyEntityRef(
ref:
@@ -681,19 +505,12 @@ export function stringifyEntityRef(
},
): string;
-// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag
-// Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@"
-// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
-// Warning: (ae-missing-release-tag) "stringifyLocationReference" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export function stringifyLocationReference(ref: {
type: string;
target: string;
}): string;
-// Warning: (ae-missing-release-tag) "SystemEntityV1alpha1" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
interface SystemEntityV1alpha1 extends Entity {
// (undocumented)
@@ -709,13 +526,9 @@ interface SystemEntityV1alpha1 extends Entity {
export { SystemEntityV1alpha1 as SystemEntity };
export { SystemEntityV1alpha1 };
-// Warning: (ae-missing-release-tag) "systemEntityV1alpha1Validator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export const systemEntityV1alpha1Validator: KindValidator;
-// Warning: (ae-missing-release-tag) "TemplateEntityV1beta2" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export interface TemplateEntityV1beta2 extends Entity {
// (undocumented)
@@ -740,8 +553,6 @@ export interface TemplateEntityV1beta2 extends Entity {
};
}
-// Warning: (ae-missing-release-tag) "templateEntityV1beta2Validator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export const templateEntityV1beta2Validator: KindValidator;
@@ -761,8 +572,6 @@ export type UNSTABLE_EntityStatusItem = {
// @alpha
export type UNSTABLE_EntityStatusLevel = 'info' | 'warning' | 'error';
-// Warning: (ae-missing-release-tag) "UserEntityV1alpha1" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
interface UserEntityV1alpha1 extends Entity {
// (undocumented)
@@ -782,13 +591,9 @@ interface UserEntityV1alpha1 extends Entity {
export { UserEntityV1alpha1 as UserEntity };
export { UserEntityV1alpha1 };
-// Warning: (ae-missing-release-tag) "userEntityV1alpha1Validator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export const userEntityV1alpha1Validator: KindValidator;
-// Warning: (ae-missing-release-tag) "Validators" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export type Validators = {
isValidApiVersion(value: unknown): boolean;
@@ -802,18 +607,12 @@ export type Validators = {
isValidTag(value: unknown): boolean;
};
-// Warning: (ae-missing-release-tag) "VIEW_URL_ANNOTATION" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export const VIEW_URL_ANNOTATION = 'backstage.io/view-url';
// Warnings were encountered during analysis:
//
-// src/EntityPolicies.d.ts:13:5 - (ae-forgotten-export) The symbol "AllEntityPolicies" needs to be exported by the entry point index.d.ts
-// src/EntityPolicies.d.ts:14:5 - (ae-forgotten-export) The symbol "AnyEntityPolicy" needs to be exported by the entry point index.d.ts
-// src/entity/Entity.d.ts:37:5 - (ae-incompatible-release-tags) The symbol "status" is marked as @public, but its signature references "UNSTABLE_EntityStatus" which is marked as @alpha
-// src/entity/policies/types.d.ts:10:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
-// src/kinds/types.d.ts:9:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
+// src/entity/Entity.d.ts:38:5 - (ae-incompatible-release-tags) The symbol "status" is marked as @public, but its signature references "UNSTABLE_EntityStatus" which is marked as @alpha
// (No @packageDocumentation comment for this package)
```
diff --git a/packages/catalog-model/src/EntityPolicies.ts b/packages/catalog-model/src/EntityPolicies.ts
index eca5e4b77a..0fff68d569 100644
--- a/packages/catalog-model/src/EntityPolicies.ts
+++ b/packages/catalog-model/src/EntityPolicies.ts
@@ -52,11 +52,12 @@ class AnyEntityPolicy implements EntityPolicy {
}
}
+/** @public */
export const EntityPolicies = {
- allOf(policies: EntityPolicy[]) {
+ allOf(policies: EntityPolicy[]): EntityPolicy {
return new AllEntityPolicies(policies);
},
- oneOf(policies: EntityPolicy[]) {
+ oneOf(policies: EntityPolicy[]): EntityPolicy {
return new AnyEntityPolicy(policies);
},
};
diff --git a/packages/catalog-model/src/entity/Entity.ts b/packages/catalog-model/src/entity/Entity.ts
index 681ac43b80..ca38fef183 100644
--- a/packages/catalog-model/src/entity/Entity.ts
+++ b/packages/catalog-model/src/entity/Entity.ts
@@ -21,6 +21,7 @@ import { UNSTABLE_EntityStatus } from './EntityStatus';
/**
* The parts of the format that's common to all versions/kinds of entity.
*
+ * @public
* @see https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/
*/
export type Entity = {
@@ -62,6 +63,7 @@ export type Entity = {
/**
* Metadata fields common to all versions/kinds of entity.
*
+ * @public
* @see https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#objectmeta-v1-meta
* @see https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/
*/
@@ -166,6 +168,8 @@ export type EntityMeta = JsonObject & {
/**
* A relation of a specific type to another entity in the catalog.
+ *
+ * @public
*/
export type EntityRelation = {
/**
@@ -181,6 +185,8 @@ export type EntityRelation = {
/**
* Holds the relation data for entities.
+ *
+ * @public
*/
export type EntityRelationSpec = {
/**
@@ -201,6 +207,8 @@ export type EntityRelationSpec = {
/**
* A link to external information that is related to the entity.
+ *
+ * @public
*/
export type EntityLink = {
/**
diff --git a/packages/catalog-model/src/entity/EntityEnvelope.ts b/packages/catalog-model/src/entity/EntityEnvelope.ts
index ed21a7d666..290738f491 100644
--- a/packages/catalog-model/src/entity/EntityEnvelope.ts
+++ b/packages/catalog-model/src/entity/EntityEnvelope.ts
@@ -18,6 +18,7 @@
* The envelope skeleton parts of an entity - whatever is necessary to be able
* to give it a ref and pass to further validation / policy checking.
*
+ * @public
* @see https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/
*/
export type EntityEnvelope = {
diff --git a/packages/catalog-model/src/entity/EntityStatus.ts b/packages/catalog-model/src/entity/EntityStatus.ts
index 92e1d1454f..8f79fbd615 100644
--- a/packages/catalog-model/src/entity/EntityStatus.ts
+++ b/packages/catalog-model/src/entity/EntityStatus.ts
@@ -18,6 +18,7 @@ import { SerializedError } from '@backstage/errors';
/**
* The current status of the entity, as claimed by various sources.
+ *
* @alpha
*/
export type UNSTABLE_EntityStatus = {
diff --git a/packages/catalog-model/src/entity/constants.ts b/packages/catalog-model/src/entity/constants.ts
index d46d839720..ff031fc1ae 100644
--- a/packages/catalog-model/src/entity/constants.ts
+++ b/packages/catalog-model/src/entity/constants.ts
@@ -16,11 +16,15 @@
/**
* The namespace that entities without an explicit namespace fall into.
+ *
+ * @public
*/
export const ENTITY_DEFAULT_NAMESPACE = 'default';
/**
* The keys of EntityMeta that are auto-generated.
+ *
+ * @public
*/
export const ENTITY_META_GENERATED_FIELDS = [
'uid',
@@ -30,6 +34,9 @@ export const ENTITY_META_GENERATED_FIELDS = [
/**
* Annotations for linking to entity from catalog pages.
+ *
+ * @public
*/
export const VIEW_URL_ANNOTATION = 'backstage.io/view-url';
+/** @public */
export const EDIT_URL_ANNOTATION = 'backstage.io/edit-url';
diff --git a/packages/catalog-model/src/entity/index.ts b/packages/catalog-model/src/entity/index.ts
index d05045fc78..eac55ea325 100644
--- a/packages/catalog-model/src/entity/index.ts
+++ b/packages/catalog-model/src/entity/index.ts
@@ -42,6 +42,7 @@ export {
serializeEntityRef,
stringifyEntityRef,
} from './ref';
+export type { EntityRefContext } from './ref';
export {
entityHasChanges,
generateEntityEtag,
diff --git a/packages/catalog-model/src/entity/policies/DefaultNamespaceEntityPolicy.ts b/packages/catalog-model/src/entity/policies/DefaultNamespaceEntityPolicy.ts
index 1750aece17..9511dfb05f 100644
--- a/packages/catalog-model/src/entity/policies/DefaultNamespaceEntityPolicy.ts
+++ b/packages/catalog-model/src/entity/policies/DefaultNamespaceEntityPolicy.ts
@@ -21,6 +21,8 @@ import { Entity } from '../Entity';
/**
* Sets a default namespace if none was set.
+ *
+ * @public
*/
export class DefaultNamespaceEntityPolicy implements EntityPolicy {
private readonly namespace: string;
diff --git a/packages/catalog-model/src/entity/policies/FieldFormatEntityPolicy.ts b/packages/catalog-model/src/entity/policies/FieldFormatEntityPolicy.ts
index ee95fd16ea..8655116ec6 100644
--- a/packages/catalog-model/src/entity/policies/FieldFormatEntityPolicy.ts
+++ b/packages/catalog-model/src/entity/policies/FieldFormatEntityPolicy.ts
@@ -29,6 +29,8 @@ import { Entity } from '../Entity';
*
* This does not take into account machine generated fields such as uid, etag
* and generation.
+ *
+ * @public
*/
export class FieldFormatEntityPolicy implements EntityPolicy {
private readonly validators: Validators;
diff --git a/packages/catalog-model/src/entity/policies/NoForeignRootFieldsEntityPolicy.ts b/packages/catalog-model/src/entity/policies/NoForeignRootFieldsEntityPolicy.ts
index 6700a935d5..1c3f865434 100644
--- a/packages/catalog-model/src/entity/policies/NoForeignRootFieldsEntityPolicy.ts
+++ b/packages/catalog-model/src/entity/policies/NoForeignRootFieldsEntityPolicy.ts
@@ -21,6 +21,8 @@ const defaultKnownFields = ['apiVersion', 'kind', 'metadata', 'spec'];
/**
* Ensures that there are no foreign root fields in the entity.
+ *
+ * @public
*/
export class NoForeignRootFieldsEntityPolicy implements EntityPolicy {
private readonly knownFields: string[];
diff --git a/packages/catalog-model/src/entity/policies/SchemaValidEntityPolicy.ts b/packages/catalog-model/src/entity/policies/SchemaValidEntityPolicy.ts
index b5a4305a3c..721dc7d2dc 100644
--- a/packages/catalog-model/src/entity/policies/SchemaValidEntityPolicy.ts
+++ b/packages/catalog-model/src/entity/policies/SchemaValidEntityPolicy.ts
@@ -27,6 +27,8 @@ import { EntityPolicy } from './types';
* This should be the first policy in the list, to ensure that other downstream
* policies can work with a structure that is at least valid in therms of the
* typescript type.
+ *
+ * @public
*/
export class SchemaValidEntityPolicy implements EntityPolicy {
private validate: ValidateFunction | undefined;
diff --git a/packages/catalog-model/src/entity/policies/types.ts b/packages/catalog-model/src/entity/policies/types.ts
index 6c7f47c332..ad0485e711 100644
--- a/packages/catalog-model/src/entity/policies/types.ts
+++ b/packages/catalog-model/src/entity/policies/types.ts
@@ -19,12 +19,14 @@ import type { Entity } from '../Entity';
/**
* A policy for validation or mutation to be applied to entities as they are
* entering the system.
+ *
+ * @public
*/
export type EntityPolicy = {
/**
* Applies validation or mutation on an entity.
*
- * @param entity The entity, as validated/mutated so far in the policy tree
+ * @param entity - The entity, as validated/mutated so far in the policy tree
* @returns The incoming entity, or a mutated version of the same, or
* undefined if this processor could not handle the entity
* @throws An error if the entity should be rejected
diff --git a/packages/catalog-model/src/entity/ref.ts b/packages/catalog-model/src/entity/ref.ts
index e2d9c5b203..c1b9383eeb 100644
--- a/packages/catalog-model/src/entity/ref.ts
+++ b/packages/catalog-model/src/entity/ref.ts
@@ -41,7 +41,8 @@ function parseRefString(ref: string): {
* Extracts the kind, namespace and name that form the name triplet of the
* given entity.
*
- * @param entity An entity
+ * @public
+ * @param entity - An entity
* @returns The complete entity name
*/
export function getEntityName(entity: Entity): EntityName {
@@ -54,8 +55,10 @@ export function getEntityName(entity: Entity): EntityName {
/**
* The context of defaults that entity reference parsing happens within.
+ *
+ * @public
*/
-type EntityRefContext = {
+export type EntityRefContext = {
/** The default kind, if none is given in the reference */
defaultKind?: string;
/** The default namespace, if none is given in the reference */
@@ -70,8 +73,9 @@ type EntityRefContext = {
* 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.
*
- * @param ref The reference to parse
- * @param context The context of defaults that the parsing happens within
+ * @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(
@@ -99,8 +103,9 @@ export function parseEntityName(
* The options object can contain default values for the kind and namespace,
* that will be used if the input reference did not specify any.
*
- * @param ref The reference to parse
- * @param context The context of defaults that the parsing happens within
+ * @public
+ * @param ref - The reference to parse
+ * @param context - The context of defaults that the parsing happens within
* @returns The compound form of the reference
*/
export function parseEntityRef(
@@ -111,6 +116,7 @@ export function parseEntityRef(
namespace: string;
name: string;
};
+/** @public */
export function parseEntityRef(
ref: EntityRef,
context?: { defaultKind: string },
@@ -119,6 +125,7 @@ export function parseEntityRef(
namespace?: string;
name: string;
};
+/** @public */
export function parseEntityRef(
ref: EntityRef,
context?: { defaultNamespace: string },
@@ -170,8 +177,9 @@ export function parseEntityRef(
* special/reserved characters, it outputs the string form, otherwise it
* outputs the compound form.
*
+ * @public
* @deprecated Use `stringifyEntityRef` instead
- * @param ref The reference to serialize
+ * @param ref - The reference to serialize
* @returns The same reference on either string or compound form
*/
export function serializeEntityRef(
@@ -219,7 +227,8 @@ export function serializeEntityRef(
* all parts of the name to lowercase and inserts the default namespace if needed.
* It is typically not the best way to represent the entity reference to the user.
*
- * @param ref The reference to serialize
+ * @public
+ * @param ref - The reference to serialize
* @returns The same reference on either string or compound form
*/
export function stringifyEntityRef(
@@ -248,9 +257,10 @@ export function stringifyEntityRef(
* The comparison is case insensitive, and all of kind, namespace, and name
* must match (after applying the optional context to the ref).
*
- * @param entity The entity to match
- * @param ref A string or compound entity ref
- * @param context An optional context of default kind and namespace, that apply
+ * @public
+ * @param entity - The entity to match
+ * @param ref - A string or compound entity ref
+ * @param context - An optional context of default kind and namespace, that apply
* to the ref if given
* @returns True if matching, false otherwise
*/
diff --git a/packages/catalog-model/src/entity/util.ts b/packages/catalog-model/src/entity/util.ts
index 84b6845347..314f3b7737 100644
--- a/packages/catalog-model/src/entity/util.ts
+++ b/packages/catalog-model/src/entity/util.ts
@@ -21,6 +21,7 @@ import { Entity } from './Entity';
/**
* Generates a new random UID for an entity.
*
+ * @public
* @returns A string with enough randomness to uniquely identify an entity
*/
export function generateEntityUid(): string {
@@ -30,6 +31,7 @@ export function generateEntityUid(): string {
/**
* Generates a new random Etag for an entity.
*
+ * @public
* @returns A string with enough randomness to uniquely identify an entity
* revision
*/
@@ -48,8 +50,9 @@ export function generateEntityEtag(): string {
* account. It only compares the actual input entity data, i.e. metadata and
* spec.
*
- * @param previous The old state of the entity
- * @param next The new state of the entity
+ * @public
+ * @param previous - The old state of the entity
+ * @param next - The new state of the entity
*/
export function entityHasChanges(previous: Entity, next: Entity): boolean {
const e1 = lodash.cloneDeep(previous);
@@ -98,8 +101,9 @@ export function entityHasChanges(previous: Entity, next: Entity): boolean {
* The previous revision is expected to be a complete model loaded from the
* catalog, including the uid, etag and generation fields.
*
- * @param previous The old state of the entity
- * @param next The new state of the entity
+ * @public
+ * @param previous - The old state of the entity
+ * @param next - The new state of the entity
* @returns An entity with the merged state of both
*/
export function generateUpdatedEntity(previous: Entity, next: Entity): Entity {
diff --git a/packages/catalog-model/src/kinds/ApiEntityV1alpha1.ts b/packages/catalog-model/src/kinds/ApiEntityV1alpha1.ts
index 2bcd9c7040..310b6695eb 100644
--- a/packages/catalog-model/src/kinds/ApiEntityV1alpha1.ts
+++ b/packages/catalog-model/src/kinds/ApiEntityV1alpha1.ts
@@ -18,6 +18,7 @@ import type { Entity } from '../entity/Entity';
import schema from '../schema/kinds/API.v1alpha1.schema.json';
import { ajvCompiledJsonSchemaValidator } from './util';
+/** @public */
export interface ApiEntityV1alpha1 extends Entity {
apiVersion: 'backstage.io/v1alpha1' | 'backstage.io/v1beta1';
kind: 'API';
@@ -30,5 +31,6 @@ export interface ApiEntityV1alpha1 extends Entity {
};
}
+/** @public */
export const apiEntityV1alpha1Validator =
ajvCompiledJsonSchemaValidator(schema);
diff --git a/packages/catalog-model/src/kinds/ComponentEntityV1alpha1.ts b/packages/catalog-model/src/kinds/ComponentEntityV1alpha1.ts
index 5312d87a35..6777778409 100644
--- a/packages/catalog-model/src/kinds/ComponentEntityV1alpha1.ts
+++ b/packages/catalog-model/src/kinds/ComponentEntityV1alpha1.ts
@@ -18,6 +18,7 @@ import type { Entity } from '../entity/Entity';
import schema from '../schema/kinds/Component.v1alpha1.schema.json';
import { ajvCompiledJsonSchemaValidator } from './util';
+/** @public */
export interface ComponentEntityV1alpha1 extends Entity {
apiVersion: 'backstage.io/v1alpha1' | 'backstage.io/v1beta1';
kind: 'Component';
@@ -33,5 +34,6 @@ export interface ComponentEntityV1alpha1 extends Entity {
};
}
+/** @public */
export const componentEntityV1alpha1Validator =
ajvCompiledJsonSchemaValidator(schema);
diff --git a/packages/catalog-model/src/kinds/DomainEntityV1alpha1.ts b/packages/catalog-model/src/kinds/DomainEntityV1alpha1.ts
index c832f35ee0..fe777af24e 100644
--- a/packages/catalog-model/src/kinds/DomainEntityV1alpha1.ts
+++ b/packages/catalog-model/src/kinds/DomainEntityV1alpha1.ts
@@ -18,6 +18,7 @@ import type { Entity } from '../entity/Entity';
import schema from '../schema/kinds/Domain.v1alpha1.schema.json';
import { ajvCompiledJsonSchemaValidator } from './util';
+/** @public */
export interface DomainEntityV1alpha1 extends Entity {
apiVersion: 'backstage.io/v1alpha1' | 'backstage.io/v1beta1';
kind: 'Domain';
@@ -26,5 +27,6 @@ export interface DomainEntityV1alpha1 extends Entity {
};
}
+/** @public */
export const domainEntityV1alpha1Validator =
ajvCompiledJsonSchemaValidator(schema);
diff --git a/packages/catalog-model/src/kinds/GroupEntityV1alpha1.ts b/packages/catalog-model/src/kinds/GroupEntityV1alpha1.ts
index 263ba311ad..f6aab856f0 100644
--- a/packages/catalog-model/src/kinds/GroupEntityV1alpha1.ts
+++ b/packages/catalog-model/src/kinds/GroupEntityV1alpha1.ts
@@ -18,6 +18,7 @@ import type { Entity } from '../entity/Entity';
import schema from '../schema/kinds/Group.v1alpha1.schema.json';
import { ajvCompiledJsonSchemaValidator } from './util';
+/** @public */
export interface GroupEntityV1alpha1 extends Entity {
apiVersion: 'backstage.io/v1alpha1' | 'backstage.io/v1beta1';
kind: 'Group';
@@ -34,5 +35,6 @@ export interface GroupEntityV1alpha1 extends Entity {
};
}
+/** @public */
export const groupEntityV1alpha1Validator =
ajvCompiledJsonSchemaValidator(schema);
diff --git a/packages/catalog-model/src/kinds/LocationEntityV1alpha1.ts b/packages/catalog-model/src/kinds/LocationEntityV1alpha1.ts
index 44f04b2c39..f2ae4bcc91 100644
--- a/packages/catalog-model/src/kinds/LocationEntityV1alpha1.ts
+++ b/packages/catalog-model/src/kinds/LocationEntityV1alpha1.ts
@@ -18,6 +18,7 @@ import type { Entity } from '../entity/Entity';
import schema from '../schema/kinds/Location.v1alpha1.schema.json';
import { ajvCompiledJsonSchemaValidator } from './util';
+/** @public */
export interface LocationEntityV1alpha1 extends Entity {
apiVersion: 'backstage.io/v1alpha1' | 'backstage.io/v1beta1';
kind: 'Location';
@@ -28,5 +29,6 @@ export interface LocationEntityV1alpha1 extends Entity {
};
}
+/** @public */
export const locationEntityV1alpha1Validator =
ajvCompiledJsonSchemaValidator(schema);
diff --git a/packages/catalog-model/src/kinds/ResourceEntityV1alpha1.ts b/packages/catalog-model/src/kinds/ResourceEntityV1alpha1.ts
index 211164f4c1..acc6ab5245 100644
--- a/packages/catalog-model/src/kinds/ResourceEntityV1alpha1.ts
+++ b/packages/catalog-model/src/kinds/ResourceEntityV1alpha1.ts
@@ -18,6 +18,7 @@ import type { Entity } from '../entity/Entity';
import schema from '../schema/kinds/Resource.v1alpha1.schema.json';
import { ajvCompiledJsonSchemaValidator } from './util';
+/** @public */
export interface ResourceEntityV1alpha1 extends Entity {
apiVersion: 'backstage.io/v1alpha1' | 'backstage.io/v1beta1';
kind: 'Resource';
@@ -29,5 +30,6 @@ export interface ResourceEntityV1alpha1 extends Entity {
};
}
+/** @public */
export const resourceEntityV1alpha1Validator =
ajvCompiledJsonSchemaValidator(schema);
diff --git a/packages/catalog-model/src/kinds/SystemEntityV1alpha1.ts b/packages/catalog-model/src/kinds/SystemEntityV1alpha1.ts
index 129e3fea50..5f90351480 100644
--- a/packages/catalog-model/src/kinds/SystemEntityV1alpha1.ts
+++ b/packages/catalog-model/src/kinds/SystemEntityV1alpha1.ts
@@ -18,6 +18,7 @@ import type { Entity } from '../entity/Entity';
import schema from '../schema/kinds/System.v1alpha1.schema.json';
import { ajvCompiledJsonSchemaValidator } from './util';
+/** @public */
export interface SystemEntityV1alpha1 extends Entity {
apiVersion: 'backstage.io/v1alpha1' | 'backstage.io/v1beta1';
kind: 'System';
@@ -27,5 +28,6 @@ export interface SystemEntityV1alpha1 extends Entity {
};
}
+/** @public */
export const systemEntityV1alpha1Validator =
ajvCompiledJsonSchemaValidator(schema);
diff --git a/packages/catalog-model/src/kinds/TemplateEntityV1beta2.ts b/packages/catalog-model/src/kinds/TemplateEntityV1beta2.ts
index 1d7aa2162c..e708d4b387 100644
--- a/packages/catalog-model/src/kinds/TemplateEntityV1beta2.ts
+++ b/packages/catalog-model/src/kinds/TemplateEntityV1beta2.ts
@@ -19,6 +19,7 @@ import type { Entity } from '../entity/Entity';
import schema from '../schema/kinds/Template.v1beta2.schema.json';
import { ajvCompiledJsonSchemaValidator } from './util';
+/** @public */
export interface TemplateEntityV1beta2 extends Entity {
apiVersion: 'backstage.io/v1beta2';
kind: 'Template';
@@ -37,5 +38,6 @@ export interface TemplateEntityV1beta2 extends Entity {
};
}
+/** @public */
export const templateEntityV1beta2Validator =
ajvCompiledJsonSchemaValidator(schema);
diff --git a/packages/catalog-model/src/kinds/UserEntityV1alpha1.ts b/packages/catalog-model/src/kinds/UserEntityV1alpha1.ts
index 65ebdb3262..d719ab35ef 100644
--- a/packages/catalog-model/src/kinds/UserEntityV1alpha1.ts
+++ b/packages/catalog-model/src/kinds/UserEntityV1alpha1.ts
@@ -18,6 +18,7 @@ import type { Entity } from '../entity/Entity';
import schema from '../schema/kinds/User.v1alpha1.schema.json';
import { ajvCompiledJsonSchemaValidator } from './util';
+/** @public */
export interface UserEntityV1alpha1 extends Entity {
apiVersion: 'backstage.io/v1alpha1' | 'backstage.io/v1beta1';
kind: 'User';
@@ -31,5 +32,6 @@ export interface UserEntityV1alpha1 extends Entity {
};
}
+/** @public */
export const userEntityV1alpha1Validator =
ajvCompiledJsonSchemaValidator(schema);
diff --git a/packages/catalog-model/src/kinds/relations.ts b/packages/catalog-model/src/kinds/relations.ts
index 57977e7168..7546d1508b 100644
--- a/packages/catalog-model/src/kinds/relations.ts
+++ b/packages/catalog-model/src/kinds/relations.ts
@@ -25,40 +25,60 @@ Naming rules for relations in priority order:
/**
* An ownership relation where the owner is usually an organizational
* entity (user or group), and the other entity can be anything.
+ *
+ * @public
*/
export const RELATION_OWNED_BY = 'ownedBy';
+/** @public */
export const RELATION_OWNER_OF = 'ownerOf';
/**
* A relation with an API entity, typically from a component
+ *
+ * @public
*/
export const RELATION_CONSUMES_API = 'consumesApi';
+/** @public */
export const RELATION_API_CONSUMED_BY = 'apiConsumedBy';
+/** @public */
export const RELATION_PROVIDES_API = 'providesApi';
+/** @public */
export const RELATION_API_PROVIDED_BY = 'apiProvidedBy';
/**
* A relation denoting a dependency on another entity.
+ *
+ * @public
*/
export const RELATION_DEPENDS_ON = 'dependsOn';
+/** @public */
export const RELATION_DEPENDENCY_OF = 'dependencyOf';
/**
* A parent/child relation to build up a tree, used for example to describe
* the organizational structure between groups.
+ *
+ * @public
*/
export const RELATION_PARENT_OF = 'parentOf';
+/** @public */
export const RELATION_CHILD_OF = 'childOf';
/**
* A membership relation, typically for users in a group.
+ *
+ * @public
*/
export const RELATION_MEMBER_OF = 'memberOf';
+/** @public */
export const RELATION_HAS_MEMBER = 'hasMember';
/**
* A part/whole relation, typically for components in a system and systems
* in a domain.
+ *
+ * @public
*/
export const RELATION_PART_OF = 'partOf';
+/** @public */
export const RELATION_HAS_PART = 'hasPart';
diff --git a/packages/catalog-model/src/kinds/types.ts b/packages/catalog-model/src/kinds/types.ts
index 0ec0d313bb..f4bc151384 100644
--- a/packages/catalog-model/src/kinds/types.ts
+++ b/packages/catalog-model/src/kinds/types.ts
@@ -18,12 +18,14 @@ import { Entity } from '../entity';
/**
* Validates entities of a certain kind.
+ *
+ * @public
*/
export type KindValidator = {
/**
* Validates the entity as a known entity kind.
*
- * @param entity The entity to validate
+ * @param entity - The entity to validate
* @returns Resolves to true, if the entity was of a kind that was known and
* handled by this validator, and was found to be valid. Resolves to false,
* if the entity was not of a kind that was known by this validator.
diff --git a/packages/catalog-model/src/location/annotation.ts b/packages/catalog-model/src/location/annotation.ts
index 137d36a0da..4bcabdb705 100644
--- a/packages/catalog-model/src/location/annotation.ts
+++ b/packages/catalog-model/src/location/annotation.ts
@@ -14,8 +14,11 @@
* limitations under the License.
*/
+/** @public */
export const LOCATION_ANNOTATION = 'backstage.io/managed-by-location';
+/** @public */
export const ORIGIN_LOCATION_ANNOTATION =
'backstage.io/managed-by-origin-location';
+/** @public */
export const SOURCE_LOCATION_ANNOTATION = 'backstage.io/source-location';
diff --git a/packages/catalog-model/src/location/helpers.ts b/packages/catalog-model/src/location/helpers.ts
index 91209e7a2a..cf12031dc1 100644
--- a/packages/catalog-model/src/location/helpers.ts
+++ b/packages/catalog-model/src/location/helpers.ts
@@ -23,8 +23,9 @@ import { LOCATION_ANNOTATION, SOURCE_LOCATION_ANNOTATION } from './annotation';
* Note that the return type is not `LocationSpec`, because we do not want to
* conflate the string form with the additional properties of that type.
*
- * @param ref A string-form location reference, e.g. 'url:https://host'
- * @returns A location reference, e.g. { type: 'url', target: 'https://host' }
+ * @public
+ * @param ref - A string-form location reference, e.g. `'url:https://host'`
+ * @returns A location reference, e.g. `{ type: 'url', target: 'https://host' }`
*/
export function parseLocationReference(ref: string): {
type: string;
@@ -67,8 +68,9 @@ export function parseLocationReference(ref: string): {
* Note that the input type is not `LocationSpec`, because we do not want to
* conflate the string form with the additional properties of that type.
*
- * @param ref A location reference, e.g. { type: 'url', target: 'https://host' }
- * @returns A string-form location reference, e.g. 'url:https://host'
+ * @public
+ * @param ref - A location reference, e.g. `{ type: 'url', target: 'https://host' }`
+ * @returns A string-form location reference, e.g. `'url:https://host'`
*/
export function stringifyLocationReference(ref: {
type: string;
@@ -89,8 +91,10 @@ export function stringifyLocationReference(ref: {
* Returns the source code location of the Entity, to the extent that one exists.
*
* If the returned location type is of type 'url', the target should be readable at least
- * using the UrlReader from @backstage/backend-common. If it is not of type 'url', the caller
+ * using the UrlReader from `@backstage/backend-common`. If it is not of type 'url', the caller
* needs to have explicit handling of each location type or signal that it is not supported.
+ *
+ * @public
*/
export function getEntitySourceLocation(entity: Entity): {
type: string;
diff --git a/packages/catalog-model/src/location/types.ts b/packages/catalog-model/src/location/types.ts
index 9837ce384d..1d16a9047d 100644
--- a/packages/catalog-model/src/location/types.ts
+++ b/packages/catalog-model/src/location/types.ts
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+/** @public */
export type LocationSpec = {
type: string;
target: string;
@@ -23,6 +24,7 @@ export type LocationSpec = {
presence?: 'optional' | 'required';
};
+/** @public */
export type Location = {
id: string;
} & LocationSpec;
diff --git a/packages/catalog-model/src/location/validation.ts b/packages/catalog-model/src/location/validation.ts
index 4857fc76bc..f6680d6eee 100644
--- a/packages/catalog-model/src/location/validation.ts
+++ b/packages/catalog-model/src/location/validation.ts
@@ -17,7 +17,10 @@
import * as yup from 'yup';
import { LocationSpec, Location } from './types';
-/** @deprecated */
+/**
+ * @public
+ * @deprecated Use JSONSchema or validators instead.
+ */
export const locationSpecSchema = yup
.object({
type: yup.string().required(),
@@ -27,7 +30,10 @@ export const locationSpecSchema = yup
.noUnknown()
.required();
-/** @deprecated */
+/**
+ * @public
+ * @deprecated Use JSONSchema or validators instead.
+ */
export const locationSchema = yup
.object({
id: yup.string().required(),
@@ -37,7 +43,10 @@ export const locationSchema = yup
.noUnknown()
.required();
-/** @deprecated */
+/**
+ * @public
+ * @deprecated Use JSONSchema or validators instead.
+ */
export const analyzeLocationSchema = yup
.object<{ location: LocationSpec }>({
location: locationSpecSchema,
diff --git a/packages/catalog-model/src/types.ts b/packages/catalog-model/src/types.ts
index 50de5a1cea..1fbb3be95c 100644
--- a/packages/catalog-model/src/types.ts
+++ b/packages/catalog-model/src/types.ts
@@ -17,10 +17,13 @@
import { JsonValue } from '@backstage/config';
import { JSONSchema7 } from 'json-schema';
+/** @public */
export type JSONSchema = JSONSchema7 & { [key in string]?: JsonValue };
/**
* A complete entity name, with the full kind-namespace-name triplet.
+ *
+ * @public
*/
export type EntityName = {
kind: string;
@@ -36,6 +39,8 @@ export type EntityName = {
*
* 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
diff --git a/packages/catalog-model/src/validation/CommonValidatorFunctions.ts b/packages/catalog-model/src/validation/CommonValidatorFunctions.ts
index 7c9736baf7..5fcd2ee755 100644
--- a/packages/catalog-model/src/validation/CommonValidatorFunctions.ts
+++ b/packages/catalog-model/src/validation/CommonValidatorFunctions.ts
@@ -19,16 +19,18 @@ import lodash from 'lodash';
/**
* Contains various helper validation and normalization functions that can be
* composed to form a Validator.
+ *
+ * @public
*/
export class CommonValidatorFunctions {
/**
* Checks that the value is on the form or , and validates
* those parts separately.
*
- * @param value The value to check
- * @param separator The separator between parts
- * @param isValidPrefix Checks that the part before the separator is valid, if present
- * @param isValidSuffix Checks that the part after the separator (or the entire value if there is no separator) is valid
+ * @param value - The value to check
+ * @param separator - The separator between parts
+ * @param isValidPrefix - Checks that the part before the separator is valid, if present
+ * @param isValidSuffix - Checks that the part after the separator (or the entire value if there is no separator) is valid
*/
static isValidPrefixAndOrSuffix(
value: unknown,
@@ -53,7 +55,7 @@ export class CommonValidatorFunctions {
/**
* Checks that the value can be safely transferred as JSON.
*
- * @param value The value to check
+ * @param value - The value to check
*/
static isJsonSafe(value: unknown): boolean {
try {
@@ -66,7 +68,7 @@ export class CommonValidatorFunctions {
/**
* Checks that the value is a valid DNS subdomain name.
*
- * @param value The value to check
+ * @param value - The value to check
* @see https://tools.ietf.org/html/rfc1123
*/
static isValidDnsSubdomain(value: unknown): boolean {
@@ -81,7 +83,7 @@ export class CommonValidatorFunctions {
/**
* Checks that the value is a valid DNS label.
*
- * @param value The value to check
+ * @param value - The value to check
* @see https://tools.ietf.org/html/rfc1123
*/
static isValidDnsLabel(value: unknown): boolean {
@@ -96,7 +98,7 @@ export class CommonValidatorFunctions {
/**
* Checks that the value is a valid URL.
*
- * @param value The value to check
+ * @param value - The value to check
*/
static isValidUrl(value: unknown): boolean {
if (typeof value !== 'string') {
@@ -115,7 +117,7 @@ export class CommonValidatorFunctions {
/**
* Checks that the value is a non empty string value.
*
- * @param value The value to check
+ * @param value - The value to check
*/
static isValidString(value: unknown): boolean {
return typeof value === 'string' && value?.trim()?.length >= 1;
diff --git a/packages/catalog-model/src/validation/KubernetesValidatorFunctions.ts b/packages/catalog-model/src/validation/KubernetesValidatorFunctions.ts
index 86d27e7b13..2423c47bef 100644
--- a/packages/catalog-model/src/validation/KubernetesValidatorFunctions.ts
+++ b/packages/catalog-model/src/validation/KubernetesValidatorFunctions.ts
@@ -20,6 +20,7 @@ import { CommonValidatorFunctions } from './CommonValidatorFunctions';
* Contains validation functions that match the Kubernetes spec, usable to
* build a catalog that is compatible with those rule sets.
*
+ * @public
* @see https://kubernetes.io/docs/concepts/overview/working-with-objects/names/
* @see https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#syntax-and-character-set
* @see https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/#syntax-and-character-set
diff --git a/packages/catalog-model/src/validation/entityEnvelopeSchemaValidator.ts b/packages/catalog-model/src/validation/entityEnvelopeSchemaValidator.ts
index aa865bcf1c..daa44ffaf1 100644
--- a/packages/catalog-model/src/validation/entityEnvelopeSchemaValidator.ts
+++ b/packages/catalog-model/src/validation/entityEnvelopeSchemaValidator.ts
@@ -22,7 +22,7 @@ import { compileAjvSchema, throwAjvError } from './ajv';
/**
* Creates a validation function that takes some arbitrary data, and either
* returns that data cast to an {@link EntityEnvelope} (or the given subtype)
- * if it matches that schema, or throws a {@link TypeError} describing the
+ * if it matches that schema, or throws a {@link globals#TypeError} describing the
* errors.
*
* Note that this validator is only meant for applying the base schema checks;
@@ -38,6 +38,7 @@ import { compileAjvSchema, throwAjvError } from './ajv';
* - EntityMeta
* - common#
*
+ * @public
* @see https://github.com/backstage/backstage/tree/master/packages/catalog-model/src/schema
*/
export function entityEnvelopeSchemaValidator<
diff --git a/packages/catalog-model/src/validation/entityKindSchemaValidator.ts b/packages/catalog-model/src/validation/entityKindSchemaValidator.ts
index a295fac205..535dba9842 100644
--- a/packages/catalog-model/src/validation/entityKindSchemaValidator.ts
+++ b/packages/catalog-model/src/validation/entityKindSchemaValidator.ts
@@ -22,20 +22,20 @@ import { compileAjvSchema, throwAjvError } from './ajv';
* Creates a validation function that takes some arbitrary data, and either
* returns that data cast to a `T` if it matches that schema, or `false` if the
* schema apiVersion/kind didn't apply to that data, or throws a
- * {@link TypeError} describing actual errors.
+ * {@link globals#TypeError} describing actual errors.
*
* This validator is highly specialized, in that it has special treatment of
* the `kind` and `apiVersion` root keys. This only works if your schema has
* their rule set to `"enum"`:
*
- *
+ * ```
+ * "apiVersion": {
+ * "enum": ["backstage.io/v1alpha1", "backstage.io/v1beta1"]
+ * },
+ * "kind": {
+ * "enum": ["Group"]
+ * },
+ * ```
*
* In the above example, the created validator will return `false` if and only
* if the kind and/or apiVersion mismatch.
@@ -52,6 +52,7 @@ import { compileAjvSchema, throwAjvError } from './ajv';
* - EntityMeta
* - common#
*
+ * @public
* @see https://github.com/backstage/backstage/tree/master/packages/catalog-model/src/schema
*/
export function entityKindSchemaValidator(
diff --git a/packages/catalog-model/src/validation/entitySchemaValidator.ts b/packages/catalog-model/src/validation/entitySchemaValidator.ts
index 8683ab6de6..dd110efd75 100644
--- a/packages/catalog-model/src/validation/entitySchemaValidator.ts
+++ b/packages/catalog-model/src/validation/entitySchemaValidator.ts
@@ -22,7 +22,7 @@ import { compileAjvSchema, throwAjvError } from './ajv';
/**
* Creates a validation function that takes some arbitrary data, and either
* returns that data cast to an {@link Entity} (or the given subtype) if it
- * matches that schema, or throws a {@link TypeError} describing the errors.
+ * matches that schema, or throws a {@link globals#TypeError} describing the errors.
*
* Note that this validator is only meant for applying the base schema checks;
* it does not take custom policies or additional processor based validation
@@ -37,6 +37,7 @@ import { compileAjvSchema, throwAjvError } from './ajv';
* - EntityMeta
* - common#
*
+ * @public
* @see https://github.com/backstage/backstage/tree/master/packages/catalog-model/src/schema
*/
export function entitySchemaValidator(
diff --git a/packages/catalog-model/src/validation/makeValidator.ts b/packages/catalog-model/src/validation/makeValidator.ts
index 0ddd9d1088..48eff566f2 100644
--- a/packages/catalog-model/src/validation/makeValidator.ts
+++ b/packages/catalog-model/src/validation/makeValidator.ts
@@ -30,6 +30,7 @@ const defaultValidators: Validators = {
isValidTag: CommonValidatorFunctions.isValidDnsLabel,
};
+/** @public */
export function makeValidator(overrides: Partial = {}): Validators {
return {
...defaultValidators,
diff --git a/packages/catalog-model/src/validation/types.ts b/packages/catalog-model/src/validation/types.ts
index cfa9d845bc..23d639c166 100644
--- a/packages/catalog-model/src/validation/types.ts
+++ b/packages/catalog-model/src/validation/types.ts
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+/** @public */
export type Validators = {
isValidApiVersion(value: unknown): boolean;
isValidKind(value: unknown): boolean;
diff --git a/packages/cli-common/api-report.md b/packages/cli-common/api-report.md
index d6d1c4fc36..f129fa3045 100644
--- a/packages/cli-common/api-report.md
+++ b/packages/cli-common/api-report.md
@@ -3,19 +3,13 @@
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
```ts
-// Warning: (ae-missing-release-tag) "findPaths" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export function findPaths(searchDir: string): Paths;
-// Warning: (ae-missing-release-tag) "isChildPath" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export function isChildPath(base: string, path: string): boolean;
-// Warning: (ae-missing-release-tag) "Paths" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public (undocumented)
+// @public
export type Paths = {
ownDir: string;
ownRoot: string;
@@ -27,9 +21,8 @@ export type Paths = {
resolveTargetRoot: ResolveFunc;
};
-// Warnings were encountered during analysis:
-//
-// src/paths.d.ts:7:5 - (ae-forgotten-export) The symbol "ResolveFunc" needs to be exported by the entry point index.d.ts
+// @public (undocumented)
+export type ResolveFunc = (...paths: string[]) => string;
// (No @packageDocumentation comment for this package)
```
diff --git a/packages/cli-common/src/index.ts b/packages/cli-common/src/index.ts
index 1f4f17fe9f..ed8158366d 100644
--- a/packages/cli-common/src/index.ts
+++ b/packages/cli-common/src/index.ts
@@ -16,4 +16,4 @@
export { findPaths } from './paths';
export { isChildPath } from './isChildPath';
-export type { Paths } from './paths';
+export type { Paths, ResolveFunc } from './paths';
diff --git a/packages/cli-common/src/isChildPath.ts b/packages/cli-common/src/isChildPath.ts
index f48c92db32..f66a0cfa94 100644
--- a/packages/cli-common/src/isChildPath.ts
+++ b/packages/cli-common/src/isChildPath.ts
@@ -18,6 +18,8 @@ import { relative, isAbsolute } from 'path';
/**
* Checks if path is the same as or a child path of base.
+ *
+ * @public
*/
export function isChildPath(base: string, path: string): boolean {
const relativePath = relative(base, path);
diff --git a/packages/cli-common/src/paths.ts b/packages/cli-common/src/paths.ts
index 12a8484797..90239dfa4a 100644
--- a/packages/cli-common/src/paths.ts
+++ b/packages/cli-common/src/paths.ts
@@ -17,10 +17,15 @@
import fs from 'fs';
import { dirname, resolve as resolvePath } from 'path';
+/** @public */
export type ResolveFunc = (...paths: string[]) => string;
-// Common paths and resolve functions used by the cli.
-// Currently assumes it is being executed within a monorepo.
+/**
+ * Common paths and resolve functions used by the cli.
+ * Currently assumes it is being executed within a monorepo.
+ *
+ * @public
+ */
export type Paths = {
// Root dir of the cli itself, containing package.json
ownDir: string;
@@ -100,6 +105,7 @@ export function findOwnRootDir(ownDir: string) {
/**
* Find paths related to a package and its execution context.
*
+ * @public
* @example
*
* const paths = findPaths(__dirname)
diff --git a/packages/cli/config/jest.js b/packages/cli/config/jest.js
index e2ff338b4e..4e11a63a6b 100644
--- a/packages/cli/config/jest.js
+++ b/packages/cli/config/jest.js
@@ -80,9 +80,8 @@ async function getConfig() {
transform: {
'\\.esm\\.js$': require.resolve('./jestEsmTransform.js'), // See jestEsmTransform.js
'\\.(js|jsx|ts|tsx)$': require.resolve('@sucrase/jest-plugin'),
- '\\.(bmp|gif|jpg|jpeg|png|frag|xml|svg)$': require.resolve(
- './jestFileTransform.js',
- ),
+ '\\.(bmp|gif|jpg|jpeg|png|frag|xml|svg|eot|woff|woff2|ttf)$':
+ require.resolve('./jestFileTransform.js'),
'\\.(yaml)$': require.resolve('yaml-jest'),
},
diff --git a/packages/config-loader/api-report.md b/packages/config-loader/api-report.md
index 38aa0b1ebb..a674f624b0 100644
--- a/packages/config-loader/api-report.md
+++ b/packages/config-loader/api-report.md
@@ -7,30 +7,31 @@ import { AppConfig } from '@backstage/config';
import { JsonObject } from '@backstage/config';
import { JSONSchema7 } from 'json-schema';
-// Warning: (ae-missing-release-tag) "ConfigSchema" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export type ConfigSchema = {
process(
appConfigs: AppConfig[],
- options?: ConfigProcessingOptions,
+ options?: ConfigSchemaProcessingOptions,
): AppConfig[];
serialize(): JsonObject;
};
-// Warning: (ae-forgotten-export) The symbol "CONFIG_VISIBILITIES" needs to be exported by the entry point index.d.ts
-// Warning: (ae-missing-release-tag) "ConfigVisibility" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
-export type ConfigVisibility = typeof CONFIG_VISIBILITIES[number];
+export type ConfigSchemaProcessingOptions = {
+ visibility?: ConfigVisibility[];
+ valueTransform?: TransformFunc;
+ withFilteredKeys?: boolean;
+};
+
+// @public
+export type ConfigVisibility = 'frontend' | 'backend' | 'secret';
-// Warning: (ae-missing-release-tag) "loadConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
+export type EnvFunc = (name: string) => Promise;
+
+// @public
export function loadConfig(options: LoadConfigOptions): Promise;
-// Warning: (ae-missing-release-tag) "LoadConfigOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export type LoadConfigOptions = {
configRoot: string;
@@ -43,28 +44,35 @@ export type LoadConfigOptions = {
};
};
-// Warning: (ae-forgotten-export) The symbol "Options" needs to be exported by the entry point index.d.ts
-// Warning: (ae-missing-release-tag) "loadConfigSchema" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
-export function loadConfigSchema(options: Options): Promise;
+export function loadConfigSchema(
+ options: LoadConfigSchemaOptions,
+): Promise;
+
+// @public (undocumented)
+export type LoadConfigSchemaOptions =
+ | {
+ dependencies: string[];
+ }
+ | {
+ serialized: JsonObject;
+ };
-// Warning: (ae-missing-release-tag) "mergeConfigSchemas" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export function mergeConfigSchemas(schemas: JSONSchema7[]): JSONSchema7;
-// Warning: (ae-missing-release-tag) "readEnvConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export function readEnvConfig(env: {
[name: string]: string | undefined;
}): AppConfig[];
-// Warnings were encountered during analysis:
-//
-// src/lib/schema/types.d.ts:83:5 - (ae-forgotten-export) The symbol "ConfigProcessingOptions" needs to be exported by the entry point index.d.ts
-// src/loader.d.ts:13:5 - (ae-forgotten-export) The symbol "EnvFunc" needs to be exported by the entry point index.d.ts
+// @public
+export type TransformFunc = (
+ value: T,
+ context: {
+ visibility: ConfigVisibility;
+ },
+) => T | undefined;
// (No @packageDocumentation comment for this package)
```
diff --git a/packages/config-loader/src/index.ts b/packages/config-loader/src/index.ts
index f605d53115..29976b52de 100644
--- a/packages/config-loader/src/index.ts
+++ b/packages/config-loader/src/index.ts
@@ -15,6 +15,13 @@
*/
export { readEnvConfig, loadConfigSchema, mergeConfigSchemas } from './lib';
-export type { ConfigSchema, ConfigVisibility } from './lib';
+export type {
+ ConfigSchema,
+ ConfigSchemaProcessingOptions,
+ ConfigVisibility,
+ EnvFunc,
+ LoadConfigSchemaOptions,
+ TransformFunc,
+} from './lib';
export { loadConfig } from './loader';
export type { LoadConfigOptions } from './loader';
diff --git a/packages/config-loader/src/lib/env.ts b/packages/config-loader/src/lib/env.ts
index 7d28e6b6ef..b244c06c64 100644
--- a/packages/config-loader/src/lib/env.ts
+++ b/packages/config-loader/src/lib/env.ts
@@ -38,6 +38,8 @@ const CONFIG_KEY_PART_PATTERN = /^[a-z][a-z0-9]*(?:[-_][a-z][a-z0-9]*)*$/i;
* For example, to set the config app.title to "My Title", use the following:
*
* APP_CONFIG_app_title='"My Title"'
+ *
+ * @public
*/
export function readEnvConfig(env: {
[name: string]: string | undefined;
diff --git a/packages/config-loader/src/lib/schema/compile.ts b/packages/config-loader/src/lib/schema/compile.ts
index 4236fd2d17..a36d2eb9a2 100644
--- a/packages/config-loader/src/lib/schema/compile.ts
+++ b/packages/config-loader/src/lib/schema/compile.ts
@@ -108,6 +108,8 @@ export function compileConfigSchemas(
/**
* Given a list of configuration schemas from packages, merge them
* into a single json schema.
+ *
+ * @public
*/
export function mergeConfigSchemas(schemas: JSONSchema[]): JSONSchema {
const merged = mergeAllOf(
diff --git a/packages/config-loader/src/lib/schema/index.ts b/packages/config-loader/src/lib/schema/index.ts
index 851be36f84..1dcb9d7b4b 100644
--- a/packages/config-loader/src/lib/schema/index.ts
+++ b/packages/config-loader/src/lib/schema/index.ts
@@ -16,4 +16,10 @@
export { mergeConfigSchemas } from './compile';
export { loadConfigSchema } from './load';
-export type { ConfigSchema, ConfigVisibility } from './types';
+export type { LoadConfigSchemaOptions } from './load';
+export type {
+ ConfigSchema,
+ ConfigVisibility,
+ ConfigSchemaProcessingOptions,
+ TransformFunc,
+} from './types';
diff --git a/packages/config-loader/src/lib/schema/load.ts b/packages/config-loader/src/lib/schema/load.ts
index b67bd0002f..4620961310 100644
--- a/packages/config-loader/src/lib/schema/load.ts
+++ b/packages/config-loader/src/lib/schema/load.ts
@@ -24,7 +24,8 @@ import {
CONFIG_VISIBILITIES,
} from './types';
-type Options =
+/** @public */
+export type LoadConfigSchemaOptions =
| {
dependencies: string[];
}
@@ -34,9 +35,11 @@ type Options =
/**
* Loads config schema for a Backstage instance.
+ *
+ * @public
*/
export async function loadConfigSchema(
- options: Options,
+ options: LoadConfigSchemaOptions,
): Promise {
let schemas: ConfigSchemaPackageEntry[];
diff --git a/packages/config-loader/src/lib/schema/types.ts b/packages/config-loader/src/lib/schema/types.ts
index 17090ad53c..ef6a197f55 100644
--- a/packages/config-loader/src/lib/schema/types.ts
+++ b/packages/config-loader/src/lib/schema/types.ts
@@ -37,8 +37,10 @@ export const CONFIG_VISIBILITIES = ['frontend', 'backend', 'secret'] as const;
/**
* A type representing the possible configuration value visibilities
+ *
+ * @public
*/
-export type ConfigVisibility = typeof CONFIG_VISIBILITIES[number];
+export type ConfigVisibility = 'frontend' | 'backend' | 'secret';
/**
* The default configuration visibility if no other values is given.
@@ -73,6 +75,8 @@ export type ValidationFunc = (configs: AppConfig[]) => ValidationResult;
/**
* A function used to transform primitive configuration values.
+ *
+ * @public
*/
export type TransformFunc = (
value: T,
@@ -81,8 +85,10 @@ export type TransformFunc = (
/**
* Options used to process configuration data with a schema.
+ *
+ * @public
*/
-type ConfigProcessingOptions = {
+export type ConfigSchemaProcessingOptions = {
/**
* The visibilities that should be included in the output data.
* If omitted, the data will not be filtered by visibility.
@@ -107,11 +113,13 @@ type ConfigProcessingOptions = {
/**
* A loaded configuration schema that is ready to process configuration data.
+ *
+ * @public
*/
export type ConfigSchema = {
process(
appConfigs: AppConfig[],
- options?: ConfigProcessingOptions,
+ options?: ConfigSchemaProcessingOptions,
): AppConfig[];
serialize(): JsonObject;
diff --git a/packages/config-loader/src/lib/transform/index.ts b/packages/config-loader/src/lib/transform/index.ts
index 5053cd7443..eaa85cca3c 100644
--- a/packages/config-loader/src/lib/transform/index.ts
+++ b/packages/config-loader/src/lib/transform/index.ts
@@ -17,3 +17,4 @@
export { applyConfigTransforms } from './apply';
export { createIncludeTransform } from './include';
export { createSubstitutionTransform } from './substitution';
+export type { EnvFunc } from './types';
diff --git a/packages/config-loader/src/lib/transform/types.ts b/packages/config-loader/src/lib/transform/types.ts
index 20e5f88718..afd3550984 100644
--- a/packages/config-loader/src/lib/transform/types.ts
+++ b/packages/config-loader/src/lib/transform/types.ts
@@ -16,6 +16,7 @@
import { JsonValue } from '@backstage/config';
+/** @public */
export type EnvFunc = (name: string) => Promise;
export type ReadFileFunc = (path: string) => Promise;
diff --git a/packages/config-loader/src/loader.ts b/packages/config-loader/src/loader.ts
index 4dbfc007a7..315b44c4ee 100644
--- a/packages/config-loader/src/loader.ts
+++ b/packages/config-loader/src/loader.ts
@@ -27,6 +27,7 @@ import {
} from './lib';
import { EnvFunc } from './lib/transform/types';
+/** @public */
export type LoadConfigOptions = {
// The root directory of the config loading context. Used to find default configs.
configRoot: string;
@@ -60,6 +61,11 @@ export type LoadConfigOptions = {
};
};
+/**
+ * Load configuration data.
+ *
+ * @public
+ */
export async function loadConfig(
options: LoadConfigOptions,
): Promise {
diff --git a/packages/config/api-report.md b/packages/config/api-report.md
index 91f37894c0..068498b17a 100644
--- a/packages/config/api-report.md
+++ b/packages/config/api-report.md
@@ -3,18 +3,14 @@
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
```ts
-// Warning: (ae-missing-release-tag) "AppConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public (undocumented)
+// @public
export type AppConfig = {
context: string;
data: JsonObject;
filteredKeys?: string[];
};
-// Warning: (ae-missing-release-tag) "Config" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public (undocumented)
+// @public
export type Config = {
subscribe?(onChange: () => void): {
unsubscribe: () => void;
@@ -37,9 +33,7 @@ export type Config = {
getOptionalStringArray(key: string): string[] | undefined;
};
-// Warning: (ae-missing-release-tag) "ConfigReader" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public (undocumented)
+// @public
export class ConfigReader implements Config {
constructor(
data: JsonObject | undefined,
@@ -83,26 +77,18 @@ export class ConfigReader implements Config {
keys(): string[];
}
-// Warning: (ae-missing-release-tag) "JsonArray" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public (undocumented)
+// @public
export interface JsonArray extends Array {}
-// Warning: (ae-missing-release-tag) "JsonObject" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public (undocumented)
+// @public
export type JsonObject = {
[key in string]?: JsonValue;
};
-// Warning: (ae-missing-release-tag) "JsonPrimitive" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public (undocumented)
+// @public
export type JsonPrimitive = number | string | boolean | null;
-// Warning: (ae-missing-release-tag) "JsonValue" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public (undocumented)
+// @public
export type JsonValue = JsonObject | JsonArray | JsonPrimitive;
// (No @packageDocumentation comment for this package)
diff --git a/packages/config/src/reader.ts b/packages/config/src/reader.ts
index c6f69e5b29..92ca0eede3 100644
--- a/packages/config/src/reader.ts
+++ b/packages/config/src/reader.ts
@@ -54,6 +54,12 @@ const errors = {
},
};
+/**
+ * An implementation of the `Config` interface that uses a plain JavaScript object
+ * for the backing data, with the ability of linking multiple readers together.
+ *
+ * @public
+ */
export class ConfigReader implements Config {
/**
* A set of key paths that where removed from the config due to not being visible.
diff --git a/packages/config/src/types.ts b/packages/config/src/types.ts
index 84de5dae70..d5f551cd69 100644
--- a/packages/config/src/types.ts
+++ b/packages/config/src/types.ts
@@ -14,17 +14,61 @@
* limitations under the License.
*/
+/**
+ * A type representing all allowed JSON primitive values.
+ *
+ * @public
+ */
export type JsonPrimitive = number | string | boolean | null;
+
+/**
+ * A type representing all allowed JSON object values.
+ *
+ * @public
+ */
export type JsonObject = { [key in string]?: JsonValue };
+
+/**
+ * A type representing all allowed JSON array values.
+ *
+ * @public
+ */
export interface JsonArray extends Array {}
+
+/**
+ * A type representing all allowed JSON values.
+ *
+ * @public
+ */
export type JsonValue = JsonObject | JsonArray | JsonPrimitive;
+/**
+ * A serialized form of configuration data that carries additional context.
+ *
+ * @public
+ */
export type AppConfig = {
+ /**
+ * A string representing the source of this configuration data, for example a filepath.
+ */
context: string;
+ /**
+ * The configuration data itself.
+ */
data: JsonObject;
+ /**
+ * A list of keys that where filtered out from the configuration when it was loaded.
+ *
+ * This can be used to warn the user if they try to read any of these keys.
+ */
filteredKeys?: string[];
};
+/**
+ * The interface used to represent static configuration at runtime.
+ *
+ * @public
+ */
export type Config = {
/**
* Subscribes to the configuration object in order to receive a notification
@@ -37,28 +81,90 @@ export type Config = {
unsubscribe: () => void;
};
+ /**
+ * Checks whether the given key is present.
+ */
has(key: string): boolean;
+ /**
+ * Lists all available configuration keys.
+ */
keys(): string[];
+ /**
+ * Same as `getOptional`, but will throw an error if there's no value for the given key.
+ */
get(key?: string): T;
+
+ /**
+ * Read out all configuration data for the given key.
+ *
+ * Usage of this method should be avoided as the typed alternatives provide
+ * much better error reporting. The main use-case of this method is to determine
+ * the type of a configuration value in the case where there are multiple possible
+ * shapes of the configuration.
+ */
getOptional(key?: string): T | undefined;
+ /**
+ * Same as `getOptionalConfig`, but will throw an error if there's no value for the given key.
+ */
getConfig(key: string): Config;
+
+ /**
+ * Creates a sub-view of the configuration object.
+ * The configuration value at the position of the provided key must be an object.
+ */
getOptionalConfig(key: string): Config | undefined;
+ /**
+ * Same as `getOptionalConfigArray`, but will throw an error if there's no value for the given key.
+ */
getConfigArray(key: string): Config[];
+
+ /**
+ * Creates a sub-view of an array of configuration objects.
+ * The configuration value at the position of the provided key must be an array of objects.
+ */
getOptionalConfigArray(key: string): Config[] | undefined;
+ /**
+ * Same as `getOptionalNumber`, but will throw an error if there's no value for the given key.
+ */
getNumber(key: string): number;
+
+ /**
+ * Reads a configuration value at the given key, expecting it to be a number.
+ */
getOptionalNumber(key: string): number | undefined;
+ /**
+ * Same as `getOptionalBoolean`, but will throw an error if there's no value for the given key.
+ */
getBoolean(key: string): boolean;
+
+ /**
+ * Reads a configuration value at the given key, expecting it to be a boolean.
+ */
getOptionalBoolean(key: string): boolean | undefined;
+ /**
+ * Same as `getOptionalString`, but will throw an error if there's no value for the given key.
+ */
getString(key: string): string;
+
+ /**
+ * Reads a configuration value at the given key, expecting it to be a string.
+ */
getOptionalString(key: string): string | undefined;
+ /**
+ * Same as `getOptionalStringArray`, but will throw an error if there's no value for the given key.
+ */
getStringArray(key: string): string[];
+
+ /**
+ * Reads a configuration value at the given key, expecting it to be an array of strings.
+ */
getOptionalStringArray(key: string): string[] | undefined;
};
diff --git a/packages/core-components/src/layout/BottomLink/BottomLink.tsx b/packages/core-components/src/layout/BottomLink/BottomLink.tsx
index fdc64a9b90..74912acf4c 100644
--- a/packages/core-components/src/layout/BottomLink/BottomLink.tsx
+++ b/packages/core-components/src/layout/BottomLink/BottomLink.tsx
@@ -49,11 +49,11 @@ export const BottomLink = ({ link, title, onClick }: BottomLinkProps) => {
-
-
- {title}
-
-
+
+
+ {title}
+
+
diff --git a/packages/dev-utils/api-report.md b/packages/dev-utils/api-report.md
index 5f58b297d5..8d54d8f98d 100644
--- a/packages/dev-utils/api-report.md
+++ b/packages/dev-utils/api-report.md
@@ -7,21 +7,42 @@
import { ApiFactory } from '@backstage/core-plugin-api';
import { AppTheme } from '@backstage/core-plugin-api';
+import { BackstagePlugin } from '@backstage/core-plugin-api';
import { ComponentType } from 'react';
-import { createPlugin } from '@backstage/core-plugin-api';
import { Entity } from '@backstage/catalog-model';
import { GridProps } from '@material-ui/core';
import { IconComponent } from '@backstage/core-plugin-api';
import { ReactNode } from 'react';
-// Warning: (ae-forgotten-export) The symbol "DevAppBuilder" needs to be exported by the entry point index.d.ts
-// Warning: (ae-missing-release-tag) "createDevApp" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export function createDevApp(): DevAppBuilder;
-// Warning: (ae-missing-release-tag) "EntityGridItem" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
+// @public
+export class DevAppBuilder {
+ addPage(opts: DevAppPageOptions): DevAppBuilder;
+ addRootChild(node: ReactNode): DevAppBuilder;
+ addThemes(themes: AppTheme[]): this;
+ build(): ComponentType<{}>;
+ registerApi<
+ Api,
+ Impl extends Api,
+ Deps extends {
+ [name in string]: unknown;
+ },
+ >(factory: ApiFactory): DevAppBuilder;
+ registerPlugin(...plugins: BackstagePlugin[]): DevAppBuilder;
+ render(): void;
+}
+
+// @public (undocumented)
+export type DevAppPageOptions = {
+ path?: string;
+ element: JSX.Element;
+ children?: JSX.Element;
+ title?: string;
+ icon?: IconComponent;
+};
+
// @public (undocumented)
export const EntityGridItem: ({
entity,
diff --git a/packages/dev-utils/src/components/EntityGridItem/EntityGridItem.tsx b/packages/dev-utils/src/components/EntityGridItem/EntityGridItem.tsx
index 30288fe7bb..55327f35e5 100644
--- a/packages/dev-utils/src/components/EntityGridItem/EntityGridItem.tsx
+++ b/packages/dev-utils/src/components/EntityGridItem/EntityGridItem.tsx
@@ -34,6 +34,7 @@ const useStyles = makeStyles(theme => ({
}),
}));
+/** @public */
export const EntityGridItem = ({
entity,
classes,
diff --git a/packages/dev-utils/src/devApp/index.tsx b/packages/dev-utils/src/devApp/index.tsx
index d72b4757c8..69394007d2 100644
--- a/packages/dev-utils/src/devApp/index.tsx
+++ b/packages/dev-utils/src/devApp/index.tsx
@@ -14,4 +14,5 @@
* limitations under the License.
*/
-export * from './render';
+export { createDevApp } from './render';
+export type { DevAppBuilder, DevAppPageOptions } from './render';
diff --git a/packages/dev-utils/src/devApp/render.tsx b/packages/dev-utils/src/devApp/render.tsx
index 38cc0befe1..755289a060 100644
--- a/packages/dev-utils/src/devApp/render.tsx
+++ b/packages/dev-utils/src/devApp/render.tsx
@@ -41,10 +41,10 @@ import {
attachComponentData,
configApiRef,
createApiFactory,
- createPlugin,
createRouteRef,
IconComponent,
RouteRef,
+ BackstagePlugin,
} from '@backstage/core-plugin-api';
import { createApp, FlatRoutes } from '@backstage/core-app-api';
@@ -57,7 +57,8 @@ const GatheringRoute: (props: {
attachComponentData(GatheringRoute, 'core.gatherMountPoints', true);
-type RegisterPageOptions = {
+/** @public */
+export type DevAppPageOptions = {
path?: string;
element: JSX.Element;
children?: JSX.Element;
@@ -65,14 +66,13 @@ type RegisterPageOptions = {
icon?: IconComponent;
};
-// TODO(rugvip): export proper plugin type from core that isn't the plugin class
-type BackstagePlugin = ReturnType;
-
/**
* DevApp builder that is similar to the App builder API, but creates an App
* with the purpose of developing one or more plugins inside it.
+ *
+ * @public
*/
-class DevAppBuilder {
+export class DevAppBuilder {
private readonly plugins = new Array();
private readonly apis = new Array();
private readonly rootChildren = new Array();
@@ -118,7 +118,7 @@ class DevAppBuilder {
* If no path is provided one will be generated.
* If no title is provided, no sidebar item will be created.
*/
- addPage(opts: RegisterPageOptions): DevAppBuilder {
+ addPage(opts: DevAppPageOptions): DevAppBuilder {
const path = opts.path ?? `/page-${this.routes.length + 1}`;
if (!this.defaultPage || path === '/') {
@@ -244,6 +244,8 @@ class DevAppBuilder {
/**
* Creates a dev app for rendering one or more plugins and exposing the touch points of the plugin.
+ *
+ * @public
*/
export function createDevApp() {
return new DevAppBuilder();
diff --git a/packages/errors/api-report.md b/packages/errors/api-report.md
index 6aa69592b7..019b6dd387 100644
--- a/packages/errors/api-report.md
+++ b/packages/errors/api-report.md
@@ -5,18 +5,12 @@
```ts
import { JsonObject } from '@backstage/config';
-// Warning: (ae-missing-release-tag) "AuthenticationError" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export class AuthenticationError extends CustomErrorBase {}
-// Warning: (ae-missing-release-tag) "ConflictError" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export class ConflictError extends CustomErrorBase {}
-// Warning: (ae-missing-release-tag) "CustomErrorBase" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public (undocumented)
export class CustomErrorBase extends Error {
constructor(message?: string, cause?: Error);
@@ -24,15 +18,11 @@ export class CustomErrorBase extends Error {
readonly cause?: Error;
}
-// Warning: (ae-missing-release-tag) "deserializeError" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export function deserializeError(
data: SerializedError,
): T;
-// Warning: (ae-missing-release-tag) "ErrorResponse" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export type ErrorResponse = {
error: SerializedError;
@@ -45,34 +35,21 @@ export type ErrorResponse = {
};
};
-// Warning: (ae-missing-release-tag) "InputError" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export class InputError extends CustomErrorBase {}
-// Warning: (ae-missing-release-tag) "NotAllowedError" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export class NotAllowedError extends CustomErrorBase {}
-// Warning: (ae-missing-release-tag) "NotFoundError" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export class NotFoundError extends CustomErrorBase {}
-// Warning: (ae-missing-release-tag) "NotModifiedError" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export class NotModifiedError extends CustomErrorBase {}
-// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
-// Warning: (ae-missing-release-tag) "parseErrorResponse" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export function parseErrorResponse(response: Response): Promise;
-// Warning: (ae-missing-release-tag) "ResponseError" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export class ResponseError extends Error {
constructor(props: {
@@ -87,8 +64,6 @@ export class ResponseError extends Error {
readonly response: Response;
}
-// Warning: (ae-missing-release-tag) "SerializedError" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export type SerializedError = JsonObject & {
name: string;
@@ -97,10 +72,6 @@ export type SerializedError = JsonObject & {
code?: string;
};
-// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
-// Warning: (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters
-// Warning: (ae-missing-release-tag) "serializeError" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export function serializeError(
error: Error,
diff --git a/packages/errors/src/errors/CustomErrorBase.ts b/packages/errors/src/errors/CustomErrorBase.ts
index fc374287c7..a392135c13 100644
--- a/packages/errors/src/errors/CustomErrorBase.ts
+++ b/packages/errors/src/errors/CustomErrorBase.ts
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+/** @public */
export class CustomErrorBase extends Error {
readonly cause?: Error;
diff --git a/packages/errors/src/errors/ResponseError.ts b/packages/errors/src/errors/ResponseError.ts
index c8927a447c..f74ad2fa0c 100644
--- a/packages/errors/src/errors/ResponseError.ts
+++ b/packages/errors/src/errors/ResponseError.ts
@@ -24,6 +24,8 @@ import {
* An error thrown as the result of a failed server request.
*
* The server is expected to respond on the ErrorResponse format.
+ *
+ * @public
*/
export class ResponseError extends Error {
/**
diff --git a/packages/errors/src/errors/common.ts b/packages/errors/src/errors/common.ts
index 51c82eeda5..dad236d4b5 100644
--- a/packages/errors/src/errors/common.ts
+++ b/packages/errors/src/errors/common.ts
@@ -29,16 +29,22 @@ import { CustomErrorBase } from './CustomErrorBase';
/**
* The given inputs are malformed and cannot be processed.
+ *
+ * @public
*/
export class InputError extends CustomErrorBase {}
/**
* The request requires authentication, which was not properly supplied.
+ *
+ * @public
*/
export class AuthenticationError extends CustomErrorBase {}
/**
* The authenticated caller is not allowed to perform this request.
+ *
+ * @public
*/
export class NotAllowedError extends CustomErrorBase {}
@@ -47,16 +53,22 @@ export class NotAllowedError extends CustomErrorBase {}
*
* Note that this error usually is used to indicate that an entity with a given
* ID does not exist, rather than signalling that an entire route is missing.
+ *
+ * @public
*/
export class NotFoundError extends CustomErrorBase {}
/**
* The request could not complete due to a conflict in the current state of the
* resource.
+ *
+ * @public
*/
export class ConflictError extends CustomErrorBase {}
/**
* The requested resource has not changed since last request.
+ *
+ * @public
*/
export class NotModifiedError extends CustomErrorBase {}
diff --git a/packages/errors/src/serialization/error.ts b/packages/errors/src/serialization/error.ts
index 46a2c2f74c..ab543164d8 100644
--- a/packages/errors/src/serialization/error.ts
+++ b/packages/errors/src/serialization/error.ts
@@ -22,6 +22,8 @@ import {
/**
* The serialized form of an Error.
+ *
+ * @public
*/
export type SerializedError = JsonObject & {
/** The name of the exception that was thrown */
@@ -37,12 +39,16 @@ export type SerializedError = JsonObject & {
/**
* Serializes an error object to a JSON friendly form.
*
- * @param error The error
- * @param options.includeStackTraces: Include stack trace in the output (default false)
+ * @public
+ * @param error - The error.
+ * @param options - Optional serialization options.
*/
export function serializeError(
error: Error,
- options?: { includeStack?: boolean },
+ options?: {
+ /** Include stack trace in the output (default false) */
+ includeStack?: boolean;
+ },
): SerializedError {
const serialized = serializeErrorInternal(error);
const result: SerializedError = {
@@ -60,6 +66,8 @@ export function serializeError(
/**
* Deserializes a serialized error object back to an Error.
+ *
+ * @public
*/
export function deserializeError(
data: SerializedError,
diff --git a/packages/errors/src/serialization/response.ts b/packages/errors/src/serialization/response.ts
index 0196b2d597..50bf8f7ab1 100644
--- a/packages/errors/src/serialization/response.ts
+++ b/packages/errors/src/serialization/response.ts
@@ -18,6 +18,8 @@ import { SerializedError } from './error';
/**
* A standard shape of JSON data returned as the body of backend errors.
+ *
+ * @public
*/
export type ErrorResponse = {
/** Details of the error that was caught */
@@ -47,7 +49,8 @@ export type ErrorResponse = {
* The code is forgiving, and constructs a useful synthetic body as best it can
* if the response body wasn't on the expected form.
*
- * @param response The response of a failed request
+ * @public
+ * @param response - The response of a failed request
*/
export async function parseErrorResponse(
response: Response,
diff --git a/plugins/catalog-backend/src/ingestion/processors/PlaceholderProcessor.test.ts b/plugins/catalog-backend/src/ingestion/processors/PlaceholderProcessor.test.ts
index 0254e854e5..c60b01d53d 100644
--- a/plugins/catalog-backend/src/ingestion/processors/PlaceholderProcessor.test.ts
+++ b/plugins/catalog-backend/src/ingestion/processors/PlaceholderProcessor.test.ts
@@ -15,6 +15,8 @@
*/
import { UrlReader } from '@backstage/backend-common';
import { Entity } from '@backstage/catalog-model';
+import { ConfigReader } from '@backstage/config';
+import { ScmIntegrations } from '@backstage/integration';
import {
jsonPlaceholderResolver,
PlaceholderProcessor,
@@ -25,6 +27,8 @@ import {
yamlPlaceholderResolver,
} from './PlaceholderProcessor';
+const integrations = ScmIntegrations.fromConfig(new ConfigReader({}));
+
describe('PlaceholderProcessor', () => {
const read: jest.MockedFunction = jest.fn();
const reader: UrlReader = { read, readTree: jest.fn(), search: jest.fn() };
@@ -44,6 +48,7 @@ describe('PlaceholderProcessor', () => {
foo: async () => 'replaced',
},
reader,
+ integrations,
});
await expect(
processor.preProcessEntity(input, { type: 't', target: 'l' }),
@@ -59,6 +64,7 @@ describe('PlaceholderProcessor', () => {
upper: upperResolver,
},
reader,
+ integrations,
});
await expect(
@@ -95,6 +101,7 @@ describe('PlaceholderProcessor', () => {
bar: jest.fn(),
},
reader,
+ integrations,
});
const entity: Entity = {
apiVersion: 'a',
@@ -115,6 +122,7 @@ describe('PlaceholderProcessor', () => {
bar: jest.fn(),
},
reader,
+ integrations,
});
const entity: Entity = {
apiVersion: 'a',
@@ -134,6 +142,7 @@ describe('PlaceholderProcessor', () => {
const processor = new PlaceholderProcessor({
resolvers: { text: textPlaceholderResolver },
reader,
+ integrations,
});
await expect(
@@ -169,6 +178,7 @@ describe('PlaceholderProcessor', () => {
const processor = new PlaceholderProcessor({
resolvers: { json: jsonPlaceholderResolver },
reader,
+ integrations,
});
await expect(
@@ -202,6 +212,7 @@ describe('PlaceholderProcessor', () => {
const processor = new PlaceholderProcessor({
resolvers: { yaml: yamlPlaceholderResolver },
reader,
+ integrations,
});
await expect(
@@ -235,6 +246,7 @@ describe('PlaceholderProcessor', () => {
const processor = new PlaceholderProcessor({
resolvers: { text: textPlaceholderResolver },
reader,
+ integrations,
});
await expect(
@@ -272,6 +284,7 @@ describe('PlaceholderProcessor', () => {
const processor = new PlaceholderProcessor({
resolvers: { text: textPlaceholderResolver },
reader,
+ integrations,
});
await expect(
@@ -311,6 +324,7 @@ describe('PlaceholderProcessor', () => {
const processor = new PlaceholderProcessor({
resolvers: { text: textPlaceholderResolver },
reader,
+ integrations,
});
await expect(
@@ -331,7 +345,7 @@ describe('PlaceholderProcessor', () => {
},
),
).rejects.toThrow(
- 'Placeholder $text could not form a URL out of ./a/b/catalog-info.yaml and ../c/catalog-info.yaml',
+ 'Placeholder $text could not form a URL out of ./a/b/catalog-info.yaml and ../c/catalog-info.yaml, TypeError: Invalid base URL: ./a/b/catalog-info.yaml',
);
expect(read).not.toBeCalled();
@@ -345,6 +359,7 @@ describe('yamlPlaceholderResolver', () => {
value: './file.yaml',
baseUrl: 'https://github.com/backstage/backstage/a/b/catalog-info.yaml',
read,
+ resolveUrl: (url, base) => integrations.resolveUrl({ url, base }),
};
beforeEach(() => {
@@ -389,6 +404,7 @@ describe('jsonPlaceholderResolver', () => {
value: './file.json',
baseUrl: 'https://github.com/backstage/backstage/a/b/catalog-info.yaml',
read,
+ resolveUrl: (url, base) => integrations.resolveUrl({ url, base }),
};
beforeEach(() => {
diff --git a/plugins/catalog-backend/src/ingestion/processors/PlaceholderProcessor.ts b/plugins/catalog-backend/src/ingestion/processors/PlaceholderProcessor.ts
index 1b015d7d93..611e166605 100644
--- a/plugins/catalog-backend/src/ingestion/processors/PlaceholderProcessor.ts
+++ b/plugins/catalog-backend/src/ingestion/processors/PlaceholderProcessor.ts
@@ -17,16 +17,19 @@
import { UrlReader } from '@backstage/backend-common';
import { Entity, LocationSpec } from '@backstage/catalog-model';
import { JsonValue } from '@backstage/config';
+import { ScmIntegrationRegistry } from '@backstage/integration';
import yaml from 'yaml';
import { CatalogProcessor } from './types';
export type ResolverRead = (url: string) => Promise;
+export type ResolverResolveUrl = (url: string, base: string) => string;
export type ResolverParams = {
key: string;
value: JsonValue;
baseUrl: string;
read: ResolverRead;
+ resolveUrl: ResolverResolveUrl;
};
export type PlaceholderResolver = (
@@ -36,6 +39,7 @@ export type PlaceholderResolver = (
type Options = {
resolvers: Record;
reader: UrlReader;
+ integrations: ScmIntegrationRegistry;
};
/**
@@ -103,12 +107,19 @@ export class PlaceholderProcessor implements CatalogProcessor {
return this.options.reader.read(url);
};
+ const resolveUrl = (url: string, base: string): string =>
+ this.options.integrations.resolveUrl({
+ url,
+ base,
+ });
+
return [
await resolver({
key: resolverKey,
value: resolverValue,
baseUrl: location.target,
read,
+ resolveUrl,
}),
true,
];
@@ -191,31 +202,27 @@ async function readTextLocation(params: ResolverParams): Promise {
}
}
-function relativeUrl({ key, value, baseUrl }: ResolverParams): string {
+function relativeUrl({
+ key,
+ value,
+ baseUrl,
+ resolveUrl,
+}: ResolverParams): string {
if (typeof value !== 'string') {
throw new Error(
`Placeholder \$${key} expected a string value parameter, in the form of an absolute URL or a relative path`,
);
}
- let url: URL;
try {
- // The two-value form of the URL constructor handles relative paths for us
- url = new URL(value, baseUrl);
- } catch {
- try {
- // Check whether value is a valid absolute URL on it's own, if not fail.
- url = new URL(value);
- } catch {
- // The only remaining case that isn't support is a relative file path that should be
- // resolved using a relative file location. Accessing local file paths can lead to
- // path traversal attacks and access to any file on the host system. Implementing this
- // would require additional security measures.
- throw new Error(
- `Placeholder \$${key} could not form a URL out of ${baseUrl} and ${value}`,
- );
- }
+ return resolveUrl(value, baseUrl);
+ } catch (e) {
+ // The only remaining case that isn't support is a relative file path that should be
+ // resolved using a relative file location. Accessing local file paths can lead to
+ // path traversal attacks and access to any file on the host system. Implementing this
+ // would require additional security measures.
+ throw new Error(
+ `Placeholder \$${key} could not form a URL out of ${baseUrl} and ${value}, ${e}`,
+ );
}
-
- return url.toString();
}
diff --git a/plugins/catalog-backend/src/next/NextCatalogBuilder.ts b/plugins/catalog-backend/src/next/NextCatalogBuilder.ts
index ed690d07b6..262df7525e 100644
--- a/plugins/catalog-backend/src/next/NextCatalogBuilder.ts
+++ b/plugins/catalog-backend/src/next/NextCatalogBuilder.ts
@@ -385,7 +385,11 @@ export class NextCatalogBuilder {
// These are always there no matter what
const processors: CatalogProcessor[] = [
- new PlaceholderProcessor({ resolvers: placeholderResolvers, reader }),
+ new PlaceholderProcessor({
+ resolvers: placeholderResolvers,
+ reader,
+ integrations,
+ }),
new BuiltinKindsEntityProcessor(),
];
diff --git a/plugins/catalog-backend/src/service/CatalogBuilder.ts b/plugins/catalog-backend/src/service/CatalogBuilder.ts
index 70c1890fbf..e32e071ebc 100644
--- a/plugins/catalog-backend/src/service/CatalogBuilder.ts
+++ b/plugins/catalog-backend/src/service/CatalogBuilder.ts
@@ -306,7 +306,11 @@ export class CatalogBuilder {
// These are always there no matter what
const processors: CatalogProcessor[] = [
StaticLocationProcessor.fromConfig(config),
- new PlaceholderProcessor({ resolvers: placeholderResolvers, reader }),
+ new PlaceholderProcessor({
+ resolvers: placeholderResolvers,
+ reader,
+ integrations,
+ }),
new BuiltinKindsEntityProcessor(),
];
diff --git a/plugins/home/api-report.md b/plugins/home/api-report.md
index a2350b803b..66b6e55306 100644
--- a/plugins/home/api-report.md
+++ b/plugins/home/api-report.md
@@ -84,6 +84,19 @@ export const HomepageCompositionRoot: (props: {
children?: ReactNode;
}) => JSX.Element;
+// Warning: (ae-missing-release-tag) "HomePageRandomJoke" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
+//
+// @public (undocumented)
+export const HomePageRandomJoke: ({
+ Renderer,
+ title: overrideTitle,
+ ...childProps
+}: ComponentRenderer & {
+ title?: string | undefined;
+} & {
+ defaultCategory?: 'any' | 'programming' | undefined;
+}) => JSX.Element;
+
// Warning: (ae-missing-release-tag) "homePlugin" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
@@ -94,19 +107,6 @@ export const homePlugin: BackstagePlugin<
{}
>;
-// Warning: (ae-missing-release-tag) "RandomJokeHomePageComponent" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public (undocumented)
-export const RandomJokeHomePageComponent: ({
- Renderer,
- title: overrideTitle,
- ...childProps
-}: ComponentRenderer & {
- title?: string | undefined;
-} & {
- defaultCategory?: 'any' | 'programming' | undefined;
-}) => JSX.Element;
-
// Warning: (ae-missing-release-tag) "SettingsModal" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
diff --git a/plugins/home/src/index.ts b/plugins/home/src/index.ts
index 812e1b2495..0c7cc2c09f 100644
--- a/plugins/home/src/index.ts
+++ b/plugins/home/src/index.ts
@@ -17,7 +17,7 @@
export {
homePlugin,
HomepageCompositionRoot,
- RandomJokeHomePageComponent,
+ HomePageRandomJoke,
ComponentAccordion,
ComponentTabs,
ComponentTab,
diff --git a/plugins/home/src/plugin.ts b/plugins/home/src/plugin.ts
index 5600d2d315..46df84c1bf 100644
--- a/plugins/home/src/plugin.ts
+++ b/plugins/home/src/plugin.ts
@@ -60,7 +60,7 @@ export const ComponentTab = homePlugin.provide(
}),
);
-export const RandomJokeHomePageComponent = homePlugin.provide(
+export const HomePageRandomJoke = homePlugin.provide(
createCardExtension<{ defaultCategory?: 'any' | 'programming' }>({
title: 'Random Joke',
components: () => import('./homePageComponents/RandomJoke'),
diff --git a/plugins/org/src/components/Cards/OwnershipCard/OwnershipCard.tsx b/plugins/org/src/components/Cards/OwnershipCard/OwnershipCard.tsx
index da7f8381e3..96e7d08c31 100644
--- a/plugins/org/src/components/Cards/OwnershipCard/OwnershipCard.tsx
+++ b/plugins/org/src/components/Cards/OwnershipCard/OwnershipCard.tsx
@@ -18,6 +18,7 @@ import { Entity } from '@backstage/catalog-model';
import {
InfoCard,
InfoCardVariants,
+ Link,
Progress,
ResponseErrorPanel,
} from '@backstage/core-components';
@@ -29,18 +30,16 @@ import {
isOwnerOf,
useEntity,
} from '@backstage/plugin-catalog-react';
-import { BackstageTheme, genPageTheme } from '@backstage/theme';
+import { BackstageTheme } from '@backstage/theme';
import {
Box,
createStyles,
Grid,
- Link,
makeStyles,
Typography,
} from '@material-ui/core';
import qs from 'qs';
import React from 'react';
-import { generatePath } from 'react-router';
import { useAsync } from 'react-use';
type EntityTypeProps = {
@@ -49,16 +48,6 @@ type EntityTypeProps = {
count: number;
};
-const createPageTheme = (
- theme: BackstageTheme,
- shapeKey: string,
- colorsKey: string,
-) => {
- const { colors } = theme.getPageTheme({ themeId: colorsKey });
- const { shape } = theme.getPageTheme({ themeId: shapeKey });
- return genPageTheme(colors, shape).backgroundImage;
-};
-
const useStyles = makeStyles((theme: BackstageTheme) =>
createStyles({
card: {
@@ -77,7 +66,7 @@ const useStyles = makeStyles((theme: BackstageTheme) =>
},
entityTypeBox: {
background: (props: { type: string }) =>
- createPageTheme(theme, props.type, props.type),
+ theme.getPageTheme({ themeId: props.type }).backgroundImage,
},
}),
);
@@ -96,7 +85,7 @@ const EntityCountTile = ({
const classes = useStyles({ type });
return (
-
+
))}
diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json
index 93cee90937..902860679d 100644
--- a/plugins/scaffolder-backend/package.json
+++ b/plugins/scaffolder-backend/package.json
@@ -39,6 +39,7 @@
"@gitbeaker/core": "^30.2.0",
"@gitbeaker/node": "^30.2.0",
"@octokit/rest": "^18.5.3",
+ "@octokit/webhooks": "^9.14.1",
"@types/express": "^4.17.6",
"azure-devops-node-api": "^11.0.1",
"command-exists": "^1.2.9",
diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubWebhook.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubWebhook.test.ts
index 7d5da3e7b8..0da08bbf9d 100644
--- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubWebhook.test.ts
+++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubWebhook.test.ts
@@ -205,4 +205,62 @@ describe('github:repository:webhook:create', () => {
},
});
});
+
+ it('should validate input', async () => {
+ const Validator = require('jsonschema').Validator;
+ const v = new Validator();
+
+ // validate default input without events specified
+ expect(v.validate(mockContext.input, action.schema?.input).valid).toBe(
+ true,
+ );
+
+ const inputWithValidEvent = {
+ ...mockContext.input,
+ events: ['push'],
+ };
+ expect(v.validate(inputWithValidEvent, action.schema?.input).valid).toBe(
+ true,
+ );
+
+ const inputWithMultipleValidEvents = {
+ ...mockContext.input,
+ events: ['push', 'pull_request'],
+ };
+ expect(
+ v.validate(inputWithMultipleValidEvents, action.schema?.input).valid,
+ ).toBe(true);
+
+ const inputWithInvalidEvent = {
+ ...mockContext.input,
+ events: ['unexpected_event'],
+ };
+ expect(v.validate(inputWithInvalidEvent, action.schema?.input).valid).toBe(
+ false,
+ );
+
+ const inputWithOneInvalidEvent = {
+ ...mockContext.input,
+ events: ['push', 'unexpected_event'],
+ };
+ expect(
+ v.validate(inputWithOneInvalidEvent, action.schema?.input).valid,
+ ).toBe(false);
+
+ const inputWithAllEvents = {
+ ...mockContext.input,
+ events: ['*'],
+ };
+ expect(v.validate(inputWithAllEvents, action.schema?.input).valid).toBe(
+ true,
+ );
+
+ const inputWithAllEventsAndMore = {
+ ...mockContext.input,
+ events: ['*', 'push'],
+ };
+ expect(
+ v.validate(inputWithAllEventsAndMore, action.schema?.input).valid,
+ ).toBe(false);
+ });
});
diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubWebhook.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubWebhook.ts
index 9aefc37034..6d8324768e 100644
--- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubWebhook.ts
+++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubWebhook.ts
@@ -16,6 +16,7 @@
import { ScmIntegrationRegistry } from '@backstage/integration';
import { createTemplateAction } from '../../createTemplateAction';
import { OctokitProvider } from './OctokitProvider';
+import { emitterEventNames } from '@octokit/webhooks';
type ContentType = 'form' | 'json';
@@ -25,6 +26,7 @@ export function createGithubWebhookAction(options: {
}) {
const { integrations, defaultWebhookSecret } = options;
const octokitProvider = new OctokitProvider(integrations);
+ const eventNames = emitterEventNames.filter(event => !event.includes('.'));
return createTemplateAction<{
repoUrl: string;
@@ -63,9 +65,20 @@ export function createGithubWebhookAction(options: {
description:
'Determines what events the hook is triggered for. Default: push',
type: 'array',
- items: {
- type: 'string',
- },
+ oneOf: [
+ {
+ items: {
+ type: 'string',
+ enum: eventNames,
+ },
+ },
+ {
+ items: {
+ type: 'string',
+ const: '*',
+ },
+ },
+ ],
},
active: {
title: 'Active',
diff --git a/plugins/scaffolder/src/api.ts b/plugins/scaffolder/src/api.ts
index 37d78d0fda..3e0ac3eccb 100644
--- a/plugins/scaffolder/src/api.ts
+++ b/plugins/scaffolder/src/api.ts
@@ -136,7 +136,7 @@ export class ScaffolderClient implements ScaffolderApi {
});
if (!response.ok) {
- throw ResponseError.fromResponse(response);
+ throw await ResponseError.fromResponse(response);
}
const schema: TemplateParameterSchema = await response.json();
diff --git a/plugins/search/api-report.md b/plugins/search/api-report.md
index 03c24609e2..bdb2ab2a54 100644
--- a/plugins/search/api-report.md
+++ b/plugins/search/api-report.md
@@ -55,6 +55,15 @@ export type FiltersState = {
checked: Array;
};
+// Warning: (ae-missing-release-tag) "HomePageSearchBar" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
+//
+// @public (undocumented)
+export const HomePageSearchBar: ({
+ placeholder,
+}: {
+ placeholder?: string | undefined;
+}) => JSX.Element;
+
// Warning: (ae-missing-release-tag) "SearchPage" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
diff --git a/plugins/search/src/components/HomePageComponent/HomePageSearchBar.tsx b/plugins/search/src/components/HomePageComponent/HomePageSearchBar.tsx
new file mode 100644
index 0000000000..94c72df3a8
--- /dev/null
+++ b/plugins/search/src/components/HomePageComponent/HomePageSearchBar.tsx
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2021 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import React from 'react';
+import { makeStyles } from '@material-ui/core/styles';
+
+import { SearchBarBase } from '../SearchBar';
+import { useNavigateToQuery } from '../util';
+
+const useStyles = makeStyles({
+ searchBar: {
+ border: '1px solid #555',
+ borderRadius: '6px',
+ fontSize: '1.5em',
+ },
+});
+
+type Props = {
+ placeholder?: string;
+};
+
+export const HomePageSearchBar = ({ placeholder }: Props) => {
+ const [query, setQuery] = React.useState('');
+ const handleSearch = useNavigateToQuery();
+ const classes = useStyles();
+
+ const handleSubmit = () => {
+ handleSearch({ query });
+ };
+
+ const handleChange = React.useCallback(
+ value => {
+ setQuery(value);
+ },
+ [setQuery],
+ );
+
+ return (
+
+ );
+};
diff --git a/plugins/search/src/components/HomePageComponent/index.ts b/plugins/search/src/components/HomePageComponent/index.ts
new file mode 100644
index 0000000000..2b1cfe27b3
--- /dev/null
+++ b/plugins/search/src/components/HomePageComponent/index.ts
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2021 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export { HomePageSearchBar } from './HomePageSearchBar';
diff --git a/plugins/search/src/components/SearchBar/SearchBar.test.tsx b/plugins/search/src/components/SearchBar/SearchBar.test.tsx
index 188ffb279b..de8ea9a5a7 100644
--- a/plugins/search/src/components/SearchBar/SearchBar.test.tsx
+++ b/plugins/search/src/components/SearchBar/SearchBar.test.tsx
@@ -20,11 +20,16 @@ import userEvent from '@testing-library/user-event';
import { SearchContextProvider } from '../SearchContext';
import { SearchBar } from './SearchBar';
-import { useApi } from '@backstage/core-plugin-api';
+import { configApiRef } from '@backstage/core-plugin-api';
+import {
+ ApiProvider,
+ ApiRegistry,
+ ConfigReader,
+} from '@backstage/core-app-api';
+import { searchApiRef } from '../../apis';
jest.mock('@backstage/core-plugin-api', () => ({
...jest.requireActual('@backstage/core-plugin-api'),
- useApi: jest.fn().mockReturnValue({}),
}));
describe('SearchBar', () => {
@@ -32,13 +37,18 @@ describe('SearchBar', () => {
term: '',
filters: {},
types: ['*'],
+ pageCursor: '',
};
- const name = 'Search term';
- const term = 'term';
-
const query = jest.fn().mockResolvedValue({});
- (useApi as jest.Mock).mockReturnValue({ query });
+
+ const apiRegistry = ApiRegistry.from([
+ [configApiRef, new ConfigReader({ app: { title: 'Mock title' } })],
+ [searchApiRef, { query }],
+ ]);
+
+ const name = 'Search';
+ const term = 'term';
afterAll(() => {
jest.resetAllMocks();
@@ -46,9 +56,11 @@ describe('SearchBar', () => {
it('Renders without exploding', async () => {
render(
-
-
- ,
+
+
+
+
+ ,
);
await waitFor(() => {
@@ -58,9 +70,12 @@ describe('SearchBar', () => {
it('Renders based on initial search', async () => {
render(
-
-
- ,
+
+
+
+
+ ,
+ ,
);
await waitFor(() => {
@@ -70,9 +85,12 @@ describe('SearchBar', () => {
it('Updates term state when text is entered', async () => {
render(
-
-
- ,
+
+
+
+
+ ,
+ ,
);
const textbox = screen.getByRole('textbox', { name });
@@ -92,16 +110,18 @@ describe('SearchBar', () => {
it('Clear button clears term state', async () => {
render(
-
-
- ,
+
+
+
+
+ ,
);
await waitFor(() => {
expect(screen.getByRole('textbox', { name })).toHaveValue(term);
});
- userEvent.click(screen.getByRole('button', { name: 'Clear term' }));
+ userEvent.click(screen.getByRole('button', { name: 'Clear' }));
await waitFor(() => {
expect(screen.getByRole('textbox', { name })).toHaveValue('');
@@ -118,9 +138,12 @@ describe('SearchBar', () => {
const debounceTime = 600;
render(
-
-
- ,
+
+
+
+
+ ,
+ ,
);
await waitFor(() => {
diff --git a/plugins/search/src/components/SearchBar/SearchBar.tsx b/plugins/search/src/components/SearchBar/SearchBar.tsx
index bdff003b7a..214e22520c 100644
--- a/plugins/search/src/components/SearchBar/SearchBar.tsx
+++ b/plugins/search/src/components/SearchBar/SearchBar.tsx
@@ -14,7 +14,8 @@
* limitations under the License.
*/
-import React, { ChangeEvent, useEffect, useState } from 'react';
+import React, { useEffect, KeyboardEvent, useState } from 'react';
+import { configApiRef, useApi } from '@backstage/core-plugin-api';
import { useDebounce } from 'react-use';
import { InputBase, InputAdornment, IconButton } from '@material-ui/core';
import SearchIcon from '@material-ui/icons/Search';
@@ -22,6 +23,69 @@ import ClearButton from '@material-ui/icons/Clear';
import { useSearch } from '../SearchContext';
+type PresenterProps = {
+ value: string;
+ onChange: (value: string) => void;
+ onClear?: () => void;
+ onSubmit?: () => void;
+ className?: string;
+ placeholder?: string;
+};
+
+export const SearchBarBase = ({
+ value,
+ onChange,
+ onSubmit,
+ className,
+ placeholder: overridePlaceholder,
+}: PresenterProps) => {
+ const configApi = useApi(configApiRef);
+
+ const onKeyDown = React.useCallback(
+ (e: KeyboardEvent) => {
+ if (onSubmit && e.key === 'Enter') {
+ onSubmit();
+ }
+ },
+ [onSubmit],
+ );
+
+ const handleClear = React.useCallback(() => {
+ onChange('');
+ }, [onChange]);
+
+ const placeholder =
+ overridePlaceholder ??
+ `Search in ${configApi.getOptionalString('app.title') || 'Backstage'}`;
+
+ return (
+ onChange(e.target.value)}
+ inputProps={{ 'aria-label': 'Search' }}
+ startAdornment={
+
+
+
+
+
+ }
+ endAdornment={
+
+
+
+
+
+ }
+ {...(className && { className })}
+ {...(onSubmit && { onKeyDown })}
+ />
+ );
+};
+
type Props = {
className?: string;
debounceTime?: number;
@@ -37,35 +101,18 @@ export const SearchBar = ({ className, debounceTime = 0 }: Props) => {
useDebounce(() => setTerm(value), debounceTime, [value]);
- const handleQuery = (e: ChangeEvent) => {
- setValue(e.target.value);
+ const handleQuery = (newValue: string) => {
+ setValue(newValue);
};
const handleClear = () => setValue('');
return (
-
-
-
-
-
- }
- endAdornment={
-
-
-
-
-
- }
+ onClear={handleClear}
/>
);
};
diff --git a/plugins/search/src/components/SearchBar/index.tsx b/plugins/search/src/components/SearchBar/index.tsx
index 840142264e..5adbda282b 100644
--- a/plugins/search/src/components/SearchBar/index.tsx
+++ b/plugins/search/src/components/SearchBar/index.tsx
@@ -14,4 +14,4 @@
* limitations under the License.
*/
-export { SearchBar } from './SearchBar';
+export { SearchBar, SearchBarBase } from './SearchBar';
diff --git a/plugins/search/src/components/util.test.tsx b/plugins/search/src/components/util.test.tsx
new file mode 100644
index 0000000000..a5b82370e3
--- /dev/null
+++ b/plugins/search/src/components/util.test.tsx
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2021 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import React from 'react';
+import { wrapInTestApp } from '@backstage/test-utils';
+import { render } from '@testing-library/react';
+import { useNavigateToQuery } from './util';
+import { Routes, Route } from 'react-router-dom';
+import { rootRouteRef } from '../plugin';
+import { act } from 'react-dom/test-utils';
+
+const navigate = jest.fn();
+jest.mock('react-router-dom', () => ({
+ ...jest.requireActual('react-router-dom'),
+ useNavigate: () => navigate,
+}));
+
+describe('util', () => {
+ describe('useNavigateToQuery', () => {
+ it('navigates to query', async () => {
+ const MyComponent = () => {
+ const navigateToQuery = useNavigateToQuery();
+ navigateToQuery({ query: 'test' });
+ return
test
;
+ };
+
+ await act(async () => {
+ await render(
+ wrapInTestApp(
+
+ } />
+ ,
+ {
+ mountedRoutes: {
+ '/search': rootRouteRef,
+ },
+ },
+ ),
+ );
+
+ expect(navigate).toHaveBeenCalledTimes(1);
+ expect(navigate).toHaveBeenCalledWith('/search?query=test');
+ });
+ });
+ });
+});
diff --git a/plugins/search/src/components/util.ts b/plugins/search/src/components/util.ts
new file mode 100644
index 0000000000..1e50a44b91
--- /dev/null
+++ b/plugins/search/src/components/util.ts
@@ -0,0 +1,34 @@
+/*
+ * 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 qs from 'qs';
+import { useCallback } from 'react';
+import { useNavigate } from 'react-router-dom';
+import { rootRouteRef } from '../plugin';
+
+import { useRouteRef } from '@backstage/core-plugin-api';
+
+export const useNavigateToQuery = () => {
+ const searchRoute = useRouteRef(rootRouteRef);
+ const navigate = useNavigate();
+ return useCallback(
+ ({ query }: { query: string }): void => {
+ const queryString = qs.stringify({ query }, { addQueryPrefix: true });
+
+ navigate(`${searchRoute()}${queryString}`);
+ },
+ [navigate, searchRoute],
+ );
+};
diff --git a/plugins/search/src/index.ts b/plugins/search/src/index.ts
index d178329ab4..d98d5416cc 100644
--- a/plugins/search/src/index.ts
+++ b/plugins/search/src/index.ts
@@ -37,4 +37,5 @@ export {
searchPlugin as plugin,
searchPlugin,
SearchResult,
+ HomePageSearchBar,
} from './plugin';
diff --git a/plugins/search/src/plugin.ts b/plugins/search/src/plugin.ts
index d89bb566e9..36094234a0 100644
--- a/plugins/search/src/plugin.ts
+++ b/plugins/search/src/plugin.ts
@@ -126,3 +126,12 @@ export const DefaultResultListItem = searchPlugin.provide(
},
}),
);
+
+export const HomePageSearchBar = searchPlugin.provide(
+ createComponentExtension({
+ component: {
+ lazy: () =>
+ import('./components/HomePageComponent').then(m => m.HomePageSearchBar),
+ },
+ }),
+);
diff --git a/plugins/techdocs/src/reader/components/TechDocsSearch.tsx b/plugins/techdocs/src/reader/components/TechDocsSearch.tsx
index 0f3ca00c0a..6f2df2cc55 100644
--- a/plugins/techdocs/src/reader/components/TechDocsSearch.tsx
+++ b/plugins/techdocs/src/reader/components/TechDocsSearch.tsx
@@ -141,7 +141,7 @@ const TechDocsSearchBar = ({
...params.InputProps,
startAdornment: (
-
+
diff --git a/plugins/todo/api-report.md b/plugins/todo/api-report.md
index 548d55accb..22fca3cb9e 100644
--- a/plugins/todo/api-report.md
+++ b/plugins/todo/api-report.md
@@ -7,22 +7,84 @@
import { ApiRef } from '@backstage/core-plugin-api';
import { BackstagePlugin } from '@backstage/core-plugin-api';
+import { DiscoveryApi } from '@backstage/core-plugin-api';
import { Entity } from '@backstage/catalog-model';
+import { IdentityApi } from '@backstage/core-plugin-api';
-// Warning: (ae-missing-release-tag) "EntityTodoContent" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public (undocumented)
+// @public
export const EntityTodoContent: () => JSX.Element;
-// Warning: (ae-forgotten-export) The symbol "TodoApi" needs to be exported by the entry point index.d.ts
-// Warning: (ae-missing-release-tag) "todoApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public (undocumented)
+// @public
+export interface TodoApi {
+ listTodos(options: TodoListOptions): Promise;
+}
+
+// @public
export const todoApiRef: ApiRef;
-// Warning: (ae-missing-release-tag) "todoPlugin" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public (undocumented)
+// @public
+export class TodoClient implements TodoApi {
+ constructor(options: TodoClientOptions);
+ // (undocumented)
+ listTodos({
+ entity,
+ offset,
+ limit,
+ orderBy,
+ filters,
+ }: TodoListOptions): Promise;
+}
+
+// @public
+export interface TodoClientOptions {
+ // (undocumented)
+ discoveryApi: DiscoveryApi;
+ // (undocumented)
+ identityApi: IdentityApi;
+}
+
+// @public
+export type TodoItem = {
+ text: string;
+ tag: string;
+ author?: string;
+ viewUrl?: string;
+ lineNumber?: number;
+ repoFilePath?: string;
+};
+
+// @public
+export type TodoListFields =
+ | 'text'
+ | 'tag'
+ | 'author'
+ | 'viewUrl'
+ | 'repoFilePath';
+
+// @public
+export type TodoListOptions = {
+ entity?: Entity;
+ offset?: number;
+ limit?: number;
+ orderBy?: {
+ field: TodoListFields;
+ direction: 'asc' | 'desc';
+ };
+ filters?: {
+ field: TodoListFields;
+ value: string;
+ }[];
+};
+
+// @public
+export type TodoListResult = {
+ items: TodoItem[];
+ totalCount: number;
+ offset: number;
+ limit: number;
+};
+
+// @public
export const todoPlugin: BackstagePlugin<{}, {}>;
// (No @packageDocumentation comment for this package)
diff --git a/plugins/todo/src/api/TodoClient.ts b/plugins/todo/src/api/TodoClient.ts
index f4fb4071e8..f75e4b6954 100644
--- a/plugins/todo/src/api/TodoClient.ts
+++ b/plugins/todo/src/api/TodoClient.ts
@@ -14,21 +14,31 @@
* limitations under the License.
*/
-import { serializeEntityRef } from '@backstage/catalog-model';
+import { stringifyEntityRef } from '@backstage/catalog-model';
import { ResponseError } from '@backstage/errors';
import { TodoApi, TodoListOptions, TodoListResult } from './types';
import { DiscoveryApi, IdentityApi } from '@backstage/core-plugin-api';
-interface Options {
+/**
+ * Options for creating a todo client.
+ *
+ * @public
+ */
+export interface TodoClientOptions {
discoveryApi: DiscoveryApi;
identityApi: IdentityApi;
}
+/**
+ * An implementation of the TodoApi that talks to the todo plugin backend.
+ *
+ * @public
+ */
export class TodoClient implements TodoApi {
private readonly discoveryApi: DiscoveryApi;
private readonly identityApi: IdentityApi;
- constructor(options: Options) {
+ constructor(options: TodoClientOptions) {
this.discoveryApi = options.discoveryApi;
this.identityApi = options.identityApi;
}
@@ -45,7 +55,7 @@ export class TodoClient implements TodoApi {
const query = new URLSearchParams();
if (entity) {
- query.set('entity', serializeEntityRef(entity) as string);
+ query.set('entity', stringifyEntityRef(entity));
}
if (typeof offset === 'number') {
query.set('offset', String(offset));
diff --git a/plugins/todo/src/api/index.ts b/plugins/todo/src/api/index.ts
index d6771aeaba..b1d9792c95 100644
--- a/plugins/todo/src/api/index.ts
+++ b/plugins/todo/src/api/index.ts
@@ -15,5 +15,12 @@
*/
export { TodoClient } from './TodoClient';
+export type { TodoClientOptions } from './TodoClient';
export { todoApiRef } from './types';
-export type { TodoApi } from './types';
+export type {
+ TodoApi,
+ TodoListOptions,
+ TodoListResult,
+ TodoItem,
+ TodoListFields,
+} from './types';
diff --git a/plugins/todo/src/api/types.ts b/plugins/todo/src/api/types.ts
index 018f1df536..f1f647f6e3 100644
--- a/plugins/todo/src/api/types.ts
+++ b/plugins/todo/src/api/types.ts
@@ -17,6 +17,11 @@
import { Entity } from '@backstage/catalog-model';
import { createApiRef } from '@backstage/core-plugin-api';
+/**
+ * TodoItem represents a single TODO comment in source code.
+ *
+ * @public
+ */
export type TodoItem = {
/** The contents of the TODO comment */
text: string;
@@ -37,23 +42,43 @@ export type TodoItem = {
repoFilePath?: string;
};
-type Fields = 'text' | 'tag' | 'author' | 'viewUrl' | 'repoFilePath';
+/**
+ * Fields that can be used to filter or order todo items.
+ *
+ * @public
+ */
+export type TodoListFields =
+ | 'text'
+ | 'tag'
+ | 'author'
+ | 'viewUrl'
+ | 'repoFilePath';
+/**
+ * Options used to list todo items.
+ *
+ * @public
+ */
export type TodoListOptions = {
entity?: Entity;
offset?: number;
limit?: number;
orderBy?: {
- field: Fields;
+ field: TodoListFields;
direction: 'asc' | 'desc';
};
filters?: {
- field: Fields;
+ field: TodoListFields;
/** Value to filter by, with '*' used as wildcard */
value: string;
}[];
};
+/**
+ * The result of listing todos.
+ *
+ * @public
+ */
export type TodoListResult = {
items: TodoItem[];
totalCount: number;
@@ -61,10 +86,25 @@ export type TodoListResult = {
limit: number;
};
+/**
+ * The API used by the todo-plugin to list todos.
+ *
+ * @public
+ */
export interface TodoApi {
+ /**
+ * Lists todo items.
+ *
+ * @public
+ */
listTodos(options: TodoListOptions): Promise;
}
+/**
+ * ApiRef for the TodoApi.
+ *
+ * @public
+ */
export const todoApiRef = createApiRef({
id: 'plugin.todo.api',
description: 'Lists TODOs',
diff --git a/plugins/todo/src/index.ts b/plugins/todo/src/index.ts
index d04df36f5e..92a85945ac 100644
--- a/plugins/todo/src/index.ts
+++ b/plugins/todo/src/index.ts
@@ -14,5 +14,13 @@
* limitations under the License.
*/
-export { todoApiRef } from './api';
+export { todoApiRef, TodoClient } from './api';
+export type {
+ TodoApi,
+ TodoListOptions,
+ TodoListResult,
+ TodoItem,
+ TodoListFields,
+ TodoClientOptions,
+} from './api';
export { todoPlugin, EntityTodoContent } from './plugin';
diff --git a/plugins/todo/src/plugin.ts b/plugins/todo/src/plugin.ts
index dd24304d0a..5415bbb902 100644
--- a/plugins/todo/src/plugin.ts
+++ b/plugins/todo/src/plugin.ts
@@ -22,8 +22,11 @@ import {
identityApiRef,
} from '@backstage/core-plugin-api';
-// import { rootRouteRef } from './routes';
-
+/**
+ * The Todo plugin instance.
+ *
+ * @public
+ */
export const todoPlugin = createPlugin({
id: 'todo',
apis: [
@@ -43,6 +46,11 @@ export const todoPlugin = createPlugin({
},
});
+/**
+ * An extension for displaying the list of todos on an entity page.
+ *
+ * @public
+ */
export const EntityTodoContent = todoPlugin.provide(
createComponentExtension({
component: {
diff --git a/yarn.lock b/yarn.lock
index 7b2a14c310..5db9fd7589 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4861,7 +4861,7 @@
"@octokit/types" "^6.16.2"
deprecation "^2.3.1"
-"@octokit/request-error@^2.0.0", "@octokit/request-error@^2.0.5", "@octokit/request-error@^2.1.0":
+"@octokit/request-error@^2.0.0", "@octokit/request-error@^2.0.2", "@octokit/request-error@^2.0.5", "@octokit/request-error@^2.1.0":
version "2.1.0"
resolved "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz#9e150357831bfc788d13a4fd4b1913d60c74d677"
integrity sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==
@@ -4906,6 +4906,26 @@
dependencies:
"@octokit/openapi-types" "^7.3.2"
+"@octokit/webhooks-methods@^2.0.0":
+ version "2.0.0"
+ resolved "https://registry.npmjs.org/@octokit/webhooks-methods/-/webhooks-methods-2.0.0.tgz#1108b9ea661ca6c81e4a8bfa63a09eb27d5bc2db"
+ integrity sha512-35cfQ4YWlnZnmZKmIxlGPUPLtbkF8lr/A/1Sk1eC0ddLMwQN06dOuLc+dI3YLQS+T+MoNt3DIQ0NynwgKPilig==
+
+"@octokit/webhooks-types@4.4.0":
+ version "4.4.0"
+ resolved "https://registry.npmjs.org/@octokit/webhooks-types/-/webhooks-types-4.4.0.tgz#0985964b72d577221574cca614770e0743fe0830"
+ integrity sha512-gK9L2pWLZ1CWWlf9zwzFBQeA3dgyWdRe6gqAedR5T7adFZpoHg4De6GeXIFySV796ooQtKhW4eFfQLFQF5ydAA==
+
+"@octokit/webhooks@^9.14.1":
+ version "9.14.1"
+ resolved "https://registry.npmjs.org/@octokit/webhooks/-/webhooks-9.14.1.tgz#d1b8fcc4c1c18ee46ec30cef9e84043b57c8d2dd"
+ integrity sha512-INsqtHKQJys5NbuE71kq6uR8BMSSkZ2L9dLanAc1jylGroQ80SW1TYXLuJlcYNakNrHCCe4c5qvNKfR/KJXrJA==
+ dependencies:
+ "@octokit/request-error" "^2.0.2"
+ "@octokit/webhooks-methods" "^2.0.0"
+ "@octokit/webhooks-types" "4.4.0"
+ aggregate-error "^3.1.0"
+
"@open-draft/until@^1.0.3":
version "1.0.3"
resolved "https://registry.npmjs.org/@open-draft/until/-/until-1.0.3.tgz#db9cc719191a62e7d9200f6e7bab21c5b848adca"
@@ -6333,9 +6353,9 @@
integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==
"@types/color@^3.0.1":
- version "3.0.1"
- resolved "https://registry.npmjs.org/@types/color/-/color-3.0.1.tgz#2900490ed04da8116c5058cd5dba3572d5a25071"
- integrity sha512-oeUWVaAwI+xINDUx+3F2vJkl/vVB03VChFF/Gl3iQCdbcakjuoJyMOba+3BXRtnBhxZ7uBYqQBi9EpLnvSoztA==
+ version "3.0.2"
+ resolved "https://registry.npmjs.org/@types/color/-/color-3.0.2.tgz#3779043e782f562aa9157b5fc6bd07e14fd8e7f3"
+ integrity sha512-INiJl6sfNn8iyC5paxVzqiVUEj2boIlFki02uRTAkKwAj++7aAF+ZfEv/XrIeBa0XI/fTZuDHW8rEEcEVnON+Q==
dependencies:
"@types/color-convert" "*"