@backstage/backend-app-api 1.7.3-next.1 → 1.7.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # @backstage/backend-app-api
2
2
 
3
+ ## 1.7.3
4
+
5
+ ### Patch Changes
6
+
7
+ - 64cea29: Updated the backend runtime to use the internal connection service implementation after the shared connection contract moved into `@backstage/connections`.
8
+ - 03133fc: Hardened backend startup against malformed installed backend features, with contextual input errors and configured boot-failure handling when invalid registrations can be attributed to a plugin or module.
9
+ - Updated dependencies
10
+ - @backstage/connections@0.3.0
11
+ - @backstage/backend-plugin-api@1.10.0
12
+
3
13
  ## 1.7.3-next.1
4
14
 
5
15
  ### Patch Changes
@@ -1,25 +1,10 @@
1
1
  'use strict';
2
2
 
3
+ var connections = require('@backstage/connections');
3
4
  var lookup = require('./lookup.cjs.js');
4
5
  var lookupStrategies = require('./lookupStrategies.cjs.js');
5
6
  var errors = require('@backstage/errors');
6
- var v4 = require('zod/v4');
7
- var getLegacyIntegrations = require('./getLegacyIntegrations.cjs.js');
8
- var combineConnectionSources = require('./combineConnectionSources.cjs.js');
9
7
 
10
- function describeError(error) {
11
- const e = errors.toError(error);
12
- if (e.name === "ZodError") {
13
- return v4.z.prettifyError(e);
14
- }
15
- if (e.cause !== void 0) {
16
- const cause = errors.toError(e.cause);
17
- if (cause.name === "ZodError") {
18
- return v4.z.prettifyError(cause);
19
- }
20
- }
21
- return e.message;
22
- }
23
8
  function getLookupStrategy(name) {
24
9
  return lookupStrategies.lookupStrategies[name];
25
10
  }
@@ -106,158 +91,19 @@ class DefaultConnectionsService {
106
91
  return new DefaultConnectionsService(options.logger, options.config);
107
92
  }
108
93
  #registerConnectionsFromConfig() {
109
- const legacy = this.#validateLegacy(getLegacyIntegrations.getLegacyIntegrations(this.config));
110
- const rawConnections = this.config.getOptional("connections");
111
- if (rawConnections !== void 0 && !Array.isArray(rawConnections)) {
112
- throw new errors.InputError(
113
- 'Expected "connections" config to be an array of connection objects'
114
- );
115
- }
116
- const fromConfig = this.#validateConfig(
117
- rawConnections ?? []
118
- );
119
- this.logger.debug(
120
- `Connections configuration resolved ${legacy.length} connection${legacy.length === 1 ? "" : "s"} from legacy integrations and ${fromConfig.length} explicit connection${fromConfig.length === 1 ? "" : "s"}`
121
- );
122
- if (legacy.length === 0 && fromConfig.length === 0) {
123
- return;
124
- }
125
94
  this.connections.push(
126
- ...combineConnectionSources.combineConnectionSources(legacy, fromConfig, this.logger)
95
+ ...connections.buildConnectionsFromConfig({
96
+ config: this.config,
97
+ logger: this.logger
98
+ })
127
99
  );
128
- const seen = /* @__PURE__ */ new Set();
129
- for (const c of this.connections) {
130
- const connectionType = lookup.getConnectionType(c.type);
131
- const strategy = getLookupStrategy(connectionType.lookupStrategy);
132
- const identity = connectionIdentityOf(strategy, c);
133
- const key = `${c.type} ${identity ?? ""}`;
134
- if (seen.has(key)) {
135
- throw new errors.InputError(
136
- identity !== void 0 ? `Duplicate connection of type "${c.type}" for ${strategy.identityField} "${identity}"` : `Duplicate connection of type "${c.type}"`
137
- );
138
- }
139
- seen.add(key);
100
+ if (this.connections.length === 0) {
101
+ return;
140
102
  }
141
- this.#assignDefaultTitles();
142
- this.#assignDefaultAuthTitles();
143
103
  this.logger.info(
144
104
  `Loaded ${this.connections.length} connection${this.connections.length === 1 ? "" : "s"} from configuration`
145
105
  );
146
106
  }
147
- #validateConfig(raw) {
148
- return raw.map((v) => {
149
- try {
150
- return this.#validateConnection(v);
151
- } catch (e) {
152
- const type = typeof v.type === "string" ? v.type : "unknown";
153
- throw new errors.InputError(
154
- `Invalid connection of type "${type}" in connections config:
155
- ${describeError(
156
- e
157
- )}`
158
- );
159
- }
160
- });
161
- }
162
- #validateLegacy(raw) {
163
- const result = [];
164
- for (const v of raw) {
165
- try {
166
- result.push(this.#validateConnection(v));
167
- } catch (e) {
168
- const type = typeof v.type === "string" ? v.type : "unknown";
169
- this.logger.error(
170
- `Failed to validate connection of type "${type}":
171
- ${describeError(
172
- e
173
- )}`
174
- );
175
- }
176
- }
177
- return result;
178
- }
179
- #validateConnection(connection) {
180
- if (typeof connection.type !== "string") {
181
- throw new errors.InputError(`Unrecognised connection type ${connection.type}`);
182
- }
183
- if (!lookup.isConnectionTypeKey(connection.type)) {
184
- throw new errors.InputError(`Unrecognised connection type ${connection.type}`);
185
- }
186
- const connectionType = lookup.getConnectionType(connection.type);
187
- const rawAuth = connection.auth;
188
- if (!Array.isArray(rawAuth) || rawAuth.length === 0) {
189
- throw new errors.InputError(
190
- `Connection of type "${connection.type}" must configure at least one auth method`
191
- );
192
- }
193
- const auth = rawAuth.map((entry) => {
194
- if (typeof entry.method !== "string") {
195
- throw new errors.InputError(
196
- `Auth entry for connection type "${connection.type}" is missing a "method" field`
197
- );
198
- }
199
- const authMethod = connectionType.authMethods.find(
200
- (am) => am.method === entry.method
201
- );
202
- if (!authMethod) {
203
- throw new errors.InputError(
204
- `Unknown auth method "${entry.method}" for connection type "${connection.type}"`
205
- );
206
- }
207
- const { method, title: title2, match: match2, ...rest } = entry;
208
- return {
209
- ...authMethod.configSchema.parse(rest),
210
- method,
211
- title: title2,
212
- match: match2
213
- };
214
- });
215
- const { type, auth: _, title, match, ...configFields } = connection;
216
- const parsed = connectionType.configSchema.parse(configFields);
217
- return {
218
- ...parsed,
219
- type: connection.type,
220
- title,
221
- match,
222
- auth
223
- };
224
- }
225
- #assignDefaultTitles() {
226
- const typeCounts = /* @__PURE__ */ new Map();
227
- for (const c of this.connections) {
228
- const type = c.type;
229
- typeCounts.set(type, (typeCounts.get(type) ?? 0) + 1);
230
- }
231
- for (const c of this.connections) {
232
- if (!c.title) {
233
- const type = c.type;
234
- const connectionType = lookup.getConnectionType(type);
235
- const displayName = connectionType.title;
236
- const identity = connectionIdentityOf(
237
- getLookupStrategy(connectionType.lookupStrategy),
238
- c
239
- );
240
- c.title = typeCounts.get(type) > 1 && identity ? `${displayName} (${identity})` : displayName;
241
- }
242
- }
243
- }
244
- #assignDefaultAuthTitles() {
245
- for (const c of this.connections) {
246
- const type = c.type;
247
- const connectionType = lookup.getConnectionType(type);
248
- for (const auth of c.auth) {
249
- const authMethod = connectionType.authMethods.find(
250
- (am) => am.method === auth.method
251
- );
252
- if (!authMethod) {
253
- throw new Error(
254
- `Unknown auth method "${auth.method}" for connection type "${type}"`
255
- );
256
- }
257
- auth.title ??= authMethod.title;
258
- }
259
- }
260
- }
261
107
  #getConnectionsForPlugin(pluginId) {
262
108
  return this.connections.flatMap(({ match, auth, ...rest }) => {
263
109
  if (match && !match.plugins.includes(pluginId)) {
@@ -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 ConnectionTypeKey,\n LookupConnectionType,\n LookupStrategy,\n} from '@backstage/connections';\nimport { getConnectionType, isConnectionTypeKey } from './lookup';\nimport { lookupStrategies } from './lookupStrategies';\nimport type { RootConnection } from './types';\nimport { JsonObject } from '@backstage/types';\nimport {\n InputError,\n NotAllowedError,\n NotFoundError,\n toError,\n} from '@backstage/errors';\nimport { z } from 'zod/v4';\nimport { getLegacyIntegrations } from './getLegacyIntegrations';\nimport { combineConnectionSources } from './combineConnectionSources';\n\nfunction describeError(error: unknown): string {\n const e = toError(error);\n if (e.name === 'ZodError') {\n return z.prettifyError(e as unknown as z.ZodError);\n }\n if (e.cause !== undefined) {\n const cause = toError(e.cause);\n if (cause.name === 'ZodError') {\n return z.prettifyError(cause as unknown as z.ZodError);\n }\n }\n return e.message;\n}\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: LookupConnectionType<TType>['query'];\n authMethods: readonly [TAuthMethod, ...TAuthMethod[]];\n }): Promise<Connection<TType, TAuthMethod>> {\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 async findOptional<\n TType extends ConnectionTypeKey,\n TAuthMethod extends ConnectionAuthMethodKey<TType>,\n >({\n type,\n query,\n authMethods,\n }: {\n type: TType;\n query: LookupConnectionType<TType>['query'];\n authMethods: readonly [TAuthMethod, ...TAuthMethod[]];\n }): Promise<Connection<TType, TAuthMethod> | undefined> {\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 (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: RootConnection[];\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 const legacy = this.#validateLegacy(getLegacyIntegrations(this.config));\n\n const rawConnections = this.config.getOptional('connections');\n if (rawConnections !== undefined && !Array.isArray(rawConnections)) {\n throw new InputError(\n 'Expected \"connections\" config to be an array of connection objects',\n );\n }\n\n const fromConfig = this.#validateConfig(\n (rawConnections as JsonObject[] | undefined) ?? [],\n );\n\n this.logger.debug(\n `Connections configuration resolved ${legacy.length} connection${\n legacy.length === 1 ? '' : 's'\n } from legacy integrations and ${fromConfig.length} explicit connection${\n fromConfig.length === 1 ? '' : 's'\n }`,\n );\n\n if (legacy.length === 0 && fromConfig.length === 0) {\n return;\n }\n\n this.connections.push(\n ...combineConnectionSources(legacy, fromConfig, this.logger),\n );\n\n const seen = new Set<string>();\n for (const c of this.connections) {\n const connectionType = getConnectionType(c.type as ConnectionTypeKey);\n const strategy = getLookupStrategy(connectionType.lookupStrategy);\n const identity = connectionIdentityOf(strategy, c);\n const key = `${c.type} ${identity ?? ''}`;\n if (seen.has(key)) {\n throw new InputError(\n identity !== undefined\n ? `Duplicate connection of type \"${c.type}\" for ${strategy.identityField} \"${identity}\"`\n : `Duplicate connection of type \"${c.type}\"`,\n );\n }\n seen.add(key);\n }\n\n this.#assignDefaultTitles();\n this.#assignDefaultAuthTitles();\n\n this.logger.info(\n `Loaded ${this.connections.length} connection${\n this.connections.length === 1 ? '' : 's'\n } from configuration`,\n );\n }\n\n #validateConfig(raw: JsonObject[]): RootConnection[] {\n return raw.map(v => {\n try {\n return this.#validateConnection(v);\n } catch (e) {\n const type = typeof v.type === 'string' ? v.type : 'unknown';\n throw new InputError(\n `Invalid connection of type \"${type}\" in connections config:\\n${describeError(\n e,\n )}`,\n );\n }\n });\n }\n\n #validateLegacy(raw: JsonObject[]): RootConnection[] {\n const result: RootConnection[] = [];\n for (const v of raw) {\n try {\n result.push(this.#validateConnection(v));\n } catch (e) {\n const type = typeof v.type === 'string' ? v.type : 'unknown';\n this.logger.error(\n `Failed to validate connection of type \"${type}\":\\n${describeError(\n e,\n )}`,\n );\n }\n }\n return result;\n }\n\n #validateConnection(connection: JsonObject): RootConnection {\n if (typeof connection.type !== 'string') {\n throw new InputError(`Unrecognised connection type ${connection.type}`);\n }\n\n if (!isConnectionTypeKey(connection.type)) {\n throw new InputError(`Unrecognised connection type ${connection.type}`);\n }\n\n const connectionType = getConnectionType(connection.type);\n\n const rawAuth = connection.auth;\n if (!Array.isArray(rawAuth) || rawAuth.length === 0) {\n throw new InputError(\n `Connection of type \"${connection.type}\" must configure at least one auth method`,\n );\n }\n\n const auth = (rawAuth as JsonObject[]).map(entry => {\n if (typeof entry.method !== 'string') {\n throw new InputError(\n `Auth entry for connection type \"${connection.type}\" is missing a \"method\" field`,\n );\n }\n const authMethod = connectionType.authMethods.find(\n am => am.method === entry.method,\n );\n if (!authMethod) {\n throw new InputError(\n `Unknown auth method \"${entry.method}\" for connection type \"${connection.type}\"`,\n );\n }\n const { method, title, match, ...rest } = entry;\n return {\n ...authMethod.configSchema.parse(rest),\n method,\n title: title as string | undefined,\n match: match as { plugins: string[] } | undefined,\n } as RootConnection['auth'][number];\n });\n\n const { type, auth: _, title, match, ...configFields } = connection;\n const parsed = connectionType.configSchema.parse(configFields);\n\n return {\n ...parsed,\n type: connection.type,\n title: title as string | undefined,\n match: match as { plugins: string[] } | undefined,\n auth,\n } as RootConnection;\n }\n\n #assignDefaultTitles(): void {\n const typeCounts = new Map<string, number>();\n for (const c of this.connections) {\n const type = c.type as ConnectionTypeKey;\n typeCounts.set(type, (typeCounts.get(type) ?? 0) + 1);\n }\n for (const c of this.connections) {\n if (!c.title) {\n const type = c.type as ConnectionTypeKey;\n const connectionType = getConnectionType(type);\n const displayName = connectionType.title;\n const identity = connectionIdentityOf(\n getLookupStrategy(connectionType.lookupStrategy),\n c,\n );\n (c as { title?: string }).title =\n typeCounts.get(type)! > 1 && identity\n ? `${displayName} (${identity})`\n : displayName;\n }\n }\n }\n\n #assignDefaultAuthTitles(): void {\n for (const c of this.connections) {\n const type = c.type as ConnectionTypeKey;\n const connectionType = getConnectionType(type);\n for (const auth of c.auth) {\n const authMethod = connectionType.authMethods.find(\n am => am.method === auth.method,\n );\n // The config schema only allows methods declared by the connection\n // type, so failing to find one means that invariant has been broken.\n if (!authMethod) {\n throw new Error(\n `Unknown auth method \"${auth.method}\" for connection type \"${type}\"`,\n );\n }\n auth.title ??= authMethod.title;\n }\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":["toError","z","lookupStrategies","NotFoundError","getConnectionType","NotAllowedError","getLegacyIntegrations","InputError","combineConnectionSources","isConnectionTypeKey","title","match"],"mappings":";;;;;;;;;AAyCA,SAAS,cAAc,KAAA,EAAwB;AAC7C,EAAA,MAAM,CAAA,GAAIA,eAAQ,KAAK,CAAA;AACvB,EAAA,IAAI,CAAA,CAAE,SAAS,UAAA,EAAY;AACzB,IAAA,OAAOC,IAAA,CAAE,cAAc,CAA0B,CAAA;AAAA,EACnD;AACA,EAAA,IAAI,CAAA,CAAE,UAAU,MAAA,EAAW;AACzB,IAAA,MAAM,KAAA,GAAQD,cAAA,CAAQ,CAAA,CAAE,KAAK,CAAA;AAC7B,IAAA,IAAI,KAAA,CAAM,SAAS,UAAA,EAAY;AAC7B,MAAA,OAAOC,IAAA,CAAE,cAAc,KAA8B,CAAA;AAAA,IACvD;AAAA,EACF;AACA,EAAA,OAAO,CAAA,CAAE,OAAA;AACX;AAEA,SAAS,kBACP,IAAA,EAC8B;AAC9B,EAAA,OAAOC,kCAAiB,IAAI,CAAA;AAC9B;AAIA,SAAS,oBAAA,CACP,UACA,UAAA,EACoB;AACpB,EAAA,IAAI,CAAC,SAAS,aAAA,EAAe;AAC3B,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,MAAM,KAAA,GAAS,UAAA,CAAuC,QAAA,CAAS,aAAa,CAAA;AAC5E,EAAA,OAAO,OAAO,KAAA,KAAU,QAAA,GAAW,KAAA,GAAQ,MAAA;AAC7C;AAEA,MAAM,wBAAA,CAAuD;AAAA,EAC1C,MAAA;AAAA,EACA,WAAA;AAAA,EAEjB,WAAA,CAAY,QAAuB,WAAA,EAA2B;AAC5D,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,WAAA,GAAc,WAAA;AAAA,EACrB;AAAA,EAEA,MAAM,KAGJ,OAAA,EAI0C;AAC1C,IAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,YAAA,CAAa,OAAO,CAAA;AAC9C,IAAA,IAAI,CAAC,MAAA,EAAQ;AACX,MAAA,MAAM,IAAIC,oBAAA;AAAA,QACR,CAAA,+BAAA,EAAkC,QAAQ,IAAI,CAAA,CAAA;AAAA,OAChD;AAAA,IACF;AACA,IAAA,OAAO,MAAA;AAAA,EACT;AAAA,EAEA,MAAM,YAAA,CAGJ;AAAA,IACA,IAAA;AAAA,IACA,KAAA;AAAA,IACA;AAAA,GACF,EAIwD;AACtD,IAAA,MAAM,cAAA,GAAiBC,yBAAkB,IAAI,CAAA;AAC7C,IAAA,MAAM,QAAA,GAAW,iBAAA,CAAkB,cAAA,CAAe,cAAc,CAAA;AAChE,IAAA,MAAM,QAAA,GAAW,QAAA,CAAS,iBAAA,CAAkB,KAAK,CAAA;AAEjD,IAAA,IAAA,CAAK,MAAA,CAAO,KAAA;AAAA,MACV,CAAA,4BAAA,EAA+B,IAAI,CAAA,CAAA,EACjC,QAAA,GAAW,CAAA,UAAA,EAAa,SAAS,aAAa,CAAA,EAAA,EAAK,QAAQ,CAAA,CAAA,CAAA,GAAM,EACnE,CAAA;AAAA,KACF;AAEA,IAAA,IAAI,UAAA;AACJ,IAAA,IAAI,aAAa,MAAA,EAAW;AAC1B,MAAA,UAAA,GAAa,KAAK,WAAA,CAAY,IAAA;AAAA,QAC5B,OAAK,CAAA,CAAE,IAAA,KAAS,QAAQ,oBAAA,CAAqB,QAAA,EAAU,CAAC,CAAA,KAAM;AAAA,OAChE;AAAA,IACF,CAAA,MAAO;AACL,MAAA,UAAA,GAAa,KAAK,WAAA,CAAY,IAAA,CAAK,CAAA,CAAA,KAAK,CAAA,CAAE,SAAS,IAAI,CAAA;AAAA,IAGzD;AAEA,IAAA,IAAI,CAAC,UAAA,EAAY;AACf,MAAA,OAAO,MAAA;AAAA,IACT;AAEA,IAAA,IAAI,UAAA,CAAW,IAAA,CAAK,MAAA,KAAW,CAAA,EAAG;AAChC,MAAA,MAAM,IAAIC,sBAAA;AAAA,QACR,CAAA,oBAAA,EAAuB,IAAI,CAAA,CAAA,EACzB,QAAA,GAAW,CAAA,KAAA,EAAQ,SAAS,aAAa,CAAA,EAAA,EAAK,QAAQ,CAAA,CAAA,CAAA,GAAM,EAC9D,CAAA,4CAAA;AAAA,OACF;AAAA,IACF;AAEA,IAAA,MAAM,YAAY,cAAA,CAAe,SAAA;AAIjC,IAAA,MAAM,QAAA,GAAW,YACb,SAAA,CAAU,UAAA,CAAW,MAAM,KAAK,CAAA,GAChC,UAAA,CAAW,IAAA,CAAK,CAAC,CAAA;AAErB,IAAA,IAAI,CAAC,QAAA,EAAU;AACb,MAAA,OAAO,MAAA;AAAA,IACT;AAEA,IAAA,IAAI,CAAE,WAAA,CAAkC,QAAA,CAAS,QAAA,CAAS,MAAM,CAAA,EAAG;AACjE,MAAA,MAAM,IAAIA,sBAAA;AAAA,QACR,CAAA,+BAAA,EAAkC,IAAI,CAAA,oBAAA,EAAuB,QAAA,CAAS,MAAM,CAAA,CAAA;AAAA,OAC9E;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,MAAA,CAAO,KAAA;AAAA,MACV,CAAA,6BAAA,EAAgC,IAAI,CAAA,CAAA,EAClC,QAAA,GAAW,CAAA,KAAA,EAAQ,QAAA,CAAS,aAAa,CAAA,EAAA,EAAK,QAAQ,CAAA,CAAA,CAAA,GAAM,EAC9D,CAAA,oBAAA,EAAuB,SAAS,MAAM,CAAA,CAAA;AAAA,KACxC;AAEA,IAAA,OAAO;AAAA,MACL,GAAG,UAAA;AAAA,MACH,IAAA,EAAM;AAAA,KACR;AAAA,EACF;AACF;AAGO,MAAM,yBAAA,CAA0B;AAAA,EACpB,MAAA;AAAA,EACA,WAAA;AAAA,EACA,MAAA;AAAA,EAET,WAAA,CAAY,QAAuB,MAAA,EAA2B;AACpE,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,cAAc,EAAC;AACpB,IAAA,IAAA,CAAK,8BAAA,EAA+B;AAAA,EACtC;AAAA,EAEA,OAAO,OAAO,OAAA,EAGgB;AAC5B,IAAA,OAAO,IAAI,yBAAA,CAA0B,OAAA,CAAQ,MAAA,EAAQ,QAAQ,MAAM,CAAA;AAAA,EACrE;AAAA,EAEA,8BAAA,GAAuC;AACrC,IAAA,MAAM,SAAS,IAAA,CAAK,eAAA,CAAgBC,2CAAA,CAAsB,IAAA,CAAK,MAAM,CAAC,CAAA;AAEtE,IAAA,MAAM,cAAA,GAAiB,IAAA,CAAK,MAAA,CAAO,WAAA,CAAY,aAAa,CAAA;AAC5D,IAAA,IAAI,mBAAmB,MAAA,IAAa,CAAC,KAAA,CAAM,OAAA,CAAQ,cAAc,CAAA,EAAG;AAClE,MAAA,MAAM,IAAIC,iBAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAEA,IAAA,MAAM,aAAa,IAAA,CAAK,eAAA;AAAA,MACrB,kBAA+C;AAAC,KACnD;AAEA,IAAA,IAAA,CAAK,MAAA,CAAO,KAAA;AAAA,MACV,sCAAsC,MAAA,CAAO,MAAM,CAAA,WAAA,EACjD,MAAA,CAAO,WAAW,CAAA,GAAI,EAAA,GAAK,GAC7B,CAAA,8BAAA,EAAiC,WAAW,MAAM,CAAA,oBAAA,EAChD,WAAW,MAAA,KAAW,CAAA,GAAI,KAAK,GACjC,CAAA;AAAA,KACF;AAEA,IAAA,IAAI,MAAA,CAAO,MAAA,KAAW,CAAA,IAAK,UAAA,CAAW,WAAW,CAAA,EAAG;AAClD,MAAA;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,WAAA,CAAY,IAAA;AAAA,MACf,GAAGC,iDAAA,CAAyB,MAAA,EAAQ,UAAA,EAAY,KAAK,MAAM;AAAA,KAC7D;AAEA,IAAA,MAAM,IAAA,uBAAW,GAAA,EAAY;AAC7B,IAAA,KAAA,MAAW,CAAA,IAAK,KAAK,WAAA,EAAa;AAChC,MAAA,MAAM,cAAA,GAAiBJ,wBAAA,CAAkB,CAAA,CAAE,IAAyB,CAAA;AACpE,MAAA,MAAM,QAAA,GAAW,iBAAA,CAAkB,cAAA,CAAe,cAAc,CAAA;AAChE,MAAA,MAAM,QAAA,GAAW,oBAAA,CAAqB,QAAA,EAAU,CAAC,CAAA;AACjD,MAAA,MAAM,MAAM,CAAA,EAAG,CAAA,CAAE,IAAI,CAAA,CAAA,EAAI,YAAY,EAAE,CAAA,CAAA;AACvC,MAAA,IAAI,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA,EAAG;AACjB,QAAA,MAAM,IAAIG,iBAAA;AAAA,UACR,QAAA,KAAa,MAAA,GACT,CAAA,8BAAA,EAAiC,CAAA,CAAE,IAAI,CAAA,MAAA,EAAS,QAAA,CAAS,aAAa,CAAA,EAAA,EAAK,QAAQ,CAAA,CAAA,CAAA,GACnF,CAAA,8BAAA,EAAiC,EAAE,IAAI,CAAA,CAAA;AAAA,SAC7C;AAAA,MACF;AACA,MAAA,IAAA,CAAK,IAAI,GAAG,CAAA;AAAA,IACd;AAEA,IAAA,IAAA,CAAK,oBAAA,EAAqB;AAC1B,IAAA,IAAA,CAAK,wBAAA,EAAyB;AAE9B,IAAA,IAAA,CAAK,MAAA,CAAO,IAAA;AAAA,MACV,CAAA,OAAA,EAAU,IAAA,CAAK,WAAA,CAAY,MAAM,CAAA,WAAA,EAC/B,KAAK,WAAA,CAAY,MAAA,KAAW,CAAA,GAAI,EAAA,GAAK,GACvC,CAAA,mBAAA;AAAA,KACF;AAAA,EACF;AAAA,EAEA,gBAAgB,GAAA,EAAqC;AACnD,IAAA,OAAO,GAAA,CAAI,IAAI,CAAA,CAAA,KAAK;AAClB,MAAA,IAAI;AACF,QAAA,OAAO,IAAA,CAAK,oBAAoB,CAAC,CAAA;AAAA,MACnC,SAAS,CAAA,EAAG;AACV,QAAA,MAAM,OAAO,OAAO,CAAA,CAAE,IAAA,KAAS,QAAA,GAAW,EAAE,IAAA,GAAO,SAAA;AACnD,QAAA,MAAM,IAAIA,iBAAA;AAAA,UACR,+BAA+B,IAAI,CAAA;AAAA,EAA6B,aAAA;AAAA,YAC9D;AAAA,WACD,CAAA;AAAA,SACH;AAAA,MACF;AAAA,IACF,CAAC,CAAA;AAAA,EACH;AAAA,EAEA,gBAAgB,GAAA,EAAqC;AACnD,IAAA,MAAM,SAA2B,EAAC;AAClC,IAAA,KAAA,MAAW,KAAK,GAAA,EAAK;AACnB,MAAA,IAAI;AACF,QAAA,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,mBAAA,CAAoB,CAAC,CAAC,CAAA;AAAA,MACzC,SAAS,CAAA,EAAG;AACV,QAAA,MAAM,OAAO,OAAO,CAAA,CAAE,IAAA,KAAS,QAAA,GAAW,EAAE,IAAA,GAAO,SAAA;AACnD,QAAA,IAAA,CAAK,MAAA,CAAO,KAAA;AAAA,UACV,0CAA0C,IAAI,CAAA;AAAA,EAAO,aAAA;AAAA,YACnD;AAAA,WACD,CAAA;AAAA,SACH;AAAA,MACF;AAAA,IACF;AACA,IAAA,OAAO,MAAA;AAAA,EACT;AAAA,EAEA,oBAAoB,UAAA,EAAwC;AAC1D,IAAA,IAAI,OAAO,UAAA,CAAW,IAAA,KAAS,QAAA,EAAU;AACvC,MAAA,MAAM,IAAIA,iBAAA,CAAW,CAAA,6BAAA,EAAgC,UAAA,CAAW,IAAI,CAAA,CAAE,CAAA;AAAA,IACxE;AAEA,IAAA,IAAI,CAACE,0BAAA,CAAoB,UAAA,CAAW,IAAI,CAAA,EAAG;AACzC,MAAA,MAAM,IAAIF,iBAAA,CAAW,CAAA,6BAAA,EAAgC,UAAA,CAAW,IAAI,CAAA,CAAE,CAAA;AAAA,IACxE;AAEA,IAAA,MAAM,cAAA,GAAiBH,wBAAA,CAAkB,UAAA,CAAW,IAAI,CAAA;AAExD,IAAA,MAAM,UAAU,UAAA,CAAW,IAAA;AAC3B,IAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,OAAO,CAAA,IAAK,OAAA,CAAQ,WAAW,CAAA,EAAG;AACnD,MAAA,MAAM,IAAIG,iBAAA;AAAA,QACR,CAAA,oBAAA,EAAuB,WAAW,IAAI,CAAA,yCAAA;AAAA,OACxC;AAAA,IACF;AAEA,IAAA,MAAM,IAAA,GAAQ,OAAA,CAAyB,GAAA,CAAI,CAAA,KAAA,KAAS;AAClD,MAAA,IAAI,OAAO,KAAA,CAAM,MAAA,KAAW,QAAA,EAAU;AACpC,QAAA,MAAM,IAAIA,iBAAA;AAAA,UACR,CAAA,gCAAA,EAAmC,WAAW,IAAI,CAAA,6BAAA;AAAA,SACpD;AAAA,MACF;AACA,MAAA,MAAM,UAAA,GAAa,eAAe,WAAA,CAAY,IAAA;AAAA,QAC5C,CAAA,EAAA,KAAM,EAAA,CAAG,MAAA,KAAW,KAAA,CAAM;AAAA,OAC5B;AACA,MAAA,IAAI,CAAC,UAAA,EAAY;AACf,QAAA,MAAM,IAAIA,iBAAA;AAAA,UACR,CAAA,qBAAA,EAAwB,KAAA,CAAM,MAAM,CAAA,uBAAA,EAA0B,WAAW,IAAI,CAAA,CAAA;AAAA,SAC/E;AAAA,MACF;AACA,MAAA,MAAM,EAAE,QAAQ,KAAA,EAAAG,MAAAA,EAAO,OAAAC,MAAAA,EAAO,GAAG,MAAK,GAAI,KAAA;AAC1C,MAAA,OAAO;AAAA,QACL,GAAG,UAAA,CAAW,YAAA,CAAa,KAAA,CAAM,IAAI,CAAA;AAAA,QACrC,MAAA;AAAA,QACA,KAAA,EAAOD,MAAAA;AAAA,QACP,KAAA,EAAOC;AAAA,OACT;AAAA,IACF,CAAC,CAAA;AAED,IAAA,MAAM,EAAE,MAAM,IAAA,EAAM,CAAA,EAAG,OAAO,KAAA,EAAO,GAAG,cAAa,GAAI,UAAA;AACzD,IAAA,MAAM,MAAA,GAAS,cAAA,CAAe,YAAA,CAAa,KAAA,CAAM,YAAY,CAAA;AAE7D,IAAA,OAAO;AAAA,MACL,GAAG,MAAA;AAAA,MACH,MAAM,UAAA,CAAW,IAAA;AAAA,MACjB,KAAA;AAAA,MACA,KAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF;AAAA,EAEA,oBAAA,GAA6B;AAC3B,IAAA,MAAM,UAAA,uBAAiB,GAAA,EAAoB;AAC3C,IAAA,KAAA,MAAW,CAAA,IAAK,KAAK,WAAA,EAAa;AAChC,MAAA,MAAM,OAAO,CAAA,CAAE,IAAA;AACf,MAAA,UAAA,CAAW,IAAI,IAAA,EAAA,CAAO,UAAA,CAAW,IAAI,IAAI,CAAA,IAAK,KAAK,CAAC,CAAA;AAAA,IACtD;AACA,IAAA,KAAA,MAAW,CAAA,IAAK,KAAK,WAAA,EAAa;AAChC,MAAA,IAAI,CAAC,EAAE,KAAA,EAAO;AACZ,QAAA,MAAM,OAAO,CAAA,CAAE,IAAA;AACf,QAAA,MAAM,cAAA,GAAiBP,yBAAkB,IAAI,CAAA;AAC7C,QAAA,MAAM,cAAc,cAAA,CAAe,KAAA;AACnC,QAAA,MAAM,QAAA,GAAW,oBAAA;AAAA,UACf,iBAAA,CAAkB,eAAe,cAAc,CAAA;AAAA,UAC/C;AAAA,SACF;AACA,QAAC,CAAA,CAAyB,KAAA,GACxB,UAAA,CAAW,GAAA,CAAI,IAAI,CAAA,GAAK,CAAA,IAAK,QAAA,GACzB,CAAA,EAAG,WAAW,CAAA,EAAA,EAAK,QAAQ,CAAA,CAAA,CAAA,GAC3B,WAAA;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EAEA,wBAAA,GAAiC;AAC/B,IAAA,KAAA,MAAW,CAAA,IAAK,KAAK,WAAA,EAAa;AAChC,MAAA,MAAM,OAAO,CAAA,CAAE,IAAA;AACf,MAAA,MAAM,cAAA,GAAiBA,yBAAkB,IAAI,CAAA;AAC7C,MAAA,KAAA,MAAW,IAAA,IAAQ,EAAE,IAAA,EAAM;AACzB,QAAA,MAAM,UAAA,GAAa,eAAe,WAAA,CAAY,IAAA;AAAA,UAC5C,CAAA,EAAA,KAAM,EAAA,CAAG,MAAA,KAAW,IAAA,CAAK;AAAA,SAC3B;AAGA,QAAA,IAAI,CAAC,UAAA,EAAY;AACf,UAAA,MAAM,IAAI,KAAA;AAAA,YACR,CAAA,qBAAA,EAAwB,IAAA,CAAK,MAAM,CAAA,uBAAA,EAA0B,IAAI,CAAA,CAAA;AAAA,WACnE;AAAA,QACF;AACA,QAAA,IAAA,CAAK,UAAU,UAAA,CAAW,KAAA;AAAA,MAC5B;AAAA,IACF;AAAA,EACF;AAAA,EAEA,yBAAyB,QAAA,EAAgC;AAMvD,IAAA,OAAO,IAAA,CAAK,YAAY,OAAA,CAAQ,CAAC,EAAE,KAAA,EAAO,IAAA,EAAM,GAAG,IAAA,EAAK,KAAM;AAC5D,MAAA,IAAI,SAAS,CAAC,KAAA,CAAM,OAAA,CAAQ,QAAA,CAAS,QAAQ,CAAA,EAAG;AAC9C,QAAA,OAAO,EAAC;AAAA,MACV;AAEA,MAAA,MAAM,gBAAoC,EAAC;AAC3C,MAAA,MAAM,YAAgC,EAAC;AACvC,MAAA,KAAA,MAAW,EAAE,KAAA,EAAO,SAAA,EAAW,GAAG,QAAA,MAAc,IAAA,EAAM;AACpD,QAAA,IAAI,SAAA,EAAW;AACb,UAAA,IAAI,CAAC,SAAA,CAAU,OAAA,CAAQ,QAAA,CAAS,QAAQ,CAAA,EAAG;AAC3C,UAAA,aAAA,CAAc,KAAK,QAAsC,CAAA;AAAA,QAC3D,CAAA,MAAO;AACL,UAAA,SAAA,CAAU,KAAK,QAAsC,CAAA;AAAA,QACvD;AAAA,MACF;AAEA,MAAA,OAAO;AAAA,QACL,EAAE,GAAG,IAAA,EAAM,IAAA,EAAM,CAAC,GAAG,aAAA,EAAe,GAAG,SAAS,CAAA;AAAE,OACpD;AAAA,IACF,CAAC,CAAA;AAAA,EACH;AAAA,EAEA,SAAA,CACE,UACA,OAAA,EAGoB;AACpB,IAAA,MAAM,MAAA,GAAS,OAAA,EAAS,MAAA,IAAU,IAAA,CAAK,MAAA;AACvC,IAAA,OAAO,IAAI,wBAAA;AAAA,MACT,MAAA;AAAA,MACA,IAAA,CAAK,yBAAyB,QAAQ;AAAA,KACxC;AAAA,EACF;AACF;;;;"}
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 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\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: LookupConnectionType<TType>['query'];\n authMethods: readonly [TAuthMethod, ...TAuthMethod[]];\n }): Promise<Connection<TType, TAuthMethod>> {\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 async findOptional<\n TType extends ConnectionTypeKey,\n TAuthMethod extends ConnectionAuthMethodKey<TType>,\n >({\n type,\n query,\n authMethods,\n }: {\n type: TType;\n query: LookupConnectionType<TType>['query'];\n authMethods: readonly [TAuthMethod, ...TAuthMethod[]];\n }): Promise<Connection<TType, TAuthMethod> | undefined> {\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 (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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"}
@@ -6,11 +6,6 @@ const connectionTypesMap = new Map(Object.entries(connections.connectionTypes));
6
6
  function getConnectionType(key) {
7
7
  return connectionTypesMap.get(key);
8
8
  }
9
- function isConnectionTypeKey(value) {
10
- if (!value) return false;
11
- return connectionTypesMap.has(value);
12
- }
13
9
 
14
10
  exports.getConnectionType = getConnectionType;
15
- exports.isConnectionTypeKey = isConnectionTypeKey;
16
11
  //# sourceMappingURL=lookup.cjs.js.map
@@ -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 ConnectionTypeKey,\n connectionTypes,\n} from '@backstage/connections';\n\nconst connectionTypesMap = new Map(Object.entries(connectionTypes));\n\nexport function getConnectionType<T extends ConnectionTypeKey>(\n key: T,\n): LookupConnectionType<T> {\n return connectionTypesMap.get(key) as LookupConnectionType<T>;\n}\n\nexport function isConnectionTypeKey(\n value: string | undefined,\n): value is ConnectionTypeKey {\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;AAEO,SAAS,oBACd,KAAA,EAC4B;AAC5B,EAAA,IAAI,CAAC,OAAO,OAAO,KAAA;AAEnB,EAAA,OAAO,kBAAA,CAAmB,IAAI,KAAK,CAAA;AACrC;;;;;"}
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 ConnectionTypeKey,\n connectionTypes,\n} from '@backstage/connections';\n\nconst connectionTypesMap = new Map(Object.entries(connectionTypes));\n\nexport function getConnectionType<T extends ConnectionTypeKey>(\n key: T,\n): LookupConnectionType<T> {\n return connectionTypesMap.get(key) as LookupConnectionType<T>;\n}\n\nexport function isConnectionTypeKey(\n value: string | undefined,\n): value is ConnectionTypeKey {\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;;;;"}
@@ -6,17 +6,21 @@ const lookupStrategies = {
6
6
  host: {
7
7
  identityField: "host",
8
8
  identityFromQuery(query) {
9
+ const { url } = query;
9
10
  try {
10
- return new URL(query.url).host;
11
+ return new URL(url).host;
11
12
  } catch {
12
13
  throw new errors.InputError(
13
- `Invalid url "${query.url}" passed to ConnectionsService.find`
14
+ `Invalid url "${url}" passed to ConnectionsService.find`
14
15
  );
15
16
  }
16
17
  }
17
18
  },
19
+ // AWS has no identity field to match against — all accounts live under a
20
+ // single connection. Account selection is handled entirely by the
21
+ // connection type's matchAuth implementation.
18
22
  aws: {
19
- identityFromQuery(_query) {
23
+ identityFromQuery() {
20
24
  return void 0;
21
25
  }
22
26
  }
@@ -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';\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 * @internal\n */\nexport const lookupStrategies = {\n host: {\n identityField: 'host' as const,\n identityFromQuery(query: { url: string }): string | undefined {\n try {\n return new URL(query.url).host;\n } catch {\n throw new InputError(\n `Invalid url \"${query.url}\" passed to ConnectionsService.find`,\n );\n }\n },\n },\n aws: {\n identityFromQuery(_query: {\n accountId?: string;\n arn?: string;\n }): string | undefined {\n return undefined;\n },\n },\n};\n"],"names":["InputError"],"mappings":";;;;AAwBO,MAAM,gBAAA,GAAmB;AAAA,EAC9B,IAAA,EAAM;AAAA,IACJ,aAAA,EAAe,MAAA;AAAA,IACf,kBAAkB,KAAA,EAA4C;AAC5D,MAAA,IAAI;AACF,QAAA,OAAO,IAAI,GAAA,CAAI,KAAA,CAAM,GAAG,CAAA,CAAE,IAAA;AAAA,MAC5B,CAAA,CAAA,MAAQ;AACN,QAAA,MAAM,IAAIA,iBAAA;AAAA,UACR,CAAA,aAAA,EAAgB,MAAM,GAAG,CAAA,mCAAA;AAAA,SAC3B;AAAA,MACF;AAAA,IACF;AAAA,GACF;AAAA,EACA,GAAA,EAAK;AAAA,IACH,kBAAkB,MAAA,EAGK;AACrB,MAAA,OAAO,MAAA;AAAA,IACT;AAAA;AAEJ;;;;"}
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 { LookupStrategy } 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 LookupStrategyDefinition = {\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 LookupStrategy,\n LookupStrategyDefinition\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;;;;"}
@@ -9,8 +9,8 @@ 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
13
  require('../connections-node/src/lookup.cjs.js');
13
- require('zod/v4');
14
14
  var withDeclaredConnections = require('./withDeclaredConnections.cjs.js');
15
15
  var validateBackendFeature = require('./validateBackendFeature.cjs.js');
16
16
  var OpaqueExtensionPointFactoryMiddleware = require('../backend-internal/src/wiring/OpaqueExtensionPointFactoryMiddleware.cjs.js');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/backend-app-api",
3
- "version": "1.7.3-next.1",
3
+ "version": "1.7.3",
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.0-next.1",
54
- "@backstage/config": "1.3.8",
55
- "@backstage/connections": "0.3.0-next.2",
56
- "@backstage/errors": "1.3.1",
57
- "@backstage/types": "1.2.2",
53
+ "@backstage/backend-plugin-api": "^1.10.0",
54
+ "@backstage/config": "^1.3.8",
55
+ "@backstage/connections": "^0.3.0",
56
+ "@backstage/errors": "^1.3.1",
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.17.7-next.2",
62
- "@backstage/backend-test-utils": "1.11.6-next.1",
63
- "@backstage/cli": "0.36.5-next.1"
61
+ "@backstage/backend-defaults": "^0.17.7",
62
+ "@backstage/backend-test-utils": "^1.11.6",
63
+ "@backstage/cli": "^0.36.5"
64
64
  },
65
65
  "configSchema": "config.schema.json"
66
66
  }
@@ -1,26 +0,0 @@
1
- 'use strict';
2
-
3
- function combineConnectionSources(legacy, fromConfig, logger) {
4
- const typeOf = (c) => c.type;
5
- const typesInConfig = new Set(fromConfig.map(typeOf));
6
- const warned = /* @__PURE__ */ new Set();
7
- const result = [];
8
- for (const legacyConn of legacy) {
9
- const type = typeOf(legacyConn);
10
- if (typesInConfig.has(type)) {
11
- if (!warned.has(type)) {
12
- warned.add(type);
13
- logger.warn(
14
- `Connection type "${type}" is defined in both legacy integrations and connections config; legacy integrations of this type are ignored.`
15
- );
16
- }
17
- continue;
18
- }
19
- result.push(legacyConn);
20
- }
21
- result.push(...fromConfig);
22
- return result;
23
- }
24
-
25
- exports.combineConnectionSources = combineConnectionSources;
26
- //# sourceMappingURL=combineConnectionSources.cjs.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"combineConnectionSources.cjs.js","sources":["../../../../connections-node/src/combineConnectionSources.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 { LoggerService } from '@backstage/backend-plugin-api';\nimport type { RootConnection } from './types';\n\n/**\n * Merges connections derived from legacy `integrations.*` config with\n * connections defined explicitly in `connections:` config.\n *\n * If any entry in `fromConfig` declares a given connection type, all legacy\n * entries of that type are discarded — the connections config fully takes\n * over for that type. A single warning is logged per discarded type.\n */\nexport function combineConnectionSources(\n legacy: RootConnection[],\n fromConfig: RootConnection[],\n logger: LoggerService,\n): RootConnection[] {\n const typeOf = (c: RootConnection) => c.type as string;\n const typesInConfig = new Set(fromConfig.map(typeOf));\n\n const warned = new Set<string>();\n const result: RootConnection[] = [];\n\n for (const legacyConn of legacy) {\n const type = typeOf(legacyConn);\n if (typesInConfig.has(type)) {\n if (!warned.has(type)) {\n warned.add(type);\n logger.warn(\n `Connection type \"${type}\" is defined in both legacy integrations and connections config; legacy integrations of this type are ignored.`,\n );\n }\n continue;\n }\n result.push(legacyConn);\n }\n\n result.push(...fromConfig);\n\n return result;\n}\n"],"names":[],"mappings":";;AA0BO,SAAS,wBAAA,CACd,MAAA,EACA,UAAA,EACA,MAAA,EACkB;AAClB,EAAA,MAAM,MAAA,GAAS,CAAC,CAAA,KAAsB,CAAA,CAAE,IAAA;AACxC,EAAA,MAAM,gBAAgB,IAAI,GAAA,CAAI,UAAA,CAAW,GAAA,CAAI,MAAM,CAAC,CAAA;AAEpD,EAAA,MAAM,MAAA,uBAAa,GAAA,EAAY;AAC/B,EAAA,MAAM,SAA2B,EAAC;AAElC,EAAA,KAAA,MAAW,cAAc,MAAA,EAAQ;AAC/B,IAAA,MAAM,IAAA,GAAO,OAAO,UAAU,CAAA;AAC9B,IAAA,IAAI,aAAA,CAAc,GAAA,CAAI,IAAI,CAAA,EAAG;AAC3B,MAAA,IAAI,CAAC,MAAA,CAAO,GAAA,CAAI,IAAI,CAAA,EAAG;AACrB,QAAA,MAAA,CAAO,IAAI,IAAI,CAAA;AACf,QAAA,MAAA,CAAO,IAAA;AAAA,UACL,oBAAoB,IAAI,CAAA,8GAAA;AAAA,SAC1B;AAAA,MACF;AACA,MAAA;AAAA,IACF;AACA,IAAA,MAAA,CAAO,KAAK,UAAU,CAAA;AAAA,EACxB;AAEA,EAAA,MAAA,CAAO,IAAA,CAAK,GAAG,UAAU,CAAA;AAEzB,EAAA,OAAO,MAAA;AACT;;;;"}
@@ -1,339 +0,0 @@
1
- 'use strict';
2
-
3
- function getLegacyIntegrations(config) {
4
- const integrations = config.getOptionalConfig("integrations");
5
- if (!integrations) {
6
- return [];
7
- }
8
- return [
9
- ...convertAwsCodeCommit(
10
- integrations.getOptionalConfigArray("awsCodeCommit") ?? []
11
- ),
12
- ...convertAwsS3(integrations.getOptionalConfigArray("awsS3") ?? []),
13
- ...convertAzure(integrations.getOptionalConfigArray("azure") ?? []),
14
- ...convertAzureBlobStorage(
15
- integrations.getOptionalConfigArray("azureBlobStorage") ?? []
16
- ),
17
- ...convertBitbucketCloud(
18
- integrations.getOptionalConfigArray("bitbucketCloud") ?? []
19
- ),
20
- ...convertBitbucketServer(
21
- integrations.getOptionalConfigArray("bitbucketServer") ?? []
22
- ),
23
- ...convertGerrit(integrations.getOptionalConfigArray("gerrit") ?? []),
24
- ...convertGitea(integrations.getOptionalConfigArray("gitea") ?? []),
25
- ...convertGithub(integrations.getOptionalConfigArray("github") ?? []),
26
- ...convertGitlab(integrations.getOptionalConfigArray("gitlab") ?? []),
27
- ...convertGoogleGcs(integrations.getOptionalConfigArray("googleGcs") ?? []),
28
- ...convertHarness(integrations.getOptionalConfigArray("harness") ?? [])
29
- ];
30
- }
31
- function convertGithub(entries) {
32
- return entries.map((entry) => {
33
- const auth = [];
34
- const token = entry.getOptionalString("token");
35
- if (token !== void 0) {
36
- auth.push({ method: "token", token });
37
- }
38
- for (const app of entry.getOptionalConfigArray("apps") ?? []) {
39
- auth.push(convertGithubApp(app));
40
- }
41
- return omitUndefined({
42
- type: "github",
43
- host: entry.getOptionalString("host"),
44
- apiBaseUrl: entry.getOptionalString("apiBaseUrl"),
45
- rawBaseUrl: entry.getOptionalString("rawBaseUrl"),
46
- auth: withNoneAuthFallback(auth)
47
- });
48
- });
49
- }
50
- function convertGitlab(entries) {
51
- return entries.map((entry) => {
52
- const auth = [];
53
- const token = entry.getOptionalString("token");
54
- if (token !== void 0) {
55
- auth.push({ method: "token", token });
56
- }
57
- return omitUndefined({
58
- type: "gitlab",
59
- host: entry.getOptionalString("host"),
60
- apiBaseUrl: entry.getOptionalString("apiBaseUrl"),
61
- baseUrl: entry.getOptionalString("baseUrl"),
62
- auth: withNoneAuthFallback(auth)
63
- });
64
- });
65
- }
66
- function convertGithubApp(app) {
67
- return omitUndefined({
68
- method: "app",
69
- appId: app.getOptional("appId"),
70
- privateKey: app.getOptionalString("privateKey"),
71
- clientId: app.getOptionalString("clientId"),
72
- clientSecret: app.getOptionalString("clientSecret"),
73
- webhookSecret: app.getOptionalString("webhookSecret"),
74
- orgs: app.getOptionalStringArray("allowedInstallationOwners"),
75
- publicAccess: app.getOptionalBoolean("publicAccess")
76
- });
77
- }
78
- function convertAzure(entries) {
79
- return entries.map((entry) => {
80
- const auth = [];
81
- for (const credential of entry.getOptionalConfigArray("credentials") ?? []) {
82
- const converted = convertAzureCredential(credential);
83
- if (converted) {
84
- auth.push(converted);
85
- }
86
- }
87
- return omitUndefined({
88
- type: "azure",
89
- host: entry.getOptionalString("host"),
90
- auth: withNoneAuthFallback(auth)
91
- });
92
- });
93
- }
94
- function convertAzureCredential(credential) {
95
- const orgs = credential.getOptionalStringArray("organizations");
96
- const personalAccessToken = credential.getOptionalString(
97
- "personalAccessToken"
98
- );
99
- if (personalAccessToken !== void 0) {
100
- return omitUndefined({
101
- method: "pat",
102
- personalAccessToken,
103
- orgs
104
- });
105
- }
106
- const clientSecret = credential.getOptionalString("clientSecret");
107
- if (clientSecret !== void 0) {
108
- return omitUndefined({
109
- method: "clientCredentials",
110
- clientId: credential.getOptionalString("clientId"),
111
- clientSecret,
112
- tenantId: credential.getOptionalString("tenantId"),
113
- orgs
114
- });
115
- }
116
- const clientId = credential.getOptionalString("clientId");
117
- if (clientId !== void 0) {
118
- return omitUndefined({
119
- method: "managedIdentity",
120
- clientId,
121
- tenantId: credential.getOptionalString("tenantId"),
122
- managedIdentityClientId: credential.getOptionalString(
123
- "managedIdentityClientId"
124
- ),
125
- orgs
126
- });
127
- }
128
- return void 0;
129
- }
130
- function convertBitbucketCloud(entries) {
131
- return entries.map((entry) => {
132
- const username = entry.getOptionalString("username");
133
- const auth = [];
134
- const token = entry.getOptionalString("token");
135
- if (username !== void 0 && token !== void 0) {
136
- auth.push({ method: "token", username, token });
137
- }
138
- const appPassword = entry.getOptionalString("appPassword");
139
- if (username !== void 0 && appPassword !== void 0) {
140
- auth.push({ method: "appPassword", username, appPassword });
141
- }
142
- const clientId = entry.getOptionalString("clientId");
143
- const clientSecret = entry.getOptionalString("clientSecret");
144
- if (clientId !== void 0 && clientSecret !== void 0) {
145
- auth.push({ method: "oauth", clientId, clientSecret });
146
- }
147
- return {
148
- type: "bitbucket-cloud",
149
- host: "bitbucket.org",
150
- auth: withNoneAuthFallback(auth)
151
- };
152
- });
153
- }
154
- function convertBitbucketServer(entries) {
155
- return entries.map((entry) => {
156
- const auth = [];
157
- const token = entry.getOptionalString("token");
158
- if (token !== void 0) {
159
- auth.push({ method: "token", token });
160
- }
161
- const username = entry.getOptionalString("username");
162
- const password = entry.getOptionalString("password");
163
- if (username !== void 0 && password !== void 0) {
164
- auth.push({ method: "basic", username, password });
165
- }
166
- return omitUndefined({
167
- type: "bitbucket-server",
168
- host: entry.getOptionalString("host"),
169
- apiBaseUrl: entry.getOptionalString("apiBaseUrl"),
170
- auth: withNoneAuthFallback(auth)
171
- });
172
- });
173
- }
174
- function convertGerrit(entries) {
175
- return entries.map((entry) => {
176
- const auth = [];
177
- const username = entry.getOptionalString("username");
178
- const password = entry.getOptionalString("password");
179
- if (username !== void 0 && password !== void 0) {
180
- auth.push({ method: "basic", username, password });
181
- }
182
- return omitUndefined({
183
- type: "gerrit",
184
- host: entry.getOptionalString("host"),
185
- baseUrl: entry.getOptionalString("baseUrl"),
186
- gitilesBaseUrl: entry.getOptionalString("gitilesBaseUrl"),
187
- cloneUrl: entry.getOptionalString("cloneUrl"),
188
- auth: withNoneAuthFallback(auth)
189
- });
190
- });
191
- }
192
- function convertGitea(entries) {
193
- return entries.map((entry) => {
194
- const auth = [];
195
- const username = entry.getOptionalString("username");
196
- const password = entry.getOptionalString("password");
197
- if (username !== void 0 && password !== void 0) {
198
- auth.push({ method: "basic", username, password });
199
- }
200
- return omitUndefined({
201
- type: "gitea",
202
- host: entry.getOptionalString("host"),
203
- baseUrl: entry.getOptionalString("baseUrl"),
204
- auth: withNoneAuthFallback(auth)
205
- });
206
- });
207
- }
208
- function convertHarness(entries) {
209
- return entries.map((entry) => {
210
- const auth = [];
211
- const token = entry.getOptionalString("token");
212
- if (token !== void 0) {
213
- const apiKey = entry.getOptionalString("apiKey");
214
- auth.push(omitUndefined({ method: "token", token, apiKey }));
215
- }
216
- return omitUndefined({
217
- type: "harness",
218
- host: entry.getOptionalString("host"),
219
- auth
220
- });
221
- });
222
- }
223
- function convertAwsCodeCommit(entries) {
224
- return entries.map((entry) => {
225
- const auth = [];
226
- const accessKeyId = entry.getOptionalString("accessKeyId");
227
- const secretAccessKey = entry.getOptionalString("secretAccessKey");
228
- if (accessKeyId !== void 0 && secretAccessKey !== void 0) {
229
- auth.push({ method: "accessKey", accessKeyId, secretAccessKey });
230
- }
231
- const roleArn = entry.getOptionalString("roleArn");
232
- if (roleArn !== void 0) {
233
- auth.push(
234
- omitUndefined({
235
- method: "assumeRole",
236
- roleArn,
237
- externalId: entry.getOptionalString("externalId")
238
- })
239
- );
240
- }
241
- const region = entry.getString("region");
242
- const host = entry.getOptionalString("host") ?? `${region}.console.aws.amazon.com`;
243
- return { type: "aws-codecommit", host, region, auth };
244
- });
245
- }
246
- function convertAwsS3(entries) {
247
- return entries.map((entry) => {
248
- const auth = [];
249
- const accessKeyId = entry.getOptionalString("accessKeyId");
250
- const secretAccessKey = entry.getOptionalString("secretAccessKey");
251
- if (accessKeyId !== void 0 && secretAccessKey !== void 0) {
252
- auth.push({ method: "accessKey", accessKeyId, secretAccessKey });
253
- }
254
- const roleArn = entry.getOptionalString("roleArn");
255
- if (roleArn !== void 0) {
256
- auth.push(
257
- omitUndefined({
258
- method: "assumeRole",
259
- roleArn,
260
- externalId: entry.getOptionalString("externalId")
261
- })
262
- );
263
- }
264
- const endpoint = entry.getOptionalString("endpoint");
265
- const host = endpoint ? new URL(endpoint).host : "amazonaws.com";
266
- return omitUndefined({
267
- type: "aws-s3",
268
- host,
269
- endpoint,
270
- s3ForcePathStyle: entry.getOptionalBoolean("s3ForcePathStyle"),
271
- auth: withNoneAuthFallback(auth)
272
- });
273
- });
274
- }
275
- function convertAzureBlobStorage(entries) {
276
- return entries.map((entry) => {
277
- const auth = [];
278
- const accountKey = entry.getOptionalString("accountKey");
279
- if (accountKey !== void 0) {
280
- auth.push({ method: "accountKey", accountKey });
281
- }
282
- const sasToken = entry.getOptionalString("sasToken");
283
- if (sasToken !== void 0) {
284
- auth.push({ method: "sasToken", sasToken });
285
- }
286
- const connectionString = entry.getOptionalString("connectionString");
287
- if (connectionString !== void 0) {
288
- auth.push({ method: "connectionString", connectionString });
289
- }
290
- if (entry.has("aadCredential")) {
291
- auth.push({
292
- method: "aadCredential",
293
- clientId: entry.getString("aadCredential.clientId"),
294
- tenantId: entry.getString("aadCredential.tenantId"),
295
- clientSecret: entry.getString("aadCredential.clientSecret")
296
- });
297
- }
298
- const endpoint = entry.getOptionalString("endpoint");
299
- const host = endpoint ? new URL(endpoint).host : entry.getOptionalString("host") ?? "blob.core.windows.net";
300
- return omitUndefined({
301
- type: "azure-blob-storage",
302
- host,
303
- accountName: entry.getOptionalString("accountName"),
304
- endpoint,
305
- endpointSuffix: entry.getOptionalString("endpointSuffix"),
306
- auth: withNoneAuthFallback(auth)
307
- });
308
- });
309
- }
310
- function convertGoogleGcs(entries) {
311
- return entries.map((entry) => {
312
- const auth = [];
313
- const clientEmail = entry.getOptionalString("clientEmail");
314
- const privateKey = entry.getOptionalString("privateKey");
315
- if (clientEmail !== void 0 && privateKey !== void 0) {
316
- auth.push({ method: "serviceAccount", clientEmail, privateKey });
317
- }
318
- return {
319
- type: "google-gcs",
320
- host: "storage.cloud.google.com",
321
- auth: withNoneAuthFallback(auth)
322
- };
323
- });
324
- }
325
- function withNoneAuthFallback(auth) {
326
- return auth.length > 0 ? auth : [{ method: "none" }];
327
- }
328
- function omitUndefined(input) {
329
- const out = {};
330
- for (const [key, value] of Object.entries(input)) {
331
- if (value !== void 0) {
332
- out[key] = value;
333
- }
334
- }
335
- return out;
336
- }
337
-
338
- exports.getLegacyIntegrations = getLegacyIntegrations;
339
- //# sourceMappingURL=getLegacyIntegrations.cjs.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"getLegacyIntegrations.cjs.js","sources":["../../../../connections-node/src/getLegacyIntegrations.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 { RootConfigService } from '@backstage/backend-plugin-api';\nimport { Config } from '@backstage/config';\nimport { JsonObject, JsonValue } from '@backstage/types';\n\n/**\n * Reads legacy `integrations.*` config and converts each entry to a connection\n * object in the same shape as `connections:` config. The result is a list of\n * unvalidated JsonObjects; the caller is expected to run them through the\n * normal connection-schema validation alongside the rest of the connections\n * config.\n */\nexport function getLegacyIntegrations(config: RootConfigService): JsonObject[] {\n const integrations = config.getOptionalConfig('integrations');\n if (!integrations) {\n return [];\n }\n\n return [\n ...convertAwsCodeCommit(\n integrations.getOptionalConfigArray('awsCodeCommit') ?? [],\n ),\n ...convertAwsS3(integrations.getOptionalConfigArray('awsS3') ?? []),\n ...convertAzure(integrations.getOptionalConfigArray('azure') ?? []),\n ...convertAzureBlobStorage(\n integrations.getOptionalConfigArray('azureBlobStorage') ?? [],\n ),\n ...convertBitbucketCloud(\n integrations.getOptionalConfigArray('bitbucketCloud') ?? [],\n ),\n ...convertBitbucketServer(\n integrations.getOptionalConfigArray('bitbucketServer') ?? [],\n ),\n ...convertGerrit(integrations.getOptionalConfigArray('gerrit') ?? []),\n ...convertGitea(integrations.getOptionalConfigArray('gitea') ?? []),\n ...convertGithub(integrations.getOptionalConfigArray('github') ?? []),\n ...convertGitlab(integrations.getOptionalConfigArray('gitlab') ?? []),\n ...convertGoogleGcs(integrations.getOptionalConfigArray('googleGcs') ?? []),\n ...convertHarness(integrations.getOptionalConfigArray('harness') ?? []),\n ];\n}\n\nfunction convertGithub(entries: Config[]): JsonObject[] {\n return entries.map(entry => {\n const auth: JsonObject[] = [];\n\n const token = entry.getOptionalString('token');\n if (token !== undefined) {\n auth.push({ method: 'token', token });\n }\n\n for (const app of entry.getOptionalConfigArray('apps') ?? []) {\n auth.push(convertGithubApp(app));\n }\n\n return omitUndefined({\n type: 'github',\n host: entry.getOptionalString('host'),\n apiBaseUrl: entry.getOptionalString('apiBaseUrl'),\n rawBaseUrl: entry.getOptionalString('rawBaseUrl'),\n auth: withNoneAuthFallback(auth),\n });\n });\n}\n\nfunction convertGitlab(entries: Config[]): JsonObject[] {\n return entries.map(entry => {\n const auth: JsonObject[] = [];\n\n const token = entry.getOptionalString('token');\n if (token !== undefined) {\n auth.push({ method: 'token', token });\n }\n\n return omitUndefined({\n type: 'gitlab',\n host: entry.getOptionalString('host'),\n apiBaseUrl: entry.getOptionalString('apiBaseUrl'),\n baseUrl: entry.getOptionalString('baseUrl'),\n auth: withNoneAuthFallback(auth),\n });\n });\n}\n\nfunction convertGithubApp(app: Config): JsonObject {\n return omitUndefined({\n method: 'app',\n appId: app.getOptional<JsonValue>('appId'),\n privateKey: app.getOptionalString('privateKey'),\n clientId: app.getOptionalString('clientId'),\n clientSecret: app.getOptionalString('clientSecret'),\n webhookSecret: app.getOptionalString('webhookSecret'),\n orgs: app.getOptionalStringArray('allowedInstallationOwners'),\n publicAccess: app.getOptionalBoolean('publicAccess'),\n });\n}\n\nfunction convertAzure(entries: Config[]): JsonObject[] {\n return entries.map(entry => {\n const auth: JsonObject[] = [];\n for (const credential of entry.getOptionalConfigArray('credentials') ??\n []) {\n const converted = convertAzureCredential(credential);\n if (converted) {\n auth.push(converted);\n }\n }\n\n return omitUndefined({\n type: 'azure',\n host: entry.getOptionalString('host'),\n auth: withNoneAuthFallback(auth),\n });\n });\n}\n\nfunction convertAzureCredential(credential: Config): JsonObject | undefined {\n const orgs = credential.getOptionalStringArray('organizations');\n const personalAccessToken = credential.getOptionalString(\n 'personalAccessToken',\n );\n if (personalAccessToken !== undefined) {\n return omitUndefined({\n method: 'pat',\n personalAccessToken,\n orgs,\n });\n }\n\n const clientSecret = credential.getOptionalString('clientSecret');\n if (clientSecret !== undefined) {\n return omitUndefined({\n method: 'clientCredentials',\n clientId: credential.getOptionalString('clientId'),\n clientSecret,\n tenantId: credential.getOptionalString('tenantId'),\n orgs,\n });\n }\n\n const clientId = credential.getOptionalString('clientId');\n if (clientId !== undefined) {\n return omitUndefined({\n method: 'managedIdentity',\n clientId,\n tenantId: credential.getOptionalString('tenantId'),\n managedIdentityClientId: credential.getOptionalString(\n 'managedIdentityClientId',\n ),\n orgs,\n });\n }\n\n return undefined;\n}\n\nfunction convertBitbucketCloud(entries: Config[]): JsonObject[] {\n return entries.map(entry => {\n const username = entry.getOptionalString('username');\n const auth: JsonObject[] = [];\n\n const token = entry.getOptionalString('token');\n if (username !== undefined && token !== undefined) {\n auth.push({ method: 'token', username, token });\n }\n\n const appPassword = entry.getOptionalString('appPassword');\n if (username !== undefined && appPassword !== undefined) {\n auth.push({ method: 'appPassword', username, appPassword });\n }\n\n const clientId = entry.getOptionalString('clientId');\n const clientSecret = entry.getOptionalString('clientSecret');\n if (clientId !== undefined && clientSecret !== undefined) {\n auth.push({ method: 'oauth', clientId, clientSecret });\n }\n\n return {\n type: 'bitbucket-cloud',\n host: 'bitbucket.org',\n auth: withNoneAuthFallback(auth),\n };\n });\n}\n\nfunction convertBitbucketServer(entries: Config[]): JsonObject[] {\n return entries.map(entry => {\n const auth: JsonObject[] = [];\n\n const token = entry.getOptionalString('token');\n if (token !== undefined) {\n auth.push({ method: 'token', token });\n }\n\n const username = entry.getOptionalString('username');\n const password = entry.getOptionalString('password');\n if (username !== undefined && password !== undefined) {\n auth.push({ method: 'basic', username, password });\n }\n\n return omitUndefined({\n type: 'bitbucket-server',\n host: entry.getOptionalString('host'),\n apiBaseUrl: entry.getOptionalString('apiBaseUrl'),\n auth: withNoneAuthFallback(auth),\n });\n });\n}\n\nfunction convertGerrit(entries: Config[]): JsonObject[] {\n return entries.map(entry => {\n const auth: JsonObject[] = [];\n\n const username = entry.getOptionalString('username');\n const password = entry.getOptionalString('password');\n if (username !== undefined && password !== undefined) {\n auth.push({ method: 'basic', username, password });\n }\n\n return omitUndefined({\n type: 'gerrit',\n host: entry.getOptionalString('host'),\n baseUrl: entry.getOptionalString('baseUrl'),\n gitilesBaseUrl: entry.getOptionalString('gitilesBaseUrl'),\n cloneUrl: entry.getOptionalString('cloneUrl'),\n auth: withNoneAuthFallback(auth),\n });\n });\n}\n\nfunction convertGitea(entries: Config[]): JsonObject[] {\n return entries.map(entry => {\n const auth: JsonObject[] = [];\n\n const username = entry.getOptionalString('username');\n const password = entry.getOptionalString('password');\n if (username !== undefined && password !== undefined) {\n auth.push({ method: 'basic', username, password });\n }\n\n return omitUndefined({\n type: 'gitea',\n host: entry.getOptionalString('host'),\n baseUrl: entry.getOptionalString('baseUrl'),\n auth: withNoneAuthFallback(auth),\n });\n });\n}\n\nfunction convertHarness(entries: Config[]): JsonObject[] {\n return entries.map(entry => {\n const auth: JsonObject[] = [];\n\n const token = entry.getOptionalString('token');\n if (token !== undefined) {\n const apiKey = entry.getOptionalString('apiKey');\n auth.push(omitUndefined({ method: 'token', token, apiKey }));\n }\n\n return omitUndefined({\n type: 'harness',\n host: entry.getOptionalString('host'),\n auth,\n });\n });\n}\n\nfunction convertAwsCodeCommit(entries: Config[]): JsonObject[] {\n return entries.map(entry => {\n const auth: JsonObject[] = [];\n\n const accessKeyId = entry.getOptionalString('accessKeyId');\n const secretAccessKey = entry.getOptionalString('secretAccessKey');\n if (accessKeyId !== undefined && secretAccessKey !== undefined) {\n auth.push({ method: 'accessKey', accessKeyId, secretAccessKey });\n }\n\n const roleArn = entry.getOptionalString('roleArn');\n if (roleArn !== undefined) {\n auth.push(\n omitUndefined({\n method: 'assumeRole',\n roleArn,\n externalId: entry.getOptionalString('externalId'),\n }),\n );\n }\n\n const region = entry.getString('region');\n const host =\n entry.getOptionalString('host') ?? `${region}.console.aws.amazon.com`;\n\n return { type: 'aws-codecommit', host, region, auth };\n });\n}\n\nfunction convertAwsS3(entries: Config[]): JsonObject[] {\n return entries.map(entry => {\n const auth: JsonObject[] = [];\n\n const accessKeyId = entry.getOptionalString('accessKeyId');\n const secretAccessKey = entry.getOptionalString('secretAccessKey');\n if (accessKeyId !== undefined && secretAccessKey !== undefined) {\n auth.push({ method: 'accessKey', accessKeyId, secretAccessKey });\n }\n\n const roleArn = entry.getOptionalString('roleArn');\n if (roleArn !== undefined) {\n auth.push(\n omitUndefined({\n method: 'assumeRole',\n roleArn,\n externalId: entry.getOptionalString('externalId'),\n }),\n );\n }\n\n const endpoint = entry.getOptionalString('endpoint');\n const host = endpoint ? new URL(endpoint).host : 'amazonaws.com';\n\n return omitUndefined({\n type: 'aws-s3',\n host,\n endpoint,\n s3ForcePathStyle: entry.getOptionalBoolean('s3ForcePathStyle'),\n auth: withNoneAuthFallback(auth),\n });\n });\n}\n\nfunction convertAzureBlobStorage(entries: Config[]): JsonObject[] {\n return entries.map(entry => {\n const auth: JsonObject[] = [];\n\n const accountKey = entry.getOptionalString('accountKey');\n if (accountKey !== undefined) {\n auth.push({ method: 'accountKey', accountKey });\n }\n\n const sasToken = entry.getOptionalString('sasToken');\n if (sasToken !== undefined) {\n auth.push({ method: 'sasToken', sasToken });\n }\n\n const connectionString = entry.getOptionalString('connectionString');\n if (connectionString !== undefined) {\n auth.push({ method: 'connectionString', connectionString });\n }\n\n if (entry.has('aadCredential')) {\n auth.push({\n method: 'aadCredential',\n clientId: entry.getString('aadCredential.clientId'),\n tenantId: entry.getString('aadCredential.tenantId'),\n clientSecret: entry.getString('aadCredential.clientSecret'),\n });\n }\n\n const endpoint = entry.getOptionalString('endpoint');\n const host = endpoint\n ? new URL(endpoint).host\n : entry.getOptionalString('host') ?? 'blob.core.windows.net';\n\n return omitUndefined({\n type: 'azure-blob-storage',\n host,\n accountName: entry.getOptionalString('accountName'),\n endpoint,\n endpointSuffix: entry.getOptionalString('endpointSuffix'),\n auth: withNoneAuthFallback(auth),\n });\n });\n}\n\nfunction convertGoogleGcs(entries: Config[]): JsonObject[] {\n return entries.map(entry => {\n const auth: JsonObject[] = [];\n\n const clientEmail = entry.getOptionalString('clientEmail');\n const privateKey = entry.getOptionalString('privateKey');\n if (clientEmail !== undefined && privateKey !== undefined) {\n auth.push({ method: 'serviceAccount', clientEmail, privateKey });\n }\n\n return {\n type: 'google-gcs',\n host: 'storage.cloud.google.com',\n auth: withNoneAuthFallback(auth),\n };\n });\n}\n\nfunction withNoneAuthFallback(auth: JsonObject[]): JsonObject[] {\n return auth.length > 0 ? auth : [{ method: 'none' }];\n}\n\nfunction omitUndefined(\n input: Record<string, JsonValue | undefined>,\n): JsonObject {\n const out: JsonObject = {};\n for (const [key, value] of Object.entries(input)) {\n if (value !== undefined) {\n out[key] = value;\n }\n }\n return out;\n}\n"],"names":[],"mappings":"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"}