@backstage/backend-defaults 0.17.5-next.1 → 0.17.5

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,32 @@
1
1
  # @backstage/backend-defaults
2
2
 
3
+ ## 0.17.5
4
+
5
+ ### Patch Changes
6
+
7
+ - aaa7d65: Improved readability of the AWS S3 URL parser by splitting the single monolithic regex into two separate patterns (standard S3 and VPC PrivateLink) with named capture groups. Also made the VPC endpoint region mandatory in the regex, fixing a potential mis-parse when the region segment was absent.
8
+ - d62c384: Fixed a bug where scheduled tasks that were initially registered with a manual trigger and later re-registered with a duration or cron cadence would never be scheduled to run.
9
+ - 8419f51: Added support for AWS PrivateLink for Amazon S3.
10
+ - a624fa3: The `connection` config option for the Redis cache store now accepts either a string URL or an object with additional connection options that are passed directly to the underlying client. The object form is only supported when `backend.cache.store` is `redis`; other stores require a plain string. This allows configuring options like `pingInterval` without needing dedicated config fields. For clustered Redis, the connection object properties are merged into cluster defaults. Fixes https://github.com/backstage/backstage/issues/31813, https://github.com/backstage/backstage/issues/31742.
11
+ - Updated dependencies
12
+ - @backstage/config-loader@1.11.0
13
+ - @backstage/plugin-auth-node@0.7.3
14
+ - @backstage/backend-app-api@1.7.2
15
+ - @backstage/backend-plugin-api@1.9.3
16
+ - @backstage/cli-node@0.3.4
17
+ - @backstage/plugin-events-node@0.4.24
18
+ - @backstage/plugin-permission-node@0.11.2
19
+
20
+ ## 0.17.5-next.2
21
+
22
+ ### Patch Changes
23
+
24
+ - a624fa3: The `connection` config option for the Redis cache store now accepts either a string URL or an object with additional connection options that are passed directly to the underlying client. The object form is only supported when `backend.cache.store` is `redis`; other stores require a plain string. This allows configuring options like `pingInterval` without needing dedicated config fields. For clustered Redis, the connection object properties are merged into cluster defaults. Fixes https://github.com/backstage/backstage/issues/31813, https://github.com/backstage/backstage/issues/31742.
25
+ - Updated dependencies
26
+ - @backstage/backend-plugin-api@1.9.3-next.1
27
+ - @backstage/cli-node@0.3.4-next.0
28
+ - @backstage/config-loader@1.11.0-next.2
29
+
3
30
  ## 0.17.5-next.1
4
31
 
5
32
  ### Patch Changes
@@ -1230,8 +1230,27 @@
1230
1230
  "const": "redis"
1231
1231
  },
1232
1232
  "connection": {
1233
- "type": "string",
1234
- "description": "A redis connection string in the form `redis://user:pass@host:port`.",
1233
+ "anyOf": [
1234
+ {
1235
+ "type": "string"
1236
+ },
1237
+ {
1238
+ "type": "object",
1239
+ "properties": {
1240
+ "url": {
1241
+ "type": "string",
1242
+ "description": "The Redis connection URL."
1243
+ }
1244
+ },
1245
+ "required": [
1246
+ "url"
1247
+ ],
1248
+ "additionalProperties": {
1249
+ "description": "Other connection settings"
1250
+ }
1251
+ }
1252
+ ],
1253
+ "description": "A redis connection string in the form `redis://user:pass@host:port`, or an object with connection options passed directly to the underlying client (e.g. `{ url: 'redis://localhost:6379', pingInterval: 60000 }`). The object form is only supported for the Redis store.",
1235
1254
  "visibility": "secret"
1236
1255
  },
1237
1256
  "defaultTtl": {
package/dist/cache.d.ts CHANGED
@@ -57,6 +57,15 @@ declare class CacheManager {
57
57
  * @returns A new CacheManager instance.
58
58
  */
59
59
  static fromConfig(config: RootConfigService, options?: CacheManagerOptions): CacheManager;
60
+ /**
61
+ * Parse the connection config, which can be either a plain URL string
62
+ * or an object with connection options (e.g. `{ url, pingInterval }`)
63
+ * passed through to the underlying store client.
64
+ *
65
+ * @param config - The configuration service
66
+ * @returns The parsed connection config, either a string or an object depending on how it was configured
67
+ */
68
+ private static parseConnection;
60
69
  /**
61
70
  * Parse store-specific options from configuration.
62
71
  *
@@ -41,7 +41,7 @@ class CacheManager {
41
41
  static fromConfig(config$1, options = {}) {
42
42
  const store = config$1.getOptionalString("backend.cache.store") || "memory";
43
43
  const defaultTtlConfig = config$1.getOptional("backend.cache.defaultTtl");
44
- const connectionString = config$1.getOptionalString("backend.cache.connection") || "";
44
+ const connection = CacheManager.parseConnection(config$1);
45
45
  const logger = options.logger?.child({
46
46
  type: "cacheManager"
47
47
  });
@@ -60,16 +60,51 @@ class CacheManager {
60
60
  );
61
61
  }
62
62
  }
63
- const storeOptions = CacheManager.parseStoreOptions(store, config$1, logger);
63
+ const storeOptions = CacheManager.parseStoreOptions(
64
+ { store, connection },
65
+ { config: config$1, logger }
66
+ );
64
67
  return new CacheManager(
65
68
  store,
66
- connectionString,
69
+ connection,
67
70
  options.onError,
68
71
  logger,
69
72
  defaultTtl,
70
73
  storeOptions
71
74
  );
72
75
  }
76
+ /**
77
+ * Parse the connection config, which can be either a plain URL string
78
+ * or an object with connection options (e.g. `{ url, pingInterval }`)
79
+ * passed through to the underlying store client.
80
+ *
81
+ * @param config - The configuration service
82
+ * @returns The parsed connection config, either a string or an object depending on how it was configured
83
+ */
84
+ static parseConnection(config) {
85
+ const raw = config.getOptional("backend.cache.connection");
86
+ const store = config.getOptionalString("backend.cache.store") || "memory";
87
+ if (raw && typeof raw === "object" && !Array.isArray(raw)) {
88
+ if (store !== "redis") {
89
+ throw new Error(
90
+ "backend.cache.connection object form is only supported when backend.cache.store is 'redis'"
91
+ );
92
+ }
93
+ const url = raw.url;
94
+ if (typeof url !== "string" || url.length === 0) {
95
+ throw new Error(
96
+ "backend.cache.connection object must include a non-empty 'url' string"
97
+ );
98
+ }
99
+ return raw;
100
+ }
101
+ if (raw !== void 0 && typeof raw !== "string") {
102
+ throw new Error(
103
+ `backend.cache.connection must be a string or object, got ${typeof raw}`
104
+ );
105
+ }
106
+ return config.getOptionalString("backend.cache.connection") ?? "";
107
+ }
73
108
  /**
74
109
  * Parse store-specific options from configuration.
75
110
  *
@@ -78,23 +113,26 @@ class CacheManager {
78
113
  * @param logger - Optional logger for warnings
79
114
  * @returns The parsed store options
80
115
  */
81
- static parseStoreOptions(store, config, logger) {
116
+ static parseStoreOptions(config, deps) {
117
+ const { store, connection } = config;
82
118
  const storeConfigPath = `backend.cache.${store}`;
83
- if (store !== "memory" && !config.has(storeConfigPath)) {
84
- logger?.warn(
119
+ if (store !== "memory" && !deps.config.has(storeConfigPath)) {
120
+ deps.logger?.warn(
85
121
  `No configuration found for cache store '${store}' at '${storeConfigPath}'.`
86
122
  );
87
123
  }
88
124
  switch (store) {
89
125
  case "redis":
90
- return CacheManager.parseRedisOptions(storeConfigPath, config, logger);
126
+ return CacheManager.parseRedisOptions(
127
+ { storeConfigPath, connection },
128
+ deps
129
+ );
91
130
  case "valkey":
92
- return CacheManager.parseValkeyOptions(storeConfigPath, config, logger);
131
+ return CacheManager.parseValkeyOptions({ storeConfigPath }, deps);
93
132
  case "infinispan":
94
133
  return InfinispanOptionsMapper.InfinispanOptionsMapper.parseInfinispanOptions(
95
- storeConfigPath,
96
- config,
97
- logger
134
+ { storeConfigPath },
135
+ deps
98
136
  );
99
137
  default:
100
138
  return void 0;
@@ -103,11 +141,11 @@ class CacheManager {
103
141
  /**
104
142
  * Parse Redis-specific options from configuration.
105
143
  */
106
- static parseRedisOptions(storeConfigPath, config$1, logger) {
144
+ static parseRedisOptions(config$1, deps) {
107
145
  const redisOptions = {
108
146
  type: "redis"
109
147
  };
110
- const redisConfig = config$1.getOptionalConfig(storeConfigPath) ?? new config.ConfigReader({});
148
+ const redisConfig = deps.config.getOptionalConfig(config$1.storeConfigPath) ?? new config.ConfigReader({});
111
149
  redisOptions.client = {
112
150
  namespace: redisConfig.getOptionalString("client.namespace"),
113
151
  keyPrefixSeparator: redisConfig.getOptionalString("client.keyPrefixSeparator") || ":",
@@ -120,14 +158,19 @@ class CacheManager {
120
158
  if (redisConfig.has("cluster")) {
121
159
  const clusterConfig = redisConfig.getConfig("cluster");
122
160
  if (!clusterConfig.has("rootNodes")) {
123
- logger?.warn(
161
+ deps.logger?.warn(
124
162
  `Redis cluster config has no 'rootNodes' key, defaulting to non-clustered mode`
125
163
  );
126
164
  return redisOptions;
127
165
  }
166
+ let defaults = clusterConfig.getOptional("defaults");
167
+ if (typeof config$1.connection === "object") {
168
+ const { url: _url, ...connectionDefaults } = config$1.connection;
169
+ defaults = { ...defaults, ...connectionDefaults };
170
+ }
128
171
  redisOptions.cluster = {
129
172
  rootNodes: clusterConfig.get("rootNodes"),
130
- defaults: clusterConfig.getOptional("defaults"),
173
+ defaults,
131
174
  minimizeConnections: clusterConfig.getOptionalBoolean(
132
175
  "minimizeConnections"
133
176
  ),
@@ -142,18 +185,18 @@ class CacheManager {
142
185
  /**
143
186
  * Parse Valkey-specific options from configuration.
144
187
  */
145
- static parseValkeyOptions(storeConfigPath, config$1, logger) {
188
+ static parseValkeyOptions(config$1, deps) {
146
189
  const valkeyOptions = {
147
190
  type: "valkey"
148
191
  };
149
- const valkeyConfig = config$1.getOptionalConfig(storeConfigPath) ?? new config.ConfigReader({});
192
+ const valkeyConfig = deps.config.getOptionalConfig(config$1.storeConfigPath) ?? new config.ConfigReader({});
150
193
  valkeyOptions.client = {
151
194
  keyPrefix: valkeyConfig.getOptionalString("client.keyPrefix")
152
195
  };
153
196
  if (valkeyConfig.has("cluster")) {
154
197
  const clusterConfig = valkeyConfig.getConfig("cluster");
155
198
  if (!clusterConfig.has("rootNodes")) {
156
- logger?.warn(
199
+ deps.logger?.warn(
157
200
  `Valkey cluster config has no 'rootNodes' key, defaulting to non-clustered mode`
158
201
  );
159
202
  return valkeyOptions;
@@ -194,13 +237,13 @@ class CacheManager {
194
237
  return `${prefix}${pluginId}`;
195
238
  }
196
239
  /** @internal */
197
- constructor(store, connectionString, errorHandler, logger, defaultTtl, storeOptions) {
240
+ constructor(store, connection, errorHandler, logger, defaultTtl, storeOptions) {
198
241
  if (!this.storeFactories.hasOwnProperty(store)) {
199
242
  throw new Error(`Unknown cache store: ${store}`);
200
243
  }
201
244
  this.logger = logger;
202
245
  this.store = store;
203
- this.connection = connectionString;
246
+ this.connection = connection;
204
247
  this.errorHandler = errorHandler;
205
248
  this.defaultTtl = defaultTtl;
206
249
  this.storeOptions = storeOptions;
@@ -225,8 +268,9 @@ class CacheManager {
225
268
  return this.storeFactories[this.store](pluginId, ttl);
226
269
  }
227
270
  createRedisStoreFactory() {
228
- const KeyvRedis = require("@keyv/redis").default;
229
- const { createCluster } = require("@keyv/redis");
271
+ const keyvRedis = require("@keyv/redis");
272
+ const KeyvRedis = keyvRedis.default;
273
+ const { createCluster } = keyvRedis;
230
274
  const stores = {};
231
275
  return (pluginId, defaultTtl) => {
232
276
  if (this.storeOptions?.type !== "redis") {
@@ -239,7 +283,7 @@ class CacheManager {
239
283
  keyPrefixSeparator: ":"
240
284
  };
241
285
  if (this.storeOptions?.cluster) {
242
- const cluster = createCluster(this.storeOptions?.cluster);
286
+ const cluster = createCluster(this.storeOptions.cluster);
243
287
  stores[pluginId] = new KeyvRedis(cluster, redisOptions);
244
288
  } else {
245
289
  stores[pluginId] = new KeyvRedis(this.connection, redisOptions);
@@ -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 {\n CacheManagerOptions,\n ttlToMilliseconds,\n CacheStoreOptions,\n RedisCacheStoreOptions,\n InfinispanClientBehaviorOptions,\n InfinispanServerConfig,\n ValkeyCacheStoreOptions,\n} from './types';\nimport { InfinispanOptionsMapper } from './providers/infinispan/InfinispanOptionsMapper';\nimport { durationToMilliseconds } from '@backstage/types';\nimport { ConfigReader, readDurationFromConfig } from '@backstage/config';\nimport {\n InfinispanClientCacheInterface,\n InfinispanKeyvStore,\n} from './providers/infinispan/InfinispanKeyvStore';\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 valkey: this.createValkeyStoreFactory(),\n memcache: this.createMemcacheStoreFactory(),\n memory: this.createMemoryStoreFactory(),\n infinispan: this.createInfinispanStoreFactory(),\n };\n\n private readonly logger?: LoggerService;\n private readonly store: keyof CacheManager['storeFactories'];\n private readonly connection: string;\n private readonly errorHandler: CacheManagerOptions['onError'];\n private readonly defaultTtl?: number;\n private readonly storeOptions?: CacheStoreOptions;\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 * @param options - Optional configuration for the CacheManager.\n * @returns A new CacheManager instance.\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 logger = options.logger?.child({\n type: 'cacheManager',\n });\n\n if (config.has('backend.cache.useRedisSets')) {\n logger?.warn(\n \"The 'backend.cache.useRedisSets' configuration key is deprecated and no longer has any effect. The underlying '@keyv/redis' and '@keyv/valkey' libraries no longer support redis sets.\",\n );\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 // Read store-specific options from config\n const storeOptions = CacheManager.parseStoreOptions(store, config, logger);\n\n return new CacheManager(\n store,\n connectionString,\n options.onError,\n logger,\n defaultTtl,\n storeOptions,\n );\n }\n\n /**\n * Parse store-specific options from configuration.\n *\n * @param store - The cache store type ('redis', 'valkey', 'memcache', 'infinispan', or 'memory')\n * @param config - The configuration service\n * @param logger - Optional logger for warnings\n * @returns The parsed store options\n */\n private static parseStoreOptions(\n store: string,\n config: RootConfigService,\n logger?: LoggerService,\n ): CacheStoreOptions | undefined {\n const storeConfigPath = `backend.cache.${store}`;\n\n if (store !== 'memory' && !config.has(storeConfigPath)) {\n logger?.warn(\n `No configuration found for cache store '${store}' at '${storeConfigPath}'.`,\n );\n }\n\n switch (store) {\n case 'redis':\n return CacheManager.parseRedisOptions(storeConfigPath, config, logger);\n case 'valkey':\n return CacheManager.parseValkeyOptions(storeConfigPath, config, logger);\n case 'infinispan':\n return InfinispanOptionsMapper.parseInfinispanOptions(\n storeConfigPath,\n config,\n logger,\n );\n default:\n return undefined;\n }\n }\n\n /**\n * Parse Redis-specific options from configuration.\n */\n private static parseRedisOptions(\n storeConfigPath: string,\n config: RootConfigService,\n logger?: LoggerService,\n ): RedisCacheStoreOptions {\n const redisOptions: RedisCacheStoreOptions = {\n type: 'redis',\n };\n\n const redisConfig =\n config.getOptionalConfig(storeConfigPath) ?? new ConfigReader({});\n\n redisOptions.client = {\n namespace: redisConfig.getOptionalString('client.namespace'),\n keyPrefixSeparator:\n redisConfig.getOptionalString('client.keyPrefixSeparator') || ':',\n clearBatchSize: redisConfig.getOptionalNumber('client.clearBatchSize'),\n useUnlink: redisConfig.getOptionalBoolean('client.useUnlink'),\n noNamespaceAffectsAll: redisConfig.getOptionalBoolean(\n 'client.noNamespaceAffectsAll',\n ),\n };\n\n if (redisConfig.has('cluster')) {\n const clusterConfig = redisConfig.getConfig('cluster');\n\n if (!clusterConfig.has('rootNodes')) {\n logger?.warn(\n `Redis cluster config has no 'rootNodes' key, defaulting to non-clustered mode`,\n );\n return redisOptions;\n }\n\n redisOptions.cluster = {\n rootNodes: clusterConfig.get('rootNodes'),\n defaults: clusterConfig.getOptional('defaults'),\n minimizeConnections: clusterConfig.getOptionalBoolean(\n 'minimizeConnections',\n ),\n useReplicas: clusterConfig.getOptionalBoolean('useReplicas'),\n maxCommandRedirections: clusterConfig.getOptionalNumber(\n 'maxCommandRedirections',\n ),\n };\n }\n\n return redisOptions;\n }\n\n /**\n * Parse Valkey-specific options from configuration.\n */\n private static parseValkeyOptions(\n storeConfigPath: string,\n config: RootConfigService,\n logger?: LoggerService,\n ): ValkeyCacheStoreOptions {\n const valkeyOptions: ValkeyCacheStoreOptions = {\n type: 'valkey',\n };\n\n const valkeyConfig =\n config.getOptionalConfig(storeConfigPath) ?? new ConfigReader({});\n\n valkeyOptions.client = {\n keyPrefix: valkeyConfig.getOptionalString('client.keyPrefix'),\n };\n\n if (valkeyConfig.has('cluster')) {\n const clusterConfig = valkeyConfig.getConfig('cluster');\n\n if (!clusterConfig.has('rootNodes')) {\n logger?.warn(\n `Valkey cluster config has no 'rootNodes' key, defaulting to non-clustered mode`,\n );\n return valkeyOptions;\n }\n\n valkeyOptions.cluster = {\n rootNodes: clusterConfig.get('rootNodes'),\n options: {\n redisOptions: clusterConfig.getOptional('defaults'),\n scaleReads: clusterConfig.getOptionalBoolean('useReplicas')\n ? 'slave'\n : undefined,\n maxRedirections: clusterConfig.getOptionalNumber(\n 'maxCommandRedirections',\n ),\n lazyConnect: clusterConfig.getOptionalBoolean('minimizeConnections'),\n },\n };\n }\n\n return valkeyOptions;\n }\n\n /**\n * Construct the full namespace based on the options and pluginId.\n *\n * @param pluginId - The plugin ID to namespace\n * @param storeOptions - Optional cache store configuration options\n * @returns The constructed namespace string combining the configured namespace with pluginId\n */\n private static constructNamespace(\n pluginId: string,\n storeOptions: RedisCacheStoreOptions | ValkeyCacheStoreOptions | undefined,\n ): string {\n let prefix: string;\n switch (storeOptions?.type) {\n case 'redis':\n prefix = storeOptions?.client?.namespace\n ? `${storeOptions.client.namespace}${\n storeOptions.client.keyPrefixSeparator ?? ':'\n }`\n : '';\n break;\n case 'valkey':\n prefix = storeOptions.client?.keyPrefix ?? '';\n break;\n default:\n prefix = '';\n }\n\n return `${prefix}${pluginId}`;\n }\n\n /** @internal */\n constructor(\n store: string,\n connectionString: string,\n errorHandler: CacheManagerOptions['onError'],\n logger?: LoggerService,\n defaultTtl?: number,\n storeOptions?: CacheStoreOptions,\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.errorHandler = errorHandler;\n this.defaultTtl = defaultTtl;\n this.storeOptions = storeOptions;\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').default;\n const { createCluster } = require('@keyv/redis');\n const stores: Record<string, typeof KeyvRedis> = {};\n\n return (pluginId, defaultTtl) => {\n if (this.storeOptions?.type !== 'redis') {\n throw new Error(\n `Internal error: Wrong config type passed to redis factory: ${this.storeOptions?.type}`,\n );\n }\n if (!stores[pluginId]) {\n const redisOptions = this.storeOptions?.client || {\n keyPrefixSeparator: ':',\n };\n if (this.storeOptions?.cluster) {\n // Create a Redis cluster\n const cluster = createCluster(this.storeOptions?.cluster);\n stores[pluginId] = new KeyvRedis(cluster, redisOptions);\n } else {\n // Create a regular Redis connection\n stores[pluginId] = new KeyvRedis(this.connection, redisOptions);\n }\n\n // Always provide an error handler to avoid stopping the process\n stores[pluginId].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: CacheManager.constructNamespace(pluginId, this.storeOptions),\n ttl: defaultTtl,\n store: stores[pluginId],\n emitErrors: false,\n useKeyPrefix: false,\n });\n };\n }\n\n private createValkeyStoreFactory(): StoreFactory {\n const KeyvValkey = require('@keyv/valkey').default;\n const { Cluster } = require('iovalkey');\n const stores: Record<string, typeof KeyvValkey> = {};\n\n return (pluginId, defaultTtl) => {\n if (this.storeOptions?.type !== 'valkey') {\n throw new Error(\n `Internal error: Wrong config type passed to valkey factory: ${this.storeOptions?.type}`,\n );\n }\n if (!stores[pluginId]) {\n const valkeyOptions = this.storeOptions?.client;\n if (this.storeOptions?.cluster) {\n // Create an iovalkey Cluster instance, which is the type that @keyv/valkey expects\n const cluster = new Cluster(\n this.storeOptions.cluster.rootNodes,\n this.storeOptions.cluster.options,\n );\n stores[pluginId] = new KeyvValkey(cluster, valkeyOptions);\n } else {\n // Create a regular Valkey connection\n stores[pluginId] = new KeyvValkey(this.connection, valkeyOptions);\n }\n\n // Always provide an error handler to avoid stopping the process\n stores[pluginId].on('error', (err: Error) => {\n this.logger?.error('Failed to create valkey cache client', err);\n this.errorHandler?.(err);\n });\n }\n return new Keyv({\n namespace: CacheManager.constructNamespace(pluginId, this.storeOptions),\n ttl: defaultTtl,\n store: stores[pluginId],\n emitErrors: false,\n useKeyPrefix: false,\n });\n };\n }\n\n private createMemcacheStoreFactory(): StoreFactory {\n const KeyvMemcache = require('@keyv/memcache').default;\n const stores: Record<string, typeof KeyvMemcache> = {};\n\n return (pluginId, defaultTtl) => {\n if (!stores[pluginId]) {\n stores[pluginId] = new KeyvMemcache(this.connection);\n // Always provide an error handler to avoid stopping the process\n stores[pluginId].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: stores[pluginId],\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 private createInfinispanStoreFactory(): StoreFactory {\n const stores: Record<string, InfinispanKeyvStore> = {};\n\n return (pluginId, defaultTtl) => {\n if (this.storeOptions?.type !== 'infinispan') {\n throw new Error(\n `Internal error: Wrong config type passed to infinispan factory: ${this.storeOptions?.type}`,\n );\n }\n\n if (!stores[pluginId]) {\n // Use sync version for testing environments\n const isTest =\n process.env.NODE_ENV === 'test' || typeof jest !== 'undefined';\n\n // Create the client promise ONCE and reuse it\n const clientPromise: Promise<InfinispanClientCacheInterface> = isTest\n ? this.createInfinispanClientSync()\n : this.createInfinispanClientAsync();\n\n this.logger?.info(\n `Creating Infinispan cache client for plugin ${pluginId} isTest = ${isTest}`,\n );\n const storeInstance = new InfinispanKeyvStore({\n clientPromise,\n logger: this.logger!,\n });\n\n stores[pluginId] = storeInstance;\n\n // Always provide an error handler to avoid stopping the process\n storeInstance.on('error', (err: Error) => {\n this.logger?.error('Failed to create infinispan cache client', err);\n this.errorHandler?.(err);\n });\n }\n\n return new Keyv({\n namespace: pluginId,\n ttl: defaultTtl,\n store: stores[pluginId],\n emitErrors: false,\n });\n };\n }\n\n /**\n * Creates an Infinispan client using dynamic import (production use).\n * @returns Promise that resolves to an Infinispan client\n */\n private async createInfinispanClientAsync(): Promise<InfinispanClientCacheInterface> {\n return this.createInfinispanClient(false);\n }\n\n /**\n * Creates an Infinispan client using synchronous import (testing purposes).\n * @returns Promise that resolves to an Infinispan client\n */\n private createInfinispanClientSync(): Promise<InfinispanClientCacheInterface> {\n return this.createInfinispanClient(true);\n }\n\n /**\n * Creates an Infinispan client based on the provided configuration.\n * @param useSync - Whether to use synchronous import (for testing) or dynamic import\n * @returns Promise that resolves to an Infinispan client\n */\n private async createInfinispanClient(\n useSync: boolean = false,\n ): Promise<InfinispanClientCacheInterface> {\n try {\n this.logger?.info('Creating Infinispan client');\n\n if (this.storeOptions?.type === 'infinispan') {\n // Import infinispan based on the useSync parameter\n const infinispan = useSync\n ? require('infinispan')\n : await import('infinispan');\n\n const client = await infinispan.client(\n this.storeOptions.servers as InfinispanServerConfig[],\n this.storeOptions.options as InfinispanClientBehaviorOptions,\n );\n\n this.logger?.info('Infinispan client created successfully');\n return client;\n }\n throw new Error('Infinispan store options are not defined');\n } catch (error: any) {\n this.logger?.error('Failed to create Infinispan client', {\n error: error.message,\n });\n throw error;\n }\n }\n}\n"],"names":["config","durationToMilliseconds","readDurationFromConfig","InfinispanOptionsMapper","ConfigReader","ttlToMilliseconds","DefaultCacheClient","Keyv","InfinispanKeyvStore"],"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 {\n CacheManagerOptions,\n ttlToMilliseconds,\n CacheStoreOptions,\n CacheStoreConnection,\n CacheStoreConnectionObject,\n CacheStoreConfiguration,\n CacheStoreDeps,\n RedisCacheStoreConfiguration,\n RedisCacheStoreOptions,\n InfinispanClientBehaviorOptions,\n InfinispanServerConfig,\n ValkeyCacheStoreOptions,\n} from './types';\nimport { InfinispanOptionsMapper } from './providers/infinispan/InfinispanOptionsMapper';\nimport { durationToMilliseconds } from '@backstage/types';\nimport { ConfigReader, readDurationFromConfig } from '@backstage/config';\nimport {\n InfinispanClientCacheInterface,\n InfinispanKeyvStore,\n} from './providers/infinispan/InfinispanKeyvStore';\nimport type { KeyvRedisOptions, RedisClusterOptions } from '@keyv/redis';\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 valkey: this.createValkeyStoreFactory(),\n memcache: this.createMemcacheStoreFactory(),\n memory: this.createMemoryStoreFactory(),\n infinispan: this.createInfinispanStoreFactory(),\n };\n\n private readonly logger?: LoggerService;\n private readonly store: keyof CacheManager['storeFactories'];\n private readonly connection: CacheStoreConnection;\n private readonly errorHandler: CacheManagerOptions['onError'];\n private readonly defaultTtl?: number;\n private readonly storeOptions?: CacheStoreOptions;\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 * @param options - Optional configuration for the CacheManager.\n * @returns A new CacheManager instance.\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 connection = CacheManager.parseConnection(config);\n const logger = options.logger?.child({\n type: 'cacheManager',\n });\n\n if (config.has('backend.cache.useRedisSets')) {\n logger?.warn(\n \"The 'backend.cache.useRedisSets' configuration key is deprecated and no longer has any effect. The underlying '@keyv/redis' and '@keyv/valkey' libraries no longer support redis sets.\",\n );\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 // Read store-specific options from config\n const storeOptions = CacheManager.parseStoreOptions(\n { store, connection },\n { config, logger },\n );\n\n return new CacheManager(\n store,\n connection,\n options.onError,\n logger,\n defaultTtl,\n storeOptions,\n );\n }\n\n /**\n * Parse the connection config, which can be either a plain URL string\n * or an object with connection options (e.g. `{ url, pingInterval }`)\n * passed through to the underlying store client.\n *\n * @param config - The configuration service\n * @returns The parsed connection config, either a string or an object depending on how it was configured\n */\n private static parseConnection(\n config: RootConfigService,\n ): CacheStoreConnection {\n const raw = config.getOptional('backend.cache.connection');\n const store = config.getOptionalString('backend.cache.store') || 'memory';\n\n if (raw && typeof raw === 'object' && !Array.isArray(raw)) {\n if (store !== 'redis') {\n throw new Error(\n \"backend.cache.connection object form is only supported when backend.cache.store is 'redis'\",\n );\n }\n\n const url = (raw as { url?: unknown }).url;\n if (typeof url !== 'string' || url.length === 0) {\n throw new Error(\n \"backend.cache.connection object must include a non-empty 'url' string\",\n );\n }\n\n return raw as CacheStoreConnectionObject;\n }\n\n if (raw !== undefined && typeof raw !== 'string') {\n throw new Error(\n `backend.cache.connection must be a string or object, got ${typeof raw}`,\n );\n }\n\n return config.getOptionalString('backend.cache.connection') ?? '';\n }\n\n /**\n * Parse store-specific options from configuration.\n *\n * @param store - The cache store type ('redis', 'valkey', 'memcache', 'infinispan', or 'memory')\n * @param config - The configuration service\n * @param logger - Optional logger for warnings\n * @returns The parsed store options\n */\n private static parseStoreOptions(\n config: { store: string; connection: CacheStoreConnection },\n deps: CacheStoreDeps,\n ): CacheStoreOptions | undefined {\n const { store, connection } = config;\n const storeConfigPath = `backend.cache.${store}`;\n\n if (store !== 'memory' && !deps.config.has(storeConfigPath)) {\n deps.logger?.warn(\n `No configuration found for cache store '${store}' at '${storeConfigPath}'.`,\n );\n }\n\n switch (store) {\n case 'redis':\n return CacheManager.parseRedisOptions(\n { storeConfigPath, connection },\n deps,\n );\n case 'valkey':\n return CacheManager.parseValkeyOptions({ storeConfigPath }, deps);\n case 'infinispan':\n return InfinispanOptionsMapper.parseInfinispanOptions(\n { storeConfigPath },\n deps,\n );\n default:\n return undefined;\n }\n }\n\n /**\n * Parse Redis-specific options from configuration.\n */\n private static parseRedisOptions(\n config: RedisCacheStoreConfiguration,\n deps: CacheStoreDeps,\n ): RedisCacheStoreOptions {\n const redisOptions: RedisCacheStoreOptions = {\n type: 'redis',\n };\n\n const redisConfig =\n deps.config.getOptionalConfig(config.storeConfigPath) ??\n new ConfigReader({});\n\n redisOptions.client = {\n namespace: redisConfig.getOptionalString('client.namespace'),\n keyPrefixSeparator:\n redisConfig.getOptionalString('client.keyPrefixSeparator') || ':',\n clearBatchSize: redisConfig.getOptionalNumber('client.clearBatchSize'),\n useUnlink: redisConfig.getOptionalBoolean('client.useUnlink'),\n noNamespaceAffectsAll: redisConfig.getOptionalBoolean(\n 'client.noNamespaceAffectsAll',\n ),\n };\n\n if (redisConfig.has('cluster')) {\n const clusterConfig = redisConfig.getConfig('cluster');\n\n if (!clusterConfig.has('rootNodes')) {\n deps.logger?.warn(\n `Redis cluster config has no 'rootNodes' key, defaulting to non-clustered mode`,\n );\n return redisOptions;\n }\n\n // When connection is an object, merge its properties into cluster\n // defaults so every node inherits those options (e.g. pingInterval).\n let defaults: RedisClusterOptions['defaults'] =\n clusterConfig.getOptional('defaults');\n\n if (typeof config.connection === 'object') {\n const { url: _url, ...connectionDefaults } = config.connection;\n defaults = { ...defaults, ...connectionDefaults };\n }\n\n redisOptions.cluster = {\n rootNodes: clusterConfig.get('rootNodes'),\n defaults,\n minimizeConnections: clusterConfig.getOptionalBoolean(\n 'minimizeConnections',\n ),\n useReplicas: clusterConfig.getOptionalBoolean('useReplicas'),\n maxCommandRedirections: clusterConfig.getOptionalNumber(\n 'maxCommandRedirections',\n ),\n };\n }\n\n return redisOptions;\n }\n\n /**\n * Parse Valkey-specific options from configuration.\n */\n private static parseValkeyOptions(\n config: CacheStoreConfiguration,\n deps: CacheStoreDeps,\n ): ValkeyCacheStoreOptions {\n const valkeyOptions: ValkeyCacheStoreOptions = {\n type: 'valkey',\n };\n\n const valkeyConfig =\n deps.config.getOptionalConfig(config.storeConfigPath) ??\n new ConfigReader({});\n\n valkeyOptions.client = {\n keyPrefix: valkeyConfig.getOptionalString('client.keyPrefix'),\n };\n\n if (valkeyConfig.has('cluster')) {\n const clusterConfig = valkeyConfig.getConfig('cluster');\n\n if (!clusterConfig.has('rootNodes')) {\n deps.logger?.warn(\n `Valkey cluster config has no 'rootNodes' key, defaulting to non-clustered mode`,\n );\n return valkeyOptions;\n }\n\n valkeyOptions.cluster = {\n rootNodes: clusterConfig.get('rootNodes'),\n options: {\n redisOptions: clusterConfig.getOptional('defaults'),\n scaleReads: clusterConfig.getOptionalBoolean('useReplicas')\n ? 'slave'\n : undefined,\n maxRedirections: clusterConfig.getOptionalNumber(\n 'maxCommandRedirections',\n ),\n lazyConnect: clusterConfig.getOptionalBoolean('minimizeConnections'),\n },\n };\n }\n\n return valkeyOptions;\n }\n\n /**\n * Construct the full namespace based on the options and pluginId.\n *\n * @param pluginId - The plugin ID to namespace\n * @param storeOptions - Optional cache store configuration options\n * @returns The constructed namespace string combining the configured namespace with pluginId\n */\n private static constructNamespace(\n pluginId: string,\n storeOptions: RedisCacheStoreOptions | ValkeyCacheStoreOptions | undefined,\n ): string {\n let prefix: string;\n switch (storeOptions?.type) {\n case 'redis':\n prefix = storeOptions?.client?.namespace\n ? `${storeOptions.client.namespace}${\n storeOptions.client.keyPrefixSeparator ?? ':'\n }`\n : '';\n break;\n case 'valkey':\n prefix = storeOptions.client?.keyPrefix ?? '';\n break;\n default:\n prefix = '';\n }\n\n return `${prefix}${pluginId}`;\n }\n\n /** @internal */\n constructor(\n store: string,\n connection: CacheStoreConnection,\n errorHandler: CacheManagerOptions['onError'],\n logger?: LoggerService,\n defaultTtl?: number,\n storeOptions?: CacheStoreOptions,\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 = connection;\n this.errorHandler = errorHandler;\n this.defaultTtl = defaultTtl;\n this.storeOptions = storeOptions;\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') as typeof import('@keyv/redis');\n const KeyvRedis = keyvRedis.default;\n const { createCluster } = keyvRedis;\n const stores: Record<string, InstanceType<typeof KeyvRedis>> = {};\n\n return (pluginId, defaultTtl) => {\n if (this.storeOptions?.type !== 'redis') {\n throw new Error(\n `Internal error: Wrong config type passed to redis factory: ${this.storeOptions?.type}`,\n );\n }\n if (!stores[pluginId]) {\n const redisOptions: KeyvRedisOptions = this.storeOptions?.client || {\n keyPrefixSeparator: ':',\n };\n if (this.storeOptions?.cluster) {\n // Create a Redis cluster\n const cluster = createCluster(this.storeOptions.cluster);\n stores[pluginId] = new KeyvRedis(cluster, redisOptions);\n } else {\n // Create a regular Redis connection\n stores[pluginId] = new KeyvRedis(this.connection, redisOptions);\n }\n\n // Always provide an error handler to avoid stopping the process\n stores[pluginId].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: CacheManager.constructNamespace(pluginId, this.storeOptions),\n ttl: defaultTtl,\n store: stores[pluginId],\n emitErrors: false,\n useKeyPrefix: false,\n });\n };\n }\n\n private createValkeyStoreFactory(): StoreFactory {\n const KeyvValkey = require('@keyv/valkey').default;\n const { Cluster } = require('iovalkey');\n const stores: Record<string, typeof KeyvValkey> = {};\n\n return (pluginId, defaultTtl) => {\n if (this.storeOptions?.type !== 'valkey') {\n throw new Error(\n `Internal error: Wrong config type passed to valkey factory: ${this.storeOptions?.type}`,\n );\n }\n if (!stores[pluginId]) {\n const valkeyOptions = this.storeOptions?.client;\n if (this.storeOptions?.cluster) {\n // Create an iovalkey Cluster instance, which is the type that @keyv/valkey expects\n const cluster = new Cluster(\n this.storeOptions.cluster.rootNodes,\n this.storeOptions.cluster.options,\n );\n stores[pluginId] = new KeyvValkey(cluster, valkeyOptions);\n } else {\n // Create a regular Valkey connection\n stores[pluginId] = new KeyvValkey(this.connection, valkeyOptions);\n }\n\n // Always provide an error handler to avoid stopping the process\n stores[pluginId].on('error', (err: Error) => {\n this.logger?.error('Failed to create valkey cache client', err);\n this.errorHandler?.(err);\n });\n }\n return new Keyv({\n namespace: CacheManager.constructNamespace(pluginId, this.storeOptions),\n ttl: defaultTtl,\n store: stores[pluginId],\n emitErrors: false,\n useKeyPrefix: false,\n });\n };\n }\n\n private createMemcacheStoreFactory(): StoreFactory {\n const KeyvMemcache = require('@keyv/memcache').default;\n const stores: Record<string, typeof KeyvMemcache> = {};\n\n return (pluginId, defaultTtl) => {\n if (!stores[pluginId]) {\n stores[pluginId] = new KeyvMemcache(this.connection);\n // Always provide an error handler to avoid stopping the process\n stores[pluginId].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: stores[pluginId],\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 private createInfinispanStoreFactory(): StoreFactory {\n const stores: Record<string, InfinispanKeyvStore> = {};\n\n return (pluginId, defaultTtl) => {\n if (this.storeOptions?.type !== 'infinispan') {\n throw new Error(\n `Internal error: Wrong config type passed to infinispan factory: ${this.storeOptions?.type}`,\n );\n }\n\n if (!stores[pluginId]) {\n // Use sync version for testing environments\n const isTest =\n process.env.NODE_ENV === 'test' || typeof jest !== 'undefined';\n\n // Create the client promise ONCE and reuse it\n const clientPromise: Promise<InfinispanClientCacheInterface> = isTest\n ? this.createInfinispanClientSync()\n : this.createInfinispanClientAsync();\n\n this.logger?.info(\n `Creating Infinispan cache client for plugin ${pluginId} isTest = ${isTest}`,\n );\n const storeInstance = new InfinispanKeyvStore({\n clientPromise,\n logger: this.logger!,\n });\n\n stores[pluginId] = storeInstance;\n\n // Always provide an error handler to avoid stopping the process\n storeInstance.on('error', (err: Error) => {\n this.logger?.error('Failed to create infinispan cache client', err);\n this.errorHandler?.(err);\n });\n }\n\n return new Keyv({\n namespace: pluginId,\n ttl: defaultTtl,\n store: stores[pluginId],\n emitErrors: false,\n });\n };\n }\n\n /**\n * Creates an Infinispan client using dynamic import (production use).\n * @returns Promise that resolves to an Infinispan client\n */\n private async createInfinispanClientAsync(): Promise<InfinispanClientCacheInterface> {\n return this.createInfinispanClient(false);\n }\n\n /**\n * Creates an Infinispan client using synchronous import (testing purposes).\n * @returns Promise that resolves to an Infinispan client\n */\n private createInfinispanClientSync(): Promise<InfinispanClientCacheInterface> {\n return this.createInfinispanClient(true);\n }\n\n /**\n * Creates an Infinispan client based on the provided configuration.\n * @param useSync - Whether to use synchronous import (for testing) or dynamic import\n * @returns Promise that resolves to an Infinispan client\n */\n private async createInfinispanClient(\n useSync: boolean = false,\n ): Promise<InfinispanClientCacheInterface> {\n try {\n this.logger?.info('Creating Infinispan client');\n\n if (this.storeOptions?.type === 'infinispan') {\n // Import infinispan based on the useSync parameter\n const infinispan = useSync\n ? require('infinispan')\n : await import('infinispan');\n\n const client = await infinispan.client(\n this.storeOptions.servers as InfinispanServerConfig[],\n this.storeOptions.options as InfinispanClientBehaviorOptions,\n );\n\n this.logger?.info('Infinispan client created successfully');\n return client;\n }\n throw new Error('Infinispan store options are not defined');\n } catch (error: any) {\n this.logger?.error('Failed to create Infinispan client', {\n error: error.message,\n });\n throw error;\n }\n }\n}\n"],"names":["config","durationToMilliseconds","readDurationFromConfig","InfinispanOptionsMapper","ConfigReader","ttlToMilliseconds","DefaultCacheClient","Keyv","InfinispanKeyvStore"],"mappings":"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"}
@@ -4,13 +4,12 @@ class InfinispanOptionsMapper {
4
4
  /**
5
5
  * Parses Infinispan options from the provided configuration path.
6
6
  *
7
- * @param storeConfigPath - The configuration path for the Infinispan store.
8
- * @param config - The root configuration service to retrieve the Infinispan configuration.
9
- * @param logger - An optional logger service for logging errors and warnings.
7
+ * @param config - The store configuration.
8
+ * @param deps - Service dependencies.
10
9
  * @returns Parsed Infinispan cache store options.
11
10
  */
12
- static parseInfinispanOptions(storeConfigPath, config, logger) {
13
- const infinispanConfig = config.getConfig(storeConfigPath);
11
+ static parseInfinispanOptions(config, deps) {
12
+ const infinispanConfig = deps.config.getConfig(config.storeConfigPath);
14
13
  const parsedOptions = {
15
14
  type: "infinispan"
16
15
  };
@@ -31,12 +30,12 @@ class InfinispanOptionsMapper {
31
30
  };
32
31
  } else {
33
32
  throw new Error(
34
- `Infinispan 'servers' configuration at ${storeConfigPath} is invalid, must be an object or an array.`
33
+ `Infinispan 'servers' configuration at ${config.storeConfigPath} is invalid, must be an object or an array.`
35
34
  );
36
35
  }
37
36
  } else {
38
- logger?.warn(
39
- `Infinispan configuration at ${storeConfigPath} is missing the 'servers' definition, will use client defaults.`
37
+ deps.logger?.warn(
38
+ `Infinispan configuration at ${config.storeConfigPath} is missing the 'servers' definition, will use client defaults.`
40
39
  );
41
40
  }
42
41
  const behaviorOptions = {};
@@ -54,8 +53,8 @@ class InfinispanOptionsMapper {
54
53
  if (clientVersion === "2.9" || clientVersion === "2.5" || clientVersion === "2.2") {
55
54
  behaviorOptions.version = clientVersion;
56
55
  } else if (clientVersion !== null && clientVersion !== void 0) {
57
- logger?.warn(
58
- `Invalid Infinispan client version "${clientVersion}" in config at ${storeConfigPath}.version. Must be "2.9", "2.5", or "2.2". It will be ignored, and the client may use a default or fail.`
56
+ deps.logger?.warn(
57
+ `Invalid Infinispan client version "${clientVersion}" in config at ${config.storeConfigPath}.version. Must be "2.9", "2.5", or "2.2". It will be ignored, and the client may use a default or fail.`
59
58
  );
60
59
  }
61
60
  behaviorOptions.cacheName = infinispanConfig.getOptionalString("cacheName") ?? "cache";
@@ -63,8 +62,8 @@ class InfinispanOptionsMapper {
63
62
  if (mediaType === "text/plain" || mediaType === "application/json") {
64
63
  behaviorOptions.mediaType = mediaType;
65
64
  } else if (mediaType !== null && mediaType !== void 0) {
66
- logger?.warn(
67
- `Invalid Infinispan mediaType "${mediaType}" in config at ${storeConfigPath}.mediaType. Must be "text/plain" | "application/json". It will be ignored, and the client may use a default or fail.`
65
+ deps.logger?.warn(
66
+ `Invalid Infinispan mediaType "${mediaType}" in config at ${config.storeConfigPath}.mediaType. Must be "text/plain" | "application/json". It will be ignored, and the client may use a default or fail.`
68
67
  );
69
68
  }
70
69
  behaviorOptions.maxRetries = infinispanConfig.getOptionalNumber("maxRetries");
@@ -103,23 +102,21 @@ class InfinispanOptionsMapper {
103
102
  if (keyType === "text/plain" || keyType === "application/json") {
104
103
  dataFormatOpts.keyType = keyType;
105
104
  } else if (keyType !== null && keyType !== void 0) {
106
- logger?.warn(
107
- `Invalid Infinispan dataFormat.keyType "${keyType}" in config at ${storeConfigPath}.dataFormat.keyType. Must be "text/plain" | "application/json". Not mapped, client will use default 'text/plain'.`
105
+ deps.logger?.warn(
106
+ `Invalid Infinispan dataFormat.keyType "${keyType}" in config at ${config.storeConfigPath}.dataFormat.keyType. Must be "text/plain" | "application/json". Not mapped, client will use default 'text/plain'.`
108
107
  );
109
108
  }
110
109
  if (valueType === "text/plain" || valueType === "application/json") {
111
110
  dataFormatOpts.valueType = valueType;
112
111
  } else if (valueType !== null && valueType !== void 0) {
113
- logger?.warn(
114
- `Invalid Infinispan dataFormat.valueType "${valueType}" in config at ${storeConfigPath}.dataFormat.valueType. Must be "text/plain" | "application/json". Not mapped, client will use default 'text/plain'.`
112
+ deps.logger?.warn(
113
+ `Invalid Infinispan dataFormat.valueType "${valueType}" in config at ${config.storeConfigPath}.dataFormat.valueType. Must be "text/plain" | "application/json". Not mapped, client will use default 'text/plain'.`
115
114
  );
116
115
  }
117
116
  behaviorOptions.dataFormat = dataFormatOpts;
118
117
  parsedOptions.options = behaviorOptions;
119
- logger?.debug(
120
- `Parsed Infinispan options from config at ${storeConfigPath}: ${JSON.stringify(
121
- parsedOptions
122
- )}`
118
+ deps.logger?.debug(
119
+ `Parsed Infinispan options from config at ${config.storeConfigPath}: ${JSON.stringify(parsedOptions)}`
123
120
  );
124
121
  return parsedOptions;
125
122
  }
@@ -1 +1 @@
1
- {"version":3,"file":"InfinispanOptionsMapper.cjs.js","sources":["../../../../../src/entrypoints/cache/providers/infinispan/InfinispanOptionsMapper.ts"],"sourcesContent":["/*\n * Copyright 2025 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 LoggerService,\n RootConfigService,\n} from '@backstage/backend-plugin-api';\nimport {\n DataFormatOptions,\n InfinispanAuthOptions,\n InfinispanCacheStoreOptions,\n InfinispanClientAuthOptions,\n InfinispanClientBehaviorOptions,\n InfinispanClusterConfig,\n InfinispanServerConfig,\n InfinispanSslOptions,\n} from '../../types';\n\nexport class InfinispanOptionsMapper {\n /**\n * Parses Infinispan options from the provided configuration path.\n *\n * @param storeConfigPath - The configuration path for the Infinispan store.\n * @param config - The root configuration service to retrieve the Infinispan configuration.\n * @param logger - An optional logger service for logging errors and warnings.\n * @returns Parsed Infinispan cache store options.\n */\n public static parseInfinispanOptions(\n storeConfigPath: string,\n config: RootConfigService,\n logger?: LoggerService,\n ): InfinispanCacheStoreOptions {\n const infinispanConfig = config.getConfig(storeConfigPath);\n const parsedOptions: Partial<InfinispanCacheStoreOptions> = {\n type: 'infinispan',\n };\n\n // Parse Servers & Clusters Configurations\n if (infinispanConfig.has('servers')) {\n const serversConfig = infinispanConfig.get('servers');\n if (Array.isArray(serversConfig)) {\n parsedOptions.servers = infinispanConfig.getConfigArray('servers').map(\n serverConf =>\n ({\n host: serverConf.getString('host'),\n port: serverConf.getOptionalNumber('port') ?? 11222,\n } as InfinispanServerConfig),\n );\n } else if (typeof serversConfig === 'object' && serversConfig !== null) {\n const serverConf = infinispanConfig.getConfig('servers');\n parsedOptions.servers = {\n host: serverConf.getOptionalString('host') ?? '127.0.0.1',\n port: serverConf.getOptionalString('port') ?? 11222,\n } as InfinispanServerConfig;\n } else {\n throw new Error(\n `Infinispan 'servers' configuration at ${storeConfigPath} is invalid, must be an object or an array.`,\n );\n }\n } else {\n logger?.warn(\n `Infinispan configuration at ${storeConfigPath} is missing the 'servers' definition, will use client defaults.`,\n );\n }\n\n // The parsed options block to send to the Infinispan client\n // This will be used to configure the Infinispan client behavior.\n const behaviorOptions: Partial<InfinispanClientBehaviorOptions> = {};\n\n behaviorOptions.clusters = infinispanConfig\n .getOptionalConfigArray('clusters')\n ?.map(clusterConf => {\n const name = clusterConf.getOptionalString('name');\n return {\n ...(name && { name }),\n servers: clusterConf.getConfigArray('servers').map(serverConf => ({\n host: serverConf.getString('host'),\n port: serverConf.getOptionalNumber('port') ?? 11222,\n })),\n } as InfinispanClusterConfig;\n });\n\n // Parse Default Options Start...\n const clientVersion =\n infinispanConfig.getOptionalString('version') ?? '2.9';\n if (\n clientVersion === '2.9' ||\n clientVersion === '2.5' ||\n clientVersion === '2.2'\n ) {\n behaviorOptions.version = clientVersion;\n } else if (clientVersion !== null && clientVersion !== undefined) {\n logger?.warn(\n `Invalid Infinispan client version \"${clientVersion}\" in config at ${storeConfigPath}.version. Must be \"2.9\", \"2.5\", or \"2.2\". It will be ignored, and the client may use a default or fail.`,\n );\n }\n\n behaviorOptions.cacheName =\n infinispanConfig.getOptionalString('cacheName') ?? 'cache';\n\n const mediaType = infinispanConfig.getOptionalString('mediaType');\n if (mediaType === 'text/plain' || mediaType === 'application/json') {\n behaviorOptions.mediaType = mediaType;\n } else if (mediaType !== null && mediaType !== undefined) {\n logger?.warn(\n `Invalid Infinispan mediaType \"${mediaType}\" in config at ${storeConfigPath}.mediaType. Must be \"text/plain\" | \"application/json\". It will be ignored, and the client may use a default or fail.`,\n );\n }\n\n behaviorOptions.maxRetries =\n infinispanConfig.getOptionalNumber('maxRetries');\n\n behaviorOptions.topologyUpdates =\n infinispanConfig.getOptionalBoolean('topologyUpdates') ?? true;\n\n // Default Options End...\n\n // Parse Authentication and SSL Options\n const authConfig = infinispanConfig.getOptionalConfig('authentication');\n const auth: Partial<InfinispanAuthOptions> = {};\n\n auth.enabled = authConfig?.getOptionalBoolean('enabled');\n auth.saslMechanism = authConfig?.getOptionalString('saslMechanism');\n auth.userName = authConfig?.getOptionalString('userName');\n auth.password = authConfig?.getOptionalString('password');\n auth.token = authConfig?.getOptionalString('token');\n auth.authzid = authConfig?.getOptionalString('authzid');\n\n behaviorOptions.authentication = auth as InfinispanAuthOptions;\n\n const sslConfig = infinispanConfig.getOptionalConfig('ssl');\n const ssl: Partial<InfinispanSslOptions> = {};\n\n ssl.enabled = sslConfig?.getOptionalBoolean('enabled');\n ssl.secureProtocol = sslConfig?.getOptionalString('secureProtocol');\n ssl.trustCerts = sslConfig?.getOptionalStringArray('trustCerts');\n ssl.sniHostName = sslConfig?.getOptionalString('sniHostname');\n\n const clientAuth = infinispanConfig.getOptionalConfig('clientAuth');\n const clientAuthOpts: Partial<InfinispanClientAuthOptions> = {};\n\n clientAuthOpts.key = clientAuth?.getOptionalString('key');\n clientAuthOpts.passphrase = clientAuth?.getOptionalString('passphrase');\n clientAuthOpts.cert = clientAuth?.getOptionalString('cert');\n\n ssl.clientAuth = clientAuthOpts as InfinispanClientAuthOptions;\n\n const cryptoStore = infinispanConfig.getOptionalConfig('cryptoStore');\n const cryptoStoreOpts: Partial<InfinispanClientAuthOptions> = {};\n\n cryptoStoreOpts.key = cryptoStore?.getOptionalString('path');\n cryptoStoreOpts.passphrase = cryptoStore?.getOptionalString('passphrase');\n\n ssl.cryptoStore = cryptoStoreOpts as InfinispanClientAuthOptions;\n\n behaviorOptions.ssl = ssl as InfinispanSslOptions;\n\n const dataFormat = infinispanConfig.getOptionalConfig('dataFormat');\n const dataFormatOpts: Partial<DataFormatOptions> = {};\n\n const keyType = dataFormat?.getOptionalString('keyType') ?? 'text/plain';\n const valueType =\n dataFormat?.getOptionalString('valueType') ?? 'text/plain';\n\n if (keyType === 'text/plain' || keyType === 'application/json') {\n dataFormatOpts.keyType = keyType;\n } else if (keyType !== null && keyType !== undefined) {\n logger?.warn(\n `Invalid Infinispan dataFormat.keyType \"${keyType}\" in config at ${storeConfigPath}.dataFormat.keyType. Must be \"text/plain\" | \"application/json\". Not mapped, client will use default 'text/plain'.`,\n );\n }\n\n if (valueType === 'text/plain' || valueType === 'application/json') {\n dataFormatOpts.valueType = valueType;\n } else if (valueType !== null && valueType !== undefined) {\n logger?.warn(\n `Invalid Infinispan dataFormat.valueType \"${valueType}\" in config at ${storeConfigPath}.dataFormat.valueType. Must be \"text/plain\" | \"application/json\". Not mapped, client will use default 'text/plain'.`,\n );\n }\n behaviorOptions.dataFormat = dataFormatOpts as DataFormatOptions;\n parsedOptions.options = behaviorOptions as InfinispanClientBehaviorOptions;\n\n logger?.debug(\n `Parsed Infinispan options from config at ${storeConfigPath}: ${JSON.stringify(\n parsedOptions,\n )}`,\n );\n return parsedOptions as InfinispanCacheStoreOptions;\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"InfinispanOptionsMapper.cjs.js","sources":["../../../../../src/entrypoints/cache/providers/infinispan/InfinispanOptionsMapper.ts"],"sourcesContent":["/*\n * Copyright 2025 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 CacheStoreConfiguration,\n CacheStoreDeps,\n DataFormatOptions,\n InfinispanAuthOptions,\n InfinispanCacheStoreOptions,\n InfinispanClientAuthOptions,\n InfinispanClientBehaviorOptions,\n InfinispanClusterConfig,\n InfinispanServerConfig,\n InfinispanSslOptions,\n} from '../../types';\n\nexport class InfinispanOptionsMapper {\n /**\n * Parses Infinispan options from the provided configuration path.\n *\n * @param config - The store configuration.\n * @param deps - Service dependencies.\n * @returns Parsed Infinispan cache store options.\n */\n public static parseInfinispanOptions(\n config: CacheStoreConfiguration,\n deps: CacheStoreDeps,\n ): InfinispanCacheStoreOptions {\n const infinispanConfig = deps.config.getConfig(config.storeConfigPath);\n const parsedOptions: Partial<InfinispanCacheStoreOptions> = {\n type: 'infinispan',\n };\n\n // Parse Servers & Clusters Configurations\n if (infinispanConfig.has('servers')) {\n const serversConfig = infinispanConfig.get('servers');\n if (Array.isArray(serversConfig)) {\n parsedOptions.servers = infinispanConfig.getConfigArray('servers').map(\n serverConf =>\n ({\n host: serverConf.getString('host'),\n port: serverConf.getOptionalNumber('port') ?? 11222,\n } as InfinispanServerConfig),\n );\n } else if (typeof serversConfig === 'object' && serversConfig !== null) {\n const serverConf = infinispanConfig.getConfig('servers');\n parsedOptions.servers = {\n host: serverConf.getOptionalString('host') ?? '127.0.0.1',\n port: serverConf.getOptionalString('port') ?? 11222,\n } as InfinispanServerConfig;\n } else {\n throw new Error(\n `Infinispan 'servers' configuration at ${config.storeConfigPath} is invalid, must be an object or an array.`,\n );\n }\n } else {\n deps.logger?.warn(\n `Infinispan configuration at ${config.storeConfigPath} is missing the 'servers' definition, will use client defaults.`,\n );\n }\n\n // The parsed options block to send to the Infinispan client\n // This will be used to configure the Infinispan client behavior.\n const behaviorOptions: Partial<InfinispanClientBehaviorOptions> = {};\n\n behaviorOptions.clusters = infinispanConfig\n .getOptionalConfigArray('clusters')\n ?.map(clusterConf => {\n const name = clusterConf.getOptionalString('name');\n return {\n ...(name && { name }),\n servers: clusterConf.getConfigArray('servers').map(serverConf => ({\n host: serverConf.getString('host'),\n port: serverConf.getOptionalNumber('port') ?? 11222,\n })),\n } as InfinispanClusterConfig;\n });\n\n // Parse Default Options Start...\n const clientVersion =\n infinispanConfig.getOptionalString('version') ?? '2.9';\n if (\n clientVersion === '2.9' ||\n clientVersion === '2.5' ||\n clientVersion === '2.2'\n ) {\n behaviorOptions.version = clientVersion;\n } else if (clientVersion !== null && clientVersion !== undefined) {\n deps.logger?.warn(\n `Invalid Infinispan client version \"${clientVersion}\" in config at ${config.storeConfigPath}.version. Must be \"2.9\", \"2.5\", or \"2.2\". It will be ignored, and the client may use a default or fail.`,\n );\n }\n\n behaviorOptions.cacheName =\n infinispanConfig.getOptionalString('cacheName') ?? 'cache';\n\n const mediaType = infinispanConfig.getOptionalString('mediaType');\n if (mediaType === 'text/plain' || mediaType === 'application/json') {\n behaviorOptions.mediaType = mediaType;\n } else if (mediaType !== null && mediaType !== undefined) {\n deps.logger?.warn(\n `Invalid Infinispan mediaType \"${mediaType}\" in config at ${config.storeConfigPath}.mediaType. Must be \"text/plain\" | \"application/json\". It will be ignored, and the client may use a default or fail.`,\n );\n }\n\n behaviorOptions.maxRetries =\n infinispanConfig.getOptionalNumber('maxRetries');\n\n behaviorOptions.topologyUpdates =\n infinispanConfig.getOptionalBoolean('topologyUpdates') ?? true;\n\n // Default Options End...\n\n // Parse Authentication and SSL Options\n const authConfig = infinispanConfig.getOptionalConfig('authentication');\n const auth: Partial<InfinispanAuthOptions> = {};\n\n auth.enabled = authConfig?.getOptionalBoolean('enabled');\n auth.saslMechanism = authConfig?.getOptionalString('saslMechanism');\n auth.userName = authConfig?.getOptionalString('userName');\n auth.password = authConfig?.getOptionalString('password');\n auth.token = authConfig?.getOptionalString('token');\n auth.authzid = authConfig?.getOptionalString('authzid');\n\n behaviorOptions.authentication = auth as InfinispanAuthOptions;\n\n const sslConfig = infinispanConfig.getOptionalConfig('ssl');\n const ssl: Partial<InfinispanSslOptions> = {};\n\n ssl.enabled = sslConfig?.getOptionalBoolean('enabled');\n ssl.secureProtocol = sslConfig?.getOptionalString('secureProtocol');\n ssl.trustCerts = sslConfig?.getOptionalStringArray('trustCerts');\n ssl.sniHostName = sslConfig?.getOptionalString('sniHostname');\n\n const clientAuth = infinispanConfig.getOptionalConfig('clientAuth');\n const clientAuthOpts: Partial<InfinispanClientAuthOptions> = {};\n\n clientAuthOpts.key = clientAuth?.getOptionalString('key');\n clientAuthOpts.passphrase = clientAuth?.getOptionalString('passphrase');\n clientAuthOpts.cert = clientAuth?.getOptionalString('cert');\n\n ssl.clientAuth = clientAuthOpts as InfinispanClientAuthOptions;\n\n const cryptoStore = infinispanConfig.getOptionalConfig('cryptoStore');\n const cryptoStoreOpts: Partial<InfinispanClientAuthOptions> = {};\n\n cryptoStoreOpts.key = cryptoStore?.getOptionalString('path');\n cryptoStoreOpts.passphrase = cryptoStore?.getOptionalString('passphrase');\n\n ssl.cryptoStore = cryptoStoreOpts as InfinispanClientAuthOptions;\n\n behaviorOptions.ssl = ssl as InfinispanSslOptions;\n\n const dataFormat = infinispanConfig.getOptionalConfig('dataFormat');\n const dataFormatOpts: Partial<DataFormatOptions> = {};\n\n const keyType = dataFormat?.getOptionalString('keyType') ?? 'text/plain';\n const valueType =\n dataFormat?.getOptionalString('valueType') ?? 'text/plain';\n\n if (keyType === 'text/plain' || keyType === 'application/json') {\n dataFormatOpts.keyType = keyType;\n } else if (keyType !== null && keyType !== undefined) {\n deps.logger?.warn(\n `Invalid Infinispan dataFormat.keyType \"${keyType}\" in config at ${config.storeConfigPath}.dataFormat.keyType. Must be \"text/plain\" | \"application/json\". Not mapped, client will use default 'text/plain'.`,\n );\n }\n\n if (valueType === 'text/plain' || valueType === 'application/json') {\n dataFormatOpts.valueType = valueType;\n } else if (valueType !== null && valueType !== undefined) {\n deps.logger?.warn(\n `Invalid Infinispan dataFormat.valueType \"${valueType}\" in config at ${config.storeConfigPath}.dataFormat.valueType. Must be \"text/plain\" | \"application/json\". Not mapped, client will use default 'text/plain'.`,\n );\n }\n behaviorOptions.dataFormat = dataFormatOpts as DataFormatOptions;\n parsedOptions.options = behaviorOptions as InfinispanClientBehaviorOptions;\n\n deps.logger?.debug(\n `Parsed Infinispan options from config at ${\n config.storeConfigPath\n }: ${JSON.stringify(parsedOptions)}`,\n );\n return parsedOptions as InfinispanCacheStoreOptions;\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.cjs.js","sources":["../../../src/entrypoints/cache/types.ts"],"sourcesContent":["/*\n * Copyright 2020 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 { LoggerService } from '@backstage/backend-plugin-api';\nimport { HumanDuration, durationToMilliseconds } from '@backstage/types';\nimport { RedisClusterOptions, KeyvRedisOptions } from '@keyv/redis';\nimport { KeyvValkeyOptions } from '@keyv/valkey';\nimport { ClusterNode, ClusterOptions } from 'iovalkey';\n\n/**\n * Options for Redis cache store.\n *\n * @public\n */\nexport type RedisCacheStoreOptions = {\n type: 'redis';\n client?: KeyvRedisOptions;\n cluster?: RedisClusterOptions;\n};\n\n/**\n * Options for Valkey cache store.\n *\n * @public\n */\nexport type ValkeyCacheStoreOptions = {\n type: 'valkey';\n client?: KeyvValkeyOptions;\n cluster?: {\n rootNodes: Array<ClusterNode>;\n options?: ClusterOptions;\n };\n};\n\n/**\n * Union type of all cache store options.\n *\n * @public\n */\nexport type CacheStoreOptions =\n | RedisCacheStoreOptions\n | ValkeyCacheStoreOptions\n | InfinispanCacheStoreOptions;\n\n/**\n * Options given when constructing a {@link CacheManager}.\n *\n * @public\n */\nexport type CacheManagerOptions = {\n /**\n * An optional logger for use by the PluginCacheManager.\n */\n logger?: LoggerService;\n\n /**\n * An optional handler for connection errors emitted from the underlying data\n * store.\n */\n onError?: (err: Error) => void;\n};\n\nexport function ttlToMilliseconds(ttl: number | HumanDuration): number {\n return typeof ttl === 'number' ? ttl : durationToMilliseconds(ttl);\n}\n\n/**\n * Configuration for a single Infinispan server.\n */\nexport type InfinispanServerConfig = {\n host: string;\n port: number;\n};\n\n/**\n * Options for putting values into Infinispan cache.\n */\nexport type InfinispanPutOptions = {\n lifespan?: string;\n maxIdle?: string;\n previous?: boolean;\n flags?: string[];\n};\n/**\n * SSL/TLS options for the Infinispan client.\n */\nexport type InfinispanSslOptions = {\n enabled: boolean;\n secureProtocol?: string;\n trustCerts?: string[]; // Array of trusted CA certificates\n clientAuth?: InfinispanClientAuthOptions;\n cryptoStore?: InfinispanCryptoStoreOptions;\n sniHostName?: string;\n};\n\n/**\n * Authentication options for the Infinispan client.\n * This is used for client-side authentication with the Infinispan server.\n */\nexport type InfinispanClientAuthOptions = {\n key?: string;\n passphrase?: string;\n cert?: string;\n};\n\n/**\n * Options for the Infinispan client crypto store.\n * This is used for storing keys and certificates securely.\n */\nexport type InfinispanCryptoStoreOptions = {\n path?: string;\n passphrase?: string;\n};\n\n/**\n * Authentication options for the Infinispan client.\n */\nexport type InfinispanAuthOptions = {\n enabled: boolean;\n saslMechanism?: string;\n userName?: string;\n password?: string;\n token?: string;\n authzid?: string;\n};\n\n/**\n * Options for the Infinispan cache store, designed to be configured\n * in app-config.yaml under `backend.cache.infinispan`.\n */\nexport type InfinispanCacheStoreOptions = {\n type: 'infinispan';\n servers: InfinispanServerConfig | InfinispanServerConfig[];\n options?: InfinispanClientBehaviorOptions;\n};\n\nexport type InfinispanClusterConfig = {\n name?: string;\n servers: InfinispanServerConfig[];\n};\n\nexport type DataFormatOptions = {\n keyType: 'text/plain' | 'application/json';\n valueType: 'text/plain' | 'application/json';\n};\n\n/**\n * Detailed client behavior options for the Infinispan client.\n * @public\n */\nexport type InfinispanClientBehaviorOptions = {\n version?: '2.9' | '2.5' | '2.2';\n cacheName?: string;\n maxRetries?: number;\n connectionTimeout?: number;\n socketTimeout?: number;\n authentication?: InfinispanAuthOptions;\n ssl?: InfinispanSslOptions;\n mediaType?: 'text/plain' | 'application/json';\n topologyUpdates?: boolean;\n clusters?: InfinispanClusterConfig[];\n dataFormat: DataFormatOptions;\n};\n"],"names":["durationToMilliseconds"],"mappings":";;;;AA2EO,SAAS,kBAAkB,GAAA,EAAqC;AACrE,EAAA,OAAO,OAAO,GAAA,KAAQ,QAAA,GAAW,GAAA,GAAMA,6BAAuB,GAAG,CAAA;AACnE;;;;"}
1
+ {"version":3,"file":"types.cjs.js","sources":["../../../src/entrypoints/cache/types.ts"],"sourcesContent":["/*\n * Copyright 2020 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 type {\n LoggerService,\n RootConfigService,\n} from '@backstage/backend-plugin-api';\nimport { durationToMilliseconds, type HumanDuration } from '@backstage/types';\nimport type { RedisClusterOptions, KeyvRedisOptions } from '@keyv/redis';\nimport type { KeyvValkeyOptions } from '@keyv/valkey';\nimport type { ClusterNode, ClusterOptions } from 'iovalkey';\n\n/**\n * An object form of a cache store connection, with a URL and additional\n * connection options passed through to the underlying client.\n *\n * @public\n */\nexport type CacheStoreConnectionObject = { url: string } & Record<\n string,\n unknown\n>;\n\n/**\n * A cache store connection, either a URL string or an object with\n * connection options passed through to the underlying client.\n *\n * @public\n */\nexport type CacheStoreConnection = string | CacheStoreConnectionObject;\n\n/**\n * Common config options passed to store-specific config parsers.\n *\n * @public\n */\nexport type CacheStoreConfiguration = {\n storeConfigPath: string;\n};\n\n/**\n * Service dependencies required by cache store config parsers.\n *\n * @public\n */\nexport type CacheStoreDeps = {\n config: RootConfigService;\n logger?: LoggerService;\n};\n\n/**\n * Parse options for the Redis cache store\n *\n * @public\n */\nexport type RedisCacheStoreConfiguration = CacheStoreConfiguration & {\n connection: CacheStoreConnection;\n};\n\n/**\n * Options for Redis cache store.\n *\n * @public\n */\nexport type RedisCacheStoreOptions = {\n type: 'redis';\n client?: KeyvRedisOptions;\n cluster?: RedisClusterOptions;\n};\n\n/**\n * Options for Valkey cache store.\n *\n * @public\n */\nexport type ValkeyCacheStoreOptions = {\n type: 'valkey';\n client?: KeyvValkeyOptions;\n cluster?: {\n rootNodes: Array<ClusterNode>;\n options?: ClusterOptions;\n };\n};\n\n/**\n * Union type of all cache store options.\n *\n * @public\n */\nexport type CacheStoreOptions =\n | RedisCacheStoreOptions\n | ValkeyCacheStoreOptions\n | InfinispanCacheStoreOptions;\n\n/**\n * Options given when constructing a {@link CacheManager}.\n *\n * @public\n */\nexport type CacheManagerOptions = {\n /**\n * An optional logger for use by the PluginCacheManager.\n */\n logger?: LoggerService;\n\n /**\n * An optional handler for connection errors emitted from the underlying data\n * store.\n */\n onError?: (err: Error) => void;\n};\n\nexport function ttlToMilliseconds(ttl: number | HumanDuration): number {\n return typeof ttl === 'number' ? ttl : durationToMilliseconds(ttl);\n}\n\n/**\n * Configuration for a single Infinispan server.\n */\nexport type InfinispanServerConfig = {\n host: string;\n port: number;\n};\n\n/**\n * Options for putting values into Infinispan cache.\n */\nexport type InfinispanPutOptions = {\n lifespan?: string;\n maxIdle?: string;\n previous?: boolean;\n flags?: string[];\n};\n/**\n * SSL/TLS options for the Infinispan client.\n */\nexport type InfinispanSslOptions = {\n enabled: boolean;\n secureProtocol?: string;\n trustCerts?: string[]; // Array of trusted CA certificates\n clientAuth?: InfinispanClientAuthOptions;\n cryptoStore?: InfinispanCryptoStoreOptions;\n sniHostName?: string;\n};\n\n/**\n * Authentication options for the Infinispan client.\n * This is used for client-side authentication with the Infinispan server.\n */\nexport type InfinispanClientAuthOptions = {\n key?: string;\n passphrase?: string;\n cert?: string;\n};\n\n/**\n * Options for the Infinispan client crypto store.\n * This is used for storing keys and certificates securely.\n */\nexport type InfinispanCryptoStoreOptions = {\n path?: string;\n passphrase?: string;\n};\n\n/**\n * Authentication options for the Infinispan client.\n */\nexport type InfinispanAuthOptions = {\n enabled: boolean;\n saslMechanism?: string;\n userName?: string;\n password?: string;\n token?: string;\n authzid?: string;\n};\n\n/**\n * Options for the Infinispan cache store, designed to be configured\n * in app-config.yaml under `backend.cache.infinispan`.\n */\nexport type InfinispanCacheStoreOptions = {\n type: 'infinispan';\n servers: InfinispanServerConfig | InfinispanServerConfig[];\n options?: InfinispanClientBehaviorOptions;\n};\n\nexport type InfinispanClusterConfig = {\n name?: string;\n servers: InfinispanServerConfig[];\n};\n\nexport type DataFormatOptions = {\n keyType: 'text/plain' | 'application/json';\n valueType: 'text/plain' | 'application/json';\n};\n\n/**\n * Detailed client behavior options for the Infinispan client.\n * @public\n */\nexport type InfinispanClientBehaviorOptions = {\n version?: '2.9' | '2.5' | '2.2';\n cacheName?: string;\n maxRetries?: number;\n connectionTimeout?: number;\n socketTimeout?: number;\n authentication?: InfinispanAuthOptions;\n ssl?: InfinispanSslOptions;\n mediaType?: 'text/plain' | 'application/json';\n topologyUpdates?: boolean;\n clusters?: InfinispanClusterConfig[];\n dataFormat: DataFormatOptions;\n};\n"],"names":["durationToMilliseconds"],"mappings":";;;;AA6HO,SAAS,kBAAkB,GAAA,EAAqC;AACrE,EAAA,OAAO,OAAO,GAAA,KAAQ,QAAA,GAAW,GAAA,GAAMA,6BAAuB,GAAG,CAAA;AACnE;;;;"}
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var version = "0.17.5-next.1";
5
+ var version = "0.17.5";
6
6
  var packageinfo = {
7
7
  version: version};
8
8
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/backend-defaults",
3
- "version": "0.17.5-next.1",
3
+ "version": "0.17.5",
4
4
  "description": "Backend defaults used by Backstage backend apps",
5
5
  "backstage": {
6
6
  "role": "node-library"
@@ -218,20 +218,20 @@
218
218
  "@aws-sdk/types": "^3.347.0",
219
219
  "@azure/identity": "^4.0.0",
220
220
  "@azure/storage-blob": "^12.5.0",
221
- "@backstage/backend-app-api": "1.7.2-next.0",
222
- "@backstage/backend-dev-utils": "0.1.7",
223
- "@backstage/backend-plugin-api": "1.9.3-next.0",
224
- "@backstage/cli-node": "0.3.3",
225
- "@backstage/config": "1.3.8",
226
- "@backstage/config-loader": "1.11.0-next.1",
227
- "@backstage/errors": "1.3.1",
228
- "@backstage/integration": "2.0.3",
229
- "@backstage/integration-aws-node": "0.2.0",
230
- "@backstage/plugin-auth-node": "0.7.3-next.0",
231
- "@backstage/plugin-events-node": "0.4.24-next.0",
232
- "@backstage/plugin-permission-common": "0.9.9",
233
- "@backstage/plugin-permission-node": "0.11.2-next.0",
234
- "@backstage/types": "1.2.2",
221
+ "@backstage/backend-app-api": "^1.7.2",
222
+ "@backstage/backend-dev-utils": "^0.1.7",
223
+ "@backstage/backend-plugin-api": "^1.9.3",
224
+ "@backstage/cli-node": "^0.3.4",
225
+ "@backstage/config": "^1.3.8",
226
+ "@backstage/config-loader": "^1.11.0",
227
+ "@backstage/errors": "^1.3.1",
228
+ "@backstage/integration": "^2.0.3",
229
+ "@backstage/integration-aws-node": "^0.2.0",
230
+ "@backstage/plugin-auth-node": "^0.7.3",
231
+ "@backstage/plugin-events-node": "^0.4.24",
232
+ "@backstage/plugin-permission-common": "^0.9.9",
233
+ "@backstage/plugin-permission-node": "^0.11.2",
234
+ "@backstage/types": "^1.2.2",
235
235
  "@google-cloud/storage": "^7.0.0",
236
236
  "@keyv/memcache": "^2.0.1",
237
237
  "@keyv/redis": "^4.0.1",
@@ -286,8 +286,8 @@
286
286
  },
287
287
  "devDependencies": {
288
288
  "@aws-sdk/util-stream-node": "^3.350.0",
289
- "@backstage/backend-test-utils": "1.11.5-next.0",
290
- "@backstage/cli": "0.36.4-next.1",
289
+ "@backstage/backend-test-utils": "^1.11.5",
290
+ "@backstage/cli": "^0.36.4",
291
291
  "@google-cloud/cloud-sql-connector": "^1.4.0",
292
292
  "@types/archiver": "^7.0.0",
293
293
  "@types/base64-stream": "^1.0.2",
@@ -302,7 +302,7 @@
302
302
  "better-sqlite3": "^12.0.0",
303
303
  "get-port": "^5.1.1",
304
304
  "http-errors": "^2.0.0",
305
- "msw": "^1.0.0",
305
+ "msw": "^2.0.0",
306
306
  "node-mocks-http": "^1.0.0",
307
307
  "supertest": "^7.0.0",
308
308
  "wait-for-expect": "^4.0.0"