@backstage/backend-plugin-api 1.9.0-next.1 → 1.9.0
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 +30 -0
- package/dist/index.d.ts +3 -3
- package/dist/services/system/types.cjs.js +1 -3
- package/dist/services/system/types.cjs.js.map +1 -1
- package/dist/services/utilities/database.cjs.js +3 -1
- package/dist/services/utilities/database.cjs.js.map +1 -1
- package/dist/wiring/createExtensionPoint.cjs.js +1 -6
- package/dist/wiring/createExtensionPoint.cjs.js.map +1 -1
- package/package.json +10 -10
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
# @backstage/backend-plugin-api
|
|
2
2
|
|
|
3
|
+
## 1.9.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 4559806: Added support for typed `examples` on actions registered via the actions registry. Action authors can now provide examples with compile-time-checked `input` and `output` values that match their schema definitions.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- 213ebe7: Aligned `.T` behavior between `ExtensionPoint` and `ServiceRef` to consistently return `null` instead of throwing.
|
|
12
|
+
- 68c557b: Added stricter type checks in `isDatabaseConflictError`.
|
|
13
|
+
- Updated dependencies
|
|
14
|
+
- @backstage/errors@1.3.0
|
|
15
|
+
- @backstage/plugin-auth-node@0.7.0
|
|
16
|
+
- @backstage/cli-common@0.2.1
|
|
17
|
+
- @backstage/plugin-permission-node@0.10.12
|
|
18
|
+
- @backstage/config@1.3.7
|
|
19
|
+
- @backstage/plugin-permission-common@0.9.8
|
|
20
|
+
|
|
21
|
+
## 1.9.0-next.2
|
|
22
|
+
|
|
23
|
+
### Patch Changes
|
|
24
|
+
|
|
25
|
+
- Updated dependencies
|
|
26
|
+
- @backstage/errors@1.3.0-next.0
|
|
27
|
+
- @backstage/plugin-auth-node@0.7.0-next.2
|
|
28
|
+
- @backstage/cli-common@0.2.1-next.1
|
|
29
|
+
- @backstage/config@1.3.7-next.0
|
|
30
|
+
- @backstage/plugin-permission-common@0.9.8-next.0
|
|
31
|
+
- @backstage/plugin-permission-node@0.10.12-next.2
|
|
32
|
+
|
|
3
33
|
## 1.9.0-next.1
|
|
4
34
|
|
|
5
35
|
### Minor Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -1764,7 +1764,7 @@ type ServiceRef<TService, TScope extends 'root' | 'plugin' = 'root' | 'plugin',
|
|
|
1764
1764
|
multiton?: TInstances extends 'multiton' ? true : false;
|
|
1765
1765
|
/**
|
|
1766
1766
|
* Utility for getting the type of the service, using `typeof serviceRef.T`.
|
|
1767
|
-
*
|
|
1767
|
+
* Reading this value will always return `null`. It is only intended for use with `typeof serviceRef.T`.
|
|
1768
1768
|
*/
|
|
1769
1769
|
T: TService;
|
|
1770
1770
|
$$type: '@backstage/ServiceRef';
|
|
@@ -1910,7 +1910,7 @@ type ExtensionPoint<T> = {
|
|
|
1910
1910
|
id: string;
|
|
1911
1911
|
/**
|
|
1912
1912
|
* Utility for getting the type of the extension point, using `typeof extensionPoint.T`.
|
|
1913
|
-
*
|
|
1913
|
+
* Reading this value will always return `null`. It is only intended for use with `typeof extensionPoint.T`.
|
|
1914
1914
|
*/
|
|
1915
1915
|
T: T;
|
|
1916
1916
|
toString(): string;
|
|
@@ -1935,7 +1935,7 @@ interface ExtensionPointFactoryContext {
|
|
|
1935
1935
|
type DepsToInstances<TDeps extends {
|
|
1936
1936
|
[key in string]: ServiceRef<unknown> | ExtensionPoint<unknown>;
|
|
1937
1937
|
}> = {
|
|
1938
|
-
[key in keyof TDeps]: TDeps[key] extends ServiceRef<unknown,
|
|
1938
|
+
[key in keyof TDeps]: TDeps[key] extends ServiceRef<unknown, 'root' | 'plugin', 'multiton'> ? Array<TDeps[key]['T']> : TDeps[key]['T'];
|
|
1939
1939
|
};
|
|
1940
1940
|
/**
|
|
1941
1941
|
* The callbacks passed to the `register` method of a backend plugin.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.cjs.js","sources":["../../../src/services/system/types.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 * A reference to a backend service. You can use these references to mark\n * dependencies on services and having their implementations injected\n * automatically.\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 /**\n * Marks whether the service is a multiton or not. Multiton services the\n * opposite of singletons - they can be provided many times, and when depended\n * on, you receive an array of all provided instances.\n */\n multiton?: TInstances extends 'multiton' ? true : false;\n\n /**\n * Utility for getting the type of the service, using `typeof serviceRef.T`.\n * Attempting to actually read this value will result in an exception.\n */\n T: TService;\n\n $$type: '@backstage/ServiceRef';\n};\n\n/** @public */\nexport interface ServiceFactory<\n TService = unknown,\n TScope extends 'plugin' | 'root' = 'plugin' | 'root',\n TInstances extends 'singleton' | 'multiton' = 'singleton' | 'multiton',\n> extends BackendFeature {\n service: ServiceRef<TService, TScope, TInstances>;\n}\n\n/** @internal */\nexport interface InternalServiceFactory<\n TService = unknown,\n TScope extends 'plugin' | 'root' = 'plugin' | 'root',\n TInstances extends 'singleton' | 'multiton' = 'singleton' | 'multiton',\n> extends ServiceFactory<TService, TScope, TInstances> {\n version: 'v1';\n featureType: 'service';\n initialization?: 'always' | 'lazy';\n deps: { [key in string]: ServiceRef<unknown> };\n createRootContext?(deps: { [key in string]: unknown }): Promise<unknown>;\n factory(\n deps: { [key in string]: unknown },\n context: unknown,\n ): Promise<TService>;\n}\n\n/** @public */\nexport interface ServiceRefOptions<\n TService,\n TScope extends 'root' | 'plugin',\n TInstances extends 'singleton' | 'multiton',\n> {\n id: string;\n scope?: TScope;\n multiton?: TInstances extends 'multiton' ? true : false;\n defaultFactory?(\n service: ServiceRef<TService, TScope>,\n ): Promise<ServiceFactory>;\n}\n\n/**\n * Creates a new service definition. This overload is used to create plugin scoped services.\n *\n * @public\n */\nexport function createServiceRef<TService>(\n options: ServiceRefOptions<TService, 'plugin', 'singleton'>,\n): ServiceRef<TService, 'plugin', 'singleton'>;\n\n/**\n * Creates a new service definition. This overload is used to create root scoped services.\n *\n * @public\n */\nexport function createServiceRef<TService>(\n options: ServiceRefOptions<TService, 'root', 'singleton'>,\n): ServiceRef<TService, 'root', 'singleton'>;\n\n/**\n * Creates a new service definition. This overload is used to create plugin scoped services.\n *\n * @public\n */\nexport function createServiceRef<TService>(\n options: ServiceRefOptions<TService, 'plugin', 'multiton'>,\n): ServiceRef<TService, 'plugin', 'multiton'>;\n\n/**\n * Creates a new service definition. This overload is used to create root scoped services.\n *\n * @public\n */\nexport function createServiceRef<TService>(\n options: ServiceRefOptions<TService, 'root', 'multiton'>,\n): ServiceRef<TService, 'root', 'multiton'>;\nexport function createServiceRef<\n TService,\n TInstances extends 'singleton' | 'multiton',\n>(\n options: ServiceRefOptions<TService, any, TInstances>,\n): ServiceRef<TService, any, TInstances> {\n const { id, scope = 'plugin', multiton = false, defaultFactory } = options;\n return {\n id,\n scope,\n multiton,\n get T(): TService {\n throw new Error(`tried to read ServiceRef.T of ${this}`);\n },\n toString() {\n return `serviceRef{${options.id}}`;\n },\n toJSON() {\n // This avoids accidental calls to T happening e.g. in tests\n return {\n $$type: '@backstage/ServiceRef',\n id,\n scope,\n multiton,\n };\n },\n $$type: '@backstage/ServiceRef',\n __defaultFactory: defaultFactory,\n } as ServiceRef<TService, typeof scope, TInstances> & {\n __defaultFactory?: (\n service: ServiceRef<TService>,\n ) => Promise<ServiceFactory<TService>>;\n };\n}\n\n/** @ignore */\ntype ServiceRefsToInstances<\n T extends { [key in string]: ServiceRef<unknown> },\n TScope extends 'root' | 'plugin' = 'root' | 'plugin',\n> = {\n [key in keyof T as T[key]['scope'] extends TScope\n ? key\n : never]: T[key]['multiton'] extends true | undefined\n ? Array<T[key]['T']>\n : T[key]['T'];\n};\n\n/** @public */\nexport interface RootServiceFactoryOptions<\n TService,\n TInstances extends 'singleton' | 'multiton',\n TImpl extends TService,\n TDeps extends { [name in string]: ServiceRef<unknown> },\n> {\n /**\n * The initialization strategy for the service factory. This service is root scoped and will use `always` by default.\n *\n * @remarks\n *\n * - `always` - The service will always be initialized regardless if it is used or not.\n * - `lazy` - The service will only be initialized if it is depended on by a different service or feature.\n *\n * Service factories for root scoped services use `always` as the default, while plugin scoped services use `lazy`.\n */\n initialization?: 'always' | 'lazy';\n service: ServiceRef<TService, 'root', TInstances>;\n deps: TDeps;\n factory(deps: ServiceRefsToInstances<TDeps, 'root'>): TImpl | Promise<TImpl>;\n}\n\n/** @public */\nexport interface PluginServiceFactoryOptions<\n TService,\n TInstances extends 'singleton' | 'multiton',\n TContext,\n TImpl extends TService,\n TDeps extends { [name in string]: ServiceRef<unknown> },\n> {\n /**\n * The initialization strategy for the service factory. This service is plugin scoped and will use `lazy` by default.\n *\n * @remarks\n *\n * - `always` - The service will always be initialized regardless if it is used or not.\n * - `lazy` - The service will only be initialized if it is depended on by a different service or feature.\n *\n * Service factories for root scoped services use `always` as the default, while plugin scoped services use `lazy`.\n */\n initialization?: 'always' | 'lazy';\n service: ServiceRef<TService, 'plugin', TInstances>;\n deps: TDeps;\n createRootContext?(\n deps: ServiceRefsToInstances<TDeps, 'root'>,\n ): TContext | Promise<TContext>;\n factory(\n deps: ServiceRefsToInstances<TDeps>,\n context: TContext,\n ): TImpl | Promise<TImpl>;\n}\n\n/**\n * Creates a root scoped service factory without options.\n *\n * @public\n * @param options - The service factory configuration.\n */\nexport function createServiceFactory<\n TService,\n TInstances extends 'singleton' | 'multiton',\n TImpl extends TService,\n TDeps extends { [name in string]: ServiceRef<unknown, 'root'> },\n>(\n options: RootServiceFactoryOptions<TService, TInstances, TImpl, TDeps>,\n): ServiceFactory<TService, 'root', TInstances>;\n/**\n * Creates a plugin scoped service factory without options.\n *\n * @public\n * @param options - The service factory configuration.\n */\nexport function createServiceFactory<\n TService,\n TInstances extends 'singleton' | 'multiton',\n TImpl extends TService,\n TDeps extends { [name in string]: ServiceRef<unknown> },\n TContext = undefined,\n>(\n options: PluginServiceFactoryOptions<\n TService,\n TInstances,\n TContext,\n TImpl,\n TDeps\n >,\n): ServiceFactory<TService, 'plugin', TInstances>;\nexport function createServiceFactory<\n TService,\n TInstances extends 'singleton' | 'multiton',\n TImpl extends TService,\n TDeps extends { [name in string]: ServiceRef<unknown> },\n TContext,\n>(\n options:\n | RootServiceFactoryOptions<TService, TInstances, TImpl, TDeps>\n | PluginServiceFactoryOptions<TService, TInstances, TContext, TImpl, TDeps>,\n): ServiceFactory<TService, 'root' | 'plugin', 'singleton' | 'multiton'> {\n if (options.service.scope === 'root') {\n const c = options as RootServiceFactoryOptions<\n TService,\n TInstances,\n TImpl,\n TDeps\n >;\n return {\n $$type: '@backstage/BackendFeature',\n version: 'v1',\n featureType: 'service',\n service: c.service,\n initialization: c.initialization,\n deps: options.deps,\n factory: async (deps: ServiceRefsToInstances<TDeps, 'root'>) =>\n c.factory(deps),\n } as InternalServiceFactory<TService, 'root', TInstances>;\n }\n const c = options as PluginServiceFactoryOptions<\n TService,\n TInstances,\n TContext,\n TImpl,\n TDeps\n >;\n return {\n $$type: '@backstage/BackendFeature',\n version: 'v1',\n featureType: 'service',\n service: c.service,\n initialization: c.initialization,\n ...('createRootContext' in options\n ? {\n createRootContext: async (\n deps: ServiceRefsToInstances<TDeps, 'root'>,\n ) => c?.createRootContext?.(deps),\n }\n : {}),\n deps: options.deps,\n factory: async (deps: ServiceRefsToInstances<TDeps>, ctx: TContext) =>\n c.factory(deps, ctx),\n } as InternalServiceFactory<TService, 'plugin', TInstances>;\n}\n"],"names":["c"],"mappings":";;AAsIO,SAAS,iBAId,OAAA,EACuC;AACvC,EAAA,MAAM,EAAE,EAAA,EAAI,KAAA,GAAQ,UAAU,QAAA,GAAW,KAAA,EAAO,gBAAe,GAAI,OAAA;AACnE,EAAA,OAAO;AAAA,IACL,EAAA;AAAA,IACA,KAAA;AAAA,IACA,QAAA;AAAA,IACA,IAAI,CAAA,GAAc;AAChB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,8BAAA,EAAiC,IAAI,CAAA,CAAE,CAAA;AAAA,IACzD,CAAA;AAAA,IACA,QAAA,GAAW;AACT,MAAA,OAAO,CAAA,WAAA,EAAc,QAAQ,EAAE,CAAA,CAAA,CAAA;AAAA,IACjC,CAAA;AAAA,IACA,MAAA,GAAS;AAEP,MAAA,OAAO;AAAA,QACL,MAAA,EAAQ,uBAAA;AAAA,QACR,EAAA;AAAA,QACA,KAAA;AAAA,QACA;AAAA,OACF;AAAA,IACF,CAAA;AAAA,IACA,MAAA,EAAQ,uBAAA;AAAA,IACR,gBAAA,EAAkB;AAAA,GACpB;AAKF;AAsGO,SAAS,qBAOd,OAAA,EAGuE;AACvE,EAAA,IAAI,OAAA,CAAQ,OAAA,CAAQ,KAAA,KAAU,MAAA,EAAQ;AACpC,IAAA,MAAMA,EAAAA,GAAI,OAAA;AAMV,IAAA,OAAO;AAAA,MACL,MAAA,EAAQ,2BAAA;AAAA,MACR,OAAA,EAAS,IAAA;AAAA,MACT,WAAA,EAAa,SAAA;AAAA,MACb,SAASA,EAAAA,CAAE,OAAA;AAAA,MACX,gBAAgBA,EAAAA,CAAE,cAAA;AAAA,MAClB,MAAM,OAAA,CAAQ,IAAA;AAAA,MACd,OAAA,EAAS,OAAO,IAAA,KACdA,EAAAA,CAAE,QAAQ,IAAI;AAAA,KAClB;AAAA,EACF;AACA,EAAA,MAAM,CAAA,GAAI,OAAA;AAOV,EAAA,OAAO;AAAA,IACL,MAAA,EAAQ,2BAAA;AAAA,IACR,OAAA,EAAS,IAAA;AAAA,IACT,WAAA,EAAa,SAAA;AAAA,IACb,SAAS,CAAA,CAAE,OAAA;AAAA,IACX,gBAAgB,CAAA,CAAE,cAAA;AAAA,IAClB,GAAI,uBAAuB,OAAA,GACvB;AAAA,MACE,iBAAA,EAAmB,OACjB,IAAA,KACG,CAAA,EAAG,oBAAoB,IAAI;AAAA,QAElC,EAAC;AAAA,IACL,MAAM,OAAA,CAAQ,IAAA;AAAA,IACd,SAAS,OAAO,IAAA,EAAqC,QACnD,CAAA,CAAE,OAAA,CAAQ,MAAM,GAAG;AAAA,GACvB;AACF;;;;;"}
|
|
1
|
+
{"version":3,"file":"types.cjs.js","sources":["../../../src/services/system/types.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 * A reference to a backend service. You can use these references to mark\n * dependencies on services and having their implementations injected\n * automatically.\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 /**\n * Marks whether the service is a multiton or not. Multiton services the\n * opposite of singletons - they can be provided many times, and when depended\n * on, you receive an array of all provided instances.\n */\n multiton?: TInstances extends 'multiton' ? true : false;\n\n /**\n * Utility for getting the type of the service, using `typeof serviceRef.T`.\n * Reading this value will always return `null`. It is only intended for use with `typeof serviceRef.T`.\n */\n T: TService;\n\n $$type: '@backstage/ServiceRef';\n};\n\n/** @public */\nexport interface ServiceFactory<\n TService = unknown,\n TScope extends 'plugin' | 'root' = 'plugin' | 'root',\n TInstances extends 'singleton' | 'multiton' = 'singleton' | 'multiton',\n> extends BackendFeature {\n service: ServiceRef<TService, TScope, TInstances>;\n}\n\n/** @internal */\nexport interface InternalServiceFactory<\n TService = unknown,\n TScope extends 'plugin' | 'root' = 'plugin' | 'root',\n TInstances extends 'singleton' | 'multiton' = 'singleton' | 'multiton',\n> extends ServiceFactory<TService, TScope, TInstances> {\n version: 'v1';\n featureType: 'service';\n initialization?: 'always' | 'lazy';\n deps: { [key in string]: ServiceRef<unknown> };\n createRootContext?(deps: { [key in string]: unknown }): Promise<unknown>;\n factory(\n deps: { [key in string]: unknown },\n context: unknown,\n ): Promise<TService>;\n}\n\n/** @public */\nexport interface ServiceRefOptions<\n TService,\n TScope extends 'root' | 'plugin',\n TInstances extends 'singleton' | 'multiton',\n> {\n id: string;\n scope?: TScope;\n multiton?: TInstances extends 'multiton' ? true : false;\n defaultFactory?(\n service: ServiceRef<TService, TScope>,\n ): Promise<ServiceFactory>;\n}\n\n/**\n * Creates a new service definition. This overload is used to create plugin scoped services.\n *\n * @public\n */\nexport function createServiceRef<TService>(\n options: ServiceRefOptions<TService, 'plugin', 'singleton'>,\n): ServiceRef<TService, 'plugin', 'singleton'>;\n\n/**\n * Creates a new service definition. This overload is used to create root scoped services.\n *\n * @public\n */\nexport function createServiceRef<TService>(\n options: ServiceRefOptions<TService, 'root', 'singleton'>,\n): ServiceRef<TService, 'root', 'singleton'>;\n\n/**\n * Creates a new service definition. This overload is used to create plugin scoped services.\n *\n * @public\n */\nexport function createServiceRef<TService>(\n options: ServiceRefOptions<TService, 'plugin', 'multiton'>,\n): ServiceRef<TService, 'plugin', 'multiton'>;\n\n/**\n * Creates a new service definition. This overload is used to create root scoped services.\n *\n * @public\n */\nexport function createServiceRef<TService>(\n options: ServiceRefOptions<TService, 'root', 'multiton'>,\n): ServiceRef<TService, 'root', 'multiton'>;\nexport function createServiceRef<\n TService,\n TInstances extends 'singleton' | 'multiton',\n>(\n options: ServiceRefOptions<TService, 'root' | 'plugin', TInstances>,\n): ServiceRef<TService, 'root' | 'plugin', TInstances> {\n const { id, scope = 'plugin', multiton = false, defaultFactory } = options;\n return {\n id,\n scope,\n multiton,\n T: null as TService,\n toString() {\n return `serviceRef{${options.id}}`;\n },\n toJSON() {\n return {\n $$type: '@backstage/ServiceRef',\n id,\n scope,\n multiton,\n };\n },\n $$type: '@backstage/ServiceRef',\n __defaultFactory: defaultFactory,\n } as ServiceRef<TService, typeof scope, TInstances> & {\n __defaultFactory?: (\n service: ServiceRef<TService>,\n ) => Promise<ServiceFactory<TService>>;\n };\n}\n\n/** @ignore */\ntype ServiceRefsToInstances<\n T extends { [key in string]: ServiceRef<unknown> },\n TScope extends 'root' | 'plugin' = 'root' | 'plugin',\n> = {\n [key in keyof T as T[key]['scope'] extends TScope\n ? key\n : never]: T[key]['multiton'] extends true | undefined\n ? Array<T[key]['T']>\n : T[key]['T'];\n};\n\n/** @public */\nexport interface RootServiceFactoryOptions<\n TService,\n TInstances extends 'singleton' | 'multiton',\n TImpl extends TService,\n TDeps extends { [name in string]: ServiceRef<unknown> },\n> {\n /**\n * The initialization strategy for the service factory. This service is root scoped and will use `always` by default.\n *\n * @remarks\n *\n * - `always` - The service will always be initialized regardless if it is used or not.\n * - `lazy` - The service will only be initialized if it is depended on by a different service or feature.\n *\n * Service factories for root scoped services use `always` as the default, while plugin scoped services use `lazy`.\n */\n initialization?: 'always' | 'lazy';\n service: ServiceRef<TService, 'root', TInstances>;\n deps: TDeps;\n factory(deps: ServiceRefsToInstances<TDeps, 'root'>): TImpl | Promise<TImpl>;\n}\n\n/** @public */\nexport interface PluginServiceFactoryOptions<\n TService,\n TInstances extends 'singleton' | 'multiton',\n TContext,\n TImpl extends TService,\n TDeps extends { [name in string]: ServiceRef<unknown> },\n> {\n /**\n * The initialization strategy for the service factory. This service is plugin scoped and will use `lazy` by default.\n *\n * @remarks\n *\n * - `always` - The service will always be initialized regardless if it is used or not.\n * - `lazy` - The service will only be initialized if it is depended on by a different service or feature.\n *\n * Service factories for root scoped services use `always` as the default, while plugin scoped services use `lazy`.\n */\n initialization?: 'always' | 'lazy';\n service: ServiceRef<TService, 'plugin', TInstances>;\n deps: TDeps;\n createRootContext?(\n deps: ServiceRefsToInstances<TDeps, 'root'>,\n ): TContext | Promise<TContext>;\n factory(\n deps: ServiceRefsToInstances<TDeps>,\n context: TContext,\n ): TImpl | Promise<TImpl>;\n}\n\n/**\n * Creates a root scoped service factory without options.\n *\n * @public\n * @param options - The service factory configuration.\n */\nexport function createServiceFactory<\n TService,\n TInstances extends 'singleton' | 'multiton',\n TImpl extends TService,\n TDeps extends { [name in string]: ServiceRef<unknown, 'root'> },\n>(\n options: RootServiceFactoryOptions<TService, TInstances, TImpl, TDeps>,\n): ServiceFactory<TService, 'root', TInstances>;\n/**\n * Creates a plugin scoped service factory without options.\n *\n * @public\n * @param options - The service factory configuration.\n */\nexport function createServiceFactory<\n TService,\n TInstances extends 'singleton' | 'multiton',\n TImpl extends TService,\n TDeps extends { [name in string]: ServiceRef<unknown> },\n TContext = undefined,\n>(\n options: PluginServiceFactoryOptions<\n TService,\n TInstances,\n TContext,\n TImpl,\n TDeps\n >,\n): ServiceFactory<TService, 'plugin', TInstances>;\nexport function createServiceFactory<\n TService,\n TInstances extends 'singleton' | 'multiton',\n TImpl extends TService,\n TDeps extends { [name in string]: ServiceRef<unknown> },\n TContext,\n>(\n options:\n | RootServiceFactoryOptions<TService, TInstances, TImpl, TDeps>\n | PluginServiceFactoryOptions<TService, TInstances, TContext, TImpl, TDeps>,\n): ServiceFactory<TService, 'root' | 'plugin', 'singleton' | 'multiton'> {\n if (options.service.scope === 'root') {\n const c = options as RootServiceFactoryOptions<\n TService,\n TInstances,\n TImpl,\n TDeps\n >;\n return {\n $$type: '@backstage/BackendFeature',\n version: 'v1',\n featureType: 'service',\n service: c.service,\n initialization: c.initialization,\n deps: options.deps,\n factory: async (deps: ServiceRefsToInstances<TDeps, 'root'>) =>\n c.factory(deps),\n } as InternalServiceFactory<TService, 'root', TInstances>;\n }\n const c = options as PluginServiceFactoryOptions<\n TService,\n TInstances,\n TContext,\n TImpl,\n TDeps\n >;\n return {\n $$type: '@backstage/BackendFeature',\n version: 'v1',\n featureType: 'service',\n service: c.service,\n initialization: c.initialization,\n ...('createRootContext' in options\n ? {\n createRootContext: async (\n deps: ServiceRefsToInstances<TDeps, 'root'>,\n ) => c?.createRootContext?.(deps),\n }\n : {}),\n deps: options.deps,\n factory: async (deps: ServiceRefsToInstances<TDeps>, ctx: TContext) =>\n c.factory(deps, ctx),\n } as InternalServiceFactory<TService, 'plugin', TInstances>;\n}\n"],"names":["c"],"mappings":";;AAsIO,SAAS,iBAId,OAAA,EACqD;AACrD,EAAA,MAAM,EAAE,EAAA,EAAI,KAAA,GAAQ,UAAU,QAAA,GAAW,KAAA,EAAO,gBAAe,GAAI,OAAA;AACnE,EAAA,OAAO;AAAA,IACL,EAAA;AAAA,IACA,KAAA;AAAA,IACA,QAAA;AAAA,IACA,CAAA,EAAG,IAAA;AAAA,IACH,QAAA,GAAW;AACT,MAAA,OAAO,CAAA,WAAA,EAAc,QAAQ,EAAE,CAAA,CAAA,CAAA;AAAA,IACjC,CAAA;AAAA,IACA,MAAA,GAAS;AACP,MAAA,OAAO;AAAA,QACL,MAAA,EAAQ,uBAAA;AAAA,QACR,EAAA;AAAA,QACA,KAAA;AAAA,QACA;AAAA,OACF;AAAA,IACF,CAAA;AAAA,IACA,MAAA,EAAQ,uBAAA;AAAA,IACR,gBAAA,EAAkB;AAAA,GACpB;AAKF;AAsGO,SAAS,qBAOd,OAAA,EAGuE;AACvE,EAAA,IAAI,OAAA,CAAQ,OAAA,CAAQ,KAAA,KAAU,MAAA,EAAQ;AACpC,IAAA,MAAMA,EAAAA,GAAI,OAAA;AAMV,IAAA,OAAO;AAAA,MACL,MAAA,EAAQ,2BAAA;AAAA,MACR,OAAA,EAAS,IAAA;AAAA,MACT,WAAA,EAAa,SAAA;AAAA,MACb,SAASA,EAAAA,CAAE,OAAA;AAAA,MACX,gBAAgBA,EAAAA,CAAE,cAAA;AAAA,MAClB,MAAM,OAAA,CAAQ,IAAA;AAAA,MACd,OAAA,EAAS,OAAO,IAAA,KACdA,EAAAA,CAAE,QAAQ,IAAI;AAAA,KAClB;AAAA,EACF;AACA,EAAA,MAAM,CAAA,GAAI,OAAA;AAOV,EAAA,OAAO;AAAA,IACL,MAAA,EAAQ,2BAAA;AAAA,IACR,OAAA,EAAS,IAAA;AAAA,IACT,WAAA,EAAa,SAAA;AAAA,IACb,SAAS,CAAA,CAAE,OAAA;AAAA,IACX,gBAAgB,CAAA,CAAE,cAAA;AAAA,IAClB,GAAI,uBAAuB,OAAA,GACvB;AAAA,MACE,iBAAA,EAAmB,OACjB,IAAA,KACG,CAAA,EAAG,oBAAoB,IAAI;AAAA,QAElC,EAAC;AAAA,IACL,MAAM,OAAA,CAAQ,IAAA;AAAA,IACd,SAAS,OAAO,IAAA,EAAqC,QACnD,CAAA,CAAE,OAAA,CAAQ,MAAM,GAAG;AAAA,GACvB;AACF;;;;;"}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var errors = require('@backstage/errors');
|
|
4
|
+
|
|
3
5
|
function isDatabaseConflictError(e) {
|
|
4
|
-
const message = e
|
|
6
|
+
const message = errors.isError(e) ? e.message : void 0;
|
|
5
7
|
return typeof message === "string" && (/SQLITE_CONSTRAINT(?:_UNIQUE)?: UNIQUE/.test(message) || /UNIQUE constraint failed:/.test(message) || /unique constraint/.test(message) || /Duplicate entry/.test(message));
|
|
6
8
|
}
|
|
7
9
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database.cjs.js","sources":["../../../src/services/utilities/database.ts"],"sourcesContent":["/*\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
|
|
1
|
+
{"version":3,"file":"database.cjs.js","sources":["../../../src/services/utilities/database.ts"],"sourcesContent":["/*\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 { isError } from '@backstage/errors';\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 = isError(e) ? e.message : undefined;\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"],"names":["isError"],"mappings":";;;;AA0BO,SAAS,wBAAwB,CAAA,EAAY;AAClD,EAAA,MAAM,OAAA,GAAUA,cAAA,CAAQ,CAAC,CAAA,GAAI,EAAE,OAAA,GAAU,MAAA;AAEzC,EAAA,OACE,OAAO,OAAA,KAAY,QAAA,KAClB,uCAAA,CAAwC,IAAA,CAAK,OAAO,CAAA,IACnD,2BAAA,CAA4B,IAAA,CAAK,OAAO,KACxC,mBAAA,CAAoB,IAAA,CAAK,OAAO,CAAA,IAChC,iBAAA,CAAkB,KAAK,OAAO,CAAA,CAAA;AAEpC;;;;"}
|
|
@@ -3,12 +3,7 @@
|
|
|
3
3
|
function createExtensionPoint(options) {
|
|
4
4
|
return {
|
|
5
5
|
id: options.id,
|
|
6
|
-
|
|
7
|
-
if (process.env.NODE_ENV === "test") {
|
|
8
|
-
return null;
|
|
9
|
-
}
|
|
10
|
-
throw new Error(`tried to read ExtensionPoint.T of ${this}`);
|
|
11
|
-
},
|
|
6
|
+
T: null,
|
|
12
7
|
toString() {
|
|
13
8
|
return `extensionPoint{${options.id}}`;
|
|
14
9
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createExtensionPoint.cjs.js","sources":["../../src/wiring/createExtensionPoint.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 { 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
|
|
1
|
+
{"version":3,"file":"createExtensionPoint.cjs.js","sources":["../../src/wiring/createExtensionPoint.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 { 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 T: null as T,\n toString() {\n return `extensionPoint{${options.id}}`;\n },\n $$type: '@backstage/ExtensionPoint',\n };\n}\n"],"names":[],"mappings":";;AAwCO,SAAS,qBACd,OAAA,EACmB;AACnB,EAAA,OAAO;AAAA,IACL,IAAI,OAAA,CAAQ,EAAA;AAAA,IACZ,CAAA,EAAG,IAAA;AAAA,IACH,QAAA,GAAW;AACT,MAAA,OAAO,CAAA,eAAA,EAAkB,QAAQ,EAAE,CAAA,CAAA,CAAA;AAAA,IACrC,CAAA;AAAA,IACA,MAAA,EAAQ;AAAA,GACV;AACF;;;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/backend-plugin-api",
|
|
3
|
-
"version": "1.9.0
|
|
3
|
+
"version": "1.9.0",
|
|
4
4
|
"description": "Core API used by Backstage backend plugins",
|
|
5
5
|
"backstage": {
|
|
6
6
|
"role": "node-library"
|
|
@@ -65,13 +65,13 @@
|
|
|
65
65
|
"test": "backstage-cli package test"
|
|
66
66
|
},
|
|
67
67
|
"dependencies": {
|
|
68
|
-
"@backstage/cli-common": "0.2.1
|
|
69
|
-
"@backstage/config": "1.3.
|
|
70
|
-
"@backstage/errors": "1.
|
|
71
|
-
"@backstage/plugin-auth-node": "0.7.0
|
|
72
|
-
"@backstage/plugin-permission-common": "0.9.
|
|
73
|
-
"@backstage/plugin-permission-node": "0.10.12
|
|
74
|
-
"@backstage/types": "1.2.2",
|
|
68
|
+
"@backstage/cli-common": "^0.2.1",
|
|
69
|
+
"@backstage/config": "^1.3.7",
|
|
70
|
+
"@backstage/errors": "^1.3.0",
|
|
71
|
+
"@backstage/plugin-auth-node": "^0.7.0",
|
|
72
|
+
"@backstage/plugin-permission-common": "^0.9.8",
|
|
73
|
+
"@backstage/plugin-permission-node": "^0.10.12",
|
|
74
|
+
"@backstage/types": "^1.2.2",
|
|
75
75
|
"@types/express": "^4.17.6",
|
|
76
76
|
"@types/json-schema": "^7.0.6",
|
|
77
77
|
"@types/luxon": "^3.0.0",
|
|
@@ -81,8 +81,8 @@
|
|
|
81
81
|
"zod": "^3.25.76 || ^4.0.0"
|
|
82
82
|
},
|
|
83
83
|
"devDependencies": {
|
|
84
|
-
"@backstage/backend-test-utils": "1.11.2
|
|
85
|
-
"@backstage/cli": "0.36.1
|
|
84
|
+
"@backstage/backend-test-utils": "^1.11.2",
|
|
85
|
+
"@backstage/cli": "^0.36.1"
|
|
86
86
|
},
|
|
87
87
|
"configSchema": "config.d.ts"
|
|
88
88
|
}
|