diff --git a/packages/frontend-plugin-api/src/blueprints/ApiBlueprint.test.ts b/packages/frontend-plugin-api/src/blueprints/ApiBlueprint.test.ts index 862f802810..6eafcf2556 100644 --- a/packages/frontend-plugin-api/src/blueprints/ApiBlueprint.test.ts +++ b/packages/frontend-plugin-api/src/blueprints/ApiBlueprint.test.ts @@ -16,21 +16,19 @@ import { createExtensionInput } from '../wiring'; import { ApiBlueprint } from './ApiBlueprint'; -import { createApiFactory, createApiRef } from '@backstage/core-plugin-api'; +import { createApiRef } from '@backstage/core-plugin-api'; describe('ApiBlueprint', () => { it('should create an extension with sensible defaults', () => { const api = createApiRef<{ foo: string }>({ id: 'test' }); - const factory = createApiFactory({ - api, - deps: {}, - factory: () => ({ foo: 'bar' }), - }); const extension = ApiBlueprint.make({ - params: { - factory, - }, + params: define => + define({ + api, + deps: {}, + factory: () => ({ foo: 'bar' }), + }), name: 'test', }); @@ -58,6 +56,97 @@ describe('ApiBlueprint', () => { `); }); + it('should properly type the API factory', () => { + const fooApi = createApiRef<{ foo: string }>({ id: 'foo' }); + const barApi = createApiRef<{ bar: string }>({ id: 'bar' }); + + expect('test').not.toBe('failing without assertions'); + + ApiBlueprint.make({ + params: define => + define({ api: fooApi, deps: {}, factory: () => ({ foo: 'foo' }) }), + }); + + ApiBlueprint.make({ + params: define => + define({ + api: fooApi, + deps: {}, + // @ts-expect-error missing property + factory: () => ({}), + }), + }); + + ApiBlueprint.make({ + params: define => + define({ + api: fooApi, + deps: {}, + // @ts-expect-error wrong property + factory: () => ({ + bar: 'bar', + }), + }), + }); + + ApiBlueprint.make({ + params: define => + define({ + api: fooApi, + deps: {}, + factory: () => ({ + // @ts-expect-error wrong type + foo: 1, + }), + }), + }); + + ApiBlueprint.make({ + params: define => + define({ + api: fooApi, + deps: { bar: barApi }, + factory: ({ bar }) => ({ foo: bar.bar }), + }), + }); + + ApiBlueprint.make({ + params: define => + define({ + api: fooApi, + deps: { bar: barApi }, + factory: ({ bar }) => ({ + // @ts-expect-error not an available property + foo: bar.foo, + }), + }), + }); + + ApiBlueprint.make({ + params: define => + define({ + api: fooApi, + deps: { bar: barApi }, + factory: ({ bar }) => ({ + // @ts-expect-error not an available property + foo: bar.foo, + }), + }), + }); + + ApiBlueprint.make({ + params: define => + define({ + api: fooApi, + deps: {}, + factory: ({ bar }) => ({ + // @ts-expect-error unknown dep + foo: bar.bar, + }), + }), + }); + }); + it('should create an extension with custom factory', () => { const api = createApiRef<{ foo: string }>({ id: 'test' }); const factory = jest.fn(() => ({ foo: 'bar' })); @@ -73,13 +162,7 @@ describe('ApiBlueprint', () => { }, name: api.id, factory(originalFactory, { config: _config, inputs: _inputs }) { - return originalFactory({ - factory: createApiFactory({ - api, - deps: {}, - factory, - }), - }); + return originalFactory(define => define({ api, deps: {}, factory })); }, }); diff --git a/packages/frontend-plugin-api/src/blueprints/ApiBlueprint.ts b/packages/frontend-plugin-api/src/blueprints/ApiBlueprint.ts index 1f28a3cf54..a066a362d9 100644 --- a/packages/frontend-plugin-api/src/blueprints/ApiBlueprint.ts +++ b/packages/frontend-plugin-api/src/blueprints/ApiBlueprint.ts @@ -14,8 +14,9 @@ * limitations under the License. */ +import { AnyApiFactory, ApiFactory } from '../apis/system'; import { createExtensionBlueprint, createExtensionDataRef } from '../wiring'; -import { AnyApiFactory } from '@backstage/core-plugin-api'; +import { createExtensionBlueprintParams } from '../wiring/createExtensionBlueprint'; const factoryDataRef = createExtensionDataRef().with({ id: 'core.api.factory', @@ -33,7 +34,14 @@ export const ApiBlueprint = createExtensionBlueprint({ dataRefs: { factory: factoryDataRef, }, - *factory(params: { factory: AnyApiFactory }) { - yield factoryDataRef(params.factory); + defineParams: < + TApi, + TImpl extends TApi, + TDeps extends { [name in string]: unknown }, + >( + params: ApiFactory, + ) => createExtensionBlueprintParams(params as AnyApiFactory), + *factory(params) { + yield factoryDataRef(params); }, });