diff --git a/.changeset/mira-looking-ostrich.md b/.changeset/mira-looking-ostrich.md index 2d75fe2ce8..fb85b10d0d 100644 --- a/.changeset/mira-looking-ostrich.md +++ b/.changeset/mira-looking-ostrich.md @@ -2,12 +2,12 @@ '@backstage/frontend-plugin-api': patch --- -Plugins should now use the new `AnalyticsBlueprint` to define and provide concrete analytics implementations. For example: +Plugins should now use the new `AnalyticsImplementationBlueprint` to define and provide concrete analytics implementations. For example: ```ts -import { AnalyticsBlueprint } from '@backstage/frontend-plugin-api'; +import { AnalyticsImplementationBlueprint } from '@backstage/frontend-plugin-api'; -const AcmeAnalytics = AnalyticsBlueprint.make({ +const AcmeAnalytics = AnalyticsImplementationBlueprint.make({ name: 'acme-analytics', params: define => define({ diff --git a/.changeset/nej-inte-ostrich.md b/.changeset/nej-inte-ostrich.md index db97567b54..434708e2e4 100644 --- a/.changeset/nej-inte-ostrich.md +++ b/.changeset/nej-inte-ostrich.md @@ -2,4 +2,4 @@ '@backstage/plugin-app': patch --- -The default implementation of the Analytics API now collects and instantiates analytics implementations exposed via `AnalyticsBlueprint` extensions. If no such extensions are discovered, the API continues to do nothing with analytics events fired within Backstage. If multiple such extensions are discovered, every discovered implementation automatically receives analytics events. +The default implementation of the Analytics API now collects and instantiates analytics implementations exposed via `AnalyticsImplementationBlueprint` extensions. If no such extensions are discovered, the API continues to do nothing with analytics events fired within Backstage. If multiple such extensions are discovered, every discovered implementation automatically receives analytics events. diff --git a/docs/plugins/analytics.md b/docs/plugins/analytics.md index 037eb3d92d..f383e8881c 100644 --- a/docs/plugins/analytics.md +++ b/docs/plugins/analytics.md @@ -103,22 +103,23 @@ export const apis: AnyApiFactory[] = [ ]; // Or, when building for the new frontend system: -import { AnalyticsBlueprint } from '@backstage/frontend-plugin-api'; +import { AnalyticsImplementationBlueprint } from '@backstage/frontend-plugin-api'; -export const acmeAnalyticsImplementation = AnalyticsBlueprint.make({ - name: 'acme', - params: define => - define({ - deps: {}, - factory() { - return { - captureEvent: event => { - window._AcmeAnalyticsQ.push(event); - }, - }; - }, - }), -}); +export const acmeAnalyticsImplementation = + AnalyticsImplementationBlueprint.make({ + name: 'acme', + params: define => + define({ + deps: {}, + factory() { + return { + captureEvent: event => { + window._AcmeAnalyticsQ.push(event); + }, + }; + }, + }), + }); ``` In reality, you would likely want to encapsulate instantiation logic and pull @@ -160,16 +161,17 @@ export const apis: AnyApiFactory[] = [ ]; // Or, when building for the new frontend system: -import { AnalyticsBlueprint } from '@backstage/frontend-plugin-api'; +import { AnalyticsImplementationBlueprint } from '@backstage/frontend-plugin-api'; -export const acmeAnalyticsImplementation = AnalyticsBlueprint.make({ - name: 'acme', - params: define => - define({ - deps: { configApi: configApiRef }, - factory: ({ configApi }) => AcmeAnalytics.fromConfig(configApi), - }), -}); +export const acmeAnalyticsImplementation = + AnalyticsImplementationBlueprint.make({ + name: 'acme', + params: define => + define({ + deps: { configApi: configApiRef }, + factory: ({ configApi }) => AcmeAnalytics.fromConfig(configApi), + }), + }); ``` If you are integrating with an analytics service (as opposed to an internal diff --git a/packages/frontend-plugin-api/report.api.md b/packages/frontend-plugin-api/report.api.md index 30c7d0d612..3d65591c57 100644 --- a/packages/frontend-plugin-api/report.api.md +++ b/packages/frontend-plugin-api/report.api.md @@ -107,30 +107,6 @@ export type AnalyticsApi = { // @public export const analyticsApiRef: ApiRef; -// @public -export const AnalyticsBlueprint: ExtensionBlueprint<{ - kind: 'analytics'; - name: undefined; - params: ( - params: AnalyticsImplementationFactory, - ) => ExtensionBlueprintParams>; - output: ConfigurableExtensionDataRef< - AnalyticsImplementationFactory<{}>, - 'core.analytics.factory', - {} - >; - inputs: {}; - config: {}; - configInput: {}; - dataRefs: { - factory: ConfigurableExtensionDataRef< - AnalyticsImplementationFactory<{}>, - 'core.analytics.factory', - {} - >; - }; -}>; - // @public export const AnalyticsContext: (options: { attributes: Partial; @@ -164,6 +140,30 @@ export type AnalyticsImplementation = { captureEvent(event: AnalyticsEvent): void; }; +// @public +export const AnalyticsImplementationBlueprint: ExtensionBlueprint<{ + kind: 'analytics'; + name: undefined; + params: ( + params: AnalyticsImplementationFactory, + ) => ExtensionBlueprintParams>; + output: ConfigurableExtensionDataRef< + AnalyticsImplementationFactory<{}>, + 'core.analytics.factory', + {} + >; + inputs: {}; + config: {}; + configInput: {}; + dataRefs: { + factory: ConfigurableExtensionDataRef< + AnalyticsImplementationFactory<{}>, + 'core.analytics.factory', + {} + >; + }; +}>; + // @public (undocumented) export type AnalyticsImplementationFactory< Deps extends { diff --git a/packages/frontend-plugin-api/src/apis/definitions/AnalyticsApi.ts b/packages/frontend-plugin-api/src/apis/definitions/AnalyticsApi.ts index 9752d0bd6f..c6ec4478f4 100644 --- a/packages/frontend-plugin-api/src/apis/definitions/AnalyticsApi.ts +++ b/packages/frontend-plugin-api/src/apis/definitions/AnalyticsApi.ts @@ -16,7 +16,7 @@ import { ApiRef, createApiRef } from '@backstage/core-plugin-api'; import { AnalyticsContextValue } from '../../analytics/types'; -import type { AnalyticsBlueprint } from '../../blueprints/'; +import type { AnalyticsImplementationBlueprint } from '../../blueprints/'; /** * Represents an event worth tracking in an analytics system that could inform @@ -149,8 +149,8 @@ export type AnalyticsApi = { * * @remarks * - * To define a concrete Analytics Implementation, use {@link AnalyticsBlueprint} - * instead. + * To define a concrete Analytics Implementation, use + * {@link AnalyticsImplementationBlueprint} instead. * * @public */ diff --git a/packages/frontend-plugin-api/src/blueprints/AnalyticsBlueprint.test.ts b/packages/frontend-plugin-api/src/blueprints/AnalyticsImplementationBlueprint.test.ts similarity index 90% rename from packages/frontend-plugin-api/src/blueprints/AnalyticsBlueprint.test.ts rename to packages/frontend-plugin-api/src/blueprints/AnalyticsImplementationBlueprint.test.ts index 1618c38335..4a9e21a13d 100644 --- a/packages/frontend-plugin-api/src/blueprints/AnalyticsBlueprint.test.ts +++ b/packages/frontend-plugin-api/src/blueprints/AnalyticsImplementationBlueprint.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { AnalyticsBlueprint } from './AnalyticsBlueprint'; +import { AnalyticsImplementationBlueprint } from './AnalyticsImplementationBlueprint'; describe('AnalyticsBlueprint', () => { it('should create an extension with sensible defaults', () => { @@ -23,7 +23,7 @@ describe('AnalyticsBlueprint', () => { factory: () => ({ captureEvent: () => {} }), }; - const extension = AnalyticsBlueprint.make({ + const extension = AnalyticsImplementationBlueprint.make({ params: define => define(factory), name: 'test', }); diff --git a/packages/frontend-plugin-api/src/blueprints/AnalyticsBlueprint.ts b/packages/frontend-plugin-api/src/blueprints/AnalyticsImplementationBlueprint.ts similarity index 95% rename from packages/frontend-plugin-api/src/blueprints/AnalyticsBlueprint.ts rename to packages/frontend-plugin-api/src/blueprints/AnalyticsImplementationBlueprint.ts index 8bd4c0526e..260a58a941 100644 --- a/packages/frontend-plugin-api/src/blueprints/AnalyticsBlueprint.ts +++ b/packages/frontend-plugin-api/src/blueprints/AnalyticsImplementationBlueprint.ts @@ -39,7 +39,7 @@ const factoryDataRef = * * @public */ -export const AnalyticsBlueprint = createExtensionBlueprint({ +export const AnalyticsImplementationBlueprint = createExtensionBlueprint({ kind: 'analytics', attachTo: [{ id: 'api:app/analytics', input: 'analyticsImplementations' }], output: [factoryDataRef], diff --git a/packages/frontend-plugin-api/src/blueprints/index.ts b/packages/frontend-plugin-api/src/blueprints/index.ts index 29aa410e80..0060571ca2 100644 --- a/packages/frontend-plugin-api/src/blueprints/index.ts +++ b/packages/frontend-plugin-api/src/blueprints/index.ts @@ -15,9 +15,9 @@ */ export { - AnalyticsBlueprint, + AnalyticsImplementationBlueprint, type AnalyticsImplementationFactory, -} from './AnalyticsBlueprint'; +} from './AnalyticsImplementationBlueprint'; export { ApiBlueprint } from './ApiBlueprint'; export { AppRootElementBlueprint } from './AppRootElementBlueprint'; export { AppRootWrapperBlueprint } from './AppRootWrapperBlueprint'; diff --git a/plugins/app/src/extensions/AnalyticsApi.test.ts b/plugins/app/src/extensions/AnalyticsApi.test.ts index 814f41b616..d0763de9d5 100644 --- a/plugins/app/src/extensions/AnalyticsApi.test.ts +++ b/plugins/app/src/extensions/AnalyticsApi.test.ts @@ -16,7 +16,7 @@ import { createExtensionTester } from '@backstage/frontend-test-utils'; import { AnalyticsApi } from './AnalyticsApi'; import { - AnalyticsBlueprint, + AnalyticsImplementationBlueprint, AnalyticsImplementation, ApiBlueprint, configApiRef, @@ -38,10 +38,10 @@ describe('AnalyticsApi', () => { const MockImplementation1 = createExtension({ name: 'mock-implementation-1', attachTo: { id: 'api:analytics', input: 'analyticsImplementations' }, - output: [AnalyticsBlueprint.dataRefs.factory], + output: [AnalyticsImplementationBlueprint.dataRefs.factory], factory() { return [ - AnalyticsBlueprint.dataRefs.factory({ + AnalyticsImplementationBlueprint.dataRefs.factory({ deps: { configApi: configApiRef }, factory: deps => ({ captureEvent: event => captureEventSpy1(event, deps), @@ -54,10 +54,10 @@ describe('AnalyticsApi', () => { const MockImplementation2 = createExtension({ name: 'mock-implementation-2', attachTo: { id: 'api:analytics', input: 'analyticsImplementations' }, - output: [AnalyticsBlueprint.dataRefs.factory], + output: [AnalyticsImplementationBlueprint.dataRefs.factory], factory() { return [ - AnalyticsBlueprint.dataRefs.factory({ + AnalyticsImplementationBlueprint.dataRefs.factory({ deps: { config: configApiRef, identityApi: identityApiRef }, factory: deps => ({ captureEvent: event => captureEventSpy2(event, deps), diff --git a/plugins/app/src/extensions/AnalyticsApi.ts b/plugins/app/src/extensions/AnalyticsApi.ts index 5e64e5abcf..f121e5a02e 100644 --- a/plugins/app/src/extensions/AnalyticsApi.ts +++ b/plugins/app/src/extensions/AnalyticsApi.ts @@ -16,7 +16,7 @@ import { analyticsApiRef, - AnalyticsBlueprint, + AnalyticsImplementationBlueprint, ApiBlueprint, ApiRef, createExtensionInput, @@ -26,7 +26,7 @@ export const AnalyticsApi = ApiBlueprint.makeWithOverrides({ name: 'analytics', inputs: { analyticsImplementations: createExtensionInput([ - AnalyticsBlueprint.dataRefs.factory, + AnalyticsImplementationBlueprint.dataRefs.factory, ]), }, factory(originalFactory, { inputs }) { @@ -35,7 +35,9 @@ export const AnalyticsApi = ApiBlueprint.makeWithOverrides({ // if they were its own deps. const aggregatedDeps = inputs.analyticsImplementations .flatMap>(impls => - Object.values(impls.get(AnalyticsBlueprint.dataRefs.factory).deps), + Object.values( + impls.get(AnalyticsImplementationBlueprint.dataRefs.factory).deps, + ), ) .reduce<{ [x: string]: ApiRef }>((accum, ref) => { accum[ref.id] = ref; @@ -48,7 +50,9 @@ export const AnalyticsApi = ApiBlueprint.makeWithOverrides({ deps: aggregatedDeps, factory: analyticsApiDeps => { const actualApis = inputs.analyticsImplementations - .map(impl => impl.get(AnalyticsBlueprint.dataRefs.factory)) + .map(impl => + impl.get(AnalyticsImplementationBlueprint.dataRefs.factory), + ) .map(({ factory, deps }) => factory( // Reconstruct a deps argument to pass to this analytics