@backstage/backend-defaults 0.4.2-next.0 → 0.4.2-next.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +45 -0
- package/auth/package.json +1 -1
- package/cache/package.json +1 -1
- package/config.d.ts +40 -0
- package/database/package.json +1 -1
- package/discovery/package.json +1 -1
- package/dist/auth.d.ts +1 -1
- package/dist/cache.cjs.js +12 -8
- package/dist/cache.cjs.js.map +1 -1
- package/dist/cache.d.ts +1 -1
- package/dist/database.d.ts +1 -1
- package/dist/discovery.d.ts +1 -1
- package/dist/httpAuth.d.ts +1 -1
- package/dist/httpRouter.d.ts +1 -1
- package/dist/lifecycle.d.ts +1 -1
- package/dist/logger.d.ts +1 -1
- package/dist/permissions.d.ts +1 -1
- package/dist/rootConfig.d.ts +1 -1
- package/dist/rootHealth.d.ts +1 -1
- package/dist/rootHttpRouter.d.ts +1 -1
- package/dist/rootLifecycle.d.ts +1 -1
- package/dist/rootLogger.d.ts +1 -1
- package/dist/scheduler.cjs.js +23 -4
- package/dist/scheduler.cjs.js.map +1 -1
- package/dist/scheduler.d.ts +1 -1
- package/dist/urlReader.cjs.js +13 -5
- package/dist/urlReader.cjs.js.map +1 -1
- package/dist/urlReader.d.ts +19 -2
- package/dist/userInfo.d.ts +1 -1
- package/httpAuth/package.json +1 -1
- package/httpRouter/package.json +1 -1
- package/lifecycle/package.json +1 -1
- package/logger/package.json +1 -1
- package/migrations/scheduler/20240712211735_nullable_next_run.js +41 -0
- package/package.json +12 -12
- package/permissions/package.json +1 -1
- package/rootConfig/package.json +1 -1
- package/rootHealth/package.json +1 -1
- package/rootHttpRouter/package.json +1 -1
- package/rootLifecycle/package.json +1 -1
- package/rootLogger/package.json +1 -1
- package/scheduler/package.json +1 -1
- package/urlReader/package.json +1 -1
- package/userInfo/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,50 @@
|
|
|
1
1
|
# @backstage/backend-defaults
|
|
2
2
|
|
|
3
|
+
## 0.4.2-next.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 0d16b52: Add access restrictions to the JWKS external access method config schema
|
|
8
|
+
- 93095ee: Make sure node-fetch is version 2.7.0 or greater
|
|
9
|
+
- ba9abf4: The `SchedulerService` now allows tasks with `frequency: { trigger: 'manual' }`. This means that the task will not be scheduled, but rather run only when manually triggered with `SchedulerService.triggerTask`.
|
|
10
|
+
- 7c5f3b0: Update the `UrlReader` service to depends on multiple instances of `UrlReaderFactoryProvider` service.
|
|
11
|
+
- 1d5f298: Avoid excessive numbers of error listeners on cache clients
|
|
12
|
+
- Updated dependencies
|
|
13
|
+
- @backstage/backend-plugin-api@0.8.0-next.2
|
|
14
|
+
- @backstage/backend-app-api@0.8.1-next.2
|
|
15
|
+
- @backstage/backend-common@0.23.4-next.2
|
|
16
|
+
- @backstage/config-loader@1.9.0-next.2
|
|
17
|
+
- @backstage/plugin-auth-node@0.5.0-next.2
|
|
18
|
+
- @backstage/plugin-permission-node@0.8.1-next.2
|
|
19
|
+
- @backstage/plugin-events-node@0.3.9-next.2
|
|
20
|
+
- @backstage/integration@1.14.0-next.0
|
|
21
|
+
- @backstage/integration-aws-node@0.1.12
|
|
22
|
+
- @backstage/backend-dev-utils@0.1.4
|
|
23
|
+
- @backstage/cli-common@0.1.14
|
|
24
|
+
- @backstage/config@1.2.0
|
|
25
|
+
- @backstage/errors@1.2.4
|
|
26
|
+
- @backstage/types@1.1.1
|
|
27
|
+
|
|
28
|
+
## 0.4.2-next.1
|
|
29
|
+
|
|
30
|
+
### Patch Changes
|
|
31
|
+
|
|
32
|
+
- Updated dependencies
|
|
33
|
+
- @backstage/config-loader@1.9.0-next.1
|
|
34
|
+
- @backstage/plugin-permission-node@0.8.1-next.1
|
|
35
|
+
- @backstage/backend-plugin-api@0.7.1-next.1
|
|
36
|
+
- @backstage/backend-app-api@0.8.1-next.1
|
|
37
|
+
- @backstage/backend-common@0.23.4-next.1
|
|
38
|
+
- @backstage/integration@1.14.0-next.0
|
|
39
|
+
- @backstage/integration-aws-node@0.1.12
|
|
40
|
+
- @backstage/backend-dev-utils@0.1.4
|
|
41
|
+
- @backstage/cli-common@0.1.14
|
|
42
|
+
- @backstage/config@1.2.0
|
|
43
|
+
- @backstage/errors@1.2.4
|
|
44
|
+
- @backstage/types@1.1.1
|
|
45
|
+
- @backstage/plugin-auth-node@0.4.18-next.1
|
|
46
|
+
- @backstage/plugin-events-node@0.3.9-next.1
|
|
47
|
+
|
|
3
48
|
## 0.4.2-next.0
|
|
4
49
|
|
|
5
50
|
### Patch Changes
|
package/auth/package.json
CHANGED
package/cache/package.json
CHANGED
package/config.d.ts
CHANGED
|
@@ -287,6 +287,46 @@ export interface Config {
|
|
|
287
287
|
*/
|
|
288
288
|
subjectPrefix?: string;
|
|
289
289
|
};
|
|
290
|
+
/**
|
|
291
|
+
* Restricts what types of access that are permitted for this access
|
|
292
|
+
* method. If no access restrictions are given, it'll have unlimited
|
|
293
|
+
* access. This access restriction applies for the framework level;
|
|
294
|
+
* individual plugins may have their own access control mechanisms
|
|
295
|
+
* on top of this.
|
|
296
|
+
*/
|
|
297
|
+
accessRestrictions?: Array<{
|
|
298
|
+
/**
|
|
299
|
+
* Permit access to make requests to this plugin.
|
|
300
|
+
*
|
|
301
|
+
* Can be further refined by setting additional fields below.
|
|
302
|
+
*/
|
|
303
|
+
plugin: string;
|
|
304
|
+
/**
|
|
305
|
+
* If given, this method is limited to only performing actions
|
|
306
|
+
* with these named permissions in this plugin.
|
|
307
|
+
*
|
|
308
|
+
* Note that this only applies where permissions checks are
|
|
309
|
+
* enabled in the first place. Endpoints that are not protected by
|
|
310
|
+
* the permissions system at all, are not affected by this
|
|
311
|
+
* setting.
|
|
312
|
+
*/
|
|
313
|
+
permission?: string | Array<string>;
|
|
314
|
+
/**
|
|
315
|
+
* If given, this method is limited to only performing actions
|
|
316
|
+
* whose permissions have these attributes.
|
|
317
|
+
*
|
|
318
|
+
* Note that this only applies where permissions checks are
|
|
319
|
+
* enabled in the first place. Endpoints that are not protected by
|
|
320
|
+
* the permissions system at all, are not affected by this
|
|
321
|
+
* setting.
|
|
322
|
+
*/
|
|
323
|
+
permissionAttribute?: {
|
|
324
|
+
/**
|
|
325
|
+
* One of more of 'create', 'read', 'update', or 'delete'.
|
|
326
|
+
*/
|
|
327
|
+
action?: string | Array<string>;
|
|
328
|
+
};
|
|
329
|
+
}>;
|
|
290
330
|
}
|
|
291
331
|
>;
|
|
292
332
|
};
|
package/database/package.json
CHANGED
package/discovery/package.json
CHANGED
package/dist/auth.d.ts
CHANGED
|
@@ -9,6 +9,6 @@ import * as _backstage_backend_plugin_api from '@backstage/backend-plugin-api';
|
|
|
9
9
|
*
|
|
10
10
|
* @public
|
|
11
11
|
*/
|
|
12
|
-
declare const authServiceFactory: _backstage_backend_plugin_api.ServiceFactoryCompat<_backstage_backend_plugin_api.AuthService, "plugin", undefined>;
|
|
12
|
+
declare const authServiceFactory: _backstage_backend_plugin_api.ServiceFactoryCompat<_backstage_backend_plugin_api.AuthService, "plugin", "singleton", undefined>;
|
|
13
13
|
|
|
14
14
|
export { authServiceFactory };
|
package/dist/cache.cjs.js
CHANGED
|
@@ -111,17 +111,10 @@ class CacheManager {
|
|
|
111
111
|
return {
|
|
112
112
|
getClient: (defaultOptions = {}) => {
|
|
113
113
|
const clientFactory = (options) => {
|
|
114
|
-
|
|
114
|
+
return this.getClientWithTtl(
|
|
115
115
|
pluginId,
|
|
116
116
|
options.defaultTtl ?? this.defaultTtl
|
|
117
117
|
);
|
|
118
|
-
concreteClient.on("error", (err) => {
|
|
119
|
-
this.logger?.error("Failed to create cache client", err);
|
|
120
|
-
if (typeof this.errorHandler === "function") {
|
|
121
|
-
this.errorHandler(err);
|
|
122
|
-
}
|
|
123
|
-
});
|
|
124
|
-
return concreteClient;
|
|
125
118
|
};
|
|
126
119
|
return new DefaultCacheClient(
|
|
127
120
|
clientFactory(defaultOptions),
|
|
@@ -140,11 +133,16 @@ class CacheManager {
|
|
|
140
133
|
return (pluginId, defaultTtl) => {
|
|
141
134
|
if (!store) {
|
|
142
135
|
store = new KeyvRedis(this.connection);
|
|
136
|
+
store.on("error", (err) => {
|
|
137
|
+
this.logger?.error("Failed to create redis cache client", err);
|
|
138
|
+
this.errorHandler?.(err);
|
|
139
|
+
});
|
|
143
140
|
}
|
|
144
141
|
return new Keyv__default.default({
|
|
145
142
|
namespace: pluginId,
|
|
146
143
|
ttl: defaultTtl,
|
|
147
144
|
store,
|
|
145
|
+
emitErrors: false,
|
|
148
146
|
useRedisSets: this.useRedisSets
|
|
149
147
|
});
|
|
150
148
|
};
|
|
@@ -155,10 +153,15 @@ class CacheManager {
|
|
|
155
153
|
return (pluginId, defaultTtl) => {
|
|
156
154
|
if (!store) {
|
|
157
155
|
store = new KeyvMemcache(this.connection);
|
|
156
|
+
store.on("error", (err) => {
|
|
157
|
+
this.logger?.error("Failed to create memcache cache client", err);
|
|
158
|
+
this.errorHandler?.(err);
|
|
159
|
+
});
|
|
158
160
|
}
|
|
159
161
|
return new Keyv__default.default({
|
|
160
162
|
namespace: pluginId,
|
|
161
163
|
ttl: defaultTtl,
|
|
164
|
+
emitErrors: false,
|
|
162
165
|
store
|
|
163
166
|
});
|
|
164
167
|
};
|
|
@@ -168,6 +171,7 @@ class CacheManager {
|
|
|
168
171
|
return (pluginId, defaultTtl) => new Keyv__default.default({
|
|
169
172
|
namespace: pluginId,
|
|
170
173
|
ttl: defaultTtl,
|
|
174
|
+
emitErrors: false,
|
|
171
175
|
store
|
|
172
176
|
});
|
|
173
177
|
}
|
package/dist/cache.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache.cjs.js","sources":["../src/entrypoints/cache/CacheClient.ts","../src/entrypoints/cache/CacheManager.ts","../src/entrypoints/cache/cacheServiceFactory.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 CacheServiceSetOptions,\n} from '@backstage/backend-plugin-api';\nimport { JsonValue } from '@backstage/types';\nimport { createHash } from 'crypto';\nimport Keyv from 'keyv';\n\nexport type CacheClientFactory = (options: CacheServiceOptions) => Keyv;\n\n/**\n * A basic, concrete implementation of the CacheService, suitable for almost\n * all uses in Backstage.\n */\nexport class DefaultCacheClient implements CacheService {\n #client: Keyv;\n #clientFactory: CacheClientFactory;\n #options: CacheServiceOptions;\n\n constructor(\n client: Keyv,\n clientFactory: CacheClientFactory,\n options: CacheServiceOptions,\n ) {\n this.#client = client;\n this.#clientFactory = clientFactory;\n this.#options = options;\n }\n\n async get<TValue extends JsonValue>(\n key: string,\n ): Promise<TValue | undefined> {\n const k = this.getNormalizedKey(key);\n const value = await this.#client.get(k);\n return value as TValue | undefined;\n }\n\n async set(\n key: string,\n value: JsonValue,\n opts: CacheServiceSetOptions = {},\n ): Promise<void> {\n const k = this.getNormalizedKey(key);\n await this.#client.set(k, value, opts.ttl);\n }\n\n async delete(key: string): Promise<void> {\n const k = this.getNormalizedKey(key);\n await this.#client.delete(k);\n }\n\n withOptions(options: CacheServiceOptions): CacheService {\n const newOptions = { ...this.#options, ...options };\n return new DefaultCacheClient(\n this.#clientFactory(newOptions),\n this.#clientFactory,\n newOptions,\n );\n }\n\n /**\n * Ensures keys are well-formed for any/all cache stores.\n */\n private getNormalizedKey(candidateKey: string): string {\n // Remove potentially invalid characters.\n const wellFormedKey = Buffer.from(candidateKey).toString('base64');\n\n // Memcache in particular doesn't do well with keys > 250 bytes.\n // Padded because a plugin ID is also prepended to the key.\n if (wellFormedKey.length < 200) {\n return wellFormedKey;\n }\n\n return createHash('sha256').update(candidateKey).digest('base64');\n }\n}\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n CacheServiceOptions,\n LoggerService,\n} from '@backstage/backend-plugin-api';\nimport { Config } from '@backstage/config';\nimport Keyv from 'keyv';\nimport { DefaultCacheClient } from './CacheClient';\nimport { CacheManagerOptions, PluginCacheManager } from './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: Config,\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 defaultTtl = config.getOptionalNumber('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 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): PluginCacheManager {\n return {\n getClient: (defaultOptions = {}) => {\n const clientFactory = (options: CacheServiceOptions) => {\n const concreteClient = this.getClientWithTtl(\n pluginId,\n options.defaultTtl ?? this.defaultTtl,\n );\n\n // Always provide an error handler to avoid stopping the process.\n concreteClient.on('error', (err: Error) => {\n // In all cases, just log the error.\n this.logger?.error('Failed to create cache client', err);\n\n // Invoke any custom error handler if provided.\n if (typeof this.errorHandler === 'function') {\n this.errorHandler(err);\n }\n });\n\n return concreteClient;\n };\n\n return new DefaultCacheClient(\n clientFactory(defaultOptions),\n clientFactory,\n defaultOptions,\n );\n },\n };\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 }\n return new Keyv({\n namespace: pluginId,\n ttl: defaultTtl,\n store,\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 }\n return new Keyv({\n namespace: pluginId,\n ttl: defaultTtl,\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 store,\n });\n }\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n coreServices,\n createServiceFactory,\n} from '@backstage/backend-plugin-api';\nimport { CacheManager } from './CacheManager';\n\n/**\n * Key-value store for caching data.\n *\n * See {@link @backstage/code-plugin-api#CacheService}\n * and {@link https://backstage.io/docs/backend-system/core-services/cache | the service docs}\n * for more information.\n *\n * @public\n */\nexport const cacheServiceFactory = createServiceFactory({\n service: coreServices.cache,\n deps: {\n config: coreServices.rootConfig,\n plugin: coreServices.pluginMetadata,\n logger: coreServices.rootLogger,\n },\n async createRootContext({ config, logger }) {\n return CacheManager.fromConfig(config, { logger });\n },\n async factory({ plugin }, manager) {\n return manager.forPlugin(plugin.getId()).getClient();\n },\n});\n"],"names":["createHash","Keyv","createServiceFactory","coreServices"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cache.cjs.js","sources":["../src/entrypoints/cache/CacheClient.ts","../src/entrypoints/cache/CacheManager.ts","../src/entrypoints/cache/cacheServiceFactory.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 CacheServiceSetOptions,\n} from '@backstage/backend-plugin-api';\nimport { JsonValue } from '@backstage/types';\nimport { createHash } from 'crypto';\nimport Keyv from 'keyv';\n\nexport type CacheClientFactory = (options: CacheServiceOptions) => Keyv;\n\n/**\n * A basic, concrete implementation of the CacheService, suitable for almost\n * all uses in Backstage.\n */\nexport class DefaultCacheClient implements CacheService {\n #client: Keyv;\n #clientFactory: CacheClientFactory;\n #options: CacheServiceOptions;\n\n constructor(\n client: Keyv,\n clientFactory: CacheClientFactory,\n options: CacheServiceOptions,\n ) {\n this.#client = client;\n this.#clientFactory = clientFactory;\n this.#options = options;\n }\n\n async get<TValue extends JsonValue>(\n key: string,\n ): Promise<TValue | undefined> {\n const k = this.getNormalizedKey(key);\n const value = await this.#client.get(k);\n return value as TValue | undefined;\n }\n\n async set(\n key: string,\n value: JsonValue,\n opts: CacheServiceSetOptions = {},\n ): Promise<void> {\n const k = this.getNormalizedKey(key);\n await this.#client.set(k, value, opts.ttl);\n }\n\n async delete(key: string): Promise<void> {\n const k = this.getNormalizedKey(key);\n await this.#client.delete(k);\n }\n\n withOptions(options: CacheServiceOptions): CacheService {\n const newOptions = { ...this.#options, ...options };\n return new DefaultCacheClient(\n this.#clientFactory(newOptions),\n this.#clientFactory,\n newOptions,\n );\n }\n\n /**\n * Ensures keys are well-formed for any/all cache stores.\n */\n private getNormalizedKey(candidateKey: string): string {\n // Remove potentially invalid characters.\n const wellFormedKey = Buffer.from(candidateKey).toString('base64');\n\n // Memcache in particular doesn't do well with keys > 250 bytes.\n // Padded because a plugin ID is also prepended to the key.\n if (wellFormedKey.length < 200) {\n return wellFormedKey;\n }\n\n return createHash('sha256').update(candidateKey).digest('base64');\n }\n}\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n CacheServiceOptions,\n LoggerService,\n} from '@backstage/backend-plugin-api';\nimport { Config } from '@backstage/config';\nimport Keyv from 'keyv';\nimport { DefaultCacheClient } from './CacheClient';\nimport { CacheManagerOptions, PluginCacheManager } from './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: Config,\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 defaultTtl = config.getOptionalNumber('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 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): PluginCacheManager {\n return {\n getClient: (defaultOptions = {}) => {\n const clientFactory = (options: CacheServiceOptions) => {\n return this.getClientWithTtl(\n pluginId,\n options.defaultTtl ?? this.defaultTtl,\n );\n };\n\n return new DefaultCacheClient(\n clientFactory(defaultOptions),\n clientFactory,\n defaultOptions,\n );\n },\n };\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 // 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","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n coreServices,\n createServiceFactory,\n} from '@backstage/backend-plugin-api';\nimport { CacheManager } from './CacheManager';\n\n/**\n * Key-value store for caching data.\n *\n * See {@link @backstage/code-plugin-api#CacheService}\n * and {@link https://backstage.io/docs/backend-system/core-services/cache | the service docs}\n * for more information.\n *\n * @public\n */\nexport const cacheServiceFactory = createServiceFactory({\n service: coreServices.cache,\n deps: {\n config: coreServices.rootConfig,\n plugin: coreServices.pluginMetadata,\n logger: coreServices.rootLogger,\n },\n async createRootContext({ config, logger }) {\n return CacheManager.fromConfig(config, { logger });\n },\n async factory({ plugin }, manager) {\n return manager.forPlugin(plugin.getId()).getClient();\n },\n});\n"],"names":["createHash","Keyv","createServiceFactory","coreServices"],"mappings":"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"}
|
package/dist/cache.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ import { Config } from '@backstage/config';
|
|
|
11
11
|
*
|
|
12
12
|
* @public
|
|
13
13
|
*/
|
|
14
|
-
declare const cacheServiceFactory: _backstage_backend_plugin_api.ServiceFactoryCompat<_backstage_backend_plugin_api.CacheService, "plugin", undefined>;
|
|
14
|
+
declare const cacheServiceFactory: _backstage_backend_plugin_api.ServiceFactoryCompat<_backstage_backend_plugin_api.CacheService, "plugin", "singleton", undefined>;
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* Options given when constructing a {@link CacheManager}.
|
package/dist/database.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ import { Config } from '@backstage/config';
|
|
|
11
11
|
*
|
|
12
12
|
* @public
|
|
13
13
|
*/
|
|
14
|
-
declare const databaseServiceFactory: _backstage_backend_plugin_api.ServiceFactoryCompat<_backstage_backend_plugin_api.DatabaseService, "plugin", undefined>;
|
|
14
|
+
declare const databaseServiceFactory: _backstage_backend_plugin_api.ServiceFactoryCompat<_backstage_backend_plugin_api.DatabaseService, "plugin", "singleton", undefined>;
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* Creation options for {@link DatabaseManager}.
|
package/dist/discovery.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ import { Config } from '@backstage/config';
|
|
|
11
11
|
*
|
|
12
12
|
* @public
|
|
13
13
|
*/
|
|
14
|
-
declare const discoveryServiceFactory: _backstage_backend_plugin_api.ServiceFactoryCompat<_backstage_backend_plugin_api.DiscoveryService, "plugin", undefined>;
|
|
14
|
+
declare const discoveryServiceFactory: _backstage_backend_plugin_api.ServiceFactoryCompat<_backstage_backend_plugin_api.DiscoveryService, "plugin", "singleton", undefined>;
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* HostDiscovery is a basic PluginEndpointDiscovery implementation
|
package/dist/httpAuth.d.ts
CHANGED
|
@@ -10,6 +10,6 @@ import { HttpAuthService } from '@backstage/backend-plugin-api';
|
|
|
10
10
|
*
|
|
11
11
|
* @public
|
|
12
12
|
*/
|
|
13
|
-
declare const httpAuthServiceFactory: _backstage_backend_plugin_api.ServiceFactoryCompat<HttpAuthService, "plugin", undefined>;
|
|
13
|
+
declare const httpAuthServiceFactory: _backstage_backend_plugin_api.ServiceFactoryCompat<HttpAuthService, "plugin", "singleton", undefined>;
|
|
14
14
|
|
|
15
15
|
export { httpAuthServiceFactory };
|
package/dist/httpRouter.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ import { RequestHandler } from 'express';
|
|
|
12
12
|
*
|
|
13
13
|
* @public
|
|
14
14
|
*/
|
|
15
|
-
declare const httpRouterServiceFactory: _backstage_backend_plugin_api.ServiceFactoryCompat<_backstage_backend_plugin_api.HttpRouterService, "plugin", undefined>;
|
|
15
|
+
declare const httpRouterServiceFactory: _backstage_backend_plugin_api.ServiceFactoryCompat<_backstage_backend_plugin_api.HttpRouterService, "plugin", "singleton", undefined>;
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* Options for {@link createLifecycleMiddleware}.
|
package/dist/lifecycle.d.ts
CHANGED
|
@@ -10,6 +10,6 @@ import { LifecycleService } from '@backstage/backend-plugin-api';
|
|
|
10
10
|
*
|
|
11
11
|
* @public
|
|
12
12
|
*/
|
|
13
|
-
declare const lifecycleServiceFactory: _backstage_backend_plugin_api.ServiceFactoryCompat<LifecycleService, "plugin", undefined>;
|
|
13
|
+
declare const lifecycleServiceFactory: _backstage_backend_plugin_api.ServiceFactoryCompat<LifecycleService, "plugin", "singleton", undefined>;
|
|
14
14
|
|
|
15
15
|
export { lifecycleServiceFactory };
|
package/dist/logger.d.ts
CHANGED
|
@@ -9,6 +9,6 @@ import * as _backstage_backend_plugin_api from '@backstage/backend-plugin-api';
|
|
|
9
9
|
*
|
|
10
10
|
* @public
|
|
11
11
|
*/
|
|
12
|
-
declare const loggerServiceFactory: _backstage_backend_plugin_api.ServiceFactoryCompat<_backstage_backend_plugin_api.LoggerService, "plugin", undefined>;
|
|
12
|
+
declare const loggerServiceFactory: _backstage_backend_plugin_api.ServiceFactoryCompat<_backstage_backend_plugin_api.LoggerService, "plugin", "singleton", undefined>;
|
|
13
13
|
|
|
14
14
|
export { loggerServiceFactory };
|
package/dist/permissions.d.ts
CHANGED
|
@@ -9,6 +9,6 @@ import * as _backstage_backend_plugin_api from '@backstage/backend-plugin-api';
|
|
|
9
9
|
*
|
|
10
10
|
* @public
|
|
11
11
|
*/
|
|
12
|
-
declare const permissionsServiceFactory: _backstage_backend_plugin_api.ServiceFactoryCompat<_backstage_backend_plugin_api.PermissionsService, "plugin", undefined>;
|
|
12
|
+
declare const permissionsServiceFactory: _backstage_backend_plugin_api.ServiceFactoryCompat<_backstage_backend_plugin_api.PermissionsService, "plugin", "singleton", undefined>;
|
|
13
13
|
|
|
14
14
|
export { permissionsServiceFactory };
|
package/dist/rootConfig.d.ts
CHANGED
|
@@ -33,6 +33,6 @@ interface RootConfigFactoryOptions {
|
|
|
33
33
|
/**
|
|
34
34
|
* @public
|
|
35
35
|
*/
|
|
36
|
-
declare const rootConfigServiceFactory: ((options?: RootConfigFactoryOptions) => _backstage_backend_plugin_api.ServiceFactory<_backstage_backend_plugin_api.RootConfigService, "root">) & _backstage_backend_plugin_api.ServiceFactory<_backstage_backend_plugin_api.RootConfigService, "root">;
|
|
36
|
+
declare const rootConfigServiceFactory: ((options?: RootConfigFactoryOptions) => _backstage_backend_plugin_api.ServiceFactory<_backstage_backend_plugin_api.RootConfigService, "root", "singleton">) & _backstage_backend_plugin_api.ServiceFactory<_backstage_backend_plugin_api.RootConfigService, "root", "singleton">;
|
|
37
37
|
|
|
38
38
|
export { type RootConfigFactoryOptions, createConfigSecretEnumerator, rootConfigServiceFactory };
|
package/dist/rootHealth.d.ts
CHANGED
|
@@ -4,6 +4,6 @@ import { RootHealthService } from '@backstage/backend-plugin-api';
|
|
|
4
4
|
/**
|
|
5
5
|
* @public
|
|
6
6
|
*/
|
|
7
|
-
declare const rootHealthServiceFactory: _backstage_backend_plugin_api.ServiceFactoryCompat<RootHealthService, "root", undefined>;
|
|
7
|
+
declare const rootHealthServiceFactory: _backstage_backend_plugin_api.ServiceFactoryCompat<RootHealthService, "root", "singleton", undefined>;
|
|
8
8
|
|
|
9
9
|
export { rootHealthServiceFactory };
|
package/dist/rootHttpRouter.d.ts
CHANGED
|
@@ -288,6 +288,6 @@ type RootHttpRouterFactoryOptions = {
|
|
|
288
288
|
configure?(context: RootHttpRouterConfigureContext): void;
|
|
289
289
|
};
|
|
290
290
|
/** @public */
|
|
291
|
-
declare const rootHttpRouterServiceFactory: ((options?: RootHttpRouterFactoryOptions) => _backstage_backend_plugin_api.ServiceFactory<_backstage_backend_plugin_api.RootHttpRouterService, "root">) & _backstage_backend_plugin_api.ServiceFactory<_backstage_backend_plugin_api.RootHttpRouterService, "root">;
|
|
291
|
+
declare const rootHttpRouterServiceFactory: ((options?: RootHttpRouterFactoryOptions) => _backstage_backend_plugin_api.ServiceFactory<_backstage_backend_plugin_api.RootHttpRouterService, "root", "singleton">) & _backstage_backend_plugin_api.ServiceFactory<_backstage_backend_plugin_api.RootHttpRouterService, "root", "singleton">;
|
|
292
292
|
|
|
293
293
|
export { DefaultRootHttpRouter, type DefaultRootHttpRouterOptions, type ExtendedHttpServer, type HttpServerCertificateOptions, type HttpServerOptions, MiddlewareFactory, type MiddlewareFactoryErrorOptions, type MiddlewareFactoryOptions, type RootHttpRouterConfigureContext, type RootHttpRouterFactoryOptions, createHealthRouter, createHttpServer, readCorsOptions, readHelmetOptions, readHttpServerOptions, rootHttpRouterServiceFactory };
|
package/dist/rootLifecycle.d.ts
CHANGED
|
@@ -10,6 +10,6 @@ import { RootLifecycleService } from '@backstage/backend-plugin-api';
|
|
|
10
10
|
*
|
|
11
11
|
* @public
|
|
12
12
|
*/
|
|
13
|
-
declare const rootLifecycleServiceFactory: _backstage_backend_plugin_api.ServiceFactoryCompat<RootLifecycleService, "root", undefined>;
|
|
13
|
+
declare const rootLifecycleServiceFactory: _backstage_backend_plugin_api.ServiceFactoryCompat<RootLifecycleService, "root", "singleton", undefined>;
|
|
14
14
|
|
|
15
15
|
export { rootLifecycleServiceFactory };
|
package/dist/rootLogger.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ import { transport } from 'winston';
|
|
|
13
13
|
*
|
|
14
14
|
* @public
|
|
15
15
|
*/
|
|
16
|
-
declare const rootLoggerServiceFactory: _backstage_backend_plugin_api.ServiceFactoryCompat<_backstage_backend_plugin_api.RootLoggerService, "root", undefined>;
|
|
16
|
+
declare const rootLoggerServiceFactory: _backstage_backend_plugin_api.ServiceFactoryCompat<_backstage_backend_plugin_api.RootLoggerService, "root", "singleton", undefined>;
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* @public
|
package/dist/scheduler.cjs.js
CHANGED
|
@@ -191,6 +191,9 @@ function isValidCronFormat(c) {
|
|
|
191
191
|
return false;
|
|
192
192
|
}
|
|
193
193
|
}
|
|
194
|
+
function isValidTrigger(t) {
|
|
195
|
+
return t === "manual";
|
|
196
|
+
}
|
|
194
197
|
zod.z.object({
|
|
195
198
|
version: zod.z.literal(1),
|
|
196
199
|
initialDelayDuration: zod.z.string().optional().refine(isValidOptionalDurationString, {
|
|
@@ -206,6 +209,10 @@ zod.z.object({
|
|
|
206
209
|
const taskSettingsV2Schema = zod.z.object({
|
|
207
210
|
version: zod.z.literal(2),
|
|
208
211
|
cadence: zod.z.string().refine(isValidCronFormat, { message: "Invalid cron" }).or(
|
|
212
|
+
zod.z.string().refine(isValidTrigger, {
|
|
213
|
+
message: "Invalid trigger, expecting 'manual'"
|
|
214
|
+
})
|
|
215
|
+
).or(
|
|
209
216
|
zod.z.string().refine(isValidOptionalDurationString, {
|
|
210
217
|
message: "Invalid duration, expecting ISO Period"
|
|
211
218
|
})
|
|
@@ -237,8 +244,8 @@ class TaskWorker {
|
|
|
237
244
|
`Task worker starting: ${this.taskId}, ${JSON.stringify(settings)}`
|
|
238
245
|
);
|
|
239
246
|
let workCheckFrequency = this.workCheckFrequency;
|
|
240
|
-
const
|
|
241
|
-
if (
|
|
247
|
+
const isDuration = settings?.cadence.startsWith("P");
|
|
248
|
+
if (isDuration) {
|
|
242
249
|
const cadence = luxon.Duration.fromISO(settings.cadence);
|
|
243
250
|
if (cadence < workCheckFrequency) {
|
|
244
251
|
workCheckFrequency = cadence;
|
|
@@ -324,7 +331,9 @@ class TaskWorker {
|
|
|
324
331
|
*/
|
|
325
332
|
async persistTask(settings) {
|
|
326
333
|
taskSettingsV2Schema.parse(settings);
|
|
327
|
-
const
|
|
334
|
+
const isManual = settings?.cadence === "manual";
|
|
335
|
+
const isDuration = settings?.cadence.startsWith("P");
|
|
336
|
+
const isCron = !isManual && !isDuration;
|
|
328
337
|
let startAt;
|
|
329
338
|
let nextStartAt;
|
|
330
339
|
if (settings.initialDelayDuration) {
|
|
@@ -337,6 +346,9 @@ class TaskWorker {
|
|
|
337
346
|
const time = new cron.CronTime(settings.cadence).sendAt().minus({ seconds: 1 }).toUTC();
|
|
338
347
|
nextStartAt = this.nextRunAtRaw(time);
|
|
339
348
|
startAt ||= nextStartAt;
|
|
349
|
+
} else if (isManual) {
|
|
350
|
+
nextStartAt = this.knex.raw("null");
|
|
351
|
+
startAt ||= nextStartAt;
|
|
340
352
|
} else {
|
|
341
353
|
startAt ||= this.knex.fn.now();
|
|
342
354
|
nextStartAt = nowPlus(luxon.Duration.fromISO(settings.cadence), this.knex);
|
|
@@ -426,12 +438,16 @@ class TaskWorker {
|
|
|
426
438
|
return rows === 1;
|
|
427
439
|
}
|
|
428
440
|
async tryReleaseTask(ticket, settings) {
|
|
429
|
-
const
|
|
441
|
+
const isManual = settings?.cadence === "manual";
|
|
442
|
+
const isDuration = settings?.cadence.startsWith("P");
|
|
443
|
+
const isCron = !isManual && !isDuration;
|
|
430
444
|
let nextRun;
|
|
431
445
|
if (isCron) {
|
|
432
446
|
const time = new cron.CronTime(settings.cadence).sendAt().toUTC();
|
|
433
447
|
this.logger.debug(`task: ${this.taskId} will next occur around ${time}`);
|
|
434
448
|
nextRun = this.nextRunAtRaw(time);
|
|
449
|
+
} else if (isManual) {
|
|
450
|
+
nextRun = this.knex.raw("null");
|
|
435
451
|
} else {
|
|
436
452
|
const dt = luxon.Duration.fromISO(settings.cadence).as("seconds");
|
|
437
453
|
this.logger.debug(
|
|
@@ -567,6 +583,9 @@ function parseDuration(frequency) {
|
|
|
567
583
|
if (typeof frequency === "object" && "cron" in frequency) {
|
|
568
584
|
return frequency.cron;
|
|
569
585
|
}
|
|
586
|
+
if (typeof frequency === "object" && "trigger" in frequency) {
|
|
587
|
+
return frequency.trigger;
|
|
588
|
+
}
|
|
570
589
|
const parsed = luxon.Duration.isDuration(frequency) ? frequency : luxon.Duration.fromObject(frequency);
|
|
571
590
|
if (!parsed.isValid) {
|
|
572
591
|
throw new Error(
|