frontend-plugin-api: remove type support for multiple attachment points
This is a follow-up to the deprecation in #32521, completely removing the Array variant from the ExtensionDefinitionAttachTo type. The runtime still supports multiple attachment points for backward compatibility, but new code will receive type errors. Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
@@ -1205,26 +1205,7 @@ export type ExtensionDefinitionAttachTo<
|
||||
input: string;
|
||||
id?: never;
|
||||
}
|
||||
| ExtensionInput<UParentInputs>
|
||||
/**
|
||||
* @deprecated Multiple attachment points are deprecated and will be removed in a future release. Use a Utility API instead to share functionality across multiple locations. See https://backstage.io/docs/frontend-system/architecture/27-sharing-extensions for migration guidance.
|
||||
*/
|
||||
| Array<
|
||||
| {
|
||||
id: string;
|
||||
input: string;
|
||||
relative?: never;
|
||||
}
|
||||
| {
|
||||
relative: {
|
||||
kind?: string;
|
||||
name?: string;
|
||||
};
|
||||
input: string;
|
||||
id?: never;
|
||||
}
|
||||
| ExtensionInput<UParentInputs>
|
||||
>;
|
||||
| ExtensionInput<UParentInputs>;
|
||||
|
||||
// @public (undocumented)
|
||||
export type ExtensionDefinitionParameters = {
|
||||
|
||||
+4
-6
@@ -32,12 +32,10 @@ describe('AnalyticsBlueprint', () => {
|
||||
{
|
||||
"$$type": "@backstage/ExtensionDefinition",
|
||||
"T": undefined,
|
||||
"attachTo": [
|
||||
{
|
||||
"id": "api:app/analytics",
|
||||
"input": "implementations",
|
||||
},
|
||||
],
|
||||
"attachTo": {
|
||||
"id": "api:app/analytics",
|
||||
"input": "implementations",
|
||||
},
|
||||
"configSchema": undefined,
|
||||
"disabled": false,
|
||||
"factory": [Function],
|
||||
|
||||
@@ -41,7 +41,7 @@ const factoryDataRef =
|
||||
*/
|
||||
export const AnalyticsImplementationBlueprint = createExtensionBlueprint({
|
||||
kind: 'analytics',
|
||||
attachTo: [{ id: 'api:app/analytics', input: 'implementations' }],
|
||||
attachTo: { id: 'api:app/analytics', input: 'implementations' },
|
||||
output: [factoryDataRef],
|
||||
dataRefs: {
|
||||
factory: factoryDataRef,
|
||||
|
||||
@@ -202,12 +202,14 @@ describe('createExtension', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should create an extension with multiple attachment points', () => {
|
||||
// Tests for backward compatibility - runtime still supports multiple attachment points
|
||||
// but the TypeScript types no longer allow them
|
||||
it('should create an extension with multiple attachment points (backward compat)', () => {
|
||||
const extension = createExtension({
|
||||
attachTo: [
|
||||
{ id: 'root', input: 'default' },
|
||||
{ id: 'other', input: 'default' },
|
||||
],
|
||||
] as any,
|
||||
output: [stringDataRef, numberDataRef.optional()],
|
||||
factory: () => [stringDataRef('bar')],
|
||||
});
|
||||
@@ -216,14 +218,14 @@ describe('createExtension', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should create an extension with relative attachment points', () => {
|
||||
it('should create an extension with relative attachment points (backward compat)', () => {
|
||||
const extension = createExtension({
|
||||
attachTo: [
|
||||
{ relative: {}, input: 'tabs' },
|
||||
{ relative: { kind: 'page' }, input: 'tabs' },
|
||||
{ relative: { name: 'index' }, input: 'tabs' },
|
||||
{ relative: { kind: 'page', name: 'index' }, input: 'tabs' },
|
||||
],
|
||||
] as any,
|
||||
output: [stringDataRef],
|
||||
factory: () => [stringDataRef('bar')],
|
||||
});
|
||||
@@ -232,7 +234,7 @@ describe('createExtension', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should create an extension with relative attachment points by reference', () => {
|
||||
it('should create an extension with relative attachment points by reference (backward compat)', () => {
|
||||
const baseOpts = {
|
||||
attachTo: { id: 'root', input: 'children' },
|
||||
inputs: {
|
||||
@@ -269,7 +271,7 @@ describe('createExtension', () => {
|
||||
parent2.inputs.tabs,
|
||||
parent3.inputs.tabs,
|
||||
parent4.inputs.otherTabs,
|
||||
],
|
||||
] as any,
|
||||
output: [stringDataRef],
|
||||
factory: () => [stringDataRef('bar')],
|
||||
});
|
||||
@@ -281,7 +283,7 @@ describe('createExtension', () => {
|
||||
parent2.inputs.tabs,
|
||||
parent3.inputs.tabs,
|
||||
parent4.inputs.otherTabs,
|
||||
],
|
||||
] as any,
|
||||
});
|
||||
expect(String(overrdeExtension)).toBe(
|
||||
'ExtensionDefinition{attachTo=page:<plugin>@tabs+<plugin>/index@tabs+page:<plugin>/index@otherTabs}',
|
||||
|
||||
@@ -134,11 +134,10 @@ export type VerifyExtensionAttachTo<
|
||||
*
|
||||
* A standard attachment point declaration will specify the ID of the parent extension, as well as the name of the input to attach to.
|
||||
*
|
||||
* There are three more advanced forms that are available for more complex use-cases:
|
||||
* There are two more advanced forms that are available for more complex use-cases:
|
||||
*
|
||||
* 1. Relative attachment points: using the `relative` property instead of `id`, the attachment point is resolved relative to the current plugin.
|
||||
* 2. Extension input references: using a reference in code to another extension's input in the same plugin. These references are always relative.
|
||||
* 3. Array of attachment points: an array of attachment points can be used to clone and attach to multiple extensions at once.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
@@ -151,12 +150,6 @@ export type VerifyExtensionAttachTo<
|
||||
* // Attach to a specific input of another extension
|
||||
* const page = ParentBlueprint.make({ ... });
|
||||
* const child = ChildBlueprint.make({ attachTo: page.inputs.children });
|
||||
*
|
||||
* // Attach to multiple parents at once (deprecated - use Utility APIs instead)
|
||||
* [
|
||||
* { id: 'page/home', input: 'widgets' },
|
||||
* { relative: { kind: 'page' }, input: 'widgets' },
|
||||
* ]
|
||||
* ```
|
||||
*
|
||||
* @public
|
||||
@@ -166,19 +159,7 @@ export type ExtensionDefinitionAttachTo<
|
||||
> =
|
||||
| { id: string; input: string; relative?: never }
|
||||
| { relative: { kind?: string; name?: string }; input: string; id?: never }
|
||||
| ExtensionInput<UParentInputs>
|
||||
/**
|
||||
* @deprecated Multiple attachment points are deprecated and will be removed in a future release. Use a Utility API instead to share functionality across multiple locations. See https://backstage.io/docs/frontend-system/architecture/27-sharing-extensions for migration guidance.
|
||||
*/
|
||||
| Array<
|
||||
| { id: string; input: string; relative?: never }
|
||||
| {
|
||||
relative: { kind?: string; name?: string };
|
||||
input: string;
|
||||
id?: never;
|
||||
}
|
||||
| ExtensionInput<UParentInputs>
|
||||
>;
|
||||
| ExtensionInput<UParentInputs>;
|
||||
|
||||
/** @public */
|
||||
export type CreateExtensionOptions<
|
||||
|
||||
@@ -92,11 +92,7 @@ describe('createExtensionBlueprint', () => {
|
||||
it('should allow creation of extension blueprints with a generator', () => {
|
||||
const TestExtensionBlueprint = createExtensionBlueprint({
|
||||
kind: 'test-extension',
|
||||
// Try multiple attachment points for this one
|
||||
attachTo: [
|
||||
{ id: 'test-1', input: 'default' },
|
||||
{ id: 'test-2', input: 'default' },
|
||||
],
|
||||
attachTo: { id: 'test-1', input: 'default' },
|
||||
output: [coreExtensionData.reactElement],
|
||||
*factory(params: { text: string }) {
|
||||
yield coreExtensionData.reactElement(<h1>{params.text}</h1>);
|
||||
@@ -112,10 +108,7 @@ describe('createExtensionBlueprint', () => {
|
||||
|
||||
expect(extension).toEqual({
|
||||
$$type: '@backstage/ExtensionDefinition',
|
||||
attachTo: [
|
||||
{ id: 'test-1', input: 'default' },
|
||||
{ id: 'test-2', input: 'default' },
|
||||
],
|
||||
attachTo: { id: 'test-1', input: 'default' },
|
||||
configSchema: undefined,
|
||||
disabled: false,
|
||||
inputs: {},
|
||||
@@ -1345,7 +1338,9 @@ describe('createExtensionBlueprint', () => {
|
||||
).toThrow('Refused to override params and factory at the same time');
|
||||
});
|
||||
|
||||
describe('with relative attachment points', () => {
|
||||
// Tests for backward compatibility - runtime still supports multiple attachment points
|
||||
// but the TypeScript types no longer allow them
|
||||
describe('with relative attachment points (backward compat)', () => {
|
||||
const dataRef = createExtensionDataRef<string>().with({ id: 'test.data' });
|
||||
|
||||
it('should create an extension with relative attachment points', () => {
|
||||
@@ -1356,7 +1351,7 @@ describe('createExtensionBlueprint', () => {
|
||||
{ relative: { kind: 'page' }, input: 'tabs' },
|
||||
{ relative: { name: 'index' }, input: 'tabs' },
|
||||
{ relative: { kind: 'page', name: 'index' }, input: 'tabs' },
|
||||
],
|
||||
] as any,
|
||||
output: [dataRef],
|
||||
factory: () => [dataRef('bar')],
|
||||
});
|
||||
@@ -1371,7 +1366,7 @@ describe('createExtensionBlueprint', () => {
|
||||
{ relative: { kind: 'page' }, input: 'tabs' },
|
||||
{ relative: { name: 'index' }, input: 'tabs' },
|
||||
{ relative: { kind: 'page', name: 'index' }, input: 'tabs' },
|
||||
],
|
||||
] as any,
|
||||
params: {},
|
||||
}),
|
||||
),
|
||||
@@ -1431,7 +1426,7 @@ describe('createExtensionBlueprint', () => {
|
||||
parent2.inputs.tabs,
|
||||
parent3.inputs.tabs,
|
||||
parent4.inputs.otherTabs,
|
||||
],
|
||||
] as any,
|
||||
output: [dataRef],
|
||||
factory: () => [dataRef('bar')],
|
||||
});
|
||||
@@ -1445,7 +1440,7 @@ describe('createExtensionBlueprint', () => {
|
||||
parent2.inputs.tabs,
|
||||
parent3.inputs.tabs,
|
||||
parent4.inputs.otherTabs,
|
||||
],
|
||||
] as any,
|
||||
params: {},
|
||||
}),
|
||||
),
|
||||
|
||||
@@ -140,6 +140,7 @@ describe('resolveExtensionDefinition', () => {
|
||||
input: 'children',
|
||||
});
|
||||
|
||||
// Test for backward compatibility - runtime still supports multiple attachment points
|
||||
expect(
|
||||
resolveExtensionDefinition(
|
||||
OpaqueExtensionDefinition.toInternal({
|
||||
@@ -157,7 +158,7 @@ describe('resolveExtensionDefinition', () => {
|
||||
kind: 'k3',
|
||||
input: 'children',
|
||||
}),
|
||||
],
|
||||
] as any,
|
||||
}),
|
||||
{ namespace: 'test' },
|
||||
).attachTo,
|
||||
|
||||
@@ -149,11 +149,11 @@ function resolveExtensionId(
|
||||
}
|
||||
|
||||
function resolveAttachTo(
|
||||
attachTo: ExtensionDefinitionAttachTo,
|
||||
attachTo: ExtensionDefinitionAttachTo | ExtensionDefinitionAttachTo[],
|
||||
namespace?: string,
|
||||
): ExtensionAttachToSpec {
|
||||
const resolveSpec = (
|
||||
spec: Exclude<ExtensionDefinitionAttachTo, Array<any>>,
|
||||
spec: ExtensionDefinitionAttachTo,
|
||||
): { id: string; input: string } => {
|
||||
if (OpaqueExtensionInput.isType(spec)) {
|
||||
const { context } = OpaqueExtensionInput.toInternal(spec);
|
||||
|
||||
Reference in New Issue
Block a user