Harmonize phantom .T getter behavior between ExtensionPoint and ServiceRef
Both `createExtensionPoint` and `createServiceRef` now consistently return `null` from the phantom `.T` getter instead of throwing. Added `toJSON()` to `ExtensionPoint` for parity with `ServiceRef`. Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> Made-with: Cursor Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> Made-with: Cursor
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-plugin-api': patch
|
||||
---
|
||||
|
||||
Harmonized the phantom `.T` getter on `ExtensionPoint` to consistently return `null` instead of throwing.
|
||||
@@ -25,6 +25,18 @@ const rootDep = createServiceRef<number>({ id: 'y', scope: 'root' });
|
||||
const pluginDep = createServiceRef<boolean>({ id: 'z' });
|
||||
function unused(..._any: any[]) {}
|
||||
|
||||
describe('createServiceRef', () => {
|
||||
it('should create a ServiceRef', () => {
|
||||
expect(ref.id).toBe('x');
|
||||
expect(ref.scope).toBe('plugin');
|
||||
expect(ref.T).toBe(null);
|
||||
expect(String(ref)).toBe('serviceRef{x}');
|
||||
expect(JSON.stringify(ref)).toBe(
|
||||
'{"$$type":"@backstage/ServiceRef","id":"x","scope":"plugin","multiton":false}',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('createServiceFactory', () => {
|
||||
it('should create a plugin scoped factory', () => {
|
||||
const factory = createServiceFactory({
|
||||
|
||||
@@ -144,13 +144,12 @@ export function createServiceRef<
|
||||
scope,
|
||||
multiton,
|
||||
get T(): TService {
|
||||
throw new Error(`tried to read ServiceRef.T of ${this}`);
|
||||
return null as TService;
|
||||
},
|
||||
toString() {
|
||||
return `serviceRef{${options.id}}`;
|
||||
},
|
||||
toJSON() {
|
||||
// This avoids accidental calls to T happening e.g. in tests
|
||||
return {
|
||||
$$type: '@backstage/ServiceRef',
|
||||
id,
|
||||
|
||||
@@ -18,10 +18,10 @@ import { createExtensionPoint } from './createExtensionPoint';
|
||||
|
||||
describe('createExtensionPoint', () => {
|
||||
it('should create an ExtensionPoint', () => {
|
||||
const extensionPoint = createExtensionPoint({ id: 'x' });
|
||||
const extensionPoint = createExtensionPoint<string>({ id: 'x' });
|
||||
expect(extensionPoint).toBeDefined();
|
||||
expect(extensionPoint.id).toBe('x');
|
||||
expect(() => extensionPoint.T).not.toThrow();
|
||||
expect(extensionPoint.T).toBe(null);
|
||||
expect(String(extensionPoint)).toBe('extensionPoint{x}');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -44,11 +44,7 @@ export function createExtensionPoint<T>(
|
||||
return {
|
||||
id: options.id,
|
||||
get T(): T {
|
||||
if (process.env.NODE_ENV === 'test') {
|
||||
// Avoid throwing errors so tests asserting extensions' properties cannot be easily broken
|
||||
return null as T;
|
||||
}
|
||||
throw new Error(`tried to read ExtensionPoint.T of ${this}`);
|
||||
return null as T;
|
||||
},
|
||||
toString() {
|
||||
return `extensionPoint{${options.id}}`;
|
||||
|
||||
Reference in New Issue
Block a user