diff --git a/.changeset/chilled-brooms-jog.md b/.changeset/chilled-brooms-jog.md
new file mode 100644
index 0000000000..d848246b2b
--- /dev/null
+++ b/.changeset/chilled-brooms-jog.md
@@ -0,0 +1,7 @@
+---
+'@backstage/backend-common': patch
+---
+
+**BREAKING**: The `CacheClient` interface must now also implement the `withOptions` method. The `.get()` method has also received a type parameter that helps ensure that `undefined` in the event of a cache miss is handled.
+
+Added a `cacheToPluginCacheManager` helper that converts a `CacheService` into a legacy `PluginCacheManager` instance.
diff --git a/.changeset/eighty-knives-repeat.md b/.changeset/eighty-knives-repeat.md
new file mode 100644
index 0000000000..3e32a3589d
--- /dev/null
+++ b/.changeset/eighty-knives-repeat.md
@@ -0,0 +1,6 @@
+---
+'@backstage/backend-app-api': patch
+'@backstage/backend-common': patch
+---
+
+Updated to match the new `CacheService` interface.
diff --git a/.changeset/twenty-pugs-explain.md b/.changeset/twenty-pugs-explain.md
new file mode 100644
index 0000000000..9ac77d2ffb
--- /dev/null
+++ b/.changeset/twenty-pugs-explain.md
@@ -0,0 +1,5 @@
+---
+'@backstage/backend-plugin-api': minor
+---
+
+**BREAKING**: The `CacheService` has been changed to remove the indirection of `getClient`, instead making the `CacheClient` methods directly available on the `CacheService`. In order to allow for the creation of clients with default options, there is now a new `.withOptions` method that must be implemented as part of the service interface.
diff --git a/packages/backend-app-api/api-report.md b/packages/backend-app-api/api-report.md
index 9329610a4c..e99135b3ec 100644
--- a/packages/backend-app-api/api-report.md
+++ b/packages/backend-app-api/api-report.md
@@ -6,6 +6,7 @@
///
import { BackendFeature } from '@backstage/backend-plugin-api';
+import { CacheClient } from '@backstage/backend-common';
import { Config } from '@backstage/config';
import { ConfigService } from '@backstage/backend-plugin-api';
import { CorsOptions } from 'cors';
@@ -22,7 +23,6 @@ import { LifecycleService } from '@backstage/backend-plugin-api';
import { LoadConfigOptionsRemote } from '@backstage/config-loader';
import { LoggerService } from '@backstage/backend-plugin-api';
import { PermissionsService } from '@backstage/backend-plugin-api';
-import { PluginCacheManager } from '@backstage/backend-common';
import { PluginDatabaseManager } from '@backstage/backend-common';
import { PluginEndpointDiscovery } from '@backstage/backend-common';
import { RequestHandler } from 'express';
@@ -48,10 +48,7 @@ export interface Backend {
}
// @public (undocumented)
-export const cacheServiceFactory: () => ServiceFactory<
- PluginCacheManager,
- 'plugin'
->;
+export const cacheServiceFactory: () => ServiceFactory;
// @public (undocumented)
export interface ConfigFactoryOptions {
diff --git a/packages/backend-app-api/src/services/implementations/cache/cacheServiceFactory.ts b/packages/backend-app-api/src/services/implementations/cache/cacheServiceFactory.ts
index 3ccd2a2fac..2208249280 100644
--- a/packages/backend-app-api/src/services/implementations/cache/cacheServiceFactory.ts
+++ b/packages/backend-app-api/src/services/implementations/cache/cacheServiceFactory.ts
@@ -31,6 +31,6 @@ export const cacheServiceFactory = createServiceFactory({
return CacheManager.fromConfig(config);
},
async factory({ plugin }, manager) {
- return manager.forPlugin(plugin.getId());
+ return manager.forPlugin(plugin.getId()).getClient();
},
});
diff --git a/packages/backend-common/api-report.md b/packages/backend-common/api-report.md
index e77a58b34c..d21ef30a0b 100644
--- a/packages/backend-common/api-report.md
+++ b/packages/backend-common/api-report.md
@@ -13,9 +13,9 @@ import { BackendFeature } from '@backstage/backend-plugin-api';
import { BitbucketCloudIntegration } from '@backstage/integration';
import { BitbucketIntegration } from '@backstage/integration';
import { BitbucketServerIntegration } from '@backstage/integration';
-import { CacheClient } from '@backstage/backend-plugin-api';
-import { CacheClientOptions } from '@backstage/backend-plugin-api';
-import { CacheClientSetOptions } from '@backstage/backend-plugin-api';
+import { CacheService as CacheClient } from '@backstage/backend-plugin-api';
+import { CacheServiceOptions as CacheClientOptions } from '@backstage/backend-plugin-api';
+import { CacheServiceSetOptions as CacheClientSetOptions } from '@backstage/backend-plugin-api';
import { Config } from '@backstage/config';
import { ConfigService } from '@backstage/backend-plugin-api';
import cors from 'cors';
@@ -38,7 +38,6 @@ import { Logger } from 'winston';
import { LoggerService } from '@backstage/backend-plugin-api';
import { MergeResult } from 'isomorphic-git';
import { PermissionsService } from '@backstage/backend-plugin-api';
-import { CacheService as PluginCacheManager } from '@backstage/backend-plugin-api';
import { DatabaseService as PluginDatabaseManager } from '@backstage/backend-plugin-api';
import { DiscoveryService as PluginEndpointDiscovery } from '@backstage/backend-plugin-api';
import { PluginMetadataService } from '@backstage/backend-plugin-api';
@@ -199,6 +198,11 @@ export type CacheManagerOptions = {
onError?: (err: Error) => void;
};
+// @public (undocumented)
+export function cacheToPluginCacheManager(
+ cache: CacheClient,
+): PluginCacheManager;
+
// @public
export const coloredFormat: winston.Logform.Format;
@@ -528,7 +532,7 @@ export const legacyPlugin: (
default: LegacyCreateRouter<
TransformedEnv<
{
- cache: PluginCacheManager;
+ cache: CacheClient;
config: ConfigService;
database: PluginDatabaseManager;
discovery: PluginEndpointDiscovery;
@@ -541,6 +545,7 @@ export const legacyPlugin: (
},
{
logger: (log: LoggerService) => Logger;
+ cache: (cache: CacheClient) => PluginCacheManager;
}
>
>;
@@ -581,7 +586,11 @@ export function makeLegacyPlugin<
// @public
export function notFoundHandler(): RequestHandler;
-export { PluginCacheManager };
+// @public (undocumented)
+export interface PluginCacheManager {
+ // (undocumented)
+ getClient(options?: CacheClientOptions): CacheClient;
+}
export { PluginDatabaseManager };
diff --git a/packages/backend-common/src/cache/CacheClient.test.ts b/packages/backend-common/src/cache/CacheClient.test.ts
index 8a5779550a..245d8687c9 100644
--- a/packages/backend-common/src/cache/CacheClient.test.ts
+++ b/packages/backend-common/src/cache/CacheClient.test.ts
@@ -32,7 +32,7 @@ describe('CacheClient', () => {
describe('CacheClient.get', () => {
it('calls client with normalized key', async () => {
- const sut = new DefaultCacheClient({ client });
+ const sut = new DefaultCacheClient(client, () => client, {});
const key = 'somekey';
await sut.get(key);
@@ -41,7 +41,7 @@ describe('CacheClient', () => {
});
it('calls client with normalized key (very long key)', async () => {
- const sut = new DefaultCacheClient({ client });
+ const sut = new DefaultCacheClient(client, () => client, {});
const key = 'x'.repeat(251);
await sut.get(key);
@@ -53,7 +53,7 @@ describe('CacheClient', () => {
});
it('rejects on underlying error', async () => {
- const sut = new DefaultCacheClient({ client });
+ const sut = new DefaultCacheClient(client, () => client, {});
const expectedError = new Error('Some runtime error');
client.get = jest.fn().mockRejectedValue(expectedError);
@@ -61,7 +61,7 @@ describe('CacheClient', () => {
});
it('resolves what underlying client resolves', async () => {
- const sut = new DefaultCacheClient({ client });
+ const sut = new DefaultCacheClient(client, () => client, {});
const expectedValue = 'some value';
client.get = jest.fn().mockResolvedValue(expectedValue);
@@ -73,7 +73,7 @@ describe('CacheClient', () => {
describe('CacheClient.set', () => {
it('calls client with normalized key', async () => {
- const sut = new DefaultCacheClient({ client });
+ const sut = new DefaultCacheClient(client, () => client, {});
const key = 'somekey';
await sut.set(key, {});
@@ -84,7 +84,7 @@ describe('CacheClient', () => {
});
it('passes ttl to client when given', async () => {
- const sut = new DefaultCacheClient({ client });
+ const sut = new DefaultCacheClient(client, () => client, {});
const expectedTtl = 3600;
await sut.set('someKey', {}, { ttl: expectedTtl });
@@ -95,7 +95,7 @@ describe('CacheClient', () => {
});
it('rejects on underlying error if configured', async () => {
- const sut = new DefaultCacheClient({ client });
+ const sut = new DefaultCacheClient(client, () => client, {});
const expectedError = new Error('Some runtime error');
client.set = jest.fn().mockRejectedValue(expectedError);
@@ -105,7 +105,7 @@ describe('CacheClient', () => {
describe('CacheClient.delete', () => {
it('calls client with normalized key', async () => {
- const sut = new DefaultCacheClient({ client });
+ const sut = new DefaultCacheClient(client, () => client, {});
const key = 'somekey';
await sut.delete(key);
@@ -116,11 +116,35 @@ describe('CacheClient', () => {
});
it('rejects on underlying error if configured', async () => {
- const sut = new DefaultCacheClient({ client });
+ const sut = new DefaultCacheClient(client, () => client, {});
const expectedError = new Error('Some runtime error');
client.delete = jest.fn().mockRejectedValue(expectedError);
return expect(sut.delete('someKey')).rejects.toEqual(expectedError);
});
});
+
+ describe('CacheClient.withOptions', () => {
+ it('merges together options to create a new instance', async () => {
+ const factory = jest.fn();
+ const sut = new DefaultCacheClient(client, factory, { foo: 1 } as any);
+ expect(factory).not.toHaveBeenCalled();
+
+ const sutA = await sut.withOptions({});
+ expect(factory).toHaveBeenLastCalledWith({ foo: 1 });
+
+ const sutA2 = await sutA.withOptions({ bar: 2 } as any);
+ expect(factory).toHaveBeenCalledWith({ foo: 1, bar: 2 });
+
+ await sutA2.withOptions({ foo: 3 } as any);
+ expect(factory).toHaveBeenCalledWith({ foo: 3, bar: 2 });
+
+ // calling .withOptions should not mutate state
+ const sutB = await sut.withOptions({ foo: 2 } as any);
+ expect(factory).toHaveBeenLastCalledWith({ foo: 2 });
+
+ await sutB.withOptions({ bar: 3 } as any);
+ expect(factory).toHaveBeenLastCalledWith({ foo: 2, bar: 3 });
+ });
+ });
});
diff --git a/packages/backend-common/src/cache/CacheClient.ts b/packages/backend-common/src/cache/CacheClient.ts
index 47cb786f14..24ee7ac455 100644
--- a/packages/backend-common/src/cache/CacheClient.ts
+++ b/packages/backend-common/src/cache/CacheClient.ts
@@ -15,50 +15,64 @@
*/
import {
- CacheClient,
- CacheClientSetOptions,
+ CacheService,
+ CacheServiceOptions,
+ CacheServiceSetOptions,
} from '@backstage/backend-plugin-api';
import { JsonValue } from '@backstage/types';
import { createHash } from 'crypto';
import Keyv from 'keyv';
-export type {
- CacheClient,
- CacheClientSetOptions,
-} from '@backstage/backend-plugin-api';
-
-type CacheClientArgs = {
- client: Keyv;
-};
+export type CacheClientFactory = (options: CacheServiceOptions) => Keyv;
/**
- * A basic, concrete implementation of the CacheClient, suitable for almost
+ * A basic, concrete implementation of the CacheService, suitable for almost
* all uses in Backstage.
*/
-export class DefaultCacheClient implements CacheClient {
- private readonly client: Keyv;
+export class DefaultCacheClient implements CacheService {
+ #client: Keyv;
+ #clientFactory: CacheClientFactory;
+ #options: CacheServiceOptions;
- constructor({ client }: CacheClientArgs) {
- this.client = client;
+ constructor(
+ client: Keyv,
+ clientFactory: CacheClientFactory,
+ options: CacheServiceOptions,
+ ) {
+ this.#client = client;
+ this.#clientFactory = clientFactory;
+ this.#options = options;
}
- async get(key: string): Promise {
+ async get(
+ key: string,
+ ): Promise {
const k = this.getNormalizedKey(key);
- return await this.client.get(k);
+ const value = await this.#client.get(k);
+ return value as TValue | undefined;
}
async set(
key: string,
value: JsonValue,
- opts: CacheClientSetOptions = {},
+ opts: CacheServiceSetOptions = {},
): Promise {
const k = this.getNormalizedKey(key);
- await this.client.set(k, value, opts.ttl);
+ await this.#client.set(k, value, opts.ttl);
}
async delete(key: string): Promise {
const k = this.getNormalizedKey(key);
- await this.client.delete(k);
+ await this.#client.delete(k);
+ }
+
+ withOptions(options: CacheServiceOptions): CacheService {
+ const newOptions = { ...this.#options, ...options };
+ return new DefaultCacheClient(
+ this.#clientFactory(newOptions),
+ this.#clientFactory,
+ newOptions,
+ );
}
/**
diff --git a/packages/backend-common/src/cache/CacheManager.test.ts b/packages/backend-common/src/cache/CacheManager.test.ts
index 50b775af25..3239be4d0e 100644
--- a/packages/backend-common/src/cache/CacheManager.test.ts
+++ b/packages/backend-common/src/cache/CacheManager.test.ts
@@ -94,7 +94,7 @@ describe('CacheManager', () => {
const client = DefaultCacheClient as jest.Mock;
const mockCalls = client.mock.calls.splice(-1);
- const realClient = mockCalls[0][0].client as Keyv;
+ const realClient = mockCalls[0][0] as Keyv;
expect(realClient.on).toHaveBeenCalledWith('error', expect.any(Function));
});
@@ -233,7 +233,7 @@ describe('CacheManager', () => {
// Retrieve the error handler attached to the cache client.
const client = DefaultCacheClient as jest.Mock;
const mockCalls = client.mock.calls.splice(-1);
- const realClient = mockCalls[0][0].client as Keyv;
+ const realClient = mockCalls[0][0] as Keyv;
const realOnError = realClient.on as jest.Mock;
const realHandler = realOnError.mock.calls.splice(-1)[0][1];
@@ -259,7 +259,7 @@ describe('CacheManager', () => {
// Retrieve the error handler attached to the cache client.
const client = DefaultCacheClient as jest.Mock;
const mockCalls = client.mock.calls.splice(-1);
- const realClient = mockCalls[0][0].client as Keyv;
+ const realClient = mockCalls[0][0] as Keyv;
const realOnError = realClient.on as jest.Mock;
const realHandler = realOnError.mock.calls.splice(-1)[0][1];
diff --git a/packages/backend-common/src/cache/CacheManager.ts b/packages/backend-common/src/cache/CacheManager.ts
index 4f7f5403a8..12ece42854 100644
--- a/packages/backend-common/src/cache/CacheManager.ts
+++ b/packages/backend-common/src/cache/CacheManager.ts
@@ -18,9 +18,13 @@ import { Config } from '@backstage/config';
import Keyv from 'keyv';
import KeyvMemcache from '@keyv/memcache';
import KeyvRedis from '@keyv/redis';
-import { LoggerService } from '@backstage/backend-plugin-api';
+import {
+ CacheService,
+ CacheServiceOptions,
+ LoggerService,
+} from '@backstage/backend-plugin-api';
import { getRootLogger } from '../logging';
-import { DefaultCacheClient, CacheClient } from './CacheClient';
+import { DefaultCacheClient } from './CacheClient';
import { NoStore } from './NoStore';
import { CacheManagerOptions, PluginCacheManager } from './types';
@@ -99,23 +103,32 @@ export class CacheManager {
*/
forPlugin(pluginId: string): PluginCacheManager {
return {
- getClient: (opts = {}): CacheClient => {
- const concreteClient = this.getClientWithTtl(pluginId, opts.defaultTtl);
+ getClient: (defaultOptions = {}) => {
+ const clientFactory = (options: CacheServiceOptions) => {
+ const concreteClient = this.getClientWithTtl(
+ pluginId,
+ options.defaultTtl,
+ );
- // Always provide an error handler to avoid stopping the process.
- concreteClient.on('error', (err: Error) => {
- // In all cases, just log the error.
- this.logger.error('Failed to create cache client', err);
+ // Always provide an error handler to avoid stopping the process.
+ concreteClient.on('error', (err: Error) => {
+ // In all cases, just log the error.
+ this.logger.error('Failed to create cache client', err);
- // Invoke any custom error handler if provided.
- if (typeof this.errorHandler === 'function') {
- this.errorHandler(err);
- }
- });
+ // Invoke any custom error handler if provided.
+ if (typeof this.errorHandler === 'function') {
+ this.errorHandler(err);
+ }
+ });
- return new DefaultCacheClient({
- client: concreteClient,
- });
+ return concreteClient;
+ };
+
+ return new DefaultCacheClient(
+ clientFactory(defaultOptions),
+ clientFactory,
+ defaultOptions,
+ );
},
};
}
@@ -164,3 +177,12 @@ export class CacheManager {
});
}
}
+
+/** @public */
+export function cacheToPluginCacheManager(
+ cache: CacheService,
+): PluginCacheManager {
+ return {
+ getClient: (opts: CacheServiceOptions) => cache.withOptions(opts),
+ };
+}
diff --git a/packages/backend-common/src/cache/index.ts b/packages/backend-common/src/cache/index.ts
index 26e6c102d8..0187aa45d5 100644
--- a/packages/backend-common/src/cache/index.ts
+++ b/packages/backend-common/src/cache/index.ts
@@ -14,9 +14,10 @@
* limitations under the License.
*/
-export type { CacheClient, CacheClientSetOptions } from './CacheClient';
-export { CacheManager } from './CacheManager';
+export { CacheManager, cacheToPluginCacheManager } from './CacheManager';
export type {
+ CacheClient,
+ CacheClientSetOptions,
PluginCacheManager,
CacheManagerOptions,
CacheClientOptions,
diff --git a/packages/backend-common/src/cache/types.ts b/packages/backend-common/src/cache/types.ts
index eeeafde5b6..93fa0ac77c 100644
--- a/packages/backend-common/src/cache/types.ts
+++ b/packages/backend-common/src/cache/types.ts
@@ -15,10 +15,15 @@
*/
import { LoggerService } from '@backstage/backend-plugin-api';
+import {
+ CacheService,
+ CacheServiceOptions,
+} from '@backstage/backend-plugin-api';
export type {
- CacheService as PluginCacheManager,
- CacheClientOptions,
+ CacheService as CacheClient,
+ CacheServiceSetOptions as CacheClientSetOptions,
+ CacheServiceOptions as CacheClientOptions,
} from '@backstage/backend-plugin-api';
/**
@@ -38,3 +43,10 @@ export type CacheManagerOptions = {
*/
onError?: (err: Error) => void;
};
+
+/**
+ * @public
+ */
+export interface PluginCacheManager {
+ getClient(options?: CacheServiceOptions): CacheService;
+}
diff --git a/packages/backend-common/src/legacy.ts b/packages/backend-common/src/legacy.ts
index 214e65e0c7..408966f3bc 100644
--- a/packages/backend-common/src/legacy.ts
+++ b/packages/backend-common/src/legacy.ts
@@ -20,6 +20,7 @@ import {
ServiceRef,
} from '@backstage/backend-plugin-api';
import { RequestHandler } from 'express';
+import { cacheToPluginCacheManager } from './cache';
import { loggerToWinstonLogger } from './logging';
/**
@@ -119,5 +120,6 @@ export const legacyPlugin = makeLegacyPlugin(
},
{
logger: log => loggerToWinstonLogger(log),
+ cache: cache => cacheToPluginCacheManager(cache),
},
);
diff --git a/packages/backend-plugin-api/api-report.md b/packages/backend-plugin-api/api-report.md
index 6a0b5e51e7..5e64502b78 100644
--- a/packages/backend-plugin-api/api-report.md
+++ b/packages/backend-plugin-api/api-report.md
@@ -72,31 +72,27 @@ export interface BackendPluginRegistrationPoints {
}
// @public
-export interface CacheClient {
+export interface CacheService {
delete(key: string): Promise;
- get(key: string): Promise;
+ get(key: string): Promise;
set(
key: string,
value: JsonValue,
- options?: CacheClientSetOptions,
+ options?: CacheServiceSetOptions,
): Promise;
+ withOptions(options: CacheServiceOptions): CacheService;
}
// @public
-export type CacheClientOptions = {
+export type CacheServiceOptions = {
defaultTtl?: number;
};
// @public
-export type CacheClientSetOptions = {
+export type CacheServiceSetOptions = {
ttl?: number;
};
-// @public
-export interface CacheService {
- getClient: (options?: CacheClientOptions) => CacheClient;
-}
-
// @public (undocumented)
export interface ConfigService extends Config {}
diff --git a/packages/backend-plugin-api/src/services/definitions/CacheService.ts b/packages/backend-plugin-api/src/services/definitions/CacheService.ts
index 2702fdac6d..ccf88823b0 100644
--- a/packages/backend-plugin-api/src/services/definitions/CacheService.ts
+++ b/packages/backend-plugin-api/src/services/definitions/CacheService.ts
@@ -17,29 +17,11 @@
import { JsonValue } from '@backstage/types';
/**
- * Manages access to cache stores that plugins get.
+ * Options passed to {@link CacheService.set}.
*
* @public
*/
-export interface CacheService {
- /**
- * Provides backend plugins cache connections for themselves.
- *
- * @remarks
- *
- * The purpose of this method is to allow plugins to get isolated data stores
- * so that plugins are discouraged from cache-level integration and/or cache
- * key collisions.
- */
- getClient: (options?: CacheClientOptions) => CacheClient;
-}
-
-/**
- * Options passed to {@link CacheClient.set}.
- *
- * @public
- */
-export type CacheClientSetOptions = {
+export type CacheServiceSetOptions = {
/**
* Optional TTL in milliseconds. Defaults to the TTL provided when the client
* was set up (or no TTL if none are provided).
@@ -48,17 +30,31 @@ export type CacheClientSetOptions = {
};
/**
- * A pre-configured, storage agnostic cache client suitable for use by
+ * Options passed to {@link CacheService.withOptions}.
+ *
+ * @public
+ */
+export type CacheServiceOptions = {
+ /**
+ * An optional default TTL (in milliseconds) to be set when getting a client
+ * instance. If not provided, data will persist indefinitely by default (or
+ * can be configured per entry at set-time).
+ */
+ defaultTtl?: number;
+};
+
+/**
+ * A pre-configured, storage agnostic cache service suitable for use by
* Backstage plugins.
*
* @public
*/
-export interface CacheClient {
+export interface CacheService {
/**
* Reads data from a cache store for the given key. If no data was found,
* returns undefined.
*/
- get(key: string): Promise;
+ get(key: string): Promise;
/**
* Writes the given data to a cache store, associated with the given key. An
@@ -68,25 +64,16 @@ export interface CacheClient {
set(
key: string,
value: JsonValue,
- options?: CacheClientSetOptions,
+ options?: CacheServiceSetOptions,
): Promise;
/**
* Removes the given key from the cache store.
*/
delete(key: string): Promise;
-}
-/**
- * Options given when constructing a {@link CacheClient}.
- *
- * @public
- */
-export type CacheClientOptions = {
/**
- * An optional default TTL (in milliseconds) to be set when getting a client
- * instance. If not provided, data will persist indefinitely by default (or
- * can be configured per entry at set-time).
+ * Creates a new {@link CacheService} instance with the given options.
*/
- defaultTtl?: number;
-};
+ withOptions(options: CacheServiceOptions): CacheService;
+}
diff --git a/packages/backend-plugin-api/src/services/definitions/index.ts b/packages/backend-plugin-api/src/services/definitions/index.ts
index 35c2f0251c..0122bc0be8 100644
--- a/packages/backend-plugin-api/src/services/definitions/index.ts
+++ b/packages/backend-plugin-api/src/services/definitions/index.ts
@@ -17,9 +17,8 @@
export { coreServices } from './coreServices';
export type {
CacheService,
- CacheClient,
- CacheClientOptions,
- CacheClientSetOptions,
+ CacheServiceOptions,
+ CacheServiceSetOptions,
} from './CacheService';
export type { ConfigService } from './ConfigService';
export type { DatabaseService } from './DatabaseService';
diff --git a/plugins/adr-backend/src/service/router.test.ts b/plugins/adr-backend/src/service/router.test.ts
index fbbd6e8532..f12b29c70a 100644
--- a/plugins/adr-backend/src/service/router.test.ts
+++ b/plugins/adr-backend/src/service/router.test.ts
@@ -107,6 +107,8 @@ class MockCacheClient implements CacheClient {
async delete(key: string) {
delete this.itemRegistry[key];
}
+
+ withOptions = () => this;
}
describe('createRouter', () => {
diff --git a/plugins/auth-backend/api-report.md b/plugins/auth-backend/api-report.md
index 88cb33863e..f6b19189cd 100644
--- a/plugins/auth-backend/api-report.md
+++ b/plugins/auth-backend/api-report.md
@@ -7,7 +7,7 @@
import { BackstageIdentityResponse } from '@backstage/plugin-auth-node';
import { BackstageSignInResult } from '@backstage/plugin-auth-node';
-import { CacheClient } from '@backstage/backend-plugin-api';
+import { CacheService } from '@backstage/backend-plugin-api';
import { CatalogApi } from '@backstage/catalog-client';
import { Config } from '@backstage/config';
import { Entity } from '@backstage/catalog-model';
@@ -486,7 +486,7 @@ export const providers: Readonly<{
signIn: {
resolver: SignInResolver;
};
- cache?: CacheClient | undefined;
+ cache?: CacheService | undefined;
}) => AuthProviderFactory;
resolvers: Readonly<{
emailMatchingUserEntityProfileEmail: () => SignInResolver;
diff --git a/plugins/auth-backend/src/providers/cloudflare-access/provider.test.ts b/plugins/auth-backend/src/providers/cloudflare-access/provider.test.ts
index 6653bc38cb..1abca4bdf4 100644
--- a/plugins/auth-backend/src/providers/cloudflare-access/provider.test.ts
+++ b/plugins/auth-backend/src/providers/cloudflare-access/provider.test.ts
@@ -83,6 +83,7 @@ const mockCacheClient = {
get: jest.fn(),
set: jest.fn(),
delete: jest.fn(),
+ withOptions: jest.fn(),
};
jest.mock('jose');
diff --git a/plugins/techdocs-backend/src/cache/TechDocsCache.test.ts b/plugins/techdocs-backend/src/cache/TechDocsCache.test.ts
index 039f1db09f..fa4c81682c 100644
--- a/plugins/techdocs-backend/src/cache/TechDocsCache.test.ts
+++ b/plugins/techdocs-backend/src/cache/TechDocsCache.test.ts
@@ -31,6 +31,7 @@ describe('TechDocsCache', () => {
get: jest.fn(),
set: jest.fn(),
delete: jest.fn(),
+ withOptions: jest.fn(),
};
CacheUnderTest = TechDocsCache.fromConfig(new ConfigReader({}), {
cache: MockClient,