@backstage/backend-plugin-api 0.8.1 → 0.9.0-next.1

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,11 +1,47 @@
1
1
  # @backstage/backend-plugin-api
2
2
 
3
- ## 0.8.1
3
+ ## 0.9.0-next.1
4
4
 
5
5
  ### Patch Changes
6
6
 
7
7
  - Updated dependencies
8
- - @backstage/plugin-auth-node@0.5.1
8
+ - @backstage/plugin-auth-node@0.5.2-next.1
9
+ - @backstage/cli-common@0.1.14
10
+ - @backstage/config@1.2.0
11
+ - @backstage/errors@1.2.4
12
+ - @backstage/types@1.1.1
13
+ - @backstage/plugin-permission-common@0.8.1
14
+
15
+ ## 0.9.0-next.0
16
+
17
+ ### Minor Changes
18
+
19
+ - 19ff127: **BREAKING**: The deprecated identity and token manager services have been removed. This means that `coreServices.identity` and `coreServices.tokenManager` are gone, along with related types and utilities in other packages.
20
+ - f687050: Removed the following deprecated exports
21
+
22
+ - `BackendPluginConfig` use `CreateBackendPluginOptions`
23
+ - `BackendModuleConfig` use `CreateBackendModuleOptions`
24
+ - `ExtensionPointConfig` use `CreateExtensionPointOptions`
25
+
26
+ - 4d82481: Removed deprecated `ServiceFactoryOrFunction` type.
27
+ - d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs.
28
+
29
+ This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config.
30
+
31
+ As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it.
32
+
33
+ ### Patch Changes
34
+
35
+ - cd38da8: Deprecate the `featureDiscoveryServiceRef` in favor of using the new `discoveryFeatureLoader` instead.
36
+ - 66dbf0a: Allow the cache service to accept the human duration format for TTL
37
+ - 0b2a402: Updates to the config schema to match reality
38
+ - Updated dependencies
39
+ - @backstage/plugin-auth-node@0.5.2-next.0
40
+ - @backstage/cli-common@0.1.14
41
+ - @backstage/config@1.2.0
42
+ - @backstage/errors@1.2.4
43
+ - @backstage/types@1.1.1
44
+ - @backstage/plugin-permission-common@0.8.1
9
45
 
10
46
  ## 0.8.0
11
47
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/backend-plugin-api__alpha",
3
- "version": "0.8.1",
3
+ "version": "0.9.0-next.1",
4
4
  "main": "../dist/alpha.cjs.js",
5
5
  "types": "../dist/alpha.d.ts"
6
6
  }
package/config.d.ts ADDED
@@ -0,0 +1,35 @@
1
+ /*
2
+ * Copyright 2024 The Backstage Authors
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ export interface Config {
18
+ backend?: {
19
+ /**
20
+ * An absolute path to a directory that can be used as a working dir, for
21
+ * example as scratch space for large operations.
22
+ *
23
+ * @remarks
24
+ *
25
+ * Note that this must be an absolute path.
26
+ *
27
+ * If not set, the operating system's designated temporary directory is
28
+ * commonly used, but that is implementation defined per plugin.
29
+ *
30
+ * Plugins are encouraged to heed this config setting if present, to allow
31
+ * deployment in severely locked-down or limited environments.
32
+ */
33
+ workingDirectory?: string;
34
+ };
35
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"alpha.cjs.js","sources":["../src/alpha.ts"],"sourcesContent":["/*\n * Copyright 2023 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 {\n BackendFeature,\n createServiceRef,\n} from '@backstage/backend-plugin-api';\n\n/** @alpha */\nexport interface FeatureDiscoveryService {\n getBackendFeatures(): Promise<{ features: Array<BackendFeature> }>;\n}\n\n/**\n * An optional service that can be used to dynamically load in additional BackendFeatures at runtime.\n * @alpha\n */\nexport const featureDiscoveryServiceRef =\n createServiceRef<FeatureDiscoveryService>({\n id: 'core.featureDiscovery',\n scope: 'root',\n });\n"],"names":["createServiceRef"],"mappings":";;;;AA8BO,MAAM,6BACXA,iCAA0C,CAAA;AAAA,EACxC,EAAI,EAAA,uBAAA;AAAA,EACJ,KAAO,EAAA,MAAA;AACT,CAAC;;;;"}
1
+ {"version":3,"file":"alpha.cjs.js","sources":["../src/alpha.ts"],"sourcesContent":["/*\n * Copyright 2023 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 {\n BackendFeature,\n createServiceRef,\n} from '@backstage/backend-plugin-api';\n\n/** @alpha */\nexport interface FeatureDiscoveryService {\n getBackendFeatures(): Promise<{ features: Array<BackendFeature> }>;\n}\n\n/**\n * An optional service that can be used to dynamically load in additional BackendFeatures at runtime.\n * @alpha\n * @deprecated The `featureDiscoveryServiceRef` is deprecated in favor of using {@link @backstage/backend-defaults#discoveryFeatureLoader} instead.\n */\nexport const featureDiscoveryServiceRef =\n createServiceRef<FeatureDiscoveryService>({\n id: 'core.featureDiscovery',\n scope: 'root',\n });\n"],"names":["createServiceRef"],"mappings":";;;;AA+BO,MAAM,6BACXA,iCAA0C,CAAA;AAAA,EACxC,EAAI,EAAA,uBAAA;AAAA,EACJ,KAAO,EAAA,MAAA;AACT,CAAC;;;;"}
package/dist/alpha.d.ts CHANGED
@@ -10,6 +10,7 @@ interface FeatureDiscoveryService {
10
10
  /**
11
11
  * An optional service that can be used to dynamically load in additional BackendFeatures at runtime.
12
12
  * @alpha
13
+ * @deprecated The `featureDiscoveryServiceRef` is deprecated in favor of using {@link @backstage/backend-defaults#discoveryFeatureLoader} instead.
13
14
  */
14
15
  declare const featureDiscoveryServiceRef: _backstage_backend_plugin_api.ServiceRef<FeatureDiscoveryService, "root", "singleton">;
15
16
 
package/dist/index.cjs.js CHANGED
@@ -25,36 +25,31 @@ function createServiceRef(options) {
25
25
  };
26
26
  }
27
27
  function createServiceFactory(options) {
28
- const configCallback = typeof options === "function" ? options : () => options;
29
- const factory = (o) => {
30
- const anyConf = configCallback(o);
31
- if (anyConf.service.scope === "root") {
32
- const c2 = anyConf;
33
- return {
34
- $$type: "@backstage/BackendFeature",
35
- version: "v1",
36
- featureType: "service",
37
- service: c2.service,
38
- initialization: c2.initialization,
39
- deps: c2.deps,
40
- factory: async (deps) => c2.factory(deps)
41
- };
42
- }
43
- const c = anyConf;
28
+ if (options.service.scope === "root") {
29
+ const c2 = options;
44
30
  return {
45
31
  $$type: "@backstage/BackendFeature",
46
32
  version: "v1",
47
33
  featureType: "service",
48
- service: c.service,
49
- initialization: c.initialization,
50
- ..."createRootContext" in c ? {
51
- createRootContext: async (deps) => c?.createRootContext?.(deps)
52
- } : {},
53
- deps: c.deps,
54
- factory: async (deps, ctx) => c.factory(deps, ctx)
34
+ service: c2.service,
35
+ initialization: c2.initialization,
36
+ deps: options.deps,
37
+ factory: async (deps) => c2.factory(deps)
55
38
  };
39
+ }
40
+ const c = options;
41
+ return {
42
+ $$type: "@backstage/BackendFeature",
43
+ version: "v1",
44
+ featureType: "service",
45
+ service: c.service,
46
+ initialization: c.initialization,
47
+ ..."createRootContext" in options ? {
48
+ createRootContext: async (deps) => c?.createRootContext?.(deps)
49
+ } : {},
50
+ deps: options.deps,
51
+ factory: async (deps, ctx) => c.factory(deps, ctx)
56
52
  };
57
- return Object.assign(factory, factory(void 0));
58
53
  }
59
54
 
60
55
  exports.coreServices = void 0;
@@ -82,9 +77,7 @@ exports.coreServices = void 0;
82
77
  coreServices2.rootLifecycle = createServiceRef({ id: "core.rootLifecycle", scope: "root" });
83
78
  coreServices2.rootLogger = createServiceRef({ id: "core.rootLogger", scope: "root" });
84
79
  coreServices2.scheduler = createServiceRef({ id: "core.scheduler" });
85
- coreServices2.tokenManager = createServiceRef({ id: "core.tokenManager" });
86
80
  coreServices2.urlReader = createServiceRef({ id: "core.urlReader" });
87
- coreServices2.identity = createServiceRef({ id: "core.identity" });
88
81
  })(exports.coreServices || (exports.coreServices = {}));
89
82
 
90
83
  function readDuration(config$1, key) {
@@ -167,15 +160,12 @@ function createBackendModule(options) {
167
160
  }
168
161
  ];
169
162
  }
170
- function backendFeatureCompatWrapper() {
171
- return backendFeatureCompatWrapper;
172
- }
173
- Object.assign(backendFeatureCompatWrapper, {
163
+ return {
174
164
  $$type: "@backstage/BackendFeature",
165
+ featureType: "registrations",
175
166
  version: "v1",
176
167
  getRegistrations
177
- });
178
- return backendFeatureCompatWrapper;
168
+ };
179
169
  }
180
170
 
181
171
  function createBackendPlugin(options) {
@@ -213,15 +203,12 @@ function createBackendPlugin(options) {
213
203
  }
214
204
  ];
215
205
  }
216
- function backendFeatureCompatWrapper() {
217
- return backendFeatureCompatWrapper;
218
- }
219
- Object.assign(backendFeatureCompatWrapper, {
206
+ return {
220
207
  $$type: "@backstage/BackendFeature",
221
208
  version: "v1",
209
+ featureType: "registrations",
222
210
  getRegistrations
223
- });
224
- return backendFeatureCompatWrapper;
211
+ };
225
212
  }
226
213
 
227
214
  function createExtensionPoint(options) {
@@ -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/createBackendModule.ts","../src/wiring/createBackendPlugin.ts","../src/wiring/createExtensionPoint.ts","../../frontend-plugin-api/src/routing/describeParentCallSite.ts","../src/wiring/createBackendFeatureLoader.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 TInstances extends 'singleton' | 'multiton' = 'singleton' | 'multiton',\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 multiton?: TInstances extends 'multiton' ? true : false;\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 TInstances extends 'singleton' | 'multiton' = 'singleton' | 'multiton',\n> extends BackendFeature {\n service: ServiceRef<TService, TScope, TInstances>;\n}\n\n/**\n * @public\n * @deprecated This type exists only as a helper for old code that relied on `createServiceFactory` to return `() => ServiceFactory` instead of `ServiceFactory`. You should remove the `()` parentheses at the end of your usages. This type will be removed in a future release.\n */\nexport interface ServiceFactoryCompat<\n TService = unknown,\n TScope extends 'plugin' | 'root' = 'plugin' | 'root',\n TInstances extends 'singleton' | 'multiton' = 'singleton' | 'multiton',\n TOpts extends object | undefined = undefined,\n> extends ServiceFactory<TService, TScope, TInstances> {\n /**\n * @deprecated Callable service factories will be removed in a future release, please re-implement the service factory using the available APIs instead. If no options are being passed, you can simply remove the trailing `()`.\n */\n (\n ...options: undefined extends TOpts ? [] : [options?: TOpts]\n ): ServiceFactory<TService, TScope, TInstances>;\n}\n\n/** @internal */\nexport interface InternalServiceFactory<\n TService = unknown,\n TScope extends 'plugin' | 'root' = 'plugin' | 'root',\n TInstances extends 'singleton' | 'multiton' = 'singleton' | 'multiton',\n> extends ServiceFactory<TService, TScope, TInstances> {\n version: 'v1';\n featureType: 'service';\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 * @deprecated The support for service factory functions is deprecated and will be removed.\n * @public\n */\nexport type ServiceFactoryOrFunction = ServiceFactory | (() => ServiceFactory);\n\n/** @public */\nexport interface ServiceRefOptions<\n TService,\n TScope extends 'root' | 'plugin',\n TInstances extends 'singleton' | 'multiton',\n> {\n id: string;\n scope?: TScope;\n multiton?: TInstances extends 'multiton' ? true : false;\n defaultFactory?(\n service: ServiceRef<TService, TScope>,\n ): Promise<ServiceFactory>;\n /**\n * @deprecated The defaultFactory must return a plain `ServiceFactory` object, support for returning a function will be removed.\n */\n defaultFactory?(\n service: ServiceRef<TService, TScope>,\n ): Promise<() => ServiceFactory>;\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 options: ServiceRefOptions<TService, 'plugin', 'singleton'>,\n): ServiceRef<TService, 'plugin', 'singleton'>;\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 options: ServiceRefOptions<TService, 'root', 'singleton'>,\n): ServiceRef<TService, 'root', 'singleton'>;\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 options: ServiceRefOptions<TService, 'plugin', 'multiton'>,\n): ServiceRef<TService, 'plugin', 'multiton'>;\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 options: ServiceRefOptions<TService, 'root', 'multiton'>,\n): ServiceRef<TService, 'root', 'multiton'>;\nexport function createServiceRef<\n TService,\n TInstances extends 'singleton' | 'multiton',\n>(\n options: ServiceRefOptions<TService, any, TInstances>,\n): ServiceRef<TService, any, TInstances> {\n const { id, scope = 'plugin', multiton = false, defaultFactory } = options;\n return {\n id,\n scope,\n multiton,\n get T(): TService {\n throw new Error(`tried to read ServiceRef.T of ${this}`);\n },\n toString() {\n return `serviceRef{${options.id}}`;\n },\n $$type: '@backstage/ServiceRef',\n __defaultFactory: defaultFactory,\n } as ServiceRef<TService, typeof scope, TInstances> & {\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\n ? key\n : never]: T[key]['multiton'] extends true | undefined\n ? Array<T[key]['T']>\n : T[key]['T'];\n};\n\n/** @public */\nexport interface RootServiceFactoryOptions<\n TService, // TODO(Rugvip): Can we forward the entire service ref type here instead of forwarding each type arg once the callback form is gone?\n TInstances extends 'singleton' | 'multiton',\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', TInstances>;\n deps: TDeps;\n factory(deps: ServiceRefsToInstances<TDeps, 'root'>): TImpl | Promise<TImpl>;\n}\n\n/** @public */\nexport interface PluginServiceFactoryOptions<\n TService,\n TInstances extends 'singleton' | 'multiton',\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', TInstances>;\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 options - The service factory configuration.\n */\nexport function createServiceFactory<\n TService,\n TInstances extends 'singleton' | 'multiton',\n TImpl extends TService,\n TDeps extends { [name in string]: ServiceRef<unknown, 'root'> },\n TOpts extends object | undefined = undefined,\n>(\n options: RootServiceFactoryOptions<TService, TInstances, TImpl, TDeps>,\n): ServiceFactoryCompat<TService, 'root', TInstances>;\n/**\n * Creates a root scoped service factory with optional options.\n *\n * @deprecated The ability to define options for service factories is deprecated\n * and will be removed. Please use the non-callback form of createServiceFactory\n * and provide an API that allows for a simple re-implementation of the service\n * factory instead.\n * @public\n * @param options - The service factory configuration.\n */\nexport function createServiceFactory<\n TService,\n TInstances extends 'singleton' | 'multiton',\n TImpl extends TService,\n TDeps extends { [name in string]: ServiceRef<unknown, 'root'> },\n TOpts extends object | undefined = undefined,\n>(\n options: (\n options?: TOpts,\n ) => RootServiceFactoryOptions<TService, TInstances, TImpl, TDeps>,\n): ServiceFactoryCompat<TService, 'root', TInstances, TOpts>;\n/**\n * Creates a plugin scoped service factory without options.\n *\n * @public\n * @param options - The service factory configuration.\n */\nexport function createServiceFactory<\n TService,\n TInstances extends 'singleton' | 'multiton',\n TImpl extends TService,\n TDeps extends { [name in string]: ServiceRef<unknown> },\n TContext = undefined,\n TOpts extends object | undefined = undefined,\n>(\n options: PluginServiceFactoryOptions<\n TService,\n TInstances,\n TContext,\n TImpl,\n TDeps\n >,\n): ServiceFactoryCompat<TService, 'plugin', TInstances>;\n/**\n * Creates a plugin scoped service factory with optional options.\n *\n * @deprecated The ability to define options for service factories is deprecated\n * and will be removed. Please use the non-callback form of createServiceFactory\n * and provide an API that allows for a simple re-implementation of the service\n * factory instead.\n * @public\n * @param options - The service factory configuration.\n */\nexport function createServiceFactory<\n TService,\n TInstances extends 'singleton' | 'multiton',\n TImpl extends TService,\n TDeps extends { [name in string]: ServiceRef<unknown> },\n TContext = undefined,\n TOpts extends object | undefined = undefined,\n>(\n options: (\n options?: TOpts,\n ) => PluginServiceFactoryOptions<\n TService,\n TInstances,\n TContext,\n TImpl,\n TDeps\n >,\n): ServiceFactoryCompat<TService, 'plugin', TInstances, TOpts>;\nexport function createServiceFactory<\n TService,\n TInstances extends 'singleton' | 'multiton',\n TImpl extends TService,\n TDeps extends { [name in string]: ServiceRef<unknown> },\n TContext,\n TOpts extends object | undefined = undefined,\n>(\n options:\n | RootServiceFactoryOptions<TService, TInstances, TImpl, TDeps>\n | PluginServiceFactoryOptions<TService, TInstances, TContext, TImpl, TDeps>\n | ((\n options: TOpts,\n ) => RootServiceFactoryOptions<TService, TInstances, TImpl, TDeps>)\n | ((\n options: TOpts,\n ) => PluginServiceFactoryOptions<\n TService,\n TInstances,\n TContext,\n TImpl,\n TDeps\n >)\n | (() => RootServiceFactoryOptions<TService, TInstances, TImpl, TDeps>)\n | (() => PluginServiceFactoryOptions<\n TService,\n TInstances,\n TContext,\n TImpl,\n TDeps\n >),\n): ServiceFactoryCompat<\n TService,\n 'root' | 'plugin',\n 'singleton' | 'multiton',\n TOpts\n> {\n const configCallback =\n typeof options === 'function' ? options : () => options;\n const factory = (\n o?: TOpts,\n ): InternalServiceFactory<TService, 'plugin' | 'root'> => {\n const anyConf = configCallback(o!);\n if (anyConf.service.scope === 'root') {\n const c = anyConf as RootServiceFactoryOptions<\n TService,\n TInstances,\n TImpl,\n TDeps\n >;\n return {\n $$type: '@backstage/BackendFeature',\n version: 'v1',\n featureType: 'service',\n service: c.service,\n initialization: c.initialization,\n deps: c.deps,\n factory: async (deps: ServiceRefsToInstances<TDeps, 'root'>) =>\n c.factory(deps),\n };\n }\n const c = anyConf as PluginServiceFactoryOptions<\n TService,\n TInstances,\n TContext,\n TImpl,\n TDeps\n >;\n return {\n $$type: '@backstage/BackendFeature',\n version: 'v1',\n featureType: 'service',\n service: c.service,\n initialization: c.initialization,\n ...('createRootContext' in c\n ? {\n createRootContext: async (\n deps: ServiceRefsToInstances<TDeps, 'root'>,\n ) => c?.createRootContext?.(deps),\n }\n : {}),\n deps: c.deps,\n factory: async (deps: ServiceRefsToInstances<TDeps>, ctx: TContext) =>\n c.factory(deps, ctx),\n };\n };\n\n // This constructs the `ServiceFactoryCompat` type, which is both a plain\n // factory object as well as a function that can be called to construct a\n // factory, potentially with options. In the future only the plain factory\n // form will be supported, but for now we need to allow callers to call the\n // factory too.\n return Object.assign(factory, factory(undefined as TOpts));\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 * Handles token authentication and credentials management.\n *\n * See {@link AuthService}\n * and {@link https://backstage.io/docs/backend-system/core-services/auth | the service docs}\n * for more information.\n *\n * @public\n */\n export const auth = createServiceRef<import('./AuthService').AuthService>({\n id: 'core.auth',\n });\n\n /**\n * Authenticated user information retrieval.\n *\n * See {@link UserInfoService}\n * and {@link https://backstage.io/docs/backend-system/core-services/user-info | the service docs}\n * for more information.\n *\n * @public\n */\n export const userInfo = createServiceRef<\n import('./UserInfoService').UserInfoService\n >({\n id: 'core.userInfo',\n });\n\n /**\n * Key-value store for caching data.\n *\n * See {@link CacheService}\n * and {@link https://backstage.io/docs/backend-system/core-services/cache | the service docs}\n * for more information.\n *\n * @public\n */\n export const cache = createServiceRef<import('./CacheService').CacheService>({\n id: 'core.cache',\n });\n\n /**\n * Access to static configuration.\n *\n * See {@link RootConfigService}\n * and {@link https://backstage.io/docs/backend-system/core-services/root-config | the service docs}\n * for more information.\n *\n * @public\n */\n export const rootConfig = createServiceRef<\n import('./RootConfigService').RootConfigService\n >({ id: 'core.rootConfig', scope: 'root' });\n\n /**\n * Database access and management via `knex`.\n *\n * See {@link DatabaseService}\n * and {@link https://backstage.io/docs/backend-system/core-services/database | the service docs}\n * for more information.\n *\n * @public\n */\n export const database = createServiceRef<\n import('./DatabaseService').DatabaseService\n >({ id: 'core.database' });\n\n /**\n * Service discovery for inter-plugin communication.\n *\n * See {@link DiscoveryService}\n * and {@link https://backstage.io/docs/backend-system/core-services/discovery | the service docs}\n * for more information.\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 RootHealthService}.\n */\n export const rootHealth = createServiceRef<\n import('./RootHealthService').RootHealthService\n >({ id: 'core.rootHealth', scope: 'root' });\n\n /**\n * Authentication of HTTP requests.\n *\n * See {@link HttpAuthService}\n * and {@link https://backstage.io/docs/backend-system/core-services/http-auth | the service docs}\n * for more information.\n *\n * @public\n */\n export const httpAuth = createServiceRef<\n import('./HttpAuthService').HttpAuthService\n >({ id: 'core.httpAuth' });\n\n /**\n * HTTP route registration for plugins.\n *\n * See {@link HttpRouterService}\n * and {@link https://backstage.io/docs/backend-system/core-services/http-router | the service docs}\n * for more information.\n *\n * @public\n */\n export const httpRouter = createServiceRef<\n import('./HttpRouterService').HttpRouterService\n >({ id: 'core.httpRouter' });\n\n /**\n * Registration of plugin startup and shutdown lifecycle hooks.\n *\n * See {@link LifecycleService}\n * and {@link https://backstage.io/docs/backend-system/core-services/lifecycle | the service docs}\n * for more information.\n *\n * @public\n */\n export const lifecycle = createServiceRef<\n import('./LifecycleService').LifecycleService\n >({ id: 'core.lifecycle' });\n\n /**\n * Plugin-level logging.\n *\n * See {@link LoggerService}\n * and {@link https://backstage.io/docs/backend-system/core-services/logger | the service docs}\n * for more information.\n *\n * @public\n */\n export const logger = createServiceRef<\n import('./LoggerService').LoggerService\n >({ id: 'core.logger' });\n\n /**\n * Permission system integration for authorization of user actions.\n *\n * See {@link PermissionsService}\n * and {@link https://backstage.io/docs/backend-system/core-services/permissions | the service docs}\n * for more information.\n *\n * @public\n */\n export const permissions = createServiceRef<\n import('./PermissionsService').PermissionsService\n >({ id: 'core.permissions' });\n\n /**\n * Built-in service for accessing metadata about the current plugin.\n *\n * See {@link PluginMetadataService}\n * and {@link https://backstage.io/docs/backend-system/core-services/plugin-metadata | the service docs}\n * for more information.\n *\n * @public\n */\n export const pluginMetadata = createServiceRef<\n import('./PluginMetadataService').PluginMetadataService\n >({ id: 'core.pluginMetadata' });\n\n /**\n * HTTP route registration for root services.\n *\n * See {@link RootHttpRouterService}\n * and {@link https://backstage.io/docs/backend-system/core-services/root-http-router | the service docs}\n * for more information.\n *\n * @public\n */\n export const rootHttpRouter = createServiceRef<\n import('./RootHttpRouterService').RootHttpRouterService\n >({ id: 'core.rootHttpRouter', scope: 'root' });\n\n /**\n * Registration of backend startup and shutdown lifecycle hooks.\n *\n * See {@link RootLifecycleService}\n * and {@link https://backstage.io/docs/backend-system/core-services/root-lifecycle | the service docs}\n * for more information.\n *\n * @public\n */\n export const rootLifecycle = createServiceRef<\n import('./RootLifecycleService').RootLifecycleService\n >({ id: 'core.rootLifecycle', scope: 'root' });\n\n /**\n * Root-level logging.\n *\n * See {@link RootLoggerService}\n * and {@link https://backstage.io/docs/backend-system/core-services/root-logger | the service docs}\n * for more information.\n *\n * @public\n */\n export const rootLogger = createServiceRef<\n import('./RootLoggerService').RootLoggerService\n >({ id: 'core.rootLogger', scope: 'root' });\n\n /**\n * Scheduling of distributed background tasks.\n *\n * See {@link SchedulerService}\n * and {@link https://backstage.io/docs/backend-system/core-services/scheduler | the service docs}\n * for more information.\n *\n * @public\n */\n export const scheduler = createServiceRef<\n import('./SchedulerService').SchedulerService\n >({ id: 'core.scheduler' });\n\n /**\n * Deprecated service authentication service, use the `auth` service instead.\n *\n * See {@link TokenManagerService}\n * and {@link https://backstage.io/docs/backend-system/core-services/token-manager | the service docs}\n * for more information.\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 * Reading content from external systems.\n *\n * See {@link UrlReaderService}\n * and {@link https://backstage.io/docs/backend-system/core-services/url-reader | the service docs}\n * for more information.\n *\n * @public\n */\n export const urlReader = createServiceRef<\n import('./UrlReaderService').UrlReaderService\n >({ id: 'core.urlReader' });\n\n /**\n * Deprecated user authentication service, use the `auth` service instead.\n *\n * See {@link IdentityService}\n * and {@link https://backstage.io/docs/backend-system/core-services/identity | the service docs}\n * for more information.\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 | { trigger: 'manual' };\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 * This task will only run when manually triggered with the `triggerTask` method; no automatic\n * scheduling. This is useful for locking of global tasks that should not be run concurrently.\n */\n | { trigger: 'manual' };\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): 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.toObject();\n }\n\n return readDurationFromConfig(config, { key });\n}\n\nfunction readFrequency(\n config: Config,\n key: string,\n): { cron: string } | HumanDuration | { trigger: 'manual' } {\n const value = config.get(key);\n if (typeof value === 'object' && (value as { cron?: string }).cron) {\n return value as { cron: string };\n }\n if (\n typeof value === 'object' &&\n (value as { trigger?: string }).trigger === 'manual'\n ) {\n return { trigger: 'manual' };\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 = readFrequency(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 { BackendFeatureCompat } from '../types';\nimport {\n BackendModuleRegistrationPoints,\n InternalBackendModuleRegistration,\n InternalBackendPluginRegistration,\n} from './types';\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): BackendFeatureCompat {\n function getRegistrations() {\n const extensionPoints: InternalBackendPluginRegistration['extensionPoints'] =\n [];\n let init: InternalBackendModuleRegistration['init'] | undefined = undefined;\n\n options.register({\n registerExtensionPoint(ext, impl) {\n if (init) {\n throw new Error('registerExtensionPoint called after registerInit');\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 return [\n {\n type: 'module',\n pluginId: options.pluginId,\n moduleId: options.moduleId,\n extensionPoints,\n init,\n },\n ];\n }\n\n function backendFeatureCompatWrapper() {\n return backendFeatureCompatWrapper;\n }\n\n Object.assign(backendFeatureCompatWrapper, {\n $$type: '@backstage/BackendFeature' as const,\n version: 'v1',\n getRegistrations,\n });\n\n return backendFeatureCompatWrapper as BackendFeatureCompat;\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 { BackendFeatureCompat } from '../types';\nimport {\n BackendPluginRegistrationPoints,\n InternalBackendPluginRegistration,\n} from './types';\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): BackendFeatureCompat {\n function getRegistrations() {\n const extensionPoints: InternalBackendPluginRegistration['extensionPoints'] =\n [];\n let init: InternalBackendPluginRegistration['init'] | undefined = undefined;\n\n options.register({\n registerExtensionPoint(ext, impl) {\n if (init) {\n throw new Error('registerExtensionPoint called after registerInit');\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 return [\n {\n type: 'plugin',\n pluginId: options.pluginId,\n extensionPoints,\n init,\n },\n ];\n }\n\n function backendFeatureCompatWrapper() {\n return backendFeatureCompatWrapper;\n }\n\n Object.assign(backendFeatureCompatWrapper, {\n $$type: '@backstage/BackendFeature' as const,\n version: 'v1',\n getRegistrations,\n });\n\n return backendFeatureCompatWrapper as BackendFeatureCompat;\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 { ExtensionPoint } 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 * Copyright 2023 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\nconst MESSAGE_MARKER = 'eHgtF5hmbrXyiEvo';\n\n// NOTE: This function is also imported and used in backend code\n\n/**\n * Internal helper that describes the location of the parent caller.\n * @internal\n */\nexport function describeParentCallSite(\n ErrorConstructor: { new (message: string): Error } = Error,\n): string {\n const { stack } = new ErrorConstructor(MESSAGE_MARKER);\n if (!stack) {\n return '<unknown>';\n }\n\n // Safari and Firefox don't include the error itself in the stack\n const startIndex = stack.includes(MESSAGE_MARKER)\n ? stack.indexOf('\\n') + 1\n : 0;\n const secondEntryStart =\n stack.indexOf('\\n', stack.indexOf('\\n', startIndex) + 1) + 1;\n const secondEntryEnd = stack.indexOf('\\n', secondEntryStart);\n\n const line = stack.substring(secondEntryStart, secondEntryEnd).trim();\n if (!line) {\n return 'unknown';\n }\n\n // Below we try to extract the location for different browsers.\n // Since RouteRefs are declared at the top-level of modules the caller name isn't interesting.\n\n // Chrome\n if (line.includes('(')) {\n return line.substring(line.indexOf('(') + 1, line.indexOf(')'));\n }\n\n // Safari & Firefox\n if (line.includes('@')) {\n return line.substring(line.indexOf('@') + 1);\n }\n\n // Give up\n return line;\n}\n","/*\n * Copyright 2024 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 { ServiceRef } from '../services';\nimport { BackendFeature } from '../types';\nimport { describeParentCallSite } from './describeParentCallSite';\nimport { InternalBackendFeatureLoader } from './types';\n\n/**\n * @public\n * Options for creating a new backend feature loader.\n */\nexport interface CreateBackendFeatureLoaderOptions<\n TDeps extends { [name in string]: unknown },\n> {\n deps?: {\n [name in keyof TDeps]: ServiceRef<TDeps[name], 'root'>;\n };\n loader(\n deps: TDeps,\n ):\n | Iterable<BackendFeature | Promise<{ default: BackendFeature }>>\n | Promise<Iterable<BackendFeature | Promise<{ default: BackendFeature }>>>\n | AsyncIterable<BackendFeature | { default: BackendFeature }>;\n}\n\n/**\n * @public\n * Creates a new backend feature loader.\n */\nexport function createBackendFeatureLoader<\n TDeps extends { [name in string]: unknown },\n>(options: CreateBackendFeatureLoaderOptions<TDeps>): BackendFeature {\n return {\n $$type: '@backstage/BackendFeature',\n version: 'v1',\n featureType: 'loader',\n description: `created at '${describeParentCallSite()}'`,\n deps: options.deps,\n async loader(deps: TDeps) {\n const it = await options.loader(deps);\n const result = new Array<BackendFeature>();\n for await (const item of it) {\n if ('$$type' in item && item.$$type === '@backstage/BackendFeature') {\n result.push(item);\n } else if ('default' in item) {\n result.push(item.default);\n } else {\n throw new Error(`Invalid item \"${item}\"`);\n }\n }\n return result;\n },\n } as InternalBackendFeatureLoader;\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/createBackendModule.ts","../src/wiring/createBackendPlugin.ts","../src/wiring/createExtensionPoint.ts","../../frontend-plugin-api/src/routing/describeParentCallSite.ts","../src/wiring/createBackendFeatureLoader.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 TInstances extends 'singleton' | 'multiton' = 'singleton' | 'multiton',\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 multiton?: TInstances extends 'multiton' ? true : false;\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 TInstances extends 'singleton' | 'multiton' = 'singleton' | 'multiton',\n> extends BackendFeature {\n service: ServiceRef<TService, TScope, TInstances>;\n}\n\n/** @internal */\nexport interface InternalServiceFactory<\n TService = unknown,\n TScope extends 'plugin' | 'root' = 'plugin' | 'root',\n TInstances extends 'singleton' | 'multiton' = 'singleton' | 'multiton',\n> extends ServiceFactory<TService, TScope, TInstances> {\n version: 'v1';\n featureType: 'service';\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/** @public */\nexport interface ServiceRefOptions<\n TService,\n TScope extends 'root' | 'plugin',\n TInstances extends 'singleton' | 'multiton',\n> {\n id: string;\n scope?: TScope;\n multiton?: TInstances extends 'multiton' ? true : false;\n defaultFactory?(\n service: ServiceRef<TService, TScope>,\n ): Promise<ServiceFactory>;\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 options: ServiceRefOptions<TService, 'plugin', 'singleton'>,\n): ServiceRef<TService, 'plugin', 'singleton'>;\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 options: ServiceRefOptions<TService, 'root', 'singleton'>,\n): ServiceRef<TService, 'root', 'singleton'>;\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 options: ServiceRefOptions<TService, 'plugin', 'multiton'>,\n): ServiceRef<TService, 'plugin', 'multiton'>;\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 options: ServiceRefOptions<TService, 'root', 'multiton'>,\n): ServiceRef<TService, 'root', 'multiton'>;\nexport function createServiceRef<\n TService,\n TInstances extends 'singleton' | 'multiton',\n>(\n options: ServiceRefOptions<TService, any, TInstances>,\n): ServiceRef<TService, any, TInstances> {\n const { id, scope = 'plugin', multiton = false, defaultFactory } = options;\n return {\n id,\n scope,\n multiton,\n get T(): TService {\n throw new Error(`tried to read ServiceRef.T of ${this}`);\n },\n toString() {\n return `serviceRef{${options.id}}`;\n },\n $$type: '@backstage/ServiceRef',\n __defaultFactory: defaultFactory,\n } as ServiceRef<TService, typeof scope, TInstances> & {\n __defaultFactory?: (\n service: ServiceRef<TService>,\n ) => Promise<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\n ? key\n : never]: T[key]['multiton'] extends true | undefined\n ? Array<T[key]['T']>\n : T[key]['T'];\n};\n\n/** @public */\nexport interface RootServiceFactoryOptions<\n TService,\n TInstances extends 'singleton' | 'multiton',\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', TInstances>;\n deps: TDeps;\n factory(deps: ServiceRefsToInstances<TDeps, 'root'>): TImpl | Promise<TImpl>;\n}\n\n/** @public */\nexport interface PluginServiceFactoryOptions<\n TService,\n TInstances extends 'singleton' | 'multiton',\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', TInstances>;\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 options - The service factory configuration.\n */\nexport function createServiceFactory<\n TService,\n TInstances extends 'singleton' | 'multiton',\n TImpl extends TService,\n TDeps extends { [name in string]: ServiceRef<unknown, 'root'> },\n>(\n options: RootServiceFactoryOptions<TService, TInstances, TImpl, TDeps>,\n): ServiceFactory<TService, 'root', TInstances>;\n/**\n * Creates a plugin scoped service factory without options.\n *\n * @public\n * @param options - The service factory configuration.\n */\nexport function createServiceFactory<\n TService,\n TInstances extends 'singleton' | 'multiton',\n TImpl extends TService,\n TDeps extends { [name in string]: ServiceRef<unknown> },\n TContext = undefined,\n>(\n options: PluginServiceFactoryOptions<\n TService,\n TInstances,\n TContext,\n TImpl,\n TDeps\n >,\n): ServiceFactory<TService, 'plugin', TInstances>;\nexport function createServiceFactory<\n TService,\n TInstances extends 'singleton' | 'multiton',\n TImpl extends TService,\n TDeps extends { [name in string]: ServiceRef<unknown> },\n TContext,\n>(\n options:\n | RootServiceFactoryOptions<TService, TInstances, TImpl, TDeps>\n | PluginServiceFactoryOptions<TService, TInstances, TContext, TImpl, TDeps>,\n): ServiceFactory<TService, 'root' | 'plugin', 'singleton' | 'multiton'> {\n if (options.service.scope === 'root') {\n const c = options as RootServiceFactoryOptions<\n TService,\n TInstances,\n TImpl,\n TDeps\n >;\n return {\n $$type: '@backstage/BackendFeature',\n version: 'v1',\n featureType: 'service',\n service: c.service,\n initialization: c.initialization,\n deps: options.deps,\n factory: async (deps: ServiceRefsToInstances<TDeps, 'root'>) =>\n c.factory(deps),\n } as InternalServiceFactory<TService, 'root', TInstances>;\n }\n const c = options as PluginServiceFactoryOptions<\n TService,\n TInstances,\n TContext,\n TImpl,\n TDeps\n >;\n return {\n $$type: '@backstage/BackendFeature',\n version: 'v1',\n featureType: 'service',\n service: c.service,\n initialization: c.initialization,\n ...('createRootContext' in options\n ? {\n createRootContext: async (\n deps: ServiceRefsToInstances<TDeps, 'root'>,\n ) => c?.createRootContext?.(deps),\n }\n : {}),\n deps: options.deps,\n factory: async (deps: ServiceRefsToInstances<TDeps>, ctx: TContext) =>\n c.factory(deps, ctx),\n } as InternalServiceFactory<TService, 'plugin', TInstances>;\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 * Handles token authentication and credentials management.\n *\n * See {@link AuthService}\n * and {@link https://backstage.io/docs/backend-system/core-services/auth | the service docs}\n * for more information.\n *\n * @public\n */\n export const auth = createServiceRef<import('./AuthService').AuthService>({\n id: 'core.auth',\n });\n\n /**\n * Authenticated user information retrieval.\n *\n * See {@link UserInfoService}\n * and {@link https://backstage.io/docs/backend-system/core-services/user-info | the service docs}\n * for more information.\n *\n * @public\n */\n export const userInfo = createServiceRef<\n import('./UserInfoService').UserInfoService\n >({\n id: 'core.userInfo',\n });\n\n /**\n * Key-value store for caching data.\n *\n * See {@link CacheService}\n * and {@link https://backstage.io/docs/backend-system/core-services/cache | the service docs}\n * for more information.\n *\n * @public\n */\n export const cache = createServiceRef<import('./CacheService').CacheService>({\n id: 'core.cache',\n });\n\n /**\n * Access to static configuration.\n *\n * See {@link RootConfigService}\n * and {@link https://backstage.io/docs/backend-system/core-services/root-config | the service docs}\n * for more information.\n *\n * @public\n */\n export const rootConfig = createServiceRef<\n import('./RootConfigService').RootConfigService\n >({ id: 'core.rootConfig', scope: 'root' });\n\n /**\n * Database access and management via `knex`.\n *\n * See {@link DatabaseService}\n * and {@link https://backstage.io/docs/backend-system/core-services/database | the service docs}\n * for more information.\n *\n * @public\n */\n export const database = createServiceRef<\n import('./DatabaseService').DatabaseService\n >({ id: 'core.database' });\n\n /**\n * Service discovery for inter-plugin communication.\n *\n * See {@link DiscoveryService}\n * and {@link https://backstage.io/docs/backend-system/core-services/discovery | the service docs}\n * for more information.\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 RootHealthService}.\n */\n export const rootHealth = createServiceRef<\n import('./RootHealthService').RootHealthService\n >({ id: 'core.rootHealth', scope: 'root' });\n\n /**\n * Authentication of HTTP requests.\n *\n * See {@link HttpAuthService}\n * and {@link https://backstage.io/docs/backend-system/core-services/http-auth | the service docs}\n * for more information.\n *\n * @public\n */\n export const httpAuth = createServiceRef<\n import('./HttpAuthService').HttpAuthService\n >({ id: 'core.httpAuth' });\n\n /**\n * HTTP route registration for plugins.\n *\n * See {@link HttpRouterService}\n * and {@link https://backstage.io/docs/backend-system/core-services/http-router | the service docs}\n * for more information.\n *\n * @public\n */\n export const httpRouter = createServiceRef<\n import('./HttpRouterService').HttpRouterService\n >({ id: 'core.httpRouter' });\n\n /**\n * Registration of plugin startup and shutdown lifecycle hooks.\n *\n * See {@link LifecycleService}\n * and {@link https://backstage.io/docs/backend-system/core-services/lifecycle | the service docs}\n * for more information.\n *\n * @public\n */\n export const lifecycle = createServiceRef<\n import('./LifecycleService').LifecycleService\n >({ id: 'core.lifecycle' });\n\n /**\n * Plugin-level logging.\n *\n * See {@link LoggerService}\n * and {@link https://backstage.io/docs/backend-system/core-services/logger | the service docs}\n * for more information.\n *\n * @public\n */\n export const logger = createServiceRef<\n import('./LoggerService').LoggerService\n >({ id: 'core.logger' });\n\n /**\n * Permission system integration for authorization of user actions.\n *\n * See {@link PermissionsService}\n * and {@link https://backstage.io/docs/backend-system/core-services/permissions | the service docs}\n * for more information.\n *\n * @public\n */\n export const permissions = createServiceRef<\n import('./PermissionsService').PermissionsService\n >({ id: 'core.permissions' });\n\n /**\n * Built-in service for accessing metadata about the current plugin.\n *\n * See {@link PluginMetadataService}\n * and {@link https://backstage.io/docs/backend-system/core-services/plugin-metadata | the service docs}\n * for more information.\n *\n * @public\n */\n export const pluginMetadata = createServiceRef<\n import('./PluginMetadataService').PluginMetadataService\n >({ id: 'core.pluginMetadata' });\n\n /**\n * HTTP route registration for root services.\n *\n * See {@link RootHttpRouterService}\n * and {@link https://backstage.io/docs/backend-system/core-services/root-http-router | the service docs}\n * for more information.\n *\n * @public\n */\n export const rootHttpRouter = createServiceRef<\n import('./RootHttpRouterService').RootHttpRouterService\n >({ id: 'core.rootHttpRouter', scope: 'root' });\n\n /**\n * Registration of backend startup and shutdown lifecycle hooks.\n *\n * See {@link RootLifecycleService}\n * and {@link https://backstage.io/docs/backend-system/core-services/root-lifecycle | the service docs}\n * for more information.\n *\n * @public\n */\n export const rootLifecycle = createServiceRef<\n import('./RootLifecycleService').RootLifecycleService\n >({ id: 'core.rootLifecycle', scope: 'root' });\n\n /**\n * Root-level logging.\n *\n * See {@link RootLoggerService}\n * and {@link https://backstage.io/docs/backend-system/core-services/root-logger | the service docs}\n * for more information.\n *\n * @public\n */\n export const rootLogger = createServiceRef<\n import('./RootLoggerService').RootLoggerService\n >({ id: 'core.rootLogger', scope: 'root' });\n\n /**\n * Scheduling of distributed background tasks.\n *\n * See {@link SchedulerService}\n * and {@link https://backstage.io/docs/backend-system/core-services/scheduler | the service docs}\n * for more information.\n *\n * @public\n */\n export const scheduler = createServiceRef<\n import('./SchedulerService').SchedulerService\n >({ id: 'core.scheduler' });\n\n /**\n * Reading content from external systems.\n *\n * See {@link UrlReaderService}\n * and {@link https://backstage.io/docs/backend-system/core-services/url-reader | the service docs}\n * for more information.\n *\n * @public\n */\n export const urlReader = createServiceRef<\n import('./UrlReaderService').UrlReaderService\n >({ id: 'core.urlReader' });\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 | { trigger: 'manual' };\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 * This task will only run when manually triggered with the `triggerTask` method; no automatic\n * scheduling. This is useful for locking of global tasks that should not be run concurrently.\n */\n | { trigger: 'manual' };\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): 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.toObject();\n }\n\n return readDurationFromConfig(config, { key });\n}\n\nfunction readFrequency(\n config: Config,\n key: string,\n): { cron: string } | HumanDuration | { trigger: 'manual' } {\n const value = config.get(key);\n if (typeof value === 'object' && (value as { cron?: string }).cron) {\n return value as { cron: string };\n }\n if (\n typeof value === 'object' &&\n (value as { trigger?: string }).trigger === 'manual'\n ) {\n return { trigger: 'manual' };\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 = readFrequency(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 } from '../types';\nimport {\n BackendModuleRegistrationPoints,\n InternalBackendModuleRegistration,\n InternalBackendPluginRegistration,\n InternalBackendRegistrations,\n} from './types';\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 function getRegistrations() {\n const extensionPoints: InternalBackendPluginRegistration['extensionPoints'] =\n [];\n let init: InternalBackendModuleRegistration['init'] | undefined = undefined;\n\n options.register({\n registerExtensionPoint(ext, impl) {\n if (init) {\n throw new Error('registerExtensionPoint called after registerInit');\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 return [\n {\n type: 'module',\n pluginId: options.pluginId,\n moduleId: options.moduleId,\n extensionPoints,\n init,\n },\n ];\n }\n\n return {\n $$type: '@backstage/BackendFeature' as const,\n featureType: 'registrations',\n version: 'v1',\n getRegistrations,\n } as InternalBackendRegistrations;\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 } from '../types';\nimport {\n BackendPluginRegistrationPoints,\n InternalBackendPluginRegistration,\n InternalBackendRegistrations,\n} from './types';\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 function getRegistrations() {\n const extensionPoints: InternalBackendPluginRegistration['extensionPoints'] =\n [];\n let init: InternalBackendPluginRegistration['init'] | undefined = undefined;\n\n options.register({\n registerExtensionPoint(ext, impl) {\n if (init) {\n throw new Error('registerExtensionPoint called after registerInit');\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 return [\n {\n type: 'plugin',\n pluginId: options.pluginId,\n extensionPoints,\n init,\n },\n ];\n }\n\n return {\n $$type: '@backstage/BackendFeature' as const,\n version: 'v1',\n featureType: 'registrations',\n getRegistrations,\n } as InternalBackendRegistrations;\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 { ExtensionPoint } 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 * Copyright 2023 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\nconst MESSAGE_MARKER = 'eHgtF5hmbrXyiEvo';\n\n// NOTE: This function is also imported and used in backend code\n\n/**\n * Internal helper that describes the location of the parent caller.\n * @internal\n */\nexport function describeParentCallSite(\n ErrorConstructor: { new (message: string): Error } = Error,\n): string {\n const { stack } = new ErrorConstructor(MESSAGE_MARKER);\n if (!stack) {\n return '<unknown>';\n }\n\n // Safari and Firefox don't include the error itself in the stack\n const startIndex = stack.includes(MESSAGE_MARKER)\n ? stack.indexOf('\\n') + 1\n : 0;\n const secondEntryStart =\n stack.indexOf('\\n', stack.indexOf('\\n', startIndex) + 1) + 1;\n const secondEntryEnd = stack.indexOf('\\n', secondEntryStart);\n\n const line = stack.substring(secondEntryStart, secondEntryEnd).trim();\n if (!line) {\n return 'unknown';\n }\n\n // Below we try to extract the location for different browsers.\n // Since RouteRefs are declared at the top-level of modules the caller name isn't interesting.\n\n // Chrome\n if (line.includes('(')) {\n return line.substring(line.indexOf('(') + 1, line.indexOf(')'));\n }\n\n // Safari & Firefox\n if (line.includes('@')) {\n return line.substring(line.indexOf('@') + 1);\n }\n\n // Give up\n return line;\n}\n","/*\n * Copyright 2024 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 { ServiceRef } from '../services';\nimport { BackendFeature } from '../types';\nimport { describeParentCallSite } from './describeParentCallSite';\nimport { InternalBackendFeatureLoader } from './types';\n\n/**\n * @public\n * Options for creating a new backend feature loader.\n */\nexport interface CreateBackendFeatureLoaderOptions<\n TDeps extends { [name in string]: unknown },\n> {\n deps?: {\n [name in keyof TDeps]: ServiceRef<TDeps[name], 'root'>;\n };\n loader(\n deps: TDeps,\n ):\n | Iterable<BackendFeature | Promise<{ default: BackendFeature }>>\n | Promise<Iterable<BackendFeature | Promise<{ default: BackendFeature }>>>\n | AsyncIterable<BackendFeature | { default: BackendFeature }>;\n}\n\n/**\n * @public\n * Creates a new backend feature loader.\n */\nexport function createBackendFeatureLoader<\n TDeps extends { [name in string]: unknown },\n>(options: CreateBackendFeatureLoaderOptions<TDeps>): BackendFeature {\n return {\n $$type: '@backstage/BackendFeature',\n version: 'v1',\n featureType: 'loader',\n description: `created at '${describeParentCallSite()}'`,\n deps: options.deps,\n async loader(deps: TDeps) {\n const it = await options.loader(deps);\n const result = new Array<BackendFeature>();\n for await (const item of it) {\n if ('$$type' in item && item.$$type === '@backstage/BackendFeature') {\n result.push(item);\n } else if ('default' in item) {\n result.push(item.default);\n } else {\n throw new Error(`Invalid item \"${item}\"`);\n }\n }\n return result;\n },\n } as InternalBackendFeatureLoader;\n}\n"],"names":["c","coreServices","config","Duration","readDurationFromConfig"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  /// <reference types="node" />
2
- import { IdentityApi } from '@backstage/plugin-auth-node';
3
2
  import { Readable } from 'stream';
4
3
  import { Config } from '@backstage/config';
5
4
  import { JsonObject, HumanDuration, JsonValue } from '@backstage/types';
@@ -9,17 +8,6 @@ import { PermissionAttributes, EvaluatorRequestOptions, PermissionEvaluator, Aut
9
8
  import { Knex } from 'knex';
10
9
  export { isChildPath } from '@backstage/cli-common';
11
10
 
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
- */
20
- interface IdentityService extends IdentityApi {
21
- }
22
-
23
11
  /**
24
12
  * A generic interface for fetching plain data from URLs.
25
13
  *
@@ -336,34 +324,6 @@ type UrlReaderServiceSearchResponseFile = {
336
324
  lastModifiedAt?: Date;
337
325
  };
338
326
 
339
- /**
340
- * 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.
341
- *
342
- * See the {@link https://backstage.io/docs/backend-system/core-services/token-manager | service documentation} for more details.
343
- *
344
- * @public
345
- * @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.
346
- */
347
- interface TokenManagerService {
348
- /**
349
- * Fetches a valid token.
350
- *
351
- * @remarks
352
- *
353
- * Tokens are valid for roughly one hour; the actual deadline is set in the
354
- * payload `exp` claim. Never hold on to tokens for reuse; always ask for a
355
- * new one for each outgoing request. This ensures that you always get a
356
- * valid, fresh one.
357
- */
358
- getToken(): Promise<{
359
- token: string;
360
- }>;
361
- /**
362
- * Validates a given token.
363
- */
364
- authenticate(token: string): Promise<void>;
365
- }
366
-
367
327
  /**
368
328
  * A function that can be called as a scheduled task.
369
329
  *
@@ -1308,10 +1268,10 @@ interface RootConfigService extends Config {
1308
1268
  */
1309
1269
  type CacheServiceSetOptions = {
1310
1270
  /**
1311
- * Optional TTL in milliseconds. Defaults to the TTL provided when the client
1271
+ * Optional TTL (in milliseconds if given as a number). Defaults to the TTL provided when the client
1312
1272
  * was set up (or no TTL if none are provided).
1313
1273
  */
1314
- ttl?: number;
1274
+ ttl?: number | HumanDuration;
1315
1275
  };
1316
1276
  /**
1317
1277
  * Options passed to {@link CacheService.withOptions}.
@@ -1320,11 +1280,11 @@ type CacheServiceSetOptions = {
1320
1280
  */
1321
1281
  type CacheServiceOptions = {
1322
1282
  /**
1323
- * An optional default TTL (in milliseconds) to be set when getting a client
1283
+ * An optional default TTL (in milliseconds if given as a number) to be set when getting a client
1324
1284
  * instance. If not provided, data will persist indefinitely by default (or
1325
1285
  * can be configured per entry at set-time).
1326
1286
  */
1327
- defaultTtl?: number;
1287
+ defaultTtl?: number | HumanDuration;
1328
1288
  };
1329
1289
  /**
1330
1290
  * A pre-configured, storage agnostic cache service suitable for use by
@@ -1384,16 +1344,6 @@ interface UserInfoService {
1384
1344
  interface BackendFeature {
1385
1345
  $$type: '@backstage/BackendFeature';
1386
1346
  }
1387
- /**
1388
- * @public
1389
- * @deprecated This type exists only as a helper for old code that relied on `createBackendFeature` and `createBackendPlugin` to return `() => BackendFeature` instead of `BackendFeature`. You should remove the `()` parentheses at the end of your usages. This type will be removed in a future release.
1390
- */
1391
- interface BackendFeatureCompat extends BackendFeature {
1392
- /**
1393
- * @deprecated You do not need to use this call signature; use the type directly instead by removing the `()` parentheses at the end. This call signature will be removed in a future release.
1394
- */
1395
- (): this;
1396
- }
1397
1347
 
1398
1348
  /**
1399
1349
  * TODO
@@ -1424,33 +1374,12 @@ type ServiceRef<TService, TScope extends 'root' | 'plugin' = 'root' | 'plugin',
1424
1374
  interface ServiceFactory<TService = unknown, TScope extends 'plugin' | 'root' = 'plugin' | 'root', TInstances extends 'singleton' | 'multiton' = 'singleton' | 'multiton'> extends BackendFeature {
1425
1375
  service: ServiceRef<TService, TScope, TInstances>;
1426
1376
  }
1427
- /**
1428
- * @public
1429
- * @deprecated This type exists only as a helper for old code that relied on `createServiceFactory` to return `() => ServiceFactory` instead of `ServiceFactory`. You should remove the `()` parentheses at the end of your usages. This type will be removed in a future release.
1430
- */
1431
- interface ServiceFactoryCompat<TService = unknown, TScope extends 'plugin' | 'root' = 'plugin' | 'root', TInstances extends 'singleton' | 'multiton' = 'singleton' | 'multiton', TOpts extends object | undefined = undefined> extends ServiceFactory<TService, TScope, TInstances> {
1432
- /**
1433
- * @deprecated Callable service factories will be removed in a future release, please re-implement the service factory using the available APIs instead. If no options are being passed, you can simply remove the trailing `()`.
1434
- */
1435
- (...options: undefined extends TOpts ? [] : [options?: TOpts]): ServiceFactory<TService, TScope, TInstances>;
1436
- }
1437
- /**
1438
- * Represents either a {@link ServiceFactory} or a function that returns one.
1439
- *
1440
- * @deprecated The support for service factory functions is deprecated and will be removed.
1441
- * @public
1442
- */
1443
- type ServiceFactoryOrFunction = ServiceFactory | (() => ServiceFactory);
1444
1377
  /** @public */
1445
1378
  interface ServiceRefOptions<TService, TScope extends 'root' | 'plugin', TInstances extends 'singleton' | 'multiton'> {
1446
1379
  id: string;
1447
1380
  scope?: TScope;
1448
1381
  multiton?: TInstances extends 'multiton' ? true : false;
1449
1382
  defaultFactory?(service: ServiceRef<TService, TScope>): Promise<ServiceFactory>;
1450
- /**
1451
- * @deprecated The defaultFactory must return a plain `ServiceFactory` object, support for returning a function will be removed.
1452
- */
1453
- defaultFactory?(service: ServiceRef<TService, TScope>): Promise<() => ServiceFactory>;
1454
1383
  }
1455
1384
  /**
1456
1385
  * Creates a new service definition. This overload is used to create plugin scoped services.
@@ -1483,8 +1412,7 @@ type ServiceRefsToInstances<T extends {
1483
1412
  [key in keyof T as T[key]['scope'] extends TScope ? key : never]: T[key]['multiton'] extends true | undefined ? Array<T[key]['T']> : T[key]['T'];
1484
1413
  };
1485
1414
  /** @public */
1486
- interface RootServiceFactoryOptions<TService, // TODO(Rugvip): Can we forward the entire service ref type here instead of forwarding each type arg once the callback form is gone?
1487
- TInstances extends 'singleton' | 'multiton', TImpl extends TService, TDeps extends {
1415
+ interface RootServiceFactoryOptions<TService, TInstances extends 'singleton' | 'multiton', TImpl extends TService, TDeps extends {
1488
1416
  [name in string]: ServiceRef<unknown>;
1489
1417
  }> {
1490
1418
  /**
@@ -1530,20 +1458,7 @@ interface PluginServiceFactoryOptions<TService, TInstances extends 'singleton' |
1530
1458
  */
1531
1459
  declare function createServiceFactory<TService, TInstances extends 'singleton' | 'multiton', TImpl extends TService, TDeps extends {
1532
1460
  [name in string]: ServiceRef<unknown, 'root'>;
1533
- }, TOpts extends object | undefined = undefined>(options: RootServiceFactoryOptions<TService, TInstances, TImpl, TDeps>): ServiceFactoryCompat<TService, 'root', TInstances>;
1534
- /**
1535
- * Creates a root scoped service factory with optional options.
1536
- *
1537
- * @deprecated The ability to define options for service factories is deprecated
1538
- * and will be removed. Please use the non-callback form of createServiceFactory
1539
- * and provide an API that allows for a simple re-implementation of the service
1540
- * factory instead.
1541
- * @public
1542
- * @param options - The service factory configuration.
1543
- */
1544
- declare function createServiceFactory<TService, TInstances extends 'singleton' | 'multiton', TImpl extends TService, TDeps extends {
1545
- [name in string]: ServiceRef<unknown, 'root'>;
1546
- }, TOpts extends object | undefined = undefined>(options: (options?: TOpts) => RootServiceFactoryOptions<TService, TInstances, TImpl, TDeps>): ServiceFactoryCompat<TService, 'root', TInstances, TOpts>;
1461
+ }>(options: RootServiceFactoryOptions<TService, TInstances, TImpl, TDeps>): ServiceFactory<TService, 'root', TInstances>;
1547
1462
  /**
1548
1463
  * Creates a plugin scoped service factory without options.
1549
1464
  *
@@ -1552,20 +1467,7 @@ declare function createServiceFactory<TService, TInstances extends 'singleton' |
1552
1467
  */
1553
1468
  declare function createServiceFactory<TService, TInstances extends 'singleton' | 'multiton', TImpl extends TService, TDeps extends {
1554
1469
  [name in string]: ServiceRef<unknown>;
1555
- }, TContext = undefined, TOpts extends object | undefined = undefined>(options: PluginServiceFactoryOptions<TService, TInstances, TContext, TImpl, TDeps>): ServiceFactoryCompat<TService, 'plugin', TInstances>;
1556
- /**
1557
- * Creates a plugin scoped service factory with optional options.
1558
- *
1559
- * @deprecated The ability to define options for service factories is deprecated
1560
- * and will be removed. Please use the non-callback form of createServiceFactory
1561
- * and provide an API that allows for a simple re-implementation of the service
1562
- * factory instead.
1563
- * @public
1564
- * @param options - The service factory configuration.
1565
- */
1566
- declare function createServiceFactory<TService, TInstances extends 'singleton' | 'multiton', TImpl extends TService, TDeps extends {
1567
- [name in string]: ServiceRef<unknown>;
1568
- }, TContext = undefined, TOpts extends object | undefined = undefined>(options: (options?: TOpts) => PluginServiceFactoryOptions<TService, TInstances, TContext, TImpl, TDeps>): ServiceFactoryCompat<TService, 'plugin', TInstances, TOpts>;
1470
+ }, TContext = undefined>(options: PluginServiceFactoryOptions<TService, TInstances, TContext, TImpl, TDeps>): ServiceFactory<TService, 'plugin', TInstances>;
1569
1471
 
1570
1472
  /**
1571
1473
  * All core services references
@@ -1737,17 +1639,6 @@ declare namespace coreServices {
1737
1639
  * @public
1738
1640
  */
1739
1641
  const scheduler: ServiceRef<SchedulerService, "plugin", "singleton">;
1740
- /**
1741
- * Deprecated service authentication service, use the `auth` service instead.
1742
- *
1743
- * See {@link TokenManagerService}
1744
- * and {@link https://backstage.io/docs/backend-system/core-services/token-manager | the service docs}
1745
- * for more information.
1746
- *
1747
- * @public
1748
- * @deprecated Please migrate to the new `coreServices.auth`, `coreServices.httpAuth`, and `coreServices.userInfo` services as needed instead
1749
- */
1750
- const tokenManager: ServiceRef<TokenManagerService, "plugin", "singleton">;
1751
1642
  /**
1752
1643
  * Reading content from external systems.
1753
1644
  *
@@ -1758,17 +1649,6 @@ declare namespace coreServices {
1758
1649
  * @public
1759
1650
  */
1760
1651
  const urlReader: ServiceRef<UrlReaderService, "plugin", "singleton">;
1761
- /**
1762
- * Deprecated user authentication service, use the `auth` service instead.
1763
- *
1764
- * See {@link IdentityService}
1765
- * and {@link https://backstage.io/docs/backend-system/core-services/identity | the service docs}
1766
- * for more information.
1767
- *
1768
- * @public
1769
- * @deprecated Please migrate to the new `coreServices.auth`, `coreServices.httpAuth`, and `coreServices.userInfo` services as needed instead
1770
- */
1771
- const identity: ServiceRef<IdentityService, "plugin", "singleton">;
1772
1652
  }
1773
1653
 
1774
1654
  /**
@@ -1881,7 +1761,7 @@ interface CreateBackendModuleOptions {
1881
1761
  * @see {@link https://backstage.io/docs/backend-system/architecture/modules | The architecture of modules}
1882
1762
  * @see {@link https://backstage.io/docs/backend-system/architecture/naming-patterns | Recommended naming patterns}
1883
1763
  */
1884
- declare function createBackendModule(options: CreateBackendModuleOptions): BackendFeatureCompat;
1764
+ declare function createBackendModule(options: CreateBackendModuleOptions): BackendFeature;
1885
1765
 
1886
1766
  /**
1887
1767
  * The configuration options passed to {@link createBackendPlugin}.
@@ -1906,7 +1786,7 @@ interface CreateBackendPluginOptions {
1906
1786
  * @see {@link https://backstage.io/docs/backend-system/architecture/plugins | The architecture of plugins}
1907
1787
  * @see {@link https://backstage.io/docs/backend-system/architecture/naming-patterns | Recommended naming patterns}
1908
1788
  */
1909
- declare function createBackendPlugin(options: CreateBackendPluginOptions): BackendFeatureCompat;
1789
+ declare function createBackendPlugin(options: CreateBackendPluginOptions): BackendFeature;
1910
1790
 
1911
1791
  /**
1912
1792
  * The configuration options passed to {@link createExtensionPoint}.
@@ -1957,20 +1837,4 @@ declare function createBackendFeatureLoader<TDeps extends {
1957
1837
  [name in string]: unknown;
1958
1838
  }>(options: CreateBackendFeatureLoaderOptions<TDeps>): BackendFeature;
1959
1839
 
1960
- /**
1961
- * @public
1962
- * @deprecated Use {@link CreateBackendPluginOptions} instead.
1963
- */
1964
- type BackendPluginConfig = CreateBackendPluginOptions;
1965
- /**
1966
- * @public
1967
- * @deprecated Use {@link CreateBackendModuleOptions} instead.
1968
- */
1969
- type BackendModuleConfig = CreateBackendModuleOptions;
1970
- /**
1971
- * @public
1972
- * @deprecated Use {@link CreateExtensionPointOptions} instead.
1973
- */
1974
- type ExtensionPointConfig = CreateExtensionPointOptions;
1975
-
1976
- export { type AuthService, type BackendFeature, type BackendFeatureCompat, 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 CreateBackendFeatureLoaderOptions, 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 PluginServiceFactoryOptions, type RootConfigService, type RootHealthService, type RootHttpRouterService, type RootLifecycleService, type RootLoggerService, type RootServiceFactoryOptions, type SchedulerService, type SchedulerServiceTaskDescriptor, type SchedulerServiceTaskFunction, type SchedulerServiceTaskInvocationDefinition, type SchedulerServiceTaskRunner, type SchedulerServiceTaskScheduleDefinition, type SchedulerServiceTaskScheduleDefinitionConfig, type ServiceFactory, type ServiceFactoryCompat, type ServiceFactoryOrFunction, type ServiceRef, type ServiceRefOptions, type TokenManagerService, type UrlReaderService, type UrlReaderServiceReadTreeOptions, type UrlReaderServiceReadTreeResponse, type UrlReaderServiceReadTreeResponseDirOptions, type UrlReaderServiceReadTreeResponseFile, type UrlReaderServiceReadUrlOptions, type UrlReaderServiceReadUrlResponse, type UrlReaderServiceSearchOptions, type UrlReaderServiceSearchResponse, type UrlReaderServiceSearchResponseFile, type UserInfoService, coreServices, createBackendFeatureLoader, createBackendModule, createBackendPlugin, createExtensionPoint, createServiceFactory, createServiceRef, isDatabaseConflictError, readSchedulerServiceTaskScheduleDefinitionFromConfig, resolvePackagePath, resolveSafeChildPath };
1840
+ export { type AuthService, type BackendFeature, type BackendModuleRegistrationPoints, type BackendPluginRegistrationPoints, type BackstageCredentials, type BackstageNonePrincipal, type BackstagePrincipalAccessRestrictions, type BackstagePrincipalTypes, type BackstageServicePrincipal, type BackstageUserInfo, type BackstageUserPrincipal, type CacheService, type CacheServiceOptions, type CacheServiceSetOptions, type CreateBackendFeatureLoaderOptions, type CreateBackendModuleOptions, type CreateBackendPluginOptions, type CreateExtensionPointOptions, type DatabaseService, type DiscoveryService, type ExtensionPoint, type HttpAuthService, type HttpRouterService, type HttpRouterServiceAuthPolicy, type LifecycleService, type LifecycleServiceShutdownHook, type LifecycleServiceShutdownOptions, type LifecycleServiceStartupHook, type LifecycleServiceStartupOptions, type LoggerService, type PermissionsService, type PermissionsServiceRequestOptions, type PluginMetadataService, type PluginServiceFactoryOptions, type RootConfigService, type RootHealthService, type RootHttpRouterService, type RootLifecycleService, type RootLoggerService, type RootServiceFactoryOptions, type SchedulerService, type SchedulerServiceTaskDescriptor, type SchedulerServiceTaskFunction, type SchedulerServiceTaskInvocationDefinition, type SchedulerServiceTaskRunner, type SchedulerServiceTaskScheduleDefinition, type SchedulerServiceTaskScheduleDefinitionConfig, type ServiceFactory, type ServiceRef, type ServiceRefOptions, type UrlReaderService, type UrlReaderServiceReadTreeOptions, type UrlReaderServiceReadTreeResponse, type UrlReaderServiceReadTreeResponseDirOptions, type UrlReaderServiceReadTreeResponseFile, type UrlReaderServiceReadUrlOptions, type UrlReaderServiceReadUrlResponse, type UrlReaderServiceSearchOptions, type UrlReaderServiceSearchResponse, type UrlReaderServiceSearchResponseFile, type UserInfoService, coreServices, createBackendFeatureLoader, 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.8.1",
3
+ "version": "0.9.0-next.1",
4
4
  "description": "Core API used by Backstage backend plugins",
5
5
  "backstage": {
6
6
  "role": "node-library"
@@ -40,6 +40,7 @@
40
40
  "types": "./dist/index.d.ts",
41
41
  "files": [
42
42
  "dist",
43
+ "config.d.ts",
43
44
  "alpha",
44
45
  "testUtils"
45
46
  ],
@@ -56,7 +57,7 @@
56
57
  "@backstage/cli-common": "^0.1.14",
57
58
  "@backstage/config": "^1.2.0",
58
59
  "@backstage/errors": "^1.2.4",
59
- "@backstage/plugin-auth-node": "^0.5.1",
60
+ "@backstage/plugin-auth-node": "^0.5.2-next.1",
60
61
  "@backstage/plugin-permission-common": "^0.8.1",
61
62
  "@backstage/types": "^1.1.1",
62
63
  "@types/express": "^4.17.6",
@@ -66,7 +67,8 @@
66
67
  "luxon": "^3.0.0"
67
68
  },
68
69
  "devDependencies": {
69
- "@backstage/backend-test-utils": "^0.5.1",
70
- "@backstage/cli": "^0.27.0"
71
- }
70
+ "@backstage/backend-test-utils": "^0.6.0-next.1",
71
+ "@backstage/cli": "^0.27.1-next.1"
72
+ },
73
+ "configSchema": "config.d.ts"
72
74
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/backend-plugin-api__testutils",
3
- "version": "0.8.1",
3
+ "version": "0.9.0-next.1",
4
4
  "main": "../dist/testUtils.cjs.js",
5
5
  "types": "../dist/testUtils.d.ts"
6
6
  }