Improve API documentation for @backstage/core-plugin-api

Signed-off-by: Jarek Łukow <jlukow@box.com>
This commit is contained in:
Jarek Łukow
2021-11-01 10:16:54 +01:00
parent e527120f74
commit 8b4284cd5c
41 changed files with 939 additions and 404 deletions
+6
View File
@@ -0,0 +1,6 @@
---
'@backstage/core-app-api': patch
'@backstage/core-plugin-api': patch
---
Improve API documentation for @backstage/core-plugin-api
+2 -5
View File
@@ -28,6 +28,7 @@ import { bitbucketAuthApiRef } from '@backstage/core-plugin-api';
import { ComponentType } from 'react';
import { ConfigReader } from '@backstage/config';
import { DiscoveryApi } from '@backstage/core-plugin-api';
import { Error as Error_2 } from '@backstage/core-plugin-api';
import { ErrorApi } from '@backstage/core-plugin-api';
import { ErrorContext } from '@backstage/core-plugin-api';
import { ExternalRouteRef } from '@backstage/core-plugin-api';
@@ -298,11 +299,7 @@ export class ErrorAlerter implements ErrorApi {
constructor(alertApi: AlertApi, errorApi: ErrorApi);
// (undocumented)
error$(): Observable<{
error: {
name: string;
message: string;
stack?: string | undefined;
};
error: Error_2;
context?: ErrorContext | undefined;
}>;
// (undocumented)
File diff suppressed because it is too large Load Diff
@@ -27,7 +27,8 @@ const AnalyticsReactContext =
/**
* A "private" (to this package) hook that enables context inheritance and a
* way to read Analytics Context values at event capture-time.
* @private
*
* @internal
*/
export const useAnalyticsContext = (): AnalyticsContextValue => {
const theContext = useContext(AnalyticsReactContext);
@@ -54,8 +55,12 @@ export const useAnalyticsContext = (): AnalyticsContextValue => {
* Provides components in the child react tree an Analytics Context, ensuring
* all analytics events captured within the context have relevant attributes.
*
* @remarks
*
* Analytics contexts are additive, meaning the context ultimately emitted with
* an event is the combination of all contexts in the parent tree.
*
* @public
*/
export const AnalyticsContext = ({
attributes,
@@ -84,6 +89,7 @@ export const AnalyticsContext = ({
*
* @param Component - Component to be wrapped with analytics context attributes
* @param values - Analytics context key/value pairs.
* @internal
*/
export function withAnalyticsContext<P>(
Component: React.ComponentType<P>,
@@ -16,6 +16,8 @@
/**
* Common analytics context attributes.
*
* @public
*/
export type CommonAnalyticsContext = {
/**
@@ -35,7 +37,9 @@ export type CommonAnalyticsContext = {
};
/**
* Allow arbitrary scalar values as context attributes too.
* Allows arbitrary scalar values as context attributes too.
*
* @public
*/
export type AnyAnalyticsContext = {
[param in string]: string | boolean | number | undefined;
@@ -43,6 +47,8 @@ export type AnyAnalyticsContext = {
/**
* Analytics context envelope.
*
* @public
*/
export type AnalyticsContextValue = CommonAnalyticsContext &
AnyAnalyticsContext;
@@ -33,7 +33,9 @@ function useAnalyticsApi(): AnalyticsApi {
}
/**
* Get a pre-configured analytics tracker.
* Gets a pre-configured analytics tracker.
*
* @public
*/
export function useAnalytics(): AnalyticsTracker {
const trackerRef = useRef<Tracker | null>(null);
@@ -17,6 +17,11 @@
import { createApiRef, ApiRef } from '../system';
import { Observable } from '@backstage/types';
/**
* Message handled by the {@link AlertApi}.
*
* @public
*/
export type AlertMessage = {
message: string;
// Severity will default to success since that is what material ui defaults the value to.
@@ -25,8 +30,9 @@ export type AlertMessage = {
/**
* The alert API is used to report alerts to the app, and display them to the user.
*
* @public
*/
export type AlertApi = {
/**
* Post an alert for handling by the application.
@@ -39,6 +45,11 @@ export type AlertApi = {
alert$(): Observable<AlertMessage>;
};
/**
* The {@link ApiRef} of {@link AlertApi}.
*
* @public
*/
export const alertApiRef: ApiRef<AlertApi> = createApiRef({
id: 'core.alert',
});
@@ -20,6 +20,8 @@ import { AnalyticsContextValue } from '../../analytics/types';
/**
* Represents an event worth tracking in an analytics system that could inform
* how users of a Backstage instance are using its features.
*
* @public
*/
export type AnalyticsEvent = {
/**
@@ -76,6 +78,8 @@ export type AnalyticsEvent = {
/**
* A structure allowing other arbitrary metadata to be provided by analytics
* event emitters.
*
* @public
*/
export type AnalyticsEventAttributes = {
[attribute in string]: string | boolean | number;
@@ -84,6 +88,8 @@ export type AnalyticsEventAttributes = {
/**
* Represents a tracker with methods that can be called to track events in a
* configured analytics service.
*
* @public
*/
export type AnalyticsTracker = {
captureEvent: (
@@ -99,9 +105,13 @@ export type AnalyticsTracker = {
/**
* The Analytics API is used to track user behavior in a Backstage instance.
*
* @remarks
*
* To instrument your App or Plugin, retrieve an analytics tracker using the
* useAnalytics() hook. This will return a pre-configured AnalyticsTracker
* with relevant methods for instrumentation.
*
* @public
*/
export type AnalyticsApi = {
/**
@@ -111,6 +121,11 @@ export type AnalyticsApi = {
captureEvent(event: AnalyticsEvent): void;
};
/**
* The {@link ApiRef} of {@link AnalyticsApi}.
*
* @public
*/
export const analyticsApiRef: ApiRef<AnalyticsApi> = createApiRef({
id: 'core.analytics',
});
@@ -20,6 +20,8 @@ import { Observable } from '@backstage/types';
/**
* Describes a theme provided by the app.
*
* @public
*/
export type AppTheme = {
/**
@@ -51,6 +53,8 @@ export type AppTheme = {
/**
* The AppThemeApi gives access to the current app theme, and allows switching
* to other options that have been registered as a part of the App.
*
* @public
*/
export type AppThemeApi = {
/**
@@ -76,6 +80,11 @@ export type AppThemeApi = {
setActiveThemeId(themeId?: string): void;
};
/**
* The {@link ApiRef} of {@link AppThemeApi}.
*
* @public
*/
export const appThemeApiRef: ApiRef<AppThemeApi> = createApiRef({
id: 'core.apptheme',
});
@@ -19,9 +19,16 @@ import { Config } from '@backstage/config';
/**
* The Config API is used to provide a mechanism to access the
* runtime configuration of the system.
*
* @public
*/
export type ConfigApi = Config;
/**
* The {@link ApiRef} of {@link ConfigApi}.
*
* @public
*/
export const configApiRef: ApiRef<ConfigApi> = createApiRef({
id: 'core.config',
});
@@ -19,6 +19,8 @@ import { ApiRef, createApiRef } from '../system';
* The discovery API is used to provide a mechanism for plugins to
* discover the endpoint to use to talk to their backend counterpart.
*
* @remarks
*
* The purpose of the discovery API is to allow for many different deployment
* setups and routing methods through a central configuration, instead
* of letting each individual plugin manage that configuration.
@@ -26,6 +28,8 @@ import { ApiRef, createApiRef } from '../system';
* Implementations of the discovery API can be a 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 DiscoveryApi = {
/**
@@ -41,6 +45,11 @@ export type DiscoveryApi = {
getBaseUrl(pluginId: string): Promise<string>;
};
/**
* The {@link ApiRef} of {@link DiscoveryApi}.
*
* @public
*/
export const discoveryApiRef: ApiRef<DiscoveryApi> = createApiRef({
id: 'core.discovery',
});
@@ -20,8 +20,10 @@ import { Observable } from '@backstage/types';
/**
* Mirrors the JavaScript Error class, for the purpose of
* providing documentation and optional fields.
*
* @public
*/
type Error = {
export type Error = {
name: string;
message: string;
stack?: string;
@@ -29,6 +31,8 @@ type Error = {
/**
* Provides additional information about an error that was posted to the application.
*
* @public
*/
export type ErrorContext = {
// If set to true, this error should not be displayed to the user. Defaults to false.
@@ -38,6 +42,8 @@ export type ErrorContext = {
/**
* The error API is used to report errors to the app, and display them to the user.
*
* @remarks
*
* Plugins can use this API as a method of displaying errors to the user, but also
* to report errors for collection by error reporting services.
*
@@ -49,6 +55,8 @@ export type ErrorContext = {
* if it would be useful to collect or log it for debugging purposes, but with
* the hidden flag set. For example, an error arising from form field validation
* should probably not be reported, while a failed REST call would be useful to report.
*
* @public
*/
export type ErrorApi = {
/**
@@ -62,6 +70,11 @@ export type ErrorApi = {
error$(): Observable<{ error: Error; context?: ErrorContext }>;
};
/**
* The {@link ApiRef} of {@link ErrorApi}.
*
* @public
*/
export const errorApiRef: ApiRef<ErrorApi> = createApiRef({
id: 'core.error',
});
@@ -17,29 +17,35 @@
import { ApiRef, createApiRef } from '../system';
/**
* The feature flags API is used to toggle functionality to users across plugins and Backstage.
* Fetaure flag descriptor.
*
* Plugins can use this API to register feature flags that they have available
* for users to enable/disable, and this API will centralize the current user's
* state of which feature flags they would like to enable.
*
* This is ideal for Backstage plugins, as well as your own App, to trial incomplete
* or unstable upcoming features. Although there will be a common interface for users
* to enable and disable feature flags, this API acts as another way to enable/disable.
* @public
*/
export type FeatureFlag = {
name: string;
pluginId: string;
};
/**
* Enum representing the state of a feature flag (inactive/active).
*
* @public
*/
export enum FeatureFlagState {
/**
* Feature flag inactive (disabled).
*/
None = 0,
/**
* Feature flag active (enabled).
*/
Active = 1,
}
/**
* Options to use when saving feature flags.
*
* @public
*/
export type FeatureFlagsSaveOptions = {
/**
@@ -55,8 +61,28 @@ export type FeatureFlagsSaveOptions = {
merge?: boolean;
};
/**
* User flags alias.
*
* @public
*/
export type UserFlags = {};
/**
* The feature flags API is used to toggle functionality to users across plugins and Backstage.
*
* @remarks
*
* Plugins can use this API to register feature flags that they have available
* for users to enable/disable, and this API will centralize the current user's
* state of which feature flags they would like to enable.
*
* This is ideal for Backstage plugins, as well as your own App, to trial incomplete
* or unstable upcoming features. Although there will be a common interface for users
* to enable and disable feature flags, this API acts as another way to enable/disable.
*
* @public
*/
export interface FeatureFlagsApi {
/**
* Registers a new feature flag. Once a feature flag has been registered it
@@ -80,6 +106,11 @@ export interface FeatureFlagsApi {
save(options: FeatureFlagsSaveOptions): void;
}
/**
* The {@link ApiRef} of {@link FeatureFlagsApi}.
*
* @public
*/
export const featureFlagsApiRef: ApiRef<FeatureFlagsApi> = createApiRef({
id: 'core.featureflags',
});
@@ -18,6 +18,8 @@ import { ProfileInfo } from './auth';
/**
* The Identity API used to identify and get information about the signed in user.
*
* @public
*/
export type IdentityApi = {
/**
@@ -49,6 +51,11 @@ export type IdentityApi = {
signOut(): Promise<void>;
};
/**
* The {@link ApiRef} of {@link IdentityApi}.
*
* @public
*/
export const identityApiRef: ApiRef<IdentityApi> = createApiRef({
id: 'core.identity',
});
@@ -21,8 +21,12 @@ import { ApiRef, createApiRef } from '../system';
/**
* Information about the auth provider that we're requesting a login towards.
*
* @remarks
*
* This should be shown to the user so that they can be informed about what login is being requested
* before a popup is shown.
*
* @public
*/
export type AuthProvider = {
/**
@@ -39,6 +43,8 @@ export type AuthProvider = {
/**
* Describes how to handle auth requests. Both how to show them to the user, and what to do when
* the user accesses the auth request.
*
* @public
*/
export type AuthRequesterOptions<AuthResponse> = {
/**
@@ -56,12 +62,16 @@ export type AuthRequesterOptions<AuthResponse> = {
/**
* Function used to trigger new auth requests for a set of scopes.
*
* @remarks
*
* The returned promise will resolve to the same value returned by the onAuthRequest in the
* AuthRequesterOptions. Or rejected, if the request is rejected.
* {@link AuthRequesterOptions}. Or rejected, if the request is rejected.
*
* This function can be called multiple times before the promise resolves. All calls
* will be merged into one request, and the scopes forwarded to the onAuthRequest will be the
* union of all requested scopes.
*
* @public
*/
export type AuthRequester<AuthResponse> = (
scopes: Set<string>,
@@ -71,8 +81,12 @@ export type AuthRequester<AuthResponse> = (
* An pending auth request for a single auth provider. The request will remain in this pending
* state until either reject() or trigger() is called.
*
* @remarks
*
* Any new requests for the same provider are merged into the existing pending request, meaning
* there will only ever be a single pending request for a given provider.
*
* @public
*/
export type PendingAuthRequest = {
/**
@@ -95,6 +109,8 @@ export type PendingAuthRequest = {
/**
* Provides helpers for implemented OAuth login flows within Backstage.
*
* @public
*/
export type OAuthRequestApi = {
/**
@@ -127,6 +143,11 @@ export type OAuthRequestApi = {
authRequest$(): Observable<PendingAuthRequest[]>;
};
/**
* The {@link ApiRef} of {@link OAuthRequestApi}.
*
* @public
*/
export const oauthRequestApiRef: ApiRef<OAuthRequestApi> = createApiRef({
id: 'core.oauthrequest',
});
@@ -17,48 +17,60 @@
import { ApiRef, createApiRef } from '../system';
import { Observable } from '@backstage/types';
/**
* Describes a value change event.
*
* @public
*/
export type StorageValueChange<T = any> = {
key: string;
newValue?: T;
};
/**
* Provides key-value persistence API.
*
* @public
*/
export interface StorageApi {
/**
* Create a bucket to store data in.
* @param {String} name Namespace for the storage to be stored under,
* @param name - Namespace for the storage to be stored under,
* will inherit previous namespaces too
*/
forBucket(name: string): StorageApi;
/**
* Get the current value for persistent data, use observe$ to be notified of updates.
*
* @param {String} key Unique key associated with the data.
* @return {Object} data The data that should is stored.
* @param key - Unique key associated with the data.
*/
get<T>(key: string): T | undefined;
/**
* Remove persistent data.
*
* @param {String} key Unique key associated with the data.
* @param key - Unique key associated with the data.
*/
remove(key: string): Promise<void>;
/**
* Save persistent data, and emit messages to anyone that is using observe$ for this key
*
* @param {String} key Unique key associated with the data.
* @param key - Unique key associated with the data.
* @param data - The data to be stored under the key.
*/
set(key: string, data: any): Promise<void>;
/**
* Observe changes on a particular key in the bucket
* @param {String} key Unique key associated with the data
* @param key - Unique key associated with the data
*/
observe$<T>(key: string): Observable<StorageValueChange<T>>;
}
/**
* The {@link ApiRef} of {@link StorageApi}.
*
* @public
*/
export const storageApiRef: ApiRef<StorageApi> = createApiRef({
id: 'core.storage',
});
@@ -32,11 +32,20 @@ import { Observable } from '@backstage/types';
* An array of scopes, or a scope string formatted according to the
* auth provider, which is typically a space separated list.
*
* @remarks
*
* See the documentation for each auth provider for the list of scopes
* supported by each provider.
*
* @public
*/
export type OAuthScope = string | string[];
/**
* Configuration of an authentication request.
*
* @public
*/
export type AuthRequestOptions = {
/**
* If this is set to true, the user will not be prompted to log in,
@@ -45,7 +54,7 @@ export type AuthRequestOptions = {
* This can be used to perform a check whether the user is logged in, or if you don't
* want to force a user to be logged in, but provide functionality if they already are.
*
* @default false
* @defaultValue false
*/
optional?: boolean;
@@ -55,7 +64,7 @@ export type AuthRequestOptions = {
*
* The method must be called synchronously from a user action for this to work in all browsers.
*
* @default false
* @defaultValue false
*/
instantPopup?: boolean;
};
@@ -63,6 +72,8 @@ export type AuthRequestOptions = {
/**
* This API provides access to OAuth 2 credentials. It lets you request access tokens,
* which can be used to act on behalf of the user when talking to APIs.
*
* @public
*/
export type OAuthApi = {
/**
@@ -95,6 +106,8 @@ export type OAuthApi = {
/**
* This API provides access to OpenID Connect credentials. It lets you request ID tokens,
* which can be passed to backend services to prove the user's identity.
*
* @public
*/
export type OpenIdConnectApi = {
/**
@@ -113,13 +126,15 @@ export type OpenIdConnectApi = {
/**
* This API provides access to profile information of the user from an auth provider.
*
* @public
*/
export type ProfileInfoApi = {
/**
* Get profile information for the user as supplied by this auth provider.
*
* If the optional flag is not set, a session is guaranteed to be returned, while if
* the optional flag is set, the session may be undefined. See @AuthRequestOptions for more details.
* the optional flag is set, the session may be undefined. See {@link AuthRequestOptions} for more details.
*/
getProfile(options?: AuthRequestOptions): Promise<ProfileInfo | undefined>;
};
@@ -127,23 +142,32 @@ export type ProfileInfoApi = {
/**
* This API provides access to the user's identity within Backstage.
*
* @remarks
*
* An auth provider that implements this interface can be used to sign-in to backstage. It is
* not intended to be used directly from a plugin, but instead serves as a connection between
* this authentication method and the app's @IdentityApi
* this authentication method and the app's {@link IdentityApi}
*
* @public
*/
export type BackstageIdentityApi = {
/**
* Get the user's identity within Backstage. This should normally not be called directly,
* use the @IdentityApi instead.
* use the {@link IdentityApi} instead.
*
* If the optional flag is not set, a session is guaranteed to be returned, while if
* the optional flag is set, the session may be undefined. See @AuthRequestOptions for more details.
* the optional flag is set, the session may be undefined. See {@link AuthRequestOptions} for more details.
*/
getBackstageIdentity(
options?: AuthRequestOptions,
): Promise<BackstageIdentity | undefined>;
};
/**
* A (user id, token) pair.
*
* @public
*/
export type BackstageIdentity = {
/**
* The backstage user ID.
@@ -163,6 +187,8 @@ export type BackstageIdentity = {
/**
* Profile information of the user.
*
* @public
*/
export type ProfileInfo = {
/**
@@ -183,14 +209,24 @@ export type ProfileInfo = {
/**
* Session state values passed to subscribers of the SessionApi.
*
* @public
*/
export enum SessionState {
/**
* User signed in.
*/
SignedIn = 'SignedIn',
/**
* User not signed in.
*/
SignedOut = 'SignedOut',
}
/**
* The SessionApi provides basic controls for any auth provider that is tied to a persistent session.
*
* @public
*/
export type SessionApi = {
/**
@@ -212,10 +248,14 @@ export type SessionApi = {
/**
* Provides authentication towards Google APIs and identities.
*
* See https://developers.google.com/identity/protocols/googlescopes for a full list of supported scopes.
* @remarks
*
* See {@link https://developers.google.com/identity/protocols/googlescopes} for a full list of supported scopes.
*
* Note that the ID token payload is only guaranteed to contain the user's numerical Google ID,
* email and expiration information. Do not rely on any other fields, as they might not be present.
*
* @public
*/
export const googleAuthApiRef: ApiRef<
OAuthApi &
@@ -230,8 +270,12 @@ export const googleAuthApiRef: ApiRef<
/**
* Provides authentication towards GitHub APIs.
*
* See https://developer.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/
* @remarks
*
* See {@link https://developer.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/}
* for a full list of supported scopes.
*
* @public
*/
export const githubAuthApiRef: ApiRef<
OAuthApi & ProfileInfoApi & BackstageIdentityApi & SessionApi
@@ -242,8 +286,12 @@ export const githubAuthApiRef: ApiRef<
/**
* Provides authentication towards Okta APIs.
*
* See https://developer.okta.com/docs/guides/implement-oauth-for-okta/scopes/
* @remarks
*
* See {@link https://developer.okta.com/docs/guides/implement-oauth-for-okta/scopes/}
* for a full list of supported scopes.
*
* @public
*/
export const oktaAuthApiRef: ApiRef<
OAuthApi &
@@ -258,8 +306,12 @@ export const oktaAuthApiRef: ApiRef<
/**
* Provides authentication towards GitLab APIs.
*
* See https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html#limiting-scopes-of-a-personal-access-token
* @remarks
*
* See {@link https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html#limiting-scopes-of-a-personal-access-token}
* for a full list of supported scopes.
*
* @public
*/
export const gitlabAuthApiRef: ApiRef<
OAuthApi & ProfileInfoApi & BackstageIdentityApi & SessionApi
@@ -270,8 +322,12 @@ export const gitlabAuthApiRef: ApiRef<
/**
* Provides authentication towards Auth0 APIs.
*
* See https://auth0.com/docs/scopes/current/oidc-scopes
* @remarks
*
* See {@link https://auth0.com/docs/scopes/current/oidc-scopes}
* for a full list of supported scopes.
*
* @public
*/
export const auth0AuthApiRef: ApiRef<
OpenIdConnectApi & ProfileInfoApi & BackstageIdentityApi & SessionApi
@@ -282,9 +338,13 @@ export const auth0AuthApiRef: ApiRef<
/**
* Provides authentication towards Microsoft APIs and identities.
*
* @remarks
*
* For more info and a full list of supported scopes, see:
* - https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-permissions-and-consent
* - https://docs.microsoft.com/en-us/graph/permissions-reference
* - {@link https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-permissions-and-consent}
* - {@link https://docs.microsoft.com/en-us/graph/permissions-reference}
*
* @public
*/
export const microsoftAuthApiRef: ApiRef<
OAuthApi &
@@ -298,6 +358,8 @@ export const microsoftAuthApiRef: ApiRef<
/**
* Provides authentication for custom identity providers.
*
* @public
*/
export const oauth2ApiRef: ApiRef<
OAuthApi &
@@ -311,6 +373,8 @@ export const oauth2ApiRef: ApiRef<
/**
* Provides authentication for custom OpenID Connect identity providers.
*
* @public
*/
export const oidcAuthApiRef: ApiRef<
OAuthApi &
@@ -323,7 +387,9 @@ export const oidcAuthApiRef: ApiRef<
});
/**
* Provides authentication for saml based identity providers
* Provides authentication for SAML-based identity providers.
*
* @public
*/
export const samlAuthApiRef: ApiRef<
ProfileInfoApi & BackstageIdentityApi & SessionApi
@@ -331,6 +397,11 @@ export const samlAuthApiRef: ApiRef<
id: 'core.auth.saml',
});
/**
* Provides authentication towards OneLogin APIs.
*
* @public
*/
export const oneloginAuthApiRef: ApiRef<
OAuthApi &
OpenIdConnectApi &
@@ -344,8 +415,12 @@ export const oneloginAuthApiRef: ApiRef<
/**
* Provides authentication towards Bitbucket APIs.
*
* See https://support.atlassian.com/bitbucket-cloud/docs/use-oauth-on-bitbucket-cloud/
* @remarks
*
* See {@link https://support.atlassian.com/bitbucket-cloud/docs/use-oauth-on-bitbucket-cloud/}
* for a full list of supported scopes.
*
* @public
*/
export const bitbucketAuthApiRef: ApiRef<
OAuthApi & ProfileInfoApi & BackstageIdentityApi & SessionApi
@@ -356,8 +431,12 @@ export const bitbucketAuthApiRef: ApiRef<
/**
* Provides authentication towards Atlassian APIs.
*
* See https://developer.atlassian.com/cloud/jira/platform/scopes-for-connect-and-oauth-2-3LO-apps/
* @remarks
*
* See {@link https://developer.atlassian.com/cloud/jira/platform/scopes-for-connect-and-oauth-2-3LO-apps/}
* for a full list of supported scopes.
*
* @public
*/
export const atlassianAuthApiRef: ApiRef<
OAuthApi & ProfileInfoApi & BackstageIdentityApi & SessionApi
@@ -16,6 +16,11 @@
import type { ApiRef } from './types';
/**
* API reference configuration - holds an ID of the referenced API.
*
* @public
*/
export type ApiRefConfig = {
id: string;
/**
@@ -57,6 +62,13 @@ class ApiRefImpl<T> implements ApiRef<T> {
}
}
/**
* Creates a reference to an API.
*
* @param config - The descriptor of the API to reference.
* @returns An API reference.
* @public
*/
export function createApiRef<T>(config: ApiRefConfig): ApiRef<T> {
return new ApiRefImpl<T>(config);
}
@@ -17,19 +17,44 @@
import { ApiRef, ApiFactory, TypesToApiRefs } from './types';
/**
* Used to infer types for a standalone ApiFactory that isn't immediately passed
* Used to infer types for a standalone {@link ApiFactory} that isn't immediately passed
* to another function.
*
* @remarks
*
* This function doesn't actually do anything, it's only used to infer types.
*
* @public
*/
export function createApiFactory<
Api,
Impl extends Api,
Deps extends { [name in string]: unknown },
>(factory: ApiFactory<Api, Impl, Deps>): ApiFactory<Api, Impl, Deps>;
/**
* Used to infer types for a standalone {@link ApiFactory} that isn't immediately passed
* to another function.
*
* @param api - Ref of the API that will be produced by the factory.
* @param instance - Implementation of the API to use.
* @public
*/
export function createApiFactory<Api, Impl extends Api>(
api: ApiRef<Api>,
instance: Impl,
): ApiFactory<Api, Impl, {}>;
/**
* Used to infer types for a standalone {@link ApiFactory} that isn't immediately passed
* to another function.
*
* @remarks
*
* Creates factory from {@link ApiRef} or returns the factory itself if provided.
*
* @param factory - Existing factory or {@link ApiRef}.
* @param instance - The instance to be returned by the factory.
* @public
*/
export function createApiFactory<
Api,
Impl extends Api,
@@ -16,5 +16,6 @@
export { useApi, useApiHolder, withApis } from './useApi';
export { createApiRef } from './ApiRef';
export type { ApiRefConfig } from './ApiRef';
export * from './types';
export * from './helpers';
@@ -14,25 +14,62 @@
* limitations under the License.
*/
/**
* API reference.
*
* @public
*/
export type ApiRef<T> = {
id: string;
T: T;
};
/**
* Catch-all {@link ApiRef} type.
*
* @public
*/
export type AnyApiRef = ApiRef<unknown>;
/**
* Transforms ApiRef type into its inner API type.
*
* @public
*/
export type ApiRefType<T> = T extends ApiRef<infer U> ? U : never;
/**
* Wraps a type with API properties into a type holding their respective {@link ApiRef}s.
* Reverse type transform of {@link ApiRefsToTypes}.
*
* @public
*/
export type TypesToApiRefs<T> = { [key in keyof T]: ApiRef<T[key]> };
/**
* Unwraps type with {@link ApiRef} properties into a type holding their respective API types.
* Reverse type transform of {@link TypesToApiRefs}.
*
* @public
*/
export type ApiRefsToTypes<T extends { [key in string]: ApiRef<unknown> }> = {
[key in keyof T]: ApiRefType<T[key]>;
};
/**
* Provides lookup of APIs through their {@link ApiRef}s.
*
* @public
*/
export type ApiHolder = {
get<T>(api: ApiRef<T>): T | undefined;
};
/**
* Describes type returning API implementations.
*
* @public
*/
export type ApiFactory<
Api,
Impl extends Api,
@@ -43,6 +80,11 @@ export type ApiFactory<
factory(deps: Deps): Impl;
};
/**
* Catch-all {@link ApiFactory} type.
*
* @public
*/
export type AnyApiFactory = ApiFactory<
unknown,
unknown,
@@ -18,6 +18,11 @@ import React, { PropsWithChildren } from 'react';
import { ApiRef, ApiHolder, TypesToApiRefs } from './types';
import { useVersionedContext } from '@backstage/version-bridge';
/**
* React hook for retrieving {@link ApiHolder}, an API catalog.
*
* @public
*/
export function useApiHolder(): ApiHolder {
const versionedHolder = useVersionedContext<{ 1: ApiHolder }>('api-context');
if (!versionedHolder) {
@@ -31,6 +36,12 @@ export function useApiHolder(): ApiHolder {
return apiHolder;
}
/**
* React hook for retrieving APIs.
*
* @param apiRef - Reference of the API to use.
* @public
*/
export function useApi<T>(apiRef: ApiRef<T>): T {
const apiHolder = useApiHolder();
@@ -41,6 +52,12 @@ export function useApi<T>(apiRef: ApiRef<T>): T {
return api;
}
/**
* Wrapper for giving component an API context.
*
* @param apis - APIs for the context.
* @public
*/
export function withApis<T>(apis: TypesToApiRefs<T>) {
return function withApisWrapper<P extends T>(
WrappedComponent: React.ComponentType<P>,
+30
View File
@@ -19,11 +19,21 @@ import { ProfileInfo } from '../apis/definitions';
import { IconComponent } from '../icons';
import { BackstagePlugin } from '../plugin/types';
/**
* Props for the BootErrorPage.
*
* @public
*/
export type BootErrorPageProps = {
step: 'load-config' | 'load-chunk';
error: Error;
};
/**
* Data and handlers associated with the user sign in event.
*
* @public
*/
export type SignInResult = {
/**
* User ID that will be returned by the IdentityApi
@@ -43,6 +53,11 @@ export type SignInResult = {
signOut?: () => Promise<void>;
};
/**
* Props for the SignInPage.
*
* @public
*/
export type SignInPageProps = {
/**
* Set the sign-in result for the app. This should only be called once.
@@ -50,12 +65,22 @@ export type SignInPageProps = {
onResult(result: SignInResult): void;
};
/**
* Props for the ErrorBoundaryFallback.
*
* @public
*/
export type ErrorBoundaryFallbackProps = {
plugin?: BackstagePlugin;
error: Error;
resetError: () => void;
};
/**
* Basic app components.
*
* @public
*/
export type AppComponents = {
NotFoundErrorPage: ComponentType<{}>;
BootErrorPage: ComponentType<BootErrorPageProps>;
@@ -75,6 +100,11 @@ export type AppComponents = {
SignInPage?: ComponentType<SignInPageProps>;
};
/**
* Provides plugins and components registered in the app.
*
* @public
*/
export type AppContext = {
/**
* Get a list of all plugins that are installed in the app.
@@ -17,6 +17,11 @@
import { useVersionedContext } from '@backstage/version-bridge';
import { AppContext as AppContextV1 } from './types';
/**
* React hook providing {@link AppContext}.
*
* @public
*/
export const useApp = (): AppContextV1 => {
const versionedContext =
useVersionedContext<{ 1: AppContextV1 }>('app-context');
@@ -39,8 +39,9 @@ export type Subscription = CoreSubscription;
/**
* Observable sequence of values and errors, see TC39.
*
* https://github.com/tc39/proposal-observable
* @remarks
*
* {@link https://github.com/tc39/proposal-observable}
* This is used as a common return type for observable values and can be created
* using many different observable implementations, such as zen-observable or RxJS 5.
*
@@ -41,6 +41,18 @@ type MaybeComponentNode = ReactNode & {
type?: ComponentWithData;
};
/**
* Stores data related to a component in a global store.
*
* @remarks
*
* See {@link https://backstage.io/docs/plugins/composability#component-data}.
*
* @param component - The component to attach the data to.
* @param type - The key under which the data will be stored.
* @param data - Arbitrary value.
* @public
*/
export function attachComponentData<P>(
component: ComponentType<P>,
type: string,
@@ -70,6 +82,18 @@ export function attachComponentData<P>(
container.map.set(type, data);
}
/**
* Retrieves data attached to a component.
*
* @remarks
*
* See {@link https://backstage.io/docs/plugins/composability#component-data}.
*
* @param node - React component to look up.
* @param type - Key of the data to retrieve.
* @returns Data stored using {@link attachComponentData}.
* @public
*/
export function getComponentData<T>(
node: ReactNode,
type: string,
@@ -22,7 +22,12 @@ import { attachComponentData } from './componentData';
import { Extension, BackstagePlugin } from '../plugin/types';
import { PluginErrorBoundary } from './PluginErrorBoundary';
type ComponentLoader<T> =
/**
* Lazy or synchronous retrieving of extension components.
*
* @public
*/
export type ComponentLoader<T> =
| {
lazy: () => Promise<T>;
}
@@ -30,9 +35,19 @@ type ComponentLoader<T> =
sync: T;
};
// We do not use ComponentType as the return type, since it doesn't let us convey the children prop.
// ComponentType inserts children as an optional prop whether the inner component accepts it or not,
// making it impossible to make the usage of children type safe.
/**
* Extension for components that can have its own URL route (top-level pages, tabs etc.).
*
* @remarks
*
* We do not use ComponentType as the return type, since it doesn't let us convey the children prop.
* ComponentType inserts children as an optional prop whether the inner component accepts it or not,
* making it impossible to make the usage of children type safe.
*
* See {@link https://backstage.io/docs/plugins/composability#extensions}.
*
* @public
*/
export function createRoutableExtension<
T extends (props: any) => JSX.Element | null,
>(options: {
@@ -97,9 +112,19 @@ export function createRoutableExtension<
});
}
// We do not use ComponentType as the return type, since it doesn't let us convey the children prop.
// ComponentType inserts children as an optional prop whether the inner component accepts it or not,
// making it impossible to make the usage of children type safe.
/**
* Plain React component extension.
*
* @remarks
*
* We do not use ComponentType as the return type, since it doesn't let us convey the children prop.
* ComponentType inserts children as an optional prop whether the inner component accepts it or not,
* making it impossible to make the usage of children type safe.
*
* See {@link https://backstage.io/docs/plugins/composability#extensions}.
*
* @public
*/
export function createComponentExtension<
T extends (props: any) => JSX.Element | null,
>(options: { component: ComponentLoader<T>; name?: string }): Extension<T> {
@@ -107,9 +132,19 @@ export function createComponentExtension<
return createReactExtension({ component, name });
}
// We do not use ComponentType as the return type, since it doesn't let us convey the children prop.
// ComponentType inserts children as an optional prop whether the inner component accepts it or not,
// making it impossible to make the usage of children type safe.
/**
* Used by {@link createComponentExtension} and {@link createRoutableExtension}.
*
* @remarks
*
* We do not use ComponentType as the return type, since it doesn't let us convey the children prop.
* ComponentType inserts children as an optional prop whether the inner component accepts it or not,
* making it impossible to make the usage of children type safe.
*
* See {@link https://backstage.io/docs/plugins/composability#extensions}.
*
* @public
*/
export function createReactExtension<
T extends (props: any) => JSX.Element | null,
>(options: {
@@ -20,5 +20,6 @@ export {
createRoutableExtension,
createComponentExtension,
} from './extensions';
export type { ComponentLoader } from './extensions';
export { useElementFilter } from './useElementFilter';
export type { ElementCollection } from './useElementFilter';
@@ -82,17 +82,23 @@ function selectChildren(
* A querying interface tailored to traversing a set of selected React elements
* and extracting data.
*
* @remarks
*
* Methods prefixed with `selectBy` are used to narrow the set of selected elements.
*
* Methods prefixed with `find` return concrete data using a deep traversal of the set.
*
* Methods prefixed with `get` return concrete data using a shallow traversal of the set.
*
* @public
*/
export interface ElementCollection {
/**
* Narrows the set of selected components by doing a deep traversal and
* only including those that have defined component data for the given `key`.
*
* @remarks
*
* Whether an element in the tree has component data set for the given key
* is determined by whether `getComponentData` returns undefined.
*
@@ -104,6 +110,8 @@ export interface ElementCollection {
* If `withStrictError` is set, the resulting selection must be a full match, meaning
* there may be no elements that were excluded in the selection. If the selection
* is not a clean match, an error will be throw with `withStrictError` as the message.
*
* @param query - Filtering query.
*/
selectByComponentData(query: {
key: string;
@@ -113,6 +121,8 @@ export interface ElementCollection {
/**
* Finds all elements using the same criteria as `selectByComponentData`, but
* returns the actual component data of each of those elements instead.
*
* @param query - Lookup query.
*/
findComponentData<T>(query: { key: string }): T[];
@@ -163,7 +173,11 @@ class Collection implements ElementCollection {
/**
* useElementFilter is a utility that helps you narrow down and retrieve data
* from a React element tree, typically operating on the `children` property
* passed in to a component. A common use-case is to construct declarative APIs
* passed in to a component.
*
* @remarks
*
* A common use-case is to construct declarative APIs
* where a React component defines its behavior based on its children, such as
* the relationship between `Routes` and `Route` in `react-router`.
*
@@ -175,6 +189,8 @@ class Collection implements ElementCollection {
* with added memoization based on the input `node`. If further memoization
* dependencies are used in the filter function, they should be added to the
* third `dependencies` argument, just like `useMemo`, `useEffect`, etc.
*
* @public
*/
export function useElementFilter<T>(
node: ReactNode,
+1 -1
View File
@@ -14,4 +14,4 @@
* limitations under the License.
*/
export type { IconComponent } from './types';
export type { IconComponent, OldIconComponent } from './types';
@@ -21,6 +21,8 @@ import { SvgIconProps } from '@material-ui/core';
* IconComponent is the common icon type used throughout Backstage when
* working with and rendering generic icons, including the app system icons.
*
* @remarks
*
* The type is based on SvgIcon from MUI, but both do not what the plugin-api
* package to have a dependency on MUI, nor do we want the props to be as broad
* as the SvgIconProps interface.
@@ -28,6 +30,8 @@ import { SvgIconProps } from '@material-ui/core';
* If you have the need to forward additional props from SvgIconProps, you can
* open an issue or submit a PR to the main Backstage repo. When doing so please
* also describe your use-case and reasoning of the addition.
*
* @public
*/
export type IconComponent = ComponentType<{
fontSize?: 'default' | 'small' | 'large';
@@ -37,5 +41,7 @@ export type IconComponent = ComponentType<{
* This exists for backwards compatibility with the old core package.
* It's used in some parts of this package in order to smooth out the
* migration, but it is not exported.
*
* @public
*/
export type OldIconComponent = ComponentType<SvgIconProps>;
@@ -24,6 +24,9 @@ import {
} from './types';
import { AnyApiFactory } from '../apis';
/**
* @internal
*/
export class PluginImpl<
Routes extends AnyRoutes,
ExternalRoutes extends AnyExternalRoutes,
@@ -80,6 +83,12 @@ export class PluginImpl<
}
}
/**
* Creates Backstage Plugin from config.
*
* @param config - Plugin configuration.
* @public
*/
export function createPlugin<
Routes extends AnyRoutes = {},
ExternalRoutes extends AnyExternalRoutes = {},
@@ -16,6 +16,8 @@
export { createPlugin } from './Plugin';
export type {
AnyExternalRoutes,
AnyRoutes,
BackstagePlugin,
Extension,
FeatureFlagOutput,
+59 -1
View File
@@ -17,29 +17,72 @@
import { RouteRef, SubRouteRef, ExternalRouteRef } from '../routing';
import { AnyApiFactory } from '../apis/system';
/**
* Route configuration.
*
* @public
*/
export type RouteOptions = {
// Whether the route path must match exactly, defaults to true.
exact?: boolean;
};
/**
* Type alias for paths.
*
* @public
*/
export type RoutePath = string;
// Replace with using RouteRefs
/**
* Replace with using {@link RouteRef}s.
*
* @public
*/
export type FeatureFlagOutput = {
type: 'feature-flag';
name: string;
};
/**
* {@link FeatureFlagOutput} type.
*
* @public
*/
export type PluginOutput = FeatureFlagOutput;
/**
* Plugin extension type.
*
* @remarks
*
* See {@link https://backstage.io/docs/plugins/composability#extensions}.
*
* @public
*/
export type Extension<T> = {
expose(plugin: BackstagePlugin<any, any>): T;
};
/**
* Catch-all route type.
*
* @public
*/
export type AnyRoutes = { [name: string]: RouteRef | SubRouteRef };
/**
* Catch-all type for {@link ExternalRouteRef}s.
*
* @public
*/
export type AnyExternalRoutes = { [name: string]: ExternalRouteRef };
/**
* Plugin type.
*
* @public
*/
export type BackstagePlugin<
Routes extends AnyRoutes = {},
ExternalRoutes extends AnyExternalRoutes = {},
@@ -52,6 +95,11 @@ export type BackstagePlugin<
externalRoutes: ExternalRoutes;
};
/**
* Plugin descriptor type.
*
* @public
*/
export type PluginConfig<
Routes extends AnyRoutes,
ExternalRoutes extends AnyExternalRoutes,
@@ -63,10 +111,20 @@ export type PluginConfig<
externalRoutes?: ExternalRoutes;
};
/**
* Holds hooks registered by the plugin.
*
* @public
*/
export type PluginHooks = {
featureFlags: FeatureFlagsHooks;
};
/**
* Interface for registering feature flags hooks.
*
* @public
*/
export type FeatureFlagsHooks = {
register(name: string): void;
};
@@ -22,6 +22,9 @@ import {
OptionalParams,
} from './types';
/**
* @internal
*/
export class ExternalRouteRefImpl<
Params extends AnyParams,
Optional extends boolean,
@@ -42,6 +45,16 @@ export class ExternalRouteRefImpl<
}
}
/**
* Creates a route descriptor, to be later bound to a concrete route by the app. Used to implement cross-plugin route references.
*
* @remarks
*
* See {@link https://backstage.io/docs/plugins/composability#routing-system}.
*
* @param options - Description of the route reference to be created.
* @public
*/
export function createExternalRouteRef<
Params extends { [param in ParamKey]: string },
Optional extends boolean = false,
@@ -24,6 +24,10 @@ import {
import { OldIconComponent } from '../icons/types';
// TODO(Rugvip): Remove this in the next breaking release, it's exported but unused
/**
* @deprecated
* @internal
*/
export type RouteRefConfig<Params extends AnyParams> = {
params?: ParamKeys<Params>;
path?: string;
@@ -31,6 +35,9 @@ export type RouteRefConfig<Params extends AnyParams> = {
title: string;
};
/**
* @internal
*/
export class RouteRefImpl<Params extends AnyParams>
implements RouteRef<Params>
{
@@ -66,6 +73,12 @@ export class RouteRefImpl<Params extends AnyParams>
}
}
/**
* Create a {@link RouteRef} from a route descriptor.
*
* @param config - Description of the route reference to be created.
* @public
*/
export function createRouteRef<
// Params is the type that we care about and the one to be embedded in the route ref.
// For example, given the params ['name', 'kind'], Params will be {name: string, kind: string}
@@ -26,6 +26,9 @@ import {
// Should match the pattern in react-router
const PARAM_PATTERN = /^\w+$/;
/**
* @internal
*/
export class SubRouteRefImpl<Params extends AnyParams>
implements SubRouteRef<Params>
{
@@ -45,18 +48,34 @@ export class SubRouteRefImpl<Params extends AnyParams>
}
}
// These utility types help us infer a Param object type from a string path
// For example, `/foo/:bar/:baz` inferred to `{ bar: string, baz: string }`
type ParamPart<S extends string> = S extends `:${infer Param}` ? Param : never;
type ParamNames<S extends string> = S extends `${infer Part}/${infer Rest}`
? ParamPart<Part> | ParamNames<Rest>
: ParamPart<S>;
type PathParams<S extends string> = { [name in ParamNames<S>]: string };
/**
* Used in {@link PathParams} type declaration.
* @public
*/
export type ParamPart<S extends string> = S extends `:${infer Param}`
? Param
: never;
/**
* Merges a param object type with with an optional params type into a params object
* Used in {@link PathParams} type declaration.
* @public
*/
type MergeParams<
export type ParamNames<S extends string> =
S extends `${infer Part}/${infer Rest}`
? ParamPart<Part> | ParamNames<Rest>
: ParamPart<S>;
/**
* This utility type helps us infer a Param object type from a string path
* For example, `/foo/:bar/:baz` inferred to `{ bar: string, baz: string }`
* @public
*/
export type PathParams<S extends string> = { [name in ParamNames<S>]: string };
/**
* Merges a param object type with with an optional params type into a params object.
* @public
*/
export type MergeParams<
P1 extends { [param in string]: string },
P2 extends AnyParams,
> = (P1[keyof P1] extends never ? {} : P1) & (P2 extends undefined ? {} : P2);
@@ -64,14 +83,22 @@ type MergeParams<
/**
* Creates a SubRouteRef type given the desired parameters and parent route parameters.
* The parameters types are merged together while ensuring that there is no overlap between the two.
*
* @public
*/
type MakeSubRouteRef<
export type MakeSubRouteRef<
Params extends { [param in string]: string },
ParentParams extends AnyParams,
> = keyof Params & keyof ParentParams extends never
? SubRouteRef<OptionalParams<MergeParams<Params, ParentParams>>>
: never;
/**
* Create a {@link SubRouteRef} from a route descriptor.
*
* @param config - Description of the route reference to be created.
* @public
*/
export function createSubRouteRef<
Path extends string,
ParentParams extends AnyParams = never,
+16 -1
View File
@@ -14,9 +14,24 @@
* limitations under the License.
*/
export type { RouteRef, SubRouteRef, ExternalRouteRef } from './types';
export type {
AnyParams,
RouteRef,
SubRouteRef,
ExternalRouteRef,
OptionalParams,
ParamKeys,
RouteFunc,
} from './types';
export { createRouteRef } from './RouteRef';
export { createSubRouteRef } from './SubRouteRef';
export type {
MakeSubRouteRef,
MergeParams,
ParamNames,
ParamPart,
PathParams,
} from './SubRouteRef';
export { createExternalRouteRef } from './ExternalRouteRef';
export { useRouteRef } from './useRouteRef';
export { useRouteRefParams } from './useRouteRefParams';
+85 -14
View File
@@ -17,32 +17,70 @@
import { OldIconComponent } from '../icons/types';
import { getOrCreateGlobalSingleton } from '@backstage/version-bridge';
/**
* Catch-all type for route params.
*
* @public
*/
export type AnyParams = { [param in string]: string } | undefined;
/**
* Type describing the key type of a route parameter mapping.
*
* @public
*/
export type ParamKeys<Params extends AnyParams> = keyof Params extends never
? []
: (keyof Params)[];
/**
* Optional route params.
*
* @public
*/
export type OptionalParams<Params extends { [param in string]: string }> =
Params[keyof Params] extends never ? undefined : Params;
// The extra TS magic here is to require a single params argument if the RouteRef
// had at least one param defined, but require 0 arguments if there are no params defined.
// Without this we'd have to pass in empty object to all parameter-less RouteRefs
// just to make TypeScript happy, or we would have to make the argument optional in
// which case you might forget to pass it in when it is actually required.
/**
* TS magic for handling route parameters.
*
* @remarks
*
* The extra TS magic here is to require a single params argument if the RouteRef
* had at least one param defined, but require 0 arguments if there are no params defined.
* Without this we'd have to pass in empty object to all parameter-less RouteRefs
* just to make TypeScript happy, or we would have to make the argument optional in
* which case you might forget to pass it in when it is actually required.
*
* @public
*/
export type RouteFunc<Params extends AnyParams> = (
...[params]: Params extends undefined ? readonly [] : readonly [Params]
) => string;
// This symbol is what we use at runtime to determine whether a given object
// is a type of RouteRef or not. It doesn't work well in TypeScript though since
// the `unique symbol` will refer to different values between package versions.
// For that reason we use the marker $$routeRefType to represent the symbol at
// compile-time instead of using the symbol directly.
/**
* This symbol is what we use at runtime to determine whether a given object
* is a type of RouteRef or not. It doesn't work well in TypeScript though since
* the `unique symbol` will refer to different values between package versions.
* For that reason we use the marker $$routeRefType to represent the symbol at
* compile-time instead of using the symbol directly.
*
* @internal
*/
export const routeRefType: unique symbol = getOrCreateGlobalSingleton<any>(
'route-ref-type',
() => Symbol('route-ref-type'),
);
/**
* Absolute route reference.
*
* @remarks
*
* See {@link https://backstage.io/docs/plugins/composability#routing-system}.
*
* @public
*/
export type RouteRef<Params extends AnyParams = any> = {
$$routeRefType: 'absolute'; // See routeRefType above
@@ -57,6 +95,15 @@ export type RouteRef<Params extends AnyParams = any> = {
title?: string;
};
/**
* Descriptor of a route relative to an absolute {@link RouteRef}.
*
* @remarks
*
* See {@link https://backstage.io/docs/plugins/composability#routing-system}.
*
* @public
*/
export type SubRouteRef<Params extends AnyParams = any> = {
$$routeRefType: 'sub'; // See routeRefType above
@@ -67,6 +114,15 @@ export type SubRouteRef<Params extends AnyParams = any> = {
params: ParamKeys<Params>;
};
/**
* Route descriptor, to be later bound to a concrete route by the app. Used to implement cross-plugin route references.
*
* @remarks
*
* See {@link https://backstage.io/docs/plugins/composability#routing-system}.
*
* @public
*/
export type ExternalRouteRef<
Params extends AnyParams = any,
Optional extends boolean = any,
@@ -78,20 +134,35 @@ export type ExternalRouteRef<
optional?: Optional;
};
/**
* @internal
*/
export type AnyRouteRef =
| RouteRef<any>
| SubRouteRef<any>
| ExternalRouteRef<any, any>;
// TODO(Rugvip): None of these should be found in the wild anymore, remove in next minor release
/** @deprecated */
/**
* @deprecated
* @internal
*/
export type ConcreteRoute = {};
/** @deprecated */
/**
* @deprecated
* @internal
*/
export type AbsoluteRouteRef = RouteRef<{}>;
/** @deprecated */
/**
* @deprecated
* @internal
*/
export type MutableRouteRef = RouteRef<{}>;
// A duplicate of the react-router RouteObject, but with routeRef added
/**
* A duplicate of the react-router RouteObject, but with routeRef added
* @internal
*/
export interface BackstageRouteObject {
caseSensitive: boolean;
children?: BackstageRouteObject[];
@@ -25,6 +25,9 @@ import {
SubRouteRef,
} from './types';
/**
* @internal
*/
export interface RouteResolver {
resolve<Params extends AnyParams>(
anyRouteRef:
@@ -35,12 +38,47 @@ export interface RouteResolver {
): RouteFunc<Params> | undefined;
}
/**
* React hook for constructing URLs to routes.
*
* @remarks
*
* See {@link https://backstage.io/docs/plugins/composability#routing-system}
*
* @param routeRef - The ref to route that should be converted to URL.
* @returns A function that will in turn return the concrete URL of the `routeRef`.
* @public
*/
export function useRouteRef<Optional extends boolean, Params extends AnyParams>(
routeRef: ExternalRouteRef<Params, Optional>,
): Optional extends true ? RouteFunc<Params> | undefined : RouteFunc<Params>;
/**
* React hook for constructing URLs to routes.
*
* @remarks
*
* See {@link https://backstage.io/docs/plugins/composability#routing-system}
*
* @param routeRef - The ref to route that should be converted to URL.
* @returns A function that will in turn return the concrete URL of the `routeRef`.
* @public
*/
export function useRouteRef<Params extends AnyParams>(
routeRef: RouteRef<Params> | SubRouteRef<Params>,
): RouteFunc<Params>;
/**
* React hook for constructing URLs to routes.
*
* @remarks
*
* See {@link https://backstage.io/docs/plugins/composability#routing-system}
*
* @param routeRef - The ref to route that should be converted to URL.
* @returns A function that will in turn return the concrete URL of the `routeRef`.
* @public
*/
export function useRouteRef<Params extends AnyParams>(
routeRef:
| RouteRef<Params>
@@ -17,6 +17,11 @@
import { useParams } from 'react-router-dom';
import { RouteRef, AnyParams, SubRouteRef } from './types';
/**
* React hook for retrieving dynamic params from the current URL.
* @param _routeRef - Ref of the current route.
* @public
*/
export function useRouteRefParams<Params extends AnyParams>(
_routeRef: RouteRef<Params> | SubRouteRef<Params>,
): Params {