@backstage/backend-plugin-api 0.7.1-next.1 → 0.8.0-next.2
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 +94 -0
- package/alpha/package.json +1 -1
- package/dist/alpha.d.ts +1 -1
- package/dist/index.cjs.js +80 -25
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +123 -71
- package/package.json +5 -5
- package/testUtils/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,99 @@
|
|
|
1
1
|
# @backstage/backend-plugin-api
|
|
2
2
|
|
|
3
|
+
## 0.8.0-next.2
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 7c5f3b0: The `createServiceRef` function now accepts a new boolean `multiple` option. The `multiple` option defaults to `false` and when set to `true`, it enables that multiple implementation are installed for the created service ref.
|
|
8
|
+
|
|
9
|
+
We're looking for ways to make it possible to augment services without the need to replace the entire service.
|
|
10
|
+
|
|
11
|
+
Typical example of that being the ability to install support for additional targets for the `UrlReader` service without replacing the service itself. This achieves that by allowing us to define services that can have multiple simultaneous implementation, allowing the `UrlReader` implementation to depend on such a service to collect all possible implementation of support for external targets:
|
|
12
|
+
|
|
13
|
+
```diff
|
|
14
|
+
// @backstage/backend-defaults
|
|
15
|
+
|
|
16
|
+
+ export const urlReaderFactoriesServiceRef = createServiceRef<ReaderFactory>({
|
|
17
|
+
+ id: 'core.urlReader.factories',
|
|
18
|
+
+ scope: 'plugin',
|
|
19
|
+
+ multiton: true,
|
|
20
|
+
+ });
|
|
21
|
+
|
|
22
|
+
...
|
|
23
|
+
|
|
24
|
+
export const urlReaderServiceFactory = createServiceFactory({
|
|
25
|
+
service: coreServices.urlReader,
|
|
26
|
+
deps: {
|
|
27
|
+
config: coreServices.rootConfig,
|
|
28
|
+
logger: coreServices.logger,
|
|
29
|
+
+ factories: urlReaderFactoriesServiceRef,
|
|
30
|
+
},
|
|
31
|
+
- async factory({ config, logger }) {
|
|
32
|
+
+ async factory({ config, logger, factories }) {
|
|
33
|
+
return UrlReaders.default({
|
|
34
|
+
config,
|
|
35
|
+
logger,
|
|
36
|
+
+ factories,
|
|
37
|
+
});
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
With that, you can then add more custom `UrlReader` factories by installing more implementations of the `urlReaderFactoriesServiceRef` in your backend instance. Something like:
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
// packages/backend/index.ts
|
|
46
|
+
import { createServiceFactory } from '@backstage/backend-plugin-api';
|
|
47
|
+
import { urlReaderFactoriesServiceRef } from '@backstage/backend-defaults';
|
|
48
|
+
...
|
|
49
|
+
|
|
50
|
+
backend.add(createServiceFactory({
|
|
51
|
+
service: urlReaderFactoriesServiceRef,
|
|
52
|
+
deps: {},
|
|
53
|
+
async factory() {
|
|
54
|
+
return CustomUrlReader.factory;
|
|
55
|
+
},
|
|
56
|
+
}));
|
|
57
|
+
|
|
58
|
+
...
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Patch Changes
|
|
63
|
+
|
|
64
|
+
- 6061061: Added `createBackendFeatureLoader`, which can be used to create an installable backend feature that can in turn load in additional backend features in a dynamic way.
|
|
65
|
+
- ba9abf4: The `SchedulerService` now allows tasks with `frequency: { trigger: 'manual' }`. This means that the task will not be scheduled, but rather run only when manually triggered with `SchedulerService.triggerTask`.
|
|
66
|
+
- 8b13183: Added `createBackendFeatureLoader`, which can be used to programmatically select and install backend features.
|
|
67
|
+
|
|
68
|
+
A feature loader can return an list of features to be installed, for example in the form on an `Array` or other for of iterable, which allows for the loader to be defined as a generator function. Both synchronous and asynchronous loaders are supported.
|
|
69
|
+
|
|
70
|
+
Additionally, a loader can depend on services in its implementation, with the restriction that it can only depend on root-scoped services, and it may not override services that have already been instantiated.
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
const searchLoader = createBackendFeatureLoader({
|
|
74
|
+
deps: {
|
|
75
|
+
config: coreServices.rootConfig,
|
|
76
|
+
},
|
|
77
|
+
*loader({ config }) {
|
|
78
|
+
// Example of a custom config flag to enable search
|
|
79
|
+
if (config.getOptionalString('customFeatureToggle.search')) {
|
|
80
|
+
yield import('@backstage/plugin-search-backend/alpha');
|
|
81
|
+
yield import('@backstage/plugin-search-backend-module-catalog/alpha');
|
|
82
|
+
yield import('@backstage/plugin-search-backend-module-explore/alpha');
|
|
83
|
+
yield import('@backstage/plugin-search-backend-module-techdocs/alpha');
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
- Updated dependencies
|
|
90
|
+
- @backstage/plugin-permission-common@0.8.1-next.1
|
|
91
|
+
- @backstage/plugin-auth-node@0.5.0-next.2
|
|
92
|
+
- @backstage/cli-common@0.1.14
|
|
93
|
+
- @backstage/config@1.2.0
|
|
94
|
+
- @backstage/errors@1.2.4
|
|
95
|
+
- @backstage/types@1.1.1
|
|
96
|
+
|
|
3
97
|
## 0.7.1-next.1
|
|
4
98
|
|
|
5
99
|
### Patch Changes
|
package/alpha/package.json
CHANGED
package/dist/alpha.d.ts
CHANGED
|
@@ -11,6 +11,6 @@ interface FeatureDiscoveryService {
|
|
|
11
11
|
* An optional service that can be used to dynamically load in additional BackendFeatures at runtime.
|
|
12
12
|
* @alpha
|
|
13
13
|
*/
|
|
14
|
-
declare const featureDiscoveryServiceRef: _backstage_backend_plugin_api.ServiceRef<FeatureDiscoveryService, "root">;
|
|
14
|
+
declare const featureDiscoveryServiceRef: _backstage_backend_plugin_api.ServiceRef<FeatureDiscoveryService, "root", "singleton">;
|
|
15
15
|
|
|
16
16
|
export { type FeatureDiscoveryService, featureDiscoveryServiceRef };
|
package/dist/index.cjs.js
CHANGED
|
@@ -9,10 +9,11 @@ require('path');
|
|
|
9
9
|
require('fs');
|
|
10
10
|
|
|
11
11
|
function createServiceRef(options) {
|
|
12
|
-
const { id, scope = "plugin", defaultFactory } = options;
|
|
12
|
+
const { id, scope = "plugin", multiton = false, defaultFactory } = options;
|
|
13
13
|
return {
|
|
14
14
|
id,
|
|
15
15
|
scope,
|
|
16
|
+
multiton,
|
|
16
17
|
get T() {
|
|
17
18
|
throw new Error(`tried to read ServiceRef.T of ${this}`);
|
|
18
19
|
},
|
|
@@ -32,6 +33,7 @@ function createServiceFactory(options) {
|
|
|
32
33
|
return {
|
|
33
34
|
$$type: "@backstage/BackendFeature",
|
|
34
35
|
version: "v1",
|
|
36
|
+
featureType: "service",
|
|
35
37
|
service: c2.service,
|
|
36
38
|
initialization: c2.initialization,
|
|
37
39
|
deps: c2.deps,
|
|
@@ -42,6 +44,7 @@ function createServiceFactory(options) {
|
|
|
42
44
|
return {
|
|
43
45
|
$$type: "@backstage/BackendFeature",
|
|
44
46
|
version: "v1",
|
|
47
|
+
featureType: "service",
|
|
45
48
|
service: c.service,
|
|
46
49
|
initialization: c.initialization,
|
|
47
50
|
..."createRootContext" in c ? {
|
|
@@ -95,15 +98,18 @@ function readDuration(config$1, key) {
|
|
|
95
98
|
}
|
|
96
99
|
return config.readDurationFromConfig(config$1, { key });
|
|
97
100
|
}
|
|
98
|
-
function
|
|
101
|
+
function readFrequency(config, key) {
|
|
99
102
|
const value = config.get(key);
|
|
100
103
|
if (typeof value === "object" && value.cron) {
|
|
101
104
|
return value;
|
|
102
105
|
}
|
|
106
|
+
if (typeof value === "object" && value.trigger === "manual") {
|
|
107
|
+
return { trigger: "manual" };
|
|
108
|
+
}
|
|
103
109
|
return readDuration(config, key);
|
|
104
110
|
}
|
|
105
111
|
function readSchedulerServiceTaskScheduleDefinitionFromConfig(config) {
|
|
106
|
-
const frequency =
|
|
112
|
+
const frequency = readFrequency(config, "frequency");
|
|
107
113
|
const timeout = readDuration(config, "timeout");
|
|
108
114
|
const initialDelay = config.has("initialDelay") ? readDuration(config, "initialDelay") : void 0;
|
|
109
115
|
const scope = config.getOptionalString("scope");
|
|
@@ -125,22 +131,7 @@ function isDatabaseConflictError(e) {
|
|
|
125
131
|
return typeof message === "string" && (/SQLITE_CONSTRAINT(?:_UNIQUE)?: UNIQUE/.test(message) || /UNIQUE constraint failed:/.test(message) || /unique constraint/.test(message) || /Duplicate entry/.test(message));
|
|
126
132
|
}
|
|
127
133
|
|
|
128
|
-
function
|
|
129
|
-
return {
|
|
130
|
-
id: options.id,
|
|
131
|
-
get T() {
|
|
132
|
-
if (process.env.NODE_ENV === "test") {
|
|
133
|
-
return null;
|
|
134
|
-
}
|
|
135
|
-
throw new Error(`tried to read ExtensionPoint.T of ${this}`);
|
|
136
|
-
},
|
|
137
|
-
toString() {
|
|
138
|
-
return `extensionPoint{${options.id}}`;
|
|
139
|
-
},
|
|
140
|
-
$$type: "@backstage/ExtensionPoint"
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
function createBackendPlugin(options) {
|
|
134
|
+
function createBackendModule(options) {
|
|
144
135
|
function getRegistrations() {
|
|
145
136
|
const extensionPoints = [];
|
|
146
137
|
let init = void 0;
|
|
@@ -163,13 +154,14 @@ function createBackendPlugin(options) {
|
|
|
163
154
|
});
|
|
164
155
|
if (!init) {
|
|
165
156
|
throw new Error(
|
|
166
|
-
`registerInit was not called by register in ${options.pluginId}`
|
|
157
|
+
`registerInit was not called by register in ${options.moduleId} module for ${options.pluginId}`
|
|
167
158
|
);
|
|
168
159
|
}
|
|
169
160
|
return [
|
|
170
161
|
{
|
|
171
|
-
type: "
|
|
162
|
+
type: "module",
|
|
172
163
|
pluginId: options.pluginId,
|
|
164
|
+
moduleId: options.moduleId,
|
|
173
165
|
extensionPoints,
|
|
174
166
|
init
|
|
175
167
|
}
|
|
@@ -185,7 +177,8 @@ function createBackendPlugin(options) {
|
|
|
185
177
|
});
|
|
186
178
|
return backendFeatureCompatWrapper;
|
|
187
179
|
}
|
|
188
|
-
|
|
180
|
+
|
|
181
|
+
function createBackendPlugin(options) {
|
|
189
182
|
function getRegistrations() {
|
|
190
183
|
const extensionPoints = [];
|
|
191
184
|
let init = void 0;
|
|
@@ -208,14 +201,13 @@ function createBackendModule(options) {
|
|
|
208
201
|
});
|
|
209
202
|
if (!init) {
|
|
210
203
|
throw new Error(
|
|
211
|
-
`registerInit was not called by register in ${options.
|
|
204
|
+
`registerInit was not called by register in ${options.pluginId}`
|
|
212
205
|
);
|
|
213
206
|
}
|
|
214
207
|
return [
|
|
215
208
|
{
|
|
216
|
-
type: "
|
|
209
|
+
type: "plugin",
|
|
217
210
|
pluginId: options.pluginId,
|
|
218
|
-
moduleId: options.moduleId,
|
|
219
211
|
extensionPoints,
|
|
220
212
|
init
|
|
221
213
|
}
|
|
@@ -232,6 +224,68 @@ function createBackendModule(options) {
|
|
|
232
224
|
return backendFeatureCompatWrapper;
|
|
233
225
|
}
|
|
234
226
|
|
|
227
|
+
function createExtensionPoint(options) {
|
|
228
|
+
return {
|
|
229
|
+
id: options.id,
|
|
230
|
+
get T() {
|
|
231
|
+
if (process.env.NODE_ENV === "test") {
|
|
232
|
+
return null;
|
|
233
|
+
}
|
|
234
|
+
throw new Error(`tried to read ExtensionPoint.T of ${this}`);
|
|
235
|
+
},
|
|
236
|
+
toString() {
|
|
237
|
+
return `extensionPoint{${options.id}}`;
|
|
238
|
+
},
|
|
239
|
+
$$type: "@backstage/ExtensionPoint"
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
const MESSAGE_MARKER = "eHgtF5hmbrXyiEvo";
|
|
244
|
+
function describeParentCallSite(ErrorConstructor = Error) {
|
|
245
|
+
const { stack } = new ErrorConstructor(MESSAGE_MARKER);
|
|
246
|
+
if (!stack) {
|
|
247
|
+
return "<unknown>";
|
|
248
|
+
}
|
|
249
|
+
const startIndex = stack.includes(MESSAGE_MARKER) ? stack.indexOf("\n") + 1 : 0;
|
|
250
|
+
const secondEntryStart = stack.indexOf("\n", stack.indexOf("\n", startIndex) + 1) + 1;
|
|
251
|
+
const secondEntryEnd = stack.indexOf("\n", secondEntryStart);
|
|
252
|
+
const line = stack.substring(secondEntryStart, secondEntryEnd).trim();
|
|
253
|
+
if (!line) {
|
|
254
|
+
return "unknown";
|
|
255
|
+
}
|
|
256
|
+
if (line.includes("(")) {
|
|
257
|
+
return line.substring(line.indexOf("(") + 1, line.indexOf(")"));
|
|
258
|
+
}
|
|
259
|
+
if (line.includes("@")) {
|
|
260
|
+
return line.substring(line.indexOf("@") + 1);
|
|
261
|
+
}
|
|
262
|
+
return line;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
function createBackendFeatureLoader(options) {
|
|
266
|
+
return {
|
|
267
|
+
$$type: "@backstage/BackendFeature",
|
|
268
|
+
version: "v1",
|
|
269
|
+
featureType: "loader",
|
|
270
|
+
description: `created at '${describeParentCallSite()}'`,
|
|
271
|
+
deps: options.deps,
|
|
272
|
+
async loader(deps) {
|
|
273
|
+
const it = await options.loader(deps);
|
|
274
|
+
const result = new Array();
|
|
275
|
+
for await (const item of it) {
|
|
276
|
+
if ("$$type" in item && item.$$type === "@backstage/BackendFeature") {
|
|
277
|
+
result.push(item);
|
|
278
|
+
} else if ("default" in item) {
|
|
279
|
+
result.push(item.default);
|
|
280
|
+
} else {
|
|
281
|
+
throw new Error(`Invalid item "${item}"`);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
return result;
|
|
285
|
+
}
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
|
|
235
289
|
exports.packagePathMocks = paths.packagePathMocks;
|
|
236
290
|
exports.resolvePackagePath = paths.resolvePackagePath;
|
|
237
291
|
exports.resolveSafeChildPath = paths.resolveSafeChildPath;
|
|
@@ -239,6 +293,7 @@ Object.defineProperty(exports, "isChildPath", {
|
|
|
239
293
|
enumerable: true,
|
|
240
294
|
get: function () { return cliCommon.isChildPath; }
|
|
241
295
|
});
|
|
296
|
+
exports.createBackendFeatureLoader = createBackendFeatureLoader;
|
|
242
297
|
exports.createBackendModule = createBackendModule;
|
|
243
298
|
exports.createBackendPlugin = createBackendPlugin;
|
|
244
299
|
exports.createExtensionPoint = createExtensionPoint;
|
package/dist/index.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs.js","sources":["../src/services/system/types.ts","../src/services/definitions/coreServices.ts","../src/services/definitions/SchedulerService.ts","../src/services/utilities/database.ts","../src/wiring/factories.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { BackendFeature } from '../../types';\n\n/**\n * TODO\n *\n * @public\n */\nexport type ServiceRef<\n TService,\n TScope extends 'root' | 'plugin' = 'root' | 'plugin',\n> = {\n id: string;\n\n /**\n * This determines the scope at which this service is available.\n *\n * Root scoped services are available to all other services but\n * may only depend on other root scoped services.\n *\n * Plugin scoped services are only available to other plugin scoped\n * services but may depend on all other services.\n */\n scope: TScope;\n\n /**\n * Utility for getting the type of the service, using `typeof serviceRef.T`.\n * Attempting to actually read this value will result in an exception.\n */\n T: TService;\n\n $$type: '@backstage/ServiceRef';\n};\n\n/** @public */\nexport interface ServiceFactory<\n TService = unknown,\n TScope extends 'plugin' | 'root' = 'plugin' | 'root',\n> extends BackendFeature {\n service: ServiceRef<TService, TScope>;\n}\n\n/**\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 TOpts extends object | undefined = undefined,\n> extends ServiceFactory<TService, TScope> {\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>;\n}\n\n/** @internal */\nexport interface InternalServiceFactory<\n TService = unknown,\n TScope extends 'plugin' | 'root' = 'plugin' | 'root',\n> extends ServiceFactory<TService, TScope> {\n version: 'v1';\n initialization?: 'always' | 'lazy';\n deps: { [key in string]: ServiceRef<unknown> };\n createRootContext?(deps: { [key in string]: unknown }): Promise<unknown>;\n factory(\n deps: { [key in string]: unknown },\n context: unknown,\n ): Promise<TService>;\n}\n\n/**\n * Represents either a {@link ServiceFactory} or a function that returns one.\n *\n * @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<TService, TScope extends 'root' | 'plugin'> {\n id: string;\n scope?: TScope;\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'>,\n): ServiceRef<TService, 'plugin'>;\n\n/**\n * Creates a new service definition. This overload is used to create root scoped services.\n *\n * @public\n */\nexport function createServiceRef<TService>(\n options: ServiceRefOptions<TService, 'root'>,\n): ServiceRef<TService, 'root'>;\n\nexport function createServiceRef<TService>(\n options: ServiceRefOptions<TService, any>,\n): ServiceRef<TService, any> {\n const { id, scope = 'plugin', defaultFactory } = options;\n return {\n id,\n scope,\n get T(): TService {\n throw new Error(`tried to read ServiceRef.T of ${this}`);\n },\n toString() {\n return `serviceRef{${options.id}}`;\n },\n $$type: '@backstage/ServiceRef',\n __defaultFactory: defaultFactory,\n } as ServiceRef<TService, typeof scope> & {\n __defaultFactory?: (\n service: ServiceRef<TService>,\n ) => Promise<ServiceFactory<TService> | (() => ServiceFactory<TService>)>;\n };\n}\n\n/** @ignore */\ntype ServiceRefsToInstances<\n T extends { [key in string]: ServiceRef<unknown> },\n TScope extends 'root' | 'plugin' = 'root' | 'plugin',\n> = {\n [key in keyof T as T[key]['scope'] extends TScope ? key : never]: T[key]['T'];\n};\n\n/** @public */\nexport interface RootServiceFactoryOptions<\n TService,\n TImpl extends TService,\n TDeps extends { [name in string]: ServiceRef<unknown> },\n> {\n /**\n * The initialization strategy for the service factory. This service is root scoped and will use `always` by default.\n *\n * @remarks\n *\n * - `always` - The service will always be initialized regardless if it is used or not.\n * - `lazy` - The service will only be initialized if it is depended on by a different service or feature.\n *\n * Service factories for root scoped services use `always` as the default, while plugin scoped services use `lazy`.\n */\n initialization?: 'always' | 'lazy';\n service: ServiceRef<TService, 'root'>;\n deps: TDeps;\n factory(deps: ServiceRefsToInstances<TDeps, 'root'>): TImpl | Promise<TImpl>;\n}\n\n/** @public */\nexport interface PluginServiceFactoryOptions<\n TService,\n TContext,\n TImpl extends TService,\n TDeps extends { [name in string]: ServiceRef<unknown> },\n> {\n /**\n * The initialization strategy for the service factory. This service is plugin scoped and will use `lazy` by default.\n *\n * @remarks\n *\n * - `always` - The service will always be initialized regardless if it is used or not.\n * - `lazy` - The service will only be initialized if it is depended on by a different service or feature.\n *\n * Service factories for root scoped services use `always` as the default, while plugin scoped services use `lazy`.\n */\n initialization?: 'always' | 'lazy';\n service: ServiceRef<TService, 'plugin'>;\n deps: TDeps;\n createRootContext?(\n deps: ServiceRefsToInstances<TDeps, 'root'>,\n ): TContext | Promise<TContext>;\n factory(\n deps: ServiceRefsToInstances<TDeps>,\n context: TContext,\n ): TImpl | Promise<TImpl>;\n}\n\n/**\n * Creates a root scoped service factory without options.\n *\n * @public\n * @param options - The service factory configuration.\n */\nexport function createServiceFactory<\n TService,\n TImpl extends TService,\n TDeps extends { [name in string]: ServiceRef<unknown, 'root'> },\n TOpts extends object | undefined = undefined,\n>(\n options: RootServiceFactoryOptions<TService, TImpl, TDeps>,\n): ServiceFactoryCompat<TService, 'root'>;\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 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, TImpl, TDeps>,\n): ServiceFactoryCompat<TService, 'root', 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 TImpl extends TService,\n TDeps extends { [name in string]: ServiceRef<unknown> },\n TContext = undefined,\n TOpts extends object | undefined = undefined,\n>(\n options: PluginServiceFactoryOptions<TService, TContext, TImpl, TDeps>,\n): ServiceFactoryCompat<TService, 'plugin'>;\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 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<TService, TContext, TImpl, TDeps>,\n): ServiceFactoryCompat<TService, 'plugin', TOpts>;\nexport function createServiceFactory<\n TService,\n TImpl extends TService,\n TDeps extends { [name in string]: ServiceRef<unknown> },\n TContext,\n TOpts extends object | undefined = undefined,\n>(\n options:\n | RootServiceFactoryOptions<TService, TImpl, TDeps>\n | PluginServiceFactoryOptions<TService, TContext, TImpl, TDeps>\n | ((options: TOpts) => RootServiceFactoryOptions<TService, TImpl, TDeps>)\n | ((\n options: TOpts,\n ) => PluginServiceFactoryOptions<TService, TContext, TImpl, TDeps>)\n | (() => RootServiceFactoryOptions<TService, TImpl, TDeps>)\n | (() => PluginServiceFactoryOptions<TService, TContext, TImpl, TDeps>),\n): ServiceFactoryCompat<TService, 'root' | 'plugin', TOpts> {\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<TService, TImpl, TDeps>;\n return {\n $$type: '@backstage/BackendFeature',\n version: 'v1',\n service: c.service,\n initialization: c.initialization,\n deps: c.deps,\n factory: async (deps: TDeps) => c.factory(deps),\n };\n }\n const c = anyConf as PluginServiceFactoryOptions<\n TService,\n TContext,\n TImpl,\n TDeps\n >;\n return {\n $$type: '@backstage/BackendFeature',\n version: 'v1',\n service: c.service,\n initialization: c.initialization,\n ...('createRootContext' in c\n ? {\n createRootContext: async (deps: TDeps) =>\n c?.createRootContext?.(deps),\n }\n : {}),\n deps: c.deps,\n factory: async (deps: TDeps, ctx: TContext) => c.factory(deps, ctx),\n };\n };\n\n // 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\n /**\n * The maximum amount of time that a single task invocation can take, before\n * it's considered timed out and gets \"released\" such that a new invocation\n * is permitted to take place (possibly, then, on a different worker).\n */\n timeout: Duration | HumanDuration;\n\n /**\n * The amount of time that should pass before the first invocation happens.\n *\n * @remarks\n *\n * This can be useful in cold start scenarios to stagger or delay some heavy\n * compute jobs. If no value is given for this field then the first invocation\n * will happen as soon as possible according to the cadence.\n *\n * NOTE: This is a per-worker delay. If you have a cluster of workers all\n * collaborating on a task that has its `scope` field set to `'global'`, then\n * you may still see the task being processed by other long-lived workers,\n * while any given single worker is in its initial sleep delay time e.g. after\n * a deployment. Therefore, this parameter is not useful for \"globally\" pausing\n * work; its main intended use is for individual machines to get a chance to\n * reach some equilibrium at startup before triggering heavy batch workloads.\n */\n initialDelay?: Duration | HumanDuration;\n\n /**\n * Sets the scope of concurrency control / locking to apply for invocations of\n * this task.\n *\n * @remarks\n *\n * When the scope is set to the default value `'global'`, the scheduler will\n * attempt to ensure that only one worker machine runs the task at a time,\n * according to the given cadence. This means that as the number of worker\n * hosts increases, the invocation frequency of this task will not go up.\n * Instead, the load is spread randomly across hosts. This setting is useful\n * for tasks that access shared resources, for example catalog ingestion tasks\n * where you do not want many machines to repeatedly import the same data and\n * trample over each other.\n *\n * When the scope is set to `'local'`, there is no concurrency control across\n * hosts. Each host runs the task according to the given cadence similarly to\n * `setInterval`, but the runtime ensures that there are no overlapping runs.\n *\n * @defaultValue 'global'\n */\n scope?: 'global' | 'local';\n}\n\n/**\n * Config options for {@link SchedulerServiceTaskScheduleDefinition}\n * that control the scheduling of a task.\n *\n * @public\n */\nexport interface SchedulerServiceTaskScheduleDefinitionConfig {\n /**\n * How often you want the task to run. The system does its best to avoid\n * overlapping invocations.\n *\n * @remarks\n *\n * This is the best effort value; under some circumstances there can be\n * deviations. For example, if the task runtime is longer than the frequency\n * and the timeout has not been given or not been exceeded yet, the next\n * invocation of this task will be delayed until after the previous one\n * finishes.\n *\n * This is a required field.\n */\n frequency:\n | {\n /**\n * A crontab style string.\n *\n * @remarks\n *\n * Overview:\n *\n * ```\n * ┌────────────── second (optional)\n * │ ┌──────────── minute\n * │ │ ┌────────── hour\n * │ │ │ ┌──────── day of month\n * │ │ │ │ ┌────── month\n * │ │ │ │ │ ┌──── day of week\n * │ │ │ │ │ │\n * │ │ │ │ │ │\n * * * * * * *\n * ```\n */\n cron: string;\n }\n | string\n | HumanDuration;\n\n /**\n * The maximum amount of time that a single task invocation can take, before\n * it's considered timed out and gets \"released\" such that a new invocation\n * is permitted to take place (possibly, then, on a different worker).\n */\n timeout: string | HumanDuration;\n\n /**\n * The amount of time that should pass before the first invocation happens.\n *\n * @remarks\n *\n * This can be useful in cold start scenarios to stagger or delay some heavy\n * compute jobs. If no value is given for this field then the first invocation\n * will happen as soon as possible according to the cadence.\n *\n * NOTE: This is a per-worker delay. If you have a cluster of workers all\n * collaborating on a task that has its `scope` field set to `'global'`, then\n * you may still see the task being processed by other long-lived workers,\n * while any given single worker is in its initial sleep delay time e.g. after\n * a deployment. Therefore, this parameter is not useful for \"globally\" pausing\n * work; its main intended use is for individual machines to get a chance to\n * reach some equilibrium at startup before triggering heavy batch workloads.\n */\n initialDelay?: string | HumanDuration;\n\n /**\n * Sets the scope of concurrency control / locking to apply for invocations of\n * this task.\n *\n * @remarks\n *\n * When the scope is set to the default value `'global'`, the scheduler will\n * attempt to ensure that only one worker machine runs the task at a time,\n * according to the given cadence. This means that as the number of worker\n * hosts increases, the invocation frequency of this task will not go up.\n * Instead, the load is spread randomly across hosts. This setting is useful\n * for tasks that access shared resources, for example catalog ingestion tasks\n * where you do not want many machines to repeatedly import the same data and\n * trample over each other.\n *\n * When the scope is set to `'local'`, there is no concurrency control across\n * hosts. Each host runs the task according to the given cadence similarly to\n * `setInterval`, but the runtime ensures that there are no overlapping runs.\n *\n * @defaultValue 'global'\n */\n scope?: 'global' | 'local';\n}\n\n/**\n * Options that apply to the invocation of a given task.\n *\n * @public\n */\nexport interface SchedulerServiceTaskInvocationDefinition {\n /**\n * A unique ID (within the scope of the plugin) for the task.\n */\n id: string;\n\n /**\n * The actual task function to be invoked regularly.\n */\n fn: SchedulerServiceTaskFunction;\n\n /**\n * An abort signal that, when triggered, will stop the recurring execution of\n * the task.\n */\n signal?: AbortSignal;\n}\n\n/**\n * A previously prepared task schedule, ready to be invoked.\n *\n * @public\n */\nexport interface SchedulerServiceTaskRunner {\n /**\n * Takes the schedule and executes an actual task using it.\n *\n * @param task - The actual runtime properties of the task\n */\n run(task: SchedulerServiceTaskInvocationDefinition): Promise<void>;\n}\n\n/**\n * Deals with the scheduling of distributed tasks, for a given plugin.\n *\n * See the {@link https://backstage.io/docs/backend-system/core-services/scheduler | service documentation} for more details.\n *\n * @public\n */\nexport interface SchedulerService {\n /**\n * Manually triggers a task by ID.\n *\n * If the task doesn't exist, a NotFoundError is thrown. If the task is\n * currently running, a ConflictError is thrown.\n *\n * @param id - The task ID\n */\n triggerTask(id: string): Promise<void>;\n\n /**\n * Schedules a task function for recurring runs.\n *\n * @remarks\n *\n * The `scope` task field controls whether to use coordinated exclusive\n * invocation across workers, or to just coordinate within the current worker.\n *\n * This convenience method performs both the scheduling and invocation in one\n * go.\n *\n * @param task - The task definition\n */\n scheduleTask(\n task: SchedulerServiceTaskScheduleDefinition &\n SchedulerServiceTaskInvocationDefinition,\n ): Promise<void>;\n\n /**\n * Creates a scheduled but dormant recurring task, ready to be launched at a\n * later time.\n *\n * @remarks\n *\n * This method is useful for pre-creating a schedule in outer code to be\n * passed into an inner implementation, such that the outer code controls\n * scheduling while inner code controls implementation.\n *\n * @param schedule - The task schedule\n */\n createScheduledTaskRunner(\n schedule: SchedulerServiceTaskScheduleDefinition,\n ): SchedulerServiceTaskRunner;\n\n /**\n * Returns all scheduled tasks registered to this scheduler.\n *\n * @remarks\n *\n * This method is useful for triggering tasks manually using the triggerTask\n * functionality. Note that the returned tasks contain only tasks that have\n * been initialized in this instance of the scheduler.\n *\n * @returns Scheduled tasks\n */\n getScheduledTasks(): Promise<SchedulerServiceTaskDescriptor[]>;\n}\n\nfunction readDuration(config: Config, key: string): 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 readCronOrDuration(\n config: Config,\n key: string,\n): { cron: string } | HumanDuration {\n const value = config.get(key);\n if (typeof value === 'object' && (value as { cron?: string }).cron) {\n return value as { cron: string };\n }\n\n return readDuration(config, key);\n}\n\n/**\n * Reads a {@link SchedulerServiceTaskScheduleDefinition} from config. Expects\n * the config not to be the root config, but the config for the definition.\n *\n * @param config - config for a TaskScheduleDefinition.\n * @public\n */\nexport function readSchedulerServiceTaskScheduleDefinitionFromConfig(\n config: Config,\n): SchedulerServiceTaskScheduleDefinition {\n const frequency = readCronOrDuration(config, 'frequency');\n const timeout = readDuration(config, 'timeout');\n\n const initialDelay = config.has('initialDelay')\n ? readDuration(config, 'initialDelay')\n : undefined;\n\n const scope = config.getOptionalString('scope');\n if (scope && !['global', 'local'].includes(scope)) {\n throw new Error(\n `Only \"global\" or \"local\" are allowed for TaskScheduleDefinition.scope, but got: ${scope}`,\n );\n }\n\n return {\n frequency,\n timeout,\n initialDelay,\n scope: scope as 'global' | 'local' | undefined,\n };\n}\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Tries to deduce whether a thrown error is a database conflict.\n *\n * @public\n * @param e - A thrown error\n * @returns True if the error looks like it was a conflict error thrown by a\n * known database engine\n */\nexport function isDatabaseConflictError(e: unknown) {\n const message = (e as any)?.message;\n\n return (\n typeof message === 'string' &&\n (/SQLITE_CONSTRAINT(?:_UNIQUE)?: UNIQUE/.test(message) ||\n /UNIQUE constraint failed:/.test(message) ||\n /unique constraint/.test(message) ||\n /Duplicate entry/.test(message)) // MySQL uniqueness error msg\n );\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { BackendFeatureCompat } from '../types';\nimport {\n BackendModuleRegistrationPoints,\n BackendPluginRegistrationPoints,\n ExtensionPoint,\n InternalBackendModuleRegistration,\n InternalBackendPluginRegistration,\n} from './types';\n\n/**\n * The configuration options passed to {@link createExtensionPoint}.\n *\n * @public\n * @see {@link https://backstage.io/docs/backend-system/architecture/extension-points | The architecture of extension points}\n * @see {@link https://backstage.io/docs/backend-system/architecture/naming-patterns | Recommended naming patterns}\n */\nexport interface CreateExtensionPointOptions {\n /**\n * The ID of this extension point.\n *\n * @see {@link https://backstage.io/docs/backend-system/architecture/naming-patterns | Recommended naming patterns}\n */\n id: string;\n}\n\n/**\n * Creates a new backend extension point.\n *\n * @public\n * @see {@link https://backstage.io/docs/backend-system/architecture/extension-points | The architecture of extension points}\n */\nexport function createExtensionPoint<T>(\n options: CreateExtensionPointOptions,\n): ExtensionPoint<T> {\n return {\n id: options.id,\n get T(): T {\n if (process.env.NODE_ENV === 'test') {\n // Avoid throwing errors so tests asserting extensions' properties cannot be easily broken\n return null as T;\n }\n throw new Error(`tried to read ExtensionPoint.T of ${this}`);\n },\n toString() {\n return `extensionPoint{${options.id}}`;\n },\n $$type: '@backstage/ExtensionPoint',\n };\n}\n\n/**\n * The configuration options passed to {@link createBackendPlugin}.\n *\n * @public\n * @see {@link https://backstage.io/docs/backend-system/architecture/plugins | The architecture of plugins}\n * @see {@link https://backstage.io/docs/backend-system/architecture/naming-patterns | Recommended naming patterns}\n */\nexport interface CreateBackendPluginOptions {\n /**\n * The ID of this plugin.\n *\n * @see {@link https://backstage.io/docs/backend-system/architecture/naming-patterns | Recommended naming patterns}\n */\n pluginId: string;\n register(reg: BackendPluginRegistrationPoints): void;\n}\n\n/**\n * Creates a new backend plugin.\n *\n * @public\n * @see {@link https://backstage.io/docs/backend-system/architecture/plugins | The architecture of plugins}\n * @see {@link https://backstage.io/docs/backend-system/architecture/naming-patterns | Recommended naming patterns}\n */\nexport function createBackendPlugin(\n options: CreateBackendPluginOptions,\n): 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/**\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"],"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/**\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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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -482,7 +482,9 @@ interface SchedulerServiceTaskScheduleDefinition {
|
|
|
482
482
|
* ```
|
|
483
483
|
*/
|
|
484
484
|
cron: string;
|
|
485
|
-
} | Duration | HumanDuration
|
|
485
|
+
} | Duration | HumanDuration | {
|
|
486
|
+
trigger: 'manual';
|
|
487
|
+
};
|
|
486
488
|
/**
|
|
487
489
|
* The maximum amount of time that a single task invocation can take, before
|
|
488
490
|
* it's considered timed out and gets "released" such that a new invocation
|
|
@@ -572,7 +574,14 @@ interface SchedulerServiceTaskScheduleDefinitionConfig {
|
|
|
572
574
|
* ```
|
|
573
575
|
*/
|
|
574
576
|
cron: string;
|
|
575
|
-
} | string | HumanDuration
|
|
577
|
+
} | string | HumanDuration
|
|
578
|
+
/**
|
|
579
|
+
* This task will only run when manually triggered with the `triggerTask` method; no automatic
|
|
580
|
+
* scheduling. This is useful for locking of global tasks that should not be run concurrently.
|
|
581
|
+
*/
|
|
582
|
+
| {
|
|
583
|
+
trigger: 'manual';
|
|
584
|
+
};
|
|
576
585
|
/**
|
|
577
586
|
* The maximum amount of time that a single task invocation can take, before
|
|
578
587
|
* it's considered timed out and gets "released" such that a new invocation
|
|
@@ -1436,7 +1445,7 @@ interface BackendFeatureCompat extends BackendFeature {
|
|
|
1436
1445
|
*
|
|
1437
1446
|
* @public
|
|
1438
1447
|
*/
|
|
1439
|
-
type ServiceRef<TService, TScope extends 'root' | 'plugin' = 'root' | 'plugin'> = {
|
|
1448
|
+
type ServiceRef<TService, TScope extends 'root' | 'plugin' = 'root' | 'plugin', TInstances extends 'singleton' | 'multiton' = 'singleton' | 'multiton'> = {
|
|
1440
1449
|
id: string;
|
|
1441
1450
|
/**
|
|
1442
1451
|
* This determines the scope at which this service is available.
|
|
@@ -1448,6 +1457,7 @@ type ServiceRef<TService, TScope extends 'root' | 'plugin' = 'root' | 'plugin'>
|
|
|
1448
1457
|
* services but may depend on all other services.
|
|
1449
1458
|
*/
|
|
1450
1459
|
scope: TScope;
|
|
1460
|
+
multiton?: TInstances extends 'multiton' ? true : false;
|
|
1451
1461
|
/**
|
|
1452
1462
|
* Utility for getting the type of the service, using `typeof serviceRef.T`.
|
|
1453
1463
|
* Attempting to actually read this value will result in an exception.
|
|
@@ -1456,18 +1466,18 @@ type ServiceRef<TService, TScope extends 'root' | 'plugin' = 'root' | 'plugin'>
|
|
|
1456
1466
|
$$type: '@backstage/ServiceRef';
|
|
1457
1467
|
};
|
|
1458
1468
|
/** @public */
|
|
1459
|
-
interface ServiceFactory<TService = unknown, TScope extends 'plugin' | 'root' = 'plugin' | 'root'> extends BackendFeature {
|
|
1460
|
-
service: ServiceRef<TService, TScope>;
|
|
1469
|
+
interface ServiceFactory<TService = unknown, TScope extends 'plugin' | 'root' = 'plugin' | 'root', TInstances extends 'singleton' | 'multiton' = 'singleton' | 'multiton'> extends BackendFeature {
|
|
1470
|
+
service: ServiceRef<TService, TScope, TInstances>;
|
|
1461
1471
|
}
|
|
1462
1472
|
/**
|
|
1463
1473
|
* @public
|
|
1464
1474
|
* @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.
|
|
1465
1475
|
*/
|
|
1466
|
-
interface ServiceFactoryCompat<TService = unknown, TScope extends 'plugin' | 'root' = 'plugin' | 'root', TOpts extends object | undefined = undefined> extends ServiceFactory<TService, TScope> {
|
|
1476
|
+
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> {
|
|
1467
1477
|
/**
|
|
1468
1478
|
* @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 `()`.
|
|
1469
1479
|
*/
|
|
1470
|
-
(...options: undefined extends TOpts ? [] : [options?: TOpts]): ServiceFactory<TService, TScope>;
|
|
1480
|
+
(...options: undefined extends TOpts ? [] : [options?: TOpts]): ServiceFactory<TService, TScope, TInstances>;
|
|
1471
1481
|
}
|
|
1472
1482
|
/**
|
|
1473
1483
|
* Represents either a {@link ServiceFactory} or a function that returns one.
|
|
@@ -1477,9 +1487,10 @@ interface ServiceFactoryCompat<TService = unknown, TScope extends 'plugin' | 'ro
|
|
|
1477
1487
|
*/
|
|
1478
1488
|
type ServiceFactoryOrFunction = ServiceFactory | (() => ServiceFactory);
|
|
1479
1489
|
/** @public */
|
|
1480
|
-
interface ServiceRefOptions<TService, TScope extends 'root' | 'plugin'> {
|
|
1490
|
+
interface ServiceRefOptions<TService, TScope extends 'root' | 'plugin', TInstances extends 'singleton' | 'multiton'> {
|
|
1481
1491
|
id: string;
|
|
1482
1492
|
scope?: TScope;
|
|
1493
|
+
multiton?: TInstances extends 'multiton' ? true : false;
|
|
1483
1494
|
defaultFactory?(service: ServiceRef<TService, TScope>): Promise<ServiceFactory>;
|
|
1484
1495
|
/**
|
|
1485
1496
|
* @deprecated The defaultFactory must return a plain `ServiceFactory` object, support for returning a function will be removed.
|
|
@@ -1491,21 +1502,34 @@ interface ServiceRefOptions<TService, TScope extends 'root' | 'plugin'> {
|
|
|
1491
1502
|
*
|
|
1492
1503
|
* @public
|
|
1493
1504
|
*/
|
|
1494
|
-
declare function createServiceRef<TService>(options: ServiceRefOptions<TService, 'plugin'>): ServiceRef<TService, 'plugin'>;
|
|
1505
|
+
declare function createServiceRef<TService>(options: ServiceRefOptions<TService, 'plugin', 'singleton'>): ServiceRef<TService, 'plugin', 'singleton'>;
|
|
1506
|
+
/**
|
|
1507
|
+
* Creates a new service definition. This overload is used to create root scoped services.
|
|
1508
|
+
*
|
|
1509
|
+
* @public
|
|
1510
|
+
*/
|
|
1511
|
+
declare function createServiceRef<TService>(options: ServiceRefOptions<TService, 'root', 'singleton'>): ServiceRef<TService, 'root', 'singleton'>;
|
|
1512
|
+
/**
|
|
1513
|
+
* Creates a new service definition. This overload is used to create plugin scoped services.
|
|
1514
|
+
*
|
|
1515
|
+
* @public
|
|
1516
|
+
*/
|
|
1517
|
+
declare function createServiceRef<TService>(options: ServiceRefOptions<TService, 'plugin', 'multiton'>): ServiceRef<TService, 'plugin', 'multiton'>;
|
|
1495
1518
|
/**
|
|
1496
1519
|
* Creates a new service definition. This overload is used to create root scoped services.
|
|
1497
1520
|
*
|
|
1498
1521
|
* @public
|
|
1499
1522
|
*/
|
|
1500
|
-
declare function createServiceRef<TService>(options: ServiceRefOptions<TService, 'root'>): ServiceRef<TService, 'root'>;
|
|
1523
|
+
declare function createServiceRef<TService>(options: ServiceRefOptions<TService, 'root', 'multiton'>): ServiceRef<TService, 'root', 'multiton'>;
|
|
1501
1524
|
/** @ignore */
|
|
1502
1525
|
type ServiceRefsToInstances<T extends {
|
|
1503
1526
|
[key in string]: ServiceRef<unknown>;
|
|
1504
1527
|
}, TScope extends 'root' | 'plugin' = 'root' | 'plugin'> = {
|
|
1505
|
-
[key in keyof T as T[key]['scope'] extends TScope ? key : never]: T[key]['T'];
|
|
1528
|
+
[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'];
|
|
1506
1529
|
};
|
|
1507
1530
|
/** @public */
|
|
1508
|
-
interface RootServiceFactoryOptions<TService,
|
|
1531
|
+
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?
|
|
1532
|
+
TInstances extends 'singleton' | 'multiton', TImpl extends TService, TDeps extends {
|
|
1509
1533
|
[name in string]: ServiceRef<unknown>;
|
|
1510
1534
|
}> {
|
|
1511
1535
|
/**
|
|
@@ -1519,12 +1543,12 @@ interface RootServiceFactoryOptions<TService, TImpl extends TService, TDeps exte
|
|
|
1519
1543
|
* Service factories for root scoped services use `always` as the default, while plugin scoped services use `lazy`.
|
|
1520
1544
|
*/
|
|
1521
1545
|
initialization?: 'always' | 'lazy';
|
|
1522
|
-
service: ServiceRef<TService, 'root'>;
|
|
1546
|
+
service: ServiceRef<TService, 'root', TInstances>;
|
|
1523
1547
|
deps: TDeps;
|
|
1524
1548
|
factory(deps: ServiceRefsToInstances<TDeps, 'root'>): TImpl | Promise<TImpl>;
|
|
1525
1549
|
}
|
|
1526
1550
|
/** @public */
|
|
1527
|
-
interface PluginServiceFactoryOptions<TService, TContext, TImpl extends TService, TDeps extends {
|
|
1551
|
+
interface PluginServiceFactoryOptions<TService, TInstances extends 'singleton' | 'multiton', TContext, TImpl extends TService, TDeps extends {
|
|
1528
1552
|
[name in string]: ServiceRef<unknown>;
|
|
1529
1553
|
}> {
|
|
1530
1554
|
/**
|
|
@@ -1538,7 +1562,7 @@ interface PluginServiceFactoryOptions<TService, TContext, TImpl extends TService
|
|
|
1538
1562
|
* Service factories for root scoped services use `always` as the default, while plugin scoped services use `lazy`.
|
|
1539
1563
|
*/
|
|
1540
1564
|
initialization?: 'always' | 'lazy';
|
|
1541
|
-
service: ServiceRef<TService, 'plugin'>;
|
|
1565
|
+
service: ServiceRef<TService, 'plugin', TInstances>;
|
|
1542
1566
|
deps: TDeps;
|
|
1543
1567
|
createRootContext?(deps: ServiceRefsToInstances<TDeps, 'root'>): TContext | Promise<TContext>;
|
|
1544
1568
|
factory(deps: ServiceRefsToInstances<TDeps>, context: TContext): TImpl | Promise<TImpl>;
|
|
@@ -1549,9 +1573,9 @@ interface PluginServiceFactoryOptions<TService, TContext, TImpl extends TService
|
|
|
1549
1573
|
* @public
|
|
1550
1574
|
* @param options - The service factory configuration.
|
|
1551
1575
|
*/
|
|
1552
|
-
declare function createServiceFactory<TService, TImpl extends TService, TDeps extends {
|
|
1576
|
+
declare function createServiceFactory<TService, TInstances extends 'singleton' | 'multiton', TImpl extends TService, TDeps extends {
|
|
1553
1577
|
[name in string]: ServiceRef<unknown, 'root'>;
|
|
1554
|
-
}, TOpts extends object | undefined = undefined>(options: RootServiceFactoryOptions<TService, TImpl, TDeps>): ServiceFactoryCompat<TService, 'root'>;
|
|
1578
|
+
}, TOpts extends object | undefined = undefined>(options: RootServiceFactoryOptions<TService, TInstances, TImpl, TDeps>): ServiceFactoryCompat<TService, 'root', TInstances>;
|
|
1555
1579
|
/**
|
|
1556
1580
|
* Creates a root scoped service factory with optional options.
|
|
1557
1581
|
*
|
|
@@ -1562,18 +1586,18 @@ declare function createServiceFactory<TService, TImpl extends TService, TDeps ex
|
|
|
1562
1586
|
* @public
|
|
1563
1587
|
* @param options - The service factory configuration.
|
|
1564
1588
|
*/
|
|
1565
|
-
declare function createServiceFactory<TService, TImpl extends TService, TDeps extends {
|
|
1589
|
+
declare function createServiceFactory<TService, TInstances extends 'singleton' | 'multiton', TImpl extends TService, TDeps extends {
|
|
1566
1590
|
[name in string]: ServiceRef<unknown, 'root'>;
|
|
1567
|
-
}, TOpts extends object | undefined = undefined>(options: (options?: TOpts) => RootServiceFactoryOptions<TService, TImpl, TDeps>): ServiceFactoryCompat<TService, 'root', TOpts>;
|
|
1591
|
+
}, TOpts extends object | undefined = undefined>(options: (options?: TOpts) => RootServiceFactoryOptions<TService, TInstances, TImpl, TDeps>): ServiceFactoryCompat<TService, 'root', TInstances, TOpts>;
|
|
1568
1592
|
/**
|
|
1569
1593
|
* Creates a plugin scoped service factory without options.
|
|
1570
1594
|
*
|
|
1571
1595
|
* @public
|
|
1572
1596
|
* @param options - The service factory configuration.
|
|
1573
1597
|
*/
|
|
1574
|
-
declare function createServiceFactory<TService, TImpl extends TService, TDeps extends {
|
|
1598
|
+
declare function createServiceFactory<TService, TInstances extends 'singleton' | 'multiton', TImpl extends TService, TDeps extends {
|
|
1575
1599
|
[name in string]: ServiceRef<unknown>;
|
|
1576
|
-
}, TContext = undefined, TOpts extends object | undefined = undefined>(options: PluginServiceFactoryOptions<TService, TContext, TImpl, TDeps>): ServiceFactoryCompat<TService, 'plugin'>;
|
|
1600
|
+
}, TContext = undefined, TOpts extends object | undefined = undefined>(options: PluginServiceFactoryOptions<TService, TInstances, TContext, TImpl, TDeps>): ServiceFactoryCompat<TService, 'plugin', TInstances>;
|
|
1577
1601
|
/**
|
|
1578
1602
|
* Creates a plugin scoped service factory with optional options.
|
|
1579
1603
|
*
|
|
@@ -1584,9 +1608,9 @@ declare function createServiceFactory<TService, TImpl extends TService, TDeps ex
|
|
|
1584
1608
|
* @public
|
|
1585
1609
|
* @param options - The service factory configuration.
|
|
1586
1610
|
*/
|
|
1587
|
-
declare function createServiceFactory<TService, TImpl extends TService, TDeps extends {
|
|
1611
|
+
declare function createServiceFactory<TService, TInstances extends 'singleton' | 'multiton', TImpl extends TService, TDeps extends {
|
|
1588
1612
|
[name in string]: ServiceRef<unknown>;
|
|
1589
|
-
}, TContext = undefined, TOpts extends object | undefined = undefined>(options: (options?: TOpts) => PluginServiceFactoryOptions<TService, TContext, TImpl, TDeps>): ServiceFactoryCompat<TService, 'plugin', TOpts>;
|
|
1613
|
+
}, TContext = undefined, TOpts extends object | undefined = undefined>(options: (options?: TOpts) => PluginServiceFactoryOptions<TService, TInstances, TContext, TImpl, TDeps>): ServiceFactoryCompat<TService, 'plugin', TInstances, TOpts>;
|
|
1590
1614
|
|
|
1591
1615
|
/**
|
|
1592
1616
|
* All core services references
|
|
@@ -1603,7 +1627,7 @@ declare namespace coreServices {
|
|
|
1603
1627
|
*
|
|
1604
1628
|
* @public
|
|
1605
1629
|
*/
|
|
1606
|
-
const auth: ServiceRef<AuthService, "plugin">;
|
|
1630
|
+
const auth: ServiceRef<AuthService, "plugin", "singleton">;
|
|
1607
1631
|
/**
|
|
1608
1632
|
* Authenticated user information retrieval.
|
|
1609
1633
|
*
|
|
@@ -1613,7 +1637,7 @@ declare namespace coreServices {
|
|
|
1613
1637
|
*
|
|
1614
1638
|
* @public
|
|
1615
1639
|
*/
|
|
1616
|
-
const userInfo: ServiceRef<UserInfoService, "plugin">;
|
|
1640
|
+
const userInfo: ServiceRef<UserInfoService, "plugin", "singleton">;
|
|
1617
1641
|
/**
|
|
1618
1642
|
* Key-value store for caching data.
|
|
1619
1643
|
*
|
|
@@ -1623,7 +1647,7 @@ declare namespace coreServices {
|
|
|
1623
1647
|
*
|
|
1624
1648
|
* @public
|
|
1625
1649
|
*/
|
|
1626
|
-
const cache: ServiceRef<CacheService, "plugin">;
|
|
1650
|
+
const cache: ServiceRef<CacheService, "plugin", "singleton">;
|
|
1627
1651
|
/**
|
|
1628
1652
|
* Access to static configuration.
|
|
1629
1653
|
*
|
|
@@ -1633,7 +1657,7 @@ declare namespace coreServices {
|
|
|
1633
1657
|
*
|
|
1634
1658
|
* @public
|
|
1635
1659
|
*/
|
|
1636
|
-
const rootConfig: ServiceRef<RootConfigService, "root">;
|
|
1660
|
+
const rootConfig: ServiceRef<RootConfigService, "root", "singleton">;
|
|
1637
1661
|
/**
|
|
1638
1662
|
* Database access and management via `knex`.
|
|
1639
1663
|
*
|
|
@@ -1643,7 +1667,7 @@ declare namespace coreServices {
|
|
|
1643
1667
|
*
|
|
1644
1668
|
* @public
|
|
1645
1669
|
*/
|
|
1646
|
-
const database: ServiceRef<DatabaseService, "plugin">;
|
|
1670
|
+
const database: ServiceRef<DatabaseService, "plugin", "singleton">;
|
|
1647
1671
|
/**
|
|
1648
1672
|
* Service discovery for inter-plugin communication.
|
|
1649
1673
|
*
|
|
@@ -1653,11 +1677,11 @@ declare namespace coreServices {
|
|
|
1653
1677
|
*
|
|
1654
1678
|
* @public
|
|
1655
1679
|
*/
|
|
1656
|
-
const discovery: ServiceRef<DiscoveryService, "plugin">;
|
|
1680
|
+
const discovery: ServiceRef<DiscoveryService, "plugin", "singleton">;
|
|
1657
1681
|
/**
|
|
1658
1682
|
* The service reference for the plugin scoped {@link RootHealthService}.
|
|
1659
1683
|
*/
|
|
1660
|
-
const rootHealth: ServiceRef<RootHealthService, "root">;
|
|
1684
|
+
const rootHealth: ServiceRef<RootHealthService, "root", "singleton">;
|
|
1661
1685
|
/**
|
|
1662
1686
|
* Authentication of HTTP requests.
|
|
1663
1687
|
*
|
|
@@ -1667,7 +1691,7 @@ declare namespace coreServices {
|
|
|
1667
1691
|
*
|
|
1668
1692
|
* @public
|
|
1669
1693
|
*/
|
|
1670
|
-
const httpAuth: ServiceRef<HttpAuthService, "plugin">;
|
|
1694
|
+
const httpAuth: ServiceRef<HttpAuthService, "plugin", "singleton">;
|
|
1671
1695
|
/**
|
|
1672
1696
|
* HTTP route registration for plugins.
|
|
1673
1697
|
*
|
|
@@ -1677,7 +1701,7 @@ declare namespace coreServices {
|
|
|
1677
1701
|
*
|
|
1678
1702
|
* @public
|
|
1679
1703
|
*/
|
|
1680
|
-
const httpRouter: ServiceRef<HttpRouterService, "plugin">;
|
|
1704
|
+
const httpRouter: ServiceRef<HttpRouterService, "plugin", "singleton">;
|
|
1681
1705
|
/**
|
|
1682
1706
|
* Registration of plugin startup and shutdown lifecycle hooks.
|
|
1683
1707
|
*
|
|
@@ -1687,7 +1711,7 @@ declare namespace coreServices {
|
|
|
1687
1711
|
*
|
|
1688
1712
|
* @public
|
|
1689
1713
|
*/
|
|
1690
|
-
const lifecycle: ServiceRef<LifecycleService, "plugin">;
|
|
1714
|
+
const lifecycle: ServiceRef<LifecycleService, "plugin", "singleton">;
|
|
1691
1715
|
/**
|
|
1692
1716
|
* Plugin-level logging.
|
|
1693
1717
|
*
|
|
@@ -1697,7 +1721,7 @@ declare namespace coreServices {
|
|
|
1697
1721
|
*
|
|
1698
1722
|
* @public
|
|
1699
1723
|
*/
|
|
1700
|
-
const logger: ServiceRef<LoggerService, "plugin">;
|
|
1724
|
+
const logger: ServiceRef<LoggerService, "plugin", "singleton">;
|
|
1701
1725
|
/**
|
|
1702
1726
|
* Permission system integration for authorization of user actions.
|
|
1703
1727
|
*
|
|
@@ -1707,7 +1731,7 @@ declare namespace coreServices {
|
|
|
1707
1731
|
*
|
|
1708
1732
|
* @public
|
|
1709
1733
|
*/
|
|
1710
|
-
const permissions: ServiceRef<PermissionsService, "plugin">;
|
|
1734
|
+
const permissions: ServiceRef<PermissionsService, "plugin", "singleton">;
|
|
1711
1735
|
/**
|
|
1712
1736
|
* Built-in service for accessing metadata about the current plugin.
|
|
1713
1737
|
*
|
|
@@ -1717,7 +1741,7 @@ declare namespace coreServices {
|
|
|
1717
1741
|
*
|
|
1718
1742
|
* @public
|
|
1719
1743
|
*/
|
|
1720
|
-
const pluginMetadata: ServiceRef<PluginMetadataService, "plugin">;
|
|
1744
|
+
const pluginMetadata: ServiceRef<PluginMetadataService, "plugin", "singleton">;
|
|
1721
1745
|
/**
|
|
1722
1746
|
* HTTP route registration for root services.
|
|
1723
1747
|
*
|
|
@@ -1727,7 +1751,7 @@ declare namespace coreServices {
|
|
|
1727
1751
|
*
|
|
1728
1752
|
* @public
|
|
1729
1753
|
*/
|
|
1730
|
-
const rootHttpRouter: ServiceRef<RootHttpRouterService, "root">;
|
|
1754
|
+
const rootHttpRouter: ServiceRef<RootHttpRouterService, "root", "singleton">;
|
|
1731
1755
|
/**
|
|
1732
1756
|
* Registration of backend startup and shutdown lifecycle hooks.
|
|
1733
1757
|
*
|
|
@@ -1737,7 +1761,7 @@ declare namespace coreServices {
|
|
|
1737
1761
|
*
|
|
1738
1762
|
* @public
|
|
1739
1763
|
*/
|
|
1740
|
-
const rootLifecycle: ServiceRef<RootLifecycleService, "root">;
|
|
1764
|
+
const rootLifecycle: ServiceRef<RootLifecycleService, "root", "singleton">;
|
|
1741
1765
|
/**
|
|
1742
1766
|
* Root-level logging.
|
|
1743
1767
|
*
|
|
@@ -1747,7 +1771,7 @@ declare namespace coreServices {
|
|
|
1747
1771
|
*
|
|
1748
1772
|
* @public
|
|
1749
1773
|
*/
|
|
1750
|
-
const rootLogger: ServiceRef<RootLoggerService, "root">;
|
|
1774
|
+
const rootLogger: ServiceRef<RootLoggerService, "root", "singleton">;
|
|
1751
1775
|
/**
|
|
1752
1776
|
* Scheduling of distributed background tasks.
|
|
1753
1777
|
*
|
|
@@ -1757,7 +1781,7 @@ declare namespace coreServices {
|
|
|
1757
1781
|
*
|
|
1758
1782
|
* @public
|
|
1759
1783
|
*/
|
|
1760
|
-
const scheduler: ServiceRef<SchedulerService, "plugin">;
|
|
1784
|
+
const scheduler: ServiceRef<SchedulerService, "plugin", "singleton">;
|
|
1761
1785
|
/**
|
|
1762
1786
|
* Deprecated service authentication service, use the `auth` service instead.
|
|
1763
1787
|
*
|
|
@@ -1768,7 +1792,7 @@ declare namespace coreServices {
|
|
|
1768
1792
|
* @public
|
|
1769
1793
|
* @deprecated Please migrate to the new `coreServices.auth`, `coreServices.httpAuth`, and `coreServices.userInfo` services as needed instead
|
|
1770
1794
|
*/
|
|
1771
|
-
const tokenManager: ServiceRef<TokenManagerService, "plugin">;
|
|
1795
|
+
const tokenManager: ServiceRef<TokenManagerService, "plugin", "singleton">;
|
|
1772
1796
|
/**
|
|
1773
1797
|
* Reading content from external systems.
|
|
1774
1798
|
*
|
|
@@ -1778,7 +1802,7 @@ declare namespace coreServices {
|
|
|
1778
1802
|
*
|
|
1779
1803
|
* @public
|
|
1780
1804
|
*/
|
|
1781
|
-
const urlReader: ServiceRef<UrlReaderService, "plugin">;
|
|
1805
|
+
const urlReader: ServiceRef<UrlReaderService, "plugin", "singleton">;
|
|
1782
1806
|
/**
|
|
1783
1807
|
* Deprecated user authentication service, use the `auth` service instead.
|
|
1784
1808
|
*
|
|
@@ -1789,7 +1813,7 @@ declare namespace coreServices {
|
|
|
1789
1813
|
* @public
|
|
1790
1814
|
* @deprecated Please migrate to the new `coreServices.auth`, `coreServices.httpAuth`, and `coreServices.userInfo` services as needed instead
|
|
1791
1815
|
*/
|
|
1792
|
-
const identity: ServiceRef<IdentityService, "plugin">;
|
|
1816
|
+
const identity: ServiceRef<IdentityService, "plugin", "singleton">;
|
|
1793
1817
|
}
|
|
1794
1818
|
|
|
1795
1819
|
/**
|
|
@@ -1874,27 +1898,34 @@ interface BackendModuleRegistrationPoints {
|
|
|
1874
1898
|
}
|
|
1875
1899
|
|
|
1876
1900
|
/**
|
|
1877
|
-
* The configuration options passed to {@link
|
|
1901
|
+
* The configuration options passed to {@link createBackendModule}.
|
|
1878
1902
|
*
|
|
1879
1903
|
* @public
|
|
1880
|
-
* @see {@link https://backstage.io/docs/backend-system/architecture/
|
|
1904
|
+
* @see {@link https://backstage.io/docs/backend-system/architecture/modules | The architecture of modules}
|
|
1881
1905
|
* @see {@link https://backstage.io/docs/backend-system/architecture/naming-patterns | Recommended naming patterns}
|
|
1882
1906
|
*/
|
|
1883
|
-
interface
|
|
1907
|
+
interface CreateBackendModuleOptions {
|
|
1884
1908
|
/**
|
|
1885
|
-
*
|
|
1909
|
+
* Should exactly match the `id` of the plugin that the module extends.
|
|
1886
1910
|
*
|
|
1887
1911
|
* @see {@link https://backstage.io/docs/backend-system/architecture/naming-patterns | Recommended naming patterns}
|
|
1888
1912
|
*/
|
|
1889
|
-
|
|
1913
|
+
pluginId: string;
|
|
1914
|
+
/**
|
|
1915
|
+
* The ID of this module, used to identify the module and ensure that it is not installed twice.
|
|
1916
|
+
*/
|
|
1917
|
+
moduleId: string;
|
|
1918
|
+
register(reg: BackendModuleRegistrationPoints): void;
|
|
1890
1919
|
}
|
|
1891
1920
|
/**
|
|
1892
|
-
* Creates a new backend
|
|
1921
|
+
* Creates a new backend module for a given plugin.
|
|
1893
1922
|
*
|
|
1894
1923
|
* @public
|
|
1895
|
-
* @see {@link https://backstage.io/docs/backend-system/architecture/
|
|
1924
|
+
* @see {@link https://backstage.io/docs/backend-system/architecture/modules | The architecture of modules}
|
|
1925
|
+
* @see {@link https://backstage.io/docs/backend-system/architecture/naming-patterns | Recommended naming patterns}
|
|
1896
1926
|
*/
|
|
1897
|
-
declare function
|
|
1927
|
+
declare function createBackendModule(options: CreateBackendModuleOptions): BackendFeatureCompat;
|
|
1928
|
+
|
|
1898
1929
|
/**
|
|
1899
1930
|
* The configuration options passed to {@link createBackendPlugin}.
|
|
1900
1931
|
*
|
|
@@ -1919,34 +1950,55 @@ interface CreateBackendPluginOptions {
|
|
|
1919
1950
|
* @see {@link https://backstage.io/docs/backend-system/architecture/naming-patterns | Recommended naming patterns}
|
|
1920
1951
|
*/
|
|
1921
1952
|
declare function createBackendPlugin(options: CreateBackendPluginOptions): BackendFeatureCompat;
|
|
1953
|
+
|
|
1922
1954
|
/**
|
|
1923
|
-
* The configuration options passed to {@link
|
|
1955
|
+
* The configuration options passed to {@link createExtensionPoint}.
|
|
1924
1956
|
*
|
|
1925
1957
|
* @public
|
|
1926
|
-
* @see {@link https://backstage.io/docs/backend-system/architecture/
|
|
1958
|
+
* @see {@link https://backstage.io/docs/backend-system/architecture/extension-points | The architecture of extension points}
|
|
1927
1959
|
* @see {@link https://backstage.io/docs/backend-system/architecture/naming-patterns | Recommended naming patterns}
|
|
1928
1960
|
*/
|
|
1929
|
-
interface
|
|
1961
|
+
interface CreateExtensionPointOptions {
|
|
1930
1962
|
/**
|
|
1931
|
-
*
|
|
1963
|
+
* The ID of this extension point.
|
|
1932
1964
|
*
|
|
1933
1965
|
* @see {@link https://backstage.io/docs/backend-system/architecture/naming-patterns | Recommended naming patterns}
|
|
1934
1966
|
*/
|
|
1935
|
-
|
|
1936
|
-
/**
|
|
1937
|
-
* The ID of this module, used to identify the module and ensure that it is not installed twice.
|
|
1938
|
-
*/
|
|
1939
|
-
moduleId: string;
|
|
1940
|
-
register(reg: BackendModuleRegistrationPoints): void;
|
|
1967
|
+
id: string;
|
|
1941
1968
|
}
|
|
1942
1969
|
/**
|
|
1943
|
-
* Creates a new backend
|
|
1970
|
+
* Creates a new backend extension point.
|
|
1944
1971
|
*
|
|
1945
1972
|
* @public
|
|
1946
|
-
* @see {@link https://backstage.io/docs/backend-system/architecture/
|
|
1947
|
-
* @see {@link https://backstage.io/docs/backend-system/architecture/naming-patterns | Recommended naming patterns}
|
|
1973
|
+
* @see {@link https://backstage.io/docs/backend-system/architecture/extension-points | The architecture of extension points}
|
|
1948
1974
|
*/
|
|
1949
|
-
declare function
|
|
1975
|
+
declare function createExtensionPoint<T>(options: CreateExtensionPointOptions): ExtensionPoint<T>;
|
|
1976
|
+
|
|
1977
|
+
/**
|
|
1978
|
+
* @public
|
|
1979
|
+
* Options for creating a new backend feature loader.
|
|
1980
|
+
*/
|
|
1981
|
+
interface CreateBackendFeatureLoaderOptions<TDeps extends {
|
|
1982
|
+
[name in string]: unknown;
|
|
1983
|
+
}> {
|
|
1984
|
+
deps?: {
|
|
1985
|
+
[name in keyof TDeps]: ServiceRef<TDeps[name], 'root'>;
|
|
1986
|
+
};
|
|
1987
|
+
loader(deps: TDeps): Iterable<BackendFeature | Promise<{
|
|
1988
|
+
default: BackendFeature;
|
|
1989
|
+
}>> | Promise<Iterable<BackendFeature | Promise<{
|
|
1990
|
+
default: BackendFeature;
|
|
1991
|
+
}>>> | AsyncIterable<BackendFeature | {
|
|
1992
|
+
default: BackendFeature;
|
|
1993
|
+
}>;
|
|
1994
|
+
}
|
|
1995
|
+
/**
|
|
1996
|
+
* @public
|
|
1997
|
+
* Creates a new backend feature loader.
|
|
1998
|
+
*/
|
|
1999
|
+
declare function createBackendFeatureLoader<TDeps extends {
|
|
2000
|
+
[name in string]: unknown;
|
|
2001
|
+
}>(options: CreateBackendFeatureLoaderOptions<TDeps>): BackendFeature;
|
|
1950
2002
|
|
|
1951
2003
|
/**
|
|
1952
2004
|
* @public
|
|
@@ -1968,20 +2020,20 @@ type ExtensionPointConfig = CreateExtensionPointOptions;
|
|
|
1968
2020
|
* @public
|
|
1969
2021
|
* @deprecated Use {@link ServiceRefOptions} instead
|
|
1970
2022
|
*/
|
|
1971
|
-
type ServiceRefConfig<TService, TScope extends 'root' | 'plugin'> = ServiceRefOptions<TService, TScope>;
|
|
2023
|
+
type ServiceRefConfig<TService, TScope extends 'root' | 'plugin', TInstances extends 'singleton' | 'multiton'> = ServiceRefOptions<TService, TScope, TInstances>;
|
|
1972
2024
|
/**
|
|
1973
2025
|
* @public
|
|
1974
2026
|
* @deprecated Use {@link RootServiceFactoryOptions} instead
|
|
1975
2027
|
*/
|
|
1976
|
-
type RootServiceFactoryConfig<TService, TImpl extends TService, TDeps extends {
|
|
2028
|
+
type RootServiceFactoryConfig<TService, TInstances extends 'singleton' | 'multiton', TImpl extends TService, TDeps extends {
|
|
1977
2029
|
[name in string]: ServiceRef<unknown>;
|
|
1978
|
-
}> = RootServiceFactoryOptions<TService, TImpl, TDeps>;
|
|
2030
|
+
}> = RootServiceFactoryOptions<TService, TInstances, TImpl, TDeps>;
|
|
1979
2031
|
/**
|
|
1980
2032
|
* @public
|
|
1981
2033
|
* @deprecated Use {@link PluginServiceFactoryOptions} instead
|
|
1982
2034
|
*/
|
|
1983
|
-
type PluginServiceFactoryConfig<TService, TContext, TImpl extends TService, TDeps extends {
|
|
2035
|
+
type PluginServiceFactoryConfig<TService, TInstances extends 'singleton' | 'multiton', TContext, TImpl extends TService, TDeps extends {
|
|
1984
2036
|
[name in string]: ServiceRef<unknown>;
|
|
1985
|
-
}> = PluginServiceFactoryOptions<TService, TContext, TImpl, TDeps>;
|
|
2037
|
+
}> = PluginServiceFactoryOptions<TService, TInstances, TContext, TImpl, TDeps>;
|
|
1986
2038
|
|
|
1987
|
-
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 CreateBackendModuleOptions, type CreateBackendPluginOptions, type CreateExtensionPointOptions, type DatabaseService, type DiscoveryService, type ExtensionPoint, type ExtensionPointConfig, type HttpAuthService, type HttpRouterService, type HttpRouterServiceAuthPolicy, type IdentityService, type LifecycleService, type LifecycleServiceShutdownHook, type LifecycleServiceShutdownOptions, type LifecycleServiceStartupHook, type LifecycleServiceStartupOptions, type LoggerService, type PermissionsService, type PermissionsServiceRequestOptions, type PluginMetadataService, type PluginServiceFactoryConfig, type PluginServiceFactoryOptions, type ReadTreeOptions, type ReadTreeResponse, type ReadTreeResponseDirOptions, type ReadTreeResponseFile, type ReadUrlOptions, type ReadUrlResponse, type RootConfigService, type RootHealthService, type RootHttpRouterService, type RootLifecycleService, type RootLoggerService, type RootServiceFactoryConfig, type RootServiceFactoryOptions, type SchedulerService, type SchedulerServiceTaskDescriptor, type SchedulerServiceTaskFunction, type SchedulerServiceTaskInvocationDefinition, type SchedulerServiceTaskRunner, type SchedulerServiceTaskScheduleDefinition, type SchedulerServiceTaskScheduleDefinitionConfig, type SearchOptions, type SearchResponse, type SearchResponseFile, type ServiceFactory, type ServiceFactoryCompat, type ServiceFactoryOrFunction, type ServiceRef, type ServiceRefConfig, 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, createBackendModule, createBackendPlugin, createExtensionPoint, createServiceFactory, createServiceRef, isDatabaseConflictError, readSchedulerServiceTaskScheduleDefinitionFromConfig, resolvePackagePath, resolveSafeChildPath };
|
|
2039
|
+
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 PluginServiceFactoryConfig, type PluginServiceFactoryOptions, type ReadTreeOptions, type ReadTreeResponse, type ReadTreeResponseDirOptions, type ReadTreeResponseFile, type ReadUrlOptions, type ReadUrlResponse, type RootConfigService, type RootHealthService, type RootHttpRouterService, type RootLifecycleService, type RootLoggerService, type RootServiceFactoryConfig, type RootServiceFactoryOptions, type SchedulerService, type SchedulerServiceTaskDescriptor, type SchedulerServiceTaskFunction, type SchedulerServiceTaskInvocationDefinition, type SchedulerServiceTaskRunner, type SchedulerServiceTaskScheduleDefinition, type SchedulerServiceTaskScheduleDefinitionConfig, type SearchOptions, type SearchResponse, type SearchResponseFile, type ServiceFactory, type ServiceFactoryCompat, type ServiceFactoryOrFunction, type ServiceRef, type ServiceRefConfig, 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 };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/backend-plugin-api",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0-next.2",
|
|
4
4
|
"description": "Core API used by Backstage backend plugins",
|
|
5
5
|
"backstage": {
|
|
6
6
|
"role": "node-library"
|
|
@@ -56,8 +56,8 @@
|
|
|
56
56
|
"@backstage/cli-common": "^0.1.14",
|
|
57
57
|
"@backstage/config": "^1.2.0",
|
|
58
58
|
"@backstage/errors": "^1.2.4",
|
|
59
|
-
"@backstage/plugin-auth-node": "^0.
|
|
60
|
-
"@backstage/plugin-permission-common": "^0.8.1-next.
|
|
59
|
+
"@backstage/plugin-auth-node": "^0.5.0-next.2",
|
|
60
|
+
"@backstage/plugin-permission-common": "^0.8.1-next.1",
|
|
61
61
|
"@backstage/types": "^1.1.1",
|
|
62
62
|
"@types/express": "^4.17.6",
|
|
63
63
|
"@types/luxon": "^3.0.0",
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
"luxon": "^3.0.0"
|
|
67
67
|
},
|
|
68
68
|
"devDependencies": {
|
|
69
|
-
"@backstage/backend-test-utils": "^0.4.5-next.
|
|
70
|
-
"@backstage/cli": "^0.27.0-next.
|
|
69
|
+
"@backstage/backend-test-utils": "^0.4.5-next.2",
|
|
70
|
+
"@backstage/cli": "^0.27.0-next.3"
|
|
71
71
|
}
|
|
72
72
|
}
|