@backstage/backend-defaults 0.5.3-next.2 → 0.5.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 +47 -0
- package/config.d.ts +5 -5
- package/dist/database.d.ts +1 -1
- package/dist/entrypoints/auth/plugin/PluginTokenHandler.cjs.js +6 -1
- package/dist/entrypoints/auth/plugin/PluginTokenHandler.cjs.js.map +1 -1
- package/dist/entrypoints/cache/CacheManager.cjs.js +9 -10
- package/dist/entrypoints/cache/CacheManager.cjs.js.map +1 -1
- package/dist/package.json.cjs.js +2 -3
- package/dist/package.json.cjs.js.map +1 -1
- package/dist/urlReader.d.ts +1 -1
- package/package.json +78 -38
- package/auth/package.json +0 -6
- package/cache/package.json +0 -6
- package/database/package.json +0 -6
- package/discovery/package.json +0 -6
- package/httpAuth/package.json +0 -6
- package/httpRouter/package.json +0 -6
- package/lifecycle/package.json +0 -6
- package/logger/package.json +0 -6
- package/permissions/package.json +0 -6
- package/rootConfig/package.json +0 -6
- package/rootHealth/package.json +0 -6
- package/rootHttpRouter/package.json +0 -6
- package/rootLifecycle/package.json +0 -6
- package/rootLogger/package.json +0 -6
- package/scheduler/package.json +0 -6
- package/urlReader/package.json +0 -6
- package/userInfo/package.json +0 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,52 @@
|
|
|
1
1
|
# @backstage/backend-defaults
|
|
2
2
|
|
|
3
|
+
## 0.5.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- bf306cb: Removed dependency `@backstage/backend-common`.
|
|
8
|
+
- e30bb46: Disabling database migrations now correctly uses the `backend.default.skipMigrations` config value.
|
|
9
|
+
- d52d7f9: Support ISO and ms string forms of durations in config too
|
|
10
|
+
- f6eaec2: Link to proper package in `rootLoggerServiceFactory` doc string.
|
|
11
|
+
- ecf6b39: Use `node-fetch` instead of native fetch, as per https://backstage.io/docs/architecture-decisions/adrs-adr013
|
|
12
|
+
- 4e58bc7: Upgrade to uuid v11 internally
|
|
13
|
+
- Updated dependencies
|
|
14
|
+
- @backstage/config@1.3.0
|
|
15
|
+
- @backstage/plugin-events-node@0.4.5
|
|
16
|
+
- @backstage/types@1.2.0
|
|
17
|
+
- @backstage/integration-aws-node@0.1.13
|
|
18
|
+
- @backstage/config-loader@1.9.2
|
|
19
|
+
- @backstage/plugin-auth-node@0.5.4
|
|
20
|
+
- @backstage/backend-plugin-api@1.0.2
|
|
21
|
+
- @backstage/backend-app-api@1.0.2
|
|
22
|
+
- @backstage/cli-common@0.1.15
|
|
23
|
+
- @backstage/backend-dev-utils@0.1.5
|
|
24
|
+
- @backstage/cli-node@0.2.10
|
|
25
|
+
- @backstage/errors@1.2.5
|
|
26
|
+
- @backstage/integration@1.15.2
|
|
27
|
+
- @backstage/plugin-permission-node@0.8.5
|
|
28
|
+
|
|
29
|
+
## 0.5.3-next.3
|
|
30
|
+
|
|
31
|
+
### Patch Changes
|
|
32
|
+
|
|
33
|
+
- ecf6b39: Use `node-fetch` instead of native fetch, as per https://backstage.io/docs/architecture-decisions/adrs-adr013
|
|
34
|
+
- Updated dependencies
|
|
35
|
+
- @backstage/integration-aws-node@0.1.13-next.0
|
|
36
|
+
- @backstage/plugin-events-node@0.4.5-next.3
|
|
37
|
+
- @backstage/backend-app-api@1.0.2-next.2
|
|
38
|
+
- @backstage/backend-dev-utils@0.1.5
|
|
39
|
+
- @backstage/backend-plugin-api@1.0.2-next.2
|
|
40
|
+
- @backstage/cli-common@0.1.15-next.0
|
|
41
|
+
- @backstage/cli-node@0.2.10-next.0
|
|
42
|
+
- @backstage/config@1.2.0
|
|
43
|
+
- @backstage/config-loader@1.9.2-next.0
|
|
44
|
+
- @backstage/errors@1.2.4
|
|
45
|
+
- @backstage/integration@1.15.1
|
|
46
|
+
- @backstage/types@1.1.1
|
|
47
|
+
- @backstage/plugin-auth-node@0.5.4-next.2
|
|
48
|
+
- @backstage/plugin-permission-node@0.8.5-next.2
|
|
49
|
+
|
|
3
50
|
## 0.5.3-next.2
|
|
4
51
|
|
|
5
52
|
### Patch Changes
|
package/config.d.ts
CHANGED
|
@@ -474,8 +474,8 @@ export interface Config {
|
|
|
474
474
|
cache?:
|
|
475
475
|
| {
|
|
476
476
|
store: 'memory';
|
|
477
|
-
/** An optional default TTL (in milliseconds). */
|
|
478
|
-
defaultTtl?: number | HumanDuration;
|
|
477
|
+
/** An optional default TTL (in milliseconds, if given as a number). */
|
|
478
|
+
defaultTtl?: number | HumanDuration | string;
|
|
479
479
|
}
|
|
480
480
|
| {
|
|
481
481
|
store: 'redis';
|
|
@@ -484,8 +484,8 @@ export interface Config {
|
|
|
484
484
|
* @visibility secret
|
|
485
485
|
*/
|
|
486
486
|
connection: string;
|
|
487
|
-
/** An optional default TTL (in milliseconds). */
|
|
488
|
-
defaultTtl?: number | HumanDuration;
|
|
487
|
+
/** An optional default TTL (in milliseconds, if given as a number). */
|
|
488
|
+
defaultTtl?: number | HumanDuration | string;
|
|
489
489
|
/**
|
|
490
490
|
* Whether or not [useRedisSets](https://github.com/jaredwray/keyv/tree/main/packages/redis#useredissets) should be configured to this redis cache.
|
|
491
491
|
* Defaults to true if unspecified.
|
|
@@ -500,7 +500,7 @@ export interface Config {
|
|
|
500
500
|
*/
|
|
501
501
|
connection: string;
|
|
502
502
|
/** An optional default TTL (in milliseconds). */
|
|
503
|
-
defaultTtl?: number | HumanDuration;
|
|
503
|
+
defaultTtl?: number | HumanDuration | string;
|
|
504
504
|
};
|
|
505
505
|
|
|
506
506
|
cors?: {
|
package/dist/database.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import * as _backstage_backend_plugin_api from '@backstage/backend-plugin-api';
|
|
3
|
-
import { DatabaseService, RootLoggerService, RootLifecycleService,
|
|
3
|
+
import { RootConfigService, DatabaseService, RootLoggerService, RootLifecycleService, LoggerService, LifecycleService } from '@backstage/backend-plugin-api';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Database access and management via `knex`.
|
|
@@ -5,6 +5,11 @@ var errors = require('@backstage/errors');
|
|
|
5
5
|
var pluginAuthNode = require('@backstage/plugin-auth-node');
|
|
6
6
|
var JwksClient = require('../JwksClient.cjs.js');
|
|
7
7
|
var types = require('@backstage/types');
|
|
8
|
+
var fetch = require('node-fetch');
|
|
9
|
+
|
|
10
|
+
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
11
|
+
|
|
12
|
+
var fetch__default = /*#__PURE__*/_interopDefaultCompat(fetch);
|
|
8
13
|
|
|
9
14
|
const SECONDS_IN_MS = 1e3;
|
|
10
15
|
const ALLOWED_PLUGIN_ID_PATTERN = /^[a-z0-9_-]+$/i;
|
|
@@ -93,7 +98,7 @@ class PluginTokenHandler {
|
|
|
93
98
|
}
|
|
94
99
|
const doCheck = async () => {
|
|
95
100
|
try {
|
|
96
|
-
const res = await
|
|
101
|
+
const res = await fetch__default.default(
|
|
97
102
|
`${await this.discovery.getBaseUrl(
|
|
98
103
|
targetPluginId
|
|
99
104
|
)}/.backstage/auth/v1/jwks.json`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PluginTokenHandler.cjs.js","sources":["../../../../src/entrypoints/auth/plugin/PluginTokenHandler.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 { DiscoveryService, LoggerService } from '@backstage/backend-plugin-api';\nimport { decodeJwt, importJWK, SignJWT, decodeProtectedHeader } from 'jose';\nimport { AuthenticationError } from '@backstage/errors';\nimport { jwtVerify } from 'jose';\nimport { tokenTypes } from '@backstage/plugin-auth-node';\nimport { JwksClient } from '../JwksClient';\nimport { HumanDuration, durationToMilliseconds } from '@backstage/types';\nimport { PluginKeySource } from './keys/types';\n\nconst SECONDS_IN_MS = 1000;\n\nconst ALLOWED_PLUGIN_ID_PATTERN = /^[a-z0-9_-]+$/i;\n\ntype Options = {\n ownPluginId: string;\n keyDuration: HumanDuration;\n keySource: PluginKeySource;\n discovery: DiscoveryService;\n logger: LoggerService;\n /**\n * JWS \"alg\" (Algorithm) Header Parameter value. Defaults to ES256.\n * Must match one of the algorithms defined for IdentityClient.\n * When setting a different algorithm, check if the `key` field\n * of the `signing_keys` table can fit the length of the generated keys.\n * If not, add a knex migration file in the migrations folder.\n * More info on supported algorithms: https://github.com/panva/jose\n */\n algorithm?: string;\n};\n\nexport class PluginTokenHandler {\n private jwksMap = new Map<string, JwksClient>();\n\n // Tracking state for isTargetPluginSupported\n private supportedTargetPlugins = new Set<string>();\n private targetPluginInflightChecks = new Map<string, Promise<boolean>>();\n\n static create(options: Options) {\n return new PluginTokenHandler(\n options.logger,\n options.ownPluginId,\n options.keySource,\n options.algorithm ?? 'ES256',\n Math.round(durationToMilliseconds(options.keyDuration) / 1000),\n options.discovery,\n );\n }\n\n private constructor(\n private readonly logger: LoggerService,\n private readonly ownPluginId: string,\n private readonly keySource: PluginKeySource,\n private readonly algorithm: string,\n private readonly keyDurationSeconds: number,\n private readonly discovery: DiscoveryService,\n ) {}\n\n async verifyToken(\n token: string,\n ): Promise<{ subject: string; limitedUserToken?: string } | undefined> {\n try {\n const { typ } = decodeProtectedHeader(token);\n if (typ !== tokenTypes.plugin.typParam) {\n return undefined;\n }\n } catch {\n return undefined;\n }\n\n const pluginId = String(decodeJwt(token).sub);\n if (!pluginId) {\n throw new AuthenticationError('Invalid plugin token: missing subject');\n }\n if (!ALLOWED_PLUGIN_ID_PATTERN.test(pluginId)) {\n throw new AuthenticationError(\n 'Invalid plugin token: forbidden subject format',\n );\n }\n\n const jwksClient = await this.getJwksClient(pluginId);\n await jwksClient.refreshKeyStore(token); // TODO(Rugvip): Refactor so that this isn't needed\n\n const { payload } = await jwtVerify<{ sub: string; obo?: string }>(\n token,\n jwksClient.getKey,\n {\n typ: tokenTypes.plugin.typParam,\n audience: this.ownPluginId,\n requiredClaims: ['iat', 'exp', 'sub', 'aud'],\n },\n ).catch(e => {\n throw new AuthenticationError('Invalid plugin token', e);\n });\n\n return { subject: `plugin:${payload.sub}`, limitedUserToken: payload.obo };\n }\n\n async issueToken(options: {\n pluginId: string;\n targetPluginId: string;\n onBehalfOf?: { token: string; expiresAt: Date };\n }): Promise<{ token: string }> {\n const { pluginId, targetPluginId, onBehalfOf } = options;\n const key = await this.keySource.getPrivateSigningKey();\n\n const sub = pluginId;\n const aud = targetPluginId;\n const iat = Math.floor(Date.now() / SECONDS_IN_MS);\n const ourExp = iat + this.keyDurationSeconds;\n const exp = onBehalfOf\n ? Math.min(\n ourExp,\n Math.floor(onBehalfOf.expiresAt.getTime() / SECONDS_IN_MS),\n )\n : ourExp;\n\n const claims = { sub, aud, iat, exp, obo: onBehalfOf?.token };\n const token = await new SignJWT(claims)\n .setProtectedHeader({\n typ: tokenTypes.plugin.typParam,\n alg: this.algorithm,\n kid: key.kid,\n })\n .setAudience(aud)\n .setSubject(sub)\n .setIssuedAt(iat)\n .setExpirationTime(exp)\n .sign(await importJWK(key));\n\n return { token };\n }\n\n private async isTargetPluginSupported(\n targetPluginId: string,\n ): Promise<boolean> {\n if (this.supportedTargetPlugins.has(targetPluginId)) {\n return true;\n }\n const inFlight = this.targetPluginInflightChecks.get(targetPluginId);\n if (inFlight) {\n return inFlight;\n }\n\n const doCheck = async () => {\n try {\n const res = await fetch(\n `${await this.discovery.getBaseUrl(\n targetPluginId,\n )}/.backstage/auth/v1/jwks.json`,\n );\n if (res.status === 404) {\n return false;\n }\n\n if (!res.ok) {\n throw new Error(`Failed to fetch jwks.json, ${res.status}`);\n }\n\n const data = await res.json();\n if (!data.keys) {\n throw new Error(`Invalid jwks.json response, missing keys`);\n }\n\n this.supportedTargetPlugins.add(targetPluginId);\n return true;\n } catch (error) {\n this.logger.error('Unexpected failure for target JWKS check', error);\n return false;\n } finally {\n this.targetPluginInflightChecks.delete(targetPluginId);\n }\n };\n\n const check = doCheck();\n this.targetPluginInflightChecks.set(targetPluginId, check);\n return check;\n }\n\n private async getJwksClient(pluginId: string) {\n const client = this.jwksMap.get(pluginId);\n if (client) {\n return client;\n }\n\n // Double check that the target plugin has a valid JWKS endpoint, otherwise avoid creating a remote key set\n if (!(await this.isTargetPluginSupported(pluginId))) {\n throw new AuthenticationError(\n `Received a plugin token where the source '${pluginId}' plugin unexpectedly does not have a JWKS endpoint. ` +\n 'The target plugin needs to be migrated to be installed in an app using the new backend system.',\n );\n }\n\n const newClient = new JwksClient(async () => {\n return new URL(\n `${await this.discovery.getBaseUrl(\n pluginId,\n )}/.backstage/auth/v1/jwks.json`,\n );\n });\n\n this.jwksMap.set(pluginId, newClient);\n return newClient;\n }\n}\n"],"names":["durationToMilliseconds","decodeProtectedHeader","tokenTypes","decodeJwt","AuthenticationError","jwtVerify","SignJWT","importJWK","JwksClient"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PluginTokenHandler.cjs.js","sources":["../../../../src/entrypoints/auth/plugin/PluginTokenHandler.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 { DiscoveryService, LoggerService } from '@backstage/backend-plugin-api';\nimport { decodeJwt, importJWK, SignJWT, decodeProtectedHeader } from 'jose';\nimport { AuthenticationError } from '@backstage/errors';\nimport { jwtVerify } from 'jose';\nimport { tokenTypes } from '@backstage/plugin-auth-node';\nimport { JwksClient } from '../JwksClient';\nimport { HumanDuration, durationToMilliseconds } from '@backstage/types';\nimport { PluginKeySource } from './keys/types';\nimport fetch from 'node-fetch';\n\nconst SECONDS_IN_MS = 1000;\n\nconst ALLOWED_PLUGIN_ID_PATTERN = /^[a-z0-9_-]+$/i;\n\ntype Options = {\n ownPluginId: string;\n keyDuration: HumanDuration;\n keySource: PluginKeySource;\n discovery: DiscoveryService;\n logger: LoggerService;\n /**\n * JWS \"alg\" (Algorithm) Header Parameter value. Defaults to ES256.\n * Must match one of the algorithms defined for IdentityClient.\n * When setting a different algorithm, check if the `key` field\n * of the `signing_keys` table can fit the length of the generated keys.\n * If not, add a knex migration file in the migrations folder.\n * More info on supported algorithms: https://github.com/panva/jose\n */\n algorithm?: string;\n};\n\nexport class PluginTokenHandler {\n private jwksMap = new Map<string, JwksClient>();\n\n // Tracking state for isTargetPluginSupported\n private supportedTargetPlugins = new Set<string>();\n private targetPluginInflightChecks = new Map<string, Promise<boolean>>();\n\n static create(options: Options) {\n return new PluginTokenHandler(\n options.logger,\n options.ownPluginId,\n options.keySource,\n options.algorithm ?? 'ES256',\n Math.round(durationToMilliseconds(options.keyDuration) / 1000),\n options.discovery,\n );\n }\n\n private constructor(\n private readonly logger: LoggerService,\n private readonly ownPluginId: string,\n private readonly keySource: PluginKeySource,\n private readonly algorithm: string,\n private readonly keyDurationSeconds: number,\n private readonly discovery: DiscoveryService,\n ) {}\n\n async verifyToken(\n token: string,\n ): Promise<{ subject: string; limitedUserToken?: string } | undefined> {\n try {\n const { typ } = decodeProtectedHeader(token);\n if (typ !== tokenTypes.plugin.typParam) {\n return undefined;\n }\n } catch {\n return undefined;\n }\n\n const pluginId = String(decodeJwt(token).sub);\n if (!pluginId) {\n throw new AuthenticationError('Invalid plugin token: missing subject');\n }\n if (!ALLOWED_PLUGIN_ID_PATTERN.test(pluginId)) {\n throw new AuthenticationError(\n 'Invalid plugin token: forbidden subject format',\n );\n }\n\n const jwksClient = await this.getJwksClient(pluginId);\n await jwksClient.refreshKeyStore(token); // TODO(Rugvip): Refactor so that this isn't needed\n\n const { payload } = await jwtVerify<{ sub: string; obo?: string }>(\n token,\n jwksClient.getKey,\n {\n typ: tokenTypes.plugin.typParam,\n audience: this.ownPluginId,\n requiredClaims: ['iat', 'exp', 'sub', 'aud'],\n },\n ).catch(e => {\n throw new AuthenticationError('Invalid plugin token', e);\n });\n\n return { subject: `plugin:${payload.sub}`, limitedUserToken: payload.obo };\n }\n\n async issueToken(options: {\n pluginId: string;\n targetPluginId: string;\n onBehalfOf?: { token: string; expiresAt: Date };\n }): Promise<{ token: string }> {\n const { pluginId, targetPluginId, onBehalfOf } = options;\n const key = await this.keySource.getPrivateSigningKey();\n\n const sub = pluginId;\n const aud = targetPluginId;\n const iat = Math.floor(Date.now() / SECONDS_IN_MS);\n const ourExp = iat + this.keyDurationSeconds;\n const exp = onBehalfOf\n ? Math.min(\n ourExp,\n Math.floor(onBehalfOf.expiresAt.getTime() / SECONDS_IN_MS),\n )\n : ourExp;\n\n const claims = { sub, aud, iat, exp, obo: onBehalfOf?.token };\n const token = await new SignJWT(claims)\n .setProtectedHeader({\n typ: tokenTypes.plugin.typParam,\n alg: this.algorithm,\n kid: key.kid,\n })\n .setAudience(aud)\n .setSubject(sub)\n .setIssuedAt(iat)\n .setExpirationTime(exp)\n .sign(await importJWK(key));\n\n return { token };\n }\n\n private async isTargetPluginSupported(\n targetPluginId: string,\n ): Promise<boolean> {\n if (this.supportedTargetPlugins.has(targetPluginId)) {\n return true;\n }\n const inFlight = this.targetPluginInflightChecks.get(targetPluginId);\n if (inFlight) {\n return inFlight;\n }\n\n const doCheck = async () => {\n try {\n const res = await fetch(\n `${await this.discovery.getBaseUrl(\n targetPluginId,\n )}/.backstage/auth/v1/jwks.json`,\n );\n if (res.status === 404) {\n return false;\n }\n\n if (!res.ok) {\n throw new Error(`Failed to fetch jwks.json, ${res.status}`);\n }\n\n const data = await res.json();\n if (!data.keys) {\n throw new Error(`Invalid jwks.json response, missing keys`);\n }\n\n this.supportedTargetPlugins.add(targetPluginId);\n return true;\n } catch (error) {\n this.logger.error('Unexpected failure for target JWKS check', error);\n return false;\n } finally {\n this.targetPluginInflightChecks.delete(targetPluginId);\n }\n };\n\n const check = doCheck();\n this.targetPluginInflightChecks.set(targetPluginId, check);\n return check;\n }\n\n private async getJwksClient(pluginId: string) {\n const client = this.jwksMap.get(pluginId);\n if (client) {\n return client;\n }\n\n // Double check that the target plugin has a valid JWKS endpoint, otherwise avoid creating a remote key set\n if (!(await this.isTargetPluginSupported(pluginId))) {\n throw new AuthenticationError(\n `Received a plugin token where the source '${pluginId}' plugin unexpectedly does not have a JWKS endpoint. ` +\n 'The target plugin needs to be migrated to be installed in an app using the new backend system.',\n );\n }\n\n const newClient = new JwksClient(async () => {\n return new URL(\n `${await this.discovery.getBaseUrl(\n pluginId,\n )}/.backstage/auth/v1/jwks.json`,\n );\n });\n\n this.jwksMap.set(pluginId, newClient);\n return newClient;\n }\n}\n"],"names":["durationToMilliseconds","decodeProtectedHeader","tokenTypes","decodeJwt","AuthenticationError","jwtVerify","SignJWT","importJWK","fetch","JwksClient"],"mappings":"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"}
|
|
@@ -4,6 +4,7 @@ var Keyv = require('keyv');
|
|
|
4
4
|
var CacheClient = require('./CacheClient.cjs.js');
|
|
5
5
|
var types$1 = require('./types.cjs.js');
|
|
6
6
|
var types = require('@backstage/types');
|
|
7
|
+
var config = require('@backstage/config');
|
|
7
8
|
|
|
8
9
|
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
9
10
|
|
|
@@ -31,23 +32,21 @@ class CacheManager {
|
|
|
31
32
|
*
|
|
32
33
|
* @param config - The loaded application configuration.
|
|
33
34
|
*/
|
|
34
|
-
static fromConfig(config, options = {}) {
|
|
35
|
-
const store = config.getOptionalString("backend.cache.store") || "memory";
|
|
36
|
-
const defaultTtlConfig = config.getOptional("backend.cache.defaultTtl");
|
|
37
|
-
const connectionString = config.getOptionalString("backend.cache.connection") || "";
|
|
38
|
-
const useRedisSets = config.getOptionalBoolean("backend.cache.useRedisSets") ?? true;
|
|
35
|
+
static fromConfig(config$1, options = {}) {
|
|
36
|
+
const store = config$1.getOptionalString("backend.cache.store") || "memory";
|
|
37
|
+
const defaultTtlConfig = config$1.getOptional("backend.cache.defaultTtl");
|
|
38
|
+
const connectionString = config$1.getOptionalString("backend.cache.connection") || "";
|
|
39
|
+
const useRedisSets = config$1.getOptionalBoolean("backend.cache.useRedisSets") ?? true;
|
|
39
40
|
const logger = options.logger?.child({
|
|
40
41
|
type: "cacheManager"
|
|
41
42
|
});
|
|
42
43
|
let defaultTtl;
|
|
43
|
-
if (defaultTtlConfig !== void 0
|
|
44
|
+
if (defaultTtlConfig !== void 0) {
|
|
44
45
|
if (typeof defaultTtlConfig === "number") {
|
|
45
46
|
defaultTtl = defaultTtlConfig;
|
|
46
|
-
} else if (typeof defaultTtlConfig === "object" && !Array.isArray(defaultTtlConfig)) {
|
|
47
|
-
defaultTtl = types.durationToMilliseconds(defaultTtlConfig);
|
|
48
47
|
} else {
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
defaultTtl = types.durationToMilliseconds(
|
|
49
|
+
config.readDurationFromConfig(config$1, { key: "backend.cache.defaultTtl" })
|
|
51
50
|
);
|
|
52
51
|
}
|
|
53
52
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CacheManager.cjs.js","sources":["../../../src/entrypoints/cache/CacheManager.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n CacheService,\n CacheServiceOptions,\n LoggerService,\n RootConfigService,\n} from '@backstage/backend-plugin-api';\nimport Keyv from 'keyv';\nimport { DefaultCacheClient } from './CacheClient';\nimport { CacheManagerOptions, ttlToMilliseconds } from './types';\nimport { durationToMilliseconds } from '@backstage/types';\n\ntype StoreFactory = (pluginId: string, defaultTtl: number | undefined) => Keyv;\n\n/**\n * Implements a Cache Manager which will automatically create new cache clients\n * for plugins when requested. All requested cache clients are created with the\n * connection details provided.\n *\n * @public\n */\nexport class CacheManager {\n /**\n * Keys represent supported `backend.cache.store` values, mapped to factories\n * that return Keyv instances appropriate to the store.\n */\n private readonly storeFactories = {\n redis: this.createRedisStoreFactory(),\n memcache: this.createMemcacheStoreFactory(),\n memory: this.createMemoryStoreFactory(),\n };\n\n private readonly logger?: LoggerService;\n private readonly store: keyof CacheManager['storeFactories'];\n private readonly connection: string;\n private readonly useRedisSets: boolean;\n private readonly errorHandler: CacheManagerOptions['onError'];\n private readonly defaultTtl?: number;\n\n /**\n * Creates a new {@link CacheManager} instance by reading from the `backend`\n * config section, specifically the `.cache` key.\n *\n * @param config - The loaded application configuration.\n */\n static fromConfig(\n config: RootConfigService,\n options: CacheManagerOptions = {},\n ): CacheManager {\n // If no `backend.cache` config is provided, instantiate the CacheManager\n // with an in-memory cache client.\n const store = config.getOptionalString('backend.cache.store') || 'memory';\n const defaultTtlConfig = config.getOptional('backend.cache.defaultTtl');\n const connectionString =\n config.getOptionalString('backend.cache.connection') || '';\n const useRedisSets =\n config.getOptionalBoolean('backend.cache.useRedisSets') ?? true;\n const logger = options.logger?.child({\n type: 'cacheManager',\n });\n\n let defaultTtl: number | undefined;\n if (defaultTtlConfig !== undefined && defaultTtlConfig !== null) {\n if (typeof defaultTtlConfig === 'number') {\n defaultTtl = defaultTtlConfig;\n } else if (\n typeof defaultTtlConfig === 'object' &&\n !Array.isArray(defaultTtlConfig)\n ) {\n defaultTtl = durationToMilliseconds(defaultTtlConfig);\n } else {\n throw new Error(\n `Invalid configuration backend.cache.defaultTtl: ${defaultTtlConfig}, expected milliseconds number or HumanDuration object`,\n );\n }\n }\n\n return new CacheManager(\n store,\n connectionString,\n useRedisSets,\n options.onError,\n logger,\n defaultTtl,\n );\n }\n\n /** @internal */\n constructor(\n store: string,\n connectionString: string,\n useRedisSets: boolean,\n errorHandler: CacheManagerOptions['onError'],\n logger?: LoggerService,\n defaultTtl?: number,\n ) {\n if (!this.storeFactories.hasOwnProperty(store)) {\n throw new Error(`Unknown cache store: ${store}`);\n }\n this.logger = logger;\n this.store = store as keyof CacheManager['storeFactories'];\n this.connection = connectionString;\n this.useRedisSets = useRedisSets;\n this.errorHandler = errorHandler;\n this.defaultTtl = defaultTtl;\n }\n\n /**\n * Generates a PluginCacheManager for consumption by plugins.\n *\n * @param pluginId - The plugin that the cache manager should be created for.\n * Plugin names should be unique.\n */\n forPlugin(pluginId: string): CacheService {\n const clientFactory = (options: CacheServiceOptions) => {\n const ttl = options.defaultTtl ?? this.defaultTtl;\n return this.getClientWithTtl(\n pluginId,\n ttl !== undefined ? ttlToMilliseconds(ttl) : undefined,\n );\n };\n\n return new DefaultCacheClient(clientFactory({}), clientFactory, {});\n }\n\n private getClientWithTtl(pluginId: string, ttl: number | undefined): Keyv {\n return this.storeFactories[this.store](pluginId, ttl);\n }\n\n private createRedisStoreFactory(): StoreFactory {\n const KeyvRedis = require('@keyv/redis');\n let store: typeof KeyvRedis | undefined;\n return (pluginId, defaultTtl) => {\n if (!store) {\n store = new KeyvRedis(this.connection, {\n useRedisSets: this.useRedisSets,\n });\n // Always provide an error handler to avoid stopping the process\n store.on('error', (err: Error) => {\n this.logger?.error('Failed to create redis cache client', err);\n this.errorHandler?.(err);\n });\n }\n return new Keyv({\n namespace: pluginId,\n ttl: defaultTtl,\n store,\n emitErrors: false,\n useRedisSets: this.useRedisSets,\n });\n };\n }\n\n private createMemcacheStoreFactory(): StoreFactory {\n const KeyvMemcache = require('@keyv/memcache');\n let store: typeof KeyvMemcache | undefined;\n return (pluginId, defaultTtl) => {\n if (!store) {\n store = new KeyvMemcache(this.connection);\n // Always provide an error handler to avoid stopping the process\n store.on('error', (err: Error) => {\n this.logger?.error('Failed to create memcache cache client', err);\n this.errorHandler?.(err);\n });\n }\n return new Keyv({\n namespace: pluginId,\n ttl: defaultTtl,\n emitErrors: false,\n store,\n });\n };\n }\n\n private createMemoryStoreFactory(): StoreFactory {\n const store = new Map();\n return (pluginId, defaultTtl) =>\n new Keyv({\n namespace: pluginId,\n ttl: defaultTtl,\n emitErrors: false,\n store,\n });\n }\n}\n"],"names":["durationToMilliseconds","ttlToMilliseconds","DefaultCacheClient","Keyv"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CacheManager.cjs.js","sources":["../../../src/entrypoints/cache/CacheManager.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n CacheService,\n CacheServiceOptions,\n LoggerService,\n RootConfigService,\n} from '@backstage/backend-plugin-api';\nimport Keyv from 'keyv';\nimport { DefaultCacheClient } from './CacheClient';\nimport { CacheManagerOptions, ttlToMilliseconds } from './types';\nimport { durationToMilliseconds } from '@backstage/types';\nimport { readDurationFromConfig } from '@backstage/config';\n\ntype StoreFactory = (pluginId: string, defaultTtl: number | undefined) => Keyv;\n\n/**\n * Implements a Cache Manager which will automatically create new cache clients\n * for plugins when requested. All requested cache clients are created with the\n * connection details provided.\n *\n * @public\n */\nexport class CacheManager {\n /**\n * Keys represent supported `backend.cache.store` values, mapped to factories\n * that return Keyv instances appropriate to the store.\n */\n private readonly storeFactories = {\n redis: this.createRedisStoreFactory(),\n memcache: this.createMemcacheStoreFactory(),\n memory: this.createMemoryStoreFactory(),\n };\n\n private readonly logger?: LoggerService;\n private readonly store: keyof CacheManager['storeFactories'];\n private readonly connection: string;\n private readonly useRedisSets: boolean;\n private readonly errorHandler: CacheManagerOptions['onError'];\n private readonly defaultTtl?: number;\n\n /**\n * Creates a new {@link CacheManager} instance by reading from the `backend`\n * config section, specifically the `.cache` key.\n *\n * @param config - The loaded application configuration.\n */\n static fromConfig(\n config: RootConfigService,\n options: CacheManagerOptions = {},\n ): CacheManager {\n // If no `backend.cache` config is provided, instantiate the CacheManager\n // with an in-memory cache client.\n const store = config.getOptionalString('backend.cache.store') || 'memory';\n const defaultTtlConfig = config.getOptional('backend.cache.defaultTtl');\n const connectionString =\n config.getOptionalString('backend.cache.connection') || '';\n const useRedisSets =\n config.getOptionalBoolean('backend.cache.useRedisSets') ?? true;\n const logger = options.logger?.child({\n type: 'cacheManager',\n });\n\n let defaultTtl: number | undefined;\n if (defaultTtlConfig !== undefined) {\n if (typeof defaultTtlConfig === 'number') {\n defaultTtl = defaultTtlConfig;\n } else {\n defaultTtl = durationToMilliseconds(\n readDurationFromConfig(config, { key: 'backend.cache.defaultTtl' }),\n );\n }\n }\n\n return new CacheManager(\n store,\n connectionString,\n useRedisSets,\n options.onError,\n logger,\n defaultTtl,\n );\n }\n\n /** @internal */\n constructor(\n store: string,\n connectionString: string,\n useRedisSets: boolean,\n errorHandler: CacheManagerOptions['onError'],\n logger?: LoggerService,\n defaultTtl?: number,\n ) {\n if (!this.storeFactories.hasOwnProperty(store)) {\n throw new Error(`Unknown cache store: ${store}`);\n }\n this.logger = logger;\n this.store = store as keyof CacheManager['storeFactories'];\n this.connection = connectionString;\n this.useRedisSets = useRedisSets;\n this.errorHandler = errorHandler;\n this.defaultTtl = defaultTtl;\n }\n\n /**\n * Generates a PluginCacheManager for consumption by plugins.\n *\n * @param pluginId - The plugin that the cache manager should be created for.\n * Plugin names should be unique.\n */\n forPlugin(pluginId: string): CacheService {\n const clientFactory = (options: CacheServiceOptions) => {\n const ttl = options.defaultTtl ?? this.defaultTtl;\n return this.getClientWithTtl(\n pluginId,\n ttl !== undefined ? ttlToMilliseconds(ttl) : undefined,\n );\n };\n\n return new DefaultCacheClient(clientFactory({}), clientFactory, {});\n }\n\n private getClientWithTtl(pluginId: string, ttl: number | undefined): Keyv {\n return this.storeFactories[this.store](pluginId, ttl);\n }\n\n private createRedisStoreFactory(): StoreFactory {\n const KeyvRedis = require('@keyv/redis');\n let store: typeof KeyvRedis | undefined;\n return (pluginId, defaultTtl) => {\n if (!store) {\n store = new KeyvRedis(this.connection, {\n useRedisSets: this.useRedisSets,\n });\n // Always provide an error handler to avoid stopping the process\n store.on('error', (err: Error) => {\n this.logger?.error('Failed to create redis cache client', err);\n this.errorHandler?.(err);\n });\n }\n return new Keyv({\n namespace: pluginId,\n ttl: defaultTtl,\n store,\n emitErrors: false,\n useRedisSets: this.useRedisSets,\n });\n };\n }\n\n private createMemcacheStoreFactory(): StoreFactory {\n const KeyvMemcache = require('@keyv/memcache');\n let store: typeof KeyvMemcache | undefined;\n return (pluginId, defaultTtl) => {\n if (!store) {\n store = new KeyvMemcache(this.connection);\n // Always provide an error handler to avoid stopping the process\n store.on('error', (err: Error) => {\n this.logger?.error('Failed to create memcache cache client', err);\n this.errorHandler?.(err);\n });\n }\n return new Keyv({\n namespace: pluginId,\n ttl: defaultTtl,\n emitErrors: false,\n store,\n });\n };\n }\n\n private createMemoryStoreFactory(): StoreFactory {\n const store = new Map();\n return (pluginId, defaultTtl) =>\n new Keyv({\n namespace: pluginId,\n ttl: defaultTtl,\n emitErrors: false,\n store,\n });\n }\n}\n"],"names":["config","durationToMilliseconds","readDurationFromConfig","ttlToMilliseconds","DefaultCacheClient","Keyv"],"mappings":"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"}
|
package/dist/package.json.cjs.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
5
|
var name = "@backstage/backend-defaults";
|
|
6
|
-
var version = "0.5.3
|
|
6
|
+
var version = "0.5.3";
|
|
7
7
|
var description = "Backend defaults used by Backstage backend apps";
|
|
8
8
|
var backstage = {
|
|
9
9
|
role: "node-library"
|
|
@@ -123,7 +123,6 @@ var dependencies = {
|
|
|
123
123
|
"@aws-sdk/credential-providers": "^3.350.0",
|
|
124
124
|
"@aws-sdk/types": "^3.347.0",
|
|
125
125
|
"@backstage/backend-app-api": "workspace:^",
|
|
126
|
-
"@backstage/backend-common": "^0.25.0",
|
|
127
126
|
"@backstage/backend-dev-utils": "workspace:^",
|
|
128
127
|
"@backstage/backend-plugin-api": "workspace:^",
|
|
129
128
|
"@backstage/cli-common": "workspace:^",
|
|
@@ -181,7 +180,7 @@ var dependencies = {
|
|
|
181
180
|
stoppable: "^1.1.0",
|
|
182
181
|
tar: "^6.1.12",
|
|
183
182
|
"triple-beam": "^1.4.1",
|
|
184
|
-
uuid: "^
|
|
183
|
+
uuid: "^11.0.0",
|
|
185
184
|
winston: "^3.2.1",
|
|
186
185
|
"winston-transport": "^4.5.0",
|
|
187
186
|
yauzl: "^3.0.0",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"package.json.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"package.json.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/dist/urlReader.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import * as _backstage_backend_plugin_api from '@backstage/backend-plugin-api';
|
|
3
|
-
import {
|
|
3
|
+
import { RootConfigService, LoggerService, UrlReaderServiceReadTreeResponse, UrlReaderService, UrlReaderServiceReadUrlOptions, UrlReaderServiceReadUrlResponse, UrlReaderServiceReadTreeOptions, UrlReaderServiceSearchOptions, UrlReaderServiceSearchResponse } from '@backstage/backend-plugin-api';
|
|
4
4
|
import { AzureIntegration, AzureDevOpsCredentialsProvider, BitbucketCloudIntegration, BitbucketIntegration, BitbucketServerIntegration, GerritIntegration, GithubIntegration, GithubCredentialsProvider, GitLabIntegration, GiteaIntegration, HarnessIntegration, AwsS3Integration } from '@backstage/integration';
|
|
5
5
|
import { Readable } from 'stream';
|
|
6
6
|
import { AwsCredentialsManager } from '@backstage/integration-aws-node';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/backend-defaults",
|
|
3
|
-
"version": "0.5.3
|
|
3
|
+
"version": "0.5.3",
|
|
4
4
|
"description": "Backend defaults used by Backstage backend apps",
|
|
5
5
|
"backstage": {
|
|
6
6
|
"role": "node-library"
|
|
@@ -113,27 +113,68 @@
|
|
|
113
113
|
},
|
|
114
114
|
"main": "./dist/index.cjs.js",
|
|
115
115
|
"types": "./dist/index.d.ts",
|
|
116
|
+
"typesVersions": {
|
|
117
|
+
"*": {
|
|
118
|
+
"index": [
|
|
119
|
+
"dist/index.d.ts"
|
|
120
|
+
],
|
|
121
|
+
"auth": [
|
|
122
|
+
"dist/auth.d.ts"
|
|
123
|
+
],
|
|
124
|
+
"cache": [
|
|
125
|
+
"dist/cache.d.ts"
|
|
126
|
+
],
|
|
127
|
+
"database": [
|
|
128
|
+
"dist/database.d.ts"
|
|
129
|
+
],
|
|
130
|
+
"discovery": [
|
|
131
|
+
"dist/discovery.d.ts"
|
|
132
|
+
],
|
|
133
|
+
"httpAuth": [
|
|
134
|
+
"dist/httpAuth.d.ts"
|
|
135
|
+
],
|
|
136
|
+
"httpRouter": [
|
|
137
|
+
"dist/httpRouter.d.ts"
|
|
138
|
+
],
|
|
139
|
+
"lifecycle": [
|
|
140
|
+
"dist/lifecycle.d.ts"
|
|
141
|
+
],
|
|
142
|
+
"logger": [
|
|
143
|
+
"dist/logger.d.ts"
|
|
144
|
+
],
|
|
145
|
+
"permissions": [
|
|
146
|
+
"dist/permissions.d.ts"
|
|
147
|
+
],
|
|
148
|
+
"rootConfig": [
|
|
149
|
+
"dist/rootConfig.d.ts"
|
|
150
|
+
],
|
|
151
|
+
"rootHealth": [
|
|
152
|
+
"dist/rootHealth.d.ts"
|
|
153
|
+
],
|
|
154
|
+
"rootHttpRouter": [
|
|
155
|
+
"dist/rootHttpRouter.d.ts"
|
|
156
|
+
],
|
|
157
|
+
"rootLifecycle": [
|
|
158
|
+
"dist/rootLifecycle.d.ts"
|
|
159
|
+
],
|
|
160
|
+
"rootLogger": [
|
|
161
|
+
"dist/rootLogger.d.ts"
|
|
162
|
+
],
|
|
163
|
+
"scheduler": [
|
|
164
|
+
"dist/scheduler.d.ts"
|
|
165
|
+
],
|
|
166
|
+
"urlReader": [
|
|
167
|
+
"dist/urlReader.d.ts"
|
|
168
|
+
],
|
|
169
|
+
"userInfo": [
|
|
170
|
+
"dist/userInfo.d.ts"
|
|
171
|
+
]
|
|
172
|
+
}
|
|
173
|
+
},
|
|
116
174
|
"files": [
|
|
117
175
|
"config.d.ts",
|
|
118
176
|
"dist",
|
|
119
|
-
"migrations"
|
|
120
|
-
"auth",
|
|
121
|
-
"cache",
|
|
122
|
-
"database",
|
|
123
|
-
"discovery",
|
|
124
|
-
"httpAuth",
|
|
125
|
-
"httpRouter",
|
|
126
|
-
"lifecycle",
|
|
127
|
-
"logger",
|
|
128
|
-
"permissions",
|
|
129
|
-
"rootConfig",
|
|
130
|
-
"rootHealth",
|
|
131
|
-
"rootHttpRouter",
|
|
132
|
-
"rootLifecycle",
|
|
133
|
-
"rootLogger",
|
|
134
|
-
"scheduler",
|
|
135
|
-
"urlReader",
|
|
136
|
-
"userInfo"
|
|
177
|
+
"migrations"
|
|
137
178
|
],
|
|
138
179
|
"scripts": {
|
|
139
180
|
"build": "backstage-cli package build",
|
|
@@ -150,21 +191,20 @@
|
|
|
150
191
|
"@aws-sdk/client-s3": "^3.350.0",
|
|
151
192
|
"@aws-sdk/credential-providers": "^3.350.0",
|
|
152
193
|
"@aws-sdk/types": "^3.347.0",
|
|
153
|
-
"@backstage/backend-app-api": "1.0.2
|
|
154
|
-
"@backstage/backend-
|
|
155
|
-
"@backstage/backend-
|
|
156
|
-
"@backstage/
|
|
157
|
-
"@backstage/cli-
|
|
158
|
-
"@backstage/
|
|
159
|
-
"@backstage/config": "1.2
|
|
160
|
-
"@backstage/
|
|
161
|
-
"@backstage/
|
|
162
|
-
"@backstage/integration": "1.
|
|
163
|
-
"@backstage/
|
|
164
|
-
"@backstage/plugin-
|
|
165
|
-
"@backstage/plugin-
|
|
166
|
-
"@backstage/
|
|
167
|
-
"@backstage/types": "1.1.1",
|
|
194
|
+
"@backstage/backend-app-api": "^1.0.2",
|
|
195
|
+
"@backstage/backend-dev-utils": "^0.1.5",
|
|
196
|
+
"@backstage/backend-plugin-api": "^1.0.2",
|
|
197
|
+
"@backstage/cli-common": "^0.1.15",
|
|
198
|
+
"@backstage/cli-node": "^0.2.10",
|
|
199
|
+
"@backstage/config": "^1.3.0",
|
|
200
|
+
"@backstage/config-loader": "^1.9.2",
|
|
201
|
+
"@backstage/errors": "^1.2.5",
|
|
202
|
+
"@backstage/integration": "^1.15.2",
|
|
203
|
+
"@backstage/integration-aws-node": "^0.1.13",
|
|
204
|
+
"@backstage/plugin-auth-node": "^0.5.4",
|
|
205
|
+
"@backstage/plugin-events-node": "^0.4.5",
|
|
206
|
+
"@backstage/plugin-permission-node": "^0.8.5",
|
|
207
|
+
"@backstage/types": "^1.2.0",
|
|
168
208
|
"@google-cloud/storage": "^7.0.0",
|
|
169
209
|
"@keyv/memcache": "^1.3.5",
|
|
170
210
|
"@keyv/redis": "^2.5.3",
|
|
@@ -209,7 +249,7 @@
|
|
|
209
249
|
"stoppable": "^1.1.0",
|
|
210
250
|
"tar": "^6.1.12",
|
|
211
251
|
"triple-beam": "^1.4.1",
|
|
212
|
-
"uuid": "^
|
|
252
|
+
"uuid": "^11.0.0",
|
|
213
253
|
"winston": "^3.2.1",
|
|
214
254
|
"winston-transport": "^4.5.0",
|
|
215
255
|
"yauzl": "^3.0.0",
|
|
@@ -218,9 +258,9 @@
|
|
|
218
258
|
},
|
|
219
259
|
"devDependencies": {
|
|
220
260
|
"@aws-sdk/util-stream-node": "^3.350.0",
|
|
221
|
-
"@backstage/backend-plugin-api": "1.0.2
|
|
222
|
-
"@backstage/backend-test-utils": "1.1.0
|
|
223
|
-
"@backstage/cli": "0.29.0
|
|
261
|
+
"@backstage/backend-plugin-api": "^1.0.2",
|
|
262
|
+
"@backstage/backend-test-utils": "^1.1.0",
|
|
263
|
+
"@backstage/cli": "^0.29.0",
|
|
224
264
|
"@types/archiver": "^6.0.0",
|
|
225
265
|
"@types/base64-stream": "^1.0.2",
|
|
226
266
|
"@types/concat-stream": "^2.0.0",
|
package/auth/package.json
DELETED
package/cache/package.json
DELETED
package/database/package.json
DELETED
package/discovery/package.json
DELETED
package/httpAuth/package.json
DELETED
package/httpRouter/package.json
DELETED
package/lifecycle/package.json
DELETED
package/logger/package.json
DELETED
package/permissions/package.json
DELETED
package/rootConfig/package.json
DELETED
package/rootHealth/package.json
DELETED
package/rootLogger/package.json
DELETED
package/scheduler/package.json
DELETED
package/urlReader/package.json
DELETED