@backstage/backend-plugin-api 0.6.19-next.1 → 0.6.19-next.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,43 @@
1
1
  # @backstage/backend-plugin-api
2
2
 
3
+ ## 0.6.19-next.3
4
+
5
+ ### Patch Changes
6
+
7
+ - 9bdc3e8: In tests, return `null` rather than throwing an error when trying to get the `ExtensionPoint.T` property, so that tests asserting the property are not easily broken.
8
+ - b2ee7f3: Deprecated all of the `UrlReader` related type names and replaced them with prefixed versions. Please update your imports.
9
+
10
+ - `ReadTreeOptions` was renamed to `UrlReaderReadTreeOptions`
11
+ - `ReadTreeResponse` was renamed to `UrlReaderReadTreeResponse`
12
+ - `ReadTreeResponseDirOptions` was renamed to `UrlReaderReadTreeResponseDirOptions`
13
+ - `ReadTreeResponseFile` was renamed to `UrlReaderReadTreeResponseFile`
14
+ - `ReadUrlResponse` was renamed to `UrlReaderReadUrlResponse`
15
+ - `ReadUrlOptions` was renamed to `UrlReaderReadUrlOptions`
16
+ - `SearchOptions` was renamed to `UrlReaderSearchOptions`
17
+ - `SearchResponse` was renamed to `UrlReaderSearchResponse`
18
+ - `SearchResponseFile` was renamed to `UrlReaderSearchResponseFile`
19
+
20
+ - Updated dependencies
21
+ - @backstage/plugin-auth-node@0.4.14-next.3
22
+ - @backstage/plugin-permission-common@0.7.14-next.0
23
+ - @backstage/cli-common@0.1.14-next.0
24
+ - @backstage/config@1.2.0
25
+ - @backstage/errors@1.2.4
26
+ - @backstage/types@1.1.1
27
+
28
+ ## 0.6.19-next.2
29
+
30
+ ### Patch Changes
31
+
32
+ - 3aa3fc7: Marked the `TokenManagerService` and `IdentityService` types as deprecated
33
+ - Updated dependencies
34
+ - @backstage/plugin-auth-node@0.4.14-next.2
35
+ - @backstage/cli-common@0.1.13
36
+ - @backstage/config@1.2.0
37
+ - @backstage/errors@1.2.4
38
+ - @backstage/types@1.1.1
39
+ - @backstage/plugin-permission-common@0.7.13
40
+
3
41
  ## 0.6.19-next.1
4
42
 
5
43
  ### Patch Changes
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/backend-plugin-api",
3
- "version": "0.6.19-next.1",
3
+ "version": "0.6.19-next.3",
4
4
  "main": "../dist/alpha.cjs.js",
5
5
  "types": "../dist/alpha.d.ts"
6
6
  }
package/dist/index.cjs.js CHANGED
@@ -129,6 +129,9 @@ function createExtensionPoint(options) {
129
129
  return {
130
130
  id: options.id,
131
131
  get T() {
132
+ if (process.env.NODE_ENV === "test") {
133
+ return null;
134
+ }
132
135
  throw new Error(`tried to read ExtensionPoint.T of ${this}`);
133
136
  },
134
137
  toString() {
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs.js","sources":["../src/services/system/types.ts","../src/services/definitions/coreServices.ts","../src/services/definitions/SchedulerService.ts","../src/services/utilities/database.ts","../src/wiring/factories.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { BackendFeature } from '../../types';\n\n/**\n * TODO\n *\n * @public\n */\nexport type ServiceRef<\n TService,\n TScope extends 'root' | 'plugin' = 'root' | 'plugin',\n> = {\n id: string;\n\n /**\n * This determines the scope at which this service is available.\n *\n * Root scoped services are available to all other services but\n * may only depend on other root scoped services.\n *\n * Plugin scoped services are only available to other plugin scoped\n * services but may depend on all other services.\n */\n scope: TScope;\n\n /**\n * Utility for getting the type of the service, using `typeof serviceRef.T`.\n * Attempting to actually read this value will result in an exception.\n */\n T: TService;\n\n $$type: '@backstage/ServiceRef';\n};\n\n/** @public */\nexport interface ServiceFactory<\n TService = unknown,\n TScope extends 'plugin' | 'root' = 'plugin' | 'root',\n> extends BackendFeature {\n service: ServiceRef<TService, TScope>;\n}\n\n/** @internal */\nexport interface InternalServiceFactory<\n TService = unknown,\n TScope extends 'plugin' | 'root' = 'plugin' | 'root',\n> extends ServiceFactory<TService, TScope> {\n version: 'v1';\n initialization?: 'always' | 'lazy';\n deps: { [key in string]: ServiceRef<unknown> };\n createRootContext?(deps: { [key in string]: unknown }): Promise<unknown>;\n factory(\n deps: { [key in string]: unknown },\n context: unknown,\n ): Promise<TService>;\n}\n\n/**\n * Represents either a {@link ServiceFactory} or a function that returns one.\n *\n * @public\n */\nexport type ServiceFactoryOrFunction = ServiceFactory | (() => ServiceFactory);\n\n/** @public */\nexport interface ServiceRefConfig<TService, TScope extends 'root' | 'plugin'> {\n id: string;\n scope?: TScope;\n defaultFactory?: (\n service: ServiceRef<TService, TScope>,\n ) => Promise<ServiceFactoryOrFunction>;\n}\n\n/**\n * Creates a new service definition. This overload is used to create plugin scoped services.\n *\n * @public\n */\nexport function createServiceRef<TService>(\n config: ServiceRefConfig<TService, 'plugin'>,\n): ServiceRef<TService, 'plugin'>;\n\n/**\n * Creates a new service definition. This overload is used to create root scoped services.\n *\n * @public\n */\nexport function createServiceRef<TService>(\n config: ServiceRefConfig<TService, 'root'>,\n): ServiceRef<TService, 'root'>;\nexport function createServiceRef<TService>(\n config: ServiceRefConfig<TService, any>,\n): ServiceRef<TService, any> {\n const { id, scope = 'plugin', defaultFactory } = config;\n return {\n id,\n scope,\n get T(): TService {\n throw new Error(`tried to read ServiceRef.T of ${this}`);\n },\n toString() {\n return `serviceRef{${config.id}}`;\n },\n $$type: '@backstage/ServiceRef',\n __defaultFactory: defaultFactory,\n } as ServiceRef<TService, typeof scope> & {\n __defaultFactory?: (\n service: ServiceRef<TService>,\n ) => Promise<ServiceFactory<TService> | (() => ServiceFactory<TService>)>;\n };\n}\n\n/** @ignore */\ntype ServiceRefsToInstances<\n T extends { [key in string]: ServiceRef<unknown> },\n TScope extends 'root' | 'plugin' = 'root' | 'plugin',\n> = {\n [key in keyof T as T[key]['scope'] extends TScope ? key : never]: T[key]['T'];\n};\n\n/** @public */\nexport interface RootServiceFactoryConfig<\n TService,\n TImpl extends TService,\n TDeps extends { [name in string]: ServiceRef<unknown> },\n> {\n /**\n * The initialization strategy for the service factory. This service is root scoped and will use `always` by default.\n *\n * @remarks\n *\n * - `always` - The service will always be initialized regardless if it is used or not.\n * - `lazy` - The service will only be initialized if it is depended on by a different service or feature.\n *\n * Service factories for root scoped services use `always` as the default, while plugin scoped services use `lazy`.\n */\n initialization?: 'always' | 'lazy';\n service: ServiceRef<TService, 'root'>;\n deps: TDeps;\n factory(deps: ServiceRefsToInstances<TDeps, 'root'>): TImpl | Promise<TImpl>;\n}\n\n/** @public */\nexport interface PluginServiceFactoryConfig<\n TService,\n TContext,\n TImpl extends TService,\n TDeps extends { [name in string]: ServiceRef<unknown> },\n> {\n /**\n * The initialization strategy for the service factory. This service is plugin scoped and will use `lazy` by default.\n *\n * @remarks\n *\n * - `always` - The service will always be initialized regardless if it is used or not.\n * - `lazy` - The service will only be initialized if it is depended on by a different service or feature.\n *\n * Service factories for root scoped services use `always` as the default, while plugin scoped services use `lazy`.\n */\n initialization?: 'always' | 'lazy';\n service: ServiceRef<TService, 'plugin'>;\n deps: TDeps;\n createRootContext?(\n deps: ServiceRefsToInstances<TDeps, 'root'>,\n ): TContext | Promise<TContext>;\n factory(\n deps: ServiceRefsToInstances<TDeps>,\n context: TContext,\n ): TImpl | Promise<TImpl>;\n}\n\n/**\n * Creates a root scoped service factory without options.\n *\n * @public\n * @param config - The service factory configuration.\n */\nexport function createServiceFactory<\n TService,\n TImpl extends TService,\n TDeps extends { [name in string]: ServiceRef<unknown, 'root'> },\n TOpts extends object | undefined = undefined,\n>(\n config: RootServiceFactoryConfig<TService, TImpl, TDeps>,\n): () => ServiceFactory<TService, 'root'>;\n/**\n * Creates a root scoped service factory with optional options.\n *\n * @public\n * @param config - The service factory configuration.\n */\nexport function createServiceFactory<\n TService,\n TImpl extends TService,\n TDeps extends { [name in string]: ServiceRef<unknown, 'root'> },\n TOpts extends object | undefined = undefined,\n>(\n config: (options?: TOpts) => RootServiceFactoryConfig<TService, TImpl, TDeps>,\n): (options?: TOpts) => ServiceFactory<TService, 'root'>;\n/**\n * Creates a plugin scoped service factory without options.\n *\n * @public\n * @param config - The service factory configuration.\n */\nexport function createServiceFactory<\n TService,\n TImpl extends TService,\n TDeps extends { [name in string]: ServiceRef<unknown> },\n TContext = undefined,\n TOpts extends object | undefined = undefined,\n>(\n config: PluginServiceFactoryConfig<TService, TContext, TImpl, TDeps>,\n): () => ServiceFactory<TService, 'plugin'>;\n/**\n * Creates a plugin scoped service factory with optional options.\n *\n * @public\n * @param config - The service factory configuration.\n */\nexport function createServiceFactory<\n TService,\n TImpl extends TService,\n TDeps extends { [name in string]: ServiceRef<unknown> },\n TContext = undefined,\n TOpts extends object | undefined = undefined,\n>(\n config: (\n options?: TOpts,\n ) => PluginServiceFactoryConfig<TService, TContext, TImpl, TDeps>,\n): (options?: TOpts) => ServiceFactory<TService, 'plugin'>;\nexport function createServiceFactory<\n TService,\n TImpl extends TService,\n TDeps extends { [name in string]: ServiceRef<unknown> },\n TContext,\n TOpts extends object | undefined = undefined,\n>(\n config:\n | RootServiceFactoryConfig<TService, TImpl, TDeps>\n | PluginServiceFactoryConfig<TService, TContext, TImpl, TDeps>\n | ((options: TOpts) => RootServiceFactoryConfig<TService, TImpl, TDeps>)\n | ((\n options: TOpts,\n ) => PluginServiceFactoryConfig<TService, TContext, TImpl, TDeps>)\n | (() => RootServiceFactoryConfig<TService, TImpl, TDeps>)\n | (() => PluginServiceFactoryConfig<TService, TContext, TImpl, TDeps>),\n): (options: TOpts) => ServiceFactory {\n const configCallback = typeof config === 'function' ? config : () => config;\n const factory = (\n options: TOpts,\n ): InternalServiceFactory<TService, 'plugin' | 'root'> => {\n const anyConf = configCallback(options);\n if (anyConf.service.scope === 'root') {\n const c = anyConf as RootServiceFactoryConfig<TService, TImpl, TDeps>;\n return {\n $$type: '@backstage/BackendFeature',\n version: 'v1',\n service: c.service,\n initialization: c.initialization,\n deps: c.deps,\n factory: async (deps: TDeps) => c.factory(deps),\n };\n }\n const c = anyConf as PluginServiceFactoryConfig<\n TService,\n TContext,\n TImpl,\n TDeps\n >;\n return {\n $$type: '@backstage/BackendFeature',\n version: 'v1',\n service: c.service,\n initialization: c.initialization,\n ...('createRootContext' in c\n ? {\n createRootContext: async (deps: TDeps) =>\n c?.createRootContext?.(deps),\n }\n : {}),\n deps: c.deps,\n factory: async (deps: TDeps, ctx: TContext) => c.factory(deps, ctx),\n };\n };\n\n factory.$$type = '@backstage/BackendFeatureFactory';\n\n return factory;\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { createServiceRef } from '../system';\n\n/**\n * All core services references\n *\n * @public\n */\nexport namespace coreServices {\n /**\n * The service reference for the plugin scoped {@link AuthService}.\n *\n * @public\n */\n export const auth = createServiceRef<import('./AuthService').AuthService>({\n id: 'core.auth',\n });\n\n /**\n * The service reference for the plugin scoped {@link UserInfoService}.\n *\n * @public\n */\n export const userInfo = createServiceRef<\n import('./UserInfoService').UserInfoService\n >({\n id: 'core.userInfo',\n });\n\n /**\n * The service reference for the plugin scoped {@link CacheService}.\n *\n * @public\n */\n export const cache = createServiceRef<import('./CacheService').CacheService>({\n id: 'core.cache',\n });\n\n /**\n * The service reference for the root scoped {@link RootConfigService}.\n *\n * @public\n */\n export const rootConfig = createServiceRef<\n import('./RootConfigService').RootConfigService\n >({ id: 'core.rootConfig', scope: 'root' });\n\n /**\n * The service reference for the plugin scoped {@link DatabaseService}.\n *\n * @public\n */\n export const database = createServiceRef<\n import('./DatabaseService').DatabaseService\n >({ id: 'core.database' });\n\n /**\n * The service reference for the plugin scoped {@link DiscoveryService}.\n *\n * @public\n */\n export const discovery = createServiceRef<\n import('./DiscoveryService').DiscoveryService\n >({ id: 'core.discovery' });\n\n /**\n * The service reference for the plugin scoped {@link HttpAuthService}.\n *\n * @public\n */\n export const httpAuth = createServiceRef<\n import('./HttpAuthService').HttpAuthService\n >({ id: 'core.httpAuth' });\n\n /**\n * The service reference for the plugin scoped {@link HttpRouterService}.\n *\n * @public\n */\n export const httpRouter = createServiceRef<\n import('./HttpRouterService').HttpRouterService\n >({ id: 'core.httpRouter' });\n\n /**\n * The service reference for the plugin scoped {@link LifecycleService}.\n *\n * @public\n */\n export const lifecycle = createServiceRef<\n import('./LifecycleService').LifecycleService\n >({ id: 'core.lifecycle' });\n\n /**\n * The service reference for the plugin scoped {@link LoggerService}.\n *\n * @public\n */\n export const logger = createServiceRef<\n import('./LoggerService').LoggerService\n >({ id: 'core.logger' });\n\n /**\n * The service reference for the plugin scoped {@link PermissionsService}.\n *\n * @public\n */\n export const permissions = createServiceRef<\n import('./PermissionsService').PermissionsService\n >({ id: 'core.permissions' });\n\n /**\n * The service reference for the plugin scoped {@link PluginMetadataService}.\n *\n * @public\n */\n export const pluginMetadata = createServiceRef<\n import('./PluginMetadataService').PluginMetadataService\n >({ id: 'core.pluginMetadata' });\n\n /**\n * The service reference for the root scoped {@link RootHttpRouterService}.\n *\n * @public\n */\n export const rootHttpRouter = createServiceRef<\n import('./RootHttpRouterService').RootHttpRouterService\n >({ id: 'core.rootHttpRouter', scope: 'root' });\n\n /**\n * The service reference for the root scoped {@link RootLifecycleService}.\n *\n * @public\n */\n export const rootLifecycle = createServiceRef<\n import('./RootLifecycleService').RootLifecycleService\n >({ id: 'core.rootLifecycle', scope: 'root' });\n\n /**\n * The service reference for the root scoped {@link RootLoggerService}.\n *\n * @public\n */\n export const rootLogger = createServiceRef<\n import('./RootLoggerService').RootLoggerService\n >({ id: 'core.rootLogger', scope: 'root' });\n\n /**\n * The service reference for the plugin scoped {@link SchedulerService}.\n *\n * @public\n */\n export const scheduler = createServiceRef<\n import('./SchedulerService').SchedulerService\n >({ id: 'core.scheduler' });\n\n /**\n * The service reference for the plugin scoped {@link TokenManagerService}.\n *\n * @public\n * @deprecated Please migrate to the new `coreServices.auth`, `coreServices.httpAuth`, and `coreServices.userInfo` services as needed instead\n */\n export const tokenManager = createServiceRef<\n import('./TokenManagerService').TokenManagerService\n >({ id: 'core.tokenManager' });\n\n /**\n * The service reference for the plugin scoped {@link UrlReaderService}.\n *\n * @public\n */\n export const urlReader = createServiceRef<\n import('./UrlReaderService').UrlReaderService\n >({ id: 'core.urlReader' });\n\n /**\n * The service reference for the plugin scoped {@link IdentityService}.\n *\n * @public\n * @deprecated Please migrate to the new `coreServices.auth`, `coreServices.httpAuth`, and `coreServices.userInfo` services as needed instead\n */\n export const identity = createServiceRef<\n import('./IdentityService').IdentityService\n >({ id: 'core.identity' });\n}\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Config, readDurationFromConfig } from '@backstage/config';\nimport { HumanDuration, JsonObject } from '@backstage/types';\nimport { Duration } from 'luxon';\n\n/**\n * A function that can be called as a scheduled task.\n *\n * It may optionally accept an abort signal argument. When the signal triggers,\n * processing should abort and return as quickly as possible.\n *\n * @public\n */\nexport type SchedulerServiceTaskFunction =\n | ((abortSignal: AbortSignal) => void | Promise<void>)\n | (() => void | Promise<void>);\n\n/**\n * A semi-opaque type to describe an actively scheduled task.\n *\n * @public\n */\nexport type SchedulerServiceTaskDescriptor = {\n /**\n * The unique identifier of the task.\n */\n id: string;\n /**\n * The scope of the task.\n */\n scope: 'global' | 'local';\n /**\n * The settings that control the task flow. This is a semi-opaque structure\n * that is mainly there for debugging purposes. Do not make any assumptions\n * about the contents of this field.\n */\n settings: { version: number } & JsonObject;\n};\n\n/**\n * Options that control the scheduling of a task.\n *\n * @public\n */\nexport interface SchedulerServiceTaskScheduleDefinition {\n /**\n * How often you want the task to run. The system does its best to avoid\n * overlapping invocations.\n *\n * @remarks\n *\n * This is the best effort value; under some circumstances there can be\n * deviations. For example, if the task runtime is longer than the frequency\n * and the timeout has not been given or not been exceeded yet, the next\n * invocation of this task will be delayed until after the previous one\n * finishes.\n *\n * This is a required field.\n */\n frequency:\n | {\n /**\n * A crontab style string.\n *\n * @remarks\n *\n * Overview:\n *\n * ```\n * ┌────────────── second (optional)\n * │ ┌──────────── minute\n * │ │ ┌────────── hour\n * │ │ │ ┌──────── day of month\n * │ │ │ │ ┌────── month\n * │ │ │ │ │ ┌──── day of week\n * │ │ │ │ │ │\n * │ │ │ │ │ │\n * * * * * * *\n * ```\n */\n cron: string;\n }\n | Duration\n | HumanDuration;\n\n /**\n * The maximum amount of time that a single task invocation can take, before\n * it's considered timed out and gets \"released\" such that a new invocation\n * is permitted to take place (possibly, then, on a different worker).\n */\n timeout: Duration | HumanDuration;\n\n /**\n * The amount of time that should pass before the first invocation happens.\n *\n * @remarks\n *\n * This can be useful in cold start scenarios to stagger or delay some heavy\n * compute jobs. If no value is given for this field then the first invocation\n * will happen as soon as possible according to the cadence.\n *\n * NOTE: This is a per-worker delay. If you have a cluster of workers all\n * collaborating on a task that has its `scope` field set to `'global'`, then\n * you may still see the task being processed by other long-lived workers,\n * while any given single worker is in its initial sleep delay time e.g. after\n * a deployment. Therefore, this parameter is not useful for \"globally\" pausing\n * work; its main intended use is for individual machines to get a chance to\n * reach some equilibrium at startup before triggering heavy batch workloads.\n */\n initialDelay?: Duration | HumanDuration;\n\n /**\n * Sets the scope of concurrency control / locking to apply for invocations of\n * this task.\n *\n * @remarks\n *\n * When the scope is set to the default value `'global'`, the scheduler will\n * attempt to ensure that only one worker machine runs the task at a time,\n * according to the given cadence. This means that as the number of worker\n * hosts increases, the invocation frequency of this task will not go up.\n * Instead, the load is spread randomly across hosts. This setting is useful\n * for tasks that access shared resources, for example catalog ingestion tasks\n * where you do not want many machines to repeatedly import the same data and\n * trample over each other.\n *\n * When the scope is set to `'local'`, there is no concurrency control across\n * hosts. Each host runs the task according to the given cadence similarly to\n * `setInterval`, but the runtime ensures that there are no overlapping runs.\n *\n * @defaultValue 'global'\n */\n scope?: 'global' | 'local';\n}\n\n/**\n * Config options for {@link SchedulerServiceTaskScheduleDefinition}\n * that control the scheduling of a task.\n *\n * @public\n */\nexport interface SchedulerServiceTaskScheduleDefinitionConfig {\n /**\n * How often you want the task to run. The system does its best to avoid\n * overlapping invocations.\n *\n * @remarks\n *\n * This is the best effort value; under some circumstances there can be\n * deviations. For example, if the task runtime is longer than the frequency\n * and the timeout has not been given or not been exceeded yet, the next\n * invocation of this task will be delayed until after the previous one\n * finishes.\n *\n * This is a required field.\n */\n frequency:\n | {\n /**\n * A crontab style string.\n *\n * @remarks\n *\n * Overview:\n *\n * ```\n * ┌────────────── second (optional)\n * │ ┌──────────── minute\n * │ │ ┌────────── hour\n * │ │ │ ┌──────── day of month\n * │ │ │ │ ┌────── month\n * │ │ │ │ │ ┌──── day of week\n * │ │ │ │ │ │\n * │ │ │ │ │ │\n * * * * * * *\n * ```\n */\n cron: string;\n }\n | string\n | HumanDuration;\n\n /**\n * The maximum amount of time that a single task invocation can take, before\n * it's considered timed out and gets \"released\" such that a new invocation\n * is permitted to take place (possibly, then, on a different worker).\n */\n timeout: string | HumanDuration;\n\n /**\n * The amount of time that should pass before the first invocation happens.\n *\n * @remarks\n *\n * This can be useful in cold start scenarios to stagger or delay some heavy\n * compute jobs. If no value is given for this field then the first invocation\n * will happen as soon as possible according to the cadence.\n *\n * NOTE: This is a per-worker delay. If you have a cluster of workers all\n * collaborating on a task that has its `scope` field set to `'global'`, then\n * you may still see the task being processed by other long-lived workers,\n * while any given single worker is in its initial sleep delay time e.g. after\n * a deployment. Therefore, this parameter is not useful for \"globally\" pausing\n * work; its main intended use is for individual machines to get a chance to\n * reach some equilibrium at startup before triggering heavy batch workloads.\n */\n initialDelay?: string | HumanDuration;\n\n /**\n * Sets the scope of concurrency control / locking to apply for invocations of\n * this task.\n *\n * @remarks\n *\n * When the scope is set to the default value `'global'`, the scheduler will\n * attempt to ensure that only one worker machine runs the task at a time,\n * according to the given cadence. This means that as the number of worker\n * hosts increases, the invocation frequency of this task will not go up.\n * Instead, the load is spread randomly across hosts. This setting is useful\n * for tasks that access shared resources, for example catalog ingestion tasks\n * where you do not want many machines to repeatedly import the same data and\n * trample over each other.\n *\n * When the scope is set to `'local'`, there is no concurrency control across\n * hosts. Each host runs the task according to the given cadence similarly to\n * `setInterval`, but the runtime ensures that there are no overlapping runs.\n *\n * @defaultValue 'global'\n */\n scope?: 'global' | 'local';\n}\n\n/**\n * Options that apply to the invocation of a given task.\n *\n * @public\n */\nexport interface SchedulerServiceTaskInvocationDefinition {\n /**\n * A unique ID (within the scope of the plugin) for the task.\n */\n id: string;\n\n /**\n * The actual task function to be invoked regularly.\n */\n fn: SchedulerServiceTaskFunction;\n\n /**\n * An abort signal that, when triggered, will stop the recurring execution of\n * the task.\n */\n signal?: AbortSignal;\n}\n\n/**\n * A previously prepared task schedule, ready to be invoked.\n *\n * @public\n */\nexport interface SchedulerServiceTaskRunner {\n /**\n * Takes the schedule and executes an actual task using it.\n *\n * @param task - The actual runtime properties of the task\n */\n run(task: SchedulerServiceTaskInvocationDefinition): Promise<void>;\n}\n\n/**\n * Deals with the scheduling of distributed tasks, for a given plugin.\n *\n * @public\n */\nexport interface SchedulerService {\n /**\n * Manually triggers a task by ID.\n *\n * If the task doesn't exist, a NotFoundError is thrown. If the task is\n * currently running, a ConflictError is thrown.\n *\n * @param id - The task ID\n */\n triggerTask(id: string): Promise<void>;\n\n /**\n * Schedules a task function for recurring runs.\n *\n * @remarks\n *\n * The `scope` task field controls whether to use coordinated exclusive\n * invocation across workers, or to just coordinate within the current worker.\n *\n * This convenience method performs both the scheduling and invocation in one\n * go.\n *\n * @param task - The task definition\n */\n scheduleTask(\n task: SchedulerServiceTaskScheduleDefinition &\n SchedulerServiceTaskInvocationDefinition,\n ): Promise<void>;\n\n /**\n * Creates a scheduled but dormant recurring task, ready to be launched at a\n * later time.\n *\n * @remarks\n *\n * This method is useful for pre-creating a schedule in outer code to be\n * passed into an inner implementation, such that the outer code controls\n * scheduling while inner code controls implementation.\n *\n * @param schedule - The task schedule\n */\n createScheduledTaskRunner(\n schedule: SchedulerServiceTaskScheduleDefinition,\n ): SchedulerServiceTaskRunner;\n\n /**\n * Returns all scheduled tasks registered to this scheduler.\n *\n * @remarks\n *\n * This method is useful for triggering tasks manually using the triggerTask\n * functionality. Note that the returned tasks contain only tasks that have\n * been initialized in this instance of the scheduler.\n *\n * @returns Scheduled tasks\n */\n getScheduledTasks(): Promise<SchedulerServiceTaskDescriptor[]>;\n}\n\nfunction readDuration(config: Config, key: string): Duration | HumanDuration {\n if (typeof config.get(key) === 'string') {\n const value = config.getString(key);\n const duration = Duration.fromISO(value);\n if (!duration.isValid) {\n throw new Error(`Invalid duration: ${value}`);\n }\n return duration;\n }\n\n return readDurationFromConfig(config, { key });\n}\n\nfunction readCronOrDuration(\n config: Config,\n key: string,\n): { cron: string } | Duration | HumanDuration {\n const value = config.get(key);\n if (typeof value === 'object' && (value as { cron?: string }).cron) {\n return value as { cron: string };\n }\n\n return readDuration(config, key);\n}\n\n/**\n * Reads a {@link SchedulerServiceTaskScheduleDefinition} from config. Expects\n * the config not to be the root config, but the config for the definition.\n *\n * @param config - config for a TaskScheduleDefinition.\n * @public\n */\nexport function readSchedulerServiceTaskScheduleDefinitionFromConfig(\n config: Config,\n): SchedulerServiceTaskScheduleDefinition {\n const frequency = readCronOrDuration(config, 'frequency');\n const timeout = readDuration(config, 'timeout');\n\n const initialDelay = config.has('initialDelay')\n ? readDuration(config, 'initialDelay')\n : undefined;\n\n const scope = config.getOptionalString('scope');\n if (scope && !['global', 'local'].includes(scope)) {\n throw new Error(\n `Only \"global\" or \"local\" are allowed for TaskScheduleDefinition.scope, but got: ${scope}`,\n );\n }\n\n return {\n frequency,\n timeout,\n initialDelay,\n scope: scope as 'global' | 'local' | undefined,\n };\n}\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Tries to deduce whether a thrown error is a database conflict.\n *\n * @public\n * @param e - A thrown error\n * @returns True if the error looks like it was a conflict error thrown by a\n * known database engine\n */\nexport function isDatabaseConflictError(e: unknown) {\n const message = (e as any)?.message;\n\n return (\n typeof message === 'string' &&\n (/SQLITE_CONSTRAINT(?:_UNIQUE)?: UNIQUE/.test(message) ||\n /UNIQUE constraint failed:/.test(message) ||\n /unique constraint/.test(message) ||\n /Duplicate entry/.test(message)) // MySQL uniqueness error msg\n );\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { BackendFeature, BackendFeatureFactory } from '../types';\nimport {\n BackendModuleRegistrationPoints,\n BackendPluginRegistrationPoints,\n ExtensionPoint,\n InternalBackendModuleRegistration,\n InternalBackendPluginRegistration,\n} from './types';\n\n/**\n * The configuration options passed to {@link createExtensionPoint}.\n *\n * @public\n * @see {@link https://backstage.io/docs/backend-system/architecture/extension-points | The architecture of extension points}\n * @see {@link https://backstage.io/docs/backend-system/architecture/naming-patterns | Recommended naming patterns}\n */\nexport interface CreateExtensionPointOptions {\n /**\n * The ID of this extension point.\n *\n * @see {@link https://backstage.io/docs/backend-system/architecture/naming-patterns | Recommended naming patterns}\n */\n id: string;\n}\n\n/**\n * Creates a new backend extension point.\n *\n * @public\n * @see {@link https://backstage.io/docs/backend-system/architecture/extension-points | The architecture of extension points}\n */\nexport function createExtensionPoint<T>(\n options: CreateExtensionPointOptions,\n): ExtensionPoint<T> {\n return {\n id: options.id,\n get T(): T {\n throw new Error(`tried to read ExtensionPoint.T of ${this}`);\n },\n toString() {\n return `extensionPoint{${options.id}}`;\n },\n $$type: '@backstage/ExtensionPoint',\n };\n}\n\n/**\n * The configuration options passed to {@link createBackendPlugin}.\n *\n * @public\n * @see {@link https://backstage.io/docs/backend-system/architecture/plugins | The architecture of plugins}\n * @see {@link https://backstage.io/docs/backend-system/architecture/naming-patterns | Recommended naming patterns}\n */\nexport interface CreateBackendPluginOptions {\n /**\n * The ID of this plugin.\n *\n * @see {@link https://backstage.io/docs/backend-system/architecture/naming-patterns | Recommended naming patterns}\n */\n pluginId: string;\n register(reg: BackendPluginRegistrationPoints): void;\n}\n\n/**\n * Creates a new backend plugin.\n *\n * @public\n * @see {@link https://backstage.io/docs/backend-system/architecture/plugins | The architecture of plugins}\n * @see {@link https://backstage.io/docs/backend-system/architecture/naming-patterns | Recommended naming patterns}\n */\nexport function createBackendPlugin(\n options: CreateBackendPluginOptions,\n): () => BackendFeature {\n const factory: BackendFeatureFactory = () => {\n let registrations: InternalBackendPluginRegistration[];\n\n return {\n $$type: '@backstage/BackendFeature',\n version: 'v1',\n getRegistrations() {\n if (registrations) {\n return registrations;\n }\n const extensionPoints: InternalBackendPluginRegistration['extensionPoints'] =\n [];\n let init: InternalBackendPluginRegistration['init'] | undefined =\n undefined;\n\n options.register({\n registerExtensionPoint(ext, impl) {\n if (init) {\n throw new Error(\n 'registerExtensionPoint called after registerInit',\n );\n }\n extensionPoints.push([ext, impl]);\n },\n registerInit(regInit) {\n if (init) {\n throw new Error('registerInit must only be called once');\n }\n init = {\n deps: regInit.deps,\n func: regInit.init,\n };\n },\n });\n\n if (!init) {\n throw new Error(\n `registerInit was not called by register in ${options.pluginId}`,\n );\n }\n\n registrations = [\n {\n type: 'plugin',\n pluginId: options.pluginId,\n extensionPoints,\n init,\n },\n ];\n return registrations;\n },\n };\n };\n factory.$$type = '@backstage/BackendFeatureFactory';\n\n return factory;\n}\n\n/**\n * The configuration options passed to {@link createBackendModule}.\n *\n * @public\n * @see {@link https://backstage.io/docs/backend-system/architecture/modules | The architecture of modules}\n * @see {@link https://backstage.io/docs/backend-system/architecture/naming-patterns | Recommended naming patterns}\n */\nexport interface CreateBackendModuleOptions {\n /**\n * Should exactly match the `id` of the plugin that the module extends.\n *\n * @see {@link https://backstage.io/docs/backend-system/architecture/naming-patterns | Recommended naming patterns}\n */\n pluginId: string;\n\n /**\n * The ID of this module, used to identify the module and ensure that it is not installed twice.\n */\n moduleId: string;\n register(reg: BackendModuleRegistrationPoints): void;\n}\n\n/**\n * Creates a new backend module for a given plugin.\n *\n * @public\n * @see {@link https://backstage.io/docs/backend-system/architecture/modules | The architecture of modules}\n * @see {@link https://backstage.io/docs/backend-system/architecture/naming-patterns | Recommended naming patterns}\n */\nexport function createBackendModule(\n options: CreateBackendModuleOptions,\n): () => BackendFeature {\n const factory: BackendFeatureFactory = () => {\n let registrations: InternalBackendModuleRegistration[];\n\n return {\n $$type: '@backstage/BackendFeature',\n version: 'v1',\n getRegistrations() {\n if (registrations) {\n return registrations;\n }\n const extensionPoints: InternalBackendPluginRegistration['extensionPoints'] =\n [];\n let init: InternalBackendModuleRegistration['init'] | undefined =\n undefined;\n\n options.register({\n registerExtensionPoint(ext, impl) {\n if (init) {\n throw new Error(\n 'registerExtensionPoint called after registerInit',\n );\n }\n extensionPoints.push([ext, impl]);\n },\n registerInit(regInit) {\n if (init) {\n throw new Error('registerInit must only be called once');\n }\n init = {\n deps: regInit.deps,\n func: regInit.init,\n };\n },\n });\n\n if (!init) {\n throw new Error(\n `registerInit was not called by register in ${options.moduleId} module for ${options.pluginId}`,\n );\n }\n\n registrations = [\n {\n type: 'module',\n pluginId: options.pluginId,\n moduleId: options.moduleId,\n extensionPoints,\n init,\n },\n ];\n return registrations;\n },\n };\n };\n factory.$$type = '@backstage/BackendFeatureFactory';\n\n return factory;\n}\n"],"names":["c","coreServices","config","Duration","readDurationFromConfig"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs.js","sources":["../src/services/system/types.ts","../src/services/definitions/coreServices.ts","../src/services/definitions/SchedulerService.ts","../src/services/utilities/database.ts","../src/wiring/factories.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { BackendFeature } from '../../types';\n\n/**\n * TODO\n *\n * @public\n */\nexport type ServiceRef<\n TService,\n TScope extends 'root' | 'plugin' = 'root' | 'plugin',\n> = {\n id: string;\n\n /**\n * This determines the scope at which this service is available.\n *\n * Root scoped services are available to all other services but\n * may only depend on other root scoped services.\n *\n * Plugin scoped services are only available to other plugin scoped\n * services but may depend on all other services.\n */\n scope: TScope;\n\n /**\n * Utility for getting the type of the service, using `typeof serviceRef.T`.\n * Attempting to actually read this value will result in an exception.\n */\n T: TService;\n\n $$type: '@backstage/ServiceRef';\n};\n\n/** @public */\nexport interface ServiceFactory<\n TService = unknown,\n TScope extends 'plugin' | 'root' = 'plugin' | 'root',\n> extends BackendFeature {\n service: ServiceRef<TService, TScope>;\n}\n\n/** @internal */\nexport interface InternalServiceFactory<\n TService = unknown,\n TScope extends 'plugin' | 'root' = 'plugin' | 'root',\n> extends ServiceFactory<TService, TScope> {\n version: 'v1';\n initialization?: 'always' | 'lazy';\n deps: { [key in string]: ServiceRef<unknown> };\n createRootContext?(deps: { [key in string]: unknown }): Promise<unknown>;\n factory(\n deps: { [key in string]: unknown },\n context: unknown,\n ): Promise<TService>;\n}\n\n/**\n * Represents either a {@link ServiceFactory} or a function that returns one.\n *\n * @public\n */\nexport type ServiceFactoryOrFunction = ServiceFactory | (() => ServiceFactory);\n\n/** @public */\nexport interface ServiceRefConfig<TService, TScope extends 'root' | 'plugin'> {\n id: string;\n scope?: TScope;\n defaultFactory?: (\n service: ServiceRef<TService, TScope>,\n ) => Promise<ServiceFactoryOrFunction>;\n}\n\n/**\n * Creates a new service definition. This overload is used to create plugin scoped services.\n *\n * @public\n */\nexport function createServiceRef<TService>(\n config: ServiceRefConfig<TService, 'plugin'>,\n): ServiceRef<TService, 'plugin'>;\n\n/**\n * Creates a new service definition. This overload is used to create root scoped services.\n *\n * @public\n */\nexport function createServiceRef<TService>(\n config: ServiceRefConfig<TService, 'root'>,\n): ServiceRef<TService, 'root'>;\nexport function createServiceRef<TService>(\n config: ServiceRefConfig<TService, any>,\n): ServiceRef<TService, any> {\n const { id, scope = 'plugin', defaultFactory } = config;\n return {\n id,\n scope,\n get T(): TService {\n throw new Error(`tried to read ServiceRef.T of ${this}`);\n },\n toString() {\n return `serviceRef{${config.id}}`;\n },\n $$type: '@backstage/ServiceRef',\n __defaultFactory: defaultFactory,\n } as ServiceRef<TService, typeof scope> & {\n __defaultFactory?: (\n service: ServiceRef<TService>,\n ) => Promise<ServiceFactory<TService> | (() => ServiceFactory<TService>)>;\n };\n}\n\n/** @ignore */\ntype ServiceRefsToInstances<\n T extends { [key in string]: ServiceRef<unknown> },\n TScope extends 'root' | 'plugin' = 'root' | 'plugin',\n> = {\n [key in keyof T as T[key]['scope'] extends TScope ? key : never]: T[key]['T'];\n};\n\n/** @public */\nexport interface RootServiceFactoryConfig<\n TService,\n TImpl extends TService,\n TDeps extends { [name in string]: ServiceRef<unknown> },\n> {\n /**\n * The initialization strategy for the service factory. This service is root scoped and will use `always` by default.\n *\n * @remarks\n *\n * - `always` - The service will always be initialized regardless if it is used or not.\n * - `lazy` - The service will only be initialized if it is depended on by a different service or feature.\n *\n * Service factories for root scoped services use `always` as the default, while plugin scoped services use `lazy`.\n */\n initialization?: 'always' | 'lazy';\n service: ServiceRef<TService, 'root'>;\n deps: TDeps;\n factory(deps: ServiceRefsToInstances<TDeps, 'root'>): TImpl | Promise<TImpl>;\n}\n\n/** @public */\nexport interface PluginServiceFactoryConfig<\n TService,\n TContext,\n TImpl extends TService,\n TDeps extends { [name in string]: ServiceRef<unknown> },\n> {\n /**\n * The initialization strategy for the service factory. This service is plugin scoped and will use `lazy` by default.\n *\n * @remarks\n *\n * - `always` - The service will always be initialized regardless if it is used or not.\n * - `lazy` - The service will only be initialized if it is depended on by a different service or feature.\n *\n * Service factories for root scoped services use `always` as the default, while plugin scoped services use `lazy`.\n */\n initialization?: 'always' | 'lazy';\n service: ServiceRef<TService, 'plugin'>;\n deps: TDeps;\n createRootContext?(\n deps: ServiceRefsToInstances<TDeps, 'root'>,\n ): TContext | Promise<TContext>;\n factory(\n deps: ServiceRefsToInstances<TDeps>,\n context: TContext,\n ): TImpl | Promise<TImpl>;\n}\n\n/**\n * Creates a root scoped service factory without options.\n *\n * @public\n * @param config - The service factory configuration.\n */\nexport function createServiceFactory<\n TService,\n TImpl extends TService,\n TDeps extends { [name in string]: ServiceRef<unknown, 'root'> },\n TOpts extends object | undefined = undefined,\n>(\n config: RootServiceFactoryConfig<TService, TImpl, TDeps>,\n): () => ServiceFactory<TService, 'root'>;\n/**\n * Creates a root scoped service factory with optional options.\n *\n * @public\n * @param config - The service factory configuration.\n */\nexport function createServiceFactory<\n TService,\n TImpl extends TService,\n TDeps extends { [name in string]: ServiceRef<unknown, 'root'> },\n TOpts extends object | undefined = undefined,\n>(\n config: (options?: TOpts) => RootServiceFactoryConfig<TService, TImpl, TDeps>,\n): (options?: TOpts) => ServiceFactory<TService, 'root'>;\n/**\n * Creates a plugin scoped service factory without options.\n *\n * @public\n * @param config - The service factory configuration.\n */\nexport function createServiceFactory<\n TService,\n TImpl extends TService,\n TDeps extends { [name in string]: ServiceRef<unknown> },\n TContext = undefined,\n TOpts extends object | undefined = undefined,\n>(\n config: PluginServiceFactoryConfig<TService, TContext, TImpl, TDeps>,\n): () => ServiceFactory<TService, 'plugin'>;\n/**\n * Creates a plugin scoped service factory with optional options.\n *\n * @public\n * @param config - The service factory configuration.\n */\nexport function createServiceFactory<\n TService,\n TImpl extends TService,\n TDeps extends { [name in string]: ServiceRef<unknown> },\n TContext = undefined,\n TOpts extends object | undefined = undefined,\n>(\n config: (\n options?: TOpts,\n ) => PluginServiceFactoryConfig<TService, TContext, TImpl, TDeps>,\n): (options?: TOpts) => ServiceFactory<TService, 'plugin'>;\nexport function createServiceFactory<\n TService,\n TImpl extends TService,\n TDeps extends { [name in string]: ServiceRef<unknown> },\n TContext,\n TOpts extends object | undefined = undefined,\n>(\n config:\n | RootServiceFactoryConfig<TService, TImpl, TDeps>\n | PluginServiceFactoryConfig<TService, TContext, TImpl, TDeps>\n | ((options: TOpts) => RootServiceFactoryConfig<TService, TImpl, TDeps>)\n | ((\n options: TOpts,\n ) => PluginServiceFactoryConfig<TService, TContext, TImpl, TDeps>)\n | (() => RootServiceFactoryConfig<TService, TImpl, TDeps>)\n | (() => PluginServiceFactoryConfig<TService, TContext, TImpl, TDeps>),\n): (options: TOpts) => ServiceFactory {\n const configCallback = typeof config === 'function' ? config : () => config;\n const factory = (\n options: TOpts,\n ): InternalServiceFactory<TService, 'plugin' | 'root'> => {\n const anyConf = configCallback(options);\n if (anyConf.service.scope === 'root') {\n const c = anyConf as RootServiceFactoryConfig<TService, TImpl, TDeps>;\n return {\n $$type: '@backstage/BackendFeature',\n version: 'v1',\n service: c.service,\n initialization: c.initialization,\n deps: c.deps,\n factory: async (deps: TDeps) => c.factory(deps),\n };\n }\n const c = anyConf as PluginServiceFactoryConfig<\n TService,\n TContext,\n TImpl,\n TDeps\n >;\n return {\n $$type: '@backstage/BackendFeature',\n version: 'v1',\n service: c.service,\n initialization: c.initialization,\n ...('createRootContext' in c\n ? {\n createRootContext: async (deps: TDeps) =>\n c?.createRootContext?.(deps),\n }\n : {}),\n deps: c.deps,\n factory: async (deps: TDeps, ctx: TContext) => c.factory(deps, ctx),\n };\n };\n\n factory.$$type = '@backstage/BackendFeatureFactory';\n\n return factory;\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { createServiceRef } from '../system';\n\n/**\n * All core services references\n *\n * @public\n */\nexport namespace coreServices {\n /**\n * The service reference for the plugin scoped {@link AuthService}.\n *\n * @public\n */\n export const auth = createServiceRef<import('./AuthService').AuthService>({\n id: 'core.auth',\n });\n\n /**\n * The service reference for the plugin scoped {@link UserInfoService}.\n *\n * @public\n */\n export const userInfo = createServiceRef<\n import('./UserInfoService').UserInfoService\n >({\n id: 'core.userInfo',\n });\n\n /**\n * The service reference for the plugin scoped {@link CacheService}.\n *\n * @public\n */\n export const cache = createServiceRef<import('./CacheService').CacheService>({\n id: 'core.cache',\n });\n\n /**\n * The service reference for the root scoped {@link RootConfigService}.\n *\n * @public\n */\n export const rootConfig = createServiceRef<\n import('./RootConfigService').RootConfigService\n >({ id: 'core.rootConfig', scope: 'root' });\n\n /**\n * The service reference for the plugin scoped {@link DatabaseService}.\n *\n * @public\n */\n export const database = createServiceRef<\n import('./DatabaseService').DatabaseService\n >({ id: 'core.database' });\n\n /**\n * The service reference for the plugin scoped {@link DiscoveryService}.\n *\n * @public\n */\n export const discovery = createServiceRef<\n import('./DiscoveryService').DiscoveryService\n >({ id: 'core.discovery' });\n\n /**\n * The service reference for the plugin scoped {@link HttpAuthService}.\n *\n * @public\n */\n export const httpAuth = createServiceRef<\n import('./HttpAuthService').HttpAuthService\n >({ id: 'core.httpAuth' });\n\n /**\n * The service reference for the plugin scoped {@link HttpRouterService}.\n *\n * @public\n */\n export const httpRouter = createServiceRef<\n import('./HttpRouterService').HttpRouterService\n >({ id: 'core.httpRouter' });\n\n /**\n * The service reference for the plugin scoped {@link LifecycleService}.\n *\n * @public\n */\n export const lifecycle = createServiceRef<\n import('./LifecycleService').LifecycleService\n >({ id: 'core.lifecycle' });\n\n /**\n * The service reference for the plugin scoped {@link LoggerService}.\n *\n * @public\n */\n export const logger = createServiceRef<\n import('./LoggerService').LoggerService\n >({ id: 'core.logger' });\n\n /**\n * The service reference for the plugin scoped {@link PermissionsService}.\n *\n * @public\n */\n export const permissions = createServiceRef<\n import('./PermissionsService').PermissionsService\n >({ id: 'core.permissions' });\n\n /**\n * The service reference for the plugin scoped {@link PluginMetadataService}.\n *\n * @public\n */\n export const pluginMetadata = createServiceRef<\n import('./PluginMetadataService').PluginMetadataService\n >({ id: 'core.pluginMetadata' });\n\n /**\n * The service reference for the root scoped {@link RootHttpRouterService}.\n *\n * @public\n */\n export const rootHttpRouter = createServiceRef<\n import('./RootHttpRouterService').RootHttpRouterService\n >({ id: 'core.rootHttpRouter', scope: 'root' });\n\n /**\n * The service reference for the root scoped {@link RootLifecycleService}.\n *\n * @public\n */\n export const rootLifecycle = createServiceRef<\n import('./RootLifecycleService').RootLifecycleService\n >({ id: 'core.rootLifecycle', scope: 'root' });\n\n /**\n * The service reference for the root scoped {@link RootLoggerService}.\n *\n * @public\n */\n export const rootLogger = createServiceRef<\n import('./RootLoggerService').RootLoggerService\n >({ id: 'core.rootLogger', scope: 'root' });\n\n /**\n * The service reference for the plugin scoped {@link SchedulerService}.\n *\n * @public\n */\n export const scheduler = createServiceRef<\n import('./SchedulerService').SchedulerService\n >({ id: 'core.scheduler' });\n\n /**\n * The service reference for the plugin scoped {@link TokenManagerService}.\n *\n * @public\n * @deprecated Please migrate to the new `coreServices.auth`, `coreServices.httpAuth`, and `coreServices.userInfo` services as needed instead\n */\n export const tokenManager = createServiceRef<\n import('./TokenManagerService').TokenManagerService\n >({ id: 'core.tokenManager' });\n\n /**\n * The service reference for the plugin scoped {@link UrlReaderService}.\n *\n * @public\n */\n export const urlReader = createServiceRef<\n import('./UrlReaderService').UrlReaderService\n >({ id: 'core.urlReader' });\n\n /**\n * The service reference for the plugin scoped {@link IdentityService}.\n *\n * @public\n * @deprecated Please migrate to the new `coreServices.auth`, `coreServices.httpAuth`, and `coreServices.userInfo` services as needed instead\n */\n export const identity = createServiceRef<\n import('./IdentityService').IdentityService\n >({ id: 'core.identity' });\n}\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Config, readDurationFromConfig } from '@backstage/config';\nimport { HumanDuration, JsonObject } from '@backstage/types';\nimport { Duration } from 'luxon';\n\n/**\n * A function that can be called as a scheduled task.\n *\n * It may optionally accept an abort signal argument. When the signal triggers,\n * processing should abort and return as quickly as possible.\n *\n * @public\n */\nexport type SchedulerServiceTaskFunction =\n | ((abortSignal: AbortSignal) => void | Promise<void>)\n | (() => void | Promise<void>);\n\n/**\n * A semi-opaque type to describe an actively scheduled task.\n *\n * @public\n */\nexport type SchedulerServiceTaskDescriptor = {\n /**\n * The unique identifier of the task.\n */\n id: string;\n /**\n * The scope of the task.\n */\n scope: 'global' | 'local';\n /**\n * The settings that control the task flow. This is a semi-opaque structure\n * that is mainly there for debugging purposes. Do not make any assumptions\n * about the contents of this field.\n */\n settings: { version: number } & JsonObject;\n};\n\n/**\n * Options that control the scheduling of a task.\n *\n * @public\n */\nexport interface SchedulerServiceTaskScheduleDefinition {\n /**\n * How often you want the task to run. The system does its best to avoid\n * overlapping invocations.\n *\n * @remarks\n *\n * This is the best effort value; under some circumstances there can be\n * deviations. For example, if the task runtime is longer than the frequency\n * and the timeout has not been given or not been exceeded yet, the next\n * invocation of this task will be delayed until after the previous one\n * finishes.\n *\n * This is a required field.\n */\n frequency:\n | {\n /**\n * A crontab style string.\n *\n * @remarks\n *\n * Overview:\n *\n * ```\n * ┌────────────── second (optional)\n * │ ┌──────────── minute\n * │ │ ┌────────── hour\n * │ │ │ ┌──────── day of month\n * │ │ │ │ ┌────── month\n * │ │ │ │ │ ┌──── day of week\n * │ │ │ │ │ │\n * │ │ │ │ │ │\n * * * * * * *\n * ```\n */\n cron: string;\n }\n | Duration\n | HumanDuration;\n\n /**\n * The maximum amount of time that a single task invocation can take, before\n * it's considered timed out and gets \"released\" such that a new invocation\n * is permitted to take place (possibly, then, on a different worker).\n */\n timeout: Duration | HumanDuration;\n\n /**\n * The amount of time that should pass before the first invocation happens.\n *\n * @remarks\n *\n * This can be useful in cold start scenarios to stagger or delay some heavy\n * compute jobs. If no value is given for this field then the first invocation\n * will happen as soon as possible according to the cadence.\n *\n * NOTE: This is a per-worker delay. If you have a cluster of workers all\n * collaborating on a task that has its `scope` field set to `'global'`, then\n * you may still see the task being processed by other long-lived workers,\n * while any given single worker is in its initial sleep delay time e.g. after\n * a deployment. Therefore, this parameter is not useful for \"globally\" pausing\n * work; its main intended use is for individual machines to get a chance to\n * reach some equilibrium at startup before triggering heavy batch workloads.\n */\n initialDelay?: Duration | HumanDuration;\n\n /**\n * Sets the scope of concurrency control / locking to apply for invocations of\n * this task.\n *\n * @remarks\n *\n * When the scope is set to the default value `'global'`, the scheduler will\n * attempt to ensure that only one worker machine runs the task at a time,\n * according to the given cadence. This means that as the number of worker\n * hosts increases, the invocation frequency of this task will not go up.\n * Instead, the load is spread randomly across hosts. This setting is useful\n * for tasks that access shared resources, for example catalog ingestion tasks\n * where you do not want many machines to repeatedly import the same data and\n * trample over each other.\n *\n * When the scope is set to `'local'`, there is no concurrency control across\n * hosts. Each host runs the task according to the given cadence similarly to\n * `setInterval`, but the runtime ensures that there are no overlapping runs.\n *\n * @defaultValue 'global'\n */\n scope?: 'global' | 'local';\n}\n\n/**\n * Config options for {@link SchedulerServiceTaskScheduleDefinition}\n * that control the scheduling of a task.\n *\n * @public\n */\nexport interface SchedulerServiceTaskScheduleDefinitionConfig {\n /**\n * How often you want the task to run. The system does its best to avoid\n * overlapping invocations.\n *\n * @remarks\n *\n * This is the best effort value; under some circumstances there can be\n * deviations. For example, if the task runtime is longer than the frequency\n * and the timeout has not been given or not been exceeded yet, the next\n * invocation of this task will be delayed until after the previous one\n * finishes.\n *\n * This is a required field.\n */\n frequency:\n | {\n /**\n * A crontab style string.\n *\n * @remarks\n *\n * Overview:\n *\n * ```\n * ┌────────────── second (optional)\n * │ ┌──────────── minute\n * │ │ ┌────────── hour\n * │ │ │ ┌──────── day of month\n * │ │ │ │ ┌────── month\n * │ │ │ │ │ ┌──── day of week\n * │ │ │ │ │ │\n * │ │ │ │ │ │\n * * * * * * *\n * ```\n */\n cron: string;\n }\n | string\n | HumanDuration;\n\n /**\n * The maximum amount of time that a single task invocation can take, before\n * it's considered timed out and gets \"released\" such that a new invocation\n * is permitted to take place (possibly, then, on a different worker).\n */\n timeout: string | HumanDuration;\n\n /**\n * The amount of time that should pass before the first invocation happens.\n *\n * @remarks\n *\n * This can be useful in cold start scenarios to stagger or delay some heavy\n * compute jobs. If no value is given for this field then the first invocation\n * will happen as soon as possible according to the cadence.\n *\n * NOTE: This is a per-worker delay. If you have a cluster of workers all\n * collaborating on a task that has its `scope` field set to `'global'`, then\n * you may still see the task being processed by other long-lived workers,\n * while any given single worker is in its initial sleep delay time e.g. after\n * a deployment. Therefore, this parameter is not useful for \"globally\" pausing\n * work; its main intended use is for individual machines to get a chance to\n * reach some equilibrium at startup before triggering heavy batch workloads.\n */\n initialDelay?: string | HumanDuration;\n\n /**\n * Sets the scope of concurrency control / locking to apply for invocations of\n * this task.\n *\n * @remarks\n *\n * When the scope is set to the default value `'global'`, the scheduler will\n * attempt to ensure that only one worker machine runs the task at a time,\n * according to the given cadence. This means that as the number of worker\n * hosts increases, the invocation frequency of this task will not go up.\n * Instead, the load is spread randomly across hosts. This setting is useful\n * for tasks that access shared resources, for example catalog ingestion tasks\n * where you do not want many machines to repeatedly import the same data and\n * trample over each other.\n *\n * When the scope is set to `'local'`, there is no concurrency control across\n * hosts. Each host runs the task according to the given cadence similarly to\n * `setInterval`, but the runtime ensures that there are no overlapping runs.\n *\n * @defaultValue 'global'\n */\n scope?: 'global' | 'local';\n}\n\n/**\n * Options that apply to the invocation of a given task.\n *\n * @public\n */\nexport interface SchedulerServiceTaskInvocationDefinition {\n /**\n * A unique ID (within the scope of the plugin) for the task.\n */\n id: string;\n\n /**\n * The actual task function to be invoked regularly.\n */\n fn: SchedulerServiceTaskFunction;\n\n /**\n * An abort signal that, when triggered, will stop the recurring execution of\n * the task.\n */\n signal?: AbortSignal;\n}\n\n/**\n * A previously prepared task schedule, ready to be invoked.\n *\n * @public\n */\nexport interface SchedulerServiceTaskRunner {\n /**\n * Takes the schedule and executes an actual task using it.\n *\n * @param task - The actual runtime properties of the task\n */\n run(task: SchedulerServiceTaskInvocationDefinition): Promise<void>;\n}\n\n/**\n * Deals with the scheduling of distributed tasks, for a given plugin.\n *\n * See the {@link https://backstage.io/docs/backend-system/core-services/scheduler | service documentation} for more details.\n *\n * @public\n */\nexport interface SchedulerService {\n /**\n * Manually triggers a task by ID.\n *\n * If the task doesn't exist, a NotFoundError is thrown. If the task is\n * currently running, a ConflictError is thrown.\n *\n * @param id - The task ID\n */\n triggerTask(id: string): Promise<void>;\n\n /**\n * Schedules a task function for recurring runs.\n *\n * @remarks\n *\n * The `scope` task field controls whether to use coordinated exclusive\n * invocation across workers, or to just coordinate within the current worker.\n *\n * This convenience method performs both the scheduling and invocation in one\n * go.\n *\n * @param task - The task definition\n */\n scheduleTask(\n task: SchedulerServiceTaskScheduleDefinition &\n SchedulerServiceTaskInvocationDefinition,\n ): Promise<void>;\n\n /**\n * Creates a scheduled but dormant recurring task, ready to be launched at a\n * later time.\n *\n * @remarks\n *\n * This method is useful for pre-creating a schedule in outer code to be\n * passed into an inner implementation, such that the outer code controls\n * scheduling while inner code controls implementation.\n *\n * @param schedule - The task schedule\n */\n createScheduledTaskRunner(\n schedule: SchedulerServiceTaskScheduleDefinition,\n ): SchedulerServiceTaskRunner;\n\n /**\n * Returns all scheduled tasks registered to this scheduler.\n *\n * @remarks\n *\n * This method is useful for triggering tasks manually using the triggerTask\n * functionality. Note that the returned tasks contain only tasks that have\n * been initialized in this instance of the scheduler.\n *\n * @returns Scheduled tasks\n */\n getScheduledTasks(): Promise<SchedulerServiceTaskDescriptor[]>;\n}\n\nfunction readDuration(config: Config, key: string): Duration | HumanDuration {\n if (typeof config.get(key) === 'string') {\n const value = config.getString(key);\n const duration = Duration.fromISO(value);\n if (!duration.isValid) {\n throw new Error(`Invalid duration: ${value}`);\n }\n return duration;\n }\n\n return readDurationFromConfig(config, { key });\n}\n\nfunction readCronOrDuration(\n config: Config,\n key: string,\n): { cron: string } | Duration | HumanDuration {\n const value = config.get(key);\n if (typeof value === 'object' && (value as { cron?: string }).cron) {\n return value as { cron: string };\n }\n\n return readDuration(config, key);\n}\n\n/**\n * Reads a {@link SchedulerServiceTaskScheduleDefinition} from config. Expects\n * the config not to be the root config, but the config for the definition.\n *\n * @param config - config for a TaskScheduleDefinition.\n * @public\n */\nexport function readSchedulerServiceTaskScheduleDefinitionFromConfig(\n config: Config,\n): SchedulerServiceTaskScheduleDefinition {\n const frequency = readCronOrDuration(config, 'frequency');\n const timeout = readDuration(config, 'timeout');\n\n const initialDelay = config.has('initialDelay')\n ? readDuration(config, 'initialDelay')\n : undefined;\n\n const scope = config.getOptionalString('scope');\n if (scope && !['global', 'local'].includes(scope)) {\n throw new Error(\n `Only \"global\" or \"local\" are allowed for TaskScheduleDefinition.scope, but got: ${scope}`,\n );\n }\n\n return {\n frequency,\n timeout,\n initialDelay,\n scope: scope as 'global' | 'local' | undefined,\n };\n}\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Tries to deduce whether a thrown error is a database conflict.\n *\n * @public\n * @param e - A thrown error\n * @returns True if the error looks like it was a conflict error thrown by a\n * known database engine\n */\nexport function isDatabaseConflictError(e: unknown) {\n const message = (e as any)?.message;\n\n return (\n typeof message === 'string' &&\n (/SQLITE_CONSTRAINT(?:_UNIQUE)?: UNIQUE/.test(message) ||\n /UNIQUE constraint failed:/.test(message) ||\n /unique constraint/.test(message) ||\n /Duplicate entry/.test(message)) // MySQL uniqueness error msg\n );\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { BackendFeature, BackendFeatureFactory } from '../types';\nimport {\n BackendModuleRegistrationPoints,\n BackendPluginRegistrationPoints,\n ExtensionPoint,\n InternalBackendModuleRegistration,\n InternalBackendPluginRegistration,\n} from './types';\n\n/**\n * The configuration options passed to {@link createExtensionPoint}.\n *\n * @public\n * @see {@link https://backstage.io/docs/backend-system/architecture/extension-points | The architecture of extension points}\n * @see {@link https://backstage.io/docs/backend-system/architecture/naming-patterns | Recommended naming patterns}\n */\nexport interface CreateExtensionPointOptions {\n /**\n * The ID of this extension point.\n *\n * @see {@link https://backstage.io/docs/backend-system/architecture/naming-patterns | Recommended naming patterns}\n */\n id: string;\n}\n\n/**\n * Creates a new backend extension point.\n *\n * @public\n * @see {@link https://backstage.io/docs/backend-system/architecture/extension-points | The architecture of extension points}\n */\nexport function createExtensionPoint<T>(\n options: CreateExtensionPointOptions,\n): ExtensionPoint<T> {\n return {\n id: options.id,\n get T(): T {\n if (process.env.NODE_ENV === 'test') {\n // Avoid throwing errors so tests asserting extensions' properties cannot be easily broken\n return null as T;\n }\n throw new Error(`tried to read ExtensionPoint.T of ${this}`);\n },\n toString() {\n return `extensionPoint{${options.id}}`;\n },\n $$type: '@backstage/ExtensionPoint',\n };\n}\n\n/**\n * The configuration options passed to {@link createBackendPlugin}.\n *\n * @public\n * @see {@link https://backstage.io/docs/backend-system/architecture/plugins | The architecture of plugins}\n * @see {@link https://backstage.io/docs/backend-system/architecture/naming-patterns | Recommended naming patterns}\n */\nexport interface CreateBackendPluginOptions {\n /**\n * The ID of this plugin.\n *\n * @see {@link https://backstage.io/docs/backend-system/architecture/naming-patterns | Recommended naming patterns}\n */\n pluginId: string;\n register(reg: BackendPluginRegistrationPoints): void;\n}\n\n/**\n * Creates a new backend plugin.\n *\n * @public\n * @see {@link https://backstage.io/docs/backend-system/architecture/plugins | The architecture of plugins}\n * @see {@link https://backstage.io/docs/backend-system/architecture/naming-patterns | Recommended naming patterns}\n */\nexport function createBackendPlugin(\n options: CreateBackendPluginOptions,\n): () => BackendFeature {\n const factory: BackendFeatureFactory = () => {\n let registrations: InternalBackendPluginRegistration[];\n\n return {\n $$type: '@backstage/BackendFeature',\n version: 'v1',\n getRegistrations() {\n if (registrations) {\n return registrations;\n }\n const extensionPoints: InternalBackendPluginRegistration['extensionPoints'] =\n [];\n let init: InternalBackendPluginRegistration['init'] | undefined =\n undefined;\n\n options.register({\n registerExtensionPoint(ext, impl) {\n if (init) {\n throw new Error(\n 'registerExtensionPoint called after registerInit',\n );\n }\n extensionPoints.push([ext, impl]);\n },\n registerInit(regInit) {\n if (init) {\n throw new Error('registerInit must only be called once');\n }\n init = {\n deps: regInit.deps,\n func: regInit.init,\n };\n },\n });\n\n if (!init) {\n throw new Error(\n `registerInit was not called by register in ${options.pluginId}`,\n );\n }\n\n registrations = [\n {\n type: 'plugin',\n pluginId: options.pluginId,\n extensionPoints,\n init,\n },\n ];\n return registrations;\n },\n };\n };\n factory.$$type = '@backstage/BackendFeatureFactory';\n\n return factory;\n}\n\n/**\n * The configuration options passed to {@link createBackendModule}.\n *\n * @public\n * @see {@link https://backstage.io/docs/backend-system/architecture/modules | The architecture of modules}\n * @see {@link https://backstage.io/docs/backend-system/architecture/naming-patterns | Recommended naming patterns}\n */\nexport interface CreateBackendModuleOptions {\n /**\n * Should exactly match the `id` of the plugin that the module extends.\n *\n * @see {@link https://backstage.io/docs/backend-system/architecture/naming-patterns | Recommended naming patterns}\n */\n pluginId: string;\n\n /**\n * The ID of this module, used to identify the module and ensure that it is not installed twice.\n */\n moduleId: string;\n register(reg: BackendModuleRegistrationPoints): void;\n}\n\n/**\n * Creates a new backend module for a given plugin.\n *\n * @public\n * @see {@link https://backstage.io/docs/backend-system/architecture/modules | The architecture of modules}\n * @see {@link https://backstage.io/docs/backend-system/architecture/naming-patterns | Recommended naming patterns}\n */\nexport function createBackendModule(\n options: CreateBackendModuleOptions,\n): () => BackendFeature {\n const factory: BackendFeatureFactory = () => {\n let registrations: InternalBackendModuleRegistration[];\n\n return {\n $$type: '@backstage/BackendFeature',\n version: 'v1',\n getRegistrations() {\n if (registrations) {\n return registrations;\n }\n const extensionPoints: InternalBackendPluginRegistration['extensionPoints'] =\n [];\n let init: InternalBackendModuleRegistration['init'] | undefined =\n undefined;\n\n options.register({\n registerExtensionPoint(ext, impl) {\n if (init) {\n throw new Error(\n 'registerExtensionPoint called after registerInit',\n );\n }\n extensionPoints.push([ext, impl]);\n },\n registerInit(regInit) {\n if (init) {\n throw new Error('registerInit must only be called once');\n }\n init = {\n deps: regInit.deps,\n func: regInit.init,\n };\n },\n });\n\n if (!init) {\n throw new Error(\n `registerInit was not called by register in ${options.moduleId} module for ${options.pluginId}`,\n );\n }\n\n registrations = [\n {\n type: 'module',\n pluginId: options.pluginId,\n moduleId: options.moduleId,\n extensionPoints,\n init,\n },\n ];\n return registrations;\n },\n };\n };\n factory.$$type = '@backstage/BackendFeatureFactory';\n\n return factory;\n}\n"],"names":["c","coreServices","config","Duration","readDurationFromConfig"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -9,35 +9,44 @@ import { PermissionAttributes, PermissionEvaluator, AuthorizePermissionRequest,
9
9
  import { Knex } from 'knex';
10
10
  export { isChildPath } from '@backstage/cli-common';
11
11
 
12
- /** @public */
12
+ /**
13
+ * This is the legacy service for identity handling in Backstage. Please migrate to the new `coreServices.auth`, `coreServices.httpAuth`, and `coreServices.userInfo` services as needed instead.
14
+ *
15
+ * See the {@link https://backstage.io/docs/backend-system/core-services/identity | service documentation} for more details.
16
+ *
17
+ * @public
18
+ * @deprecated Please {@link https://backstage.io/docs/tutorials/auth-service-migration | migrate} to the new `coreServices.auth`, `coreServices.httpAuth`, and `coreServices.userInfo` services as needed instead.
19
+ */
13
20
  interface IdentityService extends IdentityApi {
14
21
  }
15
22
 
16
23
  /**
17
24
  * A generic interface for fetching plain data from URLs.
18
25
  *
26
+ * See the {@link https://backstage.io/docs/backend-system/core-services/url-reader | service documentation} for more details.
27
+ *
19
28
  * @public
20
29
  */
21
30
  interface UrlReaderService {
22
31
  /**
23
32
  * Reads a single file and return its content.
24
33
  */
25
- readUrl(url: string, options?: ReadUrlOptions): Promise<ReadUrlResponse>;
34
+ readUrl(url: string, options?: UrlReaderReadUrlOptions): Promise<UrlReaderReadUrlResponse>;
26
35
  /**
27
36
  * Reads a full or partial file tree.
28
37
  */
29
- readTree(url: string, options?: ReadTreeOptions): Promise<ReadTreeResponse>;
38
+ readTree(url: string, options?: UrlReaderReadTreeOptions): Promise<UrlReaderReadTreeResponse>;
30
39
  /**
31
40
  * Searches for a file in a tree using a glob pattern.
32
41
  */
33
- search(url: string, options?: SearchOptions): Promise<SearchResponse>;
42
+ search(url: string, options?: UrlReaderSearchOptions): Promise<UrlReaderSearchResponse>;
34
43
  }
35
44
  /**
36
45
  * An options object for readUrl operations.
37
46
  *
38
47
  * @public
39
48
  */
40
- type ReadUrlOptions = {
49
+ type UrlReaderReadUrlOptions = {
41
50
  /**
42
51
  * An ETag which can be provided to check whether a
43
52
  * {@link UrlReaderService.readUrl} response has changed from a previous execution.
@@ -101,7 +110,7 @@ type ReadUrlOptions = {
101
110
  *
102
111
  * @public
103
112
  */
104
- type ReadUrlResponse = {
113
+ type UrlReaderReadUrlResponse = {
105
114
  /**
106
115
  * Returns the data that was read from the remote URL.
107
116
  */
@@ -132,7 +141,7 @@ type ReadUrlResponse = {
132
141
  *
133
142
  * @public
134
143
  */
135
- type ReadTreeOptions = {
144
+ type UrlReaderReadTreeOptions = {
136
145
  /**
137
146
  * A filter that can be used to select which files should be included.
138
147
  *
@@ -190,11 +199,11 @@ type ReadTreeOptions = {
190
199
  token?: string;
191
200
  };
192
201
  /**
193
- * Options that control {@link ReadTreeResponse.dir} execution.
202
+ * Options that control {@link UrlReaderReadTreeResponse.dir} execution.
194
203
  *
195
204
  * @public
196
205
  */
197
- type ReadTreeResponseDirOptions = {
206
+ type UrlReaderReadTreeResponseDirOptions = {
198
207
  /**
199
208
  * The directory to write files to.
200
209
  *
@@ -209,12 +218,12 @@ type ReadTreeResponseDirOptions = {
209
218
  *
210
219
  * @public
211
220
  */
212
- type ReadTreeResponse = {
221
+ type UrlReaderReadTreeResponse = {
213
222
  /**
214
223
  * Returns an array of all the files inside the tree, and corresponding
215
224
  * functions to read their content.
216
225
  */
217
- files(): Promise<ReadTreeResponseFile[]>;
226
+ files(): Promise<UrlReaderReadTreeResponseFile[]>;
218
227
  /**
219
228
  * Returns the tree contents as a binary archive, using a stream.
220
229
  */
@@ -225,7 +234,7 @@ type ReadTreeResponse = {
225
234
  *
226
235
  * **NOTE**: It is the responsibility of the caller to remove the directory after use.
227
236
  */
228
- dir(options?: ReadTreeResponseDirOptions): Promise<string>;
237
+ dir(options?: UrlReaderReadTreeResponseDirOptions): Promise<string>;
229
238
  /**
230
239
  * Etag returned by content provider.
231
240
  *
@@ -240,7 +249,7 @@ type ReadTreeResponse = {
240
249
  *
241
250
  * @public
242
251
  */
243
- type ReadTreeResponseFile = {
252
+ type UrlReaderReadTreeResponseFile = {
244
253
  /**
245
254
  * The filepath of the data.
246
255
  */
@@ -259,7 +268,7 @@ type ReadTreeResponseFile = {
259
268
  *
260
269
  * @public
261
270
  */
262
- type SearchOptions = {
271
+ type UrlReaderSearchOptions = {
263
272
  /**
264
273
  * An etag can be provided to check whether the search response has changed from a previous execution.
265
274
  *
@@ -297,11 +306,11 @@ type SearchOptions = {
297
306
  *
298
307
  * @public
299
308
  */
300
- type SearchResponse = {
309
+ type UrlReaderSearchResponse = {
301
310
  /**
302
311
  * The files that matched the search query.
303
312
  */
304
- files: SearchResponseFile[];
313
+ files: UrlReaderSearchResponseFile[];
305
314
  /**
306
315
  * A unique identifier of the current remote tree, usually the commit SHA or etag from the target.
307
316
  */
@@ -312,7 +321,7 @@ type SearchResponse = {
312
321
  *
313
322
  * @public
314
323
  */
315
- type SearchResponseFile = {
324
+ type UrlReaderSearchResponseFile = {
316
325
  /**
317
326
  * The full URL to the file.
318
327
  */
@@ -326,11 +335,59 @@ type SearchResponseFile = {
326
335
  */
327
336
  lastModifiedAt?: Date;
328
337
  };
338
+ /**
339
+ * @public
340
+ * @deprecated Use `UrlReaderReadTreeOptions` instead
341
+ */
342
+ type ReadTreeOptions = UrlReaderReadTreeOptions;
343
+ /**
344
+ * @public
345
+ * @deprecated Use `UrlReaderReadTreeResponse` instead
346
+ */
347
+ type ReadTreeResponse = UrlReaderReadTreeResponse;
348
+ /**
349
+ * @public
350
+ * @deprecated Use `UrlReaderReadTreeResponseDirOptions` instead
351
+ */
352
+ type ReadTreeResponseDirOptions = UrlReaderReadTreeResponseDirOptions;
353
+ /**
354
+ * @public
355
+ * @deprecated Use `UrlReaderReadTreeResponseFile` instead
356
+ */
357
+ type ReadTreeResponseFile = UrlReaderReadTreeResponseFile;
358
+ /**
359
+ * @public
360
+ * @deprecated Use `UrlReaderReadUrlResponse` instead
361
+ */
362
+ type ReadUrlResponse = UrlReaderReadUrlResponse;
363
+ /**
364
+ * @public
365
+ * @deprecated Use `UrlReaderReadUrlOptions` instead
366
+ */
367
+ type ReadUrlOptions = UrlReaderReadUrlOptions;
368
+ /**
369
+ * @public
370
+ * @deprecated Use `UrlReaderSearchOptions` instead
371
+ */
372
+ type SearchOptions = UrlReaderSearchOptions;
373
+ /**
374
+ * @public
375
+ * @deprecated Use `UrlReaderSearchResponse` instead
376
+ */
377
+ type SearchResponse = UrlReaderSearchResponse;
378
+ /**
379
+ * @public
380
+ * @deprecated Use `UrlReaderSearchResponseFile` instead
381
+ */
382
+ type SearchResponseFile = UrlReaderSearchResponseFile;
329
383
 
330
384
  /**
331
- * Interface for creating and validating tokens.
385
+ * This is the legacy service for creating and validating tokens. Please migrate to the new `coreServices.auth`, `coreServices.httpAuth`, and `coreServices.userInfo` services as needed instead.
386
+ *
387
+ * See the {@link https://backstage.io/docs/backend-system/core-services/token-manager | service documentation} for more details.
332
388
  *
333
389
  * @public
390
+ * @deprecated Please {@link https://backstage.io/docs/tutorials/auth-service-migration | migrate} to the new `coreServices.auth`, `coreServices.httpAuth`, and `coreServices.userInfo` services as needed instead.
334
391
  */
335
392
  interface TokenManagerService {
336
393
  /**
@@ -599,6 +656,8 @@ interface SchedulerServiceTaskRunner {
599
656
  /**
600
657
  * Deals with the scheduling of distributed tasks, for a given plugin.
601
658
  *
659
+ * See the {@link https://backstage.io/docs/backend-system/core-services/scheduler | service documentation} for more details.
660
+ *
602
661
  * @public
603
662
  */
604
663
  interface SchedulerService {
@@ -663,6 +722,8 @@ declare function readSchedulerServiceTaskScheduleDefinitionFromConfig(config: Co
663
722
  /**
664
723
  * A service that provides a logging facility.
665
724
  *
725
+ * See the {@link https://backstage.io/docs/backend-system/core-services/logger | service documentation} for more details.
726
+ *
666
727
  * @public
667
728
  */
668
729
  interface LoggerService {
@@ -673,7 +734,13 @@ interface LoggerService {
673
734
  child(meta: JsonObject): LoggerService;
674
735
  }
675
736
 
676
- /** @public */
737
+ /**
738
+ * Root-level logging.
739
+ *
740
+ * See the {@link https://backstage.io/docs/backend-system/core-services/root-logger | service documentation} for more details.
741
+ *
742
+ * @public
743
+ */
677
744
  interface RootLoggerService extends LoggerService {
678
745
  }
679
746
 
@@ -704,6 +771,10 @@ interface LifecycleServiceShutdownOptions {
704
771
  logger?: LoggerService;
705
772
  }
706
773
  /**
774
+ * Provides registration of plugin startup and shutdown lifecycle hooks.
775
+ *
776
+ * See the {@link https://backstage.io/docs/backend-system/core-services/lifecycle | service documentation} for more details.
777
+ *
707
778
  * @public
708
779
  */
709
780
  interface LifecycleService {
@@ -723,11 +794,21 @@ interface LifecycleService {
723
794
  addShutdownHook(hook: LifecycleServiceShutdownHook, options?: LifecycleServiceShutdownOptions): void;
724
795
  }
725
796
 
726
- /** @public */
797
+ /**
798
+ * Registration of backend startup and shutdown lifecycle hooks.
799
+ *
800
+ * See the {@link https://backstage.io/docs/backend-system/core-services/root-lifecycle | service documentation} for more details.
801
+ *
802
+ * @public
803
+ */
727
804
  interface RootLifecycleService extends LifecycleService {
728
805
  }
729
806
 
730
807
  /**
808
+ * HTTP route registration for root services.
809
+ *
810
+ * See the {@link https://backstage.io/docs/backend-system/core-services/root-http-router | service documentation} for more details.
811
+ *
731
812
  * @public
732
813
  */
733
814
  interface RootHttpRouterService {
@@ -739,30 +820,61 @@ interface RootHttpRouterService {
739
820
  }
740
821
 
741
822
  /**
823
+ * Access metadata about the current plugin.
824
+ *
825
+ * See the {@link https://backstage.io/docs/backend-system/core-services/plugin-metadata | service documentation} for more details.
826
+ *
742
827
  * @public
743
828
  */
744
829
  interface PluginMetadataService {
830
+ /**
831
+ * The ID of the current plugin.
832
+ */
745
833
  getId(): string;
746
834
  }
747
835
 
748
836
  /**
837
+ * Represents a user principal (for example when a user Backstage token issued
838
+ * by the auth backend was given to a request).
839
+ *
840
+ * @remarks
841
+ *
842
+ * Additional information about the user can be fetched using the
843
+ * {@link UserInfoService}.
844
+ *
749
845
  * @public
750
846
  */
751
847
  type BackstageUserPrincipal = {
752
848
  type: 'user';
849
+ /**
850
+ * The entity ref of the user entity that this principal represents.
851
+ */
753
852
  userEntityRef: string;
754
853
  };
755
854
  /**
855
+ * Represents a principal that is not authenticated (for example when no token
856
+ * at all was given to a request).
857
+ *
756
858
  * @public
757
859
  */
758
860
  type BackstageNonePrincipal = {
759
861
  type: 'none';
760
862
  };
761
863
  /**
864
+ * Represents a service principal (for example when an external access method
865
+ * token was given to a request, or the caller was a Backstage backend plugin).
762
866
  * @public
763
867
  */
764
868
  type BackstageServicePrincipal = {
765
869
  type: 'service';
870
+ /**
871
+ * A string that represents the service.
872
+ *
873
+ * @remarks
874
+ *
875
+ * This string is only informational, has no well defined semantics, and
876
+ * should never be used to drive actual logic in code.
877
+ */
766
878
  subject: string;
767
879
  /**
768
880
  * The access restrictions that apply to this principal.
@@ -812,14 +924,35 @@ type BackstagePrincipalAccessRestrictions = {
812
924
  };
813
925
  };
814
926
  /**
927
+ * An opaque representation of credentials, for example as passed in a
928
+ * request-response flow.
929
+ *
815
930
  * @public
816
931
  */
817
932
  type BackstageCredentials<TPrincipal = unknown> = {
818
933
  $$type: '@backstage/BackstageCredentials';
934
+ /**
935
+ * If the credentials have a limited lifetime, this is the time at which they
936
+ * expire and may no longer be accepted by a receiver.
937
+ */
819
938
  expiresAt?: Date;
939
+ /**
940
+ * The principal (originator) of the request.
941
+ *
942
+ * @remarks
943
+ *
944
+ * This is semantically the originator of a request chain, and may or may not
945
+ * represent the immediate caller of your service. For example, in
946
+ * on-behalf-of scenarios, the immediate caller may be an intermediary backend
947
+ * service, but the principal may still be a user that was the original
948
+ * caller.
949
+ */
820
950
  principal: TPrincipal;
821
951
  };
822
952
  /**
953
+ * The types of principal that can be represented in a
954
+ * {@link BackstageCredentials} object.
955
+ *
823
956
  * @public
824
957
  */
825
958
  type BackstagePrincipalTypes = {
@@ -829,25 +962,85 @@ type BackstagePrincipalTypes = {
829
962
  unknown: unknown;
830
963
  };
831
964
  /**
965
+ * Provides token authentication and credentials management.
966
+ *
967
+ * See the {@link https://backstage.io/docs/backend-system/core-services/auth | service documentation} for more details.
968
+ *
832
969
  * @public
833
970
  */
834
971
  interface AuthService {
972
+ /**
973
+ * Verifies a token and returns the associated credentials.
974
+ */
835
975
  authenticate(token: string, options?: {
976
+ /**
977
+ * If set to true, allow limited access tokens (such as cookies).
978
+ *
979
+ * If this flag is not set, or is set to false, calls with limited access
980
+ * tokens will lead to a {@link @backstage/errors#NotAllowedError} being
981
+ * thrown.
982
+ */
836
983
  allowLimitedAccess?: boolean;
837
984
  }): Promise<BackstageCredentials>;
985
+ /**
986
+ * Checks if the given credentials are of the given type, and narrows the
987
+ * TypeScript type accordingly if there's a match.
988
+ */
838
989
  isPrincipal<TType extends keyof BackstagePrincipalTypes>(credentials: BackstageCredentials, type: TType): credentials is BackstageCredentials<BackstagePrincipalTypes[TType]>;
990
+ /**
991
+ * Create a credentials object that represents an unauthenticated caller.
992
+ */
839
993
  getNoneCredentials(): Promise<BackstageCredentials<BackstageNonePrincipal>>;
994
+ /**
995
+ * Create a credentials object that represents the current service itself.
996
+ */
840
997
  getOwnServiceCredentials(): Promise<BackstageCredentials<BackstageServicePrincipal>>;
998
+ /**
999
+ * Issue a token that can be used for authenticating calls towards other
1000
+ * backend plugins.
1001
+ *
1002
+ * @remarks
1003
+ *
1004
+ * This method should be called before each request. Do not cold on to the
1005
+ * issued token and reuse it for future calls.
1006
+ */
841
1007
  getPluginRequestToken(options: {
1008
+ /**
1009
+ * The credentials of the originator of the request.
1010
+ *
1011
+ * @remarks
1012
+ *
1013
+ * This is most commonly the result of
1014
+ * {@link AuthService.getOwnServiceCredentials} when the current service is
1015
+ * the originator, or the output of {@link HttpAuthService.credentials} when
1016
+ * performing requests on behalf of an incoming request identity.
1017
+ */
842
1018
  onBehalfOf: BackstageCredentials;
1019
+ /**
1020
+ * The ID of the plugin that the request is being made to.
1021
+ */
843
1022
  targetPluginId: string;
844
1023
  }): Promise<{
845
1024
  token: string;
846
1025
  }>;
847
- getLimitedUserToken(credentials: BackstageCredentials<BackstageUserPrincipal>): Promise<{
1026
+ /**
1027
+ * Issue a limited user token that can be used e.g. in cookie flows.
1028
+ */
1029
+ getLimitedUserToken(
1030
+ /**
1031
+ * The credentials that this token should represent. Must be a user
1032
+ * principal. Commonly the output of {@link HttpAuthService.credentials} is
1033
+ * used as the input.
1034
+ */
1035
+ credentials: BackstageCredentials<BackstageUserPrincipal>): Promise<{
848
1036
  token: string;
849
1037
  expiresAt: Date;
850
1038
  }>;
1039
+ /**
1040
+ * Retrieve the public keys that have been used to sign tokens that were
1041
+ * issued by this service. This list is periodically pruned from keys that are
1042
+ * significantly past their expiry.
1043
+ */
851
1044
  listPublicServiceKeys(): Promise<{
852
1045
  keys: JsonObject[];
853
1046
  }>;
@@ -864,32 +1057,168 @@ type PermissionsServiceRequestOptions = {
864
1057
  } | {
865
1058
  credentials: BackstageCredentials;
866
1059
  };
867
- /** @public */
1060
+ /**
1061
+ * Permission system integration for authorization of user/service actions.
1062
+ *
1063
+ * See the {@link https://backstage.io/docs/permissions/overview | permissions documentation}
1064
+ * and the {@link https://backstage.io/docs/backend-system/core-services/permissions | service documentation}
1065
+ * for more details.
1066
+ *
1067
+ * @public
1068
+ */
868
1069
  interface PermissionsService extends PermissionEvaluator {
1070
+ /**
1071
+ * Evaluates
1072
+ * {@link @backstage/plugin-permission-common#Permission | Permissions} and
1073
+ * returns definitive decisions.
1074
+ *
1075
+ * @remarks
1076
+ *
1077
+ * The returned array has the same number of items, in the same order, as the
1078
+ * given requests.
1079
+ */
869
1080
  authorize(requests: AuthorizePermissionRequest[], options?: PermissionsServiceRequestOptions): Promise<AuthorizePermissionResponse[]>;
1081
+ /**
1082
+ * Evaluates {@link @backstage/plugin-permission-common#ResourcePermission | ResourcePermissions} and returns both definitive and
1083
+ * conditional decisions, depending on the configured
1084
+ * {@link @backstage/plugin-permission-node#PermissionPolicy}.
1085
+ *
1086
+ * @remarks
1087
+ *
1088
+ * This method is useful when the
1089
+ * caller needs more control over the processing of conditional decisions. For example, a plugin
1090
+ * backend may want to use {@link @backstage/plugin-permission-common#PermissionCriteria | conditions} in a database query instead of
1091
+ * evaluating each resource in memory.
1092
+ *
1093
+ * The returned array has the same number of items, in the same order, as the
1094
+ * given requests.
1095
+ */
870
1096
  authorizeConditional(requests: QueryPermissionRequest[], options?: PermissionsServiceRequestOptions): Promise<QueryPermissionResponse[]>;
871
1097
  }
872
1098
 
873
- /** @public */
1099
+ /**
1100
+ * Options for {@link HttpRouterService.addAuthPolicy}.
1101
+ *
1102
+ * @public
1103
+ */
874
1104
  interface HttpRouterServiceAuthPolicy {
875
1105
  path: string;
876
1106
  allow: 'unauthenticated' | 'user-cookie';
877
1107
  }
878
1108
  /**
1109
+ * Allows plugins to register HTTP routes.
1110
+ *
1111
+ * See the {@link https://backstage.io/docs/backend-system/core-services/http-router | service documentation} for more details.
1112
+ *
879
1113
  * @public
880
1114
  */
881
1115
  interface HttpRouterService {
1116
+ /**
1117
+ * Registers an Express request handler under the plugin's base router. This
1118
+ * typically makes its base path `/api/<plugin-id>`.
1119
+ */
882
1120
  use(handler: Handler): void;
1121
+ /**
1122
+ * Adds an auth policy to the router. This is used to allow unauthenticated or
1123
+ * cookie based access to parts of a plugin's API.
1124
+ *
1125
+ * @remarks
1126
+ *
1127
+ * The paths given follow the same pattern as the routers given to the `use`
1128
+ * method, that is, they are relative to the plugin's base URL, and can
1129
+ * contain placeholders.
1130
+ *
1131
+ * @example
1132
+ *
1133
+ * ```ts
1134
+ * http.addAuthPolicy({
1135
+ * path: '/static/:id',
1136
+ * allow: 'user-cookie',
1137
+ * });
1138
+ * ```
1139
+ *
1140
+ * This allows limited access tokens via cookies on the
1141
+ * `/api/<plugin-id>/static/*` paths, but not unauthenticated access.
1142
+ */
883
1143
  addAuthPolicy(policy: HttpRouterServiceAuthPolicy): void;
884
1144
  }
885
1145
 
886
- /** @public */
1146
+ /**
1147
+ * Provides handling of credentials in an ongoing request.
1148
+ *
1149
+ * See the {@link https://backstage.io/docs/backend-system/core-services/http-auth | service documentation} for more details.
1150
+ *
1151
+ * @public
1152
+ */
887
1153
  interface HttpAuthService {
888
- credentials<TAllowed extends keyof BackstagePrincipalTypes = 'unknown'>(req: Request<any, any, any, any, any>, options?: {
1154
+ /**
1155
+ * Extracts the caller's credentials from a request.
1156
+ *
1157
+ * @remarks
1158
+ *
1159
+ * The credentials have been validated before returning, and are guaranteed to
1160
+ * adhere to whatever policies have been added to this route using
1161
+ * {@link HttpRouterService.addAuthPolicy}, if any.
1162
+ *
1163
+ * Further restrictions can be imposed by passing in options that control the
1164
+ * allowed types of credential.
1165
+ *
1166
+ * You can narrow the returned credentials object to specific principal types
1167
+ * using {@link AuthService.isPrincipal}.
1168
+ */
1169
+ credentials<TAllowed extends keyof BackstagePrincipalTypes = 'unknown'>(
1170
+ /**
1171
+ * An Express request object.
1172
+ */
1173
+ req: Request<any, any, any, any, any>,
1174
+ /**
1175
+ * Optional further restrictions.
1176
+ */
1177
+ options?: {
1178
+ /**
1179
+ * If specified, allow only principals of the given type(s).
1180
+ *
1181
+ * If the incoming credentials were not of a type that matched this
1182
+ * restriction, a {@link @backstage/errors#NotAllowedError} is thrown.
1183
+ *
1184
+ * The default is to allow user and service principals.
1185
+ */
889
1186
  allow?: Array<TAllowed>;
1187
+ /**
1188
+ * If set to true, allow limited access tokens (such as cookies).
1189
+ *
1190
+ * If this flag is not set, or is set to false, calls with limited access
1191
+ * tokens will lead to a {@link @backstage/errors#NotAllowedError} being
1192
+ * thrown.
1193
+ */
890
1194
  allowLimitedAccess?: boolean;
891
1195
  }): Promise<BackstageCredentials<BackstagePrincipalTypes[TAllowed]>>;
892
- issueUserCookie(res: Response, options?: {
1196
+ /**
1197
+ * Issues a limited access token as a cookie on the given response object.
1198
+ * This is only possible for requests that were originally made with user
1199
+ * credentials (such as a Backstage token).
1200
+ *
1201
+ * This must be called before sending any payload data.
1202
+ */
1203
+ issueUserCookie(
1204
+ /**
1205
+ * An Express response object.
1206
+ */
1207
+ res: Response,
1208
+ /**
1209
+ * Optional further settings.
1210
+ */
1211
+ options?: {
1212
+ /**
1213
+ * Issue the cookie for this specific credential. Must be a "user" type
1214
+ * principal, or a "none" type (which leads to deleting the cookie).
1215
+ *
1216
+ * @remarks
1217
+ *
1218
+ * Normally you do not have to specify this option, because the default
1219
+ * behavior is to extract the credentials from the request that
1220
+ * corresponded to the given respnse.
1221
+ */
893
1222
  credentials?: BackstageCredentials;
894
1223
  }): Promise<{
895
1224
  expiresAt: Date;
@@ -900,6 +1229,10 @@ interface HttpAuthService {
900
1229
  * The DiscoveryService is used to provide a mechanism for backend
901
1230
  * plugins to discover the endpoints for itself or other backend plugins.
902
1231
  *
1232
+ * See the {@link https://backstage.io/docs/backend-system/core-services/discovery | service documentation} for more details.
1233
+ *
1234
+ * @remarks
1235
+ *
903
1236
  * The purpose of the discovery API is to allow for many different deployment
904
1237
  * setups and routing methods through a central configuration, instead
905
1238
  * of letting each individual plugin manage that configuration.
@@ -914,13 +1247,15 @@ interface DiscoveryService {
914
1247
  /**
915
1248
  * Returns the internal HTTP base URL for a given plugin, without a trailing slash.
916
1249
  *
1250
+ * @remarks
1251
+ *
917
1252
  * The returned URL should point to an internal endpoint for the plugin, with
918
1253
  * the shortest route possible. The URL should be used for service-to-service
919
1254
  * communication within a Backstage backend deployment.
920
1255
  *
921
- * This method must always be called just before making a request, as opposed to
922
- * fetching the URL when constructing an API client. That is to ensure that more
923
- * flexible routing patterns can be supported.
1256
+ * This method must always be called just before making each request, as opposed to
1257
+ * fetching the URL once when constructing an API client. That is to ensure that more
1258
+ * flexible routing patterns can be supported where a different result might be returned each time.
924
1259
  *
925
1260
  * For example, asking for the URL for `catalog` may return something
926
1261
  * like `http://10.1.2.3/api/catalog`
@@ -929,6 +1264,8 @@ interface DiscoveryService {
929
1264
  /**
930
1265
  * Returns the external HTTP base backend URL for a given plugin, without a trailing slash.
931
1266
  *
1267
+ * @remarks
1268
+ *
932
1269
  * The returned URL should point to an external endpoint for the plugin, such that
933
1270
  * it is reachable from the Backstage frontend and other external services. The returned
934
1271
  * URL should be usable for example as a callback / webhook URL.
@@ -944,7 +1281,9 @@ interface DiscoveryService {
944
1281
  }
945
1282
 
946
1283
  /**
947
- * The DatabaseService manages access to databases that Plugins get.
1284
+ * Manages access to databases that plugins get.
1285
+ *
1286
+ * See the {@link https://backstage.io/docs/backend-system/core-services/database | service documentation} for more details.
948
1287
  *
949
1288
  * @public
950
1289
  */
@@ -970,6 +1309,12 @@ interface DatabaseService {
970
1309
  }
971
1310
 
972
1311
  /**
1312
+ * Provides access to static configuration.
1313
+ *
1314
+ * See the {@link https://backstage.io/docs/conf/ | configuration documentation}
1315
+ * and the {@link https://backstage.io/docs/backend-system/core-services/root-config | service documentation}
1316
+ * for more details.
1317
+ *
973
1318
  * @public
974
1319
  */
975
1320
  interface RootConfigService extends Config {
@@ -1004,6 +1349,8 @@ type CacheServiceOptions = {
1004
1349
  * A pre-configured, storage agnostic cache service suitable for use by
1005
1350
  * Backstage plugins.
1006
1351
  *
1352
+ * See the {@link https://backstage.io/docs/backend-system/core-services/cache | service documentation} for more details.
1353
+ *
1007
1354
  * @public
1008
1355
  */
1009
1356
  interface CacheService {
@@ -1028,13 +1375,27 @@ interface CacheService {
1028
1375
  withOptions(options: CacheServiceOptions): CacheService;
1029
1376
  }
1030
1377
 
1031
- /** @public */
1378
+ /**
1379
+ * Represents user information that is available to the backend, based on some
1380
+ * user credentials.
1381
+ *
1382
+ * @public
1383
+ */
1032
1384
  interface BackstageUserInfo {
1033
1385
  userEntityRef: string;
1034
1386
  ownershipEntityRefs: string[];
1035
1387
  }
1036
- /** @public */
1388
+ /**
1389
+ * Authenticated user information retrieval.
1390
+ *
1391
+ * See the {@link https://backstage.io/docs/backend-system/core-services/user-info | service documentation} for more details.
1392
+ *
1393
+ * @public
1394
+ */
1037
1395
  interface UserInfoService {
1396
+ /**
1397
+ * Retrieve user information based on the provided credentials.
1398
+ */
1038
1399
  getUserInfo(credentials: BackstageCredentials): Promise<BackstageUserInfo>;
1039
1400
  }
1040
1401
 
@@ -1473,4 +1834,4 @@ type BackendModuleConfig = CreateBackendModuleOptions;
1473
1834
  */
1474
1835
  type ExtensionPointConfig = CreateExtensionPointOptions;
1475
1836
 
1476
- export { type AuthService, type BackendFeature, type BackendModuleConfig, type BackendModuleRegistrationPoints, type BackendPluginConfig, type BackendPluginRegistrationPoints, type BackstageCredentials, type BackstageNonePrincipal, type BackstagePrincipalAccessRestrictions, type BackstagePrincipalTypes, type BackstageServicePrincipal, type BackstageUserInfo, type BackstageUserPrincipal, type CacheService, type CacheServiceOptions, type CacheServiceSetOptions, type CreateBackendModuleOptions, type CreateBackendPluginOptions, type CreateExtensionPointOptions, type DatabaseService, type DiscoveryService, type ExtensionPoint, type ExtensionPointConfig, type HttpAuthService, type HttpRouterService, type HttpRouterServiceAuthPolicy, type IdentityService, type LifecycleService, type LifecycleServiceShutdownHook, type LifecycleServiceShutdownOptions, type LifecycleServiceStartupHook, type LifecycleServiceStartupOptions, type LoggerService, type PermissionsService, type PermissionsServiceRequestOptions, type PluginMetadataService, type PluginServiceFactoryConfig, type ReadTreeOptions, type ReadTreeResponse, type ReadTreeResponseDirOptions, type ReadTreeResponseFile, type ReadUrlOptions, type ReadUrlResponse, type RootConfigService, type RootHttpRouterService, type RootLifecycleService, type RootLoggerService, type RootServiceFactoryConfig, type SchedulerService, type SchedulerServiceTaskDescriptor, type SchedulerServiceTaskFunction, type SchedulerServiceTaskInvocationDefinition, type SchedulerServiceTaskRunner, type SchedulerServiceTaskScheduleDefinition, type SchedulerServiceTaskScheduleDefinitionConfig, type SearchOptions, type SearchResponse, type SearchResponseFile, type ServiceFactory, type ServiceFactoryOrFunction, type ServiceRef, type ServiceRefConfig, type TokenManagerService, type UrlReaderService, type UserInfoService, coreServices, createBackendModule, createBackendPlugin, createExtensionPoint, createServiceFactory, createServiceRef, isDatabaseConflictError, readSchedulerServiceTaskScheduleDefinitionFromConfig, resolvePackagePath, resolveSafeChildPath };
1837
+ export { type AuthService, type BackendFeature, type BackendModuleConfig, type BackendModuleRegistrationPoints, type BackendPluginConfig, type BackendPluginRegistrationPoints, type BackstageCredentials, type BackstageNonePrincipal, type BackstagePrincipalAccessRestrictions, type BackstagePrincipalTypes, type BackstageServicePrincipal, type BackstageUserInfo, type BackstageUserPrincipal, type CacheService, type CacheServiceOptions, type CacheServiceSetOptions, type CreateBackendModuleOptions, type CreateBackendPluginOptions, type CreateExtensionPointOptions, type DatabaseService, type DiscoveryService, type ExtensionPoint, type ExtensionPointConfig, type HttpAuthService, type HttpRouterService, type HttpRouterServiceAuthPolicy, type IdentityService, type LifecycleService, type LifecycleServiceShutdownHook, type LifecycleServiceShutdownOptions, type LifecycleServiceStartupHook, type LifecycleServiceStartupOptions, type LoggerService, type PermissionsService, type PermissionsServiceRequestOptions, type PluginMetadataService, type PluginServiceFactoryConfig, type ReadTreeOptions, type ReadTreeResponse, type ReadTreeResponseDirOptions, type ReadTreeResponseFile, type ReadUrlOptions, type ReadUrlResponse, type RootConfigService, type RootHttpRouterService, type RootLifecycleService, type RootLoggerService, type RootServiceFactoryConfig, type SchedulerService, type SchedulerServiceTaskDescriptor, type SchedulerServiceTaskFunction, type SchedulerServiceTaskInvocationDefinition, type SchedulerServiceTaskRunner, type SchedulerServiceTaskScheduleDefinition, type SchedulerServiceTaskScheduleDefinitionConfig, type SearchOptions, type SearchResponse, type SearchResponseFile, type ServiceFactory, type ServiceFactoryOrFunction, type ServiceRef, type ServiceRefConfig, type TokenManagerService, type UrlReaderReadTreeOptions, type UrlReaderReadTreeResponse, type UrlReaderReadTreeResponseDirOptions, type UrlReaderReadTreeResponseFile, type UrlReaderReadUrlOptions, type UrlReaderReadUrlResponse, type UrlReaderSearchOptions, type UrlReaderSearchResponse, type UrlReaderSearchResponseFile, type UrlReaderService, type UserInfoService, coreServices, createBackendModule, createBackendPlugin, createExtensionPoint, createServiceFactory, createServiceRef, isDatabaseConflictError, readSchedulerServiceTaskScheduleDefinitionFromConfig, resolvePackagePath, resolveSafeChildPath };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/backend-plugin-api",
3
- "version": "0.6.19-next.1",
3
+ "version": "0.6.19-next.3",
4
4
  "description": "Core API used by Backstage backend plugins",
5
5
  "backstage": {
6
6
  "role": "node-library"
@@ -53,11 +53,11 @@
53
53
  "test": "backstage-cli package test"
54
54
  },
55
55
  "dependencies": {
56
- "@backstage/cli-common": "^0.1.13",
56
+ "@backstage/cli-common": "^0.1.14-next.0",
57
57
  "@backstage/config": "^1.2.0",
58
58
  "@backstage/errors": "^1.2.4",
59
- "@backstage/plugin-auth-node": "^0.4.14-next.1",
60
- "@backstage/plugin-permission-common": "^0.7.13",
59
+ "@backstage/plugin-auth-node": "^0.4.14-next.3",
60
+ "@backstage/plugin-permission-common": "^0.7.14-next.0",
61
61
  "@backstage/types": "^1.1.1",
62
62
  "@types/express": "^4.17.6",
63
63
  "@types/luxon": "^3.0.0",
@@ -66,7 +66,7 @@
66
66
  "luxon": "^3.0.0"
67
67
  },
68
68
  "devDependencies": {
69
- "@backstage/backend-test-utils": "^0.4.0-next.1",
70
- "@backstage/cli": "^0.26.7-next.1"
69
+ "@backstage/backend-test-utils": "^0.4.0-next.3",
70
+ "@backstage/cli": "^0.26.7-next.3"
71
71
  }
72
72
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/backend-plugin-api",
3
- "version": "0.6.19-next.1",
3
+ "version": "0.6.19-next.3",
4
4
  "main": "../dist/testUtils.cjs.js",
5
5
  "types": "../dist/testUtils.d.ts"
6
6
  }