@backstage/backend-app-api 1.7.4-next.1 → 1.7.5-next.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 +19 -0
- package/dist/backend-internal/src/wiring/OpaqueExtensionPointFactoryMiddleware.cjs.js.map +1 -1
- package/dist/backend-internal/src/wiring/helpers.cjs.js.map +1 -1
- package/dist/connections-node/src/DefaultConnectionsService.cjs.js +9 -17
- package/dist/connections-node/src/DefaultConnectionsService.cjs.js.map +1 -1
- package/dist/connections-node/src/lookup.cjs.js.map +1 -1
- package/dist/connections-node/src/lookupStrategies.cjs.js.map +1 -1
- package/dist/connections-node/src/service.cjs.js.map +1 -1
- package/dist/lib/DependencyGraph.cjs.js.map +1 -1
- package/dist/opaque-internal/src/OpaqueType.cjs.js.map +1 -1
- package/dist/wiring/BackendInitializer.cjs.js +1 -1
- package/dist/wiring/BackendInitializer.cjs.js.map +1 -1
- package/dist/wiring/BackendStartupError.cjs.js.map +1 -1
- package/dist/wiring/BackstageBackend.cjs.js.map +1 -1
- package/dist/wiring/ServiceRegistry.cjs.js.map +1 -1
- package/dist/wiring/createAllowBootFailurePredicate.cjs.js.map +1 -1
- package/dist/wiring/createInitializationResultCollector.cjs.js.map +1 -1
- package/dist/wiring/createSpecializedBackend.cjs.js.map +1 -1
- package/dist/wiring/helpers.cjs.js.map +1 -1
- package/dist/wiring/types.cjs.js.map +1 -1
- package/dist/wiring/validateBackendFeature.cjs.js.map +1 -1
- package/dist/wiring/withDeclaredConnections.cjs.js.map +1 -1
- package/package.json +8 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# @backstage/backend-app-api
|
|
2
2
|
|
|
3
|
+
## 1.7.5-next.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies
|
|
8
|
+
- @backstage/config@1.3.10-next.0
|
|
9
|
+
- @backstage/errors@1.3.2-next.0
|
|
10
|
+
- @backstage/connections@0.4.1-next.0
|
|
11
|
+
- @backstage/backend-plugin-api@1.10.2-next.0
|
|
12
|
+
|
|
13
|
+
## 1.7.4
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- Updated dependencies
|
|
18
|
+
- @backstage/connections@0.4.0
|
|
19
|
+
- @backstage/config@1.3.9
|
|
20
|
+
- @backstage/backend-plugin-api@1.10.1
|
|
21
|
+
|
|
3
22
|
## 1.7.4-next.1
|
|
4
23
|
|
|
5
24
|
### Patch Changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OpaqueExtensionPointFactoryMiddleware.cjs.js","sources":["../../../../../backend-internal/src/wiring/OpaqueExtensionPointFactoryMiddleware.ts"],"sourcesContent":["/*\n * Copyright 2026 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 { OpaqueType } from '@internal/opaque';\n\nexport const OpaqueExtensionPointFactoryMiddleware = OpaqueType.create<{\n public: { $$type: '@backstage/ExtensionPointFactoryMiddleware' };\n versions: {\n readonly version: 'v1';\n readonly extensionPointId: string;\n readonly middleware: (original: unknown) => Promise<unknown>;\n };\n}>({\n type: '@backstage/ExtensionPointFactoryMiddleware',\n versions: ['v1'],\n});\n"],"names":["OpaqueType"],"mappings":";;;;AAkBO,MAAM,qCAAA,GAAwCA,sBAAW,MAAA,CAO7D;AAAA,EACD,IAAA,EAAM,4CAAA;AAAA,EACN,QAAA,EAAU,CAAC,IAAI;AACjB,CAAC
|
|
1
|
+
{"version":3,"file":"OpaqueExtensionPointFactoryMiddleware.cjs.js","sources":["../../../../../backend-internal/src/wiring/OpaqueExtensionPointFactoryMiddleware.ts"],"sourcesContent":["/*\n * Copyright 2026 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 { OpaqueType } from '@internal/opaque';\n\nexport const OpaqueExtensionPointFactoryMiddleware = OpaqueType.create<{\n public: { $$type: '@backstage/ExtensionPointFactoryMiddleware' };\n versions: {\n readonly version: 'v1';\n readonly extensionPointId: string;\n readonly middleware: (original: unknown) => Promise<unknown>;\n };\n}>({\n type: '@backstage/ExtensionPointFactoryMiddleware',\n versions: ['v1'],\n});\n"],"names":["OpaqueType"],"mappings":";;;;AAkBO,MAAM,qCAAA,GAAwCA,sBAAW,MAAA,CAO7D;AAAA,EACD,IAAA,EAAM,4CAAA;AAAA,EACN,QAAA,EAAU,CAAC,IAAI;AACjB,CAAC;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.cjs.js","sources":["../../../../../backend-internal/src/wiring/helpers.ts"],"sourcesContent":["/*\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 { BackendFeature } from '@backstage/backend-plugin-api';\n\n/** @internal */\nexport function isPromise<T>(value: unknown | Promise<T>): value is Promise<T> {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'then' in value &&\n typeof value.then === 'function'\n );\n}\n\n/**\n * Unwraps a backend feature from a possibly double-nested default export.\n * This is a workaround where default exports get transpiled to\n * `exports['default'] = ...` in CommonJS modules, which in turn results\n * in a double `{ default: { default: ... } }` nesting when importing\n * using a dynamic import.\n *\n * @internal\n */\nexport function unwrapFeature(\n feature: BackendFeature | { default: BackendFeature },\n): BackendFeature {\n let current: unknown = feature;\n for (let i = 0; i < 2; i++) {\n if (\n current !== null &&\n (typeof current === 'object' || typeof current === 'function')\n ) {\n if ('$$type' in current) {\n return current as BackendFeature;\n }\n if ('default' in current) {\n current = current.default;\n continue;\n }\n }\n break;\n }\n\n return current as BackendFeature;\n}\n"],"names":[],"mappings":";;AAmBO,SAAS,UAAa,KAAA,EAAkD;AAC7E,EAAA,OACE,OAAO,UAAU,QAAA,IACjB,KAAA,KAAU,QACV,MAAA,IAAU,KAAA,IACV,OAAO,KAAA,CAAM,IAAA,KAAS,UAAA;AAE1B;AAWO,SAAS,cACd,OAAA,EACgB;AAChB,EAAA,IAAI,OAAA,GAAmB,OAAA;AACvB,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA,EAAA,EAAK;AAC1B,IAAA,IACE,YAAY,IAAA,KACX,OAAO,YAAY,QAAA,IAAY,OAAO,YAAY,UAAA,CAAA,EACnD;AACA,MAAA,IAAI,YAAY,OAAA,EAAS;AACvB,QAAA,OAAO,OAAA;AAAA,MACT;AACA,MAAA,IAAI,aAAa,OAAA,EAAS;AACxB,QAAA,OAAA,GAAU,OAAA,CAAQ,OAAA;AAClB,QAAA;AAAA,MACF;AAAA,IACF;AACA,IAAA;AAAA,EACF;AAEA,EAAA,OAAO,OAAA;AACT
|
|
1
|
+
{"version":3,"file":"helpers.cjs.js","sources":["../../../../../backend-internal/src/wiring/helpers.ts"],"sourcesContent":["/*\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 { BackendFeature } from '@backstage/backend-plugin-api';\n\n/** @internal */\nexport function isPromise<T>(value: unknown | Promise<T>): value is Promise<T> {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'then' in value &&\n typeof value.then === 'function'\n );\n}\n\n/**\n * Unwraps a backend feature from a possibly double-nested default export.\n * This is a workaround where default exports get transpiled to\n * `exports['default'] = ...` in CommonJS modules, which in turn results\n * in a double `{ default: { default: ... } }` nesting when importing\n * using a dynamic import.\n *\n * @internal\n */\nexport function unwrapFeature(\n feature: BackendFeature | { default: BackendFeature },\n): BackendFeature {\n let current: unknown = feature;\n for (let i = 0; i < 2; i++) {\n if (\n current !== null &&\n (typeof current === 'object' || typeof current === 'function')\n ) {\n if ('$$type' in current) {\n return current as BackendFeature;\n }\n if ('default' in current) {\n current = current.default;\n continue;\n }\n }\n break;\n }\n\n return current as BackendFeature;\n}\n"],"names":[],"mappings":";;AAmBO,SAAS,UAAa,KAAA,EAAkD;AAC7E,EAAA,OACE,OAAO,UAAU,QAAA,IACjB,KAAA,KAAU,QACV,MAAA,IAAU,KAAA,IACV,OAAO,KAAA,CAAM,IAAA,KAAS,UAAA;AAE1B;AAWO,SAAS,cACd,OAAA,EACgB;AAChB,EAAA,IAAI,OAAA,GAAmB,OAAA;AACvB,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA,EAAA,EAAK;AAC1B,IAAA,IACE,YAAY,IAAA,KACX,OAAO,YAAY,QAAA,IAAY,OAAO,YAAY,UAAA,CAAA,EACnD;AACA,MAAA,IAAI,YAAY,OAAA,EAAS;AACvB,QAAA,OAAO,OAAA;AAAA,MACT;AACA,MAAA,IAAI,aAAa,OAAA,EAAS;AACxB,QAAA,OAAA,GAAU,OAAA,CAAQ,OAAA;AAClB,QAAA;AAAA,MACF;AAAA,IACF;AACA,IAAA;AAAA,EACF;AAEA,EAAA,OAAO,OAAA;AACT;;;"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var config = require('@backstage/connections/config');
|
|
4
4
|
var lookup = require('./lookup.cjs.js');
|
|
5
5
|
var lookupStrategies = require('./lookupStrategies.cjs.js');
|
|
6
6
|
var errors = require('@backstage/errors');
|
|
@@ -96,7 +96,7 @@ class DefaultConnectionsService {
|
|
|
96
96
|
}
|
|
97
97
|
#registerConnectionsFromConfig() {
|
|
98
98
|
this.connections.push(
|
|
99
|
-
...
|
|
99
|
+
...config.buildConnectionsFromConfig({
|
|
100
100
|
config: this.config,
|
|
101
101
|
logger: this.logger
|
|
102
102
|
})
|
|
@@ -109,23 +109,15 @@ class DefaultConnectionsService {
|
|
|
109
109
|
);
|
|
110
110
|
}
|
|
111
111
|
#getConnectionsForPlugin(pluginId) {
|
|
112
|
-
return this.connections.flatMap((
|
|
113
|
-
if (match && !match.plugins.includes(pluginId)) {
|
|
112
|
+
return this.connections.flatMap((connection) => {
|
|
113
|
+
if (connection.match && !connection.match.plugins.includes(pluginId)) {
|
|
114
114
|
return [];
|
|
115
115
|
}
|
|
116
|
-
const pluginMatched =
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
pluginMatched.push(authRest);
|
|
122
|
-
} else {
|
|
123
|
-
unmatched.push(authRest);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
return [
|
|
127
|
-
{ ...rest, auth: [...pluginMatched, ...unmatched] }
|
|
128
|
-
];
|
|
116
|
+
const pluginMatched = connection.auth.filter(
|
|
117
|
+
(a) => a.match?.plugins.includes(pluginId)
|
|
118
|
+
);
|
|
119
|
+
const unmatched = connection.auth.filter((a) => !a.match);
|
|
120
|
+
return [{ ...connection, auth: [...pluginMatched, ...unmatched] }];
|
|
129
121
|
});
|
|
130
122
|
}
|
|
131
123
|
forPlugin(pluginId, options) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DefaultConnectionsService.cjs.js","sources":["../../../../connections-node/src/DefaultConnectionsService.ts"],"sourcesContent":["/*\n * Copyright 2026 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 */\nimport {\n LoggerService,\n RootConfigService,\n} from '@backstage/backend-plugin-api';\nimport type {\n Connection,\n ConnectionAuthMethodKey,\n ConnectionsService,\n ConnectionType,\n ConnectionTypeKey,\n LookupConnectionType,\n LookupStrategy,\n ConfiguredConnection,\n} from '@backstage/connections';\nimport { buildConnectionsFromConfig } from '@backstage/connections';\nimport { getConnectionType } from './lookup';\nimport { lookupStrategies } from './lookupStrategies';\nimport { NotAllowedError, NotFoundError } from '@backstage/errors';\n\ntype ConnectionQuery<TType extends ConnectionTypeKey> =\n LookupConnectionType<TType> extends ConnectionType<infer TDefinition>\n ? TDefinition['query']\n : never;\n\nfunction getLookupStrategy<K extends LookupStrategy>(\n name: K,\n): (typeof lookupStrategies)[K] {\n return lookupStrategies[name];\n}\n\n// The identity field name is only known at runtime, so the typed connection\n// object cannot be indexed directly; this helper contains the erased read.\nfunction connectionIdentityOf(\n strategy: { identityField?: string },\n connection: object,\n): string | undefined {\n if (!strategy.identityField) {\n return undefined;\n }\n const value = (connection as Record<string, unknown>)[strategy.identityField];\n return typeof value === 'string' ? value : undefined;\n}\n\nclass PluginConnectionsService implements ConnectionsService {\n private readonly logger: LoggerService;\n private readonly connections: Connection[];\n\n constructor(logger: LoggerService, connections: Connection[]) {\n this.logger = logger;\n this.connections = connections;\n }\n\n async find<\n TType extends ConnectionTypeKey,\n TAuthMethod extends ConnectionAuthMethodKey<TType>,\n >(options: {\n type: TType;\n query: ConnectionQuery<TType>;\n authMethods?: readonly [TAuthMethod, ...TAuthMethod[]];\n }): Promise<\n Connection<TType, TAuthMethod> | Omit<Connection<TType>, 'auth'>\n > {\n const result = await this.findOptional(options);\n if (!result) {\n throw new NotFoundError(\n `Connection not found for type \"${options.type}\"`,\n );\n }\n return result;\n }\n\n private async findOptional<\n TType extends ConnectionTypeKey,\n TAuthMethod extends ConnectionAuthMethodKey<TType>,\n >({\n type,\n query,\n authMethods,\n }: {\n type: TType;\n query: ConnectionQuery<TType>;\n authMethods?: readonly [TAuthMethod, ...TAuthMethod[]];\n }): Promise<\n Connection<TType, TAuthMethod> | Omit<Connection<TType>, 'auth'> | undefined\n > {\n const connectionType = getConnectionType(type);\n const strategy = getLookupStrategy(connectionType.lookupStrategy);\n const identity = strategy.identityFromQuery(query);\n\n this.logger.debug(\n `Finding connection of type \"${type}\"${\n identity ? ` matching ${strategy.identityField} \"${identity}\"` : ''\n }`,\n );\n\n let connection: Connection<TType> | undefined;\n if (identity !== undefined) {\n connection = this.connections.find(\n c => c.type === type && connectionIdentityOf(strategy, c) === identity,\n ) as Connection<TType> | undefined;\n } else {\n connection = this.connections.find(c => c.type === type) as\n | Connection<TType>\n | undefined;\n }\n\n if (!connection) {\n return undefined;\n }\n\n if (!authMethods) {\n const { auth: _, ...info } = connection;\n return info as Omit<Connection<TType>, 'auth'>;\n }\n\n if (connection.auth.length === 0) {\n throw new NotAllowedError(\n `Connection of type \"${type}\"${\n identity ? ` for ${strategy.identityField} \"${identity}\"` : ''\n } has no auth method available to this plugin`,\n );\n }\n\n const matchAuth = connectionType.matchAuth as\n | ((authMethods: any[], query: any) => any | undefined)\n | undefined;\n\n const selected = matchAuth\n ? matchAuth(connection.auth, query)\n : connection.auth[0];\n\n if (!selected) {\n return undefined;\n }\n\n if (!(authMethods as readonly string[]).includes(selected.method)) {\n throw new NotAllowedError(\n `Connection not found for type \"${type}\" with auth method \"${selected.method}\"`,\n );\n }\n\n this.logger.debug(\n `Selected connection of type \"${type}\"${\n identity ? ` for ${strategy.identityField} \"${identity}\"` : ''\n } using auth method \"${selected.method}\"`,\n );\n\n return {\n ...connection,\n auth: selected,\n } as Connection<TType, TAuthMethod>;\n }\n}\n\n/** @public */\nexport class DefaultConnectionsService {\n private readonly logger: LoggerService;\n private readonly connections: ConfiguredConnection[];\n private readonly config: RootConfigService;\n\n private constructor(logger: LoggerService, config: RootConfigService) {\n this.logger = logger;\n this.config = config;\n this.connections = [];\n this.#registerConnectionsFromConfig();\n }\n\n static create(options: {\n logger: LoggerService;\n config: RootConfigService;\n }): DefaultConnectionsService {\n return new DefaultConnectionsService(options.logger, options.config);\n }\n\n #registerConnectionsFromConfig(): void {\n this.connections.push(\n ...buildConnectionsFromConfig({\n config: this.config,\n logger: this.logger,\n }),\n );\n\n if (this.connections.length === 0) {\n return;\n }\n\n this.logger.info(\n `Loaded ${this.connections.length} connection${\n this.connections.length === 1 ? '' : 's'\n } from configuration`,\n );\n }\n\n #getConnectionsForPlugin(pluginId: string): Connection[] {\n // Filter connections and hide auth methods based on these conditions:\n // 1. Include Connections with no plugin matcher condition\n // 2. Include Connections with a plugin matcher condition for this plugin\n // 3. Include auth methods with no plugin matcher condition\n // 4. Remove auth methods with a plugin matcher condition for other plugins\n return this.connections.flatMap(({ match, auth, ...rest }) => {\n if (match && !match.plugins.includes(pluginId)) {\n return [];\n }\n\n const pluginMatched: Connection['auth'] = [];\n const unmatched: Connection['auth'] = [];\n for (const { match: authMatch, ...authRest } of auth) {\n if (authMatch) {\n if (!authMatch.plugins.includes(pluginId)) continue;\n pluginMatched.push(authRest as Connection['auth'][number]);\n } else {\n unmatched.push(authRest as Connection['auth'][number]);\n }\n }\n\n return [\n { ...rest, auth: [...pluginMatched, ...unmatched] } as Connection,\n ];\n });\n }\n\n forPlugin(\n pluginId: string,\n options?: {\n logger: LoggerService;\n },\n ): ConnectionsService {\n const logger = options?.logger ?? this.logger;\n return new PluginConnectionsService(\n logger,\n this.#getConnectionsForPlugin(pluginId),\n );\n }\n}\n"],"names":["lookupStrategies","NotFoundError","getConnectionType","NotAllowedError","buildConnectionsFromConfig"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DefaultConnectionsService.cjs.js","sources":["../../../../connections-node/src/DefaultConnectionsService.ts"],"sourcesContent":["/*\n * Copyright 2026 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 */\nimport {\n LoggerService,\n RootConfigService,\n} from '@backstage/backend-plugin-api';\nimport type {\n Connection,\n ConnectionLookupStrategy,\n ConnectionsService,\n ConnectionTypeDefinition,\n ConnectionType,\n LookupConnectionType,\n} from '@backstage/connections';\nimport type { ConfiguredConnection } from '@backstage/connections/config';\nimport { buildConnectionsFromConfig } from '@backstage/connections/config';\nimport { getConnectionType } from './lookup';\nimport { lookupStrategies } from './lookupStrategies';\nimport { NotAllowedError, NotFoundError } from '@backstage/errors';\n\ntype ConnectionQuery<TType extends ConnectionType> =\n LookupConnectionType<TType> extends ConnectionTypeDefinition<\n infer TDefinition\n >\n ? TDefinition['query']\n : never;\n\nfunction getLookupStrategy<K extends ConnectionLookupStrategy>(\n name: K,\n): (typeof lookupStrategies)[K] {\n return lookupStrategies[name];\n}\n\n// The identity field name is only known at runtime, so the typed connection\n// object cannot be indexed directly; this helper contains the erased read.\nfunction connectionIdentityOf(\n strategy: { identityField?: string },\n connection: object,\n): string | undefined {\n if (!strategy.identityField) {\n return undefined;\n }\n const value = (connection as Record<string, unknown>)[strategy.identityField];\n return typeof value === 'string' ? value : undefined;\n}\n\nclass PluginConnectionsService implements ConnectionsService {\n private readonly logger: LoggerService;\n private readonly connections: ConfiguredConnection[];\n\n constructor(logger: LoggerService, connections: ConfiguredConnection[]) {\n this.logger = logger;\n this.connections = connections;\n }\n\n async find<\n TType extends ConnectionType,\n TAuthMethod extends LookupConnectionType<TType>['authMethods'][number]['method'],\n >(options: {\n type: TType;\n query: ConnectionQuery<TType>;\n authMethods?: readonly [TAuthMethod, ...TAuthMethod[]];\n }): Promise<\n Connection<TType, TAuthMethod> | Omit<Connection<TType>, 'auth'>\n > {\n const result = await this.findOptional(options);\n if (!result) {\n throw new NotFoundError(\n `Connection not found for type \"${options.type}\"`,\n );\n }\n return result;\n }\n\n private async findOptional<\n TType extends ConnectionType,\n TAuthMethod extends LookupConnectionType<TType>['authMethods'][number]['method'],\n >({\n type,\n query,\n authMethods,\n }: {\n type: TType;\n query: ConnectionQuery<TType>;\n authMethods?: readonly [TAuthMethod, ...TAuthMethod[]];\n }): Promise<\n Connection<TType, TAuthMethod> | Omit<Connection<TType>, 'auth'> | undefined\n > {\n const connectionType = getConnectionType(type);\n const strategy = getLookupStrategy(connectionType.lookupStrategy);\n const identity = strategy.identityFromQuery(query);\n\n this.logger.debug(\n `Finding connection of type \"${type}\"${\n identity ? ` matching ${strategy.identityField} \"${identity}\"` : ''\n }`,\n );\n\n let connection: ConfiguredConnection | undefined;\n if (identity !== undefined) {\n connection = this.connections.find(\n c => c.type === type && connectionIdentityOf(strategy, c) === identity,\n );\n } else {\n connection = this.connections.find(c => c.type === type);\n }\n\n if (!connection) {\n return undefined;\n }\n\n if (!authMethods) {\n const { auth: _, ...info } = connection;\n return info as Omit<Connection<TType>, 'auth'>;\n }\n\n if (connection.auth.length === 0) {\n throw new NotAllowedError(\n `Connection of type \"${type}\"${\n identity ? ` for ${strategy.identityField} \"${identity}\"` : ''\n } has no auth method available to this plugin`,\n );\n }\n\n const matchAuth = (connectionType as any).matchAuth as\n | ((authMethods: any[], query: any) => any | undefined)\n | undefined;\n\n const selected = matchAuth\n ? matchAuth(connection.auth, query)\n : connection.auth[0];\n\n if (!selected) {\n return undefined;\n }\n\n if (!(authMethods as readonly string[]).includes(selected.method)) {\n throw new NotAllowedError(\n `Connection not found for type \"${type}\" with auth method \"${selected.method}\"`,\n );\n }\n\n this.logger.debug(\n `Selected connection of type \"${type}\"${\n identity ? ` for ${strategy.identityField} \"${identity}\"` : ''\n } using auth method \"${selected.method}\"`,\n );\n\n return {\n ...connection,\n auth: selected,\n } as Connection<TType, TAuthMethod>;\n }\n}\n\n/** @public */\nexport class DefaultConnectionsService {\n private readonly logger: LoggerService;\n private readonly connections: ConfiguredConnection[];\n private readonly config: RootConfigService;\n\n private constructor(logger: LoggerService, config: RootConfigService) {\n this.logger = logger;\n this.config = config;\n this.connections = [];\n this.#registerConnectionsFromConfig();\n }\n\n static create(options: {\n logger: LoggerService;\n config: RootConfigService;\n }): DefaultConnectionsService {\n return new DefaultConnectionsService(options.logger, options.config);\n }\n\n #registerConnectionsFromConfig(): void {\n this.connections.push(\n ...buildConnectionsFromConfig({\n config: this.config,\n logger: this.logger,\n }),\n );\n\n if (this.connections.length === 0) {\n return;\n }\n\n this.logger.info(\n `Loaded ${this.connections.length} connection${\n this.connections.length === 1 ? '' : 's'\n } from configuration`,\n );\n }\n\n #getConnectionsForPlugin(pluginId: string): ConfiguredConnection[] {\n // Filter connections and auth methods by plugin scope. Auth entries\n // explicitly matched to this plugin are ordered before unscoped entries\n // so that plugin-specific credentials take precedence.\n return this.connections.flatMap(connection => {\n if (connection.match && !connection.match.plugins.includes(pluginId)) {\n return [];\n }\n\n const pluginMatched = connection.auth.filter(a =>\n a.match?.plugins.includes(pluginId),\n );\n const unmatched = connection.auth.filter(a => !a.match);\n\n return [{ ...connection, auth: [...pluginMatched, ...unmatched] }];\n });\n }\n\n forPlugin(\n pluginId: string,\n options?: {\n logger: LoggerService;\n },\n ): ConnectionsService {\n const logger = options?.logger ?? this.logger;\n return new PluginConnectionsService(\n logger,\n this.#getConnectionsForPlugin(pluginId),\n );\n }\n}\n"],"names":["lookupStrategies","NotFoundError","getConnectionType","NotAllowedError","buildConnectionsFromConfig"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lookup.cjs.js","sources":["../../../../connections-node/src/lookup.ts"],"sourcesContent":["/*\n * Copyright 2026 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 */\nimport {\n LookupConnectionType,\n
|
|
1
|
+
{"version":3,"file":"lookup.cjs.js","sources":["../../../../connections-node/src/lookup.ts"],"sourcesContent":["/*\n * Copyright 2026 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 */\nimport {\n LookupConnectionType,\n ConnectionType,\n connectionTypes,\n} from '@backstage/connections';\n\nconst connectionTypesMap = new Map(Object.entries(connectionTypes));\n\nexport function getConnectionType<T extends ConnectionType>(\n key: T,\n): LookupConnectionType<T> {\n return connectionTypesMap.get(key) as LookupConnectionType<T>;\n}\n\nexport function isConnectionType(\n value: string | undefined,\n): value is ConnectionType {\n if (!value) return false;\n\n return connectionTypesMap.has(value);\n}\n"],"names":["connectionTypes"],"mappings":";;;;AAqBA,MAAM,qBAAqB,IAAI,GAAA,CAAI,MAAA,CAAO,OAAA,CAAQA,2BAAe,CAAC,CAAA;AAE3D,SAAS,kBACd,GAAA,EACyB;AACzB,EAAA,OAAO,kBAAA,CAAmB,IAAI,GAAG,CAAA;AACnC;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lookupStrategies.cjs.js","sources":["../../../../connections-node/src/lookupStrategies.ts"],"sourcesContent":["/*\n * Copyright 2026 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 */\nimport { InputError } from '@backstage/errors';\nimport type {
|
|
1
|
+
{"version":3,"file":"lookupStrategies.cjs.js","sources":["../../../../connections-node/src/lookupStrategies.ts"],"sourcesContent":["/*\n * Copyright 2026 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 */\nimport { InputError } from '@backstage/errors';\nimport type { ConnectionLookupStrategy } from '@backstage/connections';\n\n// The concrete strategy is only known at runtime, so definitions receive the\n// query with its type erased and narrow it to their own query shape.\ntype ConnectionLookupStrategyDefinition = {\n identityField?: string;\n identityFromQuery(query: unknown): string | undefined;\n};\n\n/**\n * The definitions of all lookup strategies, keyed by the `lookupStrategy` of\n * each connection type. Each definition knows how to derive the identity to\n * match connections against from the query passed to `ConnectionsService.find`.\n *\n * The `identityField` of each strategy is mirrored by the `identityFields` map\n * in the config pipeline of the `@backstage/connections` package; keep the two\n * in sync when adding or changing strategies.\n *\n * @internal\n */\nexport const lookupStrategies: Record<\n ConnectionLookupStrategy,\n ConnectionLookupStrategyDefinition\n> = {\n host: {\n identityField: 'host',\n identityFromQuery(query) {\n const { url } = query as { url: string };\n try {\n return new URL(url).host;\n } catch {\n throw new InputError(\n `Invalid url \"${url}\" passed to ConnectionsService.find`,\n );\n }\n },\n },\n // AWS has no identity field to match against — all accounts live under a\n // single connection. Account selection is handled entirely by the\n // connection type's matchAuth implementation.\n aws: {\n identityFromQuery() {\n return undefined;\n },\n },\n};\n"],"names":["InputError"],"mappings":";;;;AAoCO,MAAM,gBAAA,GAGT;AAAA,EACF,IAAA,EAAM;AAAA,IACJ,aAAA,EAAe,MAAA;AAAA,IACf,kBAAkB,KAAA,EAAO;AACvB,MAAA,MAAM,EAAE,KAAI,GAAI,KAAA;AAChB,MAAA,IAAI;AACF,QAAA,OAAO,IAAI,GAAA,CAAI,GAAG,CAAA,CAAE,IAAA;AAAA,MACtB,CAAA,CAAA,MAAQ;AACN,QAAA,MAAM,IAAIA,iBAAA;AAAA,UACR,gBAAgB,GAAG,CAAA,mCAAA;AAAA,SACrB;AAAA,MACF;AAAA,IACF;AAAA,GACF;AAAA;AAAA;AAAA;AAAA,EAIA,GAAA,EAAK;AAAA,IACH,iBAAA,GAAoB;AAClB,MAAA,OAAO,MAAA;AAAA,IACT;AAAA;AAEJ;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.cjs.js","sources":["../../../../connections-node/src/service.ts"],"sourcesContent":["/*\n * Copyright 2026 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n coreServices,\n createServiceFactory,\n createServiceRef,\n type ServiceRef,\n} from '@backstage/backend-plugin-api';\nimport type { ConnectionsService } from '@backstage/connections';\nimport { DefaultConnectionsService } from './DefaultConnectionsService';\n\nfunction createConnectionsServiceFactory<\n TInstances extends 'singleton' | 'multiton',\n>(service: ServiceRef<ConnectionsService, 'plugin', TInstances>) {\n return createServiceFactory({\n service,\n deps: {\n pluginMetadata: coreServices.pluginMetadata,\n rootLogger: coreServices.rootLogger,\n logger: coreServices.logger,\n config: coreServices.rootConfig,\n },\n async createRootContext({ rootLogger, config }) {\n return DefaultConnectionsService.create({ logger: rootLogger, config });\n },\n\n async factory({ logger, pluginMetadata }, connectionsService) {\n const pluginId = pluginMetadata.getId();\n return connectionsService.forPlugin(pluginId, { logger });\n },\n });\n}\n\n/** @public */\nexport const connectionsServiceRef = createServiceRef<ConnectionsService>({\n id: 'core.connections',\n scope: 'plugin',\n defaultFactory: async service => createConnectionsServiceFactory(service),\n});\n\n/** @public */\nexport const connectionsServiceFactory = createConnectionsServiceFactory(\n connectionsServiceRef,\n);\n"],"names":["createServiceFactory","coreServices","DefaultConnectionsService","createServiceRef"],"mappings":";;;;;AAyBA,SAAS,gCAEP,OAAA,EAA+D;AAC/D,EAAA,OAAOA,qCAAA,CAAqB;AAAA,IAC1B,OAAA;AAAA,IACA,IAAA,EAAM;AAAA,MACJ,gBAAgBC,6BAAA,CAAa,cAAA;AAAA,MAC7B,YAAYA,6BAAA,CAAa,UAAA;AAAA,MACzB,QAAQA,6BAAA,CAAa,MAAA;AAAA,MACrB,QAAQA,6BAAA,CAAa;AAAA,KACvB;AAAA,IACA,MAAM,iBAAA,CAAkB,EAAE,UAAA,EAAY,QAAO,EAAG;AAC9C,MAAA,OAAOC,oDAA0B,MAAA,CAAO,EAAE,MAAA,EAAQ,UAAA,EAAY,QAAQ,CAAA;AAAA,IACxE,CAAA;AAAA,IAEA,MAAM,OAAA,CAAQ,EAAE,MAAA,EAAQ,cAAA,IAAkB,kBAAA,EAAoB;AAC5D,MAAA,MAAM,QAAA,GAAW,eAAe,KAAA,EAAM;AACtC,MAAA,OAAO,kBAAA,CAAmB,SAAA,CAAU,QAAA,EAAU,EAAE,QAAQ,CAAA;AAAA,IAC1D;AAAA,GACD,CAAA;AACH;AAGO,MAAM,wBAAwBC,iCAAA,CAAqC;AAAA,EACxE,EAAA,EAAI,kBAAA;AAAA,EACJ,KAAA,EAAO,QAAA;AAAA,EACP,cAAA,EAAgB,OAAM,OAAA,KAAW,+BAAA,CAAgC,OAAO;AAC1E,CAAC;AAGwC,+BAAA;AAAA,EACvC;AACF
|
|
1
|
+
{"version":3,"file":"service.cjs.js","sources":["../../../../connections-node/src/service.ts"],"sourcesContent":["/*\n * Copyright 2026 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n coreServices,\n createServiceFactory,\n createServiceRef,\n type ServiceRef,\n} from '@backstage/backend-plugin-api';\nimport type { ConnectionsService } from '@backstage/connections';\nimport { DefaultConnectionsService } from './DefaultConnectionsService';\n\nfunction createConnectionsServiceFactory<\n TInstances extends 'singleton' | 'multiton',\n>(service: ServiceRef<ConnectionsService, 'plugin', TInstances>) {\n return createServiceFactory({\n service,\n deps: {\n pluginMetadata: coreServices.pluginMetadata,\n rootLogger: coreServices.rootLogger,\n logger: coreServices.logger,\n config: coreServices.rootConfig,\n },\n async createRootContext({ rootLogger, config }) {\n return DefaultConnectionsService.create({ logger: rootLogger, config });\n },\n\n async factory({ logger, pluginMetadata }, connectionsService) {\n const pluginId = pluginMetadata.getId();\n return connectionsService.forPlugin(pluginId, { logger });\n },\n });\n}\n\n/** @public */\nexport const connectionsServiceRef = createServiceRef<ConnectionsService>({\n id: 'core.connections',\n scope: 'plugin',\n defaultFactory: async service => createConnectionsServiceFactory(service),\n});\n\n/** @public */\nexport const connectionsServiceFactory = createConnectionsServiceFactory(\n connectionsServiceRef,\n);\n"],"names":["createServiceFactory","coreServices","DefaultConnectionsService","createServiceRef"],"mappings":";;;;;AAyBA,SAAS,gCAEP,OAAA,EAA+D;AAC/D,EAAA,OAAOA,qCAAA,CAAqB;AAAA,IAC1B,OAAA;AAAA,IACA,IAAA,EAAM;AAAA,MACJ,gBAAgBC,6BAAA,CAAa,cAAA;AAAA,MAC7B,YAAYA,6BAAA,CAAa,UAAA;AAAA,MACzB,QAAQA,6BAAA,CAAa,MAAA;AAAA,MACrB,QAAQA,6BAAA,CAAa;AAAA,KACvB;AAAA,IACA,MAAM,iBAAA,CAAkB,EAAE,UAAA,EAAY,QAAO,EAAG;AAC9C,MAAA,OAAOC,oDAA0B,MAAA,CAAO,EAAE,MAAA,EAAQ,UAAA,EAAY,QAAQ,CAAA;AAAA,IACxE,CAAA;AAAA,IAEA,MAAM,OAAA,CAAQ,EAAE,MAAA,EAAQ,cAAA,IAAkB,kBAAA,EAAoB;AAC5D,MAAA,MAAM,QAAA,GAAW,eAAe,KAAA,EAAM;AACtC,MAAA,OAAO,kBAAA,CAAmB,SAAA,CAAU,QAAA,EAAU,EAAE,QAAQ,CAAA;AAAA,IAC1D;AAAA,GACD,CAAA;AACH;AAGO,MAAM,wBAAwBC,iCAAA,CAAqC;AAAA,EACxE,EAAA,EAAI,kBAAA;AAAA,EACJ,KAAA,EAAO,QAAA;AAAA,EACP,cAAA,EAAgB,OAAM,OAAA,KAAW,+BAAA,CAAgC,OAAO;AAC1E,CAAC;AAGwC,+BAAA;AAAA,EACvC;AACF;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DependencyGraph.cjs.js","sources":["../../src/lib/DependencyGraph.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\ninterface NodeInput<T> {\n value: T;\n consumes?: Iterable<string>;\n provides?: Iterable<string>;\n}\n\n/** @internal */\nclass Node<T> {\n static from<T>(input: NodeInput<T>) {\n return new Node<T>(\n input.value,\n input.consumes ? new Set(input.consumes) : new Set(),\n input.provides ? new Set(input.provides) : new Set(),\n );\n }\n\n readonly value: T;\n readonly consumes: Set<string>;\n readonly provides: Set<string>;\n\n private constructor(value: T, consumes: Set<string>, provides: Set<string>) {\n this.value = value;\n this.consumes = consumes;\n this.provides = provides;\n }\n}\n\n/** @internal */\nclass CycleKeySet<T> {\n static from<T>(nodes: Array<Node<T>>) {\n return new CycleKeySet<T>(nodes);\n }\n\n #nodeIds: Map<T, number>;\n #cycleKeys: Set<string>;\n\n private constructor(nodes: Array<Node<T>>) {\n this.#nodeIds = new Map(nodes.map((n, i) => [n.value, i]));\n this.#cycleKeys = new Set<string>();\n }\n\n tryAdd(path: T[]): boolean {\n const cycleKey = this.#getCycleKey(path);\n if (this.#cycleKeys.has(cycleKey)) {\n return false;\n }\n this.#cycleKeys.add(cycleKey);\n return true;\n }\n\n #getCycleKey(path: T[]): string {\n return path\n .map(n => this.#nodeIds.get(n)!)\n .sort()\n .join(',');\n }\n}\n\n/**\n * Internal helper to help validate and traverse a dependency graph.\n * @internal\n */\nexport class DependencyGraph<T> {\n static fromMap(\n nodes: Record<string, Omit<NodeInput<unknown>, 'value'>>,\n ): DependencyGraph<string> {\n return this.fromIterable(\n Object.entries(nodes).map(([key, node]) => ({\n value: String(key),\n ...node,\n })),\n );\n }\n\n static fromIterable<T>(\n nodeInputs: Iterable<NodeInput<T>>,\n ): DependencyGraph<T> {\n const nodes = new Array<Node<T>>();\n for (const nodeInput of nodeInputs) {\n nodes.push(Node.from(nodeInput));\n }\n\n return new DependencyGraph(nodes);\n }\n\n #nodes: Array<Node<T>>;\n #allProvided: Set<string>;\n\n private constructor(nodes: Array<Node<T>>) {\n this.#nodes = nodes;\n this.#allProvided = new Set();\n\n for (const node of this.#nodes.values()) {\n for (const produced of node.provides) {\n this.#allProvided.add(produced);\n }\n }\n }\n\n /**\n * Find all nodes that consume dependencies that are not provided by any other node.\n */\n findUnsatisfiedDeps(): Array<{ value: T; unsatisfied: string[] }> {\n const unsatisfiedDependencies = [];\n for (const node of this.#nodes.values()) {\n const unsatisfied = Array.from(node.consumes).filter(\n id => !this.#allProvided.has(id),\n );\n if (unsatisfied.length > 0) {\n unsatisfiedDependencies.push({ value: node.value, unsatisfied });\n }\n }\n return unsatisfiedDependencies;\n }\n\n /**\n * Detect the first circular dependency within the graph, returning the path of nodes that\n * form a cycle, with the same node as the first and last element of the array.\n */\n detectCircularDependency(): T[] | undefined {\n return this.detectCircularDependencies().next().value;\n }\n\n /**\n * Detect circular dependencies within the graph, returning the path of nodes that\n * form a cycle, with the same node as the first and last element of the array.\n */\n *detectCircularDependencies(): Generator<T[], undefined> {\n const cycleKeys = CycleKeySet.from(this.#nodes);\n\n for (const startNode of this.#nodes) {\n const visited = new Set<Node<T>>();\n const stack = new Array<[node: Node<T>, path: T[]]>([\n startNode,\n [startNode.value],\n ]);\n\n while (stack.length > 0) {\n const [node, path] = stack.pop()!;\n if (visited.has(node)) {\n continue;\n }\n visited.add(node);\n for (const consumed of node.consumes) {\n const providerNodes = this.#nodes.filter(other =>\n other.provides.has(consumed),\n );\n for (const provider of providerNodes) {\n if (provider === startNode) {\n if (cycleKeys.tryAdd(path)) {\n yield [...path, startNode.value];\n }\n\n break;\n }\n if (!visited.has(provider)) {\n stack.push([provider, [...path, provider.value]]);\n }\n }\n }\n }\n }\n return undefined;\n }\n\n /**\n * Traverses the dependency graph in topological order, calling the provided\n * function for each node and waiting for it to resolve.\n *\n * The nodes are traversed in parallel, but in such a way that no node is\n * visited before all of its dependencies.\n *\n * Dependencies of nodes that are not produced by any other nodes will be ignored.\n */\n async parallelTopologicalTraversal<TResult>(\n fn: (value: T) => Promise<TResult>,\n ): Promise<TResult[]> {\n const allProvided = this.#allProvided;\n const waiting = new Set(this.#nodes.values());\n const visited = new Set<Node<T>>();\n const results = new Array<TResult>();\n let inFlight = 0; // Keep track of how many callbacks are in flight, so that we know if we got stuck\n\n // This keeps track of a counter of how many providers there are still left\n // to be visited for each dependency. This needs to be a counter instead of\n // a flag for the special case where there are several providers of a given\n // value, even though there may be only one consumer of it.\n const producedRemaining = new Map<string, number>();\n for (const node of this.#nodes) {\n for (const provided of node.provides) {\n producedRemaining.set(\n provided,\n (producedRemaining.get(provided) ?? 0) + 1,\n );\n }\n }\n\n // Find all nodes that have no dependencies that have not already been produced by visited nodes\n async function processMoreNodes() {\n if (waiting.size === 0) {\n return;\n }\n const nodesToProcess = [];\n for (const node of waiting) {\n let ready = true;\n for (const consumed of node.consumes) {\n if (\n allProvided.has(consumed) &&\n producedRemaining.get(consumed) !== 0\n ) {\n ready = false;\n continue;\n }\n }\n if (ready) {\n nodesToProcess.push(node);\n }\n }\n\n for (const node of nodesToProcess) {\n waiting.delete(node);\n }\n\n if (nodesToProcess.length === 0 && inFlight === 0) {\n // We expect the caller to check for circular dependencies before\n // traversal, so this error should never happen\n throw new Error('Circular dependency detected');\n }\n\n await Promise.all(nodesToProcess.map(processNode));\n }\n\n // Process an individual node, and then add its produced dependencies to the set of available products\n async function processNode(node: Node<T>) {\n visited.add(node);\n inFlight += 1;\n\n const result = await fn(node.value);\n results.push(result);\n\n node.provides.forEach(produced => {\n const remaining = producedRemaining.get(produced);\n if (!remaining) {\n // This should be impossible, if the code that generates the map is correct\n throw new Error(\n `Internal error: Node provided superfluous dependency '${produced}'`,\n );\n }\n producedRemaining.set(produced, remaining - 1);\n });\n\n inFlight -= 1;\n await processMoreNodes();\n }\n\n await processMoreNodes();\n\n return results;\n }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DependencyGraph.cjs.js","sources":["../../src/lib/DependencyGraph.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\ninterface NodeInput<T> {\n value: T;\n consumes?: Iterable<string>;\n provides?: Iterable<string>;\n}\n\n/** @internal */\nclass Node<T> {\n static from<T>(input: NodeInput<T>) {\n return new Node<T>(\n input.value,\n input.consumes ? new Set(input.consumes) : new Set(),\n input.provides ? new Set(input.provides) : new Set(),\n );\n }\n\n readonly value: T;\n readonly consumes: Set<string>;\n readonly provides: Set<string>;\n\n private constructor(value: T, consumes: Set<string>, provides: Set<string>) {\n this.value = value;\n this.consumes = consumes;\n this.provides = provides;\n }\n}\n\n/** @internal */\nclass CycleKeySet<T> {\n static from<T>(nodes: Array<Node<T>>) {\n return new CycleKeySet<T>(nodes);\n }\n\n #nodeIds: Map<T, number>;\n #cycleKeys: Set<string>;\n\n private constructor(nodes: Array<Node<T>>) {\n this.#nodeIds = new Map(nodes.map((n, i) => [n.value, i]));\n this.#cycleKeys = new Set<string>();\n }\n\n tryAdd(path: T[]): boolean {\n const cycleKey = this.#getCycleKey(path);\n if (this.#cycleKeys.has(cycleKey)) {\n return false;\n }\n this.#cycleKeys.add(cycleKey);\n return true;\n }\n\n #getCycleKey(path: T[]): string {\n return path\n .map(n => this.#nodeIds.get(n)!)\n .sort()\n .join(',');\n }\n}\n\n/**\n * Internal helper to help validate and traverse a dependency graph.\n * @internal\n */\nexport class DependencyGraph<T> {\n static fromMap(\n nodes: Record<string, Omit<NodeInput<unknown>, 'value'>>,\n ): DependencyGraph<string> {\n return this.fromIterable(\n Object.entries(nodes).map(([key, node]) => ({\n value: String(key),\n ...node,\n })),\n );\n }\n\n static fromIterable<T>(\n nodeInputs: Iterable<NodeInput<T>>,\n ): DependencyGraph<T> {\n const nodes = new Array<Node<T>>();\n for (const nodeInput of nodeInputs) {\n nodes.push(Node.from(nodeInput));\n }\n\n return new DependencyGraph(nodes);\n }\n\n #nodes: Array<Node<T>>;\n #allProvided: Set<string>;\n\n private constructor(nodes: Array<Node<T>>) {\n this.#nodes = nodes;\n this.#allProvided = new Set();\n\n for (const node of this.#nodes.values()) {\n for (const produced of node.provides) {\n this.#allProvided.add(produced);\n }\n }\n }\n\n /**\n * Find all nodes that consume dependencies that are not provided by any other node.\n */\n findUnsatisfiedDeps(): Array<{ value: T; unsatisfied: string[] }> {\n const unsatisfiedDependencies = [];\n for (const node of this.#nodes.values()) {\n const unsatisfied = Array.from(node.consumes).filter(\n id => !this.#allProvided.has(id),\n );\n if (unsatisfied.length > 0) {\n unsatisfiedDependencies.push({ value: node.value, unsatisfied });\n }\n }\n return unsatisfiedDependencies;\n }\n\n /**\n * Detect the first circular dependency within the graph, returning the path of nodes that\n * form a cycle, with the same node as the first and last element of the array.\n */\n detectCircularDependency(): T[] | undefined {\n return this.detectCircularDependencies().next().value;\n }\n\n /**\n * Detect circular dependencies within the graph, returning the path of nodes that\n * form a cycle, with the same node as the first and last element of the array.\n */\n *detectCircularDependencies(): Generator<T[], undefined> {\n const cycleKeys = CycleKeySet.from(this.#nodes);\n\n for (const startNode of this.#nodes) {\n const visited = new Set<Node<T>>();\n const stack = new Array<[node: Node<T>, path: T[]]>([\n startNode,\n [startNode.value],\n ]);\n\n while (stack.length > 0) {\n const [node, path] = stack.pop()!;\n if (visited.has(node)) {\n continue;\n }\n visited.add(node);\n for (const consumed of node.consumes) {\n const providerNodes = this.#nodes.filter(other =>\n other.provides.has(consumed),\n );\n for (const provider of providerNodes) {\n if (provider === startNode) {\n if (cycleKeys.tryAdd(path)) {\n yield [...path, startNode.value];\n }\n\n break;\n }\n if (!visited.has(provider)) {\n stack.push([provider, [...path, provider.value]]);\n }\n }\n }\n }\n }\n return undefined;\n }\n\n /**\n * Traverses the dependency graph in topological order, calling the provided\n * function for each node and waiting for it to resolve.\n *\n * The nodes are traversed in parallel, but in such a way that no node is\n * visited before all of its dependencies.\n *\n * Dependencies of nodes that are not produced by any other nodes will be ignored.\n */\n async parallelTopologicalTraversal<TResult>(\n fn: (value: T) => Promise<TResult>,\n ): Promise<TResult[]> {\n const allProvided = this.#allProvided;\n const waiting = new Set(this.#nodes.values());\n const visited = new Set<Node<T>>();\n const results = new Array<TResult>();\n let inFlight = 0; // Keep track of how many callbacks are in flight, so that we know if we got stuck\n\n // This keeps track of a counter of how many providers there are still left\n // to be visited for each dependency. This needs to be a counter instead of\n // a flag for the special case where there are several providers of a given\n // value, even though there may be only one consumer of it.\n const producedRemaining = new Map<string, number>();\n for (const node of this.#nodes) {\n for (const provided of node.provides) {\n producedRemaining.set(\n provided,\n (producedRemaining.get(provided) ?? 0) + 1,\n );\n }\n }\n\n // Find all nodes that have no dependencies that have not already been produced by visited nodes\n async function processMoreNodes() {\n if (waiting.size === 0) {\n return;\n }\n const nodesToProcess = [];\n for (const node of waiting) {\n let ready = true;\n for (const consumed of node.consumes) {\n if (\n allProvided.has(consumed) &&\n producedRemaining.get(consumed) !== 0\n ) {\n ready = false;\n continue;\n }\n }\n if (ready) {\n nodesToProcess.push(node);\n }\n }\n\n for (const node of nodesToProcess) {\n waiting.delete(node);\n }\n\n if (nodesToProcess.length === 0 && inFlight === 0) {\n // We expect the caller to check for circular dependencies before\n // traversal, so this error should never happen\n throw new Error('Circular dependency detected');\n }\n\n await Promise.all(nodesToProcess.map(processNode));\n }\n\n // Process an individual node, and then add its produced dependencies to the set of available products\n async function processNode(node: Node<T>) {\n visited.add(node);\n inFlight += 1;\n\n const result = await fn(node.value);\n results.push(result);\n\n node.provides.forEach(produced => {\n const remaining = producedRemaining.get(produced);\n if (!remaining) {\n // This should be impossible, if the code that generates the map is correct\n throw new Error(\n `Internal error: Node provided superfluous dependency '${produced}'`,\n );\n }\n producedRemaining.set(produced, remaining - 1);\n });\n\n inFlight -= 1;\n await processMoreNodes();\n }\n\n await processMoreNodes();\n\n return results;\n }\n}\n"],"names":[],"mappings":";;AAuBA,MAAM,IAAA,CAAQ;AAAA,EACZ,OAAO,KAAQ,KAAA,EAAqB;AAClC,IAAA,OAAO,IAAI,IAAA;AAAA,MACT,KAAA,CAAM,KAAA;AAAA,MACN,KAAA,CAAM,WAAW,IAAI,GAAA,CAAI,MAAM,QAAQ,CAAA,uBAAQ,GAAA,EAAI;AAAA,MACnD,KAAA,CAAM,WAAW,IAAI,GAAA,CAAI,MAAM,QAAQ,CAAA,uBAAQ,GAAA;AAAI,KACrD;AAAA,EACF;AAAA,EAES,KAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EAED,WAAA,CAAY,KAAA,EAAU,QAAA,EAAuB,QAAA,EAAuB;AAC1E,IAAA,IAAA,CAAK,KAAA,GAAQ,KAAA;AACb,IAAA,IAAA,CAAK,QAAA,GAAW,QAAA;AAChB,IAAA,IAAA,CAAK,QAAA,GAAW,QAAA;AAAA,EAClB;AACF;AAGA,MAAM,WAAA,CAAe;AAAA,EACnB,OAAO,KAAQ,KAAA,EAAuB;AACpC,IAAA,OAAO,IAAI,YAAe,KAAK,CAAA;AAAA,EACjC;AAAA,EAEA,QAAA;AAAA,EACA,UAAA;AAAA,EAEQ,YAAY,KAAA,EAAuB;AACzC,IAAA,IAAA,CAAK,QAAA,GAAW,IAAI,GAAA,CAAI,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,EAAG,CAAA,KAAM,CAAC,CAAA,CAAE,KAAA,EAAO,CAAC,CAAC,CAAC,CAAA;AACzD,IAAA,IAAA,CAAK,UAAA,uBAAiB,GAAA,EAAY;AAAA,EACpC;AAAA,EAEA,OAAO,IAAA,EAAoB;AACzB,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,YAAA,CAAa,IAAI,CAAA;AACvC,IAAA,IAAI,IAAA,CAAK,UAAA,CAAW,GAAA,CAAI,QAAQ,CAAA,EAAG;AACjC,MAAA,OAAO,KAAA;AAAA,IACT;AACA,IAAA,IAAA,CAAK,UAAA,CAAW,IAAI,QAAQ,CAAA;AAC5B,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,aAAa,IAAA,EAAmB;AAC9B,IAAA,OAAO,IAAA,CACJ,GAAA,CAAI,CAAA,CAAA,KAAK,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,CAAC,CAAE,CAAA,CAC9B,IAAA,EAAK,CACL,IAAA,CAAK,GAAG,CAAA;AAAA,EACb;AACF;AAMO,MAAM,eAAA,CAAmB;AAAA,EAC9B,OAAO,QACL,KAAA,EACyB;AACzB,IAAA,OAAO,IAAA,CAAK,YAAA;AAAA,MACV,MAAA,CAAO,QAAQ,KAAK,CAAA,CAAE,IAAI,CAAC,CAAC,GAAA,EAAK,IAAI,CAAA,MAAO;AAAA,QAC1C,KAAA,EAAO,OAAO,GAAG,CAAA;AAAA,QACjB,GAAG;AAAA,OACL,CAAE;AAAA,KACJ;AAAA,EACF;AAAA,EAEA,OAAO,aACL,UAAA,EACoB;AACpB,IAAA,MAAM,KAAA,GAAQ,IAAI,KAAA,EAAe;AACjC,IAAA,KAAA,MAAW,aAAa,UAAA,EAAY;AAClC,MAAA,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,IAAA,CAAK,SAAS,CAAC,CAAA;AAAA,IACjC;AAEA,IAAA,OAAO,IAAI,gBAAgB,KAAK,CAAA;AAAA,EAClC;AAAA,EAEA,MAAA;AAAA,EACA,YAAA;AAAA,EAEQ,YAAY,KAAA,EAAuB;AACzC,IAAA,IAAA,CAAK,MAAA,GAAS,KAAA;AACd,IAAA,IAAA,CAAK,YAAA,uBAAmB,GAAA,EAAI;AAE5B,IAAA,KAAA,MAAW,IAAA,IAAQ,IAAA,CAAK,MAAA,CAAO,MAAA,EAAO,EAAG;AACvC,MAAA,KAAA,MAAW,QAAA,IAAY,KAAK,QAAA,EAAU;AACpC,QAAA,IAAA,CAAK,YAAA,CAAa,IAAI,QAAQ,CAAA;AAAA,MAChC;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,mBAAA,GAAkE;AAChE,IAAA,MAAM,0BAA0B,EAAC;AACjC,IAAA,KAAA,MAAW,IAAA,IAAQ,IAAA,CAAK,MAAA,CAAO,MAAA,EAAO,EAAG;AACvC,MAAA,MAAM,WAAA,GAAc,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,QAAQ,CAAA,CAAE,MAAA;AAAA,QAC5C,CAAA,EAAA,KAAM,CAAC,IAAA,CAAK,YAAA,CAAa,IAAI,EAAE;AAAA,OACjC;AACA,MAAA,IAAI,WAAA,CAAY,SAAS,CAAA,EAAG;AAC1B,QAAA,uBAAA,CAAwB,KAAK,EAAE,KAAA,EAAO,IAAA,CAAK,KAAA,EAAO,aAAa,CAAA;AAAA,MACjE;AAAA,IACF;AACA,IAAA,OAAO,uBAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,wBAAA,GAA4C;AAC1C,IAAA,OAAO,IAAA,CAAK,0BAAA,EAA2B,CAAE,IAAA,EAAK,CAAE,KAAA;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,CAAC,0BAAA,GAAwD;AACvD,IAAA,MAAM,SAAA,GAAY,WAAA,CAAY,IAAA,CAAK,IAAA,CAAK,MAAM,CAAA;AAE9C,IAAA,KAAA,MAAW,SAAA,IAAa,KAAK,MAAA,EAAQ;AACnC,MAAA,MAAM,OAAA,uBAAc,GAAA,EAAa;AACjC,MAAA,MAAM,KAAA,GAAQ,IAAI,KAAA,CAAkC;AAAA,QAClD,SAAA;AAAA,QACA,CAAC,UAAU,KAAK;AAAA,OACjB,CAAA;AAED,MAAA,OAAO,KAAA,CAAM,SAAS,CAAA,EAAG;AACvB,QAAA,MAAM,CAAC,IAAA,EAAM,IAAI,CAAA,GAAI,MAAM,GAAA,EAAI;AAC/B,QAAA,IAAI,OAAA,CAAQ,GAAA,CAAI,IAAI,CAAA,EAAG;AACrB,UAAA;AAAA,QACF;AACA,QAAA,OAAA,CAAQ,IAAI,IAAI,CAAA;AAChB,QAAA,KAAA,MAAW,QAAA,IAAY,KAAK,QAAA,EAAU;AACpC,UAAA,MAAM,aAAA,GAAgB,KAAK,MAAA,CAAO,MAAA;AAAA,YAAO,CAAA,KAAA,KACvC,KAAA,CAAM,QAAA,CAAS,GAAA,CAAI,QAAQ;AAAA,WAC7B;AACA,UAAA,KAAA,MAAW,YAAY,aAAA,EAAe;AACpC,YAAA,IAAI,aAAa,SAAA,EAAW;AAC1B,cAAA,IAAI,SAAA,CAAU,MAAA,CAAO,IAAI,CAAA,EAAG;AAC1B,gBAAA,MAAM,CAAC,GAAG,IAAA,EAAM,SAAA,CAAU,KAAK,CAAA;AAAA,cACjC;AAEA,cAAA;AAAA,YACF;AACA,YAAA,IAAI,CAAC,OAAA,CAAQ,GAAA,CAAI,QAAQ,CAAA,EAAG;AAC1B,cAAA,KAAA,CAAM,IAAA,CAAK,CAAC,QAAA,EAAU,CAAC,GAAG,IAAA,EAAM,QAAA,CAAS,KAAK,CAAC,CAAC,CAAA;AAAA,YAClD;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,IAAA,OAAO,MAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,6BACJ,EAAA,EACoB;AACpB,IAAA,MAAM,cAAc,IAAA,CAAK,YAAA;AACzB,IAAA,MAAM,UAAU,IAAI,GAAA,CAAI,IAAA,CAAK,MAAA,CAAO,QAAQ,CAAA;AAC5C,IAAA,MAAM,OAAA,uBAAc,GAAA,EAAa;AACjC,IAAA,MAAM,OAAA,GAAU,IAAI,KAAA,EAAe;AACnC,IAAA,IAAI,QAAA,GAAW,CAAA;AAMf,IAAA,MAAM,iBAAA,uBAAwB,GAAA,EAAoB;AAClD,IAAA,KAAA,MAAW,IAAA,IAAQ,KAAK,MAAA,EAAQ;AAC9B,MAAA,KAAA,MAAW,QAAA,IAAY,KAAK,QAAA,EAAU;AACpC,QAAA,iBAAA,CAAkB,GAAA;AAAA,UAChB,QAAA;AAAA,UAAA,CACC,iBAAA,CAAkB,GAAA,CAAI,QAAQ,CAAA,IAAK,CAAA,IAAK;AAAA,SAC3C;AAAA,MACF;AAAA,IACF;AAGA,IAAA,eAAe,gBAAA,GAAmB;AAChC,MAAA,IAAI,OAAA,CAAQ,SAAS,CAAA,EAAG;AACtB,QAAA;AAAA,MACF;AACA,MAAA,MAAM,iBAAiB,EAAC;AACxB,MAAA,KAAA,MAAW,QAAQ,OAAA,EAAS;AAC1B,QAAA,IAAI,KAAA,GAAQ,IAAA;AACZ,QAAA,KAAA,MAAW,QAAA,IAAY,KAAK,QAAA,EAAU;AACpC,UAAA,IACE,WAAA,CAAY,IAAI,QAAQ,CAAA,IACxB,kBAAkB,GAAA,CAAI,QAAQ,MAAM,CAAA,EACpC;AACA,YAAA,KAAA,GAAQ,KAAA;AACR,YAAA;AAAA,UACF;AAAA,QACF;AACA,QAAA,IAAI,KAAA,EAAO;AACT,UAAA,cAAA,CAAe,KAAK,IAAI,CAAA;AAAA,QAC1B;AAAA,MACF;AAEA,MAAA,KAAA,MAAW,QAAQ,cAAA,EAAgB;AACjC,QAAA,OAAA,CAAQ,OAAO,IAAI,CAAA;AAAA,MACrB;AAEA,MAAA,IAAI,cAAA,CAAe,MAAA,KAAW,CAAA,IAAK,QAAA,KAAa,CAAA,EAAG;AAGjD,QAAA,MAAM,IAAI,MAAM,8BAA8B,CAAA;AAAA,MAChD;AAEA,MAAA,MAAM,OAAA,CAAQ,GAAA,CAAI,cAAA,CAAe,GAAA,CAAI,WAAW,CAAC,CAAA;AAAA,IACnD;AAGA,IAAA,eAAe,YAAY,IAAA,EAAe;AACxC,MAAA,OAAA,CAAQ,IAAI,IAAI,CAAA;AAChB,MAAA,QAAA,IAAY,CAAA;AAEZ,MAAA,MAAM,MAAA,GAAS,MAAM,EAAA,CAAG,IAAA,CAAK,KAAK,CAAA;AAClC,MAAA,OAAA,CAAQ,KAAK,MAAM,CAAA;AAEnB,MAAA,IAAA,CAAK,QAAA,CAAS,QAAQ,CAAA,QAAA,KAAY;AAChC,QAAA,MAAM,SAAA,GAAY,iBAAA,CAAkB,GAAA,CAAI,QAAQ,CAAA;AAChD,QAAA,IAAI,CAAC,SAAA,EAAW;AAEd,UAAA,MAAM,IAAI,KAAA;AAAA,YACR,yDAAyD,QAAQ,CAAA,CAAA;AAAA,WACnE;AAAA,QACF;AACA,QAAA,iBAAA,CAAkB,GAAA,CAAI,QAAA,EAAU,SAAA,GAAY,CAAC,CAAA;AAAA,MAC/C,CAAC,CAAA;AAED,MAAA,QAAA,IAAY,CAAA;AACZ,MAAA,MAAM,gBAAA,EAAiB;AAAA,IACzB;AAEA,IAAA,MAAM,gBAAA,EAAiB;AAEvB,IAAA,OAAO,OAAA;AAAA,EACT;AACF;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OpaqueType.cjs.js","sources":["../../../../opaque-internal/src/OpaqueType.ts"],"sourcesContent":["/*\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\n// TODO(Rugvip): This lives here temporarily, but should be moved to a more\n// central location. It's useful for backend packages too so we'll need to have\n// it in a common package, but it might also be that we want to make it\n// available publicly too in which case it would make sense to have this be part\n// of @backstage/version-bridge. The problem with exporting it from there is\n// that it would need to be very stable at that point, so it might be a bit\n// early to put it there already.\n\n/**\n * A helper for working with opaque types.\n */\nexport class OpaqueType<\n T extends {\n public: { $$type: string };\n versions: { version: string | undefined };\n },\n> {\n /**\n * Creates a new opaque type.\n *\n * @param options.type The type identifier of the opaque type\n * @param options.versions The available versions of the opaque type\n * @returns A new opaque type helper\n */\n static create<\n T extends {\n public: { $$type: string };\n versions: { version: string | undefined };\n },\n >(options: {\n type: T['public']['$$type'];\n versions: Array<T['versions']['version']>;\n }) {\n return new OpaqueType<T>(options.type, new Set(options.versions));\n }\n\n #type: string;\n #versions: Set<string | undefined>;\n\n private constructor(type: string, versions: Set<string | undefined>) {\n this.#type = type;\n this.#versions = versions;\n }\n\n /**\n * The internal version of the opaque type, used like this: `typeof MyOpaqueType.TPublic`\n *\n * @remarks\n *\n * This property is only useful for type checking, its runtime value is `undefined`.\n */\n TPublic: T['public'] = undefined as any;\n\n /**\n * The internal version of the opaque type, used like this: `typeof MyOpaqueType.TInternal`\n *\n * @remarks\n *\n * This property is only useful for type checking, its runtime value is `undefined`.\n */\n TInternal: T['public'] & T['versions'] = undefined as any;\n\n /**\n * @param value Input value expected to be an instance of this opaque type\n * @returns True if the value matches this opaque type\n */\n isType = (value: unknown): value is T['public'] => {\n return this.#isThisInternalType(value);\n };\n\n /**\n * @param value Input value expected to be an instance of this opaque type\n * @throws If the value is not an instance of this opaque type or is of an unsupported version\n * @returns The internal version of the opaque type\n */\n toInternal = (value: unknown): T['public'] & T['versions'] => {\n if (!this.#isThisInternalType(value)) {\n throw new TypeError(\n `Invalid opaque type, expected '${\n this.#type\n }', but got '${this.#stringifyUnknown(value)}'`,\n );\n }\n\n if (!this.#versions.has(value.version)) {\n const versions = Array.from(this.#versions).map(this.#stringifyVersion);\n if (versions.length > 1) {\n versions[versions.length - 1] = `or ${versions[versions.length - 1]}`;\n }\n const expected =\n versions.length > 2 ? versions.join(', ') : versions.join(' ');\n throw new TypeError(\n `Invalid opaque type instance, got version ${this.#stringifyVersion(\n value.version,\n )}, expected ${expected}`,\n );\n }\n\n return value;\n };\n\n /**\n * Creates an instance of the opaque type, returning the public type.\n *\n * @param version The version of the instance to create\n * @param value The remaining public and internal properties of the instance\n * @returns An instance of the opaque type\n */\n createInstance<\n TVersion extends T['versions']['version'],\n TPublic extends T['public'],\n >(\n version: TVersion,\n props: Omit<T['public'], '$$type'> &\n (T['versions'] extends infer UVersion\n ? UVersion extends { version: TVersion }\n ? Omit<UVersion, 'version'>\n : never\n : never) &\n Object, // & Object to allow for object properties too, e.g. toString()\n ): TPublic {\n return Object.assign(props as object, {\n $$type: this.#type,\n ...(version && { version }),\n }) as unknown as TPublic;\n }\n\n #isThisInternalType(value: unknown): value is T['public'] & T['versions'] {\n if (value === null || typeof value !== 'object') {\n return false;\n }\n return (value as T['public']).$$type === this.#type;\n }\n\n #stringifyUnknown(value: unknown) {\n if (typeof value !== 'object') {\n return `<${typeof value}>`;\n }\n if (value === null) {\n return '<null>';\n }\n if ('$$type' in value) {\n return String(value.$$type);\n }\n return String(value);\n }\n\n #stringifyVersion = (version: string | undefined) => {\n return version ? `'${version}'` : 'undefined';\n };\n}\n"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"OpaqueType.cjs.js","sources":["../../../../opaque-internal/src/OpaqueType.ts"],"sourcesContent":["/*\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\n// TODO(Rugvip): This lives here temporarily, but should be moved to a more\n// central location. It's useful for backend packages too so we'll need to have\n// it in a common package, but it might also be that we want to make it\n// available publicly too in which case it would make sense to have this be part\n// of @backstage/version-bridge. The problem with exporting it from there is\n// that it would need to be very stable at that point, so it might be a bit\n// early to put it there already.\n\n/**\n * A helper for working with opaque types.\n */\nexport class OpaqueType<\n T extends {\n public: { $$type: string };\n versions: { version: string | undefined };\n },\n> {\n /**\n * Creates a new opaque type.\n *\n * @param options.type The type identifier of the opaque type\n * @param options.versions The available versions of the opaque type\n * @returns A new opaque type helper\n */\n static create<\n T extends {\n public: { $$type: string };\n versions: { version: string | undefined };\n },\n >(options: {\n type: T['public']['$$type'];\n versions: Array<T['versions']['version']>;\n }) {\n return new OpaqueType<T>(options.type, new Set(options.versions));\n }\n\n #type: string;\n #versions: Set<string | undefined>;\n\n private constructor(type: string, versions: Set<string | undefined>) {\n this.#type = type;\n this.#versions = versions;\n }\n\n /**\n * The internal version of the opaque type, used like this: `typeof MyOpaqueType.TPublic`\n *\n * @remarks\n *\n * This property is only useful for type checking, its runtime value is `undefined`.\n */\n TPublic: T['public'] = undefined as any;\n\n /**\n * The internal version of the opaque type, used like this: `typeof MyOpaqueType.TInternal`\n *\n * @remarks\n *\n * This property is only useful for type checking, its runtime value is `undefined`.\n */\n TInternal: T['public'] & T['versions'] = undefined as any;\n\n /**\n * @param value Input value expected to be an instance of this opaque type\n * @returns True if the value matches this opaque type\n */\n isType = (value: unknown): value is T['public'] => {\n return this.#isThisInternalType(value);\n };\n\n /**\n * @param value Input value expected to be an instance of this opaque type\n * @throws If the value is not an instance of this opaque type or is of an unsupported version\n * @returns The internal version of the opaque type\n */\n toInternal = (value: unknown): T['public'] & T['versions'] => {\n if (!this.#isThisInternalType(value)) {\n throw new TypeError(\n `Invalid opaque type, expected '${\n this.#type\n }', but got '${this.#stringifyUnknown(value)}'`,\n );\n }\n\n if (!this.#versions.has(value.version)) {\n const versions = Array.from(this.#versions).map(this.#stringifyVersion);\n if (versions.length > 1) {\n versions[versions.length - 1] = `or ${versions[versions.length - 1]}`;\n }\n const expected =\n versions.length > 2 ? versions.join(', ') : versions.join(' ');\n throw new TypeError(\n `Invalid opaque type instance, got version ${this.#stringifyVersion(\n value.version,\n )}, expected ${expected}`,\n );\n }\n\n return value;\n };\n\n /**\n * Creates an instance of the opaque type, returning the public type.\n *\n * @param version The version of the instance to create\n * @param value The remaining public and internal properties of the instance\n * @returns An instance of the opaque type\n */\n createInstance<\n TVersion extends T['versions']['version'],\n TPublic extends T['public'],\n >(\n version: TVersion,\n props: Omit<T['public'], '$$type'> &\n (T['versions'] extends infer UVersion\n ? UVersion extends { version: TVersion }\n ? Omit<UVersion, 'version'>\n : never\n : never) &\n Object, // & Object to allow for object properties too, e.g. toString()\n ): TPublic {\n return Object.assign(props as object, {\n $$type: this.#type,\n ...(version && { version }),\n }) as unknown as TPublic;\n }\n\n #isThisInternalType(value: unknown): value is T['public'] & T['versions'] {\n if (value === null || typeof value !== 'object') {\n return false;\n }\n return (value as T['public']).$$type === this.#type;\n }\n\n #stringifyUnknown(value: unknown) {\n if (typeof value !== 'object') {\n return `<${typeof value}>`;\n }\n if (value === null) {\n return '<null>';\n }\n if ('$$type' in value) {\n return String(value.$$type);\n }\n return String(value);\n }\n\n #stringifyVersion = (version: string | undefined) => {\n return version ? `'${version}'` : 'undefined';\n };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -9,7 +9,7 @@ var helpers$1 = require('./helpers.cjs.js');
|
|
|
9
9
|
var BackendStartupError = require('./BackendStartupError.cjs.js');
|
|
10
10
|
var createAllowBootFailurePredicate = require('./createAllowBootFailurePredicate.cjs.js');
|
|
11
11
|
var service = require('../connections-node/src/service.cjs.js');
|
|
12
|
-
require('@backstage/connections');
|
|
12
|
+
require('@backstage/connections/config');
|
|
13
13
|
require('../connections-node/src/lookup.cjs.js');
|
|
14
14
|
var withDeclaredConnections = require('./withDeclaredConnections.cjs.js');
|
|
15
15
|
var validateBackendFeature = require('./validateBackendFeature.cjs.js');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BackendInitializer.cjs.js","sources":["../../src/wiring/BackendInitializer.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 {\n BackendFeature,\n ExtensionPoint,\n coreServices,\n ServiceRef,\n ServiceFactory,\n LifecycleService,\n RootLifecycleService,\n createServiceFactory,\n ExtensionPointFactoryContext,\n} from '@backstage/backend-plugin-api';\nimport type { ConnectionRegistration } from '@backstage/backend-plugin-api/alpha';\nimport {\n ExtensionPointFactoryMiddleware,\n ServiceOrExtensionPoint,\n} from './types';\nimport {\n OpaqueExtensionPointFactoryMiddleware,\n unwrapFeature,\n} from '@internal/backend';\n// Direct internal import to avoid duplication\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport type {\n InternalBackendFeatureLoader,\n InternalBackendRegistrations,\n} from '../../../backend-plugin-api/src/wiring/types';\nimport { ConflictError, ForwardedError, toError } from '@backstage/errors';\nimport { DependencyGraph } from '../lib/DependencyGraph';\nimport { ServiceRegistry } from './ServiceRegistry';\nimport { createInitializationResultCollector } from './createInitializationResultCollector';\nimport { deepFreeze } from './helpers';\nimport type { RootInstanceMetadataServicePluginInfo } from '@backstage/backend-plugin-api';\nimport { BackendStartupResult } from './types';\nimport { BackendStartupError } from './BackendStartupError';\nimport { createAllowBootFailurePredicate } from './createAllowBootFailurePredicate';\nimport type { ConnectionsService } from '@backstage/connections';\nimport { connectionsServiceRef } from '@backstage/connections-node';\nimport { withDeclaredConnections } from './withDeclaredConnections';\nimport {\n assertObject,\n describeBackendFeature,\n throwInvalidBackendFeature,\n validateBackendFeature,\n validateBackendRegistration,\n validateBackendRegistrations,\n validateServiceRef,\n type ValidatedBackendFeature,\n} from './validateBackendFeature';\n\nexport interface BackendRegisterInit {\n consumes: Set<ServiceOrExtensionPoint>;\n provides: Set<ServiceOrExtensionPoint>;\n init: {\n deps: { [name: string]: ServiceOrExtensionPoint };\n func: (deps: { [name: string]: unknown }) => Promise<void>;\n };\n}\n\ntype InstalledFeatureLoader = {\n feature: InternalBackendFeatureLoader;\n source: string;\n};\n\n/**\n * A registry of backend instances, used to manage process shutdown hooks across all instances.\n */\nconst instanceRegistry = new (class InstanceRegistry {\n #registered = false;\n #instances = new Set<BackendInitializer>();\n\n register(instance: BackendInitializer) {\n if (!this.#registered) {\n this.#registered = true;\n\n process.addListener('SIGTERM', this.#exitHandler);\n process.addListener('SIGINT', this.#exitHandler);\n process.addListener('beforeExit', this.#exitHandler);\n }\n\n this.#instances.add(instance);\n }\n\n unregister(instance: BackendInitializer) {\n this.#instances.delete(instance);\n }\n\n #exitHandler = async () => {\n try {\n const results = await Promise.allSettled(\n Array.from(this.#instances).map(b => b.stop()),\n );\n const errors = results.flatMap(r =>\n r.status === 'rejected' ? [r.reason] : [],\n );\n\n if (errors.length > 0) {\n for (const error of errors) {\n console.error(error);\n }\n process.exit(1);\n } else {\n process.exit(0);\n }\n } catch (error) {\n console.error(error);\n process.exit(1);\n }\n };\n})();\n\nfunction callerKey(pluginId: string, moduleId?: string): string {\n return moduleId ? `${pluginId}\\0${moduleId}` : pluginId;\n}\n\nfunction collectCallerConnectionRegistrations(\n registrations: ReturnType<InternalBackendRegistrations['getRegistrations']>,\n): Map<string, ConnectionRegistration[]> {\n const byCaller = new Map<string, ConnectionRegistration[]>();\n\n for (const registration of registrations) {\n const declared =\n 'connections' in registration && Array.isArray(registration.connections)\n ? registration.connections\n : [];\n if (declared.length === 0) continue;\n\n const key =\n 'moduleId' in registration\n ? callerKey(registration.pluginId, registration.moduleId)\n : callerKey(registration.pluginId);\n\n const target =\n byCaller.get(key) ??\n (() => {\n const list: ConnectionRegistration[] = [];\n byCaller.set(key, list);\n return list;\n })();\n\n for (const decl of declared) {\n if (!target.some(c => c.type === decl.type)) {\n target.push({ ...decl });\n }\n }\n }\n\n return byCaller;\n}\n\nfunction createRootInstanceMetadataServiceFactory(\n registrations: ReturnType<InternalBackendRegistrations['getRegistrations']>,\n) {\n const installedPlugins: Map<string, RootInstanceMetadataServicePluginInfo> =\n new Map();\n const plugins = registrations.filter(\n registration =>\n registration.type === 'plugin' || registration.type === 'plugin-v1.1',\n );\n const modules = registrations.filter(\n registration =>\n registration.type === 'module' || registration.type === 'module-v1.1',\n );\n for (const plugin of plugins) {\n const { pluginId } = plugin;\n if (!installedPlugins.get(pluginId)) {\n installedPlugins.set(pluginId, {\n pluginId,\n modules: [],\n });\n }\n }\n for (const module of modules) {\n const { pluginId, moduleId } = module;\n const installedPlugin = installedPlugins.get(pluginId);\n if (installedPlugin) {\n (installedPlugin.modules as Array<{ moduleId: string }>).push({\n moduleId,\n });\n }\n }\n\n return createServiceFactory({\n service: coreServices.rootInstanceMetadata,\n deps: {},\n factory: async () => {\n const readonlyInstalledPlugins = deepFreeze([\n ...installedPlugins.values(),\n ]);\n const instanceMetadata = {\n getInstalledPlugins: () => Promise.resolve(readonlyInstalledPlugins),\n };\n\n return instanceMetadata;\n },\n });\n}\n\nexport class BackendInitializer {\n #startPromise?: Promise<{ result: BackendStartupResult }>;\n #stopPromise?: Promise<void>;\n #registrations = new Array<{\n feature: InternalBackendRegistrations;\n source: string;\n }>();\n #allRegistrations = new Array<\n ReturnType<InternalBackendRegistrations['getRegistrations']>[number]\n >();\n #extensionPoints = new Map<\n string,\n {\n pluginId: string;\n factory: (context: ExtensionPointFactoryContext) => unknown;\n }\n >();\n #serviceRegistry: ServiceRegistry;\n #registeredFeatures = new Array<{\n feature: Promise<BackendFeature>;\n source: string;\n }>();\n #registeredFeatureLoaders = new Array<InstalledFeatureLoader>();\n #extensionPointFactoryMiddleware: ExtensionPointFactoryMiddleware[];\n #callerConnectionRegistrations = new Map<string, ConnectionRegistration[]>();\n\n #getConnectionRegistrations(\n pluginId: string,\n moduleId?: string,\n ): ConnectionRegistration[] {\n if (moduleId) {\n return (\n this.#callerConnectionRegistrations.get(\n callerKey(pluginId, moduleId),\n ) ?? []\n );\n }\n // Aggregate registrations from the plugin\n const result: ConnectionRegistration[] = [];\n for (const [key, registrations] of this.#callerConnectionRegistrations) {\n if (key === pluginId) {\n result.push(...registrations);\n }\n }\n return result;\n }\n\n #unhandledRejectionHandler?: (reason: Error) => void;\n #uncaughtExceptionHandler?: (error: Error) => void;\n\n constructor(\n defaultApiFactories: ServiceFactory[],\n extensionPointFactoryMiddleware?: ExtensionPointFactoryMiddleware[],\n ) {\n this.#serviceRegistry = ServiceRegistry.create([...defaultApiFactories]);\n this.#extensionPointFactoryMiddleware =\n extensionPointFactoryMiddleware ?? [];\n }\n\n async #getInitDeps(\n deps: { [name: string]: ServiceOrExtensionPoint },\n resultCollector: ReturnType<typeof createInitializationResultCollector>,\n pluginId: string,\n moduleId?: string,\n ) {\n const result = new Map<string, unknown>();\n const missingRefs = new Set<ServiceOrExtensionPoint>();\n\n for (const [name, ref] of Object.entries(deps)) {\n const ep = this.#extensionPoints.get(ref.id);\n if (ep) {\n if (ep.pluginId !== pluginId) {\n throw new Error(\n `Illegal dependency: Module '${moduleId}' for plugin '${pluginId}' attempted to depend on extension point '${ref.id}' for plugin '${ep.pluginId}'. Extension points can only be used within their plugin's scope.`,\n );\n }\n if (!moduleId) {\n throw new Error(\n `Rejected dependency on extension point ${ref.id} from outside of a module`,\n );\n }\n let epImpl = ep.factory({\n reportModuleStartupFailure: ({ error }) => {\n resultCollector.amendPluginModuleResult(pluginId, moduleId, error);\n },\n });\n for (const mw of this.#extensionPointFactoryMiddleware) {\n const internal = OpaqueExtensionPointFactoryMiddleware.toInternal(mw);\n if (internal.extensionPointId === ref.id) {\n epImpl = await internal.middleware(epImpl);\n }\n }\n result.set(name, epImpl);\n } else {\n const impl = await this.#serviceRegistry.get(\n ref as ServiceRef<unknown>,\n pluginId,\n );\n if (impl) {\n if (ref.id === connectionsServiceRef.id) {\n const registrations = this.#getConnectionRegistrations(\n pluginId,\n moduleId,\n );\n result.set(\n name,\n withDeclaredConnections(\n impl as ConnectionsService,\n registrations,\n ),\n );\n } else {\n result.set(name, impl);\n }\n } else {\n missingRefs.add(ref);\n }\n }\n }\n\n if (missingRefs.size > 0) {\n const missing = Array.from(missingRefs).join(', ');\n const target = moduleId\n ? `module '${moduleId}' for plugin '${pluginId}'`\n : `plugin '${pluginId}'`;\n throw new Error(\n `Service or extension point dependencies of ${target} are missing for the following ref(s): ${missing}`,\n );\n }\n\n return Object.fromEntries(result);\n }\n\n add(feature: BackendFeature | Promise<BackendFeature>) {\n if (this.#startPromise) {\n throw new Error('feature can not be added after the backend has started');\n }\n this.#registeredFeatures.push({\n feature: Promise.resolve(feature),\n source: `features[${this.#registeredFeatures.length}]`,\n });\n }\n\n #addFeature(feature: ValidatedBackendFeature, source: string) {\n if (feature.type === 'service') {\n this.#serviceRegistry.add(feature.feature, source);\n } else if (feature.type === 'loader') {\n this.#registeredFeatureLoaders.push({\n feature: feature.feature,\n source,\n });\n } else {\n this.#registrations.push({\n feature: feature.feature,\n source,\n });\n }\n }\n\n async start(): Promise<{ result: BackendStartupResult }> {\n if (this.#startPromise) {\n throw new Error('Backend has already started');\n }\n if (this.#stopPromise) {\n throw new Error('Backend has already stopped');\n }\n\n instanceRegistry.register(this);\n\n this.#startPromise = this.#doStart();\n return await this.#startPromise;\n }\n\n async #doStart(): Promise<{ result: BackendStartupResult }> {\n this.#serviceRegistry.checkForCircularDeps();\n\n for (const { feature, source: fallbackSource } of this\n .#registeredFeatures) {\n const resolvedFeature = await feature;\n const source = describeBackendFeature(resolvedFeature) ?? fallbackSource;\n this.#addFeature(validateBackendFeature(resolvedFeature, source), source);\n }\n\n await this.#applyBackendFeatureLoaders(this.#registeredFeatureLoaders);\n\n this.#allRegistrations = this.#registrations.flatMap(\n ({ feature, source }) => validateBackendRegistrations(feature, source),\n );\n\n this.#serviceRegistry.add(\n createRootInstanceMetadataServiceFactory(this.#allRegistrations),\n );\n\n // This makes sure that any uncaught errors or unhandled rejections are\n // caught and logged, rather than terminating the process. We register these\n // as early as possible while still using the root logger service, the\n // tradeoff that if there are any unhandled errors as part of the that\n // instationation, it will cause the process to crash. If there are multiple\n // backend instances, each instance will log the error, because we can't\n // determine which instance the error came from.\n if (process.env.NODE_ENV !== 'test') {\n const rootLogger = await this.#serviceRegistry.get(\n coreServices.rootLogger,\n 'root',\n );\n this.#unhandledRejectionHandler = (reason: Error) => {\n rootLogger\n ?.child({ type: 'unhandledRejection' })\n ?.error('Unhandled rejection', reason);\n };\n this.#uncaughtExceptionHandler = (error: Error) => {\n rootLogger\n ?.child({ type: 'uncaughtException' })\n ?.error('Uncaught exception', error);\n };\n process.on('unhandledRejection', this.#unhandledRejectionHandler);\n process.on('uncaughtException', this.#uncaughtExceptionHandler);\n }\n\n // Initialize all root scoped services\n await this.#serviceRegistry.initializeEagerServicesWithScope('root');\n\n const rootConfig = await this.#serviceRegistry.get(\n coreServices.rootConfig,\n 'root',\n );\n const rootLogger = await this.#serviceRegistry.get(\n coreServices.rootLogger,\n 'root',\n );\n\n const allRegistrations = this.#allRegistrations;\n\n this.#callerConnectionRegistrations =\n collectCallerConnectionRegistrations(allRegistrations);\n\n const allPluginIds = [\n ...new Set(\n allRegistrations.flatMap(r =>\n 'pluginId' in r && typeof r.pluginId === 'string' ? [r.pluginId] : [],\n ),\n ),\n ];\n\n const resultCollector = createInitializationResultCollector({\n pluginIds: allPluginIds,\n logger: rootLogger,\n allowBootFailurePredicate: createAllowBootFailurePredicate(rootConfig),\n });\n\n const { pluginInits, moduleInits } = this.#enumerateRegistrations(\n allRegistrations,\n resultCollector,\n );\n\n // All plugins are initialized in parallel\n await Promise.all(\n [...pluginInits.keys()].map(async pluginId => {\n try {\n // Initialize all eager services\n await this.#serviceRegistry.initializeEagerServicesWithScope(\n 'plugin',\n pluginId,\n );\n\n // Modules are initialized before plugins, so that they can provide extension to the plugin\n const modules = moduleInits.get(pluginId);\n if (modules) {\n const tree = DependencyGraph.fromIterable(\n Array.from(modules).map(([moduleId, moduleInit]) => ({\n value: { moduleId, moduleInit },\n // Relationships are reversed at this point since we're only interested in the extension points.\n // If a modules provides extension point A we want it to be initialized AFTER all modules\n // that depend on extension point A, so that they can provide their extensions.\n consumes: Array.from(moduleInit.provides).map(p => p.id),\n provides: Array.from(moduleInit.consumes).map(c => c.id),\n })),\n );\n const circular = tree.detectCircularDependency();\n if (circular) {\n throw new ConflictError(\n `Circular dependency detected for modules of plugin '${pluginId}', ${circular\n .map(({ moduleId }) => `'${moduleId}'`)\n .join(' -> ')}`,\n );\n }\n await tree.parallelTopologicalTraversal(\n async ({ moduleId, moduleInit }) => {\n try {\n const moduleDeps = await this.#getInitDeps(\n moduleInit.init.deps,\n resultCollector,\n pluginId,\n moduleId,\n );\n await moduleInit.init.func(moduleDeps);\n resultCollector.onPluginModuleResult(pluginId, moduleId);\n } catch (error: unknown) {\n const err = toError(error);\n resultCollector.onPluginModuleResult(pluginId, moduleId, err);\n }\n },\n );\n }\n\n // Once all modules have been initialized, we can initialize the plugin itself\n const pluginInit = pluginInits.get(pluginId);\n // We allow modules to be installed without the accompanying plugin, so the plugin may not exist\n if (pluginInit) {\n const pluginDeps = await this.#getInitDeps(\n pluginInit.init.deps,\n resultCollector,\n pluginId,\n );\n await pluginInit.init.func(pluginDeps);\n }\n\n resultCollector.onPluginResult(pluginId);\n\n // Once the plugin and all modules have been initialized, we can signal that the plugin has stared up successfully\n const lifecycleService = await this.#getPluginLifecycleImpl(pluginId);\n await lifecycleService.startup();\n } catch (error: unknown) {\n const err = toError(error);\n resultCollector.onPluginResult(pluginId, err);\n }\n }),\n ).catch(error => {\n throw new ForwardedError(\n 'Unexpected uncaught backend startup error',\n error,\n );\n });\n\n const result = resultCollector.finalize();\n if (result.outcome === 'failure') {\n throw new BackendStartupError(result);\n }\n\n // Once all plugins and modules have been initialized, we can signal that the backend has started up successfully\n const lifecycleService = await this.#getRootLifecycleImpl();\n await lifecycleService.startup();\n\n return { result };\n }\n\n #enumerateRegistrations(\n allRegistrations: ReturnType<\n InternalBackendRegistrations['getRegistrations']\n >,\n resultCollector: ReturnType<typeof createInitializationResultCollector>,\n ): {\n pluginInits: Map<string, BackendRegisterInit>;\n moduleInits: Map<string, Map<string, BackendRegisterInit>>;\n } {\n const pluginInits = new Map<string, BackendRegisterInit>();\n const moduleInits = new Map<string, Map<string, BackendRegisterInit>>();\n\n for (const r of allRegistrations) {\n const pluginId =\n 'pluginId' in r && typeof r.pluginId === 'string'\n ? r.pluginId\n : undefined;\n const moduleId =\n 'moduleId' in r && typeof r.moduleId === 'string'\n ? r.moduleId\n : undefined;\n const addedExtensionPointIds: string[] = [];\n try {\n validateBackendRegistration(r);\n\n const provides = new Set<ExtensionPoint<unknown>>();\n\n if (r.type === 'plugin' || r.type === 'module') {\n // Handle v1 format: Array<readonly [ExtensionPoint<unknown>, unknown]>\n for (const [extRef, extImpl] of r.extensionPoints) {\n if (this.#extensionPoints.has(extRef.id)) {\n throw new Error(\n `ExtensionPoint with ID '${extRef.id}' is already registered`,\n );\n }\n this.#extensionPoints.set(extRef.id, {\n pluginId: r.pluginId,\n factory: () => extImpl,\n });\n addedExtensionPointIds.push(extRef.id);\n provides.add(extRef);\n }\n } else if (r.type === 'plugin-v1.1' || r.type === 'module-v1.1') {\n // Handle v1.1 format: Array<ExtensionPointRegistration>\n for (const extReg of r.extensionPoints) {\n if (this.#extensionPoints.has(extReg.extensionPoint.id)) {\n throw new Error(\n `ExtensionPoint with ID '${extReg.extensionPoint.id}' is already registered`,\n );\n }\n this.#extensionPoints.set(extReg.extensionPoint.id, {\n pluginId: r.pluginId,\n factory: extReg.factory,\n });\n addedExtensionPointIds.push(extReg.extensionPoint.id);\n provides.add(extReg.extensionPoint);\n }\n }\n\n if (r.type === 'plugin' || r.type === 'plugin-v1.1') {\n if (pluginInits.has(r.pluginId)) {\n throw new Error(`Plugin '${r.pluginId}' is already registered`);\n }\n pluginInits.set(r.pluginId, {\n provides,\n consumes: new Set(Object.values(r.init.deps)),\n init: r.init,\n });\n } else if (r.type === 'module' || r.type === 'module-v1.1') {\n let modules = moduleInits.get(r.pluginId);\n if (!modules) {\n modules = new Map();\n moduleInits.set(r.pluginId, modules);\n }\n if (modules.has(r.moduleId)) {\n throw new Error(\n `Module '${r.moduleId}' for plugin '${r.pluginId}' is already registered`,\n );\n }\n modules.set(r.moduleId, {\n provides,\n consumes: new Set(Object.values(r.init.deps)),\n init: r.init,\n });\n } else {\n throw new Error(`Invalid registration type '${(r as any).type}'`);\n }\n } catch (error: unknown) {\n const err = toError(error);\n // Clean up partially registered extension points\n for (const id of addedExtensionPointIds) {\n this.#extensionPoints.delete(id);\n }\n if (pluginId !== undefined && moduleId !== undefined) {\n resultCollector.onPluginModuleResult(pluginId, moduleId, err);\n } else if (pluginId !== undefined) {\n pluginInits.delete(pluginId);\n moduleInits.delete(pluginId);\n resultCollector.onPluginResult(pluginId, err);\n } else {\n throw err;\n }\n }\n }\n\n return { pluginInits, moduleInits };\n }\n\n // It's fine to call .stop() multiple times, which for example can happen with manual stop + process exit\n async stop(): Promise<void> {\n instanceRegistry.unregister(this);\n\n if (!this.#stopPromise) {\n this.#stopPromise = this.#doStop();\n }\n await this.#stopPromise;\n }\n\n async #doStop(): Promise<void> {\n if (!this.#startPromise) {\n return;\n }\n\n try {\n await this.#startPromise;\n } catch (error) {\n // The startup failed, but we may still want to do cleanup so we continue silently\n }\n\n const rootLifecycleService = await this.#getRootLifecycleImpl();\n\n // Root services like the health one need to immediately be notified of the shutdown\n await rootLifecycleService.beforeShutdown();\n\n // Get all plugins.\n const allPlugins = new Set<string>();\n for (const registration of this.#allRegistrations) {\n if (\n registration.type === 'plugin' ||\n registration.type === 'plugin-v1.1'\n ) {\n allPlugins.add(registration.pluginId);\n }\n }\n\n // Iterate through all plugins and run their shutdown hooks.\n await Promise.allSettled(\n [...allPlugins].map(async pluginId => {\n const lifecycleService = await this.#getPluginLifecycleImpl(pluginId);\n await lifecycleService.shutdown();\n }),\n );\n\n // Once all plugin shutdown hooks are done, run root shutdown hooks.\n await rootLifecycleService.shutdown();\n\n // Clean up process event listeners to prevent memory leaks and duplicate logging\n if (this.#unhandledRejectionHandler) {\n process.off('unhandledRejection', this.#unhandledRejectionHandler);\n this.#unhandledRejectionHandler = undefined;\n }\n if (this.#uncaughtExceptionHandler) {\n process.off('uncaughtException', this.#uncaughtExceptionHandler);\n this.#uncaughtExceptionHandler = undefined;\n }\n }\n\n // Bit of a hacky way to grab the lifecycle services, potentially find a nicer way to do this\n async #getRootLifecycleImpl(): Promise<\n RootLifecycleService & {\n startup(): Promise<void>;\n beforeShutdown(): Promise<void>;\n shutdown(): Promise<void>;\n }\n > {\n const lifecycleService = await this.#serviceRegistry.get(\n coreServices.rootLifecycle,\n 'root',\n );\n\n const service = lifecycleService as any;\n if (\n service &&\n typeof service.startup === 'function' &&\n typeof service.shutdown === 'function'\n ) {\n return service;\n }\n\n throw new Error('Unexpected root lifecycle service implementation');\n }\n\n async #getPluginLifecycleImpl(\n pluginId: string,\n ): Promise<\n LifecycleService & { startup(): Promise<void>; shutdown(): Promise<void> }\n > {\n const lifecycleService = await this.#serviceRegistry.get(\n coreServices.lifecycle,\n pluginId,\n );\n\n const service = lifecycleService as any;\n if (\n service &&\n typeof service.startup === 'function' &&\n typeof service.shutdown === 'function'\n ) {\n return service;\n }\n\n throw new Error('Unexpected plugin lifecycle service implementation');\n }\n\n async #applyBackendFeatureLoaders(loaders: InstalledFeatureLoader[]) {\n const servicesAddedByLoaders = new Map<string, InstalledFeatureLoader>();\n\n for (const installedLoader of loaders) {\n const { feature: loader, source: loaderSource } = installedLoader;\n if (loader.deps !== undefined) {\n assertObject(\n loader.deps,\n `${loaderSource}.deps`,\n 'a dependency object',\n );\n }\n\n const deps = new Map<string, unknown>();\n const missingRefs = new Set<ServiceOrExtensionPoint>();\n\n for (const [name, ref] of Object.entries(loader.deps ?? {})) {\n validateServiceRef(ref, `${loaderSource}.deps.${name}`);\n if (ref.scope !== 'root') {\n throw new Error(\n `Feature loaders can only depend on root scoped services, but '${name}' is scoped to '${ref.scope}'. Offending loader is ${loader.description}`,\n );\n }\n const impl = await this.#serviceRegistry.get(\n ref as ServiceRef<unknown>,\n 'root',\n );\n if (impl) {\n deps.set(name, impl);\n } else {\n missingRefs.add(ref);\n }\n }\n\n if (missingRefs.size > 0) {\n const missing = Array.from(missingRefs).join(', ');\n throw new Error(\n `No service available for the following ref(s): ${missing}, depended on by feature loader ${loader.description}`,\n );\n }\n\n let result: unknown;\n try {\n result = await loader.loader(Object.fromEntries(deps));\n } catch (error) {\n throw new ForwardedError(\n `Feature loader ${loader.description} failed`,\n error,\n );\n }\n if (!Array.isArray(result)) {\n throwInvalidBackendFeature(\n `${loaderSource} -> loader output`,\n 'an array of backend features',\n result,\n );\n }\n\n const loadedFeatures = result.map((feature, index) => {\n const fallbackSource = `${loaderSource} -> loader output[${index}]`;\n const unwrappedFeature = unwrapFeature(\n feature as BackendFeature | { default: BackendFeature },\n );\n const description = describeBackendFeature(unwrappedFeature);\n const source = description\n ? `${description} (returned by ${loaderSource}, output[${index}])`\n : fallbackSource;\n return {\n feature: validateBackendFeature(unwrappedFeature, source),\n source,\n };\n });\n\n let didAddServiceFactory = false;\n const newLoaders = new Array<InstalledFeatureLoader>();\n\n for (const loadedFeature of loadedFeatures) {\n const { feature, source } = loadedFeature;\n if (feature.type === 'loader') {\n newLoaders.push({ feature: feature.feature, source });\n } else if (feature.type === 'service') {\n validateServiceRef(feature.feature.service, `${source}.service`);\n\n // This block makes sure that feature loaders do not provide duplicate\n // implementations for the same service, but at the same time allows\n // service factories provided by feature loaders to be overridden by\n // ones that are explicitly installed with backend.add(serviceFactory).\n //\n // If a factory has already been explicitly installed, the service\n // factory provided by the loader will simply be ignored.\n if (!feature.feature.service.multiton) {\n const conflictingLoader = servicesAddedByLoaders.get(\n feature.feature.service.id,\n );\n if (conflictingLoader) {\n throw new Error(\n `Duplicate service implementations provided for ${feature.feature.service.id} by both feature loader ${loader.description} and feature loader ${conflictingLoader.feature.description}`,\n );\n }\n\n // Check that this service wasn't already explicitly added by backend.add(serviceFactory)\n if (!this.#serviceRegistry.hasBeenAdded(feature.feature.service)) {\n didAddServiceFactory = true;\n servicesAddedByLoaders.set(\n feature.feature.service.id,\n installedLoader,\n );\n this.#addFeature(feature, source);\n }\n } else {\n this.#addFeature(feature, source);\n }\n } else {\n this.#addFeature(feature, source);\n }\n }\n\n // Every time we add a new service factory we need to make sure that we don't have circular dependencies\n if (didAddServiceFactory) {\n this.#serviceRegistry.checkForCircularDeps();\n }\n\n // Apply loaders recursively, depth-first\n if (newLoaders.length > 0) {\n await this.#applyBackendFeatureLoaders(newLoaders);\n }\n }\n }\n}\n"],"names":["createServiceFactory","coreServices","deepFreeze","ServiceRegistry","OpaqueExtensionPointFactoryMiddleware","connectionsServiceRef","withDeclaredConnections","describeBackendFeature","validateBackendFeature","validateBackendRegistrations","rootLogger","createInitializationResultCollector","createAllowBootFailurePredicate","DependencyGraph","ConflictError","toError","lifecycleService","ForwardedError","BackendStartupError","validateBackendRegistration","assertObject","validateServiceRef","throwInvalidBackendFeature","unwrapFeature"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"BackendInitializer.cjs.js","sources":["../../src/wiring/BackendInitializer.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 {\n BackendFeature,\n ExtensionPoint,\n coreServices,\n ServiceRef,\n ServiceFactory,\n LifecycleService,\n RootLifecycleService,\n createServiceFactory,\n ExtensionPointFactoryContext,\n} from '@backstage/backend-plugin-api';\nimport type { ConnectionRegistration } from '@backstage/backend-plugin-api/alpha';\nimport {\n ExtensionPointFactoryMiddleware,\n ServiceOrExtensionPoint,\n} from './types';\nimport {\n OpaqueExtensionPointFactoryMiddleware,\n unwrapFeature,\n} from '@internal/backend';\n// Direct internal import to avoid duplication\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport type {\n InternalBackendFeatureLoader,\n InternalBackendRegistrations,\n} from '../../../backend-plugin-api/src/wiring/types';\nimport { ConflictError, ForwardedError, toError } from '@backstage/errors';\nimport { DependencyGraph } from '../lib/DependencyGraph';\nimport { ServiceRegistry } from './ServiceRegistry';\nimport { createInitializationResultCollector } from './createInitializationResultCollector';\nimport { deepFreeze } from './helpers';\nimport type { RootInstanceMetadataServicePluginInfo } from '@backstage/backend-plugin-api';\nimport { BackendStartupResult } from './types';\nimport { BackendStartupError } from './BackendStartupError';\nimport { createAllowBootFailurePredicate } from './createAllowBootFailurePredicate';\nimport type { ConnectionsService } from '@backstage/connections';\nimport { connectionsServiceRef } from '@backstage/connections-node';\nimport { withDeclaredConnections } from './withDeclaredConnections';\nimport {\n assertObject,\n describeBackendFeature,\n throwInvalidBackendFeature,\n validateBackendFeature,\n validateBackendRegistration,\n validateBackendRegistrations,\n validateServiceRef,\n type ValidatedBackendFeature,\n} from './validateBackendFeature';\n\nexport interface BackendRegisterInit {\n consumes: Set<ServiceOrExtensionPoint>;\n provides: Set<ServiceOrExtensionPoint>;\n init: {\n deps: { [name: string]: ServiceOrExtensionPoint };\n func: (deps: { [name: string]: unknown }) => Promise<void>;\n };\n}\n\ntype InstalledFeatureLoader = {\n feature: InternalBackendFeatureLoader;\n source: string;\n};\n\n/**\n * A registry of backend instances, used to manage process shutdown hooks across all instances.\n */\nconst instanceRegistry = new (class InstanceRegistry {\n #registered = false;\n #instances = new Set<BackendInitializer>();\n\n register(instance: BackendInitializer) {\n if (!this.#registered) {\n this.#registered = true;\n\n process.addListener('SIGTERM', this.#exitHandler);\n process.addListener('SIGINT', this.#exitHandler);\n process.addListener('beforeExit', this.#exitHandler);\n }\n\n this.#instances.add(instance);\n }\n\n unregister(instance: BackendInitializer) {\n this.#instances.delete(instance);\n }\n\n #exitHandler = async () => {\n try {\n const results = await Promise.allSettled(\n Array.from(this.#instances).map(b => b.stop()),\n );\n const errors = results.flatMap(r =>\n r.status === 'rejected' ? [r.reason] : [],\n );\n\n if (errors.length > 0) {\n for (const error of errors) {\n console.error(error);\n }\n process.exit(1);\n } else {\n process.exit(0);\n }\n } catch (error) {\n console.error(error);\n process.exit(1);\n }\n };\n})();\n\nfunction callerKey(pluginId: string, moduleId?: string): string {\n return moduleId ? `${pluginId}\\0${moduleId}` : pluginId;\n}\n\nfunction collectCallerConnectionRegistrations(\n registrations: ReturnType<InternalBackendRegistrations['getRegistrations']>,\n): Map<string, ConnectionRegistration[]> {\n const byCaller = new Map<string, ConnectionRegistration[]>();\n\n for (const registration of registrations) {\n const declared =\n 'connections' in registration && Array.isArray(registration.connections)\n ? registration.connections\n : [];\n if (declared.length === 0) continue;\n\n const key =\n 'moduleId' in registration\n ? callerKey(registration.pluginId, registration.moduleId)\n : callerKey(registration.pluginId);\n\n const target =\n byCaller.get(key) ??\n (() => {\n const list: ConnectionRegistration[] = [];\n byCaller.set(key, list);\n return list;\n })();\n\n for (const decl of declared) {\n if (!target.some(c => c.type === decl.type)) {\n target.push({ ...decl });\n }\n }\n }\n\n return byCaller;\n}\n\nfunction createRootInstanceMetadataServiceFactory(\n registrations: ReturnType<InternalBackendRegistrations['getRegistrations']>,\n) {\n const installedPlugins: Map<string, RootInstanceMetadataServicePluginInfo> =\n new Map();\n const plugins = registrations.filter(\n registration =>\n registration.type === 'plugin' || registration.type === 'plugin-v1.1',\n );\n const modules = registrations.filter(\n registration =>\n registration.type === 'module' || registration.type === 'module-v1.1',\n );\n for (const plugin of plugins) {\n const { pluginId } = plugin;\n if (!installedPlugins.get(pluginId)) {\n installedPlugins.set(pluginId, {\n pluginId,\n modules: [],\n });\n }\n }\n for (const module of modules) {\n const { pluginId, moduleId } = module;\n const installedPlugin = installedPlugins.get(pluginId);\n if (installedPlugin) {\n (installedPlugin.modules as Array<{ moduleId: string }>).push({\n moduleId,\n });\n }\n }\n\n return createServiceFactory({\n service: coreServices.rootInstanceMetadata,\n deps: {},\n factory: async () => {\n const readonlyInstalledPlugins = deepFreeze([\n ...installedPlugins.values(),\n ]);\n const instanceMetadata = {\n getInstalledPlugins: () => Promise.resolve(readonlyInstalledPlugins),\n };\n\n return instanceMetadata;\n },\n });\n}\n\nexport class BackendInitializer {\n #startPromise?: Promise<{ result: BackendStartupResult }>;\n #stopPromise?: Promise<void>;\n #registrations = new Array<{\n feature: InternalBackendRegistrations;\n source: string;\n }>();\n #allRegistrations = new Array<\n ReturnType<InternalBackendRegistrations['getRegistrations']>[number]\n >();\n #extensionPoints = new Map<\n string,\n {\n pluginId: string;\n factory: (context: ExtensionPointFactoryContext) => unknown;\n }\n >();\n #serviceRegistry: ServiceRegistry;\n #registeredFeatures = new Array<{\n feature: Promise<BackendFeature>;\n source: string;\n }>();\n #registeredFeatureLoaders = new Array<InstalledFeatureLoader>();\n #extensionPointFactoryMiddleware: ExtensionPointFactoryMiddleware[];\n #callerConnectionRegistrations = new Map<string, ConnectionRegistration[]>();\n\n #getConnectionRegistrations(\n pluginId: string,\n moduleId?: string,\n ): ConnectionRegistration[] {\n if (moduleId) {\n return (\n this.#callerConnectionRegistrations.get(\n callerKey(pluginId, moduleId),\n ) ?? []\n );\n }\n // Aggregate registrations from the plugin\n const result: ConnectionRegistration[] = [];\n for (const [key, registrations] of this.#callerConnectionRegistrations) {\n if (key === pluginId) {\n result.push(...registrations);\n }\n }\n return result;\n }\n\n #unhandledRejectionHandler?: (reason: Error) => void;\n #uncaughtExceptionHandler?: (error: Error) => void;\n\n constructor(\n defaultApiFactories: ServiceFactory[],\n extensionPointFactoryMiddleware?: ExtensionPointFactoryMiddleware[],\n ) {\n this.#serviceRegistry = ServiceRegistry.create([...defaultApiFactories]);\n this.#extensionPointFactoryMiddleware =\n extensionPointFactoryMiddleware ?? [];\n }\n\n async #getInitDeps(\n deps: { [name: string]: ServiceOrExtensionPoint },\n resultCollector: ReturnType<typeof createInitializationResultCollector>,\n pluginId: string,\n moduleId?: string,\n ) {\n const result = new Map<string, unknown>();\n const missingRefs = new Set<ServiceOrExtensionPoint>();\n\n for (const [name, ref] of Object.entries(deps)) {\n const ep = this.#extensionPoints.get(ref.id);\n if (ep) {\n if (ep.pluginId !== pluginId) {\n throw new Error(\n `Illegal dependency: Module '${moduleId}' for plugin '${pluginId}' attempted to depend on extension point '${ref.id}' for plugin '${ep.pluginId}'. Extension points can only be used within their plugin's scope.`,\n );\n }\n if (!moduleId) {\n throw new Error(\n `Rejected dependency on extension point ${ref.id} from outside of a module`,\n );\n }\n let epImpl = ep.factory({\n reportModuleStartupFailure: ({ error }) => {\n resultCollector.amendPluginModuleResult(pluginId, moduleId, error);\n },\n });\n for (const mw of this.#extensionPointFactoryMiddleware) {\n const internal = OpaqueExtensionPointFactoryMiddleware.toInternal(mw);\n if (internal.extensionPointId === ref.id) {\n epImpl = await internal.middleware(epImpl);\n }\n }\n result.set(name, epImpl);\n } else {\n const impl = await this.#serviceRegistry.get(\n ref as ServiceRef<unknown>,\n pluginId,\n );\n if (impl) {\n if (ref.id === connectionsServiceRef.id) {\n const registrations = this.#getConnectionRegistrations(\n pluginId,\n moduleId,\n );\n result.set(\n name,\n withDeclaredConnections(\n impl as ConnectionsService,\n registrations,\n ),\n );\n } else {\n result.set(name, impl);\n }\n } else {\n missingRefs.add(ref);\n }\n }\n }\n\n if (missingRefs.size > 0) {\n const missing = Array.from(missingRefs).join(', ');\n const target = moduleId\n ? `module '${moduleId}' for plugin '${pluginId}'`\n : `plugin '${pluginId}'`;\n throw new Error(\n `Service or extension point dependencies of ${target} are missing for the following ref(s): ${missing}`,\n );\n }\n\n return Object.fromEntries(result);\n }\n\n add(feature: BackendFeature | Promise<BackendFeature>) {\n if (this.#startPromise) {\n throw new Error('feature can not be added after the backend has started');\n }\n this.#registeredFeatures.push({\n feature: Promise.resolve(feature),\n source: `features[${this.#registeredFeatures.length}]`,\n });\n }\n\n #addFeature(feature: ValidatedBackendFeature, source: string) {\n if (feature.type === 'service') {\n this.#serviceRegistry.add(feature.feature, source);\n } else if (feature.type === 'loader') {\n this.#registeredFeatureLoaders.push({\n feature: feature.feature,\n source,\n });\n } else {\n this.#registrations.push({\n feature: feature.feature,\n source,\n });\n }\n }\n\n async start(): Promise<{ result: BackendStartupResult }> {\n if (this.#startPromise) {\n throw new Error('Backend has already started');\n }\n if (this.#stopPromise) {\n throw new Error('Backend has already stopped');\n }\n\n instanceRegistry.register(this);\n\n this.#startPromise = this.#doStart();\n return await this.#startPromise;\n }\n\n async #doStart(): Promise<{ result: BackendStartupResult }> {\n this.#serviceRegistry.checkForCircularDeps();\n\n for (const { feature, source: fallbackSource } of this\n .#registeredFeatures) {\n const resolvedFeature = await feature;\n const source = describeBackendFeature(resolvedFeature) ?? fallbackSource;\n this.#addFeature(validateBackendFeature(resolvedFeature, source), source);\n }\n\n await this.#applyBackendFeatureLoaders(this.#registeredFeatureLoaders);\n\n this.#allRegistrations = this.#registrations.flatMap(\n ({ feature, source }) => validateBackendRegistrations(feature, source),\n );\n\n this.#serviceRegistry.add(\n createRootInstanceMetadataServiceFactory(this.#allRegistrations),\n );\n\n // This makes sure that any uncaught errors or unhandled rejections are\n // caught and logged, rather than terminating the process. We register these\n // as early as possible while still using the root logger service, the\n // tradeoff that if there are any unhandled errors as part of the that\n // instationation, it will cause the process to crash. If there are multiple\n // backend instances, each instance will log the error, because we can't\n // determine which instance the error came from.\n if (process.env.NODE_ENV !== 'test') {\n const rootLogger = await this.#serviceRegistry.get(\n coreServices.rootLogger,\n 'root',\n );\n this.#unhandledRejectionHandler = (reason: Error) => {\n rootLogger\n ?.child({ type: 'unhandledRejection' })\n ?.error('Unhandled rejection', reason);\n };\n this.#uncaughtExceptionHandler = (error: Error) => {\n rootLogger\n ?.child({ type: 'uncaughtException' })\n ?.error('Uncaught exception', error);\n };\n process.on('unhandledRejection', this.#unhandledRejectionHandler);\n process.on('uncaughtException', this.#uncaughtExceptionHandler);\n }\n\n // Initialize all root scoped services\n await this.#serviceRegistry.initializeEagerServicesWithScope('root');\n\n const rootConfig = await this.#serviceRegistry.get(\n coreServices.rootConfig,\n 'root',\n );\n const rootLogger = await this.#serviceRegistry.get(\n coreServices.rootLogger,\n 'root',\n );\n\n const allRegistrations = this.#allRegistrations;\n\n this.#callerConnectionRegistrations =\n collectCallerConnectionRegistrations(allRegistrations);\n\n const allPluginIds = [\n ...new Set(\n allRegistrations.flatMap(r =>\n 'pluginId' in r && typeof r.pluginId === 'string' ? [r.pluginId] : [],\n ),\n ),\n ];\n\n const resultCollector = createInitializationResultCollector({\n pluginIds: allPluginIds,\n logger: rootLogger,\n allowBootFailurePredicate: createAllowBootFailurePredicate(rootConfig),\n });\n\n const { pluginInits, moduleInits } = this.#enumerateRegistrations(\n allRegistrations,\n resultCollector,\n );\n\n // All plugins are initialized in parallel\n await Promise.all(\n [...pluginInits.keys()].map(async pluginId => {\n try {\n // Initialize all eager services\n await this.#serviceRegistry.initializeEagerServicesWithScope(\n 'plugin',\n pluginId,\n );\n\n // Modules are initialized before plugins, so that they can provide extension to the plugin\n const modules = moduleInits.get(pluginId);\n if (modules) {\n const tree = DependencyGraph.fromIterable(\n Array.from(modules).map(([moduleId, moduleInit]) => ({\n value: { moduleId, moduleInit },\n // Relationships are reversed at this point since we're only interested in the extension points.\n // If a modules provides extension point A we want it to be initialized AFTER all modules\n // that depend on extension point A, so that they can provide their extensions.\n consumes: Array.from(moduleInit.provides).map(p => p.id),\n provides: Array.from(moduleInit.consumes).map(c => c.id),\n })),\n );\n const circular = tree.detectCircularDependency();\n if (circular) {\n throw new ConflictError(\n `Circular dependency detected for modules of plugin '${pluginId}', ${circular\n .map(({ moduleId }) => `'${moduleId}'`)\n .join(' -> ')}`,\n );\n }\n await tree.parallelTopologicalTraversal(\n async ({ moduleId, moduleInit }) => {\n try {\n const moduleDeps = await this.#getInitDeps(\n moduleInit.init.deps,\n resultCollector,\n pluginId,\n moduleId,\n );\n await moduleInit.init.func(moduleDeps);\n resultCollector.onPluginModuleResult(pluginId, moduleId);\n } catch (error: unknown) {\n const err = toError(error);\n resultCollector.onPluginModuleResult(pluginId, moduleId, err);\n }\n },\n );\n }\n\n // Once all modules have been initialized, we can initialize the plugin itself\n const pluginInit = pluginInits.get(pluginId);\n // We allow modules to be installed without the accompanying plugin, so the plugin may not exist\n if (pluginInit) {\n const pluginDeps = await this.#getInitDeps(\n pluginInit.init.deps,\n resultCollector,\n pluginId,\n );\n await pluginInit.init.func(pluginDeps);\n }\n\n resultCollector.onPluginResult(pluginId);\n\n // Once the plugin and all modules have been initialized, we can signal that the plugin has stared up successfully\n const lifecycleService = await this.#getPluginLifecycleImpl(pluginId);\n await lifecycleService.startup();\n } catch (error: unknown) {\n const err = toError(error);\n resultCollector.onPluginResult(pluginId, err);\n }\n }),\n ).catch(error => {\n throw new ForwardedError(\n 'Unexpected uncaught backend startup error',\n error,\n );\n });\n\n const result = resultCollector.finalize();\n if (result.outcome === 'failure') {\n throw new BackendStartupError(result);\n }\n\n // Once all plugins and modules have been initialized, we can signal that the backend has started up successfully\n const lifecycleService = await this.#getRootLifecycleImpl();\n await lifecycleService.startup();\n\n return { result };\n }\n\n #enumerateRegistrations(\n allRegistrations: ReturnType<\n InternalBackendRegistrations['getRegistrations']\n >,\n resultCollector: ReturnType<typeof createInitializationResultCollector>,\n ): {\n pluginInits: Map<string, BackendRegisterInit>;\n moduleInits: Map<string, Map<string, BackendRegisterInit>>;\n } {\n const pluginInits = new Map<string, BackendRegisterInit>();\n const moduleInits = new Map<string, Map<string, BackendRegisterInit>>();\n\n for (const r of allRegistrations) {\n const pluginId =\n 'pluginId' in r && typeof r.pluginId === 'string'\n ? r.pluginId\n : undefined;\n const moduleId =\n 'moduleId' in r && typeof r.moduleId === 'string'\n ? r.moduleId\n : undefined;\n const addedExtensionPointIds: string[] = [];\n try {\n validateBackendRegistration(r);\n\n const provides = new Set<ExtensionPoint<unknown>>();\n\n if (r.type === 'plugin' || r.type === 'module') {\n // Handle v1 format: Array<readonly [ExtensionPoint<unknown>, unknown]>\n for (const [extRef, extImpl] of r.extensionPoints) {\n if (this.#extensionPoints.has(extRef.id)) {\n throw new Error(\n `ExtensionPoint with ID '${extRef.id}' is already registered`,\n );\n }\n this.#extensionPoints.set(extRef.id, {\n pluginId: r.pluginId,\n factory: () => extImpl,\n });\n addedExtensionPointIds.push(extRef.id);\n provides.add(extRef);\n }\n } else if (r.type === 'plugin-v1.1' || r.type === 'module-v1.1') {\n // Handle v1.1 format: Array<ExtensionPointRegistration>\n for (const extReg of r.extensionPoints) {\n if (this.#extensionPoints.has(extReg.extensionPoint.id)) {\n throw new Error(\n `ExtensionPoint with ID '${extReg.extensionPoint.id}' is already registered`,\n );\n }\n this.#extensionPoints.set(extReg.extensionPoint.id, {\n pluginId: r.pluginId,\n factory: extReg.factory,\n });\n addedExtensionPointIds.push(extReg.extensionPoint.id);\n provides.add(extReg.extensionPoint);\n }\n }\n\n if (r.type === 'plugin' || r.type === 'plugin-v1.1') {\n if (pluginInits.has(r.pluginId)) {\n throw new Error(`Plugin '${r.pluginId}' is already registered`);\n }\n pluginInits.set(r.pluginId, {\n provides,\n consumes: new Set(Object.values(r.init.deps)),\n init: r.init,\n });\n } else if (r.type === 'module' || r.type === 'module-v1.1') {\n let modules = moduleInits.get(r.pluginId);\n if (!modules) {\n modules = new Map();\n moduleInits.set(r.pluginId, modules);\n }\n if (modules.has(r.moduleId)) {\n throw new Error(\n `Module '${r.moduleId}' for plugin '${r.pluginId}' is already registered`,\n );\n }\n modules.set(r.moduleId, {\n provides,\n consumes: new Set(Object.values(r.init.deps)),\n init: r.init,\n });\n } else {\n throw new Error(`Invalid registration type '${(r as any).type}'`);\n }\n } catch (error: unknown) {\n const err = toError(error);\n // Clean up partially registered extension points\n for (const id of addedExtensionPointIds) {\n this.#extensionPoints.delete(id);\n }\n if (pluginId !== undefined && moduleId !== undefined) {\n resultCollector.onPluginModuleResult(pluginId, moduleId, err);\n } else if (pluginId !== undefined) {\n pluginInits.delete(pluginId);\n moduleInits.delete(pluginId);\n resultCollector.onPluginResult(pluginId, err);\n } else {\n throw err;\n }\n }\n }\n\n return { pluginInits, moduleInits };\n }\n\n // It's fine to call .stop() multiple times, which for example can happen with manual stop + process exit\n async stop(): Promise<void> {\n instanceRegistry.unregister(this);\n\n if (!this.#stopPromise) {\n this.#stopPromise = this.#doStop();\n }\n await this.#stopPromise;\n }\n\n async #doStop(): Promise<void> {\n if (!this.#startPromise) {\n return;\n }\n\n try {\n await this.#startPromise;\n } catch (error) {\n // The startup failed, but we may still want to do cleanup so we continue silently\n }\n\n const rootLifecycleService = await this.#getRootLifecycleImpl();\n\n // Root services like the health one need to immediately be notified of the shutdown\n await rootLifecycleService.beforeShutdown();\n\n // Get all plugins.\n const allPlugins = new Set<string>();\n for (const registration of this.#allRegistrations) {\n if (\n registration.type === 'plugin' ||\n registration.type === 'plugin-v1.1'\n ) {\n allPlugins.add(registration.pluginId);\n }\n }\n\n // Iterate through all plugins and run their shutdown hooks.\n await Promise.allSettled(\n [...allPlugins].map(async pluginId => {\n const lifecycleService = await this.#getPluginLifecycleImpl(pluginId);\n await lifecycleService.shutdown();\n }),\n );\n\n // Once all plugin shutdown hooks are done, run root shutdown hooks.\n await rootLifecycleService.shutdown();\n\n // Clean up process event listeners to prevent memory leaks and duplicate logging\n if (this.#unhandledRejectionHandler) {\n process.off('unhandledRejection', this.#unhandledRejectionHandler);\n this.#unhandledRejectionHandler = undefined;\n }\n if (this.#uncaughtExceptionHandler) {\n process.off('uncaughtException', this.#uncaughtExceptionHandler);\n this.#uncaughtExceptionHandler = undefined;\n }\n }\n\n // Bit of a hacky way to grab the lifecycle services, potentially find a nicer way to do this\n async #getRootLifecycleImpl(): Promise<\n RootLifecycleService & {\n startup(): Promise<void>;\n beforeShutdown(): Promise<void>;\n shutdown(): Promise<void>;\n }\n > {\n const lifecycleService = await this.#serviceRegistry.get(\n coreServices.rootLifecycle,\n 'root',\n );\n\n const service = lifecycleService as any;\n if (\n service &&\n typeof service.startup === 'function' &&\n typeof service.shutdown === 'function'\n ) {\n return service;\n }\n\n throw new Error('Unexpected root lifecycle service implementation');\n }\n\n async #getPluginLifecycleImpl(\n pluginId: string,\n ): Promise<\n LifecycleService & { startup(): Promise<void>; shutdown(): Promise<void> }\n > {\n const lifecycleService = await this.#serviceRegistry.get(\n coreServices.lifecycle,\n pluginId,\n );\n\n const service = lifecycleService as any;\n if (\n service &&\n typeof service.startup === 'function' &&\n typeof service.shutdown === 'function'\n ) {\n return service;\n }\n\n throw new Error('Unexpected plugin lifecycle service implementation');\n }\n\n async #applyBackendFeatureLoaders(loaders: InstalledFeatureLoader[]) {\n const servicesAddedByLoaders = new Map<string, InstalledFeatureLoader>();\n\n for (const installedLoader of loaders) {\n const { feature: loader, source: loaderSource } = installedLoader;\n if (loader.deps !== undefined) {\n assertObject(\n loader.deps,\n `${loaderSource}.deps`,\n 'a dependency object',\n );\n }\n\n const deps = new Map<string, unknown>();\n const missingRefs = new Set<ServiceOrExtensionPoint>();\n\n for (const [name, ref] of Object.entries(loader.deps ?? {})) {\n validateServiceRef(ref, `${loaderSource}.deps.${name}`);\n if (ref.scope !== 'root') {\n throw new Error(\n `Feature loaders can only depend on root scoped services, but '${name}' is scoped to '${ref.scope}'. Offending loader is ${loader.description}`,\n );\n }\n const impl = await this.#serviceRegistry.get(\n ref as ServiceRef<unknown>,\n 'root',\n );\n if (impl) {\n deps.set(name, impl);\n } else {\n missingRefs.add(ref);\n }\n }\n\n if (missingRefs.size > 0) {\n const missing = Array.from(missingRefs).join(', ');\n throw new Error(\n `No service available for the following ref(s): ${missing}, depended on by feature loader ${loader.description}`,\n );\n }\n\n let result: unknown;\n try {\n result = await loader.loader(Object.fromEntries(deps));\n } catch (error) {\n throw new ForwardedError(\n `Feature loader ${loader.description} failed`,\n error,\n );\n }\n if (!Array.isArray(result)) {\n throwInvalidBackendFeature(\n `${loaderSource} -> loader output`,\n 'an array of backend features',\n result,\n );\n }\n\n const loadedFeatures = result.map((feature, index) => {\n const fallbackSource = `${loaderSource} -> loader output[${index}]`;\n const unwrappedFeature = unwrapFeature(\n feature as BackendFeature | { default: BackendFeature },\n );\n const description = describeBackendFeature(unwrappedFeature);\n const source = description\n ? `${description} (returned by ${loaderSource}, output[${index}])`\n : fallbackSource;\n return {\n feature: validateBackendFeature(unwrappedFeature, source),\n source,\n };\n });\n\n let didAddServiceFactory = false;\n const newLoaders = new Array<InstalledFeatureLoader>();\n\n for (const loadedFeature of loadedFeatures) {\n const { feature, source } = loadedFeature;\n if (feature.type === 'loader') {\n newLoaders.push({ feature: feature.feature, source });\n } else if (feature.type === 'service') {\n validateServiceRef(feature.feature.service, `${source}.service`);\n\n // This block makes sure that feature loaders do not provide duplicate\n // implementations for the same service, but at the same time allows\n // service factories provided by feature loaders to be overridden by\n // ones that are explicitly installed with backend.add(serviceFactory).\n //\n // If a factory has already been explicitly installed, the service\n // factory provided by the loader will simply be ignored.\n if (!feature.feature.service.multiton) {\n const conflictingLoader = servicesAddedByLoaders.get(\n feature.feature.service.id,\n );\n if (conflictingLoader) {\n throw new Error(\n `Duplicate service implementations provided for ${feature.feature.service.id} by both feature loader ${loader.description} and feature loader ${conflictingLoader.feature.description}`,\n );\n }\n\n // Check that this service wasn't already explicitly added by backend.add(serviceFactory)\n if (!this.#serviceRegistry.hasBeenAdded(feature.feature.service)) {\n didAddServiceFactory = true;\n servicesAddedByLoaders.set(\n feature.feature.service.id,\n installedLoader,\n );\n this.#addFeature(feature, source);\n }\n } else {\n this.#addFeature(feature, source);\n }\n } else {\n this.#addFeature(feature, source);\n }\n }\n\n // Every time we add a new service factory we need to make sure that we don't have circular dependencies\n if (didAddServiceFactory) {\n this.#serviceRegistry.checkForCircularDeps();\n }\n\n // Apply loaders recursively, depth-first\n if (newLoaders.length > 0) {\n await this.#applyBackendFeatureLoaders(newLoaders);\n }\n }\n }\n}\n"],"names":["createServiceFactory","coreServices","deepFreeze","ServiceRegistry","OpaqueExtensionPointFactoryMiddleware","connectionsServiceRef","withDeclaredConnections","describeBackendFeature","validateBackendFeature","validateBackendRegistrations","rootLogger","createInitializationResultCollector","createAllowBootFailurePredicate","DependencyGraph","ConflictError","toError","lifecycleService","ForwardedError","BackendStartupError","validateBackendRegistration","assertObject","validateServiceRef","throwInvalidBackendFeature","unwrapFeature"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BackendStartupError.cjs.js","sources":["../../src/wiring/BackendStartupError.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 { CustomErrorBase } from '@backstage/errors';\nimport { BackendStartupResult } from './types';\n\nfunction formatMessage(startupResult: BackendStartupResult): string {\n const parts: string[] = [\n 'Backend startup failed due to the following errors:',\n ];\n const failures: string[] = [];\n\n for (const plugin of startupResult.plugins) {\n if (plugin.failure && !plugin.failure.allowed) {\n failures.push(\n ` Plugin '${plugin.pluginId}' startup failed; caused by ${plugin.failure.error}`,\n );\n }\n\n for (const mod of plugin.modules) {\n if (mod.failure && !mod.failure.allowed) {\n failures.push(\n ` Module '${mod.moduleId}' for plugin '${plugin.pluginId}' startup failed; caused by ${mod.failure.error}`,\n );\n }\n }\n }\n\n if (failures.length > 0) {\n parts.push(...failures);\n }\n\n return parts.join('\\n');\n}\n\n/**\n * Error thrown when backend startup fails.\n * Includes detailed startup results for all plugins and modules.\n *\n * @public\n */\nexport class BackendStartupError extends CustomErrorBase {\n name = 'BackendStartupError' as const;\n\n /**\n * The startup results for all plugins and modules.\n */\n readonly #startupResult: BackendStartupResult;\n\n constructor(startupResult: BackendStartupResult) {\n super(formatMessage(startupResult));\n this.#startupResult = startupResult;\n }\n\n get result(): BackendStartupResult {\n return this.#startupResult;\n }\n}\n"],"names":["CustomErrorBase"],"mappings":";;;;AAmBA,SAAS,cAAc,aAAA,EAA6C;AAClE,EAAA,MAAM,KAAA,GAAkB;AAAA,IACtB;AAAA,GACF;AACA,EAAA,MAAM,WAAqB,EAAC;AAE5B,EAAA,KAAA,MAAW,MAAA,IAAU,cAAc,OAAA,EAAS;AAC1C,IAAA,IAAI,MAAA,CAAO,OAAA,IAAW,CAAC,MAAA,CAAO,QAAQ,OAAA,EAAS;AAC7C,MAAA,QAAA,CAAS,IAAA;AAAA,QACP,aAAa,MAAA,CAAO,QAAQ,CAAA,4BAAA,EAA+B,MAAA,CAAO,QAAQ,KAAK,CAAA;AAAA,OACjF;AAAA,IACF;AAEA,IAAA,KAAA,MAAW,GAAA,IAAO,OAAO,OAAA,EAAS;AAChC,MAAA,IAAI,GAAA,CAAI,OAAA,IAAW,CAAC,GAAA,CAAI,QAAQ,OAAA,EAAS;AACvC,QAAA,QAAA,CAAS,IAAA;AAAA,UACP,CAAA,UAAA,EAAa,IAAI,QAAQ,CAAA,cAAA,EAAiB,OAAO,QAAQ,CAAA,4BAAA,EAA+B,GAAA,CAAI,OAAA,CAAQ,KAAK,CAAA;AAAA,SAC3G;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,EAAA,IAAI,QAAA,CAAS,SAAS,CAAA,EAAG;AACvB,IAAA,KAAA,CAAM,IAAA,CAAK,GAAG,QAAQ,CAAA;AAAA,EACxB;AAEA,EAAA,OAAO,KAAA,CAAM,KAAK,IAAI,CAAA;AACxB;AAQO,MAAM,4BAA4BA,sBAAA,CAAgB;AAAA,EACvD,IAAA,GAAO,qBAAA;AAAA;AAAA;AAAA;AAAA,EAKE,cAAA;AAAA,EAET,YAAY,aAAA,EAAqC;AAC/C,IAAA,KAAA,CAAM,aAAA,CAAc,aAAa,CAAC,CAAA;AAClC,IAAA,IAAA,CAAK,cAAA,GAAiB,aAAA;AAAA,EACxB;AAAA,EAEA,IAAI,MAAA,GAA+B;AACjC,IAAA,OAAO,IAAA,CAAK,cAAA;AAAA,EACd;AACF
|
|
1
|
+
{"version":3,"file":"BackendStartupError.cjs.js","sources":["../../src/wiring/BackendStartupError.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 { CustomErrorBase } from '@backstage/errors';\nimport { BackendStartupResult } from './types';\n\nfunction formatMessage(startupResult: BackendStartupResult): string {\n const parts: string[] = [\n 'Backend startup failed due to the following errors:',\n ];\n const failures: string[] = [];\n\n for (const plugin of startupResult.plugins) {\n if (plugin.failure && !plugin.failure.allowed) {\n failures.push(\n ` Plugin '${plugin.pluginId}' startup failed; caused by ${plugin.failure.error}`,\n );\n }\n\n for (const mod of plugin.modules) {\n if (mod.failure && !mod.failure.allowed) {\n failures.push(\n ` Module '${mod.moduleId}' for plugin '${plugin.pluginId}' startup failed; caused by ${mod.failure.error}`,\n );\n }\n }\n }\n\n if (failures.length > 0) {\n parts.push(...failures);\n }\n\n return parts.join('\\n');\n}\n\n/**\n * Error thrown when backend startup fails.\n * Includes detailed startup results for all plugins and modules.\n *\n * @public\n */\nexport class BackendStartupError extends CustomErrorBase {\n name = 'BackendStartupError' as const;\n\n /**\n * The startup results for all plugins and modules.\n */\n readonly #startupResult: BackendStartupResult;\n\n constructor(startupResult: BackendStartupResult) {\n super(formatMessage(startupResult));\n this.#startupResult = startupResult;\n }\n\n get result(): BackendStartupResult {\n return this.#startupResult;\n }\n}\n"],"names":["CustomErrorBase"],"mappings":";;;;AAmBA,SAAS,cAAc,aAAA,EAA6C;AAClE,EAAA,MAAM,KAAA,GAAkB;AAAA,IACtB;AAAA,GACF;AACA,EAAA,MAAM,WAAqB,EAAC;AAE5B,EAAA,KAAA,MAAW,MAAA,IAAU,cAAc,OAAA,EAAS;AAC1C,IAAA,IAAI,MAAA,CAAO,OAAA,IAAW,CAAC,MAAA,CAAO,QAAQ,OAAA,EAAS;AAC7C,MAAA,QAAA,CAAS,IAAA;AAAA,QACP,aAAa,MAAA,CAAO,QAAQ,CAAA,4BAAA,EAA+B,MAAA,CAAO,QAAQ,KAAK,CAAA;AAAA,OACjF;AAAA,IACF;AAEA,IAAA,KAAA,MAAW,GAAA,IAAO,OAAO,OAAA,EAAS;AAChC,MAAA,IAAI,GAAA,CAAI,OAAA,IAAW,CAAC,GAAA,CAAI,QAAQ,OAAA,EAAS;AACvC,QAAA,QAAA,CAAS,IAAA;AAAA,UACP,CAAA,UAAA,EAAa,IAAI,QAAQ,CAAA,cAAA,EAAiB,OAAO,QAAQ,CAAA,4BAAA,EAA+B,GAAA,CAAI,OAAA,CAAQ,KAAK,CAAA;AAAA,SAC3G;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,EAAA,IAAI,QAAA,CAAS,SAAS,CAAA,EAAG;AACvB,IAAA,KAAA,CAAM,IAAA,CAAK,GAAG,QAAQ,CAAA;AAAA,EACxB;AAEA,EAAA,OAAO,KAAA,CAAM,KAAK,IAAI,CAAA;AACxB;AAQO,MAAM,4BAA4BA,sBAAA,CAAgB;AAAA,EACvD,IAAA,GAAO,qBAAA;AAAA;AAAA;AAAA;AAAA,EAKE,cAAA;AAAA,EAET,YAAY,aAAA,EAAqC;AAC/C,IAAA,KAAA,CAAM,aAAA,CAAc,aAAa,CAAC,CAAA;AAClC,IAAA,IAAA,CAAK,cAAA,GAAiB,aAAA;AAAA,EACxB;AAAA,EAEA,IAAI,MAAA,GAA+B;AACjC,IAAA,OAAO,IAAA,CAAK,cAAA;AAAA,EACd;AACF;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BackstageBackend.cjs.js","sources":["../../src/wiring/BackstageBackend.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, ServiceFactory } from '@backstage/backend-plugin-api';\nimport { isPromise, unwrapFeature } from '@internal/backend';\nimport { BackendInitializer } from './BackendInitializer';\nimport {\n Backend,\n BackendStartupResult,\n ExtensionPointFactoryMiddleware,\n} from './types';\n\nexport class BackstageBackend implements Backend {\n #initializer: BackendInitializer;\n\n constructor(\n defaultServiceFactories: ServiceFactory[],\n extensionPointFactoryMiddleware?: ExtensionPointFactoryMiddleware[],\n ) {\n this.#initializer = new BackendInitializer(\n defaultServiceFactories,\n extensionPointFactoryMiddleware,\n );\n }\n\n add(feature: BackendFeature | Promise<{ default: BackendFeature }>): void {\n if (isPromise(feature)) {\n this.#initializer.add(feature.then(unwrapFeature));\n } else {\n this.#initializer.add(unwrapFeature(feature));\n }\n }\n\n async start(): Promise<{ result: BackendStartupResult }> {\n return await this.#initializer.start();\n }\n\n async stop(): Promise<void> {\n await this.#initializer.stop();\n }\n}\n"],"names":["BackendInitializer","isPromise","unwrapFeature"],"mappings":";;;;;;AAyBO,MAAM,gBAAA,CAAoC;AAAA,EAC/C,YAAA;AAAA,EAEA,WAAA,CACE,yBACA,+BAAA,EACA;AACA,IAAA,IAAA,CAAK,eAAe,IAAIA,qCAAA;AAAA,MACtB,uBAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF;AAAA,EAEA,IAAI,OAAA,EAAsE;AACxE,IAAA,IAAIC,iBAAA,CAAU,OAAO,CAAA,EAAG;AACtB,MAAA,IAAA,CAAK,YAAA,CAAa,GAAA,CAAI,OAAA,CAAQ,IAAA,CAAKC,qBAAa,CAAC,CAAA;AAAA,IACnD,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,YAAA,CAAa,GAAA,CAAIA,qBAAA,CAAc,OAAO,CAAC,CAAA;AAAA,IAC9C;AAAA,EACF;AAAA,EAEA,MAAM,KAAA,GAAmD;AACvD,IAAA,OAAO,MAAM,IAAA,CAAK,YAAA,CAAa,KAAA,EAAM;AAAA,EACvC;AAAA,EAEA,MAAM,IAAA,GAAsB;AAC1B,IAAA,MAAM,IAAA,CAAK,aAAa,IAAA,EAAK;AAAA,EAC/B;AACF
|
|
1
|
+
{"version":3,"file":"BackstageBackend.cjs.js","sources":["../../src/wiring/BackstageBackend.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, ServiceFactory } from '@backstage/backend-plugin-api';\nimport { isPromise, unwrapFeature } from '@internal/backend';\nimport { BackendInitializer } from './BackendInitializer';\nimport {\n Backend,\n BackendStartupResult,\n ExtensionPointFactoryMiddleware,\n} from './types';\n\nexport class BackstageBackend implements Backend {\n #initializer: BackendInitializer;\n\n constructor(\n defaultServiceFactories: ServiceFactory[],\n extensionPointFactoryMiddleware?: ExtensionPointFactoryMiddleware[],\n ) {\n this.#initializer = new BackendInitializer(\n defaultServiceFactories,\n extensionPointFactoryMiddleware,\n );\n }\n\n add(feature: BackendFeature | Promise<{ default: BackendFeature }>): void {\n if (isPromise(feature)) {\n this.#initializer.add(feature.then(unwrapFeature));\n } else {\n this.#initializer.add(unwrapFeature(feature));\n }\n }\n\n async start(): Promise<{ result: BackendStartupResult }> {\n return await this.#initializer.start();\n }\n\n async stop(): Promise<void> {\n await this.#initializer.stop();\n }\n}\n"],"names":["BackendInitializer","isPromise","unwrapFeature"],"mappings":";;;;;;AAyBO,MAAM,gBAAA,CAAoC;AAAA,EAC/C,YAAA;AAAA,EAEA,WAAA,CACE,yBACA,+BAAA,EACA;AACA,IAAA,IAAA,CAAK,eAAe,IAAIA,qCAAA;AAAA,MACtB,uBAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF;AAAA,EAEA,IAAI,OAAA,EAAsE;AACxE,IAAA,IAAIC,iBAAA,CAAU,OAAO,CAAA,EAAG;AACtB,MAAA,IAAA,CAAK,YAAA,CAAa,GAAA,CAAI,OAAA,CAAQ,IAAA,CAAKC,qBAAa,CAAC,CAAA;AAAA,IACnD,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,YAAA,CAAa,GAAA,CAAIA,qBAAA,CAAc,OAAO,CAAC,CAAA;AAAA,IAC9C;AAAA,EACF;AAAA,EAEA,MAAM,KAAA,GAAmD;AACvD,IAAA,OAAO,MAAM,IAAA,CAAK,YAAA,CAAa,KAAA,EAAM;AAAA,EACvC;AAAA,EAEA,MAAM,IAAA,GAAsB;AAC1B,IAAA,MAAM,IAAA,CAAK,aAAa,IAAA,EAAK;AAAA,EAC/B;AACF;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ServiceRegistry.cjs.js","sources":["../../src/wiring/ServiceRegistry.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 {\n ServiceFactory,\n ServiceRef,\n coreServices,\n createServiceFactory,\n} from '@backstage/backend-plugin-api';\nimport { ConflictError, stringifyError } from '@backstage/errors';\n// Direct internal import to avoid duplication\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { InternalServiceFactory } from '../../../backend-plugin-api/src/services/system/types';\nimport { DependencyGraph } from '../lib/DependencyGraph';\nimport {\n assertObject,\n assertObjectLike,\n describeBackendFeature,\n throwInvalidBackendFeature,\n validateServiceRef,\n} from './validateBackendFeature';\n\n/**\n * Keep in sync with `@backstage/backend-plugin-api/src/services/system/types.ts`\n * @internal\n */\nexport type InternalServiceRef = ServiceRef<unknown> & {\n __defaultFactory?: (\n service: ServiceRef<unknown>,\n ) => Promise<ServiceFactory | (() => ServiceFactory)>;\n};\n\nfunction toInternalServiceFactory<TService, TScope extends 'plugin' | 'root'>(\n factory: ServiceFactory<TService, TScope>,\n path: string,\n): InternalServiceFactory<TService, TScope> {\n assertObjectLike(factory, path);\n const f = factory as unknown as InternalServiceFactory<TService, TScope>;\n if (f.$$type !== '@backstage/BackendFeature') {\n throwInvalidBackendFeature(\n `${path}.$$type`,\n '\"@backstage/BackendFeature\"',\n f.$$type,\n );\n }\n if (f.version !== 'v1') {\n throwInvalidBackendFeature(`${path}.version`, '\"v1\"', f.version);\n }\n\n validateServiceRef(f.service, `${path}.service`);\n assertObject(f.deps, `${path}.deps`, 'a dependency object');\n for (const [name, ref] of Object.entries(f.deps)) {\n validateServiceRef(ref, `${path}.deps.${name}`);\n }\n\n return f;\n}\n\nfunction createPluginMetadataServiceFactory(pluginId: string) {\n return createServiceFactory({\n service: coreServices.pluginMetadata,\n deps: {},\n factory: async () => ({\n getId: () => pluginId,\n }),\n });\n}\n\nexport class ServiceRegistry {\n static create(factories: Array<ServiceFactory>): ServiceRegistry {\n const factoryMap = new Map<string, InternalServiceFactory[]>();\n for (let index = 0; index < factories.length; index++) {\n const source =\n describeBackendFeature(factories[index]) ??\n `default service factories[${index}]`;\n const factory = toInternalServiceFactory(factories[index], source);\n if (factory.service.multiton) {\n const existing = factoryMap.get(factory.service.id) ?? [];\n factoryMap.set(factory.service.id, existing.concat(factory));\n } else {\n factoryMap.set(factory.service.id, [factory]);\n }\n }\n const registry = new ServiceRegistry(factoryMap);\n registry.checkForCircularDeps();\n return registry;\n }\n\n readonly #providedFactories: Map<string, InternalServiceFactory[]>;\n readonly #loadedDefaultFactories: Map<\n Function,\n Promise<InternalServiceFactory>\n >;\n readonly #implementations: Map<\n InternalServiceFactory,\n {\n context: Promise<unknown>;\n byPlugin: Map<string, Promise<unknown>>;\n }\n >;\n readonly #rootServiceImplementations = new Map<\n InternalServiceFactory,\n Promise<unknown>\n >();\n readonly #addedFactoryIds = new Set<string>();\n readonly #instantiatedFactories = new Set<string>();\n\n private constructor(factories: Map<string, InternalServiceFactory[]>) {\n this.#providedFactories = factories;\n this.#loadedDefaultFactories = new Map();\n this.#implementations = new Map();\n }\n\n #resolveFactory(\n ref: ServiceRef<unknown>,\n pluginId: string,\n ): Promise<InternalServiceFactory[]> | undefined {\n // Special case handling of the plugin metadata service, generating a custom factory for it each time\n if (ref.id === coreServices.pluginMetadata.id) {\n return Promise.resolve([\n toInternalServiceFactory(\n createPluginMetadataServiceFactory(pluginId),\n 'plugin metadata service factory',\n ),\n ]);\n }\n\n let resolvedFactory:\n | Promise<InternalServiceFactory[]>\n | InternalServiceFactory[]\n | undefined = this.#providedFactories.get(ref.id);\n const { __defaultFactory: defaultFactory } = ref as InternalServiceRef;\n if (!resolvedFactory && !defaultFactory) {\n return undefined;\n }\n\n if (!resolvedFactory) {\n let loadedFactory = this.#loadedDefaultFactories.get(defaultFactory!);\n if (!loadedFactory) {\n loadedFactory = Promise.resolve()\n .then(() => defaultFactory!(ref))\n .then(f =>\n toInternalServiceFactory(\n typeof f === 'function' ? f() : f,\n `default factory for service ${JSON.stringify(ref.id)}`,\n ),\n );\n this.#loadedDefaultFactories.set(defaultFactory!, loadedFactory);\n }\n resolvedFactory = loadedFactory.then(\n factory => [factory],\n error => {\n throw new Error(\n `Failed to instantiate service '${\n ref.id\n }' because the default factory loader threw an error, ${stringifyError(\n error,\n )}`,\n );\n },\n );\n }\n\n return Promise.resolve(resolvedFactory);\n }\n\n #checkForMissingDeps(factory: InternalServiceFactory, pluginId: string) {\n const missingDeps = Object.values(factory.deps).filter(ref => {\n if (ref.id === coreServices.pluginMetadata.id) {\n return false;\n }\n if (this.#providedFactories.get(ref.id)) {\n return false;\n }\n if (ref.multiton) {\n return false;\n }\n\n return !(ref as InternalServiceRef).__defaultFactory;\n });\n\n if (missingDeps.length) {\n const missing = missingDeps.map(r => `'${r.id}'`).join(', ');\n throw new Error(\n `Failed to instantiate service '${factory.service.id}' for '${pluginId}' because the following dependent services are missing: ${missing}`,\n );\n }\n }\n\n checkForCircularDeps(): void {\n const graph = DependencyGraph.fromIterable(\n Array.from(this.#providedFactories).map(([serviceId, factories]) => ({\n value: serviceId,\n provides: [serviceId],\n consumes: factories.flatMap(factory =>\n Object.values(factory.deps).map(d => d.id),\n ),\n })),\n );\n const circularDependencies = Array.from(graph.detectCircularDependencies());\n\n if (circularDependencies.length) {\n const cycles = circularDependencies\n .map(c => c.map(id => `'${id}'`).join(' -> '))\n .join('\\n ');\n\n throw new ConflictError(`Circular dependencies detected:\\n ${cycles}`);\n }\n }\n\n hasBeenAdded(ref: ServiceRef<any>) {\n if (ref.id === coreServices.pluginMetadata.id) {\n return true;\n }\n return this.#addedFactoryIds.has(ref.id);\n }\n\n add(factory: ServiceFactory, source?: string) {\n const factorySource =\n source ?? describeBackendFeature(factory) ?? 'service factory';\n const internalFactory = toInternalServiceFactory(factory, factorySource);\n const factoryId = internalFactory.service.id;\n if (factoryId === coreServices.pluginMetadata.id) {\n throw new Error(\n `The ${coreServices.pluginMetadata.id} service cannot be overridden`,\n );\n }\n\n if (this.#instantiatedFactories.has(factoryId)) {\n throw new Error(\n `Unable to set service factory with id ${factoryId}, service has already been instantiated`,\n );\n }\n\n if (internalFactory.service.multiton) {\n const newFactories = (\n this.#providedFactories.get(factoryId) ?? []\n ).concat(internalFactory);\n this.#providedFactories.set(factoryId, newFactories);\n } else {\n if (this.#addedFactoryIds.has(factoryId)) {\n throw new Error(\n `Duplicate service implementations provided for ${factoryId}`,\n );\n }\n\n this.#addedFactoryIds.add(factoryId);\n this.#providedFactories.set(factoryId, [internalFactory]);\n }\n }\n\n async initializeEagerServicesWithScope(\n scope: 'root' | 'plugin',\n pluginId: string = 'root',\n ) {\n for (const [factory] of this.#providedFactories.values()) {\n if (factory.service.scope === scope) {\n // Root-scoped services are eager by default, plugin-scoped are lazy by default\n if (scope === 'root' && factory.initialization !== 'lazy') {\n await this.get(factory.service, pluginId);\n } else if (scope === 'plugin' && factory.initialization === 'always') {\n await this.get(factory.service, pluginId);\n }\n }\n }\n }\n\n get<T, TInstances extends 'singleton' | 'multiton'>(\n ref: ServiceRef<T, 'plugin' | 'root', TInstances>,\n pluginId: string,\n ): Promise<TInstances extends 'multiton' ? T[] : T> | undefined {\n this.#instantiatedFactories.add(ref.id);\n\n const resolvedFactory = this.#resolveFactory(ref, pluginId);\n\n if (!resolvedFactory) {\n return ref.multiton\n ? (Promise.resolve([]) as\n | Promise<TInstances extends 'multiton' ? T[] : T>\n | undefined)\n : undefined;\n }\n\n return resolvedFactory\n .then(factories => {\n return Promise.all(\n factories.map(factory => {\n if (factory.service.scope === 'root') {\n let existing = this.#rootServiceImplementations.get(factory);\n if (!existing) {\n this.#checkForMissingDeps(factory, pluginId);\n const rootDeps = new Array<\n Promise<[name: string, impl: unknown]>\n >();\n\n for (const [name, serviceRef] of Object.entries(factory.deps)) {\n if (serviceRef.scope !== 'root') {\n throw new Error(\n `Failed to instantiate 'root' scoped service '${ref.id}' because it depends on '${serviceRef.scope}' scoped service '${serviceRef.id}'.`,\n );\n }\n const target = this.get(serviceRef, pluginId)!;\n rootDeps.push(target.then(impl => [name, impl]));\n }\n\n existing = Promise.all(rootDeps).then(entries =>\n factory.factory(Object.fromEntries(entries), undefined),\n );\n this.#rootServiceImplementations.set(factory, existing);\n }\n return existing as Promise<T>;\n }\n\n let implementation = this.#implementations.get(factory);\n if (!implementation) {\n this.#checkForMissingDeps(factory, pluginId);\n const rootDeps = new Array<\n Promise<[name: string, impl: unknown]>\n >();\n\n for (const [name, serviceRef] of Object.entries(factory.deps)) {\n if (serviceRef.scope === 'root') {\n const target = this.get(serviceRef, pluginId)!;\n rootDeps.push(target.then(impl => [name, impl]));\n }\n }\n\n implementation = {\n context: Promise.all(rootDeps)\n .then(entries =>\n factory.createRootContext?.(Object.fromEntries(entries)),\n )\n .catch(error => {\n const cause = stringifyError(error);\n throw new Error(\n `Failed to instantiate service '${ref.id}' because createRootContext threw an error, ${cause}`,\n );\n }),\n byPlugin: new Map(),\n };\n\n this.#implementations.set(factory, implementation);\n }\n\n let result = implementation.byPlugin.get(pluginId) as Promise<any>;\n if (!result) {\n const allDeps = new Array<\n Promise<[name: string, impl: unknown]>\n >();\n\n for (const [name, serviceRef] of Object.entries(factory.deps)) {\n const target = this.get(serviceRef, pluginId)!;\n allDeps.push(target.then(impl => [name, impl]));\n }\n\n result = implementation.context\n .then(context =>\n Promise.all(allDeps).then(entries =>\n factory.factory(Object.fromEntries(entries), context),\n ),\n )\n .catch(error => {\n const cause = stringifyError(error);\n throw new Error(\n `Failed to instantiate service '${ref.id}' for '${pluginId}' because the factory function threw an error, ${cause}`,\n );\n });\n implementation.byPlugin.set(pluginId, result);\n }\n return result;\n }),\n );\n })\n .then(results => (ref.multiton ? results : results[0]));\n }\n}\n"],"names":["assertObjectLike","throwInvalidBackendFeature","validateServiceRef","assertObject","createServiceFactory","coreServices","describeBackendFeature","stringifyError","DependencyGraph","ConflictError"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ServiceRegistry.cjs.js","sources":["../../src/wiring/ServiceRegistry.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 {\n ServiceFactory,\n ServiceRef,\n coreServices,\n createServiceFactory,\n} from '@backstage/backend-plugin-api';\nimport { ConflictError, stringifyError } from '@backstage/errors';\n// Direct internal import to avoid duplication\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { InternalServiceFactory } from '../../../backend-plugin-api/src/services/system/types';\nimport { DependencyGraph } from '../lib/DependencyGraph';\nimport {\n assertObject,\n assertObjectLike,\n describeBackendFeature,\n throwInvalidBackendFeature,\n validateServiceRef,\n} from './validateBackendFeature';\n\n/**\n * Keep in sync with `@backstage/backend-plugin-api/src/services/system/types.ts`\n * @internal\n */\nexport type InternalServiceRef = ServiceRef<unknown> & {\n __defaultFactory?: (\n service: ServiceRef<unknown>,\n ) => Promise<ServiceFactory | (() => ServiceFactory)>;\n};\n\nfunction toInternalServiceFactory<TService, TScope extends 'plugin' | 'root'>(\n factory: ServiceFactory<TService, TScope>,\n path: string,\n): InternalServiceFactory<TService, TScope> {\n assertObjectLike(factory, path);\n const f = factory as unknown as InternalServiceFactory<TService, TScope>;\n if (f.$$type !== '@backstage/BackendFeature') {\n throwInvalidBackendFeature(\n `${path}.$$type`,\n '\"@backstage/BackendFeature\"',\n f.$$type,\n );\n }\n if (f.version !== 'v1') {\n throwInvalidBackendFeature(`${path}.version`, '\"v1\"', f.version);\n }\n\n validateServiceRef(f.service, `${path}.service`);\n assertObject(f.deps, `${path}.deps`, 'a dependency object');\n for (const [name, ref] of Object.entries(f.deps)) {\n validateServiceRef(ref, `${path}.deps.${name}`);\n }\n\n return f;\n}\n\nfunction createPluginMetadataServiceFactory(pluginId: string) {\n return createServiceFactory({\n service: coreServices.pluginMetadata,\n deps: {},\n factory: async () => ({\n getId: () => pluginId,\n }),\n });\n}\n\nexport class ServiceRegistry {\n static create(factories: Array<ServiceFactory>): ServiceRegistry {\n const factoryMap = new Map<string, InternalServiceFactory[]>();\n for (let index = 0; index < factories.length; index++) {\n const source =\n describeBackendFeature(factories[index]) ??\n `default service factories[${index}]`;\n const factory = toInternalServiceFactory(factories[index], source);\n if (factory.service.multiton) {\n const existing = factoryMap.get(factory.service.id) ?? [];\n factoryMap.set(factory.service.id, existing.concat(factory));\n } else {\n factoryMap.set(factory.service.id, [factory]);\n }\n }\n const registry = new ServiceRegistry(factoryMap);\n registry.checkForCircularDeps();\n return registry;\n }\n\n readonly #providedFactories: Map<string, InternalServiceFactory[]>;\n readonly #loadedDefaultFactories: Map<\n Function,\n Promise<InternalServiceFactory>\n >;\n readonly #implementations: Map<\n InternalServiceFactory,\n {\n context: Promise<unknown>;\n byPlugin: Map<string, Promise<unknown>>;\n }\n >;\n readonly #rootServiceImplementations = new Map<\n InternalServiceFactory,\n Promise<unknown>\n >();\n readonly #addedFactoryIds = new Set<string>();\n readonly #instantiatedFactories = new Set<string>();\n\n private constructor(factories: Map<string, InternalServiceFactory[]>) {\n this.#providedFactories = factories;\n this.#loadedDefaultFactories = new Map();\n this.#implementations = new Map();\n }\n\n #resolveFactory(\n ref: ServiceRef<unknown>,\n pluginId: string,\n ): Promise<InternalServiceFactory[]> | undefined {\n // Special case handling of the plugin metadata service, generating a custom factory for it each time\n if (ref.id === coreServices.pluginMetadata.id) {\n return Promise.resolve([\n toInternalServiceFactory(\n createPluginMetadataServiceFactory(pluginId),\n 'plugin metadata service factory',\n ),\n ]);\n }\n\n let resolvedFactory:\n | Promise<InternalServiceFactory[]>\n | InternalServiceFactory[]\n | undefined = this.#providedFactories.get(ref.id);\n const { __defaultFactory: defaultFactory } = ref as InternalServiceRef;\n if (!resolvedFactory && !defaultFactory) {\n return undefined;\n }\n\n if (!resolvedFactory) {\n let loadedFactory = this.#loadedDefaultFactories.get(defaultFactory!);\n if (!loadedFactory) {\n loadedFactory = Promise.resolve()\n .then(() => defaultFactory!(ref))\n .then(f =>\n toInternalServiceFactory(\n typeof f === 'function' ? f() : f,\n `default factory for service ${JSON.stringify(ref.id)}`,\n ),\n );\n this.#loadedDefaultFactories.set(defaultFactory!, loadedFactory);\n }\n resolvedFactory = loadedFactory.then(\n factory => [factory],\n error => {\n throw new Error(\n `Failed to instantiate service '${\n ref.id\n }' because the default factory loader threw an error, ${stringifyError(\n error,\n )}`,\n );\n },\n );\n }\n\n return Promise.resolve(resolvedFactory);\n }\n\n #checkForMissingDeps(factory: InternalServiceFactory, pluginId: string) {\n const missingDeps = Object.values(factory.deps).filter(ref => {\n if (ref.id === coreServices.pluginMetadata.id) {\n return false;\n }\n if (this.#providedFactories.get(ref.id)) {\n return false;\n }\n if (ref.multiton) {\n return false;\n }\n\n return !(ref as InternalServiceRef).__defaultFactory;\n });\n\n if (missingDeps.length) {\n const missing = missingDeps.map(r => `'${r.id}'`).join(', ');\n throw new Error(\n `Failed to instantiate service '${factory.service.id}' for '${pluginId}' because the following dependent services are missing: ${missing}`,\n );\n }\n }\n\n checkForCircularDeps(): void {\n const graph = DependencyGraph.fromIterable(\n Array.from(this.#providedFactories).map(([serviceId, factories]) => ({\n value: serviceId,\n provides: [serviceId],\n consumes: factories.flatMap(factory =>\n Object.values(factory.deps).map(d => d.id),\n ),\n })),\n );\n const circularDependencies = Array.from(graph.detectCircularDependencies());\n\n if (circularDependencies.length) {\n const cycles = circularDependencies\n .map(c => c.map(id => `'${id}'`).join(' -> '))\n .join('\\n ');\n\n throw new ConflictError(`Circular dependencies detected:\\n ${cycles}`);\n }\n }\n\n hasBeenAdded(ref: ServiceRef<any>) {\n if (ref.id === coreServices.pluginMetadata.id) {\n return true;\n }\n return this.#addedFactoryIds.has(ref.id);\n }\n\n add(factory: ServiceFactory, source?: string) {\n const factorySource =\n source ?? describeBackendFeature(factory) ?? 'service factory';\n const internalFactory = toInternalServiceFactory(factory, factorySource);\n const factoryId = internalFactory.service.id;\n if (factoryId === coreServices.pluginMetadata.id) {\n throw new Error(\n `The ${coreServices.pluginMetadata.id} service cannot be overridden`,\n );\n }\n\n if (this.#instantiatedFactories.has(factoryId)) {\n throw new Error(\n `Unable to set service factory with id ${factoryId}, service has already been instantiated`,\n );\n }\n\n if (internalFactory.service.multiton) {\n const newFactories = (\n this.#providedFactories.get(factoryId) ?? []\n ).concat(internalFactory);\n this.#providedFactories.set(factoryId, newFactories);\n } else {\n if (this.#addedFactoryIds.has(factoryId)) {\n throw new Error(\n `Duplicate service implementations provided for ${factoryId}`,\n );\n }\n\n this.#addedFactoryIds.add(factoryId);\n this.#providedFactories.set(factoryId, [internalFactory]);\n }\n }\n\n async initializeEagerServicesWithScope(\n scope: 'root' | 'plugin',\n pluginId: string = 'root',\n ) {\n for (const [factory] of this.#providedFactories.values()) {\n if (factory.service.scope === scope) {\n // Root-scoped services are eager by default, plugin-scoped are lazy by default\n if (scope === 'root' && factory.initialization !== 'lazy') {\n await this.get(factory.service, pluginId);\n } else if (scope === 'plugin' && factory.initialization === 'always') {\n await this.get(factory.service, pluginId);\n }\n }\n }\n }\n\n get<T, TInstances extends 'singleton' | 'multiton'>(\n ref: ServiceRef<T, 'plugin' | 'root', TInstances>,\n pluginId: string,\n ): Promise<TInstances extends 'multiton' ? T[] : T> | undefined {\n this.#instantiatedFactories.add(ref.id);\n\n const resolvedFactory = this.#resolveFactory(ref, pluginId);\n\n if (!resolvedFactory) {\n return ref.multiton\n ? (Promise.resolve([]) as\n | Promise<TInstances extends 'multiton' ? T[] : T>\n | undefined)\n : undefined;\n }\n\n return resolvedFactory\n .then(factories => {\n return Promise.all(\n factories.map(factory => {\n if (factory.service.scope === 'root') {\n let existing = this.#rootServiceImplementations.get(factory);\n if (!existing) {\n this.#checkForMissingDeps(factory, pluginId);\n const rootDeps = new Array<\n Promise<[name: string, impl: unknown]>\n >();\n\n for (const [name, serviceRef] of Object.entries(factory.deps)) {\n if (serviceRef.scope !== 'root') {\n throw new Error(\n `Failed to instantiate 'root' scoped service '${ref.id}' because it depends on '${serviceRef.scope}' scoped service '${serviceRef.id}'.`,\n );\n }\n const target = this.get(serviceRef, pluginId)!;\n rootDeps.push(target.then(impl => [name, impl]));\n }\n\n existing = Promise.all(rootDeps).then(entries =>\n factory.factory(Object.fromEntries(entries), undefined),\n );\n this.#rootServiceImplementations.set(factory, existing);\n }\n return existing as Promise<T>;\n }\n\n let implementation = this.#implementations.get(factory);\n if (!implementation) {\n this.#checkForMissingDeps(factory, pluginId);\n const rootDeps = new Array<\n Promise<[name: string, impl: unknown]>\n >();\n\n for (const [name, serviceRef] of Object.entries(factory.deps)) {\n if (serviceRef.scope === 'root') {\n const target = this.get(serviceRef, pluginId)!;\n rootDeps.push(target.then(impl => [name, impl]));\n }\n }\n\n implementation = {\n context: Promise.all(rootDeps)\n .then(entries =>\n factory.createRootContext?.(Object.fromEntries(entries)),\n )\n .catch(error => {\n const cause = stringifyError(error);\n throw new Error(\n `Failed to instantiate service '${ref.id}' because createRootContext threw an error, ${cause}`,\n );\n }),\n byPlugin: new Map(),\n };\n\n this.#implementations.set(factory, implementation);\n }\n\n let result = implementation.byPlugin.get(pluginId) as Promise<any>;\n if (!result) {\n const allDeps = new Array<\n Promise<[name: string, impl: unknown]>\n >();\n\n for (const [name, serviceRef] of Object.entries(factory.deps)) {\n const target = this.get(serviceRef, pluginId)!;\n allDeps.push(target.then(impl => [name, impl]));\n }\n\n result = implementation.context\n .then(context =>\n Promise.all(allDeps).then(entries =>\n factory.factory(Object.fromEntries(entries), context),\n ),\n )\n .catch(error => {\n const cause = stringifyError(error);\n throw new Error(\n `Failed to instantiate service '${ref.id}' for '${pluginId}' because the factory function threw an error, ${cause}`,\n );\n });\n implementation.byPlugin.set(pluginId, result);\n }\n return result;\n }),\n );\n })\n .then(results => (ref.multiton ? results : results[0]));\n }\n}\n"],"names":["assertObjectLike","throwInvalidBackendFeature","validateServiceRef","assertObject","createServiceFactory","coreServices","describeBackendFeature","stringifyError","DependencyGraph","ConflictError"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createAllowBootFailurePredicate.cjs.js","sources":["../../src/wiring/createAllowBootFailurePredicate.ts"],"sourcesContent":["/*\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 { Config } from '@backstage/config';\n\nexport type AllowBootFailurePredicate = (\n pluginId: string,\n moduleId?: string,\n) => boolean;\n\n/**\n * Creates a predicate function that determines whether a boot failure should be\n * allowed for a given plugin or module based on configuration.\n *\n * @param config - The configuration object to read boot failure settings from\n * @returns A predicate function that accepts a pluginId and optional moduleId,\n * and returns true if boot failures should be allowed, false otherwise.\n */\nexport function createAllowBootFailurePredicate(\n config?: Config,\n): AllowBootFailurePredicate {\n // Read default values upfront\n const defaultPluginBootFailure =\n config?.getOptionalString('backend.startup.default.onPluginBootFailure') ??\n 'abort';\n const defaultModuleBootFailure =\n config?.getOptionalString(\n 'backend.startup.default.onPluginModuleBootFailure',\n ) ?? 'abort';\n\n // Read plugin-specific overrides upfront\n const pluginOverrides = new Map<string, string>();\n const moduleOverrides = new Map<string, Map<string, string>>();\n\n const pluginsConfig = config?.getOptionalConfig('backend.startup.plugins');\n if (pluginsConfig) {\n for (const pluginId of pluginsConfig.keys()) {\n const pluginConfig = pluginsConfig.getConfig(pluginId);\n const pluginBootFailure = pluginConfig.getOptionalString(\n 'onPluginBootFailure',\n );\n if (pluginBootFailure) {\n pluginOverrides.set(pluginId, pluginBootFailure);\n }\n\n // Read module-specific overrides\n const modulesConfig = pluginConfig.getOptionalConfig('modules');\n if (modulesConfig) {\n const moduleMap = new Map<string, string>();\n for (const moduleId of modulesConfig.keys()) {\n const moduleConfig = modulesConfig.getConfig(moduleId);\n const moduleBootFailure = moduleConfig.getOptionalString(\n 'onPluginModuleBootFailure',\n );\n if (moduleBootFailure) {\n moduleMap.set(moduleId, moduleBootFailure);\n }\n }\n if (moduleMap.size > 0) {\n moduleOverrides.set(pluginId, moduleMap);\n }\n }\n }\n }\n\n return (pluginId: string, moduleId?: string): boolean => {\n if (moduleId !== undefined) {\n // Module-specific boot failure predicate\n const moduleMap = moduleOverrides.get(pluginId);\n const moduleBootFailure =\n moduleMap?.get(moduleId) ?? defaultModuleBootFailure;\n return moduleBootFailure === 'continue';\n }\n // Plugin-specific boot failure predicate\n const pluginBootFailure =\n pluginOverrides.get(pluginId) ?? defaultPluginBootFailure;\n return pluginBootFailure === 'continue';\n };\n}\n"],"names":[],"mappings":";;AA+BO,SAAS,gCACd,MAAA,EAC2B;AAE3B,EAAA,MAAM,wBAAA,GACJ,MAAA,EAAQ,iBAAA,CAAkB,6CAA6C,CAAA,IACvE,OAAA;AACF,EAAA,MAAM,2BACJ,MAAA,EAAQ,iBAAA;AAAA,IACN;AAAA,GACF,IAAK,OAAA;AAGP,EAAA,MAAM,eAAA,uBAAsB,GAAA,EAAoB;AAChD,EAAA,MAAM,eAAA,uBAAsB,GAAA,EAAiC;AAE7D,EAAA,MAAM,aAAA,GAAgB,MAAA,EAAQ,iBAAA,CAAkB,yBAAyB,CAAA;AACzE,EAAA,IAAI,aAAA,EAAe;AACjB,IAAA,KAAA,MAAW,QAAA,IAAY,aAAA,CAAc,IAAA,EAAK,EAAG;AAC3C,MAAA,MAAM,YAAA,GAAe,aAAA,CAAc,SAAA,CAAU,QAAQ,CAAA;AACrD,MAAA,MAAM,oBAAoB,YAAA,CAAa,iBAAA;AAAA,QACrC;AAAA,OACF;AACA,MAAA,IAAI,iBAAA,EAAmB;AACrB,QAAA,eAAA,CAAgB,GAAA,CAAI,UAAU,iBAAiB,CAAA;AAAA,MACjD;AAGA,MAAA,MAAM,aAAA,GAAgB,YAAA,CAAa,iBAAA,CAAkB,SAAS,CAAA;AAC9D,MAAA,IAAI,aAAA,EAAe;AACjB,QAAA,MAAM,SAAA,uBAAgB,GAAA,EAAoB;AAC1C,QAAA,KAAA,MAAW,QAAA,IAAY,aAAA,CAAc,IAAA,EAAK,EAAG;AAC3C,UAAA,MAAM,YAAA,GAAe,aAAA,CAAc,SAAA,CAAU,QAAQ,CAAA;AACrD,UAAA,MAAM,oBAAoB,YAAA,CAAa,iBAAA;AAAA,YACrC;AAAA,WACF;AACA,UAAA,IAAI,iBAAA,EAAmB;AACrB,YAAA,SAAA,CAAU,GAAA,CAAI,UAAU,iBAAiB,CAAA;AAAA,UAC3C;AAAA,QACF;AACA,QAAA,IAAI,SAAA,CAAU,OAAO,CAAA,EAAG;AACtB,UAAA,eAAA,CAAgB,GAAA,CAAI,UAAU,SAAS,CAAA;AAAA,QACzC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,CAAC,UAAkB,QAAA,KAA+B;AACvD,IAAA,IAAI,aAAa,MAAA,EAAW;AAE1B,MAAA,MAAM,SAAA,GAAY,eAAA,CAAgB,GAAA,CAAI,QAAQ,CAAA;AAC9C,MAAA,MAAM,iBAAA,GACJ,SAAA,EAAW,GAAA,CAAI,QAAQ,CAAA,IAAK,wBAAA;AAC9B,MAAA,OAAO,iBAAA,KAAsB,UAAA;AAAA,IAC/B;AAEA,IAAA,MAAM,iBAAA,GACJ,eAAA,CAAgB,GAAA,CAAI,QAAQ,CAAA,IAAK,wBAAA;AACnC,IAAA,OAAO,iBAAA,KAAsB,UAAA;AAAA,EAC/B,CAAA;AACF
|
|
1
|
+
{"version":3,"file":"createAllowBootFailurePredicate.cjs.js","sources":["../../src/wiring/createAllowBootFailurePredicate.ts"],"sourcesContent":["/*\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 { Config } from '@backstage/config';\n\nexport type AllowBootFailurePredicate = (\n pluginId: string,\n moduleId?: string,\n) => boolean;\n\n/**\n * Creates a predicate function that determines whether a boot failure should be\n * allowed for a given plugin or module based on configuration.\n *\n * @param config - The configuration object to read boot failure settings from\n * @returns A predicate function that accepts a pluginId and optional moduleId,\n * and returns true if boot failures should be allowed, false otherwise.\n */\nexport function createAllowBootFailurePredicate(\n config?: Config,\n): AllowBootFailurePredicate {\n // Read default values upfront\n const defaultPluginBootFailure =\n config?.getOptionalString('backend.startup.default.onPluginBootFailure') ??\n 'abort';\n const defaultModuleBootFailure =\n config?.getOptionalString(\n 'backend.startup.default.onPluginModuleBootFailure',\n ) ?? 'abort';\n\n // Read plugin-specific overrides upfront\n const pluginOverrides = new Map<string, string>();\n const moduleOverrides = new Map<string, Map<string, string>>();\n\n const pluginsConfig = config?.getOptionalConfig('backend.startup.plugins');\n if (pluginsConfig) {\n for (const pluginId of pluginsConfig.keys()) {\n const pluginConfig = pluginsConfig.getConfig(pluginId);\n const pluginBootFailure = pluginConfig.getOptionalString(\n 'onPluginBootFailure',\n );\n if (pluginBootFailure) {\n pluginOverrides.set(pluginId, pluginBootFailure);\n }\n\n // Read module-specific overrides\n const modulesConfig = pluginConfig.getOptionalConfig('modules');\n if (modulesConfig) {\n const moduleMap = new Map<string, string>();\n for (const moduleId of modulesConfig.keys()) {\n const moduleConfig = modulesConfig.getConfig(moduleId);\n const moduleBootFailure = moduleConfig.getOptionalString(\n 'onPluginModuleBootFailure',\n );\n if (moduleBootFailure) {\n moduleMap.set(moduleId, moduleBootFailure);\n }\n }\n if (moduleMap.size > 0) {\n moduleOverrides.set(pluginId, moduleMap);\n }\n }\n }\n }\n\n return (pluginId: string, moduleId?: string): boolean => {\n if (moduleId !== undefined) {\n // Module-specific boot failure predicate\n const moduleMap = moduleOverrides.get(pluginId);\n const moduleBootFailure =\n moduleMap?.get(moduleId) ?? defaultModuleBootFailure;\n return moduleBootFailure === 'continue';\n }\n // Plugin-specific boot failure predicate\n const pluginBootFailure =\n pluginOverrides.get(pluginId) ?? defaultPluginBootFailure;\n return pluginBootFailure === 'continue';\n };\n}\n"],"names":[],"mappings":";;AA+BO,SAAS,gCACd,MAAA,EAC2B;AAE3B,EAAA,MAAM,wBAAA,GACJ,MAAA,EAAQ,iBAAA,CAAkB,6CAA6C,CAAA,IACvE,OAAA;AACF,EAAA,MAAM,2BACJ,MAAA,EAAQ,iBAAA;AAAA,IACN;AAAA,GACF,IAAK,OAAA;AAGP,EAAA,MAAM,eAAA,uBAAsB,GAAA,EAAoB;AAChD,EAAA,MAAM,eAAA,uBAAsB,GAAA,EAAiC;AAE7D,EAAA,MAAM,aAAA,GAAgB,MAAA,EAAQ,iBAAA,CAAkB,yBAAyB,CAAA;AACzE,EAAA,IAAI,aAAA,EAAe;AACjB,IAAA,KAAA,MAAW,QAAA,IAAY,aAAA,CAAc,IAAA,EAAK,EAAG;AAC3C,MAAA,MAAM,YAAA,GAAe,aAAA,CAAc,SAAA,CAAU,QAAQ,CAAA;AACrD,MAAA,MAAM,oBAAoB,YAAA,CAAa,iBAAA;AAAA,QACrC;AAAA,OACF;AACA,MAAA,IAAI,iBAAA,EAAmB;AACrB,QAAA,eAAA,CAAgB,GAAA,CAAI,UAAU,iBAAiB,CAAA;AAAA,MACjD;AAGA,MAAA,MAAM,aAAA,GAAgB,YAAA,CAAa,iBAAA,CAAkB,SAAS,CAAA;AAC9D,MAAA,IAAI,aAAA,EAAe;AACjB,QAAA,MAAM,SAAA,uBAAgB,GAAA,EAAoB;AAC1C,QAAA,KAAA,MAAW,QAAA,IAAY,aAAA,CAAc,IAAA,EAAK,EAAG;AAC3C,UAAA,MAAM,YAAA,GAAe,aAAA,CAAc,SAAA,CAAU,QAAQ,CAAA;AACrD,UAAA,MAAM,oBAAoB,YAAA,CAAa,iBAAA;AAAA,YACrC;AAAA,WACF;AACA,UAAA,IAAI,iBAAA,EAAmB;AACrB,YAAA,SAAA,CAAU,GAAA,CAAI,UAAU,iBAAiB,CAAA;AAAA,UAC3C;AAAA,QACF;AACA,QAAA,IAAI,SAAA,CAAU,OAAO,CAAA,EAAG;AACtB,UAAA,eAAA,CAAgB,GAAA,CAAI,UAAU,SAAS,CAAA;AAAA,QACzC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,CAAC,UAAkB,QAAA,KAA+B;AACvD,IAAA,IAAI,aAAa,MAAA,EAAW;AAE1B,MAAA,MAAM,SAAA,GAAY,eAAA,CAAgB,GAAA,CAAI,QAAQ,CAAA;AAC9C,MAAA,MAAM,iBAAA,GACJ,SAAA,EAAW,GAAA,CAAI,QAAQ,CAAA,IAAK,wBAAA;AAC9B,MAAA,OAAO,iBAAA,KAAsB,UAAA;AAAA,IAC/B;AAEA,IAAA,MAAM,iBAAA,GACJ,eAAA,CAAgB,GAAA,CAAI,QAAQ,CAAA,IAAK,wBAAA;AACnC,IAAA,OAAO,iBAAA,KAAsB,UAAA;AAAA,EAC/B,CAAA;AACF;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createInitializationResultCollector.cjs.js","sources":["../../src/wiring/createInitializationResultCollector.ts"],"sourcesContent":["/*\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 { RootLoggerService } from '@backstage/backend-plugin-api';\nimport { AllowBootFailurePredicate } from './createAllowBootFailurePredicate';\nimport {\n BackendStartupResult,\n PluginStartupResult,\n ModuleStartupResult,\n} from './types';\n\nconst LOGGER_INTERVAL_MAX = 60_000;\n\nfunction joinIds(ids: Iterable<string>): string {\n return [...ids].map(id => `'${id}'`).join(', ');\n}\n\nexport function createInitializationResultCollector(options: {\n pluginIds: string[];\n logger?: RootLoggerService;\n allowBootFailurePredicate: AllowBootFailurePredicate;\n}): {\n onPluginResult(pluginId: string, error?: Error): void;\n onPluginModuleResult(pluginId: string, moduleId: string, error?: Error): void;\n amendPluginModuleResult(\n pluginId: string,\n moduleId: string,\n error: Error,\n ): void;\n finalize(): BackendStartupResult;\n} {\n const logger = options.logger?.child({ type: 'initialization' });\n const beginAt = new Date();\n const starting = new Set(options.pluginIds.toSorted());\n const started = new Set<string>();\n\n let hasFinalized = false;\n let hasDisallowedFailures = false;\n\n const pluginResults: PluginStartupResult[] = [];\n const moduleResultsByPlugin: Map<string, ModuleStartupResult[]> = new Map(\n Array.from(starting).map(pluginId => [pluginId, []]),\n );\n\n logger?.info(`Plugin initialization started: ${joinIds(starting)}`);\n\n const getInitStatus = () => {\n let status = '';\n if (started.size > 0) {\n status = `, newly initialized: ${joinIds(started)}`;\n started.clear();\n }\n if (starting.size > 0) {\n status += `, still initializing: ${joinIds(starting)}`;\n }\n return status;\n };\n\n // Periodically log the initialization status with a fibonacci backoff\n let interval = 1000;\n let prevInterval = 0;\n let timeout: NodeJS.Timeout | undefined;\n const onTimeout = () => {\n logger?.info(`Plugin initialization in progress${getInitStatus()}`);\n\n const nextInterval = Math.min(interval + prevInterval, LOGGER_INTERVAL_MAX);\n prevInterval = interval;\n interval = nextInterval;\n\n timeout = setTimeout(onTimeout, nextInterval);\n };\n timeout = setTimeout(onTimeout, interval);\n\n return {\n onPluginResult(pluginId: string, error?: Error) {\n starting.delete(pluginId);\n started.add(pluginId);\n\n const modules = moduleResultsByPlugin.get(pluginId);\n if (!modules) {\n throw new Error(\n `Failed to push plugin result for nonexistent plugin '${pluginId}'`,\n );\n }\n\n if (!error) {\n pluginResults.push({\n pluginId,\n resultAt: new Date(),\n modules,\n });\n } else {\n const allowed = options.allowBootFailurePredicate(pluginId);\n pluginResults.push({\n pluginId,\n resultAt: new Date(),\n modules,\n failure: {\n error,\n allowed,\n },\n });\n if (allowed) {\n logger?.error(\n `Plugin '${pluginId}' threw an error during startup, but boot failure is permitted for this plugin so startup will continue.`,\n error,\n );\n } else {\n hasDisallowedFailures = true;\n const status =\n starting.size > 0\n ? `, waiting for ${starting.size} other plugins to finish before shutting down the process`\n : '';\n logger?.error(\n `Plugin '${pluginId}' threw an error during startup${status}.`,\n error,\n );\n }\n }\n },\n onPluginModuleResult(pluginId: string, moduleId: string, error?: Error) {\n const moduleResults = moduleResultsByPlugin.get(pluginId);\n if (!moduleResults) {\n throw new Error(\n `Failed to push module result for nonexistent plugin '${pluginId}'`,\n );\n }\n\n if (!error) {\n moduleResults.push({ moduleId, resultAt: new Date() });\n } else {\n const allowed = options.allowBootFailurePredicate(pluginId, moduleId);\n moduleResults.push({\n moduleId,\n resultAt: new Date(),\n failure: { error, allowed },\n });\n if (allowed) {\n logger?.error(\n `Module ${moduleId} in Plugin '${pluginId}' threw an error during startup, but boot failure is permitted for this plugin module so startup will continue.`,\n error,\n );\n } else {\n hasDisallowedFailures = true;\n const status =\n starting.size > 0\n ? `, waiting for ${starting.size} other plugins to finish before shutting down the process`\n : '';\n logger?.error(\n `Module ${moduleId} in Plugin '${pluginId}' threw an error during startup${status}.`,\n error,\n );\n }\n }\n },\n amendPluginModuleResult(pluginId: string, moduleId: string, error: Error) {\n if (hasFinalized) {\n logger?.error(\n `Plugin '${pluginId}' reported failure for module '${moduleId}' after startup`,\n error,\n );\n return;\n }\n const moduleResults = moduleResultsByPlugin.get(pluginId);\n if (!moduleResults) {\n throw new Error(\n `Failed to amend module result for nonexistent plugin '${pluginId}'`,\n );\n }\n const result = moduleResults.find(r => r.moduleId === moduleId);\n if (!result) {\n throw new Error(\n `Failed to amend module result for nonexistent module '${moduleId}' in plugin '${pluginId}'`,\n );\n }\n const allowed = options.allowBootFailurePredicate(pluginId, moduleId);\n if (allowed) {\n logger?.error(\n `Plugin '${pluginId}' reported failure for module '${moduleId}' during startup, but boot failure is permitted for this plugin module so startup will continue.`,\n error,\n );\n } else {\n hasDisallowedFailures = true;\n logger?.error(\n `Plugin '${pluginId}' reported failure for module '${moduleId}' during startup.`,\n error,\n );\n }\n result.failure = { error, allowed };\n },\n finalize() {\n hasFinalized = true;\n logger?.info(`Plugin initialization complete${getInitStatus()}`);\n\n if (timeout) {\n clearTimeout(timeout);\n timeout = undefined;\n }\n return {\n beginAt,\n resultAt: new Date(),\n outcome: hasDisallowedFailures ? 'failure' : 'success',\n plugins: pluginResults,\n };\n },\n };\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"createInitializationResultCollector.cjs.js","sources":["../../src/wiring/createInitializationResultCollector.ts"],"sourcesContent":["/*\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 { RootLoggerService } from '@backstage/backend-plugin-api';\nimport { AllowBootFailurePredicate } from './createAllowBootFailurePredicate';\nimport {\n BackendStartupResult,\n PluginStartupResult,\n ModuleStartupResult,\n} from './types';\n\nconst LOGGER_INTERVAL_MAX = 60_000;\n\nfunction joinIds(ids: Iterable<string>): string {\n return [...ids].map(id => `'${id}'`).join(', ');\n}\n\nexport function createInitializationResultCollector(options: {\n pluginIds: string[];\n logger?: RootLoggerService;\n allowBootFailurePredicate: AllowBootFailurePredicate;\n}): {\n onPluginResult(pluginId: string, error?: Error): void;\n onPluginModuleResult(pluginId: string, moduleId: string, error?: Error): void;\n amendPluginModuleResult(\n pluginId: string,\n moduleId: string,\n error: Error,\n ): void;\n finalize(): BackendStartupResult;\n} {\n const logger = options.logger?.child({ type: 'initialization' });\n const beginAt = new Date();\n const starting = new Set(options.pluginIds.toSorted());\n const started = new Set<string>();\n\n let hasFinalized = false;\n let hasDisallowedFailures = false;\n\n const pluginResults: PluginStartupResult[] = [];\n const moduleResultsByPlugin: Map<string, ModuleStartupResult[]> = new Map(\n Array.from(starting).map(pluginId => [pluginId, []]),\n );\n\n logger?.info(`Plugin initialization started: ${joinIds(starting)}`);\n\n const getInitStatus = () => {\n let status = '';\n if (started.size > 0) {\n status = `, newly initialized: ${joinIds(started)}`;\n started.clear();\n }\n if (starting.size > 0) {\n status += `, still initializing: ${joinIds(starting)}`;\n }\n return status;\n };\n\n // Periodically log the initialization status with a fibonacci backoff\n let interval = 1000;\n let prevInterval = 0;\n let timeout: NodeJS.Timeout | undefined;\n const onTimeout = () => {\n logger?.info(`Plugin initialization in progress${getInitStatus()}`);\n\n const nextInterval = Math.min(interval + prevInterval, LOGGER_INTERVAL_MAX);\n prevInterval = interval;\n interval = nextInterval;\n\n timeout = setTimeout(onTimeout, nextInterval);\n };\n timeout = setTimeout(onTimeout, interval);\n\n return {\n onPluginResult(pluginId: string, error?: Error) {\n starting.delete(pluginId);\n started.add(pluginId);\n\n const modules = moduleResultsByPlugin.get(pluginId);\n if (!modules) {\n throw new Error(\n `Failed to push plugin result for nonexistent plugin '${pluginId}'`,\n );\n }\n\n if (!error) {\n pluginResults.push({\n pluginId,\n resultAt: new Date(),\n modules,\n });\n } else {\n const allowed = options.allowBootFailurePredicate(pluginId);\n pluginResults.push({\n pluginId,\n resultAt: new Date(),\n modules,\n failure: {\n error,\n allowed,\n },\n });\n if (allowed) {\n logger?.error(\n `Plugin '${pluginId}' threw an error during startup, but boot failure is permitted for this plugin so startup will continue.`,\n error,\n );\n } else {\n hasDisallowedFailures = true;\n const status =\n starting.size > 0\n ? `, waiting for ${starting.size} other plugins to finish before shutting down the process`\n : '';\n logger?.error(\n `Plugin '${pluginId}' threw an error during startup${status}.`,\n error,\n );\n }\n }\n },\n onPluginModuleResult(pluginId: string, moduleId: string, error?: Error) {\n const moduleResults = moduleResultsByPlugin.get(pluginId);\n if (!moduleResults) {\n throw new Error(\n `Failed to push module result for nonexistent plugin '${pluginId}'`,\n );\n }\n\n if (!error) {\n moduleResults.push({ moduleId, resultAt: new Date() });\n } else {\n const allowed = options.allowBootFailurePredicate(pluginId, moduleId);\n moduleResults.push({\n moduleId,\n resultAt: new Date(),\n failure: { error, allowed },\n });\n if (allowed) {\n logger?.error(\n `Module ${moduleId} in Plugin '${pluginId}' threw an error during startup, but boot failure is permitted for this plugin module so startup will continue.`,\n error,\n );\n } else {\n hasDisallowedFailures = true;\n const status =\n starting.size > 0\n ? `, waiting for ${starting.size} other plugins to finish before shutting down the process`\n : '';\n logger?.error(\n `Module ${moduleId} in Plugin '${pluginId}' threw an error during startup${status}.`,\n error,\n );\n }\n }\n },\n amendPluginModuleResult(pluginId: string, moduleId: string, error: Error) {\n if (hasFinalized) {\n logger?.error(\n `Plugin '${pluginId}' reported failure for module '${moduleId}' after startup`,\n error,\n );\n return;\n }\n const moduleResults = moduleResultsByPlugin.get(pluginId);\n if (!moduleResults) {\n throw new Error(\n `Failed to amend module result for nonexistent plugin '${pluginId}'`,\n );\n }\n const result = moduleResults.find(r => r.moduleId === moduleId);\n if (!result) {\n throw new Error(\n `Failed to amend module result for nonexistent module '${moduleId}' in plugin '${pluginId}'`,\n );\n }\n const allowed = options.allowBootFailurePredicate(pluginId, moduleId);\n if (allowed) {\n logger?.error(\n `Plugin '${pluginId}' reported failure for module '${moduleId}' during startup, but boot failure is permitted for this plugin module so startup will continue.`,\n error,\n );\n } else {\n hasDisallowedFailures = true;\n logger?.error(\n `Plugin '${pluginId}' reported failure for module '${moduleId}' during startup.`,\n error,\n );\n }\n result.failure = { error, allowed };\n },\n finalize() {\n hasFinalized = true;\n logger?.info(`Plugin initialization complete${getInitStatus()}`);\n\n if (timeout) {\n clearTimeout(timeout);\n timeout = undefined;\n }\n return {\n beginAt,\n resultAt: new Date(),\n outcome: hasDisallowedFailures ? 'failure' : 'success',\n plugins: pluginResults,\n };\n },\n };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createSpecializedBackend.cjs.js","sources":["../../src/wiring/createSpecializedBackend.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 { coreServices } from '@backstage/backend-plugin-api';\nimport { BackstageBackend } from './BackstageBackend';\nimport { Backend, CreateSpecializedBackendOptions } from './types';\n\n/**\n * @public\n */\nexport function createSpecializedBackend(\n options: CreateSpecializedBackendOptions,\n): Backend {\n const exists = new Set<string>();\n const duplicates = new Set<string>();\n for (const { service } of options.defaultServiceFactories) {\n if (exists.has(service.id)) {\n duplicates.add(service.id);\n } else {\n exists.add(service.id);\n }\n }\n if (duplicates.size > 0) {\n const ids = Array.from(duplicates).join(', ');\n throw new Error(`Duplicate service implementations provided for ${ids}`);\n }\n if (exists.has(coreServices.pluginMetadata.id)) {\n throw new Error(\n `The ${coreServices.pluginMetadata.id} service cannot be overridden`,\n );\n }\n\n return new BackstageBackend(\n options.defaultServiceFactories,\n options.extensionPointFactoryMiddleware,\n );\n}\n"],"names":["coreServices","BackstageBackend"],"mappings":";;;;;AAuBO,SAAS,yBACd,OAAA,EACS;AACT,EAAA,MAAM,MAAA,uBAAa,GAAA,EAAY;AAC/B,EAAA,MAAM,UAAA,uBAAiB,GAAA,EAAY;AACnC,EAAA,KAAA,MAAW,EAAE,OAAA,EAAQ,IAAK,OAAA,CAAQ,uBAAA,EAAyB;AACzD,IAAA,IAAI,MAAA,CAAO,GAAA,CAAI,OAAA,CAAQ,EAAE,CAAA,EAAG;AAC1B,MAAA,UAAA,CAAW,GAAA,CAAI,QAAQ,EAAE,CAAA;AAAA,IAC3B,CAAA,MAAO;AACL,MAAA,MAAA,CAAO,GAAA,CAAI,QAAQ,EAAE,CAAA;AAAA,IACvB;AAAA,EACF;AACA,EAAA,IAAI,UAAA,CAAW,OAAO,CAAA,EAAG;AACvB,IAAA,MAAM,MAAM,KAAA,CAAM,IAAA,CAAK,UAAU,CAAA,CAAE,KAAK,IAAI,CAAA;AAC5C,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,+CAAA,EAAkD,GAAG,CAAA,CAAE,CAAA;AAAA,EACzE;AACA,EAAA,IAAI,MAAA,CAAO,GAAA,CAAIA,6BAAA,CAAa,cAAA,CAAe,EAAE,CAAA,EAAG;AAC9C,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,IAAA,EAAOA,6BAAA,CAAa,cAAA,CAAe,EAAE,CAAA,6BAAA;AAAA,KACvC;AAAA,EACF;AAEA,EAAA,OAAO,IAAIC,iCAAA;AAAA,IACT,OAAA,CAAQ,uBAAA;AAAA,IACR,OAAA,CAAQ;AAAA,GACV;AACF
|
|
1
|
+
{"version":3,"file":"createSpecializedBackend.cjs.js","sources":["../../src/wiring/createSpecializedBackend.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 { coreServices } from '@backstage/backend-plugin-api';\nimport { BackstageBackend } from './BackstageBackend';\nimport { Backend, CreateSpecializedBackendOptions } from './types';\n\n/**\n * @public\n */\nexport function createSpecializedBackend(\n options: CreateSpecializedBackendOptions,\n): Backend {\n const exists = new Set<string>();\n const duplicates = new Set<string>();\n for (const { service } of options.defaultServiceFactories) {\n if (exists.has(service.id)) {\n duplicates.add(service.id);\n } else {\n exists.add(service.id);\n }\n }\n if (duplicates.size > 0) {\n const ids = Array.from(duplicates).join(', ');\n throw new Error(`Duplicate service implementations provided for ${ids}`);\n }\n if (exists.has(coreServices.pluginMetadata.id)) {\n throw new Error(\n `The ${coreServices.pluginMetadata.id} service cannot be overridden`,\n );\n }\n\n return new BackstageBackend(\n options.defaultServiceFactories,\n options.extensionPointFactoryMiddleware,\n );\n}\n"],"names":["coreServices","BackstageBackend"],"mappings":";;;;;AAuBO,SAAS,yBACd,OAAA,EACS;AACT,EAAA,MAAM,MAAA,uBAAa,GAAA,EAAY;AAC/B,EAAA,MAAM,UAAA,uBAAiB,GAAA,EAAY;AACnC,EAAA,KAAA,MAAW,EAAE,OAAA,EAAQ,IAAK,OAAA,CAAQ,uBAAA,EAAyB;AACzD,IAAA,IAAI,MAAA,CAAO,GAAA,CAAI,OAAA,CAAQ,EAAE,CAAA,EAAG;AAC1B,MAAA,UAAA,CAAW,GAAA,CAAI,QAAQ,EAAE,CAAA;AAAA,IAC3B,CAAA,MAAO;AACL,MAAA,MAAA,CAAO,GAAA,CAAI,QAAQ,EAAE,CAAA;AAAA,IACvB;AAAA,EACF;AACA,EAAA,IAAI,UAAA,CAAW,OAAO,CAAA,EAAG;AACvB,IAAA,MAAM,MAAM,KAAA,CAAM,IAAA,CAAK,UAAU,CAAA,CAAE,KAAK,IAAI,CAAA;AAC5C,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,+CAAA,EAAkD,GAAG,CAAA,CAAE,CAAA;AAAA,EACzE;AACA,EAAA,IAAI,MAAA,CAAO,GAAA,CAAIA,6BAAA,CAAa,cAAA,CAAe,EAAE,CAAA,EAAG;AAC9C,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,IAAA,EAAOA,6BAAA,CAAa,cAAA,CAAe,EAAE,CAAA,6BAAA;AAAA,KACvC;AAAA,EACF;AAEA,EAAA,OAAO,IAAIC,iCAAA;AAAA,IACT,OAAA,CAAQ,uBAAA;AAAA,IACR,OAAA,CAAQ;AAAA,GACV;AACF;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.cjs.js","sources":["../../src/wiring/helpers.ts"],"sourcesContent":["/*\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\n/** @internal */\nexport type DeepReadonly<T> = {\n readonly [K in keyof T]: T[K] extends object ? DeepReadonly<T[K]> : T[K];\n};\n\n/**\n * Deeply freezes an object by recursively freezing all of its properties.\n * From https://gist.github.com/tkrotoff/e997cd6ff8d6cf6e51e6bb6146407fc3 +\n * https://stackoverflow.com/a/69656011\n */\nexport function deepFreeze<T>(obj: T) {\n // Can cause: \"Type instantiation is excessively deep and possibly infinite.\"\n // @ts-expect-error\n Object.values(obj).forEach(\n value => Object.isFrozen(value) || deepFreeze(value),\n );\n return Object.freeze(obj) as DeepReadonly<T>;\n}\n"],"names":[],"mappings":";;AA0BO,SAAS,WAAc,GAAA,EAAQ;AAGpC,EAAA,MAAA,CAAO,MAAA,CAAO,GAAG,CAAA,CAAE,OAAA;AAAA,IACjB,WAAS,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA,IAAK,WAAW,KAAK;AAAA,GACrD;AACA,EAAA,OAAO,MAAA,CAAO,OAAO,GAAG,CAAA;AAC1B
|
|
1
|
+
{"version":3,"file":"helpers.cjs.js","sources":["../../src/wiring/helpers.ts"],"sourcesContent":["/*\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\n/** @internal */\nexport type DeepReadonly<T> = {\n readonly [K in keyof T]: T[K] extends object ? DeepReadonly<T[K]> : T[K];\n};\n\n/**\n * Deeply freezes an object by recursively freezing all of its properties.\n * From https://gist.github.com/tkrotoff/e997cd6ff8d6cf6e51e6bb6146407fc3 +\n * https://stackoverflow.com/a/69656011\n */\nexport function deepFreeze<T>(obj: T) {\n // Can cause: \"Type instantiation is excessively deep and possibly infinite.\"\n // @ts-expect-error\n Object.values(obj).forEach(\n value => Object.isFrozen(value) || deepFreeze(value),\n );\n return Object.freeze(obj) as DeepReadonly<T>;\n}\n"],"names":[],"mappings":";;AA0BO,SAAS,WAAc,GAAA,EAAQ;AAGpC,EAAA,MAAA,CAAO,MAAA,CAAO,GAAG,CAAA,CAAE,OAAA;AAAA,IACjB,WAAS,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA,IAAK,WAAW,KAAK;AAAA,GACrD;AACA,EAAA,OAAO,MAAA,CAAO,OAAO,GAAG,CAAA;AAC1B;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.cjs.js","sources":["../../src/wiring/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 {\n BackendFeature,\n ExtensionPoint,\n ServiceRef,\n ServiceFactory,\n} from '@backstage/backend-plugin-api';\nimport { OpaqueExtensionPointFactoryMiddleware } from '@internal/backend';\n\n/**\n * A middleware entry that reimplements a specific extension point's output.\n * The framework matches by extension point ID and passes through all\n * non-matching extension points automatically.\n *\n * @public\n */\nexport interface ExtensionPointFactoryMiddleware {\n $$type: '@backstage/ExtensionPointFactoryMiddleware';\n}\n\n/**\n * Creates a typed middleware entry that reimplements a specific extension point.\n * Use this helper to preserve type inference for the middleware callback.\n *\n * @public\n */\nexport function createExtensionPointFactoryMiddleware<T>(options: {\n extensionPoint: ExtensionPoint<T>;\n middleware: (original: T) => Promise<T>;\n}): ExtensionPointFactoryMiddleware {\n return OpaqueExtensionPointFactoryMiddleware.createInstance('v1', {\n extensionPointId: options.extensionPoint.id,\n middleware: options.middleware as (original: unknown) => Promise<unknown>,\n });\n}\n\n/**\n * @public\n */\nexport interface Backend {\n add(feature: BackendFeature | Promise<{ default: BackendFeature }>): void;\n start(): Promise<{ result: BackendStartupResult }>;\n stop(): Promise<void>;\n}\n\n/**\n * @public\n */\nexport interface CreateSpecializedBackendOptions {\n defaultServiceFactories: ServiceFactory[];\n extensionPointFactoryMiddleware?: ExtensionPointFactoryMiddleware[];\n}\n\n/**\n * @public\n */\nexport type ServiceOrExtensionPoint<T = unknown> =\n | ExtensionPoint<T>\n | ServiceRef<T>;\n\n/**\n * Result of a module startup attempt.\n * @public\n */\nexport interface ModuleStartupResult {\n /**\n * The time the module startup was completed.\n */\n resultAt: Date;\n\n /**\n * The ID of the module.\n */\n moduleId: string;\n\n /**\n * If the startup failed, this contains information about the failure.\n */\n failure?: {\n /**\n * The error that occurred during startup, if any.\n */\n error: Error;\n /**\n * Whether the failure was allowed.\n */\n allowed: boolean;\n };\n}\n\n/**\n * Result of a plugin startup attempt.\n * @public\n */\nexport interface PluginStartupResult {\n /**\n * The time the plugin startup was completed.\n */\n resultAt: Date;\n /**\n * If the startup failed, this contains information about the failure.\n */\n failure?: {\n /**\n * The error that occurred during startup, if any.\n */\n error: Error;\n /**\n * Whether the failure was allowed.\n */\n allowed: boolean;\n };\n /**\n * The ID of the plugin.\n */\n pluginId: string;\n /**\n * Results for all modules belonging to this plugin.\n */\n modules: ModuleStartupResult[];\n}\n\n/**\n * Result of a backend startup attempt.\n * @public\n */\nexport interface BackendStartupResult {\n /**\n * The time the backend startup started.\n */\n beginAt: Date;\n /**\n * The time the backend startup was completed.\n */\n resultAt: Date;\n /**\n * Results for all plugins that were attempted to start.\n */\n plugins: PluginStartupResult[];\n /**\n * The outcome of the backend startup.\n */\n outcome: 'success' | 'failure';\n}\n"],"names":["OpaqueExtensionPointFactoryMiddleware"],"mappings":";;;;AAyCO,SAAS,sCAAyC,OAAA,EAGrB;AAClC,EAAA,OAAOA,2EAAA,CAAsC,eAAe,IAAA,EAAM;AAAA,IAChE,gBAAA,EAAkB,QAAQ,cAAA,CAAe,EAAA;AAAA,IACzC,YAAY,OAAA,CAAQ;AAAA,GACrB,CAAA;AACH
|
|
1
|
+
{"version":3,"file":"types.cjs.js","sources":["../../src/wiring/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 {\n BackendFeature,\n ExtensionPoint,\n ServiceRef,\n ServiceFactory,\n} from '@backstage/backend-plugin-api';\nimport { OpaqueExtensionPointFactoryMiddleware } from '@internal/backend';\n\n/**\n * A middleware entry that reimplements a specific extension point's output.\n * The framework matches by extension point ID and passes through all\n * non-matching extension points automatically.\n *\n * @public\n */\nexport interface ExtensionPointFactoryMiddleware {\n $$type: '@backstage/ExtensionPointFactoryMiddleware';\n}\n\n/**\n * Creates a typed middleware entry that reimplements a specific extension point.\n * Use this helper to preserve type inference for the middleware callback.\n *\n * @public\n */\nexport function createExtensionPointFactoryMiddleware<T>(options: {\n extensionPoint: ExtensionPoint<T>;\n middleware: (original: T) => Promise<T>;\n}): ExtensionPointFactoryMiddleware {\n return OpaqueExtensionPointFactoryMiddleware.createInstance('v1', {\n extensionPointId: options.extensionPoint.id,\n middleware: options.middleware as (original: unknown) => Promise<unknown>,\n });\n}\n\n/**\n * @public\n */\nexport interface Backend {\n add(feature: BackendFeature | Promise<{ default: BackendFeature }>): void;\n start(): Promise<{ result: BackendStartupResult }>;\n stop(): Promise<void>;\n}\n\n/**\n * @public\n */\nexport interface CreateSpecializedBackendOptions {\n defaultServiceFactories: ServiceFactory[];\n extensionPointFactoryMiddleware?: ExtensionPointFactoryMiddleware[];\n}\n\n/**\n * @public\n */\nexport type ServiceOrExtensionPoint<T = unknown> =\n | ExtensionPoint<T>\n | ServiceRef<T>;\n\n/**\n * Result of a module startup attempt.\n * @public\n */\nexport interface ModuleStartupResult {\n /**\n * The time the module startup was completed.\n */\n resultAt: Date;\n\n /**\n * The ID of the module.\n */\n moduleId: string;\n\n /**\n * If the startup failed, this contains information about the failure.\n */\n failure?: {\n /**\n * The error that occurred during startup, if any.\n */\n error: Error;\n /**\n * Whether the failure was allowed.\n */\n allowed: boolean;\n };\n}\n\n/**\n * Result of a plugin startup attempt.\n * @public\n */\nexport interface PluginStartupResult {\n /**\n * The time the plugin startup was completed.\n */\n resultAt: Date;\n /**\n * If the startup failed, this contains information about the failure.\n */\n failure?: {\n /**\n * The error that occurred during startup, if any.\n */\n error: Error;\n /**\n * Whether the failure was allowed.\n */\n allowed: boolean;\n };\n /**\n * The ID of the plugin.\n */\n pluginId: string;\n /**\n * Results for all modules belonging to this plugin.\n */\n modules: ModuleStartupResult[];\n}\n\n/**\n * Result of a backend startup attempt.\n * @public\n */\nexport interface BackendStartupResult {\n /**\n * The time the backend startup started.\n */\n beginAt: Date;\n /**\n * The time the backend startup was completed.\n */\n resultAt: Date;\n /**\n * Results for all plugins that were attempted to start.\n */\n plugins: PluginStartupResult[];\n /**\n * The outcome of the backend startup.\n */\n outcome: 'success' | 'failure';\n}\n"],"names":["OpaqueExtensionPointFactoryMiddleware"],"mappings":";;;;AAyCO,SAAS,sCAAyC,OAAA,EAGrB;AAClC,EAAA,OAAOA,2EAAA,CAAsC,eAAe,IAAA,EAAM;AAAA,IAChE,gBAAA,EAAkB,QAAQ,cAAA,CAAe,EAAA;AAAA,IACzC,YAAY,OAAA,CAAQ;AAAA,GACrB,CAAA;AACH;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validateBackendFeature.cjs.js","sources":["../../src/wiring/validateBackendFeature.ts"],"sourcesContent":["/*\n * Copyright 2026 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 { InputError } from '@backstage/errors';\n// Direct internal import to avoid duplication\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport type {\n InternalBackendFeatureLoader,\n InternalBackendRegistrations,\n} from '../../../backend-plugin-api/src/wiring/types';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport type { InternalServiceFactory } from '../../../backend-plugin-api/src/services/system/types';\n\nexport type ValidatedBackendFeature =\n | { type: 'service'; feature: InternalServiceFactory }\n | { type: 'loader'; feature: InternalBackendFeatureLoader }\n | { type: 'registrations'; feature: InternalBackendRegistrations };\n\nfunction describeValue(value: unknown): string {\n if (value === undefined) {\n return 'undefined';\n }\n if (value === null) {\n return 'null';\n }\n if (typeof value === 'string') {\n return JSON.stringify(value);\n }\n if (\n typeof value === 'number' ||\n typeof value === 'boolean' ||\n typeof value === 'bigint'\n ) {\n return String(value);\n }\n if (typeof value === 'function') {\n return 'a function';\n }\n if (Array.isArray(value)) {\n return 'an array';\n }\n return 'an object';\n}\n\nexport function throwInvalidBackendFeature(\n path: string,\n expected: string,\n value: unknown,\n): never {\n throw new InputError(\n `Invalid backend feature at ${path}, expected ${expected}, received ${describeValue(\n value,\n )}`,\n );\n}\n\nexport function assertObject(\n value: unknown,\n path: string,\n expected = 'an object',\n): asserts value is Record<string, unknown> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n throwInvalidBackendFeature(path, expected, value);\n }\n}\n\nexport function assertObjectLike(\n value: unknown,\n path: string,\n): asserts value is Record<string, unknown> {\n if (\n (typeof value !== 'object' || value === null) &&\n typeof value !== 'function'\n ) {\n throwInvalidBackendFeature(path, 'an object or function', value);\n }\n}\n\nexport function assertString(\n value: unknown,\n path: string,\n): asserts value is string {\n if (typeof value !== 'string') {\n throwInvalidBackendFeature(path, 'a string', value);\n }\n}\n\nexport function assertFunction(\n value: unknown,\n path: string,\n): asserts value is (...args: any[]) => unknown {\n if (typeof value !== 'function') {\n throwInvalidBackendFeature(path, 'a function', value);\n }\n}\n\nexport function assertArray(\n value: unknown,\n path: string,\n): asserts value is unknown[] {\n if (!Array.isArray(value)) {\n throwInvalidBackendFeature(path, 'an array', value);\n }\n}\n\nexport function validateServiceRef(value: unknown, path: string): void {\n assertObject(value, path, 'a service reference object');\n assertString(value.id, `${path}.id`);\n if (value.scope !== 'root' && value.scope !== 'plugin') {\n throwInvalidBackendFeature(\n `${path}.scope`,\n '\"root\" or \"plugin\"',\n value.scope,\n );\n }\n}\n\nexport function validateExtensionPoint(value: unknown, path: string): void {\n assertObject(value, path, 'an extension point reference object');\n assertString(value.id, `${path}.id`);\n}\n\n/**\n * Reads the registrations from a backend feature and validates the outer\n * registration objects and their identifying fields.\n *\n * Nested registration data is validated later by\n * {@link validateBackendRegistration}, when each registration is enumerated.\n */\nexport function validateBackendRegistrations(\n feature: InternalBackendRegistrations,\n source: string,\n): ReturnType<InternalBackendRegistrations['getRegistrations']> {\n assertFunction(feature.getRegistrations, `${source}.getRegistrations`);\n const registrations: unknown = feature.getRegistrations();\n assertArray(registrations, `${source}.getRegistrations()`);\n\n for (let index = 0; index < registrations.length; index++) {\n const path = `${source}.getRegistrations()[${index}]`;\n const registration = registrations[index];\n assertObject(registration, path, 'a registration object');\n\n if (\n registration.type === 'plugin' ||\n registration.type === 'module' ||\n registration.type === 'plugin-v1.1' ||\n registration.type === 'module-v1.1'\n ) {\n assertString(registration.pluginId, `${path}.pluginId`);\n }\n if (registration.type === 'module' || registration.type === 'module-v1.1') {\n const modulePath =\n typeof registration.pluginId === 'string'\n ? `module registration for plugin ${JSON.stringify(\n registration.pluginId,\n )}`\n : path;\n assertString(registration.moduleId, `${modulePath}.moduleId`);\n }\n }\n\n return registrations as ReturnType<\n InternalBackendRegistrations['getRegistrations']\n >;\n}\n\n/**\n * Validates the nested extension point and dependency data consumed while a\n * single plugin or module registration is enumerated.\n *\n * The registration object and its identifying fields have already been\n * validated by {@link validateBackendRegistrations}. Duplicate and conflicting\n * registrations are handled separately by the backend initializer.\n */\nexport function validateBackendRegistration(\n registration: ReturnType<\n InternalBackendRegistrations['getRegistrations']\n >[number],\n): void {\n let registrationPath = 'registration';\n if ('moduleId' in registration) {\n registrationPath = `module ${JSON.stringify(\n registration.moduleId,\n )} for plugin ${JSON.stringify(registration.pluginId)}`;\n } else if ('pluginId' in registration) {\n registrationPath = `plugin ${JSON.stringify(registration.pluginId)}`;\n }\n\n if (registration.type === 'plugin' || registration.type === 'module') {\n assertArray(\n registration.extensionPoints,\n `${registrationPath}.extensionPoints`,\n );\n for (let index = 0; index < registration.extensionPoints.length; index++) {\n const itemPath = `${registrationPath}.extensionPoints[${index}]`;\n const item: unknown = registration.extensionPoints[index];\n assertArray(item, itemPath);\n validateExtensionPoint(item[0], `${itemPath}[0]`);\n }\n } else if (\n registration.type === 'plugin-v1.1' ||\n registration.type === 'module-v1.1'\n ) {\n assertArray(\n registration.extensionPoints,\n `${registrationPath}.extensionPoints`,\n );\n for (let index = 0; index < registration.extensionPoints.length; index++) {\n const itemPath = `${registrationPath}.extensionPoints[${index}]`;\n const item: unknown = registration.extensionPoints[index];\n assertObject(item, itemPath, 'an extension point registration object');\n validateExtensionPoint(item.extensionPoint, `${itemPath}.extensionPoint`);\n }\n }\n\n if (\n registration.type === 'plugin' ||\n registration.type === 'module' ||\n registration.type === 'plugin-v1.1' ||\n registration.type === 'module-v1.1'\n ) {\n assertObject(\n registration.init,\n `${registrationPath}.init`,\n 'an init registration object',\n );\n assertObject(\n registration.init.deps,\n `${registrationPath}.init.deps`,\n 'a dependency object',\n );\n for (const [name, ref] of Object.entries(registration.init.deps)) {\n const path = `${registrationPath}.init.deps.${name}`;\n if (\n (registration.type === 'module' ||\n registration.type === 'module-v1.1') &&\n typeof ref === 'object' &&\n ref !== null &&\n (ref as { $$type?: unknown }).$$type === '@backstage/ExtensionPoint'\n ) {\n validateExtensionPoint(ref, path);\n } else {\n validateServiceRef(ref, path);\n }\n }\n }\n}\n\nexport function describeBackendFeature(value: unknown): string | undefined {\n if (\n (typeof value !== 'object' || value === null) &&\n typeof value !== 'function'\n ) {\n return undefined;\n }\n\n const feature = value as Record<string, unknown>;\n const service = feature.service;\n if (typeof service === 'object' && service !== null && 'id' in service) {\n const serviceId = service.id;\n if (typeof serviceId === 'string') {\n return `service factory for ${JSON.stringify(serviceId)}`;\n }\n }\n\n if (\n feature.featureType === 'loader' &&\n typeof feature.description === 'string'\n ) {\n return `feature loader ${feature.description}`;\n }\n\n if (typeof feature.description === 'string') {\n return `backend feature ${feature.description}`;\n }\n\n return undefined;\n}\n\nexport function validateBackendFeature(\n value: unknown,\n path: string,\n): ValidatedBackendFeature {\n assertObjectLike(value, path);\n if (value.$$type !== '@backstage/BackendFeature') {\n throwInvalidBackendFeature(\n `${path}.$$type`,\n '\"@backstage/BackendFeature\"',\n value.$$type,\n );\n }\n if (value.version !== 'v1') {\n throwInvalidBackendFeature(`${path}.version`, '\"v1\"', value.version);\n }\n\n if (value.featureType === 'service' || 'service' in value) {\n return {\n type: 'service',\n feature: value as unknown as InternalServiceFactory,\n };\n }\n if (value.featureType === 'loader') {\n return {\n type: 'loader',\n feature: value as unknown as InternalBackendFeatureLoader,\n };\n }\n if (value.featureType === 'registrations' || 'getRegistrations' in value) {\n return {\n type: 'registrations',\n feature: value as unknown as InternalBackendRegistrations,\n };\n }\n\n return throwInvalidBackendFeature(\n `${path}.featureType`,\n '\"service\", \"registrations\", or \"loader\"',\n value.featureType,\n );\n}\n"],"names":["InputError"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"validateBackendFeature.cjs.js","sources":["../../src/wiring/validateBackendFeature.ts"],"sourcesContent":["/*\n * Copyright 2026 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 { InputError } from '@backstage/errors';\n// Direct internal import to avoid duplication\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport type {\n InternalBackendFeatureLoader,\n InternalBackendRegistrations,\n} from '../../../backend-plugin-api/src/wiring/types';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport type { InternalServiceFactory } from '../../../backend-plugin-api/src/services/system/types';\n\nexport type ValidatedBackendFeature =\n | { type: 'service'; feature: InternalServiceFactory }\n | { type: 'loader'; feature: InternalBackendFeatureLoader }\n | { type: 'registrations'; feature: InternalBackendRegistrations };\n\nfunction describeValue(value: unknown): string {\n if (value === undefined) {\n return 'undefined';\n }\n if (value === null) {\n return 'null';\n }\n if (typeof value === 'string') {\n return JSON.stringify(value);\n }\n if (\n typeof value === 'number' ||\n typeof value === 'boolean' ||\n typeof value === 'bigint'\n ) {\n return String(value);\n }\n if (typeof value === 'function') {\n return 'a function';\n }\n if (Array.isArray(value)) {\n return 'an array';\n }\n return 'an object';\n}\n\nexport function throwInvalidBackendFeature(\n path: string,\n expected: string,\n value: unknown,\n): never {\n throw new InputError(\n `Invalid backend feature at ${path}, expected ${expected}, received ${describeValue(\n value,\n )}`,\n );\n}\n\nexport function assertObject(\n value: unknown,\n path: string,\n expected = 'an object',\n): asserts value is Record<string, unknown> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n throwInvalidBackendFeature(path, expected, value);\n }\n}\n\nexport function assertObjectLike(\n value: unknown,\n path: string,\n): asserts value is Record<string, unknown> {\n if (\n (typeof value !== 'object' || value === null) &&\n typeof value !== 'function'\n ) {\n throwInvalidBackendFeature(path, 'an object or function', value);\n }\n}\n\nexport function assertString(\n value: unknown,\n path: string,\n): asserts value is string {\n if (typeof value !== 'string') {\n throwInvalidBackendFeature(path, 'a string', value);\n }\n}\n\nexport function assertFunction(\n value: unknown,\n path: string,\n): asserts value is (...args: any[]) => unknown {\n if (typeof value !== 'function') {\n throwInvalidBackendFeature(path, 'a function', value);\n }\n}\n\nexport function assertArray(\n value: unknown,\n path: string,\n): asserts value is unknown[] {\n if (!Array.isArray(value)) {\n throwInvalidBackendFeature(path, 'an array', value);\n }\n}\n\nexport function validateServiceRef(value: unknown, path: string): void {\n assertObject(value, path, 'a service reference object');\n assertString(value.id, `${path}.id`);\n if (value.scope !== 'root' && value.scope !== 'plugin') {\n throwInvalidBackendFeature(\n `${path}.scope`,\n '\"root\" or \"plugin\"',\n value.scope,\n );\n }\n}\n\nexport function validateExtensionPoint(value: unknown, path: string): void {\n assertObject(value, path, 'an extension point reference object');\n assertString(value.id, `${path}.id`);\n}\n\n/**\n * Reads the registrations from a backend feature and validates the outer\n * registration objects and their identifying fields.\n *\n * Nested registration data is validated later by\n * {@link validateBackendRegistration}, when each registration is enumerated.\n */\nexport function validateBackendRegistrations(\n feature: InternalBackendRegistrations,\n source: string,\n): ReturnType<InternalBackendRegistrations['getRegistrations']> {\n assertFunction(feature.getRegistrations, `${source}.getRegistrations`);\n const registrations: unknown = feature.getRegistrations();\n assertArray(registrations, `${source}.getRegistrations()`);\n\n for (let index = 0; index < registrations.length; index++) {\n const path = `${source}.getRegistrations()[${index}]`;\n const registration = registrations[index];\n assertObject(registration, path, 'a registration object');\n\n if (\n registration.type === 'plugin' ||\n registration.type === 'module' ||\n registration.type === 'plugin-v1.1' ||\n registration.type === 'module-v1.1'\n ) {\n assertString(registration.pluginId, `${path}.pluginId`);\n }\n if (registration.type === 'module' || registration.type === 'module-v1.1') {\n const modulePath =\n typeof registration.pluginId === 'string'\n ? `module registration for plugin ${JSON.stringify(\n registration.pluginId,\n )}`\n : path;\n assertString(registration.moduleId, `${modulePath}.moduleId`);\n }\n }\n\n return registrations as ReturnType<\n InternalBackendRegistrations['getRegistrations']\n >;\n}\n\n/**\n * Validates the nested extension point and dependency data consumed while a\n * single plugin or module registration is enumerated.\n *\n * The registration object and its identifying fields have already been\n * validated by {@link validateBackendRegistrations}. Duplicate and conflicting\n * registrations are handled separately by the backend initializer.\n */\nexport function validateBackendRegistration(\n registration: ReturnType<\n InternalBackendRegistrations['getRegistrations']\n >[number],\n): void {\n let registrationPath = 'registration';\n if ('moduleId' in registration) {\n registrationPath = `module ${JSON.stringify(\n registration.moduleId,\n )} for plugin ${JSON.stringify(registration.pluginId)}`;\n } else if ('pluginId' in registration) {\n registrationPath = `plugin ${JSON.stringify(registration.pluginId)}`;\n }\n\n if (registration.type === 'plugin' || registration.type === 'module') {\n assertArray(\n registration.extensionPoints,\n `${registrationPath}.extensionPoints`,\n );\n for (let index = 0; index < registration.extensionPoints.length; index++) {\n const itemPath = `${registrationPath}.extensionPoints[${index}]`;\n const item: unknown = registration.extensionPoints[index];\n assertArray(item, itemPath);\n validateExtensionPoint(item[0], `${itemPath}[0]`);\n }\n } else if (\n registration.type === 'plugin-v1.1' ||\n registration.type === 'module-v1.1'\n ) {\n assertArray(\n registration.extensionPoints,\n `${registrationPath}.extensionPoints`,\n );\n for (let index = 0; index < registration.extensionPoints.length; index++) {\n const itemPath = `${registrationPath}.extensionPoints[${index}]`;\n const item: unknown = registration.extensionPoints[index];\n assertObject(item, itemPath, 'an extension point registration object');\n validateExtensionPoint(item.extensionPoint, `${itemPath}.extensionPoint`);\n }\n }\n\n if (\n registration.type === 'plugin' ||\n registration.type === 'module' ||\n registration.type === 'plugin-v1.1' ||\n registration.type === 'module-v1.1'\n ) {\n assertObject(\n registration.init,\n `${registrationPath}.init`,\n 'an init registration object',\n );\n assertObject(\n registration.init.deps,\n `${registrationPath}.init.deps`,\n 'a dependency object',\n );\n for (const [name, ref] of Object.entries(registration.init.deps)) {\n const path = `${registrationPath}.init.deps.${name}`;\n if (\n (registration.type === 'module' ||\n registration.type === 'module-v1.1') &&\n typeof ref === 'object' &&\n ref !== null &&\n (ref as { $$type?: unknown }).$$type === '@backstage/ExtensionPoint'\n ) {\n validateExtensionPoint(ref, path);\n } else {\n validateServiceRef(ref, path);\n }\n }\n }\n}\n\nexport function describeBackendFeature(value: unknown): string | undefined {\n if (\n (typeof value !== 'object' || value === null) &&\n typeof value !== 'function'\n ) {\n return undefined;\n }\n\n const feature = value as Record<string, unknown>;\n const service = feature.service;\n if (typeof service === 'object' && service !== null && 'id' in service) {\n const serviceId = service.id;\n if (typeof serviceId === 'string') {\n return `service factory for ${JSON.stringify(serviceId)}`;\n }\n }\n\n if (\n feature.featureType === 'loader' &&\n typeof feature.description === 'string'\n ) {\n return `feature loader ${feature.description}`;\n }\n\n if (typeof feature.description === 'string') {\n return `backend feature ${feature.description}`;\n }\n\n return undefined;\n}\n\nexport function validateBackendFeature(\n value: unknown,\n path: string,\n): ValidatedBackendFeature {\n assertObjectLike(value, path);\n if (value.$$type !== '@backstage/BackendFeature') {\n throwInvalidBackendFeature(\n `${path}.$$type`,\n '\"@backstage/BackendFeature\"',\n value.$$type,\n );\n }\n if (value.version !== 'v1') {\n throwInvalidBackendFeature(`${path}.version`, '\"v1\"', value.version);\n }\n\n if (value.featureType === 'service' || 'service' in value) {\n return {\n type: 'service',\n feature: value as unknown as InternalServiceFactory,\n };\n }\n if (value.featureType === 'loader') {\n return {\n type: 'loader',\n feature: value as unknown as InternalBackendFeatureLoader,\n };\n }\n if (value.featureType === 'registrations' || 'getRegistrations' in value) {\n return {\n type: 'registrations',\n feature: value as unknown as InternalBackendRegistrations,\n };\n }\n\n return throwInvalidBackendFeature(\n `${path}.featureType`,\n '\"service\", \"registrations\", or \"loader\"',\n value.featureType,\n );\n}\n"],"names":["InputError"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"withDeclaredConnections.cjs.js","sources":["../../src/wiring/withDeclaredConnections.ts"],"sourcesContent":["/*\n * Copyright 2026 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 */\nimport type { ConnectionRegistration } from '@backstage/backend-plugin-api/alpha';\nimport type { ConnectionsService } from '@backstage/connections';\nimport { InputError } from '@backstage/errors';\n\n/** @internal */\nexport function withDeclaredConnections(\n service: ConnectionsService,\n registrations: ReadonlyArray<ConnectionRegistration>,\n): ConnectionsService {\n const assertDeclared = (type: string) => {\n if (\n !registrations.some(({ type: registeredType }) => registeredType === type)\n ) {\n throw new InputError(\n `Plugin attempted to look up an undeclared connection of type \"${type}\". Declare it during register() with declareConnection(reg, { type: \"${type}\" }).`,\n );\n }\n };\n return {\n async find(options: Parameters<ConnectionsService['find']>[0]) {\n assertDeclared(options.type);\n return service.find(options);\n },\n } as ConnectionsService;\n}\n"],"names":["InputError"],"mappings":";;;;AAoBO,SAAS,uBAAA,CACd,SACA,aAAA,EACoB;AACpB,EAAA,MAAM,cAAA,GAAiB,CAAC,IAAA,KAAiB;AACvC,IAAA,IACE,CAAC,aAAA,CAAc,IAAA,CAAK,CAAC,EAAE,MAAM,cAAA,EAAe,KAAM,cAAA,KAAmB,IAAI,CAAA,EACzE;AACA,MAAA,MAAM,IAAIA,iBAAA;AAAA,QACR,CAAA,8DAAA,EAAiE,IAAI,CAAA,qEAAA,EAAwE,IAAI,CAAA,KAAA;AAAA,OACnJ;AAAA,IACF;AAAA,EACF,CAAA;AACA,EAAA,OAAO;AAAA,IACL,MAAM,KAAK,OAAA,EAAoD;AAC7D,MAAA,cAAA,CAAe,QAAQ,IAAI,CAAA;AAC3B,MAAA,OAAO,OAAA,CAAQ,KAAK,OAAO,CAAA;AAAA,IAC7B;AAAA,GACF;AACF
|
|
1
|
+
{"version":3,"file":"withDeclaredConnections.cjs.js","sources":["../../src/wiring/withDeclaredConnections.ts"],"sourcesContent":["/*\n * Copyright 2026 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 */\nimport type { ConnectionRegistration } from '@backstage/backend-plugin-api/alpha';\nimport type { ConnectionsService } from '@backstage/connections';\nimport { InputError } from '@backstage/errors';\n\n/** @internal */\nexport function withDeclaredConnections(\n service: ConnectionsService,\n registrations: ReadonlyArray<ConnectionRegistration>,\n): ConnectionsService {\n const assertDeclared = (type: string) => {\n if (\n !registrations.some(({ type: registeredType }) => registeredType === type)\n ) {\n throw new InputError(\n `Plugin attempted to look up an undeclared connection of type \"${type}\". Declare it during register() with declareConnection(reg, { type: \"${type}\" }).`,\n );\n }\n };\n return {\n async find(options: Parameters<ConnectionsService['find']>[0]) {\n assertDeclared(options.type);\n return service.find(options);\n },\n } as ConnectionsService;\n}\n"],"names":["InputError"],"mappings":";;;;AAoBO,SAAS,uBAAA,CACd,SACA,aAAA,EACoB;AACpB,EAAA,MAAM,cAAA,GAAiB,CAAC,IAAA,KAAiB;AACvC,IAAA,IACE,CAAC,aAAA,CAAc,IAAA,CAAK,CAAC,EAAE,MAAM,cAAA,EAAe,KAAM,cAAA,KAAmB,IAAI,CAAA,EACzE;AACA,MAAA,MAAM,IAAIA,iBAAA;AAAA,QACR,CAAA,8DAAA,EAAiE,IAAI,CAAA,qEAAA,EAAwE,IAAI,CAAA,KAAA;AAAA,OACnJ;AAAA,IACF;AAAA,EACF,CAAA;AACA,EAAA,OAAO;AAAA,IACL,MAAM,KAAK,OAAA,EAAoD;AAC7D,MAAA,cAAA,CAAe,QAAQ,IAAI,CAAA;AAC3B,MAAA,OAAO,OAAA,CAAQ,KAAK,OAAO,CAAA;AAAA,IAC7B;AAAA,GACF;AACF;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/backend-app-api",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.5-next.0",
|
|
4
4
|
"description": "Core API used by Backstage backend apps",
|
|
5
5
|
"backstage": {
|
|
6
6
|
"role": "node-library"
|
|
@@ -50,17 +50,17 @@
|
|
|
50
50
|
"test": "backstage-cli package test"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@backstage/backend-plugin-api": "1.10.
|
|
54
|
-
"@backstage/config": "1.3.
|
|
55
|
-
"@backstage/connections": "0.4.
|
|
56
|
-
"@backstage/errors": "1.3.
|
|
53
|
+
"@backstage/backend-plugin-api": "1.10.2-next.0",
|
|
54
|
+
"@backstage/config": "1.3.10-next.0",
|
|
55
|
+
"@backstage/connections": "0.4.1-next.0",
|
|
56
|
+
"@backstage/errors": "1.3.2-next.0",
|
|
57
57
|
"@backstage/types": "1.2.2",
|
|
58
58
|
"zod": "^3.25.76 || ^4.0.0"
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
61
|
-
"@backstage/backend-defaults": "0.
|
|
62
|
-
"@backstage/backend-test-utils": "1.11.
|
|
63
|
-
"@backstage/cli": "0.36.
|
|
61
|
+
"@backstage/backend-defaults": "0.18.1-next.0",
|
|
62
|
+
"@backstage/backend-test-utils": "1.11.8-next.0",
|
|
63
|
+
"@backstage/cli": "0.36.7-next.0"
|
|
64
64
|
},
|
|
65
65
|
"configSchema": "config.schema.json"
|
|
66
66
|
}
|